From fd7e342b8834da41faa10ab16ba0df140537ab5b Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 14:04:56 +0200 Subject: [PATCH 01/69] feat(renderer): migrate core rendering from G6 to Sigma.js (phases 0-1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0+1 of the full G6→Sigma cutover per MIGRATION.md: - vendor sigma@3 + graphology + bubblesets-js as two esbuild bundles (graphology node-safe for vitest, sigma browser-only, 267 kB combined) - add deterministic 6000n/9000e perf harness (npm run perf) encoding the MIGRATION.md acceptance gates; all five gates pass (load 729 ms, first-interaction stall 65 ms, wheel-zoom 60 FPS, 500-node select 43 ms) - new graph_model.js: graphology population + pure node/edge reducers - new sigma_adapter.js: transitional G6-shaped facade (sole sigma importer) - core.js: replace G6 instance/event choreography with sequential sigma lifecycle; delete G6#6373 zoom workaround and dead event locks - filter.js: port visibility to graphology hidden-attr diffing - tests: 645 passing (29 new for model/reducers/filter; 9 G6-source-pinning tests removed); review fixes from code-reviewer + js-reviewer passes Interactions, shapes/labels parity, bubble sets and layout parity follow in phases 2-5; g6.min.js removal in phase 6. --- .gitignore | 3 + MIGRATION.md | 167 +++++ package-lock.json | 210 ++++++- package.json | 16 +- scripts/generate_benchmark_fixture.js | 178 ++++++ scripts/perf_benchmark.js | 431 +++++++++++++ src/gll.js | 26 +- src/graph/core.js | 544 ++--------------- src/graph/filter.js | 20 +- src/graph/graph_model.js | 193 ++++++ src/graph/layout.js | 6 +- src/graph/sigma_adapter.js | 500 +++++++++++++++ src/lib/graphology.bundle.mjs | 2 + src/lib/sigma.bundle.mjs | 771 ++++++++++++++++++++++++ src/package/vendor_entry_graphology.mjs | 8 + src/package/vendor_entry_sigma.mjs | 9 + src/package/vendor_libs.js | 41 ++ tests/filter-visibility.test.js | 96 +++ tests/graph-model.test.js | 330 ++++++++++ tests/style-panel-regression.test.js | 124 +--- 20 files changed, 3023 insertions(+), 652 deletions(-) create mode 100644 MIGRATION.md create mode 100644 scripts/generate_benchmark_fixture.js create mode 100644 scripts/perf_benchmark.js create mode 100644 src/graph/graph_model.js create mode 100644 src/graph/sigma_adapter.js create mode 100644 src/lib/graphology.bundle.mjs create mode 100644 src/lib/sigma.bundle.mjs create mode 100644 src/package/vendor_entry_graphology.mjs create mode 100644 src/package/vendor_entry_sigma.mjs create mode 100644 tests/filter-visibility.test.js create mode 100644 tests/graph-model.test.js diff --git a/.gitignore b/.gitignore index 29e6524..7404a81 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ dist/ src/gll.bundle.js src/gll.bundle.js.map +# Perf benchmark artifacts (regenerate via npm run perf:fixture / npm run perf) +scripts/fixtures/ + # Compiled Java class files *.class diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 0000000..6c706f5 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,167 @@ +# Migration: AntV G6 → Sigma.js v3 + +Full cutover of the rendering stack from AntV G6 5.0.48 (canvas) to Sigma.js v3 + +graphology + bubblesets-js. G6 is removed entirely at the end; no dual-renderer +period. Work happens on a long-lived feature branch (`feat/sigma-renderer`) and +merges when the parity checklist below passes. + +## Why (measured 2026-06-10, 6000 nodes / 9000 edges, AMD Radeon 890M) + +| Metric | G6 canvas | G6 WebGL (`@antv/g-webgl`) | +|---|---|---| +| Initial load → rendered | 1.6 s | 55 s | +| Full `graph.render()` | ~10 s (includes layout) | 88–205 s, degrades per call | +| Pure redraw `graph.draw()` | 0.65 s | 90 s | +| Wheel zoom | **~4 FPS (~500 ms/tick)** | unusable | +| Warm drag-pan | ~163 FPS (fine) | unusable | +| First pan/zoom after load | **~11 s stall** (lazy init) | n/a | +| Select 500 nodes | 0.14 s | 21 s | + +- G6's WebGL renderer was spiked and rejected (10–100× slower than canvas). +- G6's `optimize-viewport-transform` behavior was tested and rejected (zoom 4 FPS + with vs 5 FPS without; it hides edges but nodes dominate zoom cost). +- The canvas pain (wheel zoom re-rendering every node, 11 s first-interaction + stall, 10 s full renders) is inherent to G6 at >10k elements. No tuning path + remains on the current stack. + +## Target stack + +| Concern | Library | Notes | +|---|---|---| +| Rendering | `sigma` v3 (WebGL nodes/edges, canvas labels) | MIT, actively maintained | +| Graph model | `graphology` + relevant `graphology-*` utils | replaces G6's internal data store | +| Bubble sets | `bubblesets-js` (standalone, MIT) | the SAME library G6's plugin wraps — outline geometry is renderer-agnostic. Drawn on a custom sigma canvas layer under the node layer; issue #7195 disappears with G6 | +| Layouts | keep `@antv/layout` headlessly (positions in → positions out) for force/radial/concentric/mds; circular + grid as trivial geometric functions | layouts were never the perf problem; replace opportunistically later. Alternative: `graphology-layout-forceatlas2` (web-worker build) for force | +| Node shapes | `@sigma/node-square` + texture-based shapes via `@sigma/node-image` (rasterize hexagon/diamond/triangle/star as SVG textures); circle is native | custom GLSL programs only if texture quality disappoints | +| Curved edges | `@sigma/edge-curve` | maps cubic/quadratic; polyline degrades to curve (note in UI docs) | +| PNG export | `@sigma/export-image` | replaces `graph.toDataURL` | +| Vendoring | esbuild bundle into `src/lib/` (same pattern as `src/package/vendor_libs.js` / `build` scripts); removes 1.12 MB `g6.min.js` | sigma+graphology ≈ 200 kB minified | + +## Concept mapping (G6 → Sigma) + +| G6 | Sigma/graphology | +|---|---| +| `new Graph({data, node.state, edge.state, behaviors, plugins})` | `new Sigma(graphologyGraph, container, settings)`; states → `nodeReducer`/`edgeReducer`; behaviors → explicit event handlers; plugins → custom layers / DOM | +| `updateData / updateNodeData / updateEdgeData` | graphology `setNodeAttribute` etc.; sigma re-renders reactively (`refresh()` when batching) | +| `render()` (async, layout+draw) | layout is explicit (run algorithm → write x/y attributes); `sigma.refresh()` is sync and cheap | +| `draw()` | `sigma.refresh({ skipIndexation: true })` for pure visual updates | +| `setElementState(map)` | maintain app-level Sets (`cache.selectedNodes` already exists) + `refresh`; reducers read them | +| `getElementState(id)` | read the same app-level Sets — G6 round-trips disappear | +| states `selected/highlight/dim` + halo | reducers return modified `color/size/zIndex/borderColor`; "halo" via border program or a bigger ghost node — decide in Phase 2 | +| `hover-activate` (1-degree) | `enterNode` event + `graph.neighbors()` + reducers (already gated by `DISABLE_HOVER_EFFECT` thresholds — keep them) | +| `drag-element` | `downNode` + mousemove → `graphToViewport`/`viewportToGraph`, standard sigma recipe | +| `drag-canvas` / `zoom-canvas` | built-in camera; `animation: false` equivalents via camera API options | +| `lasso-select` | custom canvas overlay + point-in-polygon over node viewport coords (no library dependency; ~150 LOC) | +| `click-select` (shift-multi) | `clickNode` event + modifier check | +| tooltip plugin | pure DOM positioned via `graphToViewport` on `clickNode` — `cache.toolTips` content generation is unchanged | +| minimap plugin | custom canvas layer rendering node positions at thumbnail scale (~100 LOC), or defer to a later release (decide at Phase 4) | +| bubble-sets plugin (4 groups) | `bubblesets-js` fed with node viewport rects + avoid rects → path2D on a `beforeLayer` canvas; group labels drawn on the same layer. `GraphBubbleSetManager` member/filter logic is renderer-agnostic and survives | +| `fitView / zoomTo / getZoom / translateBy` | `camera.animatedReset / camera.setState / getState` — also deletes the G6 zoom-at-non-1.0 workaround in `core.js` | +| `toDataURL` | `@sigma/export-image` | +| `setElementZIndex` (drag z-fix) | `zIndex` attribute via reducer; G6 workaround deleted | + +## Phases + +Each phase ends with tests green and a working app on the branch. + +### Phase 0 — Scaffolding (small) +- Branch `feat/sigma-renderer`; add deps; extend the esbuild vendoring so dev + serve (`npm run serve`), Electron, bundle, and inline-html dist all load sigma. +- Commit a benchmark fixture generator + Playwright perf script under `scripts/` + (recreate: 6000 nodes / 9000 edges, 8 clusters, deterministic seed; measure + load, wheel-zoom FPS, drag-pan FPS, 500-node select). These are the + acceptance gates and prevent regressions during the port. + +### Phase 1 — Data model + core lifecycle (medium) +- `Cache.iterNodes/iterEdges` populate a graphology `Graph` (keep `nodeRef` + Maps initially; collapse later — graphology attributes can become the single + source of truth in Phase 6). +- Rewrite `GraphCoreManager.createGraphInstance` (`src/graph/core.js:166`) and + `decideToRenderOrDraw` (`core.js:111`): render/draw distinction becomes + layout-vs-refresh. The `AFTER_DRAW`/`AFTER_RENDER` event-lock choreography + simplifies — sigma refresh is synchronous. +- Port `GraphFilterManager`: filtered elements get `hidden: true` attributes + (sigma reducers skip hidden cheaply) — same Sets (`nodeIDsToBeShown` etc.). + +### Phase 2 — Visual parity (medium-large) +- Node programs: circle native, square package, hexagon/diamond/triangle/star + as SVG textures via node-image. Per-node `type`/`style` from + `GraphStyleManager` maps to sigma attributes; per-layout style Maps unchanged. +- Edge rendering: straight + curved + arrows; lineDash needs a custom program + or is dropped for v1 (flag in UI docs). +- Labels: sigma's label density system replaces `MAX_NODES_BEFORE_HIDING_LABELS` + (keep the CFG as an override). Node + edge label styling parity. +- States via reducers: selected (border/halo), highlight, dim — colors from + `config.js` state specs. + +### Phase 3 — Interactions (medium) +- Node drag (with position persistence via `lm.persistNodePositions`), + click/shift-select, hover-activate with existing thresholds, lasso overlay, + hotkeys (renderer-agnostic already), tooltip. +- Delete G6 workarounds: lasso/canvas-click event juggling + (`APPLY_BUBBLE_SET_HOTFIX` paths), dragend zIndex reset, zoom-translate quirk. + +### Phase 4 — Overlays (medium) +- Bubble sets: custom layer + `bubblesets-js`; wire `GraphBubbleSetManager` + (member sync + style UI survive as-is; only the draw target changes). + `avoidMembers` becomes cheap — re-evaluate the + `MAX_NODES_BEFORE_DISABLING_AVOID_MEMBERS_IN_BUBBLE_GROUPS` threshold. +- PNG export; minimap (build or consciously defer). + +### Phase 5 — Layouts (small-medium) +- Wire `@antv/layout` (or FA2 worker) behind `GraphLayoutManager.applyLayout`; + circular/grid as geometric functions. Custom layout = position Maps, already + renderer-agnostic. Force layout for authored payloads without positions + (see commit b6f8606) must keep working. + +### Phase 6 — Cleanup + release (small) +- Remove `src/lib/g6.min.js`, the `G6` global destructures, `APPLY_BUBBLE_SET_HOTFIX`, + stale thresholds; collapse duplicate state between `nodeRef` and graphology + if not done earlier. Update README/API.md/CHANGELOG; bundle-size check + (expect ≈ −900 kB); minor version bump. + +## Files touched (from the 2026-06-10 audit; ~60 G6 call sites) + +| File | Work | +|---|---| +| `src/gll.js` | drop `G6` destructure; graphology instance in `Cache` | +| `src/graph/core.js` | full rewrite (instance, events, viewport, states) | +| `src/graph/layout.js` | layout execution + position persistence rewiring | +| `src/graph/selection.js` | swap state round-trips for app-level Sets + refresh | +| `src/graph/bubble_sets.js` | draw target → custom layer; logic survives | +| `src/graph/style.js`, `src/graph/filter.js` | attribute mapping only | +| `src/managers/ui.js` | behavior toggling → handler enable/disable | +| `src/managers/io.js`, `ui_components.js`, `metrics.js`, `api_client.js`, `query.js` | `getNodeData()/getEdgeData()` call sites → graphology reads | +| `server/*` | untouched (verified renderer-agnostic) | +| `tests/*` | new unit tests for reducers, lasso geometry, bubble-set layer, layout adapters (≥80 % on new modules); existing 622 tests must stay green | + +## Acceptance criteria (the merge gate) + +Perf at 15k elements (the Phase 0 harness): load ≤ 2 s · wheel zoom ≥ 30 FPS +(currently 4) · warm drag-pan ≥ 60 FPS · no first-interaction stall > 500 ms +(currently ~11 s) · 500-node select < 200 ms. + +Functional parity: 6 node shapes, edge styles (minus documented lineDash/polyline +degradations), labels + thresholds, all 4 bubble groups incl. styling UI and +filter/manual membership, lasso + click + shift-select, hover highlight, tooltip, +drag with persistence, all layouts incl. custom, Excel/JSON import-export +round-trip, PNG export, SSE live ingest (`?session=`), Electron + inline-html +dist builds. + +## Known risks + +1. **Shape fidelity via textures** (crisp at high zoom?) — prototype hexagon in + Phase 2 first; fall back to custom GLSL program if needed. +2. **lineDash / polyline edges** — no off-the-shelf sigma support; scope as + documented degradation or custom program. +3. **Minimap** — custom build; defer if Phase 4 runs long. +4. **Excel style round-trip** — exported styles must map back losslessly; + add a round-trip test early in Phase 2. +5. **Icon/texture-heavy styling at scale** — sigma's known weak spot; the + benchmark harness catches it. + +## Next-session kickoff prompt + +> Read MIGRATION.md and start the Sigma.js migration: create the +> `feat/sigma-renderer` branch and implement Phase 0 (deps, vendoring, benchmark +> harness with the acceptance gates), then continue with Phase 1. diff --git a/package-lock.json b/package-lock.json index 1bc2ba6..1448b36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,24 @@ { "name": "graph-lens-lite", - "version": "1.14.1", + "version": "1.14.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "graph-lens-lite", - "version": "1.14.1", + "version": "1.14.2", "dependencies": { + "@sigma/edge-curve": "^3.1.0", + "@sigma/export-image": "^3.0.0", + "@sigma/node-image": "^3.0.0", + "@sigma/node-square": "^3.0.0", + "bubblesets-js": "^3.0.1", "dompurify": "^3.4.1", - "marked": "^18.0.2" + "graphology": "^0.26.0", + "graphology-layout": "^0.6.1", + "graphology-layout-forceatlas2": "^0.10.1", + "marked": "^18.0.2", + "sigma": "^3.0.3" }, "devDependencies": { "electron": "^36.3.1", @@ -19,6 +28,7 @@ "inline-source": "^8.0.3", "inline-source-cli": "^1.2.0", "jsdom": "^29.0.2", + "playwright": "^1.60.0", "rimraf": "^6.0.1", "vitest": "^4.0.18" } @@ -1975,6 +1985,45 @@ "win32" ] }, + "node_modules/@sigma/edge-curve": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigma/edge-curve/-/edge-curve-3.1.0.tgz", + "integrity": "sha512-OFWkfAXEsm+X8l1K4K49cC0psB0gQ+gqxKA08HG5piNPdzrDZ5gG9Gza6htZ5AirOVwd/4/uq/gPpD5En+H+3Q==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.10" + } + }, + "node_modules/@sigma/export-image": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigma/export-image/-/export-image-3.0.0.tgz", + "integrity": "sha512-6JmWle7byUzAOGE3P3ttDqn2PbdnNETyFU13i4R0G3PIZcIiVqPRpRWBkz11E89oxKEzEf1XdwQKa9VxHDMD0w==", + "license": "MIT", + "dependencies": { + "file-saver": "^2.0.5" + }, + "peerDependencies": { + "sigma": ">=3.0.0-beta.10" + } + }, + "node_modules/@sigma/node-image": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigma/node-image/-/node-image-3.0.0.tgz", + "integrity": "sha512-i4WLNPugDY4jgQEZtNSiSVj4HHXOraciXLtlgdygeUxMVEhH8PJ/+Q1vQ9f/SlKFnZQ+7vH3HnsSDW6FD9aP+g==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.10" + } + }, + "node_modules/@sigma/node-square": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigma/node-square/-/node-square-3.0.0.tgz", + "integrity": "sha512-hPX2oWo7WeaSe6M3D56AXsrLyg3F+7N/YsodaJh4Sw3KTce0GAFVWWPZZklu9CITz0xi3kEmlCGulqAH0cVG2w==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.17" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2767,6 +2816,12 @@ "balanced-match": "^1.0.0" } }, + "node_modules/bubblesets-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bubblesets-js/-/bubblesets-js-3.0.1.tgz", + "integrity": "sha512-EKPfysvIU5+u5RLW3mOr94wxzA3nKzqMBX0F95L95BPBDZPVgLBUnT0kJNz4UK/TXbGs8G7yEgl5MvibRBCQoQ==", + "license": "MIT" + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -4529,6 +4584,15 @@ "@types/estree": "^1.0.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/exceljs": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz", @@ -4679,6 +4743,12 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -5095,6 +5165,59 @@ "dev": true, "license": "ISC" }, + "node_modules/graphology": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/graphology/-/graphology-0.26.0.tgz", + "integrity": "sha512-8SSImzgUUYC89Z042s+0r/vMibY7GX/Emz4LDO5e7jYXhuoWfHISPFJYjpRLUSJGq6UQ6xlenvX1p/hJdfXuXg==", + "license": "MIT", + "dependencies": { + "events": "^3.3.0" + }, + "peerDependencies": { + "graphology-types": ">=0.24.0" + } + }, + "node_modules/graphology-layout": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/graphology-layout/-/graphology-layout-0.6.1.tgz", + "integrity": "sha512-m9aMvbd0uDPffUCFPng5ibRkb2pmfNvdKjQWeZrf71RS1aOoat5874+DcyNfMeCT4aQguKC7Lj9eCbqZj/h8Ag==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.3.0", + "pandemonium": "^2.4.0" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-layout-forceatlas2": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz", + "integrity": "sha512-ogzBeF1FvWzjkikrIFwxhlZXvD2+wlY54lqhsrWprcdPjopM2J9HoMweUmIgwaTvY4bUYVimpSsOdvDv1gPRFQ==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.1.0" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-types": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz", + "integrity": "sha512-hDRKYXa8TsoZHjgEaysSRyPdT6uB78Ci8WnjgbStlQysz7xR52PInxNsmnB7IBOM1BhikxkNyCVEFgmPKnpx3Q==", + "license": "MIT", + "peer": true + }, + "node_modules/graphology-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz", + "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==", + "license": "MIT", + "peerDependencies": { + "graphology-types": ">=0.23.0" + } + }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -6832,6 +6955,15 @@ "node": ">=10" } }, + "node_modules/mnemonist": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", + "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -7078,6 +7210,12 @@ "node": ">= 0.4" } }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -7208,6 +7346,15 @@ "dev": true, "license": "(MIT AND Zlib)" }, + "node_modules/pandemonium": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz", + "integrity": "sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==", + "license": "MIT", + "dependencies": { + "mnemonist": "^0.39.2" + } + }, "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -7418,6 +7565,53 @@ "node": ">=0.10.0" } }, + "node_modules/playwright": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", + "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.60.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", + "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -8074,6 +8268,16 @@ "dev": true, "license": "ISC" }, + "node_modules/sigma": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sigma/-/sigma-3.0.3.tgz", + "integrity": "sha512-5H0zFlx6/NTQpqBg4Rm569ZOpnBOXMaS25UQThIWMU3XyzI5AhmorK/gnl87BvJBLhQd0tW4C0LIp3enWzMoNw==", + "license": "MIT", + "dependencies": { + "events": "^3.3.0", + "graphology-utils": "^2.5.2" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", diff --git a/package.json b/package.json index e44915b..2b322d1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ "serve:api": "npm run vendor-libs && node --env-file-if-exists=.env server/index.js", "version": "npm run inject-version && git add src/config.js", "test": "vitest run", - "test:watch": "vitest" + "test:watch": "vitest", + "perf:fixture": "node scripts/generate_benchmark_fixture.js", + "perf": "node scripts/perf_benchmark.js" }, "build": { "appId": "com.delta4ai.graphlenslite", @@ -72,11 +74,21 @@ "inline-source": "^8.0.3", "inline-source-cli": "^1.2.0", "jsdom": "^29.0.2", + "playwright": "^1.60.0", "rimraf": "^6.0.1", "vitest": "^4.0.18" }, "dependencies": { + "@sigma/edge-curve": "^3.1.0", + "@sigma/export-image": "^3.0.0", + "@sigma/node-image": "^3.0.0", + "@sigma/node-square": "^3.0.0", + "bubblesets-js": "^3.0.1", "dompurify": "^3.4.1", - "marked": "^18.0.2" + "graphology": "^0.26.0", + "graphology-layout": "^0.6.1", + "graphology-layout-forceatlas2": "^0.10.1", + "marked": "^18.0.2", + "sigma": "^3.0.3" } } diff --git a/scripts/generate_benchmark_fixture.js b/scripts/generate_benchmark_fixture.js new file mode 100644 index 0000000..78c045e --- /dev/null +++ b/scripts/generate_benchmark_fixture.js @@ -0,0 +1,178 @@ +#!/usr/bin/env node +// Generates the deterministic benchmark fixture for the renderer perf harness +// (MIGRATION.md Phase 0): 6000 nodes / 9000 edges in 8 clusters, ~85% of the +// edges intra-cluster. Same PRNG seed -> byte-identical output, so the file is +// never committed — regenerate via `npm run perf:fixture`. +// +// Output shape mirrors a native JSON export (IOManager.exportGraphAsJSON / +// parseJSON / preProcessData) and is accepted by both the file input +// (cache.io.loadFileWrapper) and window.renderGraphData: +// - nodes: [{id, label, style: {labelText}, D4Data: {"Node filters": {...}}}] +// - edges: [{id, source, target, D4Data: {"Edge filters": {...}}}] +// - node/edgeDataHeaders: [{subGroup, key}] (drives the data table + filters) +// - layouts.Default.positions: {id: {style: {x, y}}} — precomputed positions +// so the load measurement times rendering, not the force layout +// - selectedLayout: "Default" +// Run: node scripts/generate_benchmark_fixture.js +// Output: scripts/fixtures/benchmark_6000x9000.json + +const fs = require("fs"); +const path = require("path"); + +const SEED = 0xd417a; +const NODE_COUNT = 6000; +const EDGE_COUNT = 9000; +const CLUSTER_COUNT = 8; +const INTRA_CLUSTER_EDGE_RATIO = 0.85; +const CLUSTER_RING_RADIUS = 1600; +const CLUSTER_SPREAD = 260; + +const OUT_DIR = path.join(__dirname, "fixtures"); +const OUT_FILE = path.join(OUT_DIR, "benchmark_6000x9000.json"); + +const CATEGORIES = ["Kinase", "Receptor", "Transporter", "Enzyme", "Ligand", "Channel"]; +const PATHWAYS = ["Apoptosis", "Inflammation", "Metabolism", "Signaling", "Transport"]; + +// Deterministic 32-bit PRNG (mulberry32) — no Math.random anywhere. +function mulberry32(seed) { + let state = seed >>> 0; + return function next() { + state = (state + 0x6d2b79f5) >>> 0; + let t = state; + t = Math.imul(t ^ (t >>> 15), t | 1); + t ^= t + Math.imul(t ^ (t >>> 7), t | 61); + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +const rand = mulberry32(SEED); +const randInt = (maxExclusive) => Math.floor(rand() * maxExclusive); +const pick = (arr) => arr[randInt(arr.length)]; +const round1 = (value) => Math.round(value * 10) / 10; + +// Box-Muller gaussian fed by the seeded PRNG (for cluster blobs). +function gaussian(mean, sigma) { + const u1 = Math.max(rand(), 1e-12); + const u2 = rand(); + return mean + sigma * Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2); +} + +function clusterCenter(clusterIndex) { + const angle = (2 * Math.PI * clusterIndex) / CLUSTER_COUNT; + return { + x: Math.cos(angle) * CLUSTER_RING_RADIUS, + y: Math.sin(angle) * CLUSTER_RING_RADIUS, + }; +} + +function buildNodes() { + const nodes = []; + const positions = {}; + const nodesPerCluster = NODE_COUNT / CLUSTER_COUNT; + + for (let i = 0; i < NODE_COUNT; i++) { + const cluster = Math.floor(i / nodesPerCluster); + const id = `n${i}`; + const label = `C${cluster}-Node-${i}`; + const center = clusterCenter(cluster); + + nodes.push({ + id, + label, + style: {labelText: label}, + D4Data: { + "Node filters": { + Topology: {Cluster: `Cluster ${cluster}`}, + Biology: { + Category: pick(CATEGORIES), + // Pipe-separated multi-value categorical (exercises the splitter) + Pathway: `${pick(PATHWAYS)}|${pick(PATHWAYS)}`, + Score: round1(rand() * 100), + }, + }, + }, + }); + positions[id] = { + style: { + x: round1(gaussian(center.x, CLUSTER_SPREAD)), + y: round1(gaussian(center.y, CLUSTER_SPREAD)), + }, + }; + } + return {nodes, positions}; +} + +function buildEdges() { + const nodesPerCluster = NODE_COUNT / CLUSTER_COUNT; + const nodeInCluster = (cluster) => `n${cluster * nodesPerCluster + randInt(nodesPerCluster)}`; + const edges = []; + + for (let i = 0; i < EDGE_COUNT; i++) { + const isIntra = rand() < INTRA_CLUSTER_EDGE_RATIO; + const sourceCluster = randInt(CLUSTER_COUNT); + let targetCluster = sourceCluster; + if (!isIntra) { + targetCluster = (sourceCluster + 1 + randInt(CLUSTER_COUNT - 1)) % CLUSTER_COUNT; + } + + let source = nodeInCluster(sourceCluster); + let target = nodeInCluster(targetCluster); + // Bounded self-loop avoidance: with a 1-node cluster an unbounded retry + // would never terminate; after a few attempts keep the self-loop (the + // app supports them) rather than spin. + for (let attempt = 0; target === source && attempt < 10; attempt++) { + target = nodeInCluster(targetCluster); + } + + edges.push({ + id: `e${i}`, + source, + target, + D4Data: { + "Edge filters": { + Scores: { + Weight: round1(rand() * 10), + Type: isIntra ? "intra-cluster" : "inter-cluster", + }, + }, + }, + }); + } + return edges; +} + +function main() { + const {nodes, positions} = buildNodes(); + const edges = buildEdges(); + + const fixture = { + nodes, + edges, + nodeDataHeaders: [ + {subGroup: "Topology", key: "Cluster"}, + {subGroup: "Biology", key: "Category"}, + {subGroup: "Biology", key: "Pathway"}, + {subGroup: "Biology", key: "Score"}, + ], + edgeDataHeaders: [ + {subGroup: "Scores", key: "Weight"}, + {subGroup: "Scores", key: "Type"}, + ], + selectedLayout: "Default", + // Positions present -> parseLayouts leaves layoutType undefined -> the app + // skips the initial force layout and renders the stored coordinates. + layouts: { + Default: {positions}, + }, + }; + + fs.mkdirSync(OUT_DIR, {recursive: true}); + fs.writeFileSync(OUT_FILE, JSON.stringify(fixture)); + const sizeMb = (fs.statSync(OUT_FILE).size / 1024 / 1024).toFixed(1); + console.log( + `[fixture] ${path.relative(process.cwd(), OUT_FILE)} — ` + + `${nodes.length} nodes / ${edges.length} edges, ${CLUSTER_COUNT} clusters, ${sizeMb} MB`, + ); +} + +main(); diff --git a/scripts/perf_benchmark.js b/scripts/perf_benchmark.js new file mode 100644 index 0000000..133eb60 --- /dev/null +++ b/scripts/perf_benchmark.js @@ -0,0 +1,431 @@ +#!/usr/bin/env node +// Renderer performance benchmark (MIGRATION.md Phase 0 acceptance gates). +// Boots the app in headless chromium against the benchmark fixture and +// measures: load time, first-interaction stall, wheel-zoom FPS, drag-pan FPS +// and 500-node select time. Prints a gate table and writes JSON results to +// scripts/fixtures/perf_results_.json. +// +// Run: node scripts/perf_benchmark.js [--assert] +// --assert exit 1 when any acceptance gate fails (CI mode) +// +// Fixture loading choice: the harness calls window.renderGraphData(data) +// (src/managers/api_client.js) instead of page.setInputFiles on #fileInput. +// renderGraphData returns a promise that resolves only after preProcessData → +// createGraphInstance → graph.render() → fitView → hideLoading, i.e. exactly +// "data handed over → graph rendered", with no FileReader noise in the timing. +// The fixture is fetched in-page from the harness's own static server so the +// JSON transfer happens before the timer starts. + +const fs = require("fs"); +const http = require("http"); +const path = require("path"); +const {spawnSync} = require("child_process"); +const {chromium} = require("playwright"); + +const ROOT = path.resolve(__dirname, ".."); +const SRC_DIR = path.join(ROOT, "src"); +const FIXTURE_DIR = path.join(__dirname, "fixtures"); +const FIXTURE_FILE = path.join(FIXTURE_DIR, "benchmark_6000x9000.json"); +const FIXTURE_URL_PATH = "/__fixtures__/benchmark_6000x9000.json"; + +const LOAD_RUNS = 3; +const SELECT_RUNS = 3; +const SELECT_NODE_COUNT = 500; +const FPS_WINDOW_MS = 3000; +const WHEEL_INTERVAL_MS = 30; +const DRAG_WARMUP_MS = 1000; + +// Acceptance gates from MIGRATION.md ("Acceptance criteria"). +const GATES = [ + {key: "loadMs", label: "Load (data → rendered)", unit: "ms", limit: 2000, op: "<="}, + {key: "firstInteractionStallMs", label: "First-interaction stall", unit: "ms", limit: 500, op: "<="}, + {key: "wheelZoomFps", label: "Wheel-zoom FPS", unit: "fps", limit: 30, op: ">="}, + {key: "dragPanFps", label: "Warm drag-pan FPS", unit: "fps", limit: 60, op: ">="}, + {key: "select500Ms", label: "500-node select", unit: "ms", limit: 200, op: "<="}, +]; + +const MIME = { + ".html": "text/html", + ".js": "text/javascript", + ".mjs": "text/javascript", + ".css": "text/css", + ".json": "application/json", + ".png": "image/png", + ".svg": "image/svg+xml", + ".map": "application/json", + ".woff2": "font/woff2", +}; + +function median(values) { + const sorted = [...values].sort((a, b) => a - b); + const mid = Math.floor(sorted.length / 2); + return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2; +} + +function run(cmd, args) { + const res = spawnSync(cmd, args, {cwd: ROOT, stdio: "inherit"}); + if (res.status !== 0) { + console.error(`[perf] '${cmd} ${args.join(" ")}' failed (exit ${res.status})`); + process.exit(1); + } +} + +function ensurePreconditions() { + run("node", [path.join(SRC_DIR, "package", "vendor_libs.js")]); + if (!fs.existsSync(FIXTURE_FILE)) { + run("node", [path.join(__dirname, "generate_benchmark_fixture.js")]); + } + // Only download chromium when the pinned revision is actually missing. + if (!fs.existsSync(chromium.executablePath())) { + console.log("[perf] playwright chromium missing, installing .."); + run("npx", ["playwright", "install", "chromium"]); + } +} + +// Minimal static server: serves src/ as web root, the fixture under +// /__fixtures__/, and a no-op SSE stub for api/events so the app's +// EventSource doesn't busy-reconnect (404) during FPS measurements. +function startServer() { + const server = http.createServer((req, res) => { + const urlPath = decodeURIComponent(new URL(req.url, "http://localhost").pathname); + + if (urlPath === "/api/events") { + res.writeHead(200, {"Content-Type": "text/event-stream", "Cache-Control": "no-cache"}); + res.write(": benchmark stub\n\n"); + return; // hold the connection open, never push a graph + } + + const baseDir = urlPath.startsWith("/__fixtures__/") ? FIXTURE_DIR : SRC_DIR; + const rel = urlPath.replace(/^\/__fixtures__\//, "/"); + const file = path.join(baseDir, path.normalize(rel)); + if (!file.startsWith(baseDir) || !fs.existsSync(file) || !fs.statSync(file).isFile()) { + res.writeHead(404); + res.end("not found"); + return; + } + res.writeHead(200, {"Content-Type": MIME[path.extname(file)] || "application/octet-stream"}); + fs.createReadStream(file).pipe(res); + }); + + return new Promise((resolve) => { + server.listen(0, "127.0.0.1", () => resolve(server)); + }); +} + +/** + * Load the fixture via window.renderGraphData and time until the first frame + * after the render pipeline resolves (render + fitView + overlay hidden + one + * rAF as the painted-frame marker). Runs entirely in-page. + */ +async function measureLoadOnce(page) { + return page.evaluate(async (fixtureUrl) => { + const data = await (await fetch(fixtureUrl)).json(); + const t0 = performance.now(); + const ok = await window.renderGraphData(data); + if (!ok) throw new Error("renderGraphData reported failure"); + await new Promise((resolve) => requestAnimationFrame(resolve)); + return performance.now() - t0; + }, FIXTURE_URL_PATH); +} + +/** Center of the graph container (Node-side geometry for real mouse input). */ +async function containerCenter(page) { + const box = await page.locator("#innerGraphContainer").boundingBox(); + return {box, cx: box.x + box.width / 2, cy: box.y + box.height / 2}; +} + +/** + * Install a persistent in-page rAF counter (window.__fps). Real input events + * are driven from Node via CDP so the harness measures the renderer's real + * event path regardless of how it binds listeners (synthetic DOM WheelEvents + * bypassed G6's binding entirely — verified empirically pre-migration), while + * frame counting stays in-page. + */ +async function installFrameCounter(page) { + await page.evaluate(() => { + window.__fps = {frames: 0, start: 0, running: false}; + const loop = () => { + if (window.__fps.running) window.__fps.frames++; + requestAnimationFrame(loop); + }; + requestAnimationFrame(loop); + }); +} + +async function startFrameCounter(page) { + await page.evaluate(() => { + window.__fps.frames = 0; + window.__fps.running = true; + window.__fps.start = performance.now(); + }); +} + +async function stopFrameCounter(page) { + return page.evaluate(() => { + window.__fps.running = false; + const elapsed = performance.now() - window.__fps.start; + return {fps: window.__fps.frames / (elapsed / 1000), elapsedMs: elapsed}; + }); +} + +/** + * Idle rAF ceiling of this environment. Headless chromium pins rAF to a + * virtual 60 Hz BeginFrame regardless of --disable-frame-rate-limit (verified + * against chromium/headless-shell 1223), so a flawless renderer measures + * ~59 fps — the raw ≥60 drag-pan gate would be unreachable. The gate is + * therefore evaluated against min(60, 0.95 × ceiling). + */ +async function measureIdleFpsCeiling(page) { + await page.waitForTimeout(1000); // let deferred work from prior steps settle + await startFrameCounter(page); + await page.waitForTimeout(1000); + const {fps} = await stopFrameCounter(page); + return fps; +} + +/** + * First-interaction stall: time from the first wheel event after load until + * the next animation frame completes. t0/t1 are both taken from the in-page + * clock; the wheel itself is real CDP input. The two CDP round-trips add a few + * ms — negligible against the 500 ms gate (and the ~11 s G6 baseline). + */ +async function measureFirstInteractionStall(page) { + const {cx, cy} = await containerCenter(page); + await page.mouse.move(cx, cy); + + const t0 = await page.evaluate(() => performance.now()); + await page.mouse.wheel(0, -120); + const t1 = await page.evaluate(() => new Promise((resolve) => { + requestAnimationFrame(() => requestAnimationFrame(() => resolve(performance.now()))); + })); + // No zoom-changed sanity check here: G6 swallows the very first wheel tick + // (zoom stays constant, verified empirically) while still running its + // lazy-init work — which is exactly the stall this measures. Zoom behavior + // is asserted in measureWheelZoomFps instead. + return {stallMs: t1 - t0}; +} + +/** + * Wheel-zoom FPS: real wheel events over the canvas center for ~3 s + * (alternating direction to stay inside zoom bounds) while the in-page + * counter tallies rAF frames. + */ +async function measureWheelZoomFps(page) { + const {cx, cy} = await containerCenter(page); + await page.mouse.move(cx, cy); + const zoomBefore = await page.evaluate(() => window.cache.graph.getZoom()); + + await startFrameCounter(page); + const start = Date.now(); + let tick = 0; + while (Date.now() - start < FPS_WINDOW_MS) { + const dir = Math.floor(tick / 15) % 2 === 0 ? -1 : 1; + await page.mouse.wheel(0, dir * 120); + tick++; + await new Promise((resolve) => setTimeout(resolve, WHEEL_INTERVAL_MS)); + } + const counter = await stopFrameCounter(page); + const zoomAfter = await page.evaluate(() => window.cache.graph.getZoom()); + return {...counter, events: tick, zoomChanged: zoomAfter !== zoomBefore}; +} + +/** + * Drag-pan FPS: real mouse input (Playwright CDP) dragging on empty canvas + * while an in-page rAF counter runs. Zooms out to 0.5 first so the canvas + * corners are guaranteed node-free, then performs a warmup drag (the gate is + * "warm" drag-pan) before the measured one. + */ +async function measureDragPanFps(page) { + await page.evaluate(async () => { + await window.cache.graph.zoomTo(0.5); + }); + + const {box} = await containerCenter(page); + const startX = box.x + box.width * 0.08; + const startY = box.y + box.height * 0.12; + + const drag = async (durationMs) => { + await page.mouse.move(startX, startY); + await page.mouse.down(); + const t0 = Date.now(); + let step = 0; + while (Date.now() - t0 < durationMs) { + const phase = (step % 40) / 40 * 2 * Math.PI; + await page.mouse.move( + startX + Math.sin(phase) * box.width * 0.05, + startY + (1 - Math.cos(phase)) * box.height * 0.05, + ); + step++; + } + await page.mouse.up(); + return step; + }; + + await drag(DRAG_WARMUP_MS); // warmup: absorb any remaining lazy-init cost + + await startFrameCounter(page); + const moves = await drag(FPS_WINDOW_MS); + const counter = await stopFrameCounter(page); + return {...counter, moves}; +} + +/** + * 500-node select via the app's selection manager (cache.sm.selectNodes -> + * cache.graph.getElementState/setElementState round-trips). + * + * NOTE(sigma-migration): this call site changes with the Sigma.js port — + * selection becomes app-level Sets + sigma.refresh() (MIGRATION.md Phase 1/3). + * Keep the entry point isolated here so only this function needs updating. + */ +async function measureSelectOnce(page) { + return page.evaluate(async (count) => { + const ids = []; + for (const id of window.cache.nodeRef.keys()) { + ids.push(id); + if (ids.length >= count) break; + } + const t0 = performance.now(); + await window.cache.sm.selectNodes(ids); + await new Promise((resolve) => requestAnimationFrame(resolve)); + const elapsed = performance.now() - t0; + await window.cache.sm.selectNodes([]); // deselect so reruns stay comparable + return elapsed; + }, SELECT_NODE_COUNT); +} + +function evaluateGates(results, limitOverrides = {}) { + return GATES.map((gate) => { + const effectiveLimit = limitOverrides[gate.key] ?? gate.limit; + const measured = results[gate.key]; + const pass = gate.op === "<=" ? measured <= effectiveLimit : measured >= effectiveLimit; + return {...gate, effectiveLimit, measured, pass}; + }); +} + +function printTable(rows) { + const fmt = (v, unit) => `${unit === "fps" ? v.toFixed(1) : Math.round(v)} ${unit}`; + const widths = [28, 14, 28, 6]; + const line = (cols) => console.log(cols.map((c, i) => String(c).padEnd(widths[i])).join(" | ")); + console.log(""); + line(["Metric", "Measured", "Gate", "Pass"]); + line(widths.map((w) => "-".repeat(w))); + for (const row of rows) { + const gateText = row.effectiveLimit === row.limit + ? `${row.op} ${row.limit} ${row.unit}` + : `${row.op} ${fmt(row.effectiveLimit, row.unit)} (capped, raw ${row.limit})`; + line([row.label, fmt(row.measured, row.unit), gateText, row.pass ? "PASS" : "FAIL"]); + } + console.log(""); +} + +async function main() { + const assertGates = process.argv.includes("--assert"); + ensurePreconditions(); + + const server = await startServer(); + const baseUrl = `http://127.0.0.1:${server.address().port}`; + console.log(`[perf] serving src/ at ${baseUrl}`); + + // The sigma renderer is WebGL: measured through SwiftShader (headless + // default) a bare 6000x9000 sigma scene caps at ~8 fps, on the real GPU at + // ~60 fps — software GL emulation is the bottleneck, not the renderer. The + // Vulkan flags pick the hardware GPU when present and fall back to + // SwiftShader's Vulkan device otherwise (verified 2026-06-10, chromium + // headless + AMD Radeon 890M/RADV). FPS gates are calibrated against the + // idle rAF ceiling (see measureIdleFpsCeiling) because headless rAF is + // pinned to 60 Hz. + const browser = await chromium.launch({ + headless: true, + args: [ + "--enable-gpu", + "--use-angle=vulkan", + "--enable-features=Vulkan", + "--ignore-gpu-blocklist", + ], + }); + const page = await browser.newPage({viewport: {width: 1600, height: 900}}); + page.on("pageerror", (err) => console.error(`[perf] page error: ${err.message}`)); + + const gotoApp = async () => { + await page.goto(`${baseUrl}/graph_lens_lite.html`, {waitUntil: "load"}); + await page.waitForFunction(() => typeof window.renderGraphData === "function"); + }; + + try { + // Reload the page between load runs: re-applying a graph into a running + // app would also time the teardown of the previous 15k-element instance. + console.log(`[perf] load: ${LOAD_RUNS} runs (fresh page each) ..`); + const loadRuns = []; + for (let i = 0; i < LOAD_RUNS; i++) { + await gotoApp(); + loadRuns.push(await measureLoadOnce(page)); + console.log(`[perf] run ${i + 1}: ${Math.round(loadRuns[i])} ms`); + } + await installFrameCounter(page); + + // Must run directly after a fresh load, before any other interaction. + console.log("[perf] first-interaction stall .."); + const stall = await measureFirstInteractionStall(page); + + console.log("[perf] calibrating idle rAF ceiling .."); + const idleFps = await measureIdleFpsCeiling(page); + console.log(`[perf] ceiling: ${idleFps.toFixed(1)} fps`); + + console.log("[perf] wheel-zoom FPS (~3 s) .."); + const wheel = await measureWheelZoomFps(page); + if (!wheel.zoomChanged) { + console.warn("[perf] WARNING: wheel events did not change zoom — FPS value may be invalid"); + } + + console.log("[perf] drag-pan FPS (warmup + ~3 s) .."); + const drag = await measureDragPanFps(page); + + console.log(`[perf] ${SELECT_NODE_COUNT}-node select: ${SELECT_RUNS} runs ..`); + const selectRuns = []; + for (let i = 0; i < SELECT_RUNS; i++) { + selectRuns.push(await measureSelectOnce(page)); + console.log(`[perf] run ${i + 1}: ${Math.round(selectRuns[i])} ms`); + } + + const results = { + loadMs: median(loadRuns), + firstInteractionStallMs: stall.stallMs, + wheelZoomFps: wheel.fps, + dragPanFps: drag.fps, + select500Ms: median(selectRuns), + }; + const gateRows = evaluateGates(results, { + dragPanFps: Math.min(GATES.find((g) => g.key === "dragPanFps").limit, idleFps * 0.95), + }); + printTable(gateRows); + + const report = { + timestamp: new Date().toISOString(), + fixture: path.basename(FIXTURE_FILE), + idleFpsCeiling: idleFps, + gates: gateRows.map(({key, label, unit, limit, effectiveLimit, op, measured, pass}) => + ({key, label, unit, limit, effectiveLimit, op, measured, pass})), + raw: {loadRuns, stall, wheel, drag, selectRuns}, + }; + const stamp = report.timestamp.replace(/[:.]/g, "-"); + const outFile = path.join(FIXTURE_DIR, `perf_results_${stamp}.json`); + fs.writeFileSync(outFile, JSON.stringify(report, null, 2)); + console.log(`[perf] results written to ${path.relative(process.cwd(), outFile)}`); + + const failed = gateRows.filter((row) => !row.pass); + if (failed.length > 0) { + console.log(`[perf] ${failed.length}/${gateRows.length} gates FAILED: ${failed.map((f) => f.key).join(", ")}`); + if (assertGates) process.exitCode = 1; + } else { + console.log("[perf] all gates passed"); + } + } finally { + await browser.close(); + server.close(); + } +} + +main().catch((err) => { + console.error(`[perf] fatal: ${err.stack || err.message}`); + process.exit(1); +}); diff --git a/src/gll.js b/src/gll.js index 4e8fd95..b989311 100644 --- a/src/gll.js +++ b/src/gll.js @@ -1,17 +1,3 @@ -const { - Graph, - NodeEvent, - EdgeEvent, - GraphEvent, - CanvasEvent, - CommonEvent, - WindowEvent, - Layout, - BaseLayout, - ExtensionCategory, - register -} = G6; - import {VERSION, DEFAULTS, CFG} from './config.js'; import {GraphCoreManager} from './graph/core.js'; @@ -76,16 +62,9 @@ class Cache { }; this.EVENT_LOCKS = { - BEFORE_DRAW_RUNNING: false, AFTER_DRAW_RUNNING: false, - DRAG_END_RUNNING: false, - BEFORE_RENDER_RUNNING: false, - AFTER_RENDER_RUNNING: false, - BEFORE_LAYOUT_RUNNING: false, - AFTER_LAYOUT_RUNNING: false, ONCE_AFTER_RENDER_RUNNING: false, ONCE_AFTER_RENDER_COMPLETED: false, - IS_DESELECTING: false, BUBBLE_GROUP_REDRAW_RUNNING: false, TRIGGER_SET_LAYOUT_ONCE: false, HOTKEY_EVENTS_REGISTERED: false, @@ -199,6 +178,11 @@ class Cache { this.iterNodes(); this.iterEdges(); + // NOTE: cache.graphData (the graphology model) is built exclusively by + // gcm.createGraphInstance — a single owner keeps the renderer and the + // model from ever diverging across reload cycles. + this.graphData = null; + this.dataTable.init(); } diff --git a/src/graph/core.js b/src/graph/core.js index a71c26e..b7ce212 100644 --- a/src/graph/core.js +++ b/src/graph/core.js @@ -1,93 +1,25 @@ -const { - Graph, - NodeEvent, - EdgeEvent, - GraphEvent, - CanvasEvent, - CommonEvent, - WindowEvent, - Layout, - BaseLayout, - ExtensionCategory, - register, -} = G6; - import { StaticUtilities } from "../utilities/static.js"; import { replaceColorScale } from "../utilities/color_scale_picker.js"; import { replaceNumericScale } from "../utilities/numeric_scale_picker.js"; +import { + buildGraphologyGraph, + makeNodeReducer, + makeEdgeReducer, +} from "./graph_model.js"; +import { SigmaAdapter } from "./sigma_adapter.js"; class GraphCoreManager { constructor(cache) { this.cache = cache; + // TODO(Phase 3): transitional type-only stubs — ui.js toggles behaviors by + // `.type`; real sigma interaction wiring replaces this entirely. this.BEHAVIOURS = { - DRAG_ELEMENT: { - type: "drag-element", - cursor: { default: "default", grab: "default", grabbing: "default" }, - shadow: true, - shadowFill: "#C33D35", - shadowFillOpacity: 0.5, - shadowStroke: "#C33D35", - shadowStrokeOpacity: 1.0, - }, - DRAG_CANVAS: { - type: "drag-canvas", - key: "drag-canvas", - animation: false, - }, - ZOOM_CANVAS: { - type: "zoom-canvas", - key: "zoom-canvas", - animation: false, - }, - HOVER_ACTIVATE: { - type: "hover-activate", - enable: (event) => { - return event.targetType === "node" || event.targetType === "edge"; - }, - degree: 1, - state: "highlight", - inactiveState: "dim", - }, - LASSO_SELECT: { - type: "lasso-select", - key: "lasso-select", - trigger: ["drag"], - style: { - fill: "#C33D35", - fillOpacity: 0.3, - stroke: "#C33D35", - }, - enable: (event) => { - this.cache.ui.debug("LASSO CANVAS CLICK"); - - if (!this.cache.CFG.APPLY_BUBBLE_SET_HOTFIX) return true; - - const selected = this.cache.graph - .getNodeData() - .filter((n) => n.states?.includes("selected")); - - if (selected.length !== 0) { - this.cache.ui.debug( - "PREVENTING LASSO DESELECT EVENT BY REMOVING CANVAS CLICK EVENT", - ); - const eventHandler = this.cache.graph.getEvents()["canvas:click"]; - this.cache.graph.off("canvas:click"); - setTimeout(() => { - this.cache.ui.debug("RESTORING CANVAS CLICK EVENT"); - this.cache.graph.on("canvas:click", eventHandler); - }, 1000); - - return false; - } - return true; - }, - }, - CLICK_SELECT: { - type: "click-select", - key: "click-select", - multiple: true, - trigger: ["shift"], - }, + DRAG_ELEMENT: { type: "drag-element" }, + DRAG_CANVAS: { type: "drag-canvas" }, + ZOOM_CANVAS: { type: "zoom-canvas" }, + HOVER_ACTIVATE: { type: "hover-activate" }, + LASSO_SELECT: { type: "lasso-select" }, + CLICK_SELECT: { type: "click-select" }, }; } @@ -126,17 +58,17 @@ class GraphCoreManager { this.cache.layoutChanged || forceRender ) { - // NOTE: only `styleChanged` re-syncs cached-ref mutations to G6 here. - // `layoutChanged` does NOT trigger updateData — callers that flip it - // while mutating node.style.x/y on cache.nodeRef refs must push their - // own updateNodeData payload, or the change won't reach G6 until the - // next selection-state change. See layoutSelectedNodes in layout.js. + // NOTE: only `styleChanged` re-syncs cached-ref mutations to the + // renderer here. `layoutChanged` does NOT trigger updateData — callers + // that flip it while mutating node.style.x/y on cache.nodeRef refs must + // push their own updateNodeData payload. See layoutSelectedNodes. if (this.cache.styleChanged) { await this.cache.ui.showLoading("Loading", "Updating graph .."); await new Promise((resolve) => requestAnimationFrame(resolve)); - await this.cache.graph.updateData( - this.createSimplifiedDataForGraphObject(), - ); + await this.cache.graph.updateData({ + nodes: [...this.cache.nodeRef.values()], + edges: [...this.cache.edgeRef.values()], + }); this.cache.styleChanged = false; this.cache.labelStyleChanged = false; } @@ -148,12 +80,6 @@ class GraphCoreManager { await new Promise((resolve) => requestAnimationFrame(resolve)); return await this.cache.graph.draw(); } - - // TODO: might have to move this - if (this.cache.EVENT_LOCKS.QUERY_SELECTION_EVENT) { - this.cache.qm.storeQuery(); - this.cache.EVENT_LOCKS.QUERY_SELECTION_EVENT = false; - } } catch (errorMsg) { this.cache.ui.error(errorMsg); return false; @@ -165,206 +91,23 @@ class GraphCoreManager { async createGraphInstance() { if (this.cache.graph === null) { - const behaviors = [ - this.BEHAVIOURS.DRAG_CANVAS, - this.BEHAVIOURS.ZOOM_CANVAS, - this.BEHAVIOURS.DRAG_ELEMENT, - ]; - - if (!this.cache.CFG.DISABLE_HOVER_EFFECT) { - behaviors.push(this.BEHAVIOURS.HOVER_ACTIVATE); - } - - const plugins = [ - { - key: "tooltip", - type: "tooltip", - trigger: "click", - enterable: true, - getContent: (e, items) => { - const content = this.cache.toolTips.get(items[0].id); - requestAnimationFrame(() => { - const graphContainer = document.getElementById( - "innerGraphContainer", - ); - if (!graphContainer) return; - const tooltip = graphContainer.querySelector(".tooltip"); - if (!tooltip) return; - const body = tooltip.querySelector(".tooltip-content"); - const btn = tooltip.querySelector(".tooltip-expand-btn"); - if (!body || !btn) return; - tooltip.classList.remove("expanded"); - btn.textContent = "⛶"; - const isClipped = - body.scrollHeight > body.clientHeight + 1 || - body.scrollWidth > body.clientWidth + 1; - btn.style.display = isClipped ? "" : "none"; - }); - return content; - }, - }, - { - key: "minimap", - type: "minimap", - position: "bottom-left", + // Rebuild the graphology model from the current refs/positions; it is + // the single data source the sigma renderer reads from. + this.cache.graphData = buildGraphologyGraph(this.cache); + + const elementStates = new Map(); + this.cache.graph = new SigmaAdapter(this.cache, "innerGraphContainer", { + nodeReducer: makeNodeReducer(this.cache, elementStates), + edgeReducer: makeEdgeReducer(this.cache, elementStates), + elementStates, + settings: { + // Initial heuristic; io.preProcessData flips HIDE_LABELS based on + // CFG.MAX_NODES_BEFORE_HIDING_LABELS before this runs. + renderLabels: !this.cache.CFG.HIDE_LABELS, }, - ...[...this.cache.bs.traverseBubbleSets()].map((group) => ({ - key: `bubbleSetPlugin-${group}`, - type: "bubble-sets", - members: [], - avoidMembers: [this.cache.CFG.INVISIBLE_DUMMY_NODE.id], - // avoidMembers: [...this.cache.nodeRef.keys()], - ...this.cache.data.layouts[this.cache.data.selectedLayout] - .bubbleSetStyle[group], - strokeOpacity: 0, // hide bubble groups initially (1 node persists due to bug) - fillOpacity: 0, - label: false, - })), - ]; - - this.cache.graph = new Graph({ - container: "innerGraphContainer", - autoFit: false /* 'view' */, - animation: false, - autoResize: true, - padding: 10, - data: this.createSimplifiedDataForGraphObject(), - // NOTE: Do NOT add `type` or `style` here. In G6 v5, spec-level - // node/edge options override per-node data styles (Object.assign - // order in getComputedStyle: ...dataStyle, ...specDefault...). - // All per-node type/style is provided via createSimplifiedDataForGraphObject(). - node: { - state: { - selected: { - halo: true, - haloStroke: "#C33D35", - haloLineWidth: 12, - }, - highlight: { fill: "#C33D35", halo: true, lineWidth: 0 }, - dim: { fill: "#E4E3EA" }, - }, - }, - edge: { - state: { - highlight: { stroke: "#C33D35" }, - selected: { halo: true, haloStroke: "#C33D35", haloLineWidth: 6 }, - }, - }, - behaviors: behaviors, - plugins: plugins, - }); - - this.cache.graph.on("node:dragend", async (event) => { - /** - * Persist all positions on every drag event - * and reset zIndex elevated by G6's frontElement during drag - */ - if (this.cache.EVENT_LOCKS.DRAG_END_RUNNING) return; - - this.cache.ui.debug("DRAG END"); - this.cache.EVENT_LOCKS.DRAG_END_RUNNING = true; - await this.cache.lm.persistNodePositions(); - - const draggedId = event?.target?.id; - if (draggedId) { - await this.cache.graph.setElementZIndex(draggedId, 0); - } - - this.cache.EVENT_LOCKS.DRAG_END_RUNNING = false; }); - this.cache.graph.on("beforelayout", async () => { - this.cache.ui.debug("BEFORE LAYOUT"); - }); - - this.cache.graph.on("afterlayout", async () => { - /** - * Applies persisted positions (excel data or after moving nodes) after layouting has finished - * Also persists positions if this was the initial layout computation - */ - if (this.cache.EVENT_LOCKS.AFTER_LAYOUT_RUNNING) return; - - this.cache.ui.debug("AFTER LAYOUT"); - this.cache.EVENT_LOCKS.AFTER_LAYOUT_RUNNING = true; - - const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; - - if (layout.positions.size > 0) { - // Apply stored positions - this.cache.graph.updateNodeData( - Array.from(layout.positions, ([id, pos]) => ({ - id, - style: pos.style, - })), - ); - await this.cache.graph.draw(); - } else if (layout.layoutType) { - // Initial layout - persist the computed positions and clean up layoutType - await this.cache.lm.persistNodePositions(); - delete layout.layoutType; - this.cache.ui.debug("Initial layout positions persisted"); - } - - this.cache.EVENT_LOCKS.AFTER_LAYOUT_RUNNING = false; - }); - - this.cache.graph.on("canvas:click", async (event) => { - this.cache.ui.debug("CANVAS CLICK"); - }); - - // this.cache.graph.off("canvas:click"); - - this.cache.graph.on("node:click", async (event) => { - this.cache.ui.debug("NODE CLICK"); - }); - - this.cache.graph.on("edge:click", async (event) => { - this.cache.ui.debug("EDGE CLICK"); - }); - - this.cache.graph.on(GraphEvent.BEFORE_DRAW, async (event) => { - if (this.cache.EVENT_LOCKS.BEFORE_DRAW_RUNNING) return; - - this.cache.EVENT_LOCKS.BEFORE_DRAW_RUNNING = true; - this.cache.ui.debug("BEFORE DRAW"); - if (this.cache.EVENT_LOCKS.IS_DESELECTING) { - this.cache.ui.debug("BEFORE DRAW DESELECTION EVENT"); - this.cache.EVENT_LOCKS.IS_DESELECTING = false; - } - this.cache.EVENT_LOCKS.BEFORE_DRAW_RUNNING = false; - }); - - this.cache.graph.on(GraphEvent.AFTER_DRAW, async (event) => { - if (this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING) return; - - this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING = true; - this.cache.ui.debug("AFTER DRAW"); - await this.cache.sm.updateSelectedNodesAndEdges(); - await this.cache.bs.redrawBubbleSets(); - - this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING = false; - await this.cache.ui.hideLoading(); - }); - - this.cache.graph.on(GraphEvent.AFTER_RENDER, async () => { - this.cache.ui.debug("AFTER RENDER"); - - if (this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_COMPLETED) { - if (this.cache.EVENT_LOCKS.AFTER_RENDER_RUNNING) return; - - this.cache.EVENT_LOCKS.AFTER_RENDER_RUNNING = true; - - await this.cache.sm.updateSelectedNodesAndEdges(); - await this.cache.bs.redrawBubbleSets(); - - this.cache.EVENT_LOCKS.AFTER_RENDER_RUNNING = false; - await this.cache.ui.hideLoading(); - } else { - await this.initialAfterRenderEvent(); - } - }); - - let layout = this.cache.data.layouts[this.cache.data.selectedLayout]; + const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; // If layout has no positions yet but has a layoutType, apply that layout algorithm once if (layout.positions.size === 0 && layout.layoutType) { const internals = @@ -377,6 +120,11 @@ class GraphCoreManager { } } + /** + * One-time post-first-render routine (hotkeys, global listeners, plugin + * stubs, initial filter pass, initial layout persistence). Called + * sequentially by SigmaAdapter.render() — formerly G6's AFTER_RENDER event. + */ async initialAfterRenderEvent() { if (this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_RUNNING) return; @@ -614,8 +362,8 @@ class GraphCoreManager { } // Centre and scale the viewport so the given set of nodes fills it with - // padding. Handles the G6 zoom/translate quirk where translateTo at - // non-1 zoom misbehaves (antvis/G6#6373). + // padding. Direct camera fit — the old G6 zoom-at-non-1 translate + // workaround (antvis/G6#6373) is gone with the sigma renderer. async fitViewToNodes(nodeIDs) { const ids = [...nodeIDs]; if (ids.length === 0) { @@ -643,37 +391,7 @@ class GraphCoreManager { return; } - // all measurements at zoom 1 to avoid G6 translateTo bug at non-1 zoom - // see: https://github.com/antvis/G6/issues/6373#issuecomment-3615152579 - await this.cache.graph.zoomTo(1); - - const canvasMin = this.cache.graph.getViewportByCanvas([minX, minY]); - const canvasMax = this.cache.graph.getViewportByCanvas([maxX, maxY]); - const bboxWidth = Math.abs(canvasMax[0] - canvasMin[0]) || 1; - const bboxHeight = Math.abs(canvasMax[1] - canvasMin[1]) || 1; - - const [viewportWidth, viewportHeight] = this.cache.graph.getSize(); - const padding = 80; - // Clamp zoom so a tiny selection (e.g. a single node) doesn't punch - // the viewport to 100× and turn a clean UX into a jarring jump. - const zoomRaw = Math.min( - (viewportWidth - padding * 2) / bboxWidth, - (viewportHeight - padding * 2) / bboxHeight, - ); - const zoom = Math.min(zoomRaw, 4); - - // translateTo at zoom 1, then restore target zoom (G6 bug workaround) - const viewportCenter = [viewportWidth / 2, viewportHeight / 2]; - const bboxCenter = this.cache.graph.getViewportByCanvas([ - (minX + maxX) / 2, - (minY + maxY) / 2, - ]); - const offset = [ - viewportCenter[0] - bboxCenter[0], - viewportCenter[1] - bboxCenter[1], - ]; - await this.cache.graph.translateBy(offset); - await this.cache.graph.zoomTo(zoom); + this.cache.graph.fitViewToBounds({ minX, minY, maxX, maxY }); } async updateEdges(overrides = {}, commands = []) { @@ -857,169 +575,6 @@ class GraphCoreManager { ); } - createSimplifiedDataForGraphObject() { - const filterObject = (obj, excludedKeys) => { - return Object.keys(obj) - .filter((key) => !excludedKeys.includes(key)) // Exclude specified keys - .reduce((newObj, key) => { - newObj[key] = obj[key]; - return newObj; - }, {}); - }; - - // Get current graph nodes to preserve states - let graphNodesMap = new Map(); - if (this.cache.graph) { - try { - const graphNodes = this.cache.graph.getNodeData(); - for (const gNode of graphNodes) { - graphNodesMap.set(gNode.id, gNode); - } - } catch (e) { - // Graph might not be ready yet - } - } - - // Process nodes and exclude their unwanted properties - const filteredNodes = this.cache.data.nodes.map((node) => { - const filteredNode = filterObject(node, [ - "D4Data", - "features", - "featureValues", - "featureWithinThreshold", - "originalStyle", - "originalType", - ]); - - // Preserve states (like selection) from the current graph instance - const currentGraphNode = graphNodesMap.get(node.id); - if (currentGraphNode && currentGraphNode.states) { - filteredNode.states = currentGraphNode.states; - } - - // Preserve visibility from current graph state or loaded data - const savedVisibility = - currentGraphNode?.style?.visibility || node.style?.visibility; - - // load positions from the layouts position Map - const position = this.cache.data.layouts[ - this.cache.data.selectedLayout - ].positions.get(node.id); - - // Check if current layout has custom style for this node - const currentLayout = - this.cache.data.layouts[this.cache.data.selectedLayout]; - const layoutData = currentLayout.nodeStyles.get(node.id); - - if (layoutData) { - // Use layout-specific style and type - Object.assign( - filteredNode, - this.cache.style.getNodeStyleOrDefaults(node), - ); - // Override with layout-specific type and style - if (layoutData.type !== undefined) { - filteredNode.type = layoutData.type; - } - if (layoutData.style) { - filteredNode.style = structuredClone(layoutData.style); - } - } else { - // Use default style - Object.assign( - filteredNode, - this.cache.style.getNodeStyleOrDefaults(node), - ); - } - - // Restore visibility if it was set in the loaded data - if (savedVisibility) { - filteredNode.style.visibility = savedVisibility; - } - - if (position && position.style) { - filteredNode.style.x = position.style.x; - filteredNode.style.y = position.style.y; - } - - return filteredNode; - }); - - // Get current graph edges to preserve states - let graphEdgesMap = new Map(); - if (this.cache.graph) { - try { - const graphEdges = this.cache.graph.getEdgeData(); - for (const gEdge of graphEdges) { - graphEdgesMap.set(gEdge.id, gEdge); - } - } catch (e) { - // Graph might not be ready yet - } - } - - // Process edges if provided, and exclude unwanted properties - const filteredEdges = this.cache.data.edges.map((edge) => { - const filteredEdge = filterObject(edge, [ - "D4Data", - "features", - "featureValues", - "featureWithinThreshold", - "originalStyle", - "originalType", - ]); - - // Preserve states (like selection) from the current graph instance - const currentGraphEdge = graphEdgesMap.get(edge.id); - if (currentGraphEdge && currentGraphEdge.states) { - filteredEdge.states = currentGraphEdge.states; - } - - // Preserve visibility from current graph state or loaded data - const savedVisibility = - currentGraphEdge?.style?.visibility || edge.style?.visibility; - - // Check if current layout has custom style for this edge - const currentLayout = - this.cache.data.layouts[this.cache.data.selectedLayout]; - const layoutData = currentLayout.edgeStyles.get(edge.id); - - if (layoutData) { - // Use layout-specific style and type - Object.assign( - filteredEdge, - this.cache.style.getEdgeStyleOrDefaults(edge), - ); - // Override with layout-specific type and style - if (layoutData.type !== undefined) { - filteredEdge.type = layoutData.type; - } - if (layoutData.style) { - filteredEdge.style = structuredClone(layoutData.style); - } - } else { - // Use default style - Object.assign( - filteredEdge, - this.cache.style.getEdgeStyleOrDefaults(edge), - ); - } - - // Restore visibility if it was set in the loaded data - if (savedVisibility) { - filteredEdge.style.visibility = savedVisibility; - } - - return filteredEdge; - }); - - return { - nodes: [...filteredNodes, this.cache.CFG.INVISIBLE_DUMMY_NODE], - edges: filteredEdges, - combos: this.cache.data.combos || [], - }; - } - async preRenderEvent() { if (this.cache.styleChanged) return; @@ -1111,16 +666,9 @@ class GraphCoreManager { } resetEventLocks() { - this.cache.EVENT_LOCKS.BEFORE_DRAW_RUNNING = false; this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING = false; - this.cache.EVENT_LOCKS.DRAG_END_RUNNING = false; - this.cache.EVENT_LOCKS.BEFORE_RENDER_RUNNING = false; - this.cache.EVENT_LOCKS.AFTER_RENDER_RUNNING = false; - this.cache.EVENT_LOCKS.BEFORE_LAYOUT_RUNNING = false; - this.cache.EVENT_LOCKS.AFTER_LAYOUT_RUNNING = false; this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_RUNNING = false; this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_COMPLETED = false; - this.cache.EVENT_LOCKS.IS_DESELECTING = false; this.cache.EVENT_LOCKS.BUBBLE_GROUP_REDRAW_RUNNING = false; this.cache.EVENT_LOCKS.TRIGGER_SET_LAYOUT_ONCE = false; } @@ -1128,6 +676,10 @@ class GraphCoreManager { async destroyGraphAndRollBackUI() { await this.cache.graph?.destroy(); this.cache.graph = null; + // Drop renderer-cycle state with the instance: the graphology model is + // rebuilt by createGraphInstance, plugin stubs are re-registered there. + this.cache.graphData = null; + this.cache.INSTANCES.BUBBLE_GROUPS = {}; // isPositionsDirty = false; // syncPositionsDebounced.cancel?.(); diff --git a/src/graph/filter.js b/src/graph/filter.js index 831911c..48ee8a5 100644 --- a/src/graph/filter.js +++ b/src/graph/filter.js @@ -125,19 +125,17 @@ class GraphFilterManager { async updateElementVisibility(idsToShow, idsToHide) { this.cache.visibleElementsChanged = false; + // Current visibility comes from the graphology `hidden` attrs, surfaced + // as style.visibility by the renderer facade (sigma migration, Phase 1). const { nodes, edges } = await this.cache.graph.getData(); - const { visible, hidden } = [...nodes, ...edges].reduce( - (acc, item) => { - acc[item.style.visibility === "visible" ? "visible" : "hidden"].push( - item.id, - ); - return acc; - }, - { visible: [], hidden: [] }, - ); + const visible = new Set(); + const hidden = new Set(); + for (const item of [...nodes, ...edges]) { + (item.style.visibility === "visible" ? visible : hidden).add(item.id); + } - const showElementsDiff = idsToShow.filter((id) => hidden.includes(id)); - const hideElementsDiff = idsToHide.filter((id) => visible.includes(id)); + const showElementsDiff = idsToShow.filter((id) => hidden.has(id)); + const hideElementsDiff = idsToHide.filter((id) => visible.has(id)); if (showElementsDiff.length > 0) { await this.cache.graph.showElement(showElementsDiff); diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js new file mode 100644 index 0000000..237b2d4 --- /dev/null +++ b/src/graph/graph_model.js @@ -0,0 +1,193 @@ +/** + * Node-safe graph model for the Sigma.js renderer (MIGRATION.md Phase 1). + * + * Builds the graphology instance from the app cache and provides the + * G6-style → sigma attribute mapping plus the node/edge reducer factories. + * Must never import the sigma bundle (directly or transitively) — vitest + * imports this module under node. + */ +import { Graph } from "../lib/graphology.bundle.mjs"; + +// Former G6 state-spec colors (selected/highlight halo + fill, dim fill) +// from the old core.js Graph config. Phase 2 does full visual parity. +const STATE_ACCENT_COLOR = "#C33D35"; +const STATE_DIM_COLOR = "#E4E3EA"; + +/** + * Map a G6-shaped node style object to sigma node attributes. + * Crude Phase-1 mapping; Phase 2 does full parity (shapes, borders, badges). + * Only emits keys that are actually present on the style. + * + * @param {object} style G6 node style ({x, y, size, fill, label, labelText, visibility, ...}) + * @returns {object} partial sigma attrs ({x?, y?, size?, color?, label?, hidden?}) + */ +function nodeAttributesFromStyle(style = {}) { + const attrs = {}; + if (Number.isFinite(style.x)) attrs.x = style.x; + if (Number.isFinite(style.y)) attrs.y = style.y; + if (style.size !== undefined) { + // G6 size may be a number or [w, h] — take the first dimension. + attrs.size = Array.isArray(style.size) ? style.size[0] : style.size; + } + if (style.fill !== undefined) attrs.color = style.fill; + if (style.label === false) { + attrs.label = null; + } else if (style.label && style.labelText !== undefined) { + attrs.label = style.labelText == null ? null : String(style.labelText); + } + if (style.visibility !== undefined) { + attrs.hidden = style.visibility === "hidden"; + } + return attrs; +} + +/** + * Map a G6-shaped edge style object to sigma edge attributes. + * All edges render as straight lines in Phase 1 (curves/arrows are Phase 2). + * + * @param {object} style G6 edge style ({lineWidth, stroke, label, labelText, visibility, ...}) + * @returns {object} partial sigma attrs ({size?, color?, label?, hidden?}) + */ +function edgeAttributesFromStyle(style = {}) { + const attrs = {}; + if (style.lineWidth !== undefined) attrs.size = style.lineWidth; + if (style.stroke !== undefined) attrs.color = style.stroke; + if (style.label === false) { + attrs.label = null; + } else if (style.label && style.labelText !== undefined) { + attrs.label = style.labelText == null ? null : String(style.labelText); + } + if (style.visibility !== undefined) { + attrs.hidden = style.visibility === "hidden"; + } + return attrs; +} + +/** + * Deterministic placeholder coordinate for nodes without a position. Sigma + * hard-requires numeric x/y on every node; the initial layout pass + * overwrites these (see SigmaAdapter.render()). + */ +function placeholderPosition(index, total) { + const angle = (2 * Math.PI * index) / Math.max(total, 1); + const radius = 100 + 10 * Math.sqrt(Math.max(total, 1)); + return { x: Math.cos(angle) * radius, y: Math.sin(angle) * radius }; +} + +/** + * Build a graphology Graph from cache.nodeRef/edgeRef. Positions come from + * the selected layout's persisted positions Map when present, else from the + * node style, else a deterministic placeholder spread. + * + * @param {object} cache app cache (needs nodeRef, edgeRef, data.layouts/selectedLayout) + * @returns {Graph} + */ +function buildGraphologyGraph(cache) { + const graph = new Graph({ multi: true, allowSelfLoops: true, type: "directed" }); + const positions = cache.data?.layouts?.[cache.data?.selectedLayout]?.positions; + const total = cache.nodeRef.size; + + let index = 0; + for (const node of cache.nodeRef.values()) { + const mapped = nodeAttributesFromStyle(node.style ?? {}); + const persisted = positions?.get(node.id)?.style; + const fallback = placeholderPosition(index, total); + graph.addNode(node.id, { + x: Number.isFinite(persisted?.x) ? persisted.x : (mapped.x ?? fallback.x), + y: Number.isFinite(persisted?.y) ? persisted.y : (mapped.y ?? fallback.y), + size: mapped.size, + color: mapped.color, + label: mapped.label ?? null, + hidden: mapped.hidden ?? false, + zIndex: 0, + }); + index++; + } + + for (const edge of cache.edgeRef.values()) { + if (!graph.hasNode(edge.source) || !graph.hasNode(edge.target)) { + cache.ui?.debug?.(`Skipping edge ${edge.id}: missing endpoint node`); + continue; + } + const mapped = edgeAttributesFromStyle(edge.style ?? {}); + graph.addEdgeWithKey(edge.id, edge.source, edge.target, { + size: mapped.size, + color: mapped.color, + label: mapped.label ?? null, + hidden: mapped.hidden ?? false, + zIndex: 0, + }); + } + + return graph; +} + +/** + * Sigma nodeReducer factory. Reads the graphology `hidden` attribute plus the + * app-level element-states Map (selected/highlight/dim, formerly G6 states). + * + * @param {object} cache + * @param {Map} elementStates + */ +function makeNodeReducer(cache, elementStates) { + return (node, data) => { + if (data.hidden) return data; + const states = elementStates.get(node); + if (!states || states.length === 0) return data; + const res = { ...data }; + if (states.includes("selected")) { + res.color = STATE_ACCENT_COLOR; + res.zIndex = 1; + } else if (states.includes("highlight")) { + res.color = STATE_ACCENT_COLOR; + } else if (states.includes("dim")) { + res.color = STATE_DIM_COLOR; + } + return res; + }; +} + +/** + * Sigma edgeReducer factory. An edge is hidden when its own `hidden` attr is + * set OR either endpoint is hidden/filtered. + * + * @param {object} cache needs edgeRef and graphData (the live graphology graph) + * @param {Map} elementStates + */ +function makeEdgeReducer(cache, elementStates) { + return (edge, data) => { + if (data.hidden) return data; + const ref = cache.edgeRef.get(edge); + const graph = cache.graphData; + if (ref && graph?.hasNode(ref.source) && graph.hasNode(ref.target)) { + if ( + graph.getNodeAttribute(ref.source, "hidden") || + graph.getNodeAttribute(ref.target, "hidden") + ) { + return { ...data, hidden: true }; + } + } + const states = elementStates.get(edge); + if (!states || states.length === 0) return data; + const res = { ...data }; + if (states.includes("selected")) { + res.color = STATE_ACCENT_COLOR; + res.zIndex = 1; + } else if (states.includes("highlight")) { + res.color = STATE_ACCENT_COLOR; + } else if (states.includes("dim")) { + res.color = STATE_DIM_COLOR; + } + return res; + }; +} + +export { + buildGraphologyGraph, + nodeAttributesFromStyle, + edgeAttributesFromStyle, + makeNodeReducer, + makeEdgeReducer, + STATE_ACCENT_COLOR, + STATE_DIM_COLOR, +}; diff --git a/src/graph/layout.js b/src/graph/layout.js index 038cd12..a39a8c3 100644 --- a/src/graph/layout.js +++ b/src/graph/layout.js @@ -96,7 +96,7 @@ class GraphLayoutManager { this.cache.nodeRef.set(nodeID, node); } if (nodeUpdates.length > 0) { - this.cache.graph.updateNodeData(nodeUpdates); + await this.cache.graph.updateNodeData(nodeUpdates); } // Apply per-view edge styles - reset ALL edges, not just styled ones @@ -131,7 +131,7 @@ class GraphLayoutManager { this.cache.edgeRef.set(edgeID, edge); } if (edgeUpdates.length > 0) { - this.cache.graph.updateEdgeData(edgeUpdates); + await this.cache.graph.updateEdgeData(edgeUpdates); } // Bubble set styles are automatically used since all references now use the current layout @@ -556,7 +556,7 @@ class GraphLayoutManager { // becomes visible once the selection state changes and forces a re-read. const movedNodes = await cache.sm.getSelectedNodes(); if (movedNodes.length > 0) { - this.cache.graph.updateNodeData( + await this.cache.graph.updateNodeData( movedNodes.map(n => ({id: n.id, style: {x: n.style.x, y: n.style.y}})) ); } diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js new file mode 100644 index 0000000..4f711b5 --- /dev/null +++ b/src/graph/sigma_adapter.js @@ -0,0 +1,500 @@ +/** + * Browser-only Sigma.js adapter (MIGRATION.md Phase 1). + * + * The ONLY module in src/ that imports the sigma bundle (it references WebGL + * globals at module scope and crashes under node). Wraps the Sigma instance, + * the graphology graph, the element-states Map and a pending-layout slot + * behind the G6-shaped facade the rest of the app still calls. Facade methods + * are transitional and get slimmed/deleted in Phases 2-6. + */ +import { Sigma, exportImage } from "../lib/sigma.bundle.mjs"; +import { circular, forceAtlas2 } from "../lib/graphology.bundle.mjs"; +import { nodeAttributesFromStyle, edgeAttributesFromStyle } from "./graph_model.js"; + +const FIT_PADDING_PX = 80; +// Clamp fit zoom so a tiny selection (e.g. a single node) doesn't punch the +// viewport to 100x — same UX guard as the old G6 fitViewToNodes. +const MAX_FIT_ZOOM = 4; +const FORCE_ITERATIONS = 200; +const GRID_SPACING = 100; + +class SigmaAdapter { + /** + * @param {object} cache app cache; cache.graphData must hold the graphology graph + * @param {string|HTMLElement} container + * @param {object} opts {nodeReducer, edgeReducer, elementStates, settings} + */ + constructor(cache, container, { nodeReducer, edgeReducer, elementStates, settings = {} }) { + this.cache = cache; + this.graph = cache.graphData; + this.elementStates = elementStates; + this.pendingLayout = null; + // Single handler per event name (G6's emitter allowed several). Nothing + // dispatches these yet; Phase 3 replaces this with real sigma events. + this.eventHandlers = new Map(); + this.killed = false; + + const containerEl = + typeof container === "string" ? document.getElementById(container) : container; + + this.sigma = new Sigma(this.graph, containerEl, { + allowInvalidContainer: true, + enableEdgeEvents: false, + zIndex: true, + nodeReducer, + edgeReducer, + ...settings, + }); + } + + // ---------------------------------------------------------------- lifecycle + + /** + * G6 render = layout + draw. Runs the pending layout (if any), then the + * persisted-position choreography that used to live in core.js's G6 + * `afterlayout` handler, then a full (re-indexing) refresh. + */ + async render() { + if (this.killed) return false; + if (this.pendingLayout) await this.layout(); + await this.#applyPersistedPositions(); + + this.sigma.refresh(); + + if (this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_COMPLETED) { + await this.#postRefresh(); + } else { + // First render: run the one-time post-render routine (which re-renders + // once with ONCE_AFTER_RENDER_COMPLETED set, taking the branch above). + await this.cache.gcm.initialAfterRenderEvent(); + } + return true; + } + + /** G6 draw = pure visual update; graph structure is unchanged. */ + async draw() { + if (this.killed) return false; + this.sigma.refresh({ skipIndexation: true }); + await this.#postRefresh(); + return true; + } + + /** + * Kills the sigma instance. The `killed` guard keeps in-flight async + * choreography (e.g. a draw awaited across a reload) from refreshing a + * dead renderer — sigma throws on refresh-after-kill. + */ + destroy() { + if (this.killed) return; + this.killed = true; + this.sigma.kill(); + } + + resize() { + this.sigma.resize(); + } + + /** + * Post-refresh choreography formerly driven by G6's AFTER_DRAW/AFTER_RENDER + * events: sync selection caches/UI, redraw bubble sets, drop the overlay. + */ + async #postRefresh() { + if (this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING) return; + this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING = true; + try { + await this.cache.sm.updateSelectedNodesAndEdges(); + await this.cache.bs.redrawBubbleSets(); + } finally { + this.cache.EVENT_LOCKS.AFTER_DRAW_RUNNING = false; + // Inside finally: a throw above must never strand the loading overlay. + await this.cache.ui.hideLoading(); + } + } + + /** + * Persisted positions override layout output; a fresh initial layout gets + * persisted once and its `layoutType` marker removed (see commit b6f8606: + * authored payloads with empty positions are force-laid-out). + */ + async #applyPersistedPositions() { + const layout = this.cache.data.layouts?.[this.cache.data.selectedLayout]; + if (!layout) return; + + if (layout.positions.size > 0) { + for (const [id, pos] of layout.positions) { + const x = pos?.style?.x; + const y = pos?.style?.y; + if (!this.graph.hasNode(id) || !Number.isFinite(x) || !Number.isFinite(y)) continue; + this.graph.mergeNodeAttributes(id, { x, y }); + const ref = this.cache.nodeRef.get(id); + if (ref) { + ref.style.x = x; + ref.style.y = y; + } + } + } else if (layout.layoutType) { + await this.cache.lm.persistNodePositions(); + delete layout.layoutType; + this.cache.ui.debug("Initial layout positions persisted"); + } + } + + // --------------------------------------------------------------------- data + + /** G6-shaped bulk update ({nodes, edges} arrays of {id, type?, style?}). */ + async updateData({ nodes = [], edges = [] } = {}) { + await this.updateNodeData(nodes); + await this.updateEdgeData(edges); + } + + /** @param {Array<{id: string, type?: string, style?: object}>} payload */ + async updateNodeData(payload) { + for (const item of payload ?? []) { + // hasNode also guards the legacy INVISIBLE_DUMMY_NODE (never added here). + if (!item || !this.graph.hasNode(item.id)) continue; + const ref = this.cache.nodeRef.get(item.id); + if (ref) { + if (item.type !== undefined) ref.type = item.type; + if (item.style) Object.assign(ref.style, item.style); + } + const attrs = nodeAttributesFromStyle(item.style ?? {}); + if (Object.keys(attrs).length > 0) { + this.graph.mergeNodeAttributes(item.id, attrs); + } + } + } + + /** @param {Array<{id: string, type?: string, style?: object}>} payload */ + async updateEdgeData(payload) { + for (const item of payload ?? []) { + if (!item || !this.graph.hasEdge(item.id)) continue; + const ref = this.cache.edgeRef.get(item.id); + if (ref) { + if (item.type !== undefined) ref.type = item.type; + if (item.style) Object.assign(ref.style, item.style); + } + const attrs = edgeAttributesFromStyle(item.style ?? {}); + if (Object.keys(attrs).length > 0) { + this.graph.mergeEdgeAttributes(item.id, attrs); + } + } + } + + /** + * G6-shaped live node objects backed by cache.nodeRef. Callers (selection.js, + * layout.js) mutate .style.x/.style.y on the returned objects and push them + * back via updateNodeData; x/y/visibility are synced from graphology here. + * + * @param {string[]} [ids] + */ + getNodeData(ids) { + const refs = ids + ? [...ids].map((id) => this.cache.nodeRef.get(id)).filter(Boolean) + : [...this.cache.nodeRef.values()]; + const views = []; + for (const ref of refs) { + if (!this.graph.hasNode(ref.id)) continue; + const attrs = this.graph.getNodeAttributes(ref.id); + ref.style.x = attrs.x; + ref.style.y = attrs.y; + ref.style.visibility = attrs.hidden ? "hidden" : "visible"; + ref.states = [...(this.elementStates.get(ref.id) ?? [])]; + views.push(ref); + } + return views; + } + + /** @param {string[]} [ids] */ + getEdgeData(ids) { + const refs = ids + ? [...ids].map((id) => this.cache.edgeRef.get(id)).filter(Boolean) + : [...this.cache.edgeRef.values()]; + const views = []; + for (const ref of refs) { + if (!this.graph.hasEdge(ref.id)) continue; + const attrs = this.graph.getEdgeAttributes(ref.id); + ref.style.visibility = attrs.hidden ? "hidden" : "visible"; + ref.states = [...(this.elementStates.get(ref.id) ?? [])]; + views.push(ref); + } + return views; + } + + /** + * Synchronous (returns a plain object); callers `await` it for G6 parity, + * which is a no-op. Keep it sync — getNodeData/getEdgeData results are + * chained with array methods directly under `await` across the app. + */ + getData() { + return { nodes: this.getNodeData(), edges: this.getEdgeData() }; + } + + // ------------------------------------------------------------------- states + + /** @returns {string[]} copy of the element's states (callers mutate freely) */ + getElementState(id) { + return [...(this.elementStates.get(id) ?? [])]; + } + + /** + * G6 semantics: either (id, states[]) or a map of id → states[]. + * Triggers the draw choreography (selection UI sync happens there). + */ + async setElementState(mapOrId, states) { + if (typeof mapOrId === "string") { + this.#setStates(mapOrId, states ?? []); + } else { + for (const [id, elementStates] of Object.entries(mapOrId ?? {})) { + this.#setStates(id, elementStates ?? []); + } + } + await this.draw(); + } + + #setStates(id, states) { + if (states.length === 0) { + this.elementStates.delete(id); + } else { + this.elementStates.set(id, [...states]); + } + } + + // --------------------------------------------------------------- visibility + + // Both are `async` only for the G6 call-site contract; the body is fully + // synchronous (graphology writes + one skipIndexation refresh). + async showElement(ids) { + this.#setHidden(ids, false); + } + + async hideElement(ids) { + this.#setHidden(ids, true); + } + + #setHidden(ids, hidden) { + if (this.killed) return; + const visibility = hidden ? "hidden" : "visible"; + for (const id of Array.isArray(ids) ? ids : [ids]) { + if (this.graph.hasNode(id)) { + this.graph.setNodeAttribute(id, "hidden", hidden); + const ref = this.cache.nodeRef.get(id); + if (ref) ref.style.visibility = visibility; + } else if (this.graph.hasEdge(id)) { + this.graph.setEdgeAttribute(id, "hidden", hidden); + const ref = this.cache.edgeRef.get(id); + if (ref) ref.style.visibility = visibility; + } + } + this.sigma.refresh({ skipIndexation: true }); + } + + // ----------------------------------------------------------------- viewport + + async fitView() { + // Sigma normalizes the graph bbox, so the default camera frames everything. + this.sigma.getCamera().setState({ x: 0.5, y: 0.5, ratio: 1, angle: 0 }); + } + + /** + * Frame the given graph-space bounding box with padding. Replaces the old + * G6 zoom-at-non-1 workaround (antvis/G6#6373) with a direct camera fit. + */ + fitViewToBounds({ minX, minY, maxX, maxY }) { + const camera = this.sigma.getCamera(); + const { width, height } = this.sigma.getDimensions(); + const p1 = this.sigma.graphToViewport({ x: minX, y: minY }); + const p2 = this.sigma.graphToViewport({ x: maxX, y: maxY }); + const spanX = Math.abs(p2.x - p1.x) || 1; + const spanY = Math.abs(p2.y - p1.y) || 1; + const scale = Math.max( + spanX / Math.max(width - 2 * FIT_PADDING_PX, 1), + spanY / Math.max(height - 2 * FIT_PADDING_PX, 1), + ); + const ratio = Math.max(camera.getState().ratio * scale, 1 / MAX_FIT_ZOOM); + const center = this.sigma.viewportToFramedGraph( + this.sigma.graphToViewport({ x: (minX + maxX) / 2, y: (minY + maxY) / 2 }), + ); + camera.setState({ x: center.x, y: center.y, ratio }); + } + + /** G6 zoom z ↔ sigma camera ratio 1/z. */ + async zoomTo(zoom) { + if (!Number.isFinite(zoom) || zoom <= 0) return; + this.sigma.getCamera().setState({ ratio: 1 / zoom }); + } + + getZoom() { + return 1 / this.sigma.getCamera().getState().ratio; + } + + /** @param {[number, number]} offset viewport pixels */ + async translateBy([dx, dy]) { + const { width, height } = this.sigma.getDimensions(); + const target = this.sigma.viewportToFramedGraph({ + x: width / 2 - dx, + y: height / 2 - dy, + }); + this.sigma.getCamera().setState({ x: target.x, y: target.y }); + } + + /** Center the camera on the centroid of the given node/edge ids (zoom kept). */ + async focusElement(ids) { + const points = []; + for (const id of Array.isArray(ids) ? ids : [ids]) { + if (this.graph.hasNode(id)) { + const attrs = this.graph.getNodeAttributes(id); + points.push({ x: attrs.x, y: attrs.y }); + } else if (this.graph.hasEdge(id)) { + const edge = this.cache.edgeRef.get(id); + for (const nodeId of [edge?.source, edge?.target]) { + if (nodeId && this.graph.hasNode(nodeId)) { + const attrs = this.graph.getNodeAttributes(nodeId); + points.push({ x: attrs.x, y: attrs.y }); + } + } + } + } + if (points.length === 0) return; + const centroid = { + x: points.reduce((sum, p) => sum + p.x, 0) / points.length, + y: points.reduce((sum, p) => sum + p.y, 0) / points.length, + }; + const framed = this.sigma.viewportToFramedGraph(this.sigma.graphToViewport(centroid)); + this.sigma.getCamera().setState({ x: framed.x, y: framed.y }); + } + + /** @returns {[number, number]|null} graph-space position */ + getElementPosition(id) { + if (!this.graph.hasNode(id)) return null; + const attrs = this.graph.getNodeAttributes(id); + return [attrs.x, attrs.y]; + } + + /** Debug-only in callers; returns the camera center (framed coordinates). */ + getPosition() { + const state = this.sigma.getCamera().getState(); + return [state.x, state.y]; + } + + /** @returns {[number, number]} viewport size in px */ + getSize() { + const { width, height } = this.sigma.getDimensions(); + return [width, height]; + } + + /** Graph-space → viewport pixels (G6 name kept transitionally). */ + getViewportByCanvas([x, y]) { + const point = this.sigma.graphToViewport({ x, y }); + return [point.x, point.y]; + } + + // ------------------------------------------------------------------- layout + + /** Stores the layout spec; executed by layout() or the next render(). */ + async setLayout(spec) { + this.pendingLayout = spec; + } + + /** Execute the pending (or default) layout and write x/y into graphology. */ + async layout() { + const spec = this.pendingLayout ?? { type: this.cache.DEFAULTS.LAYOUT }; + this.pendingLayout = null; + this.#executeLayout(spec); + } + + #executeLayout(spec) { + const type = spec?.type; + if (type === "circular") { + circular.assign(this.graph, { + scale: Math.max(100, 12 * Math.sqrt(this.graph.order)), + }); + return; + } + if (type === "grid") { + const cols = Math.ceil(Math.sqrt(this.graph.order)) || 1; + let i = 0; + this.graph.forEachNode((id) => { + this.graph.mergeNodeAttributes(id, { + x: (i % cols) * GRID_SPACING, + y: Math.floor(i / cols) * GRID_SPACING, + }); + i++; + }); + return; + } + // 'force' and everything else → forceAtlas2. + // TODO(Phase 5): radial/concentric/mds parity via @antv/layout or + // equivalents; consider the FA2 web-worker build for large graphs. + if (this.graph.order < 2) return; // FA2/inferSettings throw on 0-1 nodes + forceAtlas2.assign(this.graph, { + iterations: FORCE_ITERATIONS, + settings: forceAtlas2.inferSettings(this.graph), + }); + } + + // -------------------------------------------------- events/behaviors (stubs) + + // TODO(Phase 3): real interaction wiring (drag, click/shift-select, hover, + // lasso, tooltip). Sigma's built-in camera already provides wheel-zoom and + // drag-pan; handlers registered here are stored but not dispatched yet. + + on(event, handler) { + this.eventHandlers.set(event, handler); + } + + off(event) { + this.eventHandlers.delete(event); + } + + getEvents() { + return Object.fromEntries(this.eventHandlers); + } + + async setBehaviors() {} // TODO(Phase 3) + + getBehaviors() { + return []; // TODO(Phase 3) + } + + async setElementZIndex() {} // TODO(Phase 3): dragend z-fix is gone with G6 + + // ----------------------------------------------------------- plugins (stubs) + + /** + * TODO(Phase 4): bubble sets render on a custom sigma canvas layer via + * bubblesets-js. Until then GraphBubbleSetManager talks to this inert stub + * (it tracks `members` so the manager's in-sync short-circuit keeps working). + * Returns a fresh stub per call; core.registerPluginStates caches one per + * group in INSTANCES.BUBBLE_GROUPS, which destroyGraphAndRollBackUI resets. + * + * @param {string} _group bubble group key (used from Phase 4 on) + */ + getPluginInstance(_group) { + return { + members: new Map(), + async update(opts = {}) { + if (Array.isArray(opts.members)) { + this.members = new Map(opts.members.map((id) => [id, true])); + } + }, + async drawBubbleSets() {}, + }; + } + + async updatePlugin() {} // TODO(Phase 3): tooltip enable/disable + + // ------------------------------------------------------------------- export + + /** @returns {Promise} PNG data URL of the current viewport */ + async toDataURL() { + const blob = await exportImage.toBlob(this.sigma, { format: "png" }); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = () => reject(reader.error); + reader.readAsDataURL(blob); + }); + } +} + +export { SigmaAdapter }; diff --git a/src/lib/graphology.bundle.mjs b/src/lib/graphology.bundle.mjs new file mode 100644 index 0000000..a4a8a74 --- /dev/null +++ b/src/lib/graphology.bundle.mjs @@ -0,0 +1,2 @@ +var ci=Object.create;var pe=Object.defineProperty;var di=Object.getOwnPropertyDescriptor;var fi=Object.getOwnPropertyNames;var li=Object.getPrototypeOf,pi=Object.prototype.hasOwnProperty;var H=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports),gi=(n,t)=>{for(var e in t)pe(n,e,{get:t[e],enumerable:!0})},yi=(n,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of fi(t))!pi.call(n,r)&&r!==e&&pe(n,r,{get:()=>t[r],enumerable:!(i=di(t,r))||i.enumerable});return n};var ge=(n,t,e)=>(e=n!=null?ci(li(n)):{},yi(t||!n||!n.__esModule?pe(e,"default",{value:n,enumerable:!0}):e,n));var Fe=H((Ls,ye)=>{"use strict";var xt=typeof Reflect=="object"?Reflect:null,Te=xt&&typeof xt.apply=="function"?xt.apply:function(t,e,i){return Function.prototype.apply.call(t,e,i)},Yt;xt&&typeof xt.ownKeys=="function"?Yt=xt.ownKeys:Object.getOwnPropertySymbols?Yt=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:Yt=function(t){return Object.getOwnPropertyNames(t)};function wi(n){console&&console.warn&&console.warn(n)}var je=Number.isNaN||function(t){return t!==t};function I(){I.init.call(this)}ye.exports=I;ye.exports.once=xi;I.EventEmitter=I;I.prototype._events=void 0;I.prototype._eventsCount=0;I.prototype._maxListeners=void 0;var Oe=10;function Xt(n){if(typeof n!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof n)}Object.defineProperty(I,"defaultMaxListeners",{enumerable:!0,get:function(){return Oe},set:function(n){if(typeof n!="number"||n<0||je(n))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+n+".");Oe=n}});I.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};I.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||je(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function Ce(n){return n._maxListeners===void 0?I.defaultMaxListeners:n._maxListeners}I.prototype.getMaxListeners=function(){return Ce(this)};I.prototype.emit=function(t){for(var e=[],i=1;i0&&(o=e[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var u=s[t];if(u===void 0)return!1;if(typeof u=="function")Te(u,this,e);else for(var h=u.length,f=Me(u,h),i=0;i0&&o.length>r&&!o.warned){o.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");a.name="MaxListenersExceededWarning",a.emitter=n,a.type=t,a.count=o.length,wi(a)}return n}I.prototype.addListener=function(t,e){return Ne(this,t,e,!1)};I.prototype.on=I.prototype.addListener;I.prototype.prependListener=function(t,e){return Ne(this,t,e,!0)};function mi(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Pe(n,t,e){var i={fired:!1,wrapFn:void 0,target:n,type:t,listener:e},r=mi.bind(i);return r.listener=e,i.wrapFn=r,r}I.prototype.once=function(t,e){return Xt(e),this.on(t,Pe(this,t,e)),this};I.prototype.prependOnceListener=function(t,e){return Xt(e),this.prependListener(t,Pe(this,t,e)),this};I.prototype.removeListener=function(t,e){var i,r,s,o,a;if(Xt(e),r=this._events,r===void 0)return this;if(i=r[t],i===void 0)return this;if(i===e||i.listener===e)--this._eventsCount===0?this._events=Object.create(null):(delete r[t],r.removeListener&&this.emit("removeListener",t,i.listener||e));else if(typeof i!="function"){for(s=-1,o=i.length-1;o>=0;o--)if(i[o]===e||i[o].listener===e){a=i[o].listener,s=o;break}if(s<0)return this;s===0?i.shift():bi(i,s),i.length===1&&(r[t]=i[0]),r.removeListener!==void 0&&this.emit("removeListener",t,a||e)}return this};I.prototype.off=I.prototype.removeListener;I.prototype.removeAllListeners=function(t){var e,i,r;if(i=this._events,i===void 0)return this;if(i.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):i[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete i[t]),this;if(arguments.length===0){var s=Object.keys(i),o;for(r=0;r=0;r--)this.removeListener(t,e[r]);return this};function Ue(n,t,e){var i=n._events;if(i===void 0)return[];var r=i[t];return r===void 0?[]:typeof r=="function"?e?[r.listener||r]:[r]:e?vi(r):Me(r,r.length)}I.prototype.listeners=function(t){return Ue(this,t,!0)};I.prototype.rawListeners=function(t){return Ue(this,t,!1)};I.listenerCount=function(n,t){return typeof n.listenerCount=="function"?n.listenerCount(t):ze.call(n,t)};I.prototype.listenerCount=ze;function ze(n){var t=this._events;if(t!==void 0){var e=t[n];if(typeof e=="function")return 1;if(e!==void 0)return e.length}return 0}I.prototype.eventNames=function(){return this._eventsCount>0?Yt(this._events):[]};function Me(n,t){for(var e=new Array(t),i=0;i{function kr(n){return!n||typeof n!="object"||typeof n=="function"||Array.isArray(n)||n instanceof Set||n instanceof Map||n instanceof RegExp||n instanceof Date}function rn(n,t){n=n||{};var e={};for(var i in t){var r=n[i],s=t[i];if(!kr(s)){e[i]=rn(r,s);continue}r===void 0?e[i]=s:e[i]=r}return e}sn.exports=rn});var At=H((Ts,on)=>{on.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var cn=H((Os,hn)=>{function an(n){return function(t,e){return t+Math.floor(n()*(e-t+1))}}var un=an(Math.random);un.createRandom=an;hn.exports=un});var pn=H((js,ln)=>{var Sr=cn().createRandom;function dn(n){var t=Sr(n);return function(e){for(var i=e.length,r=i-1,s=-1;++s{var Lr=Rt(),Ir=At(),Rr=pn(),Tr={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function X(n,t,e,i,r){this.wrappedCircle=r||null,this.children={},this.countChildren=0,this.id=n||null,this.next=null,this.previous=null,this.x=t||null,this.y=e||null,r?this.r=1010101:this.r=i||999}X.prototype.hasChildren=function(){return this.countChildren>0};X.prototype.addChild=function(n,t){this.children[n]=t,++this.countChildren};X.prototype.getChild=function(n){if(!this.children.hasOwnProperty(n)){var t=new X;this.children[n]=t,++this.countChildren}return this.children[n]};X.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var n=this;for(var t in n.children){var e=n.children[t];e.x+=n.x,e.y+=n.y,e.applyPositionToChildren()}}};function mn(n,t,e){for(var i in t.children){var r=t.children[i];r.hasChildren()?mn(n,r,e):e[r.id]={x:r.x,y:r.y}}}function ne(n,t){var e=n.r-t.r,i=t.x-n.x,r=t.y-n.y;return e<0||e*e0&&e*e>i*i+r*r}function Ee(n,t){for(var e=0;eu?(r=(h+u-s)/(2*h),a=Math.sqrt(Math.max(0,u/h-r*r)),e.x=n.x-r*i-a*o,e.y=n.y-r*o+a*i):(r=(h+s-u)/(2*h),a=Math.sqrt(Math.max(0,s/h-r*r)),e.x=t.x+r*i-a*o,e.y=t.y+r*o+a*i)):(e.x=t.x+e.r,e.y=t.y)}function wn(n,t){var e=n.r+t.r-1e-6,i=t.x-n.x,r=t.y-n.y;return e>0&&e*e>i*i+r*r}function Pr(n,t){var e=n.length;if(e===0)return 0;var i,r,s,o,a,u,h,f,d,c;if(i=n[0],i.x=0,i.y=0,e<=1)return i.r;if(r=n[1],i.x=-r.r,r.x=i.r,r.y=0,e<=2)return i.r+r.r;s=n[2],yn(r,i,s),i=new X(null,null,null,null,i),r=new X(null,null,null,null,r),s=new X(null,null,null,null,s),i.next=s.previous=r,r.next=i.previous=s,s.next=r.previous=i;t:for(u=3;u{var zr=Rt(),Mr=At(),Wr={dimensions:["x","y"],center:.5,scale:1};function An(n,t,e){if(!Mr(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=zr(e,Wr);var i=e.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var r=e.center,s=e.scale,o=Math.PI*2,a=(r-.5)*s,u=t.order,h=i[0],f=i[1];function d(y,E){return E[h]=s*Math.cos(y*o/u)+a,E[f]=s*Math.sin(y*o/u)+a,E}var c=0;if(!n){var p={};return t.forEachNode(function(y){p[y]=d(c++,{})}),p}t.updateEachNodeAttributes(function(y,E){return d(c++,E),E},{attributes:i})}var Dn=An.bind(null,!1);Dn.assign=An.bind(null,!0);kn.exports=Dn});var Tn=H((Ps,Rn)=>{var Fr=Rt(),qr=At(),Hr={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function Ln(n,t,e){if(!qr(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=Fr(e,Hr);var i=e.dimensions;if(!Array.isArray(i)||i.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var r=i.length,s=e.center,o=e.rng,a=e.scale,u=(s-.5)*a;function h(d){for(var c=0;c{var Kr=Rt(),Yr=At(),Xr=Math.PI/180,Vr={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function On(n,t,e,i){if(!Yr(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");i=Kr(i,Vr),i.degrees&&(e*=Xr);var r=i.dimensions;if(!Array.isArray(r)||r.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return n?void 0:{};var s=r[0],o=r[1],a=0,u=0;if(!i.centeredOnZero){var h=1/0,f=-1/0,d=1/0,c=-1/0;t.forEachNode(function(D,m){var b=m[s],G=m[o];bf&&(f=b),Gc&&(c=G)}),a=(h+f)/2,u=(d+c)/2}var p=Math.cos(e),y=Math.sin(e);function E(D){var m=D[s],b=D[o];return D[s]=a+(m-a)*p-(b-u)*y,D[o]=u+(m-a)*y+(b-u)*p,D}if(!n){var A={};return t.forEachNode(function(D,m){var b={};b[s]=m[s],b[o]=m[o],A[D]=E(b)}),A}t.updateEachNodeAttributes(function(D,m){return E(m),m},{attributes:r})}var jn=On.bind(null,!1);jn.assign=On.bind(null,!0);Cn.exports=jn});var Pn=H(Ot=>{Ot.circlepack=$n();Ot.circular=Sn();Ot.random=Tn();Ot.rotation=Nn()});var zn=H(ie=>{function Zr(n){return typeof n!="number"||isNaN(n)?1:n}function Jr(n,t){var e={},i=function(o){return typeof o>"u"?t:o};typeof t=="function"&&(i=t);var r=function(o){return i(o[n])},s=function(){return i(void 0)};return typeof n=="string"?(e.fromAttributes=r,e.fromGraph=function(o,a){return r(o.getNodeAttributes(a))},e.fromEntry=function(o,a){return r(a)}):typeof n=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},e.fromGraph=function(o,a){return i(n(a,o.getNodeAttributes(a)))},e.fromEntry=function(o,a){return i(n(o,a))}):(e.fromAttributes=s,e.fromGraph=s,e.fromEntry=s),e}function Un(n,t){var e={},i=function(o){return typeof o>"u"?t:o};typeof t=="function"&&(i=t);var r=function(o){return i(o[n])},s=function(){return i(void 0)};return typeof n=="string"?(e.fromAttributes=r,e.fromGraph=function(o,a){return r(o.getEdgeAttributes(a))},e.fromEntry=function(o,a){return r(a)},e.fromPartialEntry=e.fromEntry,e.fromMinimalEntry=e.fromEntry):typeof n=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},e.fromGraph=function(o,a){var u=o.extremities(a);return i(n(a,o.getEdgeAttributes(a),u[0],u[1],o.getNodeAttributes(u[0]),o.getNodeAttributes(u[1]),o.isUndirected(a)))},e.fromEntry=function(o,a,u,h,f,d,c){return i(n(o,a,u,h,f,d,c))},e.fromPartialEntry=function(o,a,u,h){return i(n(o,a,u,h))},e.fromMinimalEntry=function(o,a){return i(n(o,a))}):(e.fromAttributes=s,e.fromGraph=s,e.fromEntry=s,e.fromMinimalEntry=s),e}ie.createNodeValueGetter=Jr;ie.createEdgeValueGetter=Un;ie.createEdgeWeightGetter=function(n){return Un(n,Zr)}});var Hn=H((Ws,qn)=>{var U=0,O=1,k=2,S=3,ft=4,lt=5,L=6,Mn=7,re=8,Wn=9,Qr=0,Br=1,ts=2,M=0,B=1,K=2,bt=3,pt=4,j=5,V=6,at=7,ut=8,Fn=3,it=10,es=3,q=9,Ge=10;qn.exports=function(t,e,i){var r,s,o,a,u,h,f,d,c,p,y=e.length,E=i.length,A=t.adjustSizes,D=t.barnesHutTheta*t.barnesHutTheta,m,b,G,v,P,_,x,l=[];for(o=0;oWt?(st-=(Mt-Wt)/2,ot=st+Mt):(tt-=(Wt-Mt)/2,et=tt+Wt),l[0+M]=-1,l[0+B]=(tt+et)/2,l[0+K]=(st+ot)/2,l[0+bt]=Math.max(et-tt,ot-st),l[0+pt]=-1,l[0+j]=-1,l[0+V]=0,l[0+at]=0,l[0+ut]=0,r=1,o=0;o=0){e[o+U]=0)if(_=Math.pow(e[o+U]-l[s+at],2)+Math.pow(e[o+O]-l[s+ut],2),p=l[s+bt],4*p*p/_0?(x=b*e[o+L]*l[s+V]/_,e[o+k]+=G*x,e[o+S]+=v*x):_<0&&(x=-b*e[o+L]*l[s+V]/Math.sqrt(_),e[o+k]+=G*x,e[o+S]+=v*x):_>0&&(x=b*e[o+L]*l[s+V]/_,e[o+k]+=G*x,e[o+S]+=v*x),s=l[s+pt],s<0)break;continue}else{s=l[s+j];continue}else{if(h=l[s+M],h>=0&&h!==o&&(G=e[o+U]-e[h+U],v=e[o+O]-e[h+O],_=G*G+v*v,A===!0?_>0?(x=b*e[o+L]*e[h+L]/_,e[o+k]+=G*x,e[o+S]+=v*x):_<0&&(x=-b*e[o+L]*e[h+L]/Math.sqrt(_),e[o+k]+=G*x,e[o+S]+=v*x):_>0&&(x=b*e[o+L]*e[h+L]/_,e[o+k]+=G*x,e[o+S]+=v*x)),s=l[s+pt],s<0)break;continue}else for(b=t.scalingRatio,a=0;a0?(x=b*e[a+L]*e[u+L]/_/_,e[a+k]+=G*x,e[a+S]+=v*x,e[u+k]-=G*x,e[u+S]-=v*x):_<0&&(x=100*b*e[a+L]*e[u+L],e[a+k]+=G*x,e[a+S]+=v*x,e[u+k]-=G*x,e[u+S]-=v*x)):(_=Math.sqrt(G*G+v*v),_>0&&(x=b*e[a+L]*e[u+L]/_/_,e[a+k]+=G*x,e[a+S]+=v*x,e[u+k]-=G*x,e[u+S]-=v*x));for(c=t.gravity/t.scalingRatio,b=t.scalingRatio,o=0;o0&&(x=b*e[o+L]*c):_>0&&(x=b*e[o+L]*c/_),e[o+k]-=G*x,e[o+S]-=v*x;for(b=1*(t.outboundAttractionDistribution?m:1),f=0;f0&&(x=-b*P*Math.log(1+_)/_/e[a+L]):_>0&&(x=-b*P*Math.log(1+_)/_):t.outboundAttractionDistribution?_>0&&(x=-b*P/e[a+L]):_>0&&(x=-b*P)):(_=Math.sqrt(Math.pow(G,2)+Math.pow(v,2)),t.linLogMode?t.outboundAttractionDistribution?_>0&&(x=-b*P*Math.log(1+_)/_/e[a+L]):_>0&&(x=-b*P*Math.log(1+_)/_):t.outboundAttractionDistribution?(_=1,x=-b*P/e[a+L]):(_=1,x=-b*P)),_>0&&(e[a+k]+=G*x,e[a+S]+=v*x,e[u+k]-=G*x,e[u+S]-=v*x);var Ft,kt,qt,mt,Ht,Kt;if(A===!0)for(o=0;oGe&&(e[o+k]=e[o+k]*Ge/Ft,e[o+S]=e[o+S]*Ge/Ft),kt=e[o+L]*Math.sqrt((e[o+ft]-e[o+k])*(e[o+ft]-e[o+k])+(e[o+lt]-e[o+S])*(e[o+lt]-e[o+S])),qt=Math.sqrt((e[o+ft]+e[o+k])*(e[o+ft]+e[o+k])+(e[o+lt]+e[o+S])*(e[o+lt]+e[o+S]))/2,mt=.1*Math.log(1+qt)/(1+Math.sqrt(kt)),Ht=e[o+U]+e[o+k]*(mt/t.slowDown),e[o+U]=Ht,Kt=e[o+O]+e[o+S]*(mt/t.slowDown),e[o+O]=Kt);else for(o=0;o{var jt=10,Kn=3;gt.assign=function(n){n=n||{};var t=Array.prototype.slice.call(arguments).slice(1),e,i,r;for(e=0,r=t.length;e=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in n&&typeof n.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in n&&!(typeof n.gravity=="number"&&n.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in n&&!(typeof n.slowDown=="number"||n.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in n&&typeof n.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in n&&!(typeof n.barnesHutTheta=="number"&&n.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};gt.graphToByteArrays=function(n,t){var e=n.order,i=n.size,r={},s,o=new Float32Array(e*jt),a=new Float32Array(i*Kn);return s=0,n.forEachNode(function(u,h){r[u]=s,o[s]=h.x,o[s+1]=h.y,o[s+2]=0,o[s+3]=0,o[s+4]=0,o[s+5]=0,o[s+6]=1,o[s+7]=1,o[s+8]=h.size||1,o[s+9]=h.fixed?1:0,s+=jt}),s=0,n.forEachEdge(function(u,h,f,d,c,p,y){var E=r[f],A=r[d],D=t(u,h,f,d,c,p,y);o[E+6]+=D,o[A+6]+=D,a[s]=E,a[s+1]=A,a[s+2]=D,s+=Kn}),{nodes:o,edges:a}};gt.assignLayoutChanges=function(n,t,e){var i=0;n.updateEachNodeAttributes(function(r,s){return s.x=t[i],s.y=t[i+1],i+=jt,e?e(r,s):s})};gt.readGraphPositions=function(n,t){var e=0;n.forEachNode(function(i,r){t[e]=r.x,t[e+1]=r.y,e+=jt})};gt.collectLayoutChanges=function(n,t,e){for(var i=n.nodes(),r={},s=0,o=0,a=t.length;s{Xn.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var Qn=H((Hs,Jn)=>{var ns=At(),is=zn().createEdgeWeightGetter,rs=Hn(),Ct=Yn(),ss=Vn();function Zn(n,t,e){if(!ns(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof e=="number"&&(e={iterations:e});var i=e.iterations;if(typeof i!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(i<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var r=is("getEdgeWeight"in e?e.getEdgeWeight:"weight").fromEntry,s=typeof e.outputReducer=="function"?e.outputReducer:null,o=Ct.assign({},ss,e.settings),a=Ct.validateSettings(o);if(a)throw new Error("graphology-layout-forceatlas2: "+a.message);var u=Ct.graphToByteArrays(t,r),h;for(h=0;h2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var _e=Zn.bind(null,!1);_e.assign=Zn.bind(null,!0);_e.inferSettings=os;Jn.exports=_e});var Ye=ge(Fe(),1);function Gi(){let n=arguments[0];for(let t=1,e=arguments.length;tn++}function ct(){let n=arguments,t=null,e=-1;return{[Symbol.iterator](){return this},next(){let i=null;do{if(t===null){if(e++,e>=n.length)return{done:!0};t=n[e][Symbol.iterator]()}if(i=t.next(),i.done){t=null;continue}break}while(!0);return i}}}function Gt(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var It=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},w=class n extends It{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,n.prototype.constructor)}},g=class n extends It{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,n.prototype.constructor)}},$=class n extends It{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,n.prototype.constructor)}};function Ve(n,t){this.key=n,this.attributes=t,this.clear()}Ve.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function Ze(n,t){this.key=n,this.attributes=t,this.clear()}Ze.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Je(n,t){this.key=n,this.attributes=t,this.clear()}Je.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function _t(n,t,e,i,r){this.key=t,this.attributes=r,this.undirected=n,this.source=e,this.target=i}_t.prototype.attach=function(){let n="out",t="in";this.undirected&&(n=t="undirected");let e=this.source.key,i=this.target.key;this.source[n][i]=this,!(this.undirected&&e===i)&&(this.target[t][e]=this)};_t.prototype.attachMulti=function(){let n="out",t="in",e=this.source.key,i=this.target.key;this.undirected&&(n=t="undirected");let r=this.source[n],s=r[i];if(typeof s>"u"){r[i]=this,this.undirected&&e===i||(this.target[t][e]=this);return}s.previous=this,this.next=s,r[i]=this,this.target[t][e]=this};_t.prototype.detach=function(){let n=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),delete this.source[e][t],delete this.target[i][n]};_t.prototype.detachMulti=function(){let n=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[e][t],delete this.target[i][n]):(this.next.previous=void 0,this.source[e][t]=this.next,this.target[i][n]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var Qe=0,Be=1,$i=2,tn=3;function dt(n,t,e,i,r,s,o){let a,u,h,f;if(i=""+i,e===Qe){if(a=n._nodes.get(i),!a)throw new g(`Graph.${t}: could not find the "${i}" node in the graph.`);h=r,f=s}else if(e===tn){if(r=""+r,u=n._edges.get(r),!u)throw new g(`Graph.${t}: could not find the "${r}" edge in the graph.`);let d=u.source.key,c=u.target.key;if(i===d)a=u.target;else if(i===c)a=u.source;else throw new g(`Graph.${t}: the "${i}" node is not attached to the "${r}" edge (${d}, ${c}).`);h=s,f=o}else{if(u=n._edges.get(i),!u)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`);e===Be?a=u.source:a=u.target,h=r,f=s}return[a,h,f]}function Ai(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);return o.attributes[a]}}function Di(n,t,e){n.prototype[t]=function(i,r){let[s]=dt(this,t,e,i,r);return s.attributes}}function ki(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);return o.attributes.hasOwnProperty(a)}}function Si(n,t,e){n.prototype[t]=function(i,r,s,o){let[a,u,h]=dt(this,t,e,i,r,s,o);return a.attributes[u]=h,this.emit("nodeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:u}),this}}function Li(n,t,e){n.prototype[t]=function(i,r,s,o){let[a,u,h]=dt(this,t,e,i,r,s,o);if(typeof h!="function")throw new w(`Graph.${t}: updater should be a function.`);let f=a.attributes,d=h(f[u]);return f[u]=d,this.emit("nodeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:u}),this}}function Ii(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);return delete o.attributes[a],this.emit("nodeAttributesUpdated",{key:o.key,type:"remove",attributes:o.attributes,name:a}),this}}function Ri(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);if(!F(a))throw new w(`Graph.${t}: provided attributes are not a plain object.`);return o.attributes=a,this.emit("nodeAttributesUpdated",{key:o.key,type:"replace",attributes:o.attributes}),this}}function Ti(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);if(!F(a))throw new w(`Graph.${t}: provided attributes are not a plain object.`);return z(o.attributes,a),this.emit("nodeAttributesUpdated",{key:o.key,type:"merge",attributes:o.attributes,data:a}),this}}function Oi(n,t,e){n.prototype[t]=function(i,r,s){let[o,a]=dt(this,t,e,i,r,s);if(typeof a!="function")throw new w(`Graph.${t}: provided updater is not a function.`);return o.attributes=a(o.attributes),this.emit("nodeAttributesUpdated",{key:o.key,type:"update",attributes:o.attributes}),this}}var ji=[{name:n=>`get${n}Attribute`,attacher:Ai},{name:n=>`get${n}Attributes`,attacher:Di},{name:n=>`has${n}Attribute`,attacher:ki},{name:n=>`set${n}Attribute`,attacher:Si},{name:n=>`update${n}Attribute`,attacher:Li},{name:n=>`remove${n}Attribute`,attacher:Ii},{name:n=>`replace${n}Attributes`,attacher:Ri},{name:n=>`merge${n}Attributes`,attacher:Ti},{name:n=>`update${n}Attributes`,attacher:Oi}];function Ci(n){ji.forEach(function({name:t,attacher:e}){e(n,t("Node"),Qe),e(n,t("Source"),Be),e(n,t("Target"),$i),e(n,t("Opposite"),tn)})}function Ni(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return s.attributes[r]}}function Pi(n,t,e){n.prototype[t]=function(i){let r;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let s=""+i,o=""+arguments[1];if(r=Q(this,s,o,e),!r)throw new g(`Graph.${t}: could not find an edge for the given path ("${s}" - "${o}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,r=this._edges.get(i),!r)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return r.attributes}}function Ui(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return s.attributes.hasOwnProperty(r)}}function zi(n,t,e){n.prototype[t]=function(i,r,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+i,u=""+r;if(r=arguments[2],s=arguments[3],o=Q(this,a,u,e),!o)throw new g(`Graph.${t}: could not find an edge for the given path ("${a}" - "${u}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,o=this._edges.get(i),!o)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return o.attributes[r]=s,this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this}}function Mi(n,t,e){n.prototype[t]=function(i,r,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+i,u=""+r;if(r=arguments[2],s=arguments[3],o=Q(this,a,u,e),!o)throw new g(`Graph.${t}: could not find an edge for the given path ("${a}" - "${u}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,o=this._edges.get(i),!o)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof s!="function")throw new w(`Graph.${t}: updater should be a function.`);return o.attributes[r]=s(o.attributes[r]),this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this}}function Wi(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return delete s.attributes[r],this.emit("edgeAttributesUpdated",{key:s.key,type:"remove",attributes:s.attributes,name:r}),this}}function Fi(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!F(r))throw new w(`Graph.${t}: provided attributes are not a plain object.`);return s.attributes=r,this.emit("edgeAttributesUpdated",{key:s.key,type:"replace",attributes:s.attributes}),this}}function qi(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!F(r))throw new w(`Graph.${t}: provided attributes are not a plain object.`);return z(s.attributes,r),this.emit("edgeAttributesUpdated",{key:s.key,type:"merge",attributes:s.attributes,data:r}),this}}function Hi(n,t,e){n.prototype[t]=function(i,r){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new $(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new $(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+i,a=""+r;if(r=arguments[2],s=Q(this,o,a,e),!s)throw new g(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(e!=="mixed")throw new $(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,s=this._edges.get(i),!s)throw new g(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof r!="function")throw new w(`Graph.${t}: provided updater is not a function.`);return s.attributes=r(s.attributes),this.emit("edgeAttributesUpdated",{key:s.key,type:"update",attributes:s.attributes}),this}}var Ki=[{name:n=>`get${n}Attribute`,attacher:Ni},{name:n=>`get${n}Attributes`,attacher:Pi},{name:n=>`has${n}Attribute`,attacher:Ui},{name:n=>`set${n}Attribute`,attacher:zi},{name:n=>`update${n}Attribute`,attacher:Mi},{name:n=>`remove${n}Attribute`,attacher:Wi},{name:n=>`replace${n}Attributes`,attacher:Fi},{name:n=>`merge${n}Attributes`,attacher:qi},{name:n=>`update${n}Attributes`,attacher:Hi}];function Yi(n){Ki.forEach(function({name:t,attacher:e}){e(n,t("Edge"),"mixed"),e(n,t("DirectedEdge"),"directed"),e(n,t("UndirectedEdge"),"undirected")})}var Xi=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function Vi(n,t,e,i){let r=!1;for(let s in t){if(s===i)continue;let o=t[s];if(r=e(o.key,o.attributes,o.source.key,o.target.key,o.source.attributes,o.target.attributes,o.undirected),n&&r)return o.key}}function Zi(n,t,e,i){let r,s,o,a=!1;for(let u in t)if(u!==i){r=t[u];do{if(s=r.source,o=r.target,a=e(r.key,r.attributes,s.key,o.key,s.attributes,o.attributes,r.undirected),n&&a)return r.key;r=r.next}while(r!==void 0)}}function we(n,t){let e=Object.keys(n),i=e.length,r,s=0;return{[Symbol.iterator](){return this},next(){do if(r)r=r.next;else{if(s>=i)return{done:!0};let o=e[s++];if(o===t){r=void 0;continue}r=n[o]}while(!r);return{done:!1,value:{edge:r.key,attributes:r.attributes,source:r.source.key,target:r.target.key,sourceAttributes:r.source.attributes,targetAttributes:r.target.attributes,undirected:r.undirected}}}}}function Ji(n,t,e,i){let r=t[e];if(!r)return;let s=r.source,o=r.target;if(i(r.key,r.attributes,s.key,o.key,s.attributes,o.attributes,r.undirected)&&n)return r.key}function Qi(n,t,e,i){let r=t[e];if(!r)return;let s=!1;do{if(s=i(r.key,r.attributes,r.source.key,r.target.key,r.source.attributes,r.target.attributes,r.undirected),n&&s)return r.key;r=r.next}while(r!==void 0)}function me(n,t){let e=n[t];if(e.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!e)return{done:!0};let r={edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected};return e=e.next,{done:!1,value:r}}};let i=!1;return{[Symbol.iterator](){return this},next(){return i===!0?{done:!0}:(i=!0,{done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}})}}}function Bi(n,t){if(n.size===0)return[];if(t==="mixed"||t===n.type)return Array.from(n._edges.keys());let e=t==="undirected"?n.undirectedSize:n.directedSize,i=new Array(e),r=t==="undirected",s=n._edges.values(),o=0,a,u;for(;a=s.next(),a.done!==!0;)u=a.value,u.undirected===r&&(i[o++]=u.key);return i}function en(n,t,e,i){if(t.size===0)return;let r=e!=="mixed"&&e!==t.type,s=e==="undirected",o,a,u=!1,h=t._edges.values();for(;o=h.next(),o.done!==!0;){if(a=o.value,r&&a.undirected!==s)continue;let{key:f,attributes:d,source:c,target:p}=a;if(u=i(f,d,c.key,p.key,c.attributes,p.attributes,a.undirected),n&&u)return f}}function tr(n,t){if(n.size===0)return Gt();let e=t!=="mixed"&&t!==n.type,i=t==="undirected",r=n._edges.values();return{[Symbol.iterator](){return this},next(){let s,o;for(;;){if(s=r.next(),s.done)return s;if(o=s.value,!(e&&o.undirected!==i))break}return{value:{edge:o.key,attributes:o.attributes,source:o.source.key,target:o.target.key,sourceAttributes:o.source.attributes,targetAttributes:o.target.attributes,undirected:o.undirected},done:!1}}}}function be(n,t,e,i,r,s){let o=t?Zi:Vi,a;if(e!=="undirected"&&(i!=="out"&&(a=o(n,r.in,s),n&&a)||i!=="in"&&(a=o(n,r.out,s,i?void 0:r.key),n&&a))||e!=="directed"&&(a=o(n,r.undirected,s),n&&a))return a}function er(n,t,e,i){let r=[];return be(!1,n,t,e,i,function(s){r.push(s)}),r}function nr(n,t,e){let i=Gt();return n!=="undirected"&&(t!=="out"&&typeof e.in<"u"&&(i=ct(i,we(e.in))),t!=="in"&&typeof e.out<"u"&&(i=ct(i,we(e.out,t?void 0:e.key)))),n!=="directed"&&typeof e.undirected<"u"&&(i=ct(i,we(e.undirected))),i}function ve(n,t,e,i,r,s,o){let a=e?Qi:Ji,u;if(t!=="undirected"&&(typeof r.in<"u"&&i!=="out"&&(u=a(n,r.in,s,o),n&&u)||typeof r.out<"u"&&i!=="in"&&(i||r.key!==s)&&(u=a(n,r.out,s,o),n&&u))||t!=="directed"&&typeof r.undirected<"u"&&(u=a(n,r.undirected,s,o),n&&u))return u}function ir(n,t,e,i,r){let s=[];return ve(!1,n,t,e,i,r,function(o){s.push(o)}),s}function rr(n,t,e,i){let r=Gt();return n!=="undirected"&&(typeof e.in<"u"&&t!=="out"&&i in e.in&&(r=ct(r,me(e.in,i))),typeof e.out<"u"&&t!=="in"&&i in e.out&&(t||e.key!==i)&&(r=ct(r,me(e.out,i)))),n!=="directed"&&typeof e.undirected<"u"&&i in e.undirected&&(r=ct(r,me(e.undirected,i))),r}function sr(n,t){let{name:e,type:i,direction:r}=t;n.prototype[e]=function(s,o){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];if(!arguments.length)return Bi(this,i);if(arguments.length===1){s=""+s;let a=this._nodes.get(s);if(typeof a>"u")throw new g(`Graph.${e}: could not find the "${s}" node in the graph.`);return er(this.multi,i==="mixed"?this.type:i,r,a)}if(arguments.length===2){s=""+s,o=""+o;let a=this._nodes.get(s);if(!a)throw new g(`Graph.${e}: could not find the "${s}" source node in the graph.`);if(!this._nodes.has(o))throw new g(`Graph.${e}: could not find the "${o}" target node in the graph.`);return ir(i,this.multi,r,a,o)}throw new w(`Graph.${e}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function or(n,t){let{name:e,type:i,direction:r}=t,s="forEach"+e[0].toUpperCase()+e.slice(1,-1);n.prototype[s]=function(h,f,d){if(!(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)){if(arguments.length===1)return d=h,en(!1,this,i,d);if(arguments.length===2){h=""+h,d=f;let c=this._nodes.get(h);if(typeof c>"u")throw new g(`Graph.${s}: could not find the "${h}" node in the graph.`);return be(!1,this.multi,i==="mixed"?this.type:i,r,c,d)}if(arguments.length===3){h=""+h,f=""+f;let c=this._nodes.get(h);if(!c)throw new g(`Graph.${s}: could not find the "${h}" source node in the graph.`);if(!this._nodes.has(f))throw new g(`Graph.${s}: could not find the "${f}" target node in the graph.`);return ve(!1,i,this.multi,r,c,f,d)}throw new w(`Graph.${s}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let o="map"+e[0].toUpperCase()+e.slice(1);n.prototype[o]=function(){let h=Array.prototype.slice.call(arguments),f=h.pop(),d;if(h.length===0){let c=0;i!=="directed"&&(c+=this.undirectedSize),i!=="undirected"&&(c+=this.directedSize),d=new Array(c);let p=0;h.push((y,E,A,D,m,b,G)=>{d[p++]=f(y,E,A,D,m,b,G)})}else d=[],h.push((c,p,y,E,A,D,m)=>{d.push(f(c,p,y,E,A,D,m))});return this[s].apply(this,h),d};let a="filter"+e[0].toUpperCase()+e.slice(1);n.prototype[a]=function(){let h=Array.prototype.slice.call(arguments),f=h.pop(),d=[];return h.push((c,p,y,E,A,D,m)=>{f(c,p,y,E,A,D,m)&&d.push(c)}),this[s].apply(this,h),d};let u="reduce"+e[0].toUpperCase()+e.slice(1);n.prototype[u]=function(){let h=Array.prototype.slice.call(arguments);if(h.length<2||h.length>4)throw new w(`Graph.${u}: invalid number of arguments (expecting 2, 3 or 4 and got ${h.length}).`);if(typeof h[h.length-1]=="function"&&typeof h[h.length-2]!="function")throw new w(`Graph.${u}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let f,d;h.length===2?(f=h[0],d=h[1],h=[]):h.length===3?(f=h[1],d=h[2],h=[h[0]]):h.length===4&&(f=h[2],d=h[3],h=[h[0],h[1]]);let c=d;return h.push((p,y,E,A,D,m,b)=>{c=f(c,p,y,E,A,D,m,b)}),this[s].apply(this,h),c}}function ar(n,t){let{name:e,type:i,direction:r}=t,s="find"+e[0].toUpperCase()+e.slice(1,-1);n.prototype[s]=function(u,h,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return!1;if(arguments.length===1)return f=u,en(!0,this,i,f);if(arguments.length===2){u=""+u,f=h;let d=this._nodes.get(u);if(typeof d>"u")throw new g(`Graph.${s}: could not find the "${u}" node in the graph.`);return be(!0,this.multi,i==="mixed"?this.type:i,r,d,f)}if(arguments.length===3){u=""+u,h=""+h;let d=this._nodes.get(u);if(!d)throw new g(`Graph.${s}: could not find the "${u}" source node in the graph.`);if(!this._nodes.has(h))throw new g(`Graph.${s}: could not find the "${h}" target node in the graph.`);return ve(!0,i,this.multi,r,d,h,f)}throw new w(`Graph.${s}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let o="some"+e[0].toUpperCase()+e.slice(1,-1);n.prototype[o]=function(){let u=Array.prototype.slice.call(arguments),h=u.pop();return u.push((d,c,p,y,E,A,D)=>h(d,c,p,y,E,A,D)),!!this[s].apply(this,u)};let a="every"+e[0].toUpperCase()+e.slice(1,-1);n.prototype[a]=function(){let u=Array.prototype.slice.call(arguments),h=u.pop();return u.push((d,c,p,y,E,A,D)=>!h(d,c,p,y,E,A,D)),!this[s].apply(this,u)}}function ur(n,t){let{name:e,type:i,direction:r}=t,s=e.slice(0,-1)+"Entries";n.prototype[s]=function(o,a){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return Gt();if(!arguments.length)return tr(this,i);if(arguments.length===1){o=""+o;let u=this._nodes.get(o);if(!u)throw new g(`Graph.${s}: could not find the "${o}" node in the graph.`);return nr(i,r,u)}if(arguments.length===2){o=""+o,a=""+a;let u=this._nodes.get(o);if(!u)throw new g(`Graph.${s}: could not find the "${o}" source node in the graph.`);if(!this._nodes.has(a))throw new g(`Graph.${s}: could not find the "${a}" target node in the graph.`);return rr(i,r,u,a)}throw new w(`Graph.${s}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function hr(n){Xi.forEach(t=>{sr(n,t),or(n,t),ar(n,t),ur(n,t)})}var cr=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function ee(){this.A=null,this.B=null}ee.prototype.wrap=function(n){this.A===null?this.A=n:this.B===null&&(this.B=n)};ee.prototype.has=function(n){return this.A!==null&&n in this.A||this.B!==null&&n in this.B};function St(n,t,e,i,r){for(let s in i){let o=i[s],a=o.source,u=o.target,h=a===e?u:a;if(t&&t.has(h.key))continue;let f=r(h.key,h.attributes);if(n&&f)return h.key}}function xe(n,t,e,i,r){if(t!=="mixed"){if(t==="undirected")return St(n,null,i,i.undirected,r);if(typeof e=="string")return St(n,null,i,i[e],r)}let s=new ee,o;if(t!=="undirected"){if(e!=="out"){if(o=St(n,null,i,i.in,r),n&&o)return o;s.wrap(i.in)}if(e!=="in"){if(o=St(n,s,i,i.out,r),n&&o)return o;s.wrap(i.out)}}if(t!=="directed"&&(o=St(n,s,i,i.undirected,r),n&&o))return o}function dr(n,t,e){if(n!=="mixed"){if(n==="undirected")return Object.keys(e.undirected);if(typeof t=="string")return Object.keys(e[t])}let i=[];return xe(!1,n,t,e,function(r){i.push(r)}),i}function Lt(n,t,e){let i=Object.keys(e),r=i.length,s=0;return{[Symbol.iterator](){return this},next(){let o=null;do{if(s>=r)return n&&n.wrap(e),{done:!0};let a=e[i[s++]],u=a.source,h=a.target;if(o=u===t?h:u,n&&n.has(o.key)){o=null;continue}}while(o===null);return{done:!1,value:{neighbor:o.key,attributes:o.attributes}}}}}function fr(n,t,e){if(n!=="mixed"){if(n==="undirected")return Lt(null,e,e.undirected);if(typeof t=="string")return Lt(null,e,e[t])}let i=Gt(),r=new ee;return n!=="undirected"&&(t!=="out"&&(i=ct(i,Lt(r,e,e.in))),t!=="in"&&(i=ct(i,Lt(r,e,e.out)))),n!=="directed"&&(i=ct(i,Lt(r,e,e.undirected))),i}function lr(n,t){let{name:e,type:i,direction:r}=t;n.prototype[e]=function(s){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];s=""+s;let o=this._nodes.get(s);if(typeof o>"u")throw new g(`Graph.${e}: could not find the "${s}" node in the graph.`);return dr(i==="mixed"?this.type:i,r,o)}}function pr(n,t){let{name:e,type:i,direction:r}=t,s="forEach"+e[0].toUpperCase()+e.slice(1,-1);n.prototype[s]=function(h,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;h=""+h;let d=this._nodes.get(h);if(typeof d>"u")throw new g(`Graph.${s}: could not find the "${h}" node in the graph.`);xe(!1,i==="mixed"?this.type:i,r,d,f)};let o="map"+e[0].toUpperCase()+e.slice(1);n.prototype[o]=function(h,f){let d=[];return this[s](h,(c,p)=>{d.push(f(c,p))}),d};let a="filter"+e[0].toUpperCase()+e.slice(1);n.prototype[a]=function(h,f){let d=[];return this[s](h,(c,p)=>{f(c,p)&&d.push(c)}),d};let u="reduce"+e[0].toUpperCase()+e.slice(1);n.prototype[u]=function(h,f,d){if(arguments.length<3)throw new w(`Graph.${u}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let c=d;return this[s](h,(p,y)=>{c=f(c,p,y)}),c}}function gr(n,t){let{name:e,type:i,direction:r}=t,s=e[0].toUpperCase()+e.slice(1,-1),o="find"+s;n.prototype[o]=function(h,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;h=""+h;let d=this._nodes.get(h);if(typeof d>"u")throw new g(`Graph.${o}: could not find the "${h}" node in the graph.`);return xe(!0,i==="mixed"?this.type:i,r,d,f)};let a="some"+s;n.prototype[a]=function(h,f){return!!this[o](h,f)};let u="every"+s;n.prototype[u]=function(h,f){return!this[o](h,(c,p)=>!f(c,p))}}function yr(n,t){let{name:e,type:i,direction:r}=t,s=e.slice(0,-1)+"Entries";n.prototype[s]=function(o){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return Gt();o=""+o;let a=this._nodes.get(o);if(typeof a>"u")throw new g(`Graph.${s}: could not find the "${o}" node in the graph.`);return fr(i==="mixed"?this.type:i,r,a)}}function wr(n){cr.forEach(t=>{lr(n,t),pr(n,t),gr(n,t),yr(n,t)})}function Vt(n,t,e,i,r){let s=i._nodes.values(),o=i.type,a,u,h,f,d,c,p;for(;a=s.next(),a.done!==!0;){let y=!1;if(u=a.value,o!=="undirected"){f=u.out;for(h in f){d=f[h];do{if(c=d.target,y=!0,p=r(u.key,c.key,u.attributes,c.attributes,d.key,d.attributes,d.undirected),n&&p)return d;d=d.next}while(d)}}if(o!=="directed"){f=u.undirected;for(h in f)if(!(t&&u.key>h)){d=f[h];do{if(c=d.target,c.key!==h&&(c=d.source),y=!0,p=r(u.key,c.key,u.attributes,c.attributes,d.key,d.attributes,d.undirected),n&&p)return d;d=d.next}while(d)}}if(e&&!y&&(p=r(u.key,null,u.attributes,null,null,null,null),n&&p))return null}}function mr(n,t){let e={key:n};return Xe(t.attributes)||(e.attributes=z({},t.attributes)),e}function br(n,t,e){let i={key:t,source:e.source.key,target:e.target.key};return Xe(e.attributes)||(i.attributes=z({},e.attributes)),n==="mixed"&&e.undirected&&(i.undirected=!0),i}function vr(n){if(!F(n))throw new w('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in n))throw new w("Graph.import: serialized node is missing its key.");if("attributes"in n&&(!F(n.attributes)||n.attributes===null))throw new w("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function xr(n){if(!F(n))throw new w('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in n))throw new w("Graph.import: serialized edge is missing its source.");if(!("target"in n))throw new w("Graph.import: serialized edge is missing its target.");if("attributes"in n&&(!F(n.attributes)||n.attributes===null))throw new w("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in n&&typeof n.undirected!="boolean")throw new w("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var Er=_i(),Gr=new Set(["directed","undirected","mixed"]),He=new Set(["domain","_events","_eventsCount","_maxListeners"]),_r=[{name:n=>`${n}Edge`,generateKey:!0},{name:n=>`${n}DirectedEdge`,generateKey:!0,type:"directed"},{name:n=>`${n}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:n=>`${n}EdgeWithKey`},{name:n=>`${n}DirectedEdgeWithKey`,type:"directed"},{name:n=>`${n}UndirectedEdgeWithKey`,type:"undirected"}],$r={allowSelfLoops:!0,multi:!1,type:"mixed"};function Ar(n,t,e){if(e&&!F(e))throw new w(`Graph.addNode: invalid attributes. Expecting an object but got "${e}"`);if(t=""+t,e=e||{},n._nodes.has(t))throw new $(`Graph.addNode: the "${t}" node already exist in the graph.`);let i=new n.NodeDataClass(t,e);return n._nodes.set(t,i),n.emit("nodeAdded",{key:t,attributes:e}),i}function Ke(n,t,e){let i=new n.NodeDataClass(t,e);return n._nodes.set(t,i),n.emit("nodeAdded",{key:t,attributes:e}),i}function nn(n,t,e,i,r,s,o,a){if(!i&&n.type==="undirected")throw new $(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(i&&n.type==="directed")throw new $(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(a&&!F(a))throw new w(`Graph.${t}: invalid attributes. Expecting an object but got "${a}"`);if(s=""+s,o=""+o,a=a||{},!n.allowSelfLoops&&s===o)throw new $(`Graph.${t}: source & target are the same ("${s}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let u=n._nodes.get(s),h=n._nodes.get(o);if(!u)throw new g(`Graph.${t}: source node "${s}" not found.`);if(!h)throw new g(`Graph.${t}: target node "${o}" not found.`);let f={key:null,undirected:i,source:s,target:o,attributes:a};if(e)r=n._edgeKeyGenerator();else if(r=""+r,n._edges.has(r))throw new $(`Graph.${t}: the "${r}" edge already exists in the graph.`);if(!n.multi&&(i?typeof u.undirected[o]<"u":typeof u.out[o]<"u"))throw new $(`Graph.${t}: an edge linking "${s}" to "${o}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let d=new _t(i,r,u,h,a);n._edges.set(r,d);let c=s===o;return i?(u.undirectedDegree++,h.undirectedDegree++,c&&(u.undirectedLoops++,n._undirectedSelfLoopCount++)):(u.outDegree++,h.inDegree++,c&&(u.directedLoops++,n._directedSelfLoopCount++)),n.multi?d.attachMulti():d.attach(),i?n._undirectedSize++:n._directedSize++,f.key=r,n.emit("edgeAdded",f),r}function Dr(n,t,e,i,r,s,o,a,u){if(!i&&n.type==="undirected")throw new $(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(i&&n.type==="directed")throw new $(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(a){if(u){if(typeof a!="function")throw new w(`Graph.${t}: invalid updater function. Expecting a function but got "${a}"`)}else if(!F(a))throw new w(`Graph.${t}: invalid attributes. Expecting an object but got "${a}"`)}s=""+s,o=""+o;let h;if(u&&(h=a,a=void 0),!n.allowSelfLoops&&s===o)throw new $(`Graph.${t}: source & target are the same ("${s}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let f=n._nodes.get(s),d=n._nodes.get(o),c,p;if(!e&&(c=n._edges.get(r),c)){if((c.source.key!==s||c.target.key!==o)&&(!i||c.source.key!==o||c.target.key!==s))throw new $(`Graph.${t}: inconsistency detected when attempting to merge the "${r}" edge with "${s}" source & "${o}" target vs. ("${c.source.key}", "${c.target.key}").`);p=c}if(!p&&!n.multi&&f&&(p=i?f.undirected[o]:f.out[o]),p){let m=[p.key,!1,!1,!1];if(u?!h:!a)return m;if(u){let b=p.attributes;p.attributes=h(b),n.emit("edgeAttributesUpdated",{type:"replace",key:p.key,attributes:p.attributes})}else z(p.attributes,a),n.emit("edgeAttributesUpdated",{type:"merge",key:p.key,attributes:p.attributes,data:a});return m}a=a||{},u&&h&&(a=h(a));let y={key:null,undirected:i,source:s,target:o,attributes:a};if(e)r=n._edgeKeyGenerator();else if(r=""+r,n._edges.has(r))throw new $(`Graph.${t}: the "${r}" edge already exists in the graph.`);let E=!1,A=!1;f||(f=Ke(n,s,{}),E=!0,s===o&&(d=f,A=!0)),d||(d=Ke(n,o,{}),A=!0),c=new _t(i,r,f,d,a),n._edges.set(r,c);let D=s===o;return i?(f.undirectedDegree++,d.undirectedDegree++,D&&(f.undirectedLoops++,n._undirectedSelfLoopCount++)):(f.outDegree++,d.inDegree++,D&&(f.directedLoops++,n._directedSelfLoopCount++)),n.multi?c.attachMulti():c.attach(),i?n._undirectedSize++:n._directedSize++,y.key=r,n.emit("edgeAdded",y),[r,!0,E,A]}function Et(n,t){n._edges.delete(t.key);let{source:e,target:i,attributes:r}=t,s=t.undirected,o=e===i;s?(e.undirectedDegree--,i.undirectedDegree--,o&&(e.undirectedLoops--,n._undirectedSelfLoopCount--)):(e.outDegree--,i.inDegree--,o&&(e.directedLoops--,n._directedSelfLoopCount--)),n.multi?t.detachMulti():t.detach(),s?n._undirectedSize--:n._directedSize--,n.emit("edgeDropped",{key:t.key,attributes:r,source:e.key,target:i.key,undirected:s})}var R=class n extends Ye.EventEmitter{constructor(t){if(super(),t=z({},$r,t),typeof t.multi!="boolean")throw new w(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Gr.has(t.type))throw new w(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new w(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let e=t.type==="mixed"?Ve:t.type==="directed"?Ze:Je;J(this,"NodeDataClass",e);let i="geid_"+Er()+"_",r=0,s=()=>{let o;do o=i+r++;while(this._edges.has(o));return o};J(this,"_attributes",{}),J(this,"_nodes",new Map),J(this,"_edges",new Map),J(this,"_directedSize",0),J(this,"_undirectedSize",0),J(this,"_directedSelfLoopCount",0),J(this,"_undirectedSelfLoopCount",0),J(this,"_edgeKeyGenerator",s),J(this,"_options",t),He.forEach(o=>J(this,o,this[o])),nt(this,"order",()=>this._nodes.size),nt(this,"size",()=>this._edges.size),nt(this,"directedSize",()=>this._directedSize),nt(this,"undirectedSize",()=>this._undirectedSize),nt(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),nt(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),nt(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),nt(this,"multi",this._options.multi),nt(this,"type",this._options.type),nt(this,"allowSelfLoops",this._options.allowSelfLoops),nt(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,e){if(this.type==="undirected")return!1;if(arguments.length===1){let i=""+t,r=this._edges.get(i);return!!r&&!r.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.out.hasOwnProperty(e):!1}throw new w(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,e){if(this.type==="directed")return!1;if(arguments.length===1){let i=""+t,r=this._edges.get(i);return!!r&&r.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.undirected.hasOwnProperty(e):!1}throw new w(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,e){if(arguments.length===1){let i=""+t;return this._edges.has(i)}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?typeof i.out<"u"&&i.out.hasOwnProperty(e)||typeof i.undirected<"u"&&i.undirected.hasOwnProperty(e):!1}throw new w(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,e){if(this.type==="undirected")return;if(t=""+t,e=""+e,this.multi)throw new $("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let i=this._nodes.get(t);if(!i)throw new g(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new g(`Graph.directedEdge: could not find the "${e}" target node in the graph.`);let r=i.out&&i.out[e]||void 0;if(r)return r.key}undirectedEdge(t,e){if(this.type==="directed")return;if(t=""+t,e=""+e,this.multi)throw new $("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let i=this._nodes.get(t);if(!i)throw new g(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new g(`Graph.undirectedEdge: could not find the "${e}" target node in the graph.`);let r=i.undirected&&i.undirected[e]||void 0;if(r)return r.key}edge(t,e){if(this.multi)throw new $("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new g(`Graph.edge: could not find the "${e}" target node in the graph.`);let r=i.out&&i.out[e]||i.undirected&&i.undirected[e]||void 0;if(r)return r.key}areDirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in||e in i.out}areOutNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.out}areInNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in}areUndirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:e in i.undirected}areNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(e in i.in||e in i.out)||this.type!=="directed"&&e in i.undirected}areInboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.in||this.type!=="directed"&&e in i.undirected}areOutboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new g(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.out||this.type!=="directed"&&e in i.undirected}inDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree}outDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree}directedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree}undirectedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree}inboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree),i}outboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.outDegree),i}degree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.degree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree),i}inDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree-e.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree-e.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree-e.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree-e.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,r=0;return this.type!=="directed"&&(i+=e.undirectedDegree,r+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree,r+=e.directedLoops),i-r}outboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,r=0;return this.type!=="directed"&&(i+=e.undirectedDegree,r+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.outDegree,r+=e.directedLoops),i-r}degreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,r=0;return this.type!=="directed"&&(i+=e.undirectedDegree,r+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree,r+=e.directedLoops*2),i-r}source(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.source: could not find the "${t}" edge in the graph.`);return e.source.key}target(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.target: could not find the "${t}" edge in the graph.`);return e.target.key}extremities(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[e.source.key,e.target.key]}opposite(t,e){t=""+t,e=""+e;let i=this._edges.get(e);if(!i)throw new g(`Graph.opposite: could not find the "${e}" edge in the graph.`);let r=i.source.key,s=i.target.key;if(t===r)return s;if(t===s)return r;throw new g(`Graph.opposite: the "${t}" node is not attached to the "${e}" edge (${r}, ${s}).`)}hasExtremity(t,e){t=""+t,e=""+e;let i=this._edges.get(t);if(!i)throw new g(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return i.source.key===e||i.target.key===e}isUndirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return e.undirected}isDirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!e.undirected}isSelfLoop(t){t=""+t;let e=this._edges.get(t);if(!e)throw new g(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return e.source===e.target}addNode(t,e){return Ar(this,t,e).key}mergeNode(t,e){if(e&&!F(e))throw new w(`Graph.mergeNode: invalid attributes. Expecting an object but got "${e}"`);t=""+t,e=e||{};let i=this._nodes.get(t);return i?(e&&(z(i.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:i.attributes,data:e})),[t,!1]):(i=new this.NodeDataClass(t,e),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])}updateNode(t,e){if(e&&typeof e!="function")throw new w(`Graph.updateNode: invalid updater function. Expecting a function but got "${e}"`);t=""+t;let i=this._nodes.get(t);if(i){if(e){let s=i.attributes;i.attributes=e(s),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:i.attributes})}return[t,!1]}let r=e?e({}):{};return i=new this.NodeDataClass(t,r),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:r}),[t,!0]}dropNode(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new g(`Graph.dropNode: could not find the "${t}" node in the graph.`);let i;if(this.type!=="undirected"){for(let r in e.out){i=e.out[r];do Et(this,i),i=i.next;while(i)}for(let r in e.in){i=e.in[r];do Et(this,i),i=i.next;while(i)}}if(this.type!=="directed")for(let r in e.undirected){i=e.undirected[r];do Et(this,i),i=i.next;while(i)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:e.attributes})}dropEdge(t){let e;if(arguments.length>1){let i=""+arguments[0],r=""+arguments[1];if(e=Q(this,i,r,this.type),!e)throw new g(`Graph.dropEdge: could not find the "${i}" -> "${r}" edge in the graph.`)}else if(t=""+t,e=this._edges.get(t),!e)throw new g(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return Et(this,e),this}dropDirectedEdge(t,e){if(arguments.length<2)throw new $("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new $("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,e=""+e;let i=Q(this,t,e,"directed");if(!i)throw new g(`Graph.dropDirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Et(this,i),this}dropUndirectedEdge(t,e){if(arguments.length<2)throw new $("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new $("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let i=Q(this,t,e,"undirected");if(!i)throw new g(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Et(this,i),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),e;for(;e=t.next(),e.done!==!0;)e.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,e){if(typeof e!="function")throw new w("Graph.updateAttribute: updater should be a function.");let i=this._attributes[t];return this._attributes[t]=e(i),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!F(t))throw new w("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!F(t))throw new w("Graph.mergeAttributes: provided attributes are not a plain object.");return z(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new w("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,e){if(typeof t!="function")throw new w("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!qe(e))throw new w("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._nodes.values(),r,s;for(;r=i.next(),r.done!==!0;)s=r.value,s.attributes=t(s.key,s.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})}updateEachEdgeAttributes(t,e){if(typeof t!="function")throw new w("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!qe(e))throw new w("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._edges.values(),r,s,o,a;for(;r=i.next(),r.done!==!0;)s=r.value,o=s.source,a=s.target,s.attributes=t(s.key,s.attributes,o.key,a.key,o.attributes,a.attributes,s.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new w("Graph.forEachAdjacencyEntry: expecting a callback.");Vt(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new w("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");Vt(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new w("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");Vt(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new w("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");Vt(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new w("Graph.forEachNode: expecting a callback.");let e=this._nodes.values(),i,r;for(;i=e.next(),i.done!==!0;)r=i.value,t(r.key,r.attributes)}findNode(t){if(typeof t!="function")throw new w("Graph.findNode: expecting a callback.");let e=this._nodes.values(),i,r;for(;i=e.next(),i.done!==!0;)if(r=i.value,t(r.key,r.attributes))return r.key}mapNodes(t){if(typeof t!="function")throw new w("Graph.mapNode: expecting a callback.");let e=this._nodes.values(),i,r,s=new Array(this.order),o=0;for(;i=e.next(),i.done!==!0;)r=i.value,s[o++]=t(r.key,r.attributes);return s}someNode(t){if(typeof t!="function")throw new w("Graph.someNode: expecting a callback.");let e=this._nodes.values(),i,r;for(;i=e.next(),i.done!==!0;)if(r=i.value,t(r.key,r.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new w("Graph.everyNode: expecting a callback.");let e=this._nodes.values(),i,r;for(;i=e.next(),i.done!==!0;)if(r=i.value,!t(r.key,r.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new w("Graph.filterNodes: expecting a callback.");let e=this._nodes.values(),i,r,s=[];for(;i=e.next(),i.done!==!0;)r=i.value,t(r.key,r.attributes)&&s.push(r.key);return s}reduceNodes(t,e){if(typeof t!="function")throw new w("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new w("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let i=e,r=this._nodes.values(),s,o;for(;s=r.next(),s.done!==!0;)o=s.value,i=t(i,o.key,o.attributes);return i}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let e=t.next();if(e.done)return e;let i=e.value;return{value:{node:i.key,attributes:i.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),e=0;this._nodes.forEach((r,s)=>{t[e++]=mr(s,r)});let i=new Array(this._edges.size);return e=0,this._edges.forEach((r,s)=>{i[e++]=br(this.type,s,r)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:i}}import(t,e=!1){if(t instanceof n)return t.forEachNode((u,h)=>{e?this.mergeNode(u,h):this.addNode(u,h)}),t.forEachEdge((u,h,f,d,c,p,y)=>{e?y?this.mergeUndirectedEdgeWithKey(u,f,d,h):this.mergeDirectedEdgeWithKey(u,f,d,h):y?this.addUndirectedEdgeWithKey(u,f,d,h):this.addDirectedEdgeWithKey(u,f,d,h)}),this;if(!F(t))throw new w("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!F(t.attributes))throw new w("Graph.import: invalid attributes. Expecting a plain object.");e?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let i,r,s,o,a;if(t.nodes){if(s=t.nodes,!Array.isArray(s))throw new w("Graph.import: invalid nodes. Expecting an array.");for(i=0,r=s.length;i{let s=z({},i.attributes);i=new e.NodeDataClass(r,s),e._nodes.set(r,i)}),e}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new $(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new $("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new $("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let e=this.emptyCopy(t),i=this._edges.values(),r,s;for(;r=i.next(),r.done!==!0;)s=r.value,nn(e,"copy",!1,s.undirected,s.key,s.source.key,s.target.key,z({},s.attributes));return e}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((s,o)=>{t[o]=s.attributes});let e={},i={};this._edges.forEach((s,o)=>{let a=s.undirected?"--":"->",u="",h=s.source.key,f=s.target.key,d;s.undirected&&h>f&&(d=h,h=f,f=d);let c=`(${h})${a}(${f})`;o.startsWith("geid_")?this.multi&&(typeof i[c]>"u"?i[c]=0:i[c]++,u+=`${i[c]}. `):u+=`[${o}]: `,u+=c,e[u]=s.attributes});let r={};for(let s in this)this.hasOwnProperty(s)&&!He.has(s)&&typeof this[s]!="function"&&typeof s!="symbol"&&(r[s]=this[s]);return r.attributes=this._attributes,r.nodes=t,r.edges=e,J(r,"constructor",this.constructor),r}};typeof Symbol<"u"&&(R.prototype[Symbol.for("nodejs.util.inspect.custom")]=R.prototype.inspect);_r.forEach(n=>{["add","merge","update"].forEach(t=>{let e=n.name(t),i=t==="add"?nn:Dr;n.generateKey?R.prototype[e]=function(r,s,o){return i(this,e,!0,(n.type||this.type)==="undirected",null,r,s,o,t==="update")}:R.prototype[e]=function(r,s,o,a){return i(this,e,!1,(n.type||this.type)==="undirected",r,s,o,a,t==="update")}})});Ci(R);Yi(R);hr(R);wr(R);var Zt=class extends R{constructor(t){let e=z({type:"directed"},t);if("multi"in e&&e.multi!==!1)throw new w("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="directed")throw new w('DirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Jt=class extends R{constructor(t){let e=z({type:"undirected"},t);if("multi"in e&&e.multi!==!1)throw new w("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="undirected")throw new w('UndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Qt=class extends R{constructor(t){let e=z({multi:!0},t);if("multi"in e&&e.multi!==!0)throw new w("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(e)}},Bt=class extends R{constructor(t){let e=z({type:"directed",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new w("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="directed")throw new w('MultiDirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},te=class extends R{constructor(t){let e=z({type:"undirected",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new w("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="undirected")throw new w('MultiUndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}};function $t(n){n.from=function(t,e){let i=z({},t.options,e),r=new n(i);return r.import(t),r}}$t(R);$t(Zt);$t(Jt);$t(Qt);$t(Bt);$t(te);R.Graph=R;R.DirectedGraph=Zt;R.UndirectedGraph=Jt;R.MultiGraph=Qt;R.MultiDirectedGraph=Bt;R.MultiUndirectedGraph=te;R.InvalidArgumentsGraphError=w;R.NotFoundGraphError=g;R.UsageGraphError=$;var fe=ge(Pn(),1),ks=ge(Qn(),1);var hi={};gi(hi,{Area:()=>Dt,BubbleSets:()=>de,Circle:()=>zt,Line:()=>W,PointPath:()=>ht,Rectangle:()=>Y,addPadding:()=>Le,boundingBox:()=>ii,calculatePotentialOutline:()=>ai,calculateVirtualEdges:()=>si,circle:()=>ls,createGenericInfluenceArea:()=>Ie,createLineInfluenceArea:()=>Ae,createOutline:()=>Ds,createRectangleInfluenceArea:()=>ri,default:()=>de,defaultOptions:()=>Re,line:()=>ps,lineBoundingBox:()=>Se,point:()=>T,rect:()=>fs,unionBoundingBox:()=>ui});function ke(n,t,e,i,r,s){let o=n,a=t,u=e-o,h=i-a,f=r-o,d=s-a,c=f*u+d*h,p=0;c<=0?p=0:(f=u-f,d=h-d,c=f*u+d*h,c<=0?p=0:p=c*c/(u*u+h*h));let y=f*f+d*d-p;return y<0?0:y}function wt(n,t,e,i){return(n-e)*(n-e)+(t-i)*(t-i)}function Bn(n,t,e,i,r){return wt(n,t,e,i)e;if(n===0)return Math.round;let t=Math.pow(10,n);return e=>Math.round(e*t)/t}function Se(n){let t=Math.min(n.x1,n.x2),e=Math.max(n.x1,n.x2),i=Math.min(n.y1,n.y2),r=Math.max(n.y1,n.y2);return{x:t,y:i,x2:e,y2:r,width:e-t,height:r-i}}var W=class n{constructor(t,e,i,r){this.x1=t,this.y1=e,this.x2=i,this.y2=r}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new n(t.x1,t.y1,t.x2,t.y2)}cuts(t,e){if(this.y1===this.y2||ethis.y1&&e>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+i)return!1}else if(tthis.x1+i)return!1;if(this.y1this.y2+i)return!1}else if(ethis.y1+i)return!1;return!0}},C;(function(n){n[n.POINT=1]="POINT",n[n.PARALLEL=2]="PARALLEL",n[n.COINCIDENT=3]="COINCIDENT",n[n.NONE=4]="NONE"})(C||(C={}));var Pt=class{constructor(t,e=0,i=0){this.state=t,this.x=e,this.y=i}};function se(n,t){let e=(t.x2-t.x1)*(n.y1-t.y1)-(t.y2-t.y1)*(n.x1-t.x1),i=(n.x2-n.x1)*(n.y1-t.y1)-(n.y2-n.y1)*(n.x1-t.x1),r=(t.y2-t.y1)*(n.x2-n.x1)-(t.x2-t.x1)*(n.y2-n.y1);if(r){let s=e/r,o=i/r;return 0<=s&&s<=1&&0<=o&&o<=1?new Pt(C.POINT,n.x1+s*(n.x2-n.x1),n.y1+s*(n.y2-n.y1)):new Pt(C.NONE)}return new Pt(e===0||i===0?C.COINCIDENT:C.PARALLEL)}function ei(n,t){let e=(t.x2-t.x1)*(n.y1-t.y1)-(t.y2-t.y1)*(n.x1-t.x1),i=(n.x2-n.x1)*(n.y1-t.y1)-(n.y2-n.y1)*(n.x1-t.x1),r=(t.y2-t.y1)*(n.x2-n.x1)-(t.x2-t.x1)*(n.y2-n.y1);if(r){let s=e/r,o=i/r;if(0<=s&&s<=1&&0<=o&&o<=1)return s}return Number.POSITIVE_INFINITY}function us(n,t){function e(r,s,o,a){let u=ei(t,new W(r,s,o,a));return u=Math.abs(u-.5),u>=0&&u<=1?1:0}let i=e(n.x,n.y,n.x2,n.y);return i+=e(n.x,n.y,n.x,n.y2),i>1||(i+=e(n.x,n.y2,n.x2,n.y2),i>1)?!0:(i+=e(n.x2,n.y,n.x2,n.y2),i>0)}var N;(function(n){n[n.LEFT=0]="LEFT",n[n.TOP=1]="TOP",n[n.RIGHT=2]="RIGHT",n[n.BOTTOM=3]="BOTTOM"})(N||(N={}));function ce(n,t,e){let i=new Set;return n.width<=0?(i.add(N.LEFT),i.add(N.RIGHT)):tn.x+n.width&&i.add(N.RIGHT),n.height<=0?(i.add(N.TOP),i.add(N.BOTTOM)):en.y+n.height&&i.add(N.BOTTOM),i}function ni(n,t){let e=t.x1,i=t.y1,r=t.x2,s=t.y2,o=Array.from(ce(n,r,s));if(o.length===0)return!0;let a=ce(n,e,i);for(;a.size!==0;){for(let u of o)if(a.has(u))return!1;if(a.has(N.RIGHT)||a.has(N.LEFT)){let u=n.x;a.has(N.RIGHT)&&(u+=n.width),i=i+(u-e)*(s-i)/(r-e),e=u}else{let u=n.y;a.has(N.BOTTOM)&&(u+=n.height),e=e+(u-i)*(r-e)/(s-i),i=u}a=ce(n,e,i)}return!0}function hs(n,t){let e=Number.POSITIVE_INFINITY,i=0;function r(s,o,a,u){let h=ei(t,new W(s,o,a,u));h=Math.abs(h-.5),h>=0&&h<=1&&(i++,h1||(r(n.x,n.y2,n.x2,n.y2),i>1)?e:(r(n.x2,n.y,n.x2,n.y2),i===0?-1:e)}function cs(n,t){let e=0,i=se(n,new W(t.x,t.y,t.x2,t.y));e+=i.state===C.POINT?1:0;let r=se(n,new W(t.x,t.y,t.x,t.y2));e+=r.state===C.POINT?1:0;let s=se(n,new W(t.x,t.y2,t.x2,t.y2));e+=s.state===C.POINT?1:0;let o=se(n,new W(t.x2,t.y,t.x2,t.y2));return e+=o.state===C.POINT?1:0,{top:i,left:r,bottom:s,right:o,count:e}}var Y=class n{constructor(t,e,i,r){this.x=t,this.y=e,this.width=i,this.height=r}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new n(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new n(this.x,this.y,this.width,this.height)}add(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),r=Math.max(this.x2,t.x+t.width),s=Math.max(this.y2,t.y+t.height);this.x=e,this.y=i,this.width=r-e,this.height=s-i}addPoint(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),r=Math.max(this.x2,t.x),s=Math.max(this.y2,t.y);this.x=e,this.y=i,this.width=r-e,this.height=s-i}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let e=this.scaleX(t.x),i=this.scaleY(t.y),r=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),s=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),o=r-e,a=s-i;return new Y(e,i,o,a)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){let i=Math.ceil(e/this.pixelGroup),r=this.boundX(t.x-i),s=this.boundY(t.y-i),o=this.boundX(t.x2+i),a=this.boundY(t.y2+i),u=o-r,h=a-s;return new Y(r,s,u,h)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=i)}set(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=i)}incArea(t,e){if(t.width<=0||t.height<=0||e===0)return;let i=this.width,r=t.width,s=Math.max(0,t.i),o=Math.max(0,t.j),a=Math.min(t.i+t.width,i),u=Math.min(t.j+t.height,this.height);if(!(u<=0||a<=0||s>=i||u>=this.height))for(let h=o;hMath.min(o,a),Number.POSITIVE_INFINITY),r=this.area.reduce((o,a)=>Math.max(o,a),Number.NEGATIVE_INFINITY),s=o=>(o-i)/(r-i);t.scale(this.pixelGroup,this.pixelGroup);for(let o=0;oe?"black":"white",t.fillRect(r,s,1,1)}t.restore()}}};function Le(n,t){let e=i=>({x:i.x-t,y:i.y-t,width:i.width+2*t,height:i.height+2*t});return Array.isArray(n)?n.map(e):e(n)}function Ae(n,t,e){return Ie(Object.assign(Se(n),{distSquare:(i,r)=>ke(n.x1,n.y1,n.x2,n.y2,i,r)}),t,e)}function Ie(n,t,e){let i=Le(n,e),r=t.scale(i),s=t.createSub(r,i);return ds(s,t,e,(o,a)=>n.distSquare(o,a)),s}function ds(n,t,e,i){let r=e*e;for(let s=0;s{let a=r.slice(0,o);return gs(t,s,a,e,i)}).flat()}function gs(n,t,e,i,r){let s=T(t.cx,t.cy),o=ms(s,e,n);if(o==null)return[];let a=new W(s.x,s.y,o.cx,o.cy),u=ys(a,n,i,r);return ws(u,n)}function ys(n,t,e,i){let r=[],s=[];s.push(n);let o=!0;for(let a=0;a0;){let u=s.pop(),h=oi(t,u),f=h?cs(u,h):null;if(!h||!f||f.count!==2){o||r.push(u);continue}let d=i,c=ae(h,d,f,!0),p=yt(c,s)||yt(c,r),y=oe(c,t);for(;!p&&y&&d>=1;)d/=1.5,c=ae(h,d,f,!0),p=yt(c,s)||yt(c,r),y=oe(c,t);if(c&&!p&&!y&&(s.push(new W(u.x1,u.y1,c.x,c.y)),s.push(new W(c.x,c.y,u.x2,u.y2)),o=!0),o)continue;d=i,c=ae(h,d,f,!1);let E=yt(c,s)||yt(c,r);for(y=oe(c,t);!E&&y&&d>=1;)d/=1.5,c=ae(h,d,f,!1),E=yt(c,s)||yt(c,r),y=oe(c,t);c&&!E&&(s.push(new W(u.x1,u.y1,c.x,c.y)),s.push(new W(c.x,c.y,u.x2,u.y2)),o=!0),o||r.push(u)}for(;s.length>0;)r.push(s.pop());return r}function ws(n,t){let e=[];for(;n.length>0;){let i=n.pop();if(n.length===0){e.push(i);break}let r=n.pop(),s=new W(i.x1,i.y1,r.x2,r.y2);oi(t,s)?(e.push(i),n.push(r)):n.push(s)}return e}function ms(n,t,e){let i=Number.POSITIVE_INFINITY;return t.reduce((r,s)=>{let o=wt(n.x,n.y,s.cx,s.cy);if(o>i)return r;let a=new W(n.x,n.y,s.cx,s.cy),u=vs(e,a);return o*(u+1)*(u+1){t+=i.cx,e+=i.cy}),t/=n.length,e/=n.length,n.map(i=>{let r=t-i.cx,s=e-i.cy,o=r*r+s*s;return[i,o]}).sort((i,r)=>i[1]-r[1]).map(i=>i[0])}function oe(n,t){return t.some(e=>e.containsPt(n.x,n.y))}function yt(n,t){return t.some(e=>!!(Bn(e.x1,e.y1,n.x,n.y,.001)||Bn(e.x2,e.y2,n.x,n.y,.001)))}function oi(n,t){let e=Number.POSITIVE_INFINITY,i=null;for(let r of n){if(!ni(r,t))continue;let s=hs(r,t);s>=0&&sni(i,t)&&us(i,t)?e+1:e,0)}function ae(n,t,e,i){let r=e.top,s=e.left,o=e.bottom,a=e.right;if(i){if(s.state===C.POINT){if(r.state===C.POINT)return T(n.x-t,n.y-t);if(o.state===C.POINT)return T(n.x-t,n.y2+t);let c=n.width*n.height;return n.width*((s.y-n.y+(a.y-n.y))*.5)a.y?T(n.x-t,n.y-t):T(n.x2+t,n.y-t):s.yo.x?T(n.x-t,n.y-t):T(n.x-t,n.y2+t):r.xa.y?T(n.x2+t,n.y2+t):T(n.x-t,n.y2+t):s.yo.x?T(n.x2+t,n.y2+t):T(n.x2+t,n.y-t):r.xi)return!1}return!0}function Es(n=0){return t=>{if(n<0||t.length<3)return t;let e=[],i=0,r=n*n;for(;i{if(o.length<3)return o;let a=[],u=o.closed,h=o.length+3-1+(u?0:2);a.push(s(o,2-(u?0:2),0));for(let f=2-(u?0:2);f{let e=n,i=t.length;if(e>1)for(i=Math.floor(t.length/e);i<3&&e>1;)e-=1,i=Math.floor(t.length/e);let r=[];for(let s=0,o=0;o=i?this.closed?this.get(t-i):this.points[i-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){let e=this.points;if(e.length===0)return"";let i=typeof t=="function"?t:as(t),r="M";for(let s of e)r+=`${i(s.x)},${i(s.y)} L`;return r=r.slice(0,-1),this.closed&&(r+=" Z"),r}draw(t){let e=this.points;if(e.length!==0){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let i of e)t.lineTo(i.x,i.y);this.closed&&t.closePath()}}sample(t){return $s(t)(this)}simplify(t){return Es(t)(this)}bSplines(t){return _s(t)(this)}apply(t){return t(this)}containsElements(t){let e=ii(this.points);return e?t.every(i=>e.containsPt(i.cx,i.cy)&&this.withinArea(i.cx,i.cy)):!1}withinArea(t,e){if(this.length===0)return!1;let i=0,r=this.points[0],s=new W(r.x,r.y,r.x,r.y);for(let o=1;ot?f+d:f}function s(u,h){let f=Nt;return f=r(u,h,f,1),f=r(u+1,h,f,2),f=r(u,h+1,f,4),f=r(u+1,h+1,f,8),Number.isNaN(f)?-1:f}let o=ue;function a(u,h){let f=u,d=h,c=n.invertScaleX(f),p=n.invertScaleY(d);for(let y=0;yti(i.raw,t));return e<0?!1:(this.members.splice(e,1),this.dirty.add(rt.MEMBERS),!0)}removeNonMember(t){let e=this.nonMembers.findIndex(i=>ti(i.raw,t));return e<0?!1:(this.nonMembers.splice(e,1),this.dirty.add(rt.NON_MEMBERS),!0)}removeEdge(t){let e=this.edges.findIndex(i=>i.obj.equals(t));return e<0?!1:(this.edges.splice(e,1),this.dirty.add(rt.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(rt.NON_MEMBERS);for(let e of t)this.nonMembers.push({raw:e,obj:Ut(e)?zt.from(e):Y.from(e),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(rt.EDGES);for(let e of t)this.edges.push({raw:e,obj:W.from(e),area:null})}}update(){let t=this.dirty.has(rt.MEMBERS),e=this.dirty.has(rt.NON_MEMBERS),i=this.dirty.has(rt.EDGES);this.dirty.clear();let r=this.members.map(h=>h.obj);if(this.o.virtualEdges&&(t||e)){let h=this.nonMembers.map(c=>c.obj),f=si(r,h,this.o.maxRoutingIterations,this.o.morphBuffer),d=new Map(this.virtualEdges.map(c=>[c.obj.toString(),c.area]));this.virtualEdges=f.map(c=>{var p;return{raw:c,obj:c,area:(p=d.get(c.toString()))!==null&&p!==void 0?p:null}}),i=!0}let s=!1;if(t||i){let h=this.virtualEdges.concat(this.edges).map(p=>p.obj),f=ui(r,h),d=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,c=Y.from(Le(f,d));c.equals(this.activeRegion)||(s=!0,this.activeRegion=c)}if(s){let h=Math.ceil(this.activeRegion.width/this.o.pixelGroup),f=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=Dt.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(d=>d.area=null),this.nonMembers.forEach(d=>d.area=null),this.edges.forEach(d=>d.area=null),this.virtualEdges.forEach(d=>d.area=null)):(h!==this.potentialArea.width||f!==this.potentialArea.height)&&(this.potentialArea=Dt.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let o=new Map,a=h=>{if(h.area){let f=`${h.obj.width}x${h.obj.height}x${h.obj instanceof Y?"R":"C"}`;o.set(f,h.area)}},u=h=>{if(h.area)return;let f=`${h.obj.width}x${h.obj.height}x${h.obj instanceof Y?"R":"C"}`;if(o.has(f)){let c=o.get(f);h.area=this.potentialArea.copy(c,{x:h.obj.x-this.o.nodeR1,y:h.obj.y-this.o.nodeR1});return}let d=h.obj instanceof Y?ri(h.obj,this.potentialArea,this.o.nodeR1):Ie(h.obj,this.potentialArea,this.o.nodeR1);h.area=d,o.set(f,d)};this.members.forEach(a),this.nonMembers.forEach(a),this.members.forEach(u),this.nonMembers.forEach(h=>{this.activeRegion.intersects(h.obj)?u(h):h.area=null}),this.edges.forEach(h=>{h.area||(h.area=Ae(h.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(h=>{h.area||(h.area=Ae(h.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let e of this.members)e.obj.draw(t)}drawNonMembers(t){for(let e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(let e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(this.members.length===0)return new ht([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:e}=this,i=this.members.map(a=>a.area),r=this.virtualEdges.concat(this.edges).map(a=>a.area),s=this.nonMembers.filter(a=>a.area!=null).map(a=>a.area),o=this.members.map(a=>a.obj);return ai(e,i,r,s,a=>a.containsElements(o),t)}};function ai(n,t,e,i,r,s={}){let o=Object.assign({},Re,s),a=o.threshold,u=o.memberInfluenceFactor,h=o.edgeInfluenceFactor,f=o.nonMemberInfluenceFactor,d=(o.nodeR0-o.nodeR1)*(o.nodeR0-o.nodeR1),c=(o.edgeR0-o.edgeR1)*(o.edgeR0-o.edgeR1);for(let p=0;p0)f*=.8;else break}return new ht([])}function ui(n,t){if(n.length===0)return new Y(0,0,0,0);let e=Y.from(n[0]);for(let i of n)e.add(i);for(let i of t)e.add(Se(i));return e}function Ds(n,t=[],e=[],i={}){if(n.length===0)return new ht([]);let r=new de(i);return r.pushMember(...n),r.pushNonMember(...t),r.pushEdge(...e),r.compute()}var export_circlepack=fe.circlepack;var export_circular=fe.circular;var export_forceAtlas2=ks.default;var export_random=fe.random;var export_rotation=fe.rotation;export{R as Graph,hi as bubblesets,export_circlepack as circlepack,export_circular as circular,export_forceAtlas2 as forceAtlas2,export_random as random,export_rotation as rotation}; diff --git a/src/lib/sigma.bundle.mjs b/src/lib/sigma.bundle.mjs new file mode 100644 index 0000000..7e6607c --- /dev/null +++ b/src/lib/sigma.bundle.mjs @@ -0,0 +1,771 @@ +var ii=Object.create;var ct=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var oi=Object.getOwnPropertyNames;var si=Object.getPrototypeOf,ui=Object.prototype.hasOwnProperty;var ht=(t,r)=>()=>(r||t((r={exports:{}}).exports,r),r.exports),dt=(t,r)=>{for(var n in r)ct(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&ct(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?ct(n,"default",{value:t,enumerable:!0}):n,t));var Xe=ht((Go,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ve;we&&typeof we.ownKeys=="function"?Ve=we.ownKeys:Object.getOwnPropertySymbols?Ve=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ve=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function We(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return We(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return We(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(We(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ve(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=ht((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=pt(r,n,e,i,!0);return gt[t]=a,a}function Ge(t,r,n,e){return n+(r<<8)+(t<<16)}function Me(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;rw){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Ee(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function Rt(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Ee(t,r,n)}var Ei=` +precision highp float; + +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; + +uniform float u_correctionRatio; + +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main(void) { + float border = u_correctionRatio * 2.0; + float dist = length(v_diffVector) - v_radius + border; + + // No antialiasing for picking mode: + #ifdef PICKING_MODE + if (dist > border) + gl_FragColor = transparent; + else + gl_FragColor = v_color; + + #else + float t = 0.0; + if (dist > border) + t = 1.0; + else if (dist > 0.0) + t = dist / border; + + gl_FragColor = mix(v_color, transparent, t); + #endif +} +`,Ti=Ei,Ri=` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_position; +attribute float a_size; +attribute float a_angle; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; + +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; +varying float v_border; + +const float bias = 255.0 / 254.0; + +void main() { + float size = a_size * u_correctionRatio / u_sizeRatio * 4.0; + vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle)); + vec2 position = a_position + diffVector; + gl_Position = vec4( + (u_matrix * vec3(position, 1)).xy, + 0, + 1 + ); + + v_diffVector = diffVector; + v_radius = size / 2.0; + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + #endif + + v_color.a *= bias; +} +`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,yt=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Te=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:yt},{name:"a_size",size:1,type:yt},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:yt}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Te,"ANGLE_1",0);x(Te,"ANGLE_2",2*Math.PI/3);x(Te,"ANGLE_3",4*Math.PI/3);var Ci=` +precision mediump float; + +varying vec4 v_color; + +void main(void) { + gl_FragColor = v_color; +} +`,Si=Ci,Ai=` +attribute vec2 a_position; +attribute vec2 a_normal; +attribute float a_radius; +attribute vec3 a_barycentric; + +#ifdef PICKING_MODE +attribute vec4 a_id; +#else +attribute vec4 a_color; +#endif + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_lengthToThicknessRatio; +uniform float u_widenessToThicknessRatio; + +varying vec4 v_color; + +const float bias = 255.0 / 254.0; + +void main() { + float minThickness = u_minEdgeThickness; + + float normalLength = length(a_normal); + vec2 unitNormal = a_normal / normalLength; + + // These first computations are taken from edge.vert.glsl and + // edge.clamped.vert.glsl. Please read it to get better comments on what's + // happening: + float pixelsThickness = max(normalLength / u_sizeRatio, minThickness); + float webGLThickness = pixelsThickness * u_correctionRatio; + float webGLNodeRadius = a_radius * 2.0 * u_correctionRatio / u_sizeRatio; + float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0; + float webGLArrowHeadThickness = webGLThickness * u_widenessToThicknessRatio; + + float da = a_barycentric.x; + float db = a_barycentric.y; + float dc = a_barycentric.z; + + vec2 delta = vec2( + da * (webGLNodeRadius * unitNormal.y) + + db * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y + webGLArrowHeadThickness * unitNormal.x) + + dc * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y - webGLArrowHeadThickness * unitNormal.x), + + da * (-webGLNodeRadius * unitNormal.x) + + db * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x + webGLArrowHeadThickness * unitNormal.y) + + dc * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x - webGLArrowHeadThickness * unitNormal.y) + ); + + vec2 position = (u_matrix * vec3(a_position + delta, 1)).xy; + + gl_Position = vec4(position, 0, 1); + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + #endif + + v_color.a *= bias; +} +`,Li=Ai,Cr=WebGLRenderingContext,mr=Cr.UNSIGNED_BYTE,Ue=Cr.FLOAT,Pi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],ce={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function Re(t){var r=L(L({},ce),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Li,FRAGMENT_SHADER_SOURCE:Si,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Pi,ATTRIBUTES:[{name:"a_position",size:2,type:Ue},{name:"a_normal",size:2,type:Ue},{name:"a_radius",size:1,type:Ue},{name:"a_color",size:4,type:mr,normalized:!0},{name:"a_id",size:4,type:mr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:Ue}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var f=l.size||1,m=u.size||1,y=s.x,E=s.y,p=u.x,T=u.y,_=Q(l.color),b=p-y,g=T-E,w=b*b+g*g,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-g*w*f,P=b*w*f);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-k,C[o++]=-P,C[o++]=m,C[o++]=_,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,f=u.u_correctionRatio,m=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,E=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(f,a.correctionRatio),s.uniform1f(m,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(E,r.widenessToThicknessRatio)}}])})(le)}var Fo=Re();var ki=` +precision mediump float; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main(void) { + // We only handle antialiasing for normal mode: + #ifdef PICKING_MODE + gl_FragColor = v_color; + #else + float dist = length(v_normal) * v_thickness; + + float t = smoothstep( + v_thickness - v_feather, + v_thickness, + dist + ); + + gl_FragColor = mix(v_color, transparent, t); + #endif +} +`,je=ki,Ni=` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_normal; +attribute float a_normalCoef; +attribute vec2 a_positionStart; +attribute vec2 a_positionEnd; +attribute float a_positionCoef; +attribute float a_radius; +attribute float a_radiusCoef; + +uniform mat3 u_matrix; +uniform float u_zoomRatio; +uniform float u_sizeRatio; +uniform float u_pixelRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_lengthToThicknessRatio; +uniform float u_feather; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const float bias = 255.0 / 254.0; + +void main() { + float minThickness = u_minEdgeThickness; + + float radius = a_radius * a_radiusCoef; + vec2 normal = a_normal * a_normalCoef; + vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef; + + float normalLength = length(normal); + vec2 unitNormal = normal / normalLength; + + // These first computations are taken from edge.vert.glsl. Please read it to + // get better comments on what's happening: + float pixelsThickness = max(normalLength, minThickness * u_sizeRatio); + float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio; + + // Here, we move the point to leave space for the arrow head: + float direction = sign(radius); + float webGLNodeRadius = direction * radius * 2.0 * u_correctionRatio / u_sizeRatio; + float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0; + + vec2 compensationVector = vec2(-direction * unitNormal.y, direction * unitNormal.x) * (webGLNodeRadius + webGLArrowHeadLength); + + // Here is the proper position of the vertex + gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness + compensationVector, 1)).xy, 0, 1); + + v_thickness = webGLThickness / u_zoomRatio; + + v_normal = unitNormal; + + v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0; + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + #endif + + v_color.a *= bias; +} +`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function wt(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Io=wt();function Lr(t){return He([wt(t),Re(t)])}var Fi=Lr(),xt=Fi,Ii=` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_normal; +attribute float a_normalCoef; +attribute vec2 a_positionStart; +attribute vec2 a_positionEnd; +attribute float a_positionCoef; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_zoomRatio; +uniform float u_pixelRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_feather; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const float bias = 255.0 / 254.0; + +void main() { + float minThickness = u_minEdgeThickness; + + vec2 normal = a_normal * a_normalCoef; + vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef; + + float normalLength = length(normal); + vec2 unitNormal = normal / normalLength; + + // We require edges to be at least "minThickness" pixels thick *on screen* + // (so we need to compensate the size ratio): + float pixelsThickness = max(normalLength, minThickness * u_sizeRatio); + + // Then, we need to retrieve the normalized thickness of the edge in the WebGL + // referential (in a ([0, 1], [0, 1]) space), using our "magic" correction + // ratio: + float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio; + + // Here is the proper position of the vertex + gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness, 1)).xy, 0, 1); + + // For the fragment shader though, we need a thickness that takes the "magic" + // correction ratio into account (as in webGLThickness), but so that the + // antialiasing effect does not depend on the zoom level. So here's yet + // another thickness version: + v_thickness = webGLThickness / u_zoomRatio; + + v_normal = unitNormal; + + v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0; + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + #endif + + v_color.a *= bias; +} +`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],Ct=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe(Xe()),Ye=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(qe());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function $e(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Ze(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,$e(te(),o)),he(f,jr(te(),a)),he(f,$e(te(),l/m/2/y,c/m/2/y))):(he(f,$e(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,$e(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Ze(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function Ke(t){"@babel/helpers - typeof";return Ke=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},Ke(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function Qe(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||tt)},e):this.animate({ratio:this.ratio/tt})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||tt)},e):this.animate({ratio:this.ratio*tt})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Ye);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function ke(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function rt(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),et(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Me(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Ge.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=ke(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=ke(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Me(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Ge.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,et(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),et(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Ze(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Ze(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Ye),ln=un;var hn=WebGLRenderingContext,vs=hn.UNSIGNED_BYTE,gs=hn.FLOAT;var ga=` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_normal; +attribute float a_normalCoef; +attribute vec2 a_positionStart; +attribute vec2 a_positionEnd; +attribute float a_positionCoef; +attribute float a_sourceRadius; +attribute float a_targetRadius; +attribute float a_sourceRadiusCoef; +attribute float a_targetRadiusCoef; + +uniform mat3 u_matrix; +uniform float u_zoomRatio; +uniform float u_sizeRatio; +uniform float u_pixelRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_lengthToThicknessRatio; +uniform float u_feather; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const float bias = 255.0 / 254.0; + +void main() { + float minThickness = u_minEdgeThickness; + + vec2 normal = a_normal * a_normalCoef; + vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef; + + float normalLength = length(normal); + vec2 unitNormal = normal / normalLength; + + // These first computations are taken from edge.vert.glsl. Please read it to + // get better comments on what's happening: + float pixelsThickness = max(normalLength, minThickness * u_sizeRatio); + float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio; + + // Here, we move the point to leave space for the arrow heads: + // Source arrow head + float sourceRadius = a_sourceRadius * a_sourceRadiusCoef; + float sourceDirection = sign(sourceRadius); + float webGLSourceRadius = sourceDirection * sourceRadius * 2.0 * u_correctionRatio / u_sizeRatio; + float webGLSourceArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0; + vec2 sourceCompensationVector = + vec2(-sourceDirection * unitNormal.y, sourceDirection * unitNormal.x) + * (webGLSourceRadius + webGLSourceArrowHeadLength); + + // Target arrow head + float targetRadius = a_targetRadius * a_targetRadiusCoef; + float targetDirection = sign(targetRadius); + float webGLTargetRadius = targetDirection * targetRadius * 2.0 * u_correctionRatio / u_sizeRatio; + float webGLTargetArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0; + vec2 targetCompensationVector = + vec2(-targetDirection * unitNormal.y, targetDirection * unitNormal.x) + * (webGLTargetRadius + webGLTargetArrowHeadLength); + + // Here is the proper position of the vertex + gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness + sourceCompensationVector + targetCompensationVector, 1)).xy, 0, 1); + + v_thickness = webGLThickness / u_zoomRatio; + + v_normal = unitNormal; + + v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0; + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + #endif + + v_color.a *= bias; +} +`,ma=ga,dn=WebGLRenderingContext,cn=dn.UNSIGNED_BYTE,oe=dn.FLOAT,pa=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],ya={lengthToThicknessRatio:ce.lengthToThicknessRatio};function fn(t){var r=L(L({},ya),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ma,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:pa,ATTRIBUTES:[{name:"a_positionStart",size:2,type:oe},{name:"a_positionEnd",size:2,type:oe},{name:"a_normal",size:2,type:oe},{name:"a_color",size:4,type:cn,normalized:!0},{name:"a_id",size:4,type:cn,normalized:!0},{name:"a_sourceRadius",size:1,type:oe},{name:"a_targetRadius",size:1,type:oe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:oe},{name:"a_normalCoef",size:1,type:oe},{name:"a_sourceRadiusCoef",size:1,type:oe},{name:"a_targetRadiusCoef",size:1,type:oe}],CONSTANT_DATA:[[0,1,-1,0],[0,-1,1,0],[1,1,0,1],[1,1,0,1],[0,-1,1,0],[1,-1,0,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=s.size||1,g=u.size||1,w=T*T+_*_,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-_*w*c,P=T*w*c);var C=this.array;C[o++]=f,C[o++]=m,C[o++]=y,C[o++]=E,C[o++]=k,C[o++]=P,C[o++]=p,C[o++]=a,C[o++]=b,C[o++]=g}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var ms=fn();function ba(t){return He([fn(t),Re(t),Re(L(L({},t),{},{extremity:"source"}))])}var ps=ba();var vn=WebGLRenderingContext,ys=vn.UNSIGNED_BYTE,bs=vn.FLOAT;var gn=WebGLRenderingContext,_s=gn.UNSIGNED_BYTE,Es=gn.FLOAT;var Cs=fe(qe());function bn(t,r,n){return Ee(t,r,n)}function _a(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o;t.beginPath(),t.moveTo(r.x+c,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+c,r.y-l/2),t.lineTo(r.x+c,r.y-c),t.lineTo(r.x-c,r.y-c),t.lineTo(r.x-c,r.y+c),t.lineTo(r.x+c,r.y+c),t.moveTo(r.x+c,r.y+l/2),t.closePath(),t.fill()}else{var f=r.size+o;t.fillRect(r.x-f,r.y-f,f*2,f*2)}t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,bn(t,r,n)}function Ea(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function Ta(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function _n(t){var r=Ta(t,"string");return typeof r=="symbol"?r:r+""}function mn(t,r){for(var n=0;nto,NodePictogramProgram:()=>ro,createNodeImageProgram:()=>qt});var An=fe(Xe());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);n v_radius / paddingRatio || abs(diffVector.y) > v_radius / paddingRatio) { + color = u_colorizeImages ? gl_FragColor : v_color; + } + } + } + #endif + + // Crop in a circle when u_keepWithinCircle is truthy: + if (u_keepWithinCircle) { + if (dist < v_radius - border) { + gl_FragColor = color; + } else if (dist < v_radius) { + gl_FragColor = mix(transparent, color, (v_radius - dist) / border); + } + } + + // Crop in a square else: + else { + float squareHalfSize = v_radius * `).concat(Math.SQRT1_2*Math.cos(Math.PI/12),`; + if (abs(diffVector.x) > squareHalfSize || abs(diffVector.y) > squareHalfSize) { + gl_FragColor = transparent; + } else { + gl_FragColor = color; + } + } +} +`);return n}var ja=` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_position; +attribute float a_size; +attribute float a_angle; +attribute vec4 a_texture; +attribute float a_textureIndex; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; + +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; +varying vec4 v_texture; +varying float v_textureIndex; + +const float bias = 255.0 / 254.0; +const float marginRatio = 1.05; + +void main() { + float size = a_size * u_correctionRatio / u_sizeRatio * 4.0; + vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle)); + vec2 position = a_position + diffVector * marginRatio; + gl_Position = vec4( + (u_matrix * vec3(position, 1)).xy, + 0, + 1 + ); + + v_diffVector = diffVector; + v_radius = size / 2.0 / marginRatio; + + #ifdef PICKING_MODE + // For picking mode, we use the ID as the color: + v_color = a_id; + #else + // For normal mode, we use the color: + v_color = a_color; + + // Pass the texture coordinates: + v_textureIndex = a_textureIndex; + v_texture = a_texture; + #endif + + v_color.a *= bias; +} +`,Va=ja;function ye(){ye=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Wa=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function Xa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(ye().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return ye().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function Ya(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(ye().mark(function t(r){var n,e,i,a,o,s,u=arguments;return ye().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,Xa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function qa(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function $a(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ka),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Za({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(ye().mark(function i(a){var o,s;return ye().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,Ya(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},qa(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(it,"NEW_TEXTURE_EVENT","newTexture");var Qa=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,Oe=On.FLOAT,Ja=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),eo=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},Ja),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=Ba(i,Qa),y=new it(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(it.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Va,FRAGMENT_SHADER_SOURCE:Ha({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:eo,ATTRIBUTES:[{name:"a_position",size:2,type:Oe},{name:"a_size",size:1,type:Oe},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:Oe},{name:"a_textureIndex",size:1,type:Oe}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Oe}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>bo,EdgeCurvedDoubleArrowProgram:()=>_o,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>ot,default:()=>yo,indexParallelEdgesIndex:()=>po});function no(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=no(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;KDe,downloadAsImage:()=>or,downloadAsJPEG:()=>Lo,downloadAsPNG:()=>Ao,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>So});var Kn=fe(qn()),De={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Eo(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function To(t){var r=Eo(t,"string");return typeof r=="symbol"?r:r+""}function Ro(t,r,n){return(r=To(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},De),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function wo(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function xo(t,r){if(t==null)return{};var n,e,i=wo(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.format,a=xo(e,Co),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function So(t){return nr.apply(this,arguments)}function nr(){return nr=st(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=st(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Ao(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function Lo(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,sn as MouseCaptor,Na as NodeSquareProgram,un as Sigma,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; diff --git a/src/package/vendor_entry_graphology.mjs b/src/package/vendor_entry_graphology.mjs new file mode 100644 index 0000000..5976a12 --- /dev/null +++ b/src/package/vendor_entry_graphology.mjs @@ -0,0 +1,8 @@ +// Entry for the node-safe vendor bundle (src/lib/graphology.bundle.mjs). +// Pure-JS graph model, layout algorithms and bubble-set geometry — no DOM or +// WebGL references at module scope, so vitest tests may import the bundle. +// Bundled by src/package/vendor_libs.js via esbuild. +export {default as Graph} from 'graphology'; +export {circular, random, circlepack, rotation} from 'graphology-layout'; +export {default as forceAtlas2} from 'graphology-layout-forceatlas2'; +export * as bubblesets from 'bubblesets-js'; diff --git a/src/package/vendor_entry_sigma.mjs b/src/package/vendor_entry_sigma.mjs new file mode 100644 index 0000000..8a424de --- /dev/null +++ b/src/package/vendor_entry_sigma.mjs @@ -0,0 +1,9 @@ +// Entry for the browser-only vendor bundle (src/lib/sigma.bundle.mjs). +// Sigma references WebGL globals at module scope — never import this bundle +// from code that must load under node (vitest). Renderer-touching modules +// only. Bundled by src/package/vendor_libs.js via esbuild. +export {Sigma, Camera, MouseCaptor} from 'sigma'; +export {NodeSquareProgram} from '@sigma/node-square'; +export * as nodeImage from '@sigma/node-image'; +export * as edgeCurve from '@sigma/edge-curve'; +export * as exportImage from '@sigma/export-image'; diff --git a/src/package/vendor_libs.js b/src/package/vendor_libs.js index 1bfc3aa..75832a1 100644 --- a/src/package/vendor_libs.js +++ b/src/package/vendor_libs.js @@ -47,6 +47,47 @@ for (const {from, to, pkg} of copies) { console.log(`[vendor-libs] ${path.relative(root, from)} -> ${path.relative(root, to)} (${pkg}@${ver} sha256:${hash.slice(0, 16)}…)`); } +// Bundle multi-module deps (sigma + plugins, graphology + utils) into single +// ESM files under src/lib/ so they load under raw-module dev serve, Electron +// (file://), the esbuild app bundle and the inline-html dist — same parity +// goal as the plain copies above, but these packages have bare-specifier +// imports and need bundling instead of copying. +const esbuild = require('esbuild'); + +const bundles = [ + { + entry: path.join(__dirname, 'vendor_entry_graphology.mjs'), + out: path.join(libDir, 'graphology.bundle.mjs'), + pkgs: ['graphology', 'graphology-layout', 'graphology-layout-forceatlas2', 'bubblesets-js'], + }, + { + entry: path.join(__dirname, 'vendor_entry_sigma.mjs'), + out: path.join(libDir, 'sigma.bundle.mjs'), + pkgs: ['sigma', '@sigma/node-square', '@sigma/node-image', '@sigma/edge-curve', '@sigma/export-image'], + }, +]; + +for (const {entry, out, pkgs} of bundles) { + try { + esbuild.buildSync({ + entryPoints: [entry], + bundle: true, + format: 'esm', + target: 'es2020', + minify: true, + legalComments: 'eof', + outfile: out, + logLevel: 'silent', + }); + } catch (err) { + console.error(`[vendor-libs] esbuild failed for ${path.relative(root, entry)}: ${err.message}`); + process.exit(1); + } + const versions = pkgs.map((p) => `${p}@${pkgVersion(p)}`).join(' '); + const sizeKb = (fs.statSync(out).size / 1024).toFixed(0); + console.log(`[vendor-libs] ${path.relative(root, entry)} -> ${path.relative(root, out)} (${sizeKb} kB; ${versions} sha256:${sha256(out).slice(0, 16)}…)`); +} + // Regenerate assistant prompt modules from their markdown sources so the // prompts stay human-readable in source control but load as plain JS // everywhere (serve, electron, bundle, tests). diff --git a/tests/filter-visibility.test.js b/tests/filter-visibility.test.js new file mode 100644 index 0000000..2f2ab44 --- /dev/null +++ b/tests/filter-visibility.test.js @@ -0,0 +1,96 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { GraphFilterManager } from "../src/graph/filter.js"; + +// ========================================================================== +// updateElementVisibility (sigma migration Phase 1) — diffs requested +// show/hide ids against the renderer's current visibility (style.visibility, +// backed by graphology `hidden` attrs) and only pushes actual changes. +// ========================================================================== + +function item(id, visibility) { + return { id, style: { visibility } }; +} + +function createMockCache({ nodes = [], edges = [] } = {}) { + return { + visibleElementsChanged: false, + graph: { + // Sync like the real SigmaAdapter.getData (callers await it, a no-op). + getData: vi.fn(() => ({ nodes, edges })), + showElement: vi.fn(async () => {}), + hideElement: vi.fn(async () => {}), + }, + metrics: { + invalidateMetricValues: vi.fn(), + }, + }; +} + +describe("GraphFilterManager.updateElementVisibility", () => { + let cache, fm; + + beforeEach(() => { + cache = createMockCache({ + nodes: [item("n1", "visible"), item("n2", "hidden"), item("n3", "visible")], + edges: [item("e1", "hidden"), item("e2", "visible")], + }); + fm = new GraphFilterManager(cache); + }); + + it("shows only ids that are currently hidden", async () => { + await fm.updateElementVisibility(["n1", "n2", "e1"], []); + + expect(cache.graph.showElement).toHaveBeenCalledTimes(1); + expect(cache.graph.showElement).toHaveBeenCalledWith(["n2", "e1"]); + expect(cache.graph.hideElement).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(true); + }); + + it("hides only ids that are currently visible", async () => { + await fm.updateElementVisibility([], ["n2", "n3", "e2"]); + + expect(cache.graph.hideElement).toHaveBeenCalledTimes(1); + expect(cache.graph.hideElement).toHaveBeenCalledWith(["n3", "e2"]); + expect(cache.graph.showElement).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(true); + }); + + it("applies show and hide diffs in the same pass", async () => { + await fm.updateElementVisibility(["n2"], ["n1"]); + + expect(cache.graph.showElement).toHaveBeenCalledWith(["n2"]); + expect(cache.graph.hideElement).toHaveBeenCalledWith(["n1"]); + expect(cache.metrics.invalidateMetricValues).toHaveBeenCalledTimes(1); + }); + + it("is a no-op when requested state matches current state", async () => { + await fm.updateElementVisibility(["n1", "n3", "e2"], ["n2", "e1"]); + + expect(cache.graph.showElement).not.toHaveBeenCalled(); + expect(cache.graph.hideElement).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(false); + expect(cache.metrics.invalidateMetricValues).not.toHaveBeenCalled(); + }); + + it("ignores ids unknown to the renderer", async () => { + await fm.updateElementVisibility(["ghost1"], ["ghost2"]); + + expect(cache.graph.showElement).not.toHaveBeenCalled(); + expect(cache.graph.hideElement).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(false); + }); + + it("handles empty inputs without touching the renderer", async () => { + await fm.updateElementVisibility([], []); + + expect(cache.graph.showElement).not.toHaveBeenCalled(); + expect(cache.graph.hideElement).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(false); + }); + + it("invalidates metrics exactly once when anything changed", async () => { + await fm.updateElementVisibility(["n2", "e1"], ["n1", "e2"]); + + expect(cache.metrics.invalidateMetricValues).toHaveBeenCalledTimes(1); + }); +}); diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js new file mode 100644 index 0000000..c3ec77d --- /dev/null +++ b/tests/graph-model.test.js @@ -0,0 +1,330 @@ +import { describe, it, expect } from "vitest"; +import { + buildGraphologyGraph, + nodeAttributesFromStyle, + edgeAttributesFromStyle, + makeNodeReducer, + makeEdgeReducer, + STATE_ACCENT_COLOR, + STATE_DIM_COLOR, +} from "../src/graph/graph_model.js"; + +// ========================================================================== +// Graph model (sigma migration Phase 1) — graphology population from the +// app cache and the node/edge reducer factories. Node-safe: must never +// import the sigma bundle. +// ========================================================================== + +function makeNode(id, style = {}) { + return { id, style: { size: 20, fill: "#403C53", ...style } }; +} + +function makeEdge(id, source, target, style = {}) { + return { id, source, target, style: { lineWidth: 0.75, stroke: "#403C5390", ...style } }; +} + +function createMockCache({ nodes = [], edges = [], positions = new Map() } = {}) { + return { + nodeRef: new Map(nodes.map((n) => [n.id, n])), + edgeRef: new Map(edges.map((e) => [e.id, e])), + data: { + selectedLayout: "Default", + layouts: { Default: { positions } }, + }, + ui: { debug: () => {} }, + }; +} + +describe("buildGraphologyGraph — population", () => { + it("adds every node and edge with stable keys", () => { + const cache = createMockCache({ + nodes: [makeNode("a"), makeNode("b")], + edges: [makeEdge("e1", "a", "b")], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.order).toBe(2); + expect(graph.size).toBe(1); + expect(graph.hasNode("a")).toBe(true); + expect(graph.hasEdge("e1")).toBe(true); + }); + + it("uses persisted layout positions when present", () => { + const positions = new Map([["a", { style: { x: 42, y: -7 } }]]); + const cache = createMockCache({ + nodes: [makeNode("a", { x: 1, y: 1 })], + positions, + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("a", "x")).toBe(42); + expect(graph.getNodeAttribute("a", "y")).toBe(-7); + }); + + it("falls back to style x/y when no persisted position exists", () => { + const cache = createMockCache({ nodes: [makeNode("a", { x: 5, y: 6 })] }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("a", "x")).toBe(5); + expect(graph.getNodeAttribute("a", "y")).toBe(6); + }); + + it("assigns deterministic numeric placeholder coordinates otherwise", () => { + const nodes = [makeNode("a"), makeNode("b"), makeNode("c")]; + const cache = createMockCache({ nodes }); + + const first = buildGraphologyGraph(cache); + const second = buildGraphologyGraph(cache); + + for (const id of ["a", "b", "c"]) { + expect(Number.isFinite(first.getNodeAttribute(id, "x"))).toBe(true); + expect(Number.isFinite(first.getNodeAttribute(id, "y"))).toBe(true); + expect(first.getNodeAttribute(id, "x")).toBe(second.getNodeAttribute(id, "x")); + expect(first.getNodeAttribute(id, "y")).toBe(second.getNodeAttribute(id, "y")); + } + // Spread: distinct nodes get distinct placeholder coordinates. + expect(first.getNodeAttribute("a", "x")).not.toBe(first.getNodeAttribute("b", "x")); + }); + + it("ignores non-numeric persisted positions and uses the fallback", () => { + const positions = new Map([["a", { style: { x: null, y: undefined } }]]); + const cache = createMockCache({ nodes: [makeNode("a", { x: 3, y: 4 })], positions }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("a", "x")).toBe(3); + expect(graph.getNodeAttribute("a", "y")).toBe(4); + }); + + it("maps labels only when style.label is truthy", () => { + const cache = createMockCache({ + nodes: [ + makeNode("labeled", { label: true, labelText: "Gene A" }), + makeNode("unlabeled", { label: false, labelText: "ignored" }), + makeNode("bare"), + ], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("labeled", "label")).toBe("Gene A"); + expect(graph.getNodeAttribute("unlabeled", "label")).toBe(null); + expect(graph.getNodeAttribute("bare", "label")).toBe(null); + }); + + it("defaults hidden to false and honours style visibility", () => { + const cache = createMockCache({ + nodes: [makeNode("shown"), makeNode("gone", { visibility: "hidden" })], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("shown", "hidden")).toBe(false); + expect(graph.getNodeAttribute("gone", "hidden")).toBe(true); + }); + + it("takes the first dimension of an array size (G6 [w, h])", () => { + const cache = createMockCache({ nodes: [makeNode("a", { size: [30, 12] })] }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("a", "size")).toBe(30); + }); + + it("supports parallel (multi) edges and self loops with their own ids", () => { + const cache = createMockCache({ + nodes: [makeNode("a"), makeNode("b")], + edges: [ + makeEdge("e1", "a", "b"), + makeEdge("e2", "a", "b"), + makeEdge("loop", "a", "a"), + ], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.size).toBe(3); + expect(graph.hasEdge("e1")).toBe(true); + expect(graph.hasEdge("e2")).toBe(true); + expect(graph.hasEdge("loop")).toBe(true); + }); + + it("skips edges whose endpoints are missing instead of throwing", () => { + const cache = createMockCache({ + nodes: [makeNode("a")], + edges: [makeEdge("dangling", "a", "ghost")], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.size).toBe(0); + }); + + it("builds an empty graph from an empty cache without throwing", () => { + const cache = createMockCache(); + + const graph = buildGraphologyGraph(cache); + + expect(graph.order).toBe(0); + expect(graph.size).toBe(0); + }); + + it("maps edge lineWidth/stroke to size/color", () => { + const cache = createMockCache({ + nodes: [makeNode("a"), makeNode("b")], + edges: [makeEdge("e1", "a", "b", { lineWidth: 2, stroke: "#112233" })], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getEdgeAttribute("e1", "size")).toBe(2); + expect(graph.getEdgeAttribute("e1", "color")).toBe("#112233"); + }); +}); + +describe("attribute mapping helpers", () => { + it("nodeAttributesFromStyle only emits present keys", () => { + expect(nodeAttributesFromStyle({})).toEqual({}); + expect(nodeAttributesFromStyle({ fill: "#fff" })).toEqual({ color: "#fff" }); + expect(nodeAttributesFromStyle({ visibility: "visible" })).toEqual({ hidden: false }); + }); + + it("nodeAttributesFromStyle ignores non-finite coordinates", () => { + expect(nodeAttributesFromStyle({ x: NaN, y: "5" })).toEqual({}); + }); + + it("nodeAttributesFromStyle keeps a size of 0 (presence check, not truthiness)", () => { + expect(nodeAttributesFromStyle({ size: 0 })).toEqual({ size: 0 }); + }); + + it("nodeAttributesFromStyle emits no label when label is truthy but labelText is absent", () => { + // Absent or undefined labelText → no label attr at all (sigma keeps its + // default); an explicit null labelText → label: null (label cleared). + expect(nodeAttributesFromStyle({ label: true })).toEqual({}); + expect(nodeAttributesFromStyle({ label: true, labelText: undefined })).toEqual({}); + expect(nodeAttributesFromStyle({ label: true, labelText: null })).toEqual({ label: null }); + }); + + it("edgeAttributesFromStyle maps label and visibility like nodes", () => { + expect(edgeAttributesFromStyle({ label: true, labelText: "ppi" })).toEqual({ label: "ppi" }); + expect(edgeAttributesFromStyle({ label: false })).toEqual({ label: null }); + expect(edgeAttributesFromStyle({ visibility: "hidden" })).toEqual({ hidden: true }); + }); +}); + +describe("reducers — states and hidden handling", () => { + function reducerFixture() { + const nodes = [makeNode("a"), makeNode("b")]; + const edges = [makeEdge("e1", "a", "b")]; + const cache = createMockCache({ nodes, edges }); + cache.graphData = buildGraphologyGraph(cache); + const elementStates = new Map(); + return { + cache, + elementStates, + nodeReducer: makeNodeReducer(cache, elementStates), + edgeReducer: makeEdgeReducer(cache, elementStates), + }; + } + + it("node: passes data through untouched without states", () => { + const { nodeReducer } = reducerFixture(); + const data = { x: 0, y: 0, color: "#403C53", hidden: false }; + + expect(nodeReducer("a", data)).toBe(data); + }); + + it("node: hidden data wins over any state", () => { + const { nodeReducer, elementStates } = reducerFixture(); + elementStates.set("a", ["selected"]); + const data = { color: "#403C53", hidden: true }; + + const res = nodeReducer("a", data); + + expect(res.hidden).toBe(true); + expect(res.color).toBe("#403C53"); + }); + + it("node: selected gets the accent color and raised zIndex", () => { + const { nodeReducer, elementStates } = reducerFixture(); + elementStates.set("a", ["selected"]); + + const res = nodeReducer("a", { color: "#403C53", hidden: false, zIndex: 0 }); + + expect(res.color).toBe(STATE_ACCENT_COLOR); + expect(res.zIndex).toBe(1); + }); + + it("node: highlight and dim apply their state colors", () => { + const { nodeReducer, elementStates } = reducerFixture(); + + elementStates.set("a", ["highlight"]); + expect(nodeReducer("a", { color: "#403C53", hidden: false }).color).toBe(STATE_ACCENT_COLOR); + + elementStates.set("a", ["dim"]); + expect(nodeReducer("a", { color: "#403C53", hidden: false }).color).toBe(STATE_DIM_COLOR); + }); + + it("node: selected takes precedence over dim", () => { + const { nodeReducer, elementStates } = reducerFixture(); + elementStates.set("a", ["dim", "selected"]); + + const res = nodeReducer("a", { color: "#403C53", hidden: false }); + + expect(res.color).toBe(STATE_ACCENT_COLOR); + expect(res.zIndex).toBe(1); + }); + + it("node: does not mutate the input data", () => { + const { nodeReducer, elementStates } = reducerFixture(); + elementStates.set("a", ["selected"]); + const data = { color: "#403C53", hidden: false, zIndex: 0 }; + + nodeReducer("a", data); + + expect(data.color).toBe("#403C53"); + expect(data.zIndex).toBe(0); + }); + + it("edge: hidden when its own hidden attr is set", () => { + const { edgeReducer } = reducerFixture(); + + const res = edgeReducer("e1", { color: "#403C5390", hidden: true }); + + expect(res.hidden).toBe(true); + }); + + it("edge: hidden when either endpoint is hidden", () => { + const { cache, edgeReducer } = reducerFixture(); + cache.graphData.setNodeAttribute("b", "hidden", true); + + const res = edgeReducer("e1", { color: "#403C5390", hidden: false }); + + expect(res.hidden).toBe(true); + }); + + it("edge: visible with visible endpoints and no states", () => { + const { edgeReducer } = reducerFixture(); + const data = { color: "#403C5390", hidden: false }; + + expect(edgeReducer("e1", data)).toBe(data); + }); + + it("edge: selected/highlight/dim state colors", () => { + const { edgeReducer, elementStates } = reducerFixture(); + + elementStates.set("e1", ["selected"]); + const selected = edgeReducer("e1", { color: "#403C5390", hidden: false, zIndex: 0 }); + expect(selected.color).toBe(STATE_ACCENT_COLOR); + expect(selected.zIndex).toBe(1); + + elementStates.set("e1", ["highlight"]); + expect(edgeReducer("e1", { color: "#403C5390", hidden: false }).color).toBe(STATE_ACCENT_COLOR); + + elementStates.set("e1", ["dim"]); + expect(edgeReducer("e1", { color: "#403C5390", hidden: false }).color).toBe(STATE_DIM_COLOR); + }); +}); diff --git a/tests/style-panel-regression.test.js b/tests/style-panel-regression.test.js index 92d1e8c..e3b267c 100644 --- a/tests/style-panel-regression.test.js +++ b/tests/style-panel-regression.test.js @@ -1,6 +1,4 @@ import { describe, it, expect } from "vitest"; -import { readFileSync } from "fs"; -import { join } from "path"; import { DEFAULTS, CFG } from "../src/config.js"; import { StaticUtilities } from "../src/utilities/static.js"; import { GraphStyleManager } from "../src/graph/style.js"; @@ -168,120 +166,14 @@ function setupEdgeInCache(cache, edgeData) { cache.edgeRef.set(edgeData.id, edgeClone); } -// ========================================================================== -// REGRESSION: Graph constructor must not set spec-level type/style -// ========================================================================== - -describe("Graph constructor must not set spec-level node/edge type or style", () => { - const coreSource = readFileSync( - join(import.meta.dirname, "..", "src", "graph", "core.js"), - "utf8", - ); - - // Extract the Graph constructor call block - const graphConstructorMatch = coreSource.match( - /this\.cache\.graph\s*=\s*new\s+Graph\(\{[\s\S]*?\n\s*\}\)\s*;/, - ); - - it("Graph constructor call is found in source", () => { - expect(graphConstructorMatch).not.toBeNull(); - }); - - it("node config must not have a top-level type property", () => { - // Match the node: { ... } block inside the Graph constructor - const nodeBlock = graphConstructorMatch[0].match( - /node:\s*\{([\s\S]*?)\},\s*edge:/, - ); - expect(nodeBlock).not.toBeNull(); - // Should not have `type:` as a direct child (state.type patterns are fine) - const lines = nodeBlock[1].split("\n"); - const topLevelTypeLines = lines.filter((line) => /^\s*type\s*:/.test(line)); - expect(topLevelTypeLines).toHaveLength(0); - }); - - it("node config must not have a top-level style property", () => { - const nodeBlock = graphConstructorMatch[0].match( - /node:\s*\{([\s\S]*?)\},\s*edge:/, - ); - expect(nodeBlock).not.toBeNull(); - const lines = nodeBlock[1].split("\n"); - // `style:` as direct child of node config (not inside state: { ... }) - const topLevelStyleLines = lines.filter((line) => - /^\s*style\s*:/.test(line), - ); - expect(topLevelStyleLines).toHaveLength(0); - }); - - it("edge config must not have a top-level type property", () => { - const edgeBlock = graphConstructorMatch[0].match( - /edge:\s*\{([\s\S]*?)\},\s*behaviors:/, - ); - expect(edgeBlock).not.toBeNull(); - const lines = edgeBlock[1].split("\n"); - const topLevelTypeLines = lines.filter((line) => /^\s*type\s*:/.test(line)); - expect(topLevelTypeLines).toHaveLength(0); - }); - - it("edge config must not have a top-level style property", () => { - const edgeBlock = graphConstructorMatch[0].match( - /edge:\s*\{([\s\S]*?)\},\s*behaviors:/, - ); - expect(edgeBlock).not.toBeNull(); - const lines = edgeBlock[1].split("\n"); - const topLevelStyleLines = lines.filter((line) => - /^\s*style\s*:/.test(line), - ); - expect(topLevelStyleLines).toHaveLength(0); - }); -}); - -// ========================================================================== -// REGRESSION: State styles must not override user-customizable properties -// In G6 v5, state styles always override per-node data styles. Any -// user-settable property (fill, size, stroke, lineWidth, type) in a -// persistent state like "selected" would silently break the styling panel. -// ========================================================================== - -describe("State styles must not override user-customizable properties", () => { - const coreSource = readFileSync( - join(import.meta.dirname, "..", "src", "graph", "core.js"), - "utf8", - ); - - const graphConstructorMatch = coreSource.match( - /this\.cache\.graph\s*=\s*new\s+Graph\(\{[\s\S]*?\n\s*\}\)\s*;/, - ); - - // Extract the node selected state block - const nodeSelectedMatch = graphConstructorMatch[0].match( - /node:[\s\S]*?selected:\s*\{([^}]*)\}/, - ); - - // Extract the edge selected state block - const edgeSelectedMatch = graphConstructorMatch[0].match( - /edge:[\s\S]*?selected:\s*\{([^}]*)\}/, - ); - - const userCustomizableNodeProps = ["fill", "size", "stroke", "lineWidth"]; - const userCustomizableEdgeProps = ["stroke", "lineWidth"]; - - for (const prop of userCustomizableNodeProps) { - it(`node selected state must not set "${prop}"`, () => { - expect(nodeSelectedMatch).not.toBeNull(); - // Property should not appear as a key in the state block - const regex = new RegExp(`\\b${prop}\\s*:`); - expect(nodeSelectedMatch[1]).not.toMatch(regex); - }); - } - - for (const prop of userCustomizableEdgeProps) { - it(`edge selected state must not set "${prop}"`, () => { - expect(edgeSelectedMatch).not.toBeNull(); - const regex = new RegExp(`\\b${prop}\\s*:`); - expect(edgeSelectedMatch[1]).not.toMatch(regex); - }); - } -}); +// NOTE(sigma-migration): the former source-pinning regressions ("Graph +// constructor must not set spec-level node/edge type or style" and "State +// styles must not override user-customizable properties") guarded a G6 v5 +// hazard — spec-level options and state styles silently overriding per-node +// data styles. The sigma renderer has no spec-level node/edge config and its +// reducers (src/graph/graph_model.js) only adjust render-time display data, +// so the hazard is structurally impossible; reducer behavior is covered by +// tests/graph-model.test.js. // ========================================================================== // REGRESSION: Node style overrides survive the full update → render pipeline From e2ab10731980a94512dc437d53008bd657ab703a Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 14:48:57 +0200 Subject: [PATCH 02/69] feat(renderer): add visual parity for sigma renderer (phase 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 of the G6→Sigma cutover per MIGRATION.md: - node shapes: circle/square native; bordered circles/rects and diamond/hexagon/triangle/star via crisp SVG-texture programs (@sigma/node-image, new shape_textures.js); paint values validated against an SVG-safe allowlist before embedding, texture cache capped - edges: straight/curved x arrow/sourceArrow/doubleArrow program matrix; polyline degrades to curve and lineDash is not rendered (documented in API.md; values still round-trip) - labels: custom node/edge drawers (label_renderers.js) honoring per-element size/color/background/placement/offset/auto-rotate; CFG.HIDE_LABELS synced live with explicit labels kept visible (G6 semantics) - states: halo treatment per old G6 spec, colors centralized in DEFAULTS.STATE (config.js); selected > highlight > dim precedence - y-axis: app model stays y-down, flipped exactly once at the graphology boundary so legacy saved layouts keep their orientation (G6 size diameter → sigma radius likewise mapped) - tests: 700 passing (Excel style round-trip, shape textures incl. injection guards, label drawers incl. vertical-edge rotation boundary) All five perf gates still pass (load 831 ms, stall 65 ms, wheel 60 FPS, 500-node select 62 ms). --- API.md | 8 +- src/config.js | 9 + src/graph/core.js | 8 +- src/graph/graph_model.js | 194 +++++++++++++++++---- src/graph/label_renderers.js | 163 ++++++++++++++++++ src/graph/shape_textures.js | 169 ++++++++++++++++++ src/graph/sigma_adapter.js | 126 +++++++++++++- src/lib/sigma.bundle.mjs | 36 ++-- src/package/vendor_entry_sigma.mjs | 7 + tests/excel-style-roundtrip.test.js | 224 ++++++++++++++++++++++++ tests/graph-model.test.js | 256 +++++++++++++++++++++++++--- tests/label-renderers.test.js | 254 +++++++++++++++++++++++++++ tests/shape-textures.test.js | 157 +++++++++++++++++ 13 files changed, 1513 insertions(+), 98 deletions(-) create mode 100644 src/graph/label_renderers.js create mode 100644 src/graph/shape_textures.js create mode 100644 tests/excel-style-roundtrip.test.js create mode 100644 tests/label-renderers.test.js create mode 100644 tests/shape-textures.test.js diff --git a/API.md b/API.md index 45248a3..cc8520b 100644 --- a/API.md +++ b/API.md @@ -196,7 +196,7 @@ An edge is an object. `source` and `target` are required and must match node | `id` | string | `"::"` | Explicit edge id. Auto-generated if omitted. | | `label` | string | — | Display text along the edge. | | `description` | string | — | Tooltip text. | -| `type` | string | `"line"` | `line` (straight); also `cubic`, `quadratic`, `polyline`. | +| `type` | string | `"line"` | `line` (straight); also `cubic`, `quadratic`, `polyline`. **Note:** since the Sigma renderer, `polyline` renders as a curve (same as `cubic`/`quadratic`). | | `style` | object | — | Visual styling — see below. | | `D4Data` | object | — | Data attributes that define filters — see §6. | @@ -206,14 +206,14 @@ An edge is an object. `source` and `target` are required and must match node | ---------------- | ------- | ------------- | ---------------------------------------------------- | | `stroke` | hex | `"#403C5390"` | Line colour (last 2 hex digits = alpha). | | `lineWidth` | number | `0.75` | Line thickness (px). | -| `lineDash` | number | `0` | Dash length; `0` = solid, e.g. `10` = dashed. | +| `lineDash` | number | `0` | Dash length. **Note:** kept in the data model and round-trips through export, but the Sigma renderer draws all edges solid (dashes are not rendered in v1). | | `startArrow` | boolean | `false` | Arrowhead at the source end. | -| `startArrowType` | string | `"triangle"` | `triangle`/`circle`/`diamond`/`vee`/`rect`/`simple`. | +| `startArrowType` | string | `"triangle"` | `triangle`/`circle`/`diamond`/`vee`/`rect`/`simple`. Since the Sigma renderer all heads draw as triangles; the value is kept and round-trips. | | `startArrowSize` | number | `8` | Source arrowhead size. | | `endArrow` | boolean | `false` | Arrowhead at the target end. | | `endArrowType` | string | `"triangle"` | Same enum as `startArrowType`. | | `endArrowSize` | number | `8` | Target arrowhead size. | -| `halo` | boolean | `false` | Glow behind the edge. | +| `halo` | boolean | `false` | Glow behind the edge. Since the Sigma renderer, per-edge halos are kept in the model (and round-trip) but are not drawn; selection halos still render. | | `haloStroke` | hex | `"#403C53"` | Halo colour. | | `haloLineWidth` | number | `3` | Halo thickness (px). | diff --git a/src/config.js b/src/config.js index 45c99b2..6a35cb1 100644 --- a/src/config.js +++ b/src/config.js @@ -29,6 +29,15 @@ const DEFAULTS = { ENABLED: false, COLOR: "#403C53", WIDTH: 3, } }, + // Element interaction-state spec (former G6 node/edge state config in + // core.js). Single source for the styling UI and the sigma reducers. + STATE: { + ACCENT_COLOR: "#C33D35", // selected/highlight halo + highlight fill + DIM_COLOR: "#E4E3EA", // dim fill + NODE_HALO_WIDTH: 12, // px, halo ring stroke width on nodes + EDGE_HALO_WIDTH: 6, // px, emphasis width budget on selected edges + HALO_OPACITY: 0.4, + }, LAYOUT: "force", LAYOUT_INTERNALS: { "force": {gravity: 10}, diff --git a/src/graph/core.js b/src/graph/core.js index b7ce212..25bb871 100644 --- a/src/graph/core.js +++ b/src/graph/core.js @@ -100,11 +100,9 @@ class GraphCoreManager { nodeReducer: makeNodeReducer(this.cache, elementStates), edgeReducer: makeEdgeReducer(this.cache, elementStates), elementStates, - settings: { - // Initial heuristic; io.preProcessData flips HIDE_LABELS based on - // CFG.MAX_NODES_BEFORE_HIDING_LABELS before this runs. - renderLabels: !this.cache.CFG.HIDE_LABELS, - }, + // Label visibility (CFG.HIDE_LABELS) is synced live by the adapter + // on construction and on every render(). + settings: {}, }); const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index 237b2d4..abe055b 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -1,5 +1,5 @@ /** - * Node-safe graph model for the Sigma.js renderer (MIGRATION.md Phase 1). + * Node-safe graph model for the Sigma.js renderer (MIGRATION.md Phases 1-2). * * Builds the graphology instance from the app cache and provides the * G6-style → sigma attribute mapping plus the node/edge reducer factories. @@ -7,48 +7,137 @@ * imports this module under node. */ import { Graph } from "../lib/graphology.bundle.mjs"; +import { DEFAULTS } from "../config.js"; +import { shapeTextureURI, isTextureOnlyShape, HALO_EXTRA_PX } from "./shape_textures.js"; -// Former G6 state-spec colors (selected/highlight halo + fill, dim fill) -// from the old core.js Graph config. Phase 2 does full visual parity. -const STATE_ACCENT_COLOR = "#C33D35"; -const STATE_DIM_COLOR = "#E4E3EA"; +// Element interaction-state colors (former G6 state spec) live in config so +// the styling UI and the reducers share one source. +const STATE_ACCENT_COLOR = DEFAULTS.STATE.ACCENT_COLOR; +const STATE_DIM_COLOR = DEFAULTS.STATE.DIM_COLOR; + +// Texture nodes paint their fill inside the SVG; the sigma `color` attribute +// must be fully transparent or the image quad shows a colored square. +const TRANSPARENT = "#00000000"; + +/** + * The model boundary owns the y-axis convention flip: the app model (G6 + * heritage: nodeRef styles, persisted positions, Excel/JSON files) is + * y-down, sigma/graphology is y-up. Negate exactly once when crossing in + * either direction so legacy files keep their orientation and save→load + * round-trips are stable. + */ +function flipY(y) { + return -y; +} /** - * Map a G6-shaped node style object to sigma node attributes. - * Crude Phase-1 mapping; Phase 2 does full parity (shapes, borders, badges). - * Only emits keys that are actually present on the style. + * Map a G6 node style + type to sigma node attributes. + * Only emits keys that are actually present on the style; shape-program + * attributes (`type`/`shape`/`image`/...) are only emitted when `type` is + * given. Shapes without a native sigma program — and any shape with a + * border, which the native circle/square programs cannot draw — render + * through the SVG texture program ("shape"). * - * @param {object} style G6 node style ({x, y, size, fill, label, labelText, visibility, ...}) - * @returns {object} partial sigma attrs ({x?, y?, size?, color?, label?, hidden?}) + * @param {object} style G6 node style ({x, y, size, fill, stroke, lineWidth, label*, visibility, ...}) + * @param {string} [type] G6 node type (circle|diamond|hexagon|rect|triangle|star) + * @returns {object} partial sigma attrs */ -function nodeAttributesFromStyle(style = {}) { +function nodeAttributesFromStyle(style = {}, type = undefined) { const attrs = {}; if (Number.isFinite(style.x)) attrs.x = style.x; - if (Number.isFinite(style.y)) attrs.y = style.y; + if (Number.isFinite(style.y)) attrs.y = flipY(style.y); if (style.size !== undefined) { - // G6 size may be a number or [w, h] — take the first dimension. - attrs.size = Array.isArray(style.size) ? style.size[0] : style.size; + // G6 size is a diameter (or [w, h]); sigma size is a radius. + attrs.size = (Array.isArray(style.size) ? style.size[0] : style.size) / 2; } if (style.fill !== undefined) attrs.color = style.fill; + if (style.stroke !== undefined) attrs.borderColor = style.stroke; + if (style.lineWidth !== undefined) attrs.borderSize = style.lineWidth; + if (style.label === false) { attrs.label = null; } else if (style.label && style.labelText !== undefined) { attrs.label = style.labelText == null ? null : String(style.labelText); } + Object.assign(attrs, labelStyleAttributes(style)); if (style.visibility !== undefined) { attrs.hidden = style.visibility === "hidden"; } + + if (type !== undefined) Object.assign(attrs, nodeProgramAttributes(style, type)); + return attrs; +} + +/** + * Shape-program attributes for a node: which sigma program draws it, plus + * the texture data-URI when the SVG shape program is needed. + */ +function nodeProgramAttributes(style = {}, type) { + const fill = style.fill ?? DEFAULTS.NODE.FILL_COLOR; + const stroke = style.stroke ?? null; + const lineWidth = style.lineWidth ?? 0; + const hasBorder = Boolean(stroke) && lineWidth > 0; + const attrs = { shape: type }; + + if (isTextureOnlyShape(type) || hasBorder) { + const size = Array.isArray(style.size) ? style.size[0] : style.size; + attrs.type = "shape"; + attrs.fillColor = fill; + attrs.color = TRANSPARENT; + attrs.image = shapeTextureURI({ + shape: type, + fill, + stroke: hasBorder ? stroke : null, + lineWidth: hasBorder ? lineWidth : 0, + size: (size ?? DEFAULTS.NODE.SIZE) / 2, + }); + } else { + attrs.type = type === "rect" ? "square" : "circle"; + } + return attrs; +} + +/** + * Shared label styling attrs (read by the custom label renderers). + * G6 names → renderer attrs; only present keys are emitted. + */ +function labelStyleAttributes(style) { + const attrs = {}; + if (style.labelFontSize !== undefined) attrs.labelSize = style.labelFontSize; + if (style.labelFill !== undefined) attrs.labelColor = style.labelFill; + if (style.labelBackground !== undefined) attrs.labelBackground = style.labelBackground; + if (style.labelBackgroundFill !== undefined) attrs.labelBackgroundColor = style.labelBackgroundFill; + if (style.labelPlacement !== undefined) attrs.labelPlacement = style.labelPlacement; + if (style.labelOffsetX !== undefined) attrs.labelOffsetX = style.labelOffsetX; + if (style.labelOffsetY !== undefined) attrs.labelOffsetY = style.labelOffsetY; + if (style.labelPadding !== undefined) attrs.labelPadding = style.labelPadding; + if (style.labelAutoRotate !== undefined) attrs.labelAutoRotate = style.labelAutoRotate; return attrs; } /** - * Map a G6-shaped edge style object to sigma edge attributes. - * All edges render as straight lines in Phase 1 (curves/arrows are Phase 2). + * Sigma edge program key for a G6 edge type + arrow flags. + * Degradations (documented in API.md §5): `polyline` renders as a curve, + * `lineDash` is dropped, arrow head shapes all render as triangles. + */ +function sigmaEdgeType(type, style = {}) { + const curved = type === "cubic" || type === "quadratic" || type === "polyline"; + const start = Boolean(style.startArrow); + const end = Boolean(style.endArrow); + if (start && end) return curved ? "curvedDoubleArrow" : "doubleArrow"; + if (end) return curved ? "curvedArrow" : "arrow"; + if (start) return curved ? "curvedSourceArrow" : "sourceArrow"; + return curved ? "curve" : "line"; +} + +/** + * Map a G6 edge style + type to sigma edge attributes. * - * @param {object} style G6 edge style ({lineWidth, stroke, label, labelText, visibility, ...}) - * @returns {object} partial sigma attrs ({size?, color?, label?, hidden?}) + * @param {object} style G6 edge style ({lineWidth, stroke, *Arrow*, label*, visibility, ...}) + * @param {string} [type] G6 edge type (line|cubic|quadratic|polyline) + * @returns {object} partial sigma attrs */ -function edgeAttributesFromStyle(style = {}) { +function edgeAttributesFromStyle(style = {}, type = undefined) { const attrs = {}; if (style.lineWidth !== undefined) attrs.size = style.lineWidth; if (style.stroke !== undefined) attrs.color = style.stroke; @@ -57,9 +146,11 @@ function edgeAttributesFromStyle(style = {}) { } else if (style.label && style.labelText !== undefined) { attrs.label = style.labelText == null ? null : String(style.labelText); } + Object.assign(attrs, labelStyleAttributes(style)); if (style.visibility !== undefined) { attrs.hidden = style.visibility === "hidden"; } + if (type !== undefined) attrs.type = sigmaEdgeType(type, style); return attrs; } @@ -76,8 +167,9 @@ function placeholderPosition(index, total) { /** * Build a graphology Graph from cache.nodeRef/edgeRef. Positions come from - * the selected layout's persisted positions Map when present, else from the - * node style, else a deterministic placeholder spread. + * the selected layout's persisted positions Map when present (app-model + * y-down → flipped), else from the node style (flipped by the mapper), else + * a deterministic placeholder spread (already in sigma space). * * @param {object} cache app cache (needs nodeRef, edgeRef, data.layouts/selectedLayout) * @returns {Graph} @@ -89,14 +181,13 @@ function buildGraphologyGraph(cache) { let index = 0; for (const node of cache.nodeRef.values()) { - const mapped = nodeAttributesFromStyle(node.style ?? {}); + const mapped = nodeAttributesFromStyle(node.style ?? {}, node.type); const persisted = positions?.get(node.id)?.style; const fallback = placeholderPosition(index, total); graph.addNode(node.id, { + ...mapped, x: Number.isFinite(persisted?.x) ? persisted.x : (mapped.x ?? fallback.x), - y: Number.isFinite(persisted?.y) ? persisted.y : (mapped.y ?? fallback.y), - size: mapped.size, - color: mapped.color, + y: Number.isFinite(persisted?.y) ? flipY(persisted.y) : (mapped.y ?? fallback.y), label: mapped.label ?? null, hidden: mapped.hidden ?? false, zIndex: 0, @@ -109,10 +200,9 @@ function buildGraphologyGraph(cache) { cache.ui?.debug?.(`Skipping edge ${edge.id}: missing endpoint node`); continue; } - const mapped = edgeAttributesFromStyle(edge.style ?? {}); + const mapped = edgeAttributesFromStyle(edge.style ?? {}, edge.type); graph.addEdgeWithKey(edge.id, edge.source, edge.target, { - size: mapped.size, - color: mapped.color, + ...mapped, label: mapped.label ?? null, hidden: mapped.hidden ?? false, zIndex: 0, @@ -122,6 +212,35 @@ function buildGraphologyGraph(cache) { return graph; } +/** + * State treatment for a node, per the old G6 state spec: + * selected → own fill, accent halo ring, raised zIndex + * highlight → accent fill, accent halo ring + * dim → dim fill + * Halo states render through the texture program (the only sigma mechanism + * that draws a ring around non-circular shapes); the node grows by + * HALO_EXTRA_PX so the halo bleeds outward like G6's did. + */ +function applyNodeState(data, state) { + const res = { ...data }; + const shape = data.shape ?? "circle"; + const baseSize = data.size ?? DEFAULTS.NODE.SIZE / 2; + const fill = data.fillColor ?? data.color; + const stroke = data.borderColor ?? null; + const lineWidth = data.borderSize ?? 0; + + if (state === "dim" && data.type !== "shape") { + res.color = STATE_DIM_COLOR; + return res; + } + + res.type = "shape"; + res.color = TRANSPARENT; + res.image = shapeTextureURI({ shape, fill, stroke, lineWidth, size: baseSize, state }); + if (state !== "dim") res.size = baseSize + HALO_EXTRA_PX; + return res; +} + /** * Sigma nodeReducer factory. Reads the graphology `hidden` attribute plus the * app-level element-states Map (selected/highlight/dim, formerly G6 states). @@ -134,22 +253,20 @@ function makeNodeReducer(cache, elementStates) { if (data.hidden) return data; const states = elementStates.get(node); if (!states || states.length === 0) return data; - const res = { ...data }; if (states.includes("selected")) { - res.color = STATE_ACCENT_COLOR; - res.zIndex = 1; - } else if (states.includes("highlight")) { - res.color = STATE_ACCENT_COLOR; - } else if (states.includes("dim")) { - res.color = STATE_DIM_COLOR; + return { ...applyNodeState(data, "selected"), zIndex: 1 }; } - return res; + if (states.includes("highlight")) return applyNodeState(data, "highlight"); + if (states.includes("dim")) return applyNodeState(data, "dim"); + return data; }; } /** * Sigma edgeReducer factory. An edge is hidden when its own `hidden` attr is - * set OR either endpoint is hidden/filtered. + * set OR either endpoint is hidden/filtered. States: selected = accent + + * widened (the halo budget — sigma edges have no underdraw), highlight = + * accent, dim = de-emphasis color. * * @param {object} cache needs edgeRef and graphData (the live graphology graph) * @param {Map} elementStates @@ -172,6 +289,7 @@ function makeEdgeReducer(cache, elementStates) { const res = { ...data }; if (states.includes("selected")) { res.color = STATE_ACCENT_COLOR; + res.size = (data.size ?? 1) + DEFAULTS.STATE.EDGE_HALO_WIDTH / 2; res.zIndex = 1; } else if (states.includes("highlight")) { res.color = STATE_ACCENT_COLOR; @@ -186,6 +304,8 @@ export { buildGraphologyGraph, nodeAttributesFromStyle, edgeAttributesFromStyle, + sigmaEdgeType, + flipY, makeNodeReducer, makeEdgeReducer, STATE_ACCENT_COLOR, diff --git a/src/graph/label_renderers.js b/src/graph/label_renderers.js new file mode 100644 index 0000000..b8bf1a0 --- /dev/null +++ b/src/graph/label_renderers.js @@ -0,0 +1,163 @@ +/** + * Canvas label renderers for the sigma renderer (MIGRATION.md Phase 2). + * + * Replace sigma's built-in disc/straight label drawers to honour the + * per-element label attrs emitted by graph_model.js (labelSize, labelColor, + * labelBackground(Color), labelPlacement, labelOffsetX/Y, labelPadding, + * labelAutoRotate). Pure functions of (context, data, settings) — no DOM or + * sigma imports, so vitest covers them under node. + */ + +const BACKGROUND_RADIUS = 4; +const ANCHOR_GAP = 2; // px between node/edge geometry and the label box +// Last-resort font size: a non-finite size would silently corrupt the canvas +// font string ("normal undefinedpx Arial") and draw at whatever was set last. +const FALLBACK_LABEL_SIZE = 14; + +/** @returns {number} a finite label size, falling back hard */ +function finiteSize(perElement, fromSettings) { + const size = perElement ?? fromSettings; + return Number.isFinite(size) ? size : FALLBACK_LABEL_SIZE; +} + +// Unit direction per placement token; combined for corner placements +// ("left-top", "top-right", ...). Unknown tokens resolve to center. +const PLACEMENT_VECTORS = { + left: [-1, 0], + right: [1, 0], + top: [0, -1], + bottom: [0, 1], + center: [0, 0], +}; + +/** @returns {[number, number]} combined unit vector for a placement string */ +function placementVector(placement) { + let ux = 0; + let uy = 0; + for (const token of String(placement ?? "bottom").split("-")) { + const [dx, dy] = PLACEMENT_VECTORS[token] ?? [0, 0]; + ux = ux || dx; + uy = uy || dy; + } + return [ux, uy]; +} + +function resolveSettingsColor(settingsColor, data) { + if (settingsColor?.attribute) { + return data[settingsColor.attribute] || settingsColor.color || "#000"; + } + return settingsColor?.color ?? "#000"; +} + +function drawBackground(context, color, x, y, width, height) { + context.fillStyle = color; + context.beginPath(); + if (typeof context.roundRect === "function") { + context.roundRect(x, y, width, height, BACKGROUND_RADIUS); + } else { + context.rect(x, y, width, height); + } + context.fill(); +} + +/** + * Node label drawer (sigma `defaultDrawNodeLabel`). G6 parity: default + * placement is "bottom" (sigma's default drawer is right-anchored only). + * + * @param {CanvasRenderingContext2D} context + * @param {object} data node display data in viewport px (x, y, size, label, label* attrs) + * @param {object} settings sigma settings (labelSize/labelFont/labelWeight/labelColor) + */ +function drawNodeLabel(context, data, settings) { + if (!data.label) return; + + const size = finiteSize(data.labelSize, settings.labelSize); + const font = settings.labelFont; + const weight = settings.labelWeight; + const color = data.labelColor ?? resolveSettingsColor(settings.labelColor, data); + const padding = data.labelPadding ?? 2; + + context.font = `${weight} ${size}px ${font}`; + const width = context.measureText(data.label).width; + const boxWidth = width + 2 * padding; + const boxHeight = size + 2 * padding; + + const [ux, uy] = placementVector(data.labelPlacement); + const gap = ANCHOR_GAP; + const boxCenterX = + data.x + ux * (data.size + gap + boxWidth / 2) + (data.labelOffsetX ?? 0); + const boxCenterY = + data.y + uy * (data.size + gap + boxHeight / 2) + (data.labelOffsetY ?? 0); + + if (data.labelBackground && data.labelBackgroundColor) { + drawBackground( + context, + data.labelBackgroundColor, + boxCenterX - boxWidth / 2, + boxCenterY - boxHeight / 2, + boxWidth, + boxHeight, + ); + } + + context.fillStyle = color; + context.fillText(data.label, boxCenterX - width / 2, boxCenterY + size * 0.35); +} + +/** + * Straight-edge label drawer (sigma `defaultDrawEdgeLabel`). G6 parity: + * `labelPlacement` start/center/end positions along the edge, + * `labelAutoRotate` (default false) aligns the text with the edge. + * + * @param {CanvasRenderingContext2D} context + * @param {object} edgeData edge display data (label, size, label* attrs) + * @param {object} sourceData source node display data in viewport px + * @param {object} targetData target node display data in viewport px + * @param {object} settings sigma settings (edgeLabel*) + */ +function drawEdgeLabel(context, edgeData, sourceData, targetData, settings) { + if (!edgeData.label) return; + + const size = finiteSize(edgeData.labelSize, settings.edgeLabelSize); + const font = settings.edgeLabelFont; + const weight = settings.edgeLabelWeight; + const color = edgeData.labelColor ?? resolveSettingsColor(settings.edgeLabelColor, edgeData); + const padding = edgeData.labelPadding ?? 1; + + context.font = `${weight} ${size}px ${font}`; + const width = context.measureText(edgeData.label).width; + + const t = { start: 0.2, center: 0.5, end: 0.8 }[edgeData.labelPlacement] ?? 0.5; + const x = sourceData.x + (targetData.x - sourceData.x) * t + (edgeData.labelOffsetX ?? 0); + const y = sourceData.y + (targetData.y - sourceData.y) * t + (edgeData.labelOffsetY ?? 0); + + let angle = 0; + if (edgeData.labelAutoRotate) { + angle = Math.atan2(targetData.y - sourceData.y, targetData.x - sourceData.x); + // Keep text upright (never upside down); range (-π/2, π/2] so the two + // vertical-edge boundaries (±π/2 exactly) normalize consistently. + if (angle > Math.PI / 2) angle -= Math.PI; + else if (angle <= -Math.PI / 2) angle += Math.PI; + } + + context.save(); + context.translate(x, y); + context.rotate(angle); + + if (edgeData.labelBackground && edgeData.labelBackgroundColor) { + drawBackground( + context, + edgeData.labelBackgroundColor, + -width / 2 - padding, + -size / 2 - padding, + width + 2 * padding, + size + 2 * padding, + ); + } + + context.fillStyle = color; + context.fillText(edgeData.label, -width / 2, size * 0.35); + context.restore(); +} + +export { drawNodeLabel, drawEdgeLabel, placementVector }; diff --git a/src/graph/shape_textures.js b/src/graph/shape_textures.js new file mode 100644 index 0000000..18b7e5c --- /dev/null +++ b/src/graph/shape_textures.js @@ -0,0 +1,169 @@ +/** + * Node-safe SVG texture generation for non-circular node shapes + * (MIGRATION.md Phase 2, risk #1). + * + * Sigma renders circles natively; every other G6 shape (and any shape that + * needs a border or a state halo) is drawn from a crisp vector texture via + * @sigma/node-image. This module only does pure string work — no DOM, no + * sigma import — so vitest can cover it and graph_model.js may depend on it. + */ +import { DEFAULTS } from "../config.js"; + +// G6 shape vocabulary (config STYLES.NODE_FORM + io.js Shape column). +const SHAPE_NAMES = ["circle", "diamond", "hexagon", "rect", "triangle", "star"]; + +// Shapes that ALWAYS need a texture (no native sigma program). +const TEXTURE_ONLY_SHAPES = new Set(["diamond", "hexagon", "triangle", "star"]); + +// SVG canvas is a 100x100 viewBox; all geometry derives from its center. +const VIEWBOX = 100; +const CENTER = VIEWBOX / 2; +// Explicit raster size on the SVG root: data URIs take @sigma/node-image's +// raster path (it sniffs file extensions, not MIME types), and an SVG +// without width/height has no usable intrinsic size there — the atlas entry +// ends up 0×0 and the node renders invisible. +const RASTER_SIZE = 512; + +// Halo ring stroke is centered on the shape outline, so it extends half its +// width beyond the node bounds. Reducers grow `size` by this many px so the +// shape keeps its on-screen size and the halo bleeds outward (G6 parity). +const HALO_EXTRA_PX = DEFAULTS.STATE.NODE_HALO_WIDTH / 2; + +// Conservative paint-value allowlist: hex/rgb()/hsl()/named colors pass; +// anything that could break out of an SVG attribute (quotes, angle brackets, +// ampersands) or collide in the cache key (pipes) is rejected. fill/stroke +// originate from user-supplied Excel/JSON style data — never trust them. +const SAFE_PAINT_RE = /^[#a-zA-Z0-9(),.%\s-]+$/; +const FALLBACK_FILL = "#999999"; + +/** @returns {string|null} the color when safe to embed in SVG, else fallback */ +function safePaint(color, fallback) { + return typeof color === "string" && SAFE_PAINT_RE.test(color) ? color : fallback; +} + +// Full clear when the cache fills up: style churn (interactive recoloring) +// would otherwise grow it monotonically. Regeneration is cheap string work, +// so a flush beats LRU bookkeeping. +const MAX_TEXTURE_CACHE = 4096; + +const textureCache = new Map(); + +/** @returns {boolean} true when the G6 type has no native sigma program */ +function isTextureOnlyShape(type) { + return TEXTURE_ONLY_SHAPES.has(type); +} + +/** Points of a regular polygon (flat string for SVG `points`). */ +function polygonPoints(sides, radius, rotationRad = -Math.PI / 2) { + const pts = []; + for (let i = 0; i < sides; i++) { + const angle = rotationRad + (2 * Math.PI * i) / sides; + pts.push( + `${(CENTER + radius * Math.cos(angle)).toFixed(2)},${(CENTER + radius * Math.sin(angle)).toFixed(2)}`, + ); + } + return pts.join(" "); +} + +/** 5-point star points (outer radius r, inner radius 0.45 r). */ +function starPoints(radius) { + const pts = []; + for (let i = 0; i < 10; i++) { + const r = i % 2 === 0 ? radius : radius * 0.45; + const angle = -Math.PI / 2 + (Math.PI * i) / 5; + pts.push( + `${(CENTER + r * Math.cos(angle)).toFixed(2)},${(CENTER + r * Math.sin(angle)).toFixed(2)}`, + ); + } + return pts.join(" "); +} + +/** + * SVG element string for a shape outline. `radius` is the circumradius (or + * half-size for rect) in viewBox units; `paint` is an attribute string. + */ +function shapeElement(shape, radius, paint) { + switch (shape) { + case "rect": { + const side = radius * Math.SQRT1_2 * 2; // inscribe square in circumcircle + const off = CENTER - side / 2; + return ``; + } + case "diamond": + return ``; + case "triangle": + return ``; + case "hexagon": + return ``; + case "star": + return ``; + default: // circle + return ``; + } +} + +/** + * Build (and cache) an SVG data-URI for a node shape. + * + * @param {object} opts + * @param {string} opts.shape G6 type (circle|diamond|hexagon|rect|triangle|star) + * @param {string} opts.fill fill color (hex, may carry alpha) + * @param {string|null} [opts.stroke] border color (null/undefined = none) + * @param {number} [opts.lineWidth] border width in node px + * @param {number} [opts.size] node radius in px (sigma size attribute) + * @param {string|null} [opts.state] null | "selected" | "highlight" | "dim" + * @returns {string} data:image/svg+xml URI + */ +function shapeTextureURI({ shape, fill, stroke = null, lineWidth = 0, size = 10, state = null }) { + const safeShape = SHAPE_NAMES.includes(shape) ? shape : "circle"; + const safeSize = Number.isFinite(size) && size > 0 ? size : 10; + const safeFill = safePaint(fill, FALLBACK_FILL); + const safeStroke = stroke == null ? null : safePaint(stroke, null); + const key = `${safeShape}|${safeFill}|${safeStroke}|${lineWidth}|${safeSize}|${state}`; + const cached = textureCache.get(key); + if (cached) return cached; + + const { ACCENT_COLOR, DIM_COLOR, NODE_HALO_WIDTH, HALO_OPACITY } = DEFAULTS.STATE; + const hasHalo = state === "selected" || state === "highlight"; + // Old G6 state spec: highlight = accent fill + halo, no border; + // selected = own fill + accent halo; dim = dim fill, border kept. + const effFill = state === "highlight" ? ACCENT_COLOR : state === "dim" ? DIM_COLOR : safeFill; + const effStroke = state === "highlight" ? null : safeStroke; + const effLineWidth = effStroke ? lineWidth : 0; + + // px → viewBox units. With a halo the drawable px radius grows by + // HALO_EXTRA_PX, and the reducer grows the node size to match. + const unitsPerPx = VIEWBOX / (2 * (safeSize + (hasHalo ? HALO_EXTRA_PX : 0))); + const strokeUnits = effLineWidth * unitsPerPx; + const haloUnits = NODE_HALO_WIDTH * unitsPerPx; + // Keep stroke and halo inside the viewBox: the shape circumradius shrinks + // by half of whatever is painted on/over its outline. + const shapeRadius = + CENTER - (hasHalo ? haloUnits / 2 : 0) - strokeUnits / 2 - 0.5; + + const parts = []; + if (hasHalo) { + parts.push( + shapeElement( + safeShape, + shapeRadius, + `fill="none" stroke="${ACCENT_COLOR}" stroke-width="${haloUnits.toFixed(2)}" stroke-opacity="${HALO_OPACITY}" stroke-linejoin="round"`, + ), + ); + } + const strokeAttrs = effStroke + ? ` stroke="${effStroke}" stroke-width="${strokeUnits.toFixed(2)}" stroke-linejoin="round"` + : ""; + parts.push(shapeElement(safeShape, shapeRadius, `fill="${effFill}"${strokeAttrs}`)); + + const svg = + `` + + parts.join("") + + ""; + const uri = `data:image/svg+xml,${encodeURIComponent(svg)}`; + if (textureCache.size >= MAX_TEXTURE_CACHE) textureCache.clear(); + textureCache.set(key, uri); + return uri; +} + +export { shapeTextureURI, isTextureOnlyShape, HALO_EXTRA_PX, SHAPE_NAMES }; diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 4f711b5..05dac97 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -7,9 +7,86 @@ * behind the G6-shaped facade the rest of the app still calls. Facade methods * are transitional and get slimmed/deleted in Phases 2-6. */ -import { Sigma, exportImage } from "../lib/sigma.bundle.mjs"; +import { + Sigma, + exportImage, + EdgeRectangleProgram, + EdgeArrowProgram, + EdgeDoubleArrowProgram, + createEdgeArrowHeadProgram, + createEdgeCompoundProgram, + NodeSquareProgram, + nodeImage, + edgeCurve, +} from "../lib/sigma.bundle.mjs"; import { circular, forceAtlas2 } from "../lib/graphology.bundle.mjs"; -import { nodeAttributesFromStyle, edgeAttributesFromStyle } from "./graph_model.js"; +import { nodeAttributesFromStyle, edgeAttributesFromStyle, flipY } from "./graph_model.js"; +import { drawNodeLabel, drawEdgeLabel } from "./label_renderers.js"; + +// Rasterization resolution for the SVG shape textures. 512 px keeps shapes +// crisp at the ~4x zoom the UI allows (risk #1 in MIGRATION.md). +const SHAPE_TEXTURE_RESOLUTION = 512; + +/** + * Node/edge program registry (G6 type vocabulary → sigma programs). + * Nodes: circle native, square via @sigma/node-square; every other shape — + * and any bordered/haloed node — uses the SVG texture program ("shape"). + * Edges: straight programs are sigma built-ins; curved ones come from + * @sigma/edge-curve (cubic/quadratic/polyline all map to one curve type). + */ +function buildProgramRegistry() { + const shapeProgram = nodeImage.createNodeImageProgram({ + size: { mode: "force", value: SHAPE_TEXTURE_RESOLUTION }, + objectFit: "contain", + drawingMode: "background", + keepWithinCircle: false, + padding: 0, + }); + const curveOptions = (extremity) => ({ + arrowHead: extremity + ? { ...edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS.arrowHead, extremity } + : null, + drawLabel: drawCurvedEdgeLabelWithSize, + }); + return { + nodeProgramClasses: { + square: NodeSquareProgram, + shape: shapeProgram, + }, + edgeProgramClasses: { + line: EdgeRectangleProgram, + arrow: EdgeArrowProgram, + sourceArrow: createEdgeCompoundProgram([ + EdgeRectangleProgram, + createEdgeArrowHeadProgram({ extremity: "source" }), + ]), + doubleArrow: EdgeDoubleArrowProgram, + curve: edgeCurve.createEdgeCurveProgram(curveOptions(null)), + curvedArrow: edgeCurve.createEdgeCurveProgram(curveOptions("target")), + curvedSourceArrow: edgeCurve.createEdgeCurveProgram(curveOptions("source")), + curvedDoubleArrow: edgeCurve.createEdgeCurveProgram(curveOptions("both")), + }, + }; +} + +// Curved-edge labels reuse @sigma/edge-curve's drawer, proxying the settings +// so per-edge labelSize/labelColor (graph_model attrs) are honoured. +const drawCurvedEdgeLabelBase = edgeCurve.createDrawCurvedEdgeLabel( + edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS, +); +function drawCurvedEdgeLabelWithSize(context, edgeData, sourceData, targetData, settings) { + const effective = + edgeData.labelSize != null || edgeData.labelColor != null + ? { + ...settings, + edgeLabelSize: edgeData.labelSize ?? settings.edgeLabelSize, + edgeLabelColor: edgeData.labelColor + ? { color: edgeData.labelColor } + : settings.edgeLabelColor, + } + : settings; + drawCurvedEdgeLabelBase(context, edgeData, sourceData, targetData, effective); +} const FIT_PADDING_PX = 80; // Clamp fit zoom so a tiny selection (e.g. a single node) doesn't punch the @@ -43,8 +120,38 @@ class SigmaAdapter { zIndex: true, nodeReducer, edgeReducer, + ...buildProgramRegistry(), + // Custom drawers honour the per-element label attrs from graph_model + // (size, color, background, placement, offsets, auto-rotate). + defaultDrawNodeLabel: drawNodeLabel, + defaultDrawEdgeLabel: drawEdgeLabel, + renderEdgeLabels: true, ...settings, }); + this.#syncLabelVisibility(); + } + + /** + * Keep CFG.HIDE_LABELS live (io.preProcessData flips it per + * MAX_NODES_BEFORE_HIDING_LABELS on every load). Sigma's label density + * grid stays the default thinning mechanism; HIDE_LABELS is the explicit + * override on top — but elements the user explicitly labelled (style + * pipeline emits a label attr despite HIDE_LABELS) must stay visible, + * matching the old G6 semantics. + * + * NOTE: this owns renderLabels/renderEdgeLabels — a caller-supplied value + * in constructor `settings` is overwritten here by design (CFG.HIDE_LABELS + * is the single source of truth for label visibility). + */ + #syncLabelVisibility() { + let nodeLabels = true; + let edgeLabels = true; + if (this.cache.CFG?.HIDE_LABELS) { + nodeLabels = this.graph.someNode((_, attrs) => attrs.label != null); + edgeLabels = this.graph.someEdge((_, attrs) => attrs.label != null); + } + this.sigma.setSetting("renderLabels", nodeLabels); + this.sigma.setSetting("renderEdgeLabels", edgeLabels); } // ---------------------------------------------------------------- lifecycle @@ -58,6 +165,7 @@ class SigmaAdapter { if (this.killed) return false; if (this.pendingLayout) await this.layout(); await this.#applyPersistedPositions(); + this.#syncLabelVisibility(); this.sigma.refresh(); @@ -125,7 +233,8 @@ class SigmaAdapter { const x = pos?.style?.x; const y = pos?.style?.y; if (!this.graph.hasNode(id) || !Number.isFinite(x) || !Number.isFinite(y)) continue; - this.graph.mergeNodeAttributes(id, { x, y }); + // Persisted positions are app-model (y-down); graphology is y-up. + this.graph.mergeNodeAttributes(id, { x, y: flipY(y) }); const ref = this.cache.nodeRef.get(id); if (ref) { ref.style.x = x; @@ -157,7 +266,9 @@ class SigmaAdapter { if (item.type !== undefined) ref.type = item.type; if (item.style) Object.assign(ref.style, item.style); } - const attrs = nodeAttributesFromStyle(item.style ?? {}); + // Map from the merged ref where possible: shape/texture attrs depend on + // the full style (fill+stroke+lineWidth+size), not just the delta. + const attrs = nodeAttributesFromStyle(ref?.style ?? item.style ?? {}, ref?.type ?? item.type); if (Object.keys(attrs).length > 0) { this.graph.mergeNodeAttributes(item.id, attrs); } @@ -173,7 +284,8 @@ class SigmaAdapter { if (item.type !== undefined) ref.type = item.type; if (item.style) Object.assign(ref.style, item.style); } - const attrs = edgeAttributesFromStyle(item.style ?? {}); + // Merged ref: the program key depends on type + both arrow flags. + const attrs = edgeAttributesFromStyle(ref?.style ?? item.style ?? {}, ref?.type ?? item.type); if (Object.keys(attrs).length > 0) { this.graph.mergeEdgeAttributes(item.id, attrs); } @@ -196,7 +308,9 @@ class SigmaAdapter { if (!this.graph.hasNode(ref.id)) continue; const attrs = this.graph.getNodeAttributes(ref.id); ref.style.x = attrs.x; - ref.style.y = attrs.y; + // Graphology is y-up; the app model (and everything persisted from it) + // stays y-down — flip on the way out, mirror of the mapper's flip in. + ref.style.y = flipY(attrs.y); ref.style.visibility = attrs.hidden ? "hidden" : "visible"; ref.states = [...(this.elementStates.get(ref.id) ?? [])]; views.push(ref); diff --git a/src/lib/sigma.bundle.mjs b/src/lib/sigma.bundle.mjs index 7e6607c..a8ed9e9 100644 --- a/src/lib/sigma.bundle.mjs +++ b/src/lib/sigma.bundle.mjs @@ -1,8 +1,8 @@ -var ii=Object.create;var ct=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var oi=Object.getOwnPropertyNames;var si=Object.getPrototypeOf,ui=Object.prototype.hasOwnProperty;var ht=(t,r)=>()=>(r||t((r={exports:{}}).exports,r),r.exports),dt=(t,r)=>{for(var n in r)ct(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&ct(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?ct(n,"default",{value:t,enumerable:!0}):n,t));var Xe=ht((Go,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ve;we&&typeof we.ownKeys=="function"?Ve=we.ownKeys:Object.getOwnPropertySymbols?Ve=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ve=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function We(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return We(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return We(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(We(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ve(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=ht((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=pt(r,n,e,i,!0);return gt[t]=a,a}function Ge(t,r,n,e){return n+(r<<8)+(t<<16)}function Me(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;r()=>(r||t((r={exports:{}}).exports,r),r.exports),vt=(t,r)=>{for(var n in r)dt(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&dt(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?dt(n,"default",{value:t,enumerable:!0}):n,t));var qe=ft((Uo,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Xe;we&&typeof we.ownKeys=="function"?Xe=we.ownKeys:Object.getOwnPropertySymbols?Xe=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Xe=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function Ye(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return Ye(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return Ye(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(Ye(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Xe(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=ft((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=bt(r,n,e,i,!0);return pt[t]=a,a}function Me(t,r,n,e){return n+(r<<8)+(t<<16)}function Ue(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;rw){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Ee(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function Rt(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Ee(t,r,n)}var Ei=` +`).concat(n))}return i}function Tr(t,r){return Er("VERTEX",t,r)}function Rr(t,r){return Er("FRAGMENT",t,r)}function wr(t,r){var n=t.createProgram();if(n===null)throw new Error("loadProgram: error while creating the program.");var e,i;for(e=0,i=r.length;ew){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function xt(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Ei=` precision highp float; varying vec4 v_color; @@ -75,7 +75,7 @@ void main() { v_color.a *= bias; } -`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,yt=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Te=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:yt},{name:"a_size",size:1,type:yt},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:yt}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Te,"ANGLE_1",0);x(Te,"ANGLE_2",2*Math.PI/3);x(Te,"ANGLE_3",4*Math.PI/3);var Ci=` +`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,_t=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:_t},{name:"a_size",size:1,type:_t},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:_t}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Ci=` precision mediump float; varying vec4 v_color; @@ -149,7 +149,7 @@ void main() { v_color.a *= bias; } -`,Li=Ai,Cr=WebGLRenderingContext,mr=Cr.UNSIGNED_BYTE,Ue=Cr.FLOAT,Pi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],ce={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function Re(t){var r=L(L({},ce),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Li,FRAGMENT_SHADER_SOURCE:Si,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Pi,ATTRIBUTES:[{name:"a_position",size:2,type:Ue},{name:"a_normal",size:2,type:Ue},{name:"a_radius",size:1,type:Ue},{name:"a_color",size:4,type:mr,normalized:!0},{name:"a_id",size:4,type:mr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:Ue}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var f=l.size||1,m=u.size||1,y=s.x,E=s.y,p=u.x,T=u.y,_=Q(l.color),b=p-y,g=T-E,w=b*b+g*g,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-g*w*f,P=b*w*f);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-k,C[o++]=-P,C[o++]=m,C[o++]=_,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,f=u.u_correctionRatio,m=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,E=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(f,a.correctionRatio),s.uniform1f(m,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(E,r.widenessToThicknessRatio)}}])})(le)}var Fo=Re();var ki=` +`,Li=Ai,Cr=WebGLRenderingContext,mr=Cr.UNSIGNED_BYTE,Be=Cr.FLOAT,Pi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],ce={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function ye(t){var r=L(L({},ce),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Li,FRAGMENT_SHADER_SOURCE:Si,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Pi,ATTRIBUTES:[{name:"a_position",size:2,type:Be},{name:"a_normal",size:2,type:Be},{name:"a_radius",size:1,type:Be},{name:"a_color",size:4,type:mr,normalized:!0},{name:"a_id",size:4,type:mr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:Be}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var f=l.size||1,m=u.size||1,y=s.x,E=s.y,p=u.x,T=u.y,_=Q(l.color),b=p-y,g=T-E,w=b*b+g*g,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-g*w*f,P=b*w*f);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-k,C[o++]=-P,C[o++]=m,C[o++]=_,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,f=u.u_correctionRatio,m=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,E=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(f,a.correctionRatio),s.uniform1f(m,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(E,r.widenessToThicknessRatio)}}])})(le)}var zo=ye();var ki=` precision mediump float; varying vec4 v_color; @@ -243,7 +243,7 @@ void main() { v_color.a *= bias; } -`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function wt(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Io=wt();function Lr(t){return He([wt(t),Re(t)])}var Fi=Lr(),xt=Fi,Ii=` +`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function Ct(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Go=Ct();function Lr(t){return ke([Ct(t),ye(t)])}var Fi=Lr(),Ve=Fi,Ii=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -308,8 +308,8 @@ void main() { v_color.a *= bias; } -`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],Ct=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe(Xe()),Ye=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(qe());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function $e(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Ze(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,$e(te(),o)),he(f,jr(te(),a)),he(f,$e(te(),l/m/2/y,c/m/2/y))):(he(f,$e(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,$e(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Ze(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function Ke(t){"@babel/helpers - typeof";return Ke=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},Ke(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function Qe(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||tt)},e):this.animate({ratio:this.ratio/tt})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||tt)},e):this.animate({ratio:this.ratio*tt})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Ye);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function ke(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function rt(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),et(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Me(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Ge.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=ke(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=ke(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Me(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Ge.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,et(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),et(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Ze(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Ze(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Ye),ln=un;var hn=WebGLRenderingContext,vs=hn.UNSIGNED_BYTE,gs=hn.FLOAT;var ga=` +`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],We=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe(qe()),$e=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(Ze());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function Ke(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Qe(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,Ke(te(),o)),he(f,jr(te(),a)),he(f,Ke(te(),l/m/2/y,c/m/2/y))):(he(f,Ke(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,Ke(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Qe(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function Je(t){"@babel/helpers - typeof";return Je=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},Je(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function et(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||nt)},e):this.animate({ratio:this.ratio/nt})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||nt)},e):this.animate({ratio:this.ratio*nt})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})($e);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function Ne(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function it(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),rt(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Ue(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Me.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=Ne(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=Ne(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Ue(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Me.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,rt(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),rt(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Qe(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Qe(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})($e),ln=un;var hn=WebGLRenderingContext,ms=hn.UNSIGNED_BYTE,ps=hn.FLOAT;var ga=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -390,7 +390,7 @@ void main() { v_color.a *= bias; } -`,ma=ga,dn=WebGLRenderingContext,cn=dn.UNSIGNED_BYTE,oe=dn.FLOAT,pa=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],ya={lengthToThicknessRatio:ce.lengthToThicknessRatio};function fn(t){var r=L(L({},ya),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ma,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:pa,ATTRIBUTES:[{name:"a_positionStart",size:2,type:oe},{name:"a_positionEnd",size:2,type:oe},{name:"a_normal",size:2,type:oe},{name:"a_color",size:4,type:cn,normalized:!0},{name:"a_id",size:4,type:cn,normalized:!0},{name:"a_sourceRadius",size:1,type:oe},{name:"a_targetRadius",size:1,type:oe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:oe},{name:"a_normalCoef",size:1,type:oe},{name:"a_sourceRadiusCoef",size:1,type:oe},{name:"a_targetRadiusCoef",size:1,type:oe}],CONSTANT_DATA:[[0,1,-1,0],[0,-1,1,0],[1,1,0,1],[1,1,0,1],[0,-1,1,0],[1,-1,0,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=s.size||1,g=u.size||1,w=T*T+_*_,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-_*w*c,P=T*w*c);var C=this.array;C[o++]=f,C[o++]=m,C[o++]=y,C[o++]=E,C[o++]=k,C[o++]=P,C[o++]=p,C[o++]=a,C[o++]=b,C[o++]=g}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var ms=fn();function ba(t){return He([fn(t),Re(t),Re(L(L({},t),{},{extremity:"source"}))])}var ps=ba();var vn=WebGLRenderingContext,ys=vn.UNSIGNED_BYTE,bs=vn.FLOAT;var gn=WebGLRenderingContext,_s=gn.UNSIGNED_BYTE,Es=gn.FLOAT;var Cs=fe(qe());function bn(t,r,n){return Ee(t,r,n)}function _a(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o;t.beginPath(),t.moveTo(r.x+c,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+c,r.y-l/2),t.lineTo(r.x+c,r.y-c),t.lineTo(r.x-c,r.y-c),t.lineTo(r.x-c,r.y+c),t.lineTo(r.x+c,r.y+c),t.moveTo(r.x+c,r.y+l/2),t.closePath(),t.fill()}else{var f=r.size+o;t.fillRect(r.x-f,r.y-f,f*2,f*2)}t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,bn(t,r,n)}function Ea(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function Ta(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function _n(t){var r=Ta(t,"string");return typeof r=="symbol"?r:r+""}function mn(t,r){for(var n=0;nto,NodePictogramProgram:()=>ro,createNodeImageProgram:()=>qt});var An=fe(Xe());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);nno,NodePictogramProgram:()=>io,createNodeImageProgram:()=>qt});var An=fe(qe());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);n=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Wa=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function Xa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(ye().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return ye().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function Ya(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(ye().mark(function t(r){var n,e,i,a,o,s,u=arguments;return ye().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,Xa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function qa(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function $a(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ka),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Za({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(ye().mark(function i(a){var o,s;return ye().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,Ya(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},qa(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(it,"NEW_TEXTURE_EVENT","newTexture");var Qa=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,Oe=On.FLOAT,Ja=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),eo=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},Ja),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=Ba(i,Qa),y=new it(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(it.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Va,FRAGMENT_SHADER_SOURCE:Ha({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:eo,ATTRIBUTES:[{name:"a_position",size:2,type:Oe},{name:"a_size",size:1,type:Oe},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:Oe},{name:"a_textureIndex",size:1,type:Oe}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Oe}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>bo,EdgeCurvedDoubleArrowProgram:()=>_o,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>ot,default:()=>yo,indexParallelEdgesIndex:()=>po});function no(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=no(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;K=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Ya=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function qa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return be().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function $a(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,qa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function Za(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Ka(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ja),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Qa({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,$a(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},Za(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(ot,"NEW_TEXTURE_EVENT","newTexture");var eo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,De=On.FLOAT,to=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),ro=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},to),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=ja(i,eo),y=new ot(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(ot.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Xa,FRAGMENT_SHADER_SOURCE:Va({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ro,ATTRIBUTES:[{name:"a_position",size:2,type:De},{name:"a_size",size:1,type:De},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:De},{name:"a_textureIndex",size:1,type:De}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:De}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>Eo,EdgeCurvedDoubleArrowProgram:()=>To,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>ut,default:()=>_o,indexParallelEdgesIndex:()=>bo});function ao(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=ao(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;KDe,downloadAsImage:()=>or,downloadAsJPEG:()=>Lo,downloadAsPNG:()=>Ao,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>So});var Kn=fe(qn()),De={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Eo(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function To(t){var r=Eo(t,"string");return typeof r=="symbol"?r:r+""}function Ro(t,r,n){return(r=To(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},De),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function wo(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function xo(t,r){if(t==null)return{};var n,e,i=wo(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.format,a=xo(e,Co),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function So(t){return nr.apply(this,arguments)}function nr(){return nr=st(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=st(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},De),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Ao(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function Lo(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,sn as MouseCaptor,Na as NodeSquareProgram,un as Sigma,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; +`);return i}var Qt=.25,Vn={arrowHead:null,curvatureAttribute:"curvature",defaultCurvature:Qt},Wn={edgeIndexAttribute:"parallelIndex",edgeMinIndexAttribute:"parallelMinIndex",edgeMaxIndexAttribute:"parallelMaxIndex"};function bo(t,r){var n=Ae(Ae({},Wn),r||{}),e={},i={},a={},o=0;t.forEachNode(function(P){e[P]=++o+""}),t.forEachEdge(function(P,C,D,O){var I=e[D],z=e[O],G=[I,z].join("-");i[P]=G,a[G]=[I,z].sort().join("-")});var s={},u={};t.forEachEdge(function(P){var C=i[P],D=a[C];s[C]=s[C]||[],s[C].push(P),u[D]=u[D]||[],u[D].push(P)});for(var l in s){var c=s[l],f=c.length,m=u[a[l]].length;if(f===1&&m===1){var y=c[0];t.setEdgeAttribute(y,n.edgeIndexAttribute,null),t.setEdgeAttribute(y,n.edgeMaxIndexAttribute,null)}else if(f===1){var E=c[0];t.setEdgeAttribute(E,n.edgeIndexAttribute,1),t.setEdgeAttribute(E,n.edgeMaxIndexAttribute,1)}else if(f===m)for(var p=(f-1)/2,T=-p,_=0;_Fe,downloadAsImage:()=>or,downloadAsJPEG:()=>ko,downloadAsPNG:()=>Po,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>Lo});var Kn=fe(qn()),Fe={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Ro(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function wo(t){var r=Ro(t,"string");return typeof r=="symbol"?r:r+""}function xo(t,r,n){return(r=wo(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},Fe),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function Co(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function So(t,r){if(t==null)return{};var n,e,i=Co(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.format,a=So(e,Ao),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function Lo(t){return nr.apply(this,arguments)}function nr(){return nr=lt(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=lt(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Po(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function ko(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,Ve as EdgeArrowProgram,Ea as EdgeDoubleArrowProgram,We as EdgeRectangleProgram,sn as MouseCaptor,Da as NodeSquareProgram,un as Sigma,ye as createEdgeArrowHeadProgram,ke as createEdgeCompoundProgram,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; diff --git a/src/package/vendor_entry_sigma.mjs b/src/package/vendor_entry_sigma.mjs index 8a424de..3589381 100644 --- a/src/package/vendor_entry_sigma.mjs +++ b/src/package/vendor_entry_sigma.mjs @@ -3,6 +3,13 @@ // from code that must load under node (vitest). Renderer-touching modules // only. Bundled by src/package/vendor_libs.js via esbuild. export {Sigma, Camera, MouseCaptor} from 'sigma'; +export { + EdgeRectangleProgram, + EdgeArrowProgram, + EdgeDoubleArrowProgram, + createEdgeArrowHeadProgram, + createEdgeCompoundProgram, +} from 'sigma/rendering'; export {NodeSquareProgram} from '@sigma/node-square'; export * as nodeImage from '@sigma/node-image'; export * as edgeCurve from '@sigma/edge-curve'; diff --git a/tests/excel-style-roundtrip.test.js b/tests/excel-style-roundtrip.test.js new file mode 100644 index 0000000..b35a088 --- /dev/null +++ b/tests/excel-style-roundtrip.test.js @@ -0,0 +1,224 @@ +import { describe, it, expect } from "vitest"; +import { DEFAULTS, CFG } from "../src/config.js"; +import { EXCEL_NODE_PROPERTIES, EXCEL_EDGE_PROPERTIES } from "../src/managers/io.js"; +import { StaticUtilities } from "../src/utilities/static.js"; +import { GraphStyleManager } from "../src/graph/style.js"; +import { nodeAttributesFromStyle, edgeAttributesFromStyle } from "../src/graph/graph_model.js"; + +// ========================================================================== +// Excel style round-trip (MIGRATION.md risk #4): a node/edge styled through +// the style pipeline must export to the Excel column set and re-import to an +// identical nodeRef style AND identical sigma attributes via the graph_model +// mapping. Uses the REAL GraphStyleManager and io.js column definitions. +// ========================================================================== + +const styleManager = new GraphStyleManager({ cache: null }); +styleManager.cache = { DEFAULTS, CFG }; + +/** Export: run every column getter against the styled element. */ +function exportToRow(element, propertyMap) { + const row = {}; + for (const { column, get } of propertyMap) { + const value = get(element); + if (value !== undefined && value !== null) row[column] = value; + } + return row; +} + +/** Import: mirrors addNodeOrEdgeStyle (validate → coerce → apply). */ +function importFromRow(element, row, propertyMap) { + element.style = {}; + for (const { column, type, required, apply } of propertyMap) { + if (required || !type || !apply) continue; + const rawValue = row[column]; + if (rawValue === null || rawValue === undefined) continue; + if (rawValue.toString().trim() === "") continue; + + let localType = type; + let listValues = null; + if (localType.startsWith("oneOf:")) { + listValues = localType.split(":")[1].split("|"); + localType = "list"; + } + + let validated = false; + switch (localType) { + case "str": validated = true; break; + case "num": validated = StaticUtilities.isNumber(rawValue); break; + case "bool": validated = StaticUtilities.isBoolean(rawValue); break; + case "rgba": validated = StaticUtilities.isHexColor(rawValue); break; + case "list": validated = StaticUtilities.isInList(rawValue, listValues); break; + } + if (!validated) continue; + + let coerced = rawValue; + if (localType === "num") coerced = parseFloat(rawValue); + else if (localType === "bool") { + coerced = + typeof rawValue === "string" ? rawValue.trim().toLowerCase() === "true" : !!rawValue; + } + apply(element, coerced); + } +} + +function importNode(row) { + const node = { id: row["ID"] ?? "n1" }; + importFromRow(node, row, EXCEL_NODE_PROPERTIES); + const processed = styleManager.getNodeStyleOrDefaults(node); + // getNodeStyleOrDefaults omits x/y: at runtime coordinates flow through the + // layout positions Map and are synced back onto nodeRef.style by + // SigmaAdapter.getNodeData before any export. Mirror that here. + const style = { ...processed.style }; + if (node.style.x !== undefined) style.x = node.style.x; + if (node.style.y !== undefined) style.y = node.style.y; + return { ...node, type: processed.type, style }; +} + +function importEdge(row) { + const edge = { + id: `${row["Source ID"] ?? "A"}::${row["Target ID"] ?? "B"}`, + source: row["Source ID"] ?? "A", + target: row["Target ID"] ?? "B", + }; + importFromRow(edge, row, EXCEL_EDGE_PROPERTIES); + const processed = styleManager.getEdgeStyleOrDefaults(edge); + return { ...edge, type: processed.type, style: processed.style }; +} + +describe("Excel style round-trip — nodes", () => { + const FULLY_STYLED_ROW = { + "ID": "n1", + "Label": "Full Node", + "Description": "Round-trip test", + "Shape": "star", + "Size": "35", + "Fill Color": "#ABCDEF", + "Border Size": "2", + "Border Color": "#123456", + "Label Font Size": "16", + "Label Placement": "right", + "Label Color": "#654321", + "Label Background Color": "#FEDCBA", + "X Coordinate": "120", + "Y Coordinate": "-45", + }; + + it("styled node → export → re-import yields an identical type and style", () => { + const original = importNode(FULLY_STYLED_ROW); + const row = exportToRow(original, EXCEL_NODE_PROPERTIES); + const reimported = importNode(row); + + expect(reimported.type).toEqual(original.type); + expect(reimported.style).toEqual(original.style); + }); + + it("styled node → export → re-import yields identical sigma attributes", () => { + const original = importNode(FULLY_STYLED_ROW); + const row = exportToRow(original, EXCEL_NODE_PROPERTIES); + const reimported = importNode(row); + + const attrsBefore = nodeAttributesFromStyle(original.style, original.type); + const attrsAfter = nodeAttributesFromStyle(reimported.style, reimported.type); + + expect(attrsAfter).toEqual(attrsBefore); + // Sanity: the styling actually reached the sigma attrs. + expect(attrsBefore.type).toBe("shape"); // star → texture program + expect(attrsBefore.image).toContain(encodeURIComponent("#ABCDEF")); + expect(attrsBefore.borderColor).toBe("#123456"); + expect(attrsBefore.labelSize).toBe(16); + expect(attrsBefore.y).toBe(45); // y-down Excel value → y-up sigma space + }); + + it("every shape survives the round-trip", () => { + for (const shape of ["circle", "diamond", "hexagon", "rect", "triangle", "star"]) { + const original = importNode({ "ID": "n1", "Shape": shape }); + const reimported = importNode(exportToRow(original, EXCEL_NODE_PROPERTIES)); + + expect(reimported.type).toBe(shape); + expect(nodeAttributesFromStyle(reimported.style, reimported.type)).toEqual( + nodeAttributesFromStyle(original.style, original.type), + ); + } + }); + + it("a default (column-less) node round-trips to the default style", () => { + const original = importNode({ "ID": "n1" }); + const reimported = importNode(exportToRow(original, EXCEL_NODE_PROPERTIES)); + + expect(reimported.type).toBe(DEFAULTS.NODE.TYPE); + expect(reimported.style).toEqual(original.style); + }); +}); + +describe("Excel style round-trip — edges", () => { + const FULLY_STYLED_ROW = { + "Source ID": "A", + "Target ID": "B", + "Label": "Full Edge", + "Description": "Round-trip test", + "Type": "cubic", + "Line Width": "2", + "Line Dash": "10", + "Color": "#FF000080", + "Label Font Size": "14", + "Label Placement": "start", + "Label Auto Rotate": "true", + "Label Offset X": "5", + "Label Offset Y": "-3", + "Label Color": "#112233", + "Label Background Color": "#AABBCC", + "Start Arrow": "true", + "Start Arrow Size": "12", + "Start Arrow Type": "vee", + "End Arrow": "true", + "End Arrow Size": "10", + "End Arrow Type": "diamond", + "Halo Color": "#FF0000", + "Halo Width": "5", + }; + + it("styled edge → export → re-import yields an identical type and style", () => { + const original = importEdge(FULLY_STYLED_ROW); + const row = exportToRow(original, EXCEL_EDGE_PROPERTIES); + const reimported = importEdge(row); + + expect(reimported.type).toEqual(original.type); + expect(reimported.style).toEqual(original.style); + }); + + it("styled edge → export → re-import yields identical sigma attributes", () => { + const original = importEdge(FULLY_STYLED_ROW); + const row = exportToRow(original, EXCEL_EDGE_PROPERTIES); + const reimported = importEdge(row); + + const attrsBefore = edgeAttributesFromStyle(original.style, original.type); + const attrsAfter = edgeAttributesFromStyle(reimported.style, reimported.type); + + expect(attrsAfter).toEqual(attrsBefore); + expect(attrsBefore.type).toBe("curvedDoubleArrow"); // cubic + both arrows + expect(attrsBefore.size).toBe(2); + expect(attrsBefore.labelSize).toBe(14); + expect(attrsBefore.labelAutoRotate).toBe(true); + }); + + it("each edge type × arrow combination round-trips to the same program", () => { + for (const type of ["line", "cubic", "quadratic", "polyline"]) { + for (const arrows of [{}, { "End Arrow": "true" }, { "Start Arrow": "true" }]) { + const original = importEdge({ "Source ID": "A", "Target ID": "B", "Type": type, ...arrows }); + const reimported = importEdge(exportToRow(original, EXCEL_EDGE_PROPERTIES)); + + expect(edgeAttributesFromStyle(reimported.style, reimported.type).type).toBe( + edgeAttributesFromStyle(original.style, original.type).type, + ); + } + } + }); + + it("a default edge round-trips to the default style", () => { + const original = importEdge({ "Source ID": "A", "Target ID": "B" }); + const reimported = importEdge(exportToRow(original, EXCEL_EDGE_PROPERTIES)); + + expect(reimported.type).toBe(DEFAULTS.EDGE.TYPE); + expect(reimported.style).toEqual(original.style); + }); +}); diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index c3ec77d..dd66524 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -3,24 +3,40 @@ import { buildGraphologyGraph, nodeAttributesFromStyle, edgeAttributesFromStyle, + sigmaEdgeType, + flipY, makeNodeReducer, makeEdgeReducer, STATE_ACCENT_COLOR, STATE_DIM_COLOR, } from "../src/graph/graph_model.js"; +import { HALO_EXTRA_PX } from "../src/graph/shape_textures.js"; +import { DEFAULTS } from "../src/config.js"; // ========================================================================== -// Graph model (sigma migration Phase 1) — graphology population from the -// app cache and the node/edge reducer factories. Node-safe: must never +// Graph model (sigma migration Phases 1-2) — graphology population from the +// app cache, the G6→sigma attribute mapping (shapes, borders, labels, +// y-axis flip) and the node/edge reducer factories. Node-safe: must never // import the sigma bundle. +// +// Phase-2 conventions under test: +// - app model is y-down (G6 heritage), graphology/sigma y-up → flipY once +// - G6 `size` is a diameter, sigma `size` a radius → halved +// - states render as halo textures (selected/highlight), not flat fills // ========================================================================== -function makeNode(id, style = {}) { - return { id, style: { size: 20, fill: "#403C53", ...style } }; +const ACCENT_URI = encodeURIComponent(STATE_ACCENT_COLOR); // "%23C33D35" + +function makeNode(id, style = {}, type = undefined) { + const node = { id, style: { size: 20, fill: "#403C53", ...style } }; + if (type !== undefined) node.type = type; + return node; } -function makeEdge(id, source, target, style = {}) { - return { id, source, target, style: { lineWidth: 0.75, stroke: "#403C5390", ...style } }; +function makeEdge(id, source, target, style = {}, type = undefined) { + const edge = { id, source, target, style: { lineWidth: 0.75, stroke: "#403C5390", ...style } }; + if (type !== undefined) edge.type = type; + return edge; } function createMockCache({ nodes = [], edges = [], positions = new Map() } = {}) { @@ -50,7 +66,7 @@ describe("buildGraphologyGraph — population", () => { expect(graph.hasEdge("e1")).toBe(true); }); - it("uses persisted layout positions when present", () => { + it("uses persisted layout positions when present, flipping y into sigma space", () => { const positions = new Map([["a", { style: { x: 42, y: -7 } }]]); const cache = createMockCache({ nodes: [makeNode("a", { x: 1, y: 1 })], @@ -60,16 +76,16 @@ describe("buildGraphologyGraph — population", () => { const graph = buildGraphologyGraph(cache); expect(graph.getNodeAttribute("a", "x")).toBe(42); - expect(graph.getNodeAttribute("a", "y")).toBe(-7); + expect(graph.getNodeAttribute("a", "y")).toBe(7); }); - it("falls back to style x/y when no persisted position exists", () => { + it("falls back to style x/y when no persisted position exists (y flipped)", () => { const cache = createMockCache({ nodes: [makeNode("a", { x: 5, y: 6 })] }); const graph = buildGraphologyGraph(cache); expect(graph.getNodeAttribute("a", "x")).toBe(5); - expect(graph.getNodeAttribute("a", "y")).toBe(6); + expect(graph.getNodeAttribute("a", "y")).toBe(-6); }); it("assigns deterministic numeric placeholder coordinates otherwise", () => { @@ -96,7 +112,7 @@ describe("buildGraphologyGraph — population", () => { const graph = buildGraphologyGraph(cache); expect(graph.getNodeAttribute("a", "x")).toBe(3); - expect(graph.getNodeAttribute("a", "y")).toBe(4); + expect(graph.getNodeAttribute("a", "y")).toBe(-4); }); it("maps labels only when style.label is truthy", () => { @@ -126,12 +142,12 @@ describe("buildGraphologyGraph — population", () => { expect(graph.getNodeAttribute("gone", "hidden")).toBe(true); }); - it("takes the first dimension of an array size (G6 [w, h])", () => { + it("maps G6 diameter size to sigma radius (first dimension of [w, h] arrays)", () => { const cache = createMockCache({ nodes: [makeNode("a", { size: [30, 12] })] }); const graph = buildGraphologyGraph(cache); - expect(graph.getNodeAttribute("a", "size")).toBe(30); + expect(graph.getNodeAttribute("a", "size")).toBe(15); }); it("supports parallel (multi) edges and self loops with their own ids", () => { @@ -183,6 +199,74 @@ describe("buildGraphologyGraph — population", () => { expect(graph.getEdgeAttribute("e1", "size")).toBe(2); expect(graph.getEdgeAttribute("e1", "color")).toBe("#112233"); }); + + it("assigns node shape programs and textures from the G6 type", () => { + const cache = createMockCache({ + nodes: [ + makeNode("c", {}, "circle"), + makeNode("r", {}, "rect"), + makeNode("h", {}, "hexagon"), + ], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("c", "type")).toBe("circle"); + expect(graph.getNodeAttribute("r", "type")).toBe("square"); + expect(graph.getNodeAttribute("h", "type")).toBe("shape"); + expect(graph.getNodeAttribute("h", "image")).toMatch(/^data:image\/svg\+xml,/); + expect(graph.getNodeAttribute("h", "shape")).toBe("hexagon"); + }); + + it("assigns edge programs from the G6 type", () => { + const cache = createMockCache({ + nodes: [makeNode("a"), makeNode("b")], + edges: [ + makeEdge("straight", "a", "b", {}, "line"), + makeEdge("curved", "a", "b", {}, "cubic"), + makeEdge("arrowed", "a", "b", { endArrow: true }, "line"), + ], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getEdgeAttribute("straight", "type")).toBe("line"); + expect(graph.getEdgeAttribute("curved", "type")).toBe("curve"); + expect(graph.getEdgeAttribute("arrowed", "type")).toBe("arrow"); + }); +}); + +describe("y-axis orientation (Phase 2 decision #5)", () => { + it("flipY is its own inverse (single boundary flip)", () => { + expect(flipY(20)).toBe(-20); + expect(flipY(flipY(20))).toBe(20); + expect(flipY(0)).toBe(-0); + }); + + it("a G6-era persisted position round-trips to the same on-screen orientation", () => { + // Legacy file: node persisted below-right of origin in G6 space (y-down). + const legacyPersisted = { x: 100, y: 50 }; + const positions = new Map([["a", { style: { ...legacyPersisted } }]]); + const cache = createMockCache({ nodes: [makeNode("a")], positions }); + + // Load: on screen the node must sit BELOW the origin → sigma y negative. + const graph = buildGraphologyGraph(cache); + const sigmaY = graph.getNodeAttribute("a", "y"); + expect(sigmaY).toBe(-50); + + // Save: the adapter reads positions back through flipY into the app + // model (SigmaAdapter.getNodeData), which is what persistNodePositions + // and the JSON/Excel exports serialize. + const persistedAgain = { x: graph.getNodeAttribute("a", "x"), y: flipY(sigmaY) }; + expect(persistedAgain).toEqual(legacyPersisted); + + // Reload of the re-exported file lands on the same screen position. + const cache2 = createMockCache({ + nodes: [makeNode("a")], + positions: new Map([["a", { style: persistedAgain }]]), + }); + expect(buildGraphologyGraph(cache2).getNodeAttribute("a", "y")).toBe(sigmaY); + }); }); describe("attribute mapping helpers", () => { @@ -192,12 +276,48 @@ describe("attribute mapping helpers", () => { expect(nodeAttributesFromStyle({ visibility: "visible" })).toEqual({ hidden: false }); }); + it("nodeAttributesFromStyle flips y into sigma space, x unchanged", () => { + expect(nodeAttributesFromStyle({ x: 10, y: 20 })).toEqual({ x: 10, y: -20 }); + }); + it("nodeAttributesFromStyle ignores non-finite coordinates", () => { expect(nodeAttributesFromStyle({ x: NaN, y: "5" })).toEqual({}); }); - it("nodeAttributesFromStyle keeps a size of 0 (presence check, not truthiness)", () => { + it("nodeAttributesFromStyle halves G6 diameter sizes (0 stays 0)", () => { expect(nodeAttributesFromStyle({ size: 0 })).toEqual({ size: 0 }); + expect(nodeAttributesFromStyle({ size: 20 })).toEqual({ size: 10 }); + }); + + it("nodeAttributesFromStyle maps border fields", () => { + expect(nodeAttributesFromStyle({ stroke: "#123456", lineWidth: 2 })).toEqual({ + borderColor: "#123456", + borderSize: 2, + }); + }); + + it("nodeAttributesFromStyle maps label styling fields", () => { + const attrs = nodeAttributesFromStyle({ + labelFontSize: 16, + labelFill: "#654321", + labelBackground: true, + labelBackgroundFill: "#FEDCBA", + labelPlacement: "top-right", + labelOffsetX: 5, + labelOffsetY: -3, + labelPadding: 4, + }); + + expect(attrs).toEqual({ + labelSize: 16, + labelColor: "#654321", + labelBackground: true, + labelBackgroundColor: "#FEDCBA", + labelPlacement: "top-right", + labelOffsetX: 5, + labelOffsetY: -3, + labelPadding: 4, + }); }); it("nodeAttributesFromStyle emits no label when label is truthy but labelText is absent", () => { @@ -213,11 +333,58 @@ describe("attribute mapping helpers", () => { expect(edgeAttributesFromStyle({ label: false })).toEqual({ label: null }); expect(edgeAttributesFromStyle({ visibility: "hidden" })).toEqual({ hidden: true }); }); + + it("texture-only shapes get the shape program, a texture and a transparent color", () => { + for (const shape of ["diamond", "hexagon", "triangle", "star"]) { + const attrs = nodeAttributesFromStyle({ fill: "#403C53", size: 20 }, shape); + expect(attrs.type).toBe("shape"); + expect(attrs.shape).toBe(shape); + expect(attrs.fillColor).toBe("#403C53"); + expect(attrs.color).toBe("#00000000"); + expect(attrs.image).toMatch(/^data:image\/svg\+xml,/); + } + }); + + it("plain circle and rect stay on native programs with their fill color", () => { + const circle = nodeAttributesFromStyle({ fill: "#403C53" }, "circle"); + const rect = nodeAttributesFromStyle({ fill: "#403C53" }, "rect"); + + expect(circle.type).toBe("circle"); + expect(circle.image).toBeUndefined(); + expect(circle.color).toBe("#403C53"); + expect(rect.type).toBe("square"); + expect(rect.image).toBeUndefined(); + }); + + it("bordered circle/rect route through the texture program (native programs cannot draw borders)", () => { + const attrs = nodeAttributesFromStyle( + { fill: "#403C53", stroke: "#C33D35", lineWidth: 2, size: 20 }, + "circle", + ); + + expect(attrs.type).toBe("shape"); + expect(attrs.image).toContain(ACCENT_URI); + }); + + it("sigmaEdgeType maps the full type × arrows matrix", () => { + expect(sigmaEdgeType("line")).toBe("line"); + expect(sigmaEdgeType("line", { endArrow: true })).toBe("arrow"); + expect(sigmaEdgeType("line", { startArrow: true })).toBe("sourceArrow"); + expect(sigmaEdgeType("line", { startArrow: true, endArrow: true })).toBe("doubleArrow"); + for (const curved of ["cubic", "quadratic", "polyline"]) { + expect(sigmaEdgeType(curved)).toBe("curve"); + expect(sigmaEdgeType(curved, { endArrow: true })).toBe("curvedArrow"); + expect(sigmaEdgeType(curved, { startArrow: true })).toBe("curvedSourceArrow"); + expect(sigmaEdgeType(curved, { startArrow: true, endArrow: true })).toBe( + "curvedDoubleArrow", + ); + } + }); }); describe("reducers — states and hidden handling", () => { - function reducerFixture() { - const nodes = [makeNode("a"), makeNode("b")]; + function reducerFixture({ nodeType } = {}) { + const nodes = [makeNode("a", {}, nodeType), makeNode("b", {}, nodeType)]; const edges = [makeEdge("e1", "a", "b")]; const cache = createMockCache({ nodes, edges }); cache.graphData = buildGraphologyGraph(cache); @@ -248,45 +415,77 @@ describe("reducers — states and hidden handling", () => { expect(res.color).toBe("#403C53"); }); - it("node: selected gets the accent color and raised zIndex", () => { + it("node: selected gets an accent halo texture, grown size and raised zIndex", () => { const { nodeReducer, elementStates } = reducerFixture(); elementStates.set("a", ["selected"]); - const res = nodeReducer("a", { color: "#403C53", hidden: false, zIndex: 0 }); + const res = nodeReducer("a", { color: "#403C53", size: 10, hidden: false, zIndex: 0 }); - expect(res.color).toBe(STATE_ACCENT_COLOR); + expect(res.type).toBe("shape"); + expect(res.image).toContain(ACCENT_URI); // halo ring in the app accent + expect(res.image).toContain(encodeURIComponent("#403C53")); // own fill kept + expect(res.size).toBe(10 + HALO_EXTRA_PX); expect(res.zIndex).toBe(1); + expect(res.color).toBe("#00000000"); }); - it("node: highlight and dim apply their state colors", () => { + it("node: highlight gets an accent-filled halo texture without zIndex bump", () => { const { nodeReducer, elementStates } = reducerFixture(); - elementStates.set("a", ["highlight"]); - expect(nodeReducer("a", { color: "#403C53", hidden: false }).color).toBe(STATE_ACCENT_COLOR); + const res = nodeReducer("a", { color: "#403C53", size: 10, hidden: false, zIndex: 0 }); + + expect(res.type).toBe("shape"); + expect(res.image).toContain(ACCENT_URI); + expect(res.size).toBe(10 + HALO_EXTRA_PX); + expect(res.zIndex).toBe(0); + }); + + it("node: dim on a native-program node swaps the fill color only", () => { + const { nodeReducer, elementStates } = reducerFixture(); + elementStates.set("a", ["dim"]); + + const res = nodeReducer("a", { color: "#403C53", size: 10, hidden: false }); + + expect(res.color).toBe(STATE_DIM_COLOR); + expect(res.image).toBeUndefined(); + expect(res.size).toBe(10); + }); + + it("node: dim on a texture node swaps the texture to the dim fill, size unchanged", () => { + const { cache, nodeReducer, elementStates } = reducerFixture({ nodeType: "hexagon" }); + const base = { ...cache.graphData.getNodeAttributes("a") }; elementStates.set("a", ["dim"]); - expect(nodeReducer("a", { color: "#403C53", hidden: false }).color).toBe(STATE_DIM_COLOR); + + const res = nodeReducer("a", { ...base }); + + expect(res.type).toBe("shape"); + expect(res.image).not.toBe(base.image); + expect(res.image).toContain(encodeURIComponent(STATE_DIM_COLOR)); + expect(res.size).toBe(base.size); }); it("node: selected takes precedence over dim", () => { const { nodeReducer, elementStates } = reducerFixture(); elementStates.set("a", ["dim", "selected"]); - const res = nodeReducer("a", { color: "#403C53", hidden: false }); + const res = nodeReducer("a", { color: "#403C53", size: 10, hidden: false }); - expect(res.color).toBe(STATE_ACCENT_COLOR); + expect(res.image).toContain(ACCENT_URI); expect(res.zIndex).toBe(1); }); it("node: does not mutate the input data", () => { const { nodeReducer, elementStates } = reducerFixture(); elementStates.set("a", ["selected"]); - const data = { color: "#403C53", hidden: false, zIndex: 0 }; + const data = { color: "#403C53", size: 10, hidden: false, zIndex: 0 }; nodeReducer("a", data); expect(data.color).toBe("#403C53"); + expect(data.size).toBe(10); expect(data.zIndex).toBe(0); + expect(data.image).toBeUndefined(); }); it("edge: hidden when its own hidden attr is set", () => { @@ -313,12 +512,13 @@ describe("reducers — states and hidden handling", () => { expect(edgeReducer("e1", data)).toBe(data); }); - it("edge: selected/highlight/dim state colors", () => { + it("edge: selected widens by the halo budget; highlight/dim recolor", () => { const { edgeReducer, elementStates } = reducerFixture(); elementStates.set("e1", ["selected"]); - const selected = edgeReducer("e1", { color: "#403C5390", hidden: false, zIndex: 0 }); + const selected = edgeReducer("e1", { color: "#403C5390", size: 1, hidden: false, zIndex: 0 }); expect(selected.color).toBe(STATE_ACCENT_COLOR); + expect(selected.size).toBe(1 + DEFAULTS.STATE.EDGE_HALO_WIDTH / 2); expect(selected.zIndex).toBe(1); elementStates.set("e1", ["highlight"]); diff --git a/tests/label-renderers.test.js b/tests/label-renderers.test.js new file mode 100644 index 0000000..ce7a999 --- /dev/null +++ b/tests/label-renderers.test.js @@ -0,0 +1,254 @@ +import { describe, it, expect } from "vitest"; +import { drawNodeLabel, drawEdgeLabel, placementVector } from "../src/graph/label_renderers.js"; + +// ========================================================================== +// Canvas label renderers (Phase 2 label parity). Pure functions of +// (context, data, settings) — exercised with a recording stub context. +// ========================================================================== + +const CHAR_W = 6; + +function stubContext() { + const calls = []; + const record = (name) => (...args) => calls.push([name, ...args]); + return { + calls, + font: "", + fillStyle: "", + measureText: (text) => ({ width: String(text).length * CHAR_W }), + fillText: record("fillText"), + save: record("save"), + restore: record("restore"), + translate: record("translate"), + rotate: record("rotate"), + beginPath: record("beginPath"), + roundRect: record("roundRect"), + rect: record("rect"), + fill: record("fill"), + }; +} + +const SETTINGS = { + labelSize: 12, + labelFont: "Arial", + labelWeight: "normal", + labelColor: { color: "#000" }, + edgeLabelSize: 12, + edgeLabelFont: "Arial", + edgeLabelWeight: "normal", + edgeLabelColor: { color: "#000" }, +}; + +function findCall(ctx, name) { + return ctx.calls.find(([n]) => n === name); +} + +describe("placementVector", () => { + it("maps cardinal and corner placements", () => { + expect(placementVector("bottom")).toEqual([0, 1]); + expect(placementVector("top")).toEqual([0, -1]); + expect(placementVector("left")).toEqual([-1, 0]); + expect(placementVector("right")).toEqual([1, 0]); + expect(placementVector("center")).toEqual([0, 0]); + expect(placementVector("left-top")).toEqual([-1, -1]); + expect(placementVector("top-right")).toEqual([1, -1]); + }); + + it("defaults to bottom and tolerates junk", () => { + expect(placementVector(undefined)).toEqual([0, 1]); + expect(placementVector("diagonal")).toEqual([0, 0]); + }); +}); + +describe("drawNodeLabel", () => { + const NODE = { x: 100, y: 100, size: 10, label: "abc" }; + + it("draws nothing without a label", () => { + const ctx = stubContext(); + drawNodeLabel(ctx, { ...NODE, label: null }, SETTINGS); + expect(ctx.calls).toEqual([]); + }); + + it("uses settings size/color by default and per-node attrs when present", () => { + const ctx = stubContext(); + drawNodeLabel(ctx, NODE, SETTINGS); + expect(ctx.font).toBe("normal 12px Arial"); + + const ctx2 = stubContext(); + drawNodeLabel(ctx2, { ...NODE, labelSize: 20, labelColor: "#C33D35" }, SETTINGS); + expect(ctx2.font).toBe("normal 20px Arial"); + expect(ctx2.fillStyle).toBe("#C33D35"); + }); + + it("places the label below the node by default (G6 default placement)", () => { + const ctx = stubContext(); + drawNodeLabel(ctx, NODE, SETTINGS); + + const [, , x, y] = findCall(ctx, "fillText"); + expect(x).toBeCloseTo(100 - (3 * CHAR_W) / 2); // horizontally centered + expect(y).toBeGreaterThan(100 + NODE.size); // below the disc + }); + + it("honours top and right placements", () => { + const top = stubContext(); + drawNodeLabel(top, { ...NODE, labelPlacement: "top" }, SETTINGS); + expect(findCall(top, "fillText")[3]).toBeLessThan(100 - NODE.size); + + const right = stubContext(); + drawNodeLabel(right, { ...NODE, labelPlacement: "right" }, SETTINGS); + expect(findCall(right, "fillText")[2]).toBeGreaterThan(100 + NODE.size); + }); + + it("applies label offsets", () => { + const base = stubContext(); + drawNodeLabel(base, NODE, SETTINGS); + const offset = stubContext(); + drawNodeLabel(offset, { ...NODE, labelOffsetX: 7, labelOffsetY: -4 }, SETTINGS); + + expect(findCall(offset, "fillText")[2]).toBeCloseTo(findCall(base, "fillText")[2] + 7); + expect(findCall(offset, "fillText")[3]).toBeCloseTo(findCall(base, "fillText")[3] - 4); + }); + + it("draws a background only when enabled with a color", () => { + const noBg = stubContext(); + drawNodeLabel(noBg, NODE, SETTINGS); + expect(findCall(noBg, "fill")).toBeUndefined(); + + const bg = stubContext(); + drawNodeLabel( + bg, + { ...NODE, labelBackground: true, labelBackgroundColor: "#AABBCC" }, + SETTINGS, + ); + expect(findCall(bg, "roundRect")).toBeDefined(); + expect(findCall(bg, "fill")).toBeDefined(); + }); + + it("falls back to rect when the context has no roundRect", () => { + const ctx = stubContext(); + delete ctx.roundRect; + drawNodeLabel( + ctx, + { ...NODE, labelBackground: true, labelBackgroundColor: "#AABBCC" }, + SETTINGS, + ); + expect(findCall(ctx, "rect")).toBeDefined(); + }); +}); + +describe("drawEdgeLabel", () => { + const SOURCE = { x: 0, y: 0, size: 5 }; + const TARGET = { x: 100, y: 0, size: 5 }; + const EDGE = { label: "rel", size: 1 }; + + it("draws nothing without a label", () => { + const ctx = stubContext(); + drawEdgeLabel(ctx, { ...EDGE, label: null }, SOURCE, TARGET, SETTINGS); + expect(ctx.calls).toEqual([]); + }); + + it("centers on the edge midpoint by default", () => { + const ctx = stubContext(); + drawEdgeLabel(ctx, EDGE, SOURCE, TARGET, SETTINGS); + + expect(findCall(ctx, "translate").slice(1)).toEqual([50, 0]); + }); + + it("honours start/end placements along the edge", () => { + const start = stubContext(); + drawEdgeLabel(start, { ...EDGE, labelPlacement: "start" }, SOURCE, TARGET, SETTINGS); + expect(findCall(start, "translate")[1]).toBeLessThan(50); + + const end = stubContext(); + drawEdgeLabel(end, { ...EDGE, labelPlacement: "end" }, SOURCE, TARGET, SETTINGS); + expect(findCall(end, "translate")[1]).toBeGreaterThan(50); + }); + + it("only rotates when labelAutoRotate is set, and keeps text upright", () => { + const flat = stubContext(); + drawEdgeLabel(flat, EDGE, SOURCE, { x: 0, y: 100, size: 5 }, SETTINGS); + expect(findCall(flat, "rotate")[1]).toBe(0); + + const rotated = stubContext(); + drawEdgeLabel( + rotated, + { ...EDGE, labelAutoRotate: true }, + SOURCE, + { x: 0, y: 100, size: 5 }, + SETTINGS, + ); + const angle = findCall(rotated, "rotate")[1]; + expect(angle).not.toBe(0); + expect(Math.abs(angle)).toBeLessThanOrEqual(Math.PI / 2); // upright + }); + + it("normalizes both vertical-edge boundaries (±π/2) to the same angle", () => { + const edge = { label: "v", size: 1, labelAutoRotate: true }; + const at = (sy, ty) => { + const ctx = stubContext(); + drawEdgeLabel(ctx, edge, { x: 0, y: sy, size: 5 }, { x: 0, y: ty, size: 5 }, SETTINGS); + return findCall(ctx, "rotate")[1]; + }; + + const down = at(0, 100); // atan2 = +π/2 + const up = at(100, 0); // atan2 = -π/2 + + expect(down).toBeCloseTo(Math.PI / 2); + expect(up).toBeCloseTo(down); // consistent, not one flipped + }); + + it("returns early on an empty-string label without touching the canvas", () => { + const ctx = stubContext(); + drawEdgeLabel(ctx, { label: "", size: 1 }, { x: 0, y: 0 }, { x: 10, y: 0 }, SETTINGS); + expect(ctx.calls).toEqual([]); + + const nodeCtx = stubContext(); + drawNodeLabel(nodeCtx, { x: 0, y: 0, size: 5, label: "" }, SETTINGS); + expect(nodeCtx.calls).toEqual([]); + }); + + it("falls back to a finite font size when settings provide none", () => { + const ctx = stubContext(); + drawNodeLabel(ctx, { x: 0, y: 0, size: 5, label: "x" }, { ...SETTINGS, labelSize: undefined }); + expect(ctx.font).toBe("normal 14px Arial"); + + const edgeCtx = stubContext(); + drawEdgeLabel( + edgeCtx, + { label: "x", size: 1, labelSize: NaN }, + { x: 0, y: 0 }, + { x: 10, y: 0 }, + { ...SETTINGS, edgeLabelSize: undefined }, + ); + expect(edgeCtx.font).toBe("normal 14px Arial"); + }); + + it("uses per-edge size/color and draws the background pill when set", () => { + const ctx = stubContext(); + drawEdgeLabel( + ctx, + { + ...EDGE, + labelSize: 16, + labelColor: "#112233", + labelBackground: true, + labelBackgroundColor: "#AABBCC", + }, + SOURCE, + TARGET, + SETTINGS, + ); + + expect(ctx.font).toBe("normal 16px Arial"); + expect(ctx.fillStyle).toBe("#112233"); + expect(findCall(ctx, "roundRect")).toBeDefined(); + expect(findCall(ctx, "restore")).toBeDefined(); + }); + + it("applies label offsets to the anchor", () => { + const ctx = stubContext(); + drawEdgeLabel(ctx, { ...EDGE, labelOffsetX: 4, labelOffsetY: -2 }, SOURCE, TARGET, SETTINGS); + + expect(findCall(ctx, "translate").slice(1)).toEqual([54, -2]); + }); +}); diff --git a/tests/shape-textures.test.js b/tests/shape-textures.test.js new file mode 100644 index 0000000..fcfe48f --- /dev/null +++ b/tests/shape-textures.test.js @@ -0,0 +1,157 @@ +import { describe, it, expect } from "vitest"; +import { + shapeTextureURI, + isTextureOnlyShape, + HALO_EXTRA_PX, + SHAPE_NAMES, +} from "../src/graph/shape_textures.js"; +import { DEFAULTS } from "../src/config.js"; + +// ========================================================================== +// SVG texture generation for non-circular node shapes (Phase 2, risk #1). +// Pure string work — node-safe by contract. +// ========================================================================== + +const BASE = { shape: "hexagon", fill: "#403C53", size: 10 }; + +function decode(uri) { + expect(uri).toMatch(/^data:image\/svg\+xml,/); + return decodeURIComponent(uri.slice("data:image/svg+xml,".length)); +} + +describe("shapeTextureURI — shapes and determinism", () => { + it("covers the full G6 shape vocabulary with distinct textures", () => { + const uris = SHAPE_NAMES.map((shape) => shapeTextureURI({ ...BASE, shape })); + + expect(new Set(uris).size).toBe(SHAPE_NAMES.length); + for (const uri of uris) { + const svg = decode(uri); + expect(svg).toContain(" { + expect(decode(shapeTextureURI({ ...BASE, shape: "circle" }))).toContain(" { + const a = shapeTextureURI({ ...BASE }); + const b = shapeTextureURI({ ...BASE }); + + expect(a).toBe(b); // same reference via cache + }); + + it("falls back to a circle for unknown shapes and guards bad sizes", () => { + const unknown = shapeTextureURI({ ...BASE, shape: "pentagon" }); + expect(decode(unknown)).toContain(" { + it("bakes the stroke when a border is requested", () => { + const svg = decode( + shapeTextureURI({ ...BASE, stroke: "#C33D35", lineWidth: 2 }), + ); + + expect(svg).toContain('stroke="#C33D35"'); + }); + + it("omits stroke attributes without a border", () => { + const svg = decode(shapeTextureURI({ ...BASE })); + + expect(svg).not.toContain("stroke="); + }); +}); + +describe("shapeTextureURI — state variants (old G6 state spec)", () => { + const { ACCENT_COLOR, DIM_COLOR } = DEFAULTS.STATE; + + it("selected keeps the fill and adds an accent halo ring", () => { + const svg = decode(shapeTextureURI({ ...BASE, state: "selected" })); + + expect(svg).toContain(`fill="${BASE.fill}"`); + expect(svg).toContain(`stroke="${ACCENT_COLOR}"`); + expect(svg).toContain("stroke-opacity"); + }); + + it("highlight swaps the fill to the accent and drops the border", () => { + const svg = decode( + shapeTextureURI({ ...BASE, stroke: "#8CA6D9", lineWidth: 2, state: "highlight" }), + ); + + expect(svg).toContain(`fill="${ACCENT_COLOR}"`); + expect(svg).not.toContain("#8CA6D9"); + }); + + it("dim swaps the fill to the dim color, keeping the border", () => { + const svg = decode( + shapeTextureURI({ ...BASE, stroke: "#8CA6D9", lineWidth: 2, state: "dim" }), + ); + + expect(svg).toContain(`fill="${DIM_COLOR}"`); + expect(svg).toContain('stroke="#8CA6D9"'); + }); + + it("every state variant differs from the base texture", () => { + const base = shapeTextureURI({ ...BASE }); + for (const state of ["selected", "highlight", "dim"]) { + expect(shapeTextureURI({ ...BASE, state })).not.toBe(base); + } + }); +}); + +describe("shapeTextureURI — paint-value validation (user-supplied fill/stroke)", () => { + it("accepts rgb()/rgba() color functions", () => { + expect(decode(shapeTextureURI({ ...BASE, fill: "rgb(195, 61, 53)" }))) + .toContain('fill="rgb(195, 61, 53)"'); + expect(decode(shapeTextureURI({ ...BASE, fill: "rgba(195,61,53,0.5)" }))) + .toContain('fill="rgba(195,61,53,0.5)"'); + }); + + it("rejects SVG-attribute injection attempts and falls back", () => { + const svg = decode( + shapeTextureURI({ ...BASE, fill: '#ABC" onload="evil()', stroke: 'x"> diff --git a/src/lib/g6.min.js b/src/lib/g6.min.js deleted file mode 100644 index 9ad0874..0000000 --- a/src/lib/g6.min.js +++ /dev/null @@ -1,89 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).G6={})}(this,(function(t){"use strict";var e="undefined"!=typeof document?document.currentScript:null;function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function r(t){var e=function(t,e){if("object"!=n(t)||!t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var i=r.call(t,e);if("object"!=n(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==n(e)?e:e+""}function i(t,e,n){return(e=r(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;et.length)&&(e=t.length);for(var n=0,r=Array(e);n0?(v=2*Math.sqrt(g+1),t[3]=.25*v,t[0]=(h-f)/v,t[1]=(d-l)/v,t[2]=(s-u)/v):a>c&&a>p?(v=2*Math.sqrt(1+a-c-p),t[3]=(h-f)/v,t[0]=.25*v,t[1]=(s+u)/v,t[2]=(d+l)/v):c>p?(v=2*Math.sqrt(1+c-a-p),t[3]=(d-l)/v,t[0]=(s+u)/v,t[1]=.25*v,t[2]=(h+f)/v):(v=2*Math.sqrt(1+p-a-c),t[3]=(s-u)/v,t[0]=(d+l)/v,t[1]=(h+f)/v,t[2]=.25*v),t}function Q(t,e,n,r,i){var o=e[0],a=e[1],s=e[2],l=e[3],u=o+o,c=a+a,h=s+s,d=o*u,f=o*c,p=o*h,g=a*c,v=a*h,m=s*h,y=l*u,b=l*c,x=l*h,E=r[0],w=r[1],k=r[2],M=i[0],S=i[1],N=i[2],O=(1-(g+m))*E,T=(f+x)*E,C=(p-b)*E,A=(f-x)*w,P=(1-(d+m))*w,R=(v+y)*w,D=(p+b)*k,L=(v-y)*k,_=(1-(d+g))*k;return t[0]=O,t[1]=T,t[2]=C,t[3]=0,t[4]=A,t[5]=P,t[6]=R,t[7]=0,t[8]=D,t[9]=L,t[10]=_,t[11]=0,t[12]=n[0]+M-(O*M+A*S+D*N),t[13]=n[1]+S-(T*M+P*S+L*N),t[14]=n[2]+N-(C*M+R*S+_*N),t[15]=1,t}function J(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=n+n,s=r+r,l=i+i,u=n*a,c=r*a,h=r*s,d=i*a,f=i*s,p=i*l,g=o*a,v=o*s,m=o*l;return t[0]=1-h-p,t[1]=c+m,t[2]=d-v,t[3]=0,t[4]=c-m,t[5]=1-u-p,t[6]=f+g,t[7]=0,t[8]=d+v,t[9]=f-g,t[10]=1-u-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function tt(t,e,n,r,i){var o,a=1/Math.tan(e/2);return t[0]=a/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=i&&i!==1/0?(o=1/(r-i),t[10]=(i+r)*o,t[14]=2*i*r*o):(t[10]=-1,t[14]=-2*r),t}Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});var et=tt;function nt(t,e,n,r,i,o,a){var s=1/(e-n),l=1/(r-i),u=1/(o-a);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*u,t[11]=0,t[12]=(e+n)*s,t[13]=(i+r)*l,t[14]=(a+o)*u,t[15]=1,t}var rt=nt;function it(t,e,n,r,i,o,a){var s=1/(e-n),l=1/(r-i),u=1/(o-a);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=u,t[11]=0,t[12]=(e+n)*s,t[13]=(i+r)*l,t[14]=o*u,t[15]=1,t}function ot(t,e,n,r){var i,o,a,s,l,u,c,h,d,f,p=e[0],g=e[1],v=e[2],m=r[0],y=r[1],b=r[2],x=n[0],E=n[1],w=n[2];return Math.abs(p-x)0?(n[0]=2*(s*a+c*r+l*o-u*i)/h,n[1]=2*(l*a+c*i+u*r-s*o)/h,n[2]=2*(u*a+c*o+s*i-l*r)/h):(n[0]=2*(s*a+c*r+l*o-u*i),n[1]=2*(l*a+c*i+u*r-s*o),n[2]=2*(u*a+c*o+s*i-l*r)),q(t,e,n),t},fromRotation:H,fromRotationTranslation:q,fromRotationTranslationScale:function(t,e,n,r){var i=e[0],o=e[1],a=e[2],s=e[3],l=i+i,u=o+o,c=a+a,h=i*l,d=i*u,f=i*c,p=o*u,g=o*c,v=a*c,m=s*l,y=s*u,b=s*c,x=r[0],E=r[1],w=r[2];return t[0]=(1-(p+v))*x,t[1]=(d+b)*x,t[2]=(f-y)*x,t[3]=0,t[4]=(d-b)*E,t[5]=(1-(h+v))*E,t[6]=(g+m)*E,t[7]=0,t[8]=(f+y)*w,t[9]=(g-m)*w,t[10]=(1-(h+p))*w,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},fromRotationTranslationScaleOrigin:Q,fromScaling:W,fromTranslation:V,fromValues:P,fromXRotation:U,fromYRotation:$,fromZRotation:Y,frustum:function(t,e,n,r,i,o,a){var s=1/(n-e),l=1/(i-r),u=1/(o-a);return t[0]=2*o*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*o*l,t[6]=0,t[7]=0,t[8]=(n+e)*s,t[9]=(i+r)*l,t[10]=(a+o)*u,t[11]=-1,t[12]=0,t[13]=0,t[14]=a*o*2*u,t[15]=0,t},getRotation:Z,getScaling:K,getTranslation:X,identity:D,invert:_,lookAt:ot,mul:lt,multiply:j,multiplyScalar:function(t,e,n){return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t[3]=e[3]*n,t[4]=e[4]*n,t[5]=e[5]*n,t[6]=e[6]*n,t[7]=e[7]*n,t[8]=e[8]*n,t[9]=e[9]*n,t[10]=e[10]*n,t[11]=e[11]*n,t[12]=e[12]*n,t[13]=e[13]*n,t[14]=e[14]*n,t[15]=e[15]*n,t},multiplyScalarAndAdd:function(t,e,n,r){return t[0]=e[0]+n[0]*r,t[1]=e[1]+n[1]*r,t[2]=e[2]+n[2]*r,t[3]=e[3]+n[3]*r,t[4]=e[4]+n[4]*r,t[5]=e[5]+n[5]*r,t[6]=e[6]+n[6]*r,t[7]=e[7]+n[7]*r,t[8]=e[8]+n[8]*r,t[9]=e[9]+n[9]*r,t[10]=e[10]+n[10]*r,t[11]=e[11]+n[11]*r,t[12]=e[12]+n[12]*r,t[13]=e[13]+n[13]*r,t[14]=e[14]+n[14]*r,t[15]=e[15]+n[15]*r,t},ortho:rt,orthoNO:nt,orthoZO:it,perspective:et,perspectiveFromFieldOfView:function(t,e,n,r){var i=Math.tan(e.upDegrees*Math.PI/180),o=Math.tan(e.downDegrees*Math.PI/180),a=Math.tan(e.leftDegrees*Math.PI/180),s=Math.tan(e.rightDegrees*Math.PI/180),l=2/(a+s),u=2/(i+o);return t[0]=l,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=-(a-s)*l*.5,t[9]=(i-o)*u*.5,t[10]=r/(n-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*n/(n-r),t[15]=0,t},perspectiveNO:tt,perspectiveZO:function(t,e,n,r,i){var o,a=1/Math.tan(e/2);return t[0]=a/n,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=i&&i!==1/0?(o=1/(r-i),t[10]=i*o,t[14]=i*r*o):(t[10]=-1,t[14]=-r),t},rotate:function(t,e,n,r){var i,o,a,s,l,u,c,h,d,f,p,g,v,m,y,b,x,E,w,k,M,N,O,T,C=r[0],A=r[1],P=r[2],R=Math.hypot(C,A,P);return R0&&(c*=f=1/Math.sqrt(f),h*=f,d*=f);var p=l*d-u*h,g=u*c-s*d,v=s*h-l*c;return(f=p*p+g*g+v*v)>0&&(p*=f=1/Math.sqrt(f),g*=f,v*=f),t[0]=p,t[1]=g,t[2]=v,t[3]=0,t[4]=h*v-d*g,t[5]=d*p-c*v,t[6]=c*g-h*p,t[7]=0,t[8]=c,t[9]=h,t[10]=d,t[11]=0,t[12]=i,t[13]=o,t[14]=a,t[15]=1,t},translate:B,transpose:L});function ht(){var t=new N(3);return N!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function dt(t){var e=new N(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function ft(t){var e=t[0],n=t[1],r=t[2];return Math.hypot(e,n,r)}function pt(t,e,n){var r=new N(3);return r[0]=t,r[1]=e,r[2]=n,r}function gt(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}function vt(t,e,n,r){return t[0]=e,t[1]=n,t[2]=r,t}function mt(t,e,n){return t[0]=e[0]+n[0],t[1]=e[1]+n[1],t[2]=e[2]+n[2],t}function yt(t,e,n){return t[0]=e[0]-n[0],t[1]=e[1]-n[1],t[2]=e[2]-n[2],t}function bt(t,e,n){return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t}function xt(t,e){var n=e[0],r=e[1],i=e[2],o=n*n+r*r+i*i;return o>0&&(o=1/Math.sqrt(o)),t[0]=e[0]*o,t[1]=e[1]*o,t[2]=e[2]*o,t}function Et(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function wt(t,e,n){var r=e[0],i=e[1],o=e[2],a=n[0],s=n[1],l=n[2];return t[0]=i*l-o*s,t[1]=o*a-r*l,t[2]=r*s-i*a,t}function kt(t,e,n,r){var i=e[0],o=e[1],a=e[2];return t[0]=i+r*(n[0]-i),t[1]=o+r*(n[1]-o),t[2]=a+r*(n[2]-a),t}function Mt(t,e,n){var r=e[0],i=e[1],o=e[2],a=n[3]*r+n[7]*i+n[11]*o+n[15];return a=a||1,t[0]=(n[0]*r+n[4]*i+n[8]*o+n[12])/a,t[1]=(n[1]*r+n[5]*i+n[9]*o+n[13])/a,t[2]=(n[2]*r+n[6]*i+n[10]*o+n[14])/a,t}function St(t,e){var n=t[0],r=t[1],i=t[2],o=e[0],a=e[1],s=e[2];return Math.abs(n-o)<=S*Math.max(1,Math.abs(n),Math.abs(o))&&Math.abs(r-a)<=S*Math.max(1,Math.abs(r),Math.abs(a))&&Math.abs(i-s)<=S*Math.max(1,Math.abs(i),Math.abs(s))}var Nt=yt,Ot=function(t,e){var n=e[0]-t[0],r=e[1]-t[1],i=e[2]-t[2];return Math.hypot(n,r,i)},Tt=ft;function Ct(){var t=new N(4);return N!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function At(t,e,n,r){var i=new N(4);return i[0]=t,i[1]=e,i[2]=n,i[3]=r,i}function Pt(t,e,n){var r=e[0],i=e[1],o=e[2],a=e[3];return t[0]=n[0]*r+n[4]*i+n[8]*o+n[12]*a,t[1]=n[1]*r+n[5]*i+n[9]*o+n[13]*a,t[2]=n[2]*r+n[6]*i+n[10]*o+n[14]*a,t[3]=n[3]*r+n[7]*i+n[11]*o+n[15]*a,t}function Rt(){var t=new N(4);return N!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function Dt(t,e,n){n*=.5;var r=Math.sin(n);return t[0]=r*e[0],t[1]=r*e[1],t[2]=r*e[2],t[3]=Math.cos(n),t}function Lt(t,e,n){var r=e[0],i=e[1],o=e[2],a=e[3],s=n[0],l=n[1],u=n[2],c=n[3];return t[0]=r*c+a*s+i*u-o*l,t[1]=i*c+a*l+o*s-r*u,t[2]=o*c+a*u+r*l-i*s,t[3]=a*c-r*s-i*l-o*u,t}function _t(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=n*n+r*r+i*i+o*o,s=a?1/a:0;return t[0]=-n*s,t[1]=-r*s,t[2]=-i*s,t[3]=o*s,t}function It(t,e,n,r){var i=.5*Math.PI/180;e*=i,n*=i,r*=i;var o=Math.sin(e),a=Math.cos(e),s=Math.sin(n),l=Math.cos(n),u=Math.sin(r),c=Math.cos(r);return t[0]=o*l*c-a*s*u,t[1]=a*s*c+o*l*u,t[2]=a*l*u-o*s*c,t[3]=a*l*c+o*s*u,t}ht(),function(){var t=Ct()}();var jt=At,Bt=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},Ft=function(t,e,n,r,i){return t[0]=e,t[1]=n,t[2]=r,t[3]=i,t},zt=Lt,Gt=function(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=n*n+r*r+i*i+o*o;return a>0&&(a=1/Math.sqrt(a)),t[0]=n*a,t[1]=r*a,t[2]=i*a,t[3]=o*a,t};function Vt(){var t=new N(2);return N!=Float32Array&&(t[0]=0,t[1]=0),t}ht(),pt(1,0,0),pt(0,1,0),Rt(),Rt(),O(),function(){var t=Vt()}();var Wt=function(t){return null!==t&&"function"!=typeof t&&isFinite(t.length)},Ht=function(t,e){return void 0===e&&(e=[]),function(t,e){if(!Wt(t))return t;for(var n=[],r=0;r-1}(e,t)}))};function Ut(t){return"function"==typeof t}function $t(t){return null==t}function Yt(t){return Array.isArray(t)}var qt=function(t){var e=typeof t;return null!==t&&"object"===e||"function"===e};function Xt(t,e){if(t)if(Yt(t))for(var n=0,r=t.length;nn?n:t};function ae(t){return"number"==typeof t}function se(t,e,n){return void 0===n&&(n=1e-5),t===e||Math.abs(t-e)r&&(n=o,r=a)}return n}},ue=function(t,e){if(Yt(t)){for(var n,r=1/0,i=0;ii&&(r=n,a(1),++e),n[t]=o}function a(t){e=0,n=Object.create(null),t||(r=Object.create(null))}return a(),{clear:a,has:function(t){return void 0!==n[t]||void 0!==r[t]},get:function(t){var e=n[t];return void 0!==e?e:void 0!==(e=r[t])?(o(t,e),e):void 0},set:function(t,e){void 0!==n[t]?n[t]=e:o(t,e)}}}(n));var a=be.get(t);if(a.has(o))return a.get(o);var s=t.apply(this,r);return a.set(o,s),s}}function Ee(t,e){if(Object.hasOwn)return Object.hasOwn(t,e);if(null==t)throw new TypeError("Cannot convert undefined or null to object");return Object.prototype.hasOwnProperty.call(Object(t),e)}function we(t,e,n,r){for(var i in n=n||0,r=r||5,e)if(Ee(e,i)){var o=e[i];null!==o&&Jt(o)?(Jt(t[i])||(t[i]={}),ne?(r&&(clearTimeout(r),r=null),s=u,a=t.apply(i,o),r||(i=o=null)):r||!1===n.trailing||(r=setTimeout(l,c)),a};return u.cancel=function(){clearTimeout(r),s=0,r=i=o=null},u},De={},Le=function(){},_e=function(t){return t},Ie=function(t,e){return Ie=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},Ie(t,e)};function je(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}Ie(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var Be=function(){return Be=Object.assign||function(t){for(var e,n=1,r=arguments.length;n=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function Ve(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var r,i,o=n.call(t),a=[];try{for(;(void 0===e||e-- >0)&&!(r=o.next()).done;)a.push(r.value)}catch(t){i={error:t}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(i)throw i.error}}return a}function We(t,e,n){if(n||2===arguments.length)for(var r,i=0,o=e.length;i7){t[n].shift();for(var r=t[n],i=n;r.length;)e[n]="A",t.splice(i+=1,0,["C"].concat(r.splice(0,6)));t.splice(n,1)}}var Ye={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0};function qe(t){return Array.isArray(t)&&t.every((function(t){var e=t[0].toLowerCase();return Ye[e]===t.length-1&&"achlmqstvz".includes(e)}))}function Xe(t){return qe(t)&&t.every((function(t){var e=t[0];return e===e.toUpperCase()}))}function Ke(t){return Xe(t)&&t.every((function(t){var e=t[0];return"ACLMQZ".includes(e)}))}function Ze(t){for(var e=t.pathValue[t.segmentStart],n=e.toLowerCase(),r=t.data;r.length>=Ye[n]&&("m"===n&&r.length>2?(t.segments.push([e].concat(r.splice(0,2))),n="l",e="m"===e?"l":"L"):t.segments.push([e].concat(r.splice(0,Ye[n]))),Ye[n]););}function Qe(t){var e=t.index,n=t.pathValue,r=n.charCodeAt(e);return 48===r?(t.param=0,void(t.index+=1)):49===r?(t.param=1,void(t.index+=1)):void(t.err='[path-util]: invalid Arc flag "'.concat(n[e],'", expecting 0 or 1 at index ').concat(e))}function Je(t){return t>=48&&t<=57||43===t||45===t||46===t}function tn(t){return t>=48&&t<=57}function en(t){var e,n=t.max,r=t.pathValue,i=t.index,o=i,a=!1,s=!1,l=!1,u=!1;if(o>=n)t.err="[path-util]: Invalid path value at index ".concat(o,', "pathValue" is missing param');else if(43!==(e=r.charCodeAt(o))&&45!==e||(o+=1,e=r.charCodeAt(o)),tn(e)||46===e){if(46!==e){if(a=48===e,o+=1,e=r.charCodeAt(o),a&&o=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].includes(e));)t.index+=1}function rn(t){var e=t.max,n=t.pathValue,r=t.index,i=n.charCodeAt(r),o=Ye[n[r].toLowerCase()];if(t.segmentStart=r,function(t){switch(32|t){case 109:case 122:case 108:case 104:case 118:case 99:case 115:case 113:case 116:case 97:return!0;default:return!1}}(i))if(t.index+=1,nn(t),t.data=[],o){for(;;){for(var a=o;a>0;a-=1){if(97!=(32|i)||3!==a&&4!==a?en(t):Qe(t),t.err.length)return;t.data.push(t.param),nn(t),t.index=t.max)break;if(!Je(n.charCodeAt(t.index)))break}Ze(t)}else Ze(t);else t.err='[path-util]: Invalid path value "'.concat(n[r],'" is not a path command')}var on=function(t){this.pathValue=t,this.segments=[],this.max=t.length,this.index=0,this.param=0,this.segmentStart=0,this.data=[],this.err=""};function an(t){if(Xe(t))return[].concat(t);var e=function(t){if(qe(t))return[].concat(t);var e=new on(t);for(nn(e);e.index1&&(m*=N=Math.sqrt(N),y*=N);var O=m*m,T=y*y,C=(o===a?-1:1)*Math.sqrt(Math.abs((O*T-O*S*S-T*M*M)/(O*S*S+T*M*M)));f=C*m*S/y+(g+b)/2,p=C*-y*M/m+(v+x)/2,h=Math.asin(((v-p)/y*Math.pow(10,9)|0)/Math.pow(10,9)),d=Math.asin(((x-p)/y*Math.pow(10,9)|0)/Math.pow(10,9)),h=gd&&(h-=2*Math.PI),!a&&d>h&&(d-=2*Math.PI)}var A=d-h;if(Math.abs(A)>E){var P=d,R=b,D=x;d=h+E*(a&&d>h?1:-1),k=cn(b=f+m*Math.cos(d),x=p+y*Math.sin(d),m,y,i,0,a,R,D,[d,P,f,p])}A=d-h;var L=Math.cos(h),_=Math.sin(h),I=Math.cos(d),j=Math.sin(d),B=Math.tan(A/4),F=4/3*m*B,z=4/3*y*B,G=[g,v],V=[g+F*_,v-z*L],W=[b+F*j,x-z*I],H=[b,x];if(V[0]=2*G[0]-V[0],V[1]=2*G[1]-V[1],u)return V.concat(W,H,k);for(var U=[],$=0,Y=(k=V.concat(W,H,k)).length;$=o)a={x:n,y:r};else{var s=hn([t,e],[n,r],i/o);a={x:s[0],y:s[1]}}return{length:o,point:a,min:{x:Math.min(t,n),y:Math.min(e,r)},max:{x:Math.max(t,n),y:Math.max(e,r)}}}function mn(t,e){var n=t.x,r=t.y,i=e.x,o=e.y,a=n*i+r*o,s=Math.sqrt((Math.pow(n,2)+Math.pow(r,2))*(Math.pow(i,2)+Math.pow(o,2)));return(n*o-r*i<0?-1:1)*Math.acos(a/s)}function yn(t,e,n,r,i,o,a,s,l,u){var c=Math.abs,h=Math.sin,d=Math.cos,f=Math.sqrt,p=Math.PI,g=c(n),v=c(r),m=(i%360+360)%360*(p/180);if(t===s&&e===l)return{x:t,y:e};if(0===g||0===v)return vn(t,e,s,l,u).point;var y=(t-s)/2,b=(e-l)/2,x={x:d(m)*y+h(m)*b,y:-h(m)*y+d(m)*b},E=Math.pow(x.x,2)/Math.pow(g,2)+Math.pow(x.y,2)/Math.pow(v,2);E>1&&(g*=f(E),v*=f(E));var w=(Math.pow(g,2)*Math.pow(v,2)-Math.pow(g,2)*Math.pow(x.y,2)-Math.pow(v,2)*Math.pow(x.x,2))/(Math.pow(g,2)*Math.pow(x.y,2)+Math.pow(v,2)*Math.pow(x.x,2)),k=(o!==a?1:-1)*f(w=w<0?0:w),M=k*(g*x.y/v),S=k*(-v*x.x/g),N=d(m)*M-h(m)*S+(t+s)/2,O=h(m)*M+d(m)*S+(e+l)/2,T={x:(x.x-M)/g,y:(x.y-S)/v},C=mn({x:1,y:0},T),A=mn(T,{x:(-x.x-M)/g,y:(-x.y-S)/v});!a&&A>0?A-=2*p:a&&A<0&&(A+=2*p);var P=C+(A%=2*p)*u,R=g*d(P),D=v*h(P);return{x:d(m)*R-h(m)*D+N,y:h(m)*R+d(m)*D+O}}function bn(t,e,n,r,i,o,a,s,l,u,c){var h,d=c.bbox,f=void 0===d||d,p=c.length,g=void 0===p||p,v=c.sampleSize,m=void 0===v?30:v,y="number"==typeof u,b=t,x=e,E=0,w=[b,x,E],k=[b,x],M={x:0,y:0},S=[{x:b,y:x}];y&&u<=0&&(M={x:b,y:x});for(var N=0;N<=m;N+=1){if(b=(h=yn(t,e,n,r,i,o,a,s,l,N/m)).x,x=h.y,f&&S.push({x:b,y:x}),g&&(E+=gn(k,[b,x])),k=[b,x],y&&E>=u&&u>w[2]){var O=(E-u)/(E-w[2]);M={x:k[0]*(1-O)+w[0]*O,y:k[1]*(1-O)+w[1]*O}}w=[b,x,E]}return y&&u>=E&&(M={x:s,y:l}),{length:E,point:M,min:{x:Math.min.apply(null,S.map((function(t){return t.x}))),y:Math.min.apply(null,S.map((function(t){return t.y})))},max:{x:Math.max.apply(null,S.map((function(t){return t.x}))),y:Math.max.apply(null,S.map((function(t){return t.y})))}}}function xn(t,e,n,r,i,o,a,s,l){var u=1-l;return{x:Math.pow(u,3)*t+3*Math.pow(u,2)*l*n+3*u*Math.pow(l,2)*i+Math.pow(l,3)*a,y:Math.pow(u,3)*e+3*Math.pow(u,2)*l*r+3*u*Math.pow(l,2)*o+Math.pow(l,3)*s}}function En(t,e,n,r,i,o,a,s,l,u){var c,h=u.bbox,d=void 0===h||h,f=u.length,p=void 0===f||f,g=u.sampleSize,v=void 0===g?10:g,m="number"==typeof l,y=t,b=e,x=0,E=[y,b,x],w=[y,b],k={x:0,y:0},M=[{x:y,y:b}];m&&l<=0&&(k={x:y,y:b});for(var S=0;S<=v;S+=1){if(y=(c=xn(t,e,n,r,i,o,a,s,S/v)).x,b=c.y,d&&M.push({x:y,y:b}),p&&(x+=gn(w,[y,b])),w=[y,b],m&&x>=l&&l>E[2]){var N=(x-l)/(x-E[2]);k={x:w[0]*(1-N)+E[0]*N,y:w[1]*(1-N)+E[1]*N}}E=[y,b,x]}return m&&l>=x&&(k={x:a,y:s}),{length:x,point:k,min:{x:Math.min.apply(null,M.map((function(t){return t.x}))),y:Math.min.apply(null,M.map((function(t){return t.y})))},max:{x:Math.max.apply(null,M.map((function(t){return t.x}))),y:Math.max.apply(null,M.map((function(t){return t.y})))}}}function wn(t,e,n,r,i,o,a){var s=1-a;return{x:Math.pow(s,2)*t+2*s*a*n+Math.pow(a,2)*i,y:Math.pow(s,2)*e+2*s*a*r+Math.pow(a,2)*o}}function kn(t,e,n,r,i,o,a,s){var l,u=s.bbox,c=void 0===u||u,h=s.length,d=void 0===h||h,f=s.sampleSize,p=void 0===f?10:f,g="number"==typeof a,v=t,m=e,y=0,b=[v,m,y],x=[v,m],E={x:0,y:0},w=[{x:v,y:m}];g&&a<=0&&(E={x:v,y:m});for(var k=0;k<=p;k+=1){if(v=(l=wn(t,e,n,r,i,o,k/p)).x,m=l.y,c&&w.push({x:v,y:m}),d&&(y+=gn(x,[v,m])),x=[v,m],g&&y>=a&&a>b[2]){var M=(y-a)/(y-b[2]);E={x:x[0]*(1-M)+b[0]*M,y:x[1]*(1-M)+b[1]*M}}b=[v,m,y]}return g&&a>=y&&(E={x:i,y:o}),{length:y,point:E,min:{x:Math.min.apply(null,w.map((function(t){return t.x}))),y:Math.min.apply(null,w.map((function(t){return t.y})))},max:{x:Math.max.apply(null,w.map((function(t){return t.x}))),y:Math.max.apply(null,w.map((function(t){return t.y})))}}}function Mn(t,e,n){for(var r,i,o,a,s,l,u,c,h,d=ln(t),f="number"==typeof e,p=[],g=0,v=0,m=0,y=0,b=[],x=[],E=0,w={x:0,y:0},k=w,M=w,S=w,N=0,O=0,T=d.length;O=e&&(S=M),x.push(k),b.push(w),N+=E,g=(l="Z"!==c?h.slice(-2):[m,y])[0],v=l[1];return f&&e>=N&&(S={x:g,y:v}),{length:N,point:S,min:{x:Math.min.apply(null,b.map((function(t){return t.x}))),y:Math.min.apply(null,b.map((function(t){return t.y})))},max:{x:Math.max.apply(null,x.map((function(t){return t.x}))),y:Math.max.apply(null,x.map((function(t){return t.y})))}}}function Sn(t,e){var n=t.length-1,r=[],i=0,o=function(t){var e=t.length,n=e-1;return t.map((function(r,i){return t.map((function(r,o){var a,s=i+o;return 0===o||t[s]&&"M"===t[s][0]?(a=t[s],["M"].concat(a.slice(-2))):(s>=e&&(s-=n),t[s])}))}))}(t);return o.forEach((function(o,a){t.slice(1).forEach((function(r,o){i+=gn(t[(a+o)%n].slice(-2),e[o%n].slice(-2))})),r[a]=i,i=0})),o[r.indexOf(Math.min.apply(null,r))]}function Nn(t){return function(t){var e=0,n=0,r=0;return pn(t).map((function(t){var i;if("M"===t[0])return e=t[1],n=t[2],0;var o=t.slice(1),a=o[0],s=o[1],l=o[2],u=o[3],c=o[4],h=o[5];return r=function(t,e,n,r,i,o,a,s){return 3*((s-e)*(n+i)-(a-t)*(r+o)+r*(t-i)-n*(e-o)+s*(i+t/3)-a*(o+e/3))/20}(e,n,a,s,l,u,c,h),i=t.slice(-2),e=i[0],n=i[1],r})).reduce((function(t,e){return t+e}),0)}(t)>=0}function On(t){return t.map((function(t,e,n){var r=e&&n[e-1].slice(-2).concat(t.slice(1)),i=e?En(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],{bbox:!1}).length:0;return{s:t,ss:e?i?function(t,e){void 0===e&&(e=.5);var n=t.slice(0,2),r=t.slice(2,4),i=t.slice(4,6),o=t.slice(6,8),a=hn(n,r,e),s=hn(r,i,e),l=hn(i,o,e),u=hn(a,s,e),c=hn(s,l,e),h=hn(u,c,e);return[["C"].concat(a,u,h),["C"].concat(c,l,o)]}(r):[t,t]:[t],l:i}}))}function Tn(t,e,n){var r=On(t),i=On(e),o=r.length,a=i.length,s=r.filter((function(t){return t.l})).length,l=i.filter((function(t){return t.l})).length,u=r.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/s||0,c=i.filter((function(t){return t.l})).reduce((function(t,e){return t+e.l}),0)/l||0,h=n||Math.max(o,a),d=[u,c],f=[h-o,h-a],p=0,g=[r,i].map((function(t,e){return t.l===h?t.map((function(t){return t.s})):t.map((function(t,n){return p=n&&f[e]&&t.l>=d[e],f[e]-=p?1:0,p?t.ss:[t.s]})).flat()}));return g[0].length===g[1].length?g:Tn(g[0],g[1],h)}function Cn(t){var e=document.createElement("div");e.innerHTML=t;var n=e.childNodes[0];return n&&e.contains(n)&&e.removeChild(n),n}function An(){return An="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(t,e,n){var r=function(t,e){for(;!{}.hasOwnProperty.call(t,e)&&null!==(t=f(t)););return t}(t,e);if(r){var i=Object.getOwnPropertyDescriptor(r,e);return i.get?i.get.call(arguments.length<3?t:n):i.value}},An.apply(null,arguments)}function Pn(t,e,n,r){var i=An(f(t.prototype),e,n);return"function"==typeof i?function(t){return i.apply(n,t)}:i} -/*! - * @antv/g-math - * @description Geometry util - * @version 3.0.1 - * @date 5/9/2025, 8:18:51 AM - * @author AntVis - * @docs https://g.antv.antgroup.com/ - */function Rn(t,e,n,r){var i=t-n,o=e-r;return Math.sqrt(i*i+o*o)}function Dn(t,e){var n=Math.min.apply(Math,d(t)),r=Math.min.apply(Math,d(e));return{x:n,y:r,width:Math.max.apply(Math,d(t))-n,height:Math.max.apply(Math,d(e))-r}}function Ln(t,e,n,r,i,o){return n*Math.cos(i)*Math.cos(o)-r*Math.sin(i)*Math.sin(o)+t}function _n(t,e,n,r,i,o){return n*Math.sin(i)*Math.cos(o)+r*Math.cos(i)*Math.sin(o)+e}function In(t,e,n,r,i,o,a){for(var s=function(t,e,n){return Math.atan(-e/t*Math.tan(n))}(n,r,i),l=1/0,u=-1/0,c=[o,a],h=2*-Math.PI;h<=2*Math.PI;h+=Math.PI){var d=s+h;ou&&(u=p)}for(var g=function(t,e,n){return Math.atan(e/(t*Math.tan(n)))}(n,r,i),v=1/0,m=-1/0,y=[o,a],b=2*-Math.PI;b<=2*Math.PI;b+=Math.PI){var x=g+b;om&&(m=w)}return{x:l,y:v,width:u-l,height:m-v}}function jn(t,e,n,r,i,o){var a=-1,s=1/0,l=[n,r],u=20;o&&o>200&&(u=o/10);for(var c=1/u,h=c/10,f=0;f<=u;f++){var p=f*c,g=[i.apply(void 0,d(t.concat([p]))),i.apply(void 0,d(e.concat([p])))],v=Rn(l[0],l[1],g[0],g[1]);v=0&&w0&&(i=1/Math.sqrt(i)),t[0]=e[0]*i,t[1]=e[1]*i}(s,s);var l=[i-t,o-e];return Math.abs(function(t,e){return t[0]*e[0]+t[1]*e[1]}(l,s))}function Gn(t,e,n,r,i){var o=1-i;return o*o*o*t+3*e*i*o*o+3*n*i*i*o+r*i*i*i}function Vn(t,e,n,r){var i,o,a,s=-3*t+9*e-9*n+3*r,l=6*t-12*e+6*n,u=3*e-3*t,c=[];if(se(s,0))se(l,0)||(i=-u/l)>=0&&i<=1&&c.push(i);else{var h=l*l-4*s*u;se(h,0)?c.push(-l/(2*s)):h>0&&(o=(-l-(a=Math.sqrt(h)))/(2*s),(i=(-l+a)/(2*s))>=0&&i<=1&&c.push(i),o>=0&&o<=1&&c.push(o))}return c}function Wn(t,e,n,r,i,o,a,s){for(var l=[t,a],u=[e,s],c=Vn(t,n,i,a),h=Vn(e,r,o,s),d=0;d=0?[i]:[]}function qn(t,e,n,r,i,o){var a=Yn(t,n,i)[0],s=Yn(e,r,o)[0],l=[t,i],u=[e,o];return void 0!==a&&l.push($n(t,n,i,a)),void 0!==s&&u.push($n(e,r,o,s)),Dn(l,u)}function Xn(t,e,n,r,i,o,a,s){var l=function(t,e,n,r,i,o,a,s){return jn([t,n,i],[e,r,o],a,s,$n)}(t,e,n,r,i,o,a,s);return Rn(l.x,l.y,a,s)}function Kn(t,e){this.v=t,this.k=e}function Zn(t,e,n,r){var i=Object.defineProperty;try{i({},"",{})}catch(t){i=0}Zn=function(t,e,n,r){if(e)i?i(t,e,{value:n,enumerable:!r,configurable:!r,writable:!r}):t[e]=n;else{var o=function(e,n){Zn(t,e,(function(t){return this._invoke(e,n,t)}))};o("next",0),o("throw",1),o("return",2)}},Zn(t,e,n,r)}function Qn(){ -/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ -var t,e,n="function"==typeof Symbol?Symbol:{},r=n.iterator||"@@iterator",i=n.toStringTag||"@@toStringTag";function o(n,r,i,o){var l=r&&r.prototype instanceof s?r:s,u=Object.create(l.prototype);return Zn(u,"_invoke",function(n,r,i){var o,s,l,u=0,c=i||[],h=!1,d={p:0,n:0,v:t,a:f,f:f.bind(t,4),d:function(e,n){return o=e,s=0,l=t,d.n=n,a}};function f(n,r){for(s=n,l=r,e=0;!h&&u&&!i&&e3?(i=p===r)&&(l=o[(s=o[4])?5:(s=3,3)],o[4]=o[5]=t):o[0]<=f&&((i=n<2&&fr||r>p)&&(o[4]=n,o[5]=r,d.n=p,s=0))}if(i||n>1)return a;throw h=!0,r}return function(i,c,p){if(u>1)throw TypeError("Generator is already running");for(h&&1===c&&f(c,p),s=c,l=p;(e=s<2?t:l)||!h;){o||(s?s<3?(s>1&&(d.n=-1),f(s,l)):d.n=l:d.v=l);try{if(u=2,o){if(s||(i="next"),e=o[i]){if(!(e=e.call(o,l)))throw TypeError("iterator result is not an object");if(!e.done)return e;l=e.value,s<2&&(s=0)}else 1===s&&(e=o.return)&&e.call(o),s<2&&(l=TypeError("The iterator does not provide a '"+i+"' method"),s=1);o=t}else if((e=(h=d.n<0)?l:n.call(r,d))!==a)break}catch(e){o=t,s=1,l=e}finally{u=1}}return{value:e,done:h}}}(n,i,o),!0),u}var a={};function s(){}function l(){}function u(){}e=Object.getPrototypeOf;var c=[][r]?e(e([][r]())):(Zn(e={},r,(function(){return this})),e),h=u.prototype=s.prototype=Object.create(c);function d(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,u):(t.__proto__=u,Zn(t,i,"GeneratorFunction")),t.prototype=Object.create(h),t}return l.prototype=u,Zn(h,"constructor",u),Zn(u,"constructor",l),l.displayName="GeneratorFunction",Zn(u,i,"GeneratorFunction"),Zn(h),Zn(h,i,"Generator"),Zn(h,r,(function(){return this})),Zn(h,"toString",(function(){return"[object Generator]"})),(Qn=function(){return{w:o,m:d}})()}function Jn(t,e){function n(r,i,o,a){try{var s=t[r](i),l=s.value;return l instanceof Kn?e.resolve(l.v).then((function(t){n("next",t,o,a)}),(function(t){n("throw",t,o,a)})):e.resolve(l).then((function(t){s.value=t,o(s)}),(function(t){return n("throw",t,o,a)}))}catch(t){a(t)}}var r;this.next||(Zn(Jn.prototype),Zn(Jn.prototype,"function"==typeof Symbol&&Symbol.asyncIterator||"@asyncIterator",(function(){return this}))),Zn(this,"_invoke",(function(t,i,o){function a(){return new e((function(e,r){n(t,o,e,r)}))}return r=r?r.then(a,a):a()}),!0)}function tr(t,e,n,r,i){return new Jn(Qn().w(t,e,n,r),i||Promise)}function er(t,e,n,r,i){var o=tr(t,e,n,r,i);return o.next().then((function(t){return t.done?t.value:o.next()}))}function nr(t){var e=Object(t),n=[];for(var r in e)n.unshift(r);return function t(){for(;n.length;)if((r=n.pop())in e)return t.value=r,t.done=!1,t;return t.done=!0,t}}function rr(t){if(null!=t){var e=t["function"==typeof Symbol&&Symbol.iterator||"@@iterator"],r=0;if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length))return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}}}throw new TypeError(n(t)+" is not iterable")}function ir(){var t=Qn(),e=t.m(ir),n=(Object.getPrototypeOf?Object.getPrototypeOf(e):e.__proto__).constructor;function r(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===n||"GeneratorFunction"===(e.displayName||e.name))}var i={throw:1,return:2,break:3,continue:3};function o(t){var e,n;return function(r){e||(e={stop:function(){return n(r.a,2)},catch:function(){return r.v},abrupt:function(t,e){return n(r.a,i[t],e)},delegateYield:function(t,i,o){return e.resultName=i,n(r.d,rr(t),o)},finish:function(t){return n(r.f,t)}},n=function(t,n,i){r.p=e.prev,r.n=e.next;try{return t(n,i)}finally{e.next=r.n}}),e.resultName&&(e[e.resultName]=r.v,e.resultName=void 0),e.sent=r.v,e.next=r.n;try{return t.call(this,e)}finally{r.p=e.prev,r.n=e.next}}}return(ir=function(){return{wrap:function(e,n,r,i){return t.w(o(e),n,r,i&&i.reverse())},isGeneratorFunction:r,mark:t.m,awrap:function(t,e){return new Kn(t,e)},AsyncIterator:Jn,async:function(t,e,n,i,a){return(r(e)?tr:er)(o(t),e,n,i,a)},keys:nr,values:rr}})()}function or(t,e,n,r,i,o,a){try{var s=t[o](a),l=s.value}catch(t){return void n(t)}s.done?e(l):Promise.resolve(l).then(r,i)}function ar(t){return function(){var e=this,n=arguments;return new Promise((function(r,i){var o=t.apply(e,n);function a(t){or(o,r,i,a,s,"next",t)}function s(t){or(o,r,i,a,s,"throw",t)}a(void 0)}))}}function sr(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=h(t))||e){n&&(t=n);var r=0,i=function(){};return{s:i,n:function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return a=t.done,t},e:function(t){s=!0,o=t},f:function(){try{a||null==n.return||n.return()}finally{if(s)throw o}}}}function lr(t,e){if(null==t)return{};var n,r,i=function(t,e){if(null==t)return{};var n={};for(var r in t)if({}.hasOwnProperty.call(t,r)){if(-1!==e.indexOf(r))continue;n[r]=t[r]}return n}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;ri;){if(o-i>600){var s=o-i+1,l=r-i+1,u=Math.log(s),c=.5*Math.exp(2*u/3),h=.5*Math.sqrt(u*c*(s-c)/s)*(l-s/2<0?-1:1);e(t,r,Math.max(i,Math.floor(r-l*c/s+h)),Math.min(o,Math.floor(r+(s-l)*c/s+h)),a)}var d=t[r],f=i,p=o;for(n(t,i,r),a(t[o],d)>0&&n(t,i,o);f0;)p--}0===a(t[i],d)?n(t,i,p):n(t,++p,o),p<=r&&(i=p+1),r<=p&&(o=p-1)}}function n(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function r(t,e){return te?1:0}var i=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function o(t,e,n){if(!n)return e.indexOf(t);for(var r=0;r=t.minX&&e.maxY>=t.minY}function m(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function y(e,n,r,i,o){for(var a=[n,r];a.length;)if(!((r=a.pop())-(n=a.pop())<=i)){var s=n+Math.ceil((r-n)/i/2)*i;t(e,s,n,r,o),a.push(n,s,s,r)}}return i.prototype.all=function(){return this._all(this.data,[])},i.prototype.search=function(t){var e=this.data,n=[];if(!v(t,e))return n;for(var r=this.toBBox,i=[];e;){for(var o=0;o=0&&i[e].children.length>this._maxEntries;)this._split(i,e),e--;this._adjustParentBBoxes(r,i,e)},i.prototype._split=function(t,e){var n=t[e],r=n.children.length,i=this._minEntries;this._chooseSplitAxis(n,i,r);var o=this._chooseSplitIndex(n,i,r),s=m(n.children.splice(o,n.children.length-o));s.height=n.height,s.leaf=n.leaf,a(n,this.toBBox),a(s,this.toBBox),e?t[e-1].children.push(s):this._splitRoot(n,s)},i.prototype._splitRoot=function(t,e){this.data=m([t,e]),this.data.height=t.height+1,this.data.leaf=!1,a(this.data,this.toBBox)},i.prototype._chooseSplitIndex=function(t,e,n){for(var r,i=1/0,o=1/0,a=e;a<=n-e;a++){var l=s(t,0,a,this.toBBox),u=s(t,a,n,this.toBBox),c=p(l,u),d=h(l)+h(u);c=e;f--){var p=t.children[f];l(a,t.leaf?i(p):p),u+=d(a)}return u},i.prototype._adjustParentBBoxes=function(t,e,n){for(var r=n;r>=0;r--)l(e[r],t)},i.prototype._condense=function(t){for(var e=t.length-1,n=void 0;e>=0;e--)0===t[e].children.length?e>0?(n=t[e-1].children).splice(n.indexOf(t[e]),1):this.clear():a(t[e],this.toBBox)},i}()}(ur);var cr=ur.exports,hr=function(t){return t.GROUP="g",t.FRAGMENT="fragment",t.CIRCLE="circle",t.ELLIPSE="ellipse",t.IMAGE="image",t.RECT="rect",t.LINE="line",t.POLYLINE="polyline",t.POLYGON="polygon",t.TEXT="text",t.PATH="path",t.HTML="html",t.MESH="mesh",t}({}),dr=function(t){return t[t.ZERO=0]="ZERO",t[t.NEGATIVE_ONE=1]="NEGATIVE_ONE",t}({}),fr=function(){return u((function t(){s(this,t),this.plugins=[]}),[{key:"addRenderingPlugin",value:function(t){this.plugins.push(t),this.context.renderingPlugins.push(t)}},{key:"removeAllRenderingPlugins",value:function(){var t=this;this.plugins.forEach((function(e){var n=t.context.renderingPlugins.indexOf(e);n>=0&&t.context.renderingPlugins.splice(n,1)}))}}])}(),pr=function(){return u((function t(e){s(this,t),this.clipSpaceNearZ=dr.NEGATIVE_ONE,this.plugins=[],this.config=a({enableDirtyCheck:!0,enableCulling:!1,enableAutoRendering:!0,enableDirtyRectangleRendering:!0,enableDirtyRectangleRenderingDebug:!1,enableSizeAttenuation:!0,enableRenderingOptimization:!1},e)}),[{key:"registerPlugin",value:function(t){-1===this.plugins.findIndex((function(e){return e===t}))&&this.plugins.push(t)}},{key:"unregisterPlugin",value:function(t){var e=this.plugins.findIndex((function(e){return e===t}));e>-1&&this.plugins.splice(e,1)}},{key:"getPlugins",value:function(){return this.plugins}},{key:"getPlugin",value:function(t){return this.plugins.find((function(e){return e.name===t}))}},{key:"getConfig",value:function(){return this.config}},{key:"setConfig",value:function(t){Object.assign(this.config,t)}}])}(),gr=mt,vr=gt,mr=function(t,e,n){return t[0]=Math.max(e[0],n[0]),t[1]=Math.max(e[1],n[1]),t[2]=Math.max(e[2],n[2]),t},yr=function(t,e,n){return t[0]=Math.min(e[0],n[0]),t[1]=Math.min(e[1],n[1]),t[2]=Math.min(e[2],n[2]),t},br=bt,xr=Nt,Er=function(){function t(){s(this,t),this.center=[0,0,0],this.halfExtents=[0,0,0],this.min=[0,0,0],this.max=[0,0,0]}return u(t,[{key:"update",value:function(t,e){vr(this.center,t),vr(this.halfExtents,e),xr(this.min,this.center,this.halfExtents),gr(this.max,this.center,this.halfExtents)}},{key:"setMinMax",value:function(t,e){gr(this.center,e,t),br(this.center,this.center,.5),xr(this.halfExtents,e,t),br(this.halfExtents,this.halfExtents,.5),vr(this.min,t),vr(this.max,e)}},{key:"getMin",value:function(){return this.min}},{key:"getMax",value:function(){return this.max}},{key:"add",value:function(e){if(!t.isEmpty(e))if(t.isEmpty(this))this.setMinMax(e.getMin(),e.getMax());else{var n=this.center,r=n[0],i=n[1],o=n[2],a=this.halfExtents,s=a[0],l=a[1],u=a[2],c=r-s,h=r+s,d=i-l,f=i+l,p=o-u,g=o+u,v=e.center,m=v[0],y=v[1],b=v[2],x=e.halfExtents,E=x[0],w=x[1],k=x[2],M=m-E,S=m+E,N=y-w,O=y+w,T=b-k,C=b+k;Mh&&(h=S),Nf&&(f=O),Tg&&(g=C),n[0]=.5*(c+h),n[1]=.5*(d+f),n[2]=.5*(p+g),a[0]=.5*(h-c),a[1]=.5*(f-d),a[2]=.5*(g-p),this.min[0]=c,this.min[1]=d,this.min[2]=p,this.max[0]=h,this.max[1]=f,this.max[2]=g}}},{key:"setFromTransformedAABB",value:function(t,e){var n=this.center,r=this.halfExtents,i=t.center,o=t.halfExtents,a=e[0],s=e[4],l=e[8],u=e[1],c=e[5],h=e[9],d=e[2],f=e[6],p=e[10],g=Math.abs(a),v=Math.abs(s),m=Math.abs(l),y=Math.abs(u),b=Math.abs(c),x=Math.abs(h),E=Math.abs(d),w=Math.abs(f),k=Math.abs(p);n[0]=e[12]+a*i[0]+s*i[1]+l*i[2],n[1]=e[13]+u*i[0]+c*i[1]+h*i[2],n[2]=e[14]+d*i[0]+f*i[1]+p*i[2],r[0]=g*o[0]+v*o[1]+m*o[2],r[1]=y*o[0]+b*o[1]+x*o[2],r[2]=E*o[0]+w*o[1]+k*o[2],xr(this.min,n,r),gr(this.max,n,r)}},{key:"intersects",value:function(t){var e=this.getMax(),n=this.getMin(),r=t.getMax(),i=t.getMin();return n[0]<=r[0]&&e[0]>=i[0]&&n[1]<=r[1]&&e[1]>=i[1]&&n[2]<=r[2]&&e[2]>=i[2]}},{key:"intersection",value:function(e){if(!this.intersects(e))return null;var n=new t,r=mr([0,0,0],this.getMin(),e.getMin()),i=yr([0,0,0],this.getMax(),e.getMax());return n.setMinMax(r,i),n}},{key:"getNegativeFarPoint",value:function(t){return 273===t.pnVertexFlag?vr([0,0,0],this.min):272===t.pnVertexFlag?[this.min[0],this.min[1],this.max[2]]:257===t.pnVertexFlag?[this.min[0],this.max[1],this.min[2]]:256===t.pnVertexFlag?[this.min[0],this.max[1],this.max[2]]:17===t.pnVertexFlag?[this.max[0],this.min[1],this.min[2]]:16===t.pnVertexFlag?[this.max[0],this.min[1],this.max[2]]:1===t.pnVertexFlag?[this.max[0],this.max[1],this.min[2]]:[this.max[0],this.max[1],this.max[2]]}},{key:"getPositiveFarPoint",value:function(t){return 273===t.pnVertexFlag?vr([0,0,0],this.max):272===t.pnVertexFlag?[this.max[0],this.max[1],this.min[2]]:257===t.pnVertexFlag?[this.max[0],this.min[1],this.max[2]]:256===t.pnVertexFlag?[this.max[0],this.min[1],this.min[2]]:17===t.pnVertexFlag?[this.min[0],this.max[1],this.max[2]]:16===t.pnVertexFlag?[this.min[0],this.max[1],this.min[2]]:1===t.pnVertexFlag?[this.min[0],this.min[1],this.max[2]]:[this.min[0],this.min[1],this.min[2]]}}],[{key:"isEmpty",value:function(t){return!t||0===t.halfExtents[0]&&0===t.halfExtents[1]&&0===t.halfExtents[2]}}])}(),wr=function(){return u((function t(e,n){s(this,t),this.distance=e||0,this.normal=n||pt(0,1,0),this.updatePNVertexFlag()}),[{key:"updatePNVertexFlag",value:function(){this.pnVertexFlag=(Number(this.normal[0]>=0)<<8)+(Number(this.normal[1]>=0)<<4)+Number(this.normal[2]>=0)}},{key:"distanceToPoint",value:function(t){return Et(t,this.normal)-this.distance}},{key:"normalize",value:function(){var t=1/Tt(this.normal);bt(this.normal,this.normal,t),this.distance*=t}},{key:"intersectsLine",value:function(t,e,n){var r=this.distanceToPoint(t),i=r/(r-this.distanceToPoint(e)),o=i>=0&&i<=1;return o&&n&&kt(n,t,e,i),o}}])}(),kr=function(t){return t[t.OUTSIDE=4294967295]="OUTSIDE",t[t.INSIDE=0]="INSIDE",t[t.INDETERMINATE=2147483647]="INDETERMINATE",t}({}),Mr=function(){return u((function t(e){if(s(this,t),this.planes=[],e)this.planes=e;else for(var n=0;n<6;n++)this.planes.push(new wr)}),[{key:"extractFromVPMatrix",value:function(t){var e=b(t,16),n=e[0],r=e[1],i=e[2],o=e[3],a=e[4],s=e[5],l=e[6],u=e[7],c=e[8],h=e[9],d=e[10],f=e[11],p=e[12],g=e[13],v=e[14],m=e[15];vt(this.planes[0].normal,o-n,u-a,f-c),this.planes[0].distance=m-p,vt(this.planes[1].normal,o+n,u+a,f+c),this.planes[1].distance=m+p,vt(this.planes[2].normal,o+r,u+s,f+h),this.planes[2].distance=m+g,vt(this.planes[3].normal,o-r,u-s,f-h),this.planes[3].distance=m-g,vt(this.planes[4].normal,o-i,u-l,f-d),this.planes[4].distance=m-v,vt(this.planes[5].normal,o+i,u+l,f+d),this.planes[5].distance=m+v,this.planes.forEach((function(t){t.normalize(),t.updatePNVertexFlag()}))}}])}(),Sr=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;s(this,t),this.x=0,this.y=0,this.x=e,this.y=n}return u(t,[{key:"clone",value:function(){return new t(this.x,this.y)}},{key:"copyFrom",value:function(t){this.x=t.x,this.y=t.y}}])}(),Nr=function(){function t(e,n,r,i){s(this,t),this.x=e,this.y=n,this.width=r,this.height=i,this.left=e,this.right=e+r,this.top=n,this.bottom=n+i}return u(t,[{key:"toJSON",value:function(){}}],[{key:"fromRect",value:function(e){return new t(e.x,e.y,e.width,e.height)}},{key:"applyTransform",value:function(e,n){var r=At(e.x,e.y,0,1),i=At(e.x+e.width,e.y,0,1),o=At(e.x,e.y+e.height,0,1),a=At(e.x+e.width,e.y+e.height,0,1),s=Ct(),l=Ct(),u=Ct(),c=Ct();Pt(s,r,n),Pt(l,i,n),Pt(u,o,n),Pt(c,a,n);var h=Math.min(s[0],l[0],u[0],c[0]),d=Math.min(s[1],l[1],u[1],c[1]),f=Math.max(s[0],l[0],u[0],c[0]),p=Math.max(s[1],l[1],u[1],c[1]);return t.fromRect({x:h,y:d,width:f-h,height:p-d})}}])}(),Or="Method not implemented.",Tr="Use document.documentElement instead.";function Cr(t){return void 0===t?0:t>360||t<-360?t%360:t}var Ar=ht();function Pr(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];return Array.isArray(t)&&3===t.length?r?dt(t):gt(Ar,t):ae(t)?r?pt(t,e,n):vt(Ar,t,e,n):r?pt(t[0],t[1]||e,t[2]||n):vt(Ar,t[0],t[1]||e,t[2]||n)}var Rr=Math.PI/180;function Dr(t){return t*Rr}var Lr=180/Math.PI;function _r(t){return t*Lr}var Ir=Math.PI/2;function jr(t,e){return 16===e.length?function(t,e){var n,r,i=b(K(ht(),e),3),o=i[0],a=i[1],s=i[2],l=Math.asin(-e[2]/o);return l-Ir?(n=Math.atan2(e[6]/a,e[10]/s),r=Math.atan2(e[1]/o,e[0]/o)):(r=0,n=-Math.atan2(e[4]/a,e[5]/a)):(r=0,n=Math.atan2(e[4]/a,e[5]/a)),t[0]=n,t[1]=l,t[2]=r,t}(t,e):function(t,e){var n=e[0],r=e[1],i=e[2],o=e[3],a=r*r,s=i*i,l=o*o,u=n*n+a+s+l,c=n*o-r*i;return c>.499995*u?(t[0]=Ir,t[1]=2*Math.atan2(r,n),t[2]=0):c<-.499995*u?(t[0]=-Ir,t[1]=2*Math.atan2(r,n),t[2]=0):(t[0]=Math.asin(2*(n*i-o*r)),t[1]=Math.atan2(2*(n*o+r*i),1-2*(s+l)),t[2]=Math.atan2(2*(n*r+i*o),1-2*(a+s))),t}(t,e)}function Br(t,e,n,r,i){var o,a,s,l,u,c,h,d,f,p,g=Math.cos(t),v=Math.sin(t);return o=r*g,a=i*v,s=0,l=-r*v,u=i*g,c=0,h=e,d=n,f=1,(p=new N(9))[0]=o,p[1]=a,p[2]=s,p[3]=l,p[4]=u,p[5]=c,p[6]=h,p[7]=d,p[8]=f,p}function Fr(t){var e=t[0],n=t[1],r=t[3],i=t[4],o=Math.sqrt(e*e+n*n),a=Math.sqrt(r*r+i*i);if(e*i-n*r<0&&(e7&&void 0!==arguments[7]&&arguments[7]?(s=-a/v,l=-m/v):(s=-(a+o)/v,l=-2*m/v),t[0]=d,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=p,t[9]=g,t[10]=s,t[11]=-1,t[12]=0,t[13]=0,t[14]=l,t[15]=0}(this.projectionMatrix,l,l+s,o-a,o,t,this.far,this.clipSpaceNearZ===dr.ZERO),_(this.projectionMatrixInverse,this.projectionMatrix),this.triggerUpdate(),this}},{key:"setOrthographic",value:function(t,e,n,r,i,o){var a;this.projectionMode=qr.ORTHOGRAPHIC,this.rright=e,this.left=t,this.top=n,this.bottom=r,this.near=i,this.far=o;var s=(this.rright-this.left)/(2*this.zoom),l=(this.top-this.bottom)/(2*this.zoom),u=(this.rright+this.left)/2,c=(this.top+this.bottom)/2,h=u-s,d=u+s,f=c+l,p=c-l;if(null!==(a=this.view)&&void 0!==a&&a.enabled){var g=(this.rright-this.left)/this.view.fullWidth/this.zoom,v=(this.top-this.bottom)/this.view.fullHeight/this.zoom;d=(h+=g*this.view.offsetX)+g*this.view.width,p=(f-=v*this.view.offsetY)-v*this.view.height}return this.clipSpaceNearZ===dr.NEGATIVE_ONE?rt(this.projectionMatrix,h,d,f,p,i,o):it(this.projectionMatrix,h,d,f,p,i,o),_(this.projectionMatrixInverse,this.projectionMatrix),this._getOrthoMatrix(),this.triggerUpdate(),this}},{key:"setPosition",value:function(t){var e=Pr(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.position[1],arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.position[2]);return this._setPosition(e),this.setFocalPoint(this.focalPoint),this.triggerUpdate(),this}},{key:"setFocalPoint",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.focalPoint[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.focalPoint[2],r=pt(0,1,0);if(this.focalPoint=Pr(t,e,n),this.trackingMode===Yr.CINEMATIC){var i=yt(ht(),this.focalPoint,this.position);t=i[0],e=i[1],n=i[2];var o=ft(i),a=_r(Math.asin(e/o)),s=90+_r(Math.atan2(n,t)),l=T();G(l,l,Dr(s)),z(l,l,Dr(a)),r=Mt(ht(),[0,1,0],l)}return _(this.matrix,ot(T(),this.position,this.focalPoint,r)),this._getAxes(),this._getDistance(),this._getAngles(),this.triggerUpdate(),this}},{key:"getDistance",value:function(){return this.distance}},{key:"getDistanceVector",value:function(){return this.distanceVector}},{key:"setDistance",value:function(t){if(this.distance===t||t<0)return this;this.distance=t,this.distance>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?wi(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?wi(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=hi.exec(t))?new ki(e[1],e[2],e[3],1):(e=di.exec(t))?new ki(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=fi.exec(t))?wi(e[1],e[2],e[3],e[4]):(e=pi.exec(t))?wi(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=gi.exec(t))?Ci(e[1],e[2]/100,e[3]/100,1):(e=vi.exec(t))?Ci(e[1],e[2]/100,e[3]/100,e[4]):mi.hasOwnProperty(t)?Ei(mi[t]):"transparent"===t?new ki(NaN,NaN,NaN,0):null}function Ei(t){return new ki(t>>16&255,t>>8&255,255&t,1)}function wi(t,e,n,r){return r<=0&&(t=e=n=NaN),new ki(t,e,n,r)}function ki(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function Mi(){return`#${Ti(this.r)}${Ti(this.g)}${Ti(this.b)}`}function Si(){const t=Ni(this.opacity);return`${1===t?"rgb(":"rgba("}${Oi(this.r)}, ${Oi(this.g)}, ${Oi(this.b)}${1===t?")":`, ${t})`}`}function Ni(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Oi(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function Ti(t){return((t=Oi(t))<16?"0":"")+t.toString(16)}function Ci(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new Pi(t,e,n,r)}function Ai(t){if(t instanceof Pi)return new Pi(t.h,t.s,t.l,t.opacity);if(t instanceof ii||(t=xi(t)),!t)return new Pi;if(t instanceof Pi)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),o=Math.max(e,n,r),a=NaN,s=o-i,l=(o+i)/2;return s?(a=e===o?(n-r)/s+6*(n0&&l<1?0:a,new Pi(a,s,l,t.opacity)}function Pi(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function Ri(t){return(t=(t||0)%360)<0?t+360:t}function Di(t){return Math.max(0,Math.min(1,t||0))}function Li(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function _i(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var n=function(){for(var r=arguments.length,i=new Array(r),o=0;o=240?t-240:t+120,i,r),Li(t,i,r),Li(t<120?t+240:t-120,i,r),this.opacity)},clamp(){return new Pi(Ri(this.h),Di(this.s),Di(this.l),Ni(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Ni(this.opacity);return`${1===t?"hsl(":"hsla("}${Ri(this.h)}, ${100*Di(this.s)}%, ${100*Di(this.l)}%${1===t?")":`, ${t})`}`}})),_i.Cache=Map,_i.cacheList=[],_i.clearCache=function(){_i.cacheList.forEach((function(t){return t.clear()}))};var Ii=function(t){return t[t.kUnknown=0]="kUnknown",t[t.kNumber=1]="kNumber",t[t.kPercentage=2]="kPercentage",t[t.kEms=3]="kEms",t[t.kPixels=4]="kPixels",t[t.kRems=5]="kRems",t[t.kDegrees=6]="kDegrees",t[t.kRadians=7]="kRadians",t[t.kGradians=8]="kGradians",t[t.kTurns=9]="kTurns",t[t.kMilliseconds=10]="kMilliseconds",t[t.kSeconds=11]="kSeconds",t[t.kInteger=12]="kInteger",t}({}),ji=function(t){return t[t.kUNumber=0]="kUNumber",t[t.kUPercent=1]="kUPercent",t[t.kULength=2]="kULength",t[t.kUAngle=3]="kUAngle",t[t.kUTime=4]="kUTime",t[t.kUOther=5]="kUOther",t}({}),Bi=function(t){return t[t.kYes=0]="kYes",t[t.kNo=1]="kNo",t}({}),Fi=function(t){return t[t.kYes=0]="kYes",t[t.kNo=1]="kNo",t}({}),zi=[{name:"em",unit_type:Ii.kEms},{name:"px",unit_type:Ii.kPixels},{name:"deg",unit_type:Ii.kDegrees},{name:"rad",unit_type:Ii.kRadians},{name:"grad",unit_type:Ii.kGradians},{name:"ms",unit_type:Ii.kMilliseconds},{name:"s",unit_type:Ii.kSeconds},{name:"rem",unit_type:Ii.kRems},{name:"turn",unit_type:Ii.kTurns}],Gi=function(t){return t[t.kUnknownType=0]="kUnknownType",t[t.kUnparsedType=1]="kUnparsedType",t[t.kKeywordType=2]="kKeywordType",t[t.kUnitType=3]="kUnitType",t[t.kSumType=4]="kSumType",t[t.kProductType=5]="kProductType",t[t.kNegateType=6]="kNegateType",t[t.kInvertType=7]="kInvertType",t[t.kMinType=8]="kMinType",t[t.kMaxType=9]="kMaxType",t[t.kClampType=10]="kClampType",t[t.kTransformType=11]="kTransformType",t[t.kPositionType=12]="kPositionType",t[t.kURLImageType=13]="kURLImageType",t[t.kColorType=14]="kColorType",t[t.kUnsupportedColorType=15]="kUnsupportedColorType",t}({}),Vi=function(t){return t?"number"===t?Ii.kNumber:"percent"===t||"%"===t?Ii.kPercentage:function(t){return zi.find((function(e){return e.name===t})).unit_type}(t):Ii.kUnknown},Wi=function(t){var e=1;switch(t){case Ii.kPixels:case Ii.kDegrees:case Ii.kSeconds:break;case Ii.kMilliseconds:e=.001;break;case Ii.kRadians:e=180/Math.PI;break;case Ii.kGradians:e=.9;break;case Ii.kTurns:e=360}return e},Hi=function(t){switch(t){case Ii.kNumber:case Ii.kInteger:return"";case Ii.kPercentage:return"%";case Ii.kEms:return"em";case Ii.kRems:return"rem";case Ii.kPixels:return"px";case Ii.kDegrees:return"deg";case Ii.kRadians:return"rad";case Ii.kGradians:return"grad";case Ii.kMilliseconds:return"ms";case Ii.kSeconds:return"s";case Ii.kTurns:return"turn"}return""},Ui=function(){return u((function t(){s(this,t)}),[{key:"toString",value:function(){return this.buildCSSText(Bi.kNo,Fi.kNo,"")}},{key:"isNumericValue",value:function(){return this.getType()>=Gi.kUnitType&&this.getType()<=Gi.kClampType}}],[{key:"isAngle",value:function(t){return t===Ii.kDegrees||t===Ii.kRadians||t===Ii.kGradians||t===Ii.kTurns}},{key:"isLength",value:function(t){return t>=Ii.kEms&&t1&&void 0!==arguments[1]?arguments[1]:Ii.kNumber;return s(this,e),n=v(this,e),r="string"==typeof i?Vi(i):i,n.unit=r,n.value=t,n}return y(e,t),u(e,[{key:"clone",value:function(){return new e(this.value,this.unit)}},{key:"equals",value:function(t){var e=t;return this.value===e.value&&this.unit===e.unit}},{key:"getType",value:function(){return Gi.kUnitType}},{key:"convertTo",value:function(t){if(this.unit===t)return new e(this.value,this.unit);var n=Ki(this.unit);if(n!==Ki(t)||n===Ii.kUnknown)return null;var r=Wi(this.unit)/Wi(t);return new e(this.value*r,t)}},{key:"buildCSSText",value:function(t,e,n){var r;switch(this.unit){case Ii.kUnknown:break;case Ii.kInteger:r=Number(this.value).toFixed(0);break;case Ii.kNumber:case Ii.kPercentage:case Ii.kEms:case Ii.kRems:case Ii.kPixels:case Ii.kDegrees:case Ii.kRadians:case Ii.kGradians:case Ii.kMilliseconds:case Ii.kSeconds:case Ii.kTurns:var i=this.value,o=Hi(this.unit);if(i<-999999||i>999999){var a=Hi(this.unit);r=!Number.isFinite(i)||Number.isNaN(i)?function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return(Number.isFinite(t)?"NaN":t>0?"infinity":"-infinity")+e}(i,a):i+(a||"")}else r="".concat(i).concat(o)}return n+=r}}])}(Ui),Qi=new Zi(0,"px");new Zi(1,"px");var Ji=new Zi(0,"deg"),to=function(t){function e(t,n,r){var i,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1,a=arguments.length>4&&void 0!==arguments[4]&&arguments[4];return s(this,e),(i=v(this,e,["rgb"])).r=t,i.g=n,i.b=r,i.alpha=o,i.isNone=a,i}return y(e,t),u(e,[{key:"clone",value:function(){return new e(this.r,this.g,this.b,this.alpha)}},{key:"buildCSSText",value:function(t,e,n){return"".concat(n,"rgba(").concat(this.r,",").concat(this.g,",").concat(this.b,",").concat(this.alpha,")")}}])}($i),eo=new Xi("unset"),no={"":eo,unset:eo,initial:new Xi("initial"),inherit:new Xi("inherit")},ro=new to(0,0,0,0,!0),io=new to(0,0,0,0),oo=_i((function(t,e,n,r){return new to(t,e,n,r)}),(function(t,e,n,r){return"rgba(".concat(t,",").concat(e,",").concat(n,",").concat(r,")")})),ao=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ii.kNumber;return new Zi(t,e)};function so(t){var e=t.type,n=t.value;return"hex"===e?"#".concat(n):"literal"===e?n:"rgb"===e?"rgb(".concat(n.join(","),")"):"rgba(".concat(n.join(","),")")}new Zi(50,"%");var lo=function(){var t=/^(linear\-gradient)/i,e=/^(repeating\-linear\-gradient)/i,n=/^(radial\-gradient)/i,r=/^(repeating\-radial\-gradient)/i,i=/^(conic\-gradient)/i,o=/^to (left (top|bottom)|right (top|bottom)|top (left|right)|bottom (left|right)|left|right|top|bottom)/i,a=/^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,s=/^(left|center|right|top|bottom)/i,l=/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,u=/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,c=/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,h=/^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,d=/^\(/,f=/^\)/,p=/^,/,g=/^\#([0-9a-fA-F]+)/,v=/^([a-zA-Z]+)/,m=/^rgb/i,y=/^rgba/i,b=/^(([0-9]*\.[0-9]+)|([0-9]+\.?))/,x="";function E(t){throw new Error("".concat(x,": ").concat(t))}function w(){var t=R(k);return x.length>0&&E("Invalid input not EOF"),t}function k(){return M("linear-gradient",t,N)||M("repeating-linear-gradient",e,N)||M("radial-gradient",n,O)||M("repeating-radial-gradient",r,O)||M("conic-gradient",i,O)}function M(t,e,n){return S(e,(function(e){var r=n();return r&&(B(p)||E("Missing comma before color stops")),{type:t,orientation:r,colorStops:R(D)}}))}function S(t,e){var n=B(t);if(n){B(d)||E("Missing (");var r=e(n);return B(f)||E("Missing )"),r}}function N(){return j("directional",o,1)||j("angular",h,1)}function O(){var t,e,n=T();return n&&((t=[]).push(n),e=x,B(p)&&((n=T())?t.push(n):x=e)),t}function T(){var t=function(){var t=j("shape",/^(circle)/i,0);t&&(t.style=I()||C());return t}()||function(){var t=j("shape",/^(ellipse)/i,0);t&&(t.style=_()||C());return t}();if(t)t.at=A();else{var e=C();if(e){t=e;var n=A();n&&(t.at=n)}else{var r=P();r&&(t={type:"default-radial",at:r})}}return t}function C(){return j("extent-keyword",a,1)}function A(){if(j("position",/^at/,0)){var t=P();return t||E("Missing positioning value"),t}}function P(){var t={x:_(),y:_()};if(t.x||t.y)return{type:"position",value:t}}function R(t){var e=t(),n=[];if(e)for(n.push(e);B(p);)(e=t())?n.push(e):E("One extra comma");return n}function D(){var t=j("hex",g,1)||S(y,(function(){return{type:"rgba",value:R(L)}}))||S(m,(function(){return{type:"rgb",value:R(L)}}))||j("literal",v,0);return t||E("Expected color definition"),t.length=_(),t}function L(){return B(b)[1]}function _(){return j("%",u,1)||j("position-keyword",s,1)||I()}function I(){return j("px",l,1)||j("em",c,1)}function j(t,e,n){var r=B(e);if(r)return{type:t,value:r[n]}}function B(t){var e=/^[\n\r\t\s]+/.exec(x);e&&F(e[0].length);var n=t.exec(x);return n&&F(n[0].length),n}function F(t){x=x.substring(t)}return function(t){return x=t,w()}}();var uo=/^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i,co=/^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i,ho=/^p\s*\(\s*([axyn])\s*\)\s*(.*)/i,fo=/[\d.]+:(#[^\s]+|[^\)]+\))/gi;var po={left:180,top:-90,bottom:90,right:0,"left top":225,"top left":225,"left bottom":135,"bottom left":135,"right top":-45,"top right":-45,"right bottom":45,"bottom right":45},go=_i((function(t){var e;return e="angular"===t.type?Number(t.value):po[t.value]||0,ao(e,"deg")})),vo=_i((function(t){var e=50,n=50,r="%",i="%";if("position"===(null==t?void 0:t.type)){var o=t.value,a=o.x,s=o.y;"position-keyword"===(null==a?void 0:a.type)&&("left"===a.value?e=0:"center"===a.value?e=50:"right"===a.value?e=100:"top"===a.value?n=0:"bottom"===a.value&&(n=100)),"position-keyword"===(null==s?void 0:s.type)&&("left"===s.value?e=0:"center"===s.value?n=50:"right"===s.value?e=100:"top"===s.value?n=0:"bottom"===s.value&&(n=100)),"px"!==(null==a?void 0:a.type)&&"%"!==(null==a?void 0:a.type)&&"em"!==(null==a?void 0:a.type)||(r=null==a?void 0:a.type,e=Number(a.value)),"px"!==(null==s?void 0:s.type)&&"%"!==(null==s?void 0:s.type)&&"em"!==(null==s?void 0:s.type)||(i=null==s?void 0:s.type,n=Number(s.value))}return{cx:ao(e,r),cy:ao(n,i)}})),mo=_i((function(t){if(t.indexOf("linear")>-1||t.indexOf("radial")>-1)return lo(t).map((function(t){var e=t.type,n=t.orientation,r=t.colorStops;!function(t){var e,n,r=t.length;t[r-1].length=null!==(e=t[r-1].length)&&void 0!==e?e:{type:"%",value:"100"},r>1&&(t[0].length=null!==(n=t[0].length)&&void 0!==n?n:{type:"%",value:"0"});for(var i=0,o=Number(t[0].length.value),a=1;a=0)return ao(Number(e),"px");if("deg".search(t)>=0)return ao(Number(e),"deg")}var n=[];e=e.replace(t,(function(t){return n.push(t),"U".concat(t)}));var r="U(".concat(t.source,")");return n.map((function(t){return ao(Number(e.replace(new RegExp("U".concat(t),"g"),"").replace(new RegExp(r,"g"),"*0")),t)}))[0]}var ko=function(t){return wo(new RegExp("px","g"),t)},Mo=_i(ko);_i((function(t){return wo(new RegExp("%","g"),t)}));var So=function(t){return ae(t)||isFinite(Number(t))?ao(Number(t)||0,"px"):wo(new RegExp("px|%|em|rem","g"),t)},No=_i(So),Oo=function(t){return wo(new RegExp("deg|rad|grad|turn","g"),t)},To=_i(Oo);function Co(t,e,n,r){var i=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,o="",a=t.value||0,s=e.value||0,l=Ki(t.unit),u=t.convertTo(l),c=e.convertTo(l);return u&&c?(a=u.value,s=c.value,o=Hi(t.unit)):(Zi.isLength(t.unit)||Zi.isLength(e.unit))&&(a=Ro(t,i,n),s=Ro(e,i,n),o="px"),[a,s,function(t){return t+o}]}function Ao(t){var e=0;return t.unit===Ii.kDegrees?e=t.value:t.unit===Ii.kRadians?e=_r(Number(t.value)):t.unit===Ii.kTurns?e=360*Number(t.value):t.value&&(e=t.value),e}function Po(t,e){var n;return Array.isArray(t)?n=t.map((function(t){return Number(t)})):ne(t)?n=t.split(" ").map((function(t){return Number(t)})):ae(t)&&(n=[t]),2===e?1===n.length?[n[0],n[0]]:[n[0],n[1]]:4===e?1===n.length?[n[0],n[0],n[0],n[0]]:2===n.length?[n[0],n[1],n[0],n[1]]:3===n.length?[n[0],n[1],n[2],n[1]]:[n[0],n[1],n[2],n[3]]:"even"===e&&n.length%2==1?[].concat(d(n),d(n)):n}function Ro(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(t.unit===Ii.kPixels)return Number(t.value);if(t.unit===Ii.kPercentage&&n){var i=n.nodeName===hr.GROUP?n.getLocalBounds():n.getGeometryBounds();return(r?i.min[e]:0)+t.value/100*i.halfExtents[e]*2}return 0}var Do=["blur","brightness","drop-shadow","contrast","grayscale","sepia","saturate","hue-rotate","invert"];function Lo(t){return t.toString()}var _o=function(t){return"number"==typeof t?ao(t):/^\s*[-+]?(\d*\.)?\d+\s*$/.test(t)?ao(Number(t)):ao(0)},Io=_i(_o);function jo(t,e){return[t,e,Lo]}function Bo(t,e){return function(n,r){return[n,r,function(n){return Lo(oe(n,t,e))}]}}function Fo(t,e){if(t.length===e.length)return[t,e,function(t){return t}]}function zo(t){var e;return 0===t.parsedStyle.d.totalLength&&(t.parsedStyle.d.totalLength=Mn(t.parsedStyle.d.absolutePath,void 0,Be(Be({},e),{bbox:!1,length:!0})).length),t.parsedStyle.d.totalLength}function Go(t,e){return t[0]===e[0]&&t[1]===e[1]}function Vo(t,e){var n=t.prePoint,r=t.currentPoint,i=t.nextPoint,o=Math.pow(r[0]-n[0],2)+Math.pow(r[1]-n[1],2),a=Math.pow(r[0]-i[0],2)+Math.pow(r[1]-i[1],2),s=Math.pow(n[0]-i[0],2)+Math.pow(n[1]-i[1],2),l=Math.acos((o+a-s)/(2*Math.sqrt(o)*Math.sqrt(a)));if(!l||0===Math.sin(l)||se(l,0))return{xExtra:0,yExtra:0};var u=Math.abs(Math.atan2(i[1]-r[1],i[0]-r[0])),c=Math.abs(Math.atan2(i[0]-r[0],i[1]-r[1]));return u=u>Math.PI/2?Math.PI-u:u,c=c>Math.PI/2?Math.PI-c:c,{xExtra:Math.cos(l/2-u)*(e/2*(1/Math.sin(l/2)))-e/2||0,yExtra:Math.cos(c-l/2)*(e/2*(1/Math.sin(l/2)))-e/2||0}}function Wo(t,e){return[e[0]+(e[0]-t[0]),e[1]+(e[1]-t[1])]}_i((function(t){return ne(t)?t.split(" ").map(Io):t.map(Io)}));var Ho=function(t,e){var n=t.x*e.x+t.y*e.y,r=Math.sqrt((Math.pow(t.x,2)+Math.pow(t.y,2))*(Math.pow(e.x,2)+Math.pow(e.y,2)));return(t.x*e.y-t.y*e.x<0?-1:1)*Math.acos(n/r)},Uo=function(t,e,n,r,i,o,a,s){e=Math.abs(e),n=Math.abs(n);var l=Dr(r=ce(r,360));if(t.x===a.x&&t.y===a.y)return{x:t.x,y:t.y,ellipticalArcAngle:0};if(0===e||0===n)return{x:0,y:0,ellipticalArcAngle:0};var u=(t.x-a.x)/2,c=(t.y-a.y)/2,h={x:Math.cos(l)*u+Math.sin(l)*c,y:-Math.sin(l)*u+Math.cos(l)*c},d=Math.pow(h.x,2)/Math.pow(e,2)+Math.pow(h.y,2)/Math.pow(n,2);d>1&&(e*=Math.sqrt(d),n*=Math.sqrt(d));var f=(Math.pow(e,2)*Math.pow(n,2)-Math.pow(e,2)*Math.pow(h.y,2)-Math.pow(n,2)*Math.pow(h.x,2))/(Math.pow(e,2)*Math.pow(h.y,2)+Math.pow(n,2)*Math.pow(h.x,2));f=f<0?0:f;var p=(i!==o?1:-1)*Math.sqrt(f),g=p*(e*h.y/n),v=p*(-n*h.x/e),m={x:Math.cos(l)*g-Math.sin(l)*v+(t.x+a.x)/2,y:Math.sin(l)*g+Math.cos(l)*v+(t.y+a.y)/2},y={x:(h.x-g)/e,y:(h.y-v)/n},b=Ho({x:1,y:0},y),x=Ho(y,{x:(-h.x-g)/e,y:(-h.y-v)/n});!o&&x>0?x-=2*Math.PI:o&&x<0&&(x+=2*Math.PI);var E=b+(x%=2*Math.PI)*s,w=e*Math.cos(E),k=n*Math.sin(E);return{x:Math.cos(l)*w-Math.sin(l)*k+m.x,y:Math.sin(l)*w+Math.cos(l)*k+m.y,ellipticalArcStartAngle:b,ellipticalArcEndAngle:b+x,ellipticalArcAngle:E,ellipticalArcCenter:m,resultantRx:e,resultantRy:n}};function $o(t,e){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=t.arcParams,i=r.rx,o=void 0===i?0:i,a=r.ry,s=void 0===a?0:a,l=r.xRotation,u=r.arcFlag,c=r.sweepFlag,h=Uo({x:t.prePoint[0],y:t.prePoint[1]},o,s,l,!!u,!!c,{x:t.currentPoint[0],y:t.currentPoint[1]},e),d=Uo({x:t.prePoint[0],y:t.prePoint[1]},o,s,l,!!u,!!c,{x:t.currentPoint[0],y:t.currentPoint[1]},n?e+.005:e-.005),f=d.x-h.x,p=d.y-h.y,g=Math.sqrt(f*f+p*p);return{x:-f/g,y:-p/g}}function Yo(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])}function qo(t,e){return Yo(t)*Yo(e)?(t[0]*e[0]+t[1]*e[1])/(Yo(t)*Yo(e)):1}function Xo(t,e){return(t[0]*e[1]1&&(n*=Math.sqrt(f),r*=Math.sqrt(f));var p=n*n*(d*d)+r*r*(h*h),g=p?Math.sqrt((n*n*(r*r)-p)/p):1;o===a&&(g*=-1),isNaN(g)&&(g=0);var v=r?g*n*d/r:0,m=n?g*-r*h/n:0,y=(s+u)/2+Math.cos(i)*v-Math.sin(i)*m,b=(l+c)/2+Math.sin(i)*v+Math.cos(i)*m,x=[(h-v)/n,(d-m)/r],E=[(-1*h-v)/n,(-1*d-m)/r],w=Xo([1,0],x),k=Xo(x,E);return qo(x,E)<=-1&&(k=Math.PI),qo(x,E)>=1&&(k=0),0===a&&k>0&&(k-=2*Math.PI),1===a&&k<0&&(k+=2*Math.PI),{cx:y,cy:b,rx:Go(t,[u,c])?0:n,ry:Go(t,[u,c])?0:r,startAngle:w,endAngle:w+k,xRotation:i,arcFlag:o,sweepFlag:a}}var Zo=function(t){if(""===t||Array.isArray(t)&&0===t.length)return{absolutePath:[],hasArc:!1,segments:[],polygons:[],polylines:[],curve:null,totalLength:0,rect:{x:0,y:0,width:0,height:0}};var e;try{e=ln(t)}catch(n){e=ln(""),console.error("[g]: Invalid SVG Path definition: ".concat(t))}!function(t){for(var e=0;e0&&n.push(r),{polygons:e,polylines:n}}(e),i=r.polygons,o=r.polylines,a=function(t){for(var e=[],n=null,r=null,i=null,o=0,a=t.length,s=0;sWr[1][2]&&(o[0]=-o[0]),Wr[0][2]>Wr[2][0]&&(o[1]=-o[1]),Wr[1][0]>Wr[0][1]&&(o[2]=-o[2])}(function(t){return 0===t.length?[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]:t.map(ca).reduce(ha)}(t),e,n,r,i,o),[[e,n,r,o,i]]}var fa=function(){function t(t,e){for(var n=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],r=0;r<4;r++)for(var i=0;i<4;i++)for(var o=0;o<4;o++)n[r][i]+=e[r][o]*t[o][i];return n}return function(e,n,r,i,o){for(var a=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],s=0;s<4;s++)a[s][3]=o[s];for(var l=0;l<3;l++)for(var u=0;u<3;u++)a[3][l]+=e[u]*a[u][l];var c=i[0],h=i[1],d=i[2],f=i[3],p=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];p[0][0]=1-2*(h*h+d*d),p[0][1]=2*(c*h-d*f),p[0][2]=2*(c*d+h*f),p[1][0]=2*(c*h+d*f),p[1][1]=1-2*(c*c+d*d),p[1][2]=2*(h*d-c*f),p[2][0]=2*(c*d-h*f),p[2][1]=2*(h*d+c*f),p[2][2]=1-2*(c*c+h*h),a=t(a,p);var g=[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]];r[2]&&(g[2][1]=r[2],a=t(a,g)),r[1]&&(g[2][1]=0,g[2][0]=r[0],a=t(a,g)),r[0]&&(g[2][0]=0,g[1][0]=r[0],a=t(a,g));for(var v=0;v<3;v++)for(var m=0;m<3;m++)a[v][m]*=n[v];return function(t){return 0===t[0][2]&&0===t[0][3]&&0===t[1][2]&&0===t[1][3]&&0===t[2][0]&&0===t[2][1]&&1===t[2][2]&&0===t[2][3]&&0===t[3][2]&&1===t[3][3]}(a)?[a[0][0],a[0][1],a[1][0],a[1][1],a[3][0],a[3][1]]:a[0].concat(a[1],a[2],a[3])}}();function pa(t){return t.toFixed(6).replace(".000000","")}function ga(t,e){var n,r;return t.decompositionPair!==e&&(t.decompositionPair=e,n=da(t)),e.decompositionPair!==t&&(e.decompositionPair=t,r=da(e)),null===n[0]||null===r[0]?[[!1],[!0],function(n){return n?e[0].d:t[0].d}]:(n[0].push(0),r[0].push(1),[n,r,function(t){var e=function(t,e,n){var r=function(t,e){for(var n=0,r=0;r2&&void 0!==arguments[2]?arguments[2]:{forceUpdateGeometry:!1};Object.assign(t.attributes,e);var r=t.parsedStyle.clipPath,i=t.parsedStyle.offsetPath;!function(t,e){var n=Sa(t);for(var r in e)n.has(r)&&(t.parsedStyle[r]=e[r])}(t,e);var o=!!n.forceUpdateGeometry;if(!o)for(var s in e)if(wa.has(s)){o=!0;break}var l,u,c=Sa(t);c.has("fill")&&e.fill&&(t.parsedStyle.fill=xo(e.fill)),c.has("stroke")&&e.stroke&&(t.parsedStyle.stroke=xo(e.stroke)),c.has("shadowColor")&&e.shadowColor&&(t.parsedStyle.shadowColor=xo(e.shadowColor)),c.has("filter")&&e.filter&&(t.parsedStyle.filter=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if("none"===(t=t.toLowerCase().trim()))return[];for(var e,n=/\s*([\w-]+)\(([^)]*)\)/g,r=[],i=0;e=n.exec(t);){if(e.index!==i)return[];if(i=e.index+e[0].length,Do.indexOf(e[1])>-1&&r.push({name:e[1],params:e[2].split(" ").map((function(t){return wo(/deg|rad|grad|turn|px|%/g,t)||xo(t)}))}),n.lastIndex===t.length)return r}return[]}(e.filter)),c.has("radius")&&!$t(e.radius)&&(t.parsedStyle.radius=Po(e.radius,4)),c.has("lineDash")&&!$t(e.lineDash)&&(t.parsedStyle.lineDash=Po(e.lineDash,"even")),c.has("points")&&e.points&&(t.parsedStyle.points=(l=e.points,u=ne(l)?l.split(" ").map((function(t){var e=b(t.split(","),2),n=e[0],r=e[1];return[Number(n),Number(r)]})):l,{points:u,totalLength:0,segments:[]})),c.has("d")&&""===e.d&&(t.parsedStyle.d=a({},ti)),c.has("d")&&e.d&&(t.parsedStyle.d=Jo(e.d)),c.has("textTransform")&&e.textTransform&&this.runtime.CSSPropertySyntaxFactory[ei.TEXT_TRANSFORM].calculator(null,null,{value:e.textTransform},t,null),c.has("clipPath")&&!ve(e.clipPath)&&this.runtime.CSSPropertySyntaxFactory[ei.DEFINED_PATH].calculator("clipPath",r,e.clipPath,t,this.runtime),c.has("offsetPath")&&e.offsetPath&&this.runtime.CSSPropertySyntaxFactory[ei.DEFINED_PATH].calculator("offsetPath",i,e.offsetPath,t,this.runtime),c.has("transform")&&e.transform&&(t.parsedStyle.transform=la(e.transform)),c.has("transformOrigin")&&e.transformOrigin&&(t.parsedStyle.transformOrigin=ba(e.transformOrigin)),c.has("markerStart")&&e.markerStart&&(t.parsedStyle.markerStart=this.runtime.CSSPropertySyntaxFactory[ei.MARKER].calculator(null,e.markerStart,e.markerStart,null,null)),c.has("markerEnd")&&e.markerEnd&&(t.parsedStyle.markerEnd=this.runtime.CSSPropertySyntaxFactory[ei.MARKER].calculator(null,e.markerEnd,e.markerEnd,null,null)),c.has("markerMid")&&e.markerMid&&(t.parsedStyle.markerMid=this.runtime.CSSPropertySyntaxFactory[ei.MARKER].calculator("",e.markerMid,e.markerMid,null,null)),c.has("zIndex")&&!$t(e.zIndex)&&this.runtime.CSSPropertySyntaxFactory[ei.Z_INDEX].postProcessor(t),c.has("offsetDistance")&&!$t(e.offsetDistance)&&this.runtime.CSSPropertySyntaxFactory[ei.OFFSET_DISTANCE].postProcessor(t),c.has("transform")&&e.transform&&this.runtime.CSSPropertySyntaxFactory[ei.TRANSFORM].postProcessor(t),c.has("transformOrigin")&&e.transformOrigin&&this.runtime.CSSPropertySyntaxFactory[ei.TRANSFORM_ORIGIN].postProcessor(t),o&&(t.geometry.dirty=!0,t.renderable.boundsDirty=!0,t.renderable.renderBoundsDirty=!0,n.forceUpdateGeometry||this.runtime.sceneGraphService.dirtifyToRoot(t))}},{key:"updateGeometry",value:function(t){var e=t.nodeName,n=this.runtime.geometryUpdaterFactory[e];if(n){var r=t.geometry;r.contentBounds||(r.contentBounds=new Er),r.renderBounds||(r.renderBounds=new Er);var i=t.parsedStyle,o=n.update(i,t),a=o.cx,s=void 0===a?0:a,l=o.cy,u=void 0===l?0:l,c=o.cz,h=void 0===c?0:c,d=o.hwidth,f=void 0===d?0:d,p=o.hheight,g=void 0===p?0:p,v=o.hdepth,m=void 0===v?0:v,y=[Math.abs(f),Math.abs(g),m],b=i.stroke,x=i.lineWidth,E=void 0===x?1:x,w=i.increasedLineWidthForHitTesting,k=void 0===w?0:w,M=i.shadowType,S=void 0===M?"outer":M,N=i.shadowColor,O=i.filter,T=void 0===O?[]:O,C=i.transformOrigin,A=[s,u,h];r.contentBounds.update(A,y);var P=e===hr.POLYLINE||e===hr.POLYGON||e===hr.PATH?Math.SQRT2:.5;if(b&&!b.isNone){var R=((E||0)+(k||0))*P;y[0]+=R,y[1]+=R}if(r.renderBounds.update(A,y),N&&S&&"inner"!==S){var D=r.renderBounds,L=D.min,_=D.max,I=i.shadowBlur||0,j=i.shadowOffsetX||0,B=i.shadowOffsetY||0,F=L[0]-I+j,z=_[0]+I+j,G=L[1]-I+B,V=_[1]+I+B;L[0]=Math.min(L[0],F),_[0]=Math.max(_[0],z),L[1]=Math.min(L[1],G),_[1]=Math.max(_[1],V),r.renderBounds.setMinMax(L,_)}T.forEach((function(t){var e=t.name,n=t.params;if("blur"===e){var i=n[0].value;r.renderBounds.update(r.renderBounds.center,mt(r.renderBounds.halfExtents,r.renderBounds.halfExtents,[i,i,0]))}else if("drop-shadow"===e){var o=n[0].value,a=n[1].value,s=n[2].value,l=r.renderBounds,u=l.min,c=l.max,h=u[0]-s+o,d=c[0]+s+o,f=u[1]-s+a,p=c[1]+s+a;u[0]=Math.min(u[0],h),c[0]=Math.max(c[0],d),u[1]=Math.min(u[1],f),c[1]=Math.max(c[1],p),r.renderBounds.setMinMax(u,c)}})),t.geometry.dirty=!1;var W=g<0,H=(f<0?-1:1)*(C?Ro(C[0],0,t,!0):0),U=(W?-1:1)*(C?Ro(C[1],1,t,!0):0);(H||U)&&t.setOrigin(H,U)}}},{key:"updateSizeAttenuation",value:function(t,e){t.style.isSizeAttenuation?(t.style.rawLineWidth||(t.style.rawLineWidth=t.style.lineWidth),t.style.lineWidth=(t.style.rawLineWidth||1)/e,t.nodeName===hr.CIRCLE&&(t.style.rawR||(t.style.rawR=t.style.r),t.style.r=(t.style.rawR||1)/e)):(t.style.rawLineWidth&&(t.style.lineWidth=t.style.rawLineWidth,delete t.style.rawLineWidth),t.nodeName===hr.CIRCLE&&t.style.rawR&&(t.style.r=t.style.rawR,delete t.style.rawR))}}])}();function Sa(t){return t.constructor.PARSED_STYLE_LIST}var Na=function(){return u((function t(){s(this,t),this.mixer=jo}),[{key:"calculator",value:function(t,e,n,r){return Ao(n)}}])}(),Oa=function(){return u((function t(){s(this,t)}),[{key:"calculator",value:function(t,e,n,r,i){return n instanceof Xi&&(n=null),i.sceneGraphService.updateDisplayObjectDependency(t,e,n,r),"clipPath"===t&&r.forEach((function(t){0===t.childNodes.length&&i.sceneGraphService.dirtifyToRoot(t)})),n}}])}(),Ta=function(){return u((function t(){s(this,t),this.parser=xo,this.mixer=Eo}),[{key:"calculator",value:function(t,e,n,r){return n instanceof Xi?"none"===n.value?ro:io:n}}])}(),Ca=function(){return u((function t(){s(this,t)}),[{key:"calculator",value:function(t,e,n){return n instanceof Xi?[]:n}}])}();function Aa(t){var e=t.parsedStyle.fontSize;return $t(e)?null:e}var Pa=function(){return u((function t(){s(this,t),this.mixer=jo}),[{key:"calculator",value:function(t,e,n,r,i){if(ae(n))return n;if(!Zi.isRelativeUnit(n.unit))return n.value;if(n.unit===Ii.kPercentage)return 0;if(n.unit===Ii.kEms){if(r.parentNode){var o=Aa(r.parentNode);if(o)return o*=n.value}return 0}if(n.unit===Ii.kRems){var a;if(null!=r&&null!==(a=r.ownerDocument)&&void 0!==a&&a.documentElement){var s=Aa(r.ownerDocument.documentElement);if(s)return s*=n.value}return 0}}}])}(),Ra=function(){return u((function t(){s(this,t),this.mixer=Fo}),[{key:"calculator",value:function(t,e,n){return n.map((function(t){return t.value}))}}])}(),Da=function(){return u((function t(){s(this,t),this.mixer=Fo}),[{key:"calculator",value:function(t,e,n){return n.map((function(t){return t.value}))}}])}(),La=function(){return u((function t(){s(this,t)}),[{key:"calculator",value:function(t,e,n,r){var i;n instanceof Xi&&(n=null);var o=null===(i=n)||void 0===i?void 0:i.cloneNode(!0);return o&&(o.style.isMarker=!0),o}}])}(),_a=function(){return u((function t(){s(this,t),this.mixer=jo}),[{key:"calculator",value:function(t,e,n){return n.value}}])}(),Ia=function(){return u((function t(){s(this,t),this.mixer=Bo(0,1)}),[{key:"calculator",value:function(t,e,n){return n.value}},{key:"postProcessor",value:function(t){var e=t.parsedStyle,n=e.offsetPath,r=e.offsetDistance;if(n){var i=n.nodeName;if(i===hr.LINE||i===hr.PATH||i===hr.POLYLINE){var o=n.getPoint(r);o&&t.setLocalPosition(o.x,o.y)}}}}])}(),ja=function(){return u((function t(){s(this,t),this.mixer=Bo(0,1)}),[{key:"calculator",value:function(t,e,n){return n.value}}])}(),Ba=function(){return u((function t(){s(this,t),this.parser=Jo,this.mixer=ta}),[{key:"calculator",value:function(t,e,n){return n instanceof Xi&&"unset"===n.value?{absolutePath:[],hasArc:!1,segments:[],polygons:[],polylines:[],curve:null,totalLength:0,rect:new Nr(0,0,0,0)}:n}}])}(),Fa=u((function t(){s(this,t),this.mixer=ea})),za=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i0&&void 0!==arguments[0]?arguments[0]:"auto",e=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0,r=!1,i=!1,o=!!e&&!e.isNone,a=!!n&&!n.isNone;return"visiblepainted"===t||"painted"===t||"auto"===t?(r=o,i=a):"visiblefill"===t||"fill"===t?r=!0:"visiblestroke"===t||"stroke"===t?i=!0:"visible"!==t&&"all"!==t||(r=!0,i=!0),[r,i]}var Ja=1,ts="object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:{},es=Date.now(),ns={},rs=Date.now(),is=function(t){if("function"!=typeof t)throw new TypeError("".concat(t," is not a function"));var e=Date.now(),n=e-rs,r=n>16?0:16-n,i=Ja++;return ns[i]=t,Object.keys(ns).length>1||setTimeout((function(){rs=e;var t=ns;ns={},Object.keys(t).forEach((function(e){return t[e](ts.performance&&"function"==typeof ts.performance.now?ts.performance.now():Date.now()-es)}))}),r),i},os=function(t){delete ns[t]},as=function(t){return"string"!=typeof t?is:""===t?ts.requestAnimationFrame:ts["".concat(t,"RequestAnimationFrame")]},ss=function(t,e){for(var n=0;void 0!==t[n];){if(e(t[n]))return t[n];n+=1}}(["","webkit","moz","ms","o"],(function(t){return!!as(t)})),ls=as(ss),us=function(t){return"string"!=typeof t?os:""===t?ts.cancelAnimationFrame:ts["".concat(t,"CancelAnimationFrame")]||ts["".concat(t,"CancelRequestAnimationFrame")]}(ss);ts.requestAnimationFrame=ls,ts.cancelAnimationFrame=us;var cs=function(){return u((function t(){s(this,t),this.callbacks=[]}),[{key:"getCallbacksNum",value:function(){return this.callbacks.length}},{key:"tapPromise",value:function(t,e){this.callbacks.push(e)}},{key:"promise",value:function(){for(var t=arguments.length,e=new Array(t),n=0;n1&&void 0!==arguments[1]&&arguments[1],r=Gs.get(this);r||(r=this.document?this:this.defaultView?this.defaultView:null===(e=this.ownerDocument)||void 0===e?void 0:e.defaultView)&&Gs.set(this,r);if(r){if(t.manager=r.getEventService(),!t.manager)return!1;t.defaultPrevented=!1,t.path?t.path.length=0:t.page=[],n||(t.target=this),t.manager.dispatchEvent(t,t.type,n)}else this.emitter.emit(t.type,t);return!t.defaultPrevented}}])}(),Ws=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i0&&void 0!==arguments[0]?arguments[0]:{};return this.parentNode?this.parentNode.getRootNode(t):t.composed&&this.host?this.host.getRootNode(t):this}},{key:"hasChildNodes",value:function(){return this.childNodes.length>0}},{key:"isDefaultNamespace",value:function(t){throw new Error(Or)}},{key:"lookupNamespaceURI",value:function(t){throw new Error(Or)}},{key:"lookupPrefix",value:function(t){throw new Error(Or)}},{key:"normalize",value:function(){throw new Error(Or)}},{key:"isEqualNode",value:function(t){return this===t}},{key:"isSameNode",value:function(t){return this.isEqualNode(t)}},{key:"parent",get:function(){return this.parentNode}},{key:"parentElement",get:function(){return null}},{key:"nextSibling",get:function(){return null}},{key:"previousSibling",get:function(){return null}},{key:"firstChild",get:function(){return this.childNodes.length>0?this.childNodes[0]:null}},{key:"lastChild",get:function(){return this.childNodes.length>0?this.childNodes[this.childNodes.length-1]:null}},{key:"compareDocumentPosition",value:function(t){if(t===this)return 0;for(var n=t,r=this,i=[n],o=[r];null!==(a=n.parentNode)&&void 0!==a?a:r.parentNode;){var a;n=n.parentNode?(i.push(n.parentNode),n.parentNode):n,r=r.parentNode?(o.push(r.parentNode),r.parentNode):r}if(n!==r)return e.DOCUMENT_POSITION_DISCONNECTED|e.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|e.DOCUMENT_POSITION_PRECEDING;var s=i.length>o.length?i:o,l=s===i?o:i;if(s[s.length-l.length]===l[0])return s===i?e.DOCUMENT_POSITION_CONTAINED_BY|e.DOCUMENT_POSITION_FOLLOWING:e.DOCUMENT_POSITION_CONTAINS|e.DOCUMENT_POSITION_PRECEDING;for(var u=s.length-l.length,c=l.length-1;c>=0;c--){var h=l[c],d=s[u+c];if(d!==h){var f=h.parentNode.childNodes;return f.indexOf(h)0&&e;)e=e.parentNode,t--;return e}},{key:"forEach",value:function(t){for(var e=[this];e.length>0;){var n=e.pop();if(!1===t(n))break;for(var r=n.childNodes.length-1;r>=0;r--)e.push(n.childNodes[r])}}}],[{key:"isNode",value:function(t){return!!t.childNodes}}])}(Vs);Ws.DOCUMENT_POSITION_DISCONNECTED=1,Ws.DOCUMENT_POSITION_PRECEDING=2,Ws.DOCUMENT_POSITION_FOLLOWING=4,Ws.DOCUMENT_POSITION_CONTAINS=8,Ws.DOCUMENT_POSITION_CONTAINED_BY=16,Ws.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC=32;var Hs=function(){return u((function t(e,n){var r=this;s(this,t),this.nativeHTMLMap=new WeakMap,this.cursor="default",this.mappingTable={},this.mappingState={trackingData:{}},this.eventPool=new Map,this.tmpMatrix=T(),this.tmpVec3=ht(),this.onPointerDown=function(t){var e=r.createPointerEvent(t);if(r.dispatchEvent(e,"pointerdown"),"touch"===e.pointerType)r.dispatchEvent(e,"touchstart");else if("mouse"===e.pointerType||"pen"===e.pointerType){var n=2===e.button;r.dispatchEvent(e,n?"rightdown":"mousedown")}r.trackingData(t.pointerId).pressTargetsByButton[t.button]=e.composedPath(),r.freeEvent(e)},this.onPointerUp=function(t){var e=Ka.now(),n=r.createPointerEvent(t,void 0,void 0,r.context.config.alwaysTriggerPointerEventOnCanvas?r.rootTarget:void 0);if(r.dispatchEvent(n,"pointerup"),"touch"===n.pointerType)r.dispatchEvent(n,"touchend");else if("mouse"===n.pointerType||"pen"===n.pointerType){var i=2===n.button;r.dispatchEvent(n,i?"rightup":"mouseup")}var o=r.trackingData(t.pointerId),a=r.findMountedTarget(o.pressTargetsByButton[t.button]),s=a;if(a&&!n.composedPath().includes(a)){for(var l=a;l&&!n.composedPath().includes(l);){if(n.currentTarget=l,r.notifyTarget(n,"pointerupoutside"),"touch"===n.pointerType)r.notifyTarget(n,"touchendoutside");else if("mouse"===n.pointerType||"pen"===n.pointerType){var u=2===n.button;r.notifyTarget(n,u?"rightupoutside":"mouseupoutside")}Ws.isNode(l)&&(l=l.parentNode)}delete o.pressTargetsByButton[t.button],s=l}if(s){var c,h=r.clonePointerEvent(n,"click");h.target=s,h.path=[],o.clicksByButton[t.button]||(o.clicksByButton[t.button]={clickCount:0,target:h.target,timeStamp:e});var d=r.context.renderingContext.root.ownerDocument.defaultView,f=o.clicksByButton[t.button];f.target===h.target&&e-f.timeStamp=1;r--)if(t.currentTarget=n[r],this.notifyTarget(t,e),t.propagationStopped||t.propagationImmediatelyStopped)return;if(t.eventPhase=t.AT_TARGET,t.currentTarget=t.target,this.notifyTarget(t,e),!t.propagationStopped&&!t.propagationImmediatelyStopped){var i=n.indexOf(t.currentTarget);t.eventPhase=t.BUBBLING_PHASE;for(var o=i+1;oi||n>o?null:!a&&this.pickHandler(t)||this.rootTarget||null}},{key:"isNativeEventFromCanvas",value:function(t,e){var n,r=null==e?void 0:e.target;if(null!==(n=r)&&void 0!==n&&n.shadowRoot&&(r=e.composedPath()[0]),r){if(r===t)return!0;if(t&&t.contains)return t.contains(r)}return!(null==e||!e.composedPath)&&e.composedPath().indexOf(t)>-1}},{key:"getExistedHTML",value:function(t){if(t.nativeEvent.composedPath)for(var e=0,n=t.nativeEvent.composedPath();e=0;n--){var r=t[n];if(!(r===this.rootTarget||Ws.isNode(r)&&r.parentNode===e))break;e=t[n]}return e}},{key:"getCursor",value:function(t){for(var e=t;e;){var n=Ua(e)&&e.getAttribute("cursor");if(n)return n;e=Ws.isNode(e)&&e.parentNode}}}])}(),Us=function(){return u((function t(){s(this,t)}),[{key:"getOrCreateCanvas",value:function(t,e){if(this.canvas)return this.canvas;if(t||Ol.offscreenCanvas)this.canvas=t||Ol.offscreenCanvas,this.context=this.canvas.getContext("2d",a({willReadFrequently:!0},e));else try{this.canvas=new window.OffscreenCanvas(0,0),this.context=this.canvas.getContext("2d",a({willReadFrequently:!0},e)),this.context&&this.context.measureText||(this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"))}catch(t){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d",a({willReadFrequently:!0},e))}return this.canvas.width=10,this.canvas.height=10,this.canvas}},{key:"getOrCreateContext",value:function(t,e){return this.context||this.getOrCreateCanvas(t,e),this.context}}],[{key:"createCanvas",value:function(){try{return new window.OffscreenCanvas(0,0)}catch(t){}try{return document.createElement("canvas")}catch(t){}return null}}])}(),$s=function(t){return t[t.CAMERA_CHANGED=0]="CAMERA_CHANGED",t[t.DISPLAY_OBJECT_CHANGED=1]="DISPLAY_OBJECT_CHANGED",t[t.NONE=2]="NONE",t}({}),Ys=function(){return u((function t(e,n){s(this,t),this.inited=!1,this.stats={total:0,rendered:0},this.zIndexCounter=0,this.hooks={init:new ds,initAsync:new cs,dirtycheck:new fs,cull:new fs,beginFrame:new ds,beforeRender:new ds,render:new ds,afterRender:new ds,endFrame:new ds,destroy:new ds,pick:new hs,pickSync:new fs,pointerDown:new ds,pointerUp:new ds,pointerMove:new ds,pointerOut:new ds,pointerOver:new ds,pointerWheel:new ds,pointerCancel:new ds,click:new ds},this.globalRuntime=e,this.context=n}),[{key:"init",value:function(t){var e=this,n=a(a({},this.globalRuntime),this.context);this.context.renderingPlugins.forEach((function(t){t.apply(n,e.globalRuntime)})),this.hooks.init.call(),0===this.hooks.initAsync.getCallbacksNum()?(this.inited=!0,t()):this.hooks.initAsync.promise().then((function(){e.inited=!0,t()})).catch((function(t){}))}},{key:"getStats",value:function(){return this.stats}},{key:"disableDirtyRectangleRendering",value:function(){return!this.context.config.renderer.getConfig().enableDirtyRectangleRendering||this.context.renderingContext.renderReasons.has($s.CAMERA_CHANGED)}},{key:"render",value:function(t,e,n){var r=this;this.stats.total=0,this.stats.rendered=0,this.zIndexCounter=0;var i=this.context.renderingContext;if(this.globalRuntime.sceneGraphService.syncHierarchy(i.root),this.globalRuntime.sceneGraphService.triggerPendingEvents(),i.renderReasons.size&&this.inited){i.dirtyRectangleRenderingDisabled=this.disableDirtyRectangleRendering();var o=1===i.renderReasons.size&&i.renderReasons.has($s.CAMERA_CHANGED),a=!t.disableRenderHooks||!(t.disableRenderHooks&&o);a&&this.renderDisplayObject(i.root,t,i),this.hooks.beginFrame.call(e),a&&i.renderListCurrentFrame.forEach((function(t){r.hooks.beforeRender.call(t),r.hooks.render.call(t),r.hooks.afterRender.call(t)})),this.hooks.endFrame.call(e),i.renderListCurrentFrame=[],i.renderReasons.clear(),n()}}},{key:"renderDisplayObject",value:function(t,e,n){var r=this,i=e.renderer.getConfig(),o=i.enableDirtyCheck,a=i.enableCulling;function s(t){var e=t.renderable,i=t.sortable,s=o?e.dirty||n.dirtyRectangleRenderingDisabled?t:null:t;if(s){var l=a?r.hooks.cull.call(s,r.context.camera):s;l&&(r.stats.rendered+=1,n.renderListCurrentFrame.push(l))}e.dirty=!1,i.renderOrder=r.zIndexCounter,r.zIndexCounter+=1,r.stats.total+=1,i.dirty&&(r.sort(t,i),i.dirty=!1,i.dirtyChildren=[],i.dirtyReason=void 0)}for(var l=[t];l.length>0;){var u,c=l.pop();s(c);for(var h=(null===(u=c.sortable)||void 0===u||null===(u=u.sorted)||void 0===u?void 0:u.length)>0?c.sortable.sorted:c.childNodes,d=h.length-1;d>=0;d--)l.push(h[d])}}},{key:"sort",value:function(t,e){var n,r;(null==e||null===(n=e.sorted)||void 0===n?void 0:n.length)>0&&e.dirtyReason!==Jr.Z_INDEX_CHANGED?e.dirtyChildren.forEach((function(n){var r=e.sorted.indexOf(n);if(r>-1&&e.sorted.splice(r,1),t.childNodes.indexOf(n)>-1)if(0===e.sorted.length)e.sorted.push(n);else{var i=function(t,e){for(var n=0,r=t.length;n>>1;$a(t[i],e)<0?n=i+1:r=i}return n}(e.sorted,n);e.sorted.splice(i,0,n)}})):e.sorted=t.childNodes.slice().sort($a),(null===(r=e.sorted)||void 0===r?void 0:r.length)>0&&0===t.childNodes.filter((function(t){return t.parsedStyle.zIndex})).length&&(e.sorted=[])}},{key:"destroy",value:function(){this.inited=!1,this.hooks.destroy.call(),this.globalRuntime.sceneGraphService.clearPendingEvents()}},{key:"dirtify",value:function(){this.context.renderingContext.renderReasons.add($s.DISPLAY_OBJECT_CHANGED)}}])}(),qs=/\[\s*(.*)=(.*)\s*\]/,Xs=function(){return u((function t(){s(this,t)}),[{key:"selectOne",value:function(t,e){var n=this;if(t.startsWith("."))return e.find((function(e){return((null==e?void 0:e.classList)||[]).indexOf(n.getIdOrClassname(t))>-1}));if(t.startsWith("#"))return e.find((function(e){return e.id===n.getIdOrClassname(t)}));if(t.startsWith("[")){var r=this.getAttribute(t),i=r.name,o=r.value;return i?e.find((function(t){return e!==t&&("name"===i?t.name===o:n.attributeToString(t,i)===o)})):null}return e.find((function(n){return e!==n&&n.nodeName===t}))}},{key:"selectAll",value:function(t,e){var n=this;if(t.startsWith("."))return e.findAll((function(r){return e!==r&&((null==r?void 0:r.classList)||[]).indexOf(n.getIdOrClassname(t))>-1}));if(t.startsWith("#"))return e.findAll((function(r){return e!==r&&r.id===n.getIdOrClassname(t)}));if(t.startsWith("[")){var r=this.getAttribute(t),i=r.name,o=r.value;return i?e.findAll((function(t){return e!==t&&("name"===i?t.name===o:n.attributeToString(t,i)===o)})):[]}return e.findAll((function(n){return e!==n&&n.nodeName===t}))}},{key:"is",value:function(t,e){if(t.startsWith("."))return e.className===this.getIdOrClassname(t);if(t.startsWith("#"))return e.id===this.getIdOrClassname(t);if(t.startsWith("[")){var n=this.getAttribute(t),r=n.name,i=n.value;return"name"===r?e.name===i:this.attributeToString(e,r)===i}return e.nodeName===t}},{key:"getIdOrClassname",value:function(t){return t.substring(1)}},{key:"getAttribute",value:function(t){var e=t.match(qs),n="",r="";return e&&e.length>2&&(n=e[1].replace(/"/g,""),r=e[2].replace(/"/g,"")),{name:n,value:r}}},{key:"attributeToString",value:function(t,e){if(!t.getAttribute)return"";var n=t.getAttribute(e);return $t(n)?"":n.toString?n.toString():""}}])}(),Ks=function(t){return t.ATTR_MODIFIED="DOMAttrModified",t.INSERTED="DOMNodeInserted",t.MOUNTED="DOMNodeInsertedIntoDocument",t.REMOVED="removed",t.UNMOUNTED="DOMNodeRemovedFromDocument",t.REPARENT="reparent",t.DESTROY="destroy",t.BOUNDS_CHANGED="bounds-changed",t.CULLED="culled",t}({}),Zs=function(t){function e(t,n,r,i,o,a,l,u){var c;return s(this,e),(c=v(this,e,[null])).relatedNode=n,c.prevValue=r,c.newValue=i,c.attrName=o,c.attrChange=a,c.prevParsedValue=l,c.newParsedValue=u,c.type=t,c}return y(e,t),u(e)}(Is);function Qs(t){var e=t.renderable;e&&(e.renderBoundsDirty=!0,e.boundsDirty=!0)}Zs.ADDITION=2,Zs.MODIFICATION=1,Zs.REMOVAL=3;var Js,tl,el,nl=new Zs(Ks.REPARENT,null,"","","",0,"",""),rl=Vt(),il=ht(),ol=pt(1,1,1),al=T(),sl=Vt(),ll=ht(),ul=T(),cl=Rt(),hl=ht(),dl=Rt(),fl=ht(),pl=ht(),gl=ht(),vl=T(),ml=Rt(),yl=Rt(),bl=Rt(),xl={affectChildren:!0},El=function(){return u((function t(e){s(this,t),this.pendingEvents=new Map,this.boundsChangedEvent=new zs(Ks.BOUNDS_CHANGED),this.displayObjectDependencyMap=new WeakMap,this.runtime=e}),[{key:"matches",value:function(t,e){return this.runtime.sceneGraphSelector.is(t,e)}},{key:"querySelector",value:function(t,e){return this.runtime.sceneGraphSelector.selectOne(t,e)}},{key:"querySelectorAll",value:function(t,e){return this.runtime.sceneGraphSelector.selectAll(t,e)}},{key:"attach",value:function(t,e,n){var r,i=!1;t.parentNode&&(i=t.parentNode!==e,this.detach(t));var o=t.nodeName===hr.FRAGMENT,a=Za(e);t.parentNode=e;var s=o?t.childNodes:[t];ae(n)?s.forEach((function(t){e.childNodes.splice(n,0,t),t.parentNode=e})):s.forEach((function(t){e.childNodes.push(t),t.parentNode=e}));var l=e.sortable;if((null!=l&&null!==(r=l.sorted)&&void 0!==r&&r.length||l.dirty||t.parsedStyle.zIndex)&&(-1===l.dirtyChildren.indexOf(t)&&l.dirtyChildren.push(t),l.dirty=!0,l.dirtyReason=Jr.ADDED),!a){if(o)this.dirtifyFragment(t);else{var u=t.transformable;u&&this.dirtifyWorld(t,u)}i&&t.dispatchEvent(nl)}}},{key:"detach",value:function(t){var e,n;if(t.parentNode){var r=t.transformable,i=t.parentNode.sortable;(null!=i&&null!==(e=i.sorted)&&void 0!==e&&e.length||null!==(n=t.style)&&void 0!==n&&n.zIndex)&&(-1===i.dirtyChildren.indexOf(t)&&i.dirtyChildren.push(t),i.dirty=!0,i.dirtyReason=Jr.REMOVED);var o=t.parentNode.childNodes.indexOf(t);o>-1&&t.parentNode.childNodes.splice(o,1),r&&this.dirtifyWorld(t,r),t.parentNode=null}}},{key:"getOrigin",value:function(t){return t.getGeometryBounds(),t.transformable.origin}},{key:"setOrigin",value:function(t,e){"number"==typeof e&&(e=[e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0]);var n=t.transformable;if(e[0]!==n.origin[0]||e[1]!==n.origin[1]||e[2]!==n.origin[2]){var r=n.origin;r[0]=e[0],r[1]=e[1],r[2]=e[2]||0,this.dirtifyLocal(t,n)}}},{key:"rotate",value:function(t,e){"number"==typeof e&&(e=pt(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0));var n=t.transformable;if(null!==t.parentNode&&t.parentNode.transformable){var r=cl;It(r,e[0],e[1],e[2]);var i=this.getRotation(t),o=this.getRotation(t.parentNode);Bt(bl,o),_t(bl,bl),Lt(r,bl,r),Lt(n.localRotation,r,i),Gt(n.localRotation,n.localRotation),this.dirtifyLocal(t,n)}else this.rotateLocal(t,e)}},{key:"rotateLocal",value:function(t,e){"number"==typeof e&&(e=pt(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0));var n=t.transformable;It(yl,e[0],e[1],e[2]),zt(n.localRotation,n.localRotation,yl),this.dirtifyLocal(t,n)}},{key:"setEulerAngles",value:function(t,e){"number"==typeof e&&(e=pt(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0));var n=t.transformable;if(null!==t.parentNode&&t.parentNode.transformable){It(n.localRotation,e[0],e[1],e[2]);var r=this.getRotation(t.parentNode);Bt(ml,_t(cl,r)),zt(n.localRotation,n.localRotation,ml),this.dirtifyLocal(t,n)}else this.setLocalEulerAngles(t,e)}},{key:"setLocalEulerAngles",value:function(t,e){var n=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];"number"==typeof e&&(e=pt(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0));var r=t.transformable;It(r.localRotation,e[0],e[1],e[2]),n&&this.dirtifyLocal(t,r)}},{key:"translateLocal",value:function(t,e){"number"==typeof e&&(e=pt(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0));var n=t.transformable;St(e,il)||(!function(t,e,n){var r=n[0],i=n[1],o=n[2],a=n[3],s=e[0],l=e[1],u=e[2],c=i*u-o*l,h=o*s-r*u,d=r*l-i*s,f=i*d-o*h,p=o*c-r*d,g=r*h-i*c,v=2*a;c*=v,h*=v,d*=v,f*=2,p*=2,g*=2,t[0]=s+c+f,t[1]=l+h+p,t[2]=u+d+g}(e,e,n.localRotation),mt(n.localPosition,n.localPosition,e),this.dirtifyLocal(t,n))}},{key:"setPosition",value:function(t,e){var n,r=t.transformable;if(gl[0]=e[0],gl[1]=e[1],gl[2]=null!==(n=e[2])&&void 0!==n?n:0,!St(this.getPosition(t),gl)){if(gt(r.position,gl),null!==t.parentNode&&t.parentNode.transformable){var i=t.parentNode.transformable;A(vl,i.worldTransform),_(vl,vl),Mt(r.localPosition,gl,vl)}else gt(r.localPosition,gl);this.dirtifyLocal(t,r)}}},{key:"setLocalPosition",value:function(t,e){var n,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=t.transformable;pl[0]=e[0],pl[1]=e[1],pl[2]=null!==(n=e[2])&&void 0!==n?n:0,St(i.localPosition,pl)||(gt(i.localPosition,pl),r&&this.dirtifyLocal(t,i))}},{key:"scaleLocal",value:function(t,e){var n,r=t.transformable;!function(t,e,n){t[0]=e[0]*n[0],t[1]=e[1]*n[1],t[2]=e[2]*n[2]}(r.localScale,r.localScale,vt(ll,e[0],e[1],null!==(n=e[2])&&void 0!==n?n:1)),this.dirtifyLocal(t,r)}},{key:"setLocalScale",value:function(t,e){var n,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],i=t.transformable;vt(ll,e[0],e[1],null!==(n=e[2])&&void 0!==n?n:i.localScale[2]),St(ll,i.localScale)||(gt(i.localScale,ll),r&&this.dirtifyLocal(t,i))}},{key:"translate",value:function(t,e){"number"==typeof e&&(e=vt(ll,e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,arguments.length>3&&void 0!==arguments[3]?arguments[3]:0)),St(e,il)||(mt(ll,this.getPosition(t),e),this.setPosition(t,ll))}},{key:"setRotation",value:function(t,e,n,r,i){var o=t.transformable;if("number"==typeof e&&(e=jt(e,n,r,i)),null!==t.parentNode&&t.parentNode.transformable){var a=this.getRotation(t.parentNode);Bt(cl,a),_t(cl,cl),Lt(o.localRotation,cl,e),Gt(o.localRotation,o.localRotation),this.dirtifyLocal(t,o)}else this.setLocalRotation(t,e)}},{key:"setLocalRotation",value:function(t,e,n,r,i){var o=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];"number"==typeof e&&(e=Ft(cl,e,n,r,i));var a=t.transformable;Bt(a.localRotation,e),o&&this.dirtifyLocal(t,a)}},{key:"setLocalSkew",value:function(t,e,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];"number"==typeof e&&(e=function(t,e,n){return t[0]=e,t[1]=n,t}(sl,e,n));var i=t.transformable;!function(t,e){t[0]=e[0],t[1]=e[1]}(i.localSkew,e),r&&this.dirtifyLocal(t,i)}},{key:"dirtifyLocal",value:function(t,e){Za(t)||e.localDirtyFlag||(e.localDirtyFlag=!0,e.dirtyFlag||this.dirtifyWorld(t,e))}},{key:"dirtifyWorld",value:function(t,e){e.dirtyFlag||this.unfreezeParentToRoot(t),this.dirtifyWorldInternal(t,e),this.dirtifyToRoot(t,!0)}},{key:"dirtifyFragment",value:function(t){var e=t.transformable;e&&(e.frozen=!1,e.dirtyFlag=!0,e.localDirtyFlag=!0);var n=t.renderable;n&&(n.renderBoundsDirty=!0,n.boundsDirty=!0,n.dirty=!0);for(var r=t.childNodes.length,i=0;i1&&void 0!==arguments[1]&&arguments[1],n=t;for(n.renderable&&(n.renderable.dirty=!0);n;)Qs(n),n=n.parentNode;e&&t.forEach((function(t){Qs(t)})),this.informDependentDisplayObjects(t),this.pendingEvents.set(t,e)}},{key:"updateDisplayObjectDependency",value:function(t,e,n,r){if(e&&e!==n){var i=this.displayObjectDependencyMap.get(e);if(i&&i[t]){var o=i[t].indexOf(r);i[t].splice(o,1)}}if(n){var a=this.displayObjectDependencyMap.get(n);a||(this.displayObjectDependencyMap.set(n,{}),a=this.displayObjectDependencyMap.get(n)),a[t]||(a[t]=[]),a[t].push(r)}}},{key:"informDependentDisplayObjects",value:function(t){var e=this,n=this.displayObjectDependencyMap.get(t);n&&Object.keys(n).forEach((function(t){n[t].forEach((function(n){e.dirtifyToRoot(n,!0),n.dispatchEvent(new Zs(Ks.ATTR_MODIFIED,n,e,e,t,Zs.MODIFICATION,e,e)),n.isCustomElement&&n.isConnected&&n.attributeChangedCallback&&n.attributeChangedCallback(t,e,e)}))}))}},{key:"getPosition",value:function(t){var e=t.transformable;return X(e.position,this.getWorldTransform(t,e))}},{key:"getRotation",value:function(t){var e=t.transformable;return Z(e.rotation,this.getWorldTransform(t,e))}},{key:"getScale",value:function(t){var e=t.transformable;return K(e.scaling,this.getWorldTransform(t,e))}},{key:"getWorldTransform",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t.transformable;return e.localDirtyFlag||e.dirtyFlag?(t.parentNode&&t.parentNode.transformable&&this.getWorldTransform(t.parentNode),this.sync(t,e),e.worldTransform):e.worldTransform}},{key:"getLocalPosition",value:function(t){return t.transformable.localPosition}},{key:"getLocalRotation",value:function(t){return t.transformable.localRotation}},{key:"getLocalScale",value:function(t){return t.transformable.localScale}},{key:"getLocalSkew",value:function(t){return t.transformable.localSkew}},{key:"calcLocalTransform",value:function(t){if(0!==t.localSkew[0]||0!==t.localSkew[1]){Q(t.localTransform,t.localRotation,t.localPosition,pt(1,1,1),t.origin),0===t.localSkew[0]&&0===t.localSkew[1]||(D(ul),ul[4]=Math.tan(t.localSkew[0]),ul[1]=Math.tan(t.localSkew[1]),j(t.localTransform,t.localTransform,ul));var e=Q(ul,Ft(cl,0,0,0,1),vt(ll,1,1,1),t.localScale,t.origin);j(t.localTransform,t.localTransform,e)}else{var n=t.localTransform,r=t.localPosition,i=t.localRotation,o=t.localScale,a=t.origin,s=0!==r[0]||0!==r[1]||0!==r[2],l=1!==i[3]||0!==i[0]||0!==i[1]||0!==i[2],u=1!==o[0]||1!==o[1]||1!==o[2],c=0!==a[0]||0!==a[1]||0!==a[2];l||u||c?Q(n,i,r,o,a):s?V(n,r):D(n)}}},{key:"getLocalTransform",value:function(t){var e=t.transformable;return e.localDirtyFlag&&(this.calcLocalTransform(e),e.localDirtyFlag=!1),e.localTransform}},{key:"setLocalTransform",value:function(t,e){var n=X(hl,e),r=Z(dl,e),i=K(fl,e);this.setLocalScale(t,i,!1),this.setLocalPosition(t,n,!1),this.setLocalRotation(t,r,void 0,void 0,void 0,!1),this.dirtifyLocal(t,t.transformable)}},{key:"resetLocalTransform",value:function(t){this.setLocalScale(t,ol,!1),this.setLocalPosition(t,il,!1),this.setLocalEulerAngles(t,il,void 0,void 0,!1),this.setLocalSkew(t,rl,void 0,!1),this.dirtifyLocal(t,t.transformable)}},{key:"getTransformedGeometryBounds",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2?arguments[2]:void 0,r=this.getGeometryBounds(t,e);if(!Er.isEmpty(r)){var i=n||new Er;return i.setFromTransformedAABB(r,this.getWorldTransform(t)),i}return null}},{key:"getGeometryBounds",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.geometry;return n.dirty&&Ol.styleValueRegistry.updateGeometry(t),(e?n.renderBounds:n.contentBounds||null)||new Er}},{key:"getBounds",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=t.renderable;if(!r.boundsDirty&&!n&&r.bounds)return r.bounds;if(!r.renderBoundsDirty&&n&&r.renderBounds)return r.renderBounds;var i=n?r.renderBounds:r.bounds,o=this.getTransformedGeometryBounds(t,n,i);if(t.childNodes.forEach((function(t){var r=e.getBounds(t,n);r&&(o?o.add(r):(o=i||new Er).update(r.center,r.halfExtents))})),o||(o=new Er),n){var a=Ya(t);if(a){var s=a.parsedStyle.clipPath.getBounds(n);o?s&&(o=s.intersection(o)):o.update(s.center,s.halfExtents)}}return n?(r.renderBounds=o,r.renderBoundsDirty=!1):(r.bounds=o,r.boundsDirty=!1),o}},{key:"getLocalBounds",value:function(t){if(t.parentNode){var e=al;t.parentNode.transformable&&(e=_(ul,this.getWorldTransform(t.parentNode)));var n=this.getBounds(t);if(!Er.isEmpty(n)){var r=new Er;return r.setFromTransformedAABB(n,e),r}}return this.getBounds(t)}},{key:"getBoundingClientRect",value:function(t){var e,n,r=this.getGeometryBounds(t);Er.isEmpty(r)||(n=new Er).setFromTransformedAABB(r,this.getWorldTransform(t));var i=null===(e=t.ownerDocument)||void 0===e||null===(e=e.defaultView)||void 0===e?void 0:e.getContextService().getBoundingClientRect();if(n){var o=b(n.getMin(),2),a=o[0],s=o[1],l=b(n.getMax(),2),u=l[0],c=l[1];return new Nr(a+((null==i?void 0:i.left)||0),s+((null==i?void 0:i.top)||0),u-a,c-s)}return new Nr((null==i?void 0:i.left)||0,(null==i?void 0:i.top)||0,0,0)}},{key:"dirtifyWorldInternal",value:function(t,e){var n=this;if(!e.dirtyFlag){e.dirtyFlag=!0,e.frozen=!1,t.childNodes.forEach((function(t){var e=t.transformable;e.dirtyFlag||n.dirtifyWorldInternal(t,e)}));var r=t.renderable;r&&(r.renderBoundsDirty=!0,r.boundsDirty=!0,r.dirty=!0)}}},{key:"syncHierarchy",value:function(t){var e=t.transformable;if(!e.frozen){e.frozen=!0,(e.localDirtyFlag||e.dirtyFlag)&&this.sync(t,e);for(var n=t.childNodes,r=0;rs;--d){for(var v=0;v=0;f--){var p=d[f].trim();!gs.test(p)&&ps.indexOf(p)<0&&(p='"'.concat(p,'"')),d[f]=p}return"".concat(a," ").concat(l," ").concat(c," ").concat(h," ").concat(d.join(","))}(e),x=this.measureFont(b,n);0===x.fontSize&&(x.fontSize=i,x.ascent=i);var E=this.runtime.offscreenCanvasCreator.getOrCreateContext(n);E.font=b,e.isOverflowing=!1;var w=(a?this.wordWrap(t,e,n):t).split(/(?:\r\n|\r|\n)/),k=new Array(w.length),M=0;if(!v){for(var S=0;Sr&&e>=n;)e-=1,t=t.slice(0,-1);return{lineTxt:t,txtLastCharIndex:e}}function M(t,e){if(!(w<=0||w>f))if(v[t]){var n=k(v[t],e,b+1,f-w);v[t]=n.lineTxt+p}else v[t]=p}for(var S=0;S=c){e.isOverflowing=!0,S0&&y+C>f){var A=k(v[m],S-1,b+1,f);if(A.txtLastCharIndex!==S-1){if(v[m]=A.lineTxt,A.txtLastCharIndex===g.length-1)break;S=A.txtLastCharIndex+1,N=g[S],O=g[S-1],T=g[S+1],C=E(N)}if(m+1>=c){e.isOverflowing=!0,M(m,S-1);break}if(b=S-1,y=0,v[m+=1]="",this.isBreakingSpace(N))continue;this.canBreakInLastChar(N)||(v=this.trimToBreakable(v),y=this.sumTextWidthByCache(v[m]||"",E)),this.shouldBreakByKinsokuShorui(N,T)&&(v=this.trimByKinsokuShorui(v),y+=E(O||""))}y+=C,v[m]=(v[m]||"")+N}}return v.join("\n")}},{key:"isBreakingSpace",value:function(t){return"string"==typeof t&&wl.BreakingSpaces.indexOf(t.charCodeAt(0))>=0}},{key:"isNewline",value:function(t){return"string"==typeof t&&wl.Newlines.indexOf(t.charCodeAt(0))>=0}},{key:"trimToBreakable",value:function(t){var e=d(t),n=e[e.length-2],r=this.findBreakableIndex(n);if(-1===r||!n)return e;var i=n.slice(r,r+1),o=r+1,a=r+(this.isBreakingSpace(i)?0:1);return e[e.length-1]+=n.slice(o,n.length),e[e.length-2]=n.slice(0,a),e}},{key:"canBreakInLastChar",value:function(t){return!t||!kl.test(t)}},{key:"sumTextWidthByCache",value:function(t,e){return t.split("").reduce((function(t,n){return t+e(n)}),0)}},{key:"findBreakableIndex",value:function(t){for(var e=t.length-1;e>=0;e--)if(!kl.test(t[e]))return e;return-1}},{key:"getFromCache",value:function(t,e,n,r){var i=n[t];if("number"!=typeof i){var o=t.length*e;i=r.measureText(t).width+o,n[t]=i}return i}}])}(),Ol={},Tl=(tl=new Rs,el=new Ps,i(i(i(i(i(i(i(i(i(i(Js={},hr.FRAGMENT,null),hr.CIRCLE,new Os),hr.ELLIPSE,new Ts),hr.RECT,tl),hr.IMAGE,tl),hr.GROUP,new Ls),hr.LINE,new Cs),hr.TEXT,new Ds(Ol)),hr.POLYLINE,el),hr.POLYGON,el),i(i(i(Js,hr.PATH,new As),hr.HTML,new _s),hr.MESH,null)),Cl=function(t){var e=new Ta,n=new Pa;return i(i(i(i(i(i(i(i(i(i(t={},ei.PERCENTAGE,null),ei.NUMBER,new _a),ei.ANGLE,new Na),ei.DEFINED_PATH,new Oa),ei.PAINT,e),ei.COLOR,e),ei.FILTER,new Ca),ei.LENGTH,n),ei.LENGTH_PERCENTAGE,n),ei.LENGTH_PERCENTAGE_12,new Ra),i(i(i(i(i(i(i(i(i(i(t,ei.LENGTH_PERCENTAGE_14,new Da),ei.COORDINATE,new Pa),ei.OFFSET_DISTANCE,new Ia),ei.OPACITY_VALUE,new ja),ei.PATH,new Ba),ei.LIST_OF_POINTS,new Fa),ei.SHADOW_BLUR,new za),ei.TEXT,new Ga),ei.TEXT_TRANSFORM,new Va),ei.TRANSFORM,new Ms),i(i(i(t,ei.TRANSFORM_ORIGIN,new Ss),ei.Z_INDEX,new Ns),ei.MARKER,new La)}();Ol.CameraContribution=Zr,Ol.AnimationTimeline=null,Ol.EasingFunction=null,Ol.offscreenCanvasCreator=new Us,Ol.sceneGraphSelector=new Xs,Ol.sceneGraphService=new El(Ol),Ol.textService=new Nl(Ol),Ol.geometryUpdaterFactory=Tl,Ol.CSSPropertySyntaxFactory=Cl,Ol.styleValueRegistry=new Ma(Ol),Ol.layoutRegistry=null,Ol.globalThis="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{},Ol.enableStyleSyntax=!0,Ol.enableSizeAttenuation=!1;var Al=0,Pl=new Zs(Ks.INSERTED,null,"","","",0,"",""),Rl=new Zs(Ks.REMOVED,null,"","","",0,"",""),Dl=new zs(Ks.DESTROY),Ll=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i=0;t--){var e=this.childNodes[t];this.removeChild(e)}}},{key:"destroyChildren",value:function(){for(var t=this.childNodes.length-1;t>=0;t--){var e=this.childNodes[t];e.childNodes.length>0&&e.destroyChildren(),e.destroy()}}},{key:"matches",value:function(t){return Ol.sceneGraphService.matches(t,this)}},{key:"getElementById",value:function(t){return Ol.sceneGraphService.querySelector("#".concat(t),this)}},{key:"getElementsByName",value:function(t){return Ol.sceneGraphService.querySelectorAll('[name="'.concat(t,'"]'),this)}},{key:"getElementsByClassName",value:function(t){return Ol.sceneGraphService.querySelectorAll(".".concat(t),this)}},{key:"getElementsByTagName",value:function(t){return Ol.sceneGraphService.querySelectorAll(t,this)}},{key:"querySelector",value:function(t){return Ol.sceneGraphService.querySelector(t,this)}},{key:"querySelectorAll",value:function(t){return Ol.sceneGraphService.querySelectorAll(t,this)}},{key:"closest",value:function(t){var e=this;do{if(Ol.sceneGraphService.matches(t,e))return e;e=e.parentElement}while(null!==e);return null}},{key:"find",value:function(t){var e=this,n=null;return this.forEach((function(r){return r===e||!t(r)||(n=r,!1)})),n}},{key:"findAll",value:function(t){var e=this,n=[];return this.forEach((function(r){r!==e&&t(r)&&n.push(r)})),n}},{key:"after",value:function(){var t=this;if(this.parentNode){for(var e=this.parentNode.childNodes.indexOf(this),n=arguments.length,r=new Array(n),i=0;i0&&void 0!==arguments[0]?arguments[0]:{};Ol.styleValueRegistry.processProperties(this,t,{forceUpdateGeometry:!0}),this.renderable.dirty=!0}},{key:"setAttribute",value:function(t,n){var r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];ve(n)||(r||n!==this.attributes[t])&&(this.internalSetAttribute(t,n,{memoize:i}),Pn(e,"setAttribute",this)([t,n]))}},{key:"internalSetAttribute",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=this.renderable,o=this.attributes[t],a=this.parsedStyle[t];Ol.styleValueRegistry.processProperties(this,i({},t,e),n),r.dirty=!0;var s,l=this.parsedStyle[t];(this.isConnected&&(jl.relatedNode=this,jl.prevValue=o,jl.newValue=e,jl.attrName=t,jl.prevParsedValue=a,jl.newParsedValue=l,this.isMutationObserved?this.dispatchEvent(jl):(jl.target=this,this.ownerDocument.defaultView.dispatchEvent(jl,!0))),this.isCustomElement&&this.isConnected||!this.isCustomElement)&&(null===(s=this.attributeChangedCallback)||void 0===s||s.call(this,t,o,e,a,l))}},{key:"getBBox",value:function(){var t=this.getBounds(),e=b(t.getMin(),2),n=e[0],r=e[1],i=b(t.getMax(),2),o=i[0],a=i[1];return new Nr(n,r,o-n,a-r)}},{key:"setOrigin",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Ol.sceneGraphService.setOrigin(this,Pr(t,e,n,!1)),this}},{key:"getOrigin",value:function(){return Ol.sceneGraphService.getOrigin(this)}},{key:"setPosition",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Ol.sceneGraphService.setPosition(this,Pr(t,e,n,!1)),this}},{key:"setLocalPosition",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Ol.sceneGraphService.setLocalPosition(this,Pr(t,e,n,!1)),this}},{key:"translate",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Ol.sceneGraphService.translate(this,Pr(t,e,n,!1)),this}},{key:"translateLocal",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return Ol.sceneGraphService.translateLocal(this,Pr(t,e,n,!1)),this}},{key:"getPosition",value:function(){return Ol.sceneGraphService.getPosition(this)}},{key:"getLocalPosition",value:function(){return Ol.sceneGraphService.getLocalPosition(this)}},{key:"scale",value:function(t,e,n){return this.scaleLocal(t,e,n)}},{key:"scaleLocal",value:function(t,e,n){return"number"==typeof t&&(t=Pr(t,e=e||t,n=n||t,!1)),Ol.sceneGraphService.scaleLocal(this,t),this}},{key:"setLocalScale",value:function(t,e,n){return"number"==typeof t&&(t=Pr(t,e=e||t,n=n||t,!1)),Ol.sceneGraphService.setLocalScale(this,t),this}},{key:"getLocalScale",value:function(){return Ol.sceneGraphService.getLocalScale(this)}},{key:"getScale",value:function(){return Ol.sceneGraphService.getScale(this)}},{key:"getEulerAngles",value:function(){return _r(b(jr(Bl,Ol.sceneGraphService.getWorldTransform(this)),3)[2])}},{key:"getLocalEulerAngles",value:function(){return _r(b(jr(Bl,Ol.sceneGraphService.getLocalRotation(this)),3)[2])}},{key:"setEulerAngles",value:function(t){return Ol.sceneGraphService.setEulerAngles(this,0,0,t),this}},{key:"setLocalEulerAngles",value:function(t){return Ol.sceneGraphService.setLocalEulerAngles(this,0,0,t),this}},{key:"rotateLocal",value:function(t,e,n){return $t(e)&&$t(n)?Ol.sceneGraphService.rotateLocal(this,0,0,t):Ol.sceneGraphService.rotateLocal(this,t,e,n),this}},{key:"rotate",value:function(t,e,n){return $t(e)&&$t(n)?Ol.sceneGraphService.rotate(this,0,0,t):Ol.sceneGraphService.rotate(this,t,e,n),this}},{key:"setRotation",value:function(t,e,n,r){return Ol.sceneGraphService.setRotation(this,t,e,n,r),this}},{key:"setLocalRotation",value:function(t,e,n,r){return Ol.sceneGraphService.setLocalRotation(this,t,e,n,r),this}},{key:"setLocalSkew",value:function(t,e){return Ol.sceneGraphService.setLocalSkew(this,t,e),this}},{key:"getRotation",value:function(){return Ol.sceneGraphService.getRotation(this)}},{key:"getLocalRotation",value:function(){return Ol.sceneGraphService.getLocalRotation(this)}},{key:"getLocalSkew",value:function(){return Ol.sceneGraphService.getLocalSkew(this)}},{key:"getLocalTransform",value:function(){return Ol.sceneGraphService.getLocalTransform(this)}},{key:"getWorldTransform",value:function(){return Ol.sceneGraphService.getWorldTransform(this)}},{key:"setLocalTransform",value:function(t){return Ol.sceneGraphService.setLocalTransform(this,t),this}},{key:"resetLocalTransform",value:function(){Ol.sceneGraphService.resetLocalTransform(this)}},{key:"getAnimations",value:function(){return this.activeAnimations}},{key:"animate",value:function(t,e){var n,r=null===(n=this.ownerDocument)||void 0===n?void 0:n.timeline;return r?r.play(this,t,e):null}},{key:"isVisible",value:function(){var t;return"hidden"!==(null===(t=this.parsedStyle)||void 0===t?void 0:t.visibility)}},{key:"interactive",get:function(){return this.isInteractive()},set:function(t){this.style.pointerEvents=t?"auto":"none"}},{key:"isInteractive",value:function(){var t;return"none"!==(null===(t=this.parsedStyle)||void 0===t?void 0:t.pointerEvents)}},{key:"isCulled",value:function(){return!(!this.cullable||!this.cullable.enable||this.cullable.visible)}},{key:"toFront",value:function(){return this.parentNode&&(this.style.zIndex=Math.max.apply(Math,d(this.parentNode.children.map((function(t){return Number(t.style.zIndex)}))))+1),this}},{key:"toBack",value:function(){return this.parentNode&&(this.style.zIndex=Math.min.apply(Math,d(this.parentNode.children.map((function(t){return Number(t.style.zIndex)}))))-1),this}},{key:"getConfig",value:function(){return this.config}},{key:"attr",value:function(){for(var t=this,e=arguments.length,n=new Array(e),r=0;r1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.setPosition(t,e,n),this}},{key:"move",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;return this.setPosition(t,e,n),this}},{key:"setZIndex",value:function(t){return this.style.zIndex=t,this}}])}(Ll);zl.PARSED_STYLE_LIST=new Set(["class","className","clipPath","cursor","display","draggable","droppable","fill","fillOpacity","fillRule","filter","increasedLineWidthForHitTesting","lineCap","lineDash","lineDashOffset","lineJoin","lineWidth","miterLimit","hitArea","offsetDistance","offsetPath","offsetX","offsetY","opacity","pointerEvents","shadowColor","shadowType","shadowBlur","shadowOffsetX","shadowOffsetY","stroke","strokeOpacity","strokeWidth","strokeLinecap","strokeLineJoin","strokeDasharray","strokeDashoffset","transform","transformOrigin","textTransform","visibility","zIndex"]);var Gl=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),v(this,e,[a({type:hr.CIRCLE},t)])}return y(e,t),u(e)}(zl);Gl.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["cx","cy","cz","r","isBillboard","isSizeAttenuation"]));var Vl=["style"],Wl=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.style,i=lr(n,Vl);return s(this,e),(t=v(this,e,[a({style:r},i)])).isCustomElement=!0,t}return y(e,t),u(e)}(zl);Wl.PARSED_STYLE_LIST=new Set(["class","className","clipPath","cursor","draggable","droppable","opacity","pointerEvents","transform","transformOrigin","zIndex","visibility"]);var Hl=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),v(this,e,[a({type:hr.ELLIPSE},t)])}return y(e,t),u(e)}(zl);Hl.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["cx","cy","cz","rx","ry","isBillboard","isSizeAttenuation"])),(function(t){function e(){return s(this,e),v(this,e,[{type:hr.FRAGMENT}])}return y(e,t),u(e)}(zl)).PARSED_STYLE_LIST=new Set(["class","className"]);var Ul=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),v(this,e,[a({type:hr.GROUP},t)])}return y(e,t),u(e)}(zl);Ul.PARSED_STYLE_LIST=new Set(["class","className","clipPath","cursor","draggable","droppable","opacity","pointerEvents","transform","transformOrigin","zIndex","visibility"]);var $l=["style"],Yl=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.style,i=lr(n,$l);return s(this,e),(t=v(this,e,[a({type:hr.HTML,style:r},i)])).cullable.enable=!1,t}return y(e,t),u(e,[{key:"getDomElement",value:function(){return this.parsedStyle.$el}},{key:"getClientRects",value:function(){return[this.getBoundingClientRect()]}},{key:"getLocalBounds",value:function(){if(this.parentNode){var t=_(T(),this.parentNode.getWorldTransform()),e=this.getBounds();if(!Er.isEmpty(e)){var n=new Er;return n.setFromTransformedAABB(e,t),n}}return this.getBounds()}}])}(zl);Yl.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["x","y","$el","innerHTML","width","height"]));var ql=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),v(this,e,[a({type:hr.IMAGE},t)])}return y(e,t),u(e)}(zl);ql.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["x","y","z","src","width","height","isBillboard","billboardRotation","isSizeAttenuation","keepAspectRatio"]));var Xl=["style"],Kl=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.style,i=lr(n,Xl);s(this,e),(t=v(this,e,[a({type:hr.LINE,style:a({x1:0,y1:0,x2:0,y2:0,z1:0,z2:0},r)},i)])).markerStartAngle=0,t.markerEndAngle=0;var o=t.parsedStyle,l=o.markerStart,u=o.markerEnd;return l&&_l(l)&&(t.markerStartAngle=l.getLocalEulerAngles(),t.appendChild(l)),u&&_l(u)&&(t.markerEndAngle=u.getLocalEulerAngles(),t.appendChild(u)),t.transformMarker(!0),t.transformMarker(!1),t}return y(e,t),u(e,[{key:"attributeChangedCallback",value:function(t,e,n,r,i){"x1"===t||"y1"===t||"x2"===t||"y2"===t||"markerStartOffset"===t||"markerEndOffset"===t?(this.transformMarker(!0),this.transformMarker(!1)):"markerStart"===t?(r&&_l(r)&&(this.markerStartAngle=0,r.remove()),i&&_l(i)&&(this.markerStartAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!0))):"markerEnd"===t&&(r&&_l(r)&&(this.markerEndAngle=0,r.remove()),i&&_l(i)&&(this.markerEndAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!1)))}},{key:"transformMarker",value:function(t){var e=this.parsedStyle,n=e.markerStart,r=e.markerEnd,i=e.markerStartOffset,o=e.markerEndOffset,a=e.x1,s=e.x2,l=e.y1,u=e.y2,c=t?n:r;if(c&&_l(c)){var h,d,f,p,g,v,m;t?(p=a,g=l,d=s-a,f=u-l,v=i||0,m=this.markerStartAngle):(p=s,g=u,d=a-s,f=l-u,v=o||0,m=this.markerEndAngle),h=Math.atan2(f,d),c.setLocalEulerAngles(180*h/Math.PI+m),c.setLocalPosition(p+Math.cos(h)*v,g+Math.sin(h)*v)}}},{key:"getPoint",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.parsedStyle,r=Fn(n.x1,n.y1,n.x2,n.y2,t),i=r.x,o=r.y,a=Mt(ht(),pt(i,o,0),e?this.getWorldTransform():this.getLocalTransform());return new Sr(a[0],a[1])}},{key:"getPointAtLength",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.getPoint(t/this.getTotalLength(),e)}},{key:"getTotalLength",value:function(){var t=this.parsedStyle;return Bn(t.x1,t.y1,t.x2,t.y2)}}])}(zl);Kl.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["x1","y1","x2","y2","z1","z2","isBillboard","isSizeAttenuation","markerStart","markerEnd","markerStartOffset","markerEndOffset"]));var Zl=["style"],Ql=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.style,i=lr(n,Zl);s(this,e),(t=v(this,e,[a({type:hr.PATH,style:r,initialParsedStyle:{miterLimit:4,d:a({},ti)}},i)])).markerStartAngle=0,t.markerEndAngle=0,t.markerMidList=[];var o=t.parsedStyle,l=o.markerStart,u=o.markerEnd,c=o.markerMid;return l&&_l(l)&&(t.markerStartAngle=l.getLocalEulerAngles(),t.appendChild(l)),c&&_l(c)&&t.placeMarkerMid(c),u&&_l(u)&&(t.markerEndAngle=u.getLocalEulerAngles(),t.appendChild(u)),t.transformMarker(!0),t.transformMarker(!1),t}return y(e,t),u(e,[{key:"attributeChangedCallback",value:function(t,e,n,r,i){"d"===t?(this.transformMarker(!0),this.transformMarker(!1),this.placeMarkerMid(this.parsedStyle.markerMid)):"markerStartOffset"===t||"markerEndOffset"===t?(this.transformMarker(!0),this.transformMarker(!1)):"markerStart"===t?(r&&_l(r)&&(this.markerStartAngle=0,r.remove()),i&&_l(i)&&(this.markerStartAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!0))):"markerEnd"===t?(r&&_l(r)&&(this.markerEndAngle=0,r.remove()),i&&_l(i)&&(this.markerEndAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!1))):"markerMid"===t&&this.placeMarkerMid(i)}},{key:"transformMarker",value:function(t){var e=this.parsedStyle,n=e.markerStart,r=e.markerEnd,i=e.markerStartOffset,o=e.markerEndOffset,a=t?n:r;if(a&&_l(a)){var s,l,u,c,h,d,f;if(t){var p=b(this.getStartTangent(),2),g=p[0],v=p[1];c=v[0],h=v[1],l=g[0]-v[0],u=g[1]-v[1],d=i||0,f=this.markerStartAngle}else{var m=b(this.getEndTangent(),2),y=m[0],x=m[1];c=x[0],h=x[1],l=y[0]-x[0],u=y[1]-x[1],d=o||0,f=this.markerEndAngle}s=Math.atan2(u,l),a.setLocalEulerAngles(180*s/Math.PI+f),a.setLocalPosition(c+Math.cos(s)*d,h+Math.sin(s)*d)}}},{key:"placeMarkerMid",value:function(t){var e=this.parsedStyle.d.segments;if(this.markerMidList.forEach((function(t){t.remove()})),t&&_l(t))for(var n=1;n1&&void 0!==arguments[1]&&arguments[1],n=function(t,e,n){return Mn(t,e,Be(Be({},n),{bbox:!1,length:!0})).point}(this.parsedStyle.d.absolutePath,t),r=n.x,i=n.y,o=Mt(ht(),pt(r,i,0),e?this.getWorldTransform():this.getLocalTransform());return new Sr(o[0],o[1])}},{key:"getPoint",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.getPointAtLength(t*zo(this),e)}},{key:"getStartTangent",value:function(){var t=this.parsedStyle.d.segments,e=[];if(t.length>1){var n=t[0].currentPoint,r=t[1].currentPoint,i=t[1].startTangent;e=[],i?(e.push([n[0]-i[0],n[1]-i[1]]),e.push([n[0],n[1]])):(e.push([r[0],r[1]]),e.push([n[0],n[1]]))}return e}},{key:"getEndTangent",value:function(){var t=this.parsedStyle.d.segments,e=t.length,n=[];if(e>1){var r=t[e-2].currentPoint,i=t[e-1].currentPoint,o=t[e-1].endTangent;n=[],o?(n.push([i[0]-o[0],i[1]-o[1]]),n.push([i[0],i[1]])):(n.push([r[0],r[1]]),n.push([i[0],i[1]]))}return n}}])}(zl);Ql.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["d","markerStart","markerMid","markerEnd","markerStartOffset","markerEndOffset","isBillboard","isSizeAttenuation"]));var Jl=["style"],tu=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=n.style,i=lr(n,Jl);s(this,e),(t=v(this,e,[a({type:hr.POLYGON,style:r,initialParsedStyle:{points:{points:[],totalLength:0,segments:[]},miterLimit:4,isClosed:!0}},i)])).markerStartAngle=0,t.markerEndAngle=0,t.markerMidList=[];var o=t.parsedStyle,l=o.markerStart,u=o.markerEnd,c=o.markerMid;return l&&_l(l)&&(t.markerStartAngle=l.getLocalEulerAngles(),t.appendChild(l)),c&&_l(c)&&t.placeMarkerMid(c),u&&_l(u)&&(t.markerEndAngle=u.getLocalEulerAngles(),t.appendChild(u)),t.transformMarker(!0),t.transformMarker(!1),t}return y(e,t),u(e,[{key:"attributeChangedCallback",value:function(t,e,n,r,i){"points"===t?(this.transformMarker(!0),this.transformMarker(!1),this.placeMarkerMid(this.parsedStyle.markerMid)):"markerStartOffset"===t||"markerEndOffset"===t?(this.transformMarker(!0),this.transformMarker(!1)):"markerStart"===t?(r&&_l(r)&&(this.markerStartAngle=0,r.remove()),i&&_l(i)&&(this.markerStartAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!0))):"markerEnd"===t?(r&&_l(r)&&(this.markerEndAngle=0,r.remove()),i&&_l(i)&&(this.markerEndAngle=i.getLocalEulerAngles(),this.appendChild(i),this.transformMarker(!1))):"markerMid"===t&&this.placeMarkerMid(i)}},{key:"transformMarker",value:function(t){var e=this.parsedStyle,n=e.markerStart,r=e.markerEnd,i=e.markerStartOffset,o=e.markerEndOffset,a=(e.points||{}).points,s=t?n:r;if(s&&_l(s)&&a){var l,u,c,h,d,f,p;if(h=a[0][0],d=a[0][1],t)u=a[1][0]-a[0][0],c=a[1][1]-a[0][1],f=i||0,p=this.markerStartAngle;else{var g=a.length;this.parsedStyle.isClosed?(u=a[g-1][0]-a[0][0],c=a[g-1][1]-a[0][1]):(h=a[g-1][0],d=a[g-1][1],u=a[g-2][0]-a[g-1][0],c=a[g-2][1]-a[g-1][1]),f=o||0,p=this.markerEndAngle}l=Math.atan2(c,u),s.setLocalEulerAngles(180*l/Math.PI+p),s.setLocalPosition(h+Math.cos(l)*f,d+Math.sin(l)*f)}}},{key:"placeMarkerMid",value:function(t){var e=(this.parsedStyle.points||{}).points;if(this.markerMidList.forEach((function(t){t.remove()})),this.markerMidList=[],t&&_l(t)&&e)for(var n=1;n<(this.parsedStyle.isClosed?e.length:e.length-1);n++){var r=e[n][0],i=e[n][1],o=1===n?t:t.cloneNode(!0);this.markerMidList.push(o),this.appendChild(o),o.setLocalPosition(r,i)}}}])}(zl);tu.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["points","markerStart","markerMid","markerEnd","markerStartOffset","markerEndOffset","isClosed","isBillboard","isSizeAttenuation"]));var eu=["style"],nu=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.style,r=lr(t,eu);return s(this,e),v(this,e,[a({type:hr.POLYLINE,style:n,initialParsedStyle:{points:{points:[],totalLength:0,segments:[]},miterLimit:4,isClosed:!1}},r)])}return y(e,t),u(e,[{key:"getTotalLength",value:function(){return 0===(t=this).parsedStyle.points.totalLength&&(t.parsedStyle.points.totalLength=Un(t.parsedStyle.points.points)),t.parsedStyle.points.totalLength;var t}},{key:"getPointAtLength",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.getPoint(t/this.getTotalLength(),e)}},{key:"getPoint",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=this.parsedStyle.points.points;if(0===this.parsedStyle.points.segments.length){var r,i,o=[],a=0,s=this.getTotalLength();n.forEach((function(t,e){n[e+1]&&((r=[0,0])[0]=a/s,i=Bn(t[0],t[1],n[e+1][0],n[e+1][1]),a+=i,r[1]=a/s,o.push(r))})),this.parsedStyle.points.segments=o}var l=0,u=0;this.parsedStyle.points.segments.forEach((function(e,n){t>=e[0]&&t<=e[1]&&(l=(t-e[0])/(e[1]-e[0]),u=n)}));var c=Fn(n[u][0],n[u][1],n[u+1][0],n[u+1][1],l),h=c.x,d=c.y,f=Mt(ht(),pt(h,d,0),e?this.getWorldTransform():this.getLocalTransform());return new Sr(f[0],f[1])}},{key:"getStartTangent",value:function(){var t=this.parsedStyle.points.points,e=[];return e.push([t[1][0],t[1][1]]),e.push([t[0][0],t[0][1]]),e}},{key:"getEndTangent",value:function(){var t=this.parsedStyle.points.points,e=t.length-1,n=[];return n.push([t[e-1][0],t[e-1][1]]),n.push([t[e][0],t[e][1]]),n}}])}(tu);nu.PARSED_STYLE_LIST=new Set([].concat(d(tu.PARSED_STYLE_LIST),["points","markerStart","markerMid","markerEnd","markerStartOffset","markerEndOffset","isBillboard"]));var ru=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),v(this,e,[a({type:hr.RECT},t)])}return y(e,t),u(e)}(zl);ru.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["x","y","z","width","height","isBillboard","isSizeAttenuation","radius"]));var iu=["style"],ou=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.style,r=lr(t,iu);return s(this,e),v(this,e,[a({type:hr.TEXT,style:a({fill:"black"},n)},r)])}return y(e,t),u(e,[{key:"getComputedTextLength",value:function(){var t;return this.getGeometryBounds(),(null===(t=this.parsedStyle.metrics)||void 0===t?void 0:t.maxLineWidth)||0}},{key:"getLineBoundingRects",value:function(){var t;return this.getGeometryBounds(),(null===(t=this.parsedStyle.metrics)||void 0===t?void 0:t.lineMetrics)||[]}},{key:"isOverflowing",value:function(){return this.getGeometryBounds(),!!this.parsedStyle.isOverflowing}}])}(zl);ou.PARSED_STYLE_LIST=new Set([].concat(d(zl.PARSED_STYLE_LIST),["x","y","z","isBillboard","billboardRotation","isSizeAttenuation","text","textAlign","textBaseline","fontStyle","fontSize","fontFamily","fontWeight","fontVariant","lineHeight","letterSpacing","leading","wordWrap","wordWrapWidth","maxLines","textOverflow","isOverflowing","textPath","textDecorationLine","textDecorationColor","textDecorationStyle","textPathSide","textPathStartOffset","metrics","dx","dy"]));var au=function(){return u((function t(){s(this,t),this.registry={},this.define(hr.CIRCLE,Gl),this.define(hr.ELLIPSE,Hl),this.define(hr.RECT,ru),this.define(hr.IMAGE,ql),this.define(hr.LINE,Kl),this.define(hr.GROUP,Ul),this.define(hr.PATH,Ql),this.define(hr.POLYGON,tu),this.define(hr.POLYLINE,nu),this.define(hr.TEXT,ou),this.define(hr.HTML,Yl)}),[{key:"define",value:function(t,e){this.registry[t]=e}},{key:"get",value:function(t){return this.registry[t]}}])}(),su=function(t){function e(){var t;s(this,e),(t=v(this,e)).defaultView=null,t.ownerDocument=null,t.nodeName="document";try{t.timeline=new Ol.AnimationTimeline(t)}catch(t){}var n={};return Ea.forEach((function(t){var e=t.n,r=t.inh,i=t.d;r&&i&&(n[e]=Ut(i)?i(hr.GROUP):i)})),t.documentElement=new Ul({id:"g-root",style:n}),t.documentElement.ownerDocument=t,t.documentElement.parentNode=t,t.childNodes=[t.documentElement],t}return y(e,t),u(e,[{key:"children",get:function(){return this.childNodes}},{key:"childElementCount",get:function(){return this.childNodes.length}},{key:"firstElementChild",get:function(){return this.firstChild}},{key:"lastElementChild",get:function(){return this.lastChild}},{key:"createElement",value:function(t,e){if("svg"===t)return this.documentElement;var n=this.defaultView.customElements.get(t);n||(console.warn("Unsupported tagName: ",t),n="tspan"===t?ou:Ul);var r=new n(e);return r.ownerDocument=this,r}},{key:"createElementNS",value:function(t,e,n){return this.createElement(e,n)}},{key:"cloneNode",value:function(t){throw new Error(Or)}},{key:"destroy",value:function(){try{this.documentElement.destroyChildren(),this.timeline.destroy()}catch(t){}}},{key:"elementsFromBBox",value:function(t,e,n,r){var i=this.defaultView.context.rBushRoot.search({minX:t,minY:e,maxX:n,maxY:r}),o=[];return i.forEach((function(t){var e=t.displayObject,n=e.parsedStyle.pointerEvents,r=["auto","visiblepainted","visiblefill","visiblestroke","visible"].includes(void 0===n?"auto":n);(!r||r&&e.isVisible())&&!e.isCulled()&&e.isInteractive()&&o.push(e)})),o.sort((function(t,e){return e.sortable.renderOrder-t.sortable.renderOrder})),o}},{key:"elementFromPointSync",value:function(t,e){var n=this.defaultView.canvas2Viewport({x:t,y:e}),r=n.x,i=n.y,o=this.defaultView.getConfig(),a=o.width,s=o.height;if(r<0||i<0||r>a||i>s)return null;var l=this.defaultView.viewport2Client({x:r,y:i}),u=l.x,c=l.y,h=this.defaultView.getRenderingService().hooks.pickSync.call({topmost:!0,position:{x:t,y:e,viewportX:r,viewportY:i,clientX:u,clientY:c},picked:[]}).picked;return h&&h[0]||this.documentElement}},{key:"elementFromPoint",value:(r=ar(ir().mark((function t(e,n){var r,i,o,a,s,l,u,c,h,d,f;return ir().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(r=this.defaultView.canvas2Viewport({x:e,y:n}),i=r.x,o=r.y,a=this.defaultView.getConfig(),s=a.width,l=a.height,!(i<0||o<0||i>s||o>l)){t.next=4;break}return t.abrupt("return",null);case 4:return u=this.defaultView.viewport2Client({x:i,y:o}),c=u.x,h=u.y,t.next=7,this.defaultView.getRenderingService().hooks.pick.promise({topmost:!0,position:{x:e,y:n,viewportX:i,viewportY:o,clientX:c,clientY:h},picked:[]});case 7:return d=t.sent,f=d.picked,t.abrupt("return",f&&f[0]||this.documentElement);case 10:case"end":return t.stop()}}),t,this)}))),function(t,e){return r.apply(this,arguments)})},{key:"elementsFromPointSync",value:function(t,e){var n=this.defaultView.canvas2Viewport({x:t,y:e}),r=n.x,i=n.y,o=this.defaultView.getConfig(),a=o.width,s=o.height;if(r<0||i<0||r>a||i>s)return[];var l=this.defaultView.viewport2Client({x:r,y:i}),u=l.x,c=l.y,h=this.defaultView.getRenderingService().hooks.pickSync.call({topmost:!1,position:{x:t,y:e,viewportX:r,viewportY:i,clientX:u,clientY:c},picked:[]}).picked;return h[h.length-1]!==this.documentElement&&h.push(this.documentElement),h}},{key:"elementsFromPoint",value:(n=ar(ir().mark((function t(e,n){var r,i,o,a,s,l,u,c,h,d,f;return ir().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(r=this.defaultView.canvas2Viewport({x:e,y:n}),i=r.x,o=r.y,a=this.defaultView.getConfig(),s=a.width,l=a.height,!(i<0||o<0||i>s||o>l)){t.next=4;break}return t.abrupt("return",[]);case 4:return u=this.defaultView.viewport2Client({x:i,y:o}),c=u.x,h=u.y,t.next=7,this.defaultView.getRenderingService().hooks.pick.promise({topmost:!1,position:{x:e,y:n,viewportX:i,viewportY:o,clientX:c,clientY:h},picked:[]});case 7:return d=t.sent,(f=d.picked)[f.length-1]!==this.documentElement&&f.push(this.documentElement),t.abrupt("return",f);case 11:case"end":return t.stop()}}),t,this)}))),function(t,e){return n.apply(this,arguments)})},{key:"appendChild",value:function(t,e){throw new Error(Tr)}},{key:"insertBefore",value:function(t,e){throw new Error(Tr)}},{key:"removeChild",value:function(t,e){throw new Error(Tr)}},{key:"replaceChild",value:function(t,e,n){throw new Error(Tr)}},{key:"append",value:function(){throw new Error(Tr)}},{key:"prepend",value:function(){throw new Error(Tr)}},{key:"getElementById",value:function(t){return this.documentElement.getElementById(t)}},{key:"getElementsByName",value:function(t){return this.documentElement.getElementsByName(t)}},{key:"getElementsByTagName",value:function(t){return this.documentElement.getElementsByTagName(t)}},{key:"getElementsByClassName",value:function(t){return this.documentElement.getElementsByClassName(t)}},{key:"querySelector",value:function(t){return this.documentElement.querySelector(t)}},{key:"querySelectorAll",value:function(t){return this.documentElement.querySelectorAll(t)}},{key:"find",value:function(t){return this.documentElement.find(t)}},{key:"findAll",value:function(t){return this.documentElement.findAll(t)}}]);var n,r}(Ws),lu=function(){function t(e){s(this,t),this.strategies=e}return u(t,[{key:"apply",value:function(e){var n=e.camera,r=e.renderingService,i=e.renderingContext,o=this.strategies;r.hooks.cull.tap(t.tag,(function(t){if(t){var e=t.cullable;return 0===o.length?e.visible=i.unculledEntities.indexOf(t.entity)>-1:e.visible=o.every((function(e){return e.isVisible(n,t)})),!t.isCulled()&&t.isVisible()?t:(t.dispatchEvent(new zs(Ks.CULLED)),null)}return t})),r.hooks.afterRender.tap(t.tag,(function(t){t.cullable.visibilityPlaneMask=-1}))}}])}();lu.tag="Culling";var uu=function(){function t(){var e=this;s(this,t),this.autoPreventDefault=!1,this.rootPointerEvent=new Bs(null),this.rootWheelEvent=new Fs(null),this.onPointerMove=function(t){var n,r=null===(n=e.context.renderingContext.root)||void 0===n||null===(n=n.ownerDocument)||void 0===n?void 0:n.defaultView;if(!r.supportsTouchEvents||"touch"!==t.pointerType){var i,o=sr(e.normalizeToPointerEvent(t,r));try{for(o.s();!(i=o.n()).done;){var a=i.value,s=e.bootstrapEvent(e.rootPointerEvent,a,r,t);e.context.eventService.mapEvent(s)}}catch(t){o.e(t)}finally{o.f()}e.setCursor(e.context.eventService.cursor)}},this.onClick=function(t){var n,r,i=null===(n=e.context.renderingContext.root)||void 0===n||null===(n=n.ownerDocument)||void 0===n?void 0:n.defaultView,o=sr(e.normalizeToPointerEvent(t,i));try{for(o.s();!(r=o.n()).done;){var a=r.value,s=e.bootstrapEvent(e.rootPointerEvent,a,i,t);e.context.eventService.mapEvent(s)}}catch(t){o.e(t)}finally{o.f()}e.setCursor(e.context.eventService.cursor)}}return u(t,[{key:"apply",value:function(e){var n=this;this.context=e;var r=e.renderingService,i=this.context.renderingContext.root.ownerDocument.defaultView;this.context.eventService.setPickHandler((function(t){return n.context.renderingService.hooks.pickSync.call({position:t,picked:[],topmost:!0}).picked[0]||null})),r.hooks.pointerWheel.tap(t.tag,(function(t){var e=n.normalizeWheelEvent(t);n.context.eventService.mapEvent(e)})),r.hooks.pointerDown.tap(t.tag,(function(t){if(!i.supportsTouchEvents||"touch"!==t.pointerType){var e=n.normalizeToPointerEvent(t,i);if(n.autoPreventDefault&&e[0].isNormalized)(t.cancelable||!("cancelable"in t))&&t.preventDefault();var r,o=sr(e);try{for(o.s();!(r=o.n()).done;){var a=r.value,s=n.bootstrapEvent(n.rootPointerEvent,a,i,t);n.context.eventService.mapEvent(s)}}catch(t){o.e(t)}finally{o.f()}n.setCursor(n.context.eventService.cursor)}})),r.hooks.pointerUp.tap(t.tag,(function(t){if(!i.supportsTouchEvents||"touch"!==t.pointerType){var e,r=n.context.contextService.getDomElement(),o=n.context.eventService.isNativeEventFromCanvas(r,t)?"":"outside",a=sr(n.normalizeToPointerEvent(t,i));try{for(a.s();!(e=a.n()).done;){var s=e.value,l=n.bootstrapEvent(n.rootPointerEvent,s,i,t);l.type+=o,n.context.eventService.mapEvent(l)}}catch(t){a.e(t)}finally{a.f()}n.setCursor(n.context.eventService.cursor)}})),r.hooks.pointerMove.tap(t.tag,this.onPointerMove),r.hooks.pointerOver.tap(t.tag,this.onPointerMove),r.hooks.pointerOut.tap(t.tag,this.onPointerMove),r.hooks.click.tap(t.tag,this.onClick),r.hooks.pointerCancel.tap(t.tag,(function(t){var e,r=sr(n.normalizeToPointerEvent(t,i));try{for(r.s();!(e=r.n()).done;){var o=e.value,a=n.bootstrapEvent(n.rootPointerEvent,o,i,t);n.context.eventService.mapEvent(a)}}catch(t){r.e(t)}finally{r.f()}n.setCursor(n.context.eventService.cursor)}))}},{key:"bootstrapEvent",value:function(t,e,n,r){t.view=n,t.originalEvent=null,t.nativeEvent=r,t.pointerId=e.pointerId,t.width=e.width,t.height=e.height,t.isPrimary=e.isPrimary,t.pointerType=e.pointerType,t.pressure=e.pressure,t.tangentialPressure=e.tangentialPressure,t.tiltX=e.tiltX,t.tiltY=e.tiltY,t.twist=e.twist,this.transferMouseData(t,e);var i=this.context.eventService.client2Viewport({x:e.clientX,y:e.clientY}),o=i.x,a=i.y;t.viewport.x=o,t.viewport.y=a;var s=this.context.eventService.viewport2Canvas(t.viewport),l=s.x,u=s.y;return t.canvas.x=l,t.canvas.y=u,t.global.copyFrom(t.canvas),t.offset.copyFrom(t.canvas),t.isTrusted=r.isTrusted,"pointerleave"===t.type&&(t.type="pointerout"),t.type.startsWith("mouse")&&(t.type=t.type.replace("mouse","pointer")),t.type.startsWith("touch")&&(t.type=Xa[t.type]||t.type),t}},{key:"normalizeWheelEvent",value:function(t){var e=this.rootWheelEvent;this.transferMouseData(e,t),e.deltaMode=t.deltaMode,e.deltaX=t.deltaX,e.deltaY=t.deltaY,e.deltaZ=t.deltaZ;var n=this.context.eventService.client2Viewport({x:t.clientX,y:t.clientY}),r=n.x,i=n.y;e.viewport.x=r,e.viewport.y=i;var o=this.context.eventService.viewport2Canvas(e.viewport),a=o.x,s=o.y;return e.canvas.x=a,e.canvas.y=s,e.global.copyFrom(e.canvas),e.offset.copyFrom(e.canvas),e.nativeEvent=t,e.type=t.type,e}},{key:"transferMouseData",value:function(t,e){t.isTrusted=e.isTrusted,t.srcElement=e.srcElement,t.timeStamp=Ka.now(),t.type=e.type,t.altKey=e.altKey,t.metaKey=e.metaKey,t.shiftKey=e.shiftKey,t.ctrlKey=e.ctrlKey,t.button=e.button,t.buttons=e.buttons,t.client.x=e.clientX,t.client.y=e.clientY,t.movement.x=e.movementX,t.movement.y=e.movementY,t.page.x=e.pageX,t.page.y=e.pageY,t.screen.x=e.screenX,t.screen.y=e.screenY,t.relatedTarget=null}},{key:"setCursor",value:function(t){this.context.contextService.applyCursorStyle(t||this.context.config.cursor||"default")}},{key:"normalizeToPointerEvent",value:function(t,e){var n=[];if(e.isTouchEvent(t))for(var r=0;r-1,a=0,s=r.length;a1&&void 0!==arguments[1]&&arguments[1];if(t.isConnected){var n=t.rBushNode;n.aabb&&this.rBush.remove(n.aabb);var r=t.getRenderBounds();if(r){var i=t.renderable;e&&(i.dirtyRenderBounds||(i.dirtyRenderBounds=new Er),i.dirtyRenderBounds.update(r.center,r.halfExtents));var o=b(r.getMin(),2),a=o[0],s=o[1],l=b(r.getMax(),2),u=l[0],c=l[1];n.aabb||(n.aabb={}),n.aabb.displayObject=t,n.aabb.minX=a,n.aabb.minY=s,n.aabb.maxX=u,n.aabb.maxY=c}return n.aabb&&!(isNaN(n.aabb.maxX)||isNaN(n.aabb.maxX)||isNaN(n.aabb.minX)||isNaN(n.aabb.minY))?n.aabb:void 0}}},{key:"syncRTree",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(e||!this.syncing&&0!==this.syncTasks.size){this.syncing=!0;var n=[],r=new Set,i=function(i){if(!r.has(i)&&i.renderable){var o=t.syncNode(i,e);o&&(n.push(o),r.add(i))}};this.syncTasks.forEach((function(t,e){t&&e.forEach(i);for(var n=e;n;)i(n),n=n.parentElement})),this.rBush.load(n),n.length=0,this.syncing=!1}}}])}();du.tag="Prepare";var fu=function(t){return t.READY="ready",t.BEFORE_RENDER="beforerender",t.RERENDER="rerender",t.AFTER_RENDER="afterrender",t.BEFORE_DESTROY="beforedestroy",t.AFTER_DESTROY="afterdestroy",t.RESIZE="resize",t.DIRTY_RECTANGLE="dirtyrectangle",t.RENDERER_CHANGED="rendererchanged",t}({}),pu=new zs(Ks.MOUNTED),gu=new zs(Ks.UNMOUNTED),vu=new zs(fu.BEFORE_RENDER),mu=new zs(fu.RERENDER),yu=new zs(fu.AFTER_RENDER),bu=function(t){function e(t){var n;s(this,e),(n=v(this,e)).Element=zl,n.inited=!1,n.context={};var r=t.container,i=t.canvas,o=t.renderer,l=t.width,u=t.height,c=t.background,h=t.cursor,d=t.supportsMutipleCanvasesInOneContainer,f=t.cleanUpOnDestroy,p=void 0===f||f,g=t.offscreenCanvas,m=t.devicePixelRatio,y=t.requestAnimationFrame,b=t.cancelAnimationFrame,x=t.createImage,E=t.supportsTouchEvents,w=t.supportsPointerEvents,k=t.isTouchEvent,M=t.isMouseEvent,S=t.dblClickSpeed,N=l,O=u,T=m||Ha&&window.devicePixelRatio||1;return T=T>=1?Math.ceil(T):1,i&&(N=l||function(t){var e=qa(t,"width");return"auto"===e?t.offsetWidth:parseFloat(e)}(i)||i.width/T,O=u||function(t){var e=qa(t,"height");return"auto"===e?t.offsetHeight:parseFloat(e)}(i)||i.height/T),n.customElements=new au,n.devicePixelRatio=T,n.requestAnimationFrame=null!=y?y:ls.bind(Ol.globalThis),n.cancelAnimationFrame=null!=b?b:us.bind(Ol.globalThis),n.supportsTouchEvents=null!=E?E:"ontouchstart"in Ol.globalThis,n.supportsPointerEvents=null!=w?w:!!Ol.globalThis.PointerEvent,n.isTouchEvent=null!=k?k:function(t){return n.supportsTouchEvents&&t instanceof Ol.globalThis.TouchEvent},n.isMouseEvent=null!=M?M:function(t){return!Ol.globalThis.MouseEvent||t instanceof Ol.globalThis.MouseEvent&&(!n.supportsPointerEvents||!(t instanceof Ol.globalThis.PointerEvent))},g&&(Ol.offscreenCanvas=g),n.document=new su,n.document.defaultView=n,d||function(t,e,n){if(t){var r="string"==typeof t?document.getElementById(t):t;Wa.has(r)&&Wa.get(r).destroy(n),Wa.set(r,e)}}(r,n,p),n.initRenderingContext(a(a({},t),{},{width:N,height:O,background:null!=c?c:"transparent",cursor:null!=h?h:"default",cleanUpOnDestroy:p,devicePixelRatio:T,requestAnimationFrame:n.requestAnimationFrame,cancelAnimationFrame:n.cancelAnimationFrame,supportsTouchEvents:n.supportsTouchEvents,supportsPointerEvents:n.supportsPointerEvents,isTouchEvent:n.isTouchEvent,isMouseEvent:n.isMouseEvent,dblClickSpeed:null!=S?S:200,createImage:null!=x?x:function(){return new window.Image}})),n.initDefaultCamera(N,O,o.clipSpaceNearZ),n.initRenderer(o,!0),n}return y(e,t),u(e,[{key:"initRenderingContext",value:function(t){this.context.config=t,this.context.renderingContext={root:this.document.documentElement,renderListCurrentFrame:[],unculledEntities:[],renderReasons:new Set,force:!1,dirty:!1}}},{key:"initDefaultCamera",value:function(t,e,n){var r=this,i=new Ol.CameraContribution;i.clipSpaceNearZ=n,i.setType($r.EXPLORING,Yr.DEFAULT).setPosition(t/2,e/2,500).setFocalPoint(t/2,e/2,0).setOrthographic(t/-2,t/2,e/2,e/-2,.1,1e3),i.canvas=this,i.eventEmitter.on(Xr,(function(){r.context.renderingContext.renderReasons.add($s.CAMERA_CHANGED),Ol.enableSizeAttenuation&&r.getConfig().renderer.getConfig().enableSizeAttenuation&&r.updateSizeAttenuation()})),this.context.camera=i}},{key:"updateSizeAttenuation",value:function(){var t=this.getCamera().getZoom();this.document.documentElement.forEach((function(e){Ol.styleValueRegistry.updateSizeAttenuation(e,t)}))}},{key:"getConfig",value:function(){return this.context.config}},{key:"getRoot",value:function(){return this.document.documentElement}},{key:"getCamera",value:function(){return this.context.camera}},{key:"getContextService",value:function(){return this.context.contextService}},{key:"getEventService",value:function(){return this.context.eventService}},{key:"getRenderingService",value:function(){return this.context.renderingService}},{key:"getRenderingContext",value:function(){return this.context.renderingContext}},{key:"getStats",value:function(){return this.getRenderingService().getStats()}},{key:"ready",get:function(){var t=this;return this.readyPromise||(this.readyPromise=new Promise((function(e){t.resolveReadyPromise=function(){e(t)}})),this.inited&&this.resolveReadyPromise()),this.readyPromise}},{key:"destroy",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=arguments.length>1?arguments[1]:void 0;_i.clearCache(),e||this.dispatchEvent(new zs(fu.BEFORE_DESTROY)),this.frameId&&this.cancelAnimationFrame(this.frameId);var n=this.getRoot();t&&(this.unmountChildren(n),this.document.destroy(),this.getEventService().destroy()),this.getRenderingService().destroy(),this.getContextService().destroy(),this.context.rBushRoot&&this.context.rBushRoot.clear(),e||this.dispatchEvent(new zs(fu.AFTER_DESTROY));var r=function(t){t.currentTarget=null,t.manager=null,t.target=null,t.relatedNode=null};r(pu),r(gu),r(vu),r(mu),r(yu),r(jl),r(Pl),r(Rl),r(Dl)}},{key:"changeSize",value:function(t,e){this.resize(t,e)}},{key:"resize",value:function(t,e){var n=this.context.config;n.width=t,n.height=e,this.getContextService().resize(t,e);var r=this.context.camera,i=r.getProjectionMode();r.setPosition(t/2,e/2,500).setFocalPoint(t/2,e/2,0),i===qr.ORTHOGRAPHIC?r.setOrthographic(t/-2,t/2,e/2,e/-2,r.getNear(),r.getFar()):r.setAspect(t/e),this.dispatchEvent(new zs(fu.RESIZE,{width:t,height:e}))}},{key:"appendChild",value:function(t,e){return this.document.documentElement.appendChild(t,e)}},{key:"insertBefore",value:function(t,e){return this.document.documentElement.insertBefore(t,e)}},{key:"removeChild",value:function(t){return this.document.documentElement.removeChild(t)}},{key:"removeChildren",value:function(){this.document.documentElement.removeChildren()}},{key:"destroyChildren",value:function(){this.document.documentElement.destroyChildren()}},{key:"render",value:function(t){var e=this;t&&(vu.detail=t,yu.detail=t),this.dispatchEvent(vu),this.getRenderingService().render(this.getConfig(),t,(function(){e.dispatchEvent(mu)})),this.dispatchEvent(yu)}},{key:"run",value:function(){var t=this,e=function(n,r){t.render(r),t.frameId=t.requestAnimationFrame(e)};e()}},{key:"initRenderer",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!t)throw new Error("Renderer is required.");this.inited=!1,this.readyPromise=void 0,this.context.rBushRoot=new cr,this.context.renderingPlugins=[],this.context.renderingPlugins.push(new uu,new du,new lu([new hu])),this.loadRendererContainerModule(t),this.context.contextService=new this.context.ContextService(a(a({},Ol),this.context)),this.context.renderingService=new Ys(Ol,this.context),this.context.eventService=new Hs(Ol,this.context),this.context.eventService.init(),this.context.contextService.init?(this.context.contextService.init(),this.initRenderingService(t,n,!0)):this.context.contextService.initAsync().then((function(){e.initRenderingService(t,n)})).catch((function(t){console.error(t)}))}},{key:"initRenderingService",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.context.renderingService.init((function(){e.inited=!0,n?r?e.requestAnimationFrame((function(){e.dispatchEvent(new zs(fu.READY))})):e.dispatchEvent(new zs(fu.READY)):e.dispatchEvent(new zs(fu.RENDERER_CHANGED)),e.readyPromise&&e.resolveReadyPromise(),n||e.getRoot().forEach((function(t){var e=t.renderable;e&&(e.renderBoundsDirty=!0,e.boundsDirty=!0,e.dirty=!0)})),e.mountChildren(e.getRoot()),t.getConfig().enableAutoRendering&&e.run()}))}},{key:"loadRendererContainerModule",value:function(t){var e=this;t.getPlugins().forEach((function(t){t.context=e.context,t.init(Ol)}))}},{key:"setRenderer",value:function(t){var e=this.getConfig();if(e.renderer!==t){var n=e.renderer;e.renderer=t,this.destroy(!1,!0),d((null==n?void 0:n.getPlugins())||[]).reverse().forEach((function(t){t.destroy(Ol)})),this.initRenderer(t)}}},{key:"setCursor",value:function(t){this.getConfig().cursor=t,this.getContextService().applyCursorStyle(t)}},{key:"unmountChildren",value:function(t){var e=this;t.childNodes.forEach((function(t){e.unmountChildren(t)})),this.inited&&(t.isMutationObserved?t.dispatchEvent(gu):(gu.target=t,this.dispatchEvent(gu,!0)),t!==this.document.documentElement&&(t.ownerDocument=null),t.isConnected=!1),t.isCustomElement&&t.disconnectedCallback&&t.disconnectedCallback()}},{key:"mountChildren",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Za(t);this.inited?t.isConnected||(t.ownerDocument=this.document,t.isConnected=!0,n||(t.isMutationObserved?t.dispatchEvent(pu):(pu.target=t,this.dispatchEvent(pu,!0)))):console.warn("[g]: You are trying to call `canvas.appendChild` before canvas' initialization finished. You can either await `canvas.ready` or listen to `CanvasEvent.READY` manually.","appended child: ",t.nodeName),t.childNodes.forEach((function(t){e.mountChildren(t,n)})),t.isCustomElement&&t.connectedCallback&&t.connectedCallback()}},{key:"mountFragment",value:function(t){this.mountChildren(t,!1)}},{key:"client2Viewport",value:function(t){return this.getEventService().client2Viewport(t)}},{key:"viewport2Client",value:function(t){return this.getEventService().viewport2Client(t)}},{key:"viewport2Canvas",value:function(t){return this.getEventService().viewport2Canvas(t)}},{key:"canvas2Viewport",value:function(t){return this.getEventService().canvas2Viewport(t)}},{key:"getPointByClient",value:function(t,e){return this.client2Viewport({x:t,y:e})}},{key:"getClientByPoint",value:function(t,e){return this.viewport2Client({x:t,y:e})}}])}(Vs),xu=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i90)return this;this.computeMatrix()}return this._getAxes(),this.type===$r.ORBITING||this.type===$r.EXPLORING?this._getPosition():this.type===$r.TRACKING&&this._getFocalPoint(),this._update(),this}},{key:"pan",value:function(t,e){var n=Pr(t,e,0),r=dt(this.position);return mt(r,r,bt(ht(),this.right,n[0])),mt(r,r,bt(ht(),this.up,n[1])),this._setPosition(r),this.triggerUpdate(),this}},{key:"dolly",value:function(t){var e=this.forward,n=dt(this.position),r=this.dollyingStep,i=this.distance+t*this.dollyingStep;return r=Math.max(Math.min(i,this.maxDistance),this.minDistance)-this.distance,n[0]+=r*e[0],n[1]+=r*e[1],n[2]+=r*e[2],this._setPosition(n),this.type===$r.ORBITING||this.type===$r.EXPLORING?this._getDistance():this.type===$r.TRACKING&&mt(this.focalPoint,n,this.distanceVector),this.triggerUpdate(),this}},{key:"cancelLandmarkAnimation",value:function(){void 0!==this.landmarkAnimationID&&this.canvas.cancelAnimationFrame(this.landmarkAnimationID)}},{key:"createLandmark",value:function(t){var e,n,r,i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=o.position,s=void 0===a?this.position:a,l=o.focalPoint,u=void 0===l?this.focalPoint:l,c=o.roll,h=o.zoom,d=new Ol.CameraContribution;d.setType(this.type,void 0),d.setPosition(s[0],null!==(e=s[1])&&void 0!==e?e:this.position[1],null!==(n=s[2])&&void 0!==n?n:this.position[2]),d.setFocalPoint(u[0],null!==(r=u[1])&&void 0!==r?r:this.focalPoint[1],null!==(i=u[2])&&void 0!==i?i:this.focalPoint[2]),d.setRoll(null!=c?c:this.roll),d.setZoom(null!=h?h:this.zoom);var f={name:t,matrix:C(d.getWorldTransform()),right:dt(d.right),up:dt(d.up),forward:dt(d.forward),position:dt(d.getPosition()),focalPoint:dt(d.getFocalPoint()),distanceVector:dt(d.getDistanceVector()),distance:d.getDistance(),dollyingStep:d.getDollyingStep(),azimuth:d.getAzimuth(),elevation:d.getElevation(),roll:d.getRoll(),relAzimuth:d.relAzimuth,relElevation:d.relElevation,relRoll:d.relRoll,zoom:d.getZoom()};return this.landmarks.push(f),f}},{key:"gotoLandmark",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=ne(t)?this.landmarks.find((function(e){return e.name===t})):t;if(r){var i=ae(n)?{duration:n}:n,o=i.easing,a=void 0===o?"linear":o,s=i.duration,l=void 0===s?100:s,u=i.easingFunction,c=void 0===u?void 0:u,h=i.onfinish,d=void 0===h?void 0:h,f=i.onframe,p=void 0===f?void 0:f;this.cancelLandmarkAnimation();var g,v=r.position,m=r.focalPoint,y=r.zoom,b=r.roll,x=c||Ol.EasingFunction(a),E=function(){e.setFocalPoint(m),e.setPosition(v),e.setRoll(b),e.setZoom(y),e.computeMatrix(),e.triggerUpdate(),null==d||d()};if(0===l)return E();var w=function(t){void 0===g&&(g=t);var n=t-g;if(n>=l)E();else{var r,i,o=x(n/l),a=ht(),s=ht();if(kt(a,e.focalPoint,m,o),kt(s,e.position,v,o),i=e.roll*(1-o)+b*o,r=e.zoom*(1-o)+y*o,e.setFocalPoint(a),e.setPosition(s),e.setRoll(i),e.setZoom(r),Ot(a,m)+Ot(s,v)<=.01&&void 0===y&&void 0===b)return E();e.computeMatrix(),e.triggerUpdate(),n0&&Number(this._currentTime)>=this._totalDuration||this._playbackRate<0&&Number(this._currentTime)<=0)}},{key:"totalDuration",get:function(){return this._totalDuration}},{key:"_needsTick",get:function(){return this.pending||"running"===this.playState||!this._finishedFlag}},{key:"updatePromises",value:function(){var t;if(null!==(t=this.effect.target)&&void 0!==t&&t.destroyed)return this.readyPromise=void 0,this.finishedPromise=void 0,!1;var e=this.oldPlayState,n=this.pending?"pending":this.playState;return this.readyPromise&&n!==e&&("idle"===n?(this.rejectReadyPromise(),this.readyPromise=void 0):"pending"===e?this.resolveReadyPromise():"pending"===n&&(this.readyPromise=void 0)),this.finishedPromise&&n!==e&&("idle"===n?(this.rejectFinishedPromise(),this.finishedPromise=void 0):"finished"===n?this.resolveFinishedPromise():"finished"===e&&(this.finishedPromise=void 0)),this.oldPlayState=n,this.readyPromise||this.finishedPromise}},{key:"play",value:function(){this.updatePromises(),this._paused=!1,(this._isFinished||this._idle)&&(this.rewind(),this._startTime=null),this._finishedFlag=!1,this._idle=!1,this.ensureAlive(),this.timeline.applyDirtiedAnimation(this),-1===this.timeline.animations.indexOf(this)&&this.timeline.animations.push(this),this.updatePromises()}},{key:"pause",value:function(){this.updatePromises(),this.currentTime&&(this._holdTime=this.currentTime),this._isFinished||this._paused||this._idle?this._idle&&(this.rewind(),this._idle=!1):this.currentTimePending=!0,this._startTime=null,this._paused=!0,this.updatePromises()}},{key:"finish",value:function(){this.updatePromises(),this._idle||(this.currentTime=this._playbackRate>0?this._totalDuration:0,this._startTime=this._totalDuration-this.currentTime,this.currentTimePending=!1,this.timeline.applyDirtiedAnimation(this),this.updatePromises())}},{key:"cancel",value:function(){var t=this;if(this.updatePromises(),this._inEffect&&(this._inEffect=!1,this._idle=!0,this._paused=!1,this._finishedFlag=!0,this._currentTime=0,this._startTime=null,this.effect.update(null),this.timeline.applyDirtiedAnimation(this),this.updatePromises(),this.oncancel)){var e=new Eu(null,this,this.currentTime,null);setTimeout((function(){t.oncancel(e)}))}}},{key:"reverse",value:function(){this.updatePromises();var t=this.currentTime;this.playbackRate*=-1,this.play(),null!==t&&(this.currentTime=t),this.updatePromises()}},{key:"updatePlaybackRate",value:function(t){this.playbackRate=t}},{key:"targetAnimations",value:function(){var t;return(null===(t=this.effect)||void 0===t?void 0:t.target).getAnimations()}},{key:"markTarget",value:function(){var t=this.targetAnimations();-1===t.indexOf(this)&&t.push(this)}},{key:"unmarkTarget",value:function(){var t=this.targetAnimations(),e=t.indexOf(this);-1!==e&&t.splice(e,1)}},{key:"tick",value:function(t,e){this._idle||this._paused||(null===this._startTime?e&&(this.startTime=t-this._currentTime/this.playbackRate):this._isFinished||this.tickCurrentTime((t-this._startTime)*this.playbackRate)),e&&(this.currentTimePending=!1,this.fireEvents(t))}},{key:"rewind",value:function(){if(this.playbackRate>=0)this.currentTime=0;else{if(!(this._totalDuration<1/0))throw new Error("Unable to rewind negative playback rate animation with infinite duration");this.currentTime=this._totalDuration}}},{key:"persist",value:function(){throw new Error(Or)}},{key:"addEventListener",value:function(t,e,n){throw new Error(Or)}},{key:"removeEventListener",value:function(t,e,n){throw new Error(Or)}},{key:"dispatchEvent",value:function(t){throw new Error(Or)}},{key:"commitStyles",value:function(){throw new Error(Or)}},{key:"ensureAlive",value:function(){var t,e;this.playbackRate<0&&0===this.currentTime?this._inEffect=!(null===(t=this.effect)||void 0===t||!t.update(-1)):this._inEffect=!(null===(e=this.effect)||void 0===e||!e.update(this.currentTime));this._inTimeline||!this._inEffect&&this._finishedFlag||(this._inTimeline=!0,this.timeline.animations.push(this))}},{key:"tickCurrentTime",value:function(t,e){t!==this._currentTime&&(this._currentTime=t,this._isFinished&&!e&&(this._currentTime=this._playbackRate>0?this._totalDuration:0),this.ensureAlive())}},{key:"fireEvents",value:function(t){var e=this;if(this._isFinished){if(!this._finishedFlag){if(this.onfinish){var n=new Eu(null,this,this.currentTime,t);setTimeout((function(){e.onfinish&&e.onfinish(n)}))}this._finishedFlag=!0}}else{if(this.onframe&&"running"===this.playState){var r=new Eu(null,this,this.currentTime,t);this.onframe(r)}this._finishedFlag=!1}}}])}(),Mu=.1,Su="function"==typeof Float32Array,Nu=function(t,e){return 1-3*e+3*t},Ou=function(t,e){return 3*e-6*t},Tu=function(t){return 3*t},Cu=function(t,e,n){return((Nu(e,n)*t+Ou(e,n))*t+Tu(e))*t},Au=function(t,e,n){return 3*Nu(e,n)*t*t+2*Ou(e,n)*t+Tu(e)},Pu=function(t,e,n,r){if(!(t>=0&&t<=1&&n>=0&&n<=1))throw new Error("bezier x values must be in [0, 1] range");if(t===e&&n===r)return function(t){return t};for(var i=Su?new Float32Array(11):new Array(11),o=0;o<11;++o)i[o]=Cu(o*Mu,t,n);var a=function(e){for(var r=0,o=1;10!==o&&i[o]<=e;++o)r+=Mu;--o;var a=r+(e-i[o])/(i[o+1]-i[o])*Mu,s=Au(a,t,n);return s>=.001?function(t,e,n,r){for(var i=0;i<4;++i){var o=Au(e,n,r);if(0===o)return e;e-=(Cu(e,n,r)-t)/o}return e}(e,a,t,n):0===s?a:function(t,e,n,r,i){var o,a,s=0;do{(o=Cu(a=e+(n-e)/2,r,i)-t)>0?n=a:e=a}while(Math.abs(o)>1e-7&&++s<10);return a}(e,r,r+Mu,t,n)};return function(t){return 0===t||1===t?t:Cu(a(t),e,r)}},Ru=function(t){return Math.pow(t,2)},Du=function(t){return Math.pow(t,3)},Lu=function(t){return Math.pow(t,4)},_u=function(t){return Math.pow(t,5)},Iu=function(t){return Math.pow(t,6)},ju=function(t){return 1-Math.cos(t*Math.PI/2)},Bu=function(t){return 1-Math.sqrt(1-t*t)},Fu=function(t){return t*t*(3*t-2)},zu=function(t){for(var e,n=4;t<((e=Math.pow(2,--n))-1)/11;);return 1/Math.pow(4,3-n)-7.5625*Math.pow((3*e-2)/22-t,2)},Gu=function(t){var e=b(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],2),n=e[0],r=void 0===n?1:n,i=e[1],o=void 0===i?.5:i,a=oe(Number(r),1,10),s=oe(Number(o),.1,2);return 0===t||1===t?t:-a*Math.pow(2,10*(t-1))*Math.sin((t-1-s/(2*Math.PI)*Math.asin(1/a))*(2*Math.PI)/s)},Vu=function(t){var e=arguments.length>2?arguments[2]:void 0,n=b(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],4),r=n[0],i=void 0===r?1:r,o=n[1],a=void 0===o?100:o,s=n[2],l=void 0===s?10:s,u=n[3],c=void 0===u?0:u;i=oe(i,.1,1e3),a=oe(a,.1,1e3),l=oe(l,.1,1e3),c=oe(c,.1,1e3);var h=Math.sqrt(a/i),d=l/(2*Math.sqrt(a*i)),f=d<1?h*Math.sqrt(1-d*d):0,p=d<1?(d*h-c)/f:-c+h,g=e?e*t/1e3:t;return g=d<1?Math.exp(-g*d*h)*(1*Math.cos(f*g)+p*Math.sin(f*g)):(1+p*g)*Math.exp(-g*h),0===t||1===t?t:1-g},Wu=function(t){var e=b(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],2),n=e[0],r=void 0===n?10:n;return("start"===e[1]?Math.ceil:Math.floor)(oe(t,0,1)*r)/r},Hu=function(t){var e=b(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],4),n=e[0],r=e[1],i=e[2],o=e[3];return Pu(n,r,i,o)(t)},Uu=Pu(.42,0,1,1),$u=function(t){return function(e){return 1-t(1-e,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],arguments.length>2?arguments[2]:void 0)}},Yu=function(t){return function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2?arguments[2]:void 0;return e<.5?t(2*e,n,r)/2:1-t(-2*e+2,n,r)/2}},qu=function(t){return function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=arguments.length>2?arguments[2]:void 0;return e<.5?(1-t(1-2*e,n,r))/2:(t(2*e-1,n,r)+1)/2}},Xu={steps:Wu,"step-start":function(t){return Wu(t,[1,"start"])},"step-end":function(t){return Wu(t,[1,"end"])},linear:function(t){return t},"cubic-bezier":Hu,ease:function(t){return Hu(t,[.25,.1,.25,1])},in:Uu,out:$u(Uu),"in-out":Yu(Uu),"out-in":qu(Uu),"in-quad":Ru,"out-quad":$u(Ru),"in-out-quad":Yu(Ru),"out-in-quad":qu(Ru),"in-cubic":Du,"out-cubic":$u(Du),"in-out-cubic":Yu(Du),"out-in-cubic":qu(Du),"in-quart":Lu,"out-quart":$u(Lu),"in-out-quart":Yu(Lu),"out-in-quart":qu(Lu),"in-quint":_u,"out-quint":$u(_u),"in-out-quint":Yu(_u),"out-in-quint":qu(_u),"in-expo":Iu,"out-expo":$u(Iu),"in-out-expo":Yu(Iu),"out-in-expo":qu(Iu),"in-sine":ju,"out-sine":$u(ju),"in-out-sine":Yu(ju),"out-in-sine":qu(ju),"in-circ":Bu,"out-circ":$u(Bu),"in-out-circ":Yu(Bu),"out-in-circ":qu(Bu),"in-back":Fu,"out-back":$u(Fu),"in-out-back":Yu(Fu),"out-in-back":qu(Fu),"in-bounce":zu,"out-bounce":$u(zu),"in-out-bounce":Yu(zu),"out-in-bounce":qu(zu),"in-elastic":Gu,"out-elastic":$u(Gu),"in-out-elastic":Yu(Gu),"out-in-elastic":qu(Gu),spring:Vu,"spring-in":Vu,"spring-out":$u(Vu),"spring-in-out":Yu(Vu),"spring-out-in":qu(Vu)},Ku=function(t){return t};function Zu(t,e){return function(n){if(n>=1)return 1;var r=1/t;return(n+=e*r)-n%r}}var Qu="\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*",Ju=new RegExp("cubic-bezier\\(".concat(Qu,",").concat(Qu,",").concat(Qu,",").concat(Qu,"\\)")),tc=/steps\(\s*(\d+)\s*\)/,ec=/steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;function nc(t){var e=Ju.exec(t);if(e)return Pu.apply(void 0,d(e.slice(1).map(Number)));var n=tc.exec(t);if(n)return Zu(Number(n[1]),0);var r=ec.exec(t);return r?Zu(Number(r[1]),{start:1,middle:.5,end:0}[r[2]]):Xu[function(t){return function(t){return"-"===(t=t.replace(/([A-Z])/g,(function(t){return"-".concat(t.toLowerCase())}))).charAt(0)?t.substring(1):t}(t).replace(/^ease-/,"").replace(/(\(|\s).+/,"").toLowerCase().trim()}(t)]||Xu.linear}function rc(t){return Math.abs(function(t){var e;if(0===t.duration||0===t.iterations)return 0;return("auto"===t.duration?0:Number(t.duration))*(null!==(e=t.iterations)&&void 0!==e?e:1)}(t)/(t.playbackRate||1))}function ic(t,e,n){var r=function(t,e,n){if(null===e)return 0;var r=n.endTime;return e=Math.min(n.delay+t+n.endDelay,r)?2:3}(t,e,n),i=function(t,e,n,r,i){switch(r){case 1:return"backwards"===e||"both"===e?0:null;case 3:return n-i;case 2:return"forwards"===e||"both"===e?t:null;case 0:return null}}(t,n.fill,e,r,n.delay);if(null===i)return null;var o="auto"===n.duration?0:n.duration,a=function(t,e,n,r,i){var o=i;return 0===t?1!==e&&(o+=n):o+=r/t,o}(o,r,n.iterations,i,n.iterationStart),s=function(t,e,n,r,i,o){var a=t===1/0?e%1:t%1;return 0!==a||2!==n||0===r||0===i&&0!==o||(a=1),a}(a,n.iterationStart,r,n.iterations,i,o),l=function(t,e,n,r){return 2===t&&e===1/0?1/0:1===n?Math.floor(r)-1:Math.floor(r)}(r,n.iterations,s,a),u=function(t,e,n){var r=t;if("normal"!==t&&"reverse"!==t){var i=e;"alternate-reverse"===t&&(i+=1),r="normal",i!==1/0&&i%2!=0&&(r="reverse")}return"normal"===r?n:1-n}(n.direction,l,s);return n.currentIteration=l,n.progress=u,n.easingFunction(u)}function oc(t,e,n){var r=function(t,e){for(var n={},r=0;r=t.applyFrom&&e1)throw new Error("Keyframe offsets must be between 0 and 1.");n.computedOffset=i}}else if("composite"===r&&-1===["replace","add","accumulate","auto"].indexOf(i))throw new Error("".concat(i," compositing is not supported"));n[r]=i}return void 0===n.offset&&(n.offset=null),void 0===n.easing&&(n.easing=(null==e?void 0:e.easing)||"linear"),void 0===n.composite&&(n.composite="auto"),n})),r=!0,i=-1/0,o=0;o=0&&Number(t.offset)<=1})),r||function(){var t,e,r=n.length;n[r-1].computedOffset=Number(null!==(t=n[r-1].offset)&&void 0!==t?t:1),r>1&&(n[0].computedOffset=Number(null!==(e=n[0].offset)&&void 0!==e?e:0));for(var i=0,o=Number(n[0].computedOffset),a=1;a{console.warn(_c(t))};function jc(e){const{theme:n}=e;if(!n)return{};const r=Dc(t.ExtensionCategory.THEME,n);return r||(Ic(`The theme of ${n} is not registered.`),{})}function Bc(t,e){if(Array.isArray(t)&&0===t.length)return null;const n=Array.isArray(t)?t[0]:t,r=Array.isArray(t)?t.slice(1):e||[];return new Proxy(n,{get:(t,e)=>"function"!=typeof t[e]||["onframe","onfinish"].includes(e)?"finished"===e?Promise.all([n.finished,...r.map((t=>t.finished))]):Reflect.get(t,e):(...n)=>{t[e](...n),r.forEach((t=>{var r;return null===(r=t[e])||void 0===r?void 0:r.call(t,...n)}))},set:(t,e,n)=>(["onframe","onfinish"].includes(e)||r.forEach((t=>{t[e]=n})),Reflect.set(t,e,n))})}function Fc(t){const e=t.reduce(((t,e)=>(Object.entries(e).forEach((([e,n])=>{void 0===t[e]?t[e]=[n]:t[e].push(n)})),t)),{});Object.entries(e).forEach((([n,r])=>{(r.length!==t.length||r.some((t=>$t(t)))||r.every((t=>!["sourceNode","targetNode","childrenNode"].includes(n)&&Ne(t,r[0]))))&&delete e[n]}));const n=Object.entries(e).reduce(((t,[e,n])=>(n.forEach(((n,r)=>{t[r]?t[r][e]=n:t[r]={[e]:n}})),t)),[]);return 0!==t.length&&0===n.length&&n.push({_:0},{_:0}),n}function zc(t){switch(t){case"opacity":return 1;case"x":case"y":case"z":case"zIndex":return 0;case"visibility":return"visible";case"collapsed":return!1;case"states":return[];default:return}}function Gc(t,e){const{animation:n}=t;if(!1===n||!1===e)return!1;const r=Object.assign({},yc);return qt(n)&&Object.assign(r,n),qt(e)&&Object.assign(r,e),r}function Vc(e,n,r,i){var o,a;const{animation:s}=e;if(!1===s||!1===i)return[];const l=null===(o=null==e?void 0:e[n])||void 0===o?void 0:o.animation;if(!1===l)return[];const u=null==l?void 0:l[r];if(!1===u)return[];const c=null===(a=jc(e)[n])||void 0===a?void 0:a.animation,h=(e=[])=>function(e){if("string"==typeof e){return Dc(t.ExtensionCategory.ANIMATION,e)||(Ic(`The animation of ${e} is not registered.`),[])}return e}(e).map((t=>Object.assign(Object.assign(Object.assign(Object.assign({},bc),qt(s)&&s),t),qt(i)&&i)));if(u)return h(u);if(!c)return[];const d=c[r];return!1===d?[]:h(d)}function Wc(t,e,n,r=[]){if(!r&&0===t&&0===e&&0===n)return null;if(Array.isArray(r)){let i=-1;const o=[];for(let a=0;a{if(!n.length)return null;const[r,i]=e;let o;const a=n.map((e=>{var{fields:n,shape:a,states:s}=e,l=Fe(e,["fields","shape","states"]);const u=(e=>{var n;if(e){const o=t.getShape(e);if(!o)return null;const a=`get${de(e)}Style`,s=(null===(n=null==t?void 0:t[a])||void 0===n?void 0:n.bind(t))||(t=>t);return{shape:o,fromStyle:(null==s?void 0:s(r))||{},toStyle:(null==s?void 0:s(i))||{}}}return{shape:t,fromStyle:r,toStyle:i}})(a);if(!u)return null;const{shape:c,fromStyle:h,toStyle:d}=u,f=[{},{}];if(n.forEach((t=>{var e,n;Object.assign(f[0],{[t]:null!==(e=h[t])&&void 0!==e?e:zc(t)}),Object.assign(f[1],{[t]:null!==(n=d[t])&&void 0!==n?n:zc(t)})})),f.some((t=>Object.keys(t).some((t=>["x","y","z"].includes(t)))))){const{x:t=0,y:e=0,z:n,transform:r=""}=c.attributes||{};f.forEach((i=>{var o,a,s;i.transform=Wc(null!==(o=i.x)&&void 0!==o?o:t,null!==(a=i.y)&&void 0!==a?a:e,null!==(s=i.z)&&void 0!==s?s:n,r)}))}const p=c.animate(Fc(f),l);return void 0===a&&(o=p),p})).filter(Boolean),s=o||(null==a?void 0:a[0]);return s?Bc(s,a.filter((t=>t!=t))):null},Uc=[{fields:["x","y"]}],$c=Uc,Yc=[{fields:["sourceNode","targetNode"]}],qc=Yc,Xc=[{fields:["childrenNode","x","y"]}],Kc=Xc;function Zc(t){return t instanceof Float32Array||!(!Array.isArray(t)||2!==t.length&&3!==t.length)&&t.every((t=>"number"==typeof t))}function Qc(t,e,n){return t>=e&&t<=n}function Jc(t=0){if(Array.isArray(t)){const[e=0,n=e,r=e,i=n]=t;return[e,n,r,i]}return[t,t,t,t]}function th(t=0){const e=Jc(t);return e[0]+e[2]}function eh(t){return t.max[0]-t.min[0]}function nh(t){return t.max[1]-t.min[1]}function rh(t){return[eh(t),nh(t)]}function ih(t,e){const n=Zc(t)?oh(t):t.getShape("key").getBounds();return e?ah(n,e):n}function oh(t){const[e,n,r=0]=t,i=new Er;return i.setMinMax([e,n,r],[e,n,r]),i}function ah(t,e){const[n,r,i,o]=Jc(e),[a,s,l]=t.min,[u,c,h]=t.max,d=new Er;return d.setMinMax([a-o,s-n,l],[u+r,c+i,h]),d}function sh(t){if(0===t.length)return new Er;if(1===t.length)return t[0];const e=new Er;e.setMinMax(t[0].min,t[0].max);for(let n=1;nu[e.id]+s?(u[a]=u[e.id]+s,c[a]=[e.id]):u[a]===u[e.id]+s&&c[a].push(e.id)}))},f=0;f=this.maxStep},t.prototype.peek=function(){return this.isEmpty()?null:this.linkedList.head.value},t.prototype.push=function(t){this.linkedList.prepend(t),this.length>this.maxStep&&this.linkedList.deleteTail()},t.prototype.pop=function(){var t=this.linkedList.deleteHead();return t?t.value:null},t.prototype.toArray=function(){return this.linkedList.toArray().map((function(t){return t.value}))},t.prototype.clear=function(){for(;!this.isEmpty();)this.pop()}}();const Ch=(t,e,n)=>{var r;switch(n.type){case"degree":{const i=new Map;return null===(r=t.nodes)||void 0===r||r.forEach((t=>{const r=e(Nh(t),n.direction).length;i.set(Nh(t),r)})),i}case"betweenness":return Ph(t,n.directed,n.weightPropertyName);case"closeness":return Rh(t,n.directed,n.weightPropertyName);case"eigenvector":return Lh(t,n.directed);case"pagerank":return Dh(t,n.epsilon,n.linkProb);default:return Ah(t)}},Ah=t=>{var e;const n=new Map;return null===(e=t.nodes)||void 0===e||e.forEach((t=>{n.set(Nh(t),0)})),n},Ph=(t,e,n)=>{const r=Ah(t),{nodes:i=[]}=t;return i.forEach((o=>{i.forEach((i=>{if(o!==i){const{allPath:a}=Sh(t,Nh(o),Nh(i),e,n),s=a.length;a.flat().forEach((t=>{t!==Nh(o)&&t!==Nh(i)&&r.set(t,r.get(t)+1/s)}))}}))})),r},Rh=(t,e,n)=>{const r=new Map,{nodes:i=[]}=t;return i.forEach((o=>{const a=i.reduce(((r,i)=>{if(o!==i){const{length:a}=Sh(t,Nh(o),Nh(i),e,n);r+=a}return r}),0);r.set(Nh(o),1/a)})),r},Dh=(t,e,n)=>{var r;const i=new Map,o=function(t,e,n){"number"!=typeof e&&(e=1e-6),"number"!=typeof n&&(n=.85);for(var r,i=1,o=0,a=1e3,s=t.nodes,l=void 0===s?[]:s,u=t.edges,c=void 0===u?[]:u,h=l.length,d={},f={},p=0;p0&&i>e;){for(o=0,p=0;p0&&(r+=f[b]/x)}d[v]=n*r,o+=d[v]}}for(o=(1-o)/h,i=0,p=0;p{i.set(Nh(t),o[Nh(t)])})),i},Lh=(t,e)=>{const{nodes:n=[]}=t,r=_h(t,e),i=Ih(r,n.length),o=new Map;return n.forEach(((t,e)=>{o.set(Nh(t),i[e])})),o},_h=(t,e)=>{const{nodes:n=[],edges:r=[]}=t,i=Array(n.length).fill(null).map((()=>Array(n.length).fill(0)));return r.forEach((({source:t,target:r})=>{const o=n.findIndex((e=>Nh(e)===t)),a=n.findIndex((t=>Nh(t)===r));e?i[o][a]=1:(i[o][a]=1,i[a][o]=1)})),i},Ih=(t,e,n=100,r=1e-6)=>{let i=Array(e).fill(1),o=1/0;for(let a=0;ar;a++){const n=Array(e).fill(0);for(let r=0;rt+e*e),0));for(let t=0;tt+(e-i[n])*e),0)),i=n}return i};function jh(t,e,n,r=Ne){const i=new Map(t.map((t=>[n(t),t]))),o=new Map(e.map((t=>[n(t),t]))),a=new Set(i.keys()),s=new Set(o.keys()),l=[],u=[],c=[],h=[];return s.forEach((t=>{a.has(t)?r(i.get(t),o.get(t))?h.push(o.get(t)):u.push(o.get(t)):l.push(o.get(t))})),a.forEach((t=>{s.has(t)||c.push(i.get(t))})),{enter:l,exit:c,keep:h,update:u}}function Bh(t,e,n){t.forEach((t=>{(t=>{n&&!n(t)||(t.style.visibility=e)})(t)}))}class Fh{constructor(t){this.extensions=[],this.extensionMap={},this.context=t}setExtensions(t){const e=function(t,e,n){const r={},i=t=>(t in r||(r[t]=0),`${e}-${t}-${r[t]++}`);return n.map((e=>"string"==typeof e?{type:e,key:i(e)}:"function"==typeof e?e.call(t):e.key?e:Object.assign(Object.assign({},e),{key:i(e.type)})))}(this.context.graph,this.category,t),{enter:n,update:r,exit:i,keep:o}=jh(this.extensions,e,(t=>t.key));this.createExtensions(n),this.updateExtensions([...r,...o]),this.destroyExtensions(i),this.extensions=e}createExtension(t){const{category:e}=this,{key:n,type:r}=t,i=Dc(e,r);if(!i)return Ic(`The extension ${r} of ${e} is not registered.`);const o=new i(this.context,t);this.extensionMap[n]=o}createExtensions(t){t.forEach((t=>this.createExtension(t)))}updateExtension(t){const{key:e}=t,n=this.extensionMap[e];n&&n.update(t)}updateExtensions(t){t.forEach((t=>this.updateExtension(t)))}destroyExtension(t){const e=this.extensionMap[t];e&&(e.destroy(),delete this.extensionMap[t])}destroyExtensions(t){t.forEach((({key:t})=>this.destroyExtension(t)))}destroy(){Object.values(this.extensionMap).forEach((t=>t.destroy())),this.context={},this.extensions=[],this.extensionMap={}}}class zh{constructor(t,e){this.events=[],this.destroyed=!1,this.context=t,this.options=e}update(t){this.options=Object.assign(this.options,t)}destroy(){this.context={},this.options={},this.destroyed=!0}}class Gh extends zh{}class Vh extends Gh{constructor(t,e){super(t,Object.assign({},Vh.defaultOptions,e)),this.isOverlapping=(t,e)=>e.some((e=>t.intersects(e))),this.occupiedBounds=[],this.detectLabelCollision=t=>{const e=this.context.viewport,n={show:[],hide:[]};return this.occupiedBounds=[],t.forEach((t=>{const r=t.getShape("label").getRenderBounds();e.isInViewport(r,!0)&&!this.isOverlapping(r,this.occupiedBounds)?(n.show.push(t),this.occupiedBounds.push(ah(r,this.options.padding))):n.hide.push(t)})),n},this.hideLabelIfExceedViewport=(t,e)=>{const{exit:n}=jh(t,e,(t=>t.id));null==n||n.forEach(this.hideLabel)},this.nodeCentralities=new Map,this.sortNodesByCentrality=(t,e)=>{const{model:n}=this.context,r=n.getData(),i=n.getRelatedEdgesData.bind(n);return t.map((t=>(this.nodeCentralities.has(t.id)||(this.nodeCentralities=Ch(r,i,e)),{node:t,centrality:this.nodeCentralities.get(t.id)}))).sort(((t,e)=>e.centrality-t.centrality)).map((t=>t.node))},this.sortLabelElementsInView=t=>{const{sort:e,sortNode:n,sortCombo:r,sortEdge:i}=this.options,{model:o}=this.context;if(Ut(e))return t.sort(((t,n)=>e(o.getElementDataById(t.id),o.getElementDataById(n.id))));const{node:a=[],edge:s=[],combo:l=[]}=ie(t,(t=>t.type)),u=Ut(r)?l.sort(((t,e)=>r(...o.getComboData([t.id,e.id])))):l,c=Ut(n)?a.sort(((t,e)=>n(...o.getNodeData([t.id,e.id])))):this.sortNodesByCentrality(a,n),h=Ut(i)?s.sort(((t,e)=>i(...o.getEdgeData([t.id,e.id])))):s;return[...u,...c,...h]},this.labelElementsInView=[],this.isFirstRender=!0,this.onToggleVisibility=t=>{var e;if("zIndex"===(null===(e=t.data)||void 0===e?void 0:e.stage))return;if(!this.validate(t))return void(this.hiddenElements.size>0&&(this.hiddenElements.forEach(this.showLabel),this.hiddenElements.clear()));const n=this.isFirstRender?this.getLabelElements():this.getLabelElementsInView();this.hideLabelIfExceedViewport(this.labelElementsInView,n),this.labelElementsInView=n;const r=this.sortLabelElementsInView(this.labelElementsInView),{show:i,hide:o}=this.detectLabelCollision(r);for(let t=i.length-1;t>=0;t--)this.showLabel(i[t]);o.forEach(this.hideLabel)},this.hiddenElements=new Map,this.hideLabel=t=>{const e=t.getShape("label");e&&Bh(e,"hidden"),this.hiddenElements.set(t.id,t)},this.showLabel=t=>{const e=t.getShape("label");e&&Bh(e,"visible"),t.toFront(),this.hiddenElements.delete(t.id)},this.onTransform=Re(this.onToggleVisibility,this.options.throttle,{leading:!0}),this.enableToggle=!0,this.toggle=t=>{this.enableToggle&&this.onToggleVisibility(t)},this.onBeforeRender=()=>{this.enableToggle=!1},this.onAfterRender=t=>{this.onToggleVisibility(t),this.enableToggle=!0},this.bindEvents()}update(t){this.unbindEvents(),super.update(t),this.bindEvents(),this.onToggleVisibility({})}getLabelElements(){const{elementMap:t}=this.context.element,e=[];for(const n in t){const r=t[n];r.isVisible()&&r.getShape("label")&&e.push(r)}return e}getLabelElementsInView(){const t=this.context.viewport;return this.getLabelElements().filter((e=>t.isInViewport(e.getShape("key").getRenderBounds())))}bindEvents(){const{graph:e}=this.context;e.on(t.GraphEvent.BEFORE_RENDER,this.onBeforeRender),e.on(t.GraphEvent.AFTER_RENDER,this.onAfterRender),e.on(t.GraphEvent.AFTER_DRAW,this.toggle),e.on(t.GraphEvent.AFTER_LAYOUT,this.toggle),e.on(t.GraphEvent.AFTER_TRANSFORM,this.onTransform)}unbindEvents(){const{graph:e}=this.context;e.off(t.GraphEvent.BEFORE_RENDER,this.onBeforeRender),e.off(t.GraphEvent.AFTER_RENDER,this.onAfterRender),e.off(t.GraphEvent.AFTER_DRAW,this.toggle),e.off(t.GraphEvent.AFTER_LAYOUT,this.toggle),e.off(t.GraphEvent.AFTER_TRANSFORM,this.onTransform)}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}destroy(){this.unbindEvents(),super.destroy()}}Vh.defaultOptions={enable:!0,throttle:100,padding:0,sortNode:{type:"degree"}};const Wh=[0,0,0];function Hh(t,e){return t.map(((t,n)=>t+e[n]))}function Uh(t,e){return t.map(((t,n)=>t-e[n]))}function $h(t,e){return"number"==typeof e?t.map((t=>t*e)):t.map(((t,n)=>t*e[n]))}function Yh(t,e){return"number"==typeof e?t.map((t=>t/e)):t.map(((t,n)=>t/e[n]))}function qh(t,e){return t.map((t=>t*e))}function Xh(t,e){return Math.sqrt(t.reduce(((t,n,r)=>t+Math.pow(n-e[r]||0,2)),0))}function Kh(t,e){return t.reduce(((t,n,r)=>t+Math.abs(n-e[r])),0)}function Zh(t){const e=t.reduce(((t,e)=>t+Math.pow(e,2)),0);return t.map((t=>t/Math.sqrt(e)))}function Qh(t,e,n=!1){const r=t[0]*e[1]-t[1]*e[0];let i=Math.acos($h(t,e).reduce(((t,e)=>t+e),0)/(Xh(t,Wh)*Xh(e,Wh)));return n&&r<0&&(i=2*Math.PI-i),i}function Jh(t,e=!0){return e?[-t[1],t[0]]:[t[1],-t[0]]}function td(t,e){return t.map((t=>t%e))}function ed(t){return[t[0],t[1]]}function nd(t){return 2===t.length?[t[0],t[1],0]:t}function rd(t){const[e,n]=t;return e||n?Math.atan2(n,e):0}function id(t,e){const[n,r]=t,[i,o]=e;return function(t,e){const n=nd(t),r=nd(e);return[n[1]*r[2]-n[2]*r[1],n[2]*r[0]-n[0]*r[2],n[0]*r[1]-n[1]*r[0]]}(Uh(n,r),Uh(i,o)).every((t=>0===t))}function od(t,e,n=!1){if(id(t,e))return;const[r,i]=t,[o,a]=e,s=((r[0]-o[0])*(o[1]-a[1])-(r[1]-o[1])*(o[0]-a[0]))/((r[0]-i[0])*(o[1]-a[1])-(r[1]-i[1])*(o[0]-a[0])),l=a[0]-o[0]?(r[0]-o[0]+s*(i[0]-r[0]))/(a[0]-o[0]):(r[1]-o[1]+s*(i[1]-r[1]))/(a[1]-o[1]);return n||Qc(s,0,1)&&Qc(l,0,1)?[r[0]+s*(i[0]-r[0]),r[1]+s*(i[1]-r[1])]:void 0}function ad(t){if(Array.isArray(t))return Qc(t[0],0,1)&&Qc(t[1],0,1)?t:[.5,.5];const e=t.split("-");return[e.includes("left")?0:e.includes("right")?1:.5,e.includes("top")?0:e.includes("bottom")?1:.5]}function sd(t){const{x:e=0,y:n=0,z:r=0}=t.style||{};return[+e,+n,+r]}function ld(t){const{x:e,y:n,z:r}=t.style||{};return void 0!==e||void 0!==n||void 0!==r}function ud(t,e="center"){return function(t,e){const[n,r]=e,{min:i,max:o}=t;return[i[0]+n*(o[0]-i[0]),i[1]+r*(o[1]-i[1])]}(t,ad(e))}function cd(t){var e;return[t.x,t.y,null!==(e=t.z)&&void 0!==e?e:0]}function hd(t){var e;return{x:t[0],y:t[1],z:null!==(e=t[2])&&void 0!==e?e:0}}function dd(t,e=0){return t.map((t=>parseFloat(t.toFixed(e))))}function fd(t,e,n,r=!1){if(Ne(t,e))return t;const i=Zh(r?Uh(t,e):Uh(e,t)),o=[i[0]*n,i[1]*n];return Hh(ed(t),o)}function pd(t,e){return t[1]===e[1]}function gd(t,e,n){return id([t,e],[e,n])}function vd(t,e){return[2*e[0]-t[0],2*e[1]-t[1]]}function md(t,e,n,r=!0,i=!1){for(let o=0;o{const i=function(t,e){const n=xd(t,e);return Xh(t,n)}(t,e);i1?c=1:c<0&&(c=0);return[n+c*l,r+c*u]}function Ed(t,e=!0){const n=function(t){return Yh(t.reduce(((t,e)=>Hh(t,e)),[0,0]),t.length)}(t);return t.sort((([t,r],[i,o])=>{const a=Math.atan2(r-n[1],t-n[0]),s=Math.atan2(o-n[1],i-n[0]);return e?s-a:a-s}))}function wd(t,e){return[t,[t[0],e[1]],e,[e[0],t[1]]]}class kd{constructor(t,e,n){if(this.phase=e,this.pointerByTouch=[],this.initialDistance=null,this.emitter=t,kd.instance)return kd.callbacks[this.phase].push(n),kd.instance;this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.bindEvents(),kd.instance=this,kd.callbacks[this.phase].push(n)}bindEvents(){const{emitter:e}=this;e.on(t.CommonEvent.POINTER_DOWN,this.onPointerDown),e.on(t.CommonEvent.POINTER_MOVE,this.onPointerMove),e.on(t.CommonEvent.POINTER_UP,this.onPointerUp)}updatePointerPosition(t,e,n){const r=this.pointerByTouch.findIndex((e=>e.pointerId===t));r>=0&&(this.pointerByTouch[r]={x:e,y:n,pointerId:t})}onPointerDown(t){const{x:e,y:n}=t.client||{};if(void 0!==e&&void 0!==n&&(this.pointerByTouch.push({x:e,y:n,pointerId:t.pointerId}),"touch"===t.pointerType&&2===this.pointerByTouch.length)){kd.isPinching=!0;const e=this.pointerByTouch[0].x-this.pointerByTouch[1].x,n=this.pointerByTouch[0].y-this.pointerByTouch[1].y;this.initialDistance=Math.sqrt(e*e+n*n),kd.callbacks.pinchstart.forEach((e=>e(t,{scale:0})))}}onPointerMove(t){if(2!==this.pointerByTouch.length||null===this.initialDistance)return;const{x:e,y:n}=t.client||{};if(void 0===e||void 0===n)return;this.updatePointerPosition(t.pointerId,e,n);const r=this.pointerByTouch[0].x-this.pointerByTouch[1].x,i=this.pointerByTouch[0].y-this.pointerByTouch[1].y,o=Math.sqrt(r*r+i*i)/this.initialDistance;kd.callbacks.pinchmove.forEach((e=>e(t,{scale:5*(o-1)})))}onPointerUp(t){var e;kd.callbacks.pinchend.forEach((e=>e(t,{scale:0}))),kd.isPinching=!1,this.initialDistance=null,this.pointerByTouch=[],null===(e=kd.instance)||void 0===e||e.tryDestroy()}destroy(){this.emitter.off(t.CommonEvent.POINTER_DOWN,this.onPointerDown),this.emitter.off(t.CommonEvent.POINTER_MOVE,this.onPointerMove),this.emitter.off(t.CommonEvent.POINTER_UP,this.onPointerUp),kd.instance=null}off(t,e){const n=kd.callbacks[t].indexOf(e);n>-1&&kd.callbacks[t].splice(n,1),this.tryDestroy()}tryDestroy(){Object.values(kd.callbacks).every((t=>0===t.length))&&this.destroy()}}kd.isPinching=!1,kd.instance=null,kd.callbacks={pinchstart:[],pinchmove:[],pinchend:[]};const Md=t=>t.map((t=>ne(t)?t.toLocaleLowerCase():t));class Sd{constructor(e){this.map=new Map,this.boundHandlePinch=()=>{},this.recordKey=new Set,this.onKeyDown=t=>{(null==t?void 0:t.key)&&(this.recordKey.add(t.key),this.trigger(t))},this.onKeyUp=t=>{(null==t?void 0:t.key)&&this.recordKey.delete(t.key)},this.onWheel=e=>{this.triggerExtendKey(t.CommonEvent.WHEEL,e)},this.onDrag=e=>{this.triggerExtendKey(t.CommonEvent.DRAG,e)},this.handlePinch=(e,n)=>{this.triggerExtendKey(t.CommonEvent.PINCH,Object.assign(Object.assign({},e),n))},this.onFocus=()=>{this.recordKey.clear()},this.emitter=e,this.bindEvents()}bind(e,n){0!==e.length&&(e.includes(t.CommonEvent.PINCH)&&!this.pinchHandler&&(this.boundHandlePinch=this.handlePinch.bind(this),this.pinchHandler=new kd(this.emitter,"pinchmove",this.boundHandlePinch)),this.map.set(e,n))}unbind(t,e){this.map.forEach(((n,r)=>{Ne(r,t)&&(e&&e!==n||this.map.delete(r))}))}unbindAll(){this.map.clear()}match(t){const e=Md(Array.from(this.recordKey)).sort(),n=Md(t).sort();return Ne(e,n)}bindEvents(){var e;const{emitter:n}=this;n.on(t.CommonEvent.KEY_DOWN,this.onKeyDown),n.on(t.CommonEvent.KEY_UP,this.onKeyUp),n.on(t.CommonEvent.WHEEL,this.onWheel),n.on(t.CommonEvent.DRAG,this.onDrag),null===(e=globalThis.addEventListener)||void 0===e||e.call(globalThis,"focus",this.onFocus)}trigger(t){this.map.forEach(((e,n)=>{this.match(n)&&e(t)}))}triggerExtendKey(t,e){this.map.forEach(((n,r)=>{r.includes(t)&&Ne(Array.from(this.recordKey),r.filter((e=>e!==t)))&&n(e)}))}destroy(){var e,n;this.unbindAll(),this.emitter.off(t.CommonEvent.KEY_DOWN,this.onKeyDown),this.emitter.off(t.CommonEvent.KEY_UP,this.onKeyUp),this.emitter.off(t.CommonEvent.WHEEL,this.onWheel),this.emitter.off(t.CommonEvent.DRAG,this.onDrag),null===(e=this.pinchHandler)||void 0===e||e.off("pinchmove",this.boundHandlePinch),null===(n=globalThis.removeEventListener)||void 0===n||n.call(globalThis,"blur",this.onFocus)}}class Nd extends Gh{constructor(t,e){super(t,ke({},Nd.defaultOptions,e)),this.shortcut=new Sd(t.graph),this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.clearStates=this.clearStates.bind(this),this.bindEvents()}onPointerDown(t){if(!this.validate(t)||!this.isKeydown()||this.startPoint)return;const{canvas:e,graph:n}=this.context,r=Object.assign({},this.options.style);this.options.style.lineWidth&&(r.lineWidth=+this.options.style.lineWidth/n.getZoom()),this.rectShape=new ru({id:"g6-brush-select",style:r}),e.appendChild(this.rectShape),this.startPoint=[t.canvas.x,t.canvas.y]}onPointerMove(t){var e;if(!this.startPoint)return;const{immediately:n,mode:r}=this.options;this.endPoint=Od(t),null===(e=this.rectShape)||void 0===e||e.attr({x:Math.min(this.endPoint[0],this.startPoint[0]),y:Math.min(this.endPoint[1],this.startPoint[1]),width:Math.abs(this.endPoint[0]-this.startPoint[0]),height:Math.abs(this.endPoint[1]-this.startPoint[1])}),n&&"default"===r&&this.updateElementsStates(wd(this.startPoint,this.endPoint))}onPointerUp(t){this.startPoint&&(this.endPoint?(this.endPoint=Od(t),this.updateElementsStates(wd(this.startPoint,this.endPoint)),this.clearBrush()):this.clearBrush())}clearStates(){this.endPoint||this.clearElementsStates()}clearElementsStates(){const{graph:t}=this.context,e=Object.values(t.getData()).reduce(((t,e)=>Object.assign({},t,e.reduce(((t,e)=>{var n;const r=null===(n=e.states||[])||void 0===n?void 0:n.filter((t=>t!==this.options.state));return t[Nh(e)]=r,t}),{}))),{});t.setElementState(e,this.options.animation)}updateElementsStates(t){const{graph:e}=this.context,{enableElements:n,state:r,mode:i,onSelect:o}=this.options,a=this.selector(e,t,n);let s={};switch(i){case"union":a.forEach((t=>{s[t]=[...e.getElementState(t),r]}));break;case"diff":a.forEach((t=>{const n=e.getElementState(t);s[t]=n.includes(r)?n.filter((t=>t!==r)):[...n,r]}));break;case"intersect":a.forEach((t=>{const n=e.getElementState(t);s[t]=n.includes(r)?[r]:[]}));break;default:a.forEach((t=>{s[t]=[r]}))}Ut(o)&&(s=o(s)),e.setElementState(s,this.options.animation)}selector(t,e,n){if(!n||0===n.length)return[];const r=[],i=t.getData();if(n.forEach((n=>{i[`${n}s`].forEach((n=>{const i=Nh(n);"hidden"!==t.getElementVisibility(i)&&function(t,e,n,r){const i=t[0],o=t[1];let a=!1;void 0===n&&(n=0),void 0===r&&(r=e.length);const s=r-n;for(let t=0,r=s-1;to!=c>o&&i<(u-s)*(o-l)/(c-l)+s&&(a=!a)}return a}(t.getElementPosition(i),e)&&r.push(i)}))})),n.includes("edge")){const t=i.edges;null==t||t.forEach((t=>{const{source:e,target:n}=t;r.includes(e)&&r.includes(n)&&r.push(Nh(t))}))}return r}clearBrush(){var t;null===(t=this.rectShape)||void 0===t||t.remove(),this.rectShape=void 0,this.startPoint=void 0,this.endPoint=void 0}isKeydown(){const{trigger:t}=this.options,e=Array.isArray(t)?t:[t];return this.shortcut.match(e.filter((t=>"drag"!==t)))}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}bindEvents(){const{graph:e}=this.context;e.on(t.CommonEvent.POINTER_DOWN,this.onPointerDown),e.on(t.CommonEvent.POINTER_MOVE,this.onPointerMove),e.on(t.CommonEvent.POINTER_UP,this.onPointerUp),e.on(t.CanvasEvent.CLICK,this.clearStates)}unbindEvents(){const{graph:e}=this.context;e.off(t.CommonEvent.POINTER_DOWN,this.onPointerDown),e.off(t.CommonEvent.POINTER_MOVE,this.onPointerMove),e.off(t.CommonEvent.POINTER_UP,this.onPointerUp),e.off(t.CanvasEvent.CLICK,this.clearStates)}update(t){this.unbindEvents(),this.options=ke(this.options,t),this.bindEvents()}destroy(){this.unbindEvents(),super.destroy()}}Nd.defaultOptions={animation:!1,enable:!0,enableElements:["node","combo","edge"],immediately:!1,mode:"default",state:"selected",trigger:["shift"],style:{width:0,height:0,lineWidth:1,fill:"#1677FF",stroke:"#1677FF",fillOpacity:.1,zIndex:2,pointerEvents:"none"}};const Od=t=>[t.canvas.x,t.canvas.y],Td=.8,Cd=["node","edge","combo"];function Ad(t,e,n,r,i=0){"TB"===r&&e(t,i);const o=n(t);if(o)for(const t of o)Ad(t,e,n,r,i+1);"BT"===r&&e(t,i)}function Pd(t,e,n,r,i="both"){if("combo"===e||"node"===e)return Rd(t,n,r,i);const o=t.getEdgeData(n);if(!o)return[];const a=Rd(t,o.source,r-1,i),s=Rd(t,o.target,r-1,i);return Array.from(new Set([...a,...s,n]))}function Rd(t,e,n,r="both"){const i=new Set,o=new Set,a=new Set;return function(t,e,n){const r=[[t,0]];for(;r.length;){const[t,i]=r.shift();e(t,i);const o=n(t);if(o)for(const t of o)r.push([t,i+1])}}(e,((e,i)=>{i>n||(a.add(e),t.getRelatedEdgesData(e,r).forEach((t=>{const e=Nh(t);!o.has(e)&&it.getRelatedEdgesData(e,r).map((t=>t.source===e?t.target:t.source)).filter((t=>!i.has(t)&&(i.add(t),!0))))),Array.from(a)}function Dd(t){return t.states||[]}class Ld extends Gh{constructor(t,e){super(t,Object.assign({},Ld.defaultOptions,e)),this.onClickSelect=t=>ze(this,void 0,void 0,(function*(){var e,n;this.validate(t)&&(yield this.updateState(t),null===(n=(e=this.options).onClick)||void 0===n||n.call(e,t))})),this.onClickCanvas=t=>ze(this,void 0,void 0,(function*(){var e,n;this.validate(t)&&(yield this.clearState(),null===(n=(e=this.options).onClick)||void 0===n||n.call(e,t))})),this.shortcut=new Sd(t.graph),this.bindEvents()}bindEvents(){const{graph:e}=this.context;this.unbindEvents(),Cd.forEach((n=>{e.on(`${n}:${t.CommonEvent.CLICK}`,this.onClickSelect)})),e.on(t.CanvasEvent.CLICK,this.onClickCanvas)}get isMultipleSelect(){const{multiple:t,trigger:e}=this.options;return t&&this.shortcut.match(e)}getNeighborIds(t){const{target:e,targetType:n}=t,{graph:r}=this.context,{degree:i}=this.options;return Pd(r,n,e.id,"function"==typeof i?i(t):i).filter((t=>t!==e.id))}updateState(t){return ze(this,void 0,void 0,(function*(){const{state:e,unselectedState:n,neighborState:r,animation:i}=this.options;if(!e&&!r&&!n)return;const{target:o}=t,{graph:a}=this.context,s=Dd(a.getElementData(o.id)).includes(e)?"unselect":"select",l={},u=this.isMultipleSelect,c=[o.id],h=this.getNeighborIds(t);if(u)if(Object.assign(l,this.getDataStates()),"select"===s){const t=(t,e)=>{t.forEach((t=>{const r=new Set(a.getElementState(t));r.add(e),r.delete(n),l[t]=Array.from(r)}))};t(c,e),t(h,r),n&&Object.keys(l).forEach((t=>{const i=l[t];i.includes(e)||i.includes(r)||i.includes(n)||l[t].push(n)}))}else{const t=l[o.id];l[o.id]=t.filter((t=>t!==e&&t!==r)),t.includes(n)||l[o.id].push(n),h.forEach((t=>{l[t]=l[t].filter((t=>t!==r)),l[t].includes(e)||l[t].push(n)}))}else if("select"===s){Object.assign(l,this.getClearStates(!!n));const t=(t,e)=>{t.forEach((t=>{l[t]||(l[t]=a.getElementState(t)),l[t].push(e)}))};t(c,e),t(h,r),n&&Object.keys(l).forEach((t=>{c.includes(t)||h.includes(t)||l[t].push(n)}))}else Object.assign(l,this.getClearStates());yield a.setElementState(l,i)}))}getDataStates(){const{graph:t}=this.context,{nodes:e,edges:n,combos:r}=t.getData(),i={};return[...e,...n,...r].forEach((t=>{i[Nh(t)]=Dd(t)})),i}getClearStates(t=!1){const{graph:e}=this.context,{state:n,unselectedState:r,neighborState:i}=this.options,o=new Set([n,r,i]),{nodes:a,edges:s,combos:l}=e.getData(),u={};return[...a,...s,...l].forEach((e=>{const n=Dd(e),r=n.filter((t=>!o.has(t)));(t||r.length!==n.length)&&(u[Nh(e)]=r)})),u}clearState(){return ze(this,void 0,void 0,(function*(){const{graph:t}=this.context;yield t.setElementState(this.getClearStates(),this.options.animation)}))}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}unbindEvents(){const{graph:e}=this.context;Cd.forEach((n=>{e.off(`${n}:${t.CommonEvent.CLICK}`,this.onClickSelect)})),e.off(t.CanvasEvent.CLICK,this.onClickCanvas)}destroy(){this.unbindEvents(),super.destroy()}}function _d(t){var e;return!!(null===(e=t.style)||void 0===e?void 0:e.collapsed)}function Id(t,e){if(!t.startsWith(e))return!1;const n=t[e.length];return n>="A"&&n<="Z"}function jd(t,e,n=!0){if(!e)return t;if(!Id(t,e))return t;const r=t.slice(e.length);return n?function(t){var e=he(t);return e.charAt(0).toLowerCase()+e.substring(1)}(r):r}function Bd(t,e){const n=Object.entries(t).reduce(((t,[n,r])=>("className"===n||"class"===n||Id(n,e)&&Object.assign(t,{[jd(n,e)]:r}),t)),{});if("opacity"in t){const r=function(t,e){return`${e}${de(t)}`}("opacity",e),i=t.opacity;if(r in t){const e=t[r];Object.assign(n,{opacity:i*e})}else Object.assign(n,{opacity:i})}return n}function Fd(t,e){const n=e.length;return Object.keys(t).reduce(((r,i)=>{if(i.startsWith(e)){r[i.slice(n)]=t[i]}return r}),{})}function zd(t,e){const n="string"==typeof e?[e]:e,r={};return Object.keys(t).forEach((e=>{n.find((t=>e.startsWith(t)))||(r[e]=t[e])})),r}function Gd(t=0){if("number"==typeof t)return[t,t,t];const[e,n=e,r=e]=t;return[e,n,r]}function Vd(t,e){const{datum:n,graph:r}=e;return"function"==typeof t?t.call(r,n):Object.fromEntries(Object.entries(t).map((([t,e])=>"function"==typeof e?[t,e.call(r,n)]:[t,e])))}function Wd(t,e){const n=(null==t?void 0:t.style)||{},r=(null==e?void 0:e.style)||{};for(const t in n)t in r||(r[t]=n[t]);return Object.assign({},t,e,{style:r})}function Hd(t){if(t)return"string"==typeof t||"function"==typeof t||Array.isArray(t)?{type:"group",field:t=>t.id,color:t,invert:!1}:t}function Ud(t){const e="string"==typeof t?Dc("palette",t):t;if("function"!=typeof e)return e}function $d(t,e){let n=2*t;return"string"==typeof e?n=t*Number(e.replace("%",""))/100:"number"==typeof e&&(n=e),isNaN(n)&&(n=2*t),n}function Yd(t,e,n=1,r=!1){const i=r?n:1;return $d((t.max[0]-t.min[0])*i,e)}Ld.defaultOptions={animation:!0,enable:!0,multiple:!1,trigger:["shift"],state:"selected",neighborState:"selected",unselectedState:void 0,degree:0};class qd extends Wl{constructor(t){Kd(t.style),super(t),this.shapeMap={},this.animateMap={},this.render(this.attributes,this),this.setVisibility(),this.bindEvents()}get parsedAttributes(){return this.attributes}upsert(e,n,r,i,o){var a,s,l,u,c,h,d,f;const p=this.shapeMap[e];if(!1===r)return void(p&&(null===(a=null==o?void 0:o.beforeDestroy)||void 0===a||a.call(o,p),i.removeChild(p),delete this.shapeMap[e],null===(s=null==o?void 0:o.afterDestroy)||void 0===s||s.call(o,p)));const g="string"==typeof n?Dc(t.ExtensionCategory.SHAPE,n):n;if(!g)throw new Error(_c(`Shape ${n} not found`));if(!p||p.destroyed||!(p instanceof g)){p&&(null===(l=null==o?void 0:o.beforeDestroy)||void 0===l||l.call(o,p),null==p||p.destroy(),null===(u=null==o?void 0:o.afterDestroy)||void 0===u||u.call(o,p)),null===(c=null==o?void 0:o.beforeCreate)||void 0===c||c.call(o);const t=new g({className:e,style:r});return i.appendChild(t),this.shapeMap[e]=t,null===(h=null==o?void 0:o.afterCreate)||void 0===h||h.call(o,t),t}return null===(d=null==o?void 0:o.beforeUpdate)||void 0===d||d.call(o,p),Wg(p,r),null===(f=null==o?void 0:o.afterUpdate)||void 0===f||f.call(o,p),p}update(t={}){const e=Object.assign({},this.attributes,t);Kd(e),function(t,e){const{zIndex:n,transform:r,transformOrigin:i,visibility:o,cursor:a,clipPath:s,component:l}=e,u=Fe(e,["zIndex","transform","transformOrigin","visibility","cursor","clipPath","component"]);Object.assign(t.attributes,u),r&&t.setAttribute("transform",r);ae(n)&&t.setAttribute("zIndex",n);i&&t.setAttribute("transformOrigin",i);o&&t.setAttribute("visibility",o);a&&t.setAttribute("cursor",a);s&&t.setAttribute("clipPath",s);l&&t.setAttribute("component",l)}(this,e),this.render(e,this),this.setVisibility()}bindEvents(){}getGraphicStyle(t){return function(t){const{x:e,y:n,z:r,class:i,className:o,transform:a,transformOrigin:s,zIndex:l,visibility:u}=t;return Fe(t,["x","y","z","class","className","transform","transformOrigin","zIndex","visibility"])}(t)}get compositeShapes(){return[["badges","badge-"],["ports","port-"]]}animate(t,e){if(0===t.length)return null;const n=[];if(void 0!==t[0].x||void 0!==t[0].y||void 0!==t[0].z){const{x:e=0,y:n=0,z:r=0}=this.attributes;t.forEach((t=>{const{x:i=e,y:o=n,z:a=r}=t;Object.assign(t,{transform:a?[["translate3d",i,o,a]]:[["translate",i,o]]})}))}const r=super.animate(t,e);if(r&&(Xd(this,r),n.push(r)),Array.isArray(t)&&t.length>0){const r=["transform","transformOrigin","x","y","z","zIndex"];if(Object.keys(t[0]).some((t=>!r.includes(t)))){Object.entries(this.shapeMap).forEach((([r,i])=>{const o=this[`get${de(r)}Style`];if(Ut(o)){const r=t.map((t=>o.call(this,Object.assign(Object.assign({},this.attributes),t)))),a=i.animate(Fc(r),e);a&&(Xd(i,a),n.push(a))}}));const r=(r,i)=>{if(!Se(r)){const o=this[`get${de(i)}Style`];if(Ut(o)){const i=t.map((t=>o.call(this,Object.assign(Object.assign({},this.attributes),t))));Object.entries(i[0]).map((([t])=>{const o=i.map((e=>e[t])),a=r[t];if(a){const t=a.animate(Fc(o),e);t&&(Xd(a,t),n.push(t))}}))}}};this.compositeShapes.forEach((([t,e])=>{const n=Fd(this.shapeMap,e);r(n,t)}))}}return Bc(n)}getShape(t){return this.shapeMap[t]}setVisibility(){const{visibility:t}=this.attributes;Bh(this,t)}destroy(){this.shapeMap={},this.animateMap={},super.destroy()}}function Xd(t,e){null==e||e.finished.then((()=>{const n=t.activeAnimations.findIndex((t=>t===e));n>-1&&t.activeAnimations.splice(n,1)}))}function Kd(t){if(!t)return{};if("x"in t||"y"in t||"z"in t){const{x:e=0,y:n=0,z:r,transform:i}=t,o=Wc(e,n,r,i);o&&(t.transform=o)}return t}class Zd extends qd{constructor(t){super(Wd({style:Zd.defaultStyleProps},t))}isTextStyle(t){return Id(t,"label")}isBackgroundStyle(t){return Id(t,"background")}getTextStyle(t){const e=this.getGraphicStyle(t),{padding:n}=e;return zd(Fe(e,["padding"]),"background")}getBackgroundStyle(t){if(!1===t.background)return!1;const e=this.getGraphicStyle(t),{wordWrap:n,wordWrapWidth:r,padding:i}=e,o=Bd(e,"background"),{min:[a,s],center:[l,u],halfExtents:[c,h]}=this.shapeMap.text.getGeometryBounds(),[d,f,p,g]=Jc(i),v=2*c+g+f,{width:m,height:y}=o;m&&y?Object.assign(o,{x:l-Number(m)/2,y:u-Number(y)/2}):Object.assign(o,{x:a-g,y:s-d,width:n?Math.min(v,r+g+f):v,height:2*h+d+p});const{radius:b}=o;if("string"==typeof b&&b.endsWith("%")){const t=Number(b.replace("%",""))/100;o.radius=Math.min(+o.width,+o.height)*t}return o}render(t=this.parsedAttributes,e=this){this.upsert("text",ou,this.getTextStyle(t),e),this.upsert("background",ru,this.getBackgroundStyle(t),e)}getGeometryBounds(){return(this.getShape("background")||this.getShape("text")).getGeometryBounds()}}Zd.defaultStyleProps={padding:0,fontSize:12,fontFamily:"system-ui, sans-serif",wordWrap:!0,maxLines:1,wordWrapWidth:128,textOverflow:"...",textBaseline:"middle",backgroundOpacity:.75,backgroundZIndex:-1,backgroundLineWidth:0};class Qd extends qd{constructor(t){super(Wd({style:Qd.defaultStyleProps},t))}getBadgeStyle(t){return this.getGraphicStyle(t)}render(t=this.parsedAttributes,e=this){this.upsert("label",Zd,this.getBadgeStyle(t),e)}getGeometryBounds(){const t=this.getShape("label");return(t.getShape("background")||t.getShape("text")).getGeometryBounds()}}Qd.defaultStyleProps={padding:[2,4,2,4],fontSize:10,wordWrap:!1,backgroundRadius:"50%",backgroundOpacity:1};const Jd={M:["x","y"],m:["dx","dy"],H:["x"],h:["dx"],V:["y"],v:["dy"],L:["x","y"],l:["dx","dy"],Z:[],z:[],C:["x1","y1","x2","y2","x","y"],c:["dx1","dy1","dx2","dy2","dx","dy"],S:["x2","y2","x","y"],s:["dx2","dy2","dx","dy"],Q:["x1","y1","x","y"],q:["dx1","dy1","dx","dy"],T:["x","y"],t:["dx","dy"],A:["rx","ry","rotation","large-arc","sweep","x","y"],a:["rx","ry","rotation","large-arc","sweep","dx","dy"]};function tf(t){const e=[],n="string"==typeof t?function(t){const e=t.replace(/[\n\r]/g,"").replace(/-/g," -").replace(/(\d*\.)(\d+)(?=\.)/g,"$1$2 ").trim().split(/\s*,|\s+/),n=[];let r="",i={};for(;e.length>0;){let t=e.shift();t in Jd?r=t:e.unshift(t),i={type:r},Jd[r].forEach((n=>{t=e.shift(),i[n]=t})),"M"===r?r="L":"m"===r&&(r="l");const[o,...a]=Object.values(i);n.push([o,...a.map(Number)])}return n}(t):t;return n.forEach((t=>{const n=t[0];if("Z"!==n)if("A"!==n)for(let n=1;n{if(t.length<2)return[["M",0,0],["L",0,0]];const e=t[0],n=t[1],r=t[t.length-1],i=t[t.length-2];t.unshift(i,r),t.push(e,n);const o=[["M",r[0],r[1]]];for(let e=1;e{const n=t,r=c[(e+1)%c.length];return Ne(n,r)?null:[n,r]})).filter(Boolean),d=bd([s,l],h),f=xd([s,l],d);if(f&&d&&(u.transform=[["translate",f[0]+n,f[1]+r]],a)){const t=Math.atan((d[0][1]-d[1][1])/(d[0][0]-d[1][0]));u.transform.push(["rotate",t/Math.PI*180]),u.textAlign="center","right"!==e&&"left"!==e||(u.textBaseline=t>0?"right"===e?"bottom":"top":"right"===e?"top":"bottom")}return u}(c,a,r,i,s,t.d,o),{wordWrapWidth:Yd(c,n)},l)}getKeyStyle(t){return this.getGraphicStyle(t)}render(t,e){this.upsert("key",Ql,this.getKeyStyle(t),e),this.upsert("label",Zd,this.getLabelStyle(t),e)}}nf.defaultStyleProps={label:!0,labelPlacement:"bottom",labelCloseToPath:!0,labelAutoRotate:!0,labelOffsetX:0,labelOffsetY:0};let rf=class extends ql{constructor(t){super(t),this.onMounted=()=>{this.handleRadius()},this.onAttrModified=()=>{this.handleRadius()},af=this,this.isMutationObserved=!0,this.addEventListener(Ks.MOUNTED,this.onMounted),this.addEventListener(Ks.ATTR_MODIFIED,this.onAttrModified)}handleRadius(){const{radius:t,clipPath:e,width:n=0,height:r=0}=this.attributes;if(t&&n&&r){const[i,o]=this.getBounds().min,a={x:i,y:o,radius:t,width:n,height:r};if(e)Object.assign(this.parsedStyle.clipPath.style,a);else{const t=new ru({style:a});this.style.clipPath=t}}else e&&(this.style.clipPath=null)}};const of=new WeakMap;let af=null;const sf=t=>{if(af&&function(t){const e=[];let n=t.parentNode;for(;n;)e.push(n),n=n.parentNode;return e}(af).includes(t)){const e=of.get(t);e?e.includes(af)||e.push(af):of.set(t,[af])}},lf=t=>{const e=of.get(t);e&&e.forEach((t=>t.handleRadius()))};class uf extends qd{constructor(t){super(t)}isImage(){const{src:t}=this.attributes;return!!t}getIconStyle(t=this.attributes){const{width:e=0,height:n=0}=t,r=this.getGraphicStyle(t);return this.isImage()?Object.assign({x:-e/2,y:-n/2},r):Object.assign({textBaseline:"middle",textAlign:"center"},r)}render(t=this.attributes,e=this){this.upsert("icon",this.isImage()?rf:ou,this.getIconStyle(t),e)}}class cf extends qd{get context(){return this.config.context}get parsedAttributes(){return this.attributes}onframe(){}animate(t,e){const n=super.animate(t,e);return n&&(n.onframe=()=>this.onframe(),n.finished.then((()=>this.onframe()))),n}}class hf extends cf{constructor(t){super(Wd({style:hf.defaultStyleProps},t)),this.type="node"}getSize(t=this.attributes){const{size:e}=t;return Gd(e)}getKeyStyle(t){const e=this.getGraphicStyle(t);return Object.assign(zd(e,["label","halo","icon","badge","port"]))}getLabelStyle(t){if(!1===t.label||!t.labelText)return!1;const e=Bd(this.getGraphicStyle(t),"label"),{placement:n,maxWidth:r,offsetX:i,offsetY:o}=e,a=Fe(e,["placement","maxWidth","offsetX","offsetY"]),s=this.getShape("key").getLocalBounds();return Object.assign(Vg(s,n,i,o),{wordWrapWidth:Yd(s,r)},a)}getHaloStyle(t){if(!1===t.halo)return!1;const e=this.getKeyStyle(t),{fill:n}=e,r=Fe(e,["fill"]),i=Bd(this.getGraphicStyle(t),"halo");return Object.assign(Object.assign(Object.assign({},r),{stroke:n}),i)}getIconStyle(t){if(!1===t.icon||!t.iconText&&!t.iconSrc)return!1;const e=Bd(this.getGraphicStyle(t),"icon");return Object.assign(function(t,e){const n=Gd(t);let r={};return e.text&&!e.fontSize&&(r={fontSize:.5*Math.min(...n)}),!e.src||e.width&&e.height||(r={width:.5*n[0],height:.5*n[1]}),r}(t.size,e),e)}getBadgesStyle(t){var e;const n=Fd(this.shapeMap,"badge-"),r={};if(Object.keys(n).forEach((t=>{r[t]=!1})),!1===t.badge||!(null===(e=t.badges)||void 0===e?void 0:e.length))return r;const{badges:i=[],badgePalette:o,opacity:a=1}=t,s=Fe(t,["badges","badgePalette","opacity"]),l=Ud(o),u=Bd(this.getGraphicStyle(s),"badge");return i.forEach(((t,e)=>{r[e]=Object.assign(Object.assign({backgroundFill:l?l[e%(null==l?void 0:l.length)]:void 0,opacity:a},u),this.getBadgeStyle(t))})),r}getBadgeStyle(t){const e=this.getShape("key"),{placement:n="top",offsetX:r,offsetY:i}=t,o=Fe(t,["placement","offsetX","offsetY"]),a=Vg(e.getLocalBounds(),n,r,i,!0);return Object.assign(Object.assign({},a),o)}getPortsStyle(t){var e;const n=this.getPorts(),r={};if(Object.keys(n).forEach((t=>{r[t]=!1})),!1===t.port||!(null===(e=t.ports)||void 0===e?void 0:e.length))return r;const i=Bd(this.getGraphicStyle(t),"port"),{ports:o=[]}=t;return o.forEach(((e,n)=>{const o=e.key||n,a=Object.assign(Object.assign({},i),e);if(Ig(a))r[o]=!1;else{const[n,i]=this.getPortXY(t,e);r[o]=Object.assign({transform:[["translate",n,i]]},a)}})),r}getPortXY(t,e){const{placement:n="left"}=e,r=this.getShape("key");return Lg(function(t,e){if(!t)return e.getLocalBounds();const n=t.canvas.getLayer(),r=e.cloneNode();Bh(r,"hidden"),n.appendChild(r);const i=r.getLocalBounds();return r.destroy(),i}(this.context,r),n)}getPorts(){return Fd(this.shapeMap,"port-")}getCenter(){return this.getShape("key").getBounds().center}getIntersectPoint(t,e=!1){return function(t,e,n=!1){return md(t,ud(e,"center"),[ud(e,"left-top"),ud(e,"right-top"),ud(e,"right-bottom"),ud(e,"left-bottom")],!1,n).point}(t,this.getShape("key").getBounds(),e)}drawHaloShape(t,e){const n=this.getHaloStyle(t),r=this.getShape("key");this.upsert("halo",r.constructor,n,e)}drawIconShape(t,e){const n=this.getIconStyle(t);this.upsert("icon",uf,n,e),sf(this)}drawBadgeShapes(t,e){const n=this.getBadgesStyle(t);Object.keys(n).forEach((t=>{const r=n[t];this.upsert(`badge-${t}`,Qd,r,e)}))}drawPortShapes(t,e){const n=this.getPortsStyle(t);Object.keys(n).forEach((t=>{const r=n[t],i=`port-${t}`;this.upsert(i,Gl,r,e)}))}drawLabelShape(t,e){const n=this.getLabelStyle(t);this.upsert("label",Zd,n,e)}_drawKeyShape(t,e){return this.drawKeyShape(t,e)}render(t=this.parsedAttributes,e=this){this._drawKeyShape(t,e),this.getShape("key")&&(this.drawHaloShape(t,e),this.drawIconShape(t,e),this.drawBadgeShapes(t,e),this.drawLabelShape(t,e),this.drawPortShapes(t,e))}update(t){super.update(t),t&&("x"in t||"y"in t||"z"in t)&&lf(this)}onframe(){this.drawBadgeShapes(this.parsedAttributes,this),this.drawLabelShape(this.parsedAttributes,this)}}hf.defaultStyleProps={x:0,y:0,size:32,droppable:!0,draggable:!0,port:!0,ports:[],portZIndex:2,portLinkToCenter:!1,badge:!0,badges:[],badgeZIndex:3,halo:!1,haloDroppable:!1,haloLineDash:0,haloLineWidth:12,haloStrokeOpacity:.25,haloPointerEvents:"none",haloZIndex:-1,icon:!0,iconZIndex:1,label:!0,labelIsBillboard:!0,labelMaxWidth:"200%",labelPlacement:"bottom",labelWordWrap:!1,labelZIndex:0};let df=class t extends hf{constructor(e){super(Wd({style:t.defaultStyleProps},e))}drawKeyShape(t,e){return this.upsert("key",Gl,this.getKeyStyle(t),e)}getKeyStyle(t){const e=super.getKeyStyle(t);return Object.assign(Object.assign({},e),{r:Math.min(...this.getSize(t))/2})}getIconStyle(t){const e=super.getIconStyle(t),{r:n}=this.getShape("key").attributes,r=2*n*Td;return!!e&&Object.assign({width:r,height:r},e)}getIntersectPoint(t,e=!1){return yd(t,this.getShape("key").getBounds(),e)}};df.defaultStyleProps={size:32};class ff extends hf{constructor(t){super(t)}get parsedAttributes(){return this.attributes}drawKeyShape(t,e){return this.upsert("key",tu,this.getKeyStyle(t),e)}getKeyStyle(t){const e=super.getKeyStyle(t);return Object.assign(Object.assign({},e),{points:this.getPoints(t)})}getIntersectPoint(t,e=!1){var n,r;const{points:i}=this.getShape("key").attributes;return md(t,[+((null===(n=this.attributes)||void 0===n?void 0:n.x)||0),+((null===(r=this.attributes)||void 0===r?void 0:r.y)||0)],i,!0,e).point}}class pf extends ff{constructor(t){super(t)}getPoints(t){const[e,n]=this.getSize(t);return function(t,e){return[[0,-e/2],[t/2,0],[0,e/2],[-t/2,0]]}(e,n)}}class gf extends df{constructor(t){super(Wd({style:gf.defaultStyleProps},t))}parseOuterR(){const{size:t}=this.parsedAttributes;return Math.min(...Gd(t))/2}parseInnerR(){const{innerR:t}=this.parsedAttributes;return ne(t)?parseInt(t)/100*this.parseOuterR():t}drawDonutShape(t,e){const{donuts:n}=t;if(!(null==n?void 0:n.length))return;const r=n.map((t=>ae(t)?{value:t}:t)),i=Bd(this.getGraphicStyle(t),"donut"),o=Ud(t.donutPalette);if(!o)return;const a=r.reduce(((t,e)=>{var n;return t+(null!==(n=e.value)&&void 0!==n?n:0)}),0),s=this.parseOuterR(),l=this.parseInnerR();let u=0;r.forEach(((t,n)=>{const{value:c=0,color:h=o[n%o.length]}=t,d=Fe(t,["value","color"]),f=360*(0===a?1/r.length:c/a);this.upsert(`round${n}`,Ql,Object.assign(Object.assign(Object.assign({},i),{d:mf(s,l,u,u+f),fill:h}),d),e),u+=f}))}render(t,e=this){super.render(t,e),this.drawDonutShape(t,e)}}gf.defaultStyleProps={innerR:"50%",donuts:[],donutPalette:"tableau"};const vf=(t,e,n,r)=>[t+Math.sin(r)*n,e-Math.cos(r)*n],mf=(t=0,e=0,n,r)=>{const[i,o]=[0,0];return Math.abs(n-r)%360<1e-6?((t,e,n,r)=>r<=0||n<=r?[["M",t-n,e],["A",n,n,0,1,1,t+n,e],["A",n,n,0,1,1,t-n,e],["Z"]]:[["M",t-n,e],["A",n,n,0,1,1,t+n,e],["A",n,n,0,1,1,t-n,e],["Z"],["M",t+r,e],["A",r,r,0,1,0,t-r,e],["A",r,r,0,1,0,t+r,e],["Z"]])(i,o,t,e):((t,e,n,r,i,o)=>{const[a,s]=[i/360*2*Math.PI,o/360*2*Math.PI],l=[vf(t,e,r,a),vf(t,e,n,a),vf(t,e,n,s),vf(t,e,r,s)],u=s-a>Math.PI?1:0;return[["M",l[0][0],l[0][1]],["L",l[1][0],l[1][1]],["A",n,n,0,u,1,l[2][0],l[2][1]],["L",l[3][0],l[3][1]],["A",r,r,0,u,0,l[0][0],l[0][1]],["Z"]]})(i,o,t,e,n,r)};class yf extends hf{constructor(t){super(Wd({style:yf.defaultStyleProps},t))}drawKeyShape(t,e){return this.upsert("key",Hl,this.getKeyStyle(t),e)}getKeyStyle(t){const e=super.getKeyStyle(t),[n,r]=this.getSize(t);return Object.assign(Object.assign({},e),{rx:n/2,ry:r/2})}getIconStyle(t){const e=super.getIconStyle(t),{rx:n,ry:r}=this.getShape("key").attributes,i=2*Math.min(+n,+r)*Td;return!!e&&Object.assign({width:i,height:i},e)}getIntersectPoint(t,e=!1){return yd(t,this.getShape("key").getBounds(),e)}}yf.defaultStyleProps={size:[45,35]};class bf extends ff{constructor(t){super(t)}getOuterR(t){return t.outerR||Math.min(...this.getSize(t))/2}getPoints(t){return[[0,e=this.getOuterR(t)],[e*Math.sqrt(3)/2,e/2],[e*Math.sqrt(3)/2,-e/2],[0,-e],[-e*Math.sqrt(3)/2,-e/2],[-e*Math.sqrt(3)/2,e/2]];var e}getIconStyle(t){const e=super.getIconStyle(t),n=this.getOuterR(t)*Td;return!!e&&Object.assign({width:n,height:n},e)}} -/*! - * @antv/g-plugin-canvas-path-generator - * @description A G plugin of path generator with Canvas2D API - * @version 2.1.19 - * @date 5/9/2025, 8:19:59 AM - * @author AntVis - * @docs https://g.antv.antgroup.com/ - */function xf(t,e){var n=e.cx,r=void 0===n?0:n,i=e.cy,o=void 0===i?0:i,a=e.r;t.arc(r,o,a,0,2*Math.PI,!1)}function Ef(t,e){var n=e.cx,r=void 0===n?0:n,i=e.cy,o=void 0===i?0:i,a=e.rx,s=e.ry;if(t.ellipse)t.ellipse(r,o,a,s,0,0,2*Math.PI,!1);else{var l=a>s?a:s,u=a>s?1:a/s,c=a>s?s/a:1;t.save(),t.scale(u,c),t.arc(r,o,l,0,2*Math.PI)}}function wf(t,e){var n,r,i=e.x1,o=e.y1,a=e.x2,s=e.y2,l=e.markerStart,u=e.markerEnd,c=e.markerStartOffset,h=e.markerEndOffset,d=0,f=0,p=0,g=0,v=0;l&&_l(l)&&c&&(n=a-i,r=s-o,v=Math.atan2(r,n),d=Math.cos(v)*(c||0),f=Math.sin(v)*(c||0)),u&&_l(u)&&h&&(n=i-a,r=o-s,v=Math.atan2(r,n),p=Math.cos(v)*(h||0),g=Math.sin(v)*(h||0)),t.moveTo(i+d,o+f),t.lineTo(a+p,s+g)}function kf(t,e){var n,r,i=e.markerStart,o=e.markerEnd,a=e.markerStartOffset,s=e.markerEndOffset,l=e.d,u=l.absolutePath,c=l.segments,h=0,d=0,f=0,p=0,g=0;if(i&&_l(i)&&a){var v=b(i.parentNode.getStartTangent(),2),m=v[0],y=v[1];n=m[0]-y[0],r=m[1]-y[1],g=Math.atan2(r,n),h=Math.cos(g)*(a||0),d=Math.sin(g)*(a||0)}if(o&&_l(o)&&s){var x=b(o.parentNode.getEndTangent(),2),E=x[0],w=x[1];n=E[0]-w[0],r=E[1]-w[1],g=Math.atan2(r,n),f=Math.cos(g)*(s||0),p=Math.sin(g)*(s||0)}for(var k=0;kF?B:F,U=B>F?1:B/F,$=B>F?F/B:1;t.translate(I,j),t.rotate(V),t.scale(U,$),t.arc(0,0,H,z,G,!!(1-W)),t.scale(1/U,1/$),t.rotate(-V),t.translate(-I,-j)}T&&t.lineTo(M[6]+f,M[7]+p);break;case"Z":t.closePath()}}}function Mf(t,e){var n,r,i=e.markerStart,o=e.markerEnd,a=e.markerStartOffset,s=e.markerEndOffset,l=e.points.points,u=l.length,c=l[0][0],h=l[0][1],d=l[u-1][0],f=l[u-1][1],p=0,g=0,v=0,m=0,y=0;i&&_l(i)&&a&&(n=l[1][0]-l[0][0],r=l[1][1]-l[0][1],y=Math.atan2(r,n),p=Math.cos(y)*(a||0),g=Math.sin(y)*(a||0)),o&&_l(o)&&s&&(n=l[u-1][0]-l[0][0],r=l[u-1][1]-l[0][1],y=Math.atan2(r,n),v=Math.cos(y)*(s||0),m=Math.sin(y)*(s||0)),t.moveTo(c+(p||v),h+(g||m));for(var b=1;b0?1:-1,d=l>0?1:-1,f=h+d===0,p=b(a.map((function(t){return oe(t,0,Math.min(Math.abs(u)/2,Math.abs(c)/2))})),4),g=p[0],v=p[1],m=p[2],y=p[3];t.moveTo(h*g+r,o),t.lineTo(u-h*v+r,o),0!==v&&t.arc(u-h*v+r,d*v+o,v,-d*Math.PI/2,h>0?0:Math.PI,f),t.lineTo(u+r,c-d*m+o),0!==m&&t.arc(u-h*m+r,c-d*m+o,m,h>0?0:Math.PI,d>0?Math.PI/2:1.5*Math.PI,f),t.lineTo(h*y+r,c+o),0!==y&&t.arc(h*y+r,c-d*y+o,y,d>0?Math.PI/2:-Math.PI/2,h>0?Math.PI:0,f),t.lineTo(r,d*g+o),0!==g&&t.arc(h*g+r,d*g+o,g,h>0?Math.PI:0,d>0?1.5*Math.PI:Math.PI/2,f)}else t.rect(r,o,u,c)}var Of=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i=l-m&&y<=l+m)}function Lf(t,e,n,r){return t/(n*n)+e/(r*r)}function _f(t,e,n){var r=t.parsedStyle,i=r.cx,o=void 0===i?0:i,a=r.cy,s=void 0===a?0:a,l=r.rx,u=r.ry,c=r.fill,h=r.stroke,d=r.lineWidth,f=void 0===d?1:d,p=r.increasedLineWidthForHitTesting,g=void 0===p?0:p,v=r.pointerEvents,m=void 0===v?"auto":v,y=e.x,x=e.y,E=b(Qa(m,c,h),2),w=E[0],k=E[1],M=(f+g)/2,S=(y-o)*(y-o),N=(x-s)*(x-s);return w&&k||n?Lf(S,N,l+M,u+M)<=1:w?Lf(S,N,l,u)<=1:!!k&&(Lf(S,N,l-M,u-M)>=1&&Lf(S,N,l+M,u+M)<=1)}function If(t,e,n,r,i,o){return i>=t&&i<=t+n&&o>=e&&o<=e+r}function jf(t,e,n,r,i,o,a,s){var l=(Math.atan2(s-e,a-t)+2*Math.PI)%(2*Math.PI),u={x:t+n*Math.cos(l),y:e+n*Math.sin(l)};return Rn(u.x,u.y,a,s)<=o/2}function Bf(t,e,n,r,i,o,a){var s=Math.min(t,n),l=Math.max(t,n),u=Math.min(e,r),c=Math.max(e,r),h=i/2;return o>=s-h&&o<=l+h&&a>=u-h&&a<=c+h&&zn(t,e,n,r,o,a)<=i/2}function Ff(t,e,n,r,i){var o=t.length;if(o<2)return!1;for(var a=0;a0!=zf(s[1]-n)>0&&zf(e-(n-a[1])*(a[0]-s[0])/(a[1]-s[1])-a[0])<0&&(r=!r)}return r}function Wf(t,e,n){for(var r=!1,i=0;i=i.min[0]&&e.y>=i.min[1]&&e.x<=i.max[0]&&e.y<=i.max[1]}var Zf=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i0&&void 0!==arguments[0]?arguments[0]:t.api;t.rafId&&(e.cancelAnimationFrame(t.rafId),t.rafId=null)}},{key:"executeTask",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t.api;np.length<=0&&rp.length<=0||(rp.forEach((function(t){return t()})),rp=np.splice(0,t.TASK_NUM_PER_FRAME),t.rafId=e.requestAnimationFrame((function(){t.executeTask(e)})))}},{key:"sliceImage",value:function(e,n,r,i){for(var o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:t.api,s=e.naturalWidth||e.width,l=e.naturalHeight||e.height,u=n-o,c=r-o,h=Math.ceil(s/u),d=Math.ceil(l/c),f={tileSize:[n,r],gridSize:[d,h],tiles:Array(d).fill(null).map((function(){return Array(h).fill(null)}))},p=function(t){for(var o=function(o){np.push((function(){var h=o*u,d=t*c,p=[Math.min(n,s-h),Math.min(r,l-d)],g=p[0],v=p[1],m=a.createCanvas();m.width=n,m.height=r,m.getContext("2d").drawImage(e,h,d,g,v,0,0,g,v),f.tiles[t][o]={x:h,y:d,tileX:o,tileY:t,data:m},i()}))},d=0;du&&v>c,e&&("function"==typeof e.resetTransform?e.resetTransform():e.setTransform(1,0,0,1,0,0),r.clearFullScreen&&r.clearRect(e,0,0,i*n,a*n,o.background))}));var m=function(t,e){for(var i=[t];i.length>0;){var o,a=i.pop();a.isVisible()&&!a.isCulled()&&(h?r.renderDisplayObjectOptimized(a,e,r.context,Qf(r,cp)[cp],n):r.renderDisplayObject(a,e,r.context,Qf(r,cp)[cp],n));for(var s=(null===(o=a.sortable)||void 0===o||null===(o=o.sorted)||void 0===o?void 0:o.length)>0?a.sortable.sorted:a.childNodes,l=s.length-1;l>=0;l--)i.push(s[l])}};s.hooks.endFrame.tap(t.tag,(function(){if(0!==l.root.childNodes.length){h=o.renderer.getConfig().enableRenderingOptimization,Qf(r,cp)[cp]={restoreStack:[],prevObject:null,currentContext:Qf(r,cp)[cp].currentContext},Qf(r,cp)[cp].currentContext.clear(),r.clearFullScreenLastFrame=!1;var t=f.getContext(),e=f.getDPR();if(W(r.dprMatrix,[e,e,1]),j(r.vpMatrix,r.dprMatrix,a.getOrthoMatrix()),r.clearFullScreen)h?(t.save(),m(l.root,t),t.restore()):m(l.root,t),r.removedRBushNodeAABBs=[];else{var i=r.safeMergeAABB.apply(r,[r.mergeDirtyAABBs(r.renderQueue)].concat(d(r.removedRBushNodeAABBs.map((function(t){var e=t.minX,n=t.minY,r=t.maxX,i=t.maxY,o=new Er;return o.setMinMax([e,n,0],[r,i,0]),o})))));if(r.removedRBushNodeAABBs=[],Er.isEmpty(i))return void(r.renderQueue=[]);var s=r.convertAABB2Rect(i),u=s.x,c=s.y,g=s.width,v=s.height,y=Mt(r.vec3a,[u,c,0],r.vpMatrix),b=Mt(r.vec3b,[u+g,c,0],r.vpMatrix),x=Mt(r.vec3c,[u,c+v,0],r.vpMatrix),E=Mt(r.vec3d,[u+g,c+v,0],r.vpMatrix),w=Math.min(y[0],b[0],E[0],x[0]),k=Math.min(y[1],b[1],E[1],x[1]),M=Math.max(y[0],b[0],E[0],x[0]),S=Math.max(y[1],b[1],E[1],x[1]),N=Math.floor(w),O=Math.floor(k),T=Math.ceil(M-w),C=Math.ceil(S-k);t.save(),r.clearRect(t,N,O,T,C,o.background),t.beginPath(),t.rect(N,O,T,C),t.clip(),t.setTransform(r.vpMatrix[0],r.vpMatrix[1],r.vpMatrix[4],r.vpMatrix[5],r.vpMatrix[12],r.vpMatrix[13]),o.renderer.getConfig().enableDirtyRectangleRenderingDebug&&p.dispatchEvent(new zs(fu.DIRTY_RECTANGLE,{dirtyRect:{x:N,y:O,width:T,height:C}})),r.searchDirtyObjects(i).sort((function(t,e){return t.sortable.renderOrder-e.sortable.renderOrder})).forEach((function(e){e&&e.isVisible()&&!e.isCulled()&&r.renderDisplayObject(e,t,r.context,Qf(r,cp)[cp],n)})),t.restore(),r.renderQueue.forEach((function(t){r.saveDirtyAABB(t)})),r.renderQueue=[]}Qf(r,cp)[cp].restoreStack.forEach((function(){t.restore()})),Qf(r,cp)[cp].restoreStack=[]}else r.clearFullScreenLastFrame=!0})),s.hooks.render.tap(t.tag,(function(t){r.clearFullScreen||r.renderQueue.push(t)}))}},{key:"clearRect",value:function(t,e,n,r,i,o){t.clearRect(e,n,r,i),o&&(t.fillStyle=o,t.fillRect(e,n,r,i))}},{key:"renderDisplayObjectOptimized",value:function(t,e,n,r,i){var o=t.nodeName,a=!1,s=this.context.styleRendererFactory[o],l=this.pathGeneratorFactory[o],u=t.parsedStyle.clipPath;if(u){(!r.prevObject||!st(u.getWorldTransform(),r.prevObject.getWorldTransform()))&&(this.applyWorldTransform(e,u),r.prevObject=null);var c=this.pathGeneratorFactory[u.nodeName];c&&(e.save(),a=!0,e.beginPath(),c(e,u.parsedStyle),e.closePath(),e.clip())}if(s){(!r.prevObject||!st(t.getWorldTransform(),r.prevObject.getWorldTransform()))&&this.applyWorldTransform(e,t);var h=!r.prevObject;if(!h){var d=r.prevObject.nodeName;h=o===hr.TEXT?d!==hr.TEXT:o===hr.IMAGE?d!==hr.IMAGE:d===hr.TEXT||d===hr.IMAGE}s.applyStyleToContext(e,t,h,r),r.prevObject=t}l&&(e.beginPath(),l(e,t.parsedStyle),o!==hr.LINE&&o!==hr.PATH&&o!==hr.POLYLINE&&e.closePath()),s&&s.drawToContext(e,t,Qf(this,cp)[cp],this,i),a&&e.restore(),t.renderable.dirty=!1}},{key:"renderDisplayObject",value:function(t,e,n,r,i){var o=t.nodeName,a=r.restoreStack[r.restoreStack.length-1];!a||t.compareDocumentPosition(a)&Ws.DOCUMENT_POSITION_CONTAINS||(e.restore(),r.restoreStack.pop());var s=this.context.styleRendererFactory[o],l=this.pathGeneratorFactory[o],u=t.parsedStyle.clipPath;if(u){this.applyWorldTransform(e,u);var c=this.pathGeneratorFactory[u.nodeName];c&&(e.save(),r.restoreStack.push(t),e.beginPath(),c(e,u.parsedStyle),e.closePath(),e.clip())}s&&(this.applyWorldTransform(e,t),e.save(),this.applyAttributesToContext(e,t)),l&&(e.beginPath(),l(e,t.parsedStyle),o!==hr.LINE&&o!==hr.PATH&&o!==hr.POLYLINE&&e.closePath()),s&&(s.render(e,t.parsedStyle,t,n,this,i),e.restore()),t.renderable.dirty=!1}},{key:"applyAttributesToContext",value:function(t,e){var n=e.parsedStyle,r=n.stroke,i=n.fill,o=n.opacity,a=n.lineDash,s=n.lineDashOffset;a&&t.setLineDash(a),$t(s)||(t.lineDashOffset=s),$t(o)||(t.globalAlpha*=o),$t(r)||Array.isArray(r)||r.isNone||(t.strokeStyle=e.attributes.stroke),$t(i)||Array.isArray(i)||i.isNone||(t.fillStyle=e.attributes.fill)}},{key:"convertAABB2Rect",value:function(t){var e=t.getMin(),n=t.getMax(),r=Math.floor(e[0]),i=Math.floor(e[1]);return{x:r,y:i,width:Math.ceil(n[0])-r,height:Math.ceil(n[1])-i}}},{key:"mergeDirtyAABBs",value:function(t){var e=new Er;return t.forEach((function(t){var n=t.getRenderBounds();e.add(n);var r=t.renderable.dirtyRenderBounds;r&&e.add(r)})),e}},{key:"searchDirtyObjects",value:function(t){var e=b(t.getMin(),2),n=e[0],r=e[1],i=b(t.getMax(),2),o=i[0],a=i[1];return this.rBush.search({minX:n,minY:r,maxX:o,maxY:a}).map((function(t){return t.displayObject}))}},{key:"saveDirtyAABB",value:function(t){var e=t.renderable;e.dirtyRenderBounds||(e.dirtyRenderBounds=new Er);var n=t.getRenderBounds();n&&e.dirtyRenderBounds.update(n.center,n.halfExtents)}},{key:"applyWorldTransform",value:function(t,e,n){n?(A(this.tmpMat4,e.getLocalTransform()),j(this.tmpMat4,n,this.tmpMat4),j(this.tmpMat4,this.vpMatrix,this.tmpMat4)):(A(this.tmpMat4,e.getWorldTransform()),j(this.tmpMat4,this.vpMatrix,this.tmpMat4)),t.setTransform(this.tmpMat4[0],this.tmpMat4[1],this.tmpMat4[4],this.tmpMat4[5],this.tmpMat4[12],this.tmpMat4[13])}},{key:"safeMergeAABB",value:function(){for(var t=new Er,e=arguments.length,n=new Array(e),r=0;r0){if(n||e.attributes.stroke!==r.prevObject.attributes.stroke)yp(t,"strokeStyle",$t(o.stroke)||Array.isArray(o.stroke)||o.stroke.isNone?vp.strokeStyle:e.attributes.stroke,r.currentContext);(n||o.lineWidth!==i.lineWidth)&&yp(t,"lineWidth",$t(o.lineWidth)?vp.lineWidth:o.lineWidth,r.currentContext),(n||o.lineDash!==i.lineDash)&&yp(t,"lineDash",o.lineDash||vp.lineDash,r.currentContext),(n||o.lineDashOffset!==i.lineDashOffset)&&yp(t,"lineDashOffset",$t(o.lineDashOffset)?vp.lineDashOffset:o.lineDashOffset,r.currentContext);for(var u=0;u4&&void 0!==arguments[4]&&arguments[4];if(e){yp(t,"shadowColor",vp.shadowColor,r.currentContext);for(var o=0;o-1&&yp(t,"filter",s.replace(/drop-shadow\([^)]*\)/,"").trim()||vp.filter,r.currentContext)}else yp(t,"filter",vp.filter,r.currentContext)}},{key:"fillToContext",value:function(t,e,n,r,i){var o=this,a=e.parsedStyle,s=a.fill,l=a.fillRule,u=null;if(Array.isArray(s)&&s.length>0)s.forEach((function(r){var i=yp(t,"fillStyle",fp(r,e,t,o.imagePool),n.currentContext);u=null!=u?u:i,l?t.fill(l):t.fill()}));else{if(yo(s)){var c=dp(s,e,t,e.ownerDocument.defaultView.context,r,i,this.imagePool);c&&(t.fillStyle=c,u=!0)}l?t.fill(l):t.fill()}null!==u&&yp(t,"fillStyle",u,n.currentContext)}},{key:"strokeToContext",value:function(t,e,n,r,i){var o=this,a=e.parsedStyle.stroke,s=null;if(Array.isArray(a)&&a.length>0)a.forEach((function(r){var i=yp(t,"strokeStyle",fp(r,e,t,o.imagePool),n.currentContext);s=null!=s?s:i,t.stroke()}));else{if(yo(a)){var l=dp(a,e,t,e.ownerDocument.defaultView.context,r,i,this.imagePool);if(l){var u=yp(t,"strokeStyle",l,n.currentContext);s=null!=s?s:u}}t.stroke()}null!==s&&yp(t,"strokeStyle",s,n.currentContext)}},{key:"drawToContext",value:function(t,e,n,r,i){var o,a=e.nodeName,s=e.parsedStyle,l=s.opacity,u=void 0===l?vp.globalAlpha:l,c=s.fillOpacity,h=void 0===c?vp.fillOpacity:c,d=s.strokeOpacity,f=void 0===d?vp.strokeOpacity:d,p=s.lineWidth,g=void 0===p?vp.lineWidth:p,v=s.fill&&!s.fill.isNone,m=s.stroke&&!s.stroke.isNone&&g>0;if(v||m){var y=!$t(s.shadowColor)&&s.shadowBlur>0,b="inner"===s.shadowType,x=0===(null===(o=s.fill)||void 0===o?void 0:o.alpha),E=!(!s.filter||!s.filter.length),w=y&&m&&(a===hr.PATH||a===hr.LINE||a===hr.POLYLINE||x||b),k=null;if(v)w||this.applyShadowAndFilterStyleToContext(t,e,y,n),k=yp(t,"globalAlpha",u*h,n.currentContext),this.fillToContext(t,e,n,r,i),w||this.clearShadowAndFilterStyleForContext(t,y,E,n);if(m){var M=!1,S=yp(t,"globalAlpha",u*f,n.currentContext);if(k=v?k:S,w&&(this.applyShadowAndFilterStyleToContext(t,e,y,n),M=!0,b)){var N=t.globalCompositeOperation;t.globalCompositeOperation="source-atop",this.strokeToContext(t,e,n,r,i),t.globalCompositeOperation=N,this.clearShadowAndFilterStyleForContext(t,y,E,n,!0)}this.strokeToContext(t,e,n,r,i),M&&this.clearShadowAndFilterStyleForContext(t,y,E,n)}null!==k&&yp(t,"globalAlpha",k,n.currentContext)}}}])}(),xp=function(t){function e(){return s(this,e),v(this,e,arguments)}return y(e,t),u(e,[{key:"render",value:function(t,e,n,r,i,o){var a=e.fill,s=e.fillRule,l=e.opacity,u=void 0===l?1:l,c=e.fillOpacity,h=void 0===c?1:c,d=e.stroke,f=e.strokeOpacity,p=void 0===f?1:f,g=e.lineWidth,v=void 0===g?1:g,m=e.lineCap,y=e.lineJoin,b=e.shadowType,x=e.shadowColor,E=e.shadowBlur,w=e.filter,k=e.miterLimit,M=a&&!a.isNone,S=d&&!d.isNone&&v>0,N=0===(null==a?void 0:a.alpha),O=!(!w||!w.length),T=!$t(x)&&E>0,C=n.nodeName,A="inner"===b,P=S&&T&&(C===hr.PATH||C===hr.LINE||C===hr.POLYLINE||N||A);M&&(t.globalAlpha=u*h,P||Ep(n,t,T),wp(t,n,a,s,r,i,o,this.imagePool),P||this.clearShadowAndFilter(t,O,T)),S&&(t.globalAlpha=u*p,t.lineWidth=v,$t(k)||(t.miterLimit=k),$t(m)||(t.lineCap=m),$t(y)||(t.lineJoin=y),P&&(A&&(t.globalCompositeOperation="source-atop"),Ep(n,t,!0),A&&(kp(t,n,d,r,i,o,this.imagePool),t.globalCompositeOperation=vp.globalCompositeOperation,this.clearShadowAndFilter(t,O,!0))),kp(t,n,d,r,i,o,this.imagePool))}},{key:"clearShadowAndFilter",value:function(t,e,n){if(n&&(t.shadowColor="transparent",t.shadowBlur=0),e){var r=t.filter;!$t(r)&&r.indexOf("drop-shadow")>-1&&(t.filter=r.replace(/drop-shadow\([^)]*\)/,"").trim()||"none")}}}])}(bp);function Ep(t,e,n){var r=t.parsedStyle,i=r.filter,o=r.shadowColor,a=r.shadowBlur,s=r.shadowOffsetX,l=r.shadowOffsetY;i&&i.length&&(e.filter=t.style.filter),n&&(e.shadowColor=o.toString(),e.shadowBlur=a||0,e.shadowOffsetX=s||0,e.shadowOffsetY=l||0)}function wp(t,e,n,r,i,o,a,s){var l=arguments.length>8&&void 0!==arguments[8]&&arguments[8];Array.isArray(n)?n.forEach((function(n){t.fillStyle=fp(n,e,t,s),l||(r?t.fill(r):t.fill())})):(yo(n)&&(t.fillStyle=dp(n,e,t,i,o,a,s)),l||(r?t.fill(r):t.fill()))}function kp(t,e,n,r,i,o,a){var s=arguments.length>7&&void 0!==arguments[7]&&arguments[7];Array.isArray(n)?n.forEach((function(n){t.strokeStyle=fp(n,e,t,a),s||t.stroke()})):(yo(n)&&(t.strokeStyle=dp(n,e,t,r,i,o,a)),s||t.stroke())}var Mp=function(t){function e(){return s(this,e),v(this,e,arguments)}return y(e,t),u(e,[{key:"renderDownSampled",value:function(t,e,n,r){var i=r.src,o=r.imageCache;o.downSampled?t.drawImage(o.downSampled,Math.floor(r.drawRect[0]),Math.floor(r.drawRect[1]),Math.ceil(r.drawRect[2]),Math.ceil(r.drawRect[3])):this.imagePool.createDownSampledImage(i,n).then((function(){n.ownerDocument&&(n.renderable.dirty=!0,n.ownerDocument.defaultView.context.renderingService.dirtify())})).catch((function(t){console.error(t)}))}},{key:"renderTile",value:function(t,e,n,r){var i=r.src,o=r.imageCache,a=r.imageRect,s=r.drawRect,l=o.size,u=t.getTransform(),c=u.a,h=u.b,d=u.c,f=u.d,p=u.e,g=u.f;if(t.resetTransform(),null!=o&&o.gridSize){for(var v=[l[0]/a[2],l[1]/a[3]],m=[o.tileSize[0]/v[0],o.tileSize[1]/v[1]],y=[Math.floor((s[0]-a[0])/m[0]),Math.ceil((s[0]+s[2]-a[0])/m[0])],b=y[0],x=y[1],E=[Math.floor((s[1]-a[1])/m[1]),Math.ceil((s[1]+s[3]-a[1])/m[1])],w=E[1],k=E[0];k<=w;k++)for(var M=b;M<=x;M++){var S=o.tiles[k][M];if(S){var N=[Math.floor(a[0]+S.tileX*m[0]),Math.floor(a[1]+S.tileY*m[1]),Math.ceil(m[0]),Math.ceil(m[1])];t.drawImage(S.data,N[0],N[1],N[2],N[3])}}t.setTransform(c,h,d,f,p,g)}else this.imagePool.createImageTiles(i,[],(function(){n.ownerDocument&&(n.renderable.dirty=!0,n.ownerDocument.defaultView.context.renderingService.dirtify())}),n).catch((function(t){console.error(t)}))}},{key:"render",value:function(t,n,r){var i=n.x,o=void 0===i?0:i,a=n.y,s=void 0===a?0:a,l=n.width,u=n.height,c=n.src,h=n.shadowColor,d=n.shadowBlur,f=this.imagePool.getImageSync(c,r),p=null==f?void 0:f.img,g=l,v=u;if(p){var m,y,x,E,w,k,M,S,N,O,T,C,A,R,D;g||(g=p.width),v||(v=p.height),Ep(r,t,!$t(h)&&d>0);try{var L=r.ownerDocument.defaultView.getContextService().getDomElement(),_=L.width,I=L.height,j=t.getTransform(),B=j.a,F=j.b,z=function(t,e){var n=Mt(ht(),[t[0],t[1],0],e),r=Mt(ht(),[t[0]+t[2],t[1],0],e),i=Mt(ht(),[t[0],t[1]+t[3],0],e),o=Mt(ht(),[t[0]+t[2],t[1]+t[3],0],e);return[Math.min(n[0],r[0],i[0],o[0]),Math.min(n[1],r[1],i[1],o[1]),Math.max(n[0],r[0],i[0],o[0])-Math.min(n[0],r[0],i[0],o[0]),Math.max(n[1],r[1],i[1],o[1])-Math.min(n[1],r[1],i[1],o[1])]}([o,s,g,v],P(B,j.c,0,0,F,j.d,0,0,0,0,1,0,j.e,j.f,0,1)),G=(m=z,y=b([0,0,_,I],4),x=y[0],E=y[1],w=y[2],k=y[3],M=b(m,4),S=M[0],N=M[1],O=M[2],T=M[3],C=Math.max(x,S),A=Math.max(E,N),R=Math.min(x+w,S+O),D=Math.min(E+k,N+T),R<=C||D<=A?null:[C,A,R-C,D-A]);if(!G)return;if(!r.ownerDocument.defaultView.getConfig().enableLargeImageOptimization)return void e.renderFull(t,n,r,{image:p,drawRect:[o,s,g,v]});if(z[2]/f.size[0]<(f.downSamplingRate||.5))return void this.renderDownSampled(t,n,r,{src:c,imageCache:f,drawRect:[o,s,g,v]});if(!ap.isSupportTile)return void e.renderFull(t,n,r,{image:p,drawRect:[o,s,g,v]});this.renderTile(t,n,r,{src:c,imageCache:f,imageRect:z,drawRect:G})}catch(t){}}}},{key:"drawToContext",value:function(t,e,n,r,i){this.render(t,e.parsedStyle,e)}}],[{key:"renderFull",value:function(t,e,n,r){t.drawImage(r.image,Math.floor(r.drawRect[0]),Math.floor(r.drawRect[1]),Math.ceil(r.drawRect[2]),Math.ceil(r.drawRect[3]))}}])}(xp),Sp=function(t){function e(){return s(this,e),v(this,e,arguments)}return y(e,t),u(e,[{key:"render",value:function(t,e,n,r,i,o){n.getBounds();var a=e.lineWidth,s=void 0===a?1:a,l=e.textAlign,u=void 0===l?"start":l,c=e.textBaseline,h=void 0===c?"alphabetic":c,d=e.lineJoin,f=void 0===d?"miter":d,p=e.miterLimit,g=void 0===p?10:p,v=e.letterSpacing,m=void 0===v?0:v,y=e.stroke,b=e.fill,x=e.fillRule,E=e.fillOpacity,w=void 0===E?1:E,k=e.strokeOpacity,M=void 0===k?1:k,S=e.opacity,N=void 0===S?1:S,O=e.metrics,T=e.x,C=void 0===T?0:T,A=e.y,P=void 0===A?0:A,R=e.dx,D=e.dy,L=e.shadowColor,_=e.shadowBlur,I=O.font,j=O.lines,B=O.height,F=O.lineHeight,z=O.lineMetrics;t.font=I,t.lineWidth=s,t.textAlign="middle"===u?"center":u;var G=h;"alphabetic"===G&&(G="bottom"),t.lineJoin=f,$t(g)||(t.miterLimit=g);var V=P;"middle"===h?V+=-B/2-F/2:"bottom"===h||"alphabetic"===h||"ideographic"===h?V+=-B:"top"!==h&&"hanging"!==h||(V+=-F);var W=C+(R||0);V+=D||0,1===j.length&&("bottom"===G?(G="middle",V-=.5*B):"top"===G&&(G="middle",V+=.5*B)),t.textBaseline=G,Ep(n,t,!$t(L)&&_>0);for(var H=0;H0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),(t=v(this,e)).name="canvas-renderer",t.options=n,t}return y(e,t),u(e,[{key:"init",value:function(){var t,e=a({dirtyObjectNumThreshold:500,dirtyObjectRatioThreshold:.8},this.options),n=this.context.imagePool,r=new xp(n),o=(i(i(i(i(i(i(i(i(i(i(t={},hr.CIRCLE,r),hr.ELLIPSE,r),hr.RECT,r),hr.IMAGE,new Mp(n)),hr.TEXT,new Sp(n)),hr.LINE,r),hr.POLYLINE,r),hr.POLYGON,r),hr.PATH,r),hr.GROUP,void 0),i(i(i(t,hr.HTML,void 0),hr.MESH,void 0),hr.FRAGMENT,void 0));this.context.defaultStyleRendererFactory=o,this.context.styleRendererFactory=o,this.addRenderingPlugin(new hp(e))}},{key:"destroy",value:function(){this.removeAllRenderingPlugins(),delete this.context.defaultStyleRendererFactory,delete this.context.styleRendererFactory}}])}(fr),Op=function(){function t(){s(this,t)}return u(t,[{key:"apply",value:function(e,n){var r=this,i=e.renderingService,o=e.renderingContext,a=e.config;this.context=e;var s=o.root.ownerDocument.defaultView,l=function(t){i.hooks.pointerMove.call(t)},u=function(t){i.hooks.pointerUp.call(t)},c=function(t){i.hooks.pointerDown.call(t)},h=function(t){i.hooks.pointerOver.call(t)},d=function(t){i.hooks.pointerOut.call(t)},f=function(t){i.hooks.pointerCancel.call(t)},p=function(t){i.hooks.pointerWheel.call(t)},g=function(t){i.hooks.click.call(t)};i.hooks.init.tap(t.tag,(function(){var t=r.context.contextService.getDomElement();n.globalThis.navigator.msPointerEnabled?(t.style.msContentZooming="none",t.style.msTouchAction="none"):s.supportsPointerEvents&&(t.style.touchAction="none"),s.supportsPointerEvents?function(t){n.globalThis.document.addEventListener("pointermove",l,!0),t.addEventListener("pointerdown",c,!0),t.addEventListener("pointerleave",d,!0),t.addEventListener("pointerover",h,!0),n.globalThis.addEventListener("pointerup",u,!0),n.globalThis.addEventListener("pointercancel",f,!0)}(t):function(t){n.globalThis.document.addEventListener("mousemove",l,!0),t.addEventListener("mousedown",c,!0),t.addEventListener("mouseout",d,!0),t.addEventListener("mouseover",h,!0),n.globalThis.addEventListener("mouseup",u,!0)}(t),s.supportsTouchEvents&&function(t){t.addEventListener("touchstart",c,!0),t.addEventListener("touchend",u,!0),t.addEventListener("touchmove",l,!0),t.addEventListener("touchcancel",f,!0)}(t),a.useNativeClickEvent&&t.addEventListener("click",g,!0),t.addEventListener("wheel",p,{passive:!0,capture:!0})})),i.hooks.destroy.tap(t.tag,(function(){var t=r.context.contextService.getDomElement();n.globalThis.navigator.msPointerEnabled?(t.style.msContentZooming="",t.style.msTouchAction=""):s.supportsPointerEvents&&(t.style.touchAction=""),s.supportsPointerEvents?function(t){n.globalThis.document.removeEventListener("pointermove",l,!0),t.removeEventListener("pointerdown",c,!0),t.removeEventListener("pointerleave",d,!0),t.removeEventListener("pointerover",h,!0),n.globalThis.removeEventListener("pointerup",u,!0),n.globalThis.removeEventListener("pointercancel",f,!0)}(t):function(t){n.globalThis.document.removeEventListener("mousemove",l,!0),t.removeEventListener("mousedown",c,!0),t.removeEventListener("mouseout",d,!0),t.removeEventListener("mouseover",h,!0),n.globalThis.removeEventListener("mouseup",u,!0)}(t),s.supportsTouchEvents&&function(t){t.removeEventListener("touchstart",c,!0),t.removeEventListener("touchend",u,!0),t.removeEventListener("touchmove",l,!0),t.removeEventListener("touchcancel",f,!0)}(t),a.useNativeClickEvent&&t.removeEventListener("click",g,!0),t.removeEventListener("wheel",p,!0)}))}}])}();Op.tag="DOMInteraction";var Tp=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i1&&void 0!==arguments[1]?arguments[1]:[0,0,0];return"matrix(".concat([t[0],t[1],t[4],t[5],t[12]+e[0],t[13]+e[1]].join(","),")")}},{key:"apply",value:function(e,n){var r=this,i=e.camera,o=e.renderingContext,a=e.renderingService;this.context=e;var s=o.root.ownerDocument.defaultView,l=s.context.eventService.nativeHTMLMap,u=function(t,e){e.style.transform=r.joinTransformMatrix(t.getWorldTransform(),t.getOrigin())},c=function(t){var e=t.target;if(e.nodeName===hr.HTML){r.$camera||(r.$camera=r.createCamera(i));var n=r.getOrCreateEl(e);r.$camera.appendChild(n),Object.keys(e.attributes).forEach((function(t){r.updateAttribute(t,e)})),u(e,n),l.set(n,e)}},h=function(t){var e=t.target;if(e.nodeName===hr.HTML&&r.$camera){var n=r.getOrCreateEl(e);n&&(n.remove(),l.delete(n))}},d=function(t){var e=t.target;if(e.nodeName===hr.HTML){var n=t.attrName;r.updateAttribute(n,e)}},f=function(t){var e=t.target;(e.nodeName===hr.FRAGMENT?e.childNodes:[e]).forEach((function(t){if(t.nodeName===hr.HTML){var e=r.getOrCreateEl(t);u(t,e)}}))},p=function(){if(r.$camera){var t=r.context.config,e=t.width,n=t.height;r.$camera.parentElement.style.width="".concat(e||0,"px"),r.$camera.parentElement.style.height="".concat(n||0,"px")}};a.hooks.init.tap(t.tag,(function(){s.addEventListener(fu.RESIZE,p),s.addEventListener(Ks.MOUNTED,c),s.addEventListener(Ks.UNMOUNTED,h),s.addEventListener(Ks.ATTR_MODIFIED,d),s.addEventListener(Ks.BOUNDS_CHANGED,f)})),a.hooks.endFrame.tap(t.tag,(function(){r.$camera&&o.renderReasons.has($s.CAMERA_CHANGED)&&(r.$camera.style.transform=r.joinTransformMatrix(i.getOrthoMatrix()))})),a.hooks.destroy.tap(t.tag,(function(){r.$camera&&r.$camera.remove(),s.removeEventListener(fu.RESIZE,p),s.removeEventListener(Ks.MOUNTED,c),s.removeEventListener(Ks.UNMOUNTED,h),s.removeEventListener(Ks.ATTR_MODIFIED,d),s.removeEventListener(Ks.BOUNDS_CHANGED,f)}))}},{key:"createCamera",value:function(t){var e=this.context.config,n=e.document,r=e.width,i=e.height,o=this.context.contextService.getDomElement(),a=o.parentNode;if(a){var s="g-canvas-camera",l=a.querySelector("#".concat(s));if(!l){var u=(n||document).createElement("div");u.style.overflow="hidden",u.style.pointerEvents="none",u.style.position="absolute",u.style.left="0px",u.style.top="0px",u.style.width="".concat(r||0,"px"),u.style.height="".concat(i||0,"px");var c=(n||document).createElement("div");l=c,c.id=s,c.style.position="absolute",c.style.left="".concat(o.offsetLeft||0,"px"),c.style.top="".concat(o.offsetTop||0,"px"),c.style.transformOrigin="left top",c.style.transform=this.joinTransformMatrix(t.getOrthoMatrix()),c.style.pointerEvents="none",c.style.width="100%",c.style.height="100%",u.appendChild(c),a.appendChild(u)}return l}return null}},{key:"getOrCreateEl",value:function(t){var e=this.context.config.document,n=this.displayObjectHTMLElementMap.get(t);return n||(n=(e||document).createElement("div"),t.parsedStyle.$el=n,this.displayObjectHTMLElementMap.set(t,n),t.id&&(n.id=t.id),t.name&&n.setAttribute("name",t.name),t.className&&(n.className=t.className),n.style.position="absolute",n.style["will-change"]="transform",n.style.transform=this.joinTransformMatrix(t.getWorldTransform(),t.getOrigin())),n}},{key:"updateAttribute",value:function(t,e){var n=this.getOrCreateEl(e);switch(t){case"innerHTML":var r=e.parsedStyle.innerHTML;ne(r)?n.innerHTML=r:(n.innerHTML="",n.appendChild(r));break;case"x":n.style.left="".concat(e.parsedStyle.x,"px");break;case"y":n.style.top="".concat(e.parsedStyle.y,"px");break;case"transformOrigin":var i=e.parsedStyle.transformOrigin;n.style["transform-origin"]="".concat(i[0].buildCSSText(null,null,"")," ").concat(i[1].buildCSSText(null,null,""));break;case"width":var o=e.parsedStyle.width;n.style.width=ae(o)?"".concat(o,"px"):o.toString();break;case"height":var a=e.parsedStyle.height;n.style.height=ae(a)?"".concat(a,"px"):a.toString();break;case"zIndex":var s=e.parsedStyle.zIndex;n.style["z-index"]="".concat(s);break;case"visibility":var l=e.parsedStyle.visibility;n.style.visibility=l;break;case"pointerEvents":var u=e.parsedStyle.pointerEvents,c=void 0===u?"auto":u;n.style.pointerEvents=c;break;case"opacity":var h=e.parsedStyle.opacity;n.style.opacity="".concat(h);break;case"fill":var d=e.parsedStyle.fill,f="";bo(d)?f=d.isNone?"transparent":e.getAttribute("fill"):Array.isArray(d)?f=e.getAttribute("fill"):yo(d),n.style.background=f;break;case"stroke":var p=e.parsedStyle.stroke,g="";bo(p)?g=p.isNone?"transparent":e.getAttribute("stroke"):Array.isArray(p)?g=e.getAttribute("stroke"):yo(p),n.style["border-color"]=g,n.style["border-style"]="solid";break;case"lineWidth":var v=e.parsedStyle.lineWidth;n.style["border-width"]="".concat(v||0,"px");break;case"lineDash":n.style["border-style"]="dashed";break;case"filter":var m=e.style.filter;n.style.filter=m;break;default:$t(e.style[t])||""===e.style[t]||(n.style[t]=e.style[t])}}}])}(); -/*! - * @antv/g-plugin-html-renderer - * @description A G plugin for rendering HTML - * @version 2.1.24 - * @date 5/9/2025, 8:20:22 AM - * @author AntVis - * @docs https://g.antv.antgroup.com/ - */Cp.tag="HTMLRendering";var Ap=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i0&&void 0!==i[0]?i[0]:{}).type,r=e.encoderOptions,t.abrupt("return",this.context.canvas.toDataURL(n,r));case 3:case"end":return t.stop()}}),t,this)}))),function(){return t.apply(this,arguments)})}]);var t}(),Rp=function(t){function e(){var t;s(this,e);for(var n=arguments.length,r=new Array(n),i=0;i{const e=this.context.canvas,n=e.context.renderingContext.root.ownerDocument.defaultView;this.normalizeToPointerEvent(t,n).forEach((r=>{const i=this.bootstrapEvent(this.rootPointerEvent,r,n,t);Te(e.context.eventService,"mappingTable.pointerupoutside",[]),e.context.eventService.mapEvent(i)}))}}get eventService(){return this.context.canvas.context.eventService}get events(){return[t.CommonEvent.CLICK,t.CommonEvent.POINTER_DOWN,t.CommonEvent.POINTER_MOVE,t.CommonEvent.POINTER_UP,t.CommonEvent.POINTER_OVER,t.CommonEvent.POINTER_LEAVE]}getDomElement(){return this.getShape("key").getDomElement()}render(t=this.parsedAttributes,e=this){this.drawKeyShape(t,e),this.drawPortShapes(t,e)}getKeyStyle(t){const e=Ae(t,["dx","dy","innerHTML","pointerEvents","cursor"]),{dx:n=0,dy:r=0}=e,i=Fe(e,["dx","dy"]),[o,a]=this.getSize(t);return Object.assign(Object.assign({x:n,y:r},i),{width:o,height:a})}drawKeyShape(t,e){const n=this.getKeyStyle(t),{x:r,y:i,width:o=0,height:a=0}=n,s=this.upsert("key-container",ru,{x:r,y:i,width:o,height:a,opacity:0},e);return this.upsert("key",Yl,n,s)}connectedCallback(){if(!(this.context.canvas.getRenderer("main")instanceof Dp))return;const t=this.getDomElement();this.events.forEach((e=>{t.addEventListener(e,this.forwardEvents)}))}attributeChangedCallback(t,e,n){"zIndex"===t&&e!==n&&(this.getDomElement().style.zIndex=n)}destroy(){const t=this.getDomElement();this.events.forEach((e=>{t.removeEventListener(e,this.forwardEvents)})),super.destroy()}normalizeToPointerEvent(t,e){const n=[];if(e.isTouchEvent(t))for(let e=0;ethis.context.element.getElement(t))).filter(Boolean);if(0===r.length){const e=new Er,{x:n=0,y:r=0,size:i}=t,[o,a]=Gd(i);return e.setMinMax([n-o/2,r-a/2,0],[n+o/2,r+a/2,0]),e}const i=sh(r.map((t=>t.getBounds())));return n?ah(i,n):i}drawCollapsedMarkerShape(t,e){const n=this.getCollapsedMarkerStyle(t);this.upsert("collapsed-marker",uf,n,e),sf(this)}getCollapsedMarkerStyle(t){if(!t.collapsed||!t.collapsedMarker)return!1;const e=Bd(this.getGraphicStyle(t),"collapsedMarker"),{type:n}=e,r=Fe(e,["type"]),i=this.getShape("key"),[o,a]=ud(i.getLocalBounds(),"center"),s=Object.assign(Object.assign({},r),{x:o,y:a});if(n){const e=this.getCollapsedMarkerText(n,t);Object.assign(s,{text:e})}return s}getCollapsedMarkerText(t,e){const{childrenData:n=[]}=e,{model:r}=this.context;return"descendant-count"===t?r.getDescendantsData(this.id).length.toString():"child-count"===t?n.length.toString():"node-count"===t?r.getDescendantsData(this.id).filter((t=>"node"===r.getElementType(Nh(t)))).length.toString():Ut(t)?t(n):""}getComboPosition(t){const{x:e=0,y:n=0,collapsed:r,childrenData:i=[]}=t;if(0===i.length)return[+e,+n,0];if(r){const{model:t}=this.context,r=t.getDescendantsData(this.id).filter((e=>!t.isCombo(Nh(e))));if(r.length>0&&r.some(ld)){return Yh(r.reduce(((t,e)=>Hh(t,sd(e))),[0,0,0]),r.length)}return[+e,+n,0]}return this.getContentBBox(t).center}getComboStyle(t){const[e,n]=this.getComboPosition(t);return{x:e,y:n,transform:[["translate",e,n]]}}updateComboPosition(t){const e=this.getComboStyle(t);Object.assign(this.style,e);const{x:n,y:r}=e;this.context.model.syncNodeLikeDatum({id:this.id,style:{x:n,y:r}}),lf(this)}render(t,e=this){super.render(t,e),this.drawCollapsedMarkerShape(t,e)}update(t={}){super.update(t),this.updateComboPosition(this.parsedAttributes)}onframe(){super.onframe(),this.attributes.collapsed||this.updateComboPosition(this.parsedAttributes),this.drawKeyShape(this.parsedAttributes,this)}animate(t,e){const n=super.animate(this.attributes.collapsed?t:t.map((t=>{var{x:e,y:n,z:r,transform:i}=t;return Fe(t,["x","y","z","transform"])})),e);return n?new Proxy(n,{set:(t,e,n)=>("currentTime"===e&&Promise.resolve().then((()=>this.onframe())),Reflect.set(t,e,n))}):n}}Fp.defaultStyleProps={childrenNode:[],droppable:!0,draggable:!0,collapsed:!1,collapsedSize:32,collapsedMarker:!0,collapsedMarkerZIndex:1,collapsedMarkerFontSize:12,collapsedMarkerTextAlign:"center",collapsedMarkerTextBaseline:"middle",collapsedMarkerType:"child-count"};class zp extends Fp{constructor(t){super(t)}drawKeyShape(t,e){return this.upsert("key",Gl,this.getKeyStyle(t),e)}getKeyStyle(t){const{collapsed:e}=t,n=super.getKeyStyle(t),[r]=this.getKeySize(t);return Object.assign(Object.assign(Object.assign({},n),e&&Bd(n,"collapsed")),{r:r/2})}getCollapsedKeySize(t){const[e,n]=Gd(t.collapsedSize),r=Math.max(e,n)/2;return[2*r,2*r,0]}getExpandedKeySize(t){const e=this.getContentBBox(t),[n,r]=rh(e),i=Math.sqrt(Math.pow(n,2)+Math.pow(r,2))/2;return[2*i,2*i,0]}getIntersectPoint(t,e=!1){return yd(t,this.getShape("key").getBounds(),e)}}class Gp extends Fp{constructor(t){super(t)}drawKeyShape(t,e){return this.upsert("key",ru,this.getKeyStyle(t),e)}getKeyStyle(t){const e=super.getKeyStyle(t),[n,r]=this.getKeySize(t);return Object.assign(Object.assign(Object.assign({},e),t.collapsed&&Bd(e,"collapsed")),{width:n,height:r,x:-n/2,y:-r/2})}}const Vp={padding:10};function Wp(t,e,n,r,i,o){const{padding:a}=Object.assign(Vp,o),s=ih(n,a),l=ih(r,a),u=[t,...i,e];let c=null;const h=[];for(let t=0,e=u.length;to?"N":"S":r===o?n>i?"W":"E":null}function Yp(t,e){return"N"===e||"S"===e?nh(t):eh(t)}function qp(t,e,n){const r=[t[0],e[1]],i=[e[0],t[1]],o=$p(t,r),a=$p(t,i),s=n?Hp[n]:null,l=o===n||o!==s&&a!==n?r:i;return{points:[l],direction:$p(l,e)}}function Xp(t,e,n){if(ch(t,n)){const r=Jp(t,e,n);return{points:[r],direction:$p(r,e)}}{const r=dh(t,n),i=["left","right"].includes(hh(t,n))?[e[0],r[1]]:[r[0],e[1]];return{points:[i],direction:$p(i,e)}}}function Kp(t,e,n,r){const i=ch(e,n)?e:dh(e,n),o=[[i[0],t[1]],[t[0],i[1]]],a=o.filter((t=>function(t,e){return!lh(t,e)}(t,n)&&!uh(t,n,!0))),s=a.filter((e=>$p(e,t)!==r));if(s.length>0){const n=s.find((e=>$p(t,e)===r))||s[0];return{points:[n],direction:$p(n,e)}}{const i=fd(e,Ht(o,a)[0],Yp(n,r)/2);return{points:[Jp(i,t,n),i],direction:$p(i,e)}}}function Zp(t,e,n,r){let i=Xp(t,e,n);const o=nd(i.points[0]);if(lh(o,r)){i=Xp(e,t,r);const a=nd(i.points[0]);if(lh(a,n)){const s=fd(t,o,Yp(n,$p(t,o))/2),l=fd(e,a,Yp(r,$p(e,a))/2),u=[(s[0]+l[0])/2,(s[1]+l[1])/2],c=Xp(t,u,n),h=Kp(u,e,r,c.direction);i.points=[c.points[0],h.points[0]],i.direction=h.direction}}return i}function Qp(t,e,n,r,i){const o=.01,a=sh([n,r]),s=Xh(e,a.center)>Xh(t,a.center),[l,u]=s?[e,t]:[t,e],c=nh(a)+eh(a);let h;if(i){const t=[l[0]+c*Math.cos(Up[i]),l[1]+c*Math.sin(Up[i])];h=fd(dh(t,a),t,o)}else h=fd(dh(l,a),l,-.01);let d=Jp(h,u,a),f=[dd(h,2),dd(d,2)];if(Ne(dd(h),dd(d))){const t=Qh(Uh(h,l),[1,0,0])+Math.PI/2;d=[u[0]+c*Math.cos(t),u[1]+c*Math.sin(t),0],d=dd(fd(dh(d,a),u,-.01),2);f=[h,Jp(h,d,a),d]}return{points:s?f.reverse():f,direction:$p(s?h:d,e)}}function Jp(t,e,n){let r=[t[0],e[1]];return lh(r,n)&&(r=[e[0],t[1]]),r}function tg(t,e,n,r,i){let o="number"==typeof e?e:.5;"start"===e&&(o=0),"end"===e&&(o=.99);const a=cd(t.getPoint(o)),s=cd(t.getPoint(o+.01));let l="start"===e?"left":"end"===e?"right":"center";if(pd(a,s)||!n){const[e,n]=eg(t,o,r,i);return{transform:[["translate",e,n]],textAlign:l}}let u=Math.atan2(s[1]-a[1],s[0]-a[0]);s[0]{const r=a[n-1]||i,l=a[n+1]||o;if(!gd(r,t,l)&&e){const[n,i]=function(t,e,n,r){const i=Kh(t,e),o=Kh(n,e),a=Math.min(r,Math.min(i,o)/2),s=[e[0]-a/i*(e[0]-t[0]),e[1]-a/i*(e[1]-t[1])],l=[e[0]-a/o*(e[0]-n[0]),e[1]-a/o*(e[1]-n[1])];return[s,l]}(r,t,l,e);s.push(["L",n[0],n[1]],["Q",t[0],t[1],i[0],i[1]],["L",i[0],i[1]])}else s.push(["L",t[0],t[1]])})),s.push(["L",o[0],o[1]]),n&&s.push(["Z"]),s}function og(t,e,n,r,i){const o=ih(t),a=t.getCenter();let s=r&&jg(r),l=i&&jg(i);if(!s||!l){const r=(t=>{const e=Math.PI/2,n=nh(t)/2,r=eh(t)/2,i=Math.atan2(n,r)/2,o=Math.atan2(r,n)/2;return{top:[-e-o,-e+o],"top-right":[-e+o,-i],"right-top":[-e+o,-i],right:[-i,i],"bottom-right":[i,e-o],"right-bottom":[i,e-o],bottom:[e-o,e+o],"bottom-left":[e+o,Math.PI-i],"left-bottom":[e+o,Math.PI-i],left:[Math.PI-i,Math.PI+i],"top-left":[Math.PI+i,-e-o],"left-top":[Math.PI+i,-e-o]}})(o),i=r[e][0],u=r[e][1],[c,h]=rh(o),d=Math.max(c,h),f=Hh(a,[d*Math.cos(i),d*Math.sin(i),0]),p=Hh(a,[d*Math.cos(u),d*Math.sin(u),0]);s=Gg(t,f),l=Gg(t,p),n||([s,l]=[l,s])}return[s,l]}function ag(t,e,n,r,i,o){const a=t.getPorts()[i||o],s=t.getPorts()[o||i];let[l,u]=og(t,e,n,a,s);const c=function(t,e,n,r){const i=t.getCenter();if(Ne(e,n)){const t=Uh(e,i),o=[r*Math.sign(t[0])||r/2,r*Math.sign(t[1])||-r/2,0];return[Hh(e,o),Hh(n,$h(o,[1,-1,1]))]}return[fd(i,e,Xh(i,e)+r),fd(i,n,Xh(i,n)+r)]}(t,l,u,r);return a&&(l=zg(a,c[0])),s&&(u=zg(s,c.at(-1))),rg(l,u,c)}function sg(t,e,n,r,i,o,a){const s=_g(t),l=s[o||a],u=s[a||o];let[c,h]=og(t,n,r,l,u);const d=function(t,e,n,r){const i=[],o=ih(t);if(Ne(e,n)){switch(hh(e,o)){case"left":i.push([e[0]-r,e[1]]),i.push([e[0]-r,e[1]+r]),i.push([e[0],e[1]+r]);break;case"right":i.push([e[0]+r,e[1]]),i.push([e[0]+r,e[1]+r]),i.push([e[0],e[1]+r]);break;case"top":i.push([e[0],e[1]-r]),i.push([e[0]+r,e[1]-r]),i.push([e[0]+r,e[1]]);break;case"bottom":i.push([e[0],e[1]+r]),i.push([e[0]+r,e[1]+r]),i.push([e[0]+r,e[1]])}}else{const t=hh(e,o),a=hh(n,o);if(t===a){let o,a;switch(t){case"left":o=Math.min(e[0],n[0])-r,i.push([o,e[1]]),i.push([o,n[1]]);break;case"right":o=Math.max(e[0],n[0])+r,i.push([o,e[1]]),i.push([o,n[1]]);break;case"top":a=Math.min(e[1],n[1])-r,i.push([e[0],a]),i.push([n[0],a]);break;case"bottom":a=Math.max(e[1],n[1])+r,i.push([e[0],a]),i.push([n[0],a])}}else{const s=(t,e)=>({left:[e[0]-r,e[1]],right:[e[0]+r,e[1]],top:[e[0],e[1]-r],bottom:[e[0],e[1]+r]}[t]),l=s(t,e),u=s(a,n),c=Jp(l,u,o);i.push(l,c,u)}}return i}(t,c,h,i);return l&&(c=zg(l,d[0])),u&&(h=zg(u,d.at(-1))),ig([c,...d,h],e)}function lg(t,e){const n=new Set,r=new Set,i=new Set;return t.forEach((o=>{e(o).forEach((e=>{n.add(e),t.includes(e.source)&&t.includes(e.target)?r.add(e):i.add(e)}))})),{edges:Array.from(n),internal:Array.from(r),external:Array.from(i)}}function ug(t,e){const n=[];let r=t;for(;r;){n.push(r);const t=e(Nh(r));if(!t)break;r=t}if(n.some((t=>{var e;return null===(e=t.style)||void 0===e?void 0:e.collapsed}))){const t=n.reverse().findIndex(_d);return n[t]||n.at(-1)}return t}const cg=(t,e)=>[["M",-t/2,0],["L",t/2,-e/2],["L",t/2,e/2],["Z"]];var hg=Object.freeze({__proto__:null,circle:(t,e)=>{const n=Math.max(t,e)/2;return[["M",-t/2,0],["A",n,n,0,1,0,2*n-t/2,0],["A",n,n,0,1,0,-t/2,0],["Z"]]},diamond:(t,e)=>[["M",-t/2,0],["L",0,-e/2],["L",t/2,0],["L",0,e/2],["Z"]],rect:(t,e)=>[["M",-t/2,-e/2],["L",t/2,-e/2],["L",t/2,e/2],["L",-t/2,e/2],["Z"]],simple:(t,e)=>[["M",t/2,-e/2],["L",-t/2,0],["L",t/2,0],["L",-t/2,0],["L",t/2,e/2]],triangle:cg,triangleRect:(t,e)=>{const n=t/2,r=t/7,i=t-r;return[["M",-n,0],["L",0,-e/2],["L",0,e/2],["Z"],["M",i-n,-e/2],["L",i+r-n,-e/2],["L",i+r-n,e/2],["L",i-n,e/2],["Z"]]},vee:(t,e)=>[["M",-t/2,0],["L",t/2,-e/2],["L",4*t/5-t/2,0],["L",t/2,e/2],["Z"]]});class dg extends cf{constructor(t){super(Wd({style:dg.defaultStyleProps},t)),this.type="edge"}get sourceNode(){const{sourceNode:t}=this.parsedAttributes;return this.context.element.getElement(t)}get targetNode(){const{targetNode:t}=this.parsedAttributes;return this.context.element.getElement(t)}getKeyStyle(t){const e=this.getGraphicStyle(t),{loop:n}=e,r=Fe(e,["loop"]),{sourceNode:i,targetNode:o}=this;var a,s;const l={d:n&&(s=o,(a=i)&&s&&a===s)?this.getLoopPath(t):this.getKeyPath(t)};return Ql.PARSED_STYLE_LIST.forEach((t=>{t in r&&(l[t]=r[t])})),l}getLoopPath(t){const{sourcePort:e,targetPort:n}=t,r=this.sourceNode,i=ih(r),o=Math.max(eh(i),nh(i)),{placement:a,clockwise:s,dist:l=o}=Bd(this.getGraphicStyle(t),"loop");return ag(r,a,s,l,e,n)}getEndpoints(t,e=!0,n=[]){const{sourcePort:r,targetPort:i}=t,{sourceNode:o,targetNode:a}=this,[s,l]=function(t,e,n,r){const i=Bg(t,e,n,r),o=Bg(e,t,r,n);return[i,o]}(o,a,r,i);if(!e){return[s?jg(s):o.getCenter(),l?jg(l):a.getCenter()]}const u="function"==typeof n?n():n;return[Fg(s||o,u[0]||l||a),Fg(l||a,u[u.length-1]||s||o)]}getHaloStyle(t){if(!1===t.halo)return!1;const e=this.getKeyStyle(t),n=Bd(this.getGraphicStyle(t),"halo");return Object.assign(Object.assign({},e),n)}getLabelStyle(t){if(!1===t.label||!t.labelText)return!1;const e=Bd(this.getGraphicStyle(t),"label"),{placement:n,offsetX:r,offsetY:i,autoRotate:o,maxWidth:a}=e,s=Fe(e,["placement","offsetX","offsetY","autoRotate","maxWidth"]),l=tg(this.shapeMap.key,n,o,r,i),u=this.shapeMap.key.getLocalBounds(),c=function(t,e,n=1){return $d(Xh(t[0],t[1])*n,e)}([u.min,u.max],a);return Object.assign({wordWrapWidth:c},l,s)}getBadgeStyle(t){if(!1===t.badge||!t.badgeText)return!1;const e=Bd(t,"badge"),{offsetX:n,offsetY:r,placement:i}=e,o=Fe(e,["offsetX","offsetY","placement"]);return Object.assign(o,function(t,e,n,r,i){var o,a;const s=2*(null===(o=t.badge)||void 0===o?void 0:o.getGeometryBounds().halfExtents[0])||0,l=2*(null===(a=t.label)||void 0===a?void 0:a.getGeometryBounds().halfExtents[0])||0;return tg(t.key,n,!0,(l?(l/2+s/2)*("suffix"===e?1:-1):0)+r,i)}(this.shapeMap,i,t.labelPlacement,n,r))}drawArrow(t,e){var n;const r="start"===e,i=t["start"===e?"startArrow":"endArrow"],o=this.shapeMap.key;if(i){const e=this.getArrowStyle(t,r),[n,i,a]=r?["markerStart","markerStartOffset","startArrowOffset"]:["markerEnd","markerEndOffset","endArrowOffset"],s=o.parsedStyle[n];if(s)s.attr(e);else{const t=new(e.src?ql:Ql)({style:e});o.style[n]=t}o.style[i]=t[a]||e.width/2+ +e.lineWidth}else{const t=r?"markerStart":"markerEnd";null===(n=o.style[t])||void 0===n||n.destroy(),o.style[t]=null}}getArrowStyle(t,e){const n=this.getShape("key").attributes,r=e?"startArrow":"endArrow",i=Bd(this.getGraphicStyle(t),r),{size:o,type:a}=i,s=Fe(i,["size","type"]),[l,u]=Gd(function(t,e){return e||(t<4?10:4===t?12:2.5*t)}(n.lineWidth,o)),c=(Ut(a)?a:hg[a]||cg)(l,u);return Object.assign(Ae(n,["stroke","strokeOpacity","fillOpacity"]),{width:l,height:u},Object.assign({},c&&{d:c,fill:"simple"===a?"":n.stroke}),s)}drawLabelShape(t,e){const n=this.getLabelStyle(t);this.upsert("label",Zd,n,e)}drawHaloShape(t,e){const n=this.getHaloStyle(t);this.upsert("halo",Ql,n,e)}drawBadgeShape(t,e){const n=this.getBadgeStyle(t);this.upsert("badge",Qd,n,e)}drawSourceArrow(t){this.drawArrow(t,"start")}drawTargetArrow(t){this.drawArrow(t,"end")}drawKeyShape(t,e){const n=this.getKeyStyle(t);return this.upsert("key",Ql,n,e)}render(t=this.parsedAttributes,e=this){this.drawKeyShape(t,e),this.getShape("key")&&(this.drawSourceArrow(t),this.drawTargetArrow(t),this.drawLabelShape(t,e),this.drawHaloShape(t,e),this.drawBadgeShape(t,e))}onframe(){this.drawKeyShape(this.parsedAttributes,this),this.drawSourceArrow(this.parsedAttributes),this.drawTargetArrow(this.parsedAttributes),this.drawHaloShape(this.parsedAttributes,this),this.drawLabelShape(this.parsedAttributes,this),this.drawBadgeShape(this.parsedAttributes,this)}animate(t,e){const n=super.animate(t,e);return n?new Proxy(n,{set:(t,e,n)=>("currentTime"===e&&Promise.resolve().then((()=>this.onframe())),Reflect.set(t,e,n))}):n}}dg.defaultStyleProps={badge:!0,badgeOffsetX:0,badgeOffsetY:0,badgePlacement:"suffix",isBillboard:!0,label:!0,labelAutoRotate:!0,labelIsBillboard:!0,labelMaxWidth:"80%",labelOffsetX:4,labelOffsetY:0,labelPlacement:"center",labelTextBaseline:"middle",labelWordWrap:!1,halo:!1,haloDroppable:!1,haloLineDash:0,haloLineWidth:12,haloPointerEvents:"none",haloStrokeOpacity:.25,haloZIndex:-1,loop:!0,startArrow:!1,startArrowLineDash:0,startArrowLineJoin:"round",startArrowLineWidth:1,startArrowTransformOrigin:"center",startArrowType:"vee",endArrow:!1,endArrowLineDash:0,endArrowLineJoin:"round",endArrowLineWidth:1,endArrowTransformOrigin:"center",endArrowType:"vee",loopPlacement:"top",loopClockwise:!0};class fg extends dg{constructor(t){super(Wd({style:fg.defaultStyleProps},t))}getKeyPath(t){const[e,n]=this.getEndpoints(t),{controlPoints:r,curvePosition:i,curveOffset:o}=t,a=this.getControlPoints(e,n,function(t){return ae(t)?[t,1-t]:t}(i),function(t){return ae(t)?[t,-t]:t}(o),r);return rg(e,n,a)}getControlPoints(t,e,n,r,i){return 2===(null==i?void 0:i.length)?i:[ng(t,e,n[0],r[0]),ng(t,e,n[1],r[1])]}}fg.defaultStyleProps={curvePosition:.5,curveOffset:20};class pg extends fg{constructor(t){super(Wd({style:pg.defaultStyleProps},t))}getControlPoints(t,e,n,r){const i=e[0]-t[0];return[[t[0]+i*n[0]+r[0],t[1]],[e[0]-i*n[1]+r[1],e[1]]]}}pg.defaultStyleProps={curvePosition:[.5,.5],curveOffset:[0,0]};class gg extends fg{constructor(t){super(Wd({style:gg.defaultStyleProps},t))}get ref(){return this.context.model.getRootsData()[0]}getEndpoints(t){if(this.sourceNode.id===this.ref.id)return super.getEndpoints(t);const e=sd(this.ref);return[this.sourceNode.getIntersectPoint(e,!0),this.targetNode.getIntersectPoint(e)]}toRadialCoordinate(t){const e=sd(this.ref);return[Xh(t,e),rd(Uh(t,e))]}getControlPoints(t,e,n,r){const[i,o]=this.toRadialCoordinate(t),[a]=this.toRadialCoordinate(e),s=a-i;return[[t[0]+(s*n[0]+r[0])*Math.cos(o),t[1]+(s*n[0]+r[0])*Math.sin(o)],[e[0]-(s*n[1]-r[0])*Math.cos(o),e[1]-(s*n[1]-r[0])*Math.sin(o)]]}}gg.defaultStyleProps={curvePosition:.5,curveOffset:20};class vg extends fg{constructor(t){super(Wd({style:vg.defaultStyleProps},t))}getControlPoints(t,e,n,r){const i=e[1]-t[1];return[[t[0],t[1]+i*n[0]+r[0]],[e[0],e[1]-i*n[1]+r[1]]]}}vg.defaultStyleProps={curvePosition:[.5,.5],curveOffset:[0,0]};let mg=class t extends dg{constructor(e){super(Wd({style:t.defaultStyleProps},e))}getKeyPath(t){const[e,n]=this.getEndpoints(t);return[["M",e[0],e[1]],["L",n[0],n[1]]]}};mg.defaultStyleProps={};const yg={enableObstacleAvoidance:!1,offset:10,maxAllowedDirectionChange:Math.PI/2,maximumLoops:3e3,gridSize:5,startDirections:["top","right","bottom","left"],endDirections:["top","right","bottom","left"],directionMap:{right:{stepX:1,stepY:0},left:{stepX:-1,stepY:0},bottom:{stepX:0,stepY:1},top:{stepX:0,stepY:-1}},penalties:{0:0,90:0},distFunc:Kh},bg=t=>`${Math.round(t[0])}|||${Math.round(t[1])}`;function xg(t,e){const n=t=>Math.round(t/e);return ae(t)?n(t):t.map(n)}function Eg(t,e){const n=e[0]-t[0],r=e[1]-t[1];return n||r?Math.atan2(r,n):0}function wg(t,e,n,r){const i=Eg(t,e),o=n[bg(t)];return function(t,e){const n=Math.abs(t-e);return n>Math.PI?2*Math.PI-n:n}(Eg(o||r,t),i)}function kg(t,e,n){return Math.min(...e.map((e=>n(t,e))))}const Mg=(t,e,n,r)=>{if(!e)return[t];const{directionMap:i,offset:o}=r,a=ah(e.getRenderBounds(),o),s=Object.keys(i).reduce(((e,r)=>{if(n.includes(r)){const n=i[r],[o,s]=rh(a),l=[t[0]+n.stepX*o,t[1]+n.stepY*s],u=function(t){const{min:[e,n],max:[r,i]}=t,o=[e,i],a=[r,i],s=[r,n],l=[e,n];return[[o,a],[a,s],[s,l],[l,o]]}(a);for(let n=0;nxg(t,r.gridSize)))},Sg=(t,e,n,r,i,o,a)=>{const s=[];let l=[o[0]===r[0]?r[0]:t[0]*a,o[1]===r[1]?r[1]:t[1]*a];s.unshift(l);let u=t,c=e[bg(u)];for(;c;){const t=c,r=u;wg(t,r,e,n)&&(l=[t[0]===r[0]?l[0]:t[0]*a,t[1]===r[1]?l[1]:t[1]*a],s.unshift(l)),c=e[bg(t)],u=t}const h=i.map((t=>[t[0]*a,t[1]*a])),d=function(t,e,n){let r=t[0],i=n(t[0],e);for(let o=0;o{const{offset:n,gridSize:r}=e,i={};return t.forEach((t=>{if(!t||t.destroyed||!t.isVisible())return;const e=ah(t.getRenderBounds(),n);for(let t=xg(e.min[0],r);t<=xg(e.max[0],r);t+=1)for(let n=xg(e.min[1],r);n<=xg(e.max[1],r);n+=1)i[`${t}|||${n}`]=!0})),i})(a.enableObstacleAvoidance?n:[t,e],a),u=xg(i,s),c=xg(o,s),h=Mg(i,t,a.startDirections,a),d=Mg(o,e,a.endDirections,a);h.forEach((t=>delete l[bg(t)])),d.forEach((t=>delete l[bg(t)]));const f={},p={},g={},v={},m={},y=new Og;for(let t=0;tbg(t)));let x,E=a.maximumLoops,w=1/0;for(const[t,e]of Object.entries(f))m[t]<=w&&(w=m[t],x=e);for(;Object.keys(f).length>0&&E>0;){const t=y.minId(!1);if(!t)break;x=f[t];const e=bg(x);if(b.includes(e))return Sg(x,g,u,o,h,c,s);delete f[e],y.remove(e),p[e]=!0;for(const t of Object.values(a.directionMap)){const n=Hh(x,[t.stepX,t.stepY]),r=bg(n);if(p[r])continue;const i=wg(x,n,g,u);if(i>a.maxAllowedDirectionChange)continue;if(l[r])continue;f[r]||(f[r]=n);const o=a.penalties[i],c=a.distFunc(x,n)+(isNaN(o)?s:o),h=v[e]+c,b=v[r];b&&h>=b||(g[r]=x,v[r]=h,m[r]=h+kg(n,d,a.distFunc),y.add({id:r,value:m[r]}))}E-=1}return[]}class Og{constructor(){this.arr=[],this.map={},this.arr=[],this.map={}}_innerAdd(t,e){let n=0,r=e-1;for(;r-n>1;){const e=Math.floor((n+r)/2);if(this.arr[e].value>t.value)r=e;else{if(!(this.arr[e].value=0;e--)this.map[this.arr[e].id]?t=this.arr[e].id:this.arr.splice(e,1);return t}_findFirstId(){for(;this.arr.length;){const t=this.arr.shift();if(this.map[t.id])return t.id}}minId(t){return t?this._clearAndGetMinId():this._findFirstId()}}class Tg extends dg{constructor(t){super(Wd({style:Tg.defaultStyleProps},t))}getControlPoints(t){const{router:e}=t,{sourceNode:n,targetNode:r}=this,[i,o]=this.getEndpoints(t,!1);let a=[];if(e)if("shortest-path"===e.type){a=Ng(n,r,this.context.element.getNodes(),e),a.length||(a=Wp(i,o,n,r,t.controlPoints,{padding:e.offset}))}else"orth"===e.type&&(a=Wp(i,o,n,r,t.controlPoints,e));else a=t.controlPoints;return a}getPoints(t){const e=this.getControlPoints(t),[n,r]=this.getEndpoints(t,!0,e);return[n,...e,r]}getKeyPath(t){return ig(this.getPoints(t),t.radius)}getLoopPath(t){const{sourcePort:e,targetPort:n,radius:r}=t,i=this.sourceNode,o=ih(i),a=Math.max(eh(o),nh(o))/4,{placement:s,clockwise:l,dist:u=a}=Bd(this.getGraphicStyle(t),"loop");return sg(i,r,s,l,u,e,n)}}Tg.defaultStyleProps={radius:0,controlPoints:[],router:!1};class Cg extends dg{constructor(t){super(Wd({style:Cg.defaultStyleProps},t))}getKeyPath(t){const{curvePosition:e,curveOffset:n}=t,[r,i]=this.getEndpoints(t);return function(t,e,n){return[["M",t[0],t[1]],["Q",n[0],n[1],e[0],e[1]]]}(r,i,t.controlPoint||ng(r,i,e,n))}}function Ag(t){return t instanceof hf&&"node"===t.type}function Pg(t){return t instanceof dg}function Rg(t){return t instanceof Fp}Cg.defaultStyleProps={curvePosition:.5,curveOffset:30};const Dg={top:[.5,0],right:[1,.5],bottom:[.5,1],left:[0,.5],"left-top":[0,0],"top-left":[0,0],"left-bottom":[0,1],"bottom-left":[0,1],"right-top":[1,0],"top-right":[1,0],"right-bottom":[1,1],"bottom-right":[1,1],default:[.5,.5]};function Lg(t,e,n=Dg,r=!0){const i=[.5,.5],o=ne(e)?Oe(n,e.toLocaleLowerCase(),i):e;if(!r&&ne(e))return o;const[a,s]=o||i;return[t.min[0]+eh(t)*a,t.min[1]+nh(t)*s]}function _g(t){if(!t)return{};const e=t.getPorts();return(t.attributes.ports||[]).forEach(((n,r)=>{var i;const{key:o,placement:a}=n;Ig(n)&&(e[i=o||r]||(e[i]=ud(t.getShape("key").getBounds(),a)))})),e}function Ig(t){const{r:e}=t;return!e||0===Number(e)}function jg(t){return Zc(t)?t:t.getPosition()}function Bg(t,e,n,r){const i=_g(t);if(n)return i[n];const o=Object.values(i);if(0===o.length)return;const a=o.map((t=>jg(t))),s=function(t,e){const n=_g(t);if(e)return[jg(n[e])];const r=Object.values(n);return r.length>0?r.map((t=>jg(t))):[t.getCenter()]}(e,r),[l]=function(t,e){let n=1/0,r=[t[0],e[0]];return t.forEach((t=>{e.forEach((e=>{const i=Xh(t,e);ijg(t)===l))}function Fg(t,e){return Rg(t)||Ag(t)?Gg(t,e):zg(t,e)}function zg(t,e){if(!t||!e)return[0,0,0];if(Zc(t))return t;if(t.attributes.linkToCenter)return t.getPosition();return yd(Zc(e)?e:Ag(e)?e.getCenter():e.getPosition(),t.getBounds())}function Gg(t,e){if(!t||!e)return[0,0,0];const n=Zc(e)?e:Ag(e)?e.getCenter():e.getPosition();return t.getIntersectPoint(n)||t.getCenter()}function Vg(t,e="bottom",n=0,r=0,i=!1){const o=e.split("-"),[a,s]=ud(t,e),[l,u]=i?["bottom","top"]:["top","bottom"];return{transform:[["translate",a+n,s+r]],textBaseline:o.includes("top")?u:o.includes("bottom")?l:"middle",textAlign:o.includes("left")?"right":o.includes("right")?"left":"center"}}function Wg(t,e){"update"in t?t.update(e):t.attr(e)}function Hg(t){return Oe(t,"__to_be_destroyed__",!1)}class Ug extends Gh{constructor(t,e){super(t,Object.assign({},Ug.defaultOptions,e)),this.onCollapseExpand=t=>ze(this,void 0,void 0,(function*(){if(!this.validate(t))return;const{target:e}=t;if(!(Ag(n=e)||Pg(n)||Rg(n)))return;var n;const r=e.id,{model:i,graph:o}=this.context,a=i.getElementDataById(r);if(!a)return!1;const{onCollapse:s,onExpand:l,animation:u,align:c}=this.options;_d(a)?(yield o.expandElement(r,{animation:u,align:c}),null==l||l(r)):(yield o.collapseElement(r,{animation:u,align:c}),null==s||s(r))})),this.bindEvents()}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}bindEvents(){const{graph:t}=this.context,{trigger:e}=this.options;t.on(`node:${e}`,this.onCollapseExpand),t.on(`combo:${e}`,this.onCollapseExpand)}unbindEvents(){const{graph:t}=this.context,{trigger:e}=this.options;t.off(`node:${e}`,this.onCollapseExpand),t.off(`combo:${e}`,this.onCollapseExpand)}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}destroy(){this.unbindEvents(),super.destroy()}}Ug.defaultOptions={enable:!0,animation:!0,trigger:t.CommonEvent.DBLCLICK,align:!0};const $g="g6-create-edge-assist-node-id";class Yg extends Gh{constructor(t,e){super(t,Object.assign({},Yg.defaultOptions,e)),this.drop=t=>ze(this,void 0,void 0,(function*(){const{targetType:e}=t;["combo","node"].includes(e)&&this.source?yield this.handleCreateEdge(t):yield this.cancelEdge()})),this.handleCreateEdge=t=>ze(this,void 0,void 0,(function*(){var e,n,r;if(!this.validate(t))return;const{graph:i,canvas:o,batch:a,element:s}=this.context,{style:l}=this.options;if(this.source)return this.createEdge(t),void(yield this.cancelEdge());a.startBatch(),o.setCursor("crosshair"),this.source=this.getSelectedNodeIDs([t.target.id])[0];const u=i.getElementData(this.source);i.addNodeData([{id:$g,style:{visibility:"hidden",ports:[{key:"port-1",placement:[.5,.5]}],x:null===(e=u.style)||void 0===e?void 0:e.x,y:null===(n=u.style)||void 0===n?void 0:n.y}}]),i.addEdgeData([{id:"g6-create-edge-assist-edge-id",source:this.source,target:$g,style:Object.assign({pointerEvents:"none"},l)}]),yield null===(r=s.draw({animation:!1}))||void 0===r?void 0:r.finished})),this.updateAssistEdge=t=>ze(this,void 0,void 0,(function*(){var e;if(!this.source)return;const{model:n,element:r}=this.context;n.translateNodeTo($g,[t.canvas.x,t.canvas.y]),yield null===(e=r.draw({animation:!1,silence:!0}))||void 0===e?void 0:e.finished})),this.createEdge=t=>{var e,n;const{graph:r}=this.context,{style:i,onFinish:o,onCreate:a}=this.options;if(void 0===(null===(e=t.target)||void 0===e?void 0:e.id)||void 0===this.source)return;const s=null===(n=this.getSelectedNodeIDs([t.target.id]))||void 0===n?void 0:n[0];var l;const u=a({id:`${this.source}-${s}-${De[l=l||"g"]?De[l]+=1:De[l]=1,l+De[l]}`,source:this.source,target:s,style:i});u&&(r.addEdgeData([u]),o(u))},this.cancelEdge=()=>ze(this,void 0,void 0,(function*(){var t;if(!this.source)return;const{graph:e,element:n,batch:r}=this.context;e.removeNodeData([$g]),this.source=void 0,yield null===(t=n.draw({animation:!1}))||void 0===t?void 0:t.finished,r.endBatch()})),this.bindEvents()}update(t){super.update(t),this.bindEvents()}bindEvents(){const{graph:e}=this.context,{trigger:n}=this.options;this.unbindEvents(),"click"===n?(e.on(t.NodeEvent.CLICK,this.handleCreateEdge),e.on(t.ComboEvent.CLICK,this.handleCreateEdge),e.on(t.CanvasEvent.CLICK,this.cancelEdge),e.on(t.EdgeEvent.CLICK,this.cancelEdge)):(e.on(t.NodeEvent.DRAG_START,this.handleCreateEdge),e.on(t.ComboEvent.DRAG_START,this.handleCreateEdge),e.on(t.CommonEvent.POINTER_UP,this.drop)),e.on(t.CommonEvent.POINTER_MOVE,this.updateAssistEdge)}getSelectedNodeIDs(t){return Array.from(new Set(this.context.graph.getElementDataByState("node",this.options.state).map((t=>t.id)).concat(t)))}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}unbindEvents(){const{graph:e}=this.context;e.off(t.NodeEvent.CLICK,this.handleCreateEdge),e.off(t.ComboEvent.CLICK,this.handleCreateEdge),e.off(t.CanvasEvent.CLICK,this.cancelEdge),e.off(t.EdgeEvent.CLICK,this.cancelEdge),e.off(t.NodeEvent.DRAG_START,this.handleCreateEdge),e.off(t.ComboEvent.DRAG_START,this.handleCreateEdge),e.off(t.CommonEvent.POINTER_UP,this.drop),e.off(t.CommonEvent.POINTER_MOVE,this.updateAssistEdge)}destroy(){this.unbindEvents(),super.destroy()}}Yg.defaultOptions={animation:!0,enable:!0,style:{},trigger:"drag",onCreate:t=>t,onFinish:()=>{}};class qg extends Gh{constructor(t,e){super(t,Object.assign({},qg.defaultOptions,e)),this.isDragging=!1,this.onDragStart=t=>{this.validate(t)&&(this.isDragging=!0,this.context.canvas.setCursor("grabbing"))},this.onDrag=t=>{var e,n,r,i;if(!this.isDragging||kd.isPinching)return;const o=null!==(n=null===(e=t.movement)||void 0===e?void 0:e.x)&&void 0!==n?n:t.dx,a=null!==(i=null===(r=t.movement)||void 0===r?void 0:r.y)&&void 0!==i?i:t.dy;0!==(o|a)&&this.translate([o,a],!1)},this.onDragEnd=()=>{var t,e;this.isDragging=!1,this.context.canvas.setCursor(this.defaultCursor),null===(e=(t=this.options).onFinish)||void 0===e||e.call(t)},this.invokeOnFinish=ye((()=>{var t,e;null===(e=(t=this.options).onFinish)||void 0===e||e.call(t)}),300),this.shortcut=new Sd(t.graph),this.bindEvents(),this.defaultCursor=this.context.canvas.getConfig().cursor||"default"}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}bindEvents(){const{trigger:e}=this.options;if(qt(e)){const{up:t=[],down:n=[],left:r=[],right:i=[]}=e;this.shortcut.bind(t,(t=>this.onTranslate([0,1],t))),this.shortcut.bind(n,(t=>this.onTranslate([0,-1],t))),this.shortcut.bind(r,(t=>this.onTranslate([1,0],t))),this.shortcut.bind(i,(t=>this.onTranslate([-1,0],t)))}else{const{graph:e}=this.context;e.on(t.CommonEvent.DRAG_START,this.onDragStart),e.on(t.CommonEvent.DRAG,this.onDrag),e.on(t.CommonEvent.DRAG_END,this.onDragEnd)}}onTranslate(t,e){return ze(this,void 0,void 0,(function*(){if(!this.validate(e))return;const{sensitivity:n}=this.options,r=-1*n;yield this.translate($h(t,r),this.options.animation),this.invokeOnFinish()}))}translate(t,e){return ze(this,void 0,void 0,(function*(){t=this.clampByDirection(t),t=this.clampByRange(t),yield this.context.graph.translateBy(t,e)}))}clampByDirection([t,e]){const{direction:n}=this.options;return"x"===n?e=0:"y"===n&&(t=0),[t,e]}clampByRange([t,e]){const{viewport:n,canvas:r}=this.context,[i,o]=r.getSize(),[a,s,l,u]=Jc(this.options.range),c=[o*a,i*s,o*l,i*u],h=ah(oh(n.getCanvasCenter()),c),d=Uh(n.getViewportCenter(),[t,e,0]);if(!lh(d,h)){const{min:[n,r],max:[i,o]}=h;(d[0]0||d[0]>i&&t<0)&&(t=0),(d[1]0||d[1]>o&&e<0)&&(e=0)}return[t,e]}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return"function"==typeof e?e(t):!!e}unbindEvents(){this.shortcut.unbindAll();const{graph:e}=this.context;e.off(t.CommonEvent.DRAG_START,this.onDragStart),e.off(t.CommonEvent.DRAG,this.onDrag),e.off(t.CommonEvent.DRAG_END,this.onDragEnd)}destroy(){this.shortcut.destroy(),this.unbindEvents(),this.context.canvas.setCursor(this.defaultCursor),super.destroy()}}qg.defaultOptions={enable:t=>!("targetType"in t)||"canvas"===t.targetType,sensitivity:10,direction:"both",range:1/0};class Xg extends Gh{constructor(e,n){super(e,Object.assign({},Xg.defaultOptions,n)),this.enable=!1,this.enableElements=["node","combo"],this.target=[],this.shadowOrigin=[0,0],this.hiddenEdges=[],this.isDragging=!1,this.onDrop=t=>ze(this,void 0,void 0,(function*(){var e;if("link"!==this.options.dropEffect)return;const{model:n,element:r}=this.context,i=t.target.id;this.target.forEach((t=>{const e=n.getParentData(t,Cc);e&&Nh(e)===i&&n.refreshComboData(i),n.setParent(t,i,Cc)})),yield null===(e=null==r?void 0:r.draw({animation:!0}))||void 0===e?void 0:e.finished})),this.setCursor=e=>{if(this.isDragging)return;const{type:n}=e,{canvas:r}=this.context,{cursor:i}=this.options;n===t.CommonEvent.POINTER_ENTER?r.setCursor((null==i?void 0:i.grab)||"grab"):r.setCursor((null==i?void 0:i.default)||"default")},this.onDragStart=this.onDragStart.bind(this),this.onDrag=this.onDrag.bind(this),this.onDragEnd=this.onDragEnd.bind(this),this.onDrop=this.onDrop.bind(this),this.bindEvents()}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}bindEvents(){const{graph:e,canvas:n}=this.context,r=n.getLayer().getContextService().$canvas;r&&(r.addEventListener("blur",this.onDragEnd),r.addEventListener("contextmenu",this.onDragEnd)),this.enableElements.forEach((n=>{e.on(`${n}:${t.CommonEvent.DRAG_START}`,this.onDragStart),e.on(`${n}:${t.CommonEvent.DRAG}`,this.onDrag),e.on(`${n}:${t.CommonEvent.DRAG_END}`,this.onDragEnd),e.on(`${n}:${t.CommonEvent.POINTER_ENTER}`,this.setCursor),e.on(`${n}:${t.CommonEvent.POINTER_LEAVE}`,this.setCursor)})),["link"].includes(this.options.dropEffect)&&(e.on(t.ComboEvent.DROP,this.onDrop),e.on(t.CanvasEvent.DROP,this.onDrop))}getSelectedNodeIDs(t){return Array.from(new Set(this.context.graph.getElementDataByState("node",this.options.state).map((t=>t.id)).concat(t)))}getDelta(t){const e=this.context.graph.getZoom();return Yh([t.dx,t.dy],e)}onDragStart(t){var e;if(this.enable=this.validate(t),!this.enable)return;const{batch:n,canvas:r,graph:i}=this.context;r.setCursor((null===(e=this.options.cursor)||void 0===e?void 0:e.grabbing)||"grabbing"),this.isDragging=!0,n.startBatch();const o=t.target.id;i.getElementState(o).includes(this.options.state)?this.target=this.getSelectedNodeIDs([o]):this.target=[o],this.hideEdge(),this.context.graph.frontElement(this.target),this.options.shadow&&this.createShadow(this.target)}onDrag(t){if(!this.enable)return;const e=this.getDelta(t);this.options.shadow?this.moveShadow(e):this.moveElement(this.target,e)}onDragEnd(){var t,e,n;if(!this.enable)return;if(this.enable=!1,this.options.shadow){if(!this.shadow)return;this.shadow.style.visibility="hidden";const{x:t=0,y:e=0}=this.shadow.attributes,[n,r]=Uh([+t,+e],this.shadowOrigin);this.moveElement(this.target,[n,r])}this.showEdges(),null===(e=(t=this.options).onFinish)||void 0===e||e.call(t,this.target);const{batch:r,canvas:i}=this.context;r.endBatch(),i.setCursor((null===(n=this.options.cursor)||void 0===n?void 0:n.grab)||"grab"),this.isDragging=!1,this.target=[]}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}moveElement(t,e){return ze(this,void 0,void 0,(function*(){const{graph:n,model:r}=this.context,{dropEffect:i}=this.options;"move"===i&&t.forEach((t=>r.refreshComboData(t))),n.translateElementBy(Object.fromEntries(t.map((t=>[t,e]))),!1)}))}moveShadow(t){if(!this.shadow)return;const{x:e=0,y:n=0}=this.shadow.attributes,[r,i]=t;this.shadow.attr({x:+e+r,y:+n+i})}createShadow(t){const e=Bd(this.options,"shadow"),n=sh(t.map((t=>this.context.element.getElement(t).getBounds()))),[r,i]=n.min;this.shadowOrigin=[r,i];const[o,a]=rh(n),s={width:o,height:a,x:r,y:i};this.shadow?this.shadow.attr(Object.assign(Object.assign(Object.assign({},e),s),{visibility:"visible"})):(this.shadow=new ru({style:Object.assign(Object.assign(Object.assign({$layer:"transient"},e),s),{pointerEvents:"none"})}),this.context.canvas.appendChild(this.shadow))}showEdges(){this.options.shadow||0===this.hiddenEdges.length||(this.context.graph.showElement(this.hiddenEdges),this.hiddenEdges=[])}hideEdge(){const{hideEdge:t,shadow:e}=this.options;if("none"===t||e)return;const{graph:n}=this.context;this.hiddenEdges="all"===t?n.getEdgeData().map(Nh):Array.from(new Set(this.target.map((e=>n.getRelatedEdgesData(e,t).map(Nh))).flat())),n.hideElement(this.hiddenEdges)}unbindEvents(){const{graph:e,canvas:n}=this.context,r=n.getLayer().getContextService().$canvas;r&&(r.removeEventListener("blur",this.onDragEnd),r.removeEventListener("contextmenu",this.onDragEnd)),this.enableElements.forEach((n=>{e.off(`${n}:${t.CommonEvent.DRAG_START}`,this.onDragStart),e.off(`${n}:${t.CommonEvent.DRAG}`,this.onDrag),e.off(`${n}:${t.CommonEvent.DRAG_END}`,this.onDragEnd),e.off(`${n}:${t.CommonEvent.POINTER_ENTER}`,this.setCursor),e.off(`${n}:${t.CommonEvent.POINTER_LEAVE}`,this.setCursor)})),e.off(`combo:${t.CommonEvent.DROP}`,this.onDrop),e.off(`canvas:${t.CommonEvent.DROP}`,this.onDrop)}destroy(){var t;this.unbindEvents(),null===(t=this.shadow)||void 0===t||t.destroy(),super.destroy()}}Xg.defaultOptions={animation:!0,enable:t=>["node","combo"].includes(t.targetType),dropEffect:"move",state:"selected",hideEdge:"none",shadow:!1,shadowZIndex:100,shadowFill:"#F3F9FF",shadowFillOpacity:.5,shadowStroke:"#1890FF",shadowStrokeOpacity:.9,shadowLineDash:[5,5],cursor:{default:"default",grab:"grab",grabbing:"grabbing"}};var Kg=function(){function t(){this._events={}}return t.prototype.on=function(t,e,n){return this._events[t]||(this._events[t]=[]),this._events[t].push({callback:e,once:!!n}),this},t.prototype.once=function(t,e){return this.on(t,e,!0)},t.prototype.emit=function(t){for(var e=this,n=[],r=1;r{e.has(n.id)||(e.add(n.id),t.push(n))}))}return!1}function Qg(t,e,n,r){if(n(t))return!0;e.add(t.id);for(const i of r(t.id))if(!e.has(i.id)&&Qg(i,e,n,r))return!0;return!1}const Jg=()=>!0;class tv{graph;nodeFilter;edgeFilter;cacheEnabled;inEdgesMap=new Map;outEdgesMap=new Map;bothEdgesMap=new Map;allNodesMap=new Map;allEdgesMap=new Map;constructor(t){this.graph=t.graph;const e=t.nodeFilter||Jg,n=t.edgeFilter||Jg;this.nodeFilter=e,this.edgeFilter=t=>{const{source:r,target:i}=this.graph.getEdgeDetail(t.id);return!(!e(r)||!e(i))&&n(t,r,i)},"auto"===t.cache?(this.cacheEnabled=!0,this.startAutoCache()):"manual"===t.cache?this.cacheEnabled=!0:this.cacheEnabled=!1}clearCache=()=>{this.inEdgesMap.clear(),this.outEdgesMap.clear(),this.bothEdgesMap.clear(),this.allNodesMap.clear(),this.allEdgesMap.clear()};refreshCache=()=>{this.clearCache(),this.updateCache(this.graph.getAllNodes().map((t=>t.id)))};updateCache=t=>{const e=new Set;t.forEach((t=>{const n=this.bothEdgesMap.get(t);if(n&&n.forEach((t=>e.add(t.id))),this.hasNode(t)){const n=this.graph.getRelatedEdges(t,"in").filter(this.edgeFilter),r=this.graph.getRelatedEdges(t,"out").filter(this.edgeFilter),i=Array.from(new Set([...n,...r]));i.forEach((t=>e.add(t.id))),this.inEdgesMap.set(t,n),this.outEdgesMap.set(t,r),this.bothEdgesMap.set(t,i),this.allNodesMap.set(t,this.graph.getNode(t))}else this.inEdgesMap.delete(t),this.outEdgesMap.delete(t),this.bothEdgesMap.delete(t),this.allNodesMap.delete(t)})),e.forEach((t=>{this.hasEdge(t)?this.allEdgesMap.set(t,this.graph.getEdge(t)):this.allEdgesMap.delete(t)}))};startAutoCache(){this.refreshCache(),this.graph.on("changed",this.handleGraphChanged)}stopAutoCache(){this.graph.off("changed",this.handleGraphChanged)}handleGraphChanged=t=>{const e=new Set;t.changes.forEach((n=>{switch(n.type){case"NodeAdded":case"NodeRemoved":e.add(n.value.id);break;case"NodeDataUpdated":e.add(n.id);break;case"EdgeAdded":case"EdgeRemoved":e.add(n.value.source),e.add(n.value.target);break;case"EdgeUpdated":"source"!==n.propertyName&&"target"!==n.propertyName||(e.add(n.oldValue),e.add(n.newValue));break;case"EdgeDataUpdated":if(t.graph.hasEdge(n.id)){const r=t.graph.getEdge(n.id);e.add(r.source),e.add(r.target)}}})),this.updateCache(e)};checkNodeExistence(t){this.getNode(t)}hasNode(t){if(!this.graph.hasNode(t))return!1;const e=this.graph.getNode(t);return this.nodeFilter(e)}areNeighbors(t,e){return this.checkNodeExistence(t),this.getNeighbors(e).some((e=>e.id===t))}getNode(t){const e=this.graph.getNode(t);if(!this.nodeFilter(e))throw new Error("Node not found for id: "+t);return e}getRelatedEdges(t,e){if(this.checkNodeExistence(t),this.cacheEnabled)return"in"===e?this.inEdgesMap.get(t):"out"===e?this.outEdgesMap.get(t):this.bothEdgesMap.get(t);return this.graph.getRelatedEdges(t,e).filter(this.edgeFilter)}getDegree(t,e){return this.getRelatedEdges(t,e).length}getSuccessors(t){const e=this.getRelatedEdges(t,"out").map((t=>this.getNode(t.target)));return Array.from(new Set(e))}getPredecessors(t){const e=this.getRelatedEdges(t,"in").map((t=>this.getNode(t.source)));return Array.from(new Set(e))}getNeighbors(t){const e=this.getPredecessors(t),n=this.getSuccessors(t);return Array.from(new Set([...e,...n]))}hasEdge(t){if(!this.graph.hasEdge(t))return!1;const e=this.graph.getEdge(t);return this.edgeFilter(e)}getEdge(t){const e=this.graph.getEdge(t);if(!this.edgeFilter(e))throw new Error("Edge not found for id: "+t);return e}getEdgeDetail(t){const e=this.getEdge(t);return{edge:e,source:this.getNode(e.source),target:this.getNode(e.target)}}hasTreeStructure(t){return this.graph.hasTreeStructure(t)}getRoots(t){return this.graph.getRoots(t).filter(this.nodeFilter)}getChildren(t,e){return this.checkNodeExistence(t),this.graph.getChildren(t,e).filter(this.nodeFilter)}getParent(t,e){this.checkNodeExistence(t);const n=this.graph.getParent(t,e);return n&&this.nodeFilter(n)?n:null}getAllNodes(){return this.cacheEnabled?Array.from(this.allNodesMap.values()):this.graph.getAllNodes().filter(this.nodeFilter)}getAllEdges(){return this.cacheEnabled?Array.from(this.allEdgesMap.values()):this.graph.getAllEdges().filter(this.edgeFilter)}bfs(t,e,n="out"){const r={in:this.getPredecessors.bind(this),out:this.getSuccessors.bind(this),both:this.getNeighbors.bind(this)}[n];Zg([this.getNode(t)],new Set,e,r)}dfs(t,e,n="out"){const r={in:this.getPredecessors.bind(this),out:this.getSuccessors.bind(this),both:this.getNeighbors.bind(this)}[n];Qg(this.getNode(t),new Set,e,r)}}let ev=class t extends Kg{nodeMap=new Map;edgeMap=new Map;inEdgesMap=new Map;outEdgesMap=new Map;bothEdgesMap=new Map;treeIndices=new Map;changes=[];batchCount=0;onChanged=()=>{};constructor(t){super(),t&&(t.nodes&&this.addNodes(t.nodes),t.edges&&this.addEdges(t.edges),t.tree&&this.addTree(t.tree),t.onChanged&&(this.onChanged=t.onChanged))}batch=t=>{this.batchCount+=1,t(),this.batchCount-=1,this.batchCount||this.commit()};commit(){const t=this.changes;this.changes=[];const e={graph:this,changes:t};this.emit("changed",e),this.onChanged(e)}reduceChanges(t){let e=[];return t.forEach((t=>{switch(t.type){case"NodeRemoved":{let n=!1;e=e.filter((e=>{if("NodeAdded"===e.type){const r=e.value.id===t.value.id;return r&&(n=!0),!r}return"NodeDataUpdated"===e.type?e.id!==t.value.id:"TreeStructureChanged"!==e.type||e.nodeId!==t.value.id})),n||e.push(t);break}case"EdgeRemoved":{let n=!1;e=e.filter((e=>{if("EdgeAdded"===e.type){const r=e.value.id===t.value.id;return r&&(n=!0),!r}return"EdgeDataUpdated"!==e.type&&"EdgeUpdated"!==e.type||e.id!==t.value.id})),n||e.push(t);break}case"NodeDataUpdated":case"EdgeDataUpdated":case"EdgeUpdated":{const n=e.findIndex((e=>e.type===t.type&&e.id===t.id&&(void 0===t.propertyName||e.propertyName===t.propertyName))),r=e[n];r?void 0!==t.propertyName?r.newValue=t.newValue:(e.splice(n,1),e.push(t)):e.push(t);break}case"TreeStructureDetached":e=e.filter((e=>"TreeStructureAttached"===e.type?e.treeKey!==t.treeKey:"TreeStructureChanged"!==e.type||e.treeKey!==t.treeKey)),e.push(t);break;case"TreeStructureChanged":{const n=e.find((e=>"TreeStructureChanged"===e.type&&e.treeKey===t.treeKey&&e.nodeId===t.nodeId));n?n.newParentId=t.newParentId:e.push(t);break}default:e.push(t)}})),e}checkNodeExistence(t){this.getNode(t)}hasNode(t){return this.nodeMap.has(t)}areNeighbors(t,e){return this.getNeighbors(e).some((e=>e.id===t))}getNode(t){const e=this.nodeMap.get(t);if(!e)throw new Error("Node not found for id: "+t);return e}getRelatedEdges(t,e){if(this.checkNodeExistence(t),"in"===e){const e=this.inEdgesMap.get(t);return Array.from(e)}if("out"===e){const e=this.outEdgesMap.get(t);return Array.from(e)}{const e=this.bothEdgesMap.get(t);return Array.from(e)}}getDegree(t,e){return this.getRelatedEdges(t,e).length}getSuccessors(t){const e=this.getRelatedEdges(t,"out").map((t=>this.getNode(t.target)));return Array.from(new Set(e))}getPredecessors(t){const e=this.getRelatedEdges(t,"in").map((t=>this.getNode(t.source)));return Array.from(new Set(e))}getNeighbors(t){const e=this.getPredecessors(t),n=this.getSuccessors(t);return Array.from(new Set([...e,...n]))}doAddNode(t){if(this.hasNode(t.id))throw new Error("Node already exists: "+t.id);this.nodeMap.set(t.id,t),this.inEdgesMap.set(t.id,new Set),this.outEdgesMap.set(t.id,new Set),this.bothEdgesMap.set(t.id,new Set),this.treeIndices.forEach((e=>{e.childrenMap.set(t.id,new Set)})),this.changes.push({type:"NodeAdded",value:t})}addNodes(t){this.batch((()=>{for(const e of t)this.doAddNode(e)}))}addNode(t){this.addNodes([t])}doRemoveNode(t){const e=this.getNode(t),n=this.bothEdgesMap.get(t);n?.forEach((t=>this.doRemoveEdge(t.id))),this.nodeMap.delete(t),this.treeIndices.forEach((n=>{n.childrenMap.get(t)?.forEach((t=>{n.parentMap.delete(t.id)}));const r=n.parentMap.get(t);r&&n.childrenMap.get(r.id)?.delete(e),n.parentMap.delete(t),n.childrenMap.delete(t)})),this.bothEdgesMap.delete(t),this.inEdgesMap.delete(t),this.outEdgesMap.delete(t),this.changes.push({type:"NodeRemoved",value:e})}removeNodes(t){this.batch((()=>{t.forEach((t=>this.doRemoveNode(t)))}))}removeNode(t){this.removeNodes([t])}updateNodeDataProperty(t,e,n){const r=this.getNode(t);this.batch((()=>{const i=r.data[e],o=n;r.data[e]=o,this.changes.push({type:"NodeDataUpdated",id:t,propertyName:e,oldValue:i,newValue:o})}))}mergeNodeData(t,e){this.batch((()=>{Object.entries(e).forEach((([e,n])=>{this.updateNodeDataProperty(t,e,n)}))}))}updateNodeData(...t){const e=t[0],n=this.getNode(e);if("string"==typeof t[1])return void this.updateNodeDataProperty(e,t[1],t[2]);let r;if("function"==typeof t[1]){const e=t[1];r=e(n.data)}else"object"==typeof t[1]&&(r=t[1]);this.batch((()=>{const t=n.data,i=r;n.data=r,this.changes.push({type:"NodeDataUpdated",id:e,oldValue:t,newValue:i})}))}checkEdgeExistence(t){if(!this.hasEdge(t))throw new Error("Edge not found for id: "+t)}hasEdge(t){return this.edgeMap.has(t)}getEdge(t){return this.checkEdgeExistence(t),this.edgeMap.get(t)}getEdgeDetail(t){const e=this.getEdge(t);return{edge:e,source:this.getNode(e.source),target:this.getNode(e.target)}}doAddEdge(t){if(this.hasEdge(t.id))throw new Error("Edge already exists: "+t.id);this.checkNodeExistence(t.source),this.checkNodeExistence(t.target),this.edgeMap.set(t.id,t);const e=this.inEdgesMap.get(t.target),n=this.outEdgesMap.get(t.source),r=this.bothEdgesMap.get(t.source),i=this.bothEdgesMap.get(t.target);e.add(t),n.add(t),r.add(t),i.add(t),this.changes.push({type:"EdgeAdded",value:t})}addEdges(t){this.batch((()=>{for(const e of t)this.doAddEdge(e)}))}addEdge(t){this.addEdges([t])}doRemoveEdge(t){const e=this.getEdge(t),n=this.outEdgesMap.get(e.source),r=this.inEdgesMap.get(e.target),i=this.bothEdgesMap.get(e.source),o=this.bothEdgesMap.get(e.target);n.delete(e),r.delete(e),i.delete(e),o.delete(e),this.edgeMap.delete(t),this.changes.push({type:"EdgeRemoved",value:e})}removeEdges(t){this.batch((()=>{t.forEach((t=>this.doRemoveEdge(t)))}))}removeEdge(t){this.removeEdges([t])}updateEdgeSource(t,e){const n=this.getEdge(t);this.checkNodeExistence(e);const r=n.source,i=e;this.outEdgesMap.get(r).delete(n),this.bothEdgesMap.get(r).delete(n),this.outEdgesMap.get(i).add(n),this.bothEdgesMap.get(i).add(n),n.source=e,this.batch((()=>{this.changes.push({type:"EdgeUpdated",id:t,propertyName:"source",oldValue:r,newValue:i})}))}updateEdgeTarget(t,e){const n=this.getEdge(t);this.checkNodeExistence(e);const r=n.target,i=e;this.inEdgesMap.get(r).delete(n),this.bothEdgesMap.get(r).delete(n),this.inEdgesMap.get(i).add(n),this.bothEdgesMap.get(i).add(n),n.target=e,this.batch((()=>{this.changes.push({type:"EdgeUpdated",id:t,propertyName:"target",oldValue:r,newValue:i})}))}updateEdgeDataProperty(t,e,n){const r=this.getEdge(t);this.batch((()=>{const i=r.data[e],o=n;r.data[e]=o,this.changes.push({type:"EdgeDataUpdated",id:t,propertyName:e,oldValue:i,newValue:o})}))}updateEdgeData(...t){const e=t[0],n=this.getEdge(e);if("string"==typeof t[1])return void this.updateEdgeDataProperty(e,t[1],t[2]);let r;if("function"==typeof t[1]){const e=t[1];r=e(n.data)}else"object"==typeof t[1]&&(r=t[1]);this.batch((()=>{const t=n.data,i=r;n.data=r,this.changes.push({type:"EdgeDataUpdated",id:e,oldValue:t,newValue:i})}))}mergeEdgeData(t,e){this.batch((()=>{Object.entries(e).forEach((([e,n])=>{this.updateEdgeDataProperty(t,e,n)}))}))}checkTreeExistence(t){if(!this.hasTreeStructure(t))throw new Error("Tree structure not found for treeKey: "+t)}hasTreeStructure(t){return this.treeIndices.has(t)}attachTreeStructure(t){this.treeIndices.has(t)||(this.treeIndices.set(t,{parentMap:new Map,childrenMap:new Map}),this.batch((()=>{this.changes.push({type:"TreeStructureAttached",treeKey:t})})))}detachTreeStructure(t){this.checkTreeExistence(t),this.treeIndices.delete(t),this.batch((()=>{this.changes.push({type:"TreeStructureDetached",treeKey:t})}))}addTree(t,e){this.batch((()=>{this.attachTreeStructure(e);const n=[],r=Array.isArray(t)?t:[t];for(;r.length;){const t=r.shift();n.push(t),t.children&&r.push(...t.children)}this.addNodes(n),n.forEach((t=>{t.children?.forEach((n=>{this.setParent(n.id,t.id,e)}))}))}))}getRoots(t){return this.checkTreeExistence(t),this.getAllNodes().filter((e=>!this.getParent(e.id,t)))}getChildren(t,e){this.checkNodeExistence(t),this.checkTreeExistence(e);const n=this.treeIndices.get(e).childrenMap.get(t);return Array.from(n||[])}getParent(t,e){this.checkNodeExistence(t),this.checkTreeExistence(e);return this.treeIndices.get(e).parentMap.get(t)||null}getAncestors(t,e){const n=[];let r,i=this.getNode(t);for(;r=this.getParent(i.id,e);)n.push(r),i=r;return n}setParent(t,e,n){this.checkTreeExistence(n);const r=this.treeIndices.get(n);if(!r)return;const i=this.getNode(t),o=r.parentMap.get(t);if(o?.id===e)return;if(null==e)return o&&r.childrenMap.get(o.id)?.delete(i),void r.parentMap.delete(t);const a=this.getNode(e);r.parentMap.set(t,a),o&&r.childrenMap.get(o.id)?.delete(i);let s=r.childrenMap.get(a.id);s||(s=new Set,r.childrenMap.set(a.id,s)),s.add(i),this.batch((()=>{this.changes.push({type:"TreeStructureChanged",treeKey:n,nodeId:t,oldParentId:o?.id,newParentId:a.id})}))}dfsTree(t,e,n){return Qg(this.getNode(t),new Set,e,(t=>this.getChildren(t,n)))}bfsTree(t,e,n){return Zg([this.getNode(t)],new Set,e,(t=>this.getChildren(t,n)))}getAllNodes(){return Array.from(this.nodeMap.values())}getAllEdges(){return Array.from(this.edgeMap.values())}bfs(t,e,n="out"){const r={in:this.getPredecessors.bind(this),out:this.getSuccessors.bind(this),both:this.getNeighbors.bind(this)}[n];return Zg([this.getNode(t)],new Set,e,r)}dfs(t,e,n="out"){const r={in:this.getPredecessors.bind(this),out:this.getSuccessors.bind(this),both:this.getNeighbors.bind(this)}[n];return Qg(this.getNode(t),new Set,e,r)}clone(){const e=this.getAllNodes().map((t=>({...t,data:{...t.data}}))),n=this.getAllEdges().map((t=>({...t,data:{...t.data}}))),r=new t({nodes:e,edges:n});return this.treeIndices.forEach((({parentMap:t,childrenMap:e},n)=>{const i=new Map;t.forEach(((t,e)=>{i.set(e,r.getNode(t.id))}));const o=new Map;e.forEach(((t,e)=>{o.set(e,new Set(Array.from(t).map((t=>r.getNode(t.id)))))})),r.treeIndices.set(n,{parentMap:i,childrenMap:o})})),r}toJSON(){return JSON.stringify({nodes:this.getAllNodes(),edges:this.getAllEdges()})}createView(t){return new tv({graph:this,...t})}};class nv{constructor(t,e){this.context=t,this.options=e||{}}}function rv(t){const{nodes:e,edges:n}=t,r={nodes:[],edges:[],combos:[]};return e.forEach((t=>{const e=t.data._isCombo?r.combos:r.nodes,{x:n,y:i,z:o=0}=t.data;null==e||e.push({id:t.id,style:{x:n,y:i,z:o}})})),n.forEach((t=>{const{id:e,source:n,target:i,data:{points:o=[],controlPoints:a=o.slice(1,o.length-1)}}=t;r.edges.push({id:e,source:n,target:i,style:Object.assign({},(null==a?void 0:a.length)?{controlPoints:a.map(cd)}:{})})})),r}function iv(t,e,...n){if(e in t)return t[e](...n);if("instance"in t){const r=t.instance;if(e in r)return r[e](...n)}return null}function ov(t,e){if(e in t)return t[e];if("instance"in t){const n=t.instance;if(e in n)return n[e]}return null}class av extends Xg{get forceLayoutInstance(){return this.context.layout.getLayoutInstance().find((t=>["d3-force","d3-force-3d"].includes(null==t?void 0:t.id)))}validate(t){return!!this.context.layout&&(this.forceLayoutInstance?super.validate(t):(Ic("DragElementForce only works with d3-force or d3-force-3d layout"),!1))}moveElement(t,e){return ze(this,void 0,void 0,(function*(){const n=this.forceLayoutInstance;this.context.graph.getNodeData(t).forEach(((r,i)=>{const{x:o=0,y:a=0}=r.style||{};n&&iv(n,"setFixedPosition",t[i],[...Hh([+o,+a],e)])}))}))}onDragStart(t){if(this.enable=this.validate(t),!this.enable)return;this.target=this.getSelectedNodeIDs([t.target.id]),this.hideEdge(),this.context.graph.frontElement(this.target);const e=this.forceLayoutInstance;e&&ov(e,"simulation").alphaTarget(.3).restart(),this.context.graph.getNodeData(this.target).forEach((t=>{const{x:n=0,y:r=0}=t.style||{};e&&iv(e,"setFixedPosition",Nh(t),[+n,+r])}))}onDrag(t){if(!this.enable)return;const e=this.getDelta(t);this.moveElement(this.target,e)}onDragEnd(){const t=this.forceLayoutInstance;t&&ov(t,"simulation").alphaTarget(0),this.options.fixed||this.context.graph.getNodeData(this.target).forEach((e=>{t&&iv(t,"setFixedPosition",Nh(e),[null,null,null])}))}}class sv extends Gh{constructor(t,e){super(t,Object.assign({},sv.defaultOptions,e)),this.isZoomEvent=t=>Boolean(t.data&&"scale"in t.data),this.relatedEdgeToUpdate=new Set,this.zoom=this.context.graph.getZoom(),this.fixElementSize=t=>ze(this,void 0,void 0,(function*(){if(!this.validate(t))return;const{graph:e}=this.context,{state:n,nodeFilter:r,edgeFilter:i,comboFilter:o}=this.options,a=(n?e.getElementDataByState("node",n):e.getNodeData()).filter(r),s=(n?e.getElementDataByState("edge",n):e.getEdgeData()).filter(i),l=(n?e.getElementDataByState("combo",n):e.getComboData()).filter(o),u=this.isZoomEvent(t)?this.zoom=Math.max(.01,Math.min(t.data.scale,10)):this.zoom,c=[...a,...l];c.length>0&&c.forEach((t=>this.fixNodeLike(t,u))),this.updateRelatedEdges(),s.length>0&&s.forEach((t=>this.fixEdge(t,u)))})),this.cachedStyles=new Map,this.getOriginalFieldValue=(t,e,n)=>{var r;const i=this.cachedStyles.get(t)||[],o=(null===(r=i.find((t=>t.shape===e)))||void 0===r?void 0:r.style)||{};return n in o||(o[n]=e.attributes[n],this.cachedStyles.set(t,[...i.filter((t=>t.shape!==e)),{shape:e,style:o}])),o[n]},this.scaleEntireElement=(t,e,n)=>{e.setLocalScale(1/n);const r=this.cachedStyles.get(t)||[];r.push({shape:e}),this.cachedStyles.set(t,r)},this.scaleSpecificShapes=(t,e,n)=>{const r=function(t){const e=[],n=t=>{(null==t?void 0:t.children.length)&&t.children.forEach((t=>{e.push(t),n(t)}))};return n(t),e}(t);(Array.isArray(n)?n:[n]).forEach((n=>{const{shape:i,fields:o}=n,a="function"==typeof i?i(r):t.getShape(i);a&&(o?o.forEach((n=>{const r=this.getOriginalFieldValue(t.id,a,n);ae(r)&&(a.style[n]=r/e)})):this.scaleEntireElement(t.id,a,e))}))},this.skipIfExceedViewport=t=>{const{viewport:e}=this.context;return!(null==e?void 0:e.isInViewport(t.getRenderBounds(),!1,30))},this.fixNodeLike=(t,e)=>{const n=Nh(t),{element:r,model:i}=this.context,o=r.getElement(n);if(!o||this.skipIfExceedViewport(o))return;i.getRelatedEdgesData(n).forEach((t=>this.relatedEdgeToUpdate.add(Nh(t))));const a=this.options[o.type];a?this.scaleSpecificShapes(o,e,a):this.scaleEntireElement(n,o,e)},this.fixEdge=(t,e)=>{const n=Nh(t),r=this.context.element.getElement(n);if(!r||this.skipIfExceedViewport(r))return;const i=this.options.edge;if(!i)return r.style.transformOrigin="center",void this.scaleEntireElement(n,r,e);this.scaleSpecificShapes(r,e,i)},this.updateRelatedEdges=()=>{const{element:t}=this.context;this.relatedEdgeToUpdate.size>0&&this.relatedEdgeToUpdate.forEach((e=>{const n=t.getElement(e);null==n||n.update({})})),this.relatedEdgeToUpdate.clear()},this.resetTransform=t=>ze(this,void 0,void 0,(function*(){var e;(null===(e=t.data)||void 0===e?void 0:e.firstRender)||(this.options.reset?this.restoreCachedStyles():this.fixElementSize({data:{scale:this.zoom}}))})),this.bindEvents()}restoreCachedStyles(){if(this.cachedStyles.size>0){this.cachedStyles.forEach((t=>{t.forEach((({shape:t,style:e})=>{if(Se(e))t.setLocalScale(1);else{if(this.options.state)return;Object.entries(e).forEach((([e,n])=>t.style[e]=n))}}))}));const{graph:t,element:e}=this.context,n=Object.keys(Object.fromEntries(this.cachedStyles)).filter((e=>e&&"node"===t.getElementType(e)));if(n.length>0){const r=new Set;n.forEach((e=>{t.getRelatedEdgesData(e).forEach((t=>r.add(Nh(t))))})),r.forEach((t=>{const n=null==e?void 0:e.getElement(t);null==n||n.update({})}))}}}bindEvents(){const{graph:e}=this.context;e.on(t.GraphEvent.AFTER_DRAW,this.resetTransform),e.on(t.GraphEvent.AFTER_TRANSFORM,this.fixElementSize)}unbindEvents(){const{graph:e}=this.context;e.off(t.GraphEvent.AFTER_DRAW,this.resetTransform),e.off(t.GraphEvent.AFTER_TRANSFORM,this.fixElementSize)}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}destroy(){this.unbindEvents(),super.destroy()}}sv.defaultOptions={enable:t=>t.data.scale<1,nodeFilter:()=>!0,edgeFilter:()=>!0,comboFilter:()=>!0,edge:[{shape:"key",fields:["lineWidth"]},{shape:"halo",fields:["lineWidth"]},{shape:"label"}],reset:!1};class lv extends Gh{constructor(t,e){super(t,Object.assign({},lv.defaultOptions,e)),this.focus=t=>ze(this,void 0,void 0,(function*(){if(!this.validate(t))return;const{graph:e}=this.context;yield e.focusElement(t.target.id,this.options.animation)})),this.bindEvents()}bindEvents(){const{graph:e}=this.context;this.unbindEvents(),Cd.forEach((n=>{e.on(`${n}:${t.CommonEvent.CLICK}`,this.focus)}))}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}unbindEvents(){const{graph:e}=this.context;Cd.forEach((n=>{e.off(`${n}:${t.CommonEvent.CLICK}`,this.focus)}))}destroy(){this.unbindEvents(),super.destroy()}}lv.defaultOptions={animation:{easing:"ease-in",duration:500},enable:!0};class uv extends Gh{constructor(e,n){super(e,Object.assign({},uv.defaultOptions,n)),this.isFrozen=!1,this.toggleFrozen=t=>{this.isFrozen="dragstart"===t.type},this.hoverElement=e=>{if(!this.validate(e))return;const n=e.type===t.CommonEvent.POINTER_ENTER;this.updateElementsState(e,n);const{onHover:r,onHoverEnd:i}=this.options;n?null==r||r(e):null==i||i(e)},this.updateElementsState=(t,e)=>{if(!this.options.state&&!this.options.inactiveState)return;const{graph:n}=this.context,{state:r,animation:i,inactiveState:o}=this.options,a=this.getActiveIds(t),s={};if(r&&Object.assign(s,this.getElementsState(a,r,e)),o){const t=Th(n.getData(),!0).filter((t=>!a.includes(t)));Object.assign(s,this.getElementsState(t,o,e))}n.setElementState(s,i)},this.getElementsState=(t,e,n)=>{const{graph:r}=this.context,i={};return t.forEach((t=>{const o=r.getElementState(t);i[t]=n?o.includes(e)?o:[...o,e]:o.filter((t=>t!==e))})),i},this.bindEvents()}bindEvents(){const{graph:e}=this.context;this.unbindEvents(),Cd.forEach((n=>{e.on(`${n}:${t.CommonEvent.POINTER_ENTER}`,this.hoverElement),e.on(`${n}:${t.CommonEvent.POINTER_LEAVE}`,this.hoverElement)}));const n=this.context.canvas.document;n.addEventListener(`${t.CommonEvent.DRAG_START}`,this.toggleFrozen),n.addEventListener(`${t.CommonEvent.DRAG_END}`,this.toggleFrozen)}getActiveIds(t){const{graph:e}=this.context,{degree:n,direction:r}=this.options,i=t.target.id;return n?Pd(e,t.targetType,i,"function"==typeof n?n(t):n,r):[i]}validate(t){if(this.destroyed||this.isFrozen||Hg(t.target)||this.context.graph.isCollapsingExpanding)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}unbindEvents(){const{graph:e}=this.context;Cd.forEach((n=>{e.off(`${n}:${t.CommonEvent.POINTER_ENTER}`,this.hoverElement),e.off(`${n}:${t.CommonEvent.POINTER_LEAVE}`,this.hoverElement)}));const n=this.context.canvas.document;n.removeEventListener(`${t.CommonEvent.DRAG_START}`,this.toggleFrozen),n.removeEventListener(`${t.CommonEvent.DRAG_END}`,this.toggleFrozen)}destroy(){this.unbindEvents(),super.destroy()}}uv.defaultOptions={animation:!1,enable:!0,degree:0,direction:"both",state:"active",inactiveState:void 0};class cv extends Nd{onPointerDown(t){if(!super.validate(t)||!super.isKeydown()||this.points)return;const{canvas:e}=this.context;this.pathShape=new Ql({id:"g6-lasso-select",style:this.options.style}),e.appendChild(this.pathShape),this.points=[Od(t)]}onPointerMove(t){var e;if(!this.points)return;const{immediately:n,mode:r}=this.options;this.points.push(Od(t)),null===(e=this.pathShape)||void 0===e||e.setAttribute("d",function(t,e=!0){const n=[];return t.forEach(((t,e)=>{n.push([0===e?"M":"L",...t])})),e&&n.push(["Z"]),n}(this.points)),n&&"default"===r&&this.points.length>2&&super.updateElementsStates(this.points)}onPointerUp(){this.points&&(this.points.length<2||super.updateElementsStates(this.points),this.clearLasso())}clearLasso(){var t;null===(t=this.pathShape)||void 0===t||t.remove(),this.pathShape=void 0,this.points=void 0}}class hv extends Gh{constructor(t,e){super(t,Object.assign({},hv.defaultOptions,e)),this.hiddenShapes=[],this.isVisible=!0,this.setElementsVisibility=(t,e,n)=>{t.filter(Boolean).forEach((t=>{"hidden"!==e||t.isVisible()?"visible"===e&&this.hiddenShapes.includes(t)?this.hiddenShapes.splice(this.hiddenShapes.indexOf(t),1):Bh(t,e,n):this.hiddenShapes.push(t)}))},this.filterShapes=(t,e)=>{if(Ut(e))return n=>!e(t,n);const n=null==e?void 0:e[t];return t=>!t.className||!(null==n?void 0:n.includes(t.className))},this.hideShapes=t=>{if(!this.validate(t)||!this.isVisible)return;const{element:e}=this.context,{shapes:n={}}=this.options;this.setElementsVisibility(e.getNodes(),"hidden",this.filterShapes("node",n)),this.setElementsVisibility(e.getEdges(),"hidden",this.filterShapes("edge",n)),this.setElementsVisibility(e.getCombos(),"hidden",this.filterShapes("combo",n)),this.isVisible=!1},this.showShapes=ye((t=>{if(!this.validate(t)||this.isVisible)return;const{element:e}=this.context;this.setElementsVisibility(e.getNodes(),"visible"),this.setElementsVisibility(e.getEdges(),"visible"),this.setElementsVisibility(e.getCombos(),"visible"),this.isVisible=!0}),this.options.debounce),this.bindEvents()}bindEvents(){const{graph:e}=this.context;e.on(t.GraphEvent.BEFORE_TRANSFORM,this.hideShapes),e.on(t.GraphEvent.AFTER_TRANSFORM,this.showShapes)}unbindEvents(){const{graph:e}=this.context;e.off(t.GraphEvent.BEFORE_TRANSFORM,this.hideShapes),e.off(t.GraphEvent.AFTER_TRANSFORM,this.showShapes)}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}destroy(){this.unbindEvents(),super.destroy()}}hv.defaultOptions={enable:!0,debounce:200,shapes:t=>"node"===t};class dv extends Gh{constructor(t,e){super(t,Object.assign({},dv.defaultOptions,e)),this.onWheel=t=>ze(this,void 0,void 0,(function*(){this.options.preventDefault&&t.preventDefault();const e=t.deltaX,n=t.deltaY;yield this.scroll([-e,-n],t)})),this.shortcut=new Sd(t.graph),this.bindEvents()}update(t){super.update(t),this.bindEvents()}bindEvents(){var e,n;const{trigger:r}=this.options;if(this.shortcut.unbindAll(),qt(r)){null===(e=this.graphDom)||void 0===e||e.removeEventListener(t.CommonEvent.WHEEL,this.onWheel);const{up:n=[],down:i=[],left:o=[],right:a=[]}=r;this.shortcut.bind(n,(t=>this.scroll([0,-10],t))),this.shortcut.bind(i,(t=>this.scroll([0,10],t))),this.shortcut.bind(o,(t=>this.scroll([-10,0],t))),this.shortcut.bind(a,(t=>this.scroll([10,0],t)))}else null===(n=this.graphDom)||void 0===n||n.addEventListener(t.CommonEvent.WHEEL,this.onWheel,{passive:!1})}get graphDom(){return this.context.graph.getCanvas().getContextService().getDomElement()}formatDisplacement(t){const{sensitivity:e}=this.options;return t=$h(t,e),t=this.clampByDirection(t),t=this.clampByRange(t)}clampByDirection([t,e]){const{direction:n}=this.options;return"x"===n?e=0:"y"===n&&(t=0),[t,e]}clampByRange([t,e]){const{viewport:n,canvas:r}=this.context,[i,o]=r.getSize(),[a,s,l,u]=Jc(this.options.range),c=[o*a,i*s,o*l,i*u],h=ah(oh(n.getCanvasCenter()),c),d=Uh(n.getViewportCenter(),[t,e,0]);if(!lh(d,h)){const{min:[n,r],max:[i,o]}=h;(d[0]0||d[0]>i&&t<0)&&(t=0),(d[1]0||d[1]>o&&e<0)&&(e=0)}return[t,e]}scroll(t,e){return ze(this,void 0,void 0,(function*(){if(!this.validate(e))return;const{onFinish:n}=this.options,r=this.context.graph,i=this.formatDisplacement(t);yield r.translateBy(i,!1),null==n||n()}))}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}destroy(){var e;this.shortcut.destroy(),null===(e=this.graphDom)||void 0===e||e.removeEventListener(t.CommonEvent.WHEEL,this.onWheel),super.destroy()}}dv.defaultOptions={enable:!0,sensitivity:1,preventDefault:!0,range:1/0};class fv extends Gh{constructor(t,e){super(t,Object.assign({},fv.defaultOptions,e)),this.zoom=(t,e,n)=>ze(this,void 0,void 0,(function*(){if(!this.validate(e))return;const{graph:r}=this.context;let i=this.options.origin;!i&&"viewport"in e&&(i=cd(e.viewport));const{sensitivity:o,onFinish:a}=this.options,s=1+oe(t,-50,50)*o/100,l=r.getZoom();yield r.zoomTo(l*s,n,i),null==a||a()})),this.onReset=()=>ze(this,void 0,void 0,(function*(){yield this.context.graph.zoomTo(1,this.options.animation)})),this.preventDefault=t=>{this.options.preventDefault&&t.preventDefault()},this.shortcut=new Sd(t.graph),this.bindEvents()}update(t){super.update(t),this.bindEvents()}bindEvents(){const{trigger:e}=this.options;if(this.shortcut.unbindAll(),Array.isArray(e))if(e.includes(t.CommonEvent.PINCH))this.shortcut.bind([t.CommonEvent.PINCH],(t=>{this.zoom(t.scale,t,!1)}));else{const n=this.context.canvas.getContainer();null==n||n.addEventListener(t.CommonEvent.WHEEL,this.preventDefault),this.shortcut.bind([...e,t.CommonEvent.WHEEL],(t=>{const{deltaX:e,deltaY:n}=t;this.zoom(-(null!=n?n:e),t,!1)}))}if("object"==typeof e){const{zoomIn:t=[],zoomOut:n=[],reset:r=[]}=e;this.shortcut.bind(t,(t=>this.zoom(10,t,this.options.animation))),this.shortcut.bind(n,(t=>this.zoom(-10,t,this.options.animation))),this.shortcut.bind(r,this.onReset)}}validate(t){if(this.destroyed)return!1;const{enable:e}=this.options;return Ut(e)?e(t):!!e}destroy(){var e;this.shortcut.destroy(),null===(e=this.context.canvas.getContainer())||void 0===e||e.removeEventListener(t.CommonEvent.WHEEL,this.preventDefault),super.destroy()}}fv.defaultOptions={animation:{duration:200},enable:!0,sensitivity:1,trigger:[],preventDefault:!0};var pv={assign:Object.assign,getHeight:function(t,e,n,r){return void 0===r&&(r="height"),"center"===n?(t[r]+e[r])/2:t.height}},gv=pv,vv={getId:function(t){return t.id||t.name},getPreH:function(t){return t.preH||0},getPreV:function(t){return t.preV||0},getHGap:function(t){return t.hgap||18},getVGap:function(t){return t.vgap||18},getChildren:function(t){return t.children},getHeight:function(t){return t.height||36},getWidth:function(t){var e=t.label||" ";return t.width||18*e.split("").length}};function mv(t,e){var n=this;if(n.vgap=n.hgap=0,t instanceof mv)return t;n.data=t;var r=e.getHGap(t),i=e.getVGap(t);return n.preH=e.getPreH(t),n.preV=e.getPreV(t),n.width=e.getWidth(t),n.height=e.getHeight(t),n.width+=n.preH,n.height+=n.preV,n.id=e.getId(t),n.x=n.y=0,n.depth=0,n.children||(n.children=[]),n.addGap(r,i),n}gv.assign(mv.prototype,{isRoot:function(){return 0===this.depth},isLeaf:function(){return 0===this.children.length},addGap:function(t,e){var n=this;n.hgap+=t,n.vgap+=e,n.width+=2*t,n.height+=2*e},eachNode:function(t){for(var e,n=[this];e=n.shift();)t(e),n=e.children.concat(n)},DFTraverse:function(t){this.eachNode(t)},BFTraverse:function(t){for(var e,n=[this];e=n.shift();)t(e),n=n.concat(e.children)},getBoundingBox:function(){var t={left:Number.MAX_VALUE,top:Number.MAX_VALUE,width:0,height:0};return this.eachNode((function(e){t.left=Math.min(t.left,e.x),t.top=Math.min(t.top,e.y),t.width=Math.max(t.width,e.x+e.width),t.height=Math.max(t.height,e.y+e.height)})),t},translate:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.eachNode((function(n){n.x+=t,n.y+=e,n.x+=n.preH,n.y+=n.preV}))},right2left:function(){var t=this,e=t.getBoundingBox();t.eachNode((function(t){t.x=t.x-2*(t.x-e.left)-t.width})),t.translate(e.width,0)},bottom2top:function(){var t=this,e=t.getBoundingBox();t.eachNode((function(t){t.y=t.y-2*(t.y-e.top)-t.height})),t.translate(0,e.height)}});var yv=function(t,e,n){void 0===e&&(e={});var r,i=new mv(t,e=gv.assign({},vv,e)),o=[i];if(!n&&!t.collapsed)for(;r=o.shift();)if(!r.data.collapsed){var a=e.getChildren(r.data),s=a?a.length:0;if(r.children=new Array(s),a&&s)for(var l=0;l-1}(r),-1===Pv.indexOf(r))throw new TypeError("Invalid direction: "+r);if(r===Pv[0])n(t,e);else if(r===Pv[1])n(t,e),t.right2left();else if(r===Pv[2])n(t,e);else if(r===Pv[3])n(t,e),t.bottom2top();else if(r===Pv[4]||r===Pv[5]){var i=Av(t,e),o=i.left,a=i.right;n(o,e),n(a,e),e.isHorizontal?o.right2left():o.bottom2top(),a.translate(o.x-a.x,o.y-a.y),t.x=o.x,t.y=a.y;var s=t.getBoundingBox();e.isHorizontal?s.top<0&&t.translate(0,-s.top):s.left<0&&t.translate(-s.left,0)}var l=e.fixedRoot;return void 0===l&&(l=!0),l&&t.translate(-(t.x+t.width/2+t.hgap),-(t.y+t.height/2+t.vgap)),function(t,e){if(e.radial){var n=e.isHorizontal?["x","y"]:["y","x"],r=n[0],i=n[1],o={x:1/0,y:1/0},a={x:-1/0,y:-1/0},s=0;t.DFTraverse((function(t){s++;var e=t.x,n=t.y;o.x=Math.min(o.x,e),o.y=Math.min(o.y,n),a.x=Math.max(a.x,e),a.y=Math.max(a.y,n)}));var l=a[i]-o[i];if(0===l)return;var u=2*Math.PI/s;t.DFTraverse((function(e){var n=(e[i]-o[i])/l*(2*Math.PI-u)+u,a=e[r]-t[r];e.x=Math.cos(n)*a,e.y=Math.sin(n)*a}))}}(t,e),t};function _v(t,e){return _v=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_v(t,e)}var Iv=function(t,e){void 0===e&&(e={});var n=e.isHorizontal;function r(t){0===t.cs?(t.el=t,t.er=t,t.msel=t.mser=0):(t.el=t.c[0].el,t.msel=t.c[0].msel,t.er=t.c[t.cs-1].er,t.mser=t.c[t.cs-1].mser)}function i(t,e,n){for(var r=t.c[e-1],i=r.mod,u=t.c[e],c=u.mod;null!==r&&null!==u;){l(r)>n.low&&(n=n.nxt);var h=i+r.prelim+r.w-(c+u.prelim);h>0&&(c+=h,o(t,e,n.index,h));var d=l(r),f=l(u);d<=f&&null!==(r=s(r))&&(i+=r.mod),d>=f&&null!==(u=a(u))&&(c+=u.mod)}!r&&u?function(t,e,n,r){var i=t.c[0].el;i.tl=n;var o=r-n.mod-t.c[0].msel;i.mod+=o,i.prelim-=o,t.c[0].el=t.c[e].el,t.c[0].msel=t.c[e].msel}(t,e,u,c):r&&!u&&function(t,e,n,r){var i=t.c[e].er;i.tr=n;var o=r-n.mod-t.c[e].mser;i.mod+=o,i.prelim-=o,t.c[e].er=t.c[e-1].er,t.c[e].mser=t.c[e-1].mser}(t,e,r,i)}function o(t,e,n,r){t.c[e].mod+=r,t.c[e].msel+=r,t.c[e].mser+=r,function(t,e,n,r){if(n!==e-1){var i=e-n;t.c[n+1].shift+=r/i,t.c[e].shift-=r/i,t.c[e].change-=r-r/i}}(t,e,n,r)}function a(t){return 0===t.cs?t.tl:t.c[0]}function s(t){return 0===t.cs?t.tr:t.c[t.cs-1]}function l(t){return t.y+t.h}function u(t,e,n){for(;null!==n&&t>=n.low;)n=n.nxt;return{low:t,index:e,nxt:n}}Ov(t,n);var c=wv.fromNode(t,n);return function t(e){if(0!==e.cs){t(e.c[0]);for(var n=u(l(e.c[0].el),0,null),o=1;or&&(r=e.depth);var n=e.children,i=n.length,o=new Wv(e.height,[]);return n.forEach((function(e,n){var r=t(e);o.children.push(r),0===n&&(o.leftChild=r),n===i-1&&(o.rightChild=r)})),o.originNode=e,o.isLeaf=e.isLeaf(),o}(t);return function t(e){if(e.isLeaf||0===e.children.length)e.drawingDepth=r;else{var n=e.children.map((function(e){return t(e)})),i=Math.min.apply(null,n);e.drawingDepth=i-1}return e.drawingDepth}(i),function t(r){r.x=r.drawingDepth*e.rankSep,r.isLeaf?(r.y=0,n&&(r.y=n.y+n.height+e.nodeSep,r.originNode.parent!==n.originNode.parent&&(r.y+=e.subTreeSep)),n=r):(r.children.forEach((function(e){t(e)})),r.y=(r.leftChild.y+r.rightChild.y)/2)}(i),Uv(i,t,e.isHorizontal),t},qv=Lv,Xv=pv,Kv=function(t){function e(){return t.apply(this,arguments)||this}var n,r;return r=t,(n=e).prototype=Object.create(r.prototype),n.prototype.constructor=n,$v(n,r),e.prototype.execute=function(){var t=this;return t.rootNode.width=0,qv(t.rootNode,t.options,Yv)},e}(Ev),Zv={};var Qv=function(t,e){return e=Xv.assign({},Zv,e),new Kv(t,e).execute()},Jv=pv;function tm(t,e){return tm=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},tm(t,e)}var em=Ev,nm=function(t,e,n,r){var i=null;t.eachNode((function(t){!function(t,e,n,r,i){var o=("function"==typeof n?n(t):n)*t.depth;if(!r)try{if(t.id===t.parent.children[0].id)return t.x+=o,void(t.y=e?e.y:0)}catch(t){}if(t.x+=o,e){if(t.y=e.y+Jv.getHeight(e,t,i),e.parent&&t.parent.id!==e.parent.id){var a=e.parent,s=a.y+Jv.getHeight(a,t,i);t.y=s>t.y?s:t.y}}else t.y=0}(t,i,e,n,r),i=t}))},rm=Cv,im=pv,om=["LR","RL","H"],am=om[0],sm=function(t){function e(){return t.apply(this,arguments)||this}var n,r;return r=t,(n=e).prototype=Object.create(r.prototype),n.prototype.constructor=n,tm(n,r),e.prototype.execute=function(){var t=this.options,e=this.rootNode;t.isHorizontal=!0;var n=t.indent,r=void 0===n?20:n,i=t.dropCap,o=void 0===i||i,a=t.direction,s=void 0===a?am:a,l=t.align;if(s&&-1===om.indexOf(s))throw new TypeError("Invalid direction: "+s);if(s===om[0])nm(e,r,o,l);else if(s===om[1])nm(e,r,o,l),e.right2left();else if(s===om[2]){var u=rm(e,t),c=u.left,h=u.right;nm(c,r,o,l),c.right2left(),nm(h,r,o,l);var d=c.getBoundingBox();h.translate(d.width,0),e.x=h.x-e.width/2}return e},e}(em),lm={};var um=function(t,e){return e=im.assign({},lm,e),new sm(t,e).execute()},cm=pv;function hm(t,e){var n=0;return t.children.length?t.children.forEach((function(t){n+=hm(t,e)})):n=t.height,t._subTreeSep=e.getSubTreeSep(t.data),t.totalHeight=Math.max(t.height,n)+2*t._subTreeSep,t.totalHeight}function dm(t){var e=t.children,n=e.length;if(n){e.forEach((function(t){dm(t)}));var r=e[0],i=e[n-1],o=i.y-r.y+i.height,a=0;if(e.forEach((function(t){a+=t.totalHeight})),o>t.height)t.y=r.y+o/2-t.height/2;else if(1!==e.length||t.height>a){var s=t.y+(t.height-o)/2-r.y;e.forEach((function(t){t.translate(0,s)}))}else t.y=(r.y+r.height/2+i.y+i.height/2)/2-t.height/2}}var fm={getSubTreeSep:function(){return 0}};function pm(t,e){return pm=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},pm(t,e)}var gm=function(t,e){void 0===e&&(e={}),e=cm.assign({},fm,e),t.parent={x:0,width:0,height:0,y:0},t.BFTraverse((function(t){t.x=t.parent.x+t.parent.width})),t.parent=null,hm(t,e),t.startY=0,t.y=t.totalHeight/2-t.height/2,t.eachNode((function(t){var e=t.children,n=e.length;if(n){var r=e[0];if(r.startY=t.startY+t._subTreeSep,1===n)r.y=t.y+t.height/2-r.height/2;else{r.y=r.startY+r.totalHeight/2-r.height/2;for(var i=1;i{if("next"!==t&&"prev"!==t)return e},km=t=>{t.prev.next=t.next,t.next.prev=t.prev,delete t.next,delete t.prev};let Mm=class{constructor(){const t={};t.prev=t,t.next=t.prev,this.shortcut=t}dequeue(){const t=this.shortcut,e=t.prev;if(e&&e!==t)return km(e),e}enqueue(t){const e=this.shortcut;t.prev&&t.next&&km(t),t.next=e.next,e.next.prev=t,e.next=t,t.prev=e}toString(){const t=[],e=this.shortcut;let n=e.prev;for(;n!==e;)t.push(JSON.stringify(n,wm)),n=null==n?void 0:n.prev;return`[${t.join(", ")}]`}},Sm=class extends Mm{};const Nm=()=>1,Om=(t,e,n)=>{let r=[];const i=e[e.length-1],o=e[0];let a;for(;t.getAllNodes().length;){for(;a=o.dequeue();)Tm(t,e,n,a);for(;a=i.dequeue();)Tm(t,e,n,a);if(t.getAllNodes().length)for(let i=e.length-2;i>0;--i)if(a=e[i].dequeue(),a){r=r.concat(Tm(t,e,n,a,!0));break}}return r},Tm=(t,e,n,r,i)=>{var o,a;const s=[];return t.hasNode(r.v)&&(null===(o=t.getRelatedEdges(r.v,"in"))||void 0===o||o.forEach((r=>{const o=r.data.weight,a=t.getNode(r.source);i&&s.push({v:r.source,w:r.target,in:0,out:0}),void 0===a.data.out&&(a.data.out=0),a.data.out-=o,Am(e,n,Object.assign({v:a.id},a.data))})),null===(a=t.getRelatedEdges(r.v,"out"))||void 0===a||a.forEach((r=>{const i=r.data.weight,o=r.target,a=t.getNode(o);void 0===a.data.in&&(a.data.in=0),a.data.in-=i,Am(e,n,Object.assign({v:a.id},a.data))})),t.removeNode(r.v)),i?s:void 0},Cm=(t,e)=>{const n=new ev;let r=0,i=0;t.getAllNodes().forEach((t=>{n.addNode({id:t.id,data:{v:t.id,in:0,out:0}})})),t.getAllEdges().forEach((t=>{const o=n.getRelatedEdges(t.source,"out").find((e=>e.target===t.target)),a=(null==e?void 0:e(t))||1;o?n.updateEdgeData(null==o?void 0:o.id,Object.assign(Object.assign({},o.data),{weight:o.data.weight+a})):n.addEdge({id:t.id,source:t.source,target:t.target,data:{weight:a}}),i=Math.max(i,n.getNode(t.source).data.out+=a),r=Math.max(r,n.getNode(t.target).data.in+=a)}));const o=[],a=i+r+3;for(let t=0;t{Am(o,s,Object.assign({v:t.id},n.getNode(t.id).data))})),{buckets:o,zeroIdx:s,graph:n}},Am=(t,e,n)=>{n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)},Pm=(t,e)=>{const n=((t,e)=>{var n;if(t.getAllNodes().length<=1)return[];const r=Cm(t,e||Nm);return null===(n=Om(r.graph,r.buckets,r.zeroIdx).map((e=>t.getRelatedEdges(e.v,"out").filter((({target:t})=>t===e.w)))))||void 0===n?void 0:n.flat()})(t,(t=>t.data.weight||1));null==n||n.forEach((e=>{const n=e.data;t.removeEdge(e.id),n.forwardName=e.data.name,n.reversed=!0,t.addEdge({id:e.id,source:e.target,target:e.source,data:Object.assign({},n)})}))},Rm=(t,e,n,r)=>{let i;do{i=`${r}${Math.random()}`}while(t.hasNode(i));return n.dummy=e,t.addNode({id:i,data:n}),i},Dm=t=>{const e=new ev;return t.getAllNodes().forEach((n=>{t.getChildren(n.id).length||e.addNode(Object.assign({},n))})),t.getAllEdges().forEach((t=>{e.addEdge(t)})),e},Lm=(t,e)=>{const n=Number(t.x),r=Number(t.y),i=Number(e.x)-n,o=Number(e.y)-r;let a,s,l=Number(t.width)/2,u=Number(t.height)/2;return i||o?(Math.abs(o)*l>Math.abs(i)*u?(o<0&&(u=-u),a=u*i/o,s=u):(i<0&&(l=-l),a=l,s=l*o/i),{x:n+a,y:r+s}):{x:0,y:0}},_m=t=>{const e=[],n=jm(t)+1;for(let t=0;t{const n=t.data.rank;void 0!==n&&e[n]&&e[n].push(t.id)}));for(let r=0;r{return r=t.getNode(e).data.order,i=t.getNode(n).data.order,Number(r)-Number(i);var r,i}));return e},Im=(t,e,n,r)=>{const i={width:0,height:0};return ae(n)&&ae(r)&&(i.rank=n,i.order=r),Rm(t,"border",i,e)},jm=t=>{let e;return t.getAllNodes().forEach((t=>{const n=t.data.rank;void 0!==n&&(void 0===e||n>e)&&(e=n)})),e||(e=0),e},Bm=(t,e)=>t.reduce(((t,n)=>e(t)>e(n)?n:t)),Fm=(t,e,n,r,i,o)=>{r.includes(e.id)||(r.push(e.id),n||o.push(e.id),i(e.id).forEach((e=>Fm(t,e,n,r,i,o))),n&&o.push(e.id))},zm=(t,e,n,r)=>{const i=Array.isArray(e)?e:[e],o=e=>t.getNeighbors(e),a=[],s=[];return i.forEach((e=>{if(!t.hasNode(e.id))throw new Error(`Graph does not have node: ${e}`);Fm(t,e,"post"===n,s,o,a)})),a},Gm=(t,e,n,r,i,o)=>{const a={rank:o,borderType:e,width:0,height:0},s=i.data[e][o-1],l=Rm(t,"border",a,n);i.data[e][o]=l,t.setParent(l,r),s&&t.addEdge({id:`e${Math.random()}`,source:s,target:l,data:{weight:1}})},Vm=t=>{t.getAllNodes().forEach((t=>{Wm(t)})),t.getAllEdges().forEach((t=>{Wm(t)}))},Wm=t=>{const e=t.data.width;t.data.width=t.data.height,t.data.height=e},Hm=t=>{t.getAllNodes().forEach((t=>{Um(t.data)})),t.getAllEdges().forEach((t=>{var e;null===(e=t.data.points)||void 0===e||e.forEach((t=>Um(t))),t.data.hasOwnProperty("y")&&Um(t.data)}))},Um=t=>{(null==t?void 0:t.y)&&(t.y=-t.y)},$m=t=>{t.getAllNodes().forEach((t=>{Ym(t.data)})),t.getAllEdges().forEach((t=>{var e;null===(e=t.data.points)||void 0===e||e.forEach((t=>Ym(t))),t.data.hasOwnProperty("x")&&Ym(t.data)}))},Ym=t=>{const e=t.x;t.x=t.y,t.y=e},qm=(t,e,n,r,i,o,a)=>{const s=t.getChildren(a);if(!(null==s?void 0:s.length))return void(a!==e&&t.addEdge({id:`e${Math.random()}`,source:e,target:a,data:{weight:0,minlen:n}}));const l=Im(t,"_bt"),u=Im(t,"_bb"),c=t.getNode(a);t.setParent(l,a),c.data.borderTop=l,t.setParent(u,a),c.data.borderBottom=u,null==s||s.forEach((s=>{qm(t,e,n,r,i,o,s.id);const c=s.data.borderTop?s.data.borderTop:s.id,h=s.data.borderBottom?s.data.borderBottom:s.id,d=s.data.borderTop?r:2*r,f=c!==h?1:i-o[a]+1;t.addEdge({id:`e${Math.random()}`,source:l,target:c,data:{minlen:f,weight:d,nestingEdge:!0}}),t.addEdge({id:`e${Math.random()}`,source:h,target:u,data:{minlen:f,weight:d,nestingEdge:!0}})})),t.getParent(a)||t.addEdge({id:`e${Math.random()}`,source:e,target:l,data:{weight:0,minlen:i+o[a]}})},Xm=t=>{const e={},n=(r,i)=>{const o=t.getChildren(r);null==o||o.forEach((t=>n(t.id,i+1))),e[r]=i};return t.getRoots().forEach((t=>n(t.id,1))),e},Km=t=>{let e=0;return t.getAllEdges().forEach((t=>{e+=t.data.weight})),e},Zm="edge-label",Qm=(t,e,n)=>{let r=e.source,i=t.getNode(r).data.rank;const o=e.target,a=t.getNode(o).data.rank,s=e.data.labelRank;if(a===i+1)return;let l,u,c;for(t.removeEdge(e.id),c=0,++i;i{let e;for(;t.hasNode(e=`_root${Math.random()}`););return e},ty=(t,e,n)=>{const r=((t,e)=>null==t?void 0:t.reduce(((t,n,r)=>(t[n]=e[r],t)),{}))(n,n.map(((t,e)=>e))),i=e.map((e=>{const n=t.getRelatedEdges(e,"out").map((t=>({pos:r[t.target]||0,weight:t.data.weight})));return null==n?void 0:n.sort(((t,e)=>t.pos-e.pos))})),o=i.flat().filter((t=>void 0!==t));let a=1;for(;a{if(t){let e=t.pos+a;l[e]+=t.weight;let n=0;for(;e>0;)e%2&&(n+=l[e+1]),e=e-1>>1,l[e]+=t.weight;u+=t.weight*n}})),u},ey=(t,e)=>{let n=0;for(let r=1;r<(null==e?void 0:e.length);r+=1)n+=ty(t,e[r-1],e[r]);return n},ny=t=>{const e={},n=t.getAllNodes(),r=n.map((t=>{var e;return null!==(e=t.data.rank)&&void 0!==e?e:-1/0})),i=Math.max(...r),o=[];for(let t=0;tt.getNode(e.id).data.rank-t.getNode(n.id).data.rank)),s=a.filter((e=>void 0!==t.getNode(e.id).data.fixorder)).sort(((e,n)=>t.getNode(e.id).data.fixorder-t.getNode(n.id).data.fixorder));return null==s||s.forEach((n=>{isNaN(t.getNode(n.id).data.rank)||o[t.getNode(n.id).data.rank].push(n.id),e[n.id]=!0})),null==a||a.forEach((n=>t.dfsTree(n.id,(t=>{if(e.hasOwnProperty(t.id))return!0;e[t.id]=!0,isNaN(t.data.rank)||o[t.data.rank].push(t.id)})))),o},ry=t=>{var e,n;const r=[];for(;null==t?void 0:t.length;){const i=t.pop();r.push(i),null===(e=i.in.reverse())||void 0===e||e.forEach((t=>{return(e=i,t=>{t.merged||(void 0===t.barycenter||void 0===e.barycenter||t.barycenter>=e.barycenter)&&iy(e,t)})(t);var e})),null===(n=i.out)||void 0===n||n.forEach((e=>{return(n=i,e=>{e.in.push(n),0===--e.indegree&&t.push(e)})(e);var n}))}const i=r.filter((t=>!t.merged)),o=["vs","i","barycenter","weight"];return i.map((t=>{const e={};return null==o||o.forEach((n=>{void 0!==t[n]&&(e[n]=t[n])})),e}))},iy=(t,e)=>{var n;let r=0,i=0;t.weight&&(r+=t.barycenter*t.weight,i+=t.weight),e.weight&&(r+=e.barycenter*e.weight,i+=e.weight),t.vs=null===(n=e.vs)||void 0===n?void 0:n.concat(t.vs),t.barycenter=r/i,t.weight=i,t.i=Math.min(e.i,t.i),e.merged=!0},oy=(t,e,n)=>{let r,i=n;for(;e.length&&(r=e[e.length-1]).i<=i;)e.pop(),null==t||t.push(r.vs),i++;return i},ay=(t,e)=>(n,r)=>{if(void 0!==n.fixorder&&void 0!==r.fixorder)return n.fixorder-r.fixorder;if(n.barycenterr.barycenter)return 1;if(e&&void 0!==n.order&&void 0!==r.order){if(n.orderr.order)return 1}return t?r.i-n.i:n.i-r.i},sy=(t,e,n,r,i,o)=>{var a,s,l,u;let c=t.getChildren(e).map((t=>t.id));const h=t.getNode(e),d=h?h.data.borderLeft:void 0,f=h?h.data.borderRight:void 0,p={};d&&(c=null==c?void 0:c.filter((t=>t!==d&&t!==f)));const g=((t,e)=>e.map((e=>{const n=t.getRelatedEdges(e,"in");if(!(null==n?void 0:n.length))return{v:e};const r={sum:0,weight:0};return null==n||n.forEach((e=>{const n=t.getNode(e.source);r.sum+=e.data.weight*n.data.order,r.weight+=e.data.weight})),{v:e,barycenter:r.sum/r.weight,weight:r.weight}})))(t,c||[]);null==g||g.forEach((e=>{var i;if(null===(i=t.getChildren(e.v))||void 0===i?void 0:i.length){const i=sy(t,e.v,n,r,o);p[e.v]=i,i.hasOwnProperty("barycenter")&&uy(e,i)}}));const v=((t,e)=>{var n,r,i;const o={};null==t||t.forEach(((t,e)=>{o[t.v]={i:e,indegree:0,in:[],out:[],vs:[t.v]};const n=o[t.v];void 0!==t.barycenter&&(n.barycenter=t.barycenter,n.weight=t.weight)})),null===(n=e.getAllEdges())||void 0===n||n.forEach((t=>{const e=o[t.source],n=o[t.target];void 0!==e&&void 0!==n&&(n.indegree++,e.out.push(o[t.target]))}));const a=null===(i=(r=Object.values(o)).filter)||void 0===i?void 0:i.call(r,(t=>!t.indegree));return ry(a)})(g,n);ly(v,p),null===(a=v.filter((t=>t.vs.length>0)))||void 0===a||a.forEach((e=>{const n=t.getNode(e.vs[0]);n&&(e.fixorder=n.data.fixorder,e.order=n.data.order)}));const m=((t,e,n,r)=>{const i=((t,e)=>{const n={lhs:[],rhs:[]};return null==t||t.forEach((t=>{e(t)?n.lhs.push(t):n.rhs.push(t)})),n})(t,(t=>{const e=t.hasOwnProperty("fixorder")&&!isNaN(t.fixorder);return r?!e&&t.hasOwnProperty("barycenter"):e||t.hasOwnProperty("barycenter")})),o=i.lhs,a=i.rhs.sort(((t,e)=>-t.i- -e.i)),s=[];let l=0,u=0,c=0;null==o||o.sort(ay(!!e,!!n)),c=oy(s,a,c),null==o||o.forEach((t=>{var e;c+=null===(e=t.vs)||void 0===e?void 0:e.length,s.push(t.vs),l+=t.barycenter*t.weight,u+=t.weight,c=oy(s,a,c)}));const h={vs:s.flat()};return u&&(h.barycenter=l/u,h.weight=u),h})(v,r,i,o);if(d&&(m.vs=[d,m.vs,f].flat(),null===(s=t.getPredecessors(d))||void 0===s?void 0:s.length)){const e=t.getNode((null===(l=t.getPredecessors(d))||void 0===l?void 0:l[0].id)||""),n=t.getNode((null===(u=t.getPredecessors(f))||void 0===u?void 0:u[0].id)||"");m.hasOwnProperty("barycenter")||(m.barycenter=0,m.weight=0),m.barycenter=(m.barycenter*m.weight+e.data.order+n.data.order)/(m.weight+2),m.weight+=2}return m},ly=(t,e)=>{null==t||t.forEach((t=>{var n;const r=null===(n=t.vs)||void 0===n?void 0:n.map((t=>e[t]?e[t].vs:t));t.vs=r.flat()}))},uy=(t,e)=>{void 0!==t.barycenter?(t.barycenter=(t.barycenter*t.weight+e.barycenter*e.weight)/(t.weight+e.weight),t.weight+=e.weight):(t.barycenter=e.barycenter,t.weight=e.weight)},cy=(t,e,n)=>e.map((e=>((t,e,n)=>{const r=Jm(t),i=new ev({tree:[{id:r,children:[],data:{}}]});return t.getAllNodes().forEach((o=>{const a=t.getParent(o.id);(o.data.rank===e||o.data.minRank<=e&&e<=o.data.maxRank)&&(i.hasNode(o.id)||i.addNode(Object.assign({},o)),(null==a?void 0:a.id)&&!i.hasNode(null==a?void 0:a.id)&&i.addNode(Object.assign({},a)),i.setParent(o.id,(null==a?void 0:a.id)||r),t.getRelatedEdges(o.id,n).forEach((e=>{const n=e.source===o.id?e.target:e.source;i.hasNode(n)||i.addNode(Object.assign({},t.getNode(n)));const r=i.getRelatedEdges(n,"out").find((({target:t})=>t===o.id)),a=void 0!==r?r.data.weight:0;r?i.updateEdgeData(r.id,Object.assign(Object.assign({},r.data),{weight:e.data.weight+a})):i.addEdge({id:e.id,source:n,target:o.id,data:{weight:e.data.weight+a}})})),o.data.hasOwnProperty("minRank")&&i.updateNodeData(o.id,Object.assign(Object.assign({},o.data),{borderLeft:o.data.borderLeft[e],borderRight:o.data.borderRight[e]})))})),i})(t,e,n))),hy=(t,e,n,r)=>{const i=new ev;null==t||t.forEach((t=>{var o;const a=t.getRoots()[0].id,s=sy(t,a,i,e,n,r);for(let e=0;e<(null===(o=s.vs)||void 0===o?void 0:o.length);e++){const n=t.getNode(s.vs[e]);n&&(n.data.order=e)}((t,e,n)=>{const r={};let i;null==n||n.forEach((n=>{let o,a,s=t.getParent(n);for(;s;){if(o=t.getParent(s.id),o?(a=r[o.id],r[o.id]=s.id):(a=i,i=s.id),a&&a!==s.id)return e.hasNode(a)||e.addNode({id:a,data:{}}),e.hasNode(s.id)||e.addNode({id:s.id,data:{}}),void(e.hasEdge(`e${a}-${s.id}`)||e.addEdge({id:`e${a}-${s.id}`,source:a,target:s.id,data:{}}));s=o}}))})(t,i,s.vs)}))},dy=(t,e)=>{null==e||e.forEach((e=>{null==e||e.forEach(((e,n)=>{t.getNode(e).data.order=n}))}))},fy=(t,e)=>{const n=(t=>{const e={};let n=0;const r=i=>{const o=n;t.getChildren(i).forEach((t=>r(t.id))),e[i]={low:o,lim:n++}};return t.getRoots().forEach((t=>r(t.id))),e})(t);e.forEach((e=>{var r,i;let o=e,a=t.getNode(o);const s=a.data.originalEdge;if(!s)return;const l=((t,e,n,r)=>{var i,o;const a=[],s=[],l=Math.min(e[n].low,e[r].low),u=Math.max(e[n].lim,e[r].lim);let c,h;c=n;do{c=null===(i=t.getParent(c))||void 0===i?void 0:i.id,a.push(c)}while(c&&(e[c].low>l||u>e[c].lim));for(h=c,c=r;c&&c!==h;)s.push(c),c=null===(o=t.getParent(c))||void 0===o?void 0:o.id;return{lca:h,path:a.concat(s.reverse())}})(t,n,s.source,s.target),u=l.path,c=l.lca;let h=0,d=u[h],f=!0;for(;o!==s.target;){if(a=t.getNode(o),f){for(;d!==c&&(null===(r=t.getNode(d))||void 0===r?void 0:r.data.maxRank){const n={};function r(e,r){const i=function(t){return JSON.stringify(t.slice(1))}(e);r.get(i)||(!function(e,r,i,o,a){var s,l;let u;for(let c=r;c{const r=t.getNode(e.id);r.data.dummy&&(r.data.ordera)&&vy(n,e.id,u)})))}(...e),r.set(i,!0))}const i=(e,n)=>{let i,o=-1,a=0;const s=new Map;return null==n||n.forEach(((l,u)=>{var c;if("border"===(null===(c=t.getNode(l))||void 0===c?void 0:c.data.dummy)){const e=t.getPredecessors(l)||[];e.length&&(i=t.getNode(e[0].id).data.order,r([n,a,u,o,i],s),a=u,o=i)}r([n,a,n.length,i,e.length],s)})),n};return(null==e?void 0:e.length)&&e.reduce(i),n},gy=(t,e)=>{var n,r;if(null===(n=t.getNode(e))||void 0===n?void 0:n.data.dummy)return null===(r=t.getPredecessors(e))||void 0===r?void 0:r.find((e=>t.getNode(e.id).data.dummy))},vy=(t,e,n)=>{let r=e,i=n;if(r>i){const t=r;r=i,i=t}let o=t[r];o||(t[r]=o={}),o[i]=!0},my=(t,e,n)=>{let r=e,i=n;if(r>n){r=n,i=e}return!!t[r]},yy=(t,e,n,r,i,o)=>{const a=new ev,s=by(r,i,o);return null==e||e.forEach((e=>{let r;null==e||e.forEach((e=>{const i=n[e];if(a.hasNode(i)||a.addNode({id:i,data:{}}),r){const o=n[r],l=a.getRelatedEdges(o,"out").find((t=>t.target===i));l?a.updateEdgeData(l.id,Object.assign(Object.assign({},l.data),{weight:Math.max(s(t,e,r),l.data.weight||0)})):a.addEdge({id:`e${Math.random()}`,source:o,target:i,data:{weight:Math.max(s(t,e,r),0)}})}r=e}))})),a};const by=(t,e,n)=>(r,i,o)=>{const a=r.getNode(i),s=r.getNode(o);let l=0,u=0;if(l+=a.data.width/2,a.data.hasOwnProperty("labelpos"))switch((a.data.labelpos||"").toLowerCase()){case"l":u=-a.data.width/2;break;case"r":u=a.data.width/2}if(u&&(l+=n?u:-u),u=0,l+=(a.data.dummy?e:t)/2,l+=(s.data.dummy?e:t)/2,l+=s.data.width/2,s.data.labelpos)switch((s.data.labelpos||"").toLowerCase()){case"l":u=s.data.width/2;break;case"r":u=-s.data.width/2}return u&&(l+=n?u:-u),u=0,l},xy=(t,e)=>t.getNode(e).data.width||0,Ey=(t,e)=>{const{align:n,nodesep:r=0,edgesep:i=0}=e||{},o=_m(t),a=Object.assign(((t,e)=>{const n={},r=(e,r)=>{let i=0,o=0;const a=e.length,s=null==r?void 0:r[(null==r?void 0:r.length)-1];return null==r||r.forEach(((e,l)=>{var u;const c=gy(t,e),h=c?t.getNode(c.id).data.order:a;(c||e===s)&&(null===(u=r.slice(o,l+1))||void 0===u||u.forEach((e=>{var r;null===(r=t.getPredecessors(e))||void 0===r||r.forEach((r=>{var o;const a=t.getNode(r.id),s=a.data.order;!(s{l="u"===e?o:Object.values(o).reverse(),["l","r"].forEach((n=>{"r"===n&&(l=l.map((t=>Object.values(t).reverse())));const o=("u"===e?t.getPredecessors:t.getSuccessors).bind(t),u=((t,e,n,r)=>{const i={},o={},a={};return null==e||e.forEach((t=>{null==t||t.forEach(((t,e)=>{i[t]=t,o[t]=t,a[t]=e}))})),null==e||e.forEach((t=>{let e=-1;null==t||t.forEach((t=>{let s=r(t).map((t=>t.id));if(s.length){s=s.sort(((t,e)=>a[t]-a[e]));const r=(s.length-1)/2;for(let l=Math.floor(r),u=Math.ceil(r);l<=u;++l){const r=s[l];o[t]===t&&e{var s;const l={},u=yy(t,e,n,i,o,a),c=a?"borderLeft":"borderRight",h=(t,e)=>{let n=u.getAllNodes(),r=n.pop();const i={};for(;r;)i[r.id]?t(r.id):(i[r.id]=!0,n.push(r),n=n.concat(e(r.id))),r=n.pop()};return h((t=>{l[t]=(u.getRelatedEdges(t,"in")||[]).reduce(((t,e)=>Math.max(t,(l[e.source]||0)+e.data.weight)),0)}),u.getPredecessors.bind(u)),h((e=>{const n=(u.getRelatedEdges(e,"out")||[]).reduce(((t,e)=>Math.min(t,(l[e.target]||0)-e.data.weight)),Number.POSITIVE_INFINITY),r=t.getNode(e);n!==Number.POSITIVE_INFINITY&&r.data.borderType!==c&&(l[e]=Math.max(l[e],n))}),u.getSuccessors.bind(u)),null===(s=Object.values(r))||void 0===s||s.forEach((t=>{l[t]=l[n[t]]})),l})(t,l,u.root,u.align,r,i,"r"===n);"r"===n&&Object.keys(c).forEach((t=>c[t]=-c[t])),s[e+n]=c}))}));const u=((t,e)=>Bm(Object.values(e),(e=>{var n;let r=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return null===(n=Object.keys(e))||void 0===n||n.forEach((n=>{const o=e[n],a=xy(t,n)/2;r=Math.max(o+a,r),i=Math.min(o-a,i)})),r-i})))(t,s);return u&&function(t,e){const n=Object.values(e),r=Math.min(...n),i=Math.max(...n);["u","d"].forEach((n=>{["l","r"].forEach((o=>{const a=n+o,s=t[a];let l;if(s===e)return;const u=Object.values(s);l="l"===o?r-Math.min(...u):i-Math.max(...u),l&&(t[a]={},Object.keys(s).forEach((e=>{t[a][e]=s[e]+l})))}))}))}(s,u),((t,e)=>{const n={};return Object.keys(t.ul).forEach((r=>{if(e)n[r]=t[e.toLowerCase()][r];else{const e=Object.values(t).map((t=>t[r]));n[r]=(e[0]+e[1])/2}})),n})(s,n)},wy=(t,e)=>{var n;const r=Dm(t);((t,e)=>{const{ranksep:n=0}=e||{},r=_m(t);let i=0;null==r||r.forEach((e=>{const r=e.map((e=>t.getNode(e).data.height)),o=Math.max(...r,0);null==e||e.forEach((e=>{t.getNode(e).data.y=i+o/2})),i+=o+n}))})(r,e);const i=Ey(r,e);null===(n=Object.keys(i))||void 0===n||n.forEach((t=>{r.getNode(t).data.x=i[t]}))},ky=t=>{const e={},n=r=>{var i;const o=t.getNode(r);if(!o)return 0;if(e[r])return o.data.rank;let a;return e[r]=!0,null===(i=t.getRelatedEdges(r,"out"))||void 0===i||i.forEach((t=>{const e=n(t.target)-t.data.minlen;e&&(void 0===a||e0===t.getRelatedEdges(e.id,"in").length)).forEach((t=>n(t.id)))},My=(t,e)=>t.getNode(e.target).data.rank-t.getNode(e.source).data.rank-e.data.minlen,Sy=(t,e)=>{const n=r=>{e.getRelatedEdges(r,"both").forEach((i=>{const o=i.source,a=r===o?i.target:o;t.hasNode(a)||My(e,i)||(t.addNode({id:a,data:{}}),t.addEdge({id:i.id,source:r,target:a,data:{}}),n(a))}))};return t.getAllNodes().forEach((t=>n(t.id))),t.getAllNodes().length},Ny=(t,e)=>{const n=r=>{var i;null===(i=e.getRelatedEdges(r,"both"))||void 0===i||i.forEach((i=>{const o=i.source,a=r===o?i.target:o;t.hasNode(a)||void 0===e.getNode(a).data.layer&&My(e,i)||(t.addNode({id:a,data:{}}),t.addEdge({id:i.id,source:r,target:a,data:{}}),n(a))}))};return t.getAllNodes().forEach((t=>n(t.id))),t.getAllNodes().length},Oy=(t,e)=>Bm(e.getAllEdges(),(n=>t.hasNode(n.source)!==t.hasNode(n.target)?My(e,n):1/0)),Ty=(t,e,n)=>{t.getAllNodes().forEach((t=>{const r=e.getNode(t.id);r.data.rank||(r.data.rank=0),r.data.rank+=n}))},Cy=t=>{const e=(t=>{const e=new ev;return t.getAllNodes().forEach((t=>{e.addNode(Object.assign({},t))})),t.getAllEdges().forEach((t=>{const n=e.getRelatedEdges(t.source,"out").find((e=>e.target===t.target));n?e.updateEdgeData(null==n?void 0:n.id,Object.assign(Object.assign({},n.data),{weight:n.data.weight+t.data.weight||0,minlen:Math.max(n.data.minlen,t.data.minlen||1)})):e.addEdge({id:t.id,source:t.source,target:t.target,data:{weight:t.data.weight||0,minlen:t.data.minlen||1}})})),e})(t);ky(e);const n=(t=>{const e=new ev({tree:[]}),n=t.getAllNodes()[0],r=t.getAllNodes().length;let i,o;for(e.addNode(n);Sy(e,t){let n=zm(t,t.getAllNodes(),"post");n=n.slice(0,(null==n?void 0:n.length)-1),n.forEach((n=>{Py(t,e,n)}))},Py=(t,e,n)=>{const r=t.getNode(n).data.parent;t.getRelatedEdges(n,"both").find((t=>t.target===r||t.source===r)).data.cutvalue=Ry(t,e,n)},Ry=(t,e,n)=>{const r=t.getNode(n).data.parent;let i=!0,o=e.getRelatedEdges(n,"out").find((t=>t.target===r)),a=0;return o||(i=!1,o=e.getRelatedEdges(r,"out").find((t=>t.target===n))),a=o.data.weight,e.getRelatedEdges(n,"both").forEach((e=>{const o=e.source===n,s=o?e.target:e.source;if(s!==r){const r=o===i,l=e.data.weight;if(a+=r?l:-l,Fy(t,n,s)){const e=t.getRelatedEdges(n,"both").find((t=>t.source===s||t.target===s)).data.cutvalue;a+=r?-e:e}}})),a},Dy=(t,e=t.getAllNodes()[0].id)=>{Ly(t,{},1,e)},Ly=(t,e,n,r,i)=>{var o;const a=n;let s=n;const l=t.getNode(r);return e[r]=!0,null===(o=t.getNeighbors(r))||void 0===o||o.forEach((n=>{e[n.id]||(s=Ly(t,e,s,n.id,r))})),l.data.low=a,l.data.lim=s++,i?l.data.parent=i:delete l.data.parent,s},_y=t=>t.getAllEdges().find((t=>t.data.cutvalue<0)),Iy=(t,e,n)=>{let r=n.source,i=n.target;e.getRelatedEdges(r,"out").find((t=>t.target===i))||(r=n.target,i=n.source);const o=t.getNode(r),a=t.getNode(i);let s=o,l=!1;o.data.lim>a.data.lim&&(s=a,l=!0);const u=e.getAllEdges().filter((e=>l===zy(t.getNode(e.source),s)&&l!==zy(t.getNode(e.target),s)));return Bm(u,(t=>My(e,t)))},jy=(t,e,n,r)=>{const i=t.getRelatedEdges(n.source,"both").find((t=>t.source===n.target||t.target===n.target));i&&t.removeEdge(i.id),t.addEdge({id:`e${Math.random()}`,source:r.source,target:r.target,data:{}}),Dy(t),Ay(t,e),By(t,e)},By=(t,e)=>{const n=t.getAllNodes().find((t=>!t.data.parent));let r=zm(t,n,"pre");r=r.slice(1),r.forEach((n=>{const r=t.getNode(n).data.parent;let i=e.getRelatedEdges(n,"out").find((t=>t.target===r)),o=!1;!i&&e.hasNode(r)&&(i=e.getRelatedEdges(r,"out").find((t=>t.target===n)),o=!0),e.getNode(n).data.rank=(e.hasNode(r)&&e.getNode(r).data.rank||0)+(o?null==i?void 0:i.data.minlen:-(null==i?void 0:i.data.minlen))}))},Fy=(t,e,n)=>t.getRelatedEdges(e,"both").find((t=>t.source===n||t.target===n)),zy=(t,e)=>e.data.low<=t.data.lim&&t.data.lim<=e.data.lim,Gy=ky,Vy=t=>{(t=>{const e={};let n;const r=i=>{var o;const a=t.getNode(i);if(!a)return 0;if(e[i])return a.data.rank;let s;return e[i]=!0,null===(o=t.getRelatedEdges(i,"out"))||void 0===o||o.forEach((t=>{const e=r(t.target)-t.data.minlen;e&&(void 0===s||e0===t.getRelatedEdges(e.id,"in").length)).forEach((t=>{t&&r(t.id)})),void 0===n&&(n=0);const i={},o=(e,n)=>{var r;const a=t.getNode(e),s=isNaN(a.data.layer)?n:a.data.layer;(void 0===a.data.rank||a.data.rank{o(t.target,s+t.data.minlen)})))};t.getAllNodes().forEach((t=>{const e=t.data;e&&(isNaN(e.layer)?e.rank-=n:o(t.id,e.layer))}))})(t),(t=>{const e=new ev({tree:[]}),n=t.getAllNodes()[0],r=t.getAllNodes().length;let i,o;for(e.addNode(n);Ny(e,t){Cy(t)},Hy=(t,e)=>{const{ranker:n,rankdir:r="tb",nodeOrder:i,keepNodeOrder:o,align:a,nodesep:s=50,edgesep:l=20,ranksep:u=50}=e;lb(t),Pm(t);const{nestingRoot:c,nodeRankFactor:h}=(t=>{const e=Rm(t,"root",{},"_root"),n=Xm(t);let r=Math.max(...Object.values(n));Math.abs(r)===1/0&&(r=1);const i=r-1,o=2*i+1;t.getAllEdges().forEach((t=>{t.data.minlen*=o}));const a=Km(t)+1;return t.getRoots().forEach((r=>{qm(t,e,o,a,i,n,r.id)})),{nestingRoot:e,nodeRankFactor:o}})(t);((t,e)=>{switch(e){case"network-simplex":Wy(t);break;case"tight-tree":default:Vy(t);break;case"longest-path":Gy(t)}})(Dm(t),n),tb(t),((t,e=0)=>{const n=t.getAllNodes(),r=n.filter((t=>void 0!==t.data.rank)).map((t=>t.data.rank)),i=Math.min(...r),o=[];n.forEach((t=>{const e=(t.data.rank||0)-i;o[e]||(o[e]=[]),o[e].push(t.id)}));let a=0;for(let n=0;n{const n=t.getNode(e);n&&(n.data.rank=n.data.rank||0,n.data.rank+=a)})))}})(t,h),((t,e)=>{e&&t.removeNode(e),t.getAllEdges().forEach((e=>{e.data.nestingEdge&&t.removeEdge(e.id)}))})(t,c),(t=>{const e=t.getAllNodes().filter((t=>void 0!==t.data.rank)).map((t=>t.data.rank)),n=Math.min(...e);t.getAllNodes().forEach((t=>{t.data.hasOwnProperty("rank")&&n!==1/0&&(t.data.rank-=n)}))})(t),eb(t),nb(t);const d=[];((t,e)=>{t.getAllEdges().forEach((n=>Qm(t,n,e)))})(t,d),fy(t,d),(t=>{const e=n=>{const r=t.getChildren(n),i=t.getNode(n);if((null==r?void 0:r.length)&&r.forEach((t=>e(t.id))),i.data.hasOwnProperty("minRank")){i.data.borderLeft=[],i.data.borderRight=[];for(let e=i.data.minRank,r=i.data.maxRank+1;ee(t.id)))})(t),o&&((t,e)=>{const n=t.getAllNodes().filter((e=>{var n;return!(null===(n=t.getChildren(e.id))||void 0===n?void 0:n.length)})).map((t=>t.data.rank)),r=Math.max(...n),i=[];for(let t=0;t{const n=t.getNode(e);n&&!n.data.dummy&&(isNaN(n.data.rank)||(n.data.fixorder=i[n.data.rank].length,i[n.data.rank].push(e)))}))})(t,i),((t,e)=>{const n=jm(t),r=[],i=[];for(let t=1;t-1;t--)i.push(t);const o=cy(t,r,"in"),a=cy(t,i,"out");let s=ny(t);dy(t,s);let l,u=Number.POSITIVE_INFINITY;for(let n=0,r=0;r<4;++n,++r){hy(n%2?o:a,n%4>=2,!1,e),s=_m(t);const i=ey(t,s);i=2,!0,e),s=_m(t);const i=ey(t,s);i{const n=e.toLowerCase();"lr"!==n&&"rl"!==n||Vm(t)})(t,r),wy(t,{align:a,nodesep:s,edgesep:l,ranksep:u}),cb(t),sb(t),((t,e)=>{e.forEach((e=>{let n=t.getNode(e);const{data:r}=n,i=r.originalEdge;let o;i&&t.addEdge(i);let a=e;for(;n.data.dummy;)o=t.getSuccessors(a)[0],t.removeNode(a),i.data.points.push({x:n.data.x,y:n.data.y}),n.data.dummy===Zm&&(i.data.x=n.data.x,i.data.y=n.data.y,i.data.width=n.data.width,i.data.height=n.data.height),a=o.id,n=t.getNode(a)}))})(t,d),ob(t),((t,e)=>{const n=e.toLowerCase();"bt"!==n&&"rl"!==n||Hm(t),"lr"!==n&&"rl"!==n||($m(t),Vm(t))})(t,r);const{width:f,height:p}=rb(t);return ib(t),ab(t),(t=>{t.getAllEdges().forEach((e=>{const n=e.data;if(n.reversed){t.removeEdge(e.id);const r=n.forwardName;delete n.reversed,delete n.forwardName,t.addEdge({id:e.id,source:e.target,target:e.source,data:Object.assign(Object.assign({},n),{forwardName:r})})}}))})(t),{width:f,height:p}},Uy=(t,e)=>{t.getAllNodes().forEach((n=>{const r=t.getNode(n.id);if(e.hasNode(n.id)){const t=e.getNode(n.id);r.data.fixorder=t.data._order,delete t.data._order}else delete r.data.fixorder}))},$y=(t,e)=>{t.getAllNodes().forEach((n=>{var r;const i=t.getNode(n.id);if(i){const t=e.getNode(n.id);i.data.x=t.data.x,i.data.y=t.data.y,i.data._order=t.data.order,i.data._rank=t.data.rank,(null===(r=e.getChildren(n.id))||void 0===r?void 0:r.length)&&(i.data.width=t.data.width,i.data.height=t.data.height)}})),t.getAllEdges().forEach((n=>{const r=t.getEdge(n.id),i=e.getEdge(n.id);r.data.points=i?i.data.points:[],i&&i.data.hasOwnProperty("x")&&(r.data.x=i.data.x,r.data.y=i.data.y)}))},Yy=["width","height","layer","fixorder"],qy={width:0,height:0},Xy=["minlen","weight","width","height","labeloffset"],Ky={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},Zy=["labelpos"],Qy=t=>{const e=new ev({tree:[]});return t.getAllNodes().forEach((n=>{const r=db(t.getNode(n.id).data),i=Object.assign(Object.assign({},qy),r),o=hb(i,Yy);e.hasNode(n.id)||e.addNode({id:n.id,data:Object.assign({},o)});const a=t.hasTreeStructure("combo")?t.getParent(n.id,"combo"):t.getParent(n.id);$t(a)||(e.hasNode(a.id)||e.addNode(Object.assign({},a)),e.setParent(n.id,a.id))})),t.getAllEdges().forEach((n=>{const r=db(t.getEdge(n.id).data),i={};null==Zy||Zy.forEach((t=>{void 0!==r[t]&&(i[t]=r[t])})),e.addEdge({id:n.id,source:n.source,target:n.target,data:Object.assign({},Ky,hb(r,Xy),i)})})),e},Jy=(t,e)=>{const{ranksep:n=0,rankdir:r}=e;return t.getAllNodes().forEach((t=>{isNaN(t.data.layer)||t.data.layer||(t.data.layer=0)})),t.getAllEdges().forEach((t=>{var e;t.data.minlen*=2,"c"!==(null===(e=t.data.labelpos)||void 0===e?void 0:e.toLowerCase())&&("TB"===r||"BT"===r?t.data.width+=t.data.labeloffset:t.data.height+=t.data.labeloffset)})),n/2},tb=t=>{t.getAllEdges().forEach((e=>{if(e.data.width&&e.data.height){const n=t.getNode(e.source),r={e:e,rank:(t.getNode(e.target).data.rank-n.data.rank)/2+n.data.rank};Rm(t,"edge-proxy",r,"_ep")}}))},eb=t=>{let e=0;return t.getAllNodes().forEach((n=>{var r,i;n.data.borderTop&&(n.data.minRank=null===(r=t.getNode(n.data.borderTop))||void 0===r?void 0:r.data.rank,n.data.maxRank=null===(i=t.getNode(n.data.borderBottom))||void 0===i?void 0:i.data.rank,e=Math.max(e,n.data.maxRank||-1/0))})),e},nb=t=>{t.getAllNodes().forEach((e=>{"edge-proxy"===e.data.dummy&&(t.getEdge(e.data.e.id).data.labelRank=e.data.rank,t.removeNode(e.id))}))},rb=(t,e)=>{let n,r,i=0,o=0;const{marginx:a=0,marginy:s=0}={},l=t=>{if(!t.data)return;const e=t.data.x,a=t.data.y,s=t.data.width,l=t.data.height;isNaN(e)||isNaN(s)||(void 0===n&&(n=e-s/2),n=Math.min(n,e-s/2),i=Math.max(i,e+s/2)),isNaN(a)||isNaN(l)||(void 0===r&&(r=a-l/2),r=Math.min(r,a-l/2),o=Math.max(o,a+l/2))};return t.getAllNodes().forEach((t=>{l(t)})),t.getAllEdges().forEach((t=>{(null==t?void 0:t.data.hasOwnProperty("x"))&&l(t)})),n-=a,r-=s,t.getAllNodes().forEach((t=>{t.data.x-=n,t.data.y-=r})),t.getAllEdges().forEach((t=>{var e;null===(e=t.data.points)||void 0===e||e.forEach((t=>{t.x-=n,t.y-=r})),t.data.hasOwnProperty("x")&&(t.data.x-=n),t.data.hasOwnProperty("y")&&(t.data.y-=r)})),{width:i-n+a,height:o-r+s}},ib=t=>{t.getAllEdges().forEach((e=>{const n=t.getNode(e.source),r=t.getNode(e.target);let i,o;e.data.points?(i=e.data.points[0],o=e.data.points[e.data.points.length-1]):(e.data.points=[],i={x:r.data.x,y:r.data.y},o={x:n.data.x,y:n.data.y}),e.data.points.unshift(Lm(n.data,i)),e.data.points.push(Lm(r.data,o))}))},ob=t=>{t.getAllEdges().forEach((t=>{if(t.data.hasOwnProperty("x"))switch("l"!==t.data.labelpos&&"r"!==t.data.labelpos||(t.data.width-=t.data.labeloffset),t.data.labelpos){case"l":t.data.x-=t.data.width/2+t.data.labeloffset;break;case"r":t.data.x+=t.data.width/2+t.data.labeloffset}}))},ab=t=>{t.getAllEdges().forEach((t=>{var e;t.data.reversed&&(null===(e=t.data.points)||void 0===e||e.reverse())}))},sb=t=>{t.getAllNodes().forEach((e=>{var n,r,i;if(null===(n=t.getChildren(e.id))||void 0===n?void 0:n.length){const n=t.getNode(e.id),o=t.getNode(n.data.borderTop),a=t.getNode(n.data.borderBottom),s=t.getNode(n.data.borderLeft[(null===(r=n.data.borderLeft)||void 0===r?void 0:r.length)-1]),l=t.getNode(n.data.borderRight[(null===(i=n.data.borderRight)||void 0===i?void 0:i.length)-1]);n.data.width=Math.abs((null==l?void 0:l.data.x)-(null==s?void 0:s.data.x))||10,n.data.height=Math.abs((null==a?void 0:a.data.y)-(null==o?void 0:o.data.y))||10,n.data.x=((null==s?void 0:s.data.x)||0)+n.data.width/2,n.data.y=((null==o?void 0:o.data.y)||0)+n.data.height/2}})),t.getAllNodes().forEach((e=>{"border"===e.data.dummy&&t.removeNode(e.id)}))},lb=t=>{t.getAllEdges().forEach((e=>{if(e.source===e.target){const n=t.getNode(e.source);n.data.selfEdges||(n.data.selfEdges=[]),n.data.selfEdges.push(e),t.removeEdge(e.id)}}))},ub=t=>{const e=_m(t);null==e||e.forEach((e=>{let n=0;null==e||e.forEach(((e,r)=>{var i;const o=t.getNode(e);o.data.order=r+n,null===(i=o.data.selfEdges)||void 0===i||i.forEach((e=>{Rm(t,"selfedge",{width:e.data.width,height:e.data.height,rank:o.data.rank,order:r+ ++n,e:e},"_se")})),delete o.data.selfEdges}))}))},cb=t=>{t.getAllNodes().forEach((e=>{const n=t.getNode(e.id);if("selfedge"===n.data.dummy){const r=t.getNode(n.data.e.source),i=r.data.x+r.data.width/2,o=r.data.y,a=n.data.x-i,s=r.data.height/2;t.hasEdge(n.data.e.id)?t.updateEdgeData(n.data.e.id,n.data.e.data):t.addEdge({id:n.data.e.id,source:n.data.e.source,target:n.data.e.target,data:n.data.e.data}),t.removeNode(e.id),n.data.e.data.points=[{x:i+2*a/3,y:o-s},{x:i+5*a/6,y:o-s},{y:o,x:i+a},{x:i+5*a/6,y:o+s},{x:i+2*a/3,y:o+s}],n.data.e.data.x=n.data.x,n.data.e.data.y=n.data.y}}))},hb=(t,e)=>{const n={};return null==e||e.forEach((e=>{void 0!==t[e]&&(n[e]=+t[e])})),n},db=(t={})=>{const e={};return Object.keys(t).forEach((n=>{e[n.toLowerCase()]=t[n]})),e},fb=Array.isArray,pb=t=>{const e=[],n=t.length;for(let r=0;re[r][t]+e[t][i]&&(e[r][i]=e[r][t]+e[t][i]);return e},gb=(t,e)=>{const{nodes:n,edges:r}=t,i=[],o={};if(!n)throw new Error("invalid nodes data!");return n&&n.forEach(((t,e)=>{o[t.id]=e;i.push([])})),null==r||r.forEach((t=>{const{source:e,target:n}=t,r=o[e],a=o[n];void 0!==r&&void 0!==a&&(i[r][a]=1,i[a][r]=1)})),i},vb=(t,e)=>Math.sqrt((t.x-e.x)*(t.x-e.x)+(t.y-e.y)*(t.y-e.y)),mb=(t,e,n,r="TB",i,o={})=>{if(!(null==e?void 0:e.length))return;const{stopBranchFn:a,stopAllFn:s}=o;for(let l=0;l{if(null===t)return t;if(t instanceof Date)return new Date(t.getTime());if(t instanceof Array){const e=[];return t.forEach((t=>{e.push(t)})),e.map((t=>yb(t)))}if("object"==typeof t){const e={};return Object.keys(t).forEach((n=>{e[n]=yb(t[n])})),e}return t},bb=(t,e)=>{const n=yb(t);return n.data=n.data||{},e&&(ae(n.data.x)||(n.data.x=Math.random()*e[0]),ae(n.data.y)||(n.data.y=Math.random()*e[1])),n};function xb(t){if(!t)return[0,0,0];if(ae(t))return[t,t,t];if(0===t.length)return[0,0,0];const[e,n=e,r=e]=t;return[e,n,r]}function Eb(t,e){let n;return n=Ut(e)?e:ae(e)?()=>e:()=>t,n}function wb(t,e,n=!0){return e||0===e?Ut(e)?e:ae(e)?()=>e:Array.isArray(e)?()=>n?Math.max(...e)||t:e:qt(e)&&e.width&&e.height?()=>n?Math.max(e.width,e.height)||t:[e.width,e.height]:()=>t:e=>{const{size:r}=e.data||{};return r?Array.isArray(r)?n?Math.max(...r)||t:r:qt(r)&&r.width&&r.height?n?Math.max(r.width,r.height)||t:[r.width,r.height]:r:t}}const kb=(t,e,n=10)=>{let r;const i="function"==typeof e?e:()=>e||0;r=t?Array.isArray(t)?e=>t:Ut(t)?t:e=>t:t=>{var e,r,i;if(null===(e=t.data)||void 0===e?void 0:e.bboxSize)return null===(r=t.data)||void 0===r?void 0:r.bboxSize;if(null===(i=t.data)||void 0===i?void 0:i.size){const e=t.data.size;return Array.isArray(e)?e:qt(e)?[e.width,e.height]:e}return n};return t=>{const e=r(t),n=i(t);return Math.max(...xb(e))+n}},Mb={rankdir:"TB",nodesep:50,ranksep:50,edgeLabelSpace:!0,ranker:"tight-tree",controlPoints:!1,radial:!1,focusNode:null};class Sb{constructor(t={}){this.options=t,this.id="antv-dagre",this.options=Object.assign(Object.assign({},Mb),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericDagreLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericDagreLayout(!0,t,e)}))}genericDagreLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{nodeSize:i,align:o,rankdir:a="TB",ranksep:s,nodesep:l,ranksepFunc:u,nodesepFunc:c,edgeLabelSpace:h,ranker:d,nodeOrder:f,begin:p,controlPoints:g,radial:v,sortByCombo:m,preset:y}=r,b=new ev({tree:[]}),x=Eb(s||50,u),E=Eb(l||50,c);let w=E,k=x;"LR"!==a&&"RL"!==a||(w=x,k=E);const M=wb(10,i,!1),S=e.getAllNodes(),N=e.getAllEdges();let O;S.forEach((t=>{const e=xb(M(t)),n=k(t),r=w(t),i=e[0]+2*r,o=e[1]+2*n,a=t.data.layer;ae(a)?b.addNode({id:t.id,data:{width:i,height:o,layer:a}}):b.addNode({id:t.id,data:{width:i,height:o}})})),m&&(b.attachTreeStructure("combo"),S.forEach((t=>{const{parentId:e}=t.data;void 0!==e&&b.hasNode(e)&&b.setParent(t.id,e,"combo")}))),N.forEach((t=>{b.addEdge({id:t.id,source:t.source,target:t.target,data:{weight:t.data.weight||1}})})),(null==y?void 0:y.length)&&(O=new ev({nodes:y})),((t,e)=>{const{edgeLabelSpace:n,keepNodeOrder:r,prevGraph:i,rankdir:o,ranksep:a}=e;!r&&i&&Uy(t,i);const s=Qy(t);let l;n&&(e.ranksep=Jy(s,{rankdir:o,ranksep:a}));try{l=Hy(s,e)}catch(t){if("Not possible to find intersection inside of the rectangle"===t.message)return void console.error("The following error may be caused by improper layer setting, please make sure your manual layer setting does not violate the graph's structure:\n",t);throw t}$y(t,s)})(b,{prevGraph:O,edgeLabelSpace:h,keepNodeOrder:!!f,nodeOrder:f||[],acyclicer:"greedy",ranker:d,rankdir:a,nodesep:l,align:o});const T=[0,0];if(p){let t=1/0,e=1/0;b.getAllNodes().forEach((n=>{t>n.data.x&&(t=n.data.x),e>n.data.y&&(e=n.data.y)})),b.getAllEdges().forEach((n=>{var r;null===(r=n.data.points)||void 0===r||r.forEach((n=>{t>n.x&&(t=n.x),e>n.y&&(e=n.y)}))})),T[0]=p[0]-t,T[1]=p[1]-e}const C="LR"===a||"RL"===a;if(v);else{const t=new Set,e="BT"===a||"RL"===a?(t,e)=>e-t:(t,e)=>t-e;b.getAllNodes().forEach((e=>{e.data.x=e.data.x+T[0],e.data.y=e.data.y+T[1],t.add(C?e.data.x:e.data.y)}));const n=Array.from(t).sort(e),r=C?(t,e)=>t.x!==e.x:(t,e)=>t.y!==e.y,i=C?(t,e,n)=>{const r=Math.max(e.y,n.y),i=Math.min(e.y,n.y);return t.filter((t=>t.y<=r&&t.y>=i))}:(t,e,n)=>{const r=Math.max(e.x,n.x),i=Math.min(e.x,n.x);return t.filter((t=>t.x<=r&&t.x>=i))};b.getAllEdges().forEach(((t,e)=>{var o;h&&g&&"loop"!==t.data.type&&(t.data.controlPoints=Nb(null===(o=t.data.points)||void 0===o?void 0:o.map((({x:t,y:e})=>({x:t+T[0],y:e+T[1]}))),b.getNode(t.source),b.getNode(t.target),n,C,r,i))}))}let A=[];A=b.getAllNodes().map((t=>bb(t)));const P=b.getAllEdges();t&&(A.forEach((t=>{e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})})),P.forEach((t=>{e.mergeEdgeData(t.id,{controlPoints:t.data.controlPoints})})));return{nodes:A,edges:P}}))}}const Nb=(t,e,n,r,i,o,a)=>{let s=(null==t?void 0:t.slice(1,t.length-1))||[];if(e&&n){let{x:t,y:l}=e.data,{x:u,y:c}=n.data;if(i&&(t=e.data.y,l=e.data.x,u=n.data.y,c=n.data.x),c!==l&&t!==u){const h=r.indexOf(l),d=r[h+1];if(d){const t=s[0],e=i?{x:(l+d)/2,y:(null==t?void 0:t.y)||u}:{x:(null==t?void 0:t.x)||u,y:(l+d)/2};t&&!o(t,e)||s.unshift(e)}const f=r.indexOf(c),p=Math.abs(f-h);if(1===p)s=a(s,e.data,n.data),s.length||s.push(i?{x:(l+c)/2,y:t}:{x:t,y:(l+c)/2});else if(p>1){const e=r[f-1];if(e){const n=s[s.length-1],r=i?{x:(c+e)/2,y:(null==n?void 0:n.y)||u}:{x:(null==n?void 0:n.x)||t,y:(c+e)/2};n&&!o(n,r)||s.push(r)}}}}return s},Ob=(t,e,n)=>{const r=t.getAllNodes(),i=t.getAllEdges();if(!(null==r?void 0:r.length)){return{nodes:[],edges:i}}if(1===r.length){e&&t.mergeNodeData(r[0].id,{x:n[0],y:n[1]});return{nodes:[Object.assign(Object.assign({},r[0]),{data:Object.assign(Object.assign({},r[0].data),{x:n[0],y:n[1]})})],edges:i}}},Tb={radius:null,startRadius:null,endRadius:null,startAngle:0,endAngle:2*Math.PI,clockwise:!0,divisions:1,ordering:null,angleRatio:1};class Cb{constructor(t={}){this.options=t,this.id="circular",this.options=Object.assign(Object.assign({},Tb),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericCircularLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericCircularLayout(!0,t,e)}))}genericCircularLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{width:i,height:o,center:a,divisions:s,startAngle:l=0,endAngle:u=2*Math.PI,angleRatio:c,ordering:h,clockwise:d,nodeSpacing:f,nodeSize:p}=r,g=e.getAllNodes(),v=e.getAllEdges(),[m,y,b]=Pb(i,o,a),x=null==g?void 0:g.length;if(!x||1===x)return Ob(e,t,b);const E=(u-l)/x;let{radius:w,startRadius:k,endRadius:M}=r;if(f){const t=Eb(10,f),e=wb(10,p);let n=-1/0;g.forEach((t=>{const r=e(t);n{r+=0===i?n||10:(t(e)||0)+(n||10)})),w=r/(2*Math.PI)}else w||k||M?!k&&M?k=M:k&&!M&&(M=k):w=Math.min(y,m)/2;const S=E*c;let N=[];N="topology"===h?Ab(e,g):"topology-directed"===h?Ab(e,g,!0):"degree"===h?function(t,e){const n=[];return e.forEach(((t,e)=>{n.push(bb(t))})),n.sort(((e,n)=>t.getDegree(e.id,"both")-t.getDegree(n.id,"both"))),n}(e,g):g.map((t=>bb(t)));const O=Math.ceil(x/s);for(let t=0;t{e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})}));return{nodes:N,edges:v}}))}}const Ab=(t,e,n=!1)=>{const r=[bb(e[0])],i={},o=e.length;i[e[0].id]=!0;let a=0;return e.forEach(((s,l)=>{if(0!==l)if(l!==o-1&&t.getDegree(s.id,"both")===t.getDegree(e[l+1].id,"both")&&!t.areNeighbors(r[a].id,s.id)||i[s.id]){const l=n?t.getSuccessors(r[a].id):t.getNeighbors(r[a].id);let u=!1;for(let e=0;e{let r=t,i=e,o=n;return r||"undefined"==typeof window||(r=window.innerWidth),i||"undefined"==typeof window||(i=window.innerHeight),o||(o=[r/2,i/2]),[r,i,o]},Rb={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:1.5*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"};class Db{constructor(t={}){this.options=t,this.id="concentric",this.options=Object.assign(Object.assign({},Rb),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericConcentricLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericConcentricLayout(!0,t,e)}))}genericConcentricLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{center:i,width:o,height:a,sortBy:s,maxLevelDiff:l,sweep:u,clockwise:c,equidistant:h,preventOverlap:d,startAngle:f=1.5*Math.PI,nodeSize:p,nodeSpacing:g}=r,v=e.getAllNodes(),m=e.getAllEdges(),y=o||"undefined"==typeof window?o:window.innerWidth,b=a||"undefined"==typeof window?a:window.innerHeight,x=i||[y/2,b/2];if(!(null==v?void 0:v.length)||1===v.length)return Ob(e,t,x);const E=[];let w,k=0;fb(p)?w=Math.max(p[0],p[1]):Ut(p)?(w=-1/0,v.forEach((t=>{const e=Math.max(...xb(p(t)));e>w&&(w=e)}))):w=p,fb(g)?k=Math.max(g[0],g[1]):ae(g)&&(k=g),v.forEach((t=>{const e=bb(t);E.push(e);let n=w;const{data:r}=e;fb(r.size)?n=Math.max(r.size[0],r.size[1]):ae(r.size)?n=r.size:qt(r.size)&&(n=Math.max(r.size.width,r.size.height)),w=Math.max(w,n),Ut(g)&&(k=Math.max(g(t),k))}));const M={};E.forEach(((t,e)=>{M[t.id]=e}));let S=s;ne(S)&&void 0!==E[0].data[S]||(S="degree"),"degree"===S?E.sort(((t,n)=>e.getDegree(n.id,"both")-e.getDegree(t.id,"both"))):E.sort(((t,e)=>e.data[S]-t.data[S]));const N=E[0],O=(l||("degree"===S?e.getDegree(N.id,"both"):N.data[S]))/4,T=[{nodes:[]}];let C=T[0];E.forEach((t=>{if(C.nodes.length>0){const n="degree"===S?Math.abs(e.getDegree(C.nodes[0].id,"both")-e.getDegree(t.id,"both")):Math.abs(C.nodes[0].data[S]-t.data[S]);O&&n>=O&&(C={nodes:[]},T.push(C))}C.nodes.push(t)}));let A=w+k;if(!d){const t=T.length>0&&T[0].nodes.length>1,e=(Math.min(y,b)/2-A)/(T.length+(t?1:0));A=Math.min(A,e)}let P=0;if(T.forEach((t=>{const e=void 0===u?2*Math.PI-2*Math.PI/t.nodes.length:u;if(t.dTheta=e/Math.max(1,t.nodes.length-1),t.nodes.length>1&&d){const e=Math.cos(t.dTheta)-Math.cos(0),n=Math.sin(t.dTheta)-Math.sin(0),r=Math.sqrt(A*A/(e*e+n*n));P=Math.max(r,P)}t.r=P,P+=A})),h){let t=0,e=0;for(let n=0;n{0===r&&(e=n.r||0),n.r=e,e+=t}))}T.forEach((t=>{const e=t.dTheta||0,n=t.r||0;t.nodes.forEach(((t,r)=>{const i=f+(c?1:-1)*e*r;t.data.x=x[0]+n*Math.cos(i),t.data.y=x[1]+n*Math.sin(i)}))})),t&&E.forEach((t=>e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})));return{nodes:E,edges:m}}))}}function Lb(t,e,n,r){if(isNaN(e)||isNaN(n))return t;var i,o,a,s,l,u,c,h,d,f=t._root,p={data:r},g=t._x0,v=t._y0,m=t._x1,y=t._y1;if(!f)return t._root=p,t;for(;f.length;)if((u=e>=(o=(g+m)/2))?g=o:m=o,(c=n>=(a=(v+y)/2))?v=a:y=a,i=f,!(f=f[h=c<<1|u]))return i[h]=p,t;if(s=+t._x.call(null,f.data),l=+t._y.call(null,f.data),e===s&&n===l)return p.next=f,i?i[h]=p:t._root=p,t;do{i=i?i[h]=new Array(4):t._root=new Array(4),(u=e>=(o=(g+m)/2))?g=o:m=o,(c=n>=(a=(v+y)/2))?v=a:y=a}while((h=c<<1|u)==(d=(l>=a)<<1|s>=o));return i[d]=f,i[h]=p,t}function _b(t,e,n,r,i){this.node=t,this.x0=e,this.y0=n,this.x1=r,this.y1=i}function Ib(t){return t[0]}function jb(t){return t[1]}function Bb(t,e,n){var r=new Fb(null==e?Ib:e,null==n?jb:n,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function Fb(t,e,n,r,i,o){this._x=t,this._y=e,this._x0=n,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function zb(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var Gb=Bb.prototype=Fb.prototype;function Vb(t,e,n,r,i){if(isNaN(e)||isNaN(n)||isNaN(r))return t;var o,a,s,l,u,c,h,d,f,p,g,v,m=t._root,y={data:i},b=t._x0,x=t._y0,E=t._z0,w=t._x1,k=t._y1,M=t._z1;if(!m)return t._root=y,t;for(;m.length;)if((d=e>=(a=(b+w)/2))?b=a:w=a,(f=n>=(s=(x+k)/2))?x=s:k=s,(p=r>=(l=(E+M)/2))?E=l:M=l,o=m,!(m=m[g=p<<2|f<<1|d]))return o[g]=y,t;if(u=+t._x.call(null,m.data),c=+t._y.call(null,m.data),h=+t._z.call(null,m.data),e===u&&n===c&&r===h)return y.next=m,o?o[g]=y:t._root=y,t;do{o=o?o[g]=new Array(8):t._root=new Array(8),(d=e>=(a=(b+w)/2))?b=a:w=a,(f=n>=(s=(x+k)/2))?x=s:k=s,(p=r>=(l=(E+M)/2))?E=l:M=l}while((g=p<<2|f<<1|d)==(v=(h>=l)<<2|(c>=s)<<1|u>=a));return o[v]=m,o[g]=y,t}function Wb(t,e,n,r,i,o,a){this.node=t,this.x0=e,this.y0=n,this.z0=r,this.x1=i,this.y1=o,this.z1=a}Gb.copy=function(){var t,e,n=new Fb(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=zb(r),n;for(t=[{source:r,target:n._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(e=r.source[i])&&(e.length?t.push({source:e,target:r.target[i]=new Array(4)}):r.target[i]=zb(e));return n},Gb.add=function(t){const e=+this._x.call(null,t),n=+this._y.call(null,t);return Lb(this.cover(e,n),e,n,t)},Gb.addAll=function(t){var e,n,r,i,o=t.length,a=new Array(o),s=new Array(o),l=1/0,u=1/0,c=-1/0,h=-1/0;for(n=0;nc&&(c=r),ih&&(h=i));if(l>c||u>h)return this;for(this.cover(l,u).cover(c,h),n=0;nt||t>=i||r>e||e>=o;)switch(s=(ed||(o=l.y0)>f||(a=l.x1)=m)<<1|t>=v)&&(l=p[p.length-1],p[p.length-1]=p[p.length-1-u],p[p.length-1-u]=l)}else{var y=t-+this._x.call(null,g.data),b=e-+this._y.call(null,g.data),x=y*y+b*b;if(x=(s=(p+v)/2))?p=s:v=s,(c=a>=(l=(g+m)/2))?g=l:m=l,e=f,!(f=f[h=c<<1|u]))return this;if(!f.length)break;(e[h+1&3]||e[h+2&3]||e[h+3&3])&&(n=e,d=h)}for(;f.data!==t;)if(r=f,!(f=f.next))return this;return(i=f.next)&&delete f.next,r?(i?r.next=i:delete r.next,this):e?(i?e[h]=i:delete e[h],(f=e[0]||e[1]||e[2]||e[3])&&f===(e[3]||e[2]||e[1]||e[0])&&!f.length&&(n?n[d]=f:this._root=f),this):(this._root=i,this)},Gb.removeAll=function(t){for(var e=0,n=t.length;eMath.sqrt((t-r)**2+(e-i)**2+(n-o)**2);function Ub(t){return t[0]}function $b(t){return t[1]}function Yb(t){return t[2]}function qb(t,e,n,r){var i=new Xb(null==e?Ub:e,null==n?$b:n,null==r?Yb:r,NaN,NaN,NaN,NaN,NaN,NaN);return null==t?i:i.addAll(t)}function Xb(t,e,n,r,i,o,a,s,l){this._x=t,this._y=e,this._z=n,this._x0=r,this._y0=i,this._z0=o,this._x1=a,this._y1=s,this._z1=l,this._root=void 0}function Kb(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var Zb=qb.prototype=Xb.prototype;Zb.copy=function(){var t,e,n=new Xb(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),r=this._root;if(!r)return n;if(!r.length)return n._root=Kb(r),n;for(t=[{source:r,target:n._root=new Array(8)}];r=t.pop();)for(var i=0;i<8;++i)(e=r.source[i])&&(e.length?t.push({source:e,target:r.target[i]=new Array(8)}):r.target[i]=Kb(e));return n},Zb.add=function(t){const e=+this._x.call(null,t),n=+this._y.call(null,t),r=+this._z.call(null,t);return Vb(this.cover(e,n,r),e,n,r,t)},Zb.addAll=function(t){Array.isArray(t)||(t=Array.from(t));const e=t.length,n=new Float64Array(e),r=new Float64Array(e),i=new Float64Array(e);let o=1/0,a=1/0,s=1/0,l=-1/0,u=-1/0,c=-1/0;for(let h,d,f,p,g=0;gl&&(l=d),fu&&(u=f),pc&&(c=p));if(o>l||a>u||s>c)return this;this.cover(o,a,s).cover(l,u,c);for(let o=0;ot||t>=a||i>e||e>=s||o>n||n>=l;)switch(c=(nv||(a=h.y0)>m||(s=h.z0)>y||(l=h.x1)=k)<<2|(e>=w)<<1|t>=E)&&(h=b[b.length-1],b[b.length-1]=b[b.length-1-d],b[b.length-1-d]=h)}else{var M=t-+this._x.call(null,x.data),S=e-+this._y.call(null,x.data),N=n-+this._z.call(null,x.data),O=M*M+S*S+N*N;if(O{if(!h.length)do{const o=h.data;Hb(t,e,n,this._x(o),this._y(o),this._z(o))<=r&&i.push(o)}while(h=h.next);return d>l||f>u||p>c||g=(l=(m+x)/2))?m=l:x=l,(d=a>=(u=(y+E)/2))?y=u:E=u,(f=s>=(c=(b+w)/2))?b=c:w=c,e=v,!(v=v[p=f<<2|d<<1|h]))return this;if(!v.length)break;(e[p+1&7]||e[p+2&7]||e[p+3&7]||e[p+4&7]||e[p+5&7]||e[p+6&7]||e[p+7&7])&&(n=e,g=p)}for(;v.data!==t;)if(r=v,!(v=v.next))return this;return(i=v.next)&&delete v.next,r?(i?r.next=i:delete r.next,this):e?(i?e[p]=i:delete e[p],(v=e[0]||e[1]||e[2]||e[3]||e[4]||e[5]||e[6]||e[7])&&v===(e[7]||e[6]||e[5]||e[4]||e[3]||e[2]||e[1]||e[0])&&!v.length&&(n?n[g]=v:this._root=v),this):(this._root=i,this)},Zb.removeAll=function(t){for(var e=0,n=t.length;e{const{nodeStrength:n,x:r,y:i,z:a,size:s}=t.data;return{x:r,y:i,z:a,size:s,index:e,id:t.id,vx:0,vy:0,vz:0,weight:o*n}})),l=(2===i?Bb(s,(t=>t.x),(t=>t.y)):qb(s,(t=>t.x),(t=>t.y),(t=>t.z))).visitAfter(Jb),u=new Map;return s.forEach((t=>{u.set(t.id,t),function(t,e,n){e.visit(((e,r,i,o,a)=>tx(e,r,i,o,a,t,n)))}(t,l,i)})),s.map(((t,e)=>{const{id:n,data:i}=a[e],{mass:o=1}=i;r[n]={x:t.vx/o,y:t.vy/o,z:t.vz/o}})),r}function Jb(t){let e=0,n=0,r=0,i=0,o=0;const a=t.length;if(a){for(let s=0;s{var s;if((null===(s=t.data)||void 0===s?void 0:s.id)===o.id)return;const l=[n,r,i][a-1],u=o.x-t.x||.1,c=o.y-t.y||.1,h=o.z-t.z||.1,d=[u,c,h],f=l-e;let p=0;for(let t=0;tthis.lastOptions.minMovement||e<1)&&ethis.lastGraph.mergeNodeData(t.id,{x:t.data.x,y:t.data.y,z:3===this.options.dimensions?t.data.z:void 0}))),e}genericForceLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),i=e.getAllNodes(),o=e.getAllEdges(),a=this.formatOptions(r,e),{dimensions:s,width:l,height:u,nodeSize:c,getMass:h,nodeStrength:d,edgeStrength:f,linkDistance:p}=a,g=i.map(((t,e)=>Object.assign(Object.assign({},t),{data:Object.assign(Object.assign({},t.data),{x:ae(t.data.x)?t.data.x:Math.random()*l,y:ae(t.data.y)?t.data.y:Math.random()*u,z:ae(t.data.z)?t.data.z:Math.random()*Math.sqrt(l*u),size:c(t)||30,mass:h(t),nodeStrength:d(t)})}))),v=o.map((t=>Object.assign(Object.assign({},t),{data:Object.assign(Object.assign({},t.data),{edgeStrength:f(t),linkDistance:p(t,e.getNode(t.source),e.getNode(t.target))})})));if(!(null==i?void 0:i.length))return this.lastResult={nodes:[],edges:o},{nodes:[],edges:o};const m={};i.forEach(((t,e)=>{m[t.id]={x:0,y:0,z:0}}));const y=new ev({nodes:g,edges:v});this.formatCentripetal(a,y);const{maxIteration:b,minMovement:x,onTick:E}=a;if(this.lastLayoutNodes=g,this.lastLayoutEdges=v,this.lastAssign=t,this.lastGraph=e,this.lastCalcGraph=y,this.lastOptions=a,this.lastVelMap=m,"undefined"==typeof window)return;let w=0;return new Promise((n=>{this.timeInterval=window.setInterval((()=>{i&&this.running||n({nodes:sx(e,g),edges:o}),this.runOneStep(y,e,w,m,a),this.updatePosition(e,y,m,a),t&&g.forEach((t=>e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y,z:3===s?t.data.z:void 0}))),null==E||E({nodes:sx(e,g),edges:o}),w++,(w>=b||this.judgingDistance{let n=1;ae(null==t?void 0:t.data.mass)&&(n=null==t?void 0:t.data.mass);const r=e.getDegree(t.id,"both");return!r||r<5?n:5*r*n}),n.nodeSize=kb(t.nodeSize,t.nodeSpacing);const a=t.linkDistance?Eb(1,t.linkDistance):t=>1+n.nodeSize(e.getNode(t.source))+n.nodeSize(e.getNode(t.target));return n.linkDistance=a,n.nodeStrength=Eb(1,t.nodeStrength),n.edgeStrength=Eb(1,t.edgeStrength),n}formatCentripetal(t,e){const{dimensions:n,centripetalOptions:r,center:i,clusterNodeStrength:o,leafCluster:a,clustering:s,nodeClusterBy:l}=t,u=e.getAllNodes(),c=r||{leaf:2,single:2,others:1,center:t=>({x:i[0],y:i[1],z:3===n?i[2]:void 0})};let h,d;if("function"!=typeof o&&(t.clusterNodeStrength=t=>o),a&&l&&(h=rx(e,l),d=Array.from(new Set(null==u?void 0:u.map((t=>t.data[l]))))||[],t.centripetalOptions=Object.assign(c,{single:100,leaf:e=>{const{siblingLeaves:n,sameTypeLeaves:r}=h[e.id]||{};return(null==r?void 0:r.length)===(null==n?void 0:n.length)||1===(null==d?void 0:d.length)?1:t.clusterNodeStrength(e)},others:1,center:t=>{const n=e.getDegree(t.id,"both");if(!n)return{x:100,y:100,z:0};let r;if(1===n){const{sameTypeLeaves:e=[]}=h[t.id]||{};1===e.length?r=void 0:e.length>1&&(r=ax(e))}else r=void 0;return{x:null==r?void 0:r.x,y:null==r?void 0:r.y,z:null==r?void 0:r.z}}})),s&&l){h||(h=rx(e,l)),d||(d=Array.from(new Set(u.map((t=>t.data[l]))))),d=d.filter((t=>void 0!==t));const n={};d.forEach((t=>{const r=u.filter((e=>e.data[l]===t)).map((t=>e.getNode(t.id)));n[t]=ax(r)})),t.centripetalOptions=Object.assign(c,{single:e=>t.clusterNodeStrength(e),leaf:e=>t.clusterNodeStrength(e),others:e=>t.clusterNodeStrength(e),center:t=>{const e=n[t.data[l]];return{x:null==e?void 0:e.x,y:null==e?void 0:e.y,z:null==e?void 0:e.z}}})}const{leaf:f,single:p,others:g}=t.centripetalOptions||{};f&&"function"!=typeof f&&(t.centripetalOptions.leaf=()=>f),p&&"function"!=typeof p&&(t.centripetalOptions.single=()=>p),g&&"function"!=typeof g&&(t.centripetalOptions.others=()=>g)}runOneStep(t,e,n,r,i){const o={},a=t.getAllNodes(),s=t.getAllEdges();if(!(null==a?void 0:a.length))return;const{monitor:l}=i;if(this.calRepulsive(t,o,i),s&&this.calAttractive(t,o,i),this.calGravity(t,e,o,i),this.updateVelocity(t,o,r,i),l){l({energy:this.calTotalEnergy(o,a),nodes:e.getAllNodes(),edges:e.getAllEdges(),iterations:n})}}calTotalEnergy(t,e){if(!(null==e?void 0:e.length))return 0;let n=0;return e.forEach(((e,r)=>{const i=t[e.id].x,o=t[e.id].y,a=3===this.options.dimensions?t[e.id].z:0,s=i*i+o*o+a*a,{mass:l=1}=e.data;n+=l*s*.5})),n}calRepulsive(t,e,n){const{dimensions:r,factor:i,coulombDisScale:o}=n;Qb(t,i,o*o,e,r)}calAttractive(t,e,n){const{dimensions:r,nodeSize:i}=n;t.getAllEdges().forEach(((n,o)=>{const{source:a,target:s}=n,l=t.getNode(a),u=t.getNode(s);if(!l||!u)return;let c=u.data.x-l.data.x,h=u.data.y-l.data.y,d=3===r?u.data.z-l.data.z:0;c||h||(c=.01*Math.random(),h=.01*Math.random(),3!==r||d||(d=.01*Math.random()));const f=Math.sqrt(c*c+h*h+d*d);if(f{const{id:o,data:f}=r,{mass:p,x:g,y:v,z:m}=f,y=e.getNode(o);let b=0,x=0,E=0,w=h;const k=t.getDegree(o,"in"),M=t.getDegree(o,"out"),S=t.getDegree(o,"both"),N=null==i?void 0:i(y,S);if(N){const[t,e,n]=N;b=g-t,x=v-e,w=n}else b=g-c[0],x=v-c[1],E=m-c[2];if(w&&(n[o].x-=w*b/p,n[o].y-=w*x/p,n[o].z-=w*E/p),d){const{leaf:t,single:e,others:r,center:i}=d,{x:c,y:h,z:f,centerStrength:b}=(null==i?void 0:i(y,a,s,l,u))||{x:0,y:0,z:0,centerStrength:0};if(!ae(c)||!ae(h))return;const x=(g-c)/p,E=(v-h)/p,w=(m-f)/p;if(b&&(n[o].x-=b*x,n[o].y-=b*E,n[o].z-=b*w),0===S){const t=e(y);if(!t)return;return n[o].x-=t*x,n[o].y-=t*E,void(n[o].z-=t*w)}if(0===k||0===M){const e=t(y,a,s);if(!e)return;return n[o].x-=e*x,n[o].y-=e*E,void(n[o].z-=e*w)}const N=r(y);if(!N)return;n[o].x-=N*x,n[o].y-=N*E,n[o].z-=N*w}}))}updateVelocity(t,e,n,r){const{damping:i,maxSpeed:o,interval:a,dimensions:s}=r,l=t.getAllNodes();(null==l?void 0:l.length)&&l.forEach((t=>{const{id:r}=t;let l=(n[r].x+e[r].x*a)*i||.01,u=(n[r].y+e[r].y*a)*i||.01,c=3===s?(n[r].z+e[r].z*a)*i||.01:0;const h=Math.sqrt(l*l+u*u+c*c);if(h>o){const t=o/h;l*=t,u*=t,c*=t}n[r]={x:l,y:u,z:c}}))}updatePosition(t,e,n,r){const{distanceThresholdMode:i,interval:o,dimensions:a}=r,s=e.getAllNodes();if(!(null==s?void 0:s.length))return void(this.judgingDistance=0);let l=0;"max"===i?this.judgingDistance=-1/0:"min"===i&&(this.judgingDistance=1/0),s.forEach((r=>{const{id:s}=r,u=t.getNode(s);if(ae(u.data.fx)&&ae(u.data.fy))return void e.mergeNodeData(s,{x:u.data.fx,y:u.data.fy,z:3===a?u.data.fz:void 0});const c=n[s].x*o,h=n[s].y*o,d=3===a?n[s].z*o:0;e.mergeNodeData(s,{x:r.data.x+c,y:r.data.y+h,z:r.data.z+d});const f=Math.sqrt(c*c+h*h+d*d);switch(i){case"max":this.judgingDistancef&&(this.judgingDistance=f);break;default:l+=f}})),i&&"mean"!==i||(this.judgingDistance=l/s.length)}}const rx=(t,e)=>{const n=t.getAllNodes();if(!(null==n?void 0:n.length))return{};const r={};return n.forEach(((n,i)=>{1===t.getDegree(n.id,"both")&&(r[n.id]=ix(t,"leaf",n,e))})),r},ix=(t,e,n,r)=>{const i=t.getDegree(n.id,"in"),o=t.getDegree(n.id,"out");let a=n,s=[];0===i?(a=t.getSuccessors(n.id)[0],s=t.getNeighbors(a.id)):0===o&&(a=t.getPredecessors(n.id)[0],s=t.getNeighbors(a.id)),s=s.filter((e=>0===t.getDegree(e.id,"in")||0===t.getDegree(e.id,"out")));return{coreNode:a,siblingLeaves:s,sameTypeLeaves:ox(t,e,r,n,s)}},ox=(t,e,n,r,i)=>{const o=r.data[n]||"";let a=(null==i?void 0:i.filter((t=>t.data[n]===o)))||[];return a=a.filter((e=>0===t.getDegree(e.id,"in")||0===t.getDegree(e.id,"out"))),a},ax=t=>{const e={x:0,y:0};t.forEach((t=>{const{x:n,y:r}=t.data;e.x+=n||0,e.y+=r||0}));const n=t.length||1;return{x:e.x/n,y:e.y/n}},sx=(t,e)=>e.map((e=>{const{id:n,data:r}=e,i=t.getNode(n);return Object.assign(Object.assign({},i),{data:Object.assign(Object.assign({},i.data),{x:r.x,y:r.y,z:r.z})})}));var lx={};const ux=Object.prototype.toString;function cx(t){const e=ux.call(t);return e.endsWith("Array]")&&!e.includes("Big")}var hx=w(Object.freeze({__proto__:null,isAnyArray:cx}));var dx=Object.freeze({__proto__:null,default:function(t){var e,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!cx(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");if(void 0!==n.output){if(!cx(n.output))throw new TypeError("output option must be an array if specified");e=n.output}else e=new Array(t.length);var r=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!cx(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");var n=e.fromIndex,r=void 0===n?0:n,i=e.toIndex,o=void 0===i?t.length:i;if(r<0||r>=t.length||!Number.isInteger(r))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=r||o>t.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=t[r],s=r+1;s1&&void 0!==arguments[1]?arguments[1]:{};if(!cx(t))throw new TypeError("input must be an array");if(0===t.length)throw new TypeError("input must not be empty");var n=e.fromIndex,r=void 0===n?0:n,i=e.toIndex,o=void 0===i?t.length:i;if(r<0||r>=t.length||!Number.isInteger(r))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=r||o>t.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=t[r],s=r+1;sa&&(a=t[s]);return a}(t);if(r===i)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var o=n.min,a=void 0===o?n.autoMinMax?r:0:o,s=n.max,l=void 0===s?n.autoMinMax?i:1:s;if(a>=l)throw new RangeError("min option must be smaller than max option");for(var u=(l-a)/(i-r),c=0;c=0&&n?` ${xx(t,e-1)}`:xx(t,e)).padEnd(e)}function xx(t,e){let n=t.toString();if(n.length<=e)return n;let r=t.toFixed(e);if(r.length>e&&(r=t.toFixed(Math.max(0,e-(r.length-e)))),r.length<=e&&!r.startsWith("0.000")&&!r.startsWith("-0.000"))return r;let i=t.toExponential(e);return i.length>e&&(i=t.toExponential(Math.max(0,e-(i.length-e)))),i.slice(0)}function Ex(t,e,n){let r=n?t.rows:t.rows-1;if(e<0||e>r)throw new RangeError("Row index out of range")}function wx(t,e,n){let r=n?t.columns:t.columns-1;if(e<0||e>r)throw new RangeError("Column index out of range")}function kx(t,e){if(e.to1DArray&&(e=e.to1DArray()),e.length!==t.columns)throw new RangeError("vector size must be the same as the number of columns");return e}function Mx(t,e){if(e.to1DArray&&(e=e.to1DArray()),e.length!==t.rows)throw new RangeError("vector size must be the same as the number of rows");return e}function Sx(t,e){if(!px.isAnyArray(e))throw new TypeError("row indices must be an array");for(let n=0;n=t.rows)throw new RangeError("row indices are out of range")}function Nx(t,e){if(!px.isAnyArray(e))throw new TypeError("column indices must be an array");for(let n=0;n=t.columns)throw new RangeError("column indices are out of range")}function Ox(t,e,n,r,i){if(5!==arguments.length)throw new RangeError("expected 4 arguments");if(Cx("startRow",e),Cx("endRow",n),Cx("startColumn",r),Cx("endColumn",i),e>n||r>i||e<0||e>=t.rows||n<0||n>=t.rows||r<0||r>=t.columns||i<0||i>=t.columns)throw new RangeError("Submatrix indices are out of range")}function Tx(t,e=0){let n=[];for(let r=0;r=i)throw new RangeError("min must be smaller than max");let a=i-r,s=new Dx(t,e);for(let n=0;nn?(i=!0,n=e):(r=!1,i=!0);t++}return r}isReducedEchelonForm(){let t=0,e=0,n=-1,r=!0,i=!1;for(;tn?(i=!0,n=e):(r=!1,i=!0);for(let n=e+1;nt.get(r,n)&&(r=i);if(0===t.get(r,n))n++;else{t.swapRows(e,r);let i=t.get(e,n);for(let r=n;r=0;)if(0===t.maxRow(r))r--;else{let i=0,o=!1;for(;it[e]&&(t[e]=this.get(e,n));return t}case"column":{const t=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let e=0;et[n]&&(t[n]=this.get(e,n));return t}case void 0:{let t=this.get(0,0);for(let e=0;et&&(t=this.get(e,n));return t}default:throw new Error(`invalid option: ${t}`)}}maxIndex(){Ax(this);let t=this.get(0,0),e=[0,0];for(let n=0;nt&&(t=this.get(n,r),e[0]=n,e[1]=r);return e}min(t){if(this.isEmpty())return NaN;switch(t){case"row":{const t=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let e=0;ee&&(e=this.get(t,n));return e}maxRowIndex(t){Ex(this,t),Ax(this);let e=this.get(t,0),n=[t,0];for(let r=1;re&&(e=this.get(t,r),n[1]=r);return n}minRow(t){if(Ex(this,t),this.isEmpty())return NaN;let e=this.get(t,0);for(let n=1;ne&&(e=this.get(n,t));return e}maxColumnIndex(t){wx(this,t),Ax(this);let e=this.get(0,t),n=[0,t];for(let r=1;re&&(e=this.get(r,t),n[0]=r);return n}minColumn(t){if(wx(this,t),this.isEmpty())return NaN;let e=this.get(0,t);for(let n=1;n=1;r/=2)1&r&&(e=e.mmul(n)),n=n.mmul(n);return e}strassen2x2(t){t=Dx.checkMatrix(t);let e=new Dx(2,2);const n=this.get(0,0),r=t.get(0,0),i=this.get(0,1),o=t.get(0,1),a=this.get(1,0),s=t.get(1,0),l=this.get(1,1),u=t.get(1,1),c=(n+l)*(r+u),h=(a+l)*r,d=n*(o-u),f=l*(s-r),p=(n+i)*u,g=c+f-p+(i-l)*(s+u),v=d+p,m=h+f,y=c-h+d+(a-n)*(r+o);return e.set(0,0,g),e.set(0,1,v),e.set(1,0,m),e.set(1,1,y),e}strassen3x3(t){t=Dx.checkMatrix(t);let e=new Dx(3,3);const n=this.get(0,0),r=this.get(0,1),i=this.get(0,2),o=this.get(1,0),a=this.get(1,1),s=this.get(1,2),l=this.get(2,0),u=this.get(2,1),c=this.get(2,2),h=t.get(0,0),d=t.get(0,1),f=t.get(0,2),p=t.get(1,0),g=t.get(1,1),v=t.get(1,2),m=t.get(2,0),y=t.get(2,1),b=t.get(2,2),x=(n-o)*(-d+g),E=(-n+o+a)*(h-d+g),w=(o+a)*(-h+d),k=n*h,M=(-n+l+u)*(h-f+v),S=(-n+l)*(f-v),N=(l+u)*(-h+f),O=(-i+u+c)*(g+m-y),T=(i-c)*(g-y),C=i*m,A=(u+c)*(-m+y),P=(-i+a+s)*(v+m-b),R=(i-s)*(v-b),D=(a+s)*(-m+b),L=k+C+r*p,_=(n+r+i-o-a-u-c)*g+E+w+k+O+C+A,I=k+M+N+(n+r+i-a-s-l-u)*v+C+P+D,j=x+a*(-h+d+p-g-v-m+b)+E+k+C+P+R,B=x+E+w+k+s*y,F=C+P+R+D+o*f,z=k+M+S+u*(-h+f+p-g-v-m+y)+O+T+C,G=O+T+C+A+l*d,V=k+M+S+N+c*b;return e.set(0,0,L),e.set(0,1,_),e.set(0,2,I),e.set(1,0,j),e.set(1,1,B),e.set(1,2,F),e.set(2,0,z),e.set(2,1,G),e.set(2,2,V),e}mmulStrassen(t){t=Dx.checkMatrix(t);let e=this.clone(),n=e.rows,r=e.columns,i=t.rows,o=t.columns;function a(t,e,n){let r=t.rows,i=t.columns;if(r===e&&i===n)return t;{let r=Px.zeros(e,n);return r=r.setSubMatrix(t,0,0),r}}r!==i&&console.warn(`Multiplying ${n} x ${r} and ${i} x ${o} matrix: dimensions do not match.`);let s=Math.max(n,i),l=Math.max(r,o);return e=a(e,s,l),function t(e,n,r,i){if(r<=512||i<=512)return e.mmul(n);r%2==1&&i%2==1?(e=a(e,r+1,i+1),n=a(n,r+1,i+1)):r%2==1?(e=a(e,r+1,i),n=a(n,r+1,i)):i%2==1&&(e=a(e,r,i+1),n=a(n,r,i+1));let o=parseInt(e.rows/2,10),s=parseInt(e.columns/2,10),l=e.subMatrix(0,o-1,0,s-1),u=n.subMatrix(0,o-1,0,s-1),c=e.subMatrix(0,o-1,s,e.columns-1),h=n.subMatrix(0,o-1,s,n.columns-1),d=e.subMatrix(o,e.rows-1,0,s-1),f=n.subMatrix(o,n.rows-1,0,s-1),p=e.subMatrix(o,e.rows-1,s,e.columns-1),g=n.subMatrix(o,n.rows-1,s,n.columns-1),v=t(Px.add(l,p),Px.add(u,g),o,s),m=t(Px.add(d,p),u,o,s),y=t(l,Px.sub(h,g),o,s),b=t(p,Px.sub(f,u),o,s),x=t(Px.add(l,c),g,o,s),E=t(Px.sub(d,l),Px.add(u,h),o,s),w=t(Px.sub(c,p),Px.add(f,g),o,s),k=Px.add(v,b);k.sub(x),k.add(w);let M=Px.add(y,x),S=Px.add(m,b),N=Px.sub(v,m);N.add(y),N.add(E);let O=Px.zeros(2*k.rows,2*k.columns);return O=O.setSubMatrix(k,0,0),O=O.setSubMatrix(M,k.rows,0),O=O.setSubMatrix(S,0,k.columns),O=O.setSubMatrix(N,k.rows,k.columns),O.subMatrix(0,r-1,0,i-1)}(e,t=a(t,s,l),s,l)}scaleRows(t={}){if("object"!=typeof t)throw new TypeError("options must be an object");const{min:e=0,max:n=1}=t;if(!Number.isFinite(e))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(e>=n)throw new RangeError("min must be smaller than max");let r=new Dx(this.rows,this.columns);for(let t=0;t0&&gx(i,{min:e,max:n,output:i}),r.setRow(t,i)}return r}scaleColumns(t={}){if("object"!=typeof t)throw new TypeError("options must be an object");const{min:e=0,max:n=1}=t;if(!Number.isFinite(e))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(e>=n)throw new RangeError("min must be smaller than max");let r=new Dx(this.rows,this.columns);for(let t=0;tn||e<0||e>=this.columns||n<0||n>=this.columns)throw new RangeError("Argument out of range");let r=new Dx(t.length,n-e+1);for(let i=0;i=this.rows)throw new RangeError(`Row index out of range: ${t[i]}`);r.set(i,o-e,this.get(t[i],o))}return r}subMatrixColumn(t,e,n){if(void 0===e&&(e=0),void 0===n&&(n=this.rows-1),e>n||e<0||e>=this.rows||n<0||n>=this.rows)throw new RangeError("Argument out of range");let r=new Dx(n-e+1,t.length);for(let i=0;i=this.columns)throw new RangeError(`Column index out of range: ${t[i]}`);r.set(o-e,i,this.get(o,t[i]))}return r}setSubMatrix(t,e,n){if((t=Dx.checkMatrix(t)).isEmpty())return this;Ox(this,e,e+t.rows-1,n,n+t.columns-1);for(let r=0;r=0))throw new TypeError("nColumns must be a positive integer");for(let n=0;n=0)this.#t(e,n);else{if(!px.isAnyArray(e))throw new TypeError("First argument must be a positive number or an array");{const t=e;if("number"!=typeof(n=(e=t.length)?t[0].length:0))throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let r=0;r"number"==typeof t)))throw new TypeError("Input data contains non-numeric values");this.data.push(Float64Array.from(t[r]))}this.rows=e,this.columns=n}}}set(t,e,n){return this.data[t][e]=n,this}get(t,e){return this.data[t][e]}removeRow(t){return Ex(this,t),this.data.splice(t,1),this.rows-=1,this}addRow(t,e){return void 0===e&&(e=t,t=this.rows),Ex(this,t,!0),e=Float64Array.from(kx(this,e)),this.data.splice(t,0,e),this.rows+=1,this}removeColumn(t){wx(this,t);for(let e=0;e>t);return this},t.prototype.signPropagatingRightShiftM=function(t){if(t=e.checkMatrix(t),this.rows!==t.rows||this.columns!==t.columns)throw new RangeError("Matrices dimensions must be equal");for(let e=0;e>t.get(e,n));return this},t.signPropagatingRightShift=function(t,n){return new e(t).signPropagatingRightShift(n)},t.prototype.rightShift=function(t){return"number"==typeof t?this.rightShiftS(t):this.rightShiftM(t)},t.prototype.rightShiftS=function(t){for(let e=0;e>>t);return this},t.prototype.rightShiftM=function(t){if(t=e.checkMatrix(t),this.rows!==t.rows||this.columns!==t.columns)throw new RangeError("Matrices dimensions must be equal");for(let e=0;e>>t.get(e,n));return this},t.rightShift=function(t,n){return new e(t).rightShift(n)},t.prototype.zeroFillRightShift=t.prototype.rightShift,t.prototype.zeroFillRightShiftS=t.prototype.rightShiftS,t.prototype.zeroFillRightShiftM=t.prototype.rightShiftM,t.zeroFillRightShift=t.rightShift,t.prototype.not=function(){for(let t=0;t=0)this.#e=new Dx(t,t);else if(this.#e=new Dx(t),!this.isSymmetric())throw new TypeError("not symmetric data")}clone(){const t=new Lx(this.diagonalSize);for(const[e,n,r]of this.upperRightEntries())t.set(e,n,r);return t}toMatrix(){return new Dx(this)}get(t,e){return this.#e.get(t,e)}set(t,e,n){return this.#e.set(t,e,n),this.#e.set(e,t,n),this}removeCross(t){return this.#e.removeRow(t),this.#e.removeColumn(t),this}addCross(t,e){void 0===e&&(e=t,t=this.diagonalSize);const n=e.slice();return n.splice(t,1),this.#e.addRow(t,n),this.#e.addColumn(t,e),this}applyMask(t){if(t.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");const e=[];for(const[n,r]of t.entries())r||e.push(n);e.reverse();for(const t of e)this.removeCross(t);return this}toCompact(){const{diagonalSize:t}=this,e=new Array(t*(t+1)/2);for(let n=0,r=0,i=0;i=t&&(n=++r);return e}static fromCompact(t){const e=t.length,n=(Math.sqrt(8*e+1)-1)/2;if(!Number.isInteger(n))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(t)}`);const r=new Lx(n);for(let i=0,o=0,a=0;a=n&&(i=++o);return r}*upperRightEntries(){for(let t=0,e=0;t=this.diagonalSize&&(e=++t)}}*upperRightValues(){for(let t=0,e=0;t=this.diagonalSize&&(e=++t)}}}Lx.prototype.klassType="SymmetricMatrix";class _x extends Lx{static isDistanceMatrix(t){return Lx.isSymmetricMatrix(t)&&"DistanceMatrix"===t.klassSubType}constructor(t){if(super(t),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(t,e,n){return t===e&&(n=0),super.set(t,e,n)}addCross(t,e){return void 0===e&&(e=t,t=this.diagonalSize),(e=e.slice())[t]=0,super.addCross(t,e)}toSymmetricMatrix(){return new Lx(this)}clone(){const t=new _x(this.diagonalSize);for(const[e,n,r]of this.upperRightEntries())e!==n&&t.set(e,n,r);return t}toCompact(){const{diagonalSize:t}=this,e=new Array((t-1)*t/2);for(let n=1,r=0,i=0;i=t&&(n=1+ ++r);return e}static fromCompact(t){const e=t.length;if(0===e)return new this(0);const n=(Math.sqrt(8*e+1)+1)/2;if(!Number.isInteger(n))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(t)}`);const r=new this(n);for(let i=1,o=0,a=0;a=n&&(i=1+ ++o);return r}}_x.prototype.klassSubType="DistanceMatrix";class Ix extends Px{constructor(t,e,n){super(),this.matrix=t,this.rows=e,this.columns=n}}class jx extends Ix{constructor(t,e,n){Sx(t,e),Nx(t,n),super(t,e.length,n.length),this.rowIndices=e,this.columnIndices=n}set(t,e,n){return this.matrix.set(this.rowIndices[t],this.columnIndices[e],n),this}get(t,e){return this.matrix.get(this.rowIndices[t],this.columnIndices[e])}}class Bx extends Px{constructor(t,e={}){const{rows:n=1}=e;if(t.length%n!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=n,this.columns=t.length/n,this.data=t}set(t,e,n){let r=this._calculateIndex(t,e);return this.data[r]=n,this}get(t,e){let n=this._calculateIndex(t,e);return this.data[n]}_calculateIndex(t,e){return t*this.columns+e}}class Fx extends Px{constructor(t){super(),this.data=t,this.rows=t.length,this.columns=t[0].length}set(t,e,n){return this.data[t][e]=n,this}get(t,e){return this.data[t][e]}}class zx{constructor(t){let e,n,r,i,o,a,s,l,u,c=(t=Fx.checkMatrix(t)).clone(),h=c.rows,d=c.columns,f=new Float64Array(h),p=1;for(e=0;eMath.abs(l[i])&&(i=e);if(i!==n){for(r=0;r=0;i--){for(r=0;re?r.set(i,e,t.get(i,e)):i===e?r.set(i,e,1):r.set(i,e,0);return r}get upperTriangularMatrix(){let t=this.LU,e=t.rows,n=t.columns,r=new Dx(e,n);for(let i=0;iMath.abs(e)?(n=e/t,Math.abs(t)*Math.sqrt(1+n*n)):0!==e?(n=t/e,Math.abs(e)*Math.sqrt(1+n*n)):0}class Vx{constructor(t){let e,n,r,i,o=(t=Fx.checkMatrix(t)).clone(),a=t.rows,s=t.columns,l=new Float64Array(s);for(r=0;r=0;o--){for(i=0;i=0;n--){for(t=0;t=0;t--)if(0!==f[t]){for(let e=t+1;e=0;t--){if(t0;){let t,e;for(t=w-2;t>=-1&&-1!==t;t--){const e=Number.MIN_VALUE+M*Math.abs(f[t]+Math.abs(f[t+1]));if(Math.abs(v[t])<=e||Number.isNaN(v[t])){v[t]=0;break}}if(t===w-2)e=4;else{let n;for(n=w-1;n>=t&&n!==t;n--){let e=(n!==w?Math.abs(v[n]):0)+(n!==t+1?Math.abs(v[n-1]):0);if(Math.abs(f[n])<=M*e){f[n]=0;break}}n===t?e=3:n===w-1?e=1:(e=2,t=n)}switch(t++,e){case 1:{let e=v[w-2];v[w-2]=0;for(let n=w-2;n>=t;n--){let i=Gx(f[n],e),o=f[n]/i,a=e/i;if(f[n]=i,n!==t&&(e=-a*v[n-1],v[n-1]=o*v[n-1]),u)for(let t=0;t=f[t+1]);){let e=f[t];if(f[t]=f[t+1],f[t+1]=e,u&&te&&i.set(o,n,t.get(o,n)/this.s[n]);let o=this.U,a=o.rows,s=o.columns,l=new Dx(n,a);for(let t=0;tt&&e++;return e}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return Dx.diag(this.s)}};function Hx(t,e,n=!1){return t=Fx.checkMatrix(t),e=Fx.checkMatrix(e),n?new Wx(t).solve(e):t.isSquare()?new zx(t).solve(e):new Vx(t).solve(e)}function Ux(t,e){let n=[];for(let r=0;ri)return new Array(e.rows+1).fill(0);{let t=e.addRow(n,[0]);for(let e=0;e0;s--){for(h=0,a=0,u=0;u0&&(o=-o),e[s]=h*o,a-=i*o,n[s-1]=i-o,l=0;lu)do{for(i=n[u],h=(n[u+1]-i)/(2*e[u]),d=Gx(h,1),h<0&&(d=-d),n[u]=e[u]/(h+d),n[u+1]=e[u]*(h+d),f=n[u+1],o=i-n[u],a=u+2;a=u;a--)for(v=g,g=p,b=y,i=p*e[a],o=p*h,d=Gx(h,e[a]),e[a+1]=y*d,y=e[a]/d,p=h/d,h=p*n[a]-y*i,n[a+1]=o+y*(p*i+y*n[a]),l=0;lw*E);n[u]=n[u]+x,e[u]=0}for(a=0;a=u;s--)n[s]=e.get(s,u-1)/c,a+=n[s]*n[s];for(o=Math.sqrt(a),n[u]>0&&(o=-o),a-=n[u]*o,n[u]=n[u]-o,l=u;l=u;s--)i+=n[s]*e.get(s,l);for(i/=a,s=u;s<=d;s++)e.set(s,l,e.get(s,l)-i*n[s])}for(s=0;s<=d;s++){for(i=0,l=d;l>=u;l--)i+=n[l]*e.get(s,l);for(i/=a,l=u;l<=d;l++)e.set(s,l,e.get(s,l)-i*n[l])}n[u]=c*n[u],e.set(u,u-1,c*o)}}for(s=0;s=h+1;u--)if(0!==e.get(u,u-1)){for(s=u+1;s<=d;s++)n[s]=e.get(s,u-1);for(l=u;l<=d;l++){for(o=0,s=u;s<=d;s++)o+=n[s]*r.get(s,l);for(o=o/n[u]/e.get(u,u-1),s=u;s<=d;s++)r.set(s,l,r.get(s,l)+o*n[s])}}}(o,t,e,a),function(t,e,n,r,i){let o,a,s,l,u,c,h,d,f,p,g,v,m,y,b,x=t-1,E=0,w=t-1,k=Number.EPSILON,M=0,S=0,N=0,O=0,T=0,C=0,A=0,P=0;for(o=0;ow)&&(n[o]=i.get(o,o),e[o]=0),a=Math.max(o-1,0);a=E;){for(l=x;l>E&&(C=Math.abs(i.get(l-1,l-1))+Math.abs(i.get(l,l)),0===C&&(C=S),!(Math.abs(i.get(l,l-1))=0){for(A=N>=0?N+A:N-A,n[x-1]=d+A,n[x]=n[x-1],0!==A&&(n[x]=d-h/A),e[x-1]=0,e[x]=0,d=i.get(x,x-1),C=Math.abs(d)+Math.abs(A),N=d/C,O=A/C,T=Math.sqrt(N*N+O*O),N/=T,O/=T,a=x-1;a0)){for(C=Math.sqrt(C),f=l&&(A=i.get(u,u),T=d-A,C=f-A,N=(T*C-h)/i.get(u+1,u)+i.get(u,u+1),O=i.get(u+1,u+1)-A-T-C,T=i.get(u+2,u+1),C=Math.abs(N)+Math.abs(O)+Math.abs(T),N/=C,O/=C,T/=C,u!==l)&&!(Math.abs(i.get(u,u-1))*(Math.abs(O)+Math.abs(T))u+2&&i.set(o,o-3,0);for(s=u;s<=x-1&&(y=s!==x-1,s!==u&&(N=i.get(s,s-1),O=i.get(s+1,s-1),T=y?i.get(s+2,s-1):0,d=Math.abs(N)+Math.abs(O)+Math.abs(T),0!==d&&(N/=d,O/=d,T/=d)),0!==d);s++)if(C=Math.sqrt(N*N+O*O+T*T),N<0&&(C=-C),0!==C){for(s!==u?i.set(s,s-1,-C*d):l!==u&&i.set(s,s-1,-i.get(s,s-1)),N+=C,d=N/C,f=O/C,A=T/C,O/=N,T/=N,a=s;a=0;x--)if(N=n[x],O=e[x],0===O)for(l=x,i.set(x,x,1),o=x-1;o>=0;o--){for(h=i.get(o,o)-N,T=0,a=l;a<=x;a++)T+=i.get(o,a)*i.get(a,x);if(e[o]<0)A=h,C=T;else if(l=o,0===e[o]?i.set(o,x,0!==h?-T/h:-T/(k*S)):(d=i.get(o,o+1),f=i.get(o+1,o),O=(n[o]-N)*(n[o]-N)+e[o]*e[o],c=(d*C-A*T)/O,i.set(o,x,c),i.set(o+1,x,Math.abs(d)>Math.abs(A)?(-T-h*c)/d:(-C-f*c)/A)),c=Math.abs(i.get(o,x)),k*c*c>1)for(a=o;a<=x;a++)i.set(a,x,i.get(a,x)/c)}else if(O<0)for(l=x-1,Math.abs(i.get(x,x-1))>Math.abs(i.get(x-1,x))?(i.set(x-1,x-1,O/i.get(x,x-1)),i.set(x-1,x,-(i.get(x,x)-N)/i.get(x,x-1))):(b=qx(0,-i.get(x-1,x),i.get(x-1,x-1)-N,O),i.set(x-1,x-1,b[0]),i.set(x-1,x,b[1])),i.set(x,x-1,0),i.set(x,x,1),o=x-2;o>=0;o--){for(p=0,g=0,a=l;a<=x;a++)p+=i.get(o,a)*i.get(a,x-1),g+=i.get(o,a)*i.get(a,x);if(h=i.get(o,o)-N,e[o]<0)A=h,T=p,C=g;else if(l=o,0===e[o]?(b=qx(-p,-g,h,O),i.set(o,x-1,b[0]),i.set(o,x,b[1])):(d=i.get(o,o+1),f=i.get(o+1,o),v=(n[o]-N)*(n[o]-N)+e[o]*e[o]-O*O,m=2*(n[o]-N)*O,0===v&&0===m&&(v=k*S*(Math.abs(h)+Math.abs(O)+Math.abs(d)+Math.abs(f)+Math.abs(A))),b=qx(d*T-A*p+O*g,d*C-A*g-O*p,v,m),i.set(o,x-1,b[0]),i.set(o,x,b[1]),Math.abs(d)>Math.abs(A)+Math.abs(O)?(i.set(o+1,x-1,(-p-h*i.get(o,x-1)+O*i.get(o,x))/d),i.set(o+1,x,(-g-h*i.get(o,x)-O*i.get(o,x-1))/d)):(b=qx(-T-f*i.get(o,x-1),-C-f*i.get(o,x),A,O),i.set(o+1,x-1,b[0]),i.set(o+1,x,b[1]))),c=Math.max(Math.abs(i.get(o,x-1)),Math.abs(i.get(o,x))),k*c*c>1)for(a=o;a<=x;a++)i.set(a,x-1,i.get(a,x-1)/c),i.set(a,x,i.get(a,x)/c)}for(o=0;ow)for(a=o;a=E;a--)for(o=E;o<=w;o++){for(A=0,s=E;s<=Math.min(a,w);s++)A+=r.get(o,s)*i.get(s,a);r.set(o,a,A)}}(o,l,s,a,t)}this.n=o,this.e=l,this.d=s,this.V=a}get realEigenvalues(){return Array.from(this.d)}get imaginaryEigenvalues(){return Array.from(this.e)}get eigenvectorMatrix(){return this.V}get diagonalMatrix(){let t,e,n=this.n,r=this.e,i=this.d,o=new Dx(n,n);for(t=0;t0?o.set(t,t+1,r[t]):r[t]<0&&o.set(t,t-1,r[t])}return o}}function qx(t,e,n,r){let i,o;return Math.abs(n)>Math.abs(r)?(i=r/n,o=n+i*r,[(t+i*e)/o,(e-i*t)/o]):(i=n/r,o=r+i*n,[(i*t+e)/o,(i*e-t)/o])}class Xx{constructor(t){if(!(t=Fx.checkMatrix(t)).isSymmetric())throw new Error("Matrix is not symmetric");let e,n,r,i=t,o=i.rows,a=new Dx(o,o),s=!0;for(n=0;n0,a.set(n,n,Math.sqrt(Math.max(t,0))),r=n+1;r=0;o--)for(i=0;io;e++)u=t.transpose().mmul(a).div(a.transpose().mmul(a).get(0,0)),u=u.div(u.norm()),s=t.mmul(u).div(u.transpose().mmul(u).get(0,0)),e>0&&(h=s.clone().sub(c).pow(2).sum()),c=s.clone(),n?(l=n.transpose().mmul(s).div(s.transpose().mmul(s).get(0,0)),l=l.div(l.norm()),a=n.mmul(l).div(l.transpose().mmul(l).get(0,0))):a=s;if(n){let e=t.transpose().mmul(s).div(s.transpose().mmul(s).get(0,0));e=e.div(e.norm());let r=t.clone().sub(s.clone().mmul(e.transpose())),i=a.transpose().mmul(s).div(s.transpose().mmul(s).get(0,0)),o=n.clone().sub(s.clone().mulS(i.get(0,0)).mmul(l.transpose()));this.t=s,this.p=e.transpose(),this.w=u.transpose(),this.q=l,this.u=a,this.s=s.transpose().mmul(s),this.xResidual=r,this.yResidual=o,this.betas=i}else this.w=u.transpose(),this.s=s.transpose().mmul(s).sqrt(),this.t=r?s.clone().div(this.s.get(0,0)):s,this.xResidual=t.sub(s.mmul(u.transpose()))}}lx.AbstractMatrix=Px,lx.CHO=Xx,lx.CholeskyDecomposition=Xx,lx.DistanceMatrix=_x,lx.EVD=Yx,lx.EigenvalueDecomposition=Yx,lx.LU=zx,lx.LuDecomposition=zx;var Zx=lx.Matrix=Dx;lx.MatrixColumnSelectionView=class extends Ix{constructor(t,e){Nx(t,e),super(t,t.rows,e.length),this.columnIndices=e}set(t,e,n){return this.matrix.set(t,this.columnIndices[e],n),this}get(t,e){return this.matrix.get(t,this.columnIndices[e])}},lx.MatrixColumnView=class extends Ix{constructor(t,e){wx(t,e),super(t,t.rows,1),this.column=e}set(t,e,n){return this.matrix.set(t,this.column,n),this}get(t){return this.matrix.get(t,this.column)}},lx.MatrixFlipColumnView=class extends Ix{constructor(t){super(t,t.rows,t.columns)}set(t,e,n){return this.matrix.set(t,this.columns-e-1,n),this}get(t,e){return this.matrix.get(t,this.columns-e-1)}},lx.MatrixFlipRowView=class extends Ix{constructor(t){super(t,t.rows,t.columns)}set(t,e,n){return this.matrix.set(this.rows-t-1,e,n),this}get(t,e){return this.matrix.get(this.rows-t-1,e)}},lx.MatrixRowSelectionView=class extends Ix{constructor(t,e){Sx(t,e),super(t,e.length,t.columns),this.rowIndices=e}set(t,e,n){return this.matrix.set(this.rowIndices[t],e,n),this}get(t,e){return this.matrix.get(this.rowIndices[t],e)}},lx.MatrixRowView=class extends Ix{constructor(t,e){Ex(t,e),super(t,1,t.columns),this.row=e}set(t,e,n){return this.matrix.set(this.row,e,n),this}get(t,e){return this.matrix.get(this.row,e)}},lx.MatrixSelectionView=jx,lx.MatrixSubView=class extends Ix{constructor(t,e,n,r,i){Ox(t,e,n,r,i),super(t,n-e+1,i-r+1),this.startRow=e,this.startColumn=r}set(t,e,n){return this.matrix.set(this.startRow+t,this.startColumn+e,n),this}get(t,e){return this.matrix.get(this.startRow+t,this.startColumn+e)}},lx.MatrixTransposeView=class extends Ix{constructor(t){super(t,t.columns,t.rows)}set(t,e,n){return this.matrix.set(e,t,n),this}get(t,e){return this.matrix.get(e,t)}},lx.NIPALS=Kx,lx.Nipals=Kx,lx.QR=Vx,lx.QrDecomposition=Vx,lx.SVD=Wx;var Qx=lx.SingularValueDecomposition=Wx;lx.SymmetricMatrix=Lx,lx.WrapperMatrix1D=Bx,lx.WrapperMatrix2D=Fx,lx.correlation=function(t,e=t,n={}){t=new Dx(t);let r=!1;if("object"!=typeof e||Dx.isMatrix(e)||px.isAnyArray(e)?e=new Dx(e):(n=e,e=t,r=!0),t.rows!==e.rows)throw new TypeError("Both matrices must have the same number of rows");const{center:i=!0,scale:o=!0}=n;i&&(t.center("column"),r||e.center("column")),o&&(t.scale("column"),r||e.scale("column"));const a=t.standardDeviation("column",{unbiased:!0}),s=r?a:e.standardDeviation("column",{unbiased:!0}),l=t.transpose().mmul(e);for(let e=0;ee?o[t]=1/o[t]:o[t]=0;return i.mmul(Dx.diag(o).mmul(r.transpose()))},lx.solve=Hx,lx.wrap=function(t,e){if(px.isAnyArray(t))return t[0]&&px.isAnyArray(t[0])?new Fx(t):new Bx(t,e);throw new Error("the argument is not an array")};const tE=Zx,eE=Qx;Jx.Matrix&&Jx.Matrix;const nE={center:[0,0],linkDistance:50};class rE{constructor(t={}){this.options=t,this.id="mds",this.options=Object.assign(Object.assign({},nE),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericMDSLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericMDSLayout(!0,t,e)}))}genericMDSLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{center:i=[0,0],linkDistance:o=50}=r,a=e.getAllNodes(),s=e.getAllEdges();if(!(null==a?void 0:a.length)||1===a.length)return Ob(e,t,i);const l=gb({nodes:a,edges:s}),u=pb(l);iE(u);const c=((t,e)=>{const n=[];return t.forEach((t=>{const r=[];t.forEach((t=>{r.push(t*e)})),n.push(r)})),n})(u,o),h=oE(c),d=[];h.forEach(((t,e)=>{const n=bb(a[e]);n.data.x=t[0]+i[0],n.data.y=t[1]+i[1],d.push(n)})),t&&d.forEach((t=>e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})));return{nodes:d,edges:s}}))}}const iE=t=>{let e=-999999;t.forEach((t=>{t.forEach((t=>{t!==1/0&&e{n.forEach(((n,i)=>{n===1/0&&(t[r][i]=e)}))}))},oE=t=>{const e=tE.mul(tE.pow(t,2),-.5),n=e.mean("row"),r=e.mean("column"),i=e.mean();e.add(i).subRowVector(n).subColumnVector(r);const o=new eE(e),a=tE.sqrt(o.diagonalMatrix).diagonal();return o.leftSingularVectors.toJSON().map((t=>tE.mul([t],[a]).toJSON()[0].splice(0,2)))};function aE(t){return!!t.tick&&!!t.stop}const sE={gForce:!0,force2:!0,d3force:!0,fruchterman:!0,forceAtlas2:!0,force:!0,"graphin-force":!0},lE={center:[0,0],comboPadding:10,treeKey:"combo"};class uE{constructor(t={}){this.options=t,this.id="comboCombined",this.options=Object.assign(Object.assign({},lE),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericComboCombinedLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericComboCombinedLayout(!0,t,e)}))}genericComboCombinedLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=this.initVals(Object.assign(Object.assign({},this.options),n)),{center:i,treeKey:o,outerLayout:a}=r,s=e.getAllNodes().filter((t=>!t.data._isCombo)),l=e.getAllNodes().filter((t=>t.data._isCombo)),u=e.getAllEdges(),c=null==s?void 0:s.length;if(!c||1===c)return Ob(e,t,i);const h=[],d=new Map;s.forEach((t=>{d.set(t.id,t)}));const f=new Map;l.forEach((t=>{f.set(t.id,t)}));const p=new Map,g=this.getInnerGraphs(e,o,d,f,u,r,p);yield Promise.all(g);const v=new Map,m=[],y=new Map;let b=!0;e.getRoots(o).forEach((t=>{const n=p.get(t.id),r=f.get(t.id)||d.get(t.id),i={id:t.id,data:Object.assign(Object.assign({},t.data),{x:n.data.x||r.data.x,y:n.data.y||r.data.y,fx:n.data.fx||r.data.fx,fy:n.data.fy||r.data.fy,mass:n.data.mass||r.data.mass,size:n.data.size})};m.push(i),v.set(t.id,!0),isNaN(i.data.x)||0===i.data.x||isNaN(i.data.y)||0===i.data.y?(i.data.x=100*Math.random(),i.data.y=100*Math.random()):b=!1,mb(e,[t],(e=>{e.id!==t.id&&y.set(e.id,t.id)}),"TB",o)}));const x=[];let E;if(u.forEach((t=>{const e=y.get(t.source)||t.source,n=y.get(t.target)||t.target;e!==n&&v.has(e)&&v.has(n)&&x.push({id:t.id,source:e,target:n,data:{}})})),null==m?void 0:m.length){if(1===m.length)m[0].data.x=i[0],m[0].data.y=i[1];else{const t=new ev({nodes:m,edges:x}),e=a||new nx;if(b&&sE[e.id]){const e=m.length<100?new rE:new Db;yield e.assign(t)}const n=Object.assign({center:i,kg:5,preventOverlap:!0,animate:!1},"force"===e.id?{gravity:1,factor:4,linkDistance:(t,e,n)=>(Math.max(...e.data.size)||32)/2+(Math.max(...n.data.size)||32)/2+200}:{});E=yield cE(e,t,n)}p.forEach((t=>{var e;const n=E.nodes.find((e=>e.id===t.id));if(n){const{x:e,y:r}=n.data;t.data.visited=!0,t.data.x=e,t.data.y=r,h.push({id:t.id,data:{x:e,y:r}})}const{x:r,y:i}=t.data;null===(e=t.data.nodes)||void 0===e||e.forEach((t=>{h.push({id:t.id,data:{x:t.data.x+r,y:t.data.y+i}})}))})),p.forEach((({data:t})=>{const{x:e,y:n,visited:r,nodes:i}=t;null==i||i.forEach((t=>{if(!r){const r=h.find((e=>e.id===t.id));r.data.x+=e||0,r.data.y+=n||0}}))}))}t&&h.forEach((t=>{e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})}));return{nodes:h,edges:u}}))}initVals(t){const e=Object.assign({},t),{nodeSize:n,spacing:r,comboPadding:i}=t;let o,a,s;if(a=ae(r)?()=>r:Ut(r)?r:()=>0,e.spacing=a,n)if(Ut(n))o=t=>{const e=n(t),r=a(t);if(fb(t.size)){return((t.size[0]>t.size[1]?t.size[0]:t.size[1])+r)/2}return((e||32)+r)/2};else if(fb(n)){const t=(n[0]>n[1]?n[0]:n[1])/2;o=e=>t+a(e)/2}else{const t=n/2;o=e=>t+a(e)/2}else o=t=>{const e=a(t);if(t.size){if(fb(t.size)){return((t.size[0]>t.size[1]?t.size[0]:t.size[1])+e)/2}if(qt(t.size)){return((t.size.width>t.size.height?t.size.width:t.size.height)+e)/2}return(t.size+e)/2}return 32+e/2};return e.nodeSize=o,s=ae(i)?()=>i:fb(i)?()=>Math.max.apply(null,i):Ut(i)?i:()=>0,e.comboPadding=s,e}getInnerGraphs(t,e,n,r,i,o,a){const{nodeSize:s,comboPadding:l,spacing:u,innerLayout:c}=o,h=c||new Db({}),d={center:[0,0],preventOverlap:!0,nodeSpacing:u},f=[],p=t=>{let e=(null==l?void 0:l(t))||10;return fb(e)&&(e=Math.max(...e)),{size:e?[2*e,2*e]:[30,30],padding:e}};return t.getRoots(e).forEach((o=>{a.set(o.id,{id:o.id,data:{nodes:[],size:p(o).size}});let l=Promise.resolve();mb(t,[o],(o=>{var u;if(!o.data._isCombo)return;const{size:c,padding:f}=p(o);if(null===(u=t.getChildren(o.id,e))||void 0===u?void 0:u.length){const u=a.get(o.id);a.set(o.id,{id:o.id,data:Object.assign({nodes:[]},null==u?void 0:u.data)});const c=new Map,p=t.getChildren(o.id,e).map((t=>{if(t.data._isCombo)return a.has(t.id)||a.set(t.id,{id:t.id,data:Object.assign({},t.data)}),c.set(t.id,!0),a.get(t.id);const e=n.get(t.id)||r.get(t.id);return c.set(t.id,!0),{id:t.id,data:Object.assign(Object.assign({},e.data),t.data)}})),g={nodes:p,edges:i.filter((t=>c.has(t.source)&&c.has(t.target)))};let v=1/0;p.forEach((t=>{var e;let{size:n}=t.data;n||(n=(null===(e=a.get(t.id))||void 0===e?void 0:e.data.size)||(null==s?void 0:s(t))||[30,30]),ae(n)&&(n=[n,n]);const[r,i]=n;v>r&&(v=r),v>i&&(v=i),t.data.size=n})),l=l.then((()=>ze(this,void 0,void 0,(function*(){const t=new ev(g);yield cE(h,t,d,!0);const{minX:e,minY:n,maxX:r,maxY:i}=(t=>{let e=1/0,n=1/0,r=-1/0,i=-1/0;return t.forEach((t=>{let o=t.data.size;fb(o)?1===o.length&&(o=[o[0],o[0]]):ae(o)?o=[o,o]:(void 0===o||isNaN(o))&&(o=[30,30]);const a=[o[0]/2,o[1]/2],s=t.data.x-a[0],l=t.data.x+a[0],u=t.data.y-a[1],c=t.data.y+a[1];e>s&&(e=s),n>u&&(n=u),r{t.data.x-=s,t.data.y-=l}));const u=[Math.max(r-e,v)+2*f,Math.max(i-n,v)+2*f];a.get(o.id).data.size=u,a.get(o.id).data.nodes=p}))))}else a.set(o.id,{id:o.id,data:Object.assign(Object.assign({},o.data),{size:c})});return!0}),"BT",e),f.push(l)})),f}}function cE(t,e,n,r){var i;return ze(this,void 0,void 0,(function*(){return aE(t)?(t.execute(e,n),t.stop(),t.tick(null!==(i=n.iterations)&&void 0!==i?i:300)):r?yield t.assign(e,n):yield t.execute(e,n)}))}function hE(t,e){var n,r=1;function i(){var i,o,a=n.length,s=0,l=0;for(i=0;iu+p||oc+p||al.index){var g=u-s.x-s.vx,v=c-s.y-s.vy,m=g*g+v*v;mt.r&&(t.r=t[e].r)}function l(){if(e){var r,i,o=e.length;for(n=new Array(o),r=0;r[s(t,e,r),t])));for(a=0,i=new Array(u);a{}};function EE(){for(var t,e=0,n=arguments.length,r={};e=0&&(e=t.slice(n+1),t=t.slice(0,n)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),a=-1,s=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a0)for(var n,r,i=new Array(n),o=0;o=0&&e._call.call(void 0,t),e=e._next;--OE}()}finally{OE=0,function(){var t,e,n=SE,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:SE=e);NE=t,GE(r)}(),PE=0}}function zE(){var t=DE.now(),e=t-AE;e>1e3&&(RE-=e,AE=t)}function GE(t){OE||(TE&&(TE=clearTimeout(TE)),t-PE>24?(t<1/0&&(TE=setTimeout(FE,t-DE.now()-RE)),CE&&(CE=clearInterval(CE))):(CE||(AE=DE.now(),CE=setInterval(zE,1e3)),OE=1,LE(FE)))}jE.prototype=BE.prototype={constructor:jE,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?_E():+n)+(null==e?0:+e),this._next||NE===this||(NE?NE._next=this:SE=this,NE=this),this._call=t,this._time=n,GE()},stop:function(){this._call&&(this._call=null,this._time=1/0,GE())}};const VE=4294967296;function WE(t){return t.x}function HE(t){return t.y}var UE=Math.PI*(3-Math.sqrt(5));function $E(t){var e,n=1,r=.001,i=1-Math.pow(r,1/300),o=0,a=.6,s=new Map,l=BE(h),u=EE("tick","end"),c=function(){let t=1;return()=>(t=(1664525*t+1013904223)%VE)/VE}();function h(){d(),u.call("tick",e),n1?(null==n?s.delete(t):s.set(t,p(n)),e):s.get(t)},find:function(e,n,r){var i,o,a,s,l,u=0,c=t.length;for(null==r?r=1/0:r*=r,u=0;u1?(u.on(t,n),e):u.on(t)}}}function YE(){var t,e,n,r,i,o=dE(-30),a=1,s=1/0,l=.81;function u(n){var i,o=t.length,a=Bb(t,WE,HE).visitAfter(h);for(r=n,i=0;i=s)){(t.data!==e||t.next)&&(0===h&&(p+=(h=fE(n))*h),0===d&&(p+=(d=fE(n))*d),pt.id},manyBody:{},center:{x:0,y:0}},this.context={options:{},assign:!1,nodes:[],edges:[]},ke(this.options,t),this.options.forceSimulation&&(this.simulation=this.options.forceSimulation)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericLayout(!0,t,e)}))}stop(){this.simulation.stop()}tick(t){return this.simulation.tick(t),this.getResult()}restart(){this.simulation.restart()}setFixedPosition(t,e){const n=this.context.nodes.find((e=>e.id===t));n&&e.forEach(((t,e)=>{if("number"==typeof t||null===t){n[["fx","fy","fz"][e]]=t}}))}getOptions(t){var e,n;const r=ke({},this.options,t);return r.collide&&void 0===(null===(e=r.collide)||void 0===e?void 0:e.radius)&&(r.collide=r.collide||{},r.collide.radius=null!==(n=r.nodeSize)&&void 0!==n?n:10),void 0===r.iterations&&(r.link&&void 0===r.link.iterations&&(r.iterations=r.link.iterations),r.collide&&void 0===r.collide.iterations&&(r.iterations=r.collide.iterations)),this.context.options=r,r}genericLayout(t,e,n){var r;return ze(this,void 0,void 0,(function*(){const i=this.getOptions(n),o=e.getAllNodes().map((({id:t,data:e})=>Object.assign(Object.assign({id:t},e),Ae(e.data,this.config.inputNodeAttrs)))),a=e.getAllEdges().map((t=>Object.assign({},t)));Object.assign(this.context,{assign:t,nodes:o,edges:a,graph:e});const s=new Promise((t=>{this.resolver=t})),l=this.setSimulation(i);return l.nodes(o),null===(r=l.force("link"))||void 0===r||r.links(a),s}))}getResult(){const{assign:t,nodes:e,edges:n,graph:r}=this.context,i=e.map((t=>({id:t.id,data:Object.assign(Object.assign({},t.data),Ae(t,this.config.outputNodeAttrs))}))),o=n.map((({id:t,source:e,target:n,data:r})=>({id:t,source:"object"==typeof e?e.id:e,target:"object"==typeof n?n.id:n,data:r})));return t&&i.forEach((t=>r.mergeNodeData(t.id,t.data))),{nodes:i,edges:o}}initSimulation(){return $E()}setSimulation(t){const e=this.simulation||this.options.forceSimulation||this.initSimulation();return this.simulation||(this.simulation=e.on("tick",(()=>{var e;return null===(e=t.onTick)||void 0===e?void 0:e.call(t,this.getResult())})).on("end",(()=>{var t;return null===(t=this.resolver)||void 0===t?void 0:t.call(this,this.getResult())}))),QE(e,this.config.simulationAttrs.map((e=>[e,t[e]]))),Object.entries(this.forceMap).forEach((([n,r])=>{const i=n;if(t[n]){let n=e.force(i);n||(n=r(),e.force(i,n)),QE(n,Object.entries(t[i]))}else e.force(i,null)})),e}}const QE=(t,e)=>e.reduce(((e,[n,r])=>e[n]&&void 0!==r?e[n].call(t,r):e),t);var JE,tw,ew,nw,rw,iw,ow,aw,sw,lw,uw,cw,hw,dw,fw,pw,gw,vw,mw,yw,bw,xw,Ew,ww,kw,Mw,Sw,Nw,Ow,Tw,Cw,Aw,Pw,Rw,Dw,Lw,_w,Iw,jw,Bw,Fw,zw,Gw,Vw,Ww,Hw,Uw,$w,Yw,qw,Xw,Kw,Zw,Qw,Jw,tk,ek,nk,rk,ik,ok,ak,sk,lk,uk,ck,hk,dk,fk,pk,gk,vk,mk,yk,bk,xk,Ek,wk,kk,Mk,Sk,Nk,Ok,Tk,Ck,Ak,Pk,Rk,Dk,Lk,_k,Ik,jk,Bk,Fk,zk,Gk,Vk,Wk,Hk,Uk,$k,Yk,qk,Xk,Kk,Zk,Qk;function Jk(){if(nw)return ew;return nw=1,ew=function(t,e){return t===e||t!=t&&e!=e}}function tM(){if(iw)return rw;iw=1;var t=Jk();return rw=function(e,n){for(var r=e.length;r--;)if(t(e[r][0],n))return r;return-1},rw}function eM(){if(pw)return fw;pw=1;var t=tw?JE:(tw=1,JE=function(){this.__data__=[],this.size=0}),e=function(){if(aw)return ow;aw=1;var t=tM(),e=Array.prototype.splice;return ow=function(n){var r=this.__data__,i=t(r,n);return!(i<0||(i==r.length-1?r.pop():e.call(r,i,1),--this.size,0))},ow}(),n=function(){if(lw)return sw;lw=1;var t=tM();return sw=function(e){var n=this.__data__,r=t(n,e);return r<0?void 0:n[r][1]},sw}(),r=function(){if(cw)return uw;cw=1;var t=tM();return uw=function(e){return t(this.__data__,e)>-1}}(),i=function(){if(dw)return hw;dw=1;var t=tM();return hw=function(e,n){var r=this.__data__,i=t(r,e);return i<0?(++this.size,r.push([e,n])):r[i][1]=n,this},hw}();function o(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&e%1==0&&e-1&&t%1==0&&t<=9007199254740991}}function zM(){if(_M)return LM;return _M=1,LM=function(t){return function(e){return t(e)}}}var GM,VM,WM,HM,UM,$M,YM,qM,XM,KM,ZM,QM,JM,tS,eS,nS,rS,iS,oS,aS,sS,lS,uS,cS,hS,dS,fS,pS={exports:{}};function gS(){return GM||(GM=1,function(t,e){var n=nM(),r=e&&!e.nodeType&&e,i=r&&t&&!t.nodeType&&t,o=i&&i.exports===r&&n.process,a=function(){try{var t=i&&i.require&&i.require("util").types;return t||o&&o.binding&&o.binding("util")}catch(t){}}();t.exports=a}(pS,pS.exports)),pS.exports}function vS(){if(WM)return VM;WM=1;var t=function(){if(DM)return RM;DM=1;var t=oM(),e=FM(),n=wM(),r={};return r["[object Float32Array]"]=r["[object Float64Array]"]=r["[object Int8Array]"]=r["[object Int16Array]"]=r["[object Int32Array]"]=r["[object Uint8Array]"]=r["[object Uint8ClampedArray]"]=r["[object Uint16Array]"]=r["[object Uint32Array]"]=!0,r["[object Arguments]"]=r["[object Array]"]=r["[object ArrayBuffer]"]=r["[object Boolean]"]=r["[object DataView]"]=r["[object Date]"]=r["[object Error]"]=r["[object Function]"]=r["[object Map]"]=r["[object Number]"]=r["[object Object]"]=r["[object RegExp]"]=r["[object Set]"]=r["[object String]"]=r["[object WeakMap]"]=!1,RM=function(i){return n(i)&&e(i.length)&&!!r[t(i)]}}(),e=zM(),n=gS(),r=n&&n.isTypedArray,i=r?e(r):t;return VM=i}function mS(){if(UM)return HM;UM=1;var t=(Hk||(Hk=1,Wk=function(t,e){for(var n=-1,r=Array(t);++nc))return!1;var d=l.get(r),f=l.get(i);if(d&&f)return d==i&&f==r;var p=-1,g=!0,v=2&o?new t:void 0;for(l.set(r,i),l.set(i,r);++p0&&o(c)?i>1?n(c,i-1,o,a,s):t(s,c):a||(s[s.length]=c)}return s},lC}function YP(){if(fC)return dC;fC=1;var t=hC?cC:(hC=1,cC=function(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}),e=Math.max;return dC=function(n,r,i){return r=e(void 0===r?n.length-1:r,0),function(){for(var o=arguments,a=-1,s=e(o.length-r,0),l=Array(s);++a0){if(++n>=800)return arguments[0]}else n=0;return e.apply(void 0,arguments)}},vC}(),n=e(t);return yC=n}function XP(){if(EC)return xC;EC=1;var t=lP(),e=YP(),n=qP();return xC=function(r,i){return n(e(r,i,t),r+"")}}function KP(){if(kC)return wC;return kC=1,wC=function(t,e,n,r){for(var i=t.length,o=n+(r?1:-1);r?o--:++o-1}}(),n=(DC||(DC=1,RC=function(t,e,n){for(var r=-1,i=null==t?0:t.length;++r=200){var g=s?null:i(a);if(g)return o(g);d=!1,c=r,p=new t}else p=s?[]:f;t:for(;++ua){var s=o;o=a,a=s}return o+""+a+""+(t.isUndefined(i)?"\0":i)}function a(t,e){return o(t,e.v,e.w,e.name)}return n.prototype._nodeCount=0,n.prototype._edgeCount=0,n.prototype.isDirected=function(){return this._isDirected},n.prototype.isMultigraph=function(){return this._isMultigraph},n.prototype.isCompound=function(){return this._isCompound},n.prototype.setGraph=function(t){return this._label=t,this},n.prototype.graph=function(){return this._label},n.prototype.setDefaultNodeLabel=function(e){return t.isFunction(e)||(e=t.constant(e)),this._defaultNodeLabelFn=e,this},n.prototype.nodeCount=function(){return this._nodeCount},n.prototype.nodes=function(){return t.keys(this._nodes)},n.prototype.sources=function(){var e=this;return t.filter(this.nodes(),(function(n){return t.isEmpty(e._in[n])}))},n.prototype.sinks=function(){var e=this;return t.filter(this.nodes(),(function(n){return t.isEmpty(e._out[n])}))},n.prototype.setNodes=function(e,n){var r=arguments,i=this;return t.each(e,(function(t){r.length>1?i.setNode(t,n):i.setNode(t)})),this},n.prototype.setNode=function(n,r){return t.has(this._nodes,n)?(arguments.length>1&&(this._nodes[n]=r),this):(this._nodes[n]=arguments.length>1?r:this._defaultNodeLabelFn(n),this._isCompound&&(this._parent[n]=e,this._children[n]={},this._children[e][n]=!0),this._in[n]={},this._preds[n]={},this._out[n]={},this._sucs[n]={},++this._nodeCount,this)},n.prototype.node=function(t){return this._nodes[t]},n.prototype.hasNode=function(e){return t.has(this._nodes,e)},n.prototype.removeNode=function(e){var n=this;if(t.has(this._nodes,e)){var r=function(t){n.removeEdge(n._edgeObjs[t])};delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],t.each(this.children(e),(function(t){n.setParent(t)})),delete this._children[e]),t.each(t.keys(this._in[e]),r),delete this._in[e],delete this._preds[e],t.each(t.keys(this._out[e]),r),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this},n.prototype.setParent=function(n,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(t.isUndefined(r))r=e;else{for(var i=r+="";!t.isUndefined(i);i=this.parent(i))if(i===n)throw new Error("Setting "+r+" as parent of "+n+" would create a cycle");this.setNode(r)}return this.setNode(n),this._removeFromParentsChildList(n),this._parent[n]=r,this._children[r][n]=!0,this},n.prototype._removeFromParentsChildList=function(t){delete this._children[this._parent[t]][t]},n.prototype.parent=function(t){if(this._isCompound){var n=this._parent[t];if(n!==e)return n}},n.prototype.children=function(n){if(t.isUndefined(n)&&(n=e),this._isCompound){var r=this._children[n];if(r)return t.keys(r)}else{if(n===e)return this.nodes();if(this.hasNode(n))return[]}},n.prototype.predecessors=function(e){var n=this._preds[e];if(n)return t.keys(n)},n.prototype.successors=function(e){var n=this._sucs[e];if(n)return t.keys(n)},n.prototype.neighbors=function(e){var n=this.predecessors(e);if(n)return t.union(n,this.successors(e))},n.prototype.isLeaf=function(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length},n.prototype.filterNodes=function(e){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var r=this;t.each(this._nodes,(function(t,r){e(r)&&n.setNode(r,t)})),t.each(this._edgeObjs,(function(t){n.hasNode(t.v)&&n.hasNode(t.w)&&n.setEdge(t,r.edge(t))}));var i={};function o(t){var e=r.parent(t);return void 0===e||n.hasNode(e)?(i[t]=e,e):e in i?i[e]:o(e)}return this._isCompound&&t.each(n.nodes(),(function(t){n.setParent(t,o(t))})),n},n.prototype.setDefaultEdgeLabel=function(e){return t.isFunction(e)||(e=t.constant(e)),this._defaultEdgeLabelFn=e,this},n.prototype.edgeCount=function(){return this._edgeCount},n.prototype.edges=function(){return t.values(this._edgeObjs)},n.prototype.setPath=function(e,n){var r=this,i=arguments;return t.reduce(e,(function(t,e){return i.length>1?r.setEdge(t,e,n):r.setEdge(t,e),e})),this},n.prototype.setEdge=function(){var e,n,i,a,s=!1,l=arguments[0];"object"==typeof l&&null!==l&&"v"in l?(e=l.v,n=l.w,i=l.name,2===arguments.length&&(a=arguments[1],s=!0)):(e=l,n=arguments[1],i=arguments[3],arguments.length>2&&(a=arguments[2],s=!0)),e=""+e,n=""+n,t.isUndefined(i)||(i=""+i);var u=o(this._isDirected,e,n,i);if(t.has(this._edgeLabels,u))return s&&(this._edgeLabels[u]=a),this;if(!t.isUndefined(i)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(n),this._edgeLabels[u]=s?a:this._defaultEdgeLabelFn(e,n,i);var c=function(t,e,n,r){var i=""+e,o=""+n;if(!t&&i>o){var a=i;i=o,o=a}var s={v:i,w:o};r&&(s.name=r);return s}(this._isDirected,e,n,i);return e=c.v,n=c.w,Object.freeze(c),this._edgeObjs[u]=c,r(this._preds[n],e),r(this._sucs[e],n),this._in[n][u]=c,this._out[e][u]=c,this._edgeCount++,this},n.prototype.edge=function(t,e,n){var r=1===arguments.length?a(this._isDirected,arguments[0]):o(this._isDirected,t,e,n);return this._edgeLabels[r]},n.prototype.hasEdge=function(e,n,r){var i=1===arguments.length?a(this._isDirected,arguments[0]):o(this._isDirected,e,n,r);return t.has(this._edgeLabels,i)},n.prototype.removeEdge=function(t,e,n){var r=1===arguments.length?a(this._isDirected,arguments[0]):o(this._isDirected,t,e,n),s=this._edgeObjs[r];return s&&(t=s.v,e=s.w,delete this._edgeLabels[r],delete this._edgeObjs[r],i(this._preds[e],t),i(this._sucs[t],e),delete this._in[e][r],delete this._out[t][r],this._edgeCount--),this},n.prototype.inEdges=function(e,n){var r=this._in[e];if(r){var i=t.values(r);return n?t.filter(i,(function(t){return t.v===n})):i}},n.prototype.outEdges=function(e,n){var r=this._out[e];if(r){var i=t.values(r);return n?t.filter(i,(function(t){return t.w===n})):i}},n.prototype.nodeEdges=function(t,e){var n=this.inEdges(t,e);if(n)return n.concat(this.outEdges(t,e))},KC}function oR(){return eA?tA:(eA=1,tA={Graph:iR(),version:JC?QC:(JC=1,QC="2.1.8")})}function aR(){if(rA)return nA;rA=1;var t=rR(),e=iR();function n(e){return t.map(e.nodes(),(function(n){var r=e.node(n),i=e.parent(n),o={v:n};return t.isUndefined(r)||(o.value=r),t.isUndefined(i)||(o.parent=i),o}))}function r(e){return t.map(e.edges(),(function(n){var r=e.edge(n),i={v:n.v,w:n.w};return t.isUndefined(n.name)||(i.name=n.name),t.isUndefined(r)||(i.value=r),i}))}return nA={write:function(e){var i={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:n(e),edges:r(e)};t.isUndefined(e.graph())||(i.value=t.clone(e.graph()));return i},read:function(n){var r=new e(n.options).setGraph(n.value);return t.each(n.nodes,(function(t){r.setNode(t.v,t.value),t.parent&&r.setParent(t.v,t.parent)})),t.each(n.edges,(function(t){r.setEdge({v:t.v,w:t.w,name:t.name},t.value)})),r}}}function sR(){if(oA)return iA;oA=1;var t=rR();return iA=function(e){var n,r={},i=[];function o(i){t.has(r,i)||(r[i]=!0,n.push(i),t.each(e.successors(i),o),t.each(e.predecessors(i),o))}return t.each(e.nodes(),(function(t){n=[],o(t),n.length&&i.push(n)})),i},iA}function lR(){if(sA)return aA;sA=1;var t=rR();function e(){this._arr=[],this._keyIndices={}}return aA=e,e.prototype.size=function(){return this._arr.length},e.prototype.keys=function(){return this._arr.map((function(t){return t.key}))},e.prototype.has=function(e){return t.has(this._keyIndices,e)},e.prototype.priority=function(t){var e=this._keyIndices[t];if(void 0!==e)return this._arr[e].priority},e.prototype.min=function(){if(0===this.size())throw new Error("Queue underflow");return this._arr[0].key},e.prototype.add=function(e,n){var r=this._keyIndices;if(e=String(e),!t.has(r,e)){var i=this._arr,o=i.length;return r[e]=o,i.push({key:e,priority:n}),this._decrease(o),!0}return!1},e.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var t=this._arr.pop();return delete this._keyIndices[t.key],this._heapify(0),t.key},e.prototype.decrease=function(t,e){var n=this._keyIndices[t];if(e>this._arr[n].priority)throw new Error("New priority is greater than current priority. Key: "+t+" Old: "+this._arr[n].priority+" New: "+e);this._arr[n].priority=e,this._decrease(n)},e.prototype._heapify=function(t){var e=this._arr,n=2*t,r=n+1,i=t;n>1].priority0&&(o=l.removeMin(),(a=s[o]).distance!==Number.POSITIVE_INFINITY);)i(o).forEach(u);return s}(t,String(r),i||n,o||function(e){return t.outEdges(e)})};var n=t.constant(1);return lA}function cR(){if(hA)return cA;hA=1;var t=uR(),e=rR();return cA=function(n,r,i){return e.transform(n.nodes(),(function(e,o){e[o]=t(n,o,r,i)}),{})}}function hR(){if(fA)return dA;fA=1;var t=rR();return dA=function(e){var n=0,r=[],i={},o=[];function a(s){var l=i[s]={onStack:!0,lowlink:n,index:n++};if(r.push(s),e.successors(s).forEach((function(e){t.has(i,e)?i[e].onStack&&(l.lowlink=Math.min(l.lowlink,i[e].index)):(a(e),l.lowlink=Math.min(l.lowlink,i[e].lowlink))})),l.lowlink===l.index){var u,c=[];do{u=r.pop(),i[u].onStack=!1,c.push(u)}while(s!==u);o.push(c)}}return e.nodes().forEach((function(e){t.has(i,e)||a(e)})),o},dA}function dR(){if(gA)return pA;gA=1;var t=rR(),e=hR();return pA=function(n){return t.filter(e(n),(function(t){return t.length>1||1===t.length&&n.hasEdge(t[0],t[0])}))}}function fR(){if(mA)return vA;mA=1;var t=rR();vA=function(t,n,r){return function(t,e,n){var r={},i=t.nodes();return i.forEach((function(t){r[t]={},r[t][t]={distance:0},i.forEach((function(e){t!==e&&(r[t][e]={distance:Number.POSITIVE_INFINITY})})),n(t).forEach((function(n){var i=n.v===t?n.w:n.v,o=e(n);r[t][i]={distance:o,predecessor:t}}))})),i.forEach((function(t){var e=r[t];i.forEach((function(n){var o=r[n];i.forEach((function(n){var r=o[t],i=e[n],a=o[n],s=r.distance+i.distance;s0;){if(o=l.removeMin(),t.has(s,o))a.setEdge(o,s[o]);else{if(c)throw new Error("Input graph is not connected: "+r);c=!0}r.nodeEdges(o).forEach(u)}return a}}try{LA=function(){if(DA)return RA;DA=1;var t=oR();return RA={Graph:t.Graph,json:aR(),alg:PA?AA:(PA=1,AA={components:sR(),dijkstra:uR(),dijkstraAll:cR(),findCycles:dR(),floydWarshall:fR(),isAcyclic:gR(),postorder:mR(),preorder:yR(),prim:bR(),tarjan:hR(),topsort:pR()}),version:t.version}}()}catch(t){}LA||(LA=window.graphlib);var xR,ER,wR,kR,MR,SR,NR,OR,TR,CR,AR,PR,RR,DR,LR,_R,IR,jR,BR,FR,zR,GR,VR,WR,HR,UR,$R,YR,qR,XR,KR,ZR,QR,JR,tD,eD,nD,rD,iD,oD,aD,sD,lD,uD,cD,hD,dD,fD,pD,gD,vD,mD,yD,bD,xD,ED,wD,kD,MD,SD,ND,OD,TD,CD,AD,PD,RD,DD,LD,_D,ID,jD,BD,FD,zD,GD,VD,WD,HD,UD,$D,YD,qD,XD,KD,ZD,QD,JD,tL,eL,nL,rL,iL,oL=LA;function aL(){if(kR)return wR;kR=1;var t=Jk(),e=ES(),n=BM(),r=aM();return wR=function(i,o,a){if(!r(a))return!1;var s=typeof o;return!!("number"==s?e(a)&&n(o,a.length):"string"==s&&o in a)&&t(a[o],i)},wR}function sL(){if(PR)return AR;PR=1;var t=function(){if(CR)return TR;CR=1;var t=/\s/;return TR=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n},TR}(),e=/^\s+/;return AR=function(n){return n?n.slice(0,t(n)+1).replace(e,""):n}}function lL(){if(_R)return LR;_R=1;var t=function(){if(DR)return RR;DR=1;var t=sL(),e=aM(),n=wP(),r=/^[-+]0x[0-9a-f]+$/i,i=/^0b[01]+$/i,o=/^0o[0-7]+$/i,a=parseInt;return RR=function(s){if("number"==typeof s)return s;if(n(s))return NaN;if(e(s)){var l="function"==typeof s.valueOf?s.valueOf():s;s=e(l)?l+"":l}if("string"!=typeof s)return 0===s?s:+s;s=t(s);var u=i.test(s);return u||o.test(s)?a(s.slice(2),u?2:8):r.test(s)?NaN:+s}}(),e=1/0;return LR=function(n){return n?(n=t(n))===e||n===-1/0?17976931348623157e292*(n<0?-1:1):n==n?n:0:0===n?n:0}}function uL(){if(FR)return BR;FR=1;var t=KP(),e=_P(),n=function(){if(jR)return IR;jR=1;var t=lL();return IR=function(e){var n=t(e),r=n%1;return n==n?r?n-r:n:0}}(),r=Math.max;return BR=function(i,o,a){var s=null==i?0:i.length;if(!s)return-1;var l=null==a?0:n(a);return l<0&&(l=r(s+l,0)),t(i,e(o,3),l)},BR}function cL(){if(WR)return VR;WR=1;var t=$P();return VR=function(e){return(null==e?0:e.length)?t(e,1):[]}}function hL(){if(ZR)return KR;ZR=1;var t=wP();return KR=function(e,n,r){for(var i=-1,o=e.length;++in||a&&s&&u&&!l&&!c||i&&s&&u||!r&&u||!o)return 1;if(!i&&!a&&!c&&e=l?u:u*("desc"==r[i]?-1:1)}return e.index-n.index},$D}function bL(){if(XD)return qD;XD=1;var t=SP(),e=CP(),n=_P(),r=zP(),i=(WD||(WD=1,VD=function(t,e){var n=t.length;for(t.sort(e);n--;)t[n]=t[n].value;return t}),VD),o=zM(),a=yL(),s=lP(),l=MM();return qD=function(u,c,h){c=c.length?t(c,(function(t){return l(t)?function(n){return e(n,1===t.length?t[0]:t)}:t})):[s];var d=-1;c=t(c,o(n));var f=r(u,(function(e,n,r){return{criteria:t(c,(function(t){return t(e)})),index:++d,value:e}}));return i(f,(function(t,e){return a(t,e,h)}))},qD}try{iL={cloneDeep:function(){if(ER)return xR;ER=1;var t=nP();return xR=function(e){return t(e,5)}}(),constant:iP(),defaults:function(){if(SR)return MR;SR=1;var t=XP(),e=Jk(),n=aL(),r=MS(),i=Object.prototype,o=i.hasOwnProperty,a=t((function(t,a){t=Object(t);var s=-1,l=a.length,u=l>2?a[2]:void 0;for(u&&n(a[0],a[1],u)&&(l=1);++s-1?s[l?i[u]:u]:void 0}},NR}(),e=t(uL());return zR=e}(),flatten:cL(),forEach:cP(),forIn:function(){if(UR)return HR;UR=1;var t=oP(),e=uP(),n=MS();return HR=function(r,i){return null==r?r:t(r,e(i),n)}}(),has:jP(),isUndefined:FP(),last:(YR||(YR=1,$R=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0}),$R),map:GP(),mapValues:function(){if(XR)return qR;XR=1;var t=bM(),e=aP(),n=_P();return qR=function(r,i){var o={};return i=n(i,3),e(r,(function(e,n,r){t(o,n,i(e,n,r))})),o}}(),max:function(){if(eD)return tD;eD=1;var t=hL(),e=JR?QR:(JR=1,QR=function(t,e){return t>e}),n=lP();return tD=function(r){return r&&r.length?t(r,n,e):void 0}}(),merge:function(){if(mD)return vD;mD=1;var t=function(){if(fD)return dD;fD=1;var t=vM(),e=dL(),n=oP(),r=pL(),i=aM(),o=MS(),a=fL();return dD=function s(l,u,c,h,d){l!==u&&n(u,(function(n,o){if(d||(d=new t),i(n))r(l,u,o,c,s,h,d);else{var f=h?h(a(l,o),n,o+"",l,u,d):void 0;void 0===f&&(f=n),e(l,o,f)}}),o)},dD}(),e=function(){if(gD)return pD;gD=1;var t=XP(),e=aL();return pD=function(n){return t((function(t,r){var i=-1,o=r.length,a=o>1?r[o-1]:void 0,s=o>2?r[2]:void 0;for(a=n.length>3&&"function"==typeof a?(o--,a):void 0,s&&e(r[0],r[1],s)&&(a=o<3?void 0:a,o=1),t=Object(t);++i1&&r(n,i[0],i[1])?i=[]:o>2&&r(i[0],i[1],i[2])&&(i=[i[0]]),e(n,t(i,1),[])}));return KD=i}(),uniqueId:function(){if(JD)return QD;JD=1;var t=NP(),e=0;return QD=function(n){var r=++e;return t(n)+r},QD}(),values:nR(),zipObject:function(){if(rL)return nL;rL=1;var t=xM(),e=(eL||(eL=1,tL=function(t,e,n){for(var r=-1,i=t.length,o=e.length,a={};++r0;--s)if(r=e[s].dequeue()){i=i.concat(AL(t,e,n,r,!0));break}}return i}(n.graph,n.buckets,n.zeroIdx);return SL.flatten(SL.map(r,(function(e){return t.outEdges(e.v,e.w)})),!0)},CL=SL.constant(1);function AL(t,e,n,r,i){var o=i?[]:void 0;return SL.forEach(t.inEdges(r.v),(function(r){var a=t.edge(r),s=t.node(r.v);i&&o.push({v:r.v,w:r.w}),s.out-=a,PL(e,n,s)})),SL.forEach(t.outEdges(r.v),(function(r){var i=t.edge(r),o=r.w,a=t.node(o);a.in-=i,PL(e,n,a)})),t.removeNode(r.v),o}function PL(t,e,n){n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}var RL=xL,DL=TL,LL={run:function(t){var e="greedy"===t.graph().acyclicer?DL(t,function(t){return function(e){return t.edge(e).weight}}(t)):function(t){var e=[],n={},r={};function i(o){RL.has(r,o)||(r[o]=!0,n[o]=!0,RL.forEach(t.outEdges(o),(function(t){RL.has(n,t.w)?e.push(t):i(t.w)})),delete n[o])}return RL.forEach(t.nodes(),i),e}(t);RL.forEach(e,(function(e){var n=t.edge(e);t.removeEdge(e),n.forwardName=e.name,n.reversed=!0,t.setEdge(e.w,e.v,n,RL.uniqueId("rev"))}))},undo:function(t){RL.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.reversed){t.removeEdge(e);var r=n.forwardName;delete n.reversed,delete n.forwardName,t.setEdge(e.w,e.v,n,r)}}))}};var _L=xL,IL=oL.Graph,jL={addDummyNode:BL,simplify:function(t){var e=(new IL).setGraph(t.graph());return _L.forEach(t.nodes(),(function(n){e.setNode(n,t.node(n))})),_L.forEach(t.edges(),(function(n){var r=e.edge(n.v,n.w)||{weight:0,minlen:1},i=t.edge(n);e.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})})),e},asNonCompoundGraph:function(t){var e=new IL({multigraph:t.isMultigraph()}).setGraph(t.graph());return _L.forEach(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),_L.forEach(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e},successorWeights:function(t){var e=_L.map(t.nodes(),(function(e){var n={};return _L.forEach(t.outEdges(e),(function(e){n[e.w]=(n[e.w]||0)+t.edge(e).weight})),n}));return _L.zipObject(t.nodes(),e)},predecessorWeights:function(t){var e=_L.map(t.nodes(),(function(e){var n={};return _L.forEach(t.inEdges(e),(function(e){n[e.v]=(n[e.v]||0)+t.edge(e).weight})),n}));return _L.zipObject(t.nodes(),e)},intersectRect:function(t,e){var n,r,i=t.x,o=t.y,a=e.x-i,s=e.y-o,l=t.width/2,u=t.height/2;if(!a&&!s)throw new Error("Not possible to find intersection inside of the rectangle");Math.abs(s)*l>Math.abs(a)*u?(s<0&&(u=-u),n=u*a/s,r=u):(a<0&&(l=-l),n=l,r=l*s/a);return{x:i+n,y:o+r}},buildLayerMatrix:function(t){var e=_L.map(_L.range(FL(t)+1),(function(){return[]}));return _L.forEach(t.nodes(),(function(n){var r=t.node(n),i=r.rank;_L.isUndefined(i)||(e[i][r.order]=n)})),e},normalizeRanks:function(t){var e=_L.min(_L.map(t.nodes(),(function(e){return t.node(e).rank})));_L.forEach(t.nodes(),(function(n){var r=t.node(n);_L.has(r,"rank")&&(r.rank-=e)}))},removeEmptyRanks:function(t){var e=_L.min(_L.map(t.nodes(),(function(e){return t.node(e).rank}))),n=[];_L.forEach(t.nodes(),(function(r){var i=t.node(r).rank-e;n[i]||(n[i]=[]),n[i].push(r)}));var r=0,i=t.graph().nodeRankFactor;_L.forEach(n,(function(e,n){_L.isUndefined(e)&&n%i!==0?--r:r&&_L.forEach(e,(function(e){t.node(e).rank+=r}))}))},addBorderNode:function(t,e,n,r){var i={width:0,height:0};arguments.length>=4&&(i.rank=n,i.order=r);return BL(t,"border",i,e)},maxRank:FL,partition:function(t,e){var n={lhs:[],rhs:[]};return _L.forEach(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n},time:function(t,e){var n=_L.now();try{return e()}finally{console.log(t+" time: "+(_L.now()-n)+"ms")}},notime:function(t,e){return e()}};function BL(t,e,n,r){var i;do{i=_L.uniqueId(r)}while(t.hasNode(i));return n.dummy=e,t.setNode(i,n),i}function FL(t){return _L.max(_L.map(t.nodes(),(function(e){var n=t.node(e).rank;if(!_L.isUndefined(n))return n})))}var zL=xL,GL=jL,VL={run:function(t){t.graph().dummyChains=[],zL.forEach(t.edges(),(function(e){!function(t,e){var n,r,i,o=e.v,a=t.node(o).rank,s=e.w,l=t.node(s).rank,u=e.name,c=t.edge(e),h=c.labelRank;if(l===a+1)return;for(t.removeEdge(e),i=0,++a;aa.lim&&(s=a,l=!0);var u=QL.filter(e.edges(),(function(e){return l===p_(t,t.node(e.v),s)&&l!==p_(t,t.node(e.w),s)}));return QL.minBy(u,(function(t){return t_(e,t)}))}function f_(t,e,n,r){var i=n.v,o=n.w;t.removeEdge(i,o),t.setEdge(r.v,r.w,{}),u_(t),s_(t,e),function(t,e){var n=QL.find(t.nodes(),(function(t){return!e.node(t).parent})),r=n_(t,n);r=r.slice(1),QL.forEach(r,(function(n){var r=t.node(n).parent,i=e.edge(n,r),o=!1;i||(i=e.edge(r,n),o=!0),e.node(n).rank=e.node(r).rank+(o?i.minlen:-i.minlen)}))}(t,e)}function p_(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}a_.initLowLimValues=u_,a_.initCutValues=s_,a_.calcCutValue=l_,a_.leaveEdge=h_,a_.enterEdge=d_,a_.exchangeEdges=f_;var g_=HL.longestPath,v_=qL,m_=o_,y_=function(t){switch(t.graph().ranker){case"network-simplex":default:x_(t);break;case"tight-tree":!function(t){g_(t),v_(t)}(t);break;case"longest-path":b_(t)}};var b_=g_;function x_(t){m_(t)}var E_=xL,w_=function(t){var e=function(t){var e={},n=0;function r(i){var o=n;E_.forEach(t.children(i),r),e[i]={low:o,lim:n++}}return E_.forEach(t.children(),r),e}(t);E_.forEach(t.graph().dummyChains,(function(n){for(var r=t.node(n),i=r.edgeObj,o=function(t,e,n,r){var i,o,a=[],s=[],l=Math.min(e[n].low,e[r].low),u=Math.max(e[n].lim,e[r].lim);i=n;do{i=t.parent(i),a.push(i)}while(i&&(e[i].low>l||u>e[i].lim));o=i,i=r;for(;(i=t.parent(i))!==o;)s.push(i);return{path:a.concat(s.reverse()),lca:o}}(t,e,i.v,i.w),a=o.path,s=o.lca,l=0,u=a[l],c=!0;n!==i.w;){if(r=t.node(n),c){for(;(u=a[l])!==s&&t.node(u).maxRank0;)e%2&&(n+=s[e+1]),s[e=e-1>>1]+=t.weight;l+=t.weight*n}))),l}var V_=xL;var W_=xL,H_=function(t,e){var n={};return W_.forEach(t,(function(t,e){var r=n[t.v]={indegree:0,in:[],out:[],vs:[t.v],i:e};W_.isUndefined(t.barycenter)||(r.barycenter=t.barycenter,r.weight=t.weight)})),W_.forEach(e.edges(),(function(t){var e=n[t.v],r=n[t.w];W_.isUndefined(e)||W_.isUndefined(r)||(r.indegree++,e.out.push(n[t.w]))})),function(t){var e=[];function n(t){return function(e){e.merged||(W_.isUndefined(e.barycenter)||W_.isUndefined(t.barycenter)||e.barycenter>=t.barycenter)&&function(t,e){var n=0,r=0;t.weight&&(n+=t.barycenter*t.weight,r+=t.weight);e.weight&&(n+=e.barycenter*e.weight,r+=e.weight);t.vs=e.vs.concat(t.vs),t.barycenter=n/r,t.weight=r,t.i=Math.min(e.i,t.i),e.merged=!0}(t,e)}}function r(e){return function(n){n.in.push(e),0===--n.indegree&&t.push(n)}}for(;t.length;){var i=t.pop();e.push(i),W_.forEach(i.in.reverse(),n(i)),W_.forEach(i.out,r(i))}return W_.map(W_.filter(e,(function(t){return!t.merged})),(function(t){return W_.pick(t,["vs","i","barycenter","weight"])}))}(W_.filter(n,(function(t){return!t.indegree})))};var U_=xL,$_=jL;function Y_(t,e,n){for(var r;e.length&&(r=U_.last(e)).i<=n;)e.pop(),t.push(r.vs),n++;return n}var q_=xL,X_=function(t,e){return V_.map(e,(function(e){var n=t.inEdges(e);if(n.length){var r=V_.reduce(n,(function(e,n){var r=t.edge(n),i=t.node(n.v);return{sum:e.sum+r.weight*i.order,weight:e.weight+r.weight}}),{sum:0,weight:0});return{v:e,barycenter:r.sum/r.weight,weight:r.weight}}return{v:e}}))},K_=H_,Z_=function(t,e){var n=$_.partition(t,(function(t){return U_.has(t,"barycenter")})),r=n.lhs,i=U_.sortBy(n.rhs,(function(t){return-t.i})),o=[],a=0,s=0,l=0;r.sort((u=!!e,function(t,e){return t.barycentere.barycenter?1:u?e.i-t.i:t.i-e.i})),l=Y_(o,i,l),U_.forEach(r,(function(t){l+=t.vs.length,o.push(t.vs),a+=t.barycenter*t.weight,s+=t.weight,l=Y_(o,i,l)}));var u;var c={vs:U_.flatten(o,!0)};s&&(c.barycenter=a/s,c.weight=s);return c},Q_=function t(e,n,r,i){var o=e.children(n),a=e.node(n),s=a?a.borderLeft:void 0,l=a?a.borderRight:void 0,u={};s&&(o=q_.filter(o,(function(t){return t!==s&&t!==l})));var c=X_(e,o);q_.forEach(c,(function(n){if(e.children(n.v).length){var o=t(e,n.v,r,i);u[n.v]=o,q_.has(o,"barycenter")&&(a=n,s=o,q_.isUndefined(a.barycenter)?(a.barycenter=s.barycenter,a.weight=s.weight):(a.barycenter=(a.barycenter*a.weight+s.barycenter*s.weight)/(a.weight+s.weight),a.weight+=s.weight))}var a,s}));var h=K_(c,r);!function(t,e){q_.forEach(t,(function(t){t.vs=q_.flatten(t.vs.map((function(t){return e[t]?e[t].vs:t})),!0)}))}(h,u);var d=Z_(h,i);if(s&&(d.vs=q_.flatten([s,d.vs,l],!0),e.predecessors(s).length)){var f=e.node(e.predecessors(s)[0]),p=e.node(e.predecessors(l)[0]);q_.has(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+f.order+p.order)/(d.weight+2),d.weight+=2}return d};var J_=xL,tI=oL.Graph,eI=function(t,e,n){var r=function(t){var e;for(;t.hasNode(e=J_.uniqueId("_root")););return e}(t),i=new tI({compound:!0}).setGraph({root:r}).setDefaultNodeLabel((function(e){return t.node(e)}));return J_.forEach(t.nodes(),(function(o){var a=t.node(o),s=t.parent(o);(a.rank===e||a.minRank<=e&&e<=a.maxRank)&&(i.setNode(o),i.setParent(o,s||r),J_.forEach(t[n](o),(function(e){var n=e.v===o?e.w:e.v,r=i.edge(n,o),a=J_.isUndefined(r)?0:r.weight;i.setEdge(n,o,{weight:t.edge(e).weight+a})})),J_.has(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[e],borderRight:a.borderRight[e]}))})),i};var nI=xL;var rI=xL,iI=B_,oI=z_,aI=Q_,sI=eI,lI=function(t,e,n){var r,i={};nI.forEach(n,(function(n){for(var o,a,s=t.parent(n);s;){if((o=t.parent(s))?(a=i[o],i[o]=s):(a=r,r=s),a&&a!==s)return void e.setEdge(a,s);s=o}}))},uI=oL.Graph,cI=jL,hI=function(t){var e=cI.maxRank(t),n=dI(t,rI.range(1,e+1),"inEdges"),r=dI(t,rI.range(e-1,-1,-1),"outEdges"),i=iI(t);pI(t,i);for(var o,a=Number.POSITIVE_INFINITY,s=0,l=0;l<4;++s,++l){fI(s%2?n:r,s%4>=2),i=cI.buildLayerMatrix(t);var u=oI(t,i);ua)&&bI(n,e,s)}))}))}function i(e,n){var i,o=-1,a=0;return gI.forEach(n,(function(s,l){if("border"===t.node(s).dummy){var u=t.predecessors(s);u.length&&(i=t.node(u[0]).order,r(n,a,l,o,i),a=l,o=i)}r(n,a,n.length,i,e.length)})),n}return gI.reduce(e,i),n}(t,n)),i={};gI.forEach(["u","d"],(function(o){e="u"===o?n:gI.values(n).reverse(),gI.forEach(["l","r"],(function(n){"r"===n&&(e=gI.map(e,(function(t){return gI.values(t).reverse()})));var a=("u"===o?t.predecessors:t.successors).bind(t),s=function(t,e,n,r){var i={},o={},a={};return gI.forEach(e,(function(t){gI.forEach(t,(function(t,e){i[t]=t,o[t]=t,a[t]=e}))})),gI.forEach(e,(function(t){var e=-1;gI.forEach(t,(function(t){var s=r(t);if(s.length){s=gI.sortBy(s,(function(t){return a[t]}));for(var l=(s.length-1)/2,u=Math.floor(l),c=Math.ceil(l);u<=c;++u){var h=s[u];o[t]===t&&en){var r=e;e=n,n=r}var i=t[e];i||(t[e]=i={}),i[n]=!0}function xI(t,e,n){if(e>n){var r=e;e=n,n=r}return gI.has(t[e],n)}var EI=xL,wI=jL,kI=yI,MI=function(t){(function(t){var e=wI.buildLayerMatrix(t),n=t.graph().ranksep,r=0;EI.forEach(e,(function(e){var i=EI.max(EI.map(e,(function(e){return t.node(e).height})));EI.forEach(e,(function(e){t.node(e).y=r+i/2})),r+=i+n}))})(t=wI.asNonCompoundGraph(t)),EI.forEach(kI(t),(function(e,n){t.node(n).x=e}))};var SI=xL,NI=LL,OI=VL,TI=y_,CI=jL.normalizeRanks,AI=w_,PI=jL.removeEmptyRanks,RI=S_,DI=C_,LI=R_,_I=hI,II=MI,jI=jL,BI=oL.Graph,FI=function(t,e){var n=e&&e.debugTiming?jI.time:jI.notime;n("layout",(function(){var e=n(" buildLayoutGraph",(function(){return function(t){var e=new BI({multigraph:!0,compound:!0}),n=XI(t.graph());return e.setGraph(SI.merge({},GI,qI(n,zI),SI.pick(n,VI))),SI.forEach(t.nodes(),(function(n){var r=XI(t.node(n));e.setNode(n,SI.defaults(qI(r,WI),HI)),e.setParent(n,t.parent(n))})),SI.forEach(t.edges(),(function(n){var r=XI(t.edge(n));e.setEdge(n,SI.merge({},$I,qI(r,UI),SI.pick(r,YI)))})),e}(t)}));n(" runLayout",(function(){!function(t,e){e(" makeSpaceForEdgeLabels",(function(){!function(t){var e=t.graph();e.ranksep/=2,SI.forEach(t.edges(),(function(n){var r=t.edge(n);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===e.rankdir||"BT"===e.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)}))}(t)})),e(" removeSelfEdges",(function(){!function(t){SI.forEach(t.edges(),(function(e){if(e.v===e.w){var n=t.node(e.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:e,label:t.edge(e)}),t.removeEdge(e)}}))}(t)})),e(" acyclic",(function(){NI.run(t)})),e(" nestingGraph.run",(function(){RI.run(t)})),e(" rank",(function(){TI(jI.asNonCompoundGraph(t))})),e(" injectEdgeLabelProxies",(function(){!function(t){SI.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.width&&n.height){var r=t.node(e.v),i={rank:(t.node(e.w).rank-r.rank)/2+r.rank,e:e};jI.addDummyNode(t,"edge-proxy",i,"_ep")}}))}(t)})),e(" removeEmptyRanks",(function(){PI(t)})),e(" nestingGraph.cleanup",(function(){RI.cleanup(t)})),e(" normalizeRanks",(function(){CI(t)})),e(" assignRankMinMax",(function(){!function(t){var e=0;SI.forEach(t.nodes(),(function(n){var r=t.node(n);r.borderTop&&(r.minRank=t.node(r.borderTop).rank,r.maxRank=t.node(r.borderBottom).rank,e=SI.max(e,r.maxRank))})),t.graph().maxRank=e}(t)})),e(" removeEdgeLabelProxies",(function(){!function(t){SI.forEach(t.nodes(),(function(e){var n=t.node(e);"edge-proxy"===n.dummy&&(t.edge(n.e).labelRank=n.rank,t.removeNode(e))}))}(t)})),e(" normalize.run",(function(){OI.run(t)})),e(" parentDummyChains",(function(){AI(t)})),e(" addBorderSegments",(function(){DI(t)})),e(" order",(function(){_I(t)})),e(" insertSelfEdges",(function(){!function(t){var e=jI.buildLayerMatrix(t);SI.forEach(e,(function(e){var n=0;SI.forEach(e,(function(e,r){var i=t.node(e);i.order=r+n,SI.forEach(i.selfEdges,(function(e){jI.addDummyNode(t,"selfedge",{width:e.label.width,height:e.label.height,rank:i.rank,order:r+ ++n,e:e.e,label:e.label},"_se")})),delete i.selfEdges}))}))}(t)})),e(" adjustCoordinateSystem",(function(){LI.adjust(t)})),e(" position",(function(){II(t)})),e(" positionSelfEdges",(function(){!function(t){SI.forEach(t.nodes(),(function(e){var n=t.node(e);if("selfedge"===n.dummy){var r=t.node(n.e.v),i=r.x+r.width/2,o=r.y,a=n.x-i,s=r.height/2;t.setEdge(n.e,n.label),t.removeNode(e),n.label.points=[{x:i+2*a/3,y:o-s},{x:i+5*a/6,y:o-s},{x:i+a,y:o},{x:i+5*a/6,y:o+s},{x:i+2*a/3,y:o+s}],n.label.x=n.x,n.label.y=n.y}}))}(t)})),e(" removeBorderNodes",(function(){!function(t){SI.forEach(t.nodes(),(function(e){if(t.children(e).length){var n=t.node(e),r=t.node(n.borderTop),i=t.node(n.borderBottom),o=t.node(SI.last(n.borderLeft)),a=t.node(SI.last(n.borderRight));n.width=Math.abs(a.x-o.x),n.height=Math.abs(i.y-r.y),n.x=o.x+n.width/2,n.y=r.y+n.height/2}})),SI.forEach(t.nodes(),(function(e){"border"===t.node(e).dummy&&t.removeNode(e)}))}(t)})),e(" normalize.undo",(function(){OI.undo(t)})),e(" fixupEdgeLabelCoords",(function(){!function(t){SI.forEach(t.edges(),(function(e){var n=t.edge(e);if(SI.has(n,"x"))switch("l"!==n.labelpos&&"r"!==n.labelpos||(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset}}))}(t)})),e(" undoCoordinateSystem",(function(){LI.undo(t)})),e(" translateGraph",(function(){!function(t){var e=Number.POSITIVE_INFINITY,n=0,r=Number.POSITIVE_INFINITY,i=0,o=t.graph(),a=o.marginx||0,s=o.marginy||0;function l(t){var o=t.x,a=t.y,s=t.width,l=t.height;e=Math.min(e,o-s/2),n=Math.max(n,o+s/2),r=Math.min(r,a-l/2),i=Math.max(i,a+l/2)}SI.forEach(t.nodes(),(function(e){l(t.node(e))})),SI.forEach(t.edges(),(function(e){var n=t.edge(e);SI.has(n,"x")&&l(n)})),e-=a,r-=s,SI.forEach(t.nodes(),(function(n){var i=t.node(n);i.x-=e,i.y-=r})),SI.forEach(t.edges(),(function(n){var i=t.edge(n);SI.forEach(i.points,(function(t){t.x-=e,t.y-=r})),SI.has(i,"x")&&(i.x-=e),SI.has(i,"y")&&(i.y-=r)})),o.width=n-e+a,o.height=i-r+s}(t)})),e(" assignNodeIntersects",(function(){!function(t){SI.forEach(t.edges(),(function(e){var n,r,i=t.edge(e),o=t.node(e.v),a=t.node(e.w);i.points?(n=i.points[0],r=i.points[i.points.length-1]):(i.points=[],n=a,r=o),i.points.unshift(jI.intersectRect(o,n)),i.points.push(jI.intersectRect(a,r))}))}(t)})),e(" reversePoints",(function(){!function(t){SI.forEach(t.edges(),(function(e){var n=t.edge(e);n.reversed&&n.points.reverse()}))}(t)})),e(" acyclic.undo",(function(){NI.undo(t)}))}(e,n)})),n(" updateInputGraph",(function(){!function(t,e){SI.forEach(t.nodes(),(function(n){var r=t.node(n),i=e.node(n);r&&(r.x=i.x,r.y=i.y,e.children(n).length&&(r.width=i.width,r.height=i.height))})),SI.forEach(t.edges(),(function(n){var r=t.edge(n),i=e.edge(n);r.points=i.points,SI.has(i,"x")&&(r.x=i.x,r.y=i.y)})),t.graph().width=e.graph().width,t.graph().height=e.graph().height}(t,e)}))}))};var zI=["nodesep","edgesep","ranksep","marginx","marginy"],GI={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},VI=["acyclicer","ranker","rankdir","align"],WI=["width","height"],HI={width:0,height:0},UI=["minlen","weight","width","height","labeloffset"],$I={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},YI=["labelpos"];function qI(t,e){return SI.mapValues(SI.pick(t,e),Number)}function XI(t){var e={};return SI.forEach(t,(function(t,n){e[n.toLowerCase()]=t})),e}var KI=xL,ZI=jL,QI=oL.Graph,JI={debugOrdering:function(t){var e=ZI.buildLayerMatrix(t),n=new QI({compound:!0,multigraph:!0}).setGraph({});return KI.forEach(t.nodes(),(function(e){n.setNode(e,{label:e}),n.setParent(e,"layer"+t.node(e).rank)})),KI.forEach(t.edges(),(function(t){n.setEdge(t.v,t.w,{},t.name)})),KI.forEach(e,(function(t,e){var r="layer"+e;n.setNode(r,{rank:"same"}),KI.reduce(t,(function(t,e){return n.setEdge(t,e,{style:"invis"}),e}))})),n}};var tj={graphlib:oL,layout:FI,debug:JI,util:{time:jL.time,notime:jL.notime},version:"0.8.5"},ej=E(tj);class nj{constructor(t){this.id="dagre",this.options={},Object.assign(this.options,nj.defaultOptions,t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericDagreLayout(!1,t,Object.assign(Object.assign({},this.options),e))}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericDagreLayout(!0,t,Object.assign(Object.assign({},this.options),e))}))}genericDagreLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const{nodeSize:r}=n,i=new tj.graphlib.Graph;i.setGraph(n),i.setDefaultEdgeLabel((()=>({})));[...e.getAllNodes(),...e.getAllEdges()].some((({id:t})=>ae(t)))&&console.error("Dagre layout only support string id, it will convert number to string."),e.getAllNodes().forEach((t=>{const{id:e}=t,n=Object.assign({},t.data);if(void 0!==r){const[e,i]=xb(Ut(r)?r(t):r);Object.assign(n,{width:e,height:i})}i.setNode(e.toString(),n)})),e.getAllEdges().forEach((({id:t,source:e,target:n})=>{i.setEdge(e.toString(),n.toString(),{id:t})})),ej.layout(i);const o={nodes:[],edges:[]};return i.nodes().forEach((n=>{const r=i.node(n);o.nodes.push({id:n,data:r}),t&&e.mergeNodeData(n,r)})),i.edges().forEach((n=>{const r=i.edge(n),{id:a}=r,s=Fe(r,["id"]),{v:l,w:u}=n;o.edges.push({id:a,source:l,target:u,data:s}),t&&e.mergeEdgeData(a,s)})),o}))}}nj.defaultOptions={};class rj{constructor(t){this.id=t.id||0,this.rx=t.rx,this.ry=t.ry,this.fx=0,this.fy=0,this.mass=t.mass,this.degree=t.degree,this.g=t.g||0}distanceTo(t){const e=this.rx-t.rx,n=this.ry-t.ry;return Math.hypot(e,n)}setPos(t,e){this.rx=t,this.ry=e}resetForce(){this.fx=0,this.fy=0}addForce(t){const e=t.rx-this.rx,n=t.ry-this.ry;let r=Math.hypot(e,n);r=r<1e-4?1e-4:r;const i=this.g*(this.degree+1)*(t.degree+1)/r;this.fx+=i*e/r,this.fy+=i*n/r}in(t){return t.contains(this.rx,this.ry)}add(t){const e=this.mass+t.mass,n=(this.rx*this.mass+t.rx*t.mass)/e,r=(this.ry*this.mass+t.ry*t.mass)/e,i=this.degree+t.degree;return new rj({rx:n,ry:r,mass:e,degree:i})}}class ij{constructor(t){this.xmid=t.xmid,this.ymid=t.ymid,this.length=t.length,this.massCenter=t.massCenter||[0,0],this.mass=t.mass||1}getLength(){return this.length}contains(t,e){const n=this.length/2;return t<=this.xmid+n&&t>=this.xmid-n&&e<=this.ymid+n&&e>=this.ymid-n}NW(){const t=this.xmid-this.length/4,e=this.ymid+this.length/4,n=this.length/2;return new ij({xmid:t,ymid:e,length:n})}NE(){const t=this.xmid+this.length/4,e=this.ymid+this.length/4,n=this.length/2;return new ij({xmid:t,ymid:e,length:n})}SW(){const t=this.xmid-this.length/4,e=this.ymid-this.length/4,n=this.length/2;return new ij({xmid:t,ymid:e,length:n})}SE(){const t=this.xmid+this.length/4,e=this.ymid-this.length/4,n=this.length/2;return new ij({xmid:t,ymid:e,length:n})}}class oj{constructor(t){this.body=null,this.quad=null,this.NW=null,this.NE=null,this.SW=null,this.SE=null,this.theta=.5,null!=t&&(this.quad=t)}insert(t){null!=this.body?this._isExternal()?(this.quad&&(this.NW=new oj(this.quad.NW()),this.NE=new oj(this.quad.NE()),this.SW=new oj(this.quad.SW()),this.SE=new oj(this.quad.SE())),this._putBody(this.body),this._putBody(t),this.body=this.body.add(t)):(this.body=this.body.add(t),this._putBody(t)):this.body=t}_putBody(t){this.quad&&(t.in(this.quad.NW())&&this.NW?this.NW.insert(t):t.in(this.quad.NE())&&this.NE?this.NE.insert(t):t.in(this.quad.SW())&&this.SW?this.SW.insert(t):t.in(this.quad.SE())&&this.SE&&this.SE.insert(t))}_isExternal(){return null==this.NW&&null==this.NE&&null==this.SW&&null==this.SE}updateForce(t){if(null!=this.body&&t!==this.body)if(this._isExternal())t.addForce(this.body);else{(this.quad?this.quad.getLength():0)/this.body.distanceTo(t)bb(t,[a,s]))),f=r.filter((t=>{const{source:e,target:n}=t;return e!==n})),p=new ev({nodes:d,edges:f}),g=this.getSizes(p,c);if(this.run(p,e,u,g,t,o),l){for(let t=0;t250&&(n.barnesHut=!0),void 0===s&&e>100&&(n.prune=!0),0!==l||s?0===l&&s&&(n.maxIteration=100,e<=200&&e>100?n.maxIteration=500:e>200&&(n.maxIteration=950)):(n.maxIteration=250,e<=200&&e>100?n.maxIteration=1e3:e>200&&(n.maxIteration=1200)),u||(n.kr=50,e>100&&e<=500?n.kr=20:e>500&&(n.kr=1)),c||(n.kg=20,e>100&&e<=500?n.kg=10:e>500&&(n.kg=1)),n}run(t,e,n,r,i,o){const{kr:a,barnesHut:s,onTick:l}=o,u=t.getAllNodes();let c=0,h=n;const d={},f={},p={};for(let e=0;e0;)c=this.oneStep(t,{iter:h,preventOverlapIters:50,krPrime:100,sg:c,forces:d,preForces:f,bodies:p,sizes:r},o),h--,null==l||l({nodes:u,edges:e.getAllEdges()});return t}oneStep(t,e,n){const{iter:r,preventOverlapIters:i,krPrime:o,sg:a,preForces:s,bodies:l,sizes:u}=e;let{forces:c}=e;const{preventOverlap:h,barnesHut:d}=n,f=t.getAllNodes();for(let t=0;ti||!h)?this.getOptRepGraForces(t,c,l,n):this.getRepGraForces(t,r,i,c,o,u,n),this.updatePos(t,c,s,a,n)}getAttrForces(t,e,n,r,i,o){const{preventOverlap:a,dissuadeHubs:s,mode:l,prune:u}=o,c=t.getAllEdges();for(let o=0;o0&&(b=y,x=y),i[h][0]+=b*m[0],i[d][0]-=x*m[0],i[h][1]+=b*m[1],i[d][1]-=x*m[1]}return i}getOptRepGraForces(t,e,n,r){const{kg:i,center:o,prune:a}=r,s=t.getAllNodes(),l=s.length;let u=9e10,c=-9e10,h=9e10,d=-9e10;for(let e=0;e=c&&(c=i.x),i.x<=u&&(u=i.x),i.y>=d&&(d=i.y),i.y<=h&&(h=i.y))}const f=Math.max(c-u,d-h),p=new ij({xmid:(c+u)/2,ymid:(d+h)/2,length:f,massCenter:o,mass:l}),g=new oj(p);for(let e=0;e0&&(m=l*(g+1)*(c+1)/v),r[p.id][0]-=m*f[0],r[a.id][0]+=m*f[0],r[p.id][1]-=m*f[1],r[a.id][1]+=m*f[1]}const v=[p.data.x-c[0],p.data.y-c[1]],m=Math.hypot(v[0],v[1]);v[0]=v[0]/m,v[1]=v[1]/m;const y=u*(g+1);r[p.id][0]-=y*v[0],r[p.id][1]-=y*v[1]}return r}updatePos(t,e,n,r,i){const{ks:o,tao:a,prune:s,ksmax:l}=i,u=t.getAllNodes(),c=u.length,h=[],d=[];let f=0,p=0,g=r;for(let r=0;r1.5*v?1.5*v:g);for(let n=0;nf?f:c;const p=c*e[r][0],v=c*e[r][1];t.mergeNodeData(r,{x:i.x+p,y:i.y+v})}return g}}const lj={maxIteration:1e3,gravity:10,speed:5,clustering:!1,clusterGravity:10,width:300,height:300,nodeClusterBy:"cluster"};class uj{constructor(t={}){this.options=t,this.id="fruchterman",this.timeInterval=0,this.running=!1,this.options=Object.assign(Object.assign({},lj),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericFruchtermanLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericFruchtermanLayout(!0,t,e)}))}stop(){this.timeInterval&&"undefined"!=typeof window&&window.clearInterval(this.timeInterval),this.running=!1}tick(t=this.options.maxIteration||1){if(this.lastResult)return this.lastResult;for(let e=0;ethis.lastGraph.mergeNodeData(t.id,{x:t.data.x,y:t.data.y,z:3===this.options.dimensions?t.data.z:void 0}))),e}genericFruchtermanLayout(t,e,n){return ze(this,void 0,void 0,(function*(){if(this.running)return;const r=this.formatOptions(n),{dimensions:i,width:o,height:a,center:s,clustering:l,nodeClusterBy:u,maxIteration:c,onTick:h}=r,d=e.getAllNodes(),f=e.getAllEdges();if(!(null==d?void 0:d.length)){const t={nodes:[],edges:f};return this.lastResult=t,t}if(1===d.length){t&&e.mergeNodeData(d[0].id,{x:s[0],y:s[1],z:3===i?s[2]:void 0});const n={nodes:[Object.assign(Object.assign({},d[0]),{data:Object.assign(Object.assign({},d[0].data),{x:s[0],y:s[1],z:3===i?s[2]:void 0})})],edges:f};return this.lastResult=n,n}const p=d.map((t=>bb(t,[o,a]))),g=new ev({nodes:p,edges:f}),v={};if(l&&p.forEach((t=>{const e=t.data[u];v[e]||(v[e]={name:e,cx:0,cy:0,count:0})})),this.lastLayoutNodes=p,this.lastLayoutEdges=f,this.lastAssign=t,this.lastGraph=g,this.lastOptions=r,this.lastClusterMap=v,"undefined"==typeof window)return;let m=0;return new Promise((n=>{this.timeInterval=window.setInterval((()=>{this.running?(this.runOneStep(g,v,r),t&&p.forEach((({id:t,data:n})=>e.mergeNodeData(t,{x:n.x,y:n.y,z:3===i?n.z:void 0}))),null==h||h({nodes:p,edges:f}),m++,m>=c&&(window.clearInterval(this.timeInterval),n({nodes:p,edges:f}))):n({nodes:p,edges:f})}),0),this.running=!0}))}))}formatOptions(t={}){const e=Object.assign(Object.assign({},this.options),t),{clustering:n,nodeClusterBy:r}=e,{center:i,width:o,height:a}=e;return e.width=o||"undefined"==typeof window?o:window.innerWidth,e.height=a||"undefined"==typeof window?a:window.innerHeight,e.center=i||[e.width/2,e.height/2],e.clustering=n&&!!r,e}runOneStep(t,e,n){const{dimensions:r,height:i,width:o,gravity:a,center:s,speed:l,clustering:u,nodeClusterBy:c,clusterGravity:h}=n,d=i*o,f=Math.sqrt(d)/10,p=t.getAllNodes(),g=d/(p.length+1),v=Math.sqrt(g),m={};if(this.applyCalculate(t,m,v,g),u){for(const t in e)e[t].cx=0,e[t].cy=0,e[t].count=0;p.forEach((t=>{const{data:n}=t,r=e[n[c]];ae(n.x)&&(r.cx+=n.x),ae(n.y)&&(r.cy+=n.y),r.count++}));for(const t in e)e[t].cx/=e[t].count,e[t].cy/=e[t].count;const t=h||a;p.forEach(((n,r)=>{const{id:i,data:o}=n;if(!ae(o.x)||!ae(o.y))return;const a=e[o[c]],s=Math.sqrt((o.x-a.cx)*(o.x-a.cx)+(o.y-a.cy)*(o.y-a.cy)),l=v*t;m[i].x-=l*(o.x-a.cx)/s,m[i].y-=l*(o.y-a.cy)/s}))}p.forEach(((t,e)=>{const{id:n,data:i}=t;if(!ae(i.x)||!ae(i.y))return;const o=.01*v*a;m[n].x-=o*(i.x-s[0]),m[n].y-=o*(i.y-s[1]),3===r&&(m[n].z-=o*(i.z-s[2]))})),p.forEach(((e,n)=>{const{id:i,data:o}=e;if(ae(o.fx)&&ae(o.fy))return o.x=o.fx,o.y=o.fy,void(3===r&&(o.z=o.fz));if(!ae(o.x)||!ae(o.y))return;const a=Math.sqrt(m[i].x*m[i].x+m[i].y*m[i].y+(3===r?m[i].z*m[i].z:0));if(a>0){const e=Math.min(f*(l/800),a);t.mergeNodeData(i,{x:o.x+m[i].x/a*e,y:o.y+m[i].y/a*e,z:3===r?o.z+m[i].z/a*e:void 0})}}))}applyCalculate(t,e,n,r){this.calRepulsive(t,e,r),this.calAttractive(t,e,n)}calRepulsive(t,e,n){const r=t.getAllNodes();r.forEach((({data:t,id:i},o)=>{e[i]={x:0,y:0,z:0},r.forEach((({data:r,id:a},s)=>{if(o<=s||!ae(t.x)||!ae(r.x)||!ae(t.y)||!ae(r.y))return;let l=t.x-r.x,u=t.y-r.y,c=3===this.options.dimensions?t.z-r.z:0,h=l*l+u*u+c*c;0===h&&(h=1,l=.01,u=.01,c=.01);const d=n/h,f=l*d,p=u*d,g=c*d;e[i].x+=f,e[i].y+=p,e[a].x-=f,e[a].y-=p,3===this.options.dimensions&&(e[i].z+=g,e[a].z-=g)}))}))}calAttractive(t,e,n){t.getAllEdges().forEach((r=>{const{source:i,target:o}=r;if(!i||!o||i===o)return;const{data:a}=t.getNode(i),{data:s}=t.getNode(o);if(!(ae(s.x)&&ae(a.x)&&ae(s.y)&&ae(a.y)))return;const l=s.x-a.x,u=s.y-a.y,c=3===this.options.dimensions?s.z-a.z:0,h=Math.sqrt(l*l+u*u+c*c)/n,d=l*h,f=u*h,p=c*h;e[i].x+=d,e[i].y+=f,e[o].x-=d,e[o].y-=f,3===this.options.dimensions&&(e[i].z+=p,e[o].z-=p)}))}}const cj={begin:[0,0],preventOverlap:!0,preventOverlapPadding:10,condense:!1,rows:void 0,cols:void 0,position:void 0,sortBy:"degree",nodeSize:30,width:300,height:300};class hj{constructor(t={}){this.options=t,this.id="grid",this.options=Object.assign(Object.assign({},cj),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericGridLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericGridLayout(!0,t,e)}))}genericGridLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{begin:i=[0,0],condense:o,preventOverlapPadding:a,preventOverlap:s,rows:l,cols:u,nodeSpacing:c,nodeSize:h,width:d,height:f,position:p}=r;let{sortBy:g}=r;const v=e.getAllNodes(),m=e.getAllEdges(),y=null==v?void 0:v.length;if(!y||1===y)return Ob(e,t,i);const b=v.map((t=>bb(t)));"id"===g||ne(g)&&void 0!==b[0].data[g]||(g="degree"),"degree"===g?b.sort(((t,n)=>e.getDegree(n.id,"both")-e.getDegree(t.id,"both"))):"id"===g?b.sort(((t,e)=>ae(e.id)&&ae(t.id)?e.id-t.id:`${t.id}`.localeCompare(`${e.id}`))):b.sort(((t,e)=>e.data[g]-t.data[g]));const x=d||"undefined"==typeof window?d:window.innerWidth,E=f||"undefined"==typeof window?f:window.innerHeight,w=y,k={rows:l,cols:u};if(null!=l&&null!=u)k.rows=l,k.cols=u;else if(null!=l&&null==u)k.rows=l,k.cols=Math.ceil(w/k.rows);else if(null==l&&null!=u)k.cols=u,k.rows=Math.ceil(w/k.cols);else{const t=Math.sqrt(w*E/x);k.rows=Math.round(t),k.cols=Math.round(x/E*t)}if(k.rows=Math.max(k.rows,1),k.cols=Math.max(k.cols,1),k.cols*k.rows>w){const t=dj(k),e=fj(k);(t-1)*e>=w?dj(k,t-1):(e-1)*t>=w&&fj(k,e-1)}else for(;k.cols*k.rows=w?fj(k,e+1):dj(k,t+1)}let M=o?0:x/k.cols,S=o?0:E/k.rows;if(s||c){const t=Eb(10,c),n=wb(30,h,!1);b.forEach((r=>{r.data.x&&r.data.y||(r.data.x=0,r.data.y=0);const i=e.getNode(r.id),[o,s]=xb(n(i)||30),l=void 0!==t?t(r):a,u=o+l,c=s+l;M=Math.max(M,u),S=Math.max(S,c)}))}const N={},O={row:0,col:0},T={};for(let t=0;t{e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})})),C}))}}const dj=(t,e)=>{let n;const r=t.rows||5,i=t.cols||5;if(null==e)n=Math.min(r,i);else{Math.min(r,i)===t.rows?t.rows=e:t.cols=e}return n},fj=(t,e)=>{let n;const r=t.rows||5,i=t.cols||5;if(null==e)n=Math.max(r,i);else{Math.max(r,i)===t.rows?t.rows=e:t.cols=e}return n},pj=(t,e)=>t[`c-${e.row}-${e.col}`]||!1,gj=(t,e)=>t[`c-${e.row}-${e.col}`]=!0,vj=(t,e)=>{const n=t.cols||5;e.col++,e.col>=n&&(e.col=0,e.row++)},mj=(t,e,n,r,i,o,a,s)=>{let l,u;const c=i[t.id];if(c)l=c.col*n+n/2+e[0],u=c.row*r+r/2+e[1];else{for(;pj(s,a);)vj(o,a);l=a.col*n+n/2+e[0],u=a.row*r+r/2+e[1],gj(s,a),vj(o,a)}t.data.x=l,t.data.y=u},yj={iterations:10,height:10,width:10,speed:100,gravity:10,k:5},bj=(t,e,n,r,i,o)=>{e.forEach(((a,s)=>{n[s]={x:0,y:0},e.forEach(((e,l)=>{if(s===l)return;if(i[s]!==i[l])return;let u=a.x-e.x,c=a.y-e.y,h=Math.sqrt(u*u+c*c);if(0===h){h=1;const t=s>l?1:-1;u=.01*t,c=.01*t}if(h{const l=o||a/10;return r&&e.forEach(((e,n)=>{const r=t[n].x-t[i].x,o=t[n].y-t[i].y,a=Math.sqrt(r*r+o*o);let s=o/a,l=-r/a;const u=Math.sqrt(e.x*e.x+e.y*e.y);let c=Math.acos((s*e.x+l*e.y)/u);c>Math.PI/2&&(c-=Math.PI/2,s*=-1,l*=-1);const h=Math.cos(c)*u;e.x=s*h,e.y=l*h})),t.forEach(((o,a)=>{if(a===i)return;const u=Math.sqrt(e[a].x*e[a].x+e[a].y*e[a].y);if(u>0&&a!==i){const c=Math.min(l*(n/800),u);if(o.x+=e[a].x/u*c,o.y+=e[a].y/u*c,r){let e=o.x-t[i].x,n=o.y-t[i].y;const r=Math.sqrt(e*e+n*n);e=e/r*s[a],n=n/r*s[a],o.x=t[i].x+e,o.y=t[i].y+n}}})),t},Ej={maxIteration:1e3,focusNode:null,unitRadius:null,linkDistance:50,preventOverlap:!1,strictRadial:!0,maxPreventOverlapIteration:200,sortStrength:10};class wj{constructor(t={}){this.options=t,this.id="radial",this.options=Object.assign(Object.assign({},Ej),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericRadialLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericRadialLayout(!0,t,e)}))}genericRadialLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{width:i,height:o,center:a,focusNode:s,unitRadius:l,nodeSize:u,nodeSpacing:c,strictRadial:h,preventOverlap:d,maxPreventOverlapIteration:f,sortBy:p,linkDistance:g=50,sortStrength:v=10,maxIteration:m=1e3}=r,y=e.getAllNodes(),b=e.getAllEdges(),x=i||"undefined"==typeof window?i:window.innerWidth,E=o||"undefined"==typeof window?o:window.innerHeight,w=a||[x/2,E/2];if(!(null==y?void 0:y.length)||1===y.length)return Ob(e,t,w);let k=y[0];if(ne(s)){for(let t=0;tw[0]?w[0]:x-w[0],A=E-w[1]>w[1]?w[1]:E-w[1];0===C&&(C=x/2),0===A&&(A=E/2);const P=Math.min(C,A),R=Math.max(...T),D=[],L=l||P/R;T.forEach(((t,e)=>{D[e]=t*L}));const _=kj(y,N,g,D,L,p,v),I=Mj(_),j=((t,e,n)=>{try{const n=tE.mul(tE.pow(e,2),-.5),r=n.mean("row"),i=n.mean("column"),o=n.mean();n.add(o).subRowVector(r).subColumnVector(i);const a=new eE(n),s=tE.sqrt(a.diagonalMatrix).diagonal();return a.leftSingularVectors.toJSON().map((e=>tE.mul([e],[s]).toJSON()[0].splice(0,t)))}catch(t){const r=[];for(let t=0;t({x:(isNaN(t)?Math.random()*g:t)-j[M][0],y:(isNaN(e)?Math.random()*g:e)-j[M][1]})));if(this.run(m,F,I,_,D,M),d){B=kb(u,c);const t={nodes:y,nodeSizeFunc:B,positions:F,radii:D,height:E,width:x,strictRadial:Boolean(h),focusIdx:M,iterations:f||200,k:F.length/4.5};F=((t,e)=>{const n=Object.assign(Object.assign({},yj),e),{positions:r,iterations:i,width:o,k:a,speed:s=100,strictRadial:l,focusIdx:u,radii:c=[],nodeSizeFunc:h}=n,d=t.getAllNodes(),f=[],p=o/10;for(let t=0;t{f[e]={x:0,y:0}})),bj(d,r,f,a,c,h),xj(r,f,s,l,u,p,o,c);return r})(e,t)}const z=[];F.forEach(((t,e)=>{const n=bb(y[e]);n.data.x=t.x+w[0],n.data.y=t.y+w[1],z.push(n)})),t&&z.forEach((t=>e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})));return{nodes:z,edges:b}}))}run(t,e,n,r,i,o){for(let a=0;a<=t;a++){const s=a/t;this.oneIteration(s,e,i,r,n,o)}}oneIteration(t,e,n,r,i,o){const a=1-t;e.forEach(((s,l)=>{const u=vb(s,{x:0,y:0}),c=0===u?0:1/u;if(l===o)return;let h=0,d=0,f=0;e.forEach(((t,e)=>{if(l===e)return;const n=vb(s,t),o=0===n?0:1/n,a=r[e][l];f+=i[l][e],h+=i[l][e]*(t.x+a*(s.x-t.x)*o),d+=i[l][e]*(t.y+a*(s.y-t.y)*o)}));const p=0===n[l]?0:1/n[l];f*=a,f+=t*p*p,h*=a,h+=t*p*s.x*c,s.x=h/f,d*=a,d+=t*p*s.y*c,s.y=d/f}))}}const kj=(t,e,n,r,i,o,a)=>{if(!t)return[];const s=[];if(e){const l={};e.forEach(((e,u)=>{const c=[];e.forEach(((e,s)=>{var h,d;if(u===s)c.push(0);else if(r[u]===r[s])if("data"===o)c.push(e*(Math.abs(u-s)*a)/(r[u]/i));else if(o){let n,f;if(l[t[u].id])n=l[t[u].id];else{const e=("id"===o?t[u].id:null===(h=t[u].data)||void 0===h?void 0:h[o])||0;n=ne(e)?e.charCodeAt(0):e,l[t[u].id]=n}if(l[t[s].id])f=l[t[s].id];else{const e=("id"===o?t[s].id:null===(d=t[s].data)||void 0===d?void 0:d[o])||0;f=ne(e)?e.charCodeAt(0):e,l[t[s].id]=f}c.push(e*(Math.abs(n-f)*a)/(r[u]/i))}else c.push(e*n/(r[u]/i));else{const t=(n+i)/2;c.push(e*t)}})),s.push(c)}))}return s},Mj=t=>{const e=t.length,n=t[0].length,r=[];for(let i=0;i{let n=-1;return t.forEach(((t,r)=>{t.id===e&&(n=r)})),Math.max(n,0)},Nj=(t,e,n)=>{const r=t.length;for(let i=0;i{let n=0;for(let r=0;rn?t[e][r]:n);return n},Tj={center:[0,0],width:300,height:300};class Cj{constructor(t={}){this.options=t,this.id="random",this.options=Object.assign(Object.assign({},Tj),t)}execute(t,e){return ze(this,void 0,void 0,(function*(){return this.genericRandomLayout(!1,t,e)}))}assign(t,e){return ze(this,void 0,void 0,(function*(){yield this.genericRandomLayout(!0,t,e)}))}genericRandomLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const r=Object.assign(Object.assign({},this.options),n),{center:i,width:o,height:a}=r,s=e.getAllNodes(),l=o||"undefined"==typeof window?o:window.innerWidth,u=a||"undefined"==typeof window?a:window.innerHeight,c=i||[l/2,u/2],h=[];s&&s.forEach((t=>{h.push({id:t.id,data:{x:.9*(Math.random()-.5)*l+c[0],y:.9*(Math.random()-.5)*u+c[1]}})})),t&&h.forEach((t=>e.mergeNodeData(t.id,{x:t.data.x,y:t.data.y})));return{nodes:h,edges:e.getAllEdges()}}))}} -/** - * @license - * Copyright 2019 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */const Aj=Symbol("Comlink.proxy"),Pj=Symbol("Comlink.endpoint"),Rj=Symbol("Comlink.releaseProxy"),Dj=Symbol("Comlink.finalizer"),Lj=Symbol("Comlink.thrown"),_j=t=>"object"==typeof t&&null!==t||"function"==typeof t,Ij=new Map([["proxy",{canHandle:t=>_j(t)&&t[Aj],serialize(t){const{port1:e,port2:n}=new MessageChannel;return jj(t,e),[n,[n]]},deserialize:t=>(t.start(),Fj(t))}],["throw",{canHandle:t=>_j(t)&&Lj in t,serialize({value:t}){let e;return e=t instanceof Error?{isError:!0,value:{message:t.message,name:t.name,stack:t.stack}}:{isError:!1,value:t},[e,[]]},deserialize(t){if(t.isError)throw Object.assign(new Error(t.value.message),t.value);throw t.value}}]]);function jj(t,e=globalThis,n=["*"]){e.addEventListener("message",(function r(i){if(!i||!i.data)return;if(!function(t,e){for(const n of t){if(e===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(e))return!0}return!1}(n,i.origin))return void console.warn(`Invalid origin '${i.origin}' for comlink proxy`);const{id:o,type:a,path:s}=Object.assign({path:[]},i.data),l=(i.data.argumentList||[]).map(qj);let u;try{const e=s.slice(0,-1).reduce(((t,e)=>t[e]),t),n=s.reduce(((t,e)=>t[e]),t);switch(a){case"GET":u=n;break;case"SET":e[s.slice(-1)[0]]=qj(i.data.value),u=!0;break;case"APPLY":u=n.apply(e,l);break;case"CONSTRUCT":u=function(t){return Object.assign(t,{[Aj]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:e,port2:n}=new MessageChannel;jj(t,n),u=function(t,e){return $j.set(t,e),t}(e,[e])}break;case"RELEASE":u=void 0;break;default:return}}catch(t){u={value:t,[Lj]:0}}Promise.resolve(u).catch((t=>({value:t,[Lj]:0}))).then((n=>{const[i,s]=Yj(n);e.postMessage(Object.assign(Object.assign({},i),{id:o}),s),"RELEASE"===a&&(e.removeEventListener("message",r),Bj(e),Dj in t&&"function"==typeof t[Dj]&&t[Dj]())})).catch((t=>{const[n,r]=Yj({value:new TypeError("Unserializable return value"),[Lj]:0});e.postMessage(Object.assign(Object.assign({},n),{id:o}),r)}))})),e.start&&e.start()}function Bj(t){(function(t){return"MessagePort"===t.constructor.name})(t)&&t.close()}function Fj(t,e){const n=new Map;return t.addEventListener("message",(function(t){const{data:e}=t;if(!e||!e.id)return;const r=n.get(e.id);if(r)try{r(e)}finally{n.delete(e.id)}})),Hj(t,n,[],e)}function zj(t){if(t)throw new Error("Proxy has been released and is not useable")}function Gj(t){return Xj(t,new Map,{type:"RELEASE"}).then((()=>{Bj(t)}))}const Vj=new WeakMap,Wj="FinalizationRegistry"in globalThis&&new FinalizationRegistry((t=>{const e=(Vj.get(t)||0)-1;Vj.set(t,e),0===e&&Gj(t)}));function Hj(t,e,n=[],r=function(){}){let i=!1;const o=new Proxy(r,{get(r,a){if(zj(i),a===Rj)return()=>{!function(t){Wj&&Wj.unregister(t)}(o),Gj(t),e.clear(),i=!0};if("then"===a){if(0===n.length)return{then:()=>o};const r=Xj(t,e,{type:"GET",path:n.map((t=>t.toString()))}).then(qj);return r.then.bind(r)}return Hj(t,e,[...n,a])},set(r,o,a){zj(i);const[s,l]=Yj(a);return Xj(t,e,{type:"SET",path:[...n,o].map((t=>t.toString())),value:s},l).then(qj)},apply(r,o,a){zj(i);const s=n[n.length-1];if(s===Pj)return Xj(t,e,{type:"ENDPOINT"}).then(qj);if("bind"===s)return Hj(t,e,n.slice(0,-1));const[l,u]=Uj(a);return Xj(t,e,{type:"APPLY",path:n.map((t=>t.toString())),argumentList:l},u).then(qj)},construct(r,o){zj(i);const[a,s]=Uj(o);return Xj(t,e,{type:"CONSTRUCT",path:n.map((t=>t.toString())),argumentList:a},s).then(qj)}});return function(t,e){const n=(Vj.get(e)||0)+1;Vj.set(e,n),Wj&&Wj.register(t,e,t)}(o,t),o}function Uj(t){const e=t.map(Yj);return[e.map((t=>t[0])),(n=e.map((t=>t[1])),Array.prototype.concat.apply([],n))];var n}const $j=new WeakMap;function Yj(t){for(const[e,n]of Ij)if(n.canHandle(t)){const[r,i]=n.serialize(t);return[{type:"HANDLER",name:e,value:r},i]}return[{type:"RAW",value:t},$j.get(t)||[]]}function qj(t){switch(t.type){case"HANDLER":return Ij.get(t.name).deserialize(t.value);case"RAW":return t.value}}function Xj(t,e,n,r){return new Promise((i=>{const o=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.set(o,i),t.start&&t.start(),t.postMessage(Object.assign({id:o},n),r)}))}class Kj extends Kg{constructor(t,e,n){super(),this.graph=t,this.layout=e,this.options=n,this.spawnWorker()}spawnWorker(){this.proxy=Fj(new Worker(new URL("./worker.js","undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(__filename).href:"undefined"==typeof document?location.href:e&&"SCRIPT"===e.tagName.toUpperCase()&&e.src||new URL("g6.min.js",document.baseURI).href),{type:"module"})),this.running&&(this.running=!1,this.execute())}execute(){var t;return ze(this,void 0,void 0,(function*(){if(this.running)return this;this.running=!0;const e=this.layout.options,{onTick:n}=e,r=Fe(e,["onTick"]),i={};Object.keys(r).forEach((t=>{Ut(r[t])||(i[t]=r[t])}));const o={layout:{id:this.layout.id,options:i,iterations:null===(t=this.options)||void 0===t?void 0:t.iterations},nodes:this.graph.getAllNodes(),edges:this.graph.getAllEdges()},a=new Float32Array([0]),[s]=yield this.proxy.calculateLayout(o,[a]);return s}))}stop(){return this.running=!1,this.proxy.stopLayout(),this}kill(){this.proxy[Rj]()}isRunning(){return this.running}}class Zj extends nv{constructor(){super(...arguments),this.id="fishbone"}getRoot(){const t=this.context.model.getRootsData();if(!(Se(t)||t.length>2))return t[0]}formatSize(t){const e="function"==typeof t?t:()=>t;return t=>Gd(e(t))}doLayout(t,e){const{hGap:n,getRibSep:r,vGap:i,nodeSize:o,height:a}=e,{model:s}=this.context,l=this.formatSize(o);let u=l(t)[0]+r(t);const c=(t,e=0)=>{var r;return e+=n*((t.children||[]).length+1),null===(r=t.children)||void 0===r||r.forEach((t=>{var n;null===(n=s.getNodeLikeDatum(t).children)||void 0===n||n.forEach((t=>{const n=s.getNodeLikeDatum(t);e=c(n,e)}))})),e},h=t=>{if(1===t.depth)return u;const e=s.getParentData(t.id,"tree");if(tB(t)){const r=s.getParentData(e.id,"tree"),o=p(t)-p(r);return h(e)+o*n/i}{const n=(e.children||[]).indexOf(t.id),r=s.getNodeData((e.children||[]).slice(n));return d(e)-r.reduce(((t,e)=>t+c(e)),0)-l(e)[0]/2}},d=xe((t=>{if(Jj(t))return l(t)[0]/2;const e=s.getParentData(t.id,"tree");if(tB(t))return h(t)+c(t)+l(t)[0]/2;{const r=p(t)-p(e),o=n/i;return h(t)+r*o}}),(t=>t.id)),f=t=>p(s.getParentData(t,"tree")),p=xe((t=>{if(Jj(t))return a/2;if(tB(t)){const e=s.getParentData(t.id,"tree"),n=e.children.indexOf(t.id);if(0===n)return f(e.id)+i;const r=s.getNodeLikeDatum(e.children[n-1]);if(Se(r.children))return p(r)+i;const o=s.getDescendantsData(r.id);return Math.max(...o.map((t=>tB(t)?f(t.id):p(t))))+i}{if(Se(t.children))return f(t.id)+i;const e=s.getNodeLikeDatum(t.children.slice(-1)[0]);if(Se(e.children))return p(e)+i;const n=s.getDescendantsData(t.id).slice(-1)[0];return(tB(n)?f(n.id):p(n))+i}}),(t=>t.id));let g=0;const v={nodes:[],edges:[]},m=t=>{var e;null===(e=t.children)||void 0===e||e.forEach((t=>m(s.getNodeLikeDatum(t))));const n=p(t),i=d(t);if(v.nodes.push({id:t.id,x:i,y:n}),Jj(t))return;const o=s.getRelatedEdgesData(t.id,"in")[0],a=[h(t),tB(t)?n:f(t.id)];v.edges.push({id:Nh(o),controlPoints:[a],relatedNodeId:t.id}),g=Math.max(g,i+r(t)),1===t.depth&&(u=g)};return m(t),v}placeAlterative(t,e){const n=(e.children||[]).filter(((t,e)=>e%2!=0));if(0===n.length)return t;const{model:r}=this.context,i=t.nodes.find((t=>t.id===e.id)).y,o=t=>{const e=r.getAncestorsData(t,"tree");if(Se(e))return!1;const i=1===e.length?t:e[e.length-2].id;return n.includes(i)};t.nodes.forEach((t=>{o(t.id)&&(t.y=2*i-t.y)})),t.edges.forEach((t=>{o(t.relatedNodeId)&&(t.controlPoints=t.controlPoints.map((t=>[t[0],2*i-t[1]])))}))}rightToLeft(t,e){return t.nodes.forEach((t=>t.x=e.width-t.x)),t.edges.forEach((t=>{t.controlPoints=t.controlPoints.map((t=>[e.width-t[0],t[1]]))})),t}execute(t,e){return ze(this,void 0,void 0,(function*(){const n=Object.assign(Object.assign(Object.assign({},Zj.defaultOptions),this.options),e),{direction:r,nodeSize:i}=n,o=this.getRoot();if(!o)return t;const a=this.formatSize(i);n.vGap||(n.vGap=Math.max(...(t.nodes||[]).map((t=>a(t)[1])))),n.hGap||(n.hGap=Math.max(...(t.nodes||[]).map((t=>a(t)[0]))));let s=this.doLayout(o,n);this.placeAlterative(s,o),"RL"===r&&(s=this.rightToLeft(s,n));const{model:l}=this.context,u=[],c=[];return s.nodes.forEach((t=>{const{id:e,x:n,y:r}=t,i=l.getNodeLikeDatum(e);u.push(Qj(i,{x:n,y:r}))})),s.edges.forEach((t=>{const{id:e,controlPoints:n}=t,r=l.getEdgeDatum(e);c.push(Qj(r,{controlPoints:n}))})),{nodes:u,edges:c}}))}}Zj.defaultOptions={direction:"RL",getRibSep:()=>60};const Qj=(t,e)=>Object.assign(Object.assign({},t),{style:Object.assign(Object.assign({},t.style||{}),e)}),Jj=t=>0===t.depth,tB=t=>(t.depth||(t.depth=0))%2==0;class eB extends nv{constructor(){super(...arguments),this.id="snake"}formatSize(t,e){const n="function"==typeof e?e:()=>e;return t.reduce(((t,e)=>{const[r,i]=Gd(n(e))||[0,0];return[Math.max(t[0],r),Math.max(t[1],i)]}),[0,0])}validate(t){const{nodes:e=[],edges:n=[]}=t,r={},i={},o={};e.forEach((t=>{r[t.id]=0,i[t.id]=0,o[t.id]=[]})),n.forEach((t=>{r[t.target]++,i[t.source]++,o[t.source].push(t.target)}));const a=new Set,s=t=>{a.has(t)||(a.add(t),o[t].forEach(s))};if(s(e[0].id),a.size!==e.length)return!1;const l=e.filter((t=>0===r[t.id])),u=e.filter((t=>0===i[t.id]));if(1!==l.length||1!==u.length)return!1;return e.filter((t=>1===r[t.id]&&1===i[t.id])).length===e.length-2}execute(t,e){return ze(this,void 0,void 0,(function*(){var n;if(!this.validate(t))return t;const{nodeSize:r,padding:i,sortBy:o,cols:a,colGap:s,rowGap:l,clockwise:u,width:c,height:h}=Object.assign({},eB.defaultOptions,this.options,e),[d,f,p,g]=Jc(i),v=this.formatSize(t.nodes||[],r),m=Math.ceil((t.nodes||[]).length/a);let y=s||(c-g-f-a*v[0])/(a-1),b=l||(h-d-p-m*v[1])/(m-1);(b===1/0||b<0)&&(b=0),(y===1/0||y<0)&&(y=0);const x=o?null===(n=t.nodes)||void 0===n?void 0:n.sort(o):function(t){const{nodes:e=[],edges:n=[]}=t,r={},i={};e.forEach((t=>{r[t.id]=0,i[t.id]=[]})),n.forEach((t=>{r[t.target]++,i[t.source].push(t.target)}));const o=[],a=[];e.forEach((t=>{0===r[t.id]&&o.push(t.id)}));for(;o.length>0;){const t=o.shift(),n=e.find((e=>e.id===t));a.push(n),i[t].forEach((t=>{r[t]--,0===r[t]&&o.push(t)}))}return a}(t),E=(x||[]).map(((t,e)=>{const n=Math.floor(e/a),r=e%a,i=g+(u?n%2==0?r:a-1-r:n%2==0?a-1-r:r)*(v[0]+y)+v[0]/2,o=d+n*(v[1]+b)+v[1]/2;return{id:t.id,style:{x:i,y:o}}}));return{nodes:E}}))}}eB.defaultOptions={padding:0,cols:5,clockwise:!0};class nB extends zh{}function rB(t,e=!0,n){const r=document.createElement("div");return r.setAttribute("class",`g6-${t}`),Object.assign(r.style,{position:"absolute",display:"block"}),e&&Object.assign(r.style,{position:"unset",gridArea:"1 / 1 / 2 / 2",inset:"0px",height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none"}),n&&Object.assign(r.style,n),r}function iB(t,e="div",n={},r="",i=document.body){const o=document.getElementById(t);o&&o.remove();const a=document.createElement(e);return a.innerHTML=r,a.id=t,Object.assign(a.style,n),i.appendChild(a),a}class oB extends nB{constructor(t,e){super(t,Object.assign({},oB.defaultOptions,e)),this.$element=rB("background");this.context.canvas.getContainer().prepend(this.$element),this.update(e)}update(t){const e=Object.create(null,{update:{get:()=>super.update}});return ze(this,void 0,void 0,(function*(){e.update.call(this,t),Object.assign(this.$element.style,Pe(this.options,["key","type"]))}))}destroy(){super.destroy(),this.$element.remove()}}function aB(t,e,n,r,i,o){const a=n-t,s=r-e;let l=i-t,u=o-e,c=l*a+u*s,h=0;c<=0?h=0:(l=a-l,u=s-u,c=l*a+u*s,h=c<=0?0:c*c/(a*a+s*s));const d=l*l+u*u-h;return d<0?0:d}function sB(t,e,n,r){return(t-n)*(t-n)+(e-r)*(e-r)}function lB(t,e,n,r,i){return sB(t,e,n,r)this.y1&&e>=this.y2)return!1;if(t>this.x1&&t>=this.x2)return!1;if(tthis.x2+n)return!1}else if(tthis.x1+n)return!1;if(this.y1this.y2+n)return!1}else if(ethis.y1+n)return!1;return!0}}var hB,dB;!function(t){t[t.POINT=1]="POINT",t[t.PARALLEL=2]="PARALLEL",t[t.COINCIDENT=3]="COINCIDENT",t[t.NONE=4]="NONE"}(hB||(hB={}));class fB{constructor(t,e=0,n=0){this.state=t,this.x=e,this.y=n}}function pB(t,e){const n=(e.x2-e.x1)*(t.y1-e.y1)-(e.y2-e.y1)*(t.x1-e.x1),r=(t.x2-t.x1)*(t.y1-e.y1)-(t.y2-t.y1)*(t.x1-e.x1),i=(e.y2-e.y1)*(t.x2-t.x1)-(e.x2-e.x1)*(t.y2-t.y1);if(i){const e=n/i,o=r/i;return 0<=e&&e<=1&&0<=o&&o<=1?new fB(hB.POINT,t.x1+e*(t.x2-t.x1),t.y1+e*(t.y2-t.y1)):new fB(hB.NONE)}return new fB(0===n||0===r?hB.COINCIDENT:hB.PARALLEL)}function gB(t,e){const n=(e.x2-e.x1)*(t.y1-e.y1)-(e.y2-e.y1)*(t.x1-e.x1),r=(t.x2-t.x1)*(t.y1-e.y1)-(t.y2-t.y1)*(t.x1-e.x1),i=(e.y2-e.y1)*(t.x2-t.x1)-(e.x2-e.x1)*(t.y2-t.y1);if(i){const t=n/i,e=r/i;if(0<=t&&t<=1&&0<=e&&e<=1)return t}return Number.POSITIVE_INFINITY}function vB(t,e,n){const r=new Set;return t.width<=0?(r.add(dB.LEFT),r.add(dB.RIGHT)):et.x+t.width&&r.add(dB.RIGHT),t.height<=0?(r.add(dB.TOP),r.add(dB.BOTTOM)):nt.y+t.height&&r.add(dB.BOTTOM),r}function mB(t,e){let n=e.x1,r=e.y1;const i=e.x2,o=e.y2,a=Array.from(vB(t,i,o));if(0===a.length)return!0;let s=vB(t,n,r);for(;0!==s.size;){for(const t of a)if(s.has(t))return!1;if(s.has(dB.RIGHT)||s.has(dB.LEFT)){let e=t.x;s.has(dB.RIGHT)&&(e+=t.width),r+=(e-n)*(o-r)/(i-n),n=e}else{let e=t.y;s.has(dB.BOTTOM)&&(e+=t.height),n+=(e-r)*(i-n)/(o-r),r=e}s=vB(t,n,r)}return!0}function yB(t,e){let n=Number.POSITIVE_INFINITY,r=0;function i(t,i,o,a){let s=gB(e,new cB(t,i,o,a));s=Math.abs(s-.5),s>=0&&s<=1&&(r++,s1?n:(i(t.x,t.y2,t.x2,t.y2),r>1?n:(i(t.x2,t.y,t.x2,t.y2),0===r?-1:n))}function bB(t,e){let n=0;const r=pB(t,new cB(e.x,e.y,e.x2,e.y));n+=r.state===hB.POINT?1:0;const i=pB(t,new cB(e.x,e.y,e.x,e.y2));n+=i.state===hB.POINT?1:0;const o=pB(t,new cB(e.x,e.y2,e.x2,e.y2));n+=o.state===hB.POINT?1:0;const a=pB(t,new cB(e.x2,e.y,e.x2,e.y2));return n+=a.state===hB.POINT?1:0,{top:r,left:i,bottom:o,right:a,count:n}}!function(t){t[t.LEFT=0]="LEFT",t[t.TOP=1]="TOP",t[t.RIGHT=2]="RIGHT",t[t.BOTTOM=3]="BOTTOM"}(dB||(dB={}));class xB{constructor(t,e,n,r){this.x=t,this.y=e,this.width=n,this.height=r}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new xB(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new xB(this.x,this.y,this.width,this.height)}add(t){const e=Math.min(this.x,t.x),n=Math.min(this.y,t.y),r=Math.max(this.x2,t.x+t.width),i=Math.max(this.y2,t.y+t.height);this.x=e,this.y=n,this.width=r-e,this.height=i-n}addPoint(t){const e=Math.min(this.x,t.x),n=Math.min(this.y,t.y),r=Math.max(this.x2,t.x),i=Math.max(this.y2,t.y);this.x=e,this.y=n,this.width=r-e,this.height=i-n}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return!(this.area<=0||t.width<=0||t.height<=0)&&(t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){const e=this.scaleX(t.x),n=this.scaleY(t.y),r=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),i=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup));return new xB(e,n,r-e,i-n)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){const n=Math.ceil(e/this.pixelGroup),r=this.boundX(t.x-n),i=this.boundY(t.y-n),o=this.boundX(t.x2+n),a=this.boundY(t.y2+n);return new xB(r,i,o-r,a-i)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,n){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=n)}set(t,e,n){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=n)}incArea(t,e){if(t.width<=0||t.height<=0||0===e)return;const n=this.width,r=t.width,i=Math.max(0,t.i),o=Math.max(0,t.j),a=Math.min(t.i+t.width,n),s=Math.min(t.j+t.height,this.height);if(!(s<=0||a<=0||i>=n||s>=this.height))for(let l=o;lMath.min(t,e)),Number.POSITIVE_INFINITY),r=this.area.reduce(((t,e)=>Math.max(t,e)),Number.NEGATIVE_INFINITY),i=t=>(t-n)/(r-n);t.scale(this.pixelGroup,this.pixelGroup);for(let e=0;ee?"black":"white",t.fillRect(n,r,1,1)}t.restore()}}}function kB(t,e){const n=t=>({x:t.x-e,y:t.y-e,width:t.width+2*e,height:t.height+2*e});return Array.isArray(t)?t.map(n):n(t)}function MB(t,e,n){return SB(Object.assign(uB(t),{distSquare:(e,n)=>aB(t.x1,t.y1,t.x2,t.y2,e,n)}),e,n)}function SB(t,e,n){const r=kB(t,n),i=e.scale(r),o=e.createSub(i,r);return function(t,e,n,r){const i=n*n;for(let o=0;ot.distSquare(e,n))),o}function NB(t,e){return{x:t,y:e}}function OB(t,e,n,r){if(0===t.length)return[];const i=function(t){if(t.length<2)return t;let e=0,n=0;return t.forEach((t=>{e+=t.cx,n+=t.cy})),e/=t.length,n/=t.length,t.map((t=>{const r=e-t.cx,i=n-t.cy;return[t,r*r+i*i]})).sort(((t,e)=>t[1]-e[1])).map((t=>t[0]))}(t);return i.map(((t,o)=>{const a=i.slice(0,o);return function(t,e,n,r,i){const o=NB(e.cx,e.cy),a=function(t,e,n){let r=Number.POSITIVE_INFINITY;return e.reduce(((e,i)=>{const o=sB(t.x,t.y,i.cx,i.cy);if(o>r)return e;const a=new cB(t.x,t.y,i.cx,i.cy),s=function(t,e){return t.reduce(((t,n)=>mB(n,e)&&function(t,e){function n(t,n,r,i){let o=gB(e,new cB(t,n,r,i));return o=Math.abs(o-.5),o>=0&&o<=1?1:0}let r=n(t.x,t.y,t.x2,t.y);return r+=n(t.x,t.y,t.x,t.y2),r>1||(r+=n(t.x,t.y2,t.x2,t.y2),r>1||(r+=n(t.x2,t.y,t.x2,t.y2),r>0))}(n,e)?t+1:t),0)}(n,a);return o*(s+1)*(s+1)0;){const t=o.pop(),n=AB(e,t),s=n?bB(t,n):null;if(!n||!s||2!==s.count){a||i.push(t);continue}let l=r,u=PB(n,l,s,!0),c=CB(u,o)||CB(u,i),h=TB(u,e);for(;!c&&h&&l>=1;)l/=1.5,u=PB(n,l,s,!0),c=CB(u,o)||CB(u,i),h=TB(u,e);if(!u||c||h||(o.push(new cB(t.x1,t.y1,u.x,u.y)),o.push(new cB(u.x,u.y,t.x2,t.y2)),a=!0),a)continue;l=r,u=PB(n,l,s,!1);let d=CB(u,o)||CB(u,i);for(h=TB(u,e);!d&&h&&l>=1;)l/=1.5,u=PB(n,l,s,!1),d=CB(u,o)||CB(u,i),h=TB(u,e);u&&!d&&(o.push(new cB(t.x1,t.y1,u.x,u.y)),o.push(new cB(u.x,u.y,t.x2,t.y2)),a=!0),a||i.push(t)}for(;o.length>0;)i.push(o.pop());return i}(new cB(o.x,o.y,a.cx,a.cy),t,r,i);return function(t,e){const n=[];for(;t.length>0;){const r=t.pop();if(0===t.length){n.push(r);break}const i=t.pop(),o=new cB(r.x1,r.y1,i.x2,i.y2);AB(e,o)?(n.push(r),t.push(i)):t.push(o)}return n}(s,t)}(e,t,a,n,r)})).flat()}function TB(t,e){return e.some((e=>e.containsPt(t.x,t.y)))}function CB(t,e){return e.some((e=>!!lB(e.x1,e.y1,t.x,t.y,.001)||!!lB(e.x2,e.y2,t.x,t.y,.001)))}function AB(t,e){let n=Number.POSITIVE_INFINITY,r=null;for(const i of t){if(!mB(i,e))continue;const t=yB(i,e);t>=0&&ts.y?NB(t.x-e,t.y-e):NB(t.x2+e,t.y-e):o.ya.x?NB(t.x-e,t.y-e):NB(t.x-e,t.y2+e):i.xs.y?NB(t.x2+e,t.y2+e):NB(t.x-e,t.y2+e):o.ya.x?NB(t.x2+e,t.y2+e):NB(t.x2+e,t.y-e):i.xr)return!1}return!0}function DB(t,e){switch(t){case-2:return(((3-e)*e-3)*e+1)/6;case-1:return((3*e-6)*e*e+4)/6;case 0:return(((-3*e+3)*e+3)*e+1)/6;case 1:return e*e*e/6;default:throw new Error("unknown error")}}class LB{constructor(t=[],e=!0){this.points=t,this.closed=e}get(t){const e=t,n=this.points.length;return t<0?this.closed?this.get(t+n):this.points[0]:t>=n?this.closed?this.get(t-n):this.points[n-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){const e=this.points;if(0===e.length)return"";const n="function"==typeof t?t:function(t){if(!Number.isFinite(t))return t=>t;if(0===t)return Math.round;const e=Math.pow(10,t);return t=>Math.round(t*e)/e}(t);let r="M";for(const t of e)r+=`${n(t.x)},${n(t.y)} L`;return r=r.slice(0,-1),this.closed&&(r+=" Z"),r}draw(t){const e=this.points;if(0!==e.length){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(const n of e)t.lineTo(n.x,n.y);this.closed&&t.closePath()}}sample(t){return function(t=8){return e=>{let n=t,r=e.length;if(n>1)for(r=Math.floor(e.length/n);r<3&&n>1;)n-=1,r=Math.floor(e.length/n);const i=[];for(let t=0,o=0;o{if(t<0||e.length<3)return e;const n=[];let r=0;const i=t*t;for(;r{if(n.length<3)return n;const r=[],i=n.closed,o=n.length+3-1+(i?0:2);r.push(e(n,2-(i?0:2),0));for(let a=2-(i?0:2);ae.containsPt(t.cx,t.cy)&&this.withinArea(t.cx,t.cy)))}withinArea(t,e){if(0===this.length)return!1;let n=0;const r=this.points[0],i=new cB(r.x,r.y,r.x,r.y);for(let r=1;re?i+o:i}function o(t,e){let n=0;return n=i(t,e,n,1),n=i(t+1,e,n,2),n=i(t,e+1,n,4),n=i(t+1,e+1,n,8),Number.isNaN(n)?-1:n}let a=1;function s(e,n){let i=e,s=n,l=t.invertScaleX(i),u=t.invertScaleY(s);for(let e=0;eFB(e.raw,t)));return!(e<0)&&(this.members.splice(e,1),this.dirty.add(zB.MEMBERS),!0)}removeNonMember(t){const e=this.nonMembers.findIndex((e=>FB(e.raw,t)));return!(e<0)&&(this.nonMembers.splice(e,1),this.dirty.add(zB.NON_MEMBERS),!0)}removeEdge(t){const e=this.edges.findIndex((e=>e.obj.equals(t)));return!(e<0)&&(this.edges.splice(e,1),this.dirty.add(zB.NON_MEMBERS),!0)}pushNonMember(...t){if(0!==t.length){this.dirty.add(zB.NON_MEMBERS);for(const e of t)this.nonMembers.push({raw:e,obj:BB(e)?EB.from(e):xB.from(e),area:null})}}pushEdge(...t){if(0!==t.length){this.dirty.add(zB.EDGES);for(const e of t)this.edges.push({raw:e,obj:cB.from(e),area:null})}}update(){const t=this.dirty.has(zB.MEMBERS),e=this.dirty.has(zB.NON_MEMBERS);let n=this.dirty.has(zB.EDGES);this.dirty.clear();const r=this.members.map((t=>t.obj));if(this.o.virtualEdges&&(t||e)){const t=OB(r,this.nonMembers.map((t=>t.obj)),this.o.maxRoutingIterations,this.o.morphBuffer),e=new Map(this.virtualEdges.map((t=>[t.obj.toString(),t.area])));this.virtualEdges=t.map((t=>{var n;return{raw:t,obj:t,area:null!==(n=e.get(t.toString()))&&void 0!==n?n:null}})),n=!0}let i=!1;if(t||n){const t=function(t,e){if(0===t.length)return new xB(0,0,0,0);const n=xB.from(t[0]);for(const e of t)n.add(e);for(const t of e)n.add(uB(t));return n}(r,this.virtualEdges.concat(this.edges).map((t=>t.obj))),e=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,n=xB.from(kB(t,e));n.equals(this.activeRegion)||(i=!0,this.activeRegion=n)}if(i){const t=Math.ceil(this.activeRegion.width/this.o.pixelGroup),e=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=wB.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach((t=>t.area=null)),this.nonMembers.forEach((t=>t.area=null)),this.edges.forEach((t=>t.area=null)),this.virtualEdges.forEach((t=>t.area=null))):t===this.potentialArea.width&&e===this.potentialArea.height||(this.potentialArea=wB.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}const o=new Map,a=t=>{if(t.area){const e=`${t.obj.width}x${t.obj.height}x${t.obj instanceof xB?"R":"C"}`;o.set(e,t.area)}},s=t=>{if(t.area)return;const e=`${t.obj.width}x${t.obj.height}x${t.obj instanceof xB?"R":"C"}`;if(o.has(e)){const n=o.get(e);return void(t.area=this.potentialArea.copy(n,{x:t.obj.x-this.o.nodeR1,y:t.obj.y-this.o.nodeR1}))}const n=t.obj instanceof xB?function(t,e,n){const r=e.scale(t),i=e.addPadding(r,n),o=e.createSub(i,{x:t.x-n,y:t.y-n}),a=r.x-i.x,s=r.y-i.y,l=i.x2-r.x2,u=i.y2-r.y2,c=i.width-a-l,h=i.height-s-u,d=n*n;o.fillArea({x:a,y:s,width:c+1,height:h+1},d);const f=[0],p=Math.max(s,a,l,u);{const i=e.invertScaleX(r.x+r.width/2);for(let o=1;o{this.activeRegion.intersects(t.obj)?s(t):t.area=null})),this.edges.forEach((t=>{t.area||(t.area=MB(t.obj,this.potentialArea,this.o.edgeR1))})),this.virtualEdges.forEach((t=>{t.area||(t.area=MB(t.obj,this.potentialArea,this.o.edgeR1))}))}drawMembers(t){for(const e of this.members)e.obj.draw(t)}drawNonMembers(t){for(const e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(const e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(0===this.members.length)return new LB([]);this.dirty.size>0&&this.update();const{o:t,potentialArea:e}=this,n=this.members.map((t=>t.area)),r=this.virtualEdges.concat(this.edges).map((t=>t.area)),i=this.nonMembers.filter((t=>null!=t.area)).map((t=>t.area)),o=this.members.map((t=>t.obj));return function(t,e,n,r,i,o={}){const a=Object.assign({},jB,o);let s=a.threshold,l=a.memberInfluenceFactor,u=a.edgeInfluenceFactor,c=a.nonMemberInfluenceFactor;const h=(a.nodeR0-a.nodeR1)*(a.nodeR0-a.nodeR1),d=(a.edgeR0-a.edgeR1)*(a.edgeR0-a.edgeR1);for(let o=0;o0))break;c*=.8}}return new LB([])}(e,n,r,i,(t=>t.containsElements(o)),t)}};class VB extends nB{constructor(t,e){super(t,ke({},VB.defaultOptions,e)),this.members=new Map,this.avoidMembers=new Map,this.bubbleSetOptions={},this.shallRunUpdateBubbleSetsPath=!1,this.pendingRunUpdateBubbleSetsPath=!1,this.drawBubbleSets=()=>{const{style:t,bubbleSetOptions:e}=this.parseOptions();Ne(this.bubbleSetOptions,e)||this.init(),this.bubbleSetOptions=Object.assign({},e);const n=Object.assign(Object.assign({},t),{d:this.getPath()});this.shape?this.shape.update(n):(this.shape=new nf({style:n}),this.context.canvas.appendChild(this.shape))},this.updateBubbleSetsPath=t=>{if(!this.shallRunUpdateBubbleSetsPath)return void(this.pendingRunUpdateBubbleSetsPath||(this.pendingRunUpdateBubbleSetsPath=!0,setTimeout((()=>{this.shallRunUpdateBubbleSetsPath=!0,this.updateBubbleSetsPath(t)}))));if(this.pendingRunUpdateBubbleSetsPath=!1,this.shallRunUpdateBubbleSetsPath=!1,!this.shape)return;const e=Nh(t.data);[...this.options.members,...this.options.avoidMembers].includes(e)&&this.shape.update(Object.assign(Object.assign({},this.parseOptions().style),{d:this.getPath(e)}))},this.getPath=t=>{const{graph:e}=this.context,n=this.options.members,r=[...this.members.keys()],i=this.options.avoidMembers,o=[...this.avoidMembers.keys()];if(!t&&Ne(n,r)&&Ne(i,o))return this.path;const{enter:a=[],exit:s=[]}=jh(r,n,(t=>t)),{enter:l=[],exit:u=[]}=jh(o,i,(t=>t));t&&(s.push(t),a.push(t));const c=(t,n,r)=>{t.forEach((t=>{const i=r?this.members:this.avoidMembers,o=r?"pushMember":"pushNonMember",a=r?"removeMember":"removeNonMember";if(n){let n;"edge"===e.getElementType(t)?([n]=HB(e,t),this.bubbleSets.pushEdge(n)):([n]=WB(e,t),this.bubbleSets[o](n)),i.set(t,n)}else{const n=i.get(t);n&&("edge"===e.getElementType(t)?this.bubbleSets.removeEdge(n):this.bubbleSets[a](n),i.delete(t))}}))};c(s,!1,!0),c(a,!0,!0),c(u,!1,!1),c(l,!0,!1);const h=this.bubbleSets.compute().sample(8).simplify(0).bSplines().simplify(0);return this.path=ef(h.points.map(cd)),this.path},this.bindEvents(),this.bubbleSets=new GB(this.options)}bindEvents(){this.context.graph.on(t.GraphEvent.AFTER_RENDER,this.drawBubbleSets),this.context.graph.on(t.GraphEvent.AFTER_ELEMENT_UPDATE,this.updateBubbleSetsPath)}init(){this.bubbleSets=new GB(this.options),this.members=new Map,this.avoidMembers=new Map}parseOptions(){const t=this.options,{type:e,key:n,members:r,avoidMembers:i}=t,o=Fe(t,["type","key","members","avoidMembers"]),a=Object.keys(o).reduce(((t,e)=>(e in jB?t.bubbleSetOptions[e]=o[e]:t.style[e]=o[e],t)),{style:{},bubbleSetOptions:{}});return Object.assign({type:e,key:n,members:r,avoidMembers:i},a)}addMember(t){const e=Array.isArray(t)?t:[t];e.some((t=>this.options.avoidMembers.includes(t)))&&(this.options.avoidMembers=this.options.avoidMembers.filter((t=>!e.includes(t)))),this.options.members=[...new Set([...this.options.members,...e])],this.drawBubbleSets()}removeMember(t){const e=Array.isArray(t)?t:[t];this.options.members=this.options.members.filter((t=>!e.includes(t))),this.drawBubbleSets()}updateMember(t){this.options.members=Ut(t)?t(this.options.members):t,this.drawBubbleSets()}getMember(){return this.options.members}addAvoidMember(t){const e=Array.isArray(t)?t:[t];e.some((t=>this.options.members.includes(t)))&&(this.options.members=this.options.members.filter((t=>!e.includes(t)))),this.options.avoidMembers=[...new Set([...this.options.avoidMembers,...e])],this.drawBubbleSets()}removeAvoidMember(t){const e=Array.isArray(t)?t:[t];this.options.avoidMembers.some((t=>e.includes(t)))&&(this.options.avoidMembers=this.options.avoidMembers.filter((t=>!e.includes(t))),this.drawBubbleSets())}updateAvoidMember(t){this.options.avoidMembers=Array.isArray(t)?t:[t],this.drawBubbleSets()}getAvoidMember(){return this.options.avoidMembers}destroy(){this.context.graph.off(t.GraphEvent.AFTER_RENDER,this.drawBubbleSets),this.context.graph.off(t.GraphEvent.AFTER_ELEMENT_UPDATE,this.updateBubbleSetsPath),this.shape.destroy(),super.destroy()}}VB.defaultOptions=Object.assign({members:[],avoidMembers:[],fill:"lightblue",fillOpacity:.2,stroke:"blue",strokeOpacity:.2},jB);const WB=(t,e)=>(Array.isArray(e)?e:[e]).map((e=>{const n=t.getElementRenderBounds(e);return new xB(n.min[0],n.min[1],eh(n),nh(n))})),HB=(t,e)=>(Array.isArray(e)?e:[e]).map((e=>{const n=t.getEdgeData(e),r=t.getElementPosition(n.source),i=t.getElementPosition(n.target);return cB.from({x1:r[0],y1:r[1],x2:i[0],y2:i[1]})}));class UB extends nB{constructor(t,e){super(t,Object.assign({},UB.defaultOptions,e)),this.targetElement=null,this.onTriggerEvent=t=>{var e;null===(e=t.preventDefault)||void 0===e||e.call(t),this.show(t)},this.onMenuItemClick=t=>{const{onClick:e,trigger:n}=this.options;if(t.target instanceof HTMLElement&&t.target.className.includes("g6-contextmenu-li")){const n=t.target.getAttribute("value");null==e||e(n,t.target,this.targetElement),this.hide()}"click"!==n&&this.hide()},this.initElement(),this.update(e)}initElement(){this.$element=rB("contextmenu",!1,{zIndex:"99"});const{className:t}=this.options;t&&this.$element.classList.add(t);this.context.canvas.getContainer().appendChild(this.$element),iB("g6-contextmenu-css","style",{},"\n .g6-contextmenu {\n font-size: 12px;\n background-color: rgba(255, 255, 255, 0.96);\n border-radius: 4px;\n overflow: hidden;\n box-shadow: rgba(0, 0, 0, 0.12) 0px 6px 12px 0px;\n transition: visibility 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s, left 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s, top 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s;\n }\n\n .g6-contextmenu-ul {\n max-width: 256px;\n min-width: 96px;\n list-style: none;\n padding: 0;\n margin: 0;\n }\n\n .g6-contextmenu-li {\n padding: 8px 12px;\n cursor: pointer;\n user-select: none;\n }\n\n .g6-contextmenu-li:hover {\n background-color: #f5f5f5;\n cursor: pointer;\n }\n",document.head)}show(t){return ze(this,void 0,void 0,(function*(){const{enable:e,offset:n}=this.options;if("function"==typeof e&&!e(t)||!e)return void this.hide();const r=yield this.getDOMContent(t);r instanceof HTMLElement?(this.$element.innerHTML="",this.$element.appendChild(r)):this.$element.innerHTML=r;const i=this.context.graph.getCanvas().getContainer().getBoundingClientRect();this.$element.style.left=`${t.client.x-i.left+n[0]}px`,this.$element.style.top=`${t.client.y-i.top+n[1]}px`,this.$element.style.display="block",this.targetElement=t.target}))}hide(){this.$element.style.display="none",this.targetElement=null}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}destroy(){this.unbindEvents(),super.destroy(),this.$element.remove()}getDOMContent(t){return ze(this,void 0,void 0,(function*(){const{getContent:e,getItems:n}=this.options;return n?`\n
    \n ${(yield n(t)).map((t=>`
  • ${t.name}
  • `)).join("")}\n
\n `:yield e(t)}))}bindEvents(){const{graph:t}=this.context,{trigger:e}=this.options;t.on(`canvas:${e}`,this.onTriggerEvent),t.on(`node:${e}`,this.onTriggerEvent),t.on(`edge:${e}`,this.onTriggerEvent),t.on(`combo:${e}`,this.onTriggerEvent),document.addEventListener("click",this.onMenuItemClick)}unbindEvents(){const{graph:t}=this.context,{trigger:e}=this.options;t.off(`canvas:${e}`,this.onTriggerEvent),t.off(`node:${e}`,this.onTriggerEvent),t.off(`edge:${e}`,this.onTriggerEvent),t.off(`combo:${e}`,this.onTriggerEvent),document.removeEventListener("click",this.onMenuItemClick)}}UB.defaultOptions={trigger:"contextmenu",offset:[4,4],loadingContent:'
Loading...
',getContent:()=>"It is a empty context menu.",enable:()=>!0};class $B extends nB{constructor(t,e){super(t,Object.assign({},$B.defaultOptions,e)),this.edgeBundles={},this.edgePoints={},this.onBundle=()=>{const{model:t,element:e}=this.context,n=t.getEdgeData();this.divideEdges(this.options.divisions);const{cycles:r,iterRate:i,divRate:o}=this.options;let{lambda:a,divisions:s,iterations:l}=this.options;for(let t=0;t{var n;if(e.source===e.target)return;const r=Nh(e);t[r]=this.getEdgeForces(e,s,a);for(let e=0;e{const n=Nh(t),r=e.getElement(n);null==r||r.update({d:ig(this.edgePoints[n])})}))},this.bindEvents()}get nodeMap(){const t=this.context.model.getNodeData();return Object.fromEntries(t.map((t=>[Nh(t),ed(sd(t))])))}divideEdges(t){this.context.model.getEdgeData().forEach((e=>{var n;const r=Nh(e);(n=this.edgePoints)[r]||(n[r]=[]);const i=this.nodeMap[e.source],o=this.nodeMap[e.target];if(1===t)this.edgePoints[r].push(i),this.edgePoints[r].push(Yh(Hh(i,o),2)),this.edgePoints[r].push(o);else{const e=(0===this.edgePoints[r].length?Xh(i,o):JB(this.edgePoints[r]))/(t+1);let n=e;const a=[i];for(let t=1;tn;){const t=n/s,r=Hh(i,$h(Uh(o,i),t));a.push(r),s-=n,n=e}n-=s}a.push(o),this.edgePoints[r]=a}}))}getVectorPosition(t){const e=this.nodeMap[t.source],n=this.nodeMap[t.target],[r,i]=Uh(n,e);return{source:e,target:n,vx:r,vy:i,length:Xh(e,n)}}measureEdgeCompatibility(t,e){const n=this.getVectorPosition(t),r=this.getVectorPosition(e);return YB(n,r)*qB(n,r)*XB(n,r)*QB(n,r)}getEdgeBundles(){const t={},e=this.options.bundleThreshold,n=this.context.model.getEdgeData();return n.forEach(((r,i)=>{n.forEach(((n,o)=>{var a,s;if(o<=i)return;this.measureEdgeCompatibility(r,n)>=e&&(t[a=Nh(r)]||(t[a]=[]),t[Nh(r)].push(n),t[s=Nh(n)]||(t[s]=[]),t[Nh(n)].push(r))}))})),t}getSpringForce(t,e){const{pre:n,cur:r,next:i}=t;return $h(Uh(Hh(n,i),$h(r,2)),e)}getElectrostaticForce(t,e){Se(this.edgeBundles)&&(this.edgeBundles=this.getEdgeBundles());const n=this.edgeBundles[Nh(e)];let r=[0,0];return null==n||n.forEach((n=>{const i=this.edgePoints[Nh(n)][t],o=this.edgePoints[Nh(e)][t],a=Uh(i,o),s=Xh(i,o);r=Hh(r,$h(a,1/s))})),r}getEdgeForces(t,e,n){const r=this.nodeMap[t.source],i=this.nodeMap[t.target],o=this.options.K/(Xh(r,i)*(e+1)),a=[[0,0]],s=Nh(t);for(let r=1;rMath.abs(function(t,e){return t.reduce(((t,n,r)=>t+n*e[r]),0)}([t.vx,t.vy],[e.vx,e.vy])/(t.length*e.length)),qB=(t,e)=>{const n=(t.length+e.length)/2;return 2/(n/Math.min(t.length,e.length)+Math.max(t.length,e.length)/n)},XB=(t,e)=>{const n=(t.length+e.length)/2;return n/(n+Xh(Yh(Hh(t.source,t.target),2),Yh(Hh(e.source,e.target),2)))},KB=(t,e)=>{if(e.source[0]===e.target[0])return[e.source[0],t[1]];if(e.source[1]===e.target[1])return[t[0],e.source[1]];const n=(e.source[1]-e.target[1])/(e.source[0]-e.target[0]),r=(n*n*e.source[0]+n*(t[1]-e.source[1])+t[0])/(n*n+1);return[r,n*(r-e.source[0])+e.source[1]]},ZB=(t,e)=>{const n=KB(e.source,t),r=KB(e.target,t),i=Yh(Hh(n,r),2),o=Yh(Hh(t.source,t.target),2);return 0===Xh(n,r)?0:Math.max(0,1-2*Xh(o,i)/Xh(n,r))},QB=(t,e)=>Math.min(ZB(t,e),ZB(e,t)),JB=t=>{let e=0;for(let n=1;n{if("drag"===this.options.trigger&&this.isLensOn)return;const e=cd(t.canvas);this.renderLens(e),this.renderFocusElements()},this.renderLens=t=>{const e=Object.assign({},tF,this.options.style);this.isLensOn||(this.lens=new df({style:e}),this.canvas.appendChild(this.lens)),Object.assign(e,hd(t),{size:2*this.r}),this.lens.update(e)},this.getFilterData=()=>{const{filter:t}=this.options,{model:e}=this.context,n=e.getData();if(!t)return n;const{nodes:r,edges:i,combos:o}=n;return{nodes:r.filter((e=>t(Nh(e),"node"))),edges:i.filter((e=>t(Nh(e),"edge"))),combos:o.filter((e=>t(Nh(e),"combo")))}},this.getFocusElements=t=>{const{nodes:e,edges:n}=this.getFilterData(),r=e.filter((e=>Xh(sd(e),t)Nh(t)));return{nodes:r,edges:n.filter((t=>{const{source:e,target:n}=t,r=i.includes(e),o=i.includes(n);switch(this.options.nodeType){case"both":return r&&o;case"either":return r!==o;case"source":return r&&!o;case"target":return!r&&o;default:return!1}}))}},this.renderFocusElements=()=>{const{element:t,graph:e}=this.context;if(!this.isLensOn)return;const n=this.lens.getCenter(),{nodes:r,edges:i}=this.getFocusElements(n),o=new Set,a=n=>{const r=Nh(n);o.add(r);const i=t.getElement(r);if(!i)return;const a=this.shapes.get(r)||i.cloneNode();a.setPosition(i.getPosition()),a.id=i.id,this.shapes.has(r)?Object.entries(i.attributes).forEach((([t,e])=>{a.style[t]!==e&&(a.style[t]=e)})):(this.canvas.appendChild(a),this.shapes.set(r,a));const s=e.getElementType(r),l=this.getElementStyle(s,n);a.update(l)};r.forEach(a),i.forEach(a),this.shapes.forEach(((t,e)=>{o.has(e)||(t.destroy(),this.shapes.delete(e))}))},this.scaleRByWheel=t=>{var e;this.options.preventDefault&&t.preventDefault();const{clientX:n,clientY:r,deltaX:i,deltaY:o}=t,{graph:a,canvas:s}=this.context,l=a.getCanvasByClient([n,r]),u=null===(e=this.lens)||void 0===e?void 0:e.getCenter();if(!this.isLensOn||Xh(l,u)>this.r)return;const{maxR:c,minR:h}=this.options,d=i+o>0?1/.95:.95,f=Math.min(...s.getSize())/2;this.r=Math.max(h||0,Math.min(c||f,this.r*d)),this.renderLens(u),this.renderFocusElements()},this.isLensDragging=!1,this.onDragStart=t=>{var e;const n=cd(t.canvas),r=null===(e=this.lens)||void 0===e?void 0:e.getCenter();!this.isLensOn||Xh(n,r)>this.r||(this.isLensDragging=!0)},this.onDrag=t=>{if(!this.isLensDragging)return;const e=cd(t.canvas);this.renderLens(e),this.renderFocusElements()},this.onDragEnd=()=>{this.isLensDragging=!1},this.bindEvents()}get canvas(){return this.context.canvas.getLayer("transient")}get isLensOn(){return this.lens&&!this.lens.destroyed}getElementStyle(t,e){const n="node"===t?this.options.nodeStyle:this.options.edgeStyle;return"function"==typeof n?n(e):n}get graphDom(){return this.context.graph.getCanvas().getContextService().getDomElement()}bindEvents(){var e;const{graph:n}=this.context,{trigger:r,scaleRBy:i}=this.options,o=n.getCanvas().getLayer();["click","drag"].includes(r)&&o.addEventListener(t.CommonEvent.CLICK,this.onEdgeFilter),"pointermove"===r?o.addEventListener(t.CommonEvent.POINTER_MOVE,this.onEdgeFilter):"drag"===r&&(o.addEventListener(t.CommonEvent.DRAG_START,this.onDragStart),o.addEventListener(t.CommonEvent.DRAG,this.onDrag),o.addEventListener(t.CommonEvent.DRAG_END,this.onDragEnd)),"wheel"===i&&(null===(e=this.graphDom)||void 0===e||e.addEventListener(t.CommonEvent.WHEEL,this.scaleRByWheel,{passive:!1}))}unbindEvents(){var e;const{graph:n}=this.context,{trigger:r,scaleRBy:i}=this.options,o=n.getCanvas().getLayer();["click","drag"].includes(r)&&o.removeEventListener(t.CommonEvent.CLICK,this.onEdgeFilter),"pointermove"===r?o.removeEventListener(t.CommonEvent.POINTER_MOVE,this.onEdgeFilter):"drag"===r&&(o.removeEventListener(t.CommonEvent.DRAG_START,this.onDragStart),o.removeEventListener(t.CommonEvent.DRAG,this.onDrag),o.removeEventListener(t.CommonEvent.DRAG_END,this.onDragEnd)),"wheel"===i&&(null===(e=this.graphDom)||void 0===e||e.removeEventListener(t.CommonEvent.WHEEL,this.scaleRByWheel))}update(t){var e;this.unbindEvents(),super.update(t),this.r=null!==(e=t.r)&&void 0!==e?e:this.r,this.bindEvents()}destroy(){this.unbindEvents(),this.isLensOn&&this.lens.destroy(),this.shapes.forEach(((t,e)=>{t.destroy(),this.shapes.delete(e)})),super.destroy()}}eF.defaultOptions={trigger:"pointermove",r:60,nodeType:"both",filter:()=>!0,style:{lineWidth:2},nodeStyle:{label:!1},edgeStyle:{label:!0},scaleRBy:"wheel",preventDefault:!0};const nF={fill:"#ccc",fillOpacity:.1,lineWidth:2,stroke:"#000",strokeOpacity:.8,labelFontSize:12};class rF extends nB{constructor(t,e){super(t,Object.assign({},rF.defaultOptions,e)),this.r=this.options.r,this.d=this.options.d,this.onCreateFisheye=t=>{if("drag"===this.options.trigger&&this.isLensOn)return;const e=cd(t.canvas);this.onMagnify(e)},this.onMagnify=t=>{t.some(isNaN)||(this.renderLens(t),this.renderFocusElements())},this.renderLens=t=>{const e=Object.assign({},nF,this.options.style);this.isLensOn||(this.lens=new df({style:e}),this.canvas.appendChild(this.lens)),Object.assign(e,hd(t),{size:2*this.r,label:this.options.showDPercent,labelText:this.getDPercent()}),this.lens.update(e)},this.getDPercent=()=>{const{minD:t,maxD:e}=this.options;return`${Math.round((this.d-t)/(e-t)*100)}%`},this.prevMagnifiedStyleMap=new Map,this.prevOriginStyleMap=new Map,this.renderFocusElements=()=>{if(!this.isLensOn)return;const{graph:t}=this.context,e=this.lens.getCenter(),n=(this.d+1)*this.r,r=new Map,i=new Map;t.getNodeData().forEach((o=>{const a=sd(o),s=Xh(a,e);if(s>this.r)return;const l=n*s/(this.d*s+this.r),[u,c]=a,[h,d]=e,f=[h+l*((u-h)/s),d+l*((c-d)/s)],p=Nh(o),g=this.getNodeStyle(o),v=Ae(t.getElementRenderStyle(p),Object.keys(g));r.set(p,Object.assign(Object.assign({},hd(f)),g)),i.set(p,Object.assign(Object.assign({},hd(a)),v))})),this.updateStyle(r,i)},this.getNodeStyle=t=>{const{nodeStyle:e}=this.options;return"function"==typeof e?e(t):e},this.updateStyle=(t,e)=>{const{graph:n,element:r}=this.context,{enter:i,exit:o,keep:a}=jh(Array.from(this.prevMagnifiedStyleMap.keys()),Array.from(t.keys()),(t=>t)),s=new Set,l=(t,e)=>{const i=r.getElement(t);null==i||i.update(e),n.getRelatedEdgesData(t).forEach((t=>{s.add(Nh(t))}))};[...i,...a].forEach((e=>{l(e,t.get(e))})),o.forEach((t=>{l(t,this.prevOriginStyleMap.get(t)),this.prevOriginStyleMap.delete(t)})),s.forEach((t=>{const e=r.getElement(t);null==e||e.update({})})),this.prevMagnifiedStyleMap=t,e.forEach(((t,e)=>{this.prevOriginStyleMap.has(e)||this.prevOriginStyleMap.set(e,t)}))},this.isWheelValid=t=>{if(this.options.preventDefault&&t.preventDefault(),!this.isLensOn)return!1;const{clientX:e,clientY:n}=t;return!(Xh(this.context.graph.getCanvasByClient([e,n]),this.lens.getCenter())>this.r)},this.scaleR=t=>{const{maxR:e,minR:n}=this.options,r=t?1/.95:.95,i=Math.min(...this.context.canvas.getSize())/2;this.r=Math.max(n||0,Math.min(e||i,this.r*r))},this.scaleD=t=>{const{maxD:e,minD:n}=this.options,r=t?this.d+.1:this.d-.1;this.d=Math.max(n,Math.min(e,r))},this.scaleRByWheel=t=>{if(!this.isWheelValid(t))return;const{deltaX:e,deltaY:n}=t;this.scaleR(e+n>0);const r=this.lens.getCenter();this.onMagnify(r)},this.scaleDByWheel=t=>{if(!this.isWheelValid(t))return;const{deltaX:e,deltaY:n}=t;this.scaleD(e+n>0);const r=this.lens.getCenter();this.onMagnify(r)},this.isDragValid=t=>{if(this.options.preventDefault&&t.preventDefault(),!this.isLensOn)return!1;return!(Xh(cd(t.canvas),this.lens.getCenter())>this.r)},this.isLensDragging=!1,this.onDragStart=t=>{this.isDragValid(t)&&(this.isLensDragging=!0)},this.onDrag=t=>{if(!this.isLensDragging)return;const e=cd(t.canvas);this.onMagnify(e)},this.onDragEnd=()=>{this.isLensDragging=!1},this.scaleRByDrag=t=>{if(!this.isLensDragging)return;const{dx:e,dy:n}=t;this.scaleR(e-n>0);const r=this.lens.getCenter();this.onMagnify(r)},this.scaleDByDrag=t=>{if(!this.isLensDragging)return;const{dx:e,dy:n}=t;this.scaleD(e-n>0);const r=this.lens.getCenter();this.onMagnify(r)},this.bindEvents()}get canvas(){return this.context.canvas.getLayer("transient")}get isLensOn(){return this.lens&&!this.lens.destroyed}get graphDom(){return this.context.graph.getCanvas().getContextService().getDomElement()}bindEvents(){var e;const{graph:n}=this.context,{trigger:r,scaleRBy:i,scaleDBy:o}=this.options,a=n.getCanvas().getLayer();if(["click","drag"].includes(r)&&a.addEventListener(t.CommonEvent.CLICK,this.onCreateFisheye),"pointermove"===r&&a.addEventListener(t.CommonEvent.POINTER_MOVE,this.onCreateFisheye),"drag"===r||"drag"===i||"drag"===o){a.addEventListener(t.CommonEvent.DRAG_START,this.onDragStart),a.addEventListener(t.CommonEvent.DRAG_END,this.onDragEnd);const e="drag"===r?this.onDrag:"drag"===i?this.scaleRByDrag:this.scaleDByDrag;a.addEventListener(t.CommonEvent.DRAG,e)}if("wheel"===i||"wheel"===o){const n="wheel"===i?this.scaleRByWheel:this.scaleDByWheel;null===(e=this.graphDom)||void 0===e||e.addEventListener(t.CommonEvent.WHEEL,n,{passive:!1})}}unbindEvents(){var e;const{graph:n}=this.context,{trigger:r,scaleRBy:i,scaleDBy:o}=this.options,a=n.getCanvas().getLayer();if(["click","drag"].includes(r)&&a.removeEventListener(t.CommonEvent.CLICK,this.onCreateFisheye),"pointermove"===r&&a.removeEventListener(t.CommonEvent.POINTER_MOVE,this.onCreateFisheye),"drag"===r||"drag"===i||"drag"===o){a.removeEventListener(t.CommonEvent.DRAG_START,this.onDragStart),a.removeEventListener(t.CommonEvent.DRAG_END,this.onDragEnd);const e="drag"===r?this.onDrag:"drag"===i?this.scaleRByDrag:this.scaleDByDrag;a.removeEventListener(t.CommonEvent.DRAG,e)}if("wheel"===i||"wheel"===o){const n="wheel"===i?this.scaleRByWheel:this.scaleDByWheel;null===(e=this.graphDom)||void 0===e||e.removeEventListener(t.CommonEvent.WHEEL,n)}}update(t){var e,n;this.unbindEvents(),super.update(t),this.r=null!==(e=t.r)&&void 0!==e?e:this.r,this.d=null!==(n=t.d)&&void 0!==n?n:this.d,this.bindEvents()}destroy(){var t;this.unbindEvents(),this.isLensOn&&(null===(t=this.lens)||void 0===t||t.destroy()),this.prevMagnifiedStyleMap.clear(),this.prevOriginStyleMap.clear(),super.destroy()}}rF.defaultOptions={trigger:"pointermove",r:120,d:1.5,maxD:5,minD:0,showDPercent:!0,style:{},nodeStyle:{label:!0},preventDefault:!0};class iF extends nB{constructor(t,e){super(t,Object.assign({},iF.defaultOptions,e)),this.$el=this.context.canvas.getContainer(),this.graphSize=[0,0],this.onFullscreenChange=()=>{var t,e,n,r;const i=!!document.fullscreenElement;this.options.autoFit&&this.setGraphSize(i),i?null===(e=(t=this.options).onEnter)||void 0===e||e.call(t):null===(r=(n=this.options).onExit)||void 0===r||r.call(n)},this.shortcut=new Sd(t.graph),this.bindEvents(),this.style=document.createElement("style"),document.head.appendChild(this.style),this.style.innerHTML="\n :not(:root):fullscreen::backdrop {\n background: transparent;\n }\n "}bindEvents(){this.unbindEvents(),this.shortcut.unbindAll();const{request:t=[],exit:e=[]}=this.options.trigger;this.shortcut.bind(t,this.request),this.shortcut.bind(e,this.exit);["webkitfullscreenchange","mozfullscreenchange","fullscreenchange","MSFullscreenChange"].forEach((t=>{document.addEventListener(t,this.onFullscreenChange,!1)}))}unbindEvents(){this.shortcut.unbindAll();["webkitfullscreenchange","mozfullscreenchange","fullscreenchange","MSFullscreenChange"].forEach((t=>{document.removeEventListener(t,this.onFullscreenChange,!1)}))}setGraphSize(t=!0){var e,n;let r,i;t?(r=(null===(e=globalThis.screen)||void 0===e?void 0:e.width)||0,i=(null===(n=globalThis.screen)||void 0===n?void 0:n.height)||0,this.graphSize=this.context.graph.getSize()):[r,i]=this.graphSize,this.context.graph.setSize(r,i),this.context.graph.render()}request(){!document.fullscreenElement&&(document.fullscreenEnabled||Reflect.get(document,"webkitFullscreenEnabled")||Reflect.get(document,"mozFullscreenEnabled")||Reflect.get(document,"msFullscreenEnabled"))&&this.$el.requestFullscreen().catch((t=>{Ic(`Error attempting to enable full-screen: ${t.message} (${t.name})`)}))}exit(){document.fullscreenElement&&document.exitFullscreen()}update(t){this.unbindEvents(),super.update(t),this.bindEvents()}destroy(){this.exit(),this.style.remove(),super.destroy()}}iF.defaultOptions={trigger:{},autoFit:!0};class oF extends nB{constructor(t,e){super(t,Object.assign({},oF.defaultOptions,e)),this.$element=rB("grid-line",!0),this.offset=[0,0],this.currentScale=1,this.followZoom=t=>{const{data:{scale:e,origin:n}}=t;if(!e)return;const r=this.currentScale;this.currentScale=e;const i=e/r,o=$h(n||this.context.graph.getCanvasCenter(),1-i),a=this.baseSize*e,s=Hh(td($h(this.offset,i),a),o);this.$element.style.backgroundSize=`${a}px ${a}px`,this.$element.style.backgroundPosition=`${s[0]}px ${s[1]}px`,this.offset=td(s,a)},this.followTranslate=t=>{if(!this.options.follow)return;const{data:{translate:e}}=t;e&&this.updateOffset(e)},this.onTransform=t=>{const e=this.parseFollow(this.options.follow);e.zoom&&this.followZoom(t),e.translate&&this.followTranslate(t)};this.context.canvas.getContainer().prepend(this.$element),this.baseSize=this.options.size,this.updateStyle(),this.bindEvents()}update(t){super.update(t),void 0!==t.size&&(this.baseSize=t.size),this.updateStyle()}bindEvents(){const{graph:e}=this.context;e.on(t.GraphEvent.AFTER_TRANSFORM,this.onTransform)}updateStyle(){const{stroke:t,lineWidth:e,border:n,borderLineWidth:r,borderStroke:i,borderStyle:o}=this.options,a=this.baseSize*this.currentScale;Object.assign(this.$element.style,{border:n?`${r}px ${o} ${i}`:"none",backgroundImage:`linear-gradient(${t} ${e}px, transparent ${e}px), linear-gradient(90deg, ${t} ${e}px, transparent ${e}px)`,backgroundSize:`${a}px ${a}px`,backgroundRepeat:"repeat"})}updateOffset(t){const e=this.baseSize*this.currentScale;this.offset=td(Hh(this.offset,t),e),this.$element.style.backgroundPosition=`${this.offset[0]}px ${this.offset[1]}px`}parseFollow(t){var e,n;return pe(t)?{translate:t,zoom:t}:{translate:null!==(e=null==t?void 0:t.translate)&&void 0!==e&&e,zoom:null!==(n=null==t?void 0:t.zoom)&&void 0!==n&&n}}destroy(){this.context.graph.off(t.GraphEvent.AFTER_TRANSFORM,this.onTransform),this.$element.remove(),super.destroy()}}function aF(t){const e={Added:new Map,Updated:new Map,Removed:new Map};return t.forEach((t=>{const{type:n,value:r}=t,i=Nh(r);if("NodeAdded"===n||"EdgeAdded"===n||"ComboAdded"===n)e.Added.set(i,t);else if("NodeUpdated"===n||"EdgeUpdated"===n||"ComboUpdated"===n)if(e.Added.has(i))e.Added.set(i,{type:n.replace("Updated","Added"),value:r});else if(e.Updated.has(i)){const{original:t}=e.Updated.get(i);e.Updated.set(i,{type:n,value:r,original:t})}else e.Removed.has(i)||e.Updated.set(i,t);else"NodeRemoved"!==n&&"EdgeRemoved"!==n&&"ComboRemoved"!==n||(e.Added.has(i)?e.Added.delete(i):e.Updated.has(i)?(e.Updated.delete(i),e.Removed.set(i,t)):e.Removed.set(i,t))})),[...Array.from(e.Added.values()),...Array.from(e.Updated.values()),...Array.from(e.Removed.values())]}function sF(t){const{NodeAdded:e=[],NodeUpdated:n=[],NodeRemoved:r=[],EdgeAdded:i=[],EdgeUpdated:o=[],EdgeRemoved:a=[],ComboAdded:s=[],ComboUpdated:l=[],ComboRemoved:u=[]}=ie(t,(t=>t.type));return{add:{nodes:e,edges:i,combos:s},update:{nodes:n,edges:o,combos:l},remove:{nodes:r,edges:a,combos:u}}}function lF(t,e){for(const n in t)qt(t[n])&&!Array.isArray(t[n])&&null!==t[n]?(e[n]||(e[n]={}),lF(t[n],e[n])):void 0===e[n]&&(e[n]=zc(n))}function uF(t,e=!1,n){const r={animation:e,current:{add:{},update:{},remove:{}},original:{add:{},update:{},remove:{}}},{add:i,update:o,remove:a}=sF(aF(t));return["nodes","edges","combos"].forEach((t=>{o[t]&&o[t].forEach((e=>{var i,o;const a=Object.assign({},e.value);let s=Object.assign({},e.original);if(n){const t=n.graph.getElementType(Nh(e.original)),r="edge"===t?"stroke":"fill",i=n.element.getElementComputedStyle(t,e.original);s=Object.assign(Object.assign({},e.original),{style:Object.assign({[r]:i[r]},e.original.style)})}lF(a,s),(i=r.current.update)[t]||(i[t]=[]),r.current.update[t].push(a),(o=r.original.update)[t]||(o[t]=[]),r.original.update[t].push(s)})),i[t]&&i[t].forEach((e=>{var n,i;const o=Object.assign({},e.value);(n=r.current.add)[t]||(n[t]=[]),r.current.add[t].push(o),(i=r.original.remove)[t]||(i[t]=[]),r.original.remove[t].push(o)})),a[t]&&a[t].forEach((e=>{var n,i;const o=Object.assign({},e.value);(n=r.current.remove)[t]||(n[t]=[]),r.current.remove[t].push(o),(i=r.original.add)[t]||(i[t]=[]),r.original.add[t].push(o)}))})),r}oF.defaultOptions={border:!0,borderLineWidth:1,borderStroke:"#eee",borderStyle:"solid",lineWidth:1,size:20,stroke:"#eee"};class cF extends nB{constructor(e,n){super(e,Object.assign({},cF.defaultOptions,n)),this.batchChanges=null,this.batchAnimation=!1,this.undoStack=[],this.redoStack=[],this.freezed=!1,this.executeCommand=(t,e=!0)=>{var n,r,i;this.freezed=!0,null===(r=(n=this.options).executeCommand)||void 0===r||r.call(n,t);const o=e?t.original:t.current;this.context.graph.addData(o.add),this.context.graph.updateData(o.update),this.context.graph.removeData(Th(o.remove,!1)),null===(i=this.context.element)||void 0===i||i.draw({silence:!0,animation:t.animation}),this.freezed=!1},this.addCommand=e=>{var n;if(!this.freezed){if(e.type===t.GraphEvent.AFTER_DRAW){const{dataChanges:t=[],animation:r=!0}=e.data;if(null===(n=this.context.batch)||void 0===n?void 0:n.isBatching){if(!this.batchChanges)return;return this.batchChanges.push(t),void(this.batchAnimation&&(this.batchAnimation=r))}this.batchChanges=[t],this.batchAnimation=r}this.undoStackPush(uF(this.batchChanges.flat(),this.batchAnimation,this.context)),this.notify(t.HistoryEvent.ADD,this.undoStack[this.undoStack.length-1])}},this.initBatchCommand=t=>{const{initiate:e}=t.data;if(this.batchAnimation=!1,e)this.batchChanges=[];else{this.undoStack.pop()||(this.batchChanges=null)}},this.emitter=new Kg;const{graph:r}=this.context;r.on(t.GraphEvent.AFTER_DRAW,this.addCommand),r.on(t.GraphEvent.BATCH_START,this.initBatchCommand),r.on(t.GraphEvent.BATCH_END,this.addCommand)}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}undo(){var e,n,r,i;const o=this.undoStack.pop();if(o){this.executeCommand(o);if(!1===(null===(n=(e=this.options).beforeAddCommand)||void 0===n?void 0:n.call(e,o,!1)))return;this.redoStack.push(o),null===(i=(r=this.options).afterAddCommand)||void 0===i||i.call(r,o,!1),this.notify(t.HistoryEvent.UNDO,o)}return this}redo(){const e=this.redoStack.pop();return e&&(this.executeCommand(e,!1),this.undoStackPush(e),this.notify(t.HistoryEvent.REDO,e)),this}undoAndCancel(){const e=this.undoStack.pop();return e&&(this.executeCommand(e,!1),this.redoStack=[],this.notify(t.HistoryEvent.CANCEL,e)),this}undoStackPush(t){var e,n,r,i;const{stackSize:o}=this.options;0!==o&&this.undoStack.length>=o&&this.undoStack.shift();!1!==(null===(n=(e=this.options).beforeAddCommand)||void 0===n?void 0:n.call(e,t,!0))&&(this.undoStack.push(t),null===(i=(r=this.options).afterAddCommand)||void 0===i||i.call(r,t,!0))}clear(){this.undoStack=[],this.redoStack=[],this.batchChanges=null,this.batchAnimation=!1,this.notify(t.HistoryEvent.CLEAR,null)}notify(e,n){this.emitter.emit(e,{cmd:n}),this.emitter.emit(t.HistoryEvent.CHANGE,{cmd:n})}on(t,e){this.emitter.on(t,e)}destroy(){const{graph:e}=this.context;e.off(t.GraphEvent.AFTER_DRAW,this.addCommand),e.off(t.GraphEvent.BATCH_START,this.initBatchCommand),e.off(t.GraphEvent.BATCH_END,this.addCommand),this.emitter.off(),super.destroy(),this.undoStack=[],this.redoStack=[]}}cF.defaultOptions={stackSize:0};const hF={toXy(t,e){if(!e)return[...t];const n=e[0].slice(1),r=e[1].slice(1);return t.map((t=>[t[n],t[r]]))},fromXy(t,e){if(!e)return[...t];const n=e[0].slice(1),r=e[1].slice(1);return t.map((([t,e])=>({[n]:t,[r]:e})))}};let dF=class{constructor(t,e){this._cells=[],this._cellSize=e,this._reverseCellSize=1/e;for(const e of t){const t=this.coordToCellNum(e[0]),n=this.coordToCellNum(e[1]);this._cells[t]||(this._cells[t]=[]),this._cells[t][n]||(this._cells[t][n]=[]),this._cells[t][n].push(e)}}cellPoints(t,e){var n;return(null===(n=this._cells[t])||void 0===n?void 0:n[e])||[]}rangePoints(t){const e=this.coordToCellNum(t[0]),n=this.coordToCellNum(t[1]),r=this.coordToCellNum(t[2]),i=this.coordToCellNum(t[3]),o=[];for(let t=e;t<=r;t++)for(let e=n;e<=i;e++){const n=this.cellPoints(t,e);for(const t of n)o.push(t)}return o}removePoint(t){const e=this.coordToCellNum(t[0]),n=this.coordToCellNum(t[1]),r=this._cells[e][n],i=r.findIndex((([e,n])=>e===t[0]&&n===t[1]));return i>-1&&r.splice(i,1),r}trunc(t){return Math.trunc(t)}coordToCellNum(t){return this.trunc(t*this._reverseCellSize)}extendBbox(t,e){return[t[0]-e*this._cellSize,t[1]-e*this._cellSize,t[2]+e*this._cellSize,t[3]+e*this._cellSize]}};const fF=+(Math.pow(2,27)+1);function pF(t,e,n){const r=t*e,i=fF*t,o=i-(i-t),a=t-o,s=fF*e,l=s-(s-e),u=e-l,c=a*u-(r-o*l-a*l-o*u);return n?(n[0]=c,n[1]=r,n):[c,r]}function gF(t,e,n){const r=t+e,i=r-t,o=e-i,a=t-(r-i);return n?(n[0]=a+o,n[1]=r,n):[a+o,r]}function vF(t,e){const n=t.length;if(1===n){const n=pF(t[0],e);return n[0]?n:[n[1]]}const r=new Array(2*n),i=[.1,.1],o=[.1,.1];let a=0;pF(t[0],e,i),i[0]&&(r[a++]=i[0]);for(let s=1;s=r?(u=h,a+=1,a=r?(u=h,a+=1,a0){if(i<=0)return o;a=r+i}else{if(!(r<0))return o;if(i>=0)return o;a=-(r+i)}const s=33306690738754716e-32*a;return o>=s||o<=-s?o:kF(t,e,n)},function(t,e,n,r){const i=t[0]-r[0],o=e[0]-r[0],a=n[0]-r[0],s=t[1]-r[1],l=e[1]-r[1],u=n[1]-r[1],c=t[2]-r[2],h=e[2]-r[2],d=n[2]-r[2],f=o*u,p=a*l,g=a*s,v=i*u,m=i*l,y=o*s,b=c*(f-p)+h*(g-v)+d*(m-y),x=7771561172376103e-31*((Math.abs(f)+Math.abs(p))*Math.abs(c)+(Math.abs(g)+Math.abs(v))*Math.abs(h)+(Math.abs(m)+Math.abs(y))*Math.abs(d));return b>x||-b>x?b:MF(t,e,n,r)}];function NF(t){let e=SF[t.length];return e||(e=SF[t.length]=wF(t.length)),e.apply(void 0,...t)}var OF=function(){for(;SF.length<=5;)SF.push(wF(SF.length));const t=function(t,e,n,r,i,o,a){return function(...e){switch(e.length){case 0:case 1:return 0;case 2:return r(e[0],e[1]);case 3:return i(e[0],e[1],e[2]);case 4:return o(e[0],e[1],e[2],e[3]);case 5:return a(e[0],e[1],e[2],e[3],e[4])}return t(e)}}(void 0,NF,...SF);for(let e=0;e<=5;++e)t[e]=SF[e];return t}();const TF=OF[3];function CF(t,e,n,r){const i=OF(t,n,r),o=OF(e,n,r);if(i>0&&o>0||i<0&&o<0)return!1;const a=OF(n,t,e),s=OF(r,t,e);return!(a>0&&s>0||a<0&&s<0)&&(0!==i||0!==o||0!==a||0!==s||function(t,e,n,r){for(let i=0;i<2;++i){const o=t[i],a=e[i],[s,l]=[Math.min(o,a),Math.max(o,a)],u=n[i],c=r[i],[h,d]=[Math.min(u,c),Math.max(u,c)];if(da&&i>s&&!RF([t[0],e[l]],n)&&!RF([t[1],e[l]],n)&&(a=r,s=i,o=e[l]);return o}function _F(t,e,n,r,i){let o=!1;for(let a=0;au||n[1]>c));u>=n[0]&&c>=n[1]&&i.add(l),null!==h&&(t.splice(a+1,0,h),r.removePoint(h),o=!0)}return o?_F(t,e,n,r,i):t}function IF(t,e,n){const r=e||20,i=function(t){const e=[t[0]];let n=t[0];for(let r=1;r=0;o--)t[o][0]r&&(r=t[o][0]),t[o][1]>i&&(i=t[o][1]);return[r-e,i-n]}(i),a=[o[0]*BF,o[1]*BF],s=function(t){const e=t.length;if(e<3){const n=new Array(e);for(let t=0;tt[e][0]-t[n][0]||t[e][1]-t[n][1]));const r=[n[0],n[1]],i=[n[0],n[1]];for(let o=2;o1&&TF(t[r[s-2]],t[r[s-1]],a)<=0;)s-=1,r.pop();for(r.push(e),s=i.length;s>1&&TF(t[i[s-2]],t[i[s-1]],a)>=0;)s-=1,i.pop();i.push(e)}const o=new Array(i.length+r.length-2);let a=0;for(let t=0,e=r.length;t0;--t)o[a++]=i[t];return o}(i).reverse().map((t=>i[t]));s.push(s[0]);const l=i.filter((function(t){return s.indexOf(t)<0})),u=Math.ceil(1/(i.length/(o[0]*o[1]))),c=_F(s,Math.pow(r,2),a,function(t,e){return new dF(t,e)}(l,u),new Set);return n?hF.fromXy(c,n):c}const jF=Math.cos(90/(180/Math.PI)),BF=.6;const FF=(t,e,n)=>{if("sharp"===n)return[["M",t[0]-e,t[1]-e],["L",t[0]+e,t[1]-e],["L",t[0]+e,t[1]+e],["L",t[0]-e,t[1]+e],["Z"]];const r=[e,e,0,0,0];return[["M",t[0],t[1]-e],["A",...r,t[0],t[1]+e],["A",...r,t[0],t[1]-e]]},zF=(t,e,n)=>{const r=[e,e,0,0,0],i="sharp"===n?Hh(t[0],qh(Zh(Uh(t[0],t[1])),e)):t[0],o="sharp"===n?Hh(t[1],qh(Zh(Uh(t[1],t[0])),e)):t[1],a=qh(Zh(Jh(Uh(i,o),!1)),e),s=qh(a,-1),l=Hh(i,a),u=Hh(o,a),c=Hh(o,s),h=Hh(i,s);return"sharp"===n?[["M",l[0],l[1]],["L",u[0],u[1]],["L",c[0],c[1]],["L",h[0],h[1]],["Z"]]:[["M",l[0],l[1]],["L",u[0],u[1]],["A",...r,c[0],c[1]],["L",h[0],h[1]],["A",...r,l[0],l[1]]]},GF=(t,e)=>{const n=Ed(t).map(((n,r)=>{const i=(r-2+t.length)%t.length,o=(r-1+t.length)%t.length,a=(r+1)%t.length,s=t[i],l=t[o],u=t[a],c=Uh(s,l),h=Uh(l,n),d=Uh(n,u),f=(t,e)=>Qh(t,e,!0)qh(Zh(Jh(t,!1)),e),m=v(h);return[{p:ed(Hh(l,p?v(c):m)),concave:p&&l},{p:ed(Hh(n,g?v(d):m)),concave:g&&n}]})),r=[e,e,0,0,0],i=n.findIndex(((t,e)=>!(n[(e-1+n.length)%n.length][0].concave||n[(e-1+n.length)%n.length][1].concave||t[0].concave||t[0].concave||t[1].concave))),o=n.slice(i).concat(n.slice(0,i));let a=[];return o.flatMap(((t,e)=>{const i=[],s=o[n.length-1];return 0===e&&i.push(["M",...s[1].p]),t[0].concave?a.push(t[0].p,t[1].p):i.push(["A",...r,...t[0].p]),t[1].concave?a.unshift(t[1].p):i.push(["L",...t[1].p]),3===a.length&&(i.pop(),i.push(["C",...a.flat()]),a=[]),i}))},VF=(t,e)=>{const n=Ed(t).map(((e,n)=>({p:e,v:Zh(Uh(t[(n+1)%t.length],e))})));return n.forEach(((r,i)=>{const o=i>0?i-1:t.length-1,a=n[o].v,s=Zh(Hh(a,qh(r.v,Qh(a,r.v,!0)t.p)))},WF=(t,e)=>{const n=t.map(((n,r)=>{const i=t[0===r?t.length-1:r-1],o=nd(qh(Zh(Jh(Uh(i,n),!1)),e));return[Hh(i,o),Hh(n,o)]})),r=n.flat();return r.map(((t,e)=>{if(e%2==0)return null;return od([r[(e-1)%r.length],r[e%r.length]],[r[(e+1)%r.length],r[(e+2)%r.length]],!0)})).filter(Boolean).map(((t,e)=>[0===e?"M":"L",t[0],t[1]])).concat([["Z"]])};class HF extends nB{constructor(t,e){super(t,Object.assign({},HF.defaultOptions,e)),this.hullMemberIds=[],this.drawHull=()=>{if(this.shape){const t=!Ne(this.optionsCache,this.options);this.shape.update(this.getHullStyle(t))}else this.shape=new nf({style:this.getHullStyle()}),this.context.canvas.appendChild(this.shape);this.optionsCache=Object.assign({},this.options)},this.updateHullPath=t=>{this.shape&&this.options.members.includes(Nh(t.data))&&this.shape.update({d:this.getHullPath(!0)})},this.getHullPath=(t=!1)=>{const{graph:e}=this.context,n=this.getMember();if(0===n.length)return"";const r=n.map((t=>e.getNodeData(t))),i=IF(r.map(sd),this.options.concavity).slice(1).reverse(),o=i.flatMap((t=>r.filter((e=>Ne(sd(e),t))).map(Nh)));return Ne(o,this.hullMemberIds)&&!t||(this.hullMemberIds=o,this.path=function(t,e,n){if(1===t.length)return FF(t[0],e,n);if(2===t.length)return zF(t,e,n);if(3===t.length){const[r,i,o]=Ed(t);if(gd(r,i,o))return zF([r,o],e,n)}switch(n){case"smooth":return VF(t,e);case"sharp":return WF(t,e);default:return GF(t,e)}}(i,this.getPadding(),this.options.corner)),this.path},this.bindEvents()}bindEvents(){this.context.graph.on(t.GraphEvent.AFTER_RENDER,this.drawHull),this.context.graph.on(t.GraphEvent.AFTER_ELEMENT_UPDATE,this.updateHullPath)}getHullStyle(t){const e=this.options,{members:n,padding:r,corner:i}=e,o=Fe(e,["members","padding","corner"]);return Object.assign(Object.assign({},o),{d:this.getHullPath(t)})}getPadding(){const{graph:t}=this.context,e=this.hullMemberIds.reduce(((e,n)=>{const{halfExtents:r}=t.getElementRenderBounds(n),i=Math.max(r[0],r[1]);return Math.max(e,i)}),0);return e+this.options.padding}addMember(t){const e=Array.isArray(t)?t:[t];this.options.members=[...new Set([...this.options.members,...e])],this.shape.update({d:this.getHullPath()})}removeMember(t){const e=Array.isArray(t)?t:[t];this.options.members=this.options.members.filter((t=>!e.includes(t))),e.some((t=>this.hullMemberIds.includes(t)))&&this.shape.update({d:this.getHullPath()})}updateMember(t){this.options.members=Ut(t)?t(this.options.members):t,this.shape.update(this.getHullStyle(!0))}getMember(){return this.options.members}destroy(){this.context.graph.off(t.GraphEvent.AFTER_DRAW,this.drawHull),this.shape.destroy(),this.hullMemberIds=[],super.destroy()}}function UF(t,e){e(t),t.children&&t.children.forEach((function(t){t&&UF(t,e)}))}function $F(t){qF(t,!0)}function YF(t){qF(t,!1)}function qF(t,e){var n=e?"visible":"hidden";UF(t,(function(t){t.attr("visibility",n)}))}HF.defaultOptions={members:[],padding:10,corner:"rounded",concavity:1/0,fill:"lightblue",fillOpacity:.2,labelOpacity:1,stroke:"blue",strokeOpacity:.2};var XF=function(t){function e(){for(var e=[],n=0;n=this.left&&t<=this.right&&e>=this.top&&e<=this.bottom},t}();function ez(t,e){return Ut(t)?t.apply(void 0,We([],Ve(e),!1)):t}var nz,rz=function(t,e){var n=function(t){return"".concat(e,"-").concat(t)},r=Object.fromEntries(Object.entries(t).map((function(t){var e=Ve(t,2),r=e[0],i=e[1],o=n(i);return[r,{name:o,class:".".concat(o),id:"#".concat(o),toString:function(){return o}}]})));return Object.assign(r,{prefix:n}),r},iz=function(t,e,n,r){void 0===n&&(n=0),void 0===r&&(r=5),Object.entries(e).forEach((function(i){var o=Ve(i,2),a=o[0],s=o[1],l=t;Object.prototype.hasOwnProperty.call(e,a)&&(s?Jt(s)?(Jt(t[a])||(l[a]={}),ne&&t="A"&&n<="Z"};function Fz(t,e,n){void 0===n&&(n=!1);var r={};return Object.entries(t).forEach((function(t){var i=Ve(t,2),o=i[0],a=i[1];if("className"===o||"class"===o);else if(Bz(o,"show")&&Bz(jz(o,"show"),e)!==n)o===function(t,e){return"".concat(e).concat(Iz(t))}(e,"show")?r[o]=a:r[o.replace(new RegExp(Iz(e)),"")]=a;else if(!Bz(o,"show")&&Bz(o,e)!==n){var s=jz(o,e);"filter"===s&&"function"==typeof a||(r[s]=a)}})),r}function zz(t,e){return Object.entries(t).reduce((function(t,n){var r=Ve(n,2),i=r[0],o=r[1];return i.startsWith("show")?t["show".concat(e).concat(i.slice(4))]=o:t["".concat(e).concat(Iz(i))]=o,t}),{})}function Gz(t,e){void 0===e&&(e=["x","y","class","className"]);var n=["transform","transformOrigin","anchor","visibility","pointerEvents","zIndex","cursor","clipPath","clipPathTargets","offsetPath","offsetPathTargets","offsetDistance","draggable","droppable"],r={},i={};return Object.entries(t).forEach((function(t){var o=Ve(t,2),a=o[0],s=o[1];e.includes(a)||(-1!==n.indexOf(a)?i[a]=s:r[a]=s)})),[r,i]}function Vz(t,e){var n={YYYY:t.getFullYear(),MM:t.getMonth()+1,DD:t.getDate(),HH:t.getHours(),mm:t.getMinutes(),ss:t.getSeconds()},r=e;return Object.keys(n).forEach((function(t){var e=n[t];r=r.replace(t,"YYYY"===t?"".concat(e):"".concat(e).padStart(2,"0"))})),r}function Wz(t,e){if(e)try{var n=e.replace(/translate\(([+-]*[\d]+[%]*),[ ]*([+-]*[\d]+[%]*)\)/g,(function(e,n,r){return"translate(".concat(function(t,e,n){var r=t.getBBox(),i=r.width,o=r.height,a=Ve([e,n].map((function(t,e){var n;return t.includes("%")?parseFloat((null===(n=t.match(/[+-]?([0-9]*[.])?[0-9]+/))||void 0===n?void 0:n[0])||"0")/100*(0===e?i:o):t})),2);return[a[0],a[1]]}(t,n,r),")")}));t.attr("transform",n)}catch(t){}}var Hz=function(t,e){null!=e?t.replaceChildren?Array.isArray(e)?t.replaceChildren.apply(t,We([],Ve(e),!1)):t.replaceChildren(e):(t.innerHTML="",Array.isArray(e)?e.forEach((function(e){return t.appendChild(e)})):t.appendChild(e)):t.innerHTML=""};function Uz(){qF(this,"hidden"!==this.attributes.visibility)}var $z=function(t){function e(e,n){void 0===n&&(n={});var r=t.call(this,oz({},{style:n},e))||this;return r.initialized=!1,r._defaultOptions=n,r}return je(e,t),Object.defineProperty(e.prototype,"offscreenGroup",{get:function(){return this._offscreen||(this._offscreen=KF(this)),this._offscreen},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"defaultOptions",{get:function(){return this._defaultOptions},enumerable:!1,configurable:!0}),e.prototype.connectedCallback=function(){this.render(this.attributes,this),this.bindEvents(this.attributes,this),this.initialized=!0},e.prototype.disconnectedCallback=function(){var t;null===(t=this._offscreen)||void 0===t||t.destroy()},e.prototype.attributeChangedCallback=function(t){"visibility"===t&&Uz.call(this)},e.prototype.update=function(t,e){var n;return this.attr(oz({},this.attributes,t||{})),null===(n=this.render)||void 0===n?void 0:n.call(this,this.attributes,this,e)},e.prototype.clear=function(){this.removeChildren()},e.prototype.bindEvents=function(t,e){},e.prototype.getSubShapeStyle=function(t){return t.x,t.y,t.transform,t.transformOrigin,t.class,t.className,t.zIndex,Fe(t,["x","y","transform","transformOrigin","class","className","zIndex"])},e}(Wl),Yz=function(t,e,n){return[["M",t-n,e],["A",n,n,0,1,0,t+n,e],["A",n,n,0,1,0,t-n,e],["Z"]]},qz=Yz,Xz=function(t,e,n){return[["M",t,e+n],["L",t,e-n]]},Kz=function(t,e,n){return[["M",t-n,e],["L",t+n,e]]},Zz=Kz;var Qz=function(t,e,n){return[["M",t-n,e-n],["L",t+n,e],["L",t-n,e+n],["Z"]]};function Jz(t){var e=function(t){var e="default";if(qt(t)&&t instanceof Image)e="image";else if(Ut(t))e="symbol";else if(ne(t)){var n=new RegExp("data:(image|text)");e=t.match(n)?"base64":/^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(t)?"url":"symbol"}return e}(t);return["base64","url","image"].includes(e)?"image":t&&"symbol"===e?"path":null}var tG=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return je(e,t),e.prototype.render=function(t,n){var r=t.x,i=void 0===r?0:r,o=t.y,a=void 0===o?0:o,s=this.getSubShapeStyle(t),l=s.symbol,u=s.size,c=void 0===u?16:u,h=Fe(s,["symbol","size"]),d=Jz(l);pz(!!d,Rz(n),(function(t){t.maybeAppendByClassName("marker",d).attr("className","marker ".concat(d,"-marker")).call((function(t){if("image"===d){var n=2*c;t.styles({img:l,width:n,height:n,x:i-c,y:a-c})}else{n=c/2;var r=Ut(l)?l:e.getSymbol(l);t.styles(Be({d:null==r?void 0:r(i,a,n)},h))}}))}))},e.MARKER_SYMBOL_MAP=new Map,e.registerSymbol=function(t,n){e.MARKER_SYMBOL_MAP.set(t,n)},e.getSymbol=function(t){return e.MARKER_SYMBOL_MAP.get(t)},e.getSymbols=function(){return Array.from(e.MARKER_SYMBOL_MAP.keys())},e}($z);function eG(t,...e){return e.reduce(((t,e)=>n=>t(e(n))),t)}function nG(t,e){return e-t?n=>(n-t)/(e-t):t=>.5}tG.registerSymbol("cross",(function(t,e,n){return[["M",t-n,e-n],["L",t+n,e+n],["M",t+n,e-n],["L",t-n,e+n]]})),tG.registerSymbol("hyphen",(function(t,e,n){return[["M",t-n,e],["L",t+n,e]]})),tG.registerSymbol("line",Xz),tG.registerSymbol("plus",(function(t,e,n){return[["M",t-n,e],["L",t+n,e],["M",t,e-n],["L",t,e+n]]})),tG.registerSymbol("tick",(function(t,e,n){return[["M",t-n/2,e-n],["L",t+n/2,e-n],["M",t,e-n],["L",t,e+n],["M",t-n/2,e+n],["L",t+n/2,e+n]]})),tG.registerSymbol("circle",Yz),tG.registerSymbol("point",qz),tG.registerSymbol("bowtie",(function(t,e,n){var r=n-1.5;return[["M",t-n,e-r],["L",t+n,e+r],["L",t+n,e-r],["L",t-n,e+r],["Z"]]})),tG.registerSymbol("hexagon",(function(t,e,n){var r=n/2*Math.sqrt(3);return[["M",t,e-n],["L",t+r,e-n/2],["L",t+r,e+n/2],["L",t,e+n],["L",t-r,e+n/2],["L",t-r,e-n/2],["Z"]]})),tG.registerSymbol("square",(function(t,e,n){return[["M",t-n,e-n],["L",t+n,e-n],["L",t+n,e+n],["L",t-n,e+n],["Z"]]})),tG.registerSymbol("diamond",(function(t,e,n){return[["M",t-n,e],["L",t,e-n],["L",t+n,e],["L",t,e+n],["Z"]]})),tG.registerSymbol("triangle",(function(t,e,n){var r=n*Math.sin(1/3*Math.PI);return[["M",t-n,e+r],["L",t,e-r],["L",t+n,e+r],["Z"]]})),tG.registerSymbol("triangle-down",(function(t,e,n){var r=n*Math.sin(1/3*Math.PI);return[["M",t-n,e-r],["L",t+n,e-r],["L",t,e+r],["Z"]]})),tG.registerSymbol("line",Xz),tG.registerSymbol("dot",Kz),tG.registerSymbol("dash",Zz),tG.registerSymbol("smooth",(function(t,e,n){return[["M",t-n,e],["A",n/2,n/2,0,1,1,t,e],["A",n/2,n/2,0,1,0,t+n,e]]})),tG.registerSymbol("hv",(function(t,e,n){return[["M",t-n-1,e-2.5],["L",t,e-2.5],["L",t,e+2.5],["L",t+n+1,e+2.5]]})),tG.registerSymbol("vh",(function(t,e,n){return[["M",t-n-1,e+2.5],["L",t,e+2.5],["L",t,e-2.5],["L",t+n+1,e-2.5]]})),tG.registerSymbol("hvh",(function(t,e,n){return[["M",t-(n+1),e+2.5],["L",t-n/2,e+2.5],["L",t-n/2,e-2.5],["L",t+n/2,e-2.5],["L",t+n/2,e+2.5],["L",t+n+1,e+2.5]]})),tG.registerSymbol("vhv",(function(t,e){return[["M",t-5,e+2.5],["L",t-5,e],["L",t,e],["L",t,e-3],["L",t,e+3],["L",t+6.5,e+3]]}));const rG=Math.sqrt(50),iG=Math.sqrt(10),oG=Math.sqrt(2);function aG(t,e,n){const r=(e-t)/Math.max(0,n),i=Math.floor(Math.log(r)/Math.LN10),o=r/10**i;return i>=0?(o>=rG?10:o>=iG?5:o>=oG?2:1)*10**i:-(10**-i)/(o>=rG?10:o>=iG?5:o>=oG?2:1)}const sG=(t,e,n=5)=>{const r=[t,e];let i,o=0,a=r.length-1,s=r[o],l=r[a];return l0?(s=Math.floor(s/i)*i,l=Math.ceil(l/i)*i,i=aG(s,l,n)):i<0&&(s=Math.ceil(s*i)/i,l=Math.floor(l*i)/i,i=aG(s,l,n)),i>0?(r[o]=Math.floor(s/i)*i,r[a]=Math.ceil(l/i)*i):i<0&&(r[o]=Math.ceil(s*i)/i,r[a]=Math.floor(l*i)/i),r};function lG(t){return!(ve(t)||(e=t,null===e)||Number.isNaN(t));var e}var uG={exports:{}},cG={exports:{}},hG=function(t){return!(!t||"string"==typeof t)&&(t instanceof Array||Array.isArray(t)||t.length>=0&&(t.splice instanceof Function||Object.getOwnPropertyDescriptor(t,t.length-1)&&"String"!==t.constructor.name))},dG=Array.prototype.concat,fG=Array.prototype.slice,pG=cG.exports=function(t){for(var e=[],n=0,r=t.length;n=4&&1!==t[3]&&(e=", "+t[3]),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+e+")"},EG.to.keyword=function(t){return bG[t.slice(0,3)]};var MG=E(uG.exports);function SG(t,e,n){let r=n;return r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function NG(t){const e=MG.get(t);if(!e)return null;const{model:n,value:r}=e;return"rgb"===n?r:"hsl"===n?function(t){const e=t[0]/360,n=t[1]/100,r=t[2]/100,i=t[3];if(0===n)return[255*r,255*r,255*r,i];const o=r<.5?r*(1+n):r+n-r*n,a=2*r-o;return[255*SG(a,o,e+1/3),255*SG(a,o,e),255*SG(a,o,e-1/3),i]}(r):null}const OG=(t,e)=>n=>t*(1-n)+e*n,TG=(t,e)=>"number"==typeof t&&"number"==typeof e?OG(t,e):"string"==typeof t&&"string"==typeof e?((t,e)=>{const n=NG(t),r=NG(e);return null===n||null===r?n?()=>t:()=>e:t=>{const e=new Array(4);for(let i=0;i<4;i+=1){const o=n[i],a=r[i];e[i]=o*(1-t)+a*t}const[i,o,a,s]=e;return`rgba(${Math.round(i)}, ${Math.round(o)}, ${Math.round(a)}, ${s})`}})(t,e):()=>t,CG=(t,e)=>{const n=OG(t,e);return t=>Math.round(n(t))};function AG({map:t,initKey:e},n){const r=e(n);return t.has(r)?t.get(r):n}function PG(t){return"object"==typeof t?t.valueOf():t}class RG extends Map{constructor(t){if(super(),this.map=new Map,this.initKey=PG,null!==t)for(const[e,n]of t)this.set(e,n)}get(t){return super.get(AG({map:this.map,initKey:this.initKey},t))}has(t){return super.has(AG({map:this.map,initKey:this.initKey},t))}set(t,e){return super.set(function({map:t,initKey:e},n){const r=e(n);return t.has(r)?t.get(r):(t.set(r,n),n)}({map:this.map,initKey:this.initKey},t),e)}delete(t){return super.delete(function({map:t,initKey:e},n){const r=e(n);return t.has(r)&&(n=t.get(r),t.delete(r)),n}({map:this.map,initKey:this.initKey},t))}}class DG{constructor(t){this.options=ke({},this.getDefaultOptions()),this.update(t)}getOptions(){return this.options}update(t={}){this.options=ke({},this.options,t),this.rescale(t)}rescale(t){}}const LG=Symbol("defaultUnknown");function _G(t,e,n){for(let r=0;r`${t}`:"object"==typeof t?t=>JSON.stringify(t):t=>t}class BG extends DG{getDefaultOptions(){return{domain:[],range:[],unknown:LG}}constructor(t){super(t)}map(t){return 0===this.domainIndexMap.size&&_G(this.domainIndexMap,this.getDomain(),this.domainKey),IG({value:this.domainKey(t),mapper:this.domainIndexMap,from:this.getDomain(),to:this.getRange(),notFoundReturn:this.options.unknown})}invert(t){return 0===this.rangeIndexMap.size&&_G(this.rangeIndexMap,this.getRange(),this.rangeKey),IG({value:this.rangeKey(t),mapper:this.rangeIndexMap,from:this.getRange(),to:this.getDomain(),notFoundReturn:this.options.unknown})}rescale(t){const[e]=this.options.domain,[n]=this.options.range;if(this.domainKey=jG(e),this.rangeKey=jG(n),!this.rangeIndexMap)return this.rangeIndexMap=new Map,void(this.domainIndexMap=new Map);t&&!t.range||this.rangeIndexMap.clear(),(!t||t.domain||t.compare)&&(this.domainIndexMap.clear(),this.sortedDomain=void 0)}clone(){return new BG(this.options)}getRange(){return this.options.range}getDomain(){if(this.sortedDomain)return this.sortedDomain;const{domain:t,compare:e}=this.options;return this.sortedDomain=e?[...t].sort(e):t,this.sortedDomain}}function FG(t){return Math.round(1e12*t)/1e12}function zG(t){const{domain:e,range:n,paddingOuter:r,paddingInner:i,flex:o,round:a,align:s}=t,l=e.length,u=function(t,e){const n=e-t.length;return n>0?[...t,...new Array(n).fill(1)]:n<0?t.slice(0,e):t}(o,l),[c,h]=n,d=h-c,f=d/(2/l*r+1-1/l*i),p=f*i/l,g=f-l*p,v=function(t){const e=Math.min(...t);return t.map((t=>t/e))}(u),m=g/v.reduce(((t,e)=>t+e)),y=new RG(e.map(((t,e)=>{const n=v[e]*m;return[t,a?Math.floor(n):n]}))),b=new RG(e.map(((t,e)=>{const n=v[e]*m+p;return[t,a?Math.floor(n):n]}))),x=Array.from(b.values()).reduce(((t,e)=>t+e)),E=c+(d-(x-x/l*i))*s;let w=a?Math.round(E):E;const k=new Array(l);for(let t=0;t0?t:e}getPaddingOuter(){const{padding:t,paddingOuter:e}=this.options;return t>0?t:e}rescale(){super.rescale();const{align:t,domain:e,range:n,round:r,flex:i}=this.options,{adjustedRange:o,valueBandWidth:a,valueStep:s}=function(t){var e;const{domain:n}=t,r=n.length;if(0===r)return{valueBandWidth:void 0,valueStep:void 0,adjustedRange:[]};if(null===(e=t.flex)||void 0===e?void 0:e.length)return zG(t);const{range:i,paddingOuter:o,paddingInner:a,round:s,align:l}=t;let u,c,h=i[0];const d=i[1]-h,f=2*o,p=r-a;u=d/Math.max(1,f+p),s&&(u=Math.floor(u)),h+=(d-u*(r-a))*l,c=u*(1-a),s&&(h=Math.round(h),c=Math.round(c));const g=new Array(r).fill(0).map(((t,e)=>h+e*u));return{valueStep:u,valueBandWidth:c,adjustedRange:g}}({align:t,range:n,round:r,flex:i,paddingInner:this.getPaddingInner(),paddingOuter:this.getPaddingOuter(),domain:e});this.valueStep=s,this.valueBandWidth=a,this.adjustedRange=o}}const VG=(t,e,n)=>{let r,i,o=t,a=e;if(o===a&&n>0)return[o];let s=aG(o,a,n);if(0===s||!Number.isFinite(s))return[];if(s>0){o=Math.ceil(o/s),a=Math.floor(a/s),i=new Array(r=Math.ceil(a-o+1));for(let t=0;t{const[r,i]=t,[o,a]=e;let s,l;return r{const r=Math.min(t.length,e.length)-1,i=new Array(r),o=new Array(r),a=t[0]>t[r],s=a?[...t].reverse():t,l=a?[...e].reverse():e;for(let t=0;t{const n=function(t,e,n,r){let i=n,o=r||t.length;for(;ie?o=n:i=n+1}return i}(t,e,1,r)-1,a=i[n];return eG(o[n],a)(e)}},UG=(t,e,n,r)=>(Math.min(t.length,e.length)>2?HG:WG)(t,e,r?CG:n);class $G extends DG{getDefaultOptions(){return{domain:[0,1],range:[0,1],nice:!1,clamp:!1,round:!1,interpolate:OG,tickCount:5}}map(t){return lG(t)?this.output(t):this.options.unknown}invert(t){return lG(t)?this.input(t):this.options.unknown}nice(){if(!this.options.nice)return;const[t,e,n,...r]=this.getTickMethodOptions();this.options.domain=this.chooseNice()(t,e,n,...r)}getTicks(){const{tickMethod:t}=this.options,[e,n,r,...i]=this.getTickMethodOptions();return t(e,n,r,...i)}getTickMethodOptions(){const{domain:t,tickCount:e}=this.options;return[t[0],t[t.length-1],e]}chooseNice(){return sG}rescale(){this.nice();const[t,e]=this.chooseTransforms();this.composeOutput(t,this.chooseClamp(t)),this.composeInput(t,e,this.chooseClamp(e))}chooseClamp(t){const{clamp:e,range:n}=this.options,r=this.options.domain.map(t),i=Math.min(r.length,n.length);return e?function(t,e){const n=ee?t:e;return t=>Math.min(Math.max(n,t),r)}(r[0],r[i-1]):_e}composeOutput(t,e){const{domain:n,range:r,round:i,interpolate:o}=this.options,a=UG(n.map(t),r,o,i);this.output=eG(a,e,t)}composeInput(t,e,n){const{domain:r,range:i}=this.options,o=UG(i,r.map(t),OG);this.input=eG(e,n,o)}}class YG extends $G{getDefaultOptions(){return{domain:[0,1],range:[0,1],unknown:void 0,nice:!1,clamp:!1,round:!1,interpolate:TG,tickMethod:VG,tickCount:5}}chooseTransforms(){return[_e,_e]}clone(){return new YG(this.options)}}var qG=function(t){function e(e){var n=this,r=e.style,i=Fe(e,["style"]);return(n=t.call(this,ke({},{type:"column"},Be({style:r},i)))||this).columnsGroup=new Ul({name:"columns"}),n.appendChild(n.columnsGroup),n.render(),n}return je(e,t),e.prototype.render=function(){var t=this.attributes,e=t.columns,n=t.x,r=t.y;this.columnsGroup.style.transform="translate(".concat(n,", ").concat(r,")"),Rz(this.columnsGroup).selectAll(".column").data(e.flat()).join((function(t){return t.append("rect").attr("className","column").each((function(t){this.attr(t)}))}),(function(t){return t.each((function(t){this.attr(t)}))}),(function(t){return t.remove()}))},e.prototype.update=function(t){this.attr(oz({},this.attributes,t)),this.render()},e.prototype.clear=function(){this.removeChildren()},e}(zl),XG=function(t){function e(e){var n=this,r=e.style,i=Fe(e,["style"]);return(n=t.call(this,ke({},{type:"lines"},Be({style:r},i)))||this).linesGroup=n.appendChild(new Ul),n.areasGroup=n.appendChild(new Ul),n.render(),n}return je(e,t),e.prototype.render=function(){var t=this.attributes,e=t.lines,n=t.areas,r=t.x,i=t.y;this.style.transform="translate(".concat(r,", ").concat(i,")"),e&&this.renderLines(e),n&&this.renderAreas(n)},e.prototype.clear=function(){this.linesGroup.removeChildren(),this.areasGroup.removeChildren()},e.prototype.update=function(t){this.attr(oz({},this.attributes,t)),this.render()},e.prototype.renderLines=function(t){Rz(this.linesGroup).selectAll(".line").data(t).join((function(t){return t.append("path").attr("className","line").each((function(t){this.attr(t)}))}),(function(t){return t.each((function(t){this.attr(t)}))}),(function(t){return t.remove()}))},e.prototype.renderAreas=function(t){Rz(this.linesGroup).selectAll(".area").data(t).join((function(t){return t.append("path").attr("className","area").each((function(t){this.attr(t)}))}),(function(t){return t.each((function(t){this.style(t)}))}),(function(t){return t.remove()}))},e}(zl);function KG(t,e){void 0===e&&(e=!1);var n=e?t.length-1:0,r=t.map((function(t,e){return We([e===n?"M":"L"],Ve(t),!1)}));return e?r.reverse():r}function ZG(t,e){if(void 0===e&&(e=!1),t.length<=2)return KG(t);for(var n=[],r=t.length,i=0;i=0?(s[l]+=i[l],i[l]=s[l]):(s[l]+=o[l],o[l]=s[l]);return e}var eV=function(t){function e(e){return t.call(this,e,{type:"line",x:0,y:0,width:200,height:20,isStack:!1,color:["#83daad","#edbf45","#d2cef9","#e290b3","#6f63f4"],smooth:!0,lineLineWidth:1,areaOpacity:0,isGroup:!1,columnLineWidth:1,columnStroke:"#fff",scale:1,spacing:0})||this}return je(e,t),Object.defineProperty(e.prototype,"rawData",{get:function(){var t=this.attributes.data;if(!t||0===(null==t?void 0:t.length))return[[]];var e=me(t);return ae(e[0])?[e]:e},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"data",{get:function(){return this.attributes.isStack?tV(this.rawData):this.rawData},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"scales",{get:function(){return this.createScales(this.data)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"baseline",{get:function(){var t=this.scales.y,e=Ve(t.getOptions().domain||[0,0],2),n=e[0],r=e[1];return r<0?t.map(r):t.map(n<0?0:n)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"containerShape",{get:function(){var t=this.attributes;return{width:t.width,height:t.height}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"linesStyle",{get:function(){var t=this,e=this.attributes,n=e.type,r=e.isStack,i=e.smooth;if("line"!==n)throw new Error("linesStyle can only be used in line type");var o=Fz(this.attributes,"area"),a=Fz(this.attributes,"line"),s=this.containerShape.width,l=this.data;if(0===l[0].length)return{lines:[],areas:[]};var u=this.scales,c=function(t,e){var n,r=e.x,i=e.y,o=Ve(i.getOptions().range||[0,0],2),a=o[0],s=o[1];return s>a&&(n=Ve([a,s],2),s=n[0],a=n[1]),t.map((function(t){return t.map((function(t,e){return[r.map(e),oe(i.map(t),s,a)]}))}))}(l,{x:u.x,y:u.y}),h=[];if(o){var d=this.baseline;h=r?i?function(t,e,n){for(var r=[],i=t.length-1;i>=0;i-=1){var o=t[i],a=ZG(o),s=void 0;if(0===i)s=QG(a,e,n);else{var l=ZG(t[i-1],!0),u=o[0];l[0][0]="L",s=We(We(We([],Ve(a),!1),Ve(l),!1),[We(["M"],Ve(u),!1),["Z"]],!1)}r.push(s)}return r}(c,s,d):function(t,e,n){for(var r=[],i=t.length-1;i>=0;i-=1){var o=KG(t[i]),a=void 0;if(0===i)a=QG(o,e,n);else{var s=KG(t[i-1],!0);s[0][0]="L",a=We(We(We([],Ve(o),!1),Ve(s),!1),[["Z"]],!1)}r.push(a)}return r}(c,s,d):function(t,e,n,r){return t.map((function(t){return QG(e?ZG(t):KG(t),n,r)}))}(c,i,s,d)}return{lines:c.map((function(e,n){return Be({stroke:t.getColor(n),d:i?ZG(e):KG(e)},a)})),areas:h.map((function(e,n){return Be({d:e,fill:t.getColor(n)},o)}))}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"columnsStyle",{get:function(){var t=this,e=Fz(this.attributes,"column"),n=this.attributes,r=n.isStack,i=n.type,o=n.scale;if("column"!==i)throw new Error("columnsStyle can only be used in column type");var a=this.containerShape.height,s=this.rawData;if(!s)return{columns:[]};r&&(s=tV(s));var l=this.createScales(s),u=l.x,c=l.y,h=Ve(JG(s),2),d=h[0],f=h[1],p=new YG({domain:[0,f-(d>0?0:d)],range:[0,a*o]}),g=u.getBandWidth(),v=this.rawData;return{columns:s.map((function(n,i){return n.map((function(n,o){var a=g/s.length;return Be(Be({fill:t.getColor(i)},e),r?{x:u.map(o),y:c.map(n),width:g,height:p.map(v[i][o])}:{x:u.map(o)+a*i,y:n>=0?c.map(n):c.map(0),width:a,height:p.map(Math.abs(n))})}))}))}},enumerable:!1,configurable:!0}),e.prototype.render=function(t,e){var n,r,i;(n=e,r=".container",i="rect",n.querySelector(r)?Rz(n).select(r):Rz(n).append(i)).attr("className","container").node();var o=t.type,a=t.x,s=t.y,l="spark".concat(o),u=Be({x:a,y:s},"line"===o?this.linesStyle:this.columnsStyle);Rz(e).selectAll(".spark").data([o]).join((function(t){return t.append((function(t){return"line"===t?new XG({className:l,style:u}):new qG({className:l,style:u})})).attr("className","spark ".concat(l))}),(function(t){return t.update(u)}),(function(t){return t.remove()}))},e.prototype.getColor=function(t){var e=this.attributes.color;return Yt(e)?e[t%e.length]:Ut(e)?e.call(null,t):e},e.prototype.createScales=function(t){var e,n,r=this.attributes,i=r.type,o=r.scale,a=r.range,s=void 0===a?[]:a,l=r.spacing,u=this.containerShape,c=u.width,h=u.height,d=Ve(JG(t),2),f=d[0],p=d[1],g=new YG({domain:[null!==(e=s[0])&&void 0!==e?e:f,null!==(n=s[1])&&void 0!==n?n:p],range:[h,h*(1-o)]});return"line"===i?{type:i,x:new YG({domain:[0,t[0].length-1],range:[0,c]}),y:g}:{type:i,x:new GG({domain:t[0].map((function(t,e){return e})),range:[0,c],paddingInner:l,paddingOuter:l/2,align:.5}),y:g}},e.tag="sparkline",e}($z);function nV(t){if(!t)return{enter:!1,update:!1,exit:!1};var e=["enter","update","exit"],n=Object.fromEntries(Object.entries(t).filter((function(t){var n=Ve(t,1)[0];return!e.includes(n)})));return Object.fromEntries(e.map((function(e){return function(t){return"boolean"!=typeof t&&"enter"in t&&"update"in t&&"exit"in t}(t)?!1===t[e]?[e,!1]:[e,Be(Be({},t[e]),n)]:[e,n]})))}function rV(t,e){t?t.finished.then(e):e()}function iV(t,e){"update"in t?t.update(e):t.attr(e)}function oV(t,e,n){return 0===e.length?null:n?t.animate(e,n):(iV(t,{style:e.slice(-1)[0]}),null)}function aV(t,e,n){var r={},i={};return Object.entries(e).forEach((function(e){var n=Ve(e,2),o=n[0],a=n[1];if(!$t(a)){var s=t.style[o]||t.parsedStyle[o]||0;s!==a&&(r[o]=s,i[o]=a)}})),n?oV(t,[r,i],Be({fill:"both"},n)):(iV(t,i),null)}function sV(t,e){return t.style.opacity||(t.style.opacity=1),aV(t,{opacity:0},e)}var lV={fill:"#fff",lineWidth:1,radius:2,size:10,stroke:"#bfbfbf",strokeOpacity:1,zIndex:0},uV={fill:"#000",fillOpacity:.45,fontSize:12,textAlign:"center",textBaseline:"middle",zIndex:1},cV={x:0,y:0,orientation:"horizontal",showLabel:!0,type:"start"},hV=rz({foreground:"foreground",handle:"handle",selection:"selection",sparkline:"sparkline",sparklineGroup:"sparkline-group",track:"track",brushArea:"brush-area"},"slider"),dV=rz({labelGroup:"label-group",label:"label",iconGroup:"icon-group",icon:"icon",iconRect:"icon-rect",iconLine:"icon-line"},"handle"),fV=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return je(e,t),e.prototype.render=function(t,e){var n=t.x,r=t.y,i=t.size,o=void 0===i?10:i,a=t.radius,s=void 0===a?o/4:a,l=t.orientation,u=Fe(t,["x","y","size","radius","orientation"]),c=o,h=2.4*c,d=Rz(e).maybeAppendByClassName(dV.iconRect,"rect").styles(Be(Be({},u),{width:c,height:h,radius:s,x:n-c/2,y:r-h/2,transformOrigin:"center"})),f=n+1/3*c-c/2,p=n+2/3*c-c/2,g=r+1/4*h-h/2,v=r+3/4*h-h/2;d.maybeAppendByClassName("".concat(dV.iconLine,"-1"),"line").styles(Be({x1:f,x2:f,y1:g,y2:v},u)),d.maybeAppendByClassName("".concat(dV.iconLine,"-2"),"line").styles(Be({x1:p,x2:p,y1:g,y2:v},u)),"vertical"===l&&(d.node().style.transform="rotate(90)")},e}($z),pV=function(t){function e(e){return t.call(this,e,cV)||this}return je(e,t),e.prototype.renderLabel=function(t){var e=this,n=this.attributes,r=n.x,i=n.y,o=n.showLabel,a=Fz(this.attributes,"label"),s=a.x,l=void 0===s?0:s,u=a.y,c=void 0===u?0:u,h=a.transform,d=a.transformOrigin,f=Ve(Gz(Fe(a,["x","y","transform","transformOrigin"]),[]),2),p=f[0],g=f[1],v=Rz(t).maybeAppendByClassName(dV.labelGroup,"g").styles(g),m=Be(Be({},uV),p),y=m.text,b=Fe(m,["text"]);pz(!!o,v,(function(t){e.label=t.maybeAppendByClassName(dV.label,"text").styles(Be(Be({},b),{x:r+l,y:i+c,transform:h,transformOrigin:d,text:"".concat(y)})),e.label.on("mousedown",(function(t){t.stopPropagation()})),e.label.on("touchstart",(function(t){t.stopPropagation()}))}))},e.prototype.renderIcon=function(t){var e=this.attributes,n=e.x,r=e.y,i=e.orientation,o=e.type,a=Be(Be({x:n,y:r,orientation:i},lV),Fz(this.attributes,"icon")),s=this.attributes.iconShape,l=void 0===s?function(){return new fV({style:a})}:s;Rz(t).maybeAppendByClassName(dV.iconGroup,"g").selectAll(dV.icon.class).data([l]).join((function(t){return t.append("string"==typeof l?l:function(){return l(o)}).attr("className",dV.icon.name)}),(function(t){return t.update(a)}),(function(t){return t.remove()}))},e.prototype.render=function(t,e){this.renderIcon(e),this.renderLabel(e)},e}($z),gV=function(t){function e(e){var n=t.call(this,e,Be(Be(Be({x:0,y:0,animate:{duration:100,fill:"both"},brushable:!0,formatter:function(t){return t.toString()},handleSpacing:2,orientation:"horizontal",padding:0,autoFitLabel:!0,scrollable:!0,selectionFill:"#5B8FF9",selectionFillOpacity:.45,selectionZIndex:2,showHandle:!0,showLabel:!0,slidable:!0,trackFill:"#416180",trackLength:200,trackOpacity:.05,trackSize:20,trackZIndex:-1,values:[0,1],type:"range",selectionType:"select",handleIconOffset:0},zz(cV,"handle")),zz(lV,"handleIcon")),zz(uV,"handleLabel")))||this;return n.range=[0,1],n.onDragStart=function(t){return function(e){e.stopPropagation(),n.target=t,n.prevPos=n.getOrientVal(dz(e));var r=n.availableSpace,i=r.x,o=r.y,a=n.getBBox(),s=a.x,l=a.y;n.selectionStartPos=n.getRatio(n.prevPos-n.getOrientVal([i,o])-n.getOrientVal([+s,+l])),n.selectionWidth=0,document.addEventListener("pointermove",n.onDragging),document.addEventListener("pointerup",n.onDragEnd)}},n.onDragging=function(t){var e=n.attributes,r=e.slidable,i=e.brushable,o=e.type;t.stopPropagation();var a=n.getOrientVal(dz(t)),s=a-n.prevPos;if(s){var l=n.getRatio(s);switch(n.target){case"start":r&&n.setValuesOffset(l);break;case"end":r&&n.setValuesOffset(0,l);break;case"selection":r&&n.setValuesOffset(l,l);break;case"track":if(!i)return;n.selectionWidth+=l,"range"===o?n.innerSetValues([n.selectionStartPos,n.selectionStartPos+n.selectionWidth].sort(),!0):n.innerSetValues([0,n.selectionStartPos+n.selectionWidth],!0)}n.prevPos=a}},n.onDragEnd=function(){document.removeEventListener("pointermove",n.onDragging),document.removeEventListener("pointermove",n.onDragging),document.removeEventListener("pointerup",n.onDragEnd),n.target="",n.updateHandlesPosition(!1)},n.onValueChange=function(t){var e=n.attributes,r=e.onChange,i=e.type,o="range"===i?t:t[1],a="range"===i?n.getValues():n.getValues()[1],s=new zs("valuechange",{detail:{oldValue:o,value:a}});n.dispatchEvent(s),null==r||r(a)},n.selectionStartPos=0,n.selectionWidth=0,n.prevPos=0,n.target="",n}return je(e,t),Object.defineProperty(e.prototype,"values",{get:function(){return this.attributes.values},set:function(t){this.attributes.values=this.clampValues(t)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"sparklineStyle",{get:function(){if("horizontal"!==this.attributes.orientation)return null;var t=Fz(this.attributes,"sparkline");return Be(Be({zIndex:0},this.availableSpace),t)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"shape",{get:function(){var t=this.attributes,e=t.trackLength,n=t.trackSize,r=Ve(this.getOrientVal([[e,n],[n,e]]),2);return{width:r[0],height:r[1]}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"availableSpace",{get:function(){var t=this.attributes;t.x,t.y;var e=Ve(Dz(t.padding),4),n=e[0],r=e[1],i=e[2],o=e[3],a=this.shape;return{x:o,y:n,width:a.width-(o+r),height:a.height-(n+i)}},enumerable:!1,configurable:!0}),e.prototype.getValues=function(){return this.values},e.prototype.setValues=function(t,e){void 0===t&&(t=[0,0]),void 0===e&&(e=!1),this.attributes.values=t;var n=!1!==e&&this.attributes.animate;this.updateSelectionArea(n),this.updateHandlesPosition(n)},e.prototype.updateSelectionArea=function(t){var e=this.calcSelectionArea();this.foregroundGroup.selectAll(hV.selection.class).each((function(n,r){aV(this,e[r],t)}))},e.prototype.updateHandlesPosition=function(t){this.attributes.showHandle&&(this.startHandle&&aV(this.startHandle,this.getHandleStyle("start"),t),this.endHandle&&aV(this.endHandle,this.getHandleStyle("end"),t))},e.prototype.innerSetValues=function(t,e){void 0===t&&(t=[0,0]),void 0===e&&(e=!1);var n=this.values,r=this.clampValues(t);this.attributes.values=r,this.setValues(r),e&&this.onValueChange(n)},e.prototype.renderTrack=function(t){var e=this.attributes,n=e.x,r=e.y,i=Fz(this.attributes,"track");this.trackShape=Rz(t).maybeAppendByClassName(hV.track,"rect").styles(Be(Be({x:n,y:r},this.shape),i))},e.prototype.renderBrushArea=function(t){var e=this.attributes,n=e.x,r=e.y,i=e.brushable;this.brushArea=Rz(t).maybeAppendByClassName(hV.brushArea,"rect").styles(Be({x:n,y:r,fill:"transparent",cursor:i?"crosshair":"default"},this.shape))},e.prototype.renderSparkline=function(t){var e=this,n=this.attributes,r=n.x,i=n.y;pz("horizontal"===n.orientation,Rz(t).maybeAppendByClassName(hV.sparklineGroup,"g"),(function(t){var n=Be(Be({},e.sparklineStyle),{x:r,y:i});t.maybeAppendByClassName(hV.sparkline,(function(){return new eV({style:n})})).update(n)}))},e.prototype.renderHandles=function(){var t,e=this,n=this.attributes,r=n.showHandle,i=n.type,o=r?"range"===i?["start","end"]:["end"]:[],a=this;null===(t=this.foregroundGroup)||void 0===t||t.selectAll(hV.handle.class).data(o.map((function(t){return{type:t}})),(function(t){return t.type})).join((function(t){return t.append((function(t){var n=t.type;return new pV({style:e.getHandleStyle(n)})})).each((function(t){var e=t.type;this.attr("class","".concat(hV.handle.name," ").concat(e,"-handle"));var n="".concat(e,"Handle");a[n]=this,this.addEventListener("pointerdown",a.onDragStart(e))}))}),(function(t){return t.each((function(t){var e=t.type;this.update(a.getHandleStyle(e))}))}),(function(t){return t.each((function(t){var e=t.type,n="".concat(e,"Handle");a[n]=void 0})).remove()}))},e.prototype.renderSelection=function(t){var e=this.attributes,n=e.x,r=e.y,i=e.type,o=e.selectionType;this.foregroundGroup=Rz(t).maybeAppendByClassName(hV.foreground,"g");var a=Fz(this.attributes,"selection"),s=function(t){return t.style("visibility",(function(t){return t.show?"visible":"hidden"})).style("cursor",(function(t){return"select"===o?"grab":"invert"===o?"crosshair":"default"})).styles(Be(Be({},a),{transform:"translate(".concat(n,", ").concat(r,")")}))},l=this;this.foregroundGroup.selectAll(hV.selection.class).data("value"===i?[]:this.calcSelectionArea().map((function(t,e){return{style:Be({},t),index:e,show:"select"===o?1===e:1!==e}})),(function(t){return t.index})).join((function(t){return t.append("rect").attr("className",hV.selection.name).call(s).each((function(t,e){var n=this;1===e?(l.selectionShape=Rz(this),this.on("pointerdown",(function(t){n.attr("cursor","grabbing"),l.onDragStart("selection")(t)})),l.dispatchCustomEvent(this,"pointerenter","selectionMouseenter"),l.dispatchCustomEvent(this,"pointerleave","selectionMouseleave"),l.dispatchCustomEvent(this,"click","selectionClick"),this.addEventListener("pointerdown",(function(){n.attr("cursor","grabbing")})),this.addEventListener("pointerup",(function(){n.attr("cursor","pointer")})),this.addEventListener("pointerover",(function(){n.attr("cursor","pointer")}))):this.on("pointerdown",l.onDragStart("track"))}))}),(function(t){return t.call(s)}),(function(t){return t.remove()})),this.updateSelectionArea(!1),this.renderHandles()},e.prototype.render=function(t,e){this.renderTrack(e),this.renderSparkline(e),this.renderBrushArea(e),this.renderSelection(e)},e.prototype.clampValues=function(t,e){var n;void 0===e&&(e=4);var r=Ve(this.range,2),i=r[0],o=r[1],a=Ve(this.getValues().map((function(t){return Mz(t,e)})),2),s=a[0],l=a[1],u=Ve(((Array.isArray(t)?t:[s,null!=t?t:l])||[s,l]).map((function(t){return Mz(t,e)})),2),c=u[0],h=u[1];if("value"===this.attributes.type)return[0,oe(h,i,o)];c>h&&(c=(n=Ve([h,c],2))[0],h=n[1]);var d=h-c;return d>o-i?[i,o]:co?l===o&&s===c?[c,o]:[o-d,o]:[c,h]},e.prototype.calcSelectionArea=function(t){var e=Ve(this.clampValues(t),2),n=e[0],r=e[1],i=this.availableSpace,o=i.x,a=i.y,s=i.width,l=i.height;return this.getOrientVal([[{y:a,height:l,x:o,width:n*s},{y:a,height:l,x:n*s+o,width:(r-n)*s},{y:a,height:l,x:r*s,width:(1-r)*s}],[{x:o,width:s,y:a,height:n*l},{x:o,width:s,y:n*l+a,height:(r-n)*l},{x:o,width:s,y:r*l,height:(1-r)*l}]])},e.prototype.calcHandlePosition=function(t){var e=this.attributes.handleIconOffset,n=this.availableSpace,r=n.x,i=n.y,o=n.width,a=n.height,s=Ve(this.clampValues(),2),l=s[0],u=s[1],c="start"===t?-e:e,h=("start"===t?l:u)*this.getOrientVal([o,a])+c;return{x:r+this.getOrientVal([h,o/2]),y:i+this.getOrientVal([a/2,h])}},e.prototype.inferTextStyle=function(t){return"horizontal"===this.attributes.orientation?{}:"start"===t?{transformOrigin:"left center",transform:"rotate(90)",textAlign:"start"}:"end"===t?{transformOrigin:"right center",transform:"rotate(90)",textAlign:"end"}:{}},e.prototype.calcHandleText=function(t){var e,n=this.attributes,r=n.type,i=n.orientation,o=n.formatter,a=n.autoFitLabel,s=Fz(this.attributes,"handle"),l=Fz(s,"label"),u=s.spacing,c=this.getHandleSize(),h=this.clampValues(),d=o("start"===t?h[0]:h[1]),f=new ZF({style:Be(Be(Be({},l),this.inferTextStyle(t)),{text:d})}),p=f.getBBox(),g=p.width,v=p.height;if(f.destroy(),!a){if("value"===r)return{text:d,x:0,y:-v-u};var m=u+c+("horizontal"===i?g/2:0);return(e={text:d})["horizontal"===i?"x":"y"]="start"===t?-m:m,e}var y=0,b=0,x=this.availableSpace,E=x.width,w=x.height,k=this.calcSelectionArea()[1],M=k.x,S=k.y,N=k.width,O=k.height,T=u+c;if("horizontal"===i){var C=T+g/2;if("start"===t)y=M-T-g>0?-C:C;else y=E-M-N-T>g?C:-C}else{var A=v+T;b="start"===t?S-c>v?-A:T:w-(S+O)-c>v?A:-T}return{x:y,y:b,text:d}},e.prototype.getHandleLabelStyle=function(t){var e=Fz(this.attributes,"handleLabel");return Be(Be(Be({},e),this.calcHandleText(t)),this.inferTextStyle(t))},e.prototype.getHandleIconStyle=function(){var t=this.attributes.handleIconShape,e=Fz(this.attributes,"handleIcon"),n=this.getOrientVal(["ew-resize","ns-resize"]),r=this.getHandleSize();return Be({cursor:n,shape:t,size:r},e)},e.prototype.getHandleStyle=function(t){var e=this.attributes,n=e.x,r=e.y,i=e.showLabel,o=e.showLabelOnInteraction,a=e.orientation,s=this.calcHandlePosition(t),l=s.x,u=s.y,c=this.calcHandleText(t),h=i;return!i&&o&&(h=!!this.target),Be(Be(Be({},zz(this.getHandleIconStyle(),"icon")),zz(Be(Be({},this.getHandleLabelStyle(t)),c),"label")),{transform:"translate(".concat(l+n,", ").concat(u+r,")"),orientation:a,showLabel:h,type:t,zIndex:3})},e.prototype.getHandleSize=function(){var t=this.attributes,e=t.handleIconSize,n=t.width,r=t.height;return e||Math.floor((this.getOrientVal([+r,+n])+4)/2.4)},e.prototype.getOrientVal=function(t){var e=Ve(t,2),n=e[0],r=e[1];return"horizontal"===this.attributes.orientation?n:r},e.prototype.setValuesOffset=function(t,e,n){void 0===e&&(e=0),void 0===n&&(n=!1);var r=this.attributes.type,i=Ve(this.getValues(),2),o=[i[0]+("range"===r?t:0),i[1]+e].sort();n?this.setValues(o):this.innerSetValues(o,!0)},e.prototype.getRatio=function(t){var e=this.availableSpace,n=e.width,r=e.height;return t/this.getOrientVal([n,r])},e.prototype.dispatchCustomEvent=function(t,e,n){var r=this;t.on(e,(function(t){t.stopPropagation(),r.dispatchEvent(new zs(n,{detail:t}))}))},e.prototype.bindEvents=function(){this.addEventListener("wheel",this.onScroll);var t=this.brushArea;this.dispatchCustomEvent(t,"click","trackClick"),this.dispatchCustomEvent(t,"pointerenter","trackMouseenter"),this.dispatchCustomEvent(t,"pointerleave","trackMouseleave"),t.on("pointerdown",this.onDragStart("track"))},e.prototype.onScroll=function(t){if(this.attributes.scrollable){var e=t.deltaX,n=t.deltaY||e,r=this.getRatio(n);this.setValuesOffset(r,r,!0)}},e.tag="slider",e}($z),vV={data:[],animate:{enter:!1,update:{duration:100,easing:"ease-in-out-sine",fill:"both"},exit:{duration:100,fill:"both"}},showArrow:!0,showGrid:!0,showLabel:!0,showLine:!0,showTick:!0,showTitle:!0,showTrunc:!1,dataThreshold:100,lineLineWidth:1,lineStroke:"black",crossPadding:10,titleFill:"black",titleFontSize:12,titlePosition:"lb",titleSpacing:0,titleTextAlign:"center",titleTextBaseline:"middle",lineArrow:function(){return new Ql({style:{d:[["M",10,10],["L",-10,0],["L",10,-10],["L",0,0],["L",10,10],["Z"]],fill:"black",transformOrigin:"center"}})},labelAlign:"parallel",labelDirection:"positive",labelFontSize:12,labelSpacing:0,gridConnect:"line",gridControlAngles:[],gridDirection:"positive",gridLength:0,gridType:"segment",lineArrowOffset:15,lineArrowSize:10,tickDirection:"positive",tickLength:5,tickLineWidth:1,tickStroke:"black",labelOverlap:[]};ke({},vV,{style:{type:"arc"}}),ke({},vV,{style:{}});var mV=rz({mainGroup:"main-group",gridGroup:"grid-group",grid:"grid",lineGroup:"line-group",line:"line",tickGroup:"tick-group",tick:"tick",tickItem:"tick-item",labelGroup:"label-group",label:"label",labelItem:"label-item",titleGroup:"title-group",title:"title",lineFirst:"line-first",lineSecond:"line-second"},"axis"),yV=rz({lineGroup:"line-group",line:"line",regionGroup:"region-group",region:"region"},"grid");function bV(t){return t.reduce((function(t,e,n){return t.push(We([0===n?"M":"L"],Ve(e),!1)),t}),[])}function xV(t,e,n){return"surround"===e.type?function(t,e,n){var r=e.connect,i=void 0===r?"line":r,o=e.center;if("line"===i)return bV(t);if(!o)return[];var a=wz(t[0],o),s=n?0:1;return t.reduce((function(t,e,n){return 0===n?t.push(We(["M"],Ve(e),!1)):t.push(We(["A",a,a,0,0,s],Ve(e),!1)),t}),[])}(t,e,n):bV(t)}function EV(t,e,n){var r=n.type,i=n.connect,o=n.center,a=n.closed?[["Z"]]:[],s=Ve([xV(t,n),xV(e.slice().reverse(),n,!0)],2),l=s[0],u=s[1],c=Ve([t[0],e.slice(-1)[0]],2),h=c[0],d=c[1],f=function(t,e){return[l,t,u,e,a].flat()};if("line"===i||"surround"===r)return f([We(["L"],Ve(d),!1)],[We(["L"],Ve(h),!1)]);if(!o)throw new Error("Arc grid need to specified center");var p=Ve([wz(d,o),wz(h,o)],2),g=p[0],v=p[1];return f([We(["A",g,g,0,0,1],Ve(d),!1),We(["L"],Ve(d),!1)],[We(["A",v,v,0,0,0],Ve(h),!1),We(["L"],Ve(h),!1)])}var wV=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return je(e,t),e.prototype.render=function(t,e){t.type,t.center,t.areaFill,t.closed;var n=Fe(t,["type","center","areaFill","closed"]),r=function(t){var e=t.data,n=void 0===e?[]:e;return t.closed?n.map((function(t){var e=t.points,n=Ve(e,1)[0];return Be(Be({},t),{points:We(We([],Ve(e),!1),[n],!1)})})):n}(t),i=Rz(e).maybeAppendByClassName(yV.lineGroup,"g"),o=Rz(e).maybeAppendByClassName(yV.regionGroup,"g"),a=function(t,e,n,r){var i=n.animate,o=n.isBillboard,a=e.map((function(t,e){return{id:t.id||"grid-line-".concat(e),d:xV(t.points,n)}}));return t.selectAll(yV.line.class).data(a,(function(t){return t.id})).join((function(t){return t.append("path").each((function(t,e){var n=ez(Cz(Be({d:t.d},r)),[t,e,a]);this.attr(Be({class:yV.line.name,stroke:"#D9D9D9",lineWidth:1,lineDash:[4,4],isBillboard:o},n))}))}),(function(t){return t.transition((function(t,e){return aV(this,ez(Cz(Be({d:t.d},r)),[t,e,a]),i.update)}))}),(function(t){return t.transition((function(){var t=this,e=sV(this,i.exit);return rV(e,(function(){return t.remove()})),e}))})).transitions()}(i,r,t,n),s=function(t,e,n){var r=n.animate,i=n.connect,o=n.areaFill;if(e.length<2||!o||!i)return[];for(var a=Array.isArray(o)?o:[o,"transparent"],s=function(t){return a[t%a.length]},l=[],u=0;u180?1:0,E=t>e?0:1;return"M".concat(p,",").concat(g,",A").concat(s,",").concat(l,",0,").concat(x,",").concat(E,",").concat(m,",").concat(y)}function LV(t,e,n,r){var i=e.startAngle,o=e.endAngle,a=e.center,s=e.radius;return t.selectAll(mV.line.class).data([{d:DV.apply(void 0,We(We([i,o],Ve(a),!1),[s],!1))}],(function(t,e){return e})).join((function(t){return t.append("path").attr("className",mV.line.name).styles(e).styles({d:function(t){return t.d}})}),(function(t){return t.transition((function(){var t=this,e=function(t,e,n,r){if(!r)return t.attr("__keyframe_data__",n),null;var i=r.duration,o=void 0===i?0:i,a=vz(e,n),s=Math.ceil(+o/16),l=new Array(s).fill(0).map((function(t,e,n){return{__keyframe_data__:a(e/(n.length-1))}}));return t.animate(l,Be({fill:"both"},r))}(this,function(t){var e=t.attributes,n=e.startAngle,r=e.endAngle,i=e.center,o=e.radius;return We(We([n,r],Ve(i),!1),[o],!1)}(this),We(We([i,o],Ve(a),!1),[s],!1),r.update);if(e){var n=function(){var e=Oe(t.attributes,"__keyframe_data__");t.style.d=DV.apply(void 0,We([],Ve(e),!1))};e.onframe=n,e.onfinish=n}return e})).styles(e)}),(function(t){return t.remove()})).styles(n).transitions()}function _V(t){var e=Ve(t,2),n=Ve(e[0],2),r=n[0],i=n[1],o=Ve(e[1],2);return{x1:r,y1:i,x2:o[0],y2:o[1]}}function IV(t,e,n,r){var i=e.showTrunc,o=e.startPos,a=e.endPos,s=e.truncRange,l=e.lineExtension,u=Ve([o,a],2),c=Ve(u[0],2),h=c[0],d=c[1],f=Ve(u[1],2),p=f[0],g=f[1],v=Ve(l?function(t,e,n){void 0===n&&(n=[0,0]);var r=Ve([t,e,n],3),i=Ve(r[0],2),o=i[0],a=i[1],s=Ve(r[1],2),l=s[0],u=s[1],c=Ve(r[2],2),h=c[0],d=c[1],f=Ve([l-o,u-a],2),p=f[0],g=f[1],v=Math.sqrt(Math.pow(p,2)+Math.pow(g,2)),m=Ve([-h/v,d/v],2),y=m[0],b=m[1];return[y*p,y*g,b*p,b*g]}(o,a,l):new Array(4).fill(0),4),m=v[0],y=v[1],b=v[2],x=v[3],E=function(e){return t.selectAll(mV.line.class).data(e,(function(t,e){return e})).join((function(t){return t.append("line").attr("className",(function(t){return"".concat(mV.line.name," ").concat(t.className)})).styles(n).transition((function(t){return aV(this,_V(t.line),!1)}))}),(function(t){return t.styles(n).transition((function(t){return aV(this,_V(t.line),r.update)}))}),(function(t){return t.remove()})).transitions()};if(!i||!s)return E([{line:[[h+m,d+y],[p+b,g+x]],className:mV.line.name}]);var w=Ve(s,2),k=w[0],M=w[1],S=p-h,N=g-d,O=Ve([h+S*k,d+N*k],2),T=O[0],C=O[1],A=Ve([h+S*M,d+N*M],2),P=A[0],R=A[1],D=E([{line:[[h+m,d+y],[T,C]],className:mV.lineFirst.name},{line:[[P,R],[p+b,g+x]],className:mV.lineSecond.name}]);return function(t,e){e.truncRange,e.truncShape,e.lineExtension}(0,e),D}function jV(t,e,n){var r,i=e.type,o=Fz(e,"line");return r="linear"===i?IV(t,e,Sz(o,"arrow"),n):LV(t,e,Sz(o,"arrow"),n),function(t,e,n,r){var i,o=n.showArrow,a=n.showTrunc,s=n.lineArrow,l=n.lineArrowOffset,u=n.lineArrowSize;if(i="arc"===e?t.select(mV.line.class):a?t.select(mV.lineSecond.class):t.select(mV.line.class),!o||!s||"arc"===n.type&&RV(n.startAngle,n.endAngle)){var c=i.node();c&&(c.style.markerEnd=void 0)}else{var h=fz(s);h.attr(r),Az(h,u),i.style("markerEnd",h).style("markerEndOffset",-l)}}(t,i,e,o),r}function BV(t){var e=t.type,n=t.gridCenter;return"linear"===e?n:n||t.center}function FV(t,e){var n=e.gridLength;return t.map((function(t,r){var i=t.value,o=Ve(CV(i,e),2),a=o[0],s=o[1],l=Ve(mz(function(t,e){return OV(t,e.gridDirection,e)}(i,e),n),2);return{id:r,points:[[a,s],[a+l[0],s+l[1]]]}}))}function zV(t,e,n,r){var i=Fz(n,"grid"),o=i.type,a=i.areaFill,s=BV(n),l=MV(e,n.gridFilter),u="segment"===o?FV(l,n):function(t,e){var n=e.gridControlAngles,r=BV(e);if(!r)throw new Error("grid center is not provide");if(t.length<2)throw new Error("Invalid grid data");if(!n||0===n.length)throw new Error("Invalid gridControlAngles");var i=Ve(r,2),o=i[0],a=i[1];return t.map((function(t,r){var i=Ve(CV(t.value,e),2),s=i[0],l=i[1],u=Ve([s-o,l-a],2),c=u[0],h=u[1],d=[];return n.forEach((function(t){var e=QF(t),n=Ve([Math.cos(e),Math.sin(e)],2),r=n[0],i=n[1],s=c*r-h*i+o,l=c*i+h*r+a;d.push([s,l])})),{points:d,id:r}}))}(l,n),c=Be(Be({},i),{center:s,areaFill:Ut(a)?l.map((function(t,e){return ez(a,[t,e,l])})):a,animate:r,data:u});return t.selectAll(mV.grid.class).data([1]).join((function(t){return t.append((function(){return new wV({style:c})})).attr("className",mV.grid.name)}),(function(t){return t.transition((function(){return this.update(c)}))}),(function(t){return t.remove()})).transitions()}var GV=function(){function t(t,e,n,r){this.set(t,e,n,r)}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x1},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y1},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x2},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y2},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"width",{get:function(){return this.defined("x2")&&this.defined("x1")?this.x2-this.x1:void 0},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"height",{get:function(){return this.defined("y2")&&this.defined("y1")?this.y2-this.y1:void 0},enumerable:!1,configurable:!0}),t.prototype.rotatedPoints=function(t,e,n){var r=this,i=r.x1,o=r.y1,a=r.x2,s=r.y2,l=Math.cos(t),u=Math.sin(t),c=e-e*l+n*u,h=n-e*u-n*l;return[[l*i-u*s+c,u*i+l*s+h],[l*a-u*s+c,u*a+l*s+h],[l*i-u*o+c,u*i+l*o+h],[l*a-u*o+c,u*a+l*o+h]]},t.prototype.set=function(t,e,n,r){return n0,v=r-l,m=i-u,y=c*m-h*v;if(y<0===g)return!1;var b=d*m-f*v;return b<0!==g&&y>p!==g&&b>p!==g}(e,t)}))}function YV(t,e,n){var r,i,o=e.crossPadding,a=new Set,s=null,l=function(t,e){var n=t.type,r=t.labelDirection,i=t.crossSize;if(!i)return!1;if("arc"===n){var o=t.center,a=t.radius,s=Ve(o,2),l=s[0],u=s[1],c="negative"===r?0:i,h=-a-c,d=a+c,f=Ve(Dz(e),4),p=f[0],g=f[1],v=f[2],m=f[3];return new GV(l+h-m,u+h-p,l+d+g,u+d+v)}var y=Ve(t.startPos,2),b=y[0],x=y[1],E=Ve(t.endPos,2),w=E[0],k=E[1],M=Ve(PV(t)?[-e,0,e,0]:[0,e,0,-e],4),S=M[0],N=M[1],O=M[2],T=M[3],C=mz(TV(0,t),i),A=new GV(b,x,w,k);return A.x1+=T,A.y1+=S,A.x2+=N+C[0],A.y2+=O+C[1],A}(e,o),u=function(t){return!l||function(t,e,n){var r=t.x1,i=t.x2,o=t.y1,a=t.y2;return UV([[r,o],[i,o],[i,a],[r,a]],VV(e,n))}(l,t)},c=function(t,e){return!t||!t.firstChild||!function(t,e,n){var r,i,o=VV(t,n).flat(1),a=VV(e,n).flat(1),s=[[o[0],o[1],o[2],o[3]],[o[0],o[1],o[4],o[5]],[o[4],o[5],o[6],o[7]],[o[2],o[3],o[6],o[7]]];try{for(var l=Ge(s),u=l.next();!u.done;u=l.next())if($V(a,u.value))return!0}catch(t){r={error:t}}finally{try{u&&!u.done&&(i=l.return)&&i.call(l)}finally{if(r)throw r.error}}return!1}(t.firstChild,e.firstChild,Dz(n))};try{for(var h=Ge(t),d=h.next();!d.done;d=h.next()){var f=d.value;u(f)?!s||c(s,f)?s=f:(a.add(s),a.add(f)):a.add(f)}}catch(t){r={error:t}}finally{try{d&&!d.done&&(i=h.return)&&i.call(h)}finally{if(r)throw r.error}}return Array.from(a)}function qV(t,e){return void 0===e&&(e={}),$t(t)?0:"number"==typeof t?t:Math.floor(sz(t,e))}var XV=function(t,e){var n=e.seq,r=void 0===n?2:n;return t.filter((function(t,e){return!(e%r)||(YF(t),!1)}))};var KV=new Map([["hide",function(t,e,n,r){var i=t.length,o=e.keepHeader,a=e.keepTail;if(!(i<=1||2===i&&o&&a)){var s,l,u,c=XV,h=function(t){return t.forEach(r.show),t},d=2,f=t.slice(),p=t.slice(),g=Math.min.apply(Math,We([1],Ve(t.map((function(t){return t.getBBox().width}))),!1));if("linear"===n.type&&(AV(n)||PV(n))){var v=Lz(t[0]).left,m=Lz(t[i-1]).right,y=Math.abs(m-v)||1;d=Math.max(Math.floor(i*g/y),d)}for(o&&(s=f.splice(0,1)[0]),a&&(l=f.splice(-1,1)[0],f.reverse()),h(f);dg+p;x-=p){var E=b(x);if("object"==typeof E)return E.value}}}],["wrap",function(t,e,n,r,i){var o,a=e.maxLines,s=void 0===a?3:a,l=e.recoverWhenFailed,u=void 0===l||l,c=e.margin,h=void 0===c?[0,0,0,0]:c,d=ez(null!==(o=e.wordWrapWidth)&&void 0!==o?o:50,[i]),f=t.map((function(t){return t.attr("maxLines")||1})),p=Math.min.apply(Math,We([],Ve(f),!1)),g=function(){return YV(t,n,h).length<1},v=function(t){var e=t.type,n=t.labelDirection;return"linear"===e&&AV(t)?"negative"===n?"bottom":"top":"middle"}(n),m=function(e){return t.forEach((function(t,n){var i=Array.isArray(e)?e[n]:e;r.wrap(t,d,i,v)}))};if(!(p>s)){if("linear"===n.type&&AV(n)){if(m(s),g())return}else for(var y=p;y<=s;y++)if(m(y),g())return;u&&m(f)}}]]);function ZV(){for(var t=[],e=0;e=1)})(t,e,o)&&(null==a||a(t,i,e,r,n))}))}(this.node().childNodes,t,e,{hide:YF,show:$F,rotate:function(e,n){!function(t,e,n){e.setLocalEulerAngles(t);var r=eW(e.__data__.value,t,n),i=e.querySelector(mV.labelItem.class);i&&rW(i,r)}(+n,e,t)},ellipsis:function(t,e,n){t&&hz(t,e||1/0,n)},wrap:function(t,e,n){var r,i;t&&(void 0===(r=n)&&(r=2),void 0===i&&(i="top"),cz(t,{wordWrap:!0,wordWrapWidth:e,maxLines:r,textBaseline:i}))},getTextShape:function(t){return t.querySelector("text")}})}function oW(t,e,n,r,i){var o=n.indexOf(e),a=Rz(t).append(function(t,e,n,r){var i=r.labelFormatter;return Ut(i)?function(){return fz(ez(i,[t,e,n,TV(t.value,r)]))}:function(){return fz(t.label||"")}}(e,o,n,i)).attr("className",mV.labelItem.name).node(),s=Ve(Gz(kV(r,[e,o,n])),2),l=s[0],u=s[1],c=u.transform,h=Fe(u,["transform"]);Wz(a,c);var d=tW(e,a,i);return a.getLocalEulerAngles()||a.setLocalEulerAngles(d),rW(a,Be(Be({},eW(e.value,d,i)),l)),t.attr(h),a}function aW(t,e,n,r,i){var o,a,s,l=MV(e,n.labelFilter),u=Fz(n,"label"),c=t.selectAll(mV.label.class).data(l,(function(t,e){return e})).join((function(t){return t.append("g").attr("className",mV.label.name).transition((function(t){oW(this,t,e,u,n);var r=nW(t,e,n),i=r.x,o=r.y;return this.style.transform="translate(".concat(i,", ").concat(o,")"),null}))}),(function(t){return t.transition((function(t){var i=function(t,e,n,r){if(void 0===r&&(r="destroy"),function(t,e){return"text"===t.nodeName&&"text"===e.nodeName&&t.attributes.text===e.attributes.text}(t,e))return t.remove(),[null];var i=function(){"destroy"===r?t.destroy():"hide"===r&&YF(t),e.isVisible()&&$F(e)};if(!n)return i(),[null];var o=n.duration,a=void 0===o?0:o,s=n.delay,l=void 0===s?0:s,u=Math.ceil(+a/2),c=+a/4,h=Ve(t.getGeometryBounds().center,2),d=h[0],f=h[1],p=Ve(e.getGeometryBounds().center,2),g=Ve([(d+p[0])/2-d,(f+p[1])/2-f],2),v=g[0],m=g[1],y=t.style.opacity,b=void 0===y?1:y,x=e.style.opacity,E=void 0===x?1:x,w=t.style.transform||"",k=e.style.transform||"",M=t.animate([{opacity:b,transform:"translate(0, 0) ".concat(w)},{opacity:0,transform:"translate(".concat(v,", ").concat(m,") ").concat(w)}],Be(Be({fill:"both"},n),{duration:l+u+c})),S=e.animate([{opacity:0,transform:"translate(".concat(-v,", ").concat(-m,") ").concat(k),offset:.01},{opacity:E,transform:"translate(0, 0) ".concat(k)}],Be(Be({fill:"both"},n),{duration:u+c,delay:l+u-c}));return rV(S,i),[M,S]}(this.querySelector(mV.labelItem.class),oW(this,t,e,u,n),r.update),o=nW(t,e,n),a=o.x,s=o.y,l=aV(this,{transform:"translate(".concat(a,", ").concat(s,")")},r.update);return We(We([],Ve(i),!1),[l],!1)}))}),(function(t){return o=t,t.transition((function(){var t=this,e=sV(this.childNodes[0],r.exit);return rV(e,(function(){return Rz(t).remove()})),e})),o})).transitions();return s=function(){iW.call(t,n,i)},0===(a=c).length?s():Promise.all(a.map((function(t){return null==t?void 0:t.finished}))).then(s),c}function sW(t,e){return OV(t,e.tickDirection,e)}function lW(t,e,n,r,i){var o=Ve(function(t,e){var n=Ve(t,2);return[[0,0],[n[0]*e,n[1]*e]]}(r,ez(i.tickLength,[t,e,n])),2),a=Ve(o[0],2),s=a[0],l=a[1],u=Ve(o[1],2);return{x1:s,x2:u[0],y1:l,y2:u[1]}}function uW(t,e,n,r,i,o){var a=function(t,e,n,r,i){var o=i.tickFormatter,a=sW(e.value,i),s="line";return Ut(o)&&(s=function(){return ez(o,[e,n,r,a])}),t.append(s).attr("className",mV.tickItem.name)}(Rz(this),t,e,n,r);!function(t,e,n,r,i,o,a){var s=sW(t.value,o),l=lW(t,e,n,s,o),u=l.x1,c=l.x2,h=l.y1,d=l.y2,f=Ve(Gz(kV(a,[t,e,n,s])),2),p=f[0],g=f[1];"line"===r.node().nodeName&&r.styles(Be({x1:u,x2:c,y1:h,y2:d},p)),i.attr(g),r.styles(p)}(t,e,n,a,this,r,i);var s=Ve(CV(t.value,r),2),l=s[0],u=s[1];return aV(this,{transform:"translate(".concat(l,", ").concat(u,")")},o)}var cW=rz({text:"text"},"title");function hW(t){return/\S+-\S+/g.test(t)?t.split("-").map((function(t){return t[0]})):t.length>2?[t[0]]:t.split("")}function dW(t,e){var n=Object.entries(e).reduce((function(e,n){var r=Ve(n,2),i=r[0],o=r[1];return t.node().attr(i)||(e[i]=o),e}),{});t.styles(n)}var fW=function(t){function e(e){return t.call(this,e,{text:"",width:0,height:0,fill:"#4a505a",fontWeight:"bold",fontSize:12,fontFamily:"sans-serif",inset:0,spacing:0,position:"top-left"})||this}return je(e,t),e.prototype.getAvailableSpace=function(){var t=this.attributes,e=t.width,n=t.height,r=t.position,i=t.spacing,o=t.inset,a=this.querySelector(cW.text.class);if(!a)return new tz(0,0,+e,+n);var s=a.getBBox(),l=s.width,u=s.height,c=Ve(Dz(i),4),h=c[0],d=c[1],f=c[2],p=c[3],g=Ve([0,0,+e,+n],4),v=g[0],m=g[1],y=g[2],b=g[3],x=hW(r);if(x.includes("i"))return new tz(v,m,y,b);x.forEach((function(t,r){var i,o,a,s;"t"===t&&(i=Ve(0===r?[u+f,+n-u-f]:[0,+n],2),m=i[0],b=i[1]),"r"===t&&(o=Ve([+e-l-p],1),y=o[0]),"b"===t&&(a=Ve([+n-u-h],1),b=a[0]),"l"===t&&(s=Ve(0===r?[l+d,+e-l-d]:[0,+e],2),v=s[0],y=s[1])}));var E=Ve(Dz(o),4),w=E[0],k=E[1],M=E[2],S=E[3],N=Ve([S+k,w+M],2),O=N[0],T=N[1];return new tz(v+S,m+w,y-O,b-T)},e.prototype.getBBox=function(){return this.title?this.title.getBBox():new tz(0,0,0,0)},e.prototype.render=function(t,e){var n=this;t.width,t.height,t.position,t.spacing;var r=Fe(t,["width","height","position","spacing"]),i=Ve(Gz(r),1)[0],o=function(t){var e,n,r,i,o=t,a=o.width,s=o.height,l=o.position,u=Ve([+a/2,+s/2],2),c=Ve([+u[0],+u[1],"center","middle"],4),h=c[0],d=c[1],f=c[2],p=c[3],g=hW(l);return g.includes("l")&&(h=(e=Ve([0,"start"],2))[0],f=e[1]),g.includes("r")&&(h=(n=Ve([+a,"end"],2))[0],f=n[1]),g.includes("t")&&(d=(r=Ve([0,"top"],2))[0],p=r[1]),g.includes("b")&&(d=(i=Ve([+s,"bottom"],2))[0],p=i[1]),{x:h,y:d,textAlign:f,textBaseline:p}}(t),a=o.x,s=o.y,l=o.textAlign,u=o.textBaseline;pz(!!r.text,Rz(e),(function(t){n.title=t.maybeAppendByClassName(cW.text,"text").styles(i).call(dW,{x:a,y:s,textAlign:l,textBaseline:u}).node()}))},e}($z);function pW(t,e,n,r,i){var o=Ve(Gz(Fz(r,"title")),2),a=o[0],s=o[1],l=s.transform,u=s.transformOrigin,c=Fe(s,["transform","transformOrigin"]);e.styles(c);var h=l||function(t,e,n){var r=2*t.getGeometryBounds().halfExtents[1];if("vertical"===e){if("left"===n)return"rotate(-90) translate(0, ".concat(r/2,")");if("right"===n)return"rotate(-90) translate(0, -".concat(r/2,")")}return""}(t.node(),a.direction,a.position);t.styles(Be(Be({},a),{transformOrigin:u})),Wz(t.node(),h);var d=function(t,e,n){var r=n.titlePosition,i=void 0===r?"lb":r,o=n.titleSpacing,a=hW(i),s=t.node().getLocalBounds(),l=Ve(s.min,2),u=l[0],c=l[1],h=Ve(s.halfExtents,2),d=h[0],f=h[1],p=Ve(e.node().getLocalBounds().halfExtents,2),g=p[0],v=p[1],m=Ve([u+d,c+f],2),y=m[0],b=m[1],x=Ve(Dz(o),4),E=x[0],w=x[1],k=x[2],M=x[3];if(["start","end"].includes(i)&&"linear"===n.type){var S=n.startPos,N=n.endPos,O=Ve("start"===i?[S,N]:[N,S],2),T=O[0],C=O[1],A=Ve(mz(kz([-C[0]+T[0],-C[1]+T[1]]),E),2),P=A[0],R=A[1];return{x:T[0]+P,y:T[1]+R}}return a.includes("t")&&(b-=f+v+E),a.includes("r")&&(y+=d+g+w),a.includes("l")&&(y-=d+g+M),a.includes("b")&&(b+=f+v+k),{x:y,y:b}}(Rz(n._offscreen||n.querySelector(mV.mainGroup.class)),e,r),f=d.x,p=d.y;return aV(e.node(),{transform:"translate(".concat(f,", ").concat(p,")")},i)}function gW(t,e,n,r){var i=t.showLine,o=t.showTick,a=t.showLabel,s=pz(i,e.maybeAppendByClassName(mV.lineGroup,"g"),(function(e){return jV(e,t,r)}))||[],l=pz(o,e.maybeAppendByClassName(mV.tickGroup,"g"),(function(e){return function(t,e,n,r){var i=MV(e,n.tickFilter),o=Fz(n,"tick");return t.selectAll(mV.tick.class).data(i,(function(t){return t.id||t.label})).join((function(t){return t.append("g").attr("className",mV.tick.name).transition((function(t,e){return uW.call(this,t,e,i,n,o,!1)}))}),(function(t){return t.transition((function(t,e){return this.removeChildren(),uW.call(this,t,e,i,n,o,r.update)}))}),(function(t){return t.transition((function(){var t=this,e=sV(this.childNodes[0],r.exit);return rV(e,(function(){return t.remove()})),e}))})).transitions()}(e,n,t,r)}))||[],u=pz(a,e.maybeAppendByClassName(mV.labelGroup,"g"),(function(i){return aW(i,n,t,r,e.node())}))||[];return We(We(We([],Ve(s),!1),Ve(l),!1),Ve(u),!1).filter((function(t){return!!t}))}var vW=function(t){function e(e){return t.call(this,e,vV)||this}return je(e,t),e.prototype.render=function(t,e,n){var r=this,i=t.titleText,o=t.data,a=t.animate,s=t.showTitle,l=t.showGrid,u=t.dataThreshold,c=t.truncRange,h=function(t,e){if(t.length<=e)return t;for(var n=Math.floor(t.length/e),r=[],i=0;ic[0]&&e1?{width:55,height:0}:{width:0,height:0}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"pageShape",{get:function(){var t=Ve(function(t){var e;return(null===(e=t[0])||void 0===e?void 0:e.map((function(e,n){return t.map((function(t){return t[n]}))})))||[]}(this.pageViews.map((function(t){var e=t.getBBox();return[e.width,e.height]}))).map((function(t){return Math.max.apply(Math,We([],Ve(t),!1))})),2),e=t[0],n=t[1],r=this.attributes,i=r.pageWidth,o=void 0===i?e:i,a=r.pageHeight;return{pageWidth:o,pageHeight:void 0===a?n:a}},enumerable:!1,configurable:!0}),e.prototype.getContainer=function(){return this.playWindow},Object.defineProperty(e.prototype,"totalPages",{get:function(){return this.pageViews.length},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"currPage",{get:function(){return this.innerCurrPage},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var e=t.prototype.getBBox.call(this),n=e.x,r=e.y,i=this.controllerShape,o=this.pageShape,a=o.pageWidth,s=o.pageHeight;return new tz(n,r,a+i.width,s)},e.prototype.goTo=function(t){var e=this,n=this.attributes.animate,r=this,i=r.currPage,o=r.playState,a=r.playWindow,s=r.pageViews;if("idle"!==o||t<0||s.length<=0||t>=s.length)return null;s[i].setLocalPosition(0,0),this.prepareFollowingPage(t);var l=Ve(this.getFollowingPageDiff(t),2),u=l[0],c=l[1];this.playState="running";var h=oV(a,[{transform:"translate(0, 0)"},{transform:"translate(".concat(-u,", ").concat(-c,")")}],n);return rV(h,(function(){e.innerCurrPage=t,e.playState="idle",e.setVisiblePages([t]),e.updatePageInfo()})),h},e.prototype.prev=function(){var t=this.attributes.loop,e=this.pageViews.length,n=this.currPage;if(!t&&n<=0)return null;var r=t?(n-1+e)%e:oe(n-1,0,e);return this.goTo(r)},e.prototype.next=function(){var t=this.attributes.loop,e=this.pageViews.length,n=this.currPage;if(!t&&n>=e-1)return null;var r=t?(n+1)%e:oe(n+1,0,e);return this.goTo(r)},e.prototype.renderClipPath=function(t){var e=this.pageShape,n=e.pageWidth,r=e.pageHeight;n&&r?(this.clipPath=t.maybeAppendByClassName(mW.clipPath,"rect").styles({width:n,height:r}),this.contentGroup.attr("clipPath",this.clipPath.node())):this.contentGroup.style.clipPath=void 0},e.prototype.setVisiblePages=function(t){this.playWindow.children.forEach((function(e,n){t.includes(n)?$F(e):YF(e)}))},e.prototype.adjustControllerLayout=function(){var t=this,e=t.prevBtnGroup,n=t.nextBtnGroup,r=t.pageInfoGroup,i=this.attributes,o=i.orientation,a=i.controllerPadding,s=r.getBBox(),l=s.width;s.height;var u=Ve("horizontal"===o?[-180,0]:[-90,90],2),c=u[0],h=u[1];e.setLocalEulerAngles(c),n.setLocalEulerAngles(h);var d=e.getBBox(),f=d.width,p=d.height,g=n.getBBox(),v=g.width,m=g.height,y=Math.max(f,l,v),b="horizontal"===o?{offset:[[0,0],[f/2+a,0],[f+l+2*a,0]],textAlign:"start"}:{offset:[[y/2,-p-a],[y/2,0],[y/2,m+a]],textAlign:"center"},x=Ve(b.offset,3),E=Ve(x[0],2),w=E[0],k=E[1],M=Ve(x[1],2),S=M[0],N=M[1],O=Ve(x[2],2),T=O[0],C=O[1],A=b.textAlign,P=r.querySelector("text");P&&(P.style.textAlign=A),e.setLocalPosition(w,k),r.setLocalPosition(S,N),n.setLocalPosition(T,C)},e.prototype.updatePageInfo=function(){var t,e=this,n=e.currPage,r=e.pageViews,i=e.attributes.formatter;r.length<2||(null===(t=this.pageInfoGroup.querySelector(mW.pageInfo.class))||void 0===t||t.attr("text",i(n+1,r.length)),this.adjustControllerLayout())},e.prototype.getFollowingPageDiff=function(t){var e=this.currPage;if(e===t)return[0,0];var n=this.attributes.orientation,r=this.pageShape,i=r.pageWidth,o=r.pageHeight,a=t=2,s=t.maybeAppendByClassName(mW.controller,"g");if(qF(s.node(),a),a){var l=Fz(this.attributes,"button"),u=Fz(this.attributes,"pageNum"),c=Ve(Gz(l),2),h=c[0],d=c[1],f=h.size,p=Fe(h,["size"]),g=!s.select(mW.prevBtnGroup.class).node(),v=s.maybeAppendByClassName(mW.prevBtnGroup,"g").styles(d);this.prevBtnGroup=v.node();var m=v.maybeAppendByClassName(mW.prevBtn,"path"),y=s.maybeAppendByClassName(mW.nextBtnGroup,"g").styles(d);this.nextBtnGroup=y.node(),[m,y.maybeAppendByClassName(mW.nextBtn,"path")].forEach((function(t){t.styles(Be(Be({},p),{transformOrigin:"center"})),Az(t.node(),f)}));var b=s.maybeAppendByClassName(mW.pageInfoGroup,"g");this.pageInfoGroup=b.node(),b.maybeAppendByClassName(mW.pageInfo,"text").styles(u),this.updatePageInfo(),s.node().setLocalPosition(i+n,o/2),g&&(this.prevBtnGroup.addEventListener("click",(function(){e.prev()})),this.nextBtnGroup.addEventListener("click",(function(){e.next()})))}},e.prototype.render=function(t,e){var n=t.x,r=void 0===n?0:n,i=t.y,o=void 0===i?0:i;this.attr("transform","translate(".concat(r,", ").concat(o,")"));var a=Rz(e);this.renderClipPath(a),this.renderController(a),this.setVisiblePages([this.defaultPage]),this.goTo(this.defaultPage)},e.prototype.bindEvents=function(){var t=this,e=ye((function(){return t.render(t.attributes,t)}),50);this.playWindow.addEventListener(Ks.INSERTED,e),this.playWindow.addEventListener(Ks.REMOVED,e)},e}($z);function bW(t,e,n){return void 0===t&&(t="horizontal"),"horizontal"===t?e:n}tG.registerSymbol("hiddenHandle",(function(t,e,n){var r=1.4*n;return[["M",t-n,e-r],["L",t+n,e-r],["L",t+n,e+r],["L",t-n,e+r],["Z"]]})),tG.registerSymbol("verticalHandle",(function(t,e,n){var r=1.4*n,i=n/2,o=n/6,a=t+.4*r;return[["M",t,e],["L",a,e+i],["L",t+r,e+i],["L",t+r,e-i],["L",a,e-i],["Z"],["M",a,e+o],["L",t+r-2,e+o],["M",a,e-o],["L",t+r-2,e-o]]})),tG.registerSymbol("horizontalHandle",(function(t,e,n){var r=1.4*n,i=n/2,o=n/6,a=e+.4*r;return[["M",t,e],["L",t-i,a],["L",t-i,e+r],["L",t+i,e+r],["L",t+i,a],["Z"],["M",t-o,a],["L",t-o,e+r-2],["M",t+o,a],["L",t+o,e+r-2]]}));var xW=rz({layout:"flex",markerGroup:"marker-group",marker:"marker",labelGroup:"label-group",label:"label",valueGroup:"value-group",value:"value",backgroundGroup:"background-group",background:"background"},"legend-category-item");var EW=function(t){function e(e){return t.call(this,e,{span:[1,1],marker:function(){return new Gl({style:{r:6}})},markerSize:10,labelFill:"#646464",valueFill:"#646464",labelFontSize:12,valueFontSize:12,labelTextBaseline:"middle",valueTextBaseline:"middle"})||this}return je(e,t),Object.defineProperty(e.prototype,"showValue",{get:function(){var t=this.attributes.valueText;return!!t&&("string"==typeof t||"number"==typeof t?""!==t:"function"==typeof t||""!==t.attr("text"))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"actualSpace",{get:function(){var t=this.labelGroup,e=this.valueGroup,n=this.attributes.markerSize,r=t.node().getBBox(),i=r.width,o=r.height,a=e.node().getBBox(),s=a.width,l=a.height;return{markerWidth:n,labelWidth:i,valueWidth:s,height:Math.max(n,o,l)}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"span",{get:function(){var t=this.attributes.span;if(!t)return[1,1];var e=Ve(Dz(t),2),n=e[0],r=e[1],i=this.showValue?r:0,o=n+i;return[n/o,i/o]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"shape",{get:function(){var t,e=this.attributes,n=e.markerSize,r=e.width,i=this.actualSpace,o=i.markerWidth,a=i.height,s=this.actualSpace,l=s.labelWidth,u=s.valueWidth,c=Ve(this.spacing,2),h=c[0],d=c[1];if(r){var f=r-n-h-d,p=Ve(this.span,2);l=(t=Ve([p[0]*f,p[1]*f],2))[0],u=t[1]}return{width:o+l+u+h+d,height:a,markerWidth:o,labelWidth:l,valueWidth:u}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"spacing",{get:function(){var t=this.attributes.spacing;if(!t)return[0,0];var e=Ve(Dz(t),2),n=e[0],r=e[1];return this.showValue?[n,r]:[n,0]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"layout",{get:function(){var t=this.shape,e=t.markerWidth,n=t.labelWidth,r=t.valueWidth,i=t.width,o=t.height,a=Ve(this.spacing,2),s=a[0];return{height:o,width:i,markerWidth:e,labelWidth:n,valueWidth:r,position:[e/2,e+s,e+n+s+a[1]]}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"scaleSize",{get:function(){var t=function(t){var e=t.querySelector(xW.marker.class);return e?e.style:{}}(this.markerGroup.node()),e=this.attributes,n=e.markerSize,r=e.markerStrokeWidth,i=void 0===r?t.strokeWidth:r,o=e.markerLineWidth,a=void 0===o?t.lineWidth:o,s=e.markerStroke,l=void 0===s?t.stroke:s,u=+(i||a||(l?1:0))*Math.sqrt(2),c=this.markerGroup.node().getBBox(),h=c.width,d=c.height;return(1-u/Math.max(h,d))*n},enumerable:!1,configurable:!0}),e.prototype.renderMarker=function(t){var e=this,n=this.attributes.marker,r=Fz(this.attributes,"marker");this.markerGroup=t.maybeAppendByClassName(xW.markerGroup,"g").style("zIndex",0),pz(!!n,this.markerGroup,(function(){var t,i=e.markerGroup.node(),o=null===(t=i.childNodes)||void 0===t?void 0:t[0],a="string"==typeof n?new tG({style:{symbol:n},className:xW.marker.name}):n();o?a.nodeName===o.nodeName?o instanceof tG?o.update(Be(Be({},r),{symbol:n})):(!function(t,e){var n,r,i=e.attributes;try{for(var o=Ge(Object.entries(i)),a=o.next();!a.done;a=o.next()){var s=Ve(a.value,2),l=s[0],u=s[1];"id"!==l&&"className"!==l&&t.attr(l,u)}}catch(t){n={error:t}}finally{try{a&&!a.done&&(r=o.return)&&r.call(o)}finally{if(n)throw n.error}}}(o,a),Rz(o).styles(r)):(o.remove(),Rz(a).attr("className",xW.marker.name).styles(r),i.appendChild(a)):(a instanceof tG||Rz(a).attr("className",xW.marker.name).styles(r),i.appendChild(a)),e.markerGroup.node().scale(1/e.markerGroup.node().getScale()[0]);var s=Az(e.markerGroup.node(),e.scaleSize);e.markerGroup.node().style._transform="scale(".concat(s,")")}))},e.prototype.renderLabel=function(t){var e=Fz(this.attributes,"label"),n=e.text,r=Fe(e,["text"]);this.labelGroup=t.maybeAppendByClassName(xW.labelGroup,"g").style("zIndex",0),this.labelGroup.maybeAppendByClassName(xW.label,(function(){return fz(n)})).styles(r)},e.prototype.renderValue=function(t){var e=this,n=Fz(this.attributes,"value"),r=n.text,i=Fe(n,["text"]);this.valueGroup=t.maybeAppendByClassName(xW.valueGroup,"g").style("zIndex",0),pz(this.showValue,this.valueGroup,(function(){e.valueGroup.maybeAppendByClassName(xW.value,(function(){return fz(r)})).styles(i)}))},e.prototype.renderBackground=function(t){var e=this.shape,n=e.width,r=e.height,i=Fz(this.attributes,"background");this.background=t.maybeAppendByClassName(xW.backgroundGroup,"g").style("zIndex",-1),this.background.maybeAppendByClassName(xW.background,"rect").styles(Be({width:n,height:r},i))},e.prototype.adjustLayout=function(){var t=this.layout,e=t.labelWidth,n=t.valueWidth,r=t.height,i=Ve(t.position,3),o=i[0],a=i[1],s=i[2],l=r/2;this.markerGroup.styles({transform:"translate(".concat(o,", ").concat(l,")").concat(this.markerGroup.node().style._transform)}),this.labelGroup.styles({transform:"translate(".concat(a,", ").concat(l,")")}),hz(this.labelGroup.select(xW.label.class).node(),Math.ceil(e)),this.showValue&&(this.valueGroup.styles({transform:"translate(".concat(s,", ").concat(l,")")}),hz(this.valueGroup.select(xW.value.class).node(),Math.ceil(n)))},e.prototype.render=function(t,e){var n=Rz(e),r=t.x,i=void 0===r?0:r,o=t.y,a=void 0===o?0:o;n.styles({transform:"translate(".concat(i,", ").concat(a,")")}),this.renderMarker(n),this.renderLabel(n),this.renderValue(n),this.renderBackground(n),this.adjustLayout()},e}($z),wW=rz({page:"item-page",navigator:"navigator",item:"item"},"items"),kW=function(t,e,n){return void 0===n&&(n=!0),t?e(t):n},MW=function(t){function e(e){var n=t.call(this,e,{data:[],gridRow:1/0,gridCol:void 0,padding:0,width:1e3,height:100,rowPadding:0,colPadding:0,layout:"flex",orientation:"horizontal",click:Le,mouseenter:Le,mouseleave:Le})||this;return n.navigatorShape=[0,0],n}return je(e,t),Object.defineProperty(e.prototype,"pageViews",{get:function(){return this.navigator.getContainer()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"grid",{get:function(){var t=this.attributes,e=t.gridRow,n=t.gridCol,r=t.data;if(!e&&!n)throw new Error("gridRow and gridCol can not be set null at the same time");return e&&n?[e,n]:e?[e,r.length]:[r.length,n]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"renderData",{get:function(){var t=this.attributes,e=t.data,n=t.layout,r=Fz(this.attributes,"item"),i=e.map((function(t,i){var o=t.id,a=void 0===o?i:o,s=t.label,l=t.value;return{id:"".concat(a),index:i,style:Be({layout:n,labelText:s,valueText:l},Object.fromEntries(Object.entries(r).map((function(n){var r=Ve(n,2);return[r[0],ez(r[1],[t,i,e])]}))))}}));return i},enumerable:!1,configurable:!0}),e.prototype.getGridLayout=function(){var t=this,e=this.attributes,n=e.orientation,r=e.width,i=e.rowPadding,o=e.colPadding,a=Ve(this.navigatorShape,1)[0],s=Ve(this.grid,2),l=s[0],u=s[1],c=u*l,h=0;return this.pageViews.children.map((function(e,s){var d,f,p=Math.floor(s/c),g=s%c,v=t.ifHorizontal(u,l),m=[Math.floor(g/v),g%v];"vertical"===n&&m.reverse();var y=Ve(m,2),b=y[0],x=y[1],E=(r-a-(u-1)*o)/u,w=e.getBBox().height,k=Ve([0,0],2),M=k[0],S=k[1];return"horizontal"===n?(M=(d=Ve([h,b*(w+i)],2))[0],S=d[1],h=x===u-1?0:h+E+o):(M=(f=Ve([x*(E+o),h],2))[0],S=f[1],h=b===l-1?0:h+w+i),{page:p,index:s,row:b,col:x,pageIndex:g,width:E,height:w,x:M,y:S}}))},e.prototype.getFlexLayout=function(){var t=this.attributes,e=t.width,n=t.height,r=t.rowPadding,i=t.colPadding,o=Ve(this.navigatorShape,1)[0],a=Ve(this.grid,2),s=a[0],l=a[1],u=Ve([e-o,n],2),c=u[0],h=u[1],d=Ve([0,0,0,0,0,0,0,0],8),f=d[0],p=d[1],g=d[2],v=d[3],m=d[4],y=d[5],b=d[6],x=d[7];return this.pageViews.children.map((function(t,e){var n,o,a,u,d=t.getBBox(),E=d.width,w=d.height,k=0===b?0:i,M=b+k+E;return M<=c&&kW(m,(function(t){return t0?(this.navigatorShape=[55,0],t.call(this)):e},enumerable:!1,configurable:!0}),e.prototype.ifHorizontal=function(t,e){return bW(this.attributes.orientation,t,e)},e.prototype.flattenPage=function(t){t.querySelectorAll(wW.item.class).forEach((function(e){t.appendChild(e)})),t.querySelectorAll(wW.page.class).forEach((function(e){t.removeChild(e).destroy()}))},e.prototype.renderItems=function(t){var e=this.attributes,n=e.click,r=e.mouseenter,i=e.mouseleave;this.flattenPage(t);var o=this.dispatchCustomEvent.bind(this);Rz(t).selectAll(wW.item.class).data(this.renderData,(function(t){return t.id})).join((function(t){return t.append((function(t){var e=t.style;return new EW({style:e})})).attr("className",wW.item.name).on("click",(function(){null==n||n(this),o("itemClick",{item:this})})).on("pointerenter",(function(){null==r||r(this),o("itemMouseenter",{item:this})})).on("pointerleave",(function(){null==i||i(this),o("itemMouseleave",{item:this})}))}),(function(t){return t.each((function(t){var e=t.style;this.update(e)}))}),(function(t){return t.remove()}))},e.prototype.relayoutNavigator=function(){var t,e=this.attributes,n=e.layout,r=e.width,i=(null===(t=this.pageViews.children[0])||void 0===t?void 0:t.getBBox().height)||0,o=Ve(this.navigatorShape,2),a=o[0],s=o[1];this.navigator.update("grid"===n?{pageWidth:r-a,pageHeight:i-s}:{})},e.prototype.adjustLayout=function(){var t,e,n=this,r=Object.entries((t=this.itemsLayout,e="page",t.reduce((function(t,n){return(t[n[e]]=t[n[e]]||[]).push(n),t}),{}))).map((function(t){var e=Ve(t,2);return{page:e[0],layouts:e[1]}})),i=We([],Ve(this.navigator.getContainer().children),!1);r.forEach((function(t){var e=t.layouts,r=n.pageViews.appendChild(new Ul({className:wW.page.name}));e.forEach((function(t){var e=t.x,n=t.y,o=t.index,a=t.width,s=t.height,l=i[o];r.appendChild(l),Te(l,"__layout__",t),l.update({x:e,y:n,width:a,height:s})}))})),this.relayoutNavigator()},e.prototype.renderNavigator=function(t){var e=this.attributes.orientation,n=Fz(this.attributes,"nav"),r=oz({orientation:e},n),i=this;return t.selectAll(wW.navigator.class).data(["nav"]).join((function(t){return t.append((function(){return new yW({style:r})})).attr("className",wW.navigator.name).each((function(){i.navigator=this}))}),(function(t){return t.each((function(){this.update(r)}))}),(function(t){return t.remove()})),this.navigator},e.prototype.getBBox=function(){return this.navigator.getBBox()},e.prototype.render=function(t,e){var n=this.attributes.data;if(n&&0!==n.length){var r=this.renderNavigator(Rz(e));this.renderItems(r.getContainer()),this.adjustLayout()}},e.prototype.dispatchCustomEvent=function(t,e){var n=new zs(t,{detail:e});this.dispatchEvent(n)},e}($z),SW=rz({markerGroup:"marker-group",marker:"marker",labelGroup:"label-group",label:"label"},"handle"),NW={showLabel:!0,formatter:function(t){return t.toString()},markerSize:25,markerStroke:"#c5c5c5",markerFill:"#fff",markerLineWidth:1,labelFontSize:12,labelFill:"#c5c5c5",labelText:"",orientation:"vertical",spacing:0};!function(t){function e(e){return t.call(this,e,NW)||this}je(e,t),e.prototype.render=function(t,e){var n=Rz(e).maybeAppendByClassName(SW.markerGroup,"g");this.renderMarker(n);var r=Rz(e).maybeAppendByClassName(SW.labelGroup,"g");this.renderLabel(r)},e.prototype.renderMarker=function(t){var e=this,n=this.attributes,r=n.orientation,i=n.markerSymbol,o=void 0===i?bW(r,"horizontalHandle","verticalHandle"):i;pz(!!o,t,(function(t){var n=Fz(e.attributes,"marker"),r=Be({symbol:o},n);e.marker=t.maybeAppendByClassName(SW.marker,(function(){return new tG({style:r})})).update(r)}))},e.prototype.renderLabel=function(t){var e=this,n=this.attributes,r=n.showLabel,i=n.orientation,o=n.spacing,a=void 0===o?0:o,s=n.formatter;pz(r,t,(function(t){var n,r=Fz(e.attributes,"label"),o=r.text,l=Fe(r,["text"]),u=(null===(n=t.select(SW.marker.class))||void 0===n?void 0:n.node().getBBox())||{},c=u.width,h=void 0===c?0:c,d=u.height,f=Ve(bW(i,[0,(void 0===d?0:d)+a,"center","top"],[h+a,0,"start","middle"]),4),p=f[0],g=f[1],v=f[2],m=f[3];t.maybeAppendByClassName(SW.label,"text").styles(Be(Be({},l),{x:p,y:g,text:s(o).toString(),textAlign:v,textBaseline:m}))}))}}($z);var OW={showTitle:!0,padding:0,orientation:"horizontal",backgroundFill:"transparent",titleText:"",titleSpacing:4,titlePosition:"top-left",titleFill:"#2C3542",titleFontWeight:"bold",titleFontFamily:"sans-serif",titleFontSize:12},TW=oz({},OW,{});oz({},OW,zz(NW,"handle"),{color:["#d0e3fa","#acc7f6","#8daaf2","#6d8eea","#4d73cd","#325bb1","#5a3e75","#8c3c79","#e23455","#e7655b"],indicatorBackgroundFill:"#262626",indicatorLabelFill:"white",indicatorLabelFontSize:12,indicatorVisibility:"hidden",labelAlign:"value",labelDirection:"positive",labelSpacing:5,showHandle:!0,showIndicator:!0,showLabel:!0,slidable:!0,titleText:"",type:"continuous"});var CW=rz({title:"title",titleGroup:"title-group",items:"items",itemsGroup:"items-group",contentGroup:"content-group",ribbonGroup:"ribbon-group",ribbon:"ribbon",handlesGroup:"handles-group",handle:"handle",startHandle:"start-handle",endHandle:"end-handle",labelGroup:"label-group",label:"label",indicator:"indicator"},"legend"),AW=function(t){function e(e){return t.call(this,e,TW)||this}return je(e,t),e.prototype.renderTitle=function(t,e,n){var r=this.attributes,i=r.showTitle,o=r.titleText,a=Ve(Gz(Fz(this.attributes,"title")),2),s=a[0],l=a[1];this.titleGroup=t.maybeAppendByClassName(CW.titleGroup,"g").styles(l);var u=Be(Be({width:e,height:n},s),{text:i?o:""});this.title=this.titleGroup.maybeAppendByClassName(CW.title,(function(){return new fW({style:u})})).update(u)},e.prototype.renderItems=function(t,e){var n=e.x,r=e.y,i=e.width,o=e.height,a=Ve(Gz(Fz(this.attributes,"title",!0)),2),s=a[0],l=a[1],u=Be(Be({},s),{width:i,height:o,x:0,y:0});this.itemsGroup=t.maybeAppendByClassName(CW.itemsGroup,"g").styles(Be(Be({},l),{transform:"translate(".concat(n,", ").concat(r,")")}));var c=this;this.itemsGroup.selectAll(CW.items.class).data(["items"]).join((function(t){return t.append((function(){return new MW({style:u})})).attr("className",CW.items.name).each((function(){c.items=Rz(this)}))}),(function(t){return t.update(u)}),(function(t){return t.remove()}))},e.prototype.adjustLayout=function(){if(this.attributes.showTitle){var t=this.title.node().getAvailableSpace(),e=t.x,n=t.y;this.itemsGroup.node().style.transform="translate(".concat(e,", ").concat(n,")")}},Object.defineProperty(e.prototype,"availableSpace",{get:function(){var t=this.attributes,e=t.showTitle,n=t.width,r=t.height;return e?this.title.node().getAvailableSpace():new tz(0,0,n,r)},enumerable:!1,configurable:!0}),e.prototype.getBBox=function(){var e,n,r=null===(e=this.title)||void 0===e?void 0:e.node(),i=null===(n=this.items)||void 0===n?void 0:n.node();return r&&i?function(t,e){var n=t.attributes,r=n.position,i=n.spacing,o=n.inset,a=n.text,s=t.getBBox(),l=e.getBBox(),u=hW(r),c=Ve(Dz(a?i:0),4),h=c[0],d=c[1],f=c[2],p=c[3],g=Ve(Dz(o),4),v=g[0],m=g[1],y=g[2],b=g[3],x=Ve([p+d,h+f],2),E=x[0],w=x[1],k=Ve([b+m,v+y],2),M=k[0],S=k[1];if("l"===u[0])return new tz(s.x,s.y,l.width+s.width+E+M,Math.max(l.height+S,s.height));if("t"===u[0])return new tz(s.x,s.y,Math.max(l.width+M,s.width),l.height+s.height+w+S);var N=Ve([e.attributes.width||l.width,e.attributes.height||l.height],2),O=N[0],T=N[1];return new tz(l.x,l.y,O+s.width+E+M,T+s.height+w+S)}(r,i):t.prototype.getBBox.call(this)},e.prototype.render=function(t,e){var n=this.attributes,r=n.width,i=n.height,o=n.x,a=void 0===o?0:o,s=n.y,l=void 0===s?0:s,u=Rz(e);e.style.transform="translate(".concat(a,", ").concat(l,")"),this.renderTitle(u,r,i),this.renderItems(u,this.availableSpace),this.adjustLayout()},e}($z),PW={backgroundFill:"#262626",backgroundLineCap:"round",backgroundLineWidth:1,backgroundStroke:"#333",backgroundZIndex:-1,formatter:function(t){return t.toString()},labelFill:"#fff",labelFontSize:12,labelTextBaseline:"middle",padding:[2,4],position:"right",radius:0,zIndex:999},RW=rz({background:"background",labelGroup:"label-group",label:"label"},"indicator"),DW=function(t){function e(e){var n=t.call(this,e,PW)||this;return n.point=[0,0],n.group=n.appendChild(new Ul({})),n.isMutationObserved=!0,n}return je(e,t),e.prototype.renderBackground=function(){if(this.label){var t=this.attributes,e=t.position,n=Ve(Dz(t.padding),4),r=n[0],i=n[1],o=n[2],a=n[3],s=this.label.node().getLocalBounds(),l=s.min,u=s.max,c=new tz(l[0]-a,l[1]-r,u[0]+i-l[0]+a,u[1]+o-l[1]+r),h=this.getPath(e,c),d=Fz(this.attributes,"background");this.background=Rz(this.group).maybeAppendByClassName(RW.background,"path").styles(Be(Be({},d),{d:h})),this.group.appendChild(this.label.node())}},e.prototype.renderLabel=function(){var t=this.attributes,e=t.formatter,n=t.labelText,r=Ve(Gz(Fz(this.attributes,"label")),2),i=r[0],o=r[1];i.text;var a=Fe(i,["text"]);(this.label=Rz(this.group).maybeAppendByClassName(RW.labelGroup,"g").styles(o),n)&&this.label.maybeAppendByClassName(RW.label,(function(){return fz(e(n))})).style("text",e(n).toString()).selectAll("text").styles(a)},e.prototype.adjustLayout=function(){var t=Ve(this.point,2),e=t[0],n=t[1],r=this.attributes,i=r.x,o=r.y;this.group.attr("transform","translate(".concat(i-e,", ").concat(o-n,")"))},e.prototype.getPath=function(t,e){var n=this.attributes.radius,r=e.x,i=e.y,o=e.width,a=e.height,s=[["M",r+n,i],["L",r+o-n,i],["A",n,n,0,0,1,r+o,i+n],["L",r+o,i+a-n],["A",n,n,0,0,1,r+o-n,i+a],["L",r+n,i+a],["A",n,n,0,0,1,r,i+a-n],["L",r,i+n],["A",n,n,0,0,1,r+n,i],["Z"]],l={top:4,right:6,bottom:0,left:2}[t],u=this.createCorner([s[l].slice(-2),s[l+1].slice(-2)]);return s.splice.apply(s,We([l+1,1],Ve(u),!1)),s[0][0]="M",s},e.prototype.createCorner=function(t,e){void 0===e&&(e=10);var n=_z.apply(void 0,We([],Ve(t),!1)),r=Ve(t,2),i=Ve(r[0],2),o=i[0],a=i[1],s=Ve(r[1],2),l=s[0],u=s[1],c=Ve(n?[l-o,[o,l]]:[u-a,[a,u]],2),h=c[0],d=Ve(c[1],2),f=d[0],p=d[1],g=h/2,v=e*(h/Math.abs(h)),m=v/2,y=v*Math.sqrt(3)/2*.8,b=Ve([f,f+g-m,f+g,f+g+m,p],5),x=b[0],E=b[1],w=b[2],k=b[3],M=b[4];return n?(this.point=[w,a-y],[["L",x,a],["L",E,a],["L",w,a-y],["L",k,a],["L",M,a]]):(this.point=[o+y,w],[["L",o,x],["L",o,E],["L",o+y,w],["L",o,k],["L",o,M]])},e.prototype.applyVisibility=function(){"hidden"===this.attributes.visibility?YF(this):$F(this)},e.prototype.bindEvents=function(){this.label.on(Ks.BOUNDS_CHANGED,this.renderBackground)},e.prototype.render=function(){this.renderLabel(),this.renderBackground(),this.adjustLayout(),this.applyVisibility()},e}($z);function LW(t){return void 0===t&&(t=""),{CONTAINER:"".concat(t,"tooltip"),TITLE:"".concat(t,"tooltip-title"),LIST:"".concat(t,"tooltip-list"),LIST_ITEM:"".concat(t,"tooltip-list-item"),NAME:"".concat(t,"tooltip-list-item-name"),MARKER:"".concat(t,"tooltip-list-item-marker"),NAME_LABEL:"".concat(t,"tooltip-list-item-name-label"),VALUE:"".concat(t,"tooltip-list-item-value"),CROSSHAIR_X:"".concat(t,"tooltip-crosshair-x"),CROSSHAIR_Y:"".concat(t,"tooltip-crosshair-y")}}var _W={overflow:"hidden","white-space":"nowrap","text-overflow":"ellipsis"};function IW(t){var e;void 0===t&&(t="");var n=LW(t);return(e={})[".".concat(n.CONTAINER)]={position:"absolute",visibility:"visible","z-index":8,transition:"visibility 0.2s cubic-bezier(0.23, 1, 0.32, 1), left 0.4s cubic-bezier(0.23, 1, 0.32, 1), top 0.4s cubic-bezier(0.23, 1, 0.32, 1)","background-color":"rgba(255, 255, 255, 0.96)","box-shadow":"0 6px 12px 0 rgba(0, 0, 0, 0.12)","border-radius":"4px",color:"rgba(0, 0, 0, 0.65)","font-size":"12px","line-height":"20px",padding:"12px","min-width":"120px","max-width":"360px","font-family":"Roboto-Regular"},e[".".concat(n.TITLE)]={color:"rgba(0, 0, 0, 0.45)"},e[".".concat(n.LIST)]={margin:"0px","list-style-type":"none",padding:"0px"},e[".".concat(n.LIST_ITEM)]={"list-style-type":"none",display:"flex","line-height":"2em","align-items":"center","justify-content":"space-between","white-space":"nowrap"},e[".".concat(n.MARKER)]={width:"8px",height:"8px","border-radius":"50%",display:"inline-block","margin-right":"4px"},e[".".concat(n.NAME)]={display:"flex","align-items":"center","max-width":"216px"},e[".".concat(n.NAME_LABEL)]=Be({flex:1},_W),e[".".concat(n.VALUE)]=Be({display:"inline-block",float:"right",flex:1,"text-align":"right","min-width":"28px","margin-left":"30px",color:"rgba(0, 0, 0, 0.85)"},_W),e[".".concat(n.CROSSHAIR_X)]={position:"absolute",width:"1px","background-color":"rgba(0, 0, 0, 0.25)"},e[".".concat(n.CROSSHAIR_Y)]={position:"absolute",height:"1px","background-color":"rgba(0, 0, 0, 0.25)"},e}var jW=function(t){function e(e){var n,r,i=this,o=null===(r=null===(n=e.style)||void 0===n?void 0:n.template)||void 0===r?void 0:r.prefixCls,a=LW(o);return(i=t.call(this,e,{data:[],x:0,y:0,visibility:"visible",title:"",position:"bottom-right",offset:[5,5],enterable:!1,container:{x:0,y:0},bounding:null,template:{prefixCls:"",container:'
'),title:'
'),item:'
  • \n \n \n {name}\n \n {value}\n
  • ')},style:IW(o)})||this).timestamp=-1,i.prevCustomContentKey=i.attributes.contentKey,i.initShape(),i.render(i.attributes,i),i}return je(e,t),Object.defineProperty(e.prototype,"HTMLTooltipElement",{get:function(){return this.element},enumerable:!1,configurable:!0}),e.prototype.getContainer=function(){return this.element},Object.defineProperty(e.prototype,"elementSize",{get:function(){return{width:this.element.offsetWidth,height:this.element.offsetHeight}},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"HTMLTooltipItemsElements",{get:function(){var t=this.attributes,e=t.data,n=t.template;return e.map((function(t,e){var r=t.name,i=void 0===r?"":r,o=t.color,a=void 0===o?"black":o,s=t.index,l=Fe(t,["name","color","index"]),u=Be({name:i,color:a,index:null!=s?s:e},l);return Cn(function(t,e){return t&&e?t.replace(/\\?\{([^{}]+)\}/g,(function(t,n){return"\\"===t.charAt(0)?t.slice(1):void 0===e[n]?"":e[n]})):t}(n.item,u))}))},enumerable:!1,configurable:!0}),e.prototype.render=function(t,e){this.renderHTMLTooltipElement(),this.updatePosition()},e.prototype.destroy=function(){var e;null===(e=this.element)||void 0===e||e.remove(),t.prototype.destroy.call(this)},e.prototype.show=function(t,e){var n=this;if(void 0!==t&&void 0!==e){var r=function(){n.attributes.x=null!=t?t:n.attributes.x,n.attributes.y=null!=e?e:n.attributes.y,n.updatePosition()};"hidden"===this.element.style.visibility?this.closeTransition(r):r()}this.element.style.visibility="visible"},e.prototype.hide=function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.attributes.enterable&&this.isCursorEntered(t,e)||(this.element.style.visibility="hidden")},e.prototype.initShape=function(){var t=this.attributes.template;this.element=Cn(t.container),this.id&&this.element.setAttribute("id",this.id)},e.prototype.renderCustomContent=function(){if(void 0===this.prevCustomContentKey||this.prevCustomContentKey!==this.attributes.contentKey){this.prevCustomContentKey=this.attributes.contentKey;var t=this.attributes.content;t&&("string"==typeof t?this.element.innerHTML=t:Hz(this.element,t))}},e.prototype.renderHTMLTooltipElement=function(){var t,e,n=this.attributes,r=n.template,i=n.title,o=n.enterable,a=n.style,s=n.content,l=LW(r.prefixCls),u=this.element;if(this.element.style.pointerEvents=o?"auto":"none",s)this.renderCustomContent();else{i?(u.innerHTML=r.title,u.getElementsByClassName(l.TITLE)[0].innerHTML=i):null===(e=null===(t=u.getElementsByClassName(l.TITLE))||void 0===t?void 0:t[0])||void 0===e||e.remove();var c=this.HTMLTooltipItemsElements,h=document.createElement("ul");h.className=l.LIST,Hz(h,c);var d=this.element.querySelector(".".concat(l.LIST));d?d.replaceWith(h):u.appendChild(h)}!function(t,e){Object.entries(e).forEach((function(e){var n=Ve(e,2),r=n[0],i=n[1];We([t],Ve(t.querySelectorAll(r)),!1).filter((function(t){return t.matches(r)})).forEach((function(t){t&&(t.style.cssText+=Object.entries(i).reduce((function(t,e){return"".concat(t).concat(e.join(":"),";")}),""))}))}))}(u,a)},e.prototype.getRelativeOffsetFromCursor=function(t){var e=this.attributes,n=e.position,r=e.offset,i=(t||n).split("-"),o={left:[-1,0],right:[1,0],top:[0,-1],bottom:[0,1]},a=this.elementSize,s=a.width,l=a.height,u=[-s/2,-l/2];return i.forEach((function(t){var e=Ve(u,2),n=e[0],i=e[1],a=Ve(o[t],2),c=a[0],h=a[1];u=[n+(s/2+r[0])*c,i+(l/2+r[1])*h]})),u},e.prototype.setOffsetPosition=function(t){var e=Ve(t,2),n=e[0],r=e[1],i=this.attributes,o=i.x,a=void 0===o?0:o,s=i.y,l=void 0===s?0:s,u=i.container,c=u.x,h=u.y;this.element.style.left="".concat(+a+c+n,"px"),this.element.style.top="".concat(+l+h+r,"px")},e.prototype.updatePosition=function(){var t=this.attributes.showDelay,e=void 0===t?60:t,n=Date.now();this.timestamp>0&&n-this.timestampv+s.width,top:pm+s.height},b=[];l.split("-").forEach((function(t){y[t]?b.push(g[t]):b.push(t)}));var x=b.join("-");return this.getRelativeOffsetFromCursor(x)},e.prototype.isCursorEntered=function(t,e){if(this.element){var n=this.element.getBoundingClientRect(),r=n.x,i=n.y,o=n.width,a=n.height;return new tz(r,i,o,a).isPointIn(t,e)}return!1},e.prototype.closeTransition=function(t){var e=this,n=this.element.style.transition;this.element.style.transition="none",t(),setTimeout((function(){e.element.style.transition=n}),10)},e.tag="tooltip",e}($z),BW=function(t){function e(n){var r=t.call(this,oz({},e.defaultOptions,n))||this;return r.hoverColor="#f5f5f5",r.selectedColor="#e6f7ff",r.background=r.appendChild(new ru({})),r.label=r.background.appendChild(new Ul({})),r}return je(e,t),Object.defineProperty(e.prototype,"padding",{get:function(){return Dz(this.style.padding)},enumerable:!1,configurable:!0}),e.prototype.renderLabel=function(){var t=this.style,e=t.label,n=t.value,r=Fz(this.attributes,"label");Rz(this.label).maybeAppend(".label",(function(){return fz(e)})).attr("className","label").styles(r),this.label.attr("__data__",n)},e.prototype.renderBackground=function(){var t=this.label.getBBox(),e=Ve(this.padding,4),n=e[0],r=e[1],i=e[2],o=e[3],a=t.width,s=t.height,l=a+o+r,u=s+n+i,c=Fz(this.attributes,"background"),h=this.style,d=h.width,f=void 0===d?0:d,p=h.height,g=void 0===p?0:p,v=h.selected;this.background.attr(Be(Be({},c),{width:Math.max(l,f),height:Math.max(u,g),fill:v?this.selectedColor:"#fff"})),this.label.attr({transform:"translate(".concat(o,", ").concat((u-s)/2,")")})},e.prototype.render=function(){this.renderLabel(),this.renderBackground()},e.prototype.bindEvents=function(){var t=this;this.addEventListener("pointerenter",(function(){t.style.selected||t.background.attr("fill",t.hoverColor)})),this.addEventListener("pointerleave",(function(){t.style.selected||t.background.attr("fill",t.style.backgroundFill)}));var e=this;this.addEventListener("click",(function(){var n=t.style,r=n.label,i=n.value,o=n.onClick;null==o||o(i,{label:r,value:i},e)}))},e.defaultOptions={style:{value:"",label:"",cursor:"pointer"}},e}($z),FW=function(t){function e(n){var r,i,o=t.call(this,oz({},e.defaultOptions,n))||this;o.currentValue=null===(r=e.defaultOptions.style)||void 0===r?void 0:r.defaultValue,o.isPointerInSelect=!1,o.select=o.appendChild(new ru({className:"select",style:{cursor:"pointer",width:0,height:0}})),o.dropdown=o.appendChild(new ru({className:"dropdown"}));var a=o.style.defaultValue;return a&&(null===(i=o.style.options)||void 0===i?void 0:i.some((function(t){return t.value===a})))&&(o.currentValue=a),o}return je(e,t),e.prototype.setValue=function(t){this.currentValue=t,this.render()},e.prototype.getValue=function(){return this.currentValue},Object.defineProperty(e.prototype,"dropdownPadding",{get:function(){return Dz(this.style.dropdownPadding)},enumerable:!1,configurable:!0}),e.prototype.renderSelect=function(){var t,e=this,n=this.style,r=n.x,i=n.y,o=n.width,a=n.height,s=n.bordered,l=n.showDropdownIcon,u=Fz(this.attributes,"select"),c=Fz(this.attributes,"placeholder");this.select.attr(Be(Be({x:r,y:i,width:o,height:a},u),{fill:"#fff",strokeWidth:s?1:0}));var h=this.dropdownPadding;l&&Rz(this.select).maybeAppend(".dropdown-icon","path").style("d","M-5,-3.5 L0,3.5 L5,-3.5").style("transform","translate(".concat(r+o-10-h[1]-h[3],", ").concat(i+a/2,")")).style("lineWidth",1).style("stroke",this.select.style.stroke);var d=null===(t=this.style.options)||void 0===t?void 0:t.find((function(t){return t.value===e.currentValue})),f=Be({x:r+h[3]},c);Rz(this.select).selectAll(".placeholder").data(d?[]:[1]).join((function(t){return t.append("text").attr("className","placeholder").styles(f).style("y",(function(){var t=this.getBBox();return i+(a-t.height)/2}))}),(function(t){return t.styles(f)}),(function(t){return t.remove()}));var p=Fz(this.attributes,"optionLabel"),g=Be({x:r+h[3]},p);Rz(this.select).selectAll(".value").data(d?[d]:[]).join((function(t){return t.append((function(t){return fz(t.label)})).attr("className","value").styles(g).style("y",(function(){var t=this.getBBox();return i+(a-t.height)/2}))}),(function(t){return t.styles(g)}),(function(t){return t.remove()}))},e.prototype.renderDropdown=function(){var t,e,n=this,r=this.style,i=r.x,o=r.y,a=r.width,s=r.height,l=r.options,u=r.onSelect,c=r.open,h=Fz(this.attributes,"dropdown"),d=Fz(this.attributes,"option"),f=this.dropdownPadding;Rz(this.dropdown).maybeAppend(".dropdown-container","g").attr("className","dropdown-container").selectAll(".dropdown-item").data(l,(function(t){return t.value})).join((function(t){return t.append((function(t){return new BW({className:"dropdown-item",style:Be(Be(Be({},t),d),{width:a-f[1]-f[3],selected:t.value===n.currentValue,onClick:function(t,e,r){n.setValue(t),null==u||u(t,e,r),n.dispatchEvent(new zs("change",{detail:{value:t,option:e,item:r}})),YF(n.dropdown)}})})})).each((function(t,e){var n,r=(null===(n=this.parentNode)||void 0===n?void 0:n.children).reduce((function(t,n,r){return re.time?1:0}))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"space",{get:function(){var t=this.attributes,e=t.x,n=t.y,r=t.width,i=t.height,o=t.type,a=t.controllerHeight,s=oe(+i-a,0,+i),l=new tz(e,n+ +i-a,+r,a),u=0,c="time"===o?10:s;return{axisBBox:"chart"===o?new tz(e,n+s-(u=35),+r,u):new tz,controllerBBox:l,timelineBBox:new tz(e,n+("time"===o?s:s-c),+r,c-u)}},enumerable:!1,configurable:!0}),e.prototype.setBySliderValues=function(t){var e,n,r=this.data,i=Ve(Array.isArray(t)?t:[0,t],2),o=i[0],a=i[1],s=r.length,l=r[Math.floor(o*s)],u=r[Math.ceil(a*s)-(Array.isArray(t)?0:1)];this.states.values=[null!==(e=null==l?void 0:l.time)&&void 0!==e?e:r[0].time,null!==(n=null==u?void 0:u.time)&&void 0!==n?n:1/0]},e.prototype.setByTimebarValues=function(t){var e,n,r,i=this.data,o=Ve(Array.isArray(t)?t:[void 0,t],2),a=o[0],s=o[1],l=i.find((function(t){return t.time===a})),u=i.find((function(t){return t.time===s}));this.states.values=[null!==(e=null==l?void 0:l.time)&&void 0!==e?e:null===(n=i[0])||void 0===n?void 0:n.time,null!==(r=null==u?void 0:u.time)&&void 0!==r?r:1/0]},e.prototype.setByIndex=function(t){var e,n,r,i,o=this.data,a=Ve(t,2),s=a[0],l=a[1];this.states.values=[null!==(n=null===(e=o[s])||void 0===e?void 0:e.time)&&void 0!==n?n:o[0].time,null!==(i=null===(r=this.data[l])||void 0===r?void 0:r.time)&&void 0!==i?i:1/0]},Object.defineProperty(e.prototype,"sliderValues",{get:function(){var t,e=this.states,n=e.values,r=e.selectionType,i=Ve(Array.isArray(n)?n:[void 0,n],2),o=i[0],a=i[1],s=this.data,l=s.length,u="value"===r;return[(t=s.findIndex((function(t){return t.time===o})),u?0:t>-1?t/l:0),function(){if(a===1/0)return 1;var t=s.findIndex((function(t){return t.time===a}));return t>-1?t/l:u?.5:1}()]},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"values",{get:function(){var t=this.states,e=t.values,n=t.selectionType,r=Ve(Array.isArray(e)?e:[this.data[0].time,e],2),i=r[0],o=r[1];return"value"===n?o:[i,o]},enumerable:!1,configurable:!0}),e.prototype.getDatumByRatio=function(t){var e=this.data,n=e.length;return e[Math.floor(t*(n-1))]},Object.defineProperty(e.prototype,"chartHandleIconShape",{get:function(){var t=this.states.selectionType,e=this.space.timelineBBox.height;return"range"===t?function(t){return new sH({style:{type:t,height:e,iconSize:e/6}})}:function(){return new Kl({style:{x1:0,y1:-e/2,x2:0,y2:e/2,lineWidth:2,stroke:"#c8c8c8"}})}},enumerable:!1,configurable:!0}),e.prototype.getChartStyle=function(t){var e=this,n=t.x,r=t.y,i=t.width,o=t.height,a=this.states,s=a.selectionType,l=a.chartType,u=this.data,c=this.attributes,h=c.type,d=c.labelFormatter,f=Fz(this.attributes,"chart");f.type;var p=Fe(f,["type"]),g="range"===s;if("time"===h)return Be({handleIconShape:function(){return new aH({})},selectionFill:"#2e7ff8",selectionFillOpacity:1,showLabelOnInteraction:!0,handleLabelDy:g?-15:0,autoFitLabel:g,handleSpacing:g?-15:0,trackFill:"#edeeef",trackLength:i,trackOpacity:.5,trackRadius:o/2,trackSize:o/2,type:s,values:this.sliderValues,formatter:function(t){if(d)return d(t);var n=e.getDatumByRatio(t).time;return"number"==typeof n?uH(n):Vz(n,"YYYY-MM-DD HH:mm:ss")},transform:"translate(".concat(n,", ").concat(r,")"),zIndex:1},p);var v="range"===s?5:0,m=u.map((function(t){return t.value}));return Be({handleIconOffset:v,handleIconShape:this.chartHandleIconShape,selectionFill:"#fff",selectionFillOpacity:.5,selectionType:"invert",sparklineSpacing:.1,sparklineColumnLineWidth:0,sparklineColor:"#d4e5fd",sparklineAreaOpacity:1,sparklineAreaLineWidth:0,sparklineData:m,sparklineType:l,sparklineScale:.8,trackLength:i,trackSize:o,type:s,values:this.sliderValues,transform:"translate(".concat(n,", ").concat(r,")"),zIndex:1},p)},e.prototype.renderChart=function(t){void 0===t&&(t=this.space.timelineBBox),this.timeline.update(this.getChartStyle(t))},e.prototype.updateSelection=function(){this.timeline.setValues(this.sliderValues,!0),this.handleSliderChange(this.sliderValues)},e.prototype.getAxisStyle=function(t){var e=this.data,n=this.attributes,r=n.interval,i=n.labelFormatter,o=Fz(this.attributes,"axis"),a=t.x,s=t.y,l=t.width,u=We(We([],Ve(e),!1),[{time:0}],!1).map((function(t,e,n){var r=t.time;return{label:"".concat(r),value:e/(n.length-1),time:r}})),c=Be({startPos:[a,s],endPos:[a+l,s],data:u,labelFilter:function(t,e){return er?"value"===a?[0,0]:"acc"===s?[o(n),o(n)]:[0,o(i-n)]:n<0?"acc"===s?[0,o(i)]:[o(n+r-i),r]:[o(n),o(i)]}(f);return this.setByIndex(g),this.updateSelection(),g},e.prototype.internalBackward=function(t){var e,n,r=this.moveSelection("backward",t);return t||(null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onBackward)||void 0===n||n.call(e),this.dispatchOnChange()),r},e.prototype.backward=function(){this.internalBackward()},e.prototype.internalPlay=function(t){var e,n,r=this,i=this.data,o=this.attributes.loop,a=this.states.speed,s=void 0===a?1:a;this.playInterval=window.setInterval((function(){r.internalForward()[1]!==i.length||o||(r.internalPause(),r.renderController())}),1e3/s),this.states.state="play",!t&&(null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onPlay)||void 0===n||n.call(e))},e.prototype.play=function(){this.internalPlay()},e.prototype.internalPause=function(t){var e,n;clearInterval(this.playInterval),this.states.state="pause",!t&&(null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onPause)||void 0===n||n.call(e))},e.prototype.pause=function(){this.internalPause()},e.prototype.internalForward=function(t){var e,n,r=this.moveSelection("forward",t);return t||(null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onForward)||void 0===n||n.call(e),this.dispatchOnChange()),r},e.prototype.forward=function(){this.internalForward()},e.prototype.handleSpeedChange=function(t){var e,n;this.states.speed=t,"play"===this.states.state&&(this.internalPause(!0),this.internalPlay(!0)),null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onSpeedChange)||void 0===n||n.call(e,t)},e.prototype.handleSelectionTypeChange=function(t){var e,n;this.states.selectionType=t,this.renderChart(),null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onSelectionTypeChange)||void 0===n||n.call(e,t)},e.prototype.handleChartTypeChange=function(t){var e,n;this.states.chartType=t,this.renderChart(),null===(n=null===(e=this.attributes)||void 0===e?void 0:e.onChartTypeChange)||void 0===n||n.call(e,t)},e.prototype.render=function(){var t=this.space,e=t.axisBBox,n=t.controllerBBox,r=t.timelineBBox;this.renderController(n),this.renderAxis(e),this.renderChart(r),"play"===this.states.state&&this.internalPlay()},e.prototype.destroy=function(){t.prototype.destroy.call(this),this.internalPause(!0)},e.defaultOptions={style:{x:0,y:0,axisLabelFill:"#6e6e6e",axisLabelTextAlign:"left",axisLabelTextBaseline:"top",axisLabelTransform:"translate(5, -12)",axisLineLineWidth:1,axisLineStroke:"#cacdd1",axisTickLength:15,axisTickLineWidth:1,axisTickStroke:"#cacdd1",chartShowLabel:!1,chartType:"line",controllerAlign:"center",controllerHeight:40,data:[],interval:"day",loop:!1,playMode:"acc",selectionType:"range",type:"time"}},e}($z);function hH(t){const{width:e,height:n,renderer:r}=t,i=function(t){var e;const{container:n,className:r,graphCanvas:i}=t;if(n)return"string"==typeof n?document.getElementById(n):n;const o=rB(r,!1),{width:a,height:s,containerStyle:l}=t,[u,c]=function(t){const{width:e,height:n,placement:r,graphCanvas:i}=t,[o,a]=i.getSize(),[s,l]=ad(r);return[s*(o-e),l*(a-n)]}(t);return Object.assign(o.style,Object.assign({position:"absolute",left:u+"px",top:c+"px",width:a+"px",height:s+"px"},l)),null===(e=i.getContainer())||void 0===e||e.appendChild(o),o}(t);return[i,new bu({width:e,height:n,container:i,renderer:r||new Dp})]}class dH extends nB{constructor(e,n){super(e,Object.assign({},dH.defaultOptions,n)),this.typePrefix="__data__",this.draw=!1,this.fieldMap={node:new Map,edge:new Map,combo:new Map},this.selectedItems=[],this.bindEvents=()=>{const{graph:e}=this.context;e.on(t.GraphEvent.AFTER_DRAW,this.createElement)},this.changeState=(t,e)=>{const{graph:n}=this.context,{typePrefix:r}=this,i=Oe(t,[r,"id"]),o=Oe(t,[r,"style","labelText"]),[a]=i.split("__"),s=this.fieldMap[a].get(o)||[];n.setElementState(Object.fromEntries(null==s?void 0:s.map((t=>[t,e]))))},this.click=t=>{if("hover"===this.options.trigger)return;const e=Oe(t,[this.typePrefix,"id"]);this.selectedItems.includes(e)?(this.selectedItems=this.selectedItems.filter((t=>t!==e)),this.changeState(t,[])):(this.selectedItems.push(e),this.changeState(t,"selected"))},this.mouseleave=t=>{"click"!==this.options.trigger&&(this.selectedItems=[],this.changeState(t,[]))},this.mouseenter=t=>{if("click"===this.options.trigger)return;const e=Oe(t,[this.typePrefix,"id"]);this.selectedItems.includes(e)?this.selectedItems=this.selectedItems.filter((t=>t!==e)):(this.selectedItems.push(e),this.changeState(t,"active"))},this.setFieldMap=(t,e,n)=>{if(!t)return;const r=this.fieldMap[n];if(r)if(r.has(t)){const n=r.get(t);n&&(n.push(e),r.set(t,n))}else r.set(t,[e])},this.getEvents=()=>({mouseenter:this.mouseenter,mouseleave:this.mouseleave,click:this.click}),this.getMarkerData=(t,e)=>{if(!t)return[];const{model:n,element:r}=this.context,{nodes:i,edges:o,combos:a}=n.getData(),s={},l=e=>Ut(t)?t(e):t,u={node:"circle",edge:"line",combo:"rect"},c={circle:"circle",ellipse:"circle",image:"bowtie",rect:"square",star:"cross",triangle:"triangle",diamond:"diamond",cubic:"dot",line:"hyphen",polyline:"hyphen",quadratic:"hv","cubic-horizontal":"hyphen","cubic-vertical":"line"},h=(t,e)=>{t.forEach((t=>{const{id:n}=t,i=Oe(t,["data",l(t)]),o=(null==r?void 0:r.getElementType(e,t))||"circle",a=((t,e)=>null==r?void 0:r.getElementComputedStyle(t,e))(e,t),h=("edge"===e?null==a?void 0:a.stroke:null==a?void 0:a.fill)||"#1783ff";n&&i&&i.replace(/\s+/g,"")&&(this.setFieldMap(i,n,e),s[i]||(s[i]={id:`${e}__${n}`,label:i,marker:c[o]||u[e],elementType:e,lineWidth:1,stroke:h,fill:h}))}))};switch(e){case"node":h(i,"node");break;case"edge":h(o,"edge");break;case"combo":h(a,"combo");break;default:return[]}return Object.values(s)},this.createElement=()=>{if(this.draw)return void this.updateElement();const t=this.options,{width:e,height:n,nodeField:r,edgeField:i,comboField:o,trigger:a,position:s,container:l,containerStyle:u,className:c}=t,h=Fe(t,["width","height","nodeField","edgeField","comboField","trigger","position","container","containerStyle","className"]),d=this.getMarkerData(r,"node"),f=this.getMarkerData(i,"edge"),p=this.getMarkerData(o,"combo"),g=[...d,...p,...f],v=Object.assign({width:e,height:n,data:g,itemMarkerLineWidth:({lineWidth:t})=>t,itemMarker:({marker:t})=>t,itemMarkerStroke:({stroke:t})=>t,itemMarkerFill:({fill:t})=>t,gridCol:d.length},h,this.getEvents()),m=new AW({className:"legend",style:v});this.category=m;this.upsertCanvas().appendChild(m),this.draw=!0},this.bindEvents()}update(t){super.update(t),this.clear(),this.createElement()}clear(){var t,e;null===(t=this.canvas)||void 0===t||t.destroy(),null===(e=this.container)||void 0===e||e.remove(),this.canvas=void 0,this.container=void 0,this.draw=!1}updateElement(){this.category&&this.category.update({itemMarkerOpacity:({id:t})=>!this.selectedItems.length||this.selectedItems.includes(t)?1:.5,itemLabelOpacity:({id:t})=>!this.selectedItems.length||this.selectedItems.includes(t)?1:.5})}upsertCanvas(){if(this.canvas)return this.canvas;const t=this.context.canvas,[e,n]=t.getSize(),{width:r=e,height:i=n,position:o,container:a,containerStyle:s,className:l}=this.options,[u,c]=hH({width:r,height:i,graphCanvas:t,container:a,containerStyle:s,placement:o,className:"legend"});return this.container=u,l&&u.classList.add(l),this.canvas=c,this.canvas}destroy(){this.clear(),this.context.graph.off(t.GraphEvent.AFTER_DRAW,this.createElement),super.destroy()}}dH.defaultOptions={position:"bottom",trigger:"hover",orientation:"horizontal",layout:"flex",itemSpacing:4,rowPadding:10,colPadding:10,itemMarkerSize:16,itemLabelFontSize:16,width:240,height:160};class fH extends nB{constructor(t,e){super(t,Object.assign({},fH.defaultOptions,e)),this.onDraw=t=>{var e;(null===(e=null==t?void 0:t.data)||void 0===e?void 0:e.render)||this.onRender()},this.shapes=new Map,this.landmarkMap=new Map,this.mask=null,this.isMaskDragging=!1,this.onMaskDragStart=t=>{this.mask&&(this.isMaskDragging=!0,this.mask.setPointerCapture(t.pointerId),this.mask.addEventListener("pointermove",this.onMaskDrag),this.mask.addEventListener("pointerup",this.onMaskDragEnd),this.mask.addEventListener("pointercancel",this.onMaskDragEnd))},this.onMaskDrag=t=>{if(!this.mask||!this.isMaskDragging)return;const{size:[e,n]}=this.options,{movementX:r,movementY:i}=t,{left:o,top:a,width:s,height:l}=this.mask.style,[,,u,c]=this.maskBBox;let h=parseInt(o)+r,d=parseInt(a)+i,f=parseInt(s),p=parseInt(l);h<0&&(h=0),d<0&&(d=0),h+f>e&&(h=gH(e-f,0)),d+p>n&&(d=gH(n-p,0)),f0?(h=gH(h-r,0),f=pH(f+r,e)):r<0&&(f=pH(f-r,e))),p0?(d=gH(d-i,0),p=pH(p+i,n)):i<0&&(p=pH(p-i,n))),Object.assign(this.mask.style,{left:h+"px",top:d+"px",width:f+"px",height:p+"px"});const g=parseInt(o)-h,v=parseInt(a)-d;if(0===g&&0===v)return;const m=this.context.canvas.getCamera().getZoom()/this.canvas.getCamera().getZoom();this.context.graph.translateBy([g*m,v*m],!1)},this.onMaskDragEnd=t=>{this.mask&&(this.isMaskDragging=!1,this.mask.releasePointerCapture(t.pointerId),this.mask.removeEventListener("pointermove",this.onMaskDrag),this.mask.removeEventListener("pointerup",this.onMaskDragEnd),this.mask.removeEventListener("pointercancel",this.onMaskDragEnd))},this.onTransform=Re((()=>{this.isMaskDragging||(this.updateMask(),this.setCamera())}),32,{leading:!0}),this.setOnRender(),this.bindEvents()}update(t){this.unbindEvents(),super.update(t),"delay"in t&&this.setOnRender(),this.bindEvents()}setOnRender(){this.onRender=ye((()=>{this.renderMinimap(),this.renderMask()}),this.options.delay)}bindEvents(){const{graph:e}=this.context;e.on(t.GraphEvent.AFTER_DRAW,this.onDraw),e.on(t.GraphEvent.AFTER_RENDER,this.onRender),e.on(t.GraphEvent.AFTER_TRANSFORM,this.onTransform)}unbindEvents(){const{graph:e}=this.context;e.off(t.GraphEvent.AFTER_DRAW,this.onDraw),e.off(t.GraphEvent.AFTER_RENDER,this.onRender),e.off(t.GraphEvent.AFTER_TRANSFORM,this.onTransform)}renderMinimap(){const t=this.getElements(),e=this.initCanvas();this.setShapes(e,t)}getElements(){const{filter:t}=this.options,{model:e}=this.context,n=e.getData();if(!t)return n;const{nodes:r,edges:i,combos:o}=n;return{nodes:r.filter((e=>t(Nh(e),"node"))),edges:i.filter((e=>t(Nh(e),"edge"))),combos:o.filter((e=>t(Nh(e),"combo")))}}setShapes(t,e){const{nodes:n,edges:r,combos:i}=e,{shape:o}=this.options,{element:a}=this.context;if("key"===o){const e=new Set,o=n=>{const r=Nh(n);e.add(r);const i=a.getElement(r);if(!i)return;const o=i.getShape("key"),s=this.shapes.get(r)||o.cloneNode();s.setPosition(o.getPosition()),i.style.zIndex&&(s.style.zIndex=i.style.zIndex),s.id=i.id,this.shapes.has(r)?Object.entries(o.attributes).forEach((([t,e])=>{s.style[t]!==e&&(s.style[t]=e)})):(t.appendChild(s),this.shapes.set(r,s))};return r.forEach(o),i.forEach(o),n.forEach(o),void this.shapes.forEach(((n,r)=>{e.has(r)||(t.removeChild(n),this.shapes.delete(r))}))}const s=(t,e)=>{const n=a.getElement(t).getPosition();return e.setPosition(n),e};t.removeChildren(),r.forEach((e=>t.appendChild(o(Nh(e),"edge")))),i.forEach((e=>{t.appendChild(s(Nh(e),o(Nh(e),"combo")))})),n.forEach((e=>{t.appendChild(s(Nh(e),o(Nh(e),"node")))}))}initCanvas(){const{renderer:t,size:[e,n]}=this.options;if(this.canvas){const{width:r,height:i}=this.canvas.getConfig();e===r&&n===i||this.canvas.resize(e,n),t&&this.canvas.setRenderer(t)}else{const{className:r,position:i,container:o,containerStyle:a}=this.options,[s,l]=hH({renderer:t,width:e,height:n,placement:i,className:"minimap",container:o,containerStyle:a,graphCanvas:this.context.canvas});r&&s.classList.add(r),this.container=s,this.canvas=l}return this.setCamera(),this.canvas}createLandmark(t,e,n){const r=`${t.join(",")}-${e.join(",")}-${n}`;if(this.landmarkMap.has(r))return this.landmarkMap.get(r);const i=this.canvas.getCamera().createLandmark(r,{position:t,focalPoint:e,zoom:n});return this.landmarkMap.set(r,i),i}setCamera(){var t;const{canvas:e}=this.context,n=null===(t=this.canvas)||void 0===t?void 0:t.getCamera();if(!n)return;const{size:[r,i],padding:o}=this.options,[a,s,l,u]=Jc(o),{min:c,max:h,center:d}=e.getBounds("elements"),f=(r-u-s)/(h[0]-c[0]),p=(i-a-l)/(h[1]-c[1]),g=Math.min(f,p),v=this.createLandmark(d,d,g);n.gotoLandmark(v,0)}get maskBBox(){const{canvas:t}=this.context,e=t.getSize(),n=t.getCanvasByViewport([0,0]),r=t.getCanvasByViewport(e),i=this.canvas.canvas2Viewport(hd(n)),o=this.canvas.canvas2Viewport(hd(r)),a=o.x-i.x,s=o.y-i.y;return[i.x,i.y,a,s]}calculateMaskBBox(){const{size:[t,e]}=this.options;let[n,r,i,o]=this.maskBBox;return n<0&&(i=pH(i+n,t),n=0),r<0&&(o=pH(o+r,e),r=0),n+i>t&&(i=gH(t-n,0)),r+o>e&&(o=gH(e-r,0)),[pH(n,t),pH(r,e),gH(i,0),gH(o,0)]}renderMask(){const{maskStyle:t}=this.options;this.mask||(this.mask=document.createElement("div"),this.mask.addEventListener("pointerdown",this.onMaskDragStart),this.mask.draggable=!0,this.mask.addEventListener("dragstart",(t=>t.preventDefault&&t.preventDefault()))),this.container.appendChild(this.mask),Object.assign(this.mask.style,Object.assign(Object.assign({},t),{cursor:"move",position:"absolute",pointerEvents:"auto"})),this.updateMask()}updateMask(){if(!this.mask)return;const[t,e,n,r]=this.calculateMaskBBox();Object.assign(this.mask.style,{top:e+"px",left:t+"px",width:n+"px",height:r+"px"})}destroy(){var t;this.unbindEvents(),this.canvas.destroy(),null===(t=this.mask)||void 0===t||t.remove(),super.destroy()}}fH.defaultOptions={size:[240,160],shape:"key",padding:10,position:"right-bottom",maskStyle:{border:"1px solid #ddd",background:"rgba(0, 0, 0, 0.1)"},containerStyle:{border:"1px solid #ddd",background:"#fff"},delay:128};const pH=(t,e)=>Math.min(t,e),gH=(t,e)=>Math.max(t,e),vH={x1:0,y1:0,x2:0,y2:0,visibility:"hidden"};class mH extends nB{constructor(t,e){super(t,Object.assign({},mH.defaultOptions,e)),this.initSnapline=()=>{const t=this.context.canvas.getLayer("transient");this.horizontalLine||(this.horizontalLine=t.appendChild(new Kl({style:Object.assign(Object.assign({},vH),this.options.horizontalLineStyle)}))),this.verticalLine||(this.verticalLine=t.appendChild(new Kl({style:Object.assign(Object.assign({},vH),this.options.verticalLineStyle)})))},this.isHorizontalSticking=!1,this.isVerticalSticking=!1,this.enableStick=!0,this.autoSnapToLine=(t,e,n)=>ze(this,void 0,void 0,(function*(){const{verticalX:r,horizontalY:i}=n,{tolerance:o}=this.options,{min:[a,s],max:[l,u],center:[c,h]}=e;let d=0,f=0;null!==r&&(yH(l,r){const{target:e}=t,n=.5;if(this.isHorizontalSticking||this.isVerticalSticking){const[r,i]=this.getDelta(t);if(this.isHorizontalSticking&&this.isVerticalSticking&&Math.abs(r)<=n&&Math.abs(i)<=n)return this.context.graph.translateElementBy({[e.id]:[-r,-i]},!1),!1;if(this.isHorizontalSticking&&Math.abs(i)<=n)return this.context.graph.translateElementBy({[e.id]:[0,-i]},!1),!1;if(this.isVerticalSticking&&Math.abs(r)<=n)return this.context.graph.translateElementBy({[e.id]:[-r,0]},!1),!1;this.isHorizontalSticking=!1,this.isVerticalSticking=!1,this.enableStick=!1,setTimeout((()=>{this.enableStick=!0}),200)}return this.enableStick},this.calcSnaplineMetadata=(t,e)=>{const{tolerance:n,shape:r}=this.options,{min:[i,o],max:[a,s],center:[l,u]}=e;let c=null,h=null,d=null,f=null,p=null,g=null;return this.getNodes().some((e=>{if(Ne(t.id,e.id))return!1;const v=bH(e,r).getRenderBounds(),{min:[m,y],max:[b,x],center:[E,w]}=v;return null===c&&(yH(E,l){this.initSnapline()},this.onDrag=t=>ze(this,void 0,void 0,(function*(){const{target:e}=t;if(this.options.autoSnap){if(!this.enableSnap(t))return}const n=bH(e,this.options.shape).getRenderBounds(),r=this.calcSnaplineMetadata(e,n);this.hideSnapline(),null===r.verticalX&&null===r.horizontalY||this.updateSnapline(r),this.options.autoSnap&&(yield this.autoSnapToLine(e.id,n,r))})),this.onDragEnd=()=>{this.hideSnapline()},this.bindEvents()}getNodes(){var t;const{filter:e}=this.options,n=((null===(t=this.context.element)||void 0===t?void 0:t.getNodes())||[]).filter((t=>{var e;return"hidden"!==Oe(t,["style","visibility"])&&(null===(e=this.context.viewport)||void 0===e?void 0:e.isInViewport(t.getRenderBounds()))}));return e?n.filter((t=>e(t))):n}hideSnapline(){this.horizontalLine.style.visibility="hidden",this.verticalLine.style.visibility="hidden"}getLineWidth(t){const{lineWidth:e}=this.options[`${t}LineStyle`];return+(e||vH.lineWidth||1)/this.context.graph.getZoom()}updateSnapline(t){const{verticalX:e,verticalMinY:n,verticalMaxY:r,horizontalY:i,horizontalMinX:o,horizontalMaxX:a}=t,[s,l]=this.context.canvas.getSize(),{offset:u}=this.options;null!==i?Object.assign(this.horizontalLine.style,{x1:u===1/0?0:o-u,y1:i,x2:u===1/0?s:a+u,y2:i,visibility:"visible",lineWidth:this.getLineWidth("horizontal")}):this.horizontalLine.style.visibility="hidden",null!==e?Object.assign(this.verticalLine.style,{x1:e,y1:u===1/0?0:n-u,x2:e,y2:u===1/0?l:r+u,visibility:"visible",lineWidth:this.getLineWidth("vertical")}):this.verticalLine.style.visibility="hidden"}getDelta(t){const e=this.context.graph.getZoom();return Yh([t.dx,t.dy],e)}bindEvents(){return ze(this,void 0,void 0,(function*(){const{graph:e}=this.context;e.on(t.NodeEvent.DRAG_START,this.onDragStart),e.on(t.NodeEvent.DRAG,this.onDrag),e.on(t.NodeEvent.DRAG_END,this.onDragEnd)}))}unbindEvents(){const{graph:e}=this.context;e.off(t.NodeEvent.DRAG_START,this.onDragStart),e.off(t.NodeEvent.DRAG,this.onDrag),e.off(t.NodeEvent.DRAG_END,this.onDragEnd)}destroyElements(){var t,e;null===(t=this.horizontalLine)||void 0===t||t.destroy(),null===(e=this.verticalLine)||void 0===e||e.destroy()}destroy(){this.destroyElements(),this.unbindEvents(),super.destroy()}}mH.defaultOptions={tolerance:5,offset:20,autoSnap:!0,shape:"key",verticalLineStyle:{stroke:"#1783FF"},horizontalLineStyle:{stroke:"#1783FF"},filter:()=>!0};const yH=(t,e)=>Math.abs(t-e),bH=(t,e)=>"function"==typeof e?e(t):t.getShape(e),xH=["timestamp","time","date","datetime"];class EH extends nB{get padding(){return Jc(this.options.padding)}constructor(t,e){super(t,Object.assign({},EH.defaultOptions,e)),this.backup(),this.upsertTimebar()}play(){var t;null===(t=this.timebar)||void 0===t||t.play()}pause(){var t;null===(t=this.timebar)||void 0===t||t.pause()}forward(){var t;null===(t=this.timebar)||void 0===t||t.forward()}backward(){var t;null===(t=this.timebar)||void 0===t||t.backward()}reset(){var t;null===(t=this.timebar)||void 0===t||t.reset()}update(t){super.update(t),this.backup(),this.upsertTimebar()}backup(){this.originalData=wH(this.context.graph.getData())}upsertTimebar(){const{canvas:t}=this.context,e=this.options,{onChange:n,timebarType:r,data:i,x:o,y:a,width:s,height:l,mode:u}=e,c=Fe(e,["onChange","timebarType","data","x","y","width","height","mode"]),h=t.getSize(),[d]=this.padding;this.upsertCanvas().ready.then((()=>{var t;const e=Object.assign(Object.assign({x:h[0]/2-s/2,y:d,onChange:t=>{const e=(Yt(t)?t:[t,t]).map((t=>function(t){return t instanceof Date}(t)?t.getTime():t));"modify"===this.options.mode?this.filterElements(e):this.hiddenElements(e),null==n||n(e)}},c),{data:i.map((t=>ae(t)?{time:t,value:0}:t)),width:s,height:l,type:r});this.timebar?this.timebar.update(e):(this.timebar=new cH({style:e}),null===(t=this.canvas)||void 0===t||t.appendChild(this.timebar))}))}upsertCanvas(){if(this.canvas)return this.canvas;const{className:t,height:e,position:n}=this.options,r=this.context.canvas,[i]=r.getSize(),[o,,a]=this.padding,[s,l]=hH({width:i,height:e+o+a,graphCanvas:r,className:"timebar",placement:n});return this.container=s,t&&s.classList.add(t),this.canvas=l,this.canvas}filterElements(t){return ze(this,void 0,void 0,(function*(){var e;if(!this.originalData)return;const{elementTypes:n,getTime:r}=this.options,{graph:i,element:o}=this.context,a=wH(this.originalData);n.forEach((e=>{const n=`${e}s`;a[n]=(this.originalData[n]||[]).filter((e=>{const n=r(e);return!!kH(n,t)}))}));const s=[...a.nodes,...a.combos].map((t=>Nh(t)));a.edges=a.edges.filter((t=>{const e=t.source,n=t.target;return s.includes(e)&&s.includes(n)})),i.setData(a),yield null===(e=o.draw({animation:!1,silence:!0}))||void 0===e?void 0:e.finished}))}hiddenElements(t){const{graph:e}=this.context,{elementTypes:n,getTime:r}=this.options,i=[],o=[];n.forEach((e=>{var n;const a=`${e}s`;((null===(n=this.originalData)||void 0===n?void 0:n[a])||[]).forEach((e=>{const n=Nh(e),a=r(e);kH(a,t)?o.push(n):i.push(n)}))})),e.hideElement(i,!1),e.showElement(o,!1)}destroy(){var t,e,n;const{graph:r}=this.context;this.originalData&&r.setData(Object.assign({},this.originalData)),null===(t=this.timebar)||void 0===t||t.destroy(),null===(e=this.canvas)||void 0===e||e.destroy(),null===(n=this.container)||void 0===n||n.remove(),this.originalData=void 0,this.container=void 0,this.timebar=void 0,this.canvas=void 0,super.destroy()}}EH.defaultOptions={position:"bottom",enable:!0,timebarType:"time",className:"g6-timebar",width:450,height:60,zIndex:3,elementTypes:["node"],padding:10,mode:"modify",getTime:t=>MH(t,xH,void 0),loop:!1};const wH=t=>{const{nodes:e=[],edges:n=[],combos:r=[]}=t;return{nodes:[...e],edges:[...n],combos:[...r]}},kH=(t,e)=>{if(ae(e))return t===e;const[n,r]=e;return t>=n&&t<=r},MH=(t,e,n)=>{var r;for(let n=0;n{const{onClick:e}=this.options;if(t.target instanceof Element&&t.target.className.includes("g6-toolbar-item")){const n=t.target.getAttribute("value");null==e||e(n,t.target)}};const n=this.context.canvas.getContainer();this.$element.style.display="flex",n.appendChild(this.$element),iB("g6-toolbar-css","style",{},"\n .g6-toolbar {\n position: absolute;\n z-index: 100;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.1);\n opacity: 0.65;\n }\n .g6-toolbar .g6-toolbar-item {\n display: inline-block;\n width: 16px;\n height: 16px;\n padding: 4px;\n cursor: pointer;\n box-sizing: content-box;\n }\n\n .g6-toolbar .g6-toolbar-item:hover {\n background-color: #f0f0f0;\n }\n\n .g6-toolbar .g6-toolbar-item svg {\n display: inline-block;\n width: 100%;\n height: 100%;\n pointer-events: none;\n }\n",document.head),iB("g6-toolbar-svgicon","div",{display:"none"},'\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n'),this.$element.addEventListener("click",this.onToolbarItemClick),this.update(e)}update(t){const e=Object.create(null,{update:{get:()=>super.update}});return ze(this,void 0,void 0,(function*(){e.update.call(this,t);const{className:n,position:r,style:i}=this.options;this.$element.className=`g6-toolbar ${n||""}`,Object.assign(this.$element.style,i,function(t){const e={top:"unset",right:"unset",bottom:"unset",left:"unset"};return t.split("-").forEach((t=>{e[t]="8px"})),e.flexDirection=t.startsWith("top")||t.startsWith("bottom")?"row":"column",e}(r)),this.$element.innerHTML=yield this.getDOMContent()}))}destroy(){this.$element.removeEventListener("click",this.onToolbarItemClick),this.$element.remove(),super.destroy()}getDOMContent(){return ze(this,void 0,void 0,(function*(){return(yield this.options.getItems()).map((t=>{var e;return`\n
    \n \n
    `})).join("")}))}}SH.defaultOptions={position:"top-left"};class NH extends nB{constructor(t,e){super(t,Object.assign({},NH.defaultOptions,e)),this.currentTarget=null,this.tooltipElement=null,this.container=null,this.isEnable=(t,e)=>{const{enable:n}=this.options;return"function"==typeof n?n(t,e):n},this.onClick=t=>{const{target:{id:e}}=t;this.currentTarget===e?this.hide(t):this.show(t)},this.onPointerMove=t=>{const{target:e}=t;this.currentTarget&&e.id!==this.currentTarget&&this.show(t)},this.onPointerLeave=t=>{this.hide(t)},this.onCanvasMove=t=>{this.hide(t)},this.onPointerEnter=t=>{this.show(t)},this.showById=t=>ze(this,void 0,void 0,(function*(){const e={target:{id:t}};yield this.show(e)})),this.getElementData=(t,e)=>{const{model:n}=this.context;switch(e){case"node":return n.getNodeData([t]);case"edge":return n.getEdgeData([t]);case"combo":return n.getComboData([t]);default:return[]}},this.show=t=>ze(this,void 0,void 0,(function*(){var e,n;const{client:r,target:{id:i}}=t;if(Hg(t.target))return;const o=this.context.graph.getElementType(i),{getContent:a,title:s}=this.options,l=this.getElementData(i,o);if(!this.tooltipElement||!this.isEnable(t,l))return;let u,c,h={};if(a){if(h.content=yield a(t,l),!h.content)return}else{const t=this.context.graph.getElementRenderStyle(i),e="node"===o?t.fill:t.stroke;h={title:s||o,data:l.map((t=>({name:"ID",value:t.id||`${t.source} -> ${t.target}`,color:e})))}}if(this.currentTarget=i,r)u=r.x,c=r.y;else{const t=Oe(l,"0.style",{x:0,y:0});u=t.x,c=t.y}null===(n=(e=this.options).onOpenChange)||void 0===n||n.call(e,!0),this.tooltipElement.update(Object.assign(Object.assign(Object.assign({},this.tooltipStyleProps),{x:u,y:c,style:{".tooltip":{visibility:"visible"}}}),h))})),this.hide=t=>{var e,n,r,i,o;if(!t)return null===(n=(e=this.options).onOpenChange)||void 0===n||n.call(e,!1),null===(r=this.tooltipElement)||void 0===r||r.hide(),void(this.currentTarget=null);if(!this.tooltipElement)return;if(!this.currentTarget)return;const{client:{x:a,y:s}}=t;null===(o=(i=this.options).onOpenChange)||void 0===o||o.call(i,!1),this.tooltipElement.hide(a,s),this.currentTarget=null},this.initTooltip=()=>{var t;const e=new jW({className:"tooltip",style:this.tooltipStyleProps});return null===(t=this.container)||void 0===t||t.appendChild(e.HTMLTooltipElement),e},this.render(),this.bindEvents()}getEvents(){return"click"===this.options.trigger?{"node:click":this.onClick,"edge:click":this.onClick,"combo:click":this.onClick,"canvas:click":this.onPointerLeave,contextmenu:this.onPointerLeave,drag:this.onPointerLeave}:{"node:pointerenter":this.onPointerEnter,"node:pointermove":this.onPointerMove,"canvas:pointermove":this.onCanvasMove,"edge:pointerenter":this.onPointerEnter,"edge:pointermove":this.onPointerMove,"combo:pointerenter":this.onPointerEnter,"combo:pointermove":this.onPointerMove,contextmenu:this.onPointerLeave,"node:drag":this.onPointerLeave}}update(t){var e;this.unbindEvents(),super.update(t),this.tooltipElement&&(null===(e=this.container)||void 0===e||e.removeChild(this.tooltipElement.HTMLTooltipElement)),this.tooltipElement=this.initTooltip(),this.bindEvents()}render(){const{canvas:t}=this.context,e=t.getContainer();e&&(this.container=e,this.tooltipElement=this.initTooltip())}unbindEvents(){const{graph:t}=this.context,e=this.getEvents();Object.keys(e).forEach((n=>{t.off(n,e[n])}))}bindEvents(){const{graph:t}=this.context,e=this.getEvents();Object.keys(e).forEach((n=>{t.on(n,e[n])}))}get tooltipStyleProps(){const{canvas:t}=this.context,{center:e}=t.getBounds(),n=t.getContainer(),{top:r,left:i}=n.getBoundingClientRect(),{style:o,position:a,enterable:s,container:l={x:-i,y:-r},title:u,offset:c}=this.options,[h,d]=e,[f,p]=t.getSize();return{x:h,y:d,container:l,title:u,bounding:{x:0,y:0,width:f,height:p},position:a,enterable:s,offset:c,style:o}}destroy(){var t;this.unbindEvents(),this.tooltipElement&&(null===(t=this.container)||void 0===t||t.removeChild(this.tooltipElement.HTMLTooltipElement)),super.destroy()}}let OH;function TH(t,e){OH||(OH=document.createElement("canvas")),OH.width=t,OH.height=e;return OH.getContext("2d").clearRect(0,0,t,e),OH}NH.defaultOptions={trigger:"hover",position:"top-right",enterable:!1,enable:!0,offset:[10,10],style:{".tooltip":{visibility:"hidden"}}};class CH extends nB{constructor(t,e){super(t,Object.assign({},CH.defaultOptions,e)),this.$element=rB("watermark");this.context.canvas.getContainer().appendChild(this.$element),this.update(e)}update(t){const e=Object.create(null,{update:{get:()=>super.update}});return ze(this,void 0,void 0,(function*(){e.update.call(this,t);const n=this.options,{width:r,height:i,text:o,imageURL:a}=n,s=Fe(n,["width","height","text","imageURL"]);Object.keys(s).forEach((e=>{e.startsWith("background")&&(this.$element.style[e]=t[e])}));const l=a?yield function(t,e,n,r){return ze(this,void 0,void 0,(function*(){const i=TH(t,e),o=i.getContext("2d"),{rotate:a,opacity:s}=r;a&&o.rotate(a),s&&(o.globalAlpha=s);const l=new Image;return l.crossOrigin="anonymous",l.src=n,new Promise((n=>{l.onload=function(){const r=t>l.width?(t-l.width)/2:0,a=e>l.height?(e-l.height)/2:0;o.drawImage(l,0,0,l.width,l.height,r,a,t-2*r,e-2*a),n(i.toDataURL())}}))}))}(r,i,a,s):yield function(t,e,n,r){return ze(this,void 0,void 0,(function*(){const i=TH(t,e),o=i.getContext("2d"),{rotate:a,opacity:s,textFill:l,textFontSize:u,textFontFamily:c,textFontVariant:h,textFontWeight:d,textAlign:f,textBaseline:p}=r;return o.textAlign=f,o.textBaseline=p,o.translate(t/2,e/2),o.font=`${u}px ${c} ${h} ${d}`,a&&o.rotate(a),s&&(o.globalAlpha=s),l&&(o.fillStyle=l,o.fillText(`${n}`,0,0)),i.toDataURL()}))}(r,i,o,s);this.$element.style.backgroundImage=`url(${l})`}))}destroy(){super.destroy(),this.$element.remove()}}CH.defaultOptions={width:200,height:100,opacity:.2,rotate:Math.PI/12,text:"",textFill:"#000",textFontSize:16,textAlign:"center",textBaseline:"middle",backgroundRepeat:"repeat"};const AH=["#7E92B5","#F4664A","#FFBE3A"],PH={type:"group",color:["#1783FF","#00C9C9","#F08F56","#D580FF","#7863FF","#DB9D0D","#60C42D","#FF80CA","#2491B3","#17C76F"]},RH={type:"group",color:["#99ADD1","#1783FF","#00C9C9","#F08F56","#D580FF","#7863FF","#DB9D0D","#60C42D","#FF80CA","#2491B3","#17C76F"]};function DH(t){const{bgColor:e,textColor:n,nodeColor:r,nodeColorDisabled:i,nodeStroke:o,nodeHaloStrokeOpacityActive:a=.15,nodeHaloStrokeOpacitySelected:s=.25,nodeOpacityDisabled:l=.06,nodeIconOpacityInactive:u=.85,nodeOpacityInactive:c=.25,nodeBadgePalette:h=AH,nodePaletteOptions:d=PH,edgeColor:f,edgeColorDisabled:p,edgePaletteOptions:g=RH,comboColor:v,comboColorDisabled:m,comboStroke:y,comboStrokeDisabled:b,edgeColorInactive:x}=t;return{background:e,node:{palette:d,style:{donutOpacity:1,badgeBackgroundOpacity:1,badgeFill:"#fff",badgeFontSize:8,badgePadding:[0,4],badgePalette:h,fill:r,fillOpacity:1,halo:!1,iconFill:"#fff",iconOpacity:1,labelBackground:!1,labelBackgroundFill:e,labelBackgroundLineWidth:0,labelBackgroundOpacity:.75,labelFill:n,labelFillOpacity:.85,labelLineHeight:16,labelPadding:[0,2],labelFontSize:12,labelFontWeight:400,labelOpacity:1,labelOffsetY:2,lineWidth:0,portFill:r,portLineWidth:1,portStroke:o,portStrokeOpacity:.65,size:32,stroke:o,strokeOpacity:1,zIndex:2},state:{selected:{halo:!0,haloLineWidth:24,haloStrokeOpacity:s,labelFontSize:12,labelFontWeight:"bold",lineWidth:4,stroke:o},active:{halo:!0,haloLineWidth:12,haloStrokeOpacity:a},highlight:{labelFontWeight:"bold",lineWidth:4,stroke:o,strokeOpacity:.85},inactive:{badgeBackgroundOpacity:c,donutOpacity:c,fillOpacity:c,iconOpacity:u,labelFill:n,labelFillOpacity:c,strokeOpacity:c},disabled:{badgeBackgroundOpacity:.25,donutOpacity:l,fill:i,fillOpacity:l,iconFill:i,iconOpacity:.25,labelFill:n,labelFillOpacity:.25,strokeOpacity:l}},animation:{enter:"fade",exit:"fade",show:"fade",hide:"fade",expand:"node-expand",collapse:"node-collapse",update:[{fields:["x","y","fill","stroke"]}],translate:[{fields:["x","y"]}]}},edge:{palette:g,style:{badgeBackgroundFill:f,badgeFill:"#fff",badgeFontSize:8,badgeOffsetX:10,fillOpacity:1,halo:!1,haloLineWidth:12,haloStrokeOpacity:1,increasedLineWidthForHitTesting:2,labelBackground:!1,labelBackgroundFill:e,labelBackgroundLineWidth:0,labelBackgroundOpacity:.75,labelBackgroundPadding:[4,4,4,4],labelFill:n,labelFontSize:12,labelFontWeight:400,labelOpacity:1,labelPlacement:"center",labelTextBaseline:"middle",lineWidth:1,stroke:f,strokeOpacity:1,zIndex:1},state:{selected:{halo:!0,haloStrokeOpacity:.25,labelFontSize:14,labelFontWeight:"bold",lineWidth:3},active:{halo:!0,haloStrokeOpacity:.15},highlight:{labelFontWeight:"bold",lineWidth:3},inactive:{stroke:x,fillOpacity:.08,labelOpacity:.25,strokeOpacity:.08,badgeBackgroundOpacity:.25},disabled:{stroke:p,fillOpacity:.45,strokeOpacity:.45,labelOpacity:.25,badgeBackgroundOpacity:.45}},animation:{enter:"fade",exit:"fade",expand:"path-in",collapse:"path-out",show:"fade",hide:"fade",update:[{fields:["sourceNode","targetNode"]},{fields:["stroke"],shape:"key"}],translate:[{fields:["sourceNode","targetNode"]}]}},combo:{style:{collapsedMarkerFill:e,collapsedMarkerFontSize:12,collapsedMarkerFillOpacity:1,collapsedSize:32,collapsedFillOpacity:1,fill:v,halo:!1,haloLineWidth:12,haloStroke:y,haloStrokeOpacity:.25,labelBackground:!1,labelBackgroundFill:e,labelBackgroundLineWidth:0,labelBackgroundOpacity:.75,labelBackgroundPadding:[2,4,2,4],labelFill:n,labelFontSize:12,labelFontWeight:400,labelOpacity:1,lineDash:0,lineWidth:1,fillOpacity:.04,strokeOpacity:1,padding:10,stroke:y},state:{selected:{halo:!0,labelFontSize:14,labelFontWeight:700,lineWidth:4},active:{halo:!0},highlight:{labelFontWeight:700,lineWidth:4},inactive:{fillOpacity:.65,labelOpacity:.25,strokeOpacity:.65},disabled:{fill:m,fillOpacity:.25,labelOpacity:.25,stroke:b,strokeOpacity:.25}},animation:{enter:"fade",exit:"fade",show:"fade",hide:"fade",expand:"combo-expand",collapse:"combo-collapse",update:[{fields:["x","y"]},{fields:["fill","stroke","lineWidth"],shape:"key"}],translate:[{fields:["x","y"]}]}}}}const LH=DH({bgColor:"#000000",comboColor:"#fdfdfd",comboColorDisabled:"#d0e4ff",comboStroke:"#99add1",comboStrokeDisabled:"#969696",edgeColor:"#637088",edgeColorDisabled:"#637088",edgeColorInactive:"#D0E4FF",edgePaletteOptions:{type:"group",color:["#637088","#0F55A6","#008383","#9C5D38","#8B53A6","#4E40A6","#8F6608","#3E801D","#A65383","#175E75","#0F8248"]},nodeColor:"#1783ff",nodeColorDisabled:"#D0E4FF",nodeHaloStrokeOpacityActive:.25,nodeHaloStrokeOpacitySelected:.45,nodeIconOpacityInactive:.45,nodeOpacityDisabled:.25,nodeOpacityInactive:.45,nodeStroke:"#d0e4ff",textColor:"#ffffff"}),_H=DH({bgColor:"#ffffff",comboColor:"#99ADD1",comboColorDisabled:"#f0f0f0",comboStroke:"#99add1",comboStrokeDisabled:"#d9d9d9",edgeColor:"#99add1",edgeColorDisabled:"#d9d9d9",edgeColorInactive:"#1B324F",nodeColor:"#1783ff",nodeColorDisabled:"#1B324F",nodeHaloStrokeOpacityActive:.15,nodeHaloStrokeOpacitySelected:.25,nodeIconOpacityInactive:.85,nodeOpacityDisabled:.06,nodeOpacityInactive:.25,nodeStroke:"#000000",textColor:"#000000"});class IH extends zh{beforeDraw(t,e){return t}afterLayout(t,e){}}function jH(t,e,n,r,i){const o=Nh(r),a=`${n}s`,s=i?r:t.add[a].get(o)||t.update[a].get(o)||t.remove[a].get(o)||r;Object.entries(t).forEach((([t,n])=>{e===t?n[a].set(o,s):n[a].delete(o)}))}function BH(t,e){return Object.keys(t).every((n=>t[n]===e[n]))}const FH=(t,e,n,r)=>{const i=`${n}s`,o=Nh(r);t.add[i].has(o)||t.update[i].has(o)||t[e][i].set(Nh(r),r)};const zH=new WeakMap;const GH=(t,e,n=2)=>{if("object"!=typeof t||"object"!=typeof e)return t===e;const r=Object.keys(t),i=Object.keys(e);if(r.length!==i.length)return!1;for(const i of r){const r=t[i],o=e[i];if(n>1&&"object"==typeof r&&"object"==typeof o){if(!GH(r,o,n-1))return!1}else if(r!==o)return!1}return!0};function VH(t,e,n){Rc[t][e]&&Ic(`The extension ${e} of ${t} has been registered before, and will be overridden.`),Object.assign(Rc[t],{[e]:n})} -/*! - * @antv/g-plugin-dragndrop - * @description A G plugin for Drag n Drop implemented with PointerEvents - * @version 2.0.35 - * @date 5/9/2025, 8:20:14 AM - * @author AntVis - * @docs https://g.antv.antgroup.com/ - */var WH=function(){function t(e){s(this,t),this.dragndropPluginOptions=e}return u(t,[{key:"apply",value:function(e){var n=this,r=e.renderingService,i=e.renderingContext.root.ownerDocument,o=i.defaultView,a=function(t){var e=t.target,r=e===i,a=r&&n.dragndropPluginOptions.isDocumentDraggable?i:e.closest&&e.closest("[draggable=true]");if(a){var s=!1,l=t.timeStamp,u=[t.clientX,t.clientY],c=null,h=[t.clientX,t.clientY],d=function(){var t=ar(ir().mark((function t(o){var d,f,p,g,v,m;return ir().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(s){t.next=8;break}if(d=o.timeStamp-l,f=gn([o.clientX,o.clientY],u),!(d<=n.dragndropPluginOptions.dragstartTimeThreshold||f<=n.dragndropPluginOptions.dragstartDistanceThreshold)){t.next=5;break}return t.abrupt("return");case 5:o.type="dragstart",a.dispatchEvent(o),s=!0;case 8:if(o.type="drag",o.dx=o.clientX-h[0],o.dy=o.clientY-h[1],a.dispatchEvent(o),h=[o.clientX,o.clientY],r){t.next=21;break}return p="pointer"===n.dragndropPluginOptions.overlap?[o.canvasX,o.canvasY]:e.getBounds().center,t.next=17,i.elementsFromPoint(p[0],p[1]);case 17:g=t.sent,v=g[g.indexOf(e)+1],m=(null==v?void 0:v.closest("[droppable=true]"))||(n.dragndropPluginOptions.isDocumentDroppable?i:null),c!==m&&(c&&(o.type="dragleave",o.target=c,c.dispatchEvent(o)),m&&(o.type="dragenter",o.target=m,m.dispatchEvent(o)),(c=m)&&(o.type="dragover",o.target=c,c.dispatchEvent(o)));case 21:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}();o.addEventListener("pointermove",d);var f=function(t){if(s){t.detail={preventClick:!0};var e=t.clone();c&&(e.type="drop",e.target=c,c.dispatchEvent(e)),e.type="dragend",a.dispatchEvent(e),s=!1}o.removeEventListener("pointermove",d)};e.addEventListener("pointerup",f,{once:!0}),e.addEventListener("pointerupoutside",f,{once:!0})}};r.hooks.init.tap(t.tag,(function(){o.addEventListener("pointerdown",a)})),r.hooks.destroy.tap(t.tag,(function(){o.removeEventListener("pointerdown",a)}))}}])}();WH.tag="Dragndrop";var HH=function(t){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return s(this,e),(t=v(this,e)).name="dragndrop",t.options=n,t}return y(e,t),u(e,[{key:"init",value:function(){this.addRenderingPlugin(new WH(a({overlap:"pointer",isDocumentDraggable:!1,isDocumentDroppable:!1,dragstartDistanceThreshold:0,dragstartTimeThreshold:0},this.options)))}},{key:"destroy",value:function(){this.removeAllRenderingPlugins()}},{key:"setOptions",value:function(t){Object.assign(this.plugins[0].dragndropPluginOptions,t)}}])}(fr);const UH=["main"],$H=["background","main","label","transient"];class YH{getConfig(){return this.config}getLayer(t="main"){return this.extends.layers[t]||this.getLayers().main}getLayers(){return this.extends.layers}getRenderer(t){return this.extends.renderers[t]}getCamera(t="main"){return this.getLayer(t).getCamera()}getRoot(t="main"){return this.getLayer(t).getRoot()}getContextService(t="main"){return this.getLayer(t).getContextService()}setCursor(t){this.config.cursor=t,this.getLayer().setCursor(t)}get document(){return this.getLayer().document}get context(){return this.getLayer().context}constructor(t){this.config={enableMultiLayer:!0},Object.assign(this.config,t);const e=this.config,{renderer:n,background:r,cursor:i,enableMultiLayer:o}=e,a=Fe(e,["renderer","background","cursor","enableMultiLayer"]),s=o?$H:UH,l=qH(n,s),u=Object.fromEntries(s.map((t=>[t,new bu(Object.assign(Object.assign({},a),{supportsMutipleCanvasesInOneContainer:o,renderer:l[t],background:o?"background"===t?r:void 0:r}))])));XH(u),this.extends={config:this.config,renderer:n,renderers:l,layers:u}}get ready(){return Promise.all(Object.entries(this.getLayers()).map((([,t])=>t.ready)))}resize(t,e){Object.assign(this.extends.config,{width:t,height:e}),Object.values(this.getLayers()).forEach((n=>{const r=n.getCamera(),i=r.getPosition(),o=r.getFocalPoint();n.resize(t,e),r.setPosition(i),r.setFocalPoint(o)}))}getBounds(t){return sh(Object.values(this.getLayers()).map((e=>t?e.getRoot().childNodes.find((e=>e.classList.includes(t))):e.getRoot())).filter((t=>(null==t?void 0:t.childNodes.length)>0)).map((t=>t.getBounds())))}getContainer(){const t=this.extends.config.container;return"string"==typeof t?document.getElementById(t):t}getSize(){return[this.extends.config.width||0,this.extends.config.height||0]}appendChild(t,e){var n;const r=(null===(n=t.style)||void 0===n?void 0:n.$layer)||"main";return this.getLayer(r).appendChild(t,e)}setRenderer(t){if(t===this.extends.renderer)return;const e=qH(t,this.config.enableMultiLayer?$H:UH);this.extends.renderers=e,Object.entries(e).forEach((([t,e])=>this.getLayer(t).setRenderer(e))),XH(this.getLayers())}getCanvasByViewport(t){return cd(this.getLayer().viewport2Canvas(hd(t)))}getViewportByCanvas(t){return cd(this.getLayer().canvas2Viewport(hd(t)))}getViewportByClient(t){return cd(this.getLayer().client2Viewport(hd(t)))}getClientByViewport(t){return cd(this.getLayer().viewport2Client(hd(t)))}getClientByCanvas(t){return this.getClientByViewport(this.getViewportByCanvas(t))}getCanvasByClient(t){const e=this.getLayer(),n=e.client2Viewport(hd(t));return cd(e.viewport2Canvas(n))}toDataURL(){return ze(this,arguments,void 0,(function*(t={}){const e=globalThis.devicePixelRatio||1,{mode:n="viewport"}=t,r=Fe(t,["mode"]);let[i,o,a,s]=[0,0,0,0];if("viewport"===n)[a,s]=this.getSize();else if("overall"===n){const t=this.getBounds(),e=rh(t);[i,o]=t.min,[a,s]=e}const l=Cn('
    '),u=new bu({width:a,height:s,renderer:new Dp,devicePixelRatio:e,container:l,background:this.extends.config.background});yield u.ready,u.appendChild(this.getLayer("background").getRoot().cloneNode(!0)),u.appendChild(this.getRoot().cloneNode(!0));const c=this.getLayer("label").getRoot().cloneNode(!0),h=u.viewport2Canvas({x:0,y:0}),d=this.getCanvasByViewport([0,0]);c.translate([d[0]-h.x,d[1]-h.y]),c.scale(1/this.getCamera().getZoom()),u.appendChild(c),u.appendChild(this.getLayer("transient").getRoot().cloneNode(!0));const f=this.getCamera(),p=u.getCamera();if("viewport"===n)p.setZoom(f.getZoom()),p.setPosition(f.getPosition()),p.setFocalPoint(f.getFocalPoint());else if("overall"===n){const[t,e,n]=p.getPosition(),[r,a,s]=p.getFocalPoint();p.setPosition([t+i,e+o,n]),p.setFocalPoint([r+i,a+o,s])}const g=u.getContextService();return new Promise((t=>{u.addEventListener(fu.RERENDER,(()=>ze(this,void 0,void 0,(function*(){yield new Promise((t=>setTimeout(t,300)));const e=yield g.toDataURL(r);t(e)}))))}))}))}destroy(){Object.values(this.getLayers()).forEach((t=>{t.getCamera().cancelLandmarkAnimation(),t.destroy()}))}}function qH(t,e){return Object.fromEntries(e.map((e=>{const n=(null==t?void 0:t(e))||new Dp;return n instanceof Dp&&n.setConfig({enableDirtyRectangleRendering:!1}),"main"===e?n.registerPlugin(new HH({isDocumentDraggable:!0,isDocumentDroppable:!0,dragstartDistanceThreshold:10,dragstartTimeThreshold:100})):n.unregisterPlugin(n.getPlugin("dom-interaction")),[e,n]})))}function XH(t){Object.entries(t).forEach((([t,e])=>{const n=e.getContextService().getDomElement();(null==n?void 0:n.style)&&(n.style.gridArea="1 / 1 / 2 / 2",n.style.outline="none",n.tabIndex=1,"main"!==t&&(n.style.pointerEvents="none")),(null==n?void 0:n.parentElement)&&(n.parentElement.style.display="grid")}))}const KH=t=>t?parseInt(t):0;function ZH(t){if(!t)return[0,0];let e=640,n=480;const[r,i]=function(t){const e=getComputedStyle(t),n=t.clientWidth||KH(e.width),r=t.clientHeight||KH(e.height);return[n-(KH(e.paddingLeft)+KH(e.paddingRight)),r-(KH(e.paddingTop)+KH(e.paddingBottom))]}(t);e=r||e,n=i||n;return[Math.max(ae(e)?e:1,1),Math.max(ae(n)?n:1,1)]}class QH{constructor(t){this.type=t}}class JH extends QH{constructor(t,e){super(t),this.data=e}}class tU extends QH{constructor(t,e,n,r){super(t),this.animationType=e,this.animation=n,this.data=r}}class eU extends QH{constructor(t,e,n){super(t),this.elementType=e,this.data=n}}class nU extends QH{constructor(t,e){super(t),this.data=e}}function rU(t,e){t.emit(e.type,e)}function iU(t){var e;return(null===(e=null==t?void 0:t.style)||void 0===e?void 0:e.zIndex)||0}const oU="cachedStyle",aU=t=>`__${t}__`;function sU(t,e){return Oe(t,[oU,aU(e)])}class lU{constructor(t){this.tasks=[],this.animations=new Set,this.context=t}getTasks(){const t=[...this.tasks];return this.tasks=[],t}add(t,e){this.tasks.push([t,e])}animate(t,e,n){var r,i,o;null===(r=null==e?void 0:e.before)||void 0===r||r.call(e);const a=this.getTasks().map((([e,r])=>{var i,o,a;const{element:s,elementType:l,stage:u}=e,c=Vc(this.context.options,l,u,t);null===(i=null==r?void 0:r.before)||void 0===i||i.call(r);const h=c.length?Hc(s,this.inferStyle(e,n),c):null;return h?(null===(o=null==r?void 0:r.beforeAnimate)||void 0===o||o.call(r,h),h.finished.then((()=>{var t,e;null===(t=null==r?void 0:r.afterAnimate)||void 0===t||t.call(r,h),null===(e=null==r?void 0:r.after)||void 0===e||e.call(r),this.animations.delete(h)}))):null===(a=null==r?void 0:r.after)||void 0===a||a.call(r),h})).filter(Boolean);a.forEach((t=>this.animations.add(t)));const s=Bc(a);return s?(null===(i=null==e?void 0:e.beforeAnimate)||void 0===i||i.call(e,s),s.finished.then((()=>{var t,n;null===(t=null==e?void 0:e.afterAnimate)||void 0===t||t.call(e,s),null===(n=null==e?void 0:e.after)||void 0===n||n.call(e),this.release()}))):null===(o=null==e?void 0:e.after)||void 0===o||o.call(e),s}inferStyle(t,e){var n,r;const{element:i,elementType:o,stage:a,originalStyle:s,updatedStyle:l={}}=t;t.modifiedStyle||(t.modifiedStyle=Object.assign(Object.assign({},s),l));const{modifiedStyle:u}=t,c={},h={};if("enter"===a)Object.assign(c,{opacity:0});else if("exit"===a)Object.assign(h,{opacity:0});else if("show"===a)Object.assign(c,{opacity:0}),Object.assign(h,{opacity:null!==(n=sU(i,"opacity"))&&void 0!==n?n:zc("opacity")});else if("hide"===a)Object.assign(c,{opacity:null!==(r=sU(i,"opacity"))&&void 0!==r?r:zc("opacity")}),Object.assign(h,{opacity:0});else if("collapse"===a){const{collapse:t}=e||{},{target:n,descendants:r,position:a}=t;if("node"===o){if(r.includes(i.id)){const[t,e,n]=a;Object.assign(h,{x:t,y:e,z:n})}}else if("combo"===o){if(i.id===n||r.includes(i.id)){const[t,e]=a;Object.assign(h,{x:t,y:e,childrenNode:s.childrenNode})}}else"edge"===o&&Object.assign(h,{sourceNode:u.sourceNode,targetNode:u.targetNode})}else if("expand"===a){const{expand:t}=e||{},{target:n,descendants:r,position:a}=t;if("node"===o){if(i.id===n||r.includes(i.id)){const[t,e,n]=a;Object.assign(c,{x:t,y:e,z:n})}}else if("combo"===o){if(i.id===n||r.includes(i.id)){const[t,e,n]=a;Object.assign(c,{x:t,y:e,z:n,childrenNode:u.childrenNode})}}else"edge"===o&&Object.assign(c,{sourceNode:u.sourceNode,targetNode:u.targetNode})}return[Object.keys(c).length>0?Object.assign({},s,c):s,Object.keys(h).length>0?Object.assign({},u,h):u]}stop(){this.animations.forEach((t=>t.cancel()))}clear(){this.tasks=[]}release(){var t,e;const{canvas:n}=this.context,r=null===(e=null===(t=n.document)||void 0===t?void 0:t.timeline)||void 0===e?void 0:e.animationsWithPromises;r&&(n.document.timeline.animationsWithPromises=r.filter((t=>"finished"!==t.playState)))}destroy(){this.stop(),this.animations.clear(),this.tasks=[]}}class uU{constructor(t){this.batchCount=0,this.context=t}emit(t){const{graph:e}=this.context;e.emit(t.type,t)}startBatch(e=!0){this.batchCount++,1===this.batchCount&&this.emit(new JH(t.GraphEvent.BATCH_START,{initiate:e}))}endBatch(){this.batchCount--,0===this.batchCount&&this.emit(new JH(t.GraphEvent.BATCH_END))}get isBatching(){return this.batchCount>0}destroy(){this.context=null}}class cU extends Fh{constructor(e){super(e),this.currentTarget=null,this.currentTargetType=null,this.category="behavior",this.forwardCanvasEvents=e=>{const{target:n}=e,r=function(t){if(!t)return null;if(t instanceof su)return{type:"canvas",element:t};let e=t;for(;e;){if(Ag(e))return{type:"node",element:e};if(Pg(e))return{type:"edge",element:e};if(Rg(e))return{type:"combo",element:e};e=e.parentElement}return null}(n);if(!r)return;const{graph:i,canvas:o}=this.context,{type:a,element:s}=r;if("destroyed"in s&&(Hg(s)||s.destroyed))return;const{type:l,detail:u,button:c}=e,h=Object.assign(Object.assign({},e),{target:s,targetType:a,originalTarget:n});l===t.CommonEvent.POINTER_MOVE&&(this.currentTarget!==s&&(this.currentTarget&&i.emit(`${this.currentTargetType}:${t.CommonEvent.POINTER_LEAVE}`,Object.assign(Object.assign({},h),{type:t.CommonEvent.POINTER_LEAVE,target:this.currentTarget,targetType:this.currentTargetType})),s&&(Object.assign(h,{type:t.CommonEvent.POINTER_ENTER}),i.emit(`${a}:${t.CommonEvent.POINTER_ENTER}`,h))),this.currentTarget=s,this.currentTargetType=a),l===t.CommonEvent.CLICK&&2===c||(i.emit(`${a}:${l}`,h),i.emit(l,h)),l===t.CommonEvent.CLICK&&2===u&&(Object.assign(h,{type:t.CommonEvent.DBLCLICK}),i.emit(`${a}:${t.CommonEvent.DBLCLICK}`,h),i.emit(t.CommonEvent.DBLCLICK,h)),l===t.CommonEvent.POINTER_DOWN&&2===c&&(Object.assign(h,{type:t.CommonEvent.CONTEXT_MENU,preventDefault:()=>{var e;null===(e=o.getContainer())||void 0===e||e.addEventListener(t.CommonEvent.CONTEXT_MENU,(t=>t.preventDefault()),{once:!0})}}),i.emit(`${a}:${t.CommonEvent.CONTEXT_MENU}`,h),i.emit(t.CommonEvent.CONTEXT_MENU,h))},this.forwardContainerEvents=t=>{this.context.graph.emit(t.type,t)},this.forwardEvents(),this.setBehaviors(this.context.options.behaviors||[])}setBehaviors(t){this.setExtensions(t)}forwardEvents(){const e=this.context.canvas.getContainer();e&&[t.ContainerEvent.KEY_DOWN,t.ContainerEvent.KEY_UP].forEach((t=>{e.addEventListener(t,this.forwardContainerEvents)}));const n=this.context.canvas.document;n&&[t.CommonEvent.CLICK,t.CommonEvent.DBLCLICK,t.CommonEvent.POINTER_OVER,t.CommonEvent.POINTER_LEAVE,t.CommonEvent.POINTER_ENTER,t.CommonEvent.POINTER_MOVE,t.CommonEvent.POINTER_OUT,t.CommonEvent.POINTER_DOWN,t.CommonEvent.POINTER_UP,t.CommonEvent.CONTEXT_MENU,t.CommonEvent.DRAG_START,t.CommonEvent.DRAG,t.CommonEvent.DRAG_END,t.CommonEvent.DRAG_ENTER,t.CommonEvent.DRAG_OVER,t.CommonEvent.DRAG_LEAVE,t.CommonEvent.DROP,t.CommonEvent.WHEEL].forEach((t=>{n.addEventListener(t,this.forwardCanvasEvents)}))}destroy(){const e=this.context.canvas.getContainer();e&&[t.ContainerEvent.KEY_DOWN,t.ContainerEvent.KEY_UP].forEach((t=>{e.removeEventListener(t,this.forwardContainerEvents)})),this.context.canvas.document.removeAllEventListeners(),super.destroy()}}function hU(t,e){const{data:n,style:r}=t,i=Fe(t,["data","style"]),{data:o,style:a}=e,s=Fe(e,["data","style"]),l=Object.assign(Object.assign({},i),s);return(n||o)&&Object.assign(l,{data:Object.assign(Object.assign({},n),o)}),(r||a)&&Object.assign(l,{style:Object.assign(Object.assign({},r),a)}),l}function dU(t){const{data:e,style:n}=t,r=Fe(t,["data","style"]);return e&&(r.data=Object.assign({},e)),n&&(r.style=Object.assign({},n)),r}function fU(t={},e={}){const{states:n=[],data:r={},style:i={},children:o=[]}=t,a=Fe(t,["states","data","style","children"]),{states:s=[],data:l={},style:u={},children:c=[]}=e,h=(t,e)=>t.length===e.length&&t.every(((t,n)=>t===e[n])),d=(t,e)=>{const n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every((n=>t[n]===e[n]))};return!!d(a,Fe(e,["states","data","style","children"]))&&(!!h(o,c)&&(!!h(n,s)&&(!!d(r,l)&&!!d(i,u))))}function pU(t){const{id:e=Nh(t),style:n,data:r}=t,i=Fe(t,["id","style","data"]),o=Object.assign(Object.assign({},t),{style:Object.assign({},n),data:Object.assign({},r)});return function(t){return"source"in t&&"target"in t}(t)?Object.assign({id:e,data:o},i):{id:e,data:o}}function gU(t){return t.data}class vU{constructor(){this.latestRemovedComboIds=new Set,this.comboIds=new Set,this.changes=[],this.batchCount=0,this.isTraceless=!1,this.enableUpdateNodeLikeHierarchy=!0,this.model=new ev}pushChange(t){if(this.isTraceless)return;const{type:e}=t;if(e===xc.NodeUpdated||e===xc.EdgeUpdated||e===xc.ComboUpdated){const{value:n,original:r}=t;this.changes.push({value:dU(n),original:dU(r),type:e})}else this.changes.push({value:dU(t.value),type:e})}getChanges(){return this.changes}clearChanges(){this.changes=[]}batch(t){this.batchCount++,this.model.batch(t),this.batchCount--}isBatching(){return this.batchCount>0}silence(t){this.isTraceless=!0,t(),this.isTraceless=!1}isCombo(t){return this.comboIds.has(t)||this.latestRemovedComboIds.has(t)}getData(){return{nodes:this.getNodeData(),edges:this.getEdgeData(),combos:this.getComboData()}}getNodeData(t){return this.model.getAllNodes().reduce(((e,n)=>{const r=gU(n);return this.isCombo(Nh(r))||(void 0===t||t.includes(Nh(r)))&&e.push(r),e}),[])}getEdgeDatum(t){return gU(this.model.getEdge(t))}getEdgeData(t){return this.model.getAllEdges().reduce(((e,n)=>{const r=gU(n);return(void 0===t||t.includes(Nh(r)))&&e.push(r),e}),[])}getComboData(t){return this.model.getAllNodes().reduce(((e,n)=>{const r=gU(n);return this.isCombo(Nh(r))?((void 0===t||t.includes(Nh(r)))&&e.push(r),e):e}),[])}getRootsData(t=Ac){return this.model.getRoots(t).map(gU)}getAncestorsData(t,e){const{model:n}=this;return n.hasNode(t)&&n.hasTreeStructure(e)?n.getAncestors(t,e).map(gU):[]}getDescendantsData(t){const e=this.getElementDataById(t),n=[];return Ad(e,(t=>{t!==e&&n.push(t)}),(t=>this.getChildrenData(Nh(t))),"TB"),n}getParentData(t,e){const{model:n}=this;if(!e)return void Ic("The hierarchy structure key is not specified");if(!n.hasNode(t)||!n.hasTreeStructure(e))return;const r=n.getParent(t,e);return r?gU(r):void 0}getChildrenData(t){const e="node"===this.getElementType(t)?Ac:Cc,{model:n}=this;return n.hasNode(t)&&n.hasTreeStructure(e)?n.getChildren(t,e).map(gU):[]}getElementsDataByType(t){return"node"===t?this.getNodeData():"edge"===t?this.getEdgeData():"combo"===t?this.getComboData():[]}getElementDataById(t){return"edge"===this.getElementType(t)?this.getEdgeDatum(t):this.getNodeLikeDatum(t)}getNodeLikeDatum(t){return gU(this.model.getNode(t))}getNodeLikeData(t){return this.model.getAllNodes().reduce(((e,n)=>{const r=gU(n);return t?t.includes(Nh(r))&&e.push(r):e.push(r),e}),[])}getElementDataByState(t,e){return this.getElementsDataByType(t).filter((t=>{var n;return null===(n=t.states)||void 0===n?void 0:n.includes(e)}))}getElementState(t){var e;return(null===(e=this.getElementDataById(t))||void 0===e?void 0:e.states)||[]}hasNode(t){return this.model.hasNode(t)&&!this.isCombo(t)}hasEdge(t){return this.model.hasEdge(t)}hasCombo(t){return this.model.hasNode(t)&&this.isCombo(t)}getRelatedEdgesData(t,e="both"){return this.model.getRelatedEdges(t,e).map(gU)}getNeighborNodesData(t){return this.model.getNeighbors(t).map(gU)}setData(t){const{nodes:e=[],edges:n=[],combos:r=[]}=t,{nodes:i,edges:o,combos:a}=this.getData(),s=jh(i,e,(t=>Nh(t)),fU),l=jh(o,n,(t=>Nh(t)),fU),u=jh(a,r,(t=>Nh(t)),fU);this.batch((()=>{const t={nodes:s.enter,edges:l.enter,combos:u.enter};this.addData(t),this.computeZIndex(t,"add",!0);const e={nodes:s.update,edges:l.update,combos:u.update};this.updateData(e),this.computeZIndex(e,"update",!0);const n={nodes:s.exit.map(Nh),edges:l.exit.map(Nh),combos:u.exit.map(Nh)};this.removeData(n)}))}addData(t){const{nodes:e,edges:n,combos:r}=t;this.batch((()=>{this.addComboData(r),this.addNodeData(e),this.addEdgeData(n)})),this.computeZIndex(t,"add")}addNodeData(t=[]){t.length&&(this.model.addNodes(t.map((t=>(this.pushChange({value:t,type:xc.NodeAdded}),pU(t))))),this.updateNodeLikeHierarchy(t),this.computeZIndex({nodes:t},"add"))}addEdgeData(t=[]){t.length&&(this.model.addEdges(t.map((t=>(this.pushChange({value:t,type:xc.EdgeAdded}),pU(t))))),this.computeZIndex({edges:t},"add"))}addComboData(t=[]){if(!t.length)return;const{model:e}=this;e.hasTreeStructure(Cc)||e.attachTreeStructure(Cc),e.addNodes(t.map((t=>(this.comboIds.add(Nh(t)),this.pushChange({value:t,type:xc.ComboAdded}),pU(t))))),this.updateNodeLikeHierarchy(t),this.computeZIndex({combos:t},"add")}addChildrenData(t,e){const n=this.getNodeLikeDatum(t),r=e.map(Nh);this.addNodeData(e),this.updateNodeData([{id:t,children:[...n.children||[],...r]}]),this.addEdgeData(r.map((e=>({source:t,target:e}))))}computeZIndex(t,e,n=!1){!n&&this.isBatching()||this.batch((()=>{const{nodes:n=[],edges:r=[],combos:i=[]}=t;i.forEach((t=>{var n,r,i;const o=Nh(t);if("add"===e&&ae(null===(n=t.style)||void 0===n?void 0:n.zIndex))return;if("update"===e&&!("combo"in t))return;const a=this.getParentData(o,Cc),s=a?(null!==(i=null===(r=a.style)||void 0===r?void 0:r.zIndex)&&void 0!==i?i:0)+1:0;this.preventUpdateNodeLikeHierarchy((()=>{this.updateComboData([{id:o,style:{zIndex:s}}])}))})),n.forEach((t=>{var n,r,i;const o=Nh(t);if("add"===e&&ae(null===(n=t.style)||void 0===n?void 0:n.zIndex))return;if("update"===e&&!("combo"in t)&&!("children"in t))return;let a=0;const s=this.getParentData(o,Cc);if(s)a=((null===(r=s.style)||void 0===r?void 0:r.zIndex)||0)+1;else{const t=this.getParentData(o,Ac);t&&(a=(null===(i=null==t?void 0:t.style)||void 0===i?void 0:i.zIndex)||0)}this.preventUpdateNodeLikeHierarchy((()=>{this.updateNodeData([{id:o,style:{zIndex:a}}])}))})),r.forEach((t=>{var e,n,r,i,o;if(ae(null===(e=t.style)||void 0===e?void 0:e.zIndex))return;let{id:a,source:s,target:l}=t;if(a){const t=this.getEdgeDatum(a);s=t.source,l=t.target}else a=Nh(t);if(!s||!l)return;const u=(null===(r=null===(n=this.getNodeLikeDatum(s))||void 0===n?void 0:n.style)||void 0===r?void 0:r.zIndex)||0,c=(null===(o=null===(i=this.getNodeLikeDatum(l))||void 0===i?void 0:i.style)||void 0===o?void 0:o.zIndex)||0;this.updateEdgeData([{id:Nh(t),style:{zIndex:Math.max(u,c)-1}}])}))}))}getFrontZIndex(t){var e;const n=this.getElementType(t),r=this.getElementDataById(t),i=this.getData();if(Object.assign(i,{[`${n}s`]:i[`${n}s`].filter((e=>Nh(e)!==t))}),"combo"===n&&!_d(r)){const e=new Set(this.getAncestorsData(t,Cc).map(Nh));i.nodes=i.nodes.filter((t=>!e.has(Nh(t)))),i.combos=i.combos.filter((t=>!e.has(Nh(t)))),i.edges=i.edges.filter((({source:t,target:n})=>!e.has(t)&&!e.has(n)))}return Math.max((null===(e=r.style)||void 0===e?void 0:e.zIndex)||0,0,...Object.values(i).flat().map((t=>{var e;return((null===(e=null==t?void 0:t.style)||void 0===e?void 0:e.zIndex)||0)+1})))}updateNodeLikeHierarchy(t){if(!this.enableUpdateNodeLikeHierarchy)return;const{model:e}=this;t.forEach((t=>{const n=Nh(t),r=Oh(t);void 0!==r&&(e.hasTreeStructure(Cc)||e.attachTreeStructure(Cc),null===r&&this.refreshComboData(n),this.setParent(n,Oh(t),Cc));const i=t.children||[];if(i.length){e.hasTreeStructure(Ac)||e.attachTreeStructure(Ac);const t=i.filter((t=>e.hasNode(t)));t.forEach((t=>this.setParent(t,n,Ac))),t.length!==i.length&&this.updateNodeData([{id:n,children:t}])}}))}preventUpdateNodeLikeHierarchy(t){this.enableUpdateNodeLikeHierarchy=!1,t(),this.enableUpdateNodeLikeHierarchy=!0}updateData(t){const{nodes:e,edges:n,combos:r}=t;this.batch((()=>{this.updateNodeData(e),this.updateComboData(r),this.updateEdgeData(n)})),this.computeZIndex(t,"update")}updateNodeData(t=[]){if(!t.length)return;const{model:e}=this;this.batch((()=>{const n=[];t.forEach((t=>{const r=Nh(t),i=gU(e.getNode(r));if(fU(i,t))return;const o=hU(i,t);this.pushChange({value:o,original:i,type:xc.NodeUpdated}),e.mergeNodeData(r,o),n.push(o)})),this.updateNodeLikeHierarchy(n)})),this.computeZIndex({nodes:t},"update")}refreshData(){const{nodes:t,edges:e,combos:n}=this.getData();t.forEach((t=>{this.pushChange({value:t,original:t,type:xc.NodeUpdated})})),e.forEach((t=>{this.pushChange({value:t,original:t,type:xc.EdgeUpdated})})),n.forEach((t=>{this.pushChange({value:t,original:t,type:xc.ComboUpdated})}))}syncNodeLikeDatum(t){const{model:e}=this,n=Nh(t);if(!e.hasNode(n))return;const r=hU(gU(e.getNode(n)),t);e.mergeNodeData(n,r)}syncEdgeDatum(t){const{model:e}=this,n=Nh(t);if(!e.hasEdge(n))return;const r=hU(gU(e.getEdge(n)),t);e.mergeEdgeData(n,r)}updateEdgeData(t=[]){if(!t.length)return;const{model:e}=this;this.batch((()=>{t.forEach((t=>{const n=Nh(t),r=gU(e.getEdge(n));if(fU(r,t))return;t.source&&r.source!==t.source&&e.updateEdgeSource(n,t.source),t.target&&r.target!==t.target&&e.updateEdgeTarget(n,t.target);const i=hU(r,t);this.pushChange({value:i,original:r,type:xc.EdgeUpdated}),e.mergeEdgeData(n,i)}))})),this.computeZIndex({edges:t},"update")}updateComboData(t=[]){if(!t.length)return;const{model:e}=this;e.batch((()=>{const n=[];t.forEach((t=>{const r=Nh(t),i=gU(e.getNode(r));if(fU(i,t))return;const o=hU(i,t);this.pushChange({value:o,original:i,type:xc.ComboUpdated}),e.mergeNodeData(r,o),n.push(o)})),this.updateNodeLikeHierarchy(n)})),this.computeZIndex({combos:t},"update")}setParent(t,e,n,r=!0){if(t===e)return;const i=Oh(this.getNodeLikeDatum(t));if(i!==e&&n===Cc){const n={id:t,combo:e};this.isCombo(t),this.syncNodeLikeDatum(n)}this.model.setParent(t,e,n),r&&n===Cc&&function(t,e){void 0===e&&(e=new Map);var n=[];if(Array.isArray(t))for(var r=0,i=t.length;r{void 0!==t&&this.refreshComboData(t)}))}refreshComboData(t){const e=this.getComboData([t])[0],n=this.getAncestorsData(t,Cc);e&&this.pushChange({value:e,original:e,type:xc.ComboUpdated}),n.forEach((t=>{this.pushChange({value:t,original:t,type:xc.ComboUpdated})}))}getElementPosition(t){return sd(this.getElementDataById(t))}translateNodeLikeBy(t,e){this.isCombo(t)?this.translateComboBy(t,e):this.translateNodeBy(t,e)}translateNodeLikeTo(t,e){this.isCombo(t)?this.translateComboTo(t,e):this.translateNodeTo(t,e)}translateNodeBy(t,e){const n=Hh(this.getElementPosition(t),[...e,0].slice(0,3));this.translateNodeTo(t,n)}translateNodeTo(t,e){const[n=0,r=0,i=0]=e;this.preventUpdateNodeLikeHierarchy((()=>{this.updateNodeData([{id:t,style:{x:n,y:r,z:i}}])}))}translateComboBy(t,e){const[n=0,r=0,i=0]=e;if([n,r,i].some(isNaN)||[n,r,i].every((t=>0===t)))return;const o=this.getComboData([t])[0];if(!o)return;const a=new Set;Ad(o,(t=>{const e=Nh(t);if(a.has(e))return;a.add(e);const[o,s,l]=sd(t),u=hU(t,{style:{x:o+n,y:s+r,z:l+i}});this.pushChange({value:u,original:t,type:this.isCombo(e)?xc.ComboUpdated:xc.NodeUpdated}),this.model.mergeNodeData(e,u)}),(t=>this.getChildrenData(Nh(t))),"BT")}translateComboTo(t,e){var n;if(e.some(isNaN))return;const[r=0,i=0,o=0]=e,a=null===(n=this.getComboData([t]))||void 0===n?void 0:n[0];if(!a)return;const[s,l,u]=sd(a),c=r-s,h=i-l,d=o-u;Ad(a,(t=>{const e=Nh(t),[n,r,i]=sd(t),o=hU(t,{style:{x:n+c,y:r+h,z:i+d}});this.pushChange({value:o,original:t,type:this.isCombo(e)?xc.ComboUpdated:xc.NodeUpdated}),this.model.mergeNodeData(e,o)}),(t=>this.getChildrenData(Nh(t))),"BT")}removeData(t){const{nodes:e,edges:n,combos:r}=t;this.batch((()=>{this.removeEdgeData(n),this.removeNodeData(e),this.removeComboData(r),this.latestRemovedComboIds=new Set(r)}))}removeNodeData(t=[]){t.length&&this.batch((()=>{t.forEach((t=>{this.removeEdgeData(this.getRelatedEdgesData(t).map(Nh)),this.pushChange({value:this.getNodeData([t])[0],type:xc.NodeRemoved}),this.removeNodeLikeHierarchy(t)})),this.model.removeNodes(t)}))}removeEdgeData(t=[]){t.length&&(t.forEach((t=>this.pushChange({value:this.getEdgeData([t])[0],type:xc.EdgeRemoved}))),this.model.removeEdges(t))}removeComboData(t=[]){t.length&&this.batch((()=>{t.forEach((t=>{this.pushChange({value:this.getComboData([t])[0],type:xc.ComboRemoved}),this.removeNodeLikeHierarchy(t),this.comboIds.delete(t)})),this.model.removeNodes(t)}))}removeNodeLikeHierarchy(t){if(this.model.hasTreeStructure(Cc)){const e=Oh(this.getNodeLikeDatum(t));this.setParent(t,void 0,Cc,!1),this.model.getChildren(t,Cc).forEach((t=>{const n=gU(t),r=Nh(n);this.setParent(Nh(n),e,Cc,!1);const i=hU(n,{id:Nh(n),combo:e});this.pushChange({value:i,original:n,type:this.isCombo(r)?xc.ComboUpdated:xc.NodeUpdated}),this.model.mergeNodeData(Nh(n),i)})),$t(e)||this.refreshComboData(e)}}getElementType(t){if(this.model.hasNode(t))return this.isCombo(t)?"combo":"node";if(this.model.hasEdge(t))return"edge";throw new Error(_c(`Unknown element type of id: ${t}`))}destroy(){const{model:t}=this,e=t.getAllNodes(),n=t.getAllEdges();t.removeEdges(n.map((t=>t.id))),t.removeNodes(e.map((t=>t.id))),this.context={}}}class mU{constructor(t){this.elementMap={},this.shapeTypeMap={},this.paletteStyle={},this.defaultStyle={},this.stateStyle={},this.visibilityCache=new WeakMap,this.context=t}init(){this.initContainer()}initContainer(){if(!this.container||this.container.destroyed){const{canvas:t}=this.context;this.container=t.appendChild(new Ul({className:"elements"}))}}emit(t,e){e.silence||rU(this.context.graph,t)}forEachElementData(t){Cd.forEach((e=>{const n=this.context.model.getElementsDataByType(e);t(e,n)}))}getElementType(t,e){var n;const{options:r,graph:i}=this.context,o=(null===(n=r[t])||void 0===n?void 0:n.type)||e.type;return o?"string"==typeof o?o:o.call(i,e):"edge"===t?"line":"circle"}getTheme(t){return jc(this.context.options)[t]||{}}getThemeStyle(t){return this.getTheme(t).style||{}}getThemeStateStyle(t,e){const{state:n={}}=this.getTheme(t);return Object.assign({},...e.map((t=>n[t]||{})))}computePaletteStyle(){const{options:t}=this.context;this.paletteStyle={},this.forEachElementData(((e,n)=>{var r,i;const o=Object.assign({},Hd(null===(r=this.getTheme(e))||void 0===r?void 0:r.palette),Hd(null===(i=t[e])||void 0===i?void 0:i.palette));(null==o?void 0:o.field)&&Object.assign(this.paletteStyle,function(t,e){if(!e)return{};const{type:n,color:r,field:i,invert:o}=e,a=t=>{const e="string"==typeof r?Dc("palette",r):r;if("function"==typeof e){const n={};return t.forEach((([t,r])=>{n[t]=e(o?1-r:r)})),n}if(Array.isArray(e)){const n=o?[...e].reverse():e,r={};return t.forEach((([t,i])=>{r[t]=n[i%e.length]})),r}return{}},s=(t,e)=>{var n;return"string"==typeof t?null===(n=e.data)||void 0===n?void 0:n[t]:null==t?void 0:t(e)};if("group"===n){const e=ie(t,(t=>{if(!i)return"default";const e=s(i,t);return e?String(e):"default"})),n=a(Object.keys(e).map(((t,e)=>[t,e]))),r={};return Object.entries(e).forEach((([t,e])=>{e.forEach((e=>{r[Nh(e)]=n[t]}))})),r}if("value"===n){const[e,n]=t.reduce((([t,e],n)=>{const r=s(i,n);if("number"!=typeof r)throw new Error(_c(`Palette field ${i} is not a number`));return[Math.min(t,r),Math.max(e,r)]}),[1/0,-1/0]),r=n-e;return a(t.map((t=>[t.id,(s(i,t)-e)/r])))}}(n,o))}))}getPaletteStyle(t,e){const n=this.paletteStyle[e];return n?"edge"===t?{stroke:n}:{fill:n}:{}}computeElementDefaultStyle(t,e){var n;const{options:r}=this.context,i=(null===(n=r[t])||void 0===n?void 0:n.style)||{};"transform"in i&&Array.isArray(i.transform)&&(i.transform=[...i.transform]),this.defaultStyle[Nh(e.datum)]=Vd(i,e)}computeElementsDefaultStyle(t){const{graph:e}=this.context;this.forEachElementData(((n,r)=>{const i=r.length;for(let o=0;othis.getElementStateStyle(t,e,n))))}computeElementsStatesStyle(t){const{graph:e}=this.context;this.forEachElementData(((n,r)=>{const i=r.length;for(let o=0;othis.elementMap[t]))}getEdges(){return this.context.model.getEdgeData().map((t=>this.elementMap[Nh(t)]))}getCombos(){return this.context.model.getComboData().map((({id:t})=>this.elementMap[t]))}getElementComputedStyle(t,e){const n=Nh(e),r=this.getThemeStyle(t),i=this.getPaletteStyle(t,n),o=e.style||{},a=this.getDefaultStyle(n),s=this.getThemeStateStyle(t,this.getElementState(n)),l=this.getStateStyle(n),u=Object.assign({},r,i,o,a,s,l);if("combo"===t){const t=this.context.model.getChildrenData(n),e=!!u.collapsed?[]:t.map(Nh).filter((t=>this.getElement(t)));Object.assign(u,{childrenNode:e,childrenData:t})}return u}getDrawData(t){this.init();const e=this.computeChangesAndDrawData(t);if(!e)return null;const{type:n="draw",stage:r=n}=t;return this.markDestroyElement(e.drawData),this.computeStyle(r),{type:n,stage:r,data:e}}draw(t={animation:!0}){const e=this.getDrawData(t);if(!e)return;const{data:{drawData:{add:n,update:r,remove:i}}}=e;return this.destroyElements(i,t),this.createElements(n,t),this.updateElements(r,t),this.setAnimationTask(t,e)}preLayoutDraw(){return ze(this,arguments,void 0,(function*(t={animation:!0}){var e,n;const r=this.getDrawData(t);if(!r)return;const{data:{drawData:i}}=r;yield null===(n=null===(e=this.context.layout)||void 0===e?void 0:e.preLayout)||void 0===n?void 0:n.call(e,i);const{add:o,update:a,remove:s}=i;return this.destroyElements(s,t),this.createElements(o,t),this.updateElements(a,t),this.setAnimationTask(t,r)}))}setAnimationTask(e,n){const{animation:r,silence:i}=e,{data:{dataChanges:o,drawData:a},stage:s,type:l}=n;return this.context.animation.animate(r,i?{}:{before:()=>this.emit(new JH(t.GraphEvent.BEFORE_DRAW,{dataChanges:o,animation:r,stage:s,render:"render"===l}),e),beforeAnimate:n=>this.emit(new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.DRAW,n,a),e),afterAnimate:n=>this.emit(new tU(t.GraphEvent.AFTER_ANIMATE,Ec.DRAW,n,a),e),after:()=>this.emit(new JH(t.GraphEvent.AFTER_DRAW,{dataChanges:o,animation:r,stage:s,render:"render"===l,firstRender:!1===this.context.graph.rendered}),e)})}computeChangesAndDrawData(t){const{model:e}=this.context,n=e.getChanges(),r=aF(n);if(0===r.length)return null;const{NodeAdded:i=[],NodeUpdated:o=[],NodeRemoved:a=[],EdgeAdded:s=[],EdgeUpdated:l=[],EdgeRemoved:u=[],ComboAdded:c=[],ComboUpdated:h=[],ComboRemoved:d=[]}=ie(r,(t=>t.type)),f=t=>new Map(t.map((t=>{const e=t.value;return[Nh(e),e]}))),p={add:{nodes:f(i),edges:f(s),combos:f(c)},update:{nodes:f(o),edges:f(l),combos:f(h)},remove:{nodes:f(a),edges:f(u),combos:f(d)}},g=this.transformData(p,t);return e.clearChanges(),{dataChanges:n,drawData:g}}transformData(t,e){const n=this.context.transform.getTransformInstance();return Object.values(n).reduce(((t,n)=>n.beforeDraw(t,e)),t)}createElement(e,n,r){var i;const o=Nh(n);if(this.getElement(o))return;const a=this.getElementType(e,n),s=this.getElementComputedStyle(e,n),l=Dc(e,a);if(!l)return Ic(`The element ${a} of ${e} is not registered.`);this.emit(new eU(t.GraphEvent.BEFORE_ELEMENT_CREATE,e,n),r);const u=this.container.appendChild(new l({id:o,context:this.context,style:s}));this.shapeTypeMap[o]=a,this.elementMap[o]=u;const{stage:c="enter"}=r;null===(i=this.context.animation)||void 0===i||i.add({element:u,elementType:e,stage:c,originalStyle:Object.assign({},u.attributes),updatedStyle:s},{after:()=>{var i;this.emit(new eU(t.GraphEvent.AFTER_ELEMENT_CREATE,e,n),r),null===(i=u.onCreate)||void 0===i||i.call(u)}})}createElements(t,e){const{nodes:n,edges:r,combos:i}=t;[["node",n],["combo",i],["edge",r]].forEach((([t,n])=>{n.forEach((n=>this.createElement(t,n,e)))}))}getUpdateStageStyle(t,e,n){const{stage:r="update"}=n;if("translate"===r){if("node"===t||"combo"===t){const{style:{x:t=0,y:n=0,z:r=0}={}}=e;return{x:t,y:n,z:r}}return{}}return this.getElementComputedStyle(t,e)}updateElement(e,n,r){var i;const o=Nh(n),{stage:a="update"}=r,s=this.getElement(o);if(!s)return()=>null;this.emit(new eU(t.GraphEvent.BEFORE_ELEMENT_UPDATE,e,n),r);const l=this.getElementType(e,n),u=this.getUpdateStageStyle(e,n,r);this.shapeTypeMap[o]!==l&&(s.destroy(),delete this.shapeTypeMap[o],delete this.elementMap[o],this.createElement(e,n,{animation:!1,silence:!0}));const c="visibility"!==a?a:"hidden"===u.visibility?"hide":"show";"hide"===c&&delete u.visibility,null===(i=this.context.animation)||void 0===i||i.add({element:s,elementType:e,stage:c,originalStyle:Object.assign({},s.attributes),updatedStyle:u},{before:()=>{const t=this.elementMap[o];"collapse"!==a&&Wg(t,u),"visibility"===a&&(function(t,e){return aU(e)in(Oe(t,oU)||{})}(t,"opacity")||function(t,e){const n=Array.isArray(e)?e:[e];Oe(t,oU)||Te(t,oU,{}),n.forEach((e=>{Te(Oe(t,oU),aU(e),t.attributes[e])}))}(t,"opacity"),this.visibilityCache.set(t,"show"===c?"visible":"hidden"),"show"===c&&Bh(t,"visible"))},after:()=>{var i;const s=this.elementMap[o];"collapse"===a&&Wg(s,u),"hide"===c&&Bh(s,this.visibilityCache.get(s)),this.emit(new eU(t.GraphEvent.AFTER_ELEMENT_UPDATE,e,n),r),null===(i=s.onUpdate)||void 0===i||i.call(s)}})}updateElements(t,e){const{nodes:n,edges:r,combos:i}=t;[["node",n],["combo",i],["edge",r]].forEach((([t,n])=>{n.forEach((n=>this.updateElement(t,n,e)))}))}markDestroyElement(t){Object.values(t.remove).forEach((t=>{t.forEach((t=>{const e=Nh(t),n=this.getElement(e);n&&function(t){Te(t,"__to_be_destroyed__",!0)}(n)}))}))}destroyElement(e,n,r){var i;const{stage:o="exit"}=r,a=Nh(n),s=this.elementMap[a];if(!s)return()=>null;this.emit(new eU(t.GraphEvent.BEFORE_ELEMENT_DESTROY,e,n),r),null===(i=this.context.animation)||void 0===i||i.add({element:s,elementType:e,stage:o,originalStyle:Object.assign({},s.attributes),updatedStyle:{}},{after:()=>{var i;this.clearElement(a),s.destroy(),null===(i=s.onDestroy)||void 0===i||i.call(s),this.emit(new eU(t.GraphEvent.AFTER_ELEMENT_DESTROY,e,n),r)}})}destroyElements(t,e){const{nodes:n,edges:r,combos:i}=t;[["combo",i],["edge",r],["node",n]].forEach((([t,n])=>{n.forEach((n=>this.destroyElement(t,n,e)))}))}clearElement(t){delete this.paletteStyle[t],delete this.defaultStyle[t],delete this.stateStyle[t],delete this.elementMap[t],delete this.shapeTypeMap[t]}alignLayoutResultToElement(t,e){var n,r;const i=null===(n=t.nodes)||void 0===n?void 0:n.find((t=>Nh(t)===e));if(i){const n=Uh(sd(this.context.model.getNodeLikeDatum(e)),sd(i));null===(r=t.nodes)||void 0===r||r.forEach((t=>{var e,r,i;(null===(e=t.style)||void 0===e?void 0:e.x)&&(t.style.x+=n[0]),(null===(r=t.style)||void 0===r?void 0:r.y)&&(t.style.y+=n[1]),(null===(i=t.style)||void 0===i?void 0:i.z)&&(t.style.z+=n[2]||0)}))}}collapseNode(e,n){return ze(this,void 0,void 0,(function*(){var r;const{animation:i,align:o}=n,{model:a,layout:s}=this.context,l=this.computeChangesAndDrawData({stage:"collapse",animation:i});if(!l)return;this.markDestroyElement(l.drawData);const u=yield s.simulate();o&&this.alignLayoutResultToElement(u,e),a.updateData(u);const c=this.computeChangesAndDrawData({stage:"collapse",animation:i});if(!c)return;const{drawData:h}=c,{add:d,remove:f,update:p}=h;this.markDestroyElement(h);const g={animation:i,stage:"collapse",data:h};this.destroyElements(f,g),this.createElements(d,g),this.updateElements(p,g),yield null===(r=this.context.animation.animate(i,{beforeAnimate:e=>this.emit(new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.COLLAPSE,e,h),g),afterAnimate:e=>this.emit(new tU(t.GraphEvent.AFTER_ANIMATE,Ec.COLLAPSE,e,h),g)},{collapse:{target:e,descendants:Array.from(f.nodes).map((([,t])=>Nh(t))),position:sd(p.nodes.get(e))}}))||void 0===r?void 0:r.finished}))}expandNode(e,n){return ze(this,void 0,void 0,(function*(){var r;const{model:i,layout:o}=this.context,{animation:a,align:s}=n,l=sd(i.getNodeData([e])[0]),u=this.computeChangesAndDrawData({stage:"expand",animation:a});if(!u)return;const{drawData:{add:c}}=u;this.createElements(c,{animation:!1,stage:"expand",target:e}),this.context.animation.clear();const h=yield o.simulate();s&&this.alignLayoutResultToElement(h,e),i.updateData(h),this.computeStyle("expand");const d=this.computeChangesAndDrawData({stage:"collapse",animation:a});if(!d)return;const{drawData:f}=d,{update:p}=f,g={animation:a,stage:"expand",data:f};c.edges.forEach((t=>p.edges.set(Nh(t),t))),c.nodes.forEach((t=>p.nodes.set(Nh(t),t))),this.updateElements(p,g),yield null===(r=this.context.animation.animate(a,{beforeAnimate:e=>this.emit(new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.EXPAND,e,f),g),afterAnimate:e=>this.emit(new tU(t.GraphEvent.AFTER_ANIMATE,Ec.EXPAND,e,f),g)},{expand:{target:e,descendants:Array.from(c.nodes).map((([,t])=>Nh(t))),position:l}}))||void 0===r?void 0:r.finished}))}collapseCombo(e,n){return ze(this,void 0,void 0,(function*(){var r;const{model:i,element:o}=this.context;if(i.getAncestorsData(e,Cc).some((t=>_d(t))))return;const a=o.getElement(e),s=a.getComboPosition(Object.assign(Object.assign({},a.attributes),{collapsed:!0})),l=this.computeChangesAndDrawData({stage:"collapse",animation:n});if(!l)return;const{dataChanges:u,drawData:c}=l;this.markDestroyElement(c);const{update:h,remove:d}=c,f={animation:n,stage:"collapse",data:c};this.destroyElements(d,f),this.updateElements(h,f);const p=t=>Array.from(t).map((([,t])=>Nh(t)));yield null===(r=this.context.animation.animate(n,{before:()=>this.emit(new JH(t.GraphEvent.BEFORE_DRAW,{dataChanges:u,animation:n}),f),beforeAnimate:e=>this.emit(new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.COLLAPSE,e,c),f),afterAnimate:e=>this.emit(new tU(t.GraphEvent.AFTER_ANIMATE,Ec.COLLAPSE,e,c),f),after:()=>this.emit(new JH(t.GraphEvent.AFTER_DRAW,{dataChanges:u,animation:n}),f)},{collapse:{target:e,descendants:[...p(d.nodes),...p(d.combos)],position:s}}))||void 0===r?void 0:r.finished}))}expandCombo(e,n){return ze(this,void 0,void 0,(function*(){var r;const{model:i}=this.context,o=sd(i.getComboData([e])[0]);this.computeStyle("expand");const a=this.computeChangesAndDrawData({stage:"expand",animation:n});if(!a)return;const{dataChanges:s,drawData:l}=a,{add:u,update:c}=l,h={animation:n,stage:"expand",data:l,target:e};this.createElements(u,h),this.updateElements(c,h);const d=t=>Array.from(t).map((([,t])=>Nh(t)));yield null===(r=this.context.animation.animate(n,{before:()=>this.emit(new JH(t.GraphEvent.BEFORE_DRAW,{dataChanges:s,animation:n}),h),beforeAnimate:e=>this.emit(new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.EXPAND,e,l),h),afterAnimate:e=>this.emit(new tU(t.GraphEvent.AFTER_ANIMATE,Ec.EXPAND,e,l),h),after:()=>this.emit(new JH(t.GraphEvent.AFTER_DRAW,{dataChanges:s,animation:n}),h)},{expand:{target:e,descendants:[...d(u.nodes),...d(u.combos)],position:o}}))||void 0===r?void 0:r.finished}))}clear(){this.container.destroy(),this.initContainer(),this.elementMap={},this.shapeTypeMap={},this.defaultStyle={},this.stateStyle={},this.paletteStyle={}}destroy(){this.clear(),this.container.destroy(),this.context={}}}class yU{get presetOptions(){return{animation:!!Gc(this.context.options,!0)}}get options(){const{options:t}=this.context;return t.layout}constructor(t){this.instances=[],this.context=t}getLayoutInstance(){return this.instances}preLayout(e){return ze(this,void 0,void 0,(function*(){var n,r,i,o;const{graph:a,model:s}=this.context,{add:l}=e;rU(a,new JH(t.GraphEvent.BEFORE_LAYOUT,{type:"pre"}));const u=yield null===(n=this.context.layout)||void 0===n?void 0:n.simulate();null===(r=null==u?void 0:u.nodes)||void 0===r||r.forEach((t=>{const e=Nh(t),n=l.nodes.get(e);s.syncNodeLikeDatum(t),n&&Object.assign(n.style,t.style)})),null===(i=null==u?void 0:u.edges)||void 0===i||i.forEach((t=>{const e=Nh(t),n=l.edges.get(e);s.syncEdgeDatum(t),n&&Object.assign(n.style,t.style)})),null===(o=null==u?void 0:u.combos)||void 0===o||o.forEach((t=>{const e=Nh(t),n=l.combos.get(e);s.syncNodeLikeDatum(t),n&&Object.assign(n.style,t.style)})),rU(a,new JH(t.GraphEvent.AFTER_LAYOUT,{type:"pre"})),this.transformDataAfterLayout("pre",e)}))}postLayout(){return ze(this,arguments,void 0,(function*(e=this.options){if(!e)return;const n=Array.isArray(e)?e:[e],{graph:r}=this.context;rU(r,new JH(t.GraphEvent.BEFORE_LAYOUT,{type:"post"}));for(let e=0;en.afterLayout(t,e)))}simulate(){return ze(this,void 0,void 0,(function*(){if(!this.options)return{};const t=Array.isArray(this.options)?this.options:[this.options];let e={};for(let n=0;n{this.updateElementPosition(t,!1)}}):(a.execute(t),a.stop(),a.tick(o));const s=yield a.execute(t);if(r){const t=this.updateElementPosition(s,r);yield null==t?void 0:t.finished}return s}))}treeLayout(t,e,n){return ze(this,void 0,void 0,(function*(){const{type:n,animation:r}=e,i=Dc("layout",n);if(!i)return{};const{nodes:o=[],edges:a=[]}=t,s=new ev({nodes:o.map((t=>({id:Nh(t),data:t.data||{}}))),edges:a.map((t=>({id:Nh(t),source:t.source,target:t.target,data:t.data||{}})))});!function(t){if(t.hasTreeStructure(Ac))return;t.attachTreeStructure(Ac);const e=t.getAllEdges();for(const n of e){const{source:e,target:r}=n;t.setParent(r,e,Ac)}}(s);const l={nodes:[],edges:[]},u={nodes:[],edges:[]};s.getRoots(Ac).forEach((t=>{Ad(t,(t=>{t.children=s.getSuccessors(t.id)}),(t=>s.getSuccessors(t.id)),"TB");const n=i(t,e),{x:r,y:o,z:a=0}=n;Ad(n,(t=>{const{id:e,x:n,y:i,z:s=0}=t;l.nodes.push({id:e,style:{x:r,y:o,z:a}}),u.nodes.push({id:e,style:{x:n,y:i,z:s}})}),(t=>t.children),"TB")}));const c=this.inferTreeLayoutOffset(u);if(bU(u,c),r){bU(l,c),this.updateElementPosition(l,!1);const t=this.updateElementPosition(u,r);yield null==t?void 0:t.finished}return u}))}inferTreeLayoutOffset(t){var e;let[n,r]=[1/0,-1/0],[i,o]=[1/0,-1/0];null===(e=t.nodes)||void 0===e||e.forEach((t=>{const{x:e=0,y:a=0}=t.style||{};n=Math.min(n,e),r=Math.max(r,e),i=Math.min(i,a),o=Math.max(o,a)}));const{canvas:a}=this.context,s=a.getSize(),[l,u]=a.getCanvasByViewport([0,0]),[c,h]=a.getCanvasByViewport(s);if(n>=l&&r<=c&&i>=u&&o<=h)return[0,0];return[(l+c)/2-(n+r)/2,(u+h)/2-(i+o)/2]}stopLayout(){this.instance&&aE(this.instance)&&(this.instance.stop(),this.instance=void 0),this.supervisor&&(this.supervisor.stop(),this.supervisor=void 0),this.animationResult&&(this.animationResult.finish(),this.animationResult=void 0)}getLayoutData(t){const{nodeFilter:e=()=>!0,preLayout:n=!1,isLayoutInvisibleNodes:r=!1}=t,{nodes:i,edges:o,combos:a}=this.context.model.getData(),{element:s,model:l}=this.context,u=t=>s.getElement(t),c=n?t=>{var n;if(!r){if("hidden"===(null===(n=t.style)||void 0===n?void 0:n.visibility))return!1;if(l.getAncestorsData(t.id,Ac).some(_d))return!1;if(l.getAncestorsData(t.id,Cc).some(_d))return!1}return e(t)}:t=>{const n=Nh(t),r=u(n);return!!r&&(!Hg(r)&&e(t))},h=i.filter(c),d=new Map(h.map((t=>[Nh(t),t])));a.forEach((t=>d.set(Nh(t),t)));return{nodes:h,edges:o.filter((({source:t,target:e})=>d.has(t)&&d.has(e))),combos:a}}initGraphLayout(t){var e;const{element:n,viewport:r}=this.context,{type:i,enableWorker:o,animation:a,iterations:s}=t,l=Fe(t,["type","enableWorker","animation","iterations"]),[u,c]=r.getCanvasSize(),h=[u/2,c/2],d=null!==(e=null==t?void 0:t.nodeSize)&&void 0!==e?e:t=>{const e=null==n?void 0:n.getElement(t.id);return e?e.attributes.size:null==n?void 0:n.getElementComputedStyle("node",t).size},f=Dc("layout",i);if(!f)return Ic(`The layout of ${i} is not registered.`);const p=Object.getPrototypeOf(f.prototype)===nv.prototype?f:function(t,e){return class extends nv{constructor(e,n){if(super(e,n),this.instance=new t({}),this.id=this.instance.id,"stop"in this.instance&&"tick"in this.instance){const t=this.instance;this.stop=t.stop.bind(t),this.tick=e=>rv(t.tick(e))}}execute(t,e){return ze(this,void 0,void 0,(function*(){return rv(yield this.instance.execute(this.graphData2LayoutModel(t),this.transformOptions(ke({},this.options,e))))}))}transformOptions(t){const{onTick:e}=t;return e?(t.onTick=t=>e(rv(t)),t):t}graphData2LayoutModel(t){const{nodes:n=[],edges:r=[],combos:i=[]}=t,o=n.map((t=>{const e=Nh(t),{data:n,style:r,combo:i}=t,o=Fe(t,["data","style","combo"]),a={id:e,data:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},n),{data:n}),i?{parentId:i}:{}),{style:r}),o)};return(null==r?void 0:r.x)&&Object.assign(a.data,{x:r.x}),(null==r?void 0:r.y)&&Object.assign(a.data,{y:r.y}),(null==r?void 0:r.z)&&Object.assign(a.data,{z:r.z}),a})),a=new Map(o.map((t=>[t.id,t]))),s=r.filter((t=>{const{source:e,target:n}=t;return a.has(e)&&a.has(n)})).map((t=>{const{source:e,target:n,data:r,style:i}=t;return{id:Nh(t),source:e,target:n,data:Object.assign({},r),style:Object.assign({},i)}})),l=i.map((t=>({id:Nh(t),data:Object.assign({_isCombo:!0},t.data),style:Object.assign({},t.style)}))),u=new ev({nodes:[...o,...l],edges:s});return e.model.model.hasTreeStructure(Cc)&&(u.attachTreeStructure(Cc),o.forEach((t=>{const n=e.model.model.getParent(t.id,Cc);n&&u.hasNode(n.id)&&u.setParent(t.id,n.id,Cc)}))),u}}}(f,this.context),g=new p(this.context),v={nodeSize:d,width:u,height:c,center:h};switch(g.id){case"d3-force":case"d3-force-3d":Object.assign(v,{center:{x:u/2,y:c/2,z:0}})}return ke(g.options,v,l),g}updateElementPosition(t,e){const{model:n,element:r}=this.context;return r?(n.updateData(t),r.draw({animation:e,silence:!0})):null}destroy(){var t;this.stopLayout(),this.context={},null===(t=this.supervisor)||void 0===t||t.kill(),this.supervisor=void 0,this.instance=void 0,this.instances=[],this.animationResult=void 0}}const bU=(t,e)=>{var n;const[r,i]=e;null===(n=t.nodes)||void 0===n||n.forEach((t=>{if(t.style){const{x:e=0,y:n=0}=t.style;t.style.x=e+r,t.style.y=n+i}else t.style={x:r,y:i}}))};function xU(t){return t.layout?(Array.isArray(t.layout)||"preLayout"in t.layout||["antv-dagre","combo-combined","compact-box","circular","concentric","dagre","fishbone","grid","indented","mds","radial","random","snake","dendrogram","mindmap"].includes(t.layout.type)&&(t.layout.preLayout=!0),t):t}class EU extends Fh{constructor(t){super(t),this.category="plugin",this.setPlugins(this.context.options.plugins||[])}setPlugins(t){this.setExtensions(t)}getPluginInstance(t){const e=this.extensionMap[t];if(e)return e;Ic(`Cannot find the plugin ${t}, will try to find it by type.`);const n=this.extensions.find((e=>e.type===t));return n?this.extensionMap[n.key]:void 0}}const wU=["update-related-edges","collapse-expand-node","collapse-expand-combo","get-edge-actual-ends","arrange-draw-order"];class kU extends Fh{constructor(t){super(t),this.category="transform",this.setTransforms(this.context.options.transforms||[])}getTransforms(){}setTransforms(t){this.setExtensions([...wU.slice(0,wU.length-1),...t,wU[wU.length-1]])}getTransformInstance(t){return t?this.extensionMap[t]:this.extensionMap}}class MU{get padding(){return Jc(this.context.options.padding)}get paddingOffset(){const[t,e,n,r]=this.padding,[i,o,a]=[(r-e)/2,(t-n)/2,0];return[i,o,a]}constructor(t){this.landmarkCounter=0,this.context=t;const[e,n]=this.paddingOffset,{zoom:r,rotation:i,x:o=e,y:a=n}=t.options;this.transform({mode:"absolute",scale:r,translate:[o,a],rotate:i},!1)}get camera(){const{canvas:t}=this.context;return new Proxy(t.getCamera(),{get:(e,n)=>{const r=Object.entries(t.getLayers()).filter((([t])=>!["main"].includes(t))),i=r.map((([,t])=>t.getCamera())),o=e[n];if("function"==typeof o)return(...t)=>{const r=o.apply(e,t);return i.forEach((e=>{e[n].apply(e,t)})),r}}})}createLandmark(t){return this.camera.createLandmark("landmark-"+this.landmarkCounter++,t)}getAnimation(t){const e=Gc(this.context.options,t);return!!e&&Ae(Object.assign({},e),["easing","duration"])}getCanvasSize(){const{canvas:t}=this.context,{width:e=0,height:n=0}=t.getConfig();return[e,n]}getCanvasCenter(){const{canvas:t}=this.context,{width:e=0,height:n=0}=t.getConfig();return[e/2,n/2,0]}getViewportCenter(){const[t,e]=this.camera.getPosition();return[t,e,0]}getGraphCenter(){return this.context.graph.getViewportByCanvas(this.getCanvasCenter())}getZoom(){return this.camera.getZoom()}getRotation(){return this.camera.getRoll()}getTranslateOptions(t){const{camera:e}=this,{mode:n,translate:r=[]}=t,i=this.getZoom(),o=e.getPosition(),a=e.getFocalPoint(),[s,l]=this.getCanvasCenter(),[u=0,c=0,h=0]=r,d=Yh([-u,-c,-h],i);return"relative"===n?{position:Hh(o,d),focalPoint:Hh(a,d)}:{position:Hh([s,l,o[2]],d),focalPoint:Hh([s,l,a[2]],d)}}getRotateOptions(t){const{mode:e,rotate:n=0}=t;return{roll:"relative"===e?this.camera.getRoll()+n:n}}getZoomOptions(t){const{zoomRange:e}=this.context.options,n=this.camera.getZoom(),{mode:r,scale:i=1}=t;return oe("relative"===r?n*i:i,...e)}transform(e,n){return ze(this,void 0,void 0,(function*(){const{graph:r}=this.context,{translate:i,rotate:o,scale:a,origin:s}=e;this.cancelAnimation();const l=this.getAnimation(n);if(rU(r,new nU(t.GraphEvent.BEFORE_TRANSFORM,e)),!o&&a&&!i&&s&&!l)return this.camera.setZoomByViewportPoint(this.getZoomOptions(e),s),void rU(r,new nU(t.GraphEvent.AFTER_TRANSFORM,e));const u={};if(i&&Object.assign(u,this.getTranslateOptions(e)),ae(o)&&Object.assign(u,this.getRotateOptions(e)),ae(a)&&Object.assign(u,{zoom:this.getZoomOptions(e)}),l)return rU(r,new tU(t.GraphEvent.BEFORE_ANIMATE,Ec.TRANSFORM,null,e)),new Promise((n=>{this.transformResolver=n,this.camera.gotoLandmark(this.createLandmark(u),Object.assign(Object.assign({},l),{onfinish:()=>{rU(r,new tU(t.GraphEvent.AFTER_ANIMATE,Ec.TRANSFORM,null,e)),rU(r,new nU(t.GraphEvent.AFTER_TRANSFORM,e)),this.transformResolver=void 0,n()}}))}));this.camera.gotoLandmark(this.createLandmark(u),{duration:0}),rU(r,new nU(t.GraphEvent.AFTER_TRANSFORM,e))}))}fitView(t,e){return ze(this,void 0,void 0,(function*(){const[n,r,i,o]=this.padding,{when:a="always",direction:s="both"}=t||{},[l,u]=this.context.canvas.getSize(),c=l-o-r,h=u-n-i,d=this.context.canvas.getBounds(),f=this.getBBoxInViewport(d),[p,g]=rh(f);if("overflow"===a&&!("x"===s&&p>=c||"y"===s&&g>=h||"both"===s&&p>=c&&g>=h))return yield this.fitCenter({animation:e});const v=c/p,m=h/g,y="x"===s?v:"y"===s?m:Math.min(v,m),b=this.getAnimation(e);yield this.transform({mode:"relative",scale:y,translate:Hh(Uh(this.getCanvasCenter(),this.getBBoxInViewport(d).center),Yh(this.paddingOffset,y))},b)}))}fitCenter(t){return ze(this,void 0,void 0,(function*(){const e=this.context.canvas.getBounds();yield this.focus(e,t)}))}focusElements(t){return ze(this,arguments,void 0,(function*(t,e={}){const{element:n}=this.context;if(!n)return;const r=sh(t.map((t=>{return r=n.getElement(t),e.shapes?r.getShape(e.shapes).getRenderBounds():r.getRenderBounds();var r})));yield this.focus(r,e)}))}focus(t,e){return ze(this,void 0,void 0,(function*(){const n=this.context.graph.getViewportByCanvas(t.center),r=Uh(e.position||this.getCanvasCenter(),n);yield this.transform({mode:"relative",translate:Hh(r,this.paddingOffset)},e.animation)}))}getBBoxInViewport(t){const{min:e,max:n}=t,{graph:r}=this.context,[i,o]=r.getViewportByCanvas(e),[a,s]=r.getViewportByCanvas(n),l=new Er;return l.setMinMax([i,o,0],[a,s,0]),l}isInViewport(t,e=!1,n=0){const{graph:r}=this.context,i=this.getCanvasSize(),[o,a]=r.getCanvasByViewport([0,0]),[s,l]=r.getCanvasByViewport(i);let u=new Er;return u.setMinMax([o,a,0],[s,l,0]),n&&(u=ah(u,n)),Zc(t)?lh(t,u):e?function(t,e){const[n,r]=t.min,[i,o]=t.max,[a,s]=e.min,[l,u]=e.max;return n>=a&&i<=l&&r>=s&&o<=u}(t,u):u.intersects(t)}cancelAnimation(){var t,e;(null===(t=this.camera.landmarks)||void 0===t?void 0:t.length)&&this.camera.cancelLandmarkAnimation(),null===(e=this.transformResolver)||void 0===e||e.call(this)}}class SU extends Kg{constructor(t){var e;super(),this.options={},this.rendered=!1,this.destroyed=!1,this.context={model:new vU},this.isCollapsingExpanding=!1,this.onResize=ye((()=>{this.resize()}),300),this._setOptions(Object.assign({},SU.defaultOptions,t),!0),this.context.graph=this,this.options.autoResize&&(null===(e=globalThis.addEventListener)||void 0===e||e.call(globalThis,"resize",this.onResize))}getOptions(){return this.options}setOptions(t){this._setOptions(t,!1)}_setOptions(t,e){if(this.updateCanvas(t),Object.assign(this.options,function(t){return[xU].reduce(((t,e)=>e(t)),t)}(t)),e){const{data:e}=t;return void(e&&this.addData(e))}const{behaviors:n,combo:r,data:i,edge:o,layout:a,node:s,plugins:l,theme:u,transforms:c}=t;n&&this.setBehaviors(n),i&&this.setData(i),s&&this.setNode(s),o&&this.setEdge(o),r&&this.setCombo(r),a&&this.setLayout(a),u&&this.setTheme(u),l&&this.setPlugins(l),c&&this.setTransforms(c)}getSize(){return this.context.canvas?this.context.canvas.getSize():[this.options.width||0,this.options.height||0]}setSize(t,e){t&&(this.options.width=t),e&&(this.options.height=e),this.resize(t,e)}setZoomRange(t){this.options.zoomRange=t}getZoomRange(){return this.options.zoomRange}setNode(t){this.options.node=t,this.context.model.refreshData()}setEdge(t){this.options.edge=t,this.context.model.refreshData()}setCombo(t){this.options.combo=t,this.context.model.refreshData()}getTheme(){return this.options.theme}setTheme(t){this.options.theme=Ut(t)?t(this.getTheme()):t}setLayout(t){this.options.layout=Ut(t)?t(this.getLayout()):t}getLayout(){return this.options.layout}setBehaviors(t){var e;this.options.behaviors=Ut(t)?t(this.getBehaviors()):t,null===(e=this.context.behavior)||void 0===e||e.setBehaviors(this.options.behaviors)}updateBehavior(t){this.setBehaviors((e=>e.map((e=>"object"==typeof e&&e.key===t.key?Object.assign(Object.assign({},e),t):e))))}getBehaviors(){return this.options.behaviors||[]}setPlugins(t){var e;this.options.plugins=Ut(t)?t(this.getPlugins()):t,null===(e=this.context.plugin)||void 0===e||e.setPlugins(this.options.plugins)}updatePlugin(t){this.setPlugins((e=>e.map((e=>"object"==typeof e&&e.key===t.key?Object.assign(Object.assign({},e),t):e))))}getPlugins(){return this.options.plugins||[]}getPluginInstance(t){return this.context.plugin.getPluginInstance(t)}setTransforms(t){var e;this.options.transforms=Ut(t)?t(this.getTransforms()):t,null===(e=this.context.transform)||void 0===e||e.setTransforms(this.options.transforms)}updateTransform(t){this.setTransforms((e=>e.map((e=>"object"==typeof e&&e.key===t.key?Object.assign(Object.assign({},e),t):e)))),this.context.model.refreshData()}getTransforms(){return this.options.transforms||[]}getData(){return this.context.model.getData()}getElementData(t){return Array.isArray(t)?t.map((t=>this.context.model.getElementDataById(t))):this.context.model.getElementDataById(t)}getNodeData(t){return void 0===t?this.context.model.getNodeData():Array.isArray(t)?this.context.model.getNodeData(t):this.context.model.getNodeLikeDatum(t)}getEdgeData(t){return void 0===t?this.context.model.getEdgeData():Array.isArray(t)?this.context.model.getEdgeData(t):this.context.model.getEdgeDatum(t)}getComboData(t){return void 0===t?this.context.model.getComboData():Array.isArray(t)?this.context.model.getComboData(t):this.context.model.getNodeLikeDatum(t)}setData(t){this.context.model.setData(Ut(t)?t(this.getData()):t)}addData(t){this.context.model.addData(Ut(t)?t(this.getData()):t)}addNodeData(t){this.context.model.addNodeData(Ut(t)?t(this.getNodeData()):t)}addEdgeData(t){this.context.model.addEdgeData(Ut(t)?t(this.getEdgeData()):t)}addComboData(t){this.context.model.addComboData(Ut(t)?t(this.getComboData()):t)}addChildrenData(t,e){this.context.model.addChildrenData(t,e)}updateData(t){this.context.model.updateData(Ut(t)?t(this.getData()):t)}updateNodeData(t){this.context.model.updateNodeData(Ut(t)?t(this.getNodeData()):t)}updateEdgeData(t){this.context.model.updateEdgeData(Ut(t)?t(this.getEdgeData()):t)}updateComboData(t){this.context.model.updateComboData(Ut(t)?t(this.getComboData()):t)}removeData(t){this.context.model.removeData(Ut(t)?t(this.getData()):t)}removeNodeData(t){this.context.model.removeNodeData(Ut(t)?t(this.getNodeData()):t)}removeEdgeData(t){this.context.model.removeEdgeData(Ut(t)?t(this.getEdgeData()):t)}removeComboData(t){this.context.model.removeComboData(Ut(t)?t(this.getComboData()):t)}getElementType(t){return this.context.model.getElementType(t)}getRelatedEdgesData(t,e="both"){return this.context.model.getRelatedEdgesData(t,e)}getNeighborNodesData(t){return this.context.model.getNeighborNodesData(t)}getAncestorsData(t,e){return this.context.model.getAncestorsData(t,e)}getParentData(t,e){return this.context.model.getParentData(t,e)}getChildrenData(t){return this.context.model.getChildrenData(t)}getDescendantsData(t){return this.context.model.getDescendantsData(t)}getElementDataByState(t,e){return this.context.model.getElementDataByState(t,e)}initCanvas(){return ze(this,void 0,void 0,(function*(){var e;if(this.context.canvas)return yield this.context.canvas.ready;const{container:n="container",width:r,height:i,renderer:o,cursor:a,background:s,canvas:l,devicePixelRatio:u=(null!==(e=globalThis.devicePixelRatio)&&void 0!==e?e:1)}=this.options;if(n instanceof YH)this.context.canvas=n,a&&n.setCursor(a),o&&n.setRenderer(o),yield n.ready;else{const e=ne(n)?document.getElementById(n):n,c=ZH(e);this.emit(t.GraphEvent.BEFORE_CANVAS_INIT,{container:e,width:r,height:i});const h=Object.assign(Object.assign({},l),{container:e,width:r||c[0],height:i||c[1],background:s,renderer:o,cursor:a,devicePixelRatio:u}),d=new YH(h);this.context.canvas=d,yield d.ready,this.emit(t.GraphEvent.AFTER_CANVAS_INIT,{canvas:d})}}))}updateCanvas(e){var n,r;const{renderer:i,cursor:o,height:a,width:s}=e,l=this.context.canvas;l&&(i&&(this.emit(t.GraphEvent.BEFORE_RENDERER_CHANGE,{renderer:this.options.renderer}),l.setRenderer(i),this.emit(t.GraphEvent.AFTER_RENDERER_CHANGE,{renderer:i})),o&&l.setCursor(o),(ae(s)||ae(a))&&this.setSize(null!==(n=null!=s?s:this.options.width)&&void 0!==n?n:0,null!==(r=null!=a?a:this.options.height)&&void 0!==r?r:0))}initRuntime(){this.context.options=this.options,this.context.batch||(this.context.batch=new uU(this.context)),this.context.plugin||(this.context.plugin=new EU(this.context)),this.context.viewport||(this.context.viewport=new MU(this.context)),this.context.transform||(this.context.transform=new kU(this.context)),this.context.element||(this.context.element=new mU(this.context)),this.context.animation||(this.context.animation=new lU(this.context)),this.context.layout||(this.context.layout=new yU(this.context)),this.context.behavior||(this.context.behavior=new cU(this.context))}prepare(){return ze(this,void 0,void 0,(function*(){yield Promise.resolve(),this.destroyed?console.error(_c("The graph instance has been destroyed")):(yield this.initCanvas(),this.initRuntime())}))}render(){return ze(this,void 0,void 0,(function*(){if(yield this.prepare(),rU(this,new JH(t.GraphEvent.BEFORE_RENDER)),this.options.layout)if(this.rendered||(e=this.options.layout,Array.isArray(e)||!(null==e?void 0:e.preLayout))){const t=this.context.element.draw({type:"render"});yield Promise.all([null==t?void 0:t.finished,this.context.layout.postLayout()]),yield this.autoFit()}else{const t=yield this.context.element.preLayoutDraw({type:"render"});yield Promise.all([null==t?void 0:t.finished,this.autoFit()])}else{const t=this.context.element.draw({type:"render"});yield Promise.all([null==t?void 0:t.finished,this.autoFit()])}var e;this.rendered=!0,rU(this,new JH(t.GraphEvent.AFTER_RENDER))}))}draw(){return ze(this,void 0,void 0,(function*(){var t;yield this.prepare(),yield null===(t=this.context.element.draw())||void 0===t?void 0:t.finished}))}layout(t){return ze(this,void 0,void 0,(function*(){yield this.context.layout.postLayout(t)}))}stopLayout(){this.context.layout.stopLayout()}clear(){return ze(this,void 0,void 0,(function*(){const{model:t,element:e}=this.context;t.setData({}),t.clearChanges(),null==e||e.clear()}))}destroy(){var e;rU(this,new JH(t.GraphEvent.BEFORE_DESTROY));const{layout:n,animation:r,element:i,model:o,canvas:a,behavior:s,plugin:l}=this.context;null==l||l.destroy(),null==s||s.destroy(),null==n||n.destroy(),null==r||r.destroy(),null==i||i.destroy(),o.destroy(),null==a||a.destroy(),this.options={},this.context={},this.off(),null===(e=globalThis.removeEventListener)||void 0===e||e.call(globalThis,"resize",this.onResize),this.destroyed=!0,rU(this,new JH(t.GraphEvent.AFTER_DESTROY))}getCanvas(){return this.context.canvas}resize(e,n){var r;const i=ZH(null===(r=this.context.canvas)||void 0===r?void 0:r.getContainer()),o=[e||i[0],n||i[1]];if(!this.context.canvas)return;const a=this.context.canvas.getSize();Ne(o,a)||(rU(this,new JH(t.GraphEvent.BEFORE_SIZE_CHANGE,{size:o})),this.context.canvas.resize(...o),rU(this,new JH(t.GraphEvent.AFTER_SIZE_CHANGE,{size:o})))}fitView(t,e){return ze(this,void 0,void 0,(function*(){var n;yield null===(n=this.context.viewport)||void 0===n?void 0:n.fitView(t,e)}))}fitCenter(t){return ze(this,void 0,void 0,(function*(){var e;yield null===(e=this.context.viewport)||void 0===e?void 0:e.fitCenter({animation:t})}))}autoFit(){return ze(this,void 0,void 0,(function*(){const{autoFit:t}=this.context.options;if(t)if(ne(t))"view"===t?yield this.fitView():"center"===t&&(yield this.fitCenter());else{const{type:e,animation:n}=t;"view"===e?yield this.fitView(t.options,n):"center"===e&&(yield this.fitCenter(n))}}))}focusElement(t,e){return ze(this,void 0,void 0,(function*(){var n;yield null===(n=this.context.viewport)||void 0===n?void 0:n.focusElements(Array.isArray(t)?t:[t],{animation:e})}))}zoomBy(t,e,n){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"relative",scale:t,origin:n},e)}))}zoomTo(t,e,n){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"absolute",scale:t,origin:n},e)}))}getZoom(){return this.context.viewport.getZoom()}rotateBy(t,e,n){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"relative",rotate:t,origin:n},e)}))}rotateTo(t,e,n){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"absolute",rotate:t,origin:n},e)}))}getRotation(){return this.context.viewport.getRotation()}translateBy(t,e){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"relative",translate:t},e)}))}translateTo(t,e){return ze(this,void 0,void 0,(function*(){yield this.context.viewport.transform({mode:"absolute",translate:t},e)}))}getPosition(){return Uh([0,0],this.getCanvasByViewport([0,0]))}translateElementBy(t,e){return ze(this,arguments,void 0,(function*(t,e,n=!0){var r,i;const[o,a]=qt(t)?[t,null===(r=e)||void 0===r||r]:[{[t]:e},n];Object.entries(o).forEach((([t,e])=>this.context.model.translateNodeLikeBy(t,e))),yield null===(i=this.context.element.draw({animation:a,stage:"translate"}))||void 0===i?void 0:i.finished}))}translateElementTo(t,e){return ze(this,arguments,void 0,(function*(t,e,n=!0){var r,i;const[o,a]=qt(t)?[t,null===(r=e)||void 0===r||r]:[{[t]:e},n];Object.entries(o).forEach((([t,e])=>this.context.model.translateNodeLikeTo(t,e))),yield null===(i=this.context.element.draw({animation:a,stage:"translate"}))||void 0===i?void 0:i.finished}))}getElementPosition(t){return this.context.model.getElementPosition(t)}getElementRenderStyle(t){return Pe(this.context.element.getElement(t).attributes,["context"])}setElementVisibility(t,e){return ze(this,arguments,void 0,(function*(t,e,n=!0){var r,i;const[o,a]=qt(t)?[t,null===(r=e)||void 0===r||r]:[{[t]:e},n],s={nodes:[],edges:[],combos:[]};Object.entries(o).forEach((([t,e])=>{const n=this.getElementType(t);s[`${n}s`].push({id:t,style:{visibility:e}})}));const{model:l,element:u}=this.context;l.preventUpdateNodeLikeHierarchy((()=>{l.updateData(s)})),yield null===(i=u.draw({animation:a,stage:"visibility"}))||void 0===i?void 0:i.finished}))}showElement(t,e){return ze(this,void 0,void 0,(function*(){const n=Array.isArray(t)?t:[t];yield this.setElementVisibility(Object.fromEntries(n.map((t=>[t,"visible"]))),e)}))}hideElement(t,e){return ze(this,void 0,void 0,(function*(){const n=Array.isArray(t)?t:[t];yield this.setElementVisibility(Object.fromEntries(n.map((t=>[t,"hidden"]))),e)}))}getElementVisibility(t){var e,n;const r=this.context.element.getElement(t);return null!==(n=null===(e=null==r?void 0:r.style)||void 0===e?void 0:e.visibility)&&void 0!==n?n:"visible"}setElementZIndex(t,e){return ze(this,void 0,void 0,(function*(){var n;const r={nodes:[],edges:[],combos:[]},i=qt(t)?t:{[t]:e};Object.entries(i).forEach((([t,e])=>{const n=this.getElementType(t);r[`${n}s`].push({id:t,style:{zIndex:e}})}));const{model:o,element:a}=this.context;o.preventUpdateNodeLikeHierarchy((()=>o.updateData(r))),yield null===(n=a.draw({animation:!1,stage:"zIndex"}))||void 0===n?void 0:n.finished}))}frontElement(t){return ze(this,void 0,void 0,(function*(){const e=Array.isArray(t)?t:[t],{model:n}=this.context,r={};e.map((t=>{const e=n.getFrontZIndex(t);if("combo"===n.getElementType(t)){const i=n.getAncestorsData(t,Cc).at(-1)||this.getComboData(t),o=[i,...n.getDescendantsData(Nh(i))],a=e-iU(i);o.forEach((t=>{r[Nh(t)]=this.getElementZIndex(Nh(t))+a}));const{internal:s}=lg(o.map(Nh),(t=>n.getRelatedEdgesData(t)));s.forEach((t=>{const e=Nh(t);r[e]=this.getElementZIndex(e)+a}))}else r[t]=e})),yield this.setElementZIndex(r)}))}getElementZIndex(t){return iU(this.context.model.getElementDataById(t))}setElementState(t,e){return ze(this,arguments,void 0,(function*(t,e,n=!0){var r,i;const[o,a]=qt(t)?[t,null===(r=e)||void 0===r||r]:[{[t]:e},n],s={nodes:[],edges:[],combos:[]};Object.entries(o).forEach((([t,e])=>{const n=this.getElementType(t);var r;s[`${n}s`].push({id:t,states:(r=e,r?Array.isArray(r)?r:[r]:[])})})),this.updateData(s),yield null===(i=this.context.element.draw({animation:a,stage:"state"}))||void 0===i?void 0:i.finished}))}getElementState(t){return this.context.model.getElementState(t)}getElementRenderBounds(t){return this.context.element.getElement(t).getRenderBounds()}collapseElement(t){return ze(this,arguments,void 0,(function*(t,e=!0){const{model:n,element:r}=this.context;if(_d(n.getNodeLikeData([t])[0]))return;if(this.isCollapsingExpanding)return;"boolean"==typeof e&&(e={animation:e,align:!0});const i=n.getElementType(t);yield this.frontElement(t),this.isCollapsingExpanding=!0,this.setElementCollapsibility(t,!0),"node"===i?yield r.collapseNode(t,e):"combo"===i&&(yield r.collapseCombo(t,!!e.animation)),this.isCollapsingExpanding=!1}))}expandElement(t){return ze(this,arguments,void 0,(function*(t,e=!0){const{model:n,element:r}=this.context;if(!_d(n.getNodeLikeData([t])[0]))return;if(this.isCollapsingExpanding)return;"boolean"==typeof e&&(e={animation:e,align:!0});const i=n.getElementType(t);this.isCollapsingExpanding=!0,this.setElementCollapsibility(t,!1),"node"===i?yield r.expandNode(t,e):"combo"===i&&(yield r.expandCombo(t,!!e.animation)),this.isCollapsingExpanding=!1}))}setElementCollapsibility(t,e){const n=this.getElementType(t);"node"===n?this.updateNodeData([{id:t,style:{collapsed:e}}]):"combo"===n&&this.updateComboData([{id:t,style:{collapsed:e}}])}toDataURL(){return ze(this,arguments,void 0,(function*(t={}){return this.context.canvas.toDataURL(t)}))}getCanvasByViewport(t){return this.context.canvas.getCanvasByViewport(t)}getViewportByCanvas(t){return this.context.canvas.getViewportByCanvas(t)}getClientByCanvas(t){return this.context.canvas.getClientByCanvas(t)}getCanvasByClient(t){return this.context.canvas.getCanvasByClient(t)}getViewportCenter(){return this.context.viewport.getViewportCenter()}getCanvasCenter(){return this.context.viewport.getCanvasCenter()}on(t,e,n){return super.on(t,e,n)}once(t,e){return super.once(t,e)}off(t,e){return super.off(t,e)}}SU.defaultOptions={autoResize:!1,theme:"light",rotation:0,zoom:1,zoomRange:[.01,10]};const NU=(t,e)=>{const{source:n,target:r}=e,i=t.getElementDataById(n),o=t.getElementDataById(r),a=ug(i,(e=>t.getParentData(e,Cc))),s=ug(o,(e=>t.getParentData(e,Cc))),l={sourceNode:Nh(a),targetNode:Nh(s)};return e.style?Object.assign(e.style,l):e.style=l,e};class OU extends IH{constructor(t,e){super(t,ke({},OU.defaultOptions,e)),this.assignSizeByCentrality=(t,e,n,r,i,o)=>{const a=[e,n],s=[r[0],i[0]],l=[r[1],i[1]],u=[r[2],i[2]],c=(t,e)=>{if("function"==typeof o)return o(t,a,e);switch(o){case"linear":return((t,e,n)=>{const[r,i]=e,[o,a]=n;return i===r?o:o+(t-r)/(i-r)*(a-o)})(t,a,e);case"log":return((t,e,n)=>{const[r,i]=e,[o,a]=n;return o+Math.log(t-r+1)/Math.log(i-r+1)*(a-o)})(t,a,e);case"pow":return((t,e,n,r=2)=>{const[i,o]=e,[a,s]=n;return a+Math.pow((t-i)/(o-i),r)*(s-a)})(t,a,e,2);case"sqrt":return((t,e,n)=>{const[r,i]=e,[o,a]=n;return o+Math.sqrt((t-r)/(i-r))*(a-o)})(t,a,e);default:return e[0]}};return[c(t,s),c(t,l),c(t,u)]}}beforeDraw(t){const{model:e}=this.context,n=e.getNodeData(),r=Gd(this.options.maxSize),i=Gd(this.options.minSize),o=this.getCentralities(this.options.centrality),a=o.size>0?Math.max(...o.values()):0,s=o.size>0?Math.min(...o.values()):0;return n.forEach((e=>{var n;const l=this.assignSizeByCentrality(o.get(Nh(e))||0,s,a,i,r,this.options.scale),u=null===(n=this.context.element)||void 0===n?void 0:n.getElement(Nh(e)),c={size:l};this.assignLabelStyle(c,l,e,u),u&&BH(c,u.attributes)||jH(t,u?"update":"add","node",ke(e,{style:c}),!0)})),t}assignLabelStyle(t,e,n,r){var i;const o=r?r.config.style:null===(i=this.context.element)||void 0===i?void 0:i.getElementComputedStyle("node",n);if(Object.assign(t,Ae(o,["labelFontSize","labelLineHeight"])),this.options.mapLabelSize){const n=this.getLabelSizeByNodeSize(e,1/0,Number(t.labelFontSize));Object.assign(t,{labelFontSize:n,labelLineHeight:n+th(t.labelPadding)})}return t}getLabelSizeByNodeSize(t,e,n){const r=Math.min(...t)/2,[i,o]=Array.isArray(this.options.mapLabelSize)?this.options.mapLabelSize:[n,e];return Math.min(o,Math.max(r,i))}getCentralities(t){const{model:e}=this.context,n=e.getData();if("function"==typeof t)return t(n);const r=e.getRelatedEdgesData.bind(e);return Ch(n,r,t)}}OU.defaultOptions={centrality:{type:"degree"},maxSize:80,minSize:20,scale:"linear",mapLabelSize:!1};class TU extends IH{constructor(t,e){super(t,Object.assign({},TU.defaultOptions,e))}get ref(){return this.context.model.getRootsData()[0]}afterLayout(){var t;const e=sd(this.ref),{graph:n,model:r}=this.context;null===(t=r.getData().nodes)||void 0===t||t.forEach((t=>{var i;if(Nh(t)===Nh(this.ref))return;const o=rd(Uh(sd(t),e)),a=Math.abs(o)>Math.PI/2,s=!t.children||0===t.children.length,l=Nh(t),u=null===(i=this.context.element)||void 0===i?void 0:i.getElement(l);if(!u||!u.isVisible())return;const c=(s?1:-1)*(Gd(n.getElementRenderStyle(l).size)[0]/2+this.options.offset),h=[["translate",c*Math.cos(o),c*Math.sin(o)],["rotate",a?_r(o)+180:_r(o)]];r.updateNodeData([{id:Nh(t),style:{labelTextAlign:a===s?"right":"left",labelTextBaseline:"middle",labelTransform:h}}])})),n.draw()}}TU.defaultOptions={offset:5};const CU=["top","top-right","right","right-bottom","bottom","bottom-left","left","left-top"];class AU extends IH{constructor(t,e){super(t,Object.assign({},AU.defaultOptions,e)),this.cacheMergeStyle=new Map,this.getAffectedParallelEdges=t=>{const{add:{edges:e},update:{nodes:n,edges:r,combos:i},remove:{edges:o}}=t,{model:a}=this.context,s=new Map,l=(t,e)=>{a.getRelatedEdgesData(e).forEach((t=>!s.has(Nh(t))&&s.set(Nh(t),t)))};n.forEach(l),i.forEach(l);const u=t=>{const e=a.getEdgeData().map((t=>NU(a,t)));RU(t,e).forEach((t=>!s.has(Nh(t))&&s.set(Nh(t),t)))};if(o.size&&o.forEach(u),e.size&&e.forEach(u),r.size){const t=sF(aF(a.getChanges())).update.edges;r.forEach((e=>{var n;u(e);const r=null===(n=t.find((t=>Nh(t.value)===Nh(e))))||void 0===n?void 0:n.original;r&&!DU(e,r)&&u(r)}))}Se(this.options.edges)||s.forEach(((t,e)=>!this.options.edges.includes(e)&&s.delete(e)));const c=a.getEdgeData().map(Nh);return new Map([...s].sort(((t,e)=>c.indexOf(t[0])-c.indexOf(e[0]))))},this.applyBundlingStyle=(t,e,n)=>{const{edgeMap:r,reverses:i}=PU(e);r.forEach((e=>{e.forEach(((e,r,o)=>{var a;const s=o.length,l=e.style||{};if(e.source===e.target){const t=CU.length;l.loopPlacement=CU[r%t],l.loopDist=Math.floor(r/t)*n+50}else if(1===s)l.curveOffset=0;else{const t=(r%2==0?1:-1)*(i[`${e.source}|${e.target}|${r}`]?-1:1);l.curveOffset=s%2==1?t*Math.ceil(r/2)*n*2:t*(Math.floor(r/2)*n*2+n)}const u=Object.assign(e,{type:"quadratic",style:l}),c=null===(a=this.context.element)||void 0===a?void 0:a.getElement(Nh(e));c&&BH(u.style,c.attributes)||jH(t,c?"update":"add","edge",u,!0)}))}))},this.resetEdgeStyle=t=>{const e=t.style||{},n=this.cacheMergeStyle.get(Nh(t))||{};return Object.keys(n).forEach((r=>{Ne(e[r],n[r])&&(t[r]?e[r]=t[r]:delete e[r])})),Object.assign(t,{style:e})},this.applyMergingStyle=(t,e)=>{const{edgeMap:n,reverses:r}=PU(e);n.forEach((e=>{var n;if(1===e.length){const r=e[0],i=null===(n=this.context.element)||void 0===n?void 0:n.getElement(Nh(r)),o=this.resetEdgeStyle(r);return void(i&&BH(o,i.attributes)||jH(t,i?"update":"add","edge",o))}const i=e.map((({source:t,target:e,style:n={}},i)=>{const{startArrow:o,endArrow:a}=n,s={},[l,u]=r[`${t}|${e}|${i}`]?["endArrow","startArrow"]:["startArrow","endArrow"];return pe(o)&&(s[l]=o),pe(a)&&(s[u]=a),s})).reduce(((t,e)=>Object.assign(Object.assign({},t),e)),{});e.forEach(((e,n,r)=>{var o;if(0!==n)return void jH(t,"remove","edge",e);const a=Object.assign({},Ut(this.options.style)?this.options.style(r):this.options.style,{childrenData:r});this.cacheMergeStyle.set(Nh(e),a);const s=Object.assign(Object.assign({},e),{type:"line",style:Object.assign(Object.assign(Object.assign({},e.style),i),a)}),l=null===(o=this.context.element)||void 0===o?void 0:o.getElement(Nh(e));l&&BH(s.style,l.attributes)||jH(t,l?"update":"add","edge",s,!0)}))}))}}beforeDraw(t){const e=this.getAffectedParallelEdges(t);return 0===e.size||("bundle"===this.options.mode?this.applyBundlingStyle(t,e,this.options.distance):this.applyMergingStyle(t,e)),t}}AU.defaultOptions={mode:"bundle",distance:15};const PU=t=>{const e=new Map,n=new Set,r={},i=new Map;for(const[o,a]of t){if(n.has(o))continue;const{source:s,target:l}=a,u=`${s}-${l}`;e.has(u)||(e.set(u,[]),i.set(u,new Set));const c=e.get(u),h=i.get(u);c&&h&&!h.has(o)&&(c.push(a),h.add(o),n.add(o));for(const[c,h]of t)if(!n.has(c)&&c!==o&&DU(a,h)){const t=e.get(u),o=i.get(u);t&&o&&!o.has(c)&&(t.push(h),o.add(c),s===h.target&&l===h.source&&(r[`${h.source}|${h.target}|${t.length-1}`]=!0),n.add(c))}}return{edgeMap:e,reverses:r}},RU=(t,e,n)=>e.filter((e=>DU(e,t))),DU=(t,e)=>{const{sourceNode:n,targetNode:r}=t.style||{},{sourceNode:i,targetNode:o}=e.style||{};return n===i&&r===o||n===o&&r===i};const LU={animation:{"combo-collapse":Xc,"combo-expand":Kc,"node-collapse":Uc,"node-expand":$c,"path-in":Yc,"path-out":qc,fade:[{fields:["opacity"]}],translate:[{fields:["x","y"]}]},behavior:{"brush-select":Nd,"click-select":Ld,"collapse-expand":Ug,"create-edge":Yg,"drag-canvas":qg,"drag-element-force":av,"drag-element":Xg,"fix-element-size":sv,"focus-element":lv,"hover-activate":uv,"lasso-select":cv,"auto-adapt-label":Vh,"optimize-viewport-transform":hv,"scroll-canvas":dv,"zoom-canvas":fv},combo:{circle:zp,rect:Gp},edge:{cubic:fg,line:mg,polyline:Tg,quadratic:Cg,"cubic-horizontal":pg,"cubic-radial":gg,"cubic-vertical":vg},layout:{"antv-dagre":Sb,"combo-combined":uE,"compact-box":Em.compactBox,"d3-force":ZE,"force-atlas2":sj,circular:Cb,concentric:Db,dagre:nj,dendrogram:Em.dendrogram,fishbone:Zj,force:nx,fruchterman:uj,grid:hj,indented:Em.indented,mds:rE,mindmap:Em.mindmap,radial:wj,random:Cj,snake:eB},node:{circle:df,diamond:pf,ellipse:yf,hexagon:bf,html:Lp,image:_p,rect:Ip,star:jp,donut:gf,triangle:Bp},palette:{spectral:["rgb(158, 1, 66)","rgb(213, 62, 79)","rgb(244, 109, 67)","rgb(253, 174, 97)","rgb(254, 224, 139)","rgb(255, 255, 191)","rgb(230, 245, 152)","rgb(171, 221, 164)","rgb(102, 194, 165)","rgb(50, 136, 189)","rgb(94, 79, 162)"],tableau:["rgb(78, 121, 167)","rgb(242, 142, 44)","rgb(225, 87, 89)","rgb(118, 183, 178)","rgb(89, 161, 79)","rgb(237, 201, 73)","rgb(175, 122, 161)","rgb(255, 157, 167)","rgb(156, 117, 95)","rgb(186, 176, 171)"],oranges:["rgb(255, 245, 235)","rgb(254, 230, 206)","rgb(253, 208, 162)","rgb(253, 174, 107)","rgb(253, 141, 60)","rgb(241, 105, 19)","rgb(217, 72, 1)","rgb(166, 54, 3)","rgb(127, 39, 4)"],greens:["rgb(247, 252, 245)","rgb(229, 245, 224)","rgb(199, 233, 192)","rgb(161, 217, 155)","rgb(116, 196, 118)","rgb(65, 171, 93)","rgb(35, 139, 69)","rgb(0, 109, 44)","rgb(0, 68, 27)"],blues:["rgb(247, 251, 255)","rgb(222, 235, 247)","rgb(198, 219, 239)","rgb(158, 202, 225)","rgb(107, 174, 214)","rgb(66, 146, 198)","rgb(33, 113, 181)","rgb(8, 81, 156)","rgb(8, 48, 107)"]},theme:{dark:LH,light:_H},plugin:{"bubble-sets":VB,"edge-bundling":$B,"edge-filter-lens":eF,"grid-line":oF,background:oB,contextmenu:UB,fisheye:rF,fullscreen:iF,history:cF,hull:HF,legend:dH,minimap:fH,snapline:mH,timebar:EH,toolbar:SH,tooltip:NH,watermark:CH},transform:{"arrange-draw-order":class extends IH{beforeDraw(t){const{model:e}=this.context,n=t.add.combos,r=t=>{const n=[];return t.forEach(((t,r)=>{const i=e.getAncestorsData(r,"combo").map((t=>Nh(t))).reverse();n.push([r,t,i.length])})),new Map(n.sort((([,,t],[,,e])=>e-t)).map((([t,e])=>[t,e])))};return t.add.combos=r(n),t.update.combos=r(t.update.combos),t}},"collapse-expand-combo":class extends IH{beforeDraw(t,e){if("visibility"===e.stage)return t;if(!this.context.model.model.hasTreeStructure(Cc))return t;const{model:n}=this.context,{add:r,update:i}=t,o=[...t.update.combos.entries(),...t.add.combos.entries()];for(;o.length;){const[e,a]=o.pop();if(_d(a)){const a=n.getDescendantsData(e),s=a.map(Nh),{internal:l,external:u}=lg(s,(t=>n.getRelatedEdgesData(t)));a.forEach((e=>{const r=Nh(e),i=o.findIndex((([t])=>t===r));-1!==i&&o.splice(i,1);const a=n.getElementType(r);jH(t,"remove",a,e)})),l.forEach((e=>jH(t,"remove","edge",e))),u.forEach((t=>{var e;const n=Nh(t);(null===(e=this.context.element)||void 0===e?void 0:e.getElement(n))?i.edges.set(n,t):r.edges.set(n,t)}))}else{const r=n.getChildrenData(e),i=r.map(Nh),{edges:a}=lg(i,(t=>n.getRelatedEdgesData(t)));[...r,...a].forEach((e=>{var r;const i=Nh(e),a=n.getElementType(i),s=null===(r=this.context.element)||void 0===r?void 0:r.getElement(i);jH(t,s?"update":"add",a,e),"combo"===a&&o.push([i,e])}))}}return t}},"collapse-expand-node":class extends IH{getElement(t){return this.context.element.getElement(t)}handleExpand(t,e){if(FH(e,"add","node",t),_d(t))return;const n=Nh(t);FH(e,"add","node",t);this.context.model.getRelatedEdgesData(n,"out").forEach((t=>{jH(e,"add","edge",t)}));this.context.model.getChildrenData(n).forEach((t=>{this.handleExpand(t,e)}))}beforeDraw(t){const{graph:e,model:n}=this.context;if(!n.model.hasTreeStructure(Ac))return t;const{add:{nodes:r,edges:i},update:{nodes:o}}=t,a=new Map,s=new Map;r.forEach(((t,e)=>{_d(t)&&a.set(e,t)})),i.forEach((t=>{if("node"!==e.getElementType(t.source))return;const n=e.getNodeData(t.source);_d(n)&&a.set(t.source,n)})),o.forEach(((t,e)=>{const n=this.getElement(e);if(!n)return;const r=n.attributes.collapsed;_d(t)?r||a.set(e,t):r&&s.set(e,t)}));const l=new Set;return a.forEach(((e,r)=>{n.getDescendantsData(r).forEach((e=>{const r=Nh(e);if(l.has(r))return;jH(t,"remove","node",e);n.getRelatedEdgesData(r).forEach((e=>{jH(t,"remove","edge",e)})),l.add(r)}))})),s.forEach(((e,r)=>{n.getAncestorsData(r,Ac).some(_d)?jH(t,"remove","node",e):this.handleExpand(e,t)})),t}},"get-edge-actual-ends":class extends IH{beforeDraw(t){const{add:e,update:n}=t,{model:r}=this.context;return[...e.edges.entries(),...n.edges.entries()].forEach((([,t])=>{NU(r,t)})),t}},"map-node-size":OU,"place-radial-labels":TU,"process-parallel-edges":AU,"update-related-edges":class extends IH{beforeDraw(t,e){const{stage:n}=e;if("visibility"===n)return t;const{model:r}=this.context,{update:{nodes:i,edges:o,combos:a}}=t,s=(t,e)=>{r.getRelatedEdgesData(e).forEach((t=>!o.has(Nh(t))&&o.set(Nh(t),t)))};return i.forEach(s),a.forEach(s),t}}},shape:{circle:Gl,ellipse:Hl,group:Ul,html:Yl,image:rf,line:Kl,path:Ql,polygon:tu,polyline:nu,rect:ru,text:ou,label:Zd,badge:Qd}};Object.entries(LU).forEach((([t,e])=>{Object.entries(e).forEach((([e,n])=>{VH(t,e,n)}))}));t.AntVDagreLayout=Sb,t.AutoAdaptLabel=Vh,t.Background=oB,t.Badge=Qd,t.BaseBehavior=Gh,t.BaseCombo=Fp,t.BaseEdge=dg,t.BaseLayout=nv,t.BaseNode=hf,t.BasePlugin=nB,t.BaseShape=qd,t.BaseTransform=IH,t.BrushSelect=Nd,t.BubbleSets=VB,t.CameraSetting=class extends nB{constructor(t,e){super(t,e),this.setOptions=t=>{const e=(t,e)=>{switch(t){case"projectionMode":return"perspective"===e?1:0;case"cameraType":return{orbiting:0,exploring:1,tracking:2}[e];case"aspect":return"number"==typeof e?e:this.getCanvasAspect();default:return e}};Object.entries({cameraType:"setType",near:"setNear",far:"setFar",fov:"setFov",aspect:"setAspect",projectionMode:"setProjectionMode",distance:"setDistance",minDistance:"setMinDistance",maxDistance:"setMaxDistance",roll:"setRoll",elevation:"setElevation",azimuth:"setAzimuth"}).forEach((([n,r])=>{const i=t[n];if(void 0!==i){const t=e(n,i);this.context.canvas.getCamera()[r](t)}}))},this.bindEvents()}update(t){this.setOptions(t),super.update(t)}bindEvents(){this.context.graph.once(t.GraphEvent.BEFORE_DRAW,(()=>this.setOptions(this.options)))}getCanvasAspect(){const[t,e]=this.context.viewport.getCanvasSize();return t/e}},t.Canvas=YH,t.Circle=df,t.CircleCombo=zp,t.CircularLayout=Cb,t.ClickSelect=Ld,t.CollapseExpand=Ug,t.ComboCombinedLayout=uE,t.CompactBoxLayout=Em.compactBox,t.ConcentricLayout=Db,t.Contextmenu=UB,t.CreateEdge=Yg,t.Cubic=fg,t.CubicHorizontal=pg,t.CubicRadial=gg,t.CubicVertical=vg,t.D3ForceLayout=ZE,t.DagreLayout=nj,t.DendrogramLayout=Em.dendrogram,t.Diamond=pf,t.Donut=gf,t.DragCanvas=qg,t.DragElement=Xg,t.DragElementForce=av,t.EdgeBundling=$B,t.EdgeFilterLens=eF,t.Ellipse=yf,t.FishboneLayout=Zj,t.Fisheye=rF,t.FixElementSize=sv,t.FocusElement=lv,t.ForceAtlas2Layout=sj,t.ForceLayout=nx,t.FruchtermanLayout=uj,t.Fullscreen=iF,t.Graph=SU,t.GridLayout=hj,t.GridLine=oF,t.HTML=Lp,t.Hexagon=bf,t.History=cF,t.HoverActivate=uv,t.Hull=HF,t.Icon=uf,t.Image=_p,t.IndentedLayout=Em.indented,t.Label=Zd,t.LassoSelect=cv,t.Legend=dH,t.Line=mg,t.MDSLayout=rE,t.MapNodeSize=OU,t.MindmapLayout=Em.mindmap,t.Minimap=fH,t.OptimizeViewportTransform=hv,t.PlaceRadialLabels=TU,t.Polyline=Tg,t.ProcessParallelEdges=AU,t.Quadratic=Cg,t.RadialLayout=wj,t.RandomLayout=Cj,t.Rect=Ip,t.RectCombo=Gp,t.ScrollCanvas=dv,t.Shortcut=Sd,t.SnakeLayout=eB,t.Snapline=mH,t.Star=jp,t.Timebar=EH,t.Toolbar=SH,t.Tooltip=NH,t.Triangle=Bp,t.Watermark=CH,t.ZoomCanvas=fv,t.effect=function(t,e,n){zH.has(t)||zH.set(t,{});const r=zH.get(t);if(!r[e])return r[e]=n,!0;const i=r[e];return!GH(i,n)&&(r[e]=n,!0)},t.getExtension=Dc,t.getExtensions=function(t){return Rc[t]},t.iconfont={css:"//at.alicdn.com/t/a/font_470089_8hnbbf8n4u8.css",js:"//at.alicdn.com/t/a/font_470089_8hnbbf8n4u8.js"},t.idOf=Nh,t.invokeLayoutMethod=iv,t.isCollapsed=_d,t.omitStyleProps=zd,t.parseSize=Gd,t.positionOf=sd,t.register=VH,t.setVisibility=Bh,t.subStyleProps=Bd,t.treeToGraphData=function(t,e){const{getNodeData:n=(t,e)=>{if(t.depth=e,!t.children)return t;const{children:n}=t,r=Fe(t,["children"]);return Object.assign(Object.assign({},r),{children:n.map((t=>t.id))})},getEdgeData:r=(t,e)=>({source:t.id,target:e.id}),getChildren:i=t=>t.children||[]}=e||{},o=[],a=[];return Ad(t,((t,e)=>{o.push(n(t,e));const s=i(t);for(const e of s)a.push(r(t,e))}),(t=>i(t)),"TB"),{nodes:o,edges:a}},t.version=Lc})); diff --git a/src/managers/api_client.js b/src/managers/api_client.js index 944438e..55f2fad 100644 --- a/src/managers/api_client.js +++ b/src/managers/api_client.js @@ -150,9 +150,10 @@ async function applyGraph(cache, data) { } /** - * Build a serializing scheduler for graph application. G6 graph teardown - * corrupts if a new render starts while the previous one is still settling, so - * applications must never overlap. Under replace semantics only the latest + * Build a serializing scheduler for graph application. Renderer teardown and + * re-render must never overlap (the destroy/create choreography spans several + * awaits), so applications run strictly one at a time. Under replace semantics + * only the latest * payload matters, so intermediate payloads that arrive mid-render are * coalesced away. * diff --git a/src/managers/io.js b/src/managers/io.js index 9c18929..791ad3d 100644 --- a/src/managers/io.js +++ b/src/managers/io.js @@ -1768,7 +1768,6 @@ class IOManager { } async exportPNG() { - // https://g6.antv.antgroup.com/en/api/reference/g6/dataurloptions#properties try { await this.cache.ui.showLoading("Loading", "Generating picture data"); diff --git a/src/package/vendor_libs.js b/src/package/vendor_libs.js index e36c03b..6409f1c 100644 --- a/src/package/vendor_libs.js +++ b/src/package/vendor_libs.js @@ -1,6 +1,6 @@ #!/usr/bin/env node // Copies ESM builds of npm deps into src/lib/ so they load under raw-module -// dev serve (npm run serve) and keep parity with vendored libs (g6, exceljs). +// dev serve (npm run serve) and keep parity with vendored libs (exceljs). // Also regenerates the assistant system prompt JS module from its .md source. const fs = require('fs'); const path = require('path'); diff --git a/src/utilities/tour.js b/src/utilities/tour.js index 870b7d0..cde636c 100644 --- a/src/utilities/tour.js +++ b/src/utilities/tour.js @@ -199,7 +199,7 @@ const TOUR_STEPS = [ targets: [ {selector: "#innerGraphContainer"}, {selector: "#lassoWrapper"}, - {selector: ".g6-minimap"}, + {selector: ".gll-minimap"}, ], position: "left", }, From cb190f82df860c874a77fe6629dfbcc23cd15708 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 19:15:17 +0200 Subject: [PATCH 07/69] fix(bubbles): correct manual-group visibility filter precedence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - updateManualGroupStatus mixed && / || without parentheses, so filtered-out or stale manual members could still count toward the status badge - remove the dead INVISIBLE_DUMMY_NODE config and its guard conditions in bubble_sets.js — nothing adds the dummy node since the sigma cutover, and the nodeRef/current-graph checks subsume every guard - document the bubble label placement/close-to-path/auto-rotate no-op knobs in the 1.15.0 changelog entry --- CHANGELOG.md | 2 +- package-lock.json | 4 ++-- src/config.js | 7 ------ src/graph/bubble_sets.js | 46 +++++++++++++------------------------- src/graph/sigma_adapter.js | 1 - tests/config.test.js | 5 ----- 6 files changed, 18 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67079d4..8f59f26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ The entire rendering stack moved from AntV G6 5.x (canvas) to Sigma.js v3 (WebGL * Layouts run headlessly: force (graphology forceAtlas2), circular/grid (geometric), radial/concentric/mds (`@antv/layout` v2) * Fixed slow deselection when clicking empty canvas on large graphs (antvis/G6#7195) — removed from Known Issues * Distribution is ≈0.9 MB smaller (the 1.1 MB vendored `g6.min.js` is gone; sigma + graphology + headless layouts add ≈0.2 MB) -* Documented degradations: dashed edges render solid and polyline edges render curved (no off-the-shelf WebGL programs for either) +* Documented degradations: dashed edges render solid and polyline edges render curved (no off-the-shelf WebGL programs for either); the bubble-group label placement / close-to-path / auto-rotate style knobs are currently no-ops (labels render at the outline top) ## 1.14.2 diff --git a/package-lock.json b/package-lock.json index d6610eb..f5f6c9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "graph-lens-lite", - "version": "1.14.2", + "version": "1.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "graph-lens-lite", - "version": "1.14.2", + "version": "1.15.0", "dependencies": { "@antv/layout": "^2.0.0", "@sigma/edge-curve": "^3.1.0", diff --git a/src/config.js b/src/config.js index e9fa2b4..db7d005 100644 --- a/src/config.js +++ b/src/config.js @@ -252,13 +252,6 @@ const CFG = { // Set to true to reset positions of selected elements when clicking the reset selection button in the top right selection frame RESET_SELECTION_BUTTON_RESETS_POSITIONS: true, - INVISIBLE_DUMMY_NODE: { - id: "INVISIBLEDUMMYNODEWITHIMPOSSIBLEID", - style: { - visibility: "hidden" - }, - }, - INVISIBLE_CHAR: "\u200B", // AI Assistant configuration lives entirely in localStorage (key diff --git a/src/graph/bubble_sets.js b/src/graph/bubble_sets.js index f77b734..9a9e53d 100644 --- a/src/graph/bubble_sets.js +++ b/src/graph/bubble_sets.js @@ -106,18 +106,14 @@ class GraphBubbleSetManager { for (let prop of propsInGroup) { let nodeIDsToBeGrouped = this.cache.propIDsToNodeIDsToBeShown.get(prop) || []; for (let nodeID of nodeIDsToBeGrouped) { - // Explicitly exclude dummy node - if (nodeID !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id) { - actualMembers.add(nodeID); - } + actualMembers.add(nodeID); } } // Add members from manual group selection const manualMembers = currentLayout[`${group}ManualMembers`] || new Set(); for (let nodeID of manualMembers) { - // Explicitly exclude dummy node - if (nodeID !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id && this.cache.nodeRef.has(nodeID)) { + if (this.cache.nodeRef.has(nodeID)) { actualMembers.add(nodeID); } } @@ -205,9 +201,8 @@ class GraphBubbleSetManager { for (let prop of propsInGroup) { let nodeIDsToBeGrouped = this.cache.propIDsToNodeIDsToBeShown.get(prop) || []; for (let nodeID of nodeIDsToBeGrouped) { - // Explicitly exclude dummy node and hidden dangling nodes - if (nodeID !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id && - !this.cache.hiddenDanglingNodeIDs.has(nodeID)) { + // Exclude hidden dangling nodes + if (!this.cache.hiddenDanglingNodeIDs.has(nodeID)) { newSetMembers.add(nodeID); } } @@ -217,9 +212,8 @@ class GraphBubbleSetManager { const manualMembers = this.cache.data.layouts[this.cache.data.selectedLayout][`${group}ManualMembers`]; if (manualMembers && manualMembers.size > 0) { for (let nodeID of manualMembers) { - // Only add if node is still visible (not filtered out), and explicitly exclude dummy node and hidden dangling nodes - if (nodeID !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id && - this.cache.nodeRef.has(nodeID) && + // Only add if node is still visible (not filtered out or hidden dangling) + if (this.cache.nodeRef.has(nodeID) && !this.cache.hiddenDanglingNodeIDs.has(nodeID)) { newSetMembers.add(nodeID); } @@ -235,15 +229,10 @@ class GraphBubbleSetManager { } async updateBubbleSet(group, members) { - // Ensure dummy node is never included in members - const filteredMembers = members instanceof Set - ? new Set([...members].filter(id => id !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id)) - : [...members].filter(id => id !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id); - - let empty = !filteredMembers || (filteredMembers instanceof Set ? filteredMembers.size === 0 : filteredMembers.length === 0); - const membersAsArray = filteredMembers instanceof Set ? [...filteredMembers] : filteredMembers; + let empty = !members || (members instanceof Set ? members.size === 0 : members.length === 0); + const membersAsArray = members instanceof Set ? [...members] : members; - const avoidMembers = empty ? [] : this.getAvoidMembers(filteredMembers); + const avoidMembers = empty ? [] : this.getAvoidMembers(members); if (StaticUtilities.arraysAreEqual(membersAsArray, [...this.cache.INSTANCES.BUBBLE_GROUPS[group].members.keys()])) { this.cache.ui.debug("BUBBLE GROUPS IN SYNC - SKIPPING UPDATE"); @@ -296,10 +285,7 @@ class GraphBubbleSetManager { } const manualMembers = this.cache.data.layouts[this.cache.data.selectedLayout][`${group}ManualMembers`]; - // Filter out dummy node from selected nodes - const selectedNodeIds = [...this.cache.selectedNodes].filter(nodeId => - nodeId !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id - ); + const selectedNodeIds = [...this.cache.selectedNodes]; if (selectedNodeIds.length === 0) { this.cache.ui.warning("No nodes selected"); @@ -372,12 +358,11 @@ class GraphBubbleSetManager { for (let [group, quadrantPosition] of Object.entries(this.cache.DEFAULTS.BUBBLE_GROUP_QUADRANT_POSITIONS)) { const manualMembers = this.cache.data.layouts[this.cache.data.selectedLayout][`${group}ManualMembers`] || new Set(); - // Filter out nodes that are no longer visible (filtered out) and explicitly exclude dummy node + // Filter out nodes that are no longer visible (filtered out) const visibleMembers = [...manualMembers].filter(nodeId => - nodeId !== this.cache.CFG.INVISIBLE_DUMMY_NODE.id && this.cache.nodeRef.has(nodeId) && - this.cache.propIDsToNodeIDsToBeShown.size === 0 || - [...this.cache.propIDsToNodeIDsToBeShown.values()].some(set => set.has(nodeId)) + (this.cache.propIDsToNodeIDsToBeShown.size === 0 || + [...this.cache.propIDsToNodeIDsToBeShown.values()].some(set => set.has(nodeId))) ); if (visibleMembers.length > 0) { @@ -401,15 +386,14 @@ class GraphBubbleSetManager { } cleanupManualGroupMembers() { - // Remove nodes from manual groups that are no longer visible (filtered out) or are the dummy node + // Remove nodes from manual groups that are no longer visible (filtered out) for (let group of Object.keys(this.cache.DEFAULTS.BUBBLE_GROUP_STYLE)) { const manualMembers = this.cache.data.layouts[this.cache.data.selectedLayout][`${group}ManualMembers`]; if (manualMembers && manualMembers.size > 0) { const toRemove = []; for (let nodeId of manualMembers) { - // Check if node is filtered out (not visible) or is the dummy node - if (nodeId === this.cache.CFG.INVISIBLE_DUMMY_NODE.id || !this.cache.nodeRef.has(nodeId)) { + if (!this.cache.nodeRef.has(nodeId)) { toRemove.push(nodeId); } } diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 8822c6b..b09825f 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -267,7 +267,6 @@ class SigmaAdapter { /** @param {Array<{id: string, type?: string, style?: object}>} payload */ async updateNodeData(payload) { for (const item of payload ?? []) { - // hasNode also guards the legacy INVISIBLE_DUMMY_NODE (never added here). if (!item || !this.graph.hasNode(item.id)) continue; const ref = this.cache.nodeRef.get(item.id); if (ref) { diff --git a/tests/config.test.js b/tests/config.test.js index dbc2c7a..07898da 100644 --- a/tests/config.test.js +++ b/tests/config.test.js @@ -214,11 +214,6 @@ describe('CFG', () => { expect(typeof CFG.EXCEL_EDGE_HEADER).toBe('string') }) - it('INVISIBLE_DUMMY_NODE has hidden visibility', () => { - expect(CFG.INVISIBLE_DUMMY_NODE.style.visibility).toBe('hidden') - expect(CFG.INVISIBLE_DUMMY_NODE.id).toBeTruthy() - }) - it('boolean flags default correctly', () => { expect(typeof CFG.HIDE_LABELS).toBe('boolean') expect(typeof CFG.DISABLE_HOVER_EFFECT).toBe('boolean') From be9fc04da9ee7a4a29ef5c78769ec53a895b71c0 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 20:47:52 +0200 Subject: [PATCH 08/69] fix(interactions): group drag, lasso toggle, drag label pinning - dragging a selected node now moves the whole selection (per-frame delta applied to every selected id; cache.selectedNodes normalized Set/Array) - lasso overlay canvas z-index 1000 -> 900 so the toolbar (z 1000) stays clickable and the lasso icon can disable lasso mode - dragged node's label pinned via forceLabel for the drag duration so sigma's label grid can't drop or reassign it mid-drag --- src/graph/interactions.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/graph/interactions.js b/src/graph/interactions.js index 4d7a188..b136528 100644 --- a/src/graph/interactions.js +++ b/src/graph/interactions.js @@ -31,6 +31,7 @@ class InteractionManager { this.enabled = { drag: true, click: true, hover: true, tooltip: true, lasso: false }; this.draggedNode = null; + this.dragGroup = null; this.dragMoved = false; // Covers the click that ends a micro-drag (1-2 move events — sigma's // captor only swallows clicks after >=3 dragged events itself). @@ -115,6 +116,13 @@ class InteractionManager { if (!this.enabled.drag) return; this.draggedNode = node; this.dragMoved = false; + // Dragging a selected node moves the whole selection along. + // (selectedNodes starts as a Set and becomes an array after the first + // selection — new Set() tolerates both.) + const selected = new Set(this.cache.selectedNodes ?? []); + this.dragGroup = selected.has(node) ? selected : null; + // Pin the label so sigma's per-frame label grid can't drop it mid-drag. + this.adapter.graph.mergeNodeAttributes(node, { forceLabel: true }); // Pin the normalization bbox: without it every x/y write re-normalizes // the coordinate space and the graph swims under the cursor. const sigma = this.adapter.sigma; @@ -127,7 +135,16 @@ class InteractionManager { // as-is; the flip to app space happens once in getNodeData (see // graph_model.js flipY contract). const pos = this.adapter.sigma.viewportToGraph(event); - this.adapter.graph.mergeNodeAttributes(this.draggedNode, { x: pos.x, y: pos.y }); + const graph = this.adapter.graph; + // Move by delta so a group drag preserves relative positions. + const dragged = graph.getNodeAttributes(this.draggedNode); + const dx = pos.x - dragged.x; + const dy = pos.y - dragged.y; + for (const id of this.dragGroup ?? [this.draggedNode]) { + if (!graph.hasNode(id)) continue; + const a = graph.getNodeAttributes(id); + graph.mergeNodeAttributes(id, { x: a.x + dx, y: a.y + dy }); + } this.dragMoved = true; this.hideTooltip(); // Keep the camera from panning along with the node drag. @@ -139,8 +156,12 @@ class InteractionManager { async #onMouseUp() { if (!this.draggedNode) return; const moved = this.dragMoved; + const dragged = this.draggedNode; this.draggedNode = null; + this.dragGroup = null; this.dragMoved = false; + const graph = this.adapter.graph; + if (graph.hasNode(dragged)) graph.mergeNodeAttributes(dragged, { forceLabel: false }); if (!moved) return; // Set synchronously before any await: sigma emits clickNode right after // mouseup with no microtask boundary, so the flag must already be up. @@ -233,11 +254,12 @@ class InteractionManager { const canvas = document.createElement("canvas"); canvas.className = "lasso-overlay"; // Sits above sigma's layers and swallows all pointer input while active, - // which is what disables camera pan / node drag in lasso mode. + // which is what disables camera pan / node drag in lasso mode. Stays + // below the toolbar (1000) so its lasso toggle remains clickable. Object.assign(canvas.style, { position: "absolute", inset: "0", - zIndex: "1000", + zIndex: "900", cursor: "crosshair", touchAction: "none", display: "none", From f821ea43b19539afb216368297220f9607910631 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 20:48:05 +0200 Subject: [PATCH 09/69] fix(renderer): texture black boxes, restyle flicker, hover theft, container resize - force TEXTURE_MIN_FILTER=LINEAR after every atlas bindTextures: ANGLE/radeonsi intermittently fails generateMipmap on NPOT atlas re-uploads, leaving textures mipmap-incomplete and sampled opaque black (the hover black boxes after restyling) - atlas regeneration debounce 500 -> 50 ms so restyled nodes aren't invisible (transparent base color) while their new textures load - hover drawer gated during node drag so passed-over nodes can't pop their hover label (square program wraps its instance drawHover; shape/circle go through defaultDrawNodeHover) - debounced ResizeObserver on the graph container replaces the five race-prone setTimeout resize workarounds in ui.js; sigma v3 only auto-resizes on window resize, so panel toggles left a stale viewport until the next zoom/pan --- src/graph/sigma_adapter.js | 80 ++++++++++++++++++++++++++++-- src/lib/sigma.bundle.mjs | 28 +++++------ src/managers/ui.js | 31 ------------ src/package/vendor_entry_sigma.mjs | 1 + 4 files changed, 92 insertions(+), 48 deletions(-) diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index b09825f..8828a1d 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -15,6 +15,7 @@ import { EdgeDoubleArrowProgram, createEdgeArrowHeadProgram, createEdgeCompoundProgram, + drawDiscNodeHover, NodeSquareProgram, nodeImage, edgeCurve, @@ -29,6 +30,33 @@ import { Minimap } from "./minimap.js"; // Rasterization resolution for the SVG shape textures. 512 px keeps shapes // crisp at the ~4x zoom the UI allows (risk #1 in MIGRATION.md). const SHAPE_TEXTURE_RESOLUTION = 512; +// @sigma/node-image defaults to 500 ms before regenerating the texture atlas +// after a miss; style changes left nodes invisible (transparent base color) +// for that long. 50 ms keeps batching without visible flicker. +const ATLAS_REGEN_DEBOUNCE_MS = 50; +// Trailing-edge debounce for container ResizeObserver → sigma.resize(); +// rides out the 0.3 s CSS panel transitions without a resize per frame. +const RESIZE_DEBOUNCE_MS = 50; + +/** + * While a node drag is in flight, sigma's captor still updates hoveredNode on + * every mousemove, popping passed-over nodes' hover labels. Gate any hover + * drawer so only the dragged node may draw while a drag is active. + * + * @param {(context, data, settings) => void} drawer + * @param {() => string|null} getDraggedNode + */ +function guardHoverDrawer(drawer, getDraggedNode) { + // Defensive: if a future sigma bundle moves the wrapped drawer off the + // instance/export we read it from, fail to "no hover" instead of throwing + // inside sigma's render loop (which would swallow the error silently). + if (typeof drawer !== "function") return () => {}; + return (context, data, settings) => { + const dragged = getDraggedNode(); + if (dragged && data.key !== dragged) return; + drawer(context, data, settings); + }; +} /** * Node/edge program registry (G6 type vocabulary → sigma programs). @@ -36,15 +64,43 @@ const SHAPE_TEXTURE_RESOLUTION = 512; * and any bordered/haloed node — uses the SVG texture program ("shape"). * Edges: straight programs are sigma built-ins; curved ones come from * @sigma/edge-curve (cubic/quadratic/polyline all map to one curve type). + * + * @param {() => string|null} getDraggedNode hover-guard input (see + * guardHoverDrawer); NodeSquareProgram carries its own instance drawHover + * which bypasses defaultDrawNodeHover, so it gets wrapped here. */ -function buildProgramRegistry() { +function buildProgramRegistry(getDraggedNode) { const shapeProgram = nodeImage.createNodeImageProgram({ size: { mode: "force", value: SHAPE_TEXTURE_RESOLUTION }, objectFit: "contain", drawingMode: "background", keepWithinCircle: false, padding: 0, + debounceTimeout: ATLAS_REGEN_DEBOUNCE_MS, }); + // ANGLE/radeonsi intermittently fails generateMipmap on NPOT atlas + // re-uploads (GL_INVALID_OPERATION), leaving textures mipmap-incomplete — + // sampled as opaque black (the hover-after-restyle black boxes). The + // program never sets TEXTURE_MIN_FILTER, so the NEAREST_MIPMAP_LINEAR + // default requires a complete mip chain; force LINEAR, which needs none. + // 512 px rasters lose nothing visible to non-mipmapped minification. + const originalBindTextures = shapeProgram.prototype.bindTextures; + shapeProgram.prototype.bindTextures = function () { + originalBindTextures.call(this); + const gl = this.normalProgram?.gl ?? this.gl; + if (!gl) return; + for (let i = 0; i < (this.textures?.length ?? 0); i++) { + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.textures[i]); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + } + }; + class GuardedSquareProgram extends NodeSquareProgram { + constructor(...args) { + super(...args); + this.drawHover = guardHoverDrawer(this.drawHover, getDraggedNode); + } + } const curveOptions = (extremity) => ({ arrowHead: extremity ? { ...edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS.arrowHead, extremity } @@ -53,7 +109,7 @@ function buildProgramRegistry() { }); return { nodeProgramClasses: { - square: NodeSquareProgram, + square: GuardedSquareProgram, shape: shapeProgram, }, edgeProgramClasses: { @@ -116,20 +172,36 @@ class SigmaAdapter { const containerEl = typeof container === "string" ? document.getElementById(container) : container; + // Lazy read: this.interactions is assigned AFTER new Sigma(...); the + // closure only runs per hover render, by which time it exists. + const getDraggedNode = () => this.interactions?.draggedNode ?? null; + this.sigma = new Sigma(this.graph, containerEl, { allowInvalidContainer: true, enableEdgeEvents: true, zIndex: true, nodeReducer, edgeReducer, - ...buildProgramRegistry(), + ...buildProgramRegistry(getDraggedNode), // Custom drawers honour the per-element label attrs from graph_model // (size, color, background, placement, offsets, auto-rotate). defaultDrawNodeLabel: drawNodeLabel, defaultDrawEdgeLabel: drawEdgeLabel, + defaultDrawNodeHover: guardHoverDrawer(drawDiscNodeHover, getDraggedNode), renderEdgeLabels: true, ...settings, }); + // Sigma only auto-resizes on window resize. Sidebar/bottom-bar toggles + // animate the container via CSS (0.3 s), which used to blank the graph + // until the next zoom/pan; observe the container directly instead. + this.resizeDebounce = null; + this.resizeObserver = new ResizeObserver(() => { + clearTimeout(this.resizeDebounce); + this.resizeDebounce = setTimeout(() => { + if (!this.killed) this.sigma.resize(); + }, RESIZE_DEBOUNCE_MS); + }); + this.resizeObserver.observe(containerEl); this.interactions = new InteractionManager(this, cache, hoverIds, containerEl); this.bubbleLayer = new BubbleSetLayer(this, cache); this.minimap = new Minimap(this, containerEl); @@ -200,6 +272,8 @@ class SigmaAdapter { destroy() { if (this.killed) return; this.killed = true; + clearTimeout(this.resizeDebounce); + this.resizeObserver.disconnect(); this.bubbleLayer.destroy(); this.minimap.destroy(); this.interactions.destroy(); diff --git a/src/lib/sigma.bundle.mjs b/src/lib/sigma.bundle.mjs index a8ed9e9..a8e4170 100644 --- a/src/lib/sigma.bundle.mjs +++ b/src/lib/sigma.bundle.mjs @@ -1,8 +1,8 @@ -var ii=Object.create;var dt=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var oi=Object.getOwnPropertyNames;var si=Object.getPrototypeOf,ui=Object.prototype.hasOwnProperty;var ft=(t,r)=>()=>(r||t((r={exports:{}}).exports,r),r.exports),vt=(t,r)=>{for(var n in r)dt(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&dt(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?dt(n,"default",{value:t,enumerable:!0}):n,t));var qe=ft((Uo,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Xe;we&&typeof we.ownKeys=="function"?Xe=we.ownKeys:Object.getOwnPropertySymbols?Xe=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Xe=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function Ye(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return Ye(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return Ye(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(Ye(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Xe(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=ft((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=bt(r,n,e,i,!0);return pt[t]=a,a}function Me(t,r,n,e){return n+(r<<8)+(t<<16)}function Ue(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;r()=>(r||t((r={exports:{}}).exports,r),r.exports),gt=(t,r)=>{for(var n in r)ft(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&ft(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?ft(n,"default",{value:t,enumerable:!0}):n,t));var $e=vt((Uo,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ye;we&&typeof we.ownKeys=="function"?Ye=we.ownKeys:Object.getOwnPropertySymbols?Ye=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ye=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function qe(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return qe(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return qe(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(qe(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ye(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=vt((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=_t(r,n,e,i,!0);return yt[t]=a,a}function Me(t,r,n,e){return n+(r<<8)+(t<<16)}function Ue(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;rw){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function xt(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Ei=` +`).concat(n))}return i}function Tr(t,r){return Er("VERTEX",t,r)}function Rr(t,r){return Er("FRAGMENT",t,r)}function wr(t,r){var n=t.createProgram();if(n===null)throw new Error("loadProgram: error while creating the program.");var e,i;for(e=0,i=r.length;ew){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function je(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Ei=` precision highp float; varying vec4 v_color; @@ -75,7 +75,7 @@ void main() { v_color.a *= bias; } -`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,_t=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:_t},{name:"a_size",size:1,type:_t},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:_t}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Ci=` +`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,Et=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:Et},{name:"a_size",size:1,type:Et},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Et}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Ci=` precision mediump float; varying vec4 v_color; @@ -175,7 +175,7 @@ void main(void) { gl_FragColor = mix(v_color, transparent, t); #endif } -`,je=ki,Ni=` +`,Ve=ki,Ni=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -243,7 +243,7 @@ void main() { v_color.a *= bias; } -`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function Ct(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Go=Ct();function Lr(t){return ke([Ct(t),ye(t)])}var Fi=Lr(),Ve=Fi,Ii=` +`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function Ct(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:Ve,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Go=Ct();function Lr(t){return ke([Ct(t),ye(t)])}var Fi=Lr(),We=Fi,Ii=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -308,8 +308,8 @@ void main() { v_color.a *= bias; } -`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],We=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe(qe()),$e=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(Ze());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function Ke(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Qe(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,Ke(te(),o)),he(f,jr(te(),a)),he(f,Ke(te(),l/m/2/y,c/m/2/y))):(he(f,Ke(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,Ke(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Qe(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function Je(t){"@babel/helpers - typeof";return Je=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},Je(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function et(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||nt)},e):this.animate({ratio:this.ratio/nt})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||nt)},e):this.animate({ratio:this.ratio*nt})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})($e);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function Ne(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function it(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),rt(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Ue(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Me.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=Ne(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=Ne(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Ue(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Me.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,rt(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),rt(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Qe(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Qe(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})($e),ln=un;var hn=WebGLRenderingContext,ms=hn.UNSIGNED_BYTE,ps=hn.FLOAT;var ga=` +`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],Xe=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:Ve,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe($e()),Ze=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(Ke());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function Qe(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Je(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,Qe(te(),o)),he(f,jr(te(),a)),he(f,Qe(te(),l/m/2/y,c/m/2/y))):(he(f,Qe(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,Qe(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Je(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function et(t){"@babel/helpers - typeof";return et=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},et(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function tt(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||it)},e):this.animate({ratio:this.ratio/it})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||it)},e):this.animate({ratio:this.ratio*it})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Ze);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function Ne(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function at(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),nt(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Ue(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Me.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=Ne(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=Ne(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Ue(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Me.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,nt(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),nt(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Je(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Je(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Ze),ln=un;var hn=WebGLRenderingContext,ms=hn.UNSIGNED_BYTE,ps=hn.FLOAT;var ga=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -390,7 +390,7 @@ void main() { v_color.a *= bias; } -`,ma=ga,dn=WebGLRenderingContext,cn=dn.UNSIGNED_BYTE,oe=dn.FLOAT,pa=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],ya={lengthToThicknessRatio:ce.lengthToThicknessRatio};function fn(t){var r=L(L({},ya),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ma,FRAGMENT_SHADER_SOURCE:je,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:pa,ATTRIBUTES:[{name:"a_positionStart",size:2,type:oe},{name:"a_positionEnd",size:2,type:oe},{name:"a_normal",size:2,type:oe},{name:"a_color",size:4,type:cn,normalized:!0},{name:"a_id",size:4,type:cn,normalized:!0},{name:"a_sourceRadius",size:1,type:oe},{name:"a_targetRadius",size:1,type:oe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:oe},{name:"a_normalCoef",size:1,type:oe},{name:"a_sourceRadiusCoef",size:1,type:oe},{name:"a_targetRadiusCoef",size:1,type:oe}],CONSTANT_DATA:[[0,1,-1,0],[0,-1,1,0],[1,1,0,1],[1,1,0,1],[0,-1,1,0],[1,-1,0,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=s.size||1,g=u.size||1,w=T*T+_*_,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-_*w*c,P=T*w*c);var C=this.array;C[o++]=f,C[o++]=m,C[o++]=y,C[o++]=E,C[o++]=k,C[o++]=P,C[o++]=p,C[o++]=a,C[o++]=b,C[o++]=g}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var ys=fn();function ba(t){return ke([fn(t),ye(t),ye(L(L({},t),{},{extremity:"source"}))])}var _a=ba(),Ea=_a;var vn=WebGLRenderingContext,bs=vn.UNSIGNED_BYTE,_s=vn.FLOAT;var gn=WebGLRenderingContext,Es=gn.UNSIGNED_BYTE,Ts=gn.FLOAT;var Ss=fe(Ze());function bn(t,r,n){return Te(t,r,n)}function Ta(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o;t.beginPath(),t.moveTo(r.x+c,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+c,r.y-l/2),t.lineTo(r.x+c,r.y-c),t.lineTo(r.x-c,r.y-c),t.lineTo(r.x-c,r.y+c),t.lineTo(r.x+c,r.y+c),t.moveTo(r.x+c,r.y+l/2),t.closePath(),t.fill()}else{var f=r.size+o;t.fillRect(r.x-f,r.y-f,f*2,f*2)}t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,bn(t,r,n)}function Ra(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function wa(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function _n(t){var r=wa(t,"string");return typeof r=="symbol"?r:r+""}function mn(t,r){for(var n=0;nno,NodePictogramProgram:()=>io,createNodeImageProgram:()=>qt});var An=fe(qe());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);nno,NodePictogramProgram:()=>io,createNodeImageProgram:()=>qt});var An=fe($e());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);n=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Ya=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function qa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return be().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function $a(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,qa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function Za(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Ka(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ja),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Qa({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,$a(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},Za(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(ot,"NEW_TEXTURE_EVENT","newTexture");var eo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,De=On.FLOAT,to=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),ro=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},to),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=ja(i,eo),y=new ot(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(ot.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Xa,FRAGMENT_SHADER_SOURCE:Va({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ro,ATTRIBUTES:[{name:"a_position",size:2,type:De},{name:"a_size",size:1,type:De},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:De},{name:"a_textureIndex",size:1,type:De}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:De}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>Eo,EdgeCurvedDoubleArrowProgram:()=>To,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>ut,default:()=>_o,indexParallelEdgesIndex:()=>bo});function ao(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=ao(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;K=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Ya=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function qa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return be().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function $a(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,qa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function Za(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Ka(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ja),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Qa({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,$a(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},Za(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(st,"NEW_TEXTURE_EVENT","newTexture");var eo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,De=On.FLOAT,to=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),ro=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},to),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=ja(i,eo),y=new st(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(st.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Xa,FRAGMENT_SHADER_SOURCE:Va({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ro,ATTRIBUTES:[{name:"a_position",size:2,type:De},{name:"a_size",size:1,type:De},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:De},{name:"a_textureIndex",size:1,type:De}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:De}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>Eo,EdgeCurvedDoubleArrowProgram:()=>To,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>lt,default:()=>_o,indexParallelEdgesIndex:()=>bo});function ao(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=ao(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;KFe,downloadAsImage:()=>or,downloadAsJPEG:()=>ko,downloadAsPNG:()=>Po,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>Lo});var Kn=fe(qn()),Fe={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Ro(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function wo(t){var r=Ro(t,"string");return typeof r=="symbol"?r:r+""}function xo(t,r,n){return(r=wo(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},Fe),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function Co(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function So(t,r){if(t==null)return{};var n,e,i=Co(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.format,a=So(e,Ao),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function Lo(t){return nr.apply(this,arguments)}function nr(){return nr=lt(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=lt(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Po(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function ko(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,Ve as EdgeArrowProgram,Ea as EdgeDoubleArrowProgram,We as EdgeRectangleProgram,sn as MouseCaptor,Da as NodeSquareProgram,un as Sigma,ye as createEdgeArrowHeadProgram,ke as createEdgeCompoundProgram,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; +`);return i}var Qt=.25,Vn={arrowHead:null,curvatureAttribute:"curvature",defaultCurvature:Qt},Wn={edgeIndexAttribute:"parallelIndex",edgeMinIndexAttribute:"parallelMinIndex",edgeMaxIndexAttribute:"parallelMaxIndex"};function bo(t,r){var n=Ae(Ae({},Wn),r||{}),e={},i={},a={},o=0;t.forEachNode(function(P){e[P]=++o+""}),t.forEachEdge(function(P,C,D,O){var I=e[D],z=e[O],G=[I,z].join("-");i[P]=G,a[G]=[I,z].sort().join("-")});var s={},u={};t.forEachEdge(function(P){var C=i[P],D=a[C];s[C]=s[C]||[],s[C].push(P),u[D]=u[D]||[],u[D].push(P)});for(var l in s){var c=s[l],f=c.length,m=u[a[l]].length;if(f===1&&m===1){var y=c[0];t.setEdgeAttribute(y,n.edgeIndexAttribute,null),t.setEdgeAttribute(y,n.edgeMaxIndexAttribute,null)}else if(f===1){var E=c[0];t.setEdgeAttribute(E,n.edgeIndexAttribute,1),t.setEdgeAttribute(E,n.edgeMaxIndexAttribute,1)}else if(f===m)for(var p=(f-1)/2,T=-p,_=0;_Fe,downloadAsImage:()=>or,downloadAsJPEG:()=>ko,downloadAsPNG:()=>Po,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>Lo});var Kn=fe(qn()),Fe={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Ro(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function wo(t){var r=Ro(t,"string");return typeof r=="symbol"?r:r+""}function xo(t,r,n){return(r=wo(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},Fe),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function Co(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function So(t,r){if(t==null)return{};var n,e,i=Co(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.format,a=So(e,Ao),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function Lo(t){return nr.apply(this,arguments)}function nr(){return nr=ct(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=ct(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Po(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function ko(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,We as EdgeArrowProgram,Ea as EdgeDoubleArrowProgram,Xe as EdgeRectangleProgram,sn as MouseCaptor,Da as NodeSquareProgram,un as Sigma,ye as createEdgeArrowHeadProgram,ke as createEdgeCompoundProgram,je as drawDiscNodeHover,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; diff --git a/src/managers/ui.js b/src/managers/ui.js index 8d4be8d..ab345bb 100644 --- a/src/managers/ui.js +++ b/src/managers/ui.js @@ -181,13 +181,6 @@ class UIManager { this.hideBottomBar(); queryBtn.classList.remove("highlight"); } - - // Wait for CSS transition to complete (300ms) before resizing graph canvas - setTimeout(() => { - if (this.cache.graph) { - this.cache.graph.resize(); - } - }, 300); } async closeBottomBar() { @@ -207,11 +200,6 @@ class UIManager { const bottomBar = document.getElementById("bottomBar"); if (bottomBar.classList.contains("active")) { this.hideBottomBar(); - setTimeout(() => { - if (this.cache.graph) { - this.cache.graph.resize(); - } - }, 300); } } @@ -232,13 +220,6 @@ class UIManager { } await this.hideLoading(); - - // Wait for CSS transition to complete (300ms) before resizing graph canvas - setTimeout(() => { - if (this.cache.graph) { - this.cache.graph.resize(); - } - }, 300); } async reloadApp() { @@ -374,11 +355,6 @@ class UIManager { bottomBar.style.height = finalHeight + 'px'; mainContent.style.height = newMainHeight + 'px'; this.bottomBarHeight = finalHeight; - - // Resize graph canvas after manual resize (no transition, resize immediately) - if (this.cache.graph) { - this.cache.graph.resize(); - } } shadowBar.style.display = 'none'; @@ -417,13 +393,6 @@ class UIManager { styleBtn.classList.add("highlight"); outerGraphContainer.classList.add("styling-panel-active"); } - - // Wait for CSS transition to complete (300ms) before resizing graph canvas - setTimeout(() => { - if (this.cache.graph) { - this.cache.graph.resize(); - } - }, 300); } toggleSelectionEditor() { diff --git a/src/package/vendor_entry_sigma.mjs b/src/package/vendor_entry_sigma.mjs index 3589381..0d66e14 100644 --- a/src/package/vendor_entry_sigma.mjs +++ b/src/package/vendor_entry_sigma.mjs @@ -9,6 +9,7 @@ export { EdgeDoubleArrowProgram, createEdgeArrowHeadProgram, createEdgeCompoundProgram, + drawDiscNodeHover, } from 'sigma/rendering'; export {NodeSquareProgram} from '@sigma/node-square'; export * as nodeImage from '@sigma/node-image'; From d3a5e9e5d6c6dcaf81f0a36ab1751680393c8d73 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 20:48:19 +0200 Subject: [PATCH 10/69] fix(core): listener stacking, style re-apply on rebuild, metrics gate, empty-query AST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - hotkey/global event registration guarded by module-scope flags: Cache.reset() recreated EVENT_LOCKS on every file load, stacking anonymous document listeners (even counts made the lasso hotkey a no-op) - createGraphInstance re-applies per-layout node/edge styles when the layout carries any (lost in fd7e342: G6's createSimplifiedDataForGraphObject merged them, buildGraphologyGraph doesn't) — fixes data-editor apply and JSON load rendering unstyled until a manual workspace switch; skipped when no custom styles exist (the reset pass costs ~700 ms at 15k elements) - updateMetricUI also proceeds when the selected metric has no cached values: under sigma fresh elements report 'visible', the visibility diff is empty, and visibleElementsChanged never fired on load, so metrics silently never computed - empty query AST now matches everything (no constraints) instead of nothing - new tests: query AST empty/malformed semantics, metrics gate (jsdom, real centrality calculations) --- src/gll.js | 2 - src/graph/core.js | 31 ++++++++-- src/managers/metrics.js | 6 +- src/managers/query.js | 3 + tests/metrics-gate.test.js | 113 +++++++++++++++++++++++++++++++++++++ tests/query-ast.test.js | 28 ++++++++- 6 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 tests/metrics-gate.test.js diff --git a/src/gll.js b/src/gll.js index e8b5bb1..39cd6d6 100644 --- a/src/gll.js +++ b/src/gll.js @@ -67,8 +67,6 @@ class Cache { ONCE_AFTER_RENDER_COMPLETED: false, BUBBLE_GROUP_REDRAW_RUNNING: false, TRIGGER_SET_LAYOUT_ONCE: false, - HOTKEY_EVENTS_REGISTERED: false, - GLOBAL_EVENTS_REGISTERED: false, SKIP_QUERY_VALIDATION: false, QUERY_SELECTION_EVENT: false, QUERY_UPDATE_EVENT: false, diff --git a/src/graph/core.js b/src/graph/core.js index 84610b5..8997a52 100644 --- a/src/graph/core.js +++ b/src/graph/core.js @@ -8,6 +8,15 @@ import { } from "./graph_model.js"; import { SigmaAdapter } from "./sigma_adapter.js"; +// One-time listener registration guards. These must live at module scope: +// the Cache singleton is reset *in place* on every file load (Cache.reset()), +// which would re-arm EVENT_LOCKS-based guards and stack duplicate document/ +// window listeners (even counts turn toggle hotkeys into no-ops). The handlers +// resolve managers through `this.cache.*`, which always points at the live, +// in-place-reset Cache instance. +let hotkeysRegistered = false; +let globalEventsRegistered = false; + class GraphCoreManager { constructor(cache) { this.cache = cache; @@ -100,6 +109,18 @@ class GraphCoreManager { }); const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; + + // Re-apply per-layout node/edge styles on every graph rebuild (data-editor + // apply, JSON load). buildGraphologyGraph does not merge layout.nodeStyles/ + // edgeStyles, and the only other applyLayoutStyles caller is changeLayout(). + // Runs before the layout algorithm below so freshly computed positions are + // never clobbered by the style reset. Skipped when the layout carries no + // custom styles: refs are already originalStyle right after a rebuild, and + // the full reset pass clones every element (~700 ms at 15k elements). + if (layout.nodeStyles?.size || layout.edgeStyles?.size) { + await this.cache.lm.applyLayoutStyles(layout); + } + // If layout has no positions yet but has a layoutType, apply that layout algorithm once if (layout.positions.size === 0 && layout.layoutType) { const internals = @@ -682,7 +703,7 @@ class GraphCoreManager { } registerHotkeyEvents() { - if (this.cache.EVENT_LOCKS.HOTKEY_EVENTS_REGISTERED) return; + if (hotkeysRegistered) return; document.addEventListener("keydown", async (event) => { const activeElement = document.activeElement; @@ -736,11 +757,13 @@ class GraphCoreManager { } }); - this.cache.EVENT_LOCKS.HOTKEY_EVENTS_REGISTERED = true; + hotkeysRegistered = true; } registerGlobalEventListeners() { - if (this.cache.EVENT_LOCKS.GLOBAL_EVENTS_REGISTERED) return; + // All targets (document, queryTextArea, innerGraphContainer, bottomBar) + // are static DOM that survives file loads — same stacking hazard as hotkeys. + if (globalEventsRegistered) return; [ "input", @@ -770,7 +793,7 @@ class GraphCoreManager { this.cache.ui.makeBottomBarResizable(); this.registerTooltipWheelHandler(); this.registerTooltipExpandToggle(); - this.cache.EVENT_LOCKS.GLOBAL_EVENTS_REGISTERED = true; + globalEventsRegistered = true; } registerTooltipExpandToggle() { diff --git a/src/managers/metrics.js b/src/managers/metrics.js index dbfe100..aaeb6da 100644 --- a/src/managers/metrics.js +++ b/src/managers/metrics.js @@ -77,7 +77,11 @@ class NetworkMetrics { } async updateMetricUI() { - if (!this.cache.visibleElementsChanged) return; + // Recompute when visibility changed OR the selected metric was never + // computed. Under sigma a fresh load produces no visibility diff (elements + // start visible), so gating on the flag alone would block metrics forever. + const cached = this.metricValueCache.get(this.selected); + if (!this.cache.visibleElementsChanged && cached?.values?.size) return; const metricName = this.m[this.selected].label; await this.cache.ui.showLoading("Calculating", `Network Metric: ${metricName}`); diff --git a/src/managers/query.js b/src/managers/query.js index a73c8e3..5636fc2 100644 --- a/src/managers/query.js +++ b/src/managers/query.js @@ -23,6 +23,9 @@ class QueryAST { #evalExpr(expr, element, requestedMainGroup) { if (!Array.isArray(expr)) return false; + /* ---------- 0. empty query = no constraints = match everything ------ */ + if (expr.length === 0) return true; + /* ---------- 1. unwrap single-element containers --------------------- */ if (expr.length === 1) { return this.#evalExpr(expr[0], element, requestedMainGroup); diff --git a/tests/metrics-gate.test.js b/tests/metrics-gate.test.js new file mode 100644 index 0000000..cc4c5ac --- /dev/null +++ b/tests/metrics-gate.test.js @@ -0,0 +1,113 @@ +// @vitest-environment jsdom +import { describe, it, expect, beforeEach, vi } from 'vitest' +import { NetworkMetrics } from '../src/managers/metrics.js' + +// ========================================================================== +// NetworkMetrics.updateMetricUI gating +// +// Requirement: metrics must compute on a fresh load even when no visibility +// diff has occurred (under sigma, fresh elements report "visible", so +// cache.visibleElementsChanged stays false). The gate may only skip when the +// selected metric already has cached values AND visibility is unchanged. +// +// Uses the real degree-centrality calculation and real DOM elements; only the +// loading-spinner UI is stubbed. +// ========================================================================== + +// Helper: minimal cache for NetworkMetrics + calculateDegreeCentrality +function makeCache({ visibleElementsChanged = false } = {}) { + return { + visibleElementsChanged, + nodeIDsToBeShown: new Set(['A', 'B', 'C']), + edgeIDsToBeShown: new Set(['A::B', 'B::C']), + edgeRef: new Map([ + ['A::B', { source: 'A', target: 'B' }], + ['B::C', { source: 'B', target: 'C' }], + ]), + toolTips: new Map(), + ui: { + showLoading: vi.fn(async () => {}), + hideLoading: vi.fn(async () => {}), + }, + } +} + +// Helper: NetworkMetrics wired to a live DOM (multiselect, table, info button) +function makeMetrics(cache) { + const metrics = new NetworkMetrics(cache) + document.body.appendChild(metrics.buildMetricUI()) + return metrics +} + +beforeEach(() => { + document.body.innerHTML = '' + // jsdom has no requestAnimationFrame by default + globalThis.requestAnimationFrame = (cb) => cb() +}) + +describe('NetworkMetrics.updateMetricUI gating', () => { + it('computes on fresh load when visibleElementsChanged is false and cache is empty', async () => { + // Arrange + const cache = makeCache({ visibleElementsChanged: false }) + const metrics = makeMetrics(cache) + expect(metrics.metricValueCache.size).toBe(0) + + // Act + await metrics.updateMetricUI() + + // Assert: node list populated, graph-level table populated, values cached + expect(metrics.multiselect.options.length).toBe(3) + expect(metrics.table.querySelectorAll('tr').length).toBeGreaterThan(0) + const cached = metrics.metricValueCache.get('centrality') + expect(cached?.values?.size).toBe(3) + // B is the path center → highest degree centrality, listed first + expect(metrics.multiselect.options[0].value).toBe('B') + }) + + it('skips recomputation when cached values exist and visibility is unchanged', async () => { + // Arrange: first pass fills the cache + const cache = makeCache({ visibleElementsChanged: false }) + const metrics = makeMetrics(cache) + await metrics.updateMetricUI() + cache.ui.showLoading.mockClear() + metrics.multiselect.innerHTML = '' + + // Act + await metrics.updateMetricUI() + + // Assert: early return — no loading UI, no DOM rebuild + expect(cache.ui.showLoading).not.toHaveBeenCalled() + expect(metrics.multiselect.options.length).toBe(0) + }) + + it('recomputes when visibleElementsChanged is true even with cached values', async () => { + // Arrange + const cache = makeCache({ visibleElementsChanged: false }) + const metrics = makeMetrics(cache) + await metrics.updateMetricUI() + metrics.multiselect.innerHTML = '' + + // Act: visibility diff occurred (e.g. filter change) + cache.visibleElementsChanged = true + await metrics.updateMetricUI() + + // Assert: full recompute repopulates the node list + expect(metrics.multiselect.options.length).toBe(3) + }) + + it('computes a never-computed metric after dropdown switch with no visibility diff', async () => { + // Arrange: centrality cached, pagerank never computed + const cache = makeCache({ visibleElementsChanged: false }) + const metrics = makeMetrics(cache) + await metrics.updateMetricUI() + + // Act: user switches the metric dropdown (handler sets selected, then updates) + metrics.selected = 'pagerank' + await metrics.updateMetricUI() + + // Assert + const cached = metrics.metricValueCache.get('pagerank') + expect(cached?.values?.size).toBe(3) + expect(metrics.multiselect.options.length).toBe(3) + }) +}) diff --git a/tests/query-ast.test.js b/tests/query-ast.test.js index 7ecd612..4b055e4 100644 --- a/tests/query-ast.test.js +++ b/tests/query-ast.test.js @@ -402,6 +402,30 @@ describe('QueryAST: edge evaluation', () => { }) }) +// -------------------------------------------------------------------------- +// Empty query semantics: no constraints = match everything +// -------------------------------------------------------------------------- + +describe('QueryAST: empty instructions', () => { + it('matches any node via testNode', () => { + const ast = new QueryAST([]) + expect(ast.testNode(makeNode({ g: { a: 5 } }))).toBe(true) + expect(ast.testNode(makeNode())).toBe(true) + }) + + it('matches any edge via testEdge', () => { + const ast = new QueryAST([]) + expect(ast.testEdge(makeEdge({ groupX: { weight: 0.5 } }))).toBe(true) + expect(ast.testEdge(makeEdge())).toBe(true) + }) + + it('does not change non-empty invalid input semantics', () => { + // Non-empty but malformed expression still falls through to false + const ast = new QueryAST([{ type: 'garbage' }, { type: 'garbage' }]) + expect(ast.testNode(makeNode({ g: { a: 5 } }))).toBe(false) + }) +}) + // -------------------------------------------------------------------------- // Edge cases / robustness // -------------------------------------------------------------------------- @@ -425,10 +449,10 @@ describe('QueryAST: edge cases', () => { expect(ast.testNode(node)).toBe(false) }) - it('returns false for empty instructions', () => { + it('matches everything for empty instructions (no constraints)', () => { const ast = new QueryAST([]) const node = makeNode({ g: { a: 5 } }) - expect(ast.testNode(node)).toBe(false) + expect(ast.testNode(node)).toBe(true) }) it('handles single instruction without nesting', () => { From 4b2535298c5bf8e4b7daf73214770152495de071 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 20:48:42 +0200 Subject: [PATCH 11/69] fix(bubbles): zoom-invariant outlines; implement label placement/close-to-path/auto-rotate - bubblesets-js influence radii were fixed pixel constants: zoomed out, non-member avoid discs cancelled the members' energy field and the outline collapsed to an empty path, vanishing the group. Field constants now scale with sigma's node-size factor (1/sqrt(camera.ratio)), with a one-shot no-avoid retry as safety net and the ratio bucket in the outline cache key so empty results aren't sticky - settle-recompute machinery removed (dead once recompute keys on ratio buckets) - labelPlacement (top/bottom/left/right/center), labelCloseToPath and labelAutoRotate style knobs now work: outlineLabelAnchor returns anchor + tangent angle + outward normal per placement; detached labels stand off along the normal; auto-rotate aligns text to the outline tangent. Default placement 'bottom' restores the old G6 look (labels move from the hardcoded top) --- src/graph/bubble_geometry.js | 103 ++++++++++++++++++++++++++----- src/graph/bubble_layer.js | 110 ++++++++++++++++++++------------- tests/bubble-geometry.test.js | 112 ++++++++++++++++++++++++++++++++-- 3 files changed, 261 insertions(+), 64 deletions(-) diff --git a/src/graph/bubble_geometry.js b/src/graph/bubble_geometry.js index ba2b52b..fde2758 100644 --- a/src/graph/bubble_geometry.js +++ b/src/graph/bubble_geometry.js @@ -12,8 +12,25 @@ import { bubblesets } from "../lib/graphology.bundle.mjs"; // PointPath post-processing per the bubblesets-js README: sample the raw // marching-squares outline, B-spline it and drop collinear points. 8 px // sampling is the library's own example default and keeps point counts in -// the low hundreds. +// the low hundreds. Scaled with opts.scale (an 8 px step would flatten a +// zoomed-out outline whose features are ~2 px) but never below 1 px. const OUTLINE_SAMPLE_PX = 8; +const OUTLINE_SAMPLE_MIN_PX = 1; + +// bubblesets-js influence-field defaults (the library's own pixel-tuned +// constants). They are absolute pixel radii, so the caller must scale them +// with the on-screen node size (opts.scale): zoomed far out, an unscaled +// 50 px negative disc around every avoid node swallows the (shrunken) +// members' positive field and the outline collapses to nothing. +const FIELD_NODE_R0 = 15; +const FIELD_NODE_R1 = 50; +const FIELD_EDGE_R0 = 10; +const FIELD_EDGE_R1 = 20; +const FIELD_MORPH_BUFFER = 10; +const FIELD_PIXEL_GROUP = 4; +// Marching-squares grid cell can never go below 1 px (pixelGroup 0 hangs +// the library; sub-pixel cells just waste time). +const FIELD_PIXEL_GROUP_MIN = 1; /** * Axis-aligned square around a node's viewport position. @@ -32,19 +49,31 @@ function nodeViewportRect(x, y, radius) { * * @param {Array<{x,y,width,height}>} memberRects * @param {Array<{x,y,width,height}>} avoidRects - * @param {{virtualEdges?: boolean}} [opts] virtualEdges routes connecting - * corridors around avoid rects (the per-group style enables it); its cost - * is O(members × avoid) — see MAX_NODES_BEFORE_DISABLING_AVOID_MEMBERS_ - * IN_BUBBLE_GROUPS in config.js for the measured budget. + * @param {{virtualEdges?: boolean, scale?: number}} [opts] + * virtualEdges routes connecting corridors around avoid rects (the + * per-group style enables it); its cost is O(members × avoid) — see + * MAX_NODES_BEFORE_DISABLING_AVOID_MEMBERS_IN_BUBBLE_GROUPS in config.js + * for the measured budget. + * scale multiplies the bubblesets influence-field pixel constants so the + * field stays proportional to the rects at any zoom (1 = library + * defaults; pass sigma's node-size zoom factor). * @returns {Array<{x: number, y: number}>} closed polygon (empty when no * members or the outline collapsed) */ function computeOutlinePoints(memberRects, avoidRects = [], opts = {}) { if (!memberRects || memberRects.length === 0) return []; + const s = opts.scale ?? 1; const path = bubblesets.createOutline(memberRects, avoidRects, [], { virtualEdges: opts.virtualEdges !== false, + nodeR0: FIELD_NODE_R0 * s, + nodeR1: FIELD_NODE_R1 * s, + edgeR0: FIELD_EDGE_R0 * s, + edgeR1: FIELD_EDGE_R1 * s, + morphBuffer: FIELD_MORPH_BUFFER * s, + pixelGroup: Math.max(FIELD_PIXEL_GROUP_MIN, FIELD_PIXEL_GROUP * s), }); - const sampled = path.sample(OUTLINE_SAMPLE_PX).simplify(0).bSplines().simplify(0); + const samplePx = Math.max(OUTLINE_SAMPLE_MIN_PX, OUTLINE_SAMPLE_PX * s); + const sampled = path.sample(samplePx).simplify(0).bSplines().simplify(0); const points = []; for (let i = 0; i < sampled.length; i++) { const p = sampled.get(i); @@ -53,20 +82,62 @@ function computeOutlinePoints(memberRects, avoidRects = [], opts = {}) { return points; } +// Extreme-point comparators per placement (viewport space is y-down, so +// "top" is the smallest y). Unknown placements fall back to "top". +const PLACEMENT_EXTREME = { + top: (p, q) => p.y < q.y, + bottom: (p, q) => p.y > q.y, + left: (p, q) => p.x < q.x, + right: (p, q) => p.x > q.x, +}; + /** - * Label anchor: the topmost outline point (smallest y — viewport space is - * y-down, so this is the visual top, where the old G6 plugin hung labels). + * Label anchor for an outline polygon. + * + * For edge placements ("top"/"bottom"/"left"/"right") the anchor is the + * extreme outline vertex in that direction; angle is the outline tangent at + * that vertex (from its two ring neighbors), normalized into [-PI/2, PI/2] + * so rotated text stays upright; (nx, ny) is the outward unit normal + * (perpendicular to the tangent, flipped if it points toward the vertex + * centroid). "center" returns the vertex centroid with angle 0, nx = ny = 0. * * @param {Array<{x: number, y: number}>} points - * @returns {{x: number, y: number}|null} + * @param {"top"|"bottom"|"left"|"right"|"center"} [placement] + * @returns {{x: number, y: number, angle: number, nx: number, ny: number}|null} */ -function outlineLabelAnchor(points) { +function outlineLabelAnchor(points, placement = "top") { if (!points || points.length === 0) return null; - let top = points[0]; + const n = points.length; + let cx = 0; + let cy = 0; for (const p of points) { - if (p.y < top.y) top = p; + cx += p.x; + cy += p.y; + } + cx /= n; + cy /= n; + if (placement === "center") return { x: cx, y: cy, angle: 0, nx: 0, ny: 0 }; + + const isBetter = PLACEMENT_EXTREME[placement] ?? PLACEMENT_EXTREME.top; + let idx = 0; + for (let i = 1; i < n; i++) { + if (isBetter(points[i], points[idx])) idx = i; + } + const anchor = points[idx]; + const prev = points[(idx - 1 + n) % n]; + const next = points[(idx + 1) % n]; + + let angle = Math.atan2(next.y - prev.y, next.x - prev.x); + if (angle > Math.PI / 2) angle -= Math.PI; + else if (angle < -Math.PI / 2) angle += Math.PI; + + let nx = -Math.sin(angle); + let ny = Math.cos(angle); + if (nx * (cx - anchor.x) + ny * (cy - anchor.y) > 0) { + nx = -nx; + ny = -ny; } - return { x: top.x, y: top.y }; + return { x: anchor.x, y: anchor.y, angle, nx, ny }; } /** @@ -105,8 +176,7 @@ function positionsChecksum(points) { } // Style fields that change the painted result; everything else the manager -// passes (members, avoidMembers, label placement extras) is keyed elsewhere -// or ignored by the layer. +// passes (members, avoidMembers) is keyed elsewhere by the layer. const STYLE_KEY_FIELDS = [ "fill", "fillOpacity", @@ -123,6 +193,9 @@ const STYLE_KEY_FIELDS = [ "labelBackgroundRadius", "labelOffsetX", "labelOffsetY", + "labelPlacement", + "labelCloseToPath", + "labelAutoRotate", ]; /** diff --git a/src/graph/bubble_layer.js b/src/graph/bubble_layer.js index c427235..2813e1e 100644 --- a/src/graph/bubble_layer.js +++ b/src/graph/bubble_layer.js @@ -14,8 +14,10 @@ * identity key in #syncGroupOutline catches them on the next frame, so * a filter event can never leave a stale outline painted) * - camera pan/zoom → cheap reprojection of the cached points (exact for - * pans; node radii drift slightly under zoom until the camera settles - * and #scheduleSettleRecompute re-fits the outline) + * pans; under zoom the cache key quantizes log2(camera.ratio) into + * RATIO_RECOMPUTE_LOG2-wide buckets, so node-radius drift forces a + * re-fit at each bucket crossing — this also keeps an empty outline + * from sticking once the zoom moves on) * This replaces the G6 plugin's recompute-per-draw churn (the patched * updateBubbleSetsPath path coalescing, issue #7195) with an owned cache. */ @@ -31,11 +33,14 @@ import { const LAYER_NAME = "bubbleSets"; const OUTLINE_STROKE_WIDTH = 2; -// Zoom drift before the settled camera forces an outline re-fit (node -// screen radii scale non-linearly with the camera ratio, so a reprojected -// outline slowly stops hugging the nodes). +// Zoom drift before an outline re-fit: log2(camera.ratio) is quantized into +// buckets of this width inside the outline cache key (node screen radii +// scale non-linearly with the camera ratio, so a reprojected outline slowly +// stops hugging the nodes). const RATIO_RECOMPUTE_LOG2 = 0.3; -const SETTLE_RECOMPUTE_MS = 150; +// Extra screen-px gap (beyond half the font box) between the outline and a +// label drawn with labelCloseToPath: false. +const LABEL_STANDOFF_PX = 8; class BubbleSetLayer { /** @@ -49,13 +54,12 @@ class BubbleSetLayer { /** @type {Map, avoidMembers: string[], opts: object}>} */ this.groups = new Map(); - // Per-group outline cache: identity key + graph-space points + the - // camera ratio the outline was fitted at. - /** @type {Map, computedRatio: number}>} */ + // Per-group outline cache: identity key (membership, style, positions, + // viewport size, ratio bucket) + graph-space points. + /** @type {Map}>} */ this.outlines = new Map(); this.rafHandle = null; - this.settleTimer = null; this.lastPaintSignature = null; const sigma = adapter.sigma; @@ -98,7 +102,6 @@ class BubbleSetLayer { if (this.killed) return; this.killed = true; if (this.rafHandle !== null) cancelAnimationFrame(this.rafHandle); - if (this.settleTimer !== null) clearTimeout(this.settleTimer); this.adapter.sigma.off("afterRender", this.renderHandler); // sigma.kill() may or may not remove custom layer canvases; remove() on // an already-detached node is a no-op, so drop ours defensively. @@ -186,8 +189,9 @@ class BubbleSetLayer { /** * Recompute the group's outline when its identity (members, positions, - * style) changed, or when the camera ratio drifted too far from the one - * the outline was fitted at (debounced to camera idle). + * style) changed, or when the camera ratio left the log2 bucket the + * outline was fitted in (between crossings the cached points are merely + * reprojected). * * @returns {boolean} true when the cached outline was replaced */ @@ -207,16 +211,16 @@ class BubbleSetLayer { // here is the O(n) position checksum. Hidden flips stay correct: an // unhide changes visibleMembers.length, and a same-count hidden swap // changes the checksum (different nodes contribute their positions). + // The ratio bucket keys the zoom level the outline was fitted at: a + // bucket crossing recomputes (radius drift re-fit), and an empty + // outline can never outlive the zoom level that produced it. + const ratioBucket = Math.round(Math.log2(camera.ratio) / RATIO_RECOMPUTE_LOG2); const key = `${state.membersKey}|${state.avoidKey}|${visibleMembers.length}` + - `|${styleKey(state.opts)}|${positionsChecksum(memberPositions)}|${width}x${height}`; + `|${styleKey(state.opts)}|${positionsChecksum(memberPositions)}` + + `|${width}x${height}|r${ratioBucket}`; const cached = this.outlines.get(group); - if (cached && cached.key === key) { - if (Math.abs(Math.log2(camera.ratio / cached.computedRatio)) > RATIO_RECOMPUTE_LOG2) { - this.#scheduleSettleRecompute(); - } - return false; - } + if (cached && cached.key === key) return false; if (visibleMembers.length === 0) { this.outlines.delete(group); @@ -238,28 +242,29 @@ class BubbleSetLayer { avoidRects.push(toRect({ attrs })); } - const viewportPoints = computeOutlinePoints(memberRects, avoidRects, { - virtualEdges: state.opts.virtualEdges, - }); + // Zoom-invariant influence field: bubblesets-js' radii are absolute + // pixels, so they must shrink/grow with the node rects. With sigma's + // default settings scaleSize(s, ratio) = s / sqrt(ratio), making + // fieldScale = scaleSize(1) / scaleSize(1, 1) exactly the node-radius + // zoom factor, normalized to 1 at camera ratio 1 (the reference zoom + // the pixel constants were tuned for) for any zoomToSizeRatioFunction. + const fieldScale = sigma.scaleSize(1) / sigma.scaleSize(1, 1); + const outlineOpts = { virtualEdges: state.opts.virtualEdges, scale: fieldScale }; + let viewportPoints = computeOutlinePoints(memberRects, avoidRects, outlineOpts); + // Safety net: at extreme zoom-out the avoid nodes' negative field can + // still cancel the members' field entirely and collapse the outline. + // A hull that ignores avoid nodes beats a vanished group. + if (viewportPoints.length === 0 && avoidRects.length > 0) { + viewportPoints = computeOutlinePoints(memberRects, [], outlineOpts); + } this.outlines.set(group, { key, // Round-trip assumes camera.angle === 0 (the app never rotates the camera). graphPoints: viewportPoints.map((p) => sigma.viewportToGraph(p)), - computedRatio: camera.ratio, }); return true; } - #scheduleSettleRecompute() { - if (this.settleTimer !== null) clearTimeout(this.settleTimer); - this.settleTimer = setTimeout(() => { - this.settleTimer = null; - if (this.killed) return; - this.outlines.clear(); - this.scheduleRedraw(); - }, SETTLE_RECOMPUTE_MS); - } - #drawGroup(ctx, group, state) { const sigma = this.adapter.sigma; // Reprojection assumes camera.angle === 0 (the app never rotates the camera). @@ -291,34 +296,50 @@ class BubbleSetLayer { } /** - * Group label at the topmost outline point (the old plugin's default - * hanging position). Honors text/fill/size/padding/background/offsets; - * labelPlacement/labelCloseToPath/labelAutoRotate are documented - * degradations of the port. + * Group label at the outline extreme picked by labelPlacement (the old G6 + * plugin's surface): labelCloseToPath: false pushes it off the path along + * the outward normal; labelAutoRotate aligns on-path labels with the + * outline tangent. labelOffsetX/Y stay additive in screen space. */ #drawLabel(ctx, points, opts, defaults) { const text = opts.labelText ?? defaults.labelText ?? ""; if (!text) return; - const anchor = outlineLabelAnchor(points); + const placement = opts.labelPlacement ?? defaults.labelPlacement ?? "bottom"; + const closeToPath = opts.labelCloseToPath ?? defaults.labelCloseToPath ?? true; + const autoRotate = opts.labelAutoRotate ?? defaults.labelAutoRotate ?? true; + const anchor = outlineLabelAnchor(points, placement); if (!anchor) return; const fontSize = opts.labelFontSize ?? defaults.labelFontSize ?? 12; const padding = opts.labelPadding ?? defaults.labelPadding ?? 2; - const x = anchor.x + (opts.labelOffsetX ?? 0); - const y = anchor.y + (opts.labelOffsetY ?? 0); + // Off-path labels clear the outline by half the padded font box plus a + // fixed gap, pushed along the outward normal (no-op for "center"). + const standoff = closeToPath ? 0 : fontSize / 2 + padding + LABEL_STANDOFF_PX; + const x = anchor.x + anchor.nx * standoff + (opts.labelOffsetX ?? 0); + const y = anchor.y + anchor.ny * standoff + (opts.labelOffsetY ?? 0); ctx.font = `${fontSize}px Arial, sans-serif`; ctx.textAlign = "center"; ctx.textBaseline = "middle"; const textWidth = ctx.measureText(text).width; + // Rotation only makes sense hugging the path; "center" has no tangent. + const rotated = autoRotate && closeToPath && placement !== "center"; + if (rotated) { + ctx.save(); + ctx.translate(x, y); + ctx.rotate(anchor.angle); + } + const lx = rotated ? 0 : x; + const ly = rotated ? 0 : y; + if (opts.labelBackground ?? defaults.labelBackground) { const radius = opts.labelBackgroundRadius ?? defaults.labelBackgroundRadius ?? 5; ctx.fillStyle = opts.labelBackgroundFill ?? defaults.labelBackgroundFill ?? "#403C53"; ctx.beginPath(); ctx.roundRect( - x - textWidth / 2 - padding, - y - fontSize / 2 - padding, + lx - textWidth / 2 - padding, + ly - fontSize / 2 - padding, textWidth + 2 * padding, fontSize + 2 * padding, radius, @@ -326,7 +347,8 @@ class BubbleSetLayer { ctx.fill(); } ctx.fillStyle = opts.labelFill ?? defaults.labelFill ?? "#fff"; - ctx.fillText(text, x, y); + ctx.fillText(text, lx, ly); + if (rotated) ctx.restore(); } } diff --git a/tests/bubble-geometry.test.js b/tests/bubble-geometry.test.js index 81f9d7f..f941bb4 100644 --- a/tests/bubble-geometry.test.js +++ b/tests/bubble-geometry.test.js @@ -68,22 +68,120 @@ describe("computeOutlinePoints", () => { expect(pointInPolygon({ x: 50, y: 50 }, outline)).toBe(true); expect(pointInPolygon({ x: 75, y: 50 }, outline)).toBe(true); }); + + describe("scale option (zoom-invariant influence field)", () => { + // The avoid-member scenario shrunk by the scale factor must keep its + // shape: members enclosed, avoid node excluded. Without scaling the + // influence constants, the fixed 50 px negative disc of the avoid node + // would swallow the shrunken members' field. + it.each([0.25, 0.1])("preserves member/avoid geometry rescaled by %f", (s) => { + const members = [rectAt(50 * s, 100 * s, 10 * s), rectAt(250 * s, 100 * s, 10 * s)]; + const avoid = [rectAt(150 * s, 100 * s, 10 * s)]; + const outline = computeOutlinePoints(members, avoid, { scale: s }); + expect(outline.length).toBeGreaterThan(3); + expect(pointInPolygon({ x: 50 * s, y: 100 * s }, outline)).toBe(true); + expect(pointInPolygon({ x: 250 * s, y: 100 * s }, outline)).toBe(true); + expect(pointInPolygon({ x: 150 * s, y: 100 * s }, outline)).toBe(false); + }); + + it("keeps a dense zoomed-out group intact where unscaled constants lose it", () => { + // Zoomed-out screen geometry: two 1 px members 6 px apart inside two + // rings of 32 avoid nodes (the dense-graph repro for the vanishing + // outline). Unscaled, the avoid nodes' negative field corrupts the + // outline (a member ends up outside); scaled it hugs both members + // and excludes the ring. + const members = [rectAt(0, 0, 1), rectAt(6, 0, 1)]; + const avoid = []; + for (const radius of [14, 22]) { + for (let i = 0; i < 16; i++) { + const ang = (i / 16) * 2 * Math.PI; + avoid.push(rectAt(3 + radius * Math.cos(ang), radius * Math.sin(ang), 1)); + } + } + + const unscaled = computeOutlinePoints(members, avoid); + const coversBoth = (outline) => + outline.length > 0 && + pointInPolygon({ x: 0, y: 0 }, outline) && + pointInPolygon({ x: 6, y: 0 }, outline); + expect(coversBoth(unscaled)).toBe(false); + + const scaled = computeOutlinePoints(members, avoid, { scale: 0.1 }); + expect(coversBoth(scaled)).toBe(true); + expect(pointInPolygon({ x: 17, y: 0 }, scaled)).toBe(false); + }); + }); }); describe("outlineLabelAnchor", () => { - it("returns the topmost point (smallest y — viewport space is y-down)", () => { + // Axis-aligned diamond-cornered square ring (clockwise in y-down viewport + // space) with a unique extreme vertex per side and centroid (5, 5); each + // extreme's ring neighbors form an axis-aligned tangent. + const ring = [ + { x: 0, y: 0 }, + { x: 5, y: -1 }, // top apex + { x: 10, y: 0 }, + { x: 11, y: 5 }, // right apex + { x: 10, y: 10 }, + { x: 5, y: 11 }, // bottom apex + { x: 0, y: 10 }, + { x: -1, y: 5 }, // left apex + ]; + + it("defaults to the topmost point (smallest y — viewport space is y-down)", () => { const points = [ { x: 5, y: 9 }, { x: 7, y: 2 }, { x: 1, y: 6 }, ]; - expect(outlineLabelAnchor(points)).toEqual({ x: 7, y: 2 }); + expect(outlineLabelAnchor(points)).toMatchObject({ x: 7, y: 2 }); }); it("returns null for empty or missing outlines", () => { expect(outlineLabelAnchor([])).toBeNull(); expect(outlineLabelAnchor(null)).toBeNull(); }); + + it.each([ + ["top", { x: 5, y: -1 }], + ["bottom", { x: 5, y: 11 }], + ["left", { x: -1, y: 5 }], + ["right", { x: 11, y: 5 }], + ])("picks the %s extreme vertex", (placement, expected) => { + expect(outlineLabelAnchor(ring, placement)).toMatchObject(expected); + }); + + it("returns a horizontal tangent angle on horizontal edges", () => { + // Top apex neighbors (0,0)/(10,0) and bottom apex neighbors + // (10,10)/(0,10) are horizontal; bottom's reversed tangent (PI) must + // normalize back to 0 so text stays upright. + expect(outlineLabelAnchor(ring, "top").angle).toBeCloseTo(0); + expect(outlineLabelAnchor(ring, "bottom").angle).toBeCloseTo(0); + }); + + it("returns a vertical tangent angle within [-PI/2, PI/2] on vertical edges", () => { + expect(Math.abs(outlineLabelAnchor(ring, "left").angle)).toBeCloseTo(Math.PI / 2); + expect(Math.abs(outlineLabelAnchor(ring, "right").angle)).toBeCloseTo(Math.PI / 2); + }); + + it.each([ + ["top", { nx: 0, ny: -1 }], + ["bottom", { nx: 0, ny: 1 }], + ["left", { nx: -1, ny: 0 }], + ["right", { nx: 1, ny: 0 }], + ])("normal at the %s extreme points away from the centroid", (placement, normal) => { + const anchor = outlineLabelAnchor(ring, placement); + expect(anchor.nx).toBeCloseTo(normal.nx); + expect(anchor.ny).toBeCloseTo(normal.ny); + }); + + it("center placement returns the vertex centroid with no rotation or normal", () => { + expect(outlineLabelAnchor(ring, "center")).toEqual({ x: 5, y: 5, angle: 0, nx: 0, ny: 0 }); + }); + + it("falls back to top for unknown placements", () => { + expect(outlineLabelAnchor(ring, "diagonal")).toMatchObject({ x: 5, y: -1 }); + }); }); describe("idsKey", () => { @@ -171,9 +269,7 @@ describe("positionsChecksum", () => { describe("styleKey", () => { it("is stable for equal styles and ignores irrelevant fields", () => { const style = { fill: "#403C53", fillOpacity: 0.25, stroke: "#C33D35", label: true }; - expect(styleKey({ ...style, labelCloseToPath: true })).toBe( - styleKey({ ...style, labelCloseToPath: false }), - ); + expect(styleKey({ ...style, members: ["a"] })).toBe(styleKey({ ...style, members: ["b"] })); }); it("changes when a painted field changes", () => { @@ -184,6 +280,12 @@ describe("styleKey", () => { expect(styleKey({ fillOpacity: 0 })).not.toBe(styleKey({ fillOpacity: 0.25 })); }); + it("changes when a label placement knob changes (paint signature must invalidate)", () => { + expect(styleKey({ labelPlacement: "top" })).not.toBe(styleKey({ labelPlacement: "bottom" })); + expect(styleKey({ labelCloseToPath: true })).not.toBe(styleKey({ labelCloseToPath: false })); + expect(styleKey({ labelAutoRotate: true })).not.toBe(styleKey({ labelAutoRotate: false })); + }); + it("distinguishes the literal string \"undefined\" from a missing field", () => { expect(styleKey({ fill: "undefined" })).not.toBe(styleKey({})); }); From f472233ba5e61e40ed863f22a2a394dd8ce5e948 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Wed, 10 Jun 2026 20:48:54 +0200 Subject: [PATCH 12/69] feat(renderer): restore node badges on sigma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - badge data (badge/badges/badgePalette/badgeFontSize) flowed through the style pipeline but was never mapped to sigma attributes nor drawn — badges now render as G6-parity colored pills with white text on the node perimeter (all 12 placements) - badge_clear emits explicit badge:false + empty arrays so mergeNodeAttributes can't leave stale badges - texture->native program transitions clear stale image/fillColor attrs (wrong hover state-texture colors) and restore the fill color - v1 limitation: badges draw in the label pass, so they follow label visibility/thinning --- src/graph/graph_model.js | 30 +++++++ src/graph/label_renderers.js | 62 ++++++++++++- tests/graph-model.test.js | 88 +++++++++++++++++- tests/label-renderers.test.js | 165 +++++++++++++++++++++++++++++++++- 4 files changed, 339 insertions(+), 6 deletions(-) diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index 5c9f17a..10a7caf 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -60,6 +60,7 @@ function nodeAttributesFromStyle(style = {}, type = undefined) { attrs.label = style.labelText == null ? null : String(style.labelText); } Object.assign(attrs, labelStyleAttributes(style)); + Object.assign(attrs, badgeAttributes(style)); if (style.visibility !== undefined) { attrs.hidden = style.visibility === "hidden"; } @@ -68,6 +69,27 @@ function nodeAttributesFromStyle(style = {}, type = undefined) { return attrs; } +/** + * Badge attrs (read by drawNodeLabel). Emitted whenever the style carries + * explicit badge fields — including badge:false / empty arrays — because the + * adapter merges attributes; omitting the keys on a badge_clear would leave + * stale badges in graphology. Missing palette entries get the default badge + * color baked in so the renderer needs no config import. + */ +function badgeAttributes(style) { + if (style.badge === undefined && style.badges === undefined) return {}; + const badges = style.badge ? (style.badges ?? []) : []; + const attrs = { + badge: badges.length > 0, + badges, + badgePalette: badges.map((_, i) => style.badgePalette?.[i] ?? DEFAULTS.NODE.BADGE.COLOR), + }; + if (badges.length > 0) { + attrs.badgeFontSize = style.badgeFontSize ?? DEFAULTS.NODE.BADGE.FONT_SIZE; + } + return attrs; +} + /** * Shape-program attributes for a node: which sigma program draws it, plus * the texture data-URI when the SVG shape program is needed. @@ -93,6 +115,14 @@ function nodeProgramAttributes(style = {}, type) { }); } else { attrs.type = type === "rect" ? "square" : "circle"; + // Texture→native transitions (e.g. border removed) merge over the old + // attrs, so clear exactly what the shape branch sets: a stale fillColor + // corrupts state textures on hover and a stale TRANSPARENT color makes + // the node invisible. The image program skips non-string images, so + // null is safe. + attrs.color = fill; + attrs.fillColor = null; + attrs.image = null; } return attrs; } diff --git a/src/graph/label_renderers.js b/src/graph/label_renderers.js index b8bf1a0..b3153ec 100644 --- a/src/graph/label_renderers.js +++ b/src/graph/label_renderers.js @@ -49,20 +49,76 @@ function resolveSettingsColor(settingsColor, data) { return settingsColor?.color ?? "#000"; } -function drawBackground(context, color, x, y, width, height) { +function drawBackground(context, color, x, y, width, height, radius = BACKGROUND_RADIUS) { context.fillStyle = color; context.beginPath(); if (typeof context.roundRect === "function") { - context.roundRect(x, y, width, height, BACKGROUND_RADIUS); + context.roundRect(x, y, width, height, radius); } else { context.rect(x, y, width, height); } context.fill(); } +// G6 v5 badge parity: a badge is a small colored pill with white text, +// anchored on the node perimeter. Fallbacks mirror DEFAULTS.NODE.BADGE +// (config is intentionally not imported — this module stays dependency-free; +// graph_model.js bakes the configured defaults into the attrs). +const BADGE_TEXT_COLOR = "#FFFFFF"; +const FALLBACK_BADGE_COLOR = "#C33D35"; +const FALLBACK_BADGE_FONT_SIZE = 8; +const BADGE_PADDING = 2; + +/** + * Draw the node's badges as colored pills with white text, each centered on + * the node perimeter per its placement. Called from drawNodeLabel, so badges + * follow label visibility (v1 limitation). + * + * @param {CanvasRenderingContext2D} context + * @param {object} data node display data (x, y, size, badge, badges, badgePalette, badgeFontSize) + * @param {object} settings sigma settings (labelFont) + */ +function drawNodeBadges(context, data, settings) { + if (!data.badge || !Array.isArray(data.badges) || data.badges.length === 0) return; + + const size = Number.isFinite(data.badgeFontSize) + ? data.badgeFontSize + : FALLBACK_BADGE_FONT_SIZE; + context.font = `bold ${size}px ${settings.labelFont}`; + + data.badges.forEach((badge, index) => { + const text = badge?.text == null ? "" : String(badge.text); + if (!text) return; + + const width = context.measureText(text).width; + const boxWidth = width + 2 * BADGE_PADDING; + const boxHeight = size + 2 * BADGE_PADDING; + + // Normalize corner placements onto the perimeter circle. + const [ux, uy] = placementVector(badge.placement); + const norm = Math.hypot(ux, uy) || 1; + const cx = data.x + (ux / norm) * data.size; + const cy = data.y + (uy / norm) * data.size; + + const color = data.badgePalette?.[index] ?? FALLBACK_BADGE_COLOR; + drawBackground( + context, + color, + cx - boxWidth / 2, + cy - boxHeight / 2, + boxWidth, + boxHeight, + boxHeight / 2, // pill: fully rounded ends + ); + context.fillStyle = BADGE_TEXT_COLOR; + context.fillText(text, cx - width / 2, cy + size * 0.35); + }); +} + /** * Node label drawer (sigma `defaultDrawNodeLabel`). G6 parity: default * placement is "bottom" (sigma's default drawer is right-anchored only). + * Also draws the node's badges (see drawNodeBadges) after the label. * * @param {CanvasRenderingContext2D} context * @param {object} data node display data in viewport px (x, y, size, label, label* attrs) @@ -102,6 +158,8 @@ function drawNodeLabel(context, data, settings) { context.fillStyle = color; context.fillText(data.label, boxCenterX - width / 2, boxCenterY + size * 0.35); + + drawNodeBadges(context, data, settings); } /** diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index 95d7f44..45e521f 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -351,10 +351,27 @@ describe("attribute mapping helpers", () => { const rect = nodeAttributesFromStyle({ fill: "#403C53" }, "rect"); expect(circle.type).toBe("circle"); - expect(circle.image).toBeUndefined(); + expect(circle.image).toBeNull(); expect(circle.color).toBe("#403C53"); expect(rect.type).toBe("square"); - expect(rect.image).toBeUndefined(); + expect(rect.image).toBeNull(); + }); + + it("native programs clear texture-only attrs so shape→native merges don't go stale", () => { + // The adapter applies updates via mergeNodeAttributes: a node leaving the + // texture program (e.g. border removed) must null out image/fillColor or + // hover would later read a stale fillColor into its state textures. + const attrs = nodeAttributesFromStyle({ fill: "#403C53" }, "circle"); + + expect(attrs.image).toBeNull(); + expect(attrs.fillColor).toBeNull(); + expect(attrs.color).toBe("#403C53"); // never left at the texture TRANSPARENT + }); + + it("native programs restore the default fill when the style has none", () => { + const attrs = nodeAttributesFromStyle({}, "circle"); + + expect(attrs.color).toBe(DEFAULTS.NODE.FILL_COLOR); }); it("bordered circle/rect route through the texture program (native programs cannot draw borders)", () => { @@ -383,6 +400,73 @@ describe("attribute mapping helpers", () => { }); }); +describe("badge attribute mapping", () => { + const BADGES = [ + { text: "A", placement: "right-top" }, + { text: "B", placement: "left" }, + ]; + + it("maps badge attrs when badges are set", () => { + const attrs = nodeAttributesFromStyle({ + badge: true, + badges: BADGES, + badgePalette: ["#112233", "#445566"], + badgeFontSize: 10, + }); + + expect(attrs).toEqual({ + badge: true, + badges: BADGES, + badgePalette: ["#112233", "#445566"], + badgeFontSize: 10, + }); + }); + + it("omits badge keys entirely when the style carries no badge fields", () => { + expect(nodeAttributesFromStyle({ fill: "#fff" })).toEqual({ color: "#fff" }); + }); + + it("emits badge:false and empty arrays on badge_clear results (not omitted)", () => { + // The adapter merges attributes — omitting the keys would leave stale + // badges in graphology after a badge_clear command. + const attrs = nodeAttributesFromStyle({ badge: false, badges: [], badgePalette: [] }); + + expect(attrs).toEqual({ badge: false, badges: [], badgePalette: [] }); + }); + + it("treats badge:true with no badges as cleared", () => { + expect(nodeAttributesFromStyle({ badge: true, badges: [] })).toEqual({ + badge: false, + badges: [], + badgePalette: [], + }); + }); + + it("bakes the default badge color into missing palette entries", () => { + const attrs = nodeAttributesFromStyle({ + badge: true, + badges: BADGES, + badgePalette: ["#112233"], + }); + + expect(attrs.badgePalette).toEqual(["#112233", DEFAULTS.NODE.BADGE.COLOR]); + expect(attrs.badgeFontSize).toBe(DEFAULTS.NODE.BADGE.FONT_SIZE); + }); + + it("propagates badge attrs into the built graph", () => { + const cache = createMockCache({ + nodes: [makeNode("a", { badge: true, badges: [BADGES[0]] })], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("a", "badge")).toBe(true); + expect(graph.getNodeAttribute("a", "badges")).toEqual([BADGES[0]]); + expect(graph.getNodeAttribute("a", "badgePalette")).toEqual([DEFAULTS.NODE.BADGE.COLOR]); + }); + +}); + describe("reducers — states and hidden handling", () => { function reducerFixture({ nodeType } = {}) { const nodes = [makeNode("a", {}, nodeType), makeNode("b", {}, nodeType)]; diff --git a/tests/label-renderers.test.js b/tests/label-renderers.test.js index ce7a999..52291b7 100644 --- a/tests/label-renderers.test.js +++ b/tests/label-renderers.test.js @@ -1,5 +1,6 @@ import { describe, it, expect } from "vitest"; import { drawNodeLabel, drawEdgeLabel, placementVector } from "../src/graph/label_renderers.js"; +import { DEFAULTS } from "../src/config.js"; // ========================================================================== // Canvas label renderers (Phase 2 label parity). Pure functions of @@ -11,10 +12,9 @@ const CHAR_W = 6; function stubContext() { const calls = []; const record = (name) => (...args) => calls.push([name, ...args]); - return { + const ctx = { calls, font: "", - fillStyle: "", measureText: (text) => ({ width: String(text).length * CHAR_W }), fillText: record("fillText"), save: record("save"), @@ -26,6 +26,17 @@ function stubContext() { rect: record("rect"), fill: record("fill"), }; + // fillStyle assignments are recorded in the call log (badge tests need the + // order of pill/text colors) while reads keep returning the latest value. + let fillStyle = ""; + Object.defineProperty(ctx, "fillStyle", { + get: () => fillStyle, + set: (value) => { + fillStyle = value; + calls.push(["fillStyle", value]); + }, + }); + return ctx; } const SETTINGS = { @@ -58,6 +69,31 @@ describe("placementVector", () => { expect(placementVector(undefined)).toEqual([0, 1]); expect(placementVector("diagonal")).toEqual([0, 0]); }); + + it("maps all 12 badge placements (DEFAULTS.STYLES.NODE_BADGE_PLACEMENTS)", () => { + const expected = { + left: [-1, 0], + right: [1, 0], + top: [0, -1], + bottom: [0, 1], + "left-top": [-1, -1], + "left-bottom": [-1, 1], + "right-top": [1, -1], + "right-bottom": [1, 1], + "top-left": [-1, -1], + "top-right": [1, -1], + "bottom-left": [-1, 1], + "bottom-right": [1, 1], + }; + + // The fixture must stay in sync with the configured placement list. + expect(Object.keys(expected).sort()).toEqual( + [...DEFAULTS.STYLES.NODE_BADGE_PLACEMENTS].sort(), + ); + for (const [placement, vector] of Object.entries(expected)) { + expect(placementVector(placement), placement).toEqual(vector); + } + }); }); describe("drawNodeLabel", () => { @@ -136,6 +172,131 @@ describe("drawNodeLabel", () => { }); }); +describe("drawNodeLabel — badges (G6 v5 parity: colored pill + white text)", () => { + const NODE = { x: 100, y: 100, size: 10, label: "abc" }; + const BADGE_FONT = 8; + const BADGE_PAD = 2; + const badged = (badges, extra = {}) => ({ + ...NODE, + badge: true, + badges, + badgePalette: ["#112233"], + badgeFontSize: BADGE_FONT, + ...extra, + }); + const fillTexts = (ctx) => ctx.calls.filter(([name]) => name === "fillText"); + const fillStyles = (ctx) => + ctx.calls.filter(([name]) => name === "fillStyle").map(([, value]) => value); + + it("draws no badges without badge attrs", () => { + const ctx = stubContext(); + + drawNodeLabel(ctx, NODE, SETTINGS); + + expect(fillTexts(ctx)).toHaveLength(1); // label only + expect(findCall(ctx, "roundRect")).toBeUndefined(); + }); + + it("draws a colored pill with white text on the node perimeter (right placement)", () => { + const ctx = stubContext(); + + drawNodeLabel(ctx, badged([{ text: "B", placement: "right" }]), SETTINGS); + + // Pill: 1-char text (6px) + 2px padding → 10×12 box centered at (110, 100), + // fully rounded ends (radius = half height). + const boxWidth = CHAR_W + 2 * BADGE_PAD; + const boxHeight = BADGE_FONT + 2 * BADGE_PAD; + expect(findCall(ctx, "roundRect").slice(1)).toEqual([ + 110 - boxWidth / 2, + 100 - boxHeight / 2, + boxWidth, + boxHeight, + boxHeight / 2, + ]); + + const texts = fillTexts(ctx); + expect(texts).toHaveLength(2); // label + badge + const [, badgeText, bx, by] = texts[1]; + expect(badgeText).toBe("B"); + expect(bx).toBeCloseTo(110 - CHAR_W / 2); + expect(by).toBeCloseTo(100 + BADGE_FONT * 0.35); + + const styles = fillStyles(ctx); + expect(styles).toContain("#112233"); // pill color from the palette + expect(styles[styles.length - 1]).toBe("#FFFFFF"); // badge text drawn white, last + expect(ctx.font).toBe(`bold ${BADGE_FONT}px Arial`); + }); + + it("normalizes corner placements onto the perimeter circle (top-right)", () => { + const ctx = stubContext(); + + drawNodeLabel(ctx, badged([{ text: "B", placement: "top-right" }]), SETTINGS); + + const [, , bx, by] = fillTexts(ctx)[1]; + const d = NODE.size / Math.SQRT2; + expect(bx).toBeCloseTo(100 + d - CHAR_W / 2); + expect(by).toBeCloseTo(100 - d + BADGE_FONT * 0.35); + }); + + it("draws one pill per badge and falls back to the default badge color", () => { + const ctx = stubContext(); + + drawNodeLabel( + ctx, + badged([ + { text: "A", placement: "left" }, + { text: "B", placement: "right" }, + ]), + SETTINGS, + ); + + expect(ctx.calls.filter(([name]) => name === "roundRect")).toHaveLength(2); + expect(fillTexts(ctx)).toHaveLength(3); // label + 2 badges + const styles = fillStyles(ctx); + expect(styles).toContain("#112233"); // palette entry for badge 0 + expect(styles).toContain(DEFAULTS.NODE.BADGE.COLOR); // fallback for badge 1 + }); + + it("skips empty-text badges and ignores badge attrs when badge is false", () => { + const empty = stubContext(); + drawNodeLabel(empty, badged([{ text: "", placement: "left" }]), SETTINGS); + expect(fillTexts(empty)).toHaveLength(1); + + const off = stubContext(); + drawNodeLabel( + off, + { ...badged([{ text: "B", placement: "left" }]), badge: false }, + SETTINGS, + ); + expect(fillTexts(off)).toHaveLength(1); + expect(findCall(off, "roundRect")).toBeUndefined(); + }); + + it("follows label visibility (v1: no label → no badges)", () => { + const ctx = stubContext(); + + drawNodeLabel( + ctx, + { ...badged([{ text: "B", placement: "right" }]), label: null }, + SETTINGS, + ); + + expect(ctx.calls).toEqual([]); + }); + + it("falls back to a finite badge font size", () => { + const ctx = stubContext(); + + drawNodeLabel( + ctx, + badged([{ text: "B", placement: "right" }], { badgeFontSize: NaN }), + SETTINGS, + ); + + expect(ctx.font).toBe("bold 8px Arial"); + }); +}); + describe("drawEdgeLabel", () => { const SOURCE = { x: 0, y: 0, size: 5 }; const TARGET = { x: 100, y: 0, size: 5 }; From 755009bd00af29c9e6d4fbdea6bc7e67fe312fdd Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 07:30:35 +0200 Subject: [PATCH 13/69] feat(layout): live-animating ForceAtlas2 via web-worker supervisor - export FA2Layout from the node-safe graphology vendor bundle (worker module only touches Worker/window.URL at instantiation) - executeLayout force branch: where Worker exists, run the FA2 worker supervisor for a bounded time budget (min(5000, 500 + 2*order) ms) so the layout animates live without blocking the main thread; stop()+kill() in finally; per-graph re-entrancy guard - node (vitest) keeps the deterministic synchronous forceAtlas2.assign path unchanged; test seam via optional ForceSupervisor override - 5 new tests (818 total green); perf gates unaffected (benchmark fixture carries persisted positions, force never runs during timed load) --- src/graph/layout_algorithms.js | 61 +++++++++++- src/lib/graphology.bundle.mjs | 14 +-- src/package/vendor_entry_graphology.mjs | 3 + tests/layout-algorithms.test.js | 124 +++++++++++++++++++++++- 4 files changed, 191 insertions(+), 11 deletions(-) diff --git a/src/graph/layout_algorithms.js b/src/graph/layout_algorithms.js index 8515a96..65a1daa 100644 --- a/src/graph/layout_algorithms.js +++ b/src/graph/layout_algorithms.js @@ -9,6 +9,7 @@ import { circular, forceAtlas2, + FA2Layout, RadialLayout, ConcentricLayout, MDSLayout, @@ -17,6 +18,50 @@ import { const FORCE_ITERATIONS = 200; const GRID_SPACING = 100; +// Live force-layout time budget. FA2 has no usable convergence signal, so the +// worker simply runs for a bounded wall-clock window: a base so small graphs +// settle visibly, a per-node share so larger graphs get proportionally more +// time, and a hard cap so huge graphs never hold the render pipeline hostage +// (render() awaits executeLayout before persisting positions). +const FORCE_ANIMATE_BASE_MS = 500; +const FORCE_ANIMATE_PER_NODE_MS = 2; +const FORCE_ANIMATE_MAX_MS = 5000; + +/** Graphs with a worker-supervised force layout currently in flight. */ +const animatingGraphs = new WeakSet(); + +/** + * Run FA2 through the web-worker supervisor for a bounded time window. + * Sigma is bound to the same graphology instance, so every per-tick position + * assign from the supervisor triggers a refresh — the layout animates live + * without blocking the main thread. Resolves once the window elapses and the + * worker is killed. Re-entrant calls for a graph that is already animating + * are no-ops (the running supervisor uses the same inferred settings). + * @param {import('graphology').default} graph + * @param {typeof FA2Layout} Supervisor + * @returns {Promise} + */ +async function executeForceAnimated(graph, Supervisor) { + if (animatingGraphs.has(graph)) return; + animatingGraphs.add(graph); + const budgetMs = Math.min( + FORCE_ANIMATE_MAX_MS, + FORCE_ANIMATE_BASE_MS + graph.order * FORCE_ANIMATE_PER_NODE_MS, + ); + let layout = null; + try { + layout = new Supervisor(graph, { settings: forceAtlas2.inferSettings(graph) }); + layout.start(); + await new Promise((resolve) => setTimeout(resolve, budgetMs)); + } finally { + if (layout) { + layout.stop(); + layout.kill(); // terminates the worker + unbinds the graph listeners + } + animatingGraphs.delete(graph); + } +} + const ANTV_LAYOUTS = { radial: RadialLayout, concentric: ConcentricLayout, @@ -55,9 +100,12 @@ async function executeAntvLayout(graph, LayoutClass, options) { * @param {import('graphology').default} graph * @param {{type?: string}|null|undefined} spec type + the LAYOUT_INTERNALS * options for it; missing/unknown type falls back to forceAtlas2 + * @param {{ForceSupervisor?: typeof FA2Layout}} [testOverrides] test seam: + * substitute the FA2 worker supervisor class (vitest has no Worker global, + * so the animated branch is otherwise unreachable under node) * @returns {Promise} */ -export async function executeLayout(graph, spec) { +export async function executeLayout(graph, spec, testOverrides = {}) { const { type, ...options } = spec ?? {}; if (type === "circular") { // graphology's circular ignores the G6-era startRadius/endRadius options. @@ -84,7 +132,16 @@ export async function executeLayout(graph, spec) { await executeAntvLayout(graph, AntvLayout, options); return; } - // 'force' and everything else → forceAtlas2. + // 'force' and everything else → forceAtlas2. Where Worker exists (browser, + // Electron renderer) the FA2 worker supervisor animates the layout live; + // under node (vitest) Worker is undefined → deterministic synchronous path. + const Supervisor = + testOverrides.ForceSupervisor ?? + (typeof Worker === "undefined" ? null : FA2Layout); + if (Supervisor) { + await executeForceAnimated(graph, Supervisor); + return; + } forceAtlas2.assign(graph, { iterations: FORCE_ITERATIONS, settings: forceAtlas2.inferSettings(graph), diff --git a/src/lib/graphology.bundle.mjs b/src/lib/graphology.bundle.mjs index e9282bd..2b82936 100644 --- a/src/lib/graphology.bundle.mjs +++ b/src/lib/graphology.bundle.mjs @@ -1,12 +1,12 @@ -var _o=Object.create;var yr=Object.defineProperty;var $o=Object.getOwnPropertyDescriptor;var Ao=Object.getOwnPropertyNames;var Ro=Object.getPrototypeOf,No=Object.prototype.hasOwnProperty;var Vn=r=>{throw TypeError(r)};var Lo=(r,t,e)=>t in r?yr(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var qt=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports),rn=(r,t)=>{for(var e in t)yr(r,e,{get:t[e],enumerable:!0})},To=(r,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of Ao(t))!No.call(r,u)&&u!==e&&yr(r,u,{get:()=>t[u],enumerable:!(i=$o(t,u))||i.enumerable});return r};var nn=(r,t,e)=>(e=r!=null?_o(Ro(r)):{},To(t||!r||!r.__esModule?yr(e,"default",{value:r,enumerable:!0}):e,r));var Bn=(r,t,e)=>Lo(r,typeof t!="symbol"?t+"":t,e),sn=(r,t,e)=>t.has(r)||Vn("Cannot "+e);var se=(r,t,e)=>(sn(r,t,"read from private field"),e?e.call(r):t.get(r)),on=(r,t,e)=>t.has(r)?Vn("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),mr=(r,t,e,i)=>(sn(r,t,"write to private field"),i?i.call(r,e):t.set(r,e),e),un=(r,t,e)=>(sn(r,t,"access private method"),e);var ni=qt((Nh,an)=>{"use strict";var Oe=typeof Reflect=="object"?Reflect:null,Kn=Oe&&typeof Oe.apply=="function"?Oe.apply:function(t,e,i){return Function.prototype.apply.call(t,e,i)},br;Oe&&typeof Oe.ownKeys=="function"?br=Oe.ownKeys:Object.getOwnPropertySymbols?br=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:br=function(t){return Object.getOwnPropertyNames(t)};function Go(r){console&&console.warn&&console.warn(r)}var Xn=Number.isNaN||function(t){return t!==t};function gt(){gt.init.call(this)}an.exports=gt;an.exports.once=Fo;gt.EventEmitter=gt;gt.prototype._events=void 0;gt.prototype._eventsCount=0;gt.prototype._maxListeners=void 0;var Yn=10;function Er(r){if(typeof r!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof r)}Object.defineProperty(gt,"defaultMaxListeners",{enumerable:!0,get:function(){return Yn},set:function(r){if(typeof r!="number"||r<0||Xn(r))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+r+".");Yn=r}});gt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};gt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||Xn(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function Qn(r){return r._maxListeners===void 0?gt.defaultMaxListeners:r._maxListeners}gt.prototype.getMaxListeners=function(){return Qn(this)};gt.prototype.emit=function(t){for(var e=[],i=1;i0&&(c=e[0]),c instanceof Error)throw c;var f=new Error("Unhandled error."+(c?" ("+c.message+")":""));throw f.context=c,f}var p=h[t];if(p===void 0)return!1;if(typeof p=="function")Kn(p,this,e);else for(var d=p.length,v=ei(p,d),i=0;i0&&c.length>u&&!c.warned){c.warned=!0;var f=new Error("Possible EventEmitter memory leak detected. "+c.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");f.name="MaxListenersExceededWarning",f.emitter=r,f.type=t,f.count=c.length,Go(f)}return r}gt.prototype.addListener=function(t,e){return Jn(this,t,e,!1)};gt.prototype.on=gt.prototype.addListener;gt.prototype.prependListener=function(t,e){return Jn(this,t,e,!0)};function Oo(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Zn(r,t,e){var i={fired:!1,wrapFn:void 0,target:r,type:t,listener:e},u=Oo.bind(i);return u.listener=e,i.wrapFn=u,u}gt.prototype.once=function(t,e){return Er(e),this.on(t,Zn(this,t,e)),this};gt.prototype.prependOnceListener=function(t,e){return Er(e),this.prependListener(t,Zn(this,t,e)),this};gt.prototype.removeListener=function(t,e){var i,u,h,c,f;if(Er(e),u=this._events,u===void 0)return this;if(i=u[t],i===void 0)return this;if(i===e||i.listener===e)--this._eventsCount===0?this._events=Object.create(null):(delete u[t],u.removeListener&&this.emit("removeListener",t,i.listener||e));else if(typeof i!="function"){for(h=-1,c=i.length-1;c>=0;c--)if(i[c]===e||i[c].listener===e){f=i[c].listener,h=c;break}if(h<0)return this;h===0?i.shift():Co(i,h),i.length===1&&(u[t]=i[0]),u.removeListener!==void 0&&this.emit("removeListener",t,f||e)}return this};gt.prototype.off=gt.prototype.removeListener;gt.prototype.removeAllListeners=function(t){var e,i,u;if(i=this._events,i===void 0)return this;if(i.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):i[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete i[t]),this;if(arguments.length===0){var h=Object.keys(i),c;for(u=0;u=0;u--)this.removeListener(t,e[u]);return this};function Hn(r,t,e){var i=r._events;if(i===void 0)return[];var u=i[t];return u===void 0?[]:typeof u=="function"?e?[u.listener||u]:[u]:e?Po(u):ei(u,u.length)}gt.prototype.listeners=function(t){return Hn(this,t,!0)};gt.prototype.rawListeners=function(t){return Hn(this,t,!1)};gt.listenerCount=function(r,t){return typeof r.listenerCount=="function"?r.listenerCount(t):ti.call(r,t)};gt.prototype.listenerCount=ti;function ti(r){var t=this._events;if(t!==void 0){var e=t[r];if(typeof e=="function")return 1;if(e!==void 0)return e.length}return 0}gt.prototype.eventNames=function(){return this._eventsCount>0?br(this._events):[]};function ei(r,t){for(var e=new Array(t),i=0;i{function Ku(r){return!r||typeof r!="object"||typeof r=="function"||Array.isArray(r)||r instanceof Set||r instanceof Map||r instanceof RegExp||r instanceof Date}function yi(r,t){r=r||{};var e={};for(var i in t){var u=r[i],h=t[i];if(!Ku(h)){e[i]=yi(u,h);continue}u===void 0?e[i]=h:e[i]=u}return e}mi.exports=yi});var Ue=qt((Gh,bi)=>{bi.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var Si=qt((Oh,xi)=>{function Ei(r){return function(t,e){return t+Math.floor(r()*(e-t+1))}}var vi=Ei(Math.random);vi.createRandom=Ei;xi.exports=vi});var Ii=qt((Ch,Di)=>{var Yu=Si().createRandom;function ki(r){var t=Yu(r);return function(e){for(var i=e.length,u=i-1,h=-1;++h{var Xu=Ze(),Qu=Ue(),Ju=Ii(),Zu={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function Bt(r,t,e,i,u){this.wrappedCircle=u||null,this.children={},this.countChildren=0,this.id=r||null,this.next=null,this.previous=null,this.x=t||null,this.y=e||null,u?this.r=1010101:this.r=i||999}Bt.prototype.hasChildren=function(){return this.countChildren>0};Bt.prototype.addChild=function(r,t){this.children[r]=t,++this.countChildren};Bt.prototype.getChild=function(r){if(!this.children.hasOwnProperty(r)){var t=new Bt;this.children[r]=t,++this.countChildren}return this.children[r]};Bt.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var r=this;for(var t in r.children){var e=r.children[t];e.x+=r.x,e.y+=r.y,e.applyPositionToChildren()}}};function Ai(r,t,e){for(var i in t.children){var u=t.children[i];u.hasChildren()?Ai(r,u,e):e[u.id]={x:u.x,y:u.y}}}function jr(r,t){var e=r.r-t.r,i=t.x-r.x,u=t.y-r.y;return e<0||e*e0&&e*e>i*i+u*u}function gn(r,t){for(var e=0;ep?(u=(d+p-h)/(2*d),f=Math.sqrt(Math.max(0,p/d-u*u)),e.x=r.x-u*i-f*c,e.y=r.y-u*c+f*i):(u=(d+h-p)/(2*d),f=Math.sqrt(Math.max(0,h/d-u*u)),e.x=t.x+u*i-f*c,e.y=t.y+u*c+f*i)):(e.x=t.x+e.r,e.y=t.y)}function $i(r,t){var e=r.r+t.r-1e-6,i=t.x-r.x,u=t.y-r.y;return e>0&&e*e>i*i+u*u}function na(r,t){var e=r.length;if(e===0)return 0;var i,u,h,c,f,p,d,v,x,E;if(i=r[0],i.x=0,i.y=0,e<=1)return i.r;if(u=r[1],i.x=-u.r,u.x=i.r,u.y=0,e<=2)return i.r+u.r;h=r[2],_i(u,i,h),i=new Bt(null,null,null,null,i),u=new Bt(null,null,null,null,u),h=new Bt(null,null,null,null,h),i.next=h.previous=u,u.next=i.previous=h,h.next=u.previous=i;t:for(p=3;p{var sa=Ze(),oa=Ue(),ua={dimensions:["x","y"],center:.5,scale:1};function Pi(r,t,e){if(!oa(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=sa(e,ua);var i=e.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=e.center,h=e.scale,c=Math.PI*2,f=(u-.5)*h,p=t.order,d=i[0],v=i[1];function x(_,N){return N[d]=h*Math.cos(_*c/p)+f,N[v]=h*Math.sin(_*c/p)+f,N}var E=0;if(!r){var M={};return t.forEachNode(function(_){M[_]=x(E++,{})}),M}t.updateEachNodeAttributes(function(_,N){return x(E++,N),N},{attributes:i})}var Fi=Pi.bind(null,!1);Fi.assign=Pi.bind(null,!0);zi.exports=Fi});var Bi=qt((zh,Vi)=>{var aa=Ze(),ha=Ue(),ca={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function qi(r,t,e){if(!ha(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=aa(e,ca);var i=e.dimensions;if(!Array.isArray(i)||i.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=i.length,h=e.center,c=e.rng,f=e.scale,p=(h-.5)*f;function d(x){for(var E=0;E{var la=Ze(),fa=Ue(),da=Math.PI/180,ga={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function Ki(r,t,e,i){if(!fa(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");i=la(i,ga),i.degrees&&(e*=da);var u=i.dimensions;if(!Array.isArray(u)||u.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return r?void 0:{};var h=u[0],c=u[1],f=0,p=0;if(!i.centeredOnZero){var d=1/0,v=-1/0,x=1/0,E=-1/0;t.forEachNode(function(q,L){var z=L[h],K=L[c];zv&&(v=z),KE&&(E=K)}),f=(d+v)/2,p=(x+E)/2}var M=Math.cos(e),_=Math.sin(e);function N(q){var L=q[h],z=q[c];return q[h]=f+(L-f)*M-(z-p)*_,q[c]=p+(L-f)*_+(z-p)*M,q}if(!r){var C={};return t.forEachNode(function(q,L){var z={};z[h]=L[h],z[c]=L[c],C[q]=N(z)}),C}t.updateEachNodeAttributes(function(q,L){return N(L),L},{attributes:u})}var Yi=Ki.bind(null,!1);Yi.assign=Ki.bind(null,!0);Xi.exports=Yi});var Ji=qt(tr=>{tr.circlepack=Ci();tr.circular=Ui();tr.random=Bi();tr.rotation=Qi()});var Hi=qt(_r=>{function pa(r){return typeof r!="number"||isNaN(r)?1:r}function wa(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getNodeAttributes(f))},e.fromEntry=function(c,f){return u(f)}):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){return i(r(f,c.getNodeAttributes(f)))},e.fromEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h),e}function Zi(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getEdgeAttributes(f))},e.fromEntry=function(c,f){return u(f)},e.fromPartialEntry=e.fromEntry,e.fromMinimalEntry=e.fromEntry):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){var p=c.extremities(f);return i(r(f,c.getEdgeAttributes(f),p[0],p[1],c.getNodeAttributes(p[0]),c.getNodeAttributes(p[1]),c.isUndirected(f)))},e.fromEntry=function(c,f,p,d,v,x,E){return i(r(c,f,p,d,v,x,E))},e.fromPartialEntry=function(c,f,p,d){return i(r(c,f,p,d))},e.fromMinimalEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h,e.fromMinimalEntry=h),e}_r.createNodeValueGetter=wa;_r.createEdgeValueGetter=Zi;_r.createEdgeWeightGetter=function(r){return Zi(r,pa)}});var is=qt((Vh,ns)=>{var At=0,St=1,ct=2,lt=3,Ee=4,ve=5,ft=6,ts=7,$r=8,es=9,ya=0,ma=1,ba=2,Tt=0,re=1,Wt=2,Ae=3,xe=4,Mt=5,Kt=6,le=7,fe=8,rs=3,ue=10,Ea=3,zt=9,pn=10;ns.exports=function(t,e,i){var u,h,c,f,p,d,v,x,E,M,_=e.length,N=i.length,C=t.adjustSizes,q=t.barnesHutTheta*t.barnesHutTheta,L,z,K,P,it,T,O,j=[];for(c=0;c<_;c+=ue)e[c+Ee]=e[c+ct],e[c+ve]=e[c+lt],e[c+ct]=0,e[c+lt]=0;if(t.outboundAttractionDistribution){for(L=0,c=0;c<_;c+=ue)L+=e[c+ft];L/=_/ue}if(t.barnesHutOptimize){var rt=1/0,at=-1/0,pt=1/0,_t=-1/0,$t,Yt,Xt;for(c=0;c<_;c+=ue)rt=Math.min(rt,e[c+At]),at=Math.max(at,e[c+At]),pt=Math.min(pt,e[c+St]),_t=Math.max(_t,e[c+St]);var Ut=at-rt,Qt=_t-pt;for(Ut>Qt?(pt-=(Ut-Qt)/2,_t=pt+Ut):(rt-=(Qt-Ut)/2,at=rt+Qt),j[0+Tt]=-1,j[0+re]=(rt+at)/2,j[0+Wt]=(pt+_t)/2,j[0+Ae]=Math.max(at-rt,_t-pt),j[0+xe]=-1,j[0+Mt]=-1,j[0+Kt]=0,j[0+le]=0,j[0+fe]=0,u=1,c=0;c<_;c+=ue)for(h=0,Xt=rs;;)if(j[h+Mt]>=0){e[c+At]=0)if(T=Math.pow(e[c+At]-j[h+le],2)+Math.pow(e[c+St]-j[h+fe],2),M=j[h+Ae],4*M*M/T0?(O=z*e[c+ft]*j[h+Kt]/T,e[c+ct]+=K*O,e[c+lt]+=P*O):T<0&&(O=-z*e[c+ft]*j[h+Kt]/Math.sqrt(T),e[c+ct]+=K*O,e[c+lt]+=P*O):T>0&&(O=z*e[c+ft]*j[h+Kt]/T,e[c+ct]+=K*O,e[c+lt]+=P*O),h=j[h+xe],h<0)break;continue}else{h=j[h+Mt];continue}else{if(d=j[h+Tt],d>=0&&d!==c&&(K=e[c+At]-e[d+At],P=e[c+St]-e[d+St],T=K*K+P*P,C===!0?T>0?(O=z*e[c+ft]*e[d+ft]/T,e[c+ct]+=K*O,e[c+lt]+=P*O):T<0&&(O=-z*e[c+ft]*e[d+ft]/Math.sqrt(T),e[c+ct]+=K*O,e[c+lt]+=P*O):T>0&&(O=z*e[c+ft]*e[d+ft]/T,e[c+ct]+=K*O,e[c+lt]+=P*O)),h=j[h+xe],h<0)break;continue}else for(z=t.scalingRatio,f=0;f<_;f+=ue)for(p=0;p0?(O=z*e[f+ft]*e[p+ft]/T/T,e[f+ct]+=K*O,e[f+lt]+=P*O,e[p+ct]-=K*O,e[p+lt]-=P*O):T<0&&(O=100*z*e[f+ft]*e[p+ft],e[f+ct]+=K*O,e[f+lt]+=P*O,e[p+ct]-=K*O,e[p+lt]-=P*O)):(T=Math.sqrt(K*K+P*P),T>0&&(O=z*e[f+ft]*e[p+ft]/T/T,e[f+ct]+=K*O,e[f+lt]+=P*O,e[p+ct]-=K*O,e[p+lt]-=P*O));for(E=t.gravity/t.scalingRatio,z=t.scalingRatio,c=0;c<_;c+=ue)O=0,K=e[c+At],P=e[c+St],T=Math.sqrt(Math.pow(K,2)+Math.pow(P,2)),t.strongGravityMode?T>0&&(O=z*e[c+ft]*E):T>0&&(O=z*e[c+ft]*E/T),e[c+ct]-=K*O,e[c+lt]-=P*O;for(z=1*(t.outboundAttractionDistribution?L:1),v=0;v0&&(O=-z*it*Math.log(1+T)/T/e[f+ft]):T>0&&(O=-z*it*Math.log(1+T)/T):t.outboundAttractionDistribution?T>0&&(O=-z*it/e[f+ft]):T>0&&(O=-z*it)):(T=Math.sqrt(Math.pow(K,2)+Math.pow(P,2)),t.linLogMode?t.outboundAttractionDistribution?T>0&&(O=-z*it*Math.log(1+T)/T/e[f+ft]):T>0&&(O=-z*it*Math.log(1+T)/T):t.outboundAttractionDistribution?(T=1,O=-z*it/e[f+ft]):(T=1,O=-z*it)),T>0&&(e[f+ct]+=K*O,e[f+lt]+=P*O,e[p+ct]-=K*O,e[p+lt]-=P*O);var ge,je,Le,et,_e,Te;if(C===!0)for(c=0;c<_;c+=ue)e[c+es]!==1&&(ge=Math.sqrt(Math.pow(e[c+ct],2)+Math.pow(e[c+lt],2)),ge>pn&&(e[c+ct]=e[c+ct]*pn/ge,e[c+lt]=e[c+lt]*pn/ge),je=e[c+ft]*Math.sqrt((e[c+Ee]-e[c+ct])*(e[c+Ee]-e[c+ct])+(e[c+ve]-e[c+lt])*(e[c+ve]-e[c+lt])),Le=Math.sqrt((e[c+Ee]+e[c+ct])*(e[c+Ee]+e[c+ct])+(e[c+ve]+e[c+lt])*(e[c+ve]+e[c+lt]))/2,et=.1*Math.log(1+Le)/(1+Math.sqrt(je)),_e=e[c+At]+e[c+ct]*(et/t.slowDown),e[c+At]=_e,Te=e[c+St]+e[c+lt]*(et/t.slowDown),e[c+St]=Te);else for(c=0;c<_;c+=ue)e[c+es]!==1&&(je=e[c+ft]*Math.sqrt((e[c+Ee]-e[c+ct])*(e[c+Ee]-e[c+ct])+(e[c+ve]-e[c+lt])*(e[c+ve]-e[c+lt])),Le=Math.sqrt((e[c+Ee]+e[c+ct])*(e[c+Ee]+e[c+ct])+(e[c+ve]+e[c+lt])*(e[c+ve]+e[c+lt]))/2,et=e[c+ts]*Math.log(1+Le)/(1+Math.sqrt(je)),e[c+ts]=Math.min(1,Math.sqrt(et*(Math.pow(e[c+ct],2)+Math.pow(e[c+lt],2))/(1+Math.sqrt(je)))),_e=e[c+At]+e[c+ct]*(et/t.slowDown),e[c+At]=_e,Te=e[c+St]+e[c+lt]*(et/t.slowDown),e[c+St]=Te);return{}}});var os=qt(Se=>{var er=10,ss=3;Se.assign=function(r){r=r||{};var t=Array.prototype.slice.call(arguments).slice(1),e,i,u;for(e=0,u=t.length;e=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in r&&typeof r.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in r&&!(typeof r.gravity=="number"&&r.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in r&&!(typeof r.slowDown=="number"||r.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in r&&typeof r.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in r&&!(typeof r.barnesHutTheta=="number"&&r.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};Se.graphToByteArrays=function(r,t){var e=r.order,i=r.size,u={},h,c=new Float32Array(e*er),f=new Float32Array(i*ss);return h=0,r.forEachNode(function(p,d){u[p]=h,c[h]=d.x,c[h+1]=d.y,c[h+2]=0,c[h+3]=0,c[h+4]=0,c[h+5]=0,c[h+6]=1,c[h+7]=1,c[h+8]=d.size||1,c[h+9]=d.fixed?1:0,h+=er}),h=0,r.forEachEdge(function(p,d,v,x,E,M,_){var N=u[v],C=u[x],q=t(p,d,v,x,E,M,_);c[N+6]+=q,c[C+6]+=q,f[h]=N,f[h+1]=C,f[h+2]=q,h+=ss}),{nodes:c,edges:f}};Se.assignLayoutChanges=function(r,t,e){var i=0;r.updateEachNodeAttributes(function(u,h){return h.x=t[i],h.y=t[i+1],i+=er,e?e(u,h):h})};Se.readGraphPositions=function(r,t){var e=0;r.forEachNode(function(i,u){t[e]=u.x,t[e+1]=u.y,e+=er})};Se.collectLayoutChanges=function(r,t,e){for(var i=r.nodes(),u={},h=0,c=0,f=t.length;h{us.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var ls=qt((Yh,cs)=>{var va=Ue(),xa=Hi().createEdgeWeightGetter,Sa=is(),rr=os(),ka=as();function hs(r,t,e){if(!va(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof e=="number"&&(e={iterations:e});var i=e.iterations;if(typeof i!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(i<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var u=xa("getEdgeWeight"in e?e.getEdgeWeight:"weight").fromEntry,h=typeof e.outputReducer=="function"?e.outputReducer:null,c=rr.assign({},ka,e.settings),f=rr.validateSettings(c);if(f)throw new Error("graphology-layout-forceatlas2: "+f.message);var p=rr.graphToByteArrays(t,u),d;for(d=0;d2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var wn=hs.bind(null,!1);wn.assign=hs.bind(null,!0);wn.inferSettings=Ma;cs.exports=wn});var ui=nn(ni(),1);function Uo(){let r=arguments[0];for(let t=1,e=arguments.length;tr++}function me(){let r=arguments,t=null,e=-1;return{[Symbol.iterator](){return this},next(){let i=null;do{if(t===null){if(e++,e>=r.length)return{done:!0};t=r[e][Symbol.iterator]()}if(i=t.next(),i.done){t=null;continue}break}while(!0);return i}}}function Pe(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var Je=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},Q=class r extends Je{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},V=class r extends Je{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},tt=class r extends Je{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}};function hi(r,t){this.key=r,this.attributes=t,this.clear()}hi.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function ci(r,t){this.key=r,this.attributes=t,this.clear()}ci.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function li(r,t){this.key=r,this.attributes=t,this.clear()}li.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function Fe(r,t,e,i,u){this.key=t,this.attributes=u,this.undirected=r,this.source=e,this.target=i}Fe.prototype.attach=function(){let r="out",t="in";this.undirected&&(r=t="undirected");let e=this.source.key,i=this.target.key;this.source[r][i]=this,!(this.undirected&&e===i)&&(this.target[t][e]=this)};Fe.prototype.attachMulti=function(){let r="out",t="in",e=this.source.key,i=this.target.key;this.undirected&&(r=t="undirected");let u=this.source[r],h=u[i];if(typeof h>"u"){u[i]=this,this.undirected&&e===i||(this.target[t][e]=this);return}h.previous=this,this.next=h,u[i]=this,this.target[t][e]=this};Fe.prototype.detach=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),delete this.source[e][t],delete this.target[i][r]};Fe.prototype.detachMulti=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[e][t],delete this.target[i][r]):(this.next.previous=void 0,this.source[e][t]=this.next,this.target[i][r]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var fi=0,di=1,Wo=2,gi=3;function be(r,t,e,i,u,h,c){let f,p,d,v;if(i=""+i,e===fi){if(f=r._nodes.get(i),!f)throw new V(`Graph.${t}: could not find the "${i}" node in the graph.`);d=u,v=h}else if(e===gi){if(u=""+u,p=r._edges.get(u),!p)throw new V(`Graph.${t}: could not find the "${u}" edge in the graph.`);let x=p.source.key,E=p.target.key;if(i===x)f=p.target;else if(i===E)f=p.source;else throw new V(`Graph.${t}: the "${i}" node is not attached to the "${u}" edge (${x}, ${E}).`);d=h,v=c}else{if(p=r._edges.get(i),!p)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`);e===di?f=p.source:f=p.target,d=u,v=h}return[f,d,v]}function Vo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);return c.attributes[f]}}function Bo(r,t,e){r.prototype[t]=function(i,u){let[h]=be(this,t,e,i,u);return h.attributes}}function Ko(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);return c.attributes.hasOwnProperty(f)}}function Yo(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,p,d]=be(this,t,e,i,u,h,c);return f.attributes[p]=d,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:p}),this}}function Xo(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,p,d]=be(this,t,e,i,u,h,c);if(typeof d!="function")throw new Q(`Graph.${t}: updater should be a function.`);let v=f.attributes,x=d(v[p]);return v[p]=x,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:p}),this}}function Qo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);return delete c.attributes[f],this.emit("nodeAttributesUpdated",{key:c.key,type:"remove",attributes:c.attributes,name:f}),this}}function Jo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);if(!Pt(f))throw new Q(`Graph.${t}: provided attributes are not a plain object.`);return c.attributes=f,this.emit("nodeAttributesUpdated",{key:c.key,type:"replace",attributes:c.attributes}),this}}function Zo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);if(!Pt(f))throw new Q(`Graph.${t}: provided attributes are not a plain object.`);return Lt(c.attributes,f),this.emit("nodeAttributesUpdated",{key:c.key,type:"merge",attributes:c.attributes,data:f}),this}}function Ho(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=be(this,t,e,i,u,h);if(typeof f!="function")throw new Q(`Graph.${t}: provided updater is not a function.`);return c.attributes=f(c.attributes),this.emit("nodeAttributesUpdated",{key:c.key,type:"update",attributes:c.attributes}),this}}var tu=[{name:r=>`get${r}Attribute`,attacher:Vo},{name:r=>`get${r}Attributes`,attacher:Bo},{name:r=>`has${r}Attribute`,attacher:Ko},{name:r=>`set${r}Attribute`,attacher:Yo},{name:r=>`update${r}Attribute`,attacher:Xo},{name:r=>`remove${r}Attribute`,attacher:Qo},{name:r=>`replace${r}Attributes`,attacher:Jo},{name:r=>`merge${r}Attributes`,attacher:Zo},{name:r=>`update${r}Attributes`,attacher:Ho}];function eu(r){tu.forEach(function({name:t,attacher:e}){e(r,t("Node"),fi),e(r,t("Source"),di),e(r,t("Target"),Wo),e(r,t("Opposite"),gi)})}function ru(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes[u]}}function nu(r,t,e){r.prototype[t]=function(i){let u;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let h=""+i,c=""+arguments[1];if(u=ee(this,h,c,e),!u)throw new V(`Graph.${t}: could not find an edge for the given path ("${h}" - "${c}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,u=this._edges.get(i),!u)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return u.attributes}}function iu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes.hasOwnProperty(u)}}function su(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,p=""+u;if(u=arguments[2],h=arguments[3],c=ee(this,f,p,e),!c)throw new V(`Graph.${t}: could not find an edge for the given path ("${f}" - "${p}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return c.attributes[u]=h,this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function ou(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,p=""+u;if(u=arguments[2],h=arguments[3],c=ee(this,f,p,e),!c)throw new V(`Graph.${t}: could not find an edge for the given path ("${f}" - "${p}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof h!="function")throw new Q(`Graph.${t}: updater should be a function.`);return c.attributes[u]=h(c.attributes[u]),this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function uu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return delete h.attributes[u],this.emit("edgeAttributesUpdated",{key:h.key,type:"remove",attributes:h.attributes,name:u}),this}}function au(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!Pt(u))throw new Q(`Graph.${t}: provided attributes are not a plain object.`);return h.attributes=u,this.emit("edgeAttributesUpdated",{key:h.key,type:"replace",attributes:h.attributes}),this}}function hu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!Pt(u))throw new Q(`Graph.${t}: provided attributes are not a plain object.`);return Lt(h.attributes,u),this.emit("edgeAttributesUpdated",{key:h.key,type:"merge",attributes:h.attributes,data:u}),this}}function cu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new tt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new tt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=ee(this,c,f,e),!h)throw new V(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new tt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new V(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof u!="function")throw new Q(`Graph.${t}: provided updater is not a function.`);return h.attributes=u(h.attributes),this.emit("edgeAttributesUpdated",{key:h.key,type:"update",attributes:h.attributes}),this}}var lu=[{name:r=>`get${r}Attribute`,attacher:ru},{name:r=>`get${r}Attributes`,attacher:nu},{name:r=>`has${r}Attribute`,attacher:iu},{name:r=>`set${r}Attribute`,attacher:su},{name:r=>`update${r}Attribute`,attacher:ou},{name:r=>`remove${r}Attribute`,attacher:uu},{name:r=>`replace${r}Attributes`,attacher:au},{name:r=>`merge${r}Attributes`,attacher:hu},{name:r=>`update${r}Attributes`,attacher:cu}];function fu(r){lu.forEach(function({name:t,attacher:e}){e(r,t("Edge"),"mixed"),e(r,t("DirectedEdge"),"directed"),e(r,t("UndirectedEdge"),"undirected")})}var du=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function gu(r,t,e,i){let u=!1;for(let h in t){if(h===i)continue;let c=t[h];if(u=e(c.key,c.attributes,c.source.key,c.target.key,c.source.attributes,c.target.attributes,c.undirected),r&&u)return c.key}}function pu(r,t,e,i){let u,h,c,f=!1;for(let p in t)if(p!==i){u=t[p];do{if(h=u.source,c=u.target,f=e(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected),r&&f)return u.key;u=u.next}while(u!==void 0)}}function hn(r,t){let e=Object.keys(r),i=e.length,u,h=0;return{[Symbol.iterator](){return this},next(){do if(u)u=u.next;else{if(h>=i)return{done:!0};let c=e[h++];if(c===t){u=void 0;continue}u=r[c]}while(!u);return{done:!1,value:{edge:u.key,attributes:u.attributes,source:u.source.key,target:u.target.key,sourceAttributes:u.source.attributes,targetAttributes:u.target.attributes,undirected:u.undirected}}}}}function wu(r,t,e,i){let u=t[e];if(!u)return;let h=u.source,c=u.target;if(i(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected)&&r)return u.key}function yu(r,t,e,i){let u=t[e];if(!u)return;let h=!1;do{if(h=i(u.key,u.attributes,u.source.key,u.target.key,u.source.attributes,u.target.attributes,u.undirected),r&&h)return u.key;u=u.next}while(u!==void 0)}function cn(r,t){let e=r[t];if(e.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!e)return{done:!0};let u={edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected};return e=e.next,{done:!1,value:u}}};let i=!1;return{[Symbol.iterator](){return this},next(){return i===!0?{done:!0}:(i=!0,{done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}})}}}function mu(r,t){if(r.size===0)return[];if(t==="mixed"||t===r.type)return Array.from(r._edges.keys());let e=t==="undirected"?r.undirectedSize:r.directedSize,i=new Array(e),u=t==="undirected",h=r._edges.values(),c=0,f,p;for(;f=h.next(),f.done!==!0;)p=f.value,p.undirected===u&&(i[c++]=p.key);return i}function pi(r,t,e,i){if(t.size===0)return;let u=e!=="mixed"&&e!==t.type,h=e==="undirected",c,f,p=!1,d=t._edges.values();for(;c=d.next(),c.done!==!0;){if(f=c.value,u&&f.undirected!==h)continue;let{key:v,attributes:x,source:E,target:M}=f;if(p=i(v,x,E.key,M.key,E.attributes,M.attributes,f.undirected),r&&p)return v}}function bu(r,t){if(r.size===0)return Pe();let e=t!=="mixed"&&t!==r.type,i=t==="undirected",u=r._edges.values();return{[Symbol.iterator](){return this},next(){let h,c;for(;;){if(h=u.next(),h.done)return h;if(c=h.value,!(e&&c.undirected!==i))break}return{value:{edge:c.key,attributes:c.attributes,source:c.source.key,target:c.target.key,sourceAttributes:c.source.attributes,targetAttributes:c.target.attributes,undirected:c.undirected},done:!1}}}}function ln(r,t,e,i,u,h){let c=t?pu:gu,f;if(e!=="undirected"&&(i!=="out"&&(f=c(r,u.in,h),r&&f)||i!=="in"&&(f=c(r,u.out,h,i?void 0:u.key),r&&f))||e!=="directed"&&(f=c(r,u.undirected,h),r&&f))return f}function Eu(r,t,e,i){let u=[];return ln(!1,r,t,e,i,function(h){u.push(h)}),u}function vu(r,t,e){let i=Pe();return r!=="undirected"&&(t!=="out"&&typeof e.in<"u"&&(i=me(i,hn(e.in))),t!=="in"&&typeof e.out<"u"&&(i=me(i,hn(e.out,t?void 0:e.key)))),r!=="directed"&&typeof e.undirected<"u"&&(i=me(i,hn(e.undirected))),i}function fn(r,t,e,i,u,h,c){let f=e?yu:wu,p;if(t!=="undirected"&&(typeof u.in<"u"&&i!=="out"&&(p=f(r,u.in,h,c),r&&p)||typeof u.out<"u"&&i!=="in"&&(i||u.key!==h)&&(p=f(r,u.out,h,c),r&&p))||t!=="directed"&&typeof u.undirected<"u"&&(p=f(r,u.undirected,h,c),r&&p))return p}function xu(r,t,e,i,u){let h=[];return fn(!1,r,t,e,i,u,function(c){h.push(c)}),h}function Su(r,t,e,i){let u=Pe();return r!=="undirected"&&(typeof e.in<"u"&&t!=="out"&&i in e.in&&(u=me(u,cn(e.in,i))),typeof e.out<"u"&&t!=="in"&&i in e.out&&(t||e.key!==i)&&(u=me(u,cn(e.out,i)))),r!=="directed"&&typeof e.undirected<"u"&&i in e.undirected&&(u=me(u,cn(e.undirected,i))),u}function ku(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h,c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];if(!arguments.length)return mu(this,i);if(arguments.length===1){h=""+h;let f=this._nodes.get(h);if(typeof f>"u")throw new V(`Graph.${e}: could not find the "${h}" node in the graph.`);return Eu(this.multi,i==="mixed"?this.type:i,u,f)}if(arguments.length===2){h=""+h,c=""+c;let f=this._nodes.get(h);if(!f)throw new V(`Graph.${e}: could not find the "${h}" source node in the graph.`);if(!this._nodes.has(c))throw new V(`Graph.${e}: could not find the "${c}" target node in the graph.`);return xu(i,this.multi,u,f,c)}throw new Q(`Graph.${e}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Mu(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,v,x){if(!(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)){if(arguments.length===1)return x=d,pi(!1,this,i,x);if(arguments.length===2){d=""+d,x=v;let E=this._nodes.get(d);if(typeof E>"u")throw new V(`Graph.${h}: could not find the "${d}" node in the graph.`);return ln(!1,this.multi,i==="mixed"?this.type:i,u,E,x)}if(arguments.length===3){d=""+d,v=""+v;let E=this._nodes.get(d);if(!E)throw new V(`Graph.${h}: could not find the "${d}" source node in the graph.`);if(!this._nodes.has(v))throw new V(`Graph.${h}: could not find the "${v}" target node in the graph.`);return fn(!1,i,this.multi,u,E,v,x)}throw new Q(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(){let d=Array.prototype.slice.call(arguments),v=d.pop(),x;if(d.length===0){let E=0;i!=="directed"&&(E+=this.undirectedSize),i!=="undirected"&&(E+=this.directedSize),x=new Array(E);let M=0;d.push((_,N,C,q,L,z,K)=>{x[M++]=v(_,N,C,q,L,z,K)})}else x=[],d.push((E,M,_,N,C,q,L)=>{x.push(v(E,M,_,N,C,q,L))});return this[h].apply(this,d),x};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(){let d=Array.prototype.slice.call(arguments),v=d.pop(),x=[];return d.push((E,M,_,N,C,q,L)=>{v(E,M,_,N,C,q,L)&&x.push(E)}),this[h].apply(this,d),x};let p="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[p]=function(){let d=Array.prototype.slice.call(arguments);if(d.length<2||d.length>4)throw new Q(`Graph.${p}: invalid number of arguments (expecting 2, 3 or 4 and got ${d.length}).`);if(typeof d[d.length-1]=="function"&&typeof d[d.length-2]!="function")throw new Q(`Graph.${p}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let v,x;d.length===2?(v=d[0],x=d[1],d=[]):d.length===3?(v=d[1],x=d[2],d=[d[0]]):d.length===4&&(v=d[2],x=d[3],d=[d[0],d[1]]);let E=x;return d.push((M,_,N,C,q,L,z)=>{E=v(E,M,_,N,C,q,L,z)}),this[h].apply(this,d),E}}function Du(r,t){let{name:e,type:i,direction:u}=t,h="find"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(p,d,v){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return!1;if(arguments.length===1)return v=p,pi(!0,this,i,v);if(arguments.length===2){p=""+p,v=d;let x=this._nodes.get(p);if(typeof x>"u")throw new V(`Graph.${h}: could not find the "${p}" node in the graph.`);return ln(!0,this.multi,i==="mixed"?this.type:i,u,x,v)}if(arguments.length===3){p=""+p,d=""+d;let x=this._nodes.get(p);if(!x)throw new V(`Graph.${h}: could not find the "${p}" source node in the graph.`);if(!this._nodes.has(d))throw new V(`Graph.${h}: could not find the "${d}" target node in the graph.`);return fn(!0,i,this.multi,u,x,d,v)}throw new Q(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let c="some"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[c]=function(){let p=Array.prototype.slice.call(arguments),d=p.pop();return p.push((x,E,M,_,N,C,q)=>d(x,E,M,_,N,C,q)),!!this[h].apply(this,p)};let f="every"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[f]=function(){let p=Array.prototype.slice.call(arguments),d=p.pop();return p.push((x,E,M,_,N,C,q)=>!d(x,E,M,_,N,C,q)),!this[h].apply(this,p)}}function Iu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return Pe();if(!arguments.length)return bu(this,i);if(arguments.length===1){c=""+c;let p=this._nodes.get(c);if(!p)throw new V(`Graph.${h}: could not find the "${c}" node in the graph.`);return vu(i,u,p)}if(arguments.length===2){c=""+c,f=""+f;let p=this._nodes.get(c);if(!p)throw new V(`Graph.${h}: could not find the "${c}" source node in the graph.`);if(!this._nodes.has(f))throw new V(`Graph.${h}: could not find the "${f}" target node in the graph.`);return Su(i,u,p,f)}throw new Q(`Graph.${h}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function ju(r){du.forEach(t=>{ku(r,t),Mu(r,t),Du(r,t),Iu(r,t)})}var _u=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function Ir(){this.A=null,this.B=null}Ir.prototype.wrap=function(r){this.A===null?this.A=r:this.B===null&&(this.B=r)};Ir.prototype.has=function(r){return this.A!==null&&r in this.A||this.B!==null&&r in this.B};function Xe(r,t,e,i,u){for(let h in i){let c=i[h],f=c.source,p=c.target,d=f===e?p:f;if(t&&t.has(d.key))continue;let v=u(d.key,d.attributes);if(r&&v)return d.key}}function dn(r,t,e,i,u){if(t!=="mixed"){if(t==="undirected")return Xe(r,null,i,i.undirected,u);if(typeof e=="string")return Xe(r,null,i,i[e],u)}let h=new Ir,c;if(t!=="undirected"){if(e!=="out"){if(c=Xe(r,null,i,i.in,u),r&&c)return c;h.wrap(i.in)}if(e!=="in"){if(c=Xe(r,h,i,i.out,u),r&&c)return c;h.wrap(i.out)}}if(t!=="directed"&&(c=Xe(r,h,i,i.undirected,u),r&&c))return c}function $u(r,t,e){if(r!=="mixed"){if(r==="undirected")return Object.keys(e.undirected);if(typeof t=="string")return Object.keys(e[t])}let i=[];return dn(!1,r,t,e,function(u){i.push(u)}),i}function Qe(r,t,e){let i=Object.keys(e),u=i.length,h=0;return{[Symbol.iterator](){return this},next(){let c=null;do{if(h>=u)return r&&r.wrap(e),{done:!0};let f=e[i[h++]],p=f.source,d=f.target;if(c=p===t?d:p,r&&r.has(c.key)){c=null;continue}}while(c===null);return{done:!1,value:{neighbor:c.key,attributes:c.attributes}}}}}function Au(r,t,e){if(r!=="mixed"){if(r==="undirected")return Qe(null,e,e.undirected);if(typeof t=="string")return Qe(null,e,e[t])}let i=Pe(),u=new Ir;return r!=="undirected"&&(t!=="out"&&(i=me(i,Qe(u,e,e.in))),t!=="in"&&(i=me(i,Qe(u,e,e.out)))),r!=="directed"&&(i=me(i,Qe(u,e,e.undirected))),i}function Ru(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];h=""+h;let c=this._nodes.get(h);if(typeof c>"u")throw new V(`Graph.${e}: could not find the "${h}" node in the graph.`);return $u(i==="mixed"?this.type:i,u,c)}}function Nu(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,v){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let x=this._nodes.get(d);if(typeof x>"u")throw new V(`Graph.${h}: could not find the "${d}" node in the graph.`);dn(!1,i==="mixed"?this.type:i,u,x,v)};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(d,v){let x=[];return this[h](d,(E,M)=>{x.push(v(E,M))}),x};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(d,v){let x=[];return this[h](d,(E,M)=>{v(E,M)&&x.push(E)}),x};let p="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[p]=function(d,v,x){if(arguments.length<3)throw new Q(`Graph.${p}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let E=x;return this[h](d,(M,_)=>{E=v(E,M,_)}),E}}function Lu(r,t){let{name:e,type:i,direction:u}=t,h=e[0].toUpperCase()+e.slice(1,-1),c="find"+h;r.prototype[c]=function(d,v){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let x=this._nodes.get(d);if(typeof x>"u")throw new V(`Graph.${c}: could not find the "${d}" node in the graph.`);return dn(!0,i==="mixed"?this.type:i,u,x,v)};let f="some"+h;r.prototype[f]=function(d,v){return!!this[c](d,v)};let p="every"+h;r.prototype[p]=function(d,v){return!this[c](d,(E,M)=>!v(E,M))}}function Tu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return Pe();c=""+c;let f=this._nodes.get(c);if(typeof f>"u")throw new V(`Graph.${h}: could not find the "${c}" node in the graph.`);return Au(i==="mixed"?this.type:i,u,f)}}function Gu(r){_u.forEach(t=>{Ru(r,t),Nu(r,t),Lu(r,t),Tu(r,t)})}function vr(r,t,e,i,u){let h=i._nodes.values(),c=i.type,f,p,d,v,x,E,M;for(;f=h.next(),f.done!==!0;){let _=!1;if(p=f.value,c!=="undirected"){v=p.out;for(d in v){x=v[d];do{if(E=x.target,_=!0,M=u(p.key,E.key,p.attributes,E.attributes,x.key,x.attributes,x.undirected),r&&M)return x;x=x.next}while(x)}}if(c!=="directed"){v=p.undirected;for(d in v)if(!(t&&p.key>d)){x=v[d];do{if(E=x.target,E.key!==d&&(E=x.source),_=!0,M=u(p.key,E.key,p.attributes,E.attributes,x.key,x.attributes,x.undirected),r&&M)return x;x=x.next}while(x)}}if(e&&!_&&(M=u(p.key,null,p.attributes,null,null,null,null),r&&M))return null}}function Ou(r,t){let e={key:r};return ai(t.attributes)||(e.attributes=Lt({},t.attributes)),e}function Cu(r,t,e){let i={key:t,source:e.source.key,target:e.target.key};return ai(e.attributes)||(i.attributes=Lt({},e.attributes)),r==="mixed"&&e.undirected&&(i.undirected=!0),i}function Pu(r){if(!Pt(r))throw new Q('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in r))throw new Q("Graph.import: serialized node is missing its key.");if("attributes"in r&&(!Pt(r.attributes)||r.attributes===null))throw new Q("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function Fu(r){if(!Pt(r))throw new Q('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in r))throw new Q("Graph.import: serialized edge is missing its source.");if(!("target"in r))throw new Q("Graph.import: serialized edge is missing its target.");if("attributes"in r&&(!Pt(r.attributes)||r.attributes===null))throw new Q("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in r&&typeof r.undirected!="boolean")throw new Q("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var zu=qo(),Uu=new Set(["directed","undirected","mixed"]),si=new Set(["domain","_events","_eventsCount","_maxListeners"]),qu=[{name:r=>`${r}Edge`,generateKey:!0},{name:r=>`${r}DirectedEdge`,generateKey:!0,type:"directed"},{name:r=>`${r}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:r=>`${r}EdgeWithKey`},{name:r=>`${r}DirectedEdgeWithKey`,type:"directed"},{name:r=>`${r}UndirectedEdgeWithKey`,type:"undirected"}],Wu={allowSelfLoops:!0,multi:!1,type:"mixed"};function Vu(r,t,e){if(e&&!Pt(e))throw new Q(`Graph.addNode: invalid attributes. Expecting an object but got "${e}"`);if(t=""+t,e=e||{},r._nodes.has(t))throw new tt(`Graph.addNode: the "${t}" node already exist in the graph.`);let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function oi(r,t,e){let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function wi(r,t,e,i,u,h,c,f){if(!i&&r.type==="undirected")throw new tt(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new tt(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(f&&!Pt(f))throw new Q(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`);if(h=""+h,c=""+c,f=f||{},!r.allowSelfLoops&&h===c)throw new tt(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let p=r._nodes.get(h),d=r._nodes.get(c);if(!p)throw new V(`Graph.${t}: source node "${h}" not found.`);if(!d)throw new V(`Graph.${t}: target node "${c}" not found.`);let v={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new tt(`Graph.${t}: the "${u}" edge already exists in the graph.`);if(!r.multi&&(i?typeof p.undirected[c]<"u":typeof p.out[c]<"u"))throw new tt(`Graph.${t}: an edge linking "${h}" to "${c}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let x=new Fe(i,u,p,d,f);r._edges.set(u,x);let E=h===c;return i?(p.undirectedDegree++,d.undirectedDegree++,E&&(p.undirectedLoops++,r._undirectedSelfLoopCount++)):(p.outDegree++,d.inDegree++,E&&(p.directedLoops++,r._directedSelfLoopCount++)),r.multi?x.attachMulti():x.attach(),i?r._undirectedSize++:r._directedSize++,v.key=u,r.emit("edgeAdded",v),u}function Bu(r,t,e,i,u,h,c,f,p){if(!i&&r.type==="undirected")throw new tt(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new tt(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(f){if(p){if(typeof f!="function")throw new Q(`Graph.${t}: invalid updater function. Expecting a function but got "${f}"`)}else if(!Pt(f))throw new Q(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`)}h=""+h,c=""+c;let d;if(p&&(d=f,f=void 0),!r.allowSelfLoops&&h===c)throw new tt(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let v=r._nodes.get(h),x=r._nodes.get(c),E,M;if(!e&&(E=r._edges.get(u),E)){if((E.source.key!==h||E.target.key!==c)&&(!i||E.source.key!==c||E.target.key!==h))throw new tt(`Graph.${t}: inconsistency detected when attempting to merge the "${u}" edge with "${h}" source & "${c}" target vs. ("${E.source.key}", "${E.target.key}").`);M=E}if(!M&&!r.multi&&v&&(M=i?v.undirected[c]:v.out[c]),M){let L=[M.key,!1,!1,!1];if(p?!d:!f)return L;if(p){let z=M.attributes;M.attributes=d(z),r.emit("edgeAttributesUpdated",{type:"replace",key:M.key,attributes:M.attributes})}else Lt(M.attributes,f),r.emit("edgeAttributesUpdated",{type:"merge",key:M.key,attributes:M.attributes,data:f});return L}f=f||{},p&&d&&(f=d(f));let _={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new tt(`Graph.${t}: the "${u}" edge already exists in the graph.`);let N=!1,C=!1;v||(v=oi(r,h,{}),N=!0,h===c&&(x=v,C=!0)),x||(x=oi(r,c,{}),C=!0),E=new Fe(i,u,v,x,f),r._edges.set(u,E);let q=h===c;return i?(v.undirectedDegree++,x.undirectedDegree++,q&&(v.undirectedLoops++,r._undirectedSelfLoopCount++)):(v.outDegree++,x.inDegree++,q&&(v.directedLoops++,r._directedSelfLoopCount++)),r.multi?E.attachMulti():E.attach(),i?r._undirectedSize++:r._directedSize++,_.key=u,r.emit("edgeAdded",_),[u,!0,N,C]}function Ce(r,t){r._edges.delete(t.key);let{source:e,target:i,attributes:u}=t,h=t.undirected,c=e===i;h?(e.undirectedDegree--,i.undirectedDegree--,c&&(e.undirectedLoops--,r._undirectedSelfLoopCount--)):(e.outDegree--,i.inDegree--,c&&(e.directedLoops--,r._directedSelfLoopCount--)),r.multi?t.detachMulti():t.detach(),h?r._undirectedSize--:r._directedSize--,r.emit("edgeDropped",{key:t.key,attributes:u,source:e.key,target:i.key,undirected:h})}var yt=class r extends ui.EventEmitter{constructor(t){if(super(),t=Lt({},Wu,t),typeof t.multi!="boolean")throw new Q(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Uu.has(t.type))throw new Q(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new Q(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let e=t.type==="mixed"?hi:t.type==="directed"?ci:li;te(this,"NodeDataClass",e);let i="geid_"+zu()+"_",u=0,h=()=>{let c;do c=i+u++;while(this._edges.has(c));return c};te(this,"_attributes",{}),te(this,"_nodes",new Map),te(this,"_edges",new Map),te(this,"_directedSize",0),te(this,"_undirectedSize",0),te(this,"_directedSelfLoopCount",0),te(this,"_undirectedSelfLoopCount",0),te(this,"_edgeKeyGenerator",h),te(this,"_options",t),si.forEach(c=>te(this,c,this[c])),oe(this,"order",()=>this._nodes.size),oe(this,"size",()=>this._edges.size),oe(this,"directedSize",()=>this._directedSize),oe(this,"undirectedSize",()=>this._undirectedSize),oe(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),oe(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),oe(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),oe(this,"multi",this._options.multi),oe(this,"type",this._options.type),oe(this,"allowSelfLoops",this._options.allowSelfLoops),oe(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,e){if(this.type==="undirected")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&!u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.out.hasOwnProperty(e):!1}throw new Q(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,e){if(this.type==="directed")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.undirected.hasOwnProperty(e):!1}throw new Q(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,e){if(arguments.length===1){let i=""+t;return this._edges.has(i)}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?typeof i.out<"u"&&i.out.hasOwnProperty(e)||typeof i.undirected<"u"&&i.undirected.hasOwnProperty(e):!1}throw new Q(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,e){if(this.type==="undirected")return;if(t=""+t,e=""+e,this.multi)throw new tt("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let i=this._nodes.get(t);if(!i)throw new V(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new V(`Graph.directedEdge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||void 0;if(u)return u.key}undirectedEdge(t,e){if(this.type==="directed")return;if(t=""+t,e=""+e,this.multi)throw new tt("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let i=this._nodes.get(t);if(!i)throw new V(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new V(`Graph.undirectedEdge: could not find the "${e}" target node in the graph.`);let u=i.undirected&&i.undirected[e]||void 0;if(u)return u.key}edge(t,e){if(this.multi)throw new tt("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new V(`Graph.edge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||i.undirected&&i.undirected[e]||void 0;if(u)return u.key}areDirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in||e in i.out}areOutNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.out}areInNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in}areUndirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:e in i.undirected}areNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(e in i.in||e in i.out)||this.type!=="directed"&&e in i.undirected}areInboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.in||this.type!=="directed"&&e in i.undirected}areOutboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new V(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.out||this.type!=="directed"&&e in i.undirected}inDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree}outDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree}directedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree}undirectedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree}inboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree),i}outboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.outDegree),i}degree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.degree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree),i}inDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree-e.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree-e.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree-e.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree-e.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree,u+=e.directedLoops),i-u}outboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.outDegree,u+=e.directedLoops),i-u}degreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree,u+=e.directedLoops*2),i-u}source(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.source: could not find the "${t}" edge in the graph.`);return e.source.key}target(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.target: could not find the "${t}" edge in the graph.`);return e.target.key}extremities(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[e.source.key,e.target.key]}opposite(t,e){t=""+t,e=""+e;let i=this._edges.get(e);if(!i)throw new V(`Graph.opposite: could not find the "${e}" edge in the graph.`);let u=i.source.key,h=i.target.key;if(t===u)return h;if(t===h)return u;throw new V(`Graph.opposite: the "${t}" node is not attached to the "${e}" edge (${u}, ${h}).`)}hasExtremity(t,e){t=""+t,e=""+e;let i=this._edges.get(t);if(!i)throw new V(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return i.source.key===e||i.target.key===e}isUndirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return e.undirected}isDirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!e.undirected}isSelfLoop(t){t=""+t;let e=this._edges.get(t);if(!e)throw new V(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return e.source===e.target}addNode(t,e){return Vu(this,t,e).key}mergeNode(t,e){if(e&&!Pt(e))throw new Q(`Graph.mergeNode: invalid attributes. Expecting an object but got "${e}"`);t=""+t,e=e||{};let i=this._nodes.get(t);return i?(e&&(Lt(i.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:i.attributes,data:e})),[t,!1]):(i=new this.NodeDataClass(t,e),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])}updateNode(t,e){if(e&&typeof e!="function")throw new Q(`Graph.updateNode: invalid updater function. Expecting a function but got "${e}"`);t=""+t;let i=this._nodes.get(t);if(i){if(e){let h=i.attributes;i.attributes=e(h),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:i.attributes})}return[t,!1]}let u=e?e({}):{};return i=new this.NodeDataClass(t,u),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:u}),[t,!0]}dropNode(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new V(`Graph.dropNode: could not find the "${t}" node in the graph.`);let i;if(this.type!=="undirected"){for(let u in e.out){i=e.out[u];do Ce(this,i),i=i.next;while(i)}for(let u in e.in){i=e.in[u];do Ce(this,i),i=i.next;while(i)}}if(this.type!=="directed")for(let u in e.undirected){i=e.undirected[u];do Ce(this,i),i=i.next;while(i)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:e.attributes})}dropEdge(t){let e;if(arguments.length>1){let i=""+arguments[0],u=""+arguments[1];if(e=ee(this,i,u,this.type),!e)throw new V(`Graph.dropEdge: could not find the "${i}" -> "${u}" edge in the graph.`)}else if(t=""+t,e=this._edges.get(t),!e)throw new V(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return Ce(this,e),this}dropDirectedEdge(t,e){if(arguments.length<2)throw new tt("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new tt("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,e=""+e;let i=ee(this,t,e,"directed");if(!i)throw new V(`Graph.dropDirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Ce(this,i),this}dropUndirectedEdge(t,e){if(arguments.length<2)throw new tt("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new tt("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let i=ee(this,t,e,"undirected");if(!i)throw new V(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Ce(this,i),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),e;for(;e=t.next(),e.done!==!0;)e.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,e){if(typeof e!="function")throw new Q("Graph.updateAttribute: updater should be a function.");let i=this._attributes[t];return this._attributes[t]=e(i),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!Pt(t))throw new Q("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!Pt(t))throw new Q("Graph.mergeAttributes: provided attributes are not a plain object.");return Lt(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new Q("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,e){if(typeof t!="function")throw new Q("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!ii(e))throw new Q("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._nodes.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,h.attributes=t(h.key,h.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})}updateEachEdgeAttributes(t,e){if(typeof t!="function")throw new Q("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!ii(e))throw new Q("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._edges.values(),u,h,c,f;for(;u=i.next(),u.done!==!0;)h=u.value,c=h.source,f=h.target,h.attributes=t(h.key,h.attributes,c.key,f.key,c.attributes,f.attributes,h.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new Q("Graph.forEachAdjacencyEntry: expecting a callback.");vr(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new Q("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");vr(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new Q("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");vr(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new Q("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");vr(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new Q("Graph.forEachNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)}findNode(t){if(typeof t!="function")throw new Q("Graph.findNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return u.key}mapNodes(t){if(typeof t!="function")throw new Q("Graph.mapNode: expecting a callback.");let e=this._nodes.values(),i,u,h=new Array(this.order),c=0;for(;i=e.next(),i.done!==!0;)u=i.value,h[c++]=t(u.key,u.attributes);return h}someNode(t){if(typeof t!="function")throw new Q("Graph.someNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new Q("Graph.everyNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,!t(u.key,u.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new Q("Graph.filterNodes: expecting a callback.");let e=this._nodes.values(),i,u,h=[];for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)&&h.push(u.key);return h}reduceNodes(t,e){if(typeof t!="function")throw new Q("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new Q("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let i=e,u=this._nodes.values(),h,c;for(;h=u.next(),h.done!==!0;)c=h.value,i=t(i,c.key,c.attributes);return i}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let e=t.next();if(e.done)return e;let i=e.value;return{value:{node:i.key,attributes:i.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),e=0;this._nodes.forEach((u,h)=>{t[e++]=Ou(h,u)});let i=new Array(this._edges.size);return e=0,this._edges.forEach((u,h)=>{i[e++]=Cu(this.type,h,u)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:i}}import(t,e=!1){if(t instanceof r)return t.forEachNode((p,d)=>{e?this.mergeNode(p,d):this.addNode(p,d)}),t.forEachEdge((p,d,v,x,E,M,_)=>{e?_?this.mergeUndirectedEdgeWithKey(p,v,x,d):this.mergeDirectedEdgeWithKey(p,v,x,d):_?this.addUndirectedEdgeWithKey(p,v,x,d):this.addDirectedEdgeWithKey(p,v,x,d)}),this;if(!Pt(t))throw new Q("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!Pt(t.attributes))throw new Q("Graph.import: invalid attributes. Expecting a plain object.");e?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let i,u,h,c,f;if(t.nodes){if(h=t.nodes,!Array.isArray(h))throw new Q("Graph.import: invalid nodes. Expecting an array.");for(i=0,u=h.length;i{let h=Lt({},i.attributes);i=new e.NodeDataClass(u,h),e._nodes.set(u,i)}),e}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new tt(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new tt("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new tt("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let e=this.emptyCopy(t),i=this._edges.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,wi(e,"copy",!1,h.undirected,h.key,h.source.key,h.target.key,Lt({},h.attributes));return e}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((h,c)=>{t[c]=h.attributes});let e={},i={};this._edges.forEach((h,c)=>{let f=h.undirected?"--":"->",p="",d=h.source.key,v=h.target.key,x;h.undirected&&d>v&&(x=d,d=v,v=x);let E=`(${d})${f}(${v})`;c.startsWith("geid_")?this.multi&&(typeof i[E]>"u"?i[E]=0:i[E]++,p+=`${i[E]}. `):p+=`[${c}]: `,p+=E,e[p]=h.attributes});let u={};for(let h in this)this.hasOwnProperty(h)&&!si.has(h)&&typeof this[h]!="function"&&typeof h!="symbol"&&(u[h]=this[h]);return u.attributes=this._attributes,u.nodes=t,u.edges=e,te(u,"constructor",this.constructor),u}};typeof Symbol<"u"&&(yt.prototype[Symbol.for("nodejs.util.inspect.custom")]=yt.prototype.inspect);qu.forEach(r=>{["add","merge","update"].forEach(t=>{let e=r.name(t),i=t==="add"?wi:Bu;r.generateKey?yt.prototype[e]=function(u,h,c){return i(this,e,!0,(r.type||this.type)==="undirected",null,u,h,c,t==="update")}:yt.prototype[e]=function(u,h,c,f){return i(this,e,!1,(r.type||this.type)==="undirected",u,h,c,f,t==="update")}})});eu(yt);fu(yt);ju(yt);Gu(yt);var xr=class extends yt{constructor(t){let e=Lt({type:"directed"},t);if("multi"in e&&e.multi!==!1)throw new Q("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="directed")throw new Q('DirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Sr=class extends yt{constructor(t){let e=Lt({type:"undirected"},t);if("multi"in e&&e.multi!==!1)throw new Q("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="undirected")throw new Q('UndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},kr=class extends yt{constructor(t){let e=Lt({multi:!0},t);if("multi"in e&&e.multi!==!0)throw new Q("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(e)}},Mr=class extends yt{constructor(t){let e=Lt({type:"directed",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new Q("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="directed")throw new Q('MultiDirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Dr=class extends yt{constructor(t){let e=Lt({type:"undirected",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new Q("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="undirected")throw new Q('MultiUndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}};function ze(r){r.from=function(t,e){let i=Lt({},t.options,e),u=new r(i);return u.import(t),u}}ze(yt);ze(xr);ze(Sr);ze(kr);ze(Mr);ze(Dr);yt.Graph=yt;yt.DirectedGraph=xr;yt.UndirectedGraph=Sr;yt.MultiGraph=kr;yt.MultiDirectedGraph=Mr;yt.MultiUndirectedGraph=Dr;yt.InvalidArgumentsGraphError=Q;yt.NotFoundGraphError=V;yt.UsageGraphError=tt;var tn=nn(Ji(),1),Ah=nn(ls(),1);function ne(r,t,e,i){function u(h){return h instanceof e?h:new e(function(c){c(h)})}return new(e||(e=Promise))(function(h,c){function f(v){try{d(i.next(v))}catch(x){c(x)}}function p(v){try{d(i.throw(v))}catch(x){c(x)}}function d(v){v.done?h(v.value):u(v.value).then(f,p)}d((i=i.apply(r,t||[])).next())})}var Da={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},Dt=class extends Error{constructor(t,e,i){super(t),this.position=e,this.token=i,this.name="ExpressionError"}},ot;(function(r){r[r.STRING=0]="STRING",r[r.NUMBER=1]="NUMBER",r[r.BOOLEAN=2]="BOOLEAN",r[r.NULL=3]="NULL",r[r.IDENTIFIER=4]="IDENTIFIER",r[r.OPERATOR=5]="OPERATOR",r[r.FUNCTION=6]="FUNCTION",r[r.DOT=7]="DOT",r[r.BRACKET_LEFT=8]="BRACKET_LEFT",r[r.BRACKET_RIGHT=9]="BRACKET_RIGHT",r[r.PAREN_LEFT=10]="PAREN_LEFT",r[r.PAREN_RIGHT=11]="PAREN_RIGHT",r[r.COMMA=12]="COMMA",r[r.QUESTION=13]="QUESTION",r[r.COLON=14]="COLON",r[r.DOLLAR=15]="DOLLAR"})(ot||(ot={}));var Ia=new Set([32,9,10,13]),ja=new Set([43,45,42,47,37,33,38,124,61,60,62]),_a=new Map([["true",ot.BOOLEAN],["false",ot.BOOLEAN],["null",ot.NULL]]),yn=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),$a=new Map([[46,ot.DOT],[91,ot.BRACKET_LEFT],[93,ot.BRACKET_RIGHT],[40,ot.PAREN_LEFT],[41,ot.PAREN_RIGHT],[44,ot.COMMA],[63,ot.QUESTION],[58,ot.COLON],[36,ot.DOLLAR]]),ds=new Map;for(let[r,t]of $a.entries())ds.set(r,{type:t,value:String.fromCharCode(r)});function nr(r){return r>=48&&r<=57}function mn(r){return r>=97&&r<=122||r>=65&&r<=90||r===95}function fs(r){return mn(r)||nr(r)}function Aa(r){return ja.has(r)}var kt;(function(r){r[r.Program=0]="Program",r[r.Literal=1]="Literal",r[r.Identifier=2]="Identifier",r[r.MemberExpression=3]="MemberExpression",r[r.CallExpression=4]="CallExpression",r[r.BinaryExpression=5]="BinaryExpression",r[r.UnaryExpression=6]="UnaryExpression",r[r.ConditionalExpression=7]="ConditionalExpression"})(kt||(kt={}));var Ra=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),Na={type:kt.Literal,value:null},La={type:kt.Literal,value:!0},Ta={type:kt.Literal,value:!1},Ga=r=>{let t=0,e=r.length,i=()=>t>=e?null:r[t],u=()=>r[t++],h=x=>{let E=i();return E!==null&&E.type===x},c=x=>x.type===ot.OPERATOR?Ra.get(x.value)||-1:x.type===ot.DOT||x.type===ot.BRACKET_LEFT?9:x.type===ot.QUESTION?1:-1,f=x=>{let E,M;if(u().type===ot.DOT){if(!h(ot.IDENTIFIER)){let N=i();throw new Dt("Expected property name",t,N?N.value:"")}let _=u();E={type:kt.Identifier,name:_.value},M=!1}else{if(E=d(0),!h(ot.BRACKET_RIGHT)){let _=i();throw new Dt("Expected closing bracket",t,_?_.value:"")}u(),M=!0}return{type:kt.MemberExpression,object:x,property:E,computed:M}},p=()=>{let x=i();if(!x)throw new Dt("Unexpected end of input",t,"");if(x.type===ot.OPERATOR&&(x.value==="!"||x.value==="-")){u();let E=p();return{type:kt.UnaryExpression,operator:x.value,argument:E,prefix:!0}}switch(x.type){case ot.NUMBER:return u(),{type:kt.Literal,value:Number(x.value)};case ot.STRING:return u(),{type:kt.Literal,value:x.value};case ot.BOOLEAN:return u(),x.value==="true"?La:Ta;case ot.NULL:return u(),Na;case ot.IDENTIFIER:return u(),{type:kt.Identifier,name:x.value};case ot.FUNCTION:return(()=>{let E=u(),M=[];if(!h(ot.PAREN_LEFT)){let _=i();throw new Dt("Expected opening parenthesis after function name",t,_?_.value:"")}for(u();;){if(h(ot.PAREN_RIGHT)){u();break}if(!i()){let N=i();throw new Dt("Expected closing parenthesis",t,N?N.value:"")}if(M.length>0){if(!h(ot.COMMA)){let N=i();throw new Dt("Expected comma between function arguments",t,N?N.value:"")}u()}let _=d(0);M.push(_)}return{type:kt.CallExpression,callee:{type:kt.Identifier,name:E.value},arguments:M}})();case ot.PAREN_LEFT:{u();let E=d(0);if(!h(ot.PAREN_RIGHT)){let M=i();throw new Dt("Expected closing parenthesis",t,M?M.value:"")}return u(),E}default:throw new Dt(`Unexpected token: ${x.type}`,t,x.value)}},d=(x=0)=>{let E=p();for(;t")}u();let C=d(0);E={type:kt.ConditionalExpression,test:E,consequent:N,alternate:C}}}return E},v=d();return{type:kt.Program,body:v}},Oa=(r,t,e)=>{let i=t;e&&(i={...t,context:{...t.context,...e}});let u=h=>{switch(h.type){case kt.Literal:return(c=>c.value)(h);case kt.Identifier:return(c=>{if(!(c.name in i.context))throw new Dt(`Undefined variable: ${c.name}`);return i.context[c.name]})(h);case kt.MemberExpression:return(c=>{let f=u(c.object);if(f==null)throw new Dt("Cannot access property of null or undefined");return f[c.computed?u(c.property):c.property.name]})(h);case kt.CallExpression:return(c=>{let f=i.functions[c.callee.name];if(!f)throw new Dt(`Undefined function: ${c.callee.name}`);return f(...c.arguments.map((p=>u(p))))})(h);case kt.BinaryExpression:return(c=>{if(c.operator==="&&"){let d=u(c.left);return d&&u(c.right)}if(c.operator==="||")return u(c.left)||u(c.right);let f=u(c.left),p=u(c.right);switch(c.operator){case"+":return f+p;case"-":return f-p;case"*":return f*p;case"/":return f/p;case"%":return f%p;case"===":return f===p;case"!==":return f!==p;case">":return f>p;case">=":return f>=p;case"<":return f{let f=u(c.argument);if(c.prefix)switch(c.operator){case"!":return!f;case"-":if(typeof f!="number")throw new Dt(`Cannot apply unary - to non-number: ${f}`);return-f;default:throw new Dt(`Unknown operator: ${c.operator}`)}throw new Dt(`Postfix operators are not supported: ${c.operator}`)})(h);case kt.ConditionalExpression:return(c=>{let f=u(c.test);return u(f?c.consequent:c.alternate)})(h);default:throw new Dt(`Evaluation error: Unsupported node type: ${h.type}`)}};return u(r.body)};function bn(r){let t=(u=>{let h=u,c=h.length,f=new Array(Math.ceil(c/3)),p=0,d=0;function v(C){let q=d+1;d++;let L="",z=!1;for(;d({context:u,functions:h}))({},Da);return(u={})=>Oa(e,i,u)}function gs(r,t={}){return bn(r)(t)}function ps(r,t){if(typeof r!="string")return;let e=r.trim();if(e)try{return bn(e),gs(e,t)}catch{return}}function qe(r){return typeof r=="number"}function En(r){if(!r)return[0,0,0];if(qe(r))return[r,r,r];if(Array.isArray(r)&&r.length===0)return[0,0,0];let[t,e=t,i=t]=r;return[t,e,i]}function ws(r){return qe(r)?!0:Array.isArray(r)?r.every(t=>qe(t)):!1}function ae(r){return r==null}function ys(r){return typeof r=="string"}function ms(r){return typeof r=="function"}function ir(r,t){if(typeof r=="function")return r;if(typeof r=="string"){let e=r;return(...i)=>{let u={};for(let h=0;hr}function bs(r,t=10,e="node"){if(ae(r))return()=>t;if(ys(r)){let i=ir(r,[e]);return u=>{let h=i(u);return ws(h)?h:t}}return ms(r)?r:qe(r)?()=>r:Array.isArray(r)?()=>r:()=>t}var Ar=(r,t,e=10,i=0)=>{let u=bs(t,i),h=bs(r,e);return c=>{let[f,p,d]=En(h(c)),[v,x,E]=En(u(c));return[f+v,p+x,d+E]}};var Rr=class{constructor(t,e={}){this.edgeIdCounter=new Map,this.nodeMap=Fa(t.nodes,e.node),this.edgeMap=za(t.edges||[],e.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let e=this.indexNodeCache.get(t);return e?this.nodeMap.get(e):void 0}nodeIndexOf(t){var e;return this.nodeIndexCache||this.buildNodeIndexCache(),(e=this.nodeIndexCache.get(t))!==null&&e!==void 0?e:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let e=0;this.nodeMap.forEach(i=>t(i,e++))}originalNode(t){let e=this.nodeMap.get(t);return e?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let e=0;this.edgeMap.forEach(i=>t(i,e++))}originalEdge(t){let e=this.edgeMap.get(t);return e?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let e=`${t.source}-${t.target}`,i=this.edgeIdCounter.get(e)||0,u=i===0?e:`${e}-${i}`;return this.edgeIdCounter.set(e,i+1),u}degree(t,e="both"){this.degreeCache||this.buildDegreeCache();let i=this.degreeCache.get(t);return i?i[e]:0}neighbors(t,e="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),e==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(e==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let i=this.inAdjacencyCache.get(t),u=this.outAdjacencyCache.get(t);if(!i&&!u)return[];if(!i)return Array.from(u);if(!u)return Array.from(i);let h=new Set;return i.forEach(c=>h.add(c)),u.forEach(c=>h.add(c)),Array.from(h)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let e=new Map;for(let i of t)e.set(i.id,i);this.nodeMap=e,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:e,target:i}=t;if(t.source===t.target)continue;this.degreeCache.has(e)||this.degreeCache.set(e,{in:0,out:0,both:0});let u=this.degreeCache.get(t.source);u&&(u.out++,u.both++),this.degreeCache.has(i)||this.degreeCache.set(i,{in:0,out:0,both:0});let h=this.degreeCache.get(t.target);h&&(h.in++,h.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((e,i)=>{this.nodeIndexCache.set(i,t),this.indexNodeCache.set(t,i),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Ca=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],Pa=["id","source","target","points"];function Fa(r,t){if(!r)throw new Error("Data.nodes is required");let e=new Map;for(let i of r){let u={_original:i};for(let h of Ca){let c=i[h];ae(c)||(u[h]=c)}if(t){let h=t(i);for(let c in h){let f=h[c];ae(f)||(u[c]=f)}}if(ae(u.id))throw new Error("Node is missing id field");e.set(u.id,u)}return e}function za(r,t,e){let i=new Map;for(let u of r){let h={_original:u};for(let c of Pa){let f=u[c];ae(f)||(h[c]=f)}if(t){let c=t(u);for(let f in c){let p=c[f];ae(p)||(h[f]=p)}}if(ae(h.source)||ae(h.target))throw new Error("Edge is missing source or target field");ae(h.id)&&(h.id=e?.(u)),i.set(h.id,h)}return i}var Nr=class{constructor(t,e={}){this.graph=new Rr(t,e)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((e,i)=>{e.sourceNode=this.graph.node(e.source),e.targetNode=this.graph.node(e.target),t(e,i)})}destroy(){this.graph.destroy()}};var vs=Symbol("Comlink.proxy"),Ua=Symbol("Comlink.endpoint"),qa=Symbol("Comlink.releaseProxy"),vn=Symbol("Comlink.finalizer"),Tr=Symbol("Comlink.thrown"),xs=r=>typeof r=="object"&&r!==null||typeof r=="function",Wa={canHandle:r=>xs(r)&&r[vs],serialize(r){let{port1:t,port2:e}=new MessageChannel;return ks(r,t),[e,[e]]},deserialize(r){return r.start(),Sn(r)}},Va={canHandle:r=>xs(r)&&Tr in r,serialize({value:r}){let t;return r instanceof Error?t={isError:!0,value:{message:r.message,name:r.name,stack:r.stack}}:t={isError:!1,value:r},[t,[]]},deserialize(r){throw r.isError?Object.assign(new Error(r.value.message),r.value):r.value}},Ss=new Map([["proxy",Wa],["throw",Va]]);function Ba(r,t){for(let e of r)if(t===e||e==="*"||e instanceof RegExp&&e.test(t))return!0;return!1}function ks(r,t=globalThis,e=["*"]){t.addEventListener("message",function i(u){if(!u||!u.data)return;if(!Ba(e,u.origin)){console.warn(`Invalid origin '${u.origin}' for comlink proxy`);return}let{id:h,type:c,path:f}=Object.assign({path:[]},u.data),p=(u.data.argumentList||[]).map(Re),d;try{let v=f.slice(0,-1).reduce((E,M)=>E[M],r),x=f.reduce((E,M)=>E[M],r);switch(c){case"GET":d=x;break;case"SET":v[f.slice(-1)[0]]=Re(u.data.value),d=!0;break;case"APPLY":d=x.apply(v,p);break;case"CONSTRUCT":{let E=new x(...p);d=Za(E)}break;case"ENDPOINT":{let{port1:E,port2:M}=new MessageChannel;ks(r,M),d=Ja(E,[E])}break;case"RELEASE":d=void 0;break;default:return}}catch(v){d={value:v,[Tr]:0}}Promise.resolve(d).catch(v=>({value:v,[Tr]:0})).then(v=>{let[x,E]=Cr(v);t.postMessage(Object.assign(Object.assign({},x),{id:h}),E),c==="RELEASE"&&(t.removeEventListener("message",i),Ms(t),vn in r&&typeof r[vn]=="function"&&r[vn]())}).catch(v=>{let[x,E]=Cr({value:new TypeError("Unserializable return value"),[Tr]:0});t.postMessage(Object.assign(Object.assign({},x),{id:h}),E)})}),t.start&&t.start()}function Ka(r){return r.constructor.name==="MessagePort"}function Ms(r){Ka(r)&&r.close()}function Sn(r,t){let e=new Map;return r.addEventListener("message",function(u){let{data:h}=u;if(!h||!h.id)return;let c=e.get(h.id);if(c)try{c(h)}finally{e.delete(h.id)}}),xn(r,e,[],t)}function Lr(r){if(r)throw new Error("Proxy has been released and is not useable")}function Ds(r){return We(r,new Map,{type:"RELEASE"}).then(()=>{Ms(r)})}var Gr=new WeakMap,Or="FinalizationRegistry"in globalThis&&new FinalizationRegistry(r=>{let t=(Gr.get(r)||0)-1;Gr.set(r,t),t===0&&Ds(r)});function Ya(r,t){let e=(Gr.get(t)||0)+1;Gr.set(t,e),Or&&Or.register(r,t,r)}function Xa(r){Or&&Or.unregister(r)}function xn(r,t,e=[],i=function(){}){let u=!1,h=new Proxy(i,{get(c,f){if(Lr(u),f===qa)return()=>{Xa(h),Ds(r),t.clear(),u=!0};if(f==="then"){if(e.length===0)return{then:()=>h};let p=We(r,t,{type:"GET",path:e.map(d=>d.toString())}).then(Re);return p.then.bind(p)}return xn(r,t,[...e,f])},set(c,f,p){Lr(u);let[d,v]=Cr(p);return We(r,t,{type:"SET",path:[...e,f].map(x=>x.toString()),value:d},v).then(Re)},apply(c,f,p){Lr(u);let d=e[e.length-1];if(d===Ua)return We(r,t,{type:"ENDPOINT"}).then(Re);if(d==="bind")return xn(r,t,e.slice(0,-1));let[v,x]=Es(p);return We(r,t,{type:"APPLY",path:e.map(E=>E.toString()),argumentList:v},x).then(Re)},construct(c,f){Lr(u);let[p,d]=Es(f);return We(r,t,{type:"CONSTRUCT",path:e.map(v=>v.toString()),argumentList:p},d).then(Re)}});return Ya(h,r),h}function Qa(r){return Array.prototype.concat.apply([],r)}function Es(r){let t=r.map(Cr);return[t.map(e=>e[0]),Qa(t.map(e=>e[1]))]}var Is=new WeakMap;function Ja(r,t){return Is.set(r,t),r}function Za(r){return Object.assign(r,{[vs]:!0})}function Cr(r){for(let[t,e]of Ss)if(e.canHandle(r)){let[i,u]=e.serialize(r);return[{type:"HANDLER",name:t,value:i},u]}return[{type:"RAW",value:r},Is.get(r)||[]]}function Re(r){switch(r.type){case"HANDLER":return Ss.get(r.name).deserialize(r.value);case"RAW":return r.value}}function We(r,t,e,i){return new Promise(u=>{let h=Ha();t.set(h,u),r.start&&r.start(),r.postMessage(Object.assign({id:h},e),i)})}function Ha(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var Pr=class{constructor(){this.worker=null,this.workerApi=null}execute(t,e,i){return ne(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,e,i)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return ne(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),i=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:i}),this.workerApi=Sn(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let e=document.currentScript;if(e?.src)return e.src;let i=document.getElementsByTagName("script");for(let u=i.length-1;u>=0;u--){let h=i[u].src;if(h&&(h.includes("index.js")||h.includes("index.min.js")))return h}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let u=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(u!==t)return u}let e=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(e!==t)return e;let i=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(i!==t)return i}return"./worker.js"}};var ke=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,e){return Object.assign({},t,e||{})}execute(t,e){return ne(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,e);let{node:i,edge:u,enableWorker:h}=this.runtimeOptions;this.context=new Nr(t,{node:i,edge:u}),this.model=this.context.graph,h&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,e){var i;return ne(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new Pr);let u=yield this.supervisor.execute(this.id,t,e);(i=this.context)===null||i===void 0||i.replace(u)}catch(u){console.error("Layout in worker failed, fallback to main thread layout.",u),yield this.layout(e)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function Ve(r,t,e=2){if(r.nodeCount()===1){let u=r.firstNode();u.x=t[0],u.y=t[1],e===3&&(u.z=t[2]||0)}}function js(r,t){let e=r.nodes();return e.sort(t),r.setNodeOrder(e),r}function _s(r,t="desc"){return js(r,(e,i)=>{let u=r.degree(e.id),h=r.degree(i.id);return t==="asc"?u-h:h-u})}function $s(r,t){return js(r,(e,i)=>{let u=r.originalNode(e.id),h=r.originalNode(i.id);return t(u,h)})}var Be=r=>{let{width:t,height:e,center:i}=r,u=t??(typeof window<"u"?window.innerWidth:0),h=e??(typeof window<"u"?window.innerHeight:0),c=i??[u/2,h/2];return{width:u,height:h,center:c}};var Fr={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},zr=class extends ke{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return Fr}layout(){return ne(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=Be(this.options),u=this.model.nodeCount();if(!u||u===1){Ve(this.model,i);return}let{sortBy:h,maxLevelDiff:c,sweep:f,clockwise:p,equidistant:d,preventOverlap:v,startAngle:x=Fr.startAngle,nodeSize:E,nodeSpacing:M}=this.options,_=!h||h==="degree"?"degree":ir(h,["node"]);if(_==="degree")_s(this.model);else{let T=(O,j)=>{let rt=_(O),at=_(j);return rt===at?0:rt>at?-1:1};$s(this.model,T)}let N=this.model.nodes(),C=new Map;for(let T of N){let O=_==="degree"?this.model.degree(T.id):_(T._original);C.set(T.id,O)}let q=this.model.firstNode(),L=c||C.get(q.id)/4,z=Ar(E,M,Fr.nodeSize,Fr.nodeSpacing),K=new Map;for(let T of N)K.set(T.id,Math.max(...z(T._original)));let P=[{nodes:[]}],it=P[0];for(let T=0;T0){let j=it.nodes[0],rt=Math.abs(C.get(j.id)-C.get(O.id));L&&rt>=L&&(it={nodes:[]},P.push(it))}it.nodes.push(O)}for(let T of P){let O=T.nodes.map(j=>K.get(j.id));T.nodeSizes=O,T.maxNodeSize=Math.max(...O)}if(P.forEach(T=>{let O=f===void 0?2*Math.PI-2*Math.PI/T.nodes.length:f;T.dTheta=O/Math.max(1,T.nodes.length-1)}),v){let T=0;for(let O=0;O1){let rt=j.nodeSizes||[],at=0;for(let Xt=0;Xt0?at/$t:0;T=Math.max(Yt,T)}if(j.r=T,O{rt===0&&(O=j.r||0),j.r=O,O+=T})}P.forEach(T=>{let O=T.dTheta||0,j=T.r||0;T.nodes.forEach((rt,at)=>{let pt=x+(p?1:-1)*O*at;rt.x=i[0]+j*Math.cos(pt),rt.y=i[1]+j*Math.sin(pt)})})})}};function As(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function Ur(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var t=r.default;if(typeof t=="function"){var e=function i(){var u=!1;try{u=this instanceof i}catch{}return u?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};e.prototype=t.prototype}else e={};return Object.defineProperty(e,"__esModule",{value:!0}),Object.keys(r).forEach(function(i){var u=Object.getOwnPropertyDescriptor(r,i);Object.defineProperty(e,i,u.get?u:{enumerable:!0,get:function(){return r[i]}})}),e}var ut={};var kn={};rn(kn,{isAnyArray:()=>Me});var th=Object.prototype.toString;function Me(r){let t=th.call(r);return t.endsWith("Array]")&&!t.includes("Big")}var Rs=Ur(kn);var Mn={};rn(Mn,{default:()=>eh});function Ns(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Me(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;fc&&(c=r[f]);return c}function Ls(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Me(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;f1&&arguments[1]!==void 0?arguments[1]:{};if(Me(r)){if(r.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var e;if(t.output!==void 0){if(!Me(t.output))throw new TypeError("output option must be an array if specified");e=t.output}else e=new Array(r.length);var i=Ls(r),u=Ns(r);if(i===u)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var h=t.min,c=h===void 0?t.autoMinMax?i:0:h,f=t.max,p=f===void 0?t.autoMinMax?u:1:f;if(c>=p)throw new RangeError("min option must be smaller than max option");for(var d=(p-c)/(u-i),v=0;v{throw TypeError(r)};var Fo=(r,t,e)=>t in r?Nr(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var te=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports),_n=(r,t)=>{for(var e in t)Nr(r,e,{get:t[e],enumerable:!0})},zo=(r,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of Co(t))!No.call(r,u)&&u!==e&&Nr(r,u,{get:()=>t[u],enumerable:!(i=Mo(t,u))||i.enumerable});return r};var Fr=(r,t,e)=>(e=r!=null?Oo(Po(r)):{},zo(t||!r||!r.__esModule?Nr(e,"default",{value:r,enumerable:!0}):e,r));var pi=(r,t,e)=>Fo(r,typeof t!="symbol"?t+"":t,e),Rn=(r,t,e)=>t.has(r)||gi("Cannot "+e);var ke=(r,t,e)=>(Rn(r,t,"read from private field"),e?e.call(r):t.get(r)),jn=(r,t,e)=>t.has(r)?gi("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),zr=(r,t,e,i)=>(Rn(r,t,"write to private field"),i?i.call(r,e):t.set(r,e),e),An=(r,t,e)=>(Rn(r,t,"access private method"),e);var Ii=te((Wa,$n)=>{"use strict";var ur=typeof Reflect=="object"?Reflect:null,wi=ur&&typeof ur.apply=="function"?ur.apply:function(t,e,i){return Function.prototype.apply.call(t,e,i)},Ur;ur&&typeof ur.ownKeys=="function"?Ur=ur.ownKeys:Object.getOwnPropertySymbols?Ur=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:Ur=function(t){return Object.getOwnPropertyNames(t)};function Uo(r){console&&console.warn&&console.warn(r)}var mi=Number.isNaN||function(t){return t!==t};function Rt(){Rt.init.call(this)}$n.exports=Rt;$n.exports.once=Bo;Rt.EventEmitter=Rt;Rt.prototype._events=void 0;Rt.prototype._eventsCount=0;Rt.prototype._maxListeners=void 0;var yi=10;function qr(r){if(typeof r!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof r)}Object.defineProperty(Rt,"defaultMaxListeners",{enumerable:!0,get:function(){return yi},set:function(r){if(typeof r!="number"||r<0||mi(r))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+r+".");yi=r}});Rt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};Rt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||mi(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function bi(r){return r._maxListeners===void 0?Rt.defaultMaxListeners:r._maxListeners}Rt.prototype.getMaxListeners=function(){return bi(this)};Rt.prototype.emit=function(t){for(var e=[],i=1;i0&&(c=e[0]),c instanceof Error)throw c;var f=new Error("Unhandled error."+(c?" ("+c.message+")":""));throw f.context=c,f}var g=h[t];if(g===void 0)return!1;if(typeof g=="function")wi(g,this,e);else for(var d=g.length,b=ki(g,d),i=0;i0&&c.length>u&&!c.warned){c.warned=!0;var f=new Error("Possible EventEmitter memory leak detected. "+c.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");f.name="MaxListenersExceededWarning",f.emitter=r,f.type=t,f.count=c.length,Uo(f)}return r}Rt.prototype.addListener=function(t,e){return Ei(this,t,e,!1)};Rt.prototype.on=Rt.prototype.addListener;Rt.prototype.prependListener=function(t,e){return Ei(this,t,e,!0)};function qo(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function vi(r,t,e){var i={fired:!1,wrapFn:void 0,target:r,type:t,listener:e},u=qo.bind(i);return u.listener=e,i.wrapFn=u,u}Rt.prototype.once=function(t,e){return qr(e),this.on(t,vi(this,t,e)),this};Rt.prototype.prependOnceListener=function(t,e){return qr(e),this.prependListener(t,vi(this,t,e)),this};Rt.prototype.removeListener=function(t,e){var i,u,h,c,f;if(qr(e),u=this._events,u===void 0)return this;if(i=u[t],i===void 0)return this;if(i===e||i.listener===e)--this._eventsCount===0?this._events=Object.create(null):(delete u[t],u.removeListener&&this.emit("removeListener",t,i.listener||e));else if(typeof i!="function"){for(h=-1,c=i.length-1;c>=0;c--)if(i[c]===e||i[c].listener===e){f=i[c].listener,h=c;break}if(h<0)return this;h===0?i.shift():Wo(i,h),i.length===1&&(u[t]=i[0]),u.removeListener!==void 0&&this.emit("removeListener",t,f||e)}return this};Rt.prototype.off=Rt.prototype.removeListener;Rt.prototype.removeAllListeners=function(t){var e,i,u;if(i=this._events,i===void 0)return this;if(i.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):i[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete i[t]),this;if(arguments.length===0){var h=Object.keys(i),c;for(u=0;u=0;u--)this.removeListener(t,e[u]);return this};function Si(r,t,e){var i=r._events;if(i===void 0)return[];var u=i[t];return u===void 0?[]:typeof u=="function"?e?[u.listener||u]:[u]:e?Vo(u):ki(u,u.length)}Rt.prototype.listeners=function(t){return Si(this,t,!0)};Rt.prototype.rawListeners=function(t){return Si(this,t,!1)};Rt.listenerCount=function(r,t){return typeof r.listenerCount=="function"?r.listenerCount(t):xi.call(r,t)};Rt.prototype.listenerCount=xi;function xi(r){var t=this._events;if(t!==void 0){var e=t[r];if(typeof e=="function")return 1;if(e!==void 0)return e.length}return 0}Rt.prototype.eventNames=function(){return this._eventsCount>0?Ur(this._events):[]};function ki(r,t){for(var e=new Array(t),i=0;i{function Hu(r){return!r||typeof r!="object"||typeof r=="function"||Array.isArray(r)||r instanceof Set||r instanceof Map||r instanceof RegExp||r instanceof Date}function Fi(r,t){r=r||{};var e={};for(var i in t){var u=r[i],h=t[i];if(!Hu(h)){e[i]=Fi(u,h);continue}u===void 0?e[i]=h:e[i]=u}return e}zi.exports=Fi});var Qe=te((Ka,Ui)=>{Ui.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var Bi=te((Ya,Vi)=>{function qi(r){return function(t,e){return t+Math.floor(r()*(e-t+1))}}var Wi=qi(Math.random);Wi.createRandom=qi;Vi.exports=Wi});var Qi=te((Xa,Xi)=>{var th=Bi().createRandom;function Ki(r){var t=th(r);return function(e){for(var i=e.length,u=i-1,h=-1;++h{var eh=kr(),rh=Qe(),nh=Qi(),ih={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function le(r,t,e,i,u){this.wrappedCircle=u||null,this.children={},this.countChildren=0,this.id=r||null,this.next=null,this.previous=null,this.x=t||null,this.y=e||null,u?this.r=1010101:this.r=i||999}le.prototype.hasChildren=function(){return this.countChildren>0};le.prototype.addChild=function(r,t){this.children[r]=t,++this.countChildren};le.prototype.getChild=function(r){if(!this.children.hasOwnProperty(r)){var t=new le;this.children[r]=t,++this.countChildren}return this.children[r]};le.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var r=this;for(var t in r.children){var e=r.children[t];e.x+=r.x,e.y+=r.y,e.applyPositionToChildren()}}};function ts(r,t,e){for(var i in t.children){var u=t.children[i];u.hasChildren()?ts(r,u,e):e[u.id]={x:u.x,y:u.y}}}function Zr(r,t){var e=r.r-t.r,i=t.x-r.x,u=t.y-r.y;return e<0||e*e0&&e*e>i*i+u*u}function Cn(r,t){for(var e=0;eg?(u=(d+g-h)/(2*d),f=Math.sqrt(Math.max(0,g/d-u*u)),e.x=r.x-u*i-f*c,e.y=r.y-u*c+f*i):(u=(d+h-g)/(2*d),f=Math.sqrt(Math.max(0,h/d-u*u)),e.x=t.x+u*i-f*c,e.y=t.y+u*c+f*i)):(e.x=t.x+e.r,e.y=t.y)}function Hi(r,t){var e=r.r+t.r-1e-6,i=t.x-r.x,u=t.y-r.y;return e>0&&e*e>i*i+u*u}function ah(r,t){var e=r.length;if(e===0)return 0;var i,u,h,c,f,g,d,b,m,v;if(i=r[0],i.x=0,i.y=0,e<=1)return i.r;if(u=r[1],i.x=-u.r,u.x=i.r,u.y=0,e<=2)return i.r+u.r;h=r[2],Ji(u,i,h),i=new le(null,null,null,null,i),u=new le(null,null,null,null,u),h=new le(null,null,null,null,h),i.next=h.previous=u,u.next=i.previous=h,h.next=u.previous=i;t:for(g=3;g{var lh=kr(),fh=Qe(),dh={dimensions:["x","y"],center:.5,scale:1};function hs(r,t,e){if(!fh(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=lh(e,dh);var i=e.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=e.center,h=e.scale,c=Math.PI*2,f=(u-.5)*h,g=t.order,d=i[0],b=i[1];function m($,P){return P[d]=h*Math.cos($*c/g)+f,P[b]=h*Math.sin($*c/g)+f,P}var v=0;if(!r){var D={};return t.forEachNode(function($){D[$]=m(v++,{})}),D}t.updateEachNodeAttributes(function($,P){return m(v++,P),P},{attributes:i})}var as=hs.bind(null,!1);as.assign=hs.bind(null,!0);cs.exports=as});var ps=te((Ja,gs)=>{var gh=kr(),ph=Qe(),wh={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function fs(r,t,e){if(!ph(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=gh(e,wh);var i=e.dimensions;if(!Array.isArray(i)||i.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=i.length,h=e.center,c=e.rng,f=e.scale,g=(h-.5)*f;function d(m){for(var v=0;v{var yh=kr(),mh=Qe(),bh=Math.PI/180,Eh={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function ws(r,t,e,i){if(!mh(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");i=yh(i,Eh),i.degrees&&(e*=bh);var u=i.dimensions;if(!Array.isArray(u)||u.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return r?void 0:{};var h=u[0],c=u[1],f=0,g=0;if(!i.centeredOnZero){var d=1/0,b=-1/0,m=1/0,v=-1/0;t.forEachNode(function(B,G){var F=G[h],V=G[c];Fb&&(b=F),Vv&&(v=V)}),f=(d+b)/2,g=(m+v)/2}var D=Math.cos(e),$=Math.sin(e);function P(B){var G=B[h],F=B[c];return B[h]=f+(G-f)*D-(F-g)*$,B[c]=g+(G-f)*$+(F-g)*D,B}if(!r){var q={};return t.forEachNode(function(B,G){var F={};F[h]=G[h],F[c]=G[c],q[B]=P(F)}),q}t.updateEachNodeAttributes(function(B,G){return P(G),G},{attributes:u})}var ys=ws.bind(null,!1);ys.assign=ws.bind(null,!0);ms.exports=ys});var Es=te(Ir=>{Ir.circlepack=us();Ir.circular=ls();Ir.random=ps();Ir.rotation=bs()});var Pn=te(Jr=>{function vh(r){return typeof r!="number"||isNaN(r)?1:r}function Sh(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getNodeAttributes(f))},e.fromEntry=function(c,f){return u(f)}):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){return i(r(f,c.getNodeAttributes(f)))},e.fromEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h),e}function vs(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getEdgeAttributes(f))},e.fromEntry=function(c,f){return u(f)},e.fromPartialEntry=e.fromEntry,e.fromMinimalEntry=e.fromEntry):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){var g=c.extremities(f);return i(r(f,c.getEdgeAttributes(f),g[0],g[1],c.getNodeAttributes(g[0]),c.getNodeAttributes(g[1]),c.isUndirected(f)))},e.fromEntry=function(c,f,g,d,b,m,v){return i(r(c,f,g,d,b,m,v))},e.fromPartialEntry=function(c,f,g,d){return i(r(c,f,g,d))},e.fromMinimalEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h,e.fromMinimalEntry=h),e}Jr.createNodeValueGetter=Sh;Jr.createEdgeValueGetter=vs;Jr.createEdgeWeightGetter=function(r){return vs(r,vh)}});var Is=te((rc,Ds)=>{var Wt=0,Mt=1,St=2,xt=3,Pe=4,Ne=5,kt=6,Ss=7,Hr=8,xs=9,xh=0,kh=1,Dh=2,Yt=0,be=1,se=2,Ze=3,ze=4,Nt=5,fe=6,Te=7,Le=8,ks=3,Ie=10,Ih=3,ne=9,Nn=10;Ds.exports=function(t,e,i){var u,h,c,f,g,d,b,m,v,D,$=e.length,P=i.length,q=t.adjustSizes,B=t.barnesHutTheta*t.barnesHutTheta,G,F,V,z,ot,O,N,A=[];for(c=0;c<$;c+=Ie)e[c+Pe]=e[c+St],e[c+Ne]=e[c+xt],e[c+St]=0,e[c+xt]=0;if(t.outboundAttractionDistribution){for(G=0,c=0;c<$;c+=Ie)G+=e[c+kt];G/=$/Ie}if(t.barnesHutOptimize){var nt=1/0,dt=-1/0,wt=1/0,Pt=-1/0,yt,Qt,ue;for(c=0;c<$;c+=Ie)nt=Math.min(nt,e[c+Wt]),dt=Math.max(dt,e[c+Wt]),wt=Math.min(wt,e[c+Mt]),Pt=Math.max(Pt,e[c+Mt]);var gt=dt-nt,j=Pt-wt;for(gt>j?(wt-=(gt-j)/2,Pt=wt+gt):(nt-=(j-gt)/2,dt=nt+j),A[0+Yt]=-1,A[0+be]=(nt+dt)/2,A[0+se]=(wt+Pt)/2,A[0+Ze]=Math.max(dt-nt,Pt-wt),A[0+ze]=-1,A[0+Nt]=-1,A[0+fe]=0,A[0+Te]=0,A[0+Le]=0,u=1,c=0;c<$;c+=Ie)for(h=0,ue=ks;;)if(A[h+Nt]>=0){e[c+Wt]=0)if(O=Math.pow(e[c+Wt]-A[h+Te],2)+Math.pow(e[c+Mt]-A[h+Le],2),D=A[h+Ze],4*D*D/O0?(N=F*e[c+kt]*A[h+fe]/O,e[c+St]+=V*N,e[c+xt]+=z*N):O<0&&(N=-F*e[c+kt]*A[h+fe]/Math.sqrt(O),e[c+St]+=V*N,e[c+xt]+=z*N):O>0&&(N=F*e[c+kt]*A[h+fe]/O,e[c+St]+=V*N,e[c+xt]+=z*N),h=A[h+ze],h<0)break;continue}else{h=A[h+Nt];continue}else{if(d=A[h+Yt],d>=0&&d!==c&&(V=e[c+Wt]-e[d+Wt],z=e[c+Mt]-e[d+Mt],O=V*V+z*z,q===!0?O>0?(N=F*e[c+kt]*e[d+kt]/O,e[c+St]+=V*N,e[c+xt]+=z*N):O<0&&(N=-F*e[c+kt]*e[d+kt]/Math.sqrt(O),e[c+St]+=V*N,e[c+xt]+=z*N):O>0&&(N=F*e[c+kt]*e[d+kt]/O,e[c+St]+=V*N,e[c+xt]+=z*N)),h=A[h+ze],h<0)break;continue}else for(F=t.scalingRatio,f=0;f<$;f+=Ie)for(g=0;g0?(N=F*e[f+kt]*e[g+kt]/O/O,e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N):O<0&&(N=100*F*e[f+kt]*e[g+kt],e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N)):(O=Math.sqrt(V*V+z*z),O>0&&(N=F*e[f+kt]*e[g+kt]/O/O,e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N));for(v=t.gravity/t.scalingRatio,F=t.scalingRatio,c=0;c<$;c+=Ie)N=0,V=e[c+Wt],z=e[c+Mt],O=Math.sqrt(Math.pow(V,2)+Math.pow(z,2)),t.strongGravityMode?O>0&&(N=F*e[c+kt]*v):O>0&&(N=F*e[c+kt]*v/O),e[c+St]-=V*N,e[c+xt]-=z*N;for(F=1*(t.outboundAttractionDistribution?G:1),b=0;b0&&(N=-F*ot*Math.log(1+O)/O/e[f+kt]):O>0&&(N=-F*ot*Math.log(1+O)/O):t.outboundAttractionDistribution?O>0&&(N=-F*ot/e[f+kt]):O>0&&(N=-F*ot)):(O=Math.sqrt(Math.pow(V,2)+Math.pow(z,2)),t.linLogMode?t.outboundAttractionDistribution?O>0&&(N=-F*ot*Math.log(1+O)/O/e[f+kt]):O>0&&(N=-F*ot*Math.log(1+O)/O):t.outboundAttractionDistribution?(O=1,N=-F*ot/e[f+kt]):(O=1,N=-F*ot)),O>0&&(e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N);var he,ve,Q,I,bt,It;if(q===!0)for(c=0;c<$;c+=Ie)e[c+xs]!==1&&(he=Math.sqrt(Math.pow(e[c+St],2)+Math.pow(e[c+xt],2)),he>Nn&&(e[c+St]=e[c+St]*Nn/he,e[c+xt]=e[c+xt]*Nn/he),ve=e[c+kt]*Math.sqrt((e[c+Pe]-e[c+St])*(e[c+Pe]-e[c+St])+(e[c+Ne]-e[c+xt])*(e[c+Ne]-e[c+xt])),Q=Math.sqrt((e[c+Pe]+e[c+St])*(e[c+Pe]+e[c+St])+(e[c+Ne]+e[c+xt])*(e[c+Ne]+e[c+xt]))/2,I=.1*Math.log(1+Q)/(1+Math.sqrt(ve)),bt=e[c+Wt]+e[c+St]*(I/t.slowDown),e[c+Wt]=bt,It=e[c+Mt]+e[c+xt]*(I/t.slowDown),e[c+Mt]=It);else for(c=0;c<$;c+=Ie)e[c+xs]!==1&&(ve=e[c+kt]*Math.sqrt((e[c+Pe]-e[c+St])*(e[c+Pe]-e[c+St])+(e[c+Ne]-e[c+xt])*(e[c+Ne]-e[c+xt])),Q=Math.sqrt((e[c+Pe]+e[c+St])*(e[c+Pe]+e[c+St])+(e[c+Ne]+e[c+xt])*(e[c+Ne]+e[c+xt]))/2,I=e[c+Ss]*Math.log(1+Q)/(1+Math.sqrt(ve)),e[c+Ss]=Math.min(1,Math.sqrt(I*(Math.pow(e[c+St],2)+Math.pow(e[c+xt],2))/(1+Math.sqrt(ve)))),bt=e[c+Wt]+e[c+St]*(I/t.slowDown),e[c+Wt]=bt,It=e[c+Mt]+e[c+xt]*(I/t.slowDown),e[c+Mt]=It);return{}}});var Fn=te(Ue=>{var _r=10,_s=3;Ue.assign=function(r){r=r||{};var t=Array.prototype.slice.call(arguments).slice(1),e,i,u;for(e=0,u=t.length;e=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in r&&typeof r.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in r&&!(typeof r.gravity=="number"&&r.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in r&&!(typeof r.slowDown=="number"||r.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in r&&typeof r.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in r&&!(typeof r.barnesHutTheta=="number"&&r.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};Ue.graphToByteArrays=function(r,t){var e=r.order,i=r.size,u={},h,c=new Float32Array(e*_r),f=new Float32Array(i*_s);return h=0,r.forEachNode(function(g,d){u[g]=h,c[h]=d.x,c[h+1]=d.y,c[h+2]=0,c[h+3]=0,c[h+4]=0,c[h+5]=0,c[h+6]=1,c[h+7]=1,c[h+8]=d.size||1,c[h+9]=d.fixed?1:0,h+=_r}),h=0,r.forEachEdge(function(g,d,b,m,v,D,$){var P=u[b],q=u[m],B=t(g,d,b,m,v,D,$);c[P+6]+=B,c[q+6]+=B,f[h]=P,f[h+1]=q,f[h+2]=B,h+=_s}),{nodes:c,edges:f}};Ue.assignLayoutChanges=function(r,t,e){var i=0;r.updateEachNodeAttributes(function(u,h){return h.x=t[i],h.y=t[i+1],i+=_r,e?e(u,h):h})};Ue.readGraphPositions=function(r,t){var e=0;r.forEachNode(function(i,u){t[e]=u.x,t[e+1]=u.y,e+=_r})};Ue.collectLayoutChanges=function(r,t,e){for(var i=r.nodes(),u={},h=0,c=0,f=t.length;h{Rs.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var $s=te((sc,As)=>{var _h=Qe(),Rh=Pn().createEdgeWeightGetter,jh=Is(),Rr=Fn(),Ah=zn();function js(r,t,e){if(!_h(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof e=="number"&&(e={iterations:e});var i=e.iterations;if(typeof i!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(i<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var u=Rh("getEdgeWeight"in e?e.getEdgeWeight:"weight").fromEntry,h=typeof e.outputReducer=="function"?e.outputReducer:null,c=Rr.assign({},Ah,e.settings),f=Rr.validateSettings(c);if(f)throw new Error("graphology-layout-forceatlas2: "+f.message);var g=Rr.graphToByteArrays(t,u),d;for(d=0;d2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var Un=js.bind(null,!1);Un.assign=js.bind(null,!0);Un.inferSettings=$h;As.exports=Un});var Ls=te((oc,Ts)=>{Ts.exports=function(){var t,e,i={};(function(){var h=0,c=1,f=2,g=3,d=4,b=5,m=6,v=7,D=8,$=9,P=0,q=1,B=2,G=0,F=1,V=2,z=3,ot=4,O=5,N=6,A=7,nt=8,dt=3,wt=10,Pt=3,yt=9,Qt=10;i.exports=function(gt,j,he){var ve,Q,I,bt,It,X,ae,qt,st,mr,pe=j.length,Dn=he.length,Ye=gt.adjustSizes,In=gt.barnesHutTheta*gt.barnesHutTheta,tr,_t,Et,vt,we,rt,ut,M=[];for(I=0;Irr?(ce-=(er-rr)/2,Fe=ce+er):(Zt-=(rr-er)/2,je=Zt+rr),M[0+G]=-1,M[0+F]=(Zt+je)/2,M[0+V]=(ce+Fe)/2,M[0+z]=Math.max(je-Zt,Fe-ce),M[0+ot]=-1,M[0+O]=-1,M[0+N]=0,M[0+A]=0,M[0+nt]=0,ve=1,I=0;I=0){j[I+h]=0)if(rt=Math.pow(j[I+h]-M[Q+A],2)+Math.pow(j[I+c]-M[Q+nt],2),mr=M[Q+z],4*mr*mr/rt0?(ut=_t*j[I+m]*M[Q+N]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt<0&&(ut=-_t*j[I+m]*M[Q+N]/Math.sqrt(rt),j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt>0&&(ut=_t*j[I+m]*M[Q+N]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut),Q=M[Q+ot],Q<0)break;continue}else{Q=M[Q+O];continue}else{if(X=M[Q+G],X>=0&&X!==I&&(Et=j[I+h]-j[X+h],vt=j[I+c]-j[X+c],rt=Et*Et+vt*vt,Ye===!0?rt>0?(ut=_t*j[I+m]*j[X+m]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt<0&&(ut=-_t*j[I+m]*j[X+m]/Math.sqrt(rt),j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt>0&&(ut=_t*j[I+m]*j[X+m]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut)),Q=M[Q+ot],Q<0)break;continue}else for(_t=gt.scalingRatio,bt=0;bt0?(ut=_t*j[bt+m]*j[It+m]/rt/rt,j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut):rt<0&&(ut=100*_t*j[bt+m]*j[It+m],j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut)):(rt=Math.sqrt(Et*Et+vt*vt),rt>0&&(ut=_t*j[bt+m]*j[It+m]/rt/rt,j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut));for(st=gt.gravity/gt.scalingRatio,_t=gt.scalingRatio,I=0;I0&&(ut=_t*j[I+m]*st):rt>0&&(ut=_t*j[I+m]*st/rt),j[I+f]-=Et*ut,j[I+g]-=vt*ut;for(_t=1*(gt.outboundAttractionDistribution?tr:1),ae=0;ae0&&(ut=-_t*we*Math.log(1+rt)/rt/j[bt+m]):rt>0&&(ut=-_t*we*Math.log(1+rt)/rt):gt.outboundAttractionDistribution?rt>0&&(ut=-_t*we/j[bt+m]):rt>0&&(ut=-_t*we)):(rt=Math.sqrt(Math.pow(Et,2)+Math.pow(vt,2)),gt.linLogMode?gt.outboundAttractionDistribution?rt>0&&(ut=-_t*we*Math.log(1+rt)/rt/j[bt+m]):rt>0&&(ut=-_t*we*Math.log(1+rt)/rt):gt.outboundAttractionDistribution?(rt=1,ut=-_t*we/j[bt+m]):(rt=1,ut=-_t*we)),rt>0&&(j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut);var nr,Xe,ir,Ae,sr,or;if(Ye===!0)for(I=0;IQt&&(j[I+f]=j[I+f]*Qt/nr,j[I+g]=j[I+g]*Qt/nr),Xe=j[I+m]*Math.sqrt((j[I+d]-j[I+f])*(j[I+d]-j[I+f])+(j[I+b]-j[I+g])*(j[I+b]-j[I+g])),ir=Math.sqrt((j[I+d]+j[I+f])*(j[I+d]+j[I+f])+(j[I+b]+j[I+g])*(j[I+b]+j[I+g]))/2,Ae=.1*Math.log(1+ir)/(1+Math.sqrt(Xe)),sr=j[I+h]+j[I+f]*(Ae/gt.slowDown),j[I+h]=sr,or=j[I+c]+j[I+g]*(Ae/gt.slowDown),j[I+c]=or);else for(I=0;I{var Th=Ls(),Lh=Qe(),Gh=Pn().createEdgeWeightGetter,fr=Fn(),Oh=zn();function qe(r,t){if(t=t||{},!Lh(r))throw new Error("graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.");var e=Gh("getEdgeWeight"in t?t.getEdgeWeight:"weight").fromEntry,i=fr.assign({},Oh,t.settings),u=fr.validateSettings(i);if(u)throw new Error("graphology-layout-forceatlas2/worker: "+u.message);this.worker=null,this.graph=r,this.settings=i,this.getEdgeWeight=e,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer=="function"?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var h=void 0,c=this;this.handleGraphUpdate=function(){c.worker&&c.worker.terminate(),h&&clearTimeout(h),h=setTimeout(function(){h=void 0,c.spawnWorker()},0)},r.on("nodeAdded",this.handleGraphUpdate),r.on("edgeAdded",this.handleGraphUpdate),r.on("nodeDropped",this.handleGraphUpdate),r.on("edgeDropped",this.handleGraphUpdate),this.spawnWorker()}qe.prototype.isRunning=function(){return this.running};qe.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=fr.createWorker(Th),this.worker.addEventListener("message",this.handleMessage),this.running&&(this.running=!1,this.start())};qe.prototype.handleMessage=function(r){if(this.running){var t=new Float32Array(r.data.nodes);fr.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&fr.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}};qe.prototype.askForIterations=function(r){var t=this.matrices,e={settings:this.settings,nodes:t.nodes.buffer},i=[t.nodes.buffer];return r&&(e.edges=t.edges.buffer,i.push(t.edges.buffer)),this.worker.postMessage(e,i),this};qe.prototype.start=function(){if(this.killed)throw new Error("graphology-layout-forceatlas2/worker.start: layout was killed.");return this.running?this:(this.matrices=fr.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)};qe.prototype.stop=function(){return this.running=!1,this};qe.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener("nodeAdded",this.handleGraphUpdate),this.graph.removeListener("edgeAdded",this.handleGraphUpdate),this.graph.removeListener("nodeDropped",this.handleGraphUpdate),this.graph.removeListener("edgeDropped",this.handleGraphUpdate)};Gs.exports=qe});var Ai=Fr(Ii(),1);function Yo(){let r=arguments[0];for(let t=1,e=arguments.length;tr++}function Me(){let r=arguments,t=null,e=-1;return{[Symbol.iterator](){return this},next(){let i=null;do{if(t===null){if(e++,e>=r.length)return{done:!0};t=r[e][Symbol.iterator]()}if(i=t.next(),i.done){t=null;continue}break}while(!0);return i}}}function ar(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var xr=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},tt=class r extends xr{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},Z=class r extends xr{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},at=class r extends xr{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}};function Ti(r,t){this.key=r,this.attributes=t,this.clear()}Ti.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function Li(r,t){this.key=r,this.attributes=t,this.clear()}Li.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Gi(r,t){this.key=r,this.attributes=t,this.clear()}Gi.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function cr(r,t,e,i,u){this.key=t,this.attributes=u,this.undirected=r,this.source=e,this.target=i}cr.prototype.attach=function(){let r="out",t="in";this.undirected&&(r=t="undirected");let e=this.source.key,i=this.target.key;this.source[r][i]=this,!(this.undirected&&e===i)&&(this.target[t][e]=this)};cr.prototype.attachMulti=function(){let r="out",t="in",e=this.source.key,i=this.target.key;this.undirected&&(r=t="undirected");let u=this.source[r],h=u[i];if(typeof h>"u"){u[i]=this,this.undirected&&e===i||(this.target[t][e]=this);return}h.previous=this,this.next=h,u[i]=this,this.target[t][e]=this};cr.prototype.detach=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),delete this.source[e][t],delete this.target[i][r]};cr.prototype.detachMulti=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[e][t],delete this.target[i][r]):(this.next.previous=void 0,this.source[e][t]=this.next,this.target[i][r]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var Oi=0,Mi=1,Qo=2,Ci=3;function Ce(r,t,e,i,u,h,c){let f,g,d,b;if(i=""+i,e===Oi){if(f=r._nodes.get(i),!f)throw new Z(`Graph.${t}: could not find the "${i}" node in the graph.`);d=u,b=h}else if(e===Ci){if(u=""+u,g=r._edges.get(u),!g)throw new Z(`Graph.${t}: could not find the "${u}" edge in the graph.`);let m=g.source.key,v=g.target.key;if(i===m)f=g.target;else if(i===v)f=g.source;else throw new Z(`Graph.${t}: the "${i}" node is not attached to the "${u}" edge (${m}, ${v}).`);d=h,b=c}else{if(g=r._edges.get(i),!g)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`);e===Mi?f=g.source:f=g.target,d=u,b=h}return[f,d,b]}function Zo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return c.attributes[f]}}function Jo(r,t,e){r.prototype[t]=function(i,u){let[h]=Ce(this,t,e,i,u);return h.attributes}}function Ho(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return c.attributes.hasOwnProperty(f)}}function tu(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,g,d]=Ce(this,t,e,i,u,h,c);return f.attributes[g]=d,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:g}),this}}function eu(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,g,d]=Ce(this,t,e,i,u,h,c);if(typeof d!="function")throw new tt(`Graph.${t}: updater should be a function.`);let b=f.attributes,m=d(b[g]);return b[g]=m,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:g}),this}}function ru(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return delete c.attributes[f],this.emit("nodeAttributesUpdated",{key:c.key,type:"remove",attributes:c.attributes,name:f}),this}}function nu(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(!ee(f))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return c.attributes=f,this.emit("nodeAttributesUpdated",{key:c.key,type:"replace",attributes:c.attributes}),this}}function iu(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(!ee(f))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Kt(c.attributes,f),this.emit("nodeAttributesUpdated",{key:c.key,type:"merge",attributes:c.attributes,data:f}),this}}function su(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(typeof f!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return c.attributes=f(c.attributes),this.emit("nodeAttributesUpdated",{key:c.key,type:"update",attributes:c.attributes}),this}}var ou=[{name:r=>`get${r}Attribute`,attacher:Zo},{name:r=>`get${r}Attributes`,attacher:Jo},{name:r=>`has${r}Attribute`,attacher:Ho},{name:r=>`set${r}Attribute`,attacher:tu},{name:r=>`update${r}Attribute`,attacher:eu},{name:r=>`remove${r}Attribute`,attacher:ru},{name:r=>`replace${r}Attributes`,attacher:nu},{name:r=>`merge${r}Attributes`,attacher:iu},{name:r=>`update${r}Attributes`,attacher:su}];function uu(r){ou.forEach(function({name:t,attacher:e}){e(r,t("Node"),Oi),e(r,t("Source"),Mi),e(r,t("Target"),Qo),e(r,t("Opposite"),Ci)})}function hu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes[u]}}function au(r,t,e){r.prototype[t]=function(i){let u;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let h=""+i,c=""+arguments[1];if(u=me(this,h,c,e),!u)throw new Z(`Graph.${t}: could not find an edge for the given path ("${h}" - "${c}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,u=this._edges.get(i),!u)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return u.attributes}}function cu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes.hasOwnProperty(u)}}function lu(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,g=""+u;if(u=arguments[2],h=arguments[3],c=me(this,f,g,e),!c)throw new Z(`Graph.${t}: could not find an edge for the given path ("${f}" - "${g}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return c.attributes[u]=h,this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function fu(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,g=""+u;if(u=arguments[2],h=arguments[3],c=me(this,f,g,e),!c)throw new Z(`Graph.${t}: could not find an edge for the given path ("${f}" - "${g}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof h!="function")throw new tt(`Graph.${t}: updater should be a function.`);return c.attributes[u]=h(c.attributes[u]),this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function du(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return delete h.attributes[u],this.emit("edgeAttributesUpdated",{key:h.key,type:"remove",attributes:h.attributes,name:u}),this}}function gu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!ee(u))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return h.attributes=u,this.emit("edgeAttributesUpdated",{key:h.key,type:"replace",attributes:h.attributes}),this}}function pu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!ee(u))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Kt(h.attributes,u),this.emit("edgeAttributesUpdated",{key:h.key,type:"merge",attributes:h.attributes,data:u}),this}}function wu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof u!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return h.attributes=u(h.attributes),this.emit("edgeAttributesUpdated",{key:h.key,type:"update",attributes:h.attributes}),this}}var yu=[{name:r=>`get${r}Attribute`,attacher:hu},{name:r=>`get${r}Attributes`,attacher:au},{name:r=>`has${r}Attribute`,attacher:cu},{name:r=>`set${r}Attribute`,attacher:lu},{name:r=>`update${r}Attribute`,attacher:fu},{name:r=>`remove${r}Attribute`,attacher:du},{name:r=>`replace${r}Attributes`,attacher:gu},{name:r=>`merge${r}Attributes`,attacher:pu},{name:r=>`update${r}Attributes`,attacher:wu}];function mu(r){yu.forEach(function({name:t,attacher:e}){e(r,t("Edge"),"mixed"),e(r,t("DirectedEdge"),"directed"),e(r,t("UndirectedEdge"),"undirected")})}var bu=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function Eu(r,t,e,i){let u=!1;for(let h in t){if(h===i)continue;let c=t[h];if(u=e(c.key,c.attributes,c.source.key,c.target.key,c.source.attributes,c.target.attributes,c.undirected),r&&u)return c.key}}function vu(r,t,e,i){let u,h,c,f=!1;for(let g in t)if(g!==i){u=t[g];do{if(h=u.source,c=u.target,f=e(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected),r&&f)return u.key;u=u.next}while(u!==void 0)}}function Tn(r,t){let e=Object.keys(r),i=e.length,u,h=0;return{[Symbol.iterator](){return this},next(){do if(u)u=u.next;else{if(h>=i)return{done:!0};let c=e[h++];if(c===t){u=void 0;continue}u=r[c]}while(!u);return{done:!1,value:{edge:u.key,attributes:u.attributes,source:u.source.key,target:u.target.key,sourceAttributes:u.source.attributes,targetAttributes:u.target.attributes,undirected:u.undirected}}}}}function Su(r,t,e,i){let u=t[e];if(!u)return;let h=u.source,c=u.target;if(i(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected)&&r)return u.key}function xu(r,t,e,i){let u=t[e];if(!u)return;let h=!1;do{if(h=i(u.key,u.attributes,u.source.key,u.target.key,u.source.attributes,u.target.attributes,u.undirected),r&&h)return u.key;u=u.next}while(u!==void 0)}function Ln(r,t){let e=r[t];if(e.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!e)return{done:!0};let u={edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected};return e=e.next,{done:!1,value:u}}};let i=!1;return{[Symbol.iterator](){return this},next(){return i===!0?{done:!0}:(i=!0,{done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}})}}}function ku(r,t){if(r.size===0)return[];if(t==="mixed"||t===r.type)return Array.from(r._edges.keys());let e=t==="undirected"?r.undirectedSize:r.directedSize,i=new Array(e),u=t==="undirected",h=r._edges.values(),c=0,f,g;for(;f=h.next(),f.done!==!0;)g=f.value,g.undirected===u&&(i[c++]=g.key);return i}function Pi(r,t,e,i){if(t.size===0)return;let u=e!=="mixed"&&e!==t.type,h=e==="undirected",c,f,g=!1,d=t._edges.values();for(;c=d.next(),c.done!==!0;){if(f=c.value,u&&f.undirected!==h)continue;let{key:b,attributes:m,source:v,target:D}=f;if(g=i(b,m,v.key,D.key,v.attributes,D.attributes,f.undirected),r&&g)return b}}function Du(r,t){if(r.size===0)return ar();let e=t!=="mixed"&&t!==r.type,i=t==="undirected",u=r._edges.values();return{[Symbol.iterator](){return this},next(){let h,c;for(;;){if(h=u.next(),h.done)return h;if(c=h.value,!(e&&c.undirected!==i))break}return{value:{edge:c.key,attributes:c.attributes,source:c.source.key,target:c.target.key,sourceAttributes:c.source.attributes,targetAttributes:c.target.attributes,undirected:c.undirected},done:!1}}}}function Gn(r,t,e,i,u,h){let c=t?vu:Eu,f;if(e!=="undirected"&&(i!=="out"&&(f=c(r,u.in,h),r&&f)||i!=="in"&&(f=c(r,u.out,h,i?void 0:u.key),r&&f))||e!=="directed"&&(f=c(r,u.undirected,h),r&&f))return f}function Iu(r,t,e,i){let u=[];return Gn(!1,r,t,e,i,function(h){u.push(h)}),u}function _u(r,t,e){let i=ar();return r!=="undirected"&&(t!=="out"&&typeof e.in<"u"&&(i=Me(i,Tn(e.in))),t!=="in"&&typeof e.out<"u"&&(i=Me(i,Tn(e.out,t?void 0:e.key)))),r!=="directed"&&typeof e.undirected<"u"&&(i=Me(i,Tn(e.undirected))),i}function On(r,t,e,i,u,h,c){let f=e?xu:Su,g;if(t!=="undirected"&&(typeof u.in<"u"&&i!=="out"&&(g=f(r,u.in,h,c),r&&g)||typeof u.out<"u"&&i!=="in"&&(i||u.key!==h)&&(g=f(r,u.out,h,c),r&&g))||t!=="directed"&&typeof u.undirected<"u"&&(g=f(r,u.undirected,h,c),r&&g))return g}function Ru(r,t,e,i,u){let h=[];return On(!1,r,t,e,i,u,function(c){h.push(c)}),h}function ju(r,t,e,i){let u=ar();return r!=="undirected"&&(typeof e.in<"u"&&t!=="out"&&i in e.in&&(u=Me(u,Ln(e.in,i))),typeof e.out<"u"&&t!=="in"&&i in e.out&&(t||e.key!==i)&&(u=Me(u,Ln(e.out,i)))),r!=="directed"&&typeof e.undirected<"u"&&i in e.undirected&&(u=Me(u,Ln(e.undirected,i))),u}function Au(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h,c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];if(!arguments.length)return ku(this,i);if(arguments.length===1){h=""+h;let f=this._nodes.get(h);if(typeof f>"u")throw new Z(`Graph.${e}: could not find the "${h}" node in the graph.`);return Iu(this.multi,i==="mixed"?this.type:i,u,f)}if(arguments.length===2){h=""+h,c=""+c;let f=this._nodes.get(h);if(!f)throw new Z(`Graph.${e}: could not find the "${h}" source node in the graph.`);if(!this._nodes.has(c))throw new Z(`Graph.${e}: could not find the "${c}" target node in the graph.`);return Ru(i,this.multi,u,f,c)}throw new tt(`Graph.${e}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function $u(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,b,m){if(!(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)){if(arguments.length===1)return m=d,Pi(!1,this,i,m);if(arguments.length===2){d=""+d,m=b;let v=this._nodes.get(d);if(typeof v>"u")throw new Z(`Graph.${h}: could not find the "${d}" node in the graph.`);return Gn(!1,this.multi,i==="mixed"?this.type:i,u,v,m)}if(arguments.length===3){d=""+d,b=""+b;let v=this._nodes.get(d);if(!v)throw new Z(`Graph.${h}: could not find the "${d}" source node in the graph.`);if(!this._nodes.has(b))throw new Z(`Graph.${h}: could not find the "${b}" target node in the graph.`);return On(!1,i,this.multi,u,v,b,m)}throw new tt(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(){let d=Array.prototype.slice.call(arguments),b=d.pop(),m;if(d.length===0){let v=0;i!=="directed"&&(v+=this.undirectedSize),i!=="undirected"&&(v+=this.directedSize),m=new Array(v);let D=0;d.push(($,P,q,B,G,F,V)=>{m[D++]=b($,P,q,B,G,F,V)})}else m=[],d.push((v,D,$,P,q,B,G)=>{m.push(b(v,D,$,P,q,B,G))});return this[h].apply(this,d),m};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(){let d=Array.prototype.slice.call(arguments),b=d.pop(),m=[];return d.push((v,D,$,P,q,B,G)=>{b(v,D,$,P,q,B,G)&&m.push(v)}),this[h].apply(this,d),m};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(){let d=Array.prototype.slice.call(arguments);if(d.length<2||d.length>4)throw new tt(`Graph.${g}: invalid number of arguments (expecting 2, 3 or 4 and got ${d.length}).`);if(typeof d[d.length-1]=="function"&&typeof d[d.length-2]!="function")throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let b,m;d.length===2?(b=d[0],m=d[1],d=[]):d.length===3?(b=d[1],m=d[2],d=[d[0]]):d.length===4&&(b=d[2],m=d[3],d=[d[0],d[1]]);let v=m;return d.push((D,$,P,q,B,G,F)=>{v=b(v,D,$,P,q,B,G,F)}),this[h].apply(this,d),v}}function Tu(r,t){let{name:e,type:i,direction:u}=t,h="find"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(g,d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return!1;if(arguments.length===1)return b=g,Pi(!0,this,i,b);if(arguments.length===2){g=""+g,b=d;let m=this._nodes.get(g);if(typeof m>"u")throw new Z(`Graph.${h}: could not find the "${g}" node in the graph.`);return Gn(!0,this.multi,i==="mixed"?this.type:i,u,m,b)}if(arguments.length===3){g=""+g,d=""+d;let m=this._nodes.get(g);if(!m)throw new Z(`Graph.${h}: could not find the "${g}" source node in the graph.`);if(!this._nodes.has(d))throw new Z(`Graph.${h}: could not find the "${d}" target node in the graph.`);return On(!0,i,this.multi,u,m,d,b)}throw new tt(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let c="some"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[c]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((m,v,D,$,P,q,B)=>d(m,v,D,$,P,q,B)),!!this[h].apply(this,g)};let f="every"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[f]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((m,v,D,$,P,q,B)=>!d(m,v,D,$,P,q,B)),!this[h].apply(this,g)}}function Lu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return ar();if(!arguments.length)return Du(this,i);if(arguments.length===1){c=""+c;let g=this._nodes.get(c);if(!g)throw new Z(`Graph.${h}: could not find the "${c}" node in the graph.`);return _u(i,u,g)}if(arguments.length===2){c=""+c,f=""+f;let g=this._nodes.get(c);if(!g)throw new Z(`Graph.${h}: could not find the "${c}" source node in the graph.`);if(!this._nodes.has(f))throw new Z(`Graph.${h}: could not find the "${f}" target node in the graph.`);return ju(i,u,g,f)}throw new tt(`Graph.${h}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Gu(r){bu.forEach(t=>{Au(r,t),$u(r,t),Tu(r,t),Lu(r,t)})}var Ou=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function Qr(){this.A=null,this.B=null}Qr.prototype.wrap=function(r){this.A===null?this.A=r:this.B===null&&(this.B=r)};Qr.prototype.has=function(r){return this.A!==null&&r in this.A||this.B!==null&&r in this.B};function vr(r,t,e,i,u){for(let h in i){let c=i[h],f=c.source,g=c.target,d=f===e?g:f;if(t&&t.has(d.key))continue;let b=u(d.key,d.attributes);if(r&&b)return d.key}}function Mn(r,t,e,i,u){if(t!=="mixed"){if(t==="undirected")return vr(r,null,i,i.undirected,u);if(typeof e=="string")return vr(r,null,i,i[e],u)}let h=new Qr,c;if(t!=="undirected"){if(e!=="out"){if(c=vr(r,null,i,i.in,u),r&&c)return c;h.wrap(i.in)}if(e!=="in"){if(c=vr(r,h,i,i.out,u),r&&c)return c;h.wrap(i.out)}}if(t!=="directed"&&(c=vr(r,h,i,i.undirected,u),r&&c))return c}function Mu(r,t,e){if(r!=="mixed"){if(r==="undirected")return Object.keys(e.undirected);if(typeof t=="string")return Object.keys(e[t])}let i=[];return Mn(!1,r,t,e,function(u){i.push(u)}),i}function Sr(r,t,e){let i=Object.keys(e),u=i.length,h=0;return{[Symbol.iterator](){return this},next(){let c=null;do{if(h>=u)return r&&r.wrap(e),{done:!0};let f=e[i[h++]],g=f.source,d=f.target;if(c=g===t?d:g,r&&r.has(c.key)){c=null;continue}}while(c===null);return{done:!1,value:{neighbor:c.key,attributes:c.attributes}}}}}function Cu(r,t,e){if(r!=="mixed"){if(r==="undirected")return Sr(null,e,e.undirected);if(typeof t=="string")return Sr(null,e,e[t])}let i=ar(),u=new Qr;return r!=="undirected"&&(t!=="out"&&(i=Me(i,Sr(u,e,e.in))),t!=="in"&&(i=Me(i,Sr(u,e,e.out)))),r!=="directed"&&(i=Me(i,Sr(u,e,e.undirected))),i}function Pu(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];h=""+h;let c=this._nodes.get(h);if(typeof c>"u")throw new Z(`Graph.${e}: could not find the "${h}" node in the graph.`);return Mu(i==="mixed"?this.type:i,u,c)}}function Nu(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let m=this._nodes.get(d);if(typeof m>"u")throw new Z(`Graph.${h}: could not find the "${d}" node in the graph.`);Mn(!1,i==="mixed"?this.type:i,u,m,b)};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(d,b){let m=[];return this[h](d,(v,D)=>{m.push(b(v,D))}),m};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(d,b){let m=[];return this[h](d,(v,D)=>{b(v,D)&&m.push(v)}),m};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(d,b,m){if(arguments.length<3)throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let v=m;return this[h](d,(D,$)=>{v=b(v,D,$)}),v}}function Fu(r,t){let{name:e,type:i,direction:u}=t,h=e[0].toUpperCase()+e.slice(1,-1),c="find"+h;r.prototype[c]=function(d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let m=this._nodes.get(d);if(typeof m>"u")throw new Z(`Graph.${c}: could not find the "${d}" node in the graph.`);return Mn(!0,i==="mixed"?this.type:i,u,m,b)};let f="some"+h;r.prototype[f]=function(d,b){return!!this[c](d,b)};let g="every"+h;r.prototype[g]=function(d,b){return!this[c](d,(v,D)=>!b(v,D))}}function zu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return ar();c=""+c;let f=this._nodes.get(c);if(typeof f>"u")throw new Z(`Graph.${h}: could not find the "${c}" node in the graph.`);return Cu(i==="mixed"?this.type:i,u,f)}}function Uu(r){Ou.forEach(t=>{Pu(r,t),Nu(r,t),Fu(r,t),zu(r,t)})}function Wr(r,t,e,i,u){let h=i._nodes.values(),c=i.type,f,g,d,b,m,v,D;for(;f=h.next(),f.done!==!0;){let $=!1;if(g=f.value,c!=="undirected"){b=g.out;for(d in b){m=b[d];do{if(v=m.target,$=!0,D=u(g.key,v.key,g.attributes,v.attributes,m.key,m.attributes,m.undirected),r&&D)return m;m=m.next}while(m)}}if(c!=="directed"){b=g.undirected;for(d in b)if(!(t&&g.key>d)){m=b[d];do{if(v=m.target,v.key!==d&&(v=m.source),$=!0,D=u(g.key,v.key,g.attributes,v.attributes,m.key,m.attributes,m.undirected),r&&D)return m;m=m.next}while(m)}}if(e&&!$&&(D=u(g.key,null,g.attributes,null,null,null,null),r&&D))return null}}function qu(r,t){let e={key:r};return $i(t.attributes)||(e.attributes=Kt({},t.attributes)),e}function Wu(r,t,e){let i={key:t,source:e.source.key,target:e.target.key};return $i(e.attributes)||(i.attributes=Kt({},e.attributes)),r==="mixed"&&e.undirected&&(i.undirected=!0),i}function Vu(r){if(!ee(r))throw new tt('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in r))throw new tt("Graph.import: serialized node is missing its key.");if("attributes"in r&&(!ee(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function Bu(r){if(!ee(r))throw new tt('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in r))throw new tt("Graph.import: serialized edge is missing its source.");if(!("target"in r))throw new tt("Graph.import: serialized edge is missing its target.");if("attributes"in r&&(!ee(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in r&&typeof r.undirected!="boolean")throw new tt("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var Ku=Xo(),Yu=new Set(["directed","undirected","mixed"]),Ri=new Set(["domain","_events","_eventsCount","_maxListeners"]),Xu=[{name:r=>`${r}Edge`,generateKey:!0},{name:r=>`${r}DirectedEdge`,generateKey:!0,type:"directed"},{name:r=>`${r}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:r=>`${r}EdgeWithKey`},{name:r=>`${r}DirectedEdgeWithKey`,type:"directed"},{name:r=>`${r}UndirectedEdgeWithKey`,type:"undirected"}],Qu={allowSelfLoops:!0,multi:!1,type:"mixed"};function Zu(r,t,e){if(e&&!ee(e))throw new tt(`Graph.addNode: invalid attributes. Expecting an object but got "${e}"`);if(t=""+t,e=e||{},r._nodes.has(t))throw new at(`Graph.addNode: the "${t}" node already exist in the graph.`);let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function ji(r,t,e){let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function Ni(r,t,e,i,u,h,c,f){if(!i&&r.type==="undirected")throw new at(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new at(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(f&&!ee(f))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`);if(h=""+h,c=""+c,f=f||{},!r.allowSelfLoops&&h===c)throw new at(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let g=r._nodes.get(h),d=r._nodes.get(c);if(!g)throw new Z(`Graph.${t}: source node "${h}" not found.`);if(!d)throw new Z(`Graph.${t}: target node "${c}" not found.`);let b={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new at(`Graph.${t}: the "${u}" edge already exists in the graph.`);if(!r.multi&&(i?typeof g.undirected[c]<"u":typeof g.out[c]<"u"))throw new at(`Graph.${t}: an edge linking "${h}" to "${c}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let m=new cr(i,u,g,d,f);r._edges.set(u,m);let v=h===c;return i?(g.undirectedDegree++,d.undirectedDegree++,v&&(g.undirectedLoops++,r._undirectedSelfLoopCount++)):(g.outDegree++,d.inDegree++,v&&(g.directedLoops++,r._directedSelfLoopCount++)),r.multi?m.attachMulti():m.attach(),i?r._undirectedSize++:r._directedSize++,b.key=u,r.emit("edgeAdded",b),u}function Ju(r,t,e,i,u,h,c,f,g){if(!i&&r.type==="undirected")throw new at(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new at(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(f){if(g){if(typeof f!="function")throw new tt(`Graph.${t}: invalid updater function. Expecting a function but got "${f}"`)}else if(!ee(f))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`)}h=""+h,c=""+c;let d;if(g&&(d=f,f=void 0),!r.allowSelfLoops&&h===c)throw new at(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let b=r._nodes.get(h),m=r._nodes.get(c),v,D;if(!e&&(v=r._edges.get(u),v)){if((v.source.key!==h||v.target.key!==c)&&(!i||v.source.key!==c||v.target.key!==h))throw new at(`Graph.${t}: inconsistency detected when attempting to merge the "${u}" edge with "${h}" source & "${c}" target vs. ("${v.source.key}", "${v.target.key}").`);D=v}if(!D&&!r.multi&&b&&(D=i?b.undirected[c]:b.out[c]),D){let G=[D.key,!1,!1,!1];if(g?!d:!f)return G;if(g){let F=D.attributes;D.attributes=d(F),r.emit("edgeAttributesUpdated",{type:"replace",key:D.key,attributes:D.attributes})}else Kt(D.attributes,f),r.emit("edgeAttributesUpdated",{type:"merge",key:D.key,attributes:D.attributes,data:f});return G}f=f||{},g&&d&&(f=d(f));let $={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new at(`Graph.${t}: the "${u}" edge already exists in the graph.`);let P=!1,q=!1;b||(b=ji(r,h,{}),P=!0,h===c&&(m=b,q=!0)),m||(m=ji(r,c,{}),q=!0),v=new cr(i,u,b,m,f),r._edges.set(u,v);let B=h===c;return i?(b.undirectedDegree++,m.undirectedDegree++,B&&(b.undirectedLoops++,r._undirectedSelfLoopCount++)):(b.outDegree++,m.inDegree++,B&&(b.directedLoops++,r._directedSelfLoopCount++)),r.multi?v.attachMulti():v.attach(),i?r._undirectedSize++:r._directedSize++,$.key=u,r.emit("edgeAdded",$),[u,!0,P,q]}function hr(r,t){r._edges.delete(t.key);let{source:e,target:i,attributes:u}=t,h=t.undirected,c=e===i;h?(e.undirectedDegree--,i.undirectedDegree--,c&&(e.undirectedLoops--,r._undirectedSelfLoopCount--)):(e.outDegree--,i.inDegree--,c&&(e.directedLoops--,r._directedSelfLoopCount--)),r.multi?t.detachMulti():t.detach(),h?r._undirectedSize--:r._directedSize--,r.emit("edgeDropped",{key:t.key,attributes:u,source:e.key,target:i.key,undirected:h})}var At=class r extends Ai.EventEmitter{constructor(t){if(super(),t=Kt({},Qu,t),typeof t.multi!="boolean")throw new tt(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Yu.has(t.type))throw new tt(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new tt(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let e=t.type==="mixed"?Ti:t.type==="directed"?Li:Gi;ye(this,"NodeDataClass",e);let i="geid_"+Ku()+"_",u=0,h=()=>{let c;do c=i+u++;while(this._edges.has(c));return c};ye(this,"_attributes",{}),ye(this,"_nodes",new Map),ye(this,"_edges",new Map),ye(this,"_directedSize",0),ye(this,"_undirectedSize",0),ye(this,"_directedSelfLoopCount",0),ye(this,"_undirectedSelfLoopCount",0),ye(this,"_edgeKeyGenerator",h),ye(this,"_options",t),Ri.forEach(c=>ye(this,c,this[c])),De(this,"order",()=>this._nodes.size),De(this,"size",()=>this._edges.size),De(this,"directedSize",()=>this._directedSize),De(this,"undirectedSize",()=>this._undirectedSize),De(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),De(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),De(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),De(this,"multi",this._options.multi),De(this,"type",this._options.type),De(this,"allowSelfLoops",this._options.allowSelfLoops),De(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,e){if(this.type==="undirected")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&!u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.out.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,e){if(this.type==="directed")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,e){if(arguments.length===1){let i=""+t;return this._edges.has(i)}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?typeof i.out<"u"&&i.out.hasOwnProperty(e)||typeof i.undirected<"u"&&i.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,e){if(this.type==="undirected")return;if(t=""+t,e=""+e,this.multi)throw new at("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let i=this._nodes.get(t);if(!i)throw new Z(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.directedEdge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||void 0;if(u)return u.key}undirectedEdge(t,e){if(this.type==="directed")return;if(t=""+t,e=""+e,this.multi)throw new at("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let i=this._nodes.get(t);if(!i)throw new Z(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.undirectedEdge: could not find the "${e}" target node in the graph.`);let u=i.undirected&&i.undirected[e]||void 0;if(u)return u.key}edge(t,e){if(this.multi)throw new at("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.edge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||i.undirected&&i.undirected[e]||void 0;if(u)return u.key}areDirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in||e in i.out}areOutNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.out}areInNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in}areUndirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:e in i.undirected}areNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(e in i.in||e in i.out)||this.type!=="directed"&&e in i.undirected}areInboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.in||this.type!=="directed"&&e in i.undirected}areOutboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.out||this.type!=="directed"&&e in i.undirected}inDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree}outDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree}directedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree}undirectedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree}inboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree),i}outboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.outDegree),i}degree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.degree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree),i}inDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree-e.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree-e.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree-e.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree-e.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree,u+=e.directedLoops),i-u}outboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.outDegree,u+=e.directedLoops),i-u}degreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree,u+=e.directedLoops*2),i-u}source(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.source: could not find the "${t}" edge in the graph.`);return e.source.key}target(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.target: could not find the "${t}" edge in the graph.`);return e.target.key}extremities(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[e.source.key,e.target.key]}opposite(t,e){t=""+t,e=""+e;let i=this._edges.get(e);if(!i)throw new Z(`Graph.opposite: could not find the "${e}" edge in the graph.`);let u=i.source.key,h=i.target.key;if(t===u)return h;if(t===h)return u;throw new Z(`Graph.opposite: the "${t}" node is not attached to the "${e}" edge (${u}, ${h}).`)}hasExtremity(t,e){t=""+t,e=""+e;let i=this._edges.get(t);if(!i)throw new Z(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return i.source.key===e||i.target.key===e}isUndirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return e.undirected}isDirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!e.undirected}isSelfLoop(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return e.source===e.target}addNode(t,e){return Zu(this,t,e).key}mergeNode(t,e){if(e&&!ee(e))throw new tt(`Graph.mergeNode: invalid attributes. Expecting an object but got "${e}"`);t=""+t,e=e||{};let i=this._nodes.get(t);return i?(e&&(Kt(i.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:i.attributes,data:e})),[t,!1]):(i=new this.NodeDataClass(t,e),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])}updateNode(t,e){if(e&&typeof e!="function")throw new tt(`Graph.updateNode: invalid updater function. Expecting a function but got "${e}"`);t=""+t;let i=this._nodes.get(t);if(i){if(e){let h=i.attributes;i.attributes=e(h),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:i.attributes})}return[t,!1]}let u=e?e({}):{};return i=new this.NodeDataClass(t,u),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:u}),[t,!0]}dropNode(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.dropNode: could not find the "${t}" node in the graph.`);let i;if(this.type!=="undirected"){for(let u in e.out){i=e.out[u];do hr(this,i),i=i.next;while(i)}for(let u in e.in){i=e.in[u];do hr(this,i),i=i.next;while(i)}}if(this.type!=="directed")for(let u in e.undirected){i=e.undirected[u];do hr(this,i),i=i.next;while(i)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:e.attributes})}dropEdge(t){let e;if(arguments.length>1){let i=""+arguments[0],u=""+arguments[1];if(e=me(this,i,u,this.type),!e)throw new Z(`Graph.dropEdge: could not find the "${i}" -> "${u}" edge in the graph.`)}else if(t=""+t,e=this._edges.get(t),!e)throw new Z(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return hr(this,e),this}dropDirectedEdge(t,e){if(arguments.length<2)throw new at("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new at("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,e=""+e;let i=me(this,t,e,"directed");if(!i)throw new Z(`Graph.dropDirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return hr(this,i),this}dropUndirectedEdge(t,e){if(arguments.length<2)throw new at("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new at("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let i=me(this,t,e,"undirected");if(!i)throw new Z(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return hr(this,i),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),e;for(;e=t.next(),e.done!==!0;)e.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,e){if(typeof e!="function")throw new tt("Graph.updateAttribute: updater should be a function.");let i=this._attributes[t];return this._attributes[t]=e(i),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!ee(t))throw new tt("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!ee(t))throw new tt("Graph.mergeAttributes: provided attributes are not a plain object.");return Kt(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new tt("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!_i(e))throw new tt("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._nodes.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,h.attributes=t(h.key,h.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})}updateEachEdgeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!_i(e))throw new tt("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._edges.values(),u,h,c,f;for(;u=i.next(),u.done!==!0;)h=u.value,c=h.source,f=h.target,h.attributes=t(h.key,h.attributes,c.key,f.key,c.attributes,f.attributes,h.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntry: expecting a callback.");Wr(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");Wr(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");Wr(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");Wr(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new tt("Graph.forEachNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)}findNode(t){if(typeof t!="function")throw new tt("Graph.findNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return u.key}mapNodes(t){if(typeof t!="function")throw new tt("Graph.mapNode: expecting a callback.");let e=this._nodes.values(),i,u,h=new Array(this.order),c=0;for(;i=e.next(),i.done!==!0;)u=i.value,h[c++]=t(u.key,u.attributes);return h}someNode(t){if(typeof t!="function")throw new tt("Graph.someNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new tt("Graph.everyNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,!t(u.key,u.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new tt("Graph.filterNodes: expecting a callback.");let e=this._nodes.values(),i,u,h=[];for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)&&h.push(u.key);return h}reduceNodes(t,e){if(typeof t!="function")throw new tt("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new tt("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let i=e,u=this._nodes.values(),h,c;for(;h=u.next(),h.done!==!0;)c=h.value,i=t(i,c.key,c.attributes);return i}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let e=t.next();if(e.done)return e;let i=e.value;return{value:{node:i.key,attributes:i.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),e=0;this._nodes.forEach((u,h)=>{t[e++]=qu(h,u)});let i=new Array(this._edges.size);return e=0,this._edges.forEach((u,h)=>{i[e++]=Wu(this.type,h,u)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:i}}import(t,e=!1){if(t instanceof r)return t.forEachNode((g,d)=>{e?this.mergeNode(g,d):this.addNode(g,d)}),t.forEachEdge((g,d,b,m,v,D,$)=>{e?$?this.mergeUndirectedEdgeWithKey(g,b,m,d):this.mergeDirectedEdgeWithKey(g,b,m,d):$?this.addUndirectedEdgeWithKey(g,b,m,d):this.addDirectedEdgeWithKey(g,b,m,d)}),this;if(!ee(t))throw new tt("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!ee(t.attributes))throw new tt("Graph.import: invalid attributes. Expecting a plain object.");e?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let i,u,h,c,f;if(t.nodes){if(h=t.nodes,!Array.isArray(h))throw new tt("Graph.import: invalid nodes. Expecting an array.");for(i=0,u=h.length;i{let h=Kt({},i.attributes);i=new e.NodeDataClass(u,h),e._nodes.set(u,i)}),e}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new at(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new at("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new at("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let e=this.emptyCopy(t),i=this._edges.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,Ni(e,"copy",!1,h.undirected,h.key,h.source.key,h.target.key,Kt({},h.attributes));return e}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((h,c)=>{t[c]=h.attributes});let e={},i={};this._edges.forEach((h,c)=>{let f=h.undirected?"--":"->",g="",d=h.source.key,b=h.target.key,m;h.undirected&&d>b&&(m=d,d=b,b=m);let v=`(${d})${f}(${b})`;c.startsWith("geid_")?this.multi&&(typeof i[v]>"u"?i[v]=0:i[v]++,g+=`${i[v]}. `):g+=`[${c}]: `,g+=v,e[g]=h.attributes});let u={};for(let h in this)this.hasOwnProperty(h)&&!Ri.has(h)&&typeof this[h]!="function"&&typeof h!="symbol"&&(u[h]=this[h]);return u.attributes=this._attributes,u.nodes=t,u.edges=e,ye(u,"constructor",this.constructor),u}};typeof Symbol<"u"&&(At.prototype[Symbol.for("nodejs.util.inspect.custom")]=At.prototype.inspect);Xu.forEach(r=>{["add","merge","update"].forEach(t=>{let e=r.name(t),i=t==="add"?Ni:Ju;r.generateKey?At.prototype[e]=function(u,h,c){return i(this,e,!0,(r.type||this.type)==="undirected",null,u,h,c,t==="update")}:At.prototype[e]=function(u,h,c,f){return i(this,e,!1,(r.type||this.type)==="undirected",u,h,c,f,t==="update")}})});uu(At);mu(At);Gu(At);Uu(At);var Vr=class extends At{constructor(t){let e=Kt({type:"directed"},t);if("multi"in e&&e.multi!==!1)throw new tt("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="directed")throw new tt('DirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Br=class extends At{constructor(t){let e=Kt({type:"undirected"},t);if("multi"in e&&e.multi!==!1)throw new tt("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="undirected")throw new tt('UndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Kr=class extends At{constructor(t){let e=Kt({multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(e)}},Yr=class extends At{constructor(t){let e=Kt({type:"directed",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="directed")throw new tt('MultiDirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Xr=class extends At{constructor(t){let e=Kt({type:"undirected",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="undirected")throw new tt('MultiUndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}};function lr(r){r.from=function(t,e){let i=Kt({},t.options,e),u=new r(i);return u.import(t),u}}lr(At);lr(Vr);lr(Br);lr(Kr);lr(Yr);lr(Xr);At.Graph=At;At.DirectedGraph=Vr;At.UndirectedGraph=Br;At.MultiGraph=Kr;At.MultiDirectedGraph=Yr;At.MultiUndirectedGraph=Xr;At.InvalidArgumentsGraphError=tt;At.NotFoundGraphError=Z;At.UsageGraphError=at;var kn=Fr(Es(),1),za=Fr($s(),1),Ua=Fr(Os(),1);function Ee(r,t,e,i){function u(h){return h instanceof e?h:new e(function(c){c(h)})}return new(e||(e=Promise))(function(h,c){function f(b){try{d(i.next(b))}catch(m){c(m)}}function g(b){try{d(i.throw(b))}catch(m){c(m)}}function d(b){b.done?h(b.value):u(b.value).then(f,g)}d((i=i.apply(r,t||[])).next())})}var Mh={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},Ft=class extends Error{constructor(t,e,i){super(t),this.position=e,this.token=i,this.name="ExpressionError"}},ft;(function(r){r[r.STRING=0]="STRING",r[r.NUMBER=1]="NUMBER",r[r.BOOLEAN=2]="BOOLEAN",r[r.NULL=3]="NULL",r[r.IDENTIFIER=4]="IDENTIFIER",r[r.OPERATOR=5]="OPERATOR",r[r.FUNCTION=6]="FUNCTION",r[r.DOT=7]="DOT",r[r.BRACKET_LEFT=8]="BRACKET_LEFT",r[r.BRACKET_RIGHT=9]="BRACKET_RIGHT",r[r.PAREN_LEFT=10]="PAREN_LEFT",r[r.PAREN_RIGHT=11]="PAREN_RIGHT",r[r.COMMA=12]="COMMA",r[r.QUESTION=13]="QUESTION",r[r.COLON=14]="COLON",r[r.DOLLAR=15]="DOLLAR"})(ft||(ft={}));var Ch=new Set([32,9,10,13]),Ph=new Set([43,45,42,47,37,33,38,124,61,60,62]),Nh=new Map([["true",ft.BOOLEAN],["false",ft.BOOLEAN],["null",ft.NULL]]),qn=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),Fh=new Map([[46,ft.DOT],[91,ft.BRACKET_LEFT],[93,ft.BRACKET_RIGHT],[40,ft.PAREN_LEFT],[41,ft.PAREN_RIGHT],[44,ft.COMMA],[63,ft.QUESTION],[58,ft.COLON],[36,ft.DOLLAR]]),Cs=new Map;for(let[r,t]of Fh.entries())Cs.set(r,{type:t,value:String.fromCharCode(r)});function jr(r){return r>=48&&r<=57}function Wn(r){return r>=97&&r<=122||r>=65&&r<=90||r===95}function Ms(r){return Wn(r)||jr(r)}function zh(r){return Ph.has(r)}var Ct;(function(r){r[r.Program=0]="Program",r[r.Literal=1]="Literal",r[r.Identifier=2]="Identifier",r[r.MemberExpression=3]="MemberExpression",r[r.CallExpression=4]="CallExpression",r[r.BinaryExpression=5]="BinaryExpression",r[r.UnaryExpression=6]="UnaryExpression",r[r.ConditionalExpression=7]="ConditionalExpression"})(Ct||(Ct={}));var Uh=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),qh={type:Ct.Literal,value:null},Wh={type:Ct.Literal,value:!0},Vh={type:Ct.Literal,value:!1},Bh=r=>{let t=0,e=r.length,i=()=>t>=e?null:r[t],u=()=>r[t++],h=m=>{let v=i();return v!==null&&v.type===m},c=m=>m.type===ft.OPERATOR?Uh.get(m.value)||-1:m.type===ft.DOT||m.type===ft.BRACKET_LEFT?9:m.type===ft.QUESTION?1:-1,f=m=>{let v,D;if(u().type===ft.DOT){if(!h(ft.IDENTIFIER)){let P=i();throw new Ft("Expected property name",t,P?P.value:"")}let $=u();v={type:Ct.Identifier,name:$.value},D=!1}else{if(v=d(0),!h(ft.BRACKET_RIGHT)){let $=i();throw new Ft("Expected closing bracket",t,$?$.value:"")}u(),D=!0}return{type:Ct.MemberExpression,object:m,property:v,computed:D}},g=()=>{let m=i();if(!m)throw new Ft("Unexpected end of input",t,"");if(m.type===ft.OPERATOR&&(m.value==="!"||m.value==="-")){u();let v=g();return{type:Ct.UnaryExpression,operator:m.value,argument:v,prefix:!0}}switch(m.type){case ft.NUMBER:return u(),{type:Ct.Literal,value:Number(m.value)};case ft.STRING:return u(),{type:Ct.Literal,value:m.value};case ft.BOOLEAN:return u(),m.value==="true"?Wh:Vh;case ft.NULL:return u(),qh;case ft.IDENTIFIER:return u(),{type:Ct.Identifier,name:m.value};case ft.FUNCTION:return(()=>{let v=u(),D=[];if(!h(ft.PAREN_LEFT)){let $=i();throw new Ft("Expected opening parenthesis after function name",t,$?$.value:"")}for(u();;){if(h(ft.PAREN_RIGHT)){u();break}if(!i()){let P=i();throw new Ft("Expected closing parenthesis",t,P?P.value:"")}if(D.length>0){if(!h(ft.COMMA)){let P=i();throw new Ft("Expected comma between function arguments",t,P?P.value:"")}u()}let $=d(0);D.push($)}return{type:Ct.CallExpression,callee:{type:Ct.Identifier,name:v.value},arguments:D}})();case ft.PAREN_LEFT:{u();let v=d(0);if(!h(ft.PAREN_RIGHT)){let D=i();throw new Ft("Expected closing parenthesis",t,D?D.value:"")}return u(),v}default:throw new Ft(`Unexpected token: ${m.type}`,t,m.value)}},d=(m=0)=>{let v=g();for(;t")}u();let q=d(0);v={type:Ct.ConditionalExpression,test:v,consequent:P,alternate:q}}}return v},b=d();return{type:Ct.Program,body:b}},Kh=(r,t,e)=>{let i=t;e&&(i={...t,context:{...t.context,...e}});let u=h=>{switch(h.type){case Ct.Literal:return(c=>c.value)(h);case Ct.Identifier:return(c=>{if(!(c.name in i.context))throw new Ft(`Undefined variable: ${c.name}`);return i.context[c.name]})(h);case Ct.MemberExpression:return(c=>{let f=u(c.object);if(f==null)throw new Ft("Cannot access property of null or undefined");return f[c.computed?u(c.property):c.property.name]})(h);case Ct.CallExpression:return(c=>{let f=i.functions[c.callee.name];if(!f)throw new Ft(`Undefined function: ${c.callee.name}`);return f(...c.arguments.map((g=>u(g))))})(h);case Ct.BinaryExpression:return(c=>{if(c.operator==="&&"){let d=u(c.left);return d&&u(c.right)}if(c.operator==="||")return u(c.left)||u(c.right);let f=u(c.left),g=u(c.right);switch(c.operator){case"+":return f+g;case"-":return f-g;case"*":return f*g;case"/":return f/g;case"%":return f%g;case"===":return f===g;case"!==":return f!==g;case">":return f>g;case">=":return f>=g;case"<":return f{let f=u(c.argument);if(c.prefix)switch(c.operator){case"!":return!f;case"-":if(typeof f!="number")throw new Ft(`Cannot apply unary - to non-number: ${f}`);return-f;default:throw new Ft(`Unknown operator: ${c.operator}`)}throw new Ft(`Postfix operators are not supported: ${c.operator}`)})(h);case Ct.ConditionalExpression:return(c=>{let f=u(c.test);return u(f?c.consequent:c.alternate)})(h);default:throw new Ft(`Evaluation error: Unsupported node type: ${h.type}`)}};return u(r.body)};function Vn(r){let t=(u=>{let h=u,c=h.length,f=new Array(Math.ceil(c/3)),g=0,d=0;function b(q){let B=d+1;d++;let G="",F=!1;for(;d({context:u,functions:h}))({},Mh);return(u={})=>Kh(e,i,u)}function Ps(r,t={}){return Vn(r)(t)}function Ns(r,t){if(typeof r!="string")return;let e=r.trim();if(e)try{return Vn(e),Ps(e,t)}catch{return}}function dr(r){return typeof r=="number"}function Bn(r){if(!r)return[0,0,0];if(dr(r))return[r,r,r];if(Array.isArray(r)&&r.length===0)return[0,0,0];let[t,e=t,i=t]=r;return[t,e,i]}function Fs(r){return dr(r)?!0:Array.isArray(r)?r.every(t=>dr(t)):!1}function _e(r){return r==null}function zs(r){return typeof r=="string"}function Us(r){return typeof r=="function"}function Ar(r,t){if(typeof r=="function")return r;if(typeof r=="string"){let e=r;return(...i)=>{let u={};for(let h=0;hr}function qs(r,t=10,e="node"){if(_e(r))return()=>t;if(zs(r)){let i=Ar(r,[e]);return u=>{let h=i(u);return Fs(h)?h:t}}return Us(r)?r:dr(r)?()=>r:Array.isArray(r)?()=>r:()=>t}var tn=(r,t,e=10,i=0)=>{let u=qs(t,i),h=qs(r,e);return c=>{let[f,g,d]=Bn(h(c)),[b,m,v]=Bn(u(c));return[f+b,g+m,d+v]}};var en=class{constructor(t,e={}){this.edgeIdCounter=new Map,this.nodeMap=Qh(t.nodes,e.node),this.edgeMap=Zh(t.edges||[],e.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let e=this.indexNodeCache.get(t);return e?this.nodeMap.get(e):void 0}nodeIndexOf(t){var e;return this.nodeIndexCache||this.buildNodeIndexCache(),(e=this.nodeIndexCache.get(t))!==null&&e!==void 0?e:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let e=0;this.nodeMap.forEach(i=>t(i,e++))}originalNode(t){let e=this.nodeMap.get(t);return e?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let e=0;this.edgeMap.forEach(i=>t(i,e++))}originalEdge(t){let e=this.edgeMap.get(t);return e?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let e=`${t.source}-${t.target}`,i=this.edgeIdCounter.get(e)||0,u=i===0?e:`${e}-${i}`;return this.edgeIdCounter.set(e,i+1),u}degree(t,e="both"){this.degreeCache||this.buildDegreeCache();let i=this.degreeCache.get(t);return i?i[e]:0}neighbors(t,e="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),e==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(e==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let i=this.inAdjacencyCache.get(t),u=this.outAdjacencyCache.get(t);if(!i&&!u)return[];if(!i)return Array.from(u);if(!u)return Array.from(i);let h=new Set;return i.forEach(c=>h.add(c)),u.forEach(c=>h.add(c)),Array.from(h)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let e=new Map;for(let i of t)e.set(i.id,i);this.nodeMap=e,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:e,target:i}=t;if(t.source===t.target)continue;this.degreeCache.has(e)||this.degreeCache.set(e,{in:0,out:0,both:0});let u=this.degreeCache.get(t.source);u&&(u.out++,u.both++),this.degreeCache.has(i)||this.degreeCache.set(i,{in:0,out:0,both:0});let h=this.degreeCache.get(t.target);h&&(h.in++,h.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((e,i)=>{this.nodeIndexCache.set(i,t),this.indexNodeCache.set(t,i),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Yh=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],Xh=["id","source","target","points"];function Qh(r,t){if(!r)throw new Error("Data.nodes is required");let e=new Map;for(let i of r){let u={_original:i};for(let h of Yh){let c=i[h];_e(c)||(u[h]=c)}if(t){let h=t(i);for(let c in h){let f=h[c];_e(f)||(u[c]=f)}}if(_e(u.id))throw new Error("Node is missing id field");e.set(u.id,u)}return e}function Zh(r,t,e){let i=new Map;for(let u of r){let h={_original:u};for(let c of Xh){let f=u[c];_e(f)||(h[c]=f)}if(t){let c=t(u);for(let f in c){let g=c[f];_e(g)||(h[f]=g)}}if(_e(h.source)||_e(h.target))throw new Error("Edge is missing source or target field");_e(h.id)&&(h.id=e?.(u)),i.set(h.id,h)}return i}var rn=class{constructor(t,e={}){this.graph=new en(t,e)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((e,i)=>{e.sourceNode=this.graph.node(e.source),e.targetNode=this.graph.node(e.target),t(e,i)})}destroy(){this.graph.destroy()}};var Vs=Symbol("Comlink.proxy"),Jh=Symbol("Comlink.endpoint"),Hh=Symbol("Comlink.releaseProxy"),Kn=Symbol("Comlink.finalizer"),sn=Symbol("Comlink.thrown"),Bs=r=>typeof r=="object"&&r!==null||typeof r=="function",ta={canHandle:r=>Bs(r)&&r[Vs],serialize(r){let{port1:t,port2:e}=new MessageChannel;return Ys(r,t),[e,[e]]},deserialize(r){return r.start(),Xn(r)}},ea={canHandle:r=>Bs(r)&&sn in r,serialize({value:r}){let t;return r instanceof Error?t={isError:!0,value:{message:r.message,name:r.name,stack:r.stack}}:t={isError:!1,value:r},[t,[]]},deserialize(r){throw r.isError?Object.assign(new Error(r.value.message),r.value):r.value}},Ks=new Map([["proxy",ta],["throw",ea]]);function ra(r,t){for(let e of r)if(t===e||e==="*"||e instanceof RegExp&&e.test(t))return!0;return!1}function Ys(r,t=globalThis,e=["*"]){t.addEventListener("message",function i(u){if(!u||!u.data)return;if(!ra(e,u.origin)){console.warn(`Invalid origin '${u.origin}' for comlink proxy`);return}let{id:h,type:c,path:f}=Object.assign({path:[]},u.data),g=(u.data.argumentList||[]).map(Je),d;try{let b=f.slice(0,-1).reduce((v,D)=>v[D],r),m=f.reduce((v,D)=>v[D],r);switch(c){case"GET":d=m;break;case"SET":b[f.slice(-1)[0]]=Je(u.data.value),d=!0;break;case"APPLY":d=m.apply(b,g);break;case"CONSTRUCT":{let v=new m(...g);d=ha(v)}break;case"ENDPOINT":{let{port1:v,port2:D}=new MessageChannel;Ys(r,D),d=ua(v,[v])}break;case"RELEASE":d=void 0;break;default:return}}catch(b){d={value:b,[sn]:0}}Promise.resolve(d).catch(b=>({value:b,[sn]:0})).then(b=>{let[m,v]=hn(b);t.postMessage(Object.assign(Object.assign({},m),{id:h}),v),c==="RELEASE"&&(t.removeEventListener("message",i),Xs(t),Kn in r&&typeof r[Kn]=="function"&&r[Kn]())}).catch(b=>{let[m,v]=hn({value:new TypeError("Unserializable return value"),[sn]:0});t.postMessage(Object.assign(Object.assign({},m),{id:h}),v)})}),t.start&&t.start()}function na(r){return r.constructor.name==="MessagePort"}function Xs(r){na(r)&&r.close()}function Xn(r,t){let e=new Map;return r.addEventListener("message",function(u){let{data:h}=u;if(!h||!h.id)return;let c=e.get(h.id);if(c)try{c(h)}finally{e.delete(h.id)}}),Yn(r,e,[],t)}function nn(r){if(r)throw new Error("Proxy has been released and is not useable")}function Qs(r){return gr(r,new Map,{type:"RELEASE"}).then(()=>{Xs(r)})}var on=new WeakMap,un="FinalizationRegistry"in globalThis&&new FinalizationRegistry(r=>{let t=(on.get(r)||0)-1;on.set(r,t),t===0&&Qs(r)});function ia(r,t){let e=(on.get(t)||0)+1;on.set(t,e),un&&un.register(r,t,r)}function sa(r){un&&un.unregister(r)}function Yn(r,t,e=[],i=function(){}){let u=!1,h=new Proxy(i,{get(c,f){if(nn(u),f===Hh)return()=>{sa(h),Qs(r),t.clear(),u=!0};if(f==="then"){if(e.length===0)return{then:()=>h};let g=gr(r,t,{type:"GET",path:e.map(d=>d.toString())}).then(Je);return g.then.bind(g)}return Yn(r,t,[...e,f])},set(c,f,g){nn(u);let[d,b]=hn(g);return gr(r,t,{type:"SET",path:[...e,f].map(m=>m.toString()),value:d},b).then(Je)},apply(c,f,g){nn(u);let d=e[e.length-1];if(d===Jh)return gr(r,t,{type:"ENDPOINT"}).then(Je);if(d==="bind")return Yn(r,t,e.slice(0,-1));let[b,m]=Ws(g);return gr(r,t,{type:"APPLY",path:e.map(v=>v.toString()),argumentList:b},m).then(Je)},construct(c,f){nn(u);let[g,d]=Ws(f);return gr(r,t,{type:"CONSTRUCT",path:e.map(b=>b.toString()),argumentList:g},d).then(Je)}});return ia(h,r),h}function oa(r){return Array.prototype.concat.apply([],r)}function Ws(r){let t=r.map(hn);return[t.map(e=>e[0]),oa(t.map(e=>e[1]))]}var Zs=new WeakMap;function ua(r,t){return Zs.set(r,t),r}function ha(r){return Object.assign(r,{[Vs]:!0})}function hn(r){for(let[t,e]of Ks)if(e.canHandle(r)){let[i,u]=e.serialize(r);return[{type:"HANDLER",name:t,value:i},u]}return[{type:"RAW",value:r},Zs.get(r)||[]]}function Je(r){switch(r.type){case"HANDLER":return Ks.get(r.name).deserialize(r.value);case"RAW":return r.value}}function gr(r,t,e,i){return new Promise(u=>{let h=aa();t.set(h,u),r.start&&r.start(),r.postMessage(Object.assign({id:h},e),i)})}function aa(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var an=class{constructor(){this.worker=null,this.workerApi=null}execute(t,e,i){return Ee(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,e,i)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return Ee(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),i=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:i}),this.workerApi=Xn(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let e=document.currentScript;if(e?.src)return e.src;let i=document.getElementsByTagName("script");for(let u=i.length-1;u>=0;u--){let h=i[u].src;if(h&&(h.includes("index.js")||h.includes("index.min.js")))return h}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let u=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(u!==t)return u}let e=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(e!==t)return e;let i=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(i!==t)return i}return"./worker.js"}};var We=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,e){return Object.assign({},t,e||{})}execute(t,e){return Ee(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,e);let{node:i,edge:u,enableWorker:h}=this.runtimeOptions;this.context=new rn(t,{node:i,edge:u}),this.model=this.context.graph,h&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,e){var i;return Ee(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new an);let u=yield this.supervisor.execute(this.id,t,e);(i=this.context)===null||i===void 0||i.replace(u)}catch(u){console.error("Layout in worker failed, fallback to main thread layout.",u),yield this.layout(e)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function pr(r,t,e=2){if(r.nodeCount()===1){let u=r.firstNode();u.x=t[0],u.y=t[1],e===3&&(u.z=t[2]||0)}}function Js(r,t){let e=r.nodes();return e.sort(t),r.setNodeOrder(e),r}function Hs(r,t="desc"){return Js(r,(e,i)=>{let u=r.degree(e.id),h=r.degree(i.id);return t==="asc"?u-h:h-u})}function to(r,t){return Js(r,(e,i)=>{let u=r.originalNode(e.id),h=r.originalNode(i.id);return t(u,h)})}var wr=r=>{let{width:t,height:e,center:i}=r,u=t??(typeof window<"u"?window.innerWidth:0),h=e??(typeof window<"u"?window.innerHeight:0),c=i??[u/2,h/2];return{width:u,height:h,center:c}};var cn={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},ln=class extends We{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return cn}layout(){return Ee(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=wr(this.options),u=this.model.nodeCount();if(!u||u===1){pr(this.model,i);return}let{sortBy:h,maxLevelDiff:c,sweep:f,clockwise:g,equidistant:d,preventOverlap:b,startAngle:m=cn.startAngle,nodeSize:v,nodeSpacing:D}=this.options,$=!h||h==="degree"?"degree":Ar(h,["node"]);if($==="degree")Hs(this.model);else{let O=(N,A)=>{let nt=$(N),dt=$(A);return nt===dt?0:nt>dt?-1:1};to(this.model,O)}let P=this.model.nodes(),q=new Map;for(let O of P){let N=$==="degree"?this.model.degree(O.id):$(O._original);q.set(O.id,N)}let B=this.model.firstNode(),G=c||q.get(B.id)/4,F=tn(v,D,cn.nodeSize,cn.nodeSpacing),V=new Map;for(let O of P)V.set(O.id,Math.max(...F(O._original)));let z=[{nodes:[]}],ot=z[0];for(let O=0;O0){let A=ot.nodes[0],nt=Math.abs(q.get(A.id)-q.get(N.id));G&&nt>=G&&(ot={nodes:[]},z.push(ot))}ot.nodes.push(N)}for(let O of z){let N=O.nodes.map(A=>V.get(A.id));O.nodeSizes=N,O.maxNodeSize=Math.max(...N)}if(z.forEach(O=>{let N=f===void 0?2*Math.PI-2*Math.PI/O.nodes.length:f;O.dTheta=N/Math.max(1,O.nodes.length-1)}),b){let O=0;for(let N=0;N1){let nt=A.nodeSizes||[],dt=0;for(let ue=0;ue0?dt/yt:0;O=Math.max(Qt,O)}if(A.r=O,N{nt===0&&(N=A.r||0),A.r=N,N+=O})}z.forEach(O=>{let N=O.dTheta||0,A=O.r||0;O.nodes.forEach((nt,dt)=>{let wt=m+(g?1:-1)*N*dt;nt.x=i[0]+A*Math.cos(wt),nt.y=i[1]+A*Math.sin(wt)})})})}};function eo(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function fn(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var t=r.default;if(typeof t=="function"){var e=function i(){var u=!1;try{u=this instanceof i}catch{}return u?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};e.prototype=t.prototype}else e={};return Object.defineProperty(e,"__esModule",{value:!0}),Object.keys(r).forEach(function(i){var u=Object.getOwnPropertyDescriptor(r,i);Object.defineProperty(e,i,u.get?u:{enumerable:!0,get:function(){return r[i]}})}),e}var pt={};var Qn={};_n(Qn,{isAnyArray:()=>Ve});var ca=Object.prototype.toString;function Ve(r){let t=ca.call(r);return t.endsWith("Array]")&&!t.includes("Big")}var ro=fn(Qn);var Zn={};_n(Zn,{default:()=>la});function no(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Ve(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;fc&&(c=r[f]);return c}function io(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Ve(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;f1&&arguments[1]!==void 0?arguments[1]:{};if(Ve(r)){if(r.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var e;if(t.output!==void 0){if(!Ve(t.output))throw new TypeError("output option must be an array if specified");e=t.output}else e=new Array(r.length);var i=io(r),u=no(r);if(i===u)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var h=t.min,c=h===void 0?t.autoMinMax?i:0:h,f=t.max,g=f===void 0?t.autoMinMax?u:1:f;if(c>=g)throw new RangeError("min option must be smaller than max option");for(var d=(g-c)/(u-i),b=0;b=0&&s?` ${p(g,a-1)}`:p(g,a)).padEnd(a)}function p(g,a){let s=g.toString();if(s.length<=a)return s;let n=g.toFixed(a);if(n.length>a&&(n=g.toFixed(Math.max(0,a-(n.length-a)))),n.length<=a&&!n.startsWith("0.000")&&!n.startsWith("-0.000"))return n;let o=g.toExponential(a);return o.length>a&&(o=g.toExponential(Math.max(0,a-(o.length-a)))),o.slice(0)}function d(g,a){g.prototype.add=function(n){return typeof n=="number"?this.addS(n):this.addM(n)},g.prototype.addS=function(n){for(let o=0;o>n);return this},g.prototype.signPropagatingRightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>n.get(o,l));return this},g.signPropagatingRightShift=function(n,o){return new a(n).signPropagatingRightShift(o)},g.prototype.rightShift=function(n){return typeof n=="number"?this.rightShiftS(n):this.rightShiftM(n)},g.prototype.rightShiftS=function(n){for(let o=0;o>>n);return this},g.prototype.rightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>>n.get(o,l));return this},g.rightShift=function(n,o){return new a(n).rightShift(o)},g.prototype.zeroFillRightShift=g.prototype.rightShift,g.prototype.zeroFillRightShiftS=g.prototype.rightShiftS,g.prototype.zeroFillRightShiftM=g.prototype.rightShiftM,g.zeroFillRightShift=g.rightShift,g.prototype.not=function(){for(let n=0;nn)throw new RangeError("Row index out of range")}function x(g,a,s){let n=s?g.columns:g.columns-1;if(a<0||a>n)throw new RangeError("Column index out of range")}function E(g,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==g.columns)throw new RangeError("vector size must be the same as the number of columns");return a}function M(g,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==g.rows)throw new RangeError("vector size must be the same as the number of rows");return a}function _(g,a){if(!r.isAnyArray(a))throw new TypeError("row indices must be an array");for(let s=0;s=g.rows)throw new RangeError("row indices are out of range")}function N(g,a){if(!r.isAnyArray(a))throw new TypeError("column indices must be an array");for(let s=0;s=g.columns)throw new RangeError("column indices are out of range")}function C(g,a,s,n,o){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(L("startRow",a),L("endRow",s),L("startColumn",n),L("endColumn",o),a>s||n>o||a<0||a>=g.rows||s<0||s>=g.rows||n<0||n>=g.columns||o<0||o>=g.columns)throw new RangeError("Submatrix indices are out of range")}function q(g,a=0){let s=[];for(let n=0;n=l)throw new RangeError("min must be smaller than max");let y=l-o,m=new B(a,s);for(let b=0;bn?(l=!0,n=s):(o=!1,l=!0);a++}return o}isReducedEchelonForm(){let a=0,s=0,n=-1,o=!0,l=!1;for(;an?(l=!0,n=s):(o=!1,l=!0);for(let w=s+1;wa.get(o,n)&&(o=l);if(a.get(o,n)===0)n++;else{a.swapRows(s,o);let l=a.get(s,n);for(let w=n;w=0;)if(a.maxRow(o)===0)o--;else{let l=0,w=!1;for(;ls[n]&&(s[n]=this.get(n,o));return s}case"column":{let s=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let n=0;ns[o]&&(s[o]=this.get(n,o));return s}case void 0:{let s=this.get(0,0);for(let n=0;ns&&(s=this.get(n,o));return s}default:throw new Error(`invalid option: ${a}`)}}maxIndex(){z(this);let a=this.get(0,0),s=[0,0];for(let n=0;na&&(a=this.get(n,o),s[0]=n,s[1]=o);return s}min(a){if(this.isEmpty())return NaN;switch(a){case"row":{let s=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let n=0;ns&&(s=this.get(a,n));return s}maxRowIndex(a){v(this,a),z(this);let s=this.get(a,0),n=[a,0];for(let o=1;os&&(s=this.get(a,o),n[1]=o);return n}minRow(a){if(v(this,a),this.isEmpty())return NaN;let s=this.get(a,0);for(let n=1;ns&&(s=this.get(n,a));return s}maxColumnIndex(a){x(this,a),z(this);let s=this.get(0,a),n=[0,a];for(let o=1;os&&(s=this.get(o,a),n[0]=o);return n}minColumn(a){if(x(this,a),this.isEmpty())return NaN;let s=this.get(0,a);for(let n=1;n=1;o/=2)(o&1)!==0&&(s=s.mmul(n)),n=n.mmul(n);return s}strassen2x2(a){a=B.checkMatrix(a);let s=new B(2,2),n=this.get(0,0),o=a.get(0,0),l=this.get(0,1),w=a.get(0,1),y=this.get(1,0),m=a.get(1,0),b=this.get(1,1),I=a.get(1,1),S=(n+b)*(o+I),A=(y+b)*o,W=n*(w-I),$=b*(m-o),R=(n+l)*I,Y=(y-n)*(o+w),k=(l-b)*(m+I),U=S+$-R+k,J=W+R,nt=A+$,st=S-A+W+Y;return s.set(0,0,U),s.set(0,1,J),s.set(1,0,nt),s.set(1,1,st),s}strassen3x3(a){a=B.checkMatrix(a);let s=new B(3,3),n=this.get(0,0),o=this.get(0,1),l=this.get(0,2),w=this.get(1,0),y=this.get(1,1),m=this.get(1,2),b=this.get(2,0),I=this.get(2,1),S=this.get(2,2),A=a.get(0,0),W=a.get(0,1),$=a.get(0,2),R=a.get(1,0),Y=a.get(1,1),k=a.get(1,2),U=a.get(2,0),J=a.get(2,1),nt=a.get(2,2),st=(n+o+l-w-y-I-S)*Y,Et=(n-w)*(-W+Y),Z=y*(-A+W+R-Y-k-U+nt),H=(-n+w+y)*(A-W+Y),wt=(w+y)*(-A+W),D=n*A,G=(-n+b+I)*(A-$+k),X=(-n+b)*($-k),F=(b+I)*(-A+$),vt=(n+o+l-y-m-b-I)*k,dt=I*(-A+$+R-Y-k-U+J),bt=(-l+I+S)*(Y+U-J),xt=(l-S)*(Y-J),Ot=l*U,ie=(I+S)*(-U+J),Rt=(-l+y+m)*(k+U-nt),ce=(l-m)*(k-nt),ye=(y+m)*(-U+nt),ht=o*R,Ct=m*J,Zt=w*$,Ht=b*W,Nt=S*nt,Eo=D+Ot+ht,vo=st+H+wt+D+bt+Ot+ie,xo=D+G+F+vt+Ot+Rt+ye,So=Et+Z+H+D+Ot+Rt+ce,ko=Et+H+wt+D+Ct,Mo=Ot+Rt+ce+ye+Zt,Do=D+G+X+dt+bt+xt+Ot,Io=bt+xt+Ot+ie+Ht,jo=D+G+X+F+Nt;return s.set(0,0,Eo),s.set(0,1,vo),s.set(0,2,xo),s.set(1,0,So),s.set(1,1,ko),s.set(1,2,Mo),s.set(2,0,Do),s.set(2,1,Io),s.set(2,2,jo),s}mmulStrassen(a){a=B.checkMatrix(a);let s=this.clone(),n=s.rows,o=s.columns,l=a.rows,w=a.columns;o!==l&&console.warn(`Multiplying ${n} x ${o} and ${l} x ${w} matrix: dimensions do not match.`);function y(S,A,W){let $=S.rows,R=S.columns;if($===A&&R===W)return S;{let Y=et.zeros(A,W);return Y=Y.setSubMatrix(S,0,0),Y}}let m=Math.max(n,l),b=Math.max(o,w);s=y(s,m,b),a=y(a,m,b);function I(S,A,W,$){if(W<=512||$<=512)return S.mmul(A);W%2===1&&$%2===1?(S=y(S,W+1,$+1),A=y(A,W+1,$+1)):W%2===1?(S=y(S,W+1,$),A=y(A,W+1,$)):$%2===1&&(S=y(S,W,$+1),A=y(A,W,$+1));let R=parseInt(S.rows/2,10),Y=parseInt(S.columns/2,10),k=S.subMatrix(0,R-1,0,Y-1),U=A.subMatrix(0,R-1,0,Y-1),J=S.subMatrix(0,R-1,Y,S.columns-1),nt=A.subMatrix(0,R-1,Y,A.columns-1),st=S.subMatrix(R,S.rows-1,0,Y-1),Et=A.subMatrix(R,A.rows-1,0,Y-1),Z=S.subMatrix(R,S.rows-1,Y,S.columns-1),H=A.subMatrix(R,A.rows-1,Y,A.columns-1),wt=I(et.add(k,Z),et.add(U,H),R,Y),D=I(et.add(st,Z),U,R,Y),G=I(k,et.sub(nt,H),R,Y),X=I(Z,et.sub(Et,U),R,Y),F=I(et.add(k,J),H,R,Y),vt=I(et.sub(st,k),et.add(U,nt),R,Y),dt=I(et.sub(J,Z),et.add(Et,H),R,Y),bt=et.add(wt,X);bt.sub(F),bt.add(dt);let xt=et.add(G,F),Ot=et.add(D,X),ie=et.sub(wt,D);ie.add(G),ie.add(vt);let Rt=et.zeros(2*bt.rows,2*bt.columns);return Rt=Rt.setSubMatrix(bt,0,0),Rt=Rt.setSubMatrix(xt,bt.rows,0),Rt=Rt.setSubMatrix(Ot,0,bt.columns),Rt=Rt.setSubMatrix(ie,bt.rows,bt.columns),Rt.subMatrix(0,W-1,0,$-1)}return I(s,a,m,b)}scaleRows(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new B(this.rows,this.columns);for(let l=0;l0&&t(w,{min:s,max:n,output:w}),o.setRow(l,w)}return o}scaleColumns(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new B(this.rows,this.columns);for(let l=0;ln||s<0||s>=this.columns||n<0||n>=this.columns)throw new RangeError("Argument out of range");let o=new B(a.length,n-s+1);for(let l=0;l=this.rows)throw new RangeError(`Row index out of range: ${a[l]}`);o.set(l,w-s,this.get(a[l],w))}return o}subMatrixColumn(a,s,n){if(s===void 0&&(s=0),n===void 0&&(n=this.rows-1),s>n||s<0||s>=this.rows||n<0||n>=this.rows)throw new RangeError("Argument out of range");let o=new B(n-s+1,a.length);for(let l=0;l=this.columns)throw new RangeError(`Column index out of range: ${a[l]}`);o.set(w-s,l,this.get(w,a[l]))}return o}setSubMatrix(a,s,n){if(a=B.checkMatrix(a),a.isEmpty())return this;let o=s+a.rows-1,l=n+a.columns-1;C(this,s,o,n,l);for(let w=0;wtypeof a=="number")}et.random=et.rand,et.randomInt=et.randInt,et.diagonal=et.diag,et.prototype.diagonal=et.prototype.diag,et.identity=et.eye,et.prototype.negate=et.prototype.neg,et.prototype.tensorProduct=et.prototype.kroneckerProduct;let pr=class pr extends et{constructor(s,n){super();on(this,Ye);Bn(this,"data");if(pr.isMatrix(s))un(this,Ye,Dn).call(this,s.rows,s.columns),pr.copy(s,this);else if(Number.isInteger(s)&&s>=0)un(this,Ye,Dn).call(this,s,n);else if(r.isAnyArray(s)){let o=s;if(s=o.length,n=s?o[0].length:0,typeof n!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let l=0;l"u"&&(n=s,s=this.columns),x(this,s,!0),n=M(this,n);for(let o=0;o=0)for(let o=0;o=0)mr(this,Ft,new B(s,s));else if(mr(this,Ft,new B(s)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return se(this,Ft).size}get rows(){return se(this,Ft).rows}get columns(){return se(this,Ft).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(s){return B.isMatrix(s)&&s.klassType==="SymmetricMatrix"}static zeros(s){return new this(s)}static ones(s){return new this(s).fill(1)}clone(){let s=new wr(this.diagonalSize);for(let[n,o,l]of this.upperRightEntries())s.set(n,o,l);return s}toMatrix(){return new B(this)}get(s,n){return se(this,Ft).get(s,n)}set(s,n,o){return se(this,Ft).set(s,n,o),se(this,Ft).set(n,s,o),this}removeCross(s){return se(this,Ft).removeRow(s),se(this,Ft).removeColumn(s),this}addCross(s,n){n===void 0&&(n=s,s=this.diagonalSize);let o=n.slice();return o.splice(s,1),se(this,Ft).addRow(s,o),se(this,Ft).addColumn(s,n),this}applyMask(s){if(s.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let n=[];for(let[o,l]of s.entries())l||n.push(o);n.reverse();for(let o of n)this.removeCross(o);return this}toCompact(){let{diagonalSize:s}=this,n=new Array(s*(s+1)/2);for(let o=0,l=0,w=0;w=s&&(o=++l);return n}static fromCompact(s){let n=s.length,o=(Math.sqrt(8*n+1)-1)/2;if(!Number.isInteger(o))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(s)}`);let l=new wr(o);for(let w=0,y=0,m=0;m=o&&(w=++y);return l}*upperRightEntries(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}}*upperRightValues(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}};Ft=new WeakMap;let $e=wr;$e.prototype.klassType="SymmetricMatrix";class cr extends $e{static isDistanceMatrix(a){return $e.isSymmetricMatrix(a)&&a.klassSubType==="DistanceMatrix"}constructor(a){if(super(a),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(a,s,n){return a===s&&(n=0),super.set(a,s,n)}addCross(a,s){return s===void 0&&(s=a,a=this.diagonalSize),s=s.slice(),s[a]=0,super.addCross(a,s)}toSymmetricMatrix(){return new $e(this)}clone(){let a=new cr(this.diagonalSize);for(let[s,n,o]of this.upperRightEntries())s!==n&&a.set(s,n,o);return a}toCompact(){let{diagonalSize:a}=this,s=(a-1)*a/2,n=new Array(s);for(let o=1,l=0,w=0;w=a&&(o=++l+1);return n}static fromCompact(a){let s=a.length;if(s===0)return new this(0);let n=(Math.sqrt(8*s+1)+1)/2;if(!Number.isInteger(n))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(a)}`);let o=new this(n);for(let l=1,w=0,y=0;y=n&&(l=++w+1);return o}}cr.prototype.klassSubType="DistanceMatrix";class pe extends et{constructor(a,s,n){super(),this.matrix=a,this.rows=s,this.columns=n}}class Hs extends pe{constructor(a,s){x(a,s),super(a,a.rows,1),this.column=s}set(a,s,n){return this.matrix.set(a,this.column,n),this}get(a){return this.matrix.get(a,this.column)}}class to extends pe{constructor(a,s){N(a,s),super(a,a.rows,s.length),this.columnIndices=s}set(a,s,n){return this.matrix.set(a,this.columnIndices[s],n),this}get(a,s){return this.matrix.get(a,this.columnIndices[s])}}class eo extends pe{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(a,this.columns-s-1,n),this}get(a,s){return this.matrix.get(a,this.columns-s-1)}}class ro extends pe{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(this.rows-a-1,s,n),this}get(a,s){return this.matrix.get(this.rows-a-1,s)}}class no extends pe{constructor(a,s){v(a,s),super(a,1,a.columns),this.row=s}set(a,s,n){return this.matrix.set(this.row,s,n),this}get(a,s){return this.matrix.get(this.row,s)}}class io extends pe{constructor(a,s){_(a,s),super(a,s.length,a.columns),this.rowIndices=s}set(a,s,n){return this.matrix.set(this.rowIndices[a],s,n),this}get(a,s){return this.matrix.get(this.rowIndices[a],s)}}class lr extends pe{constructor(a,s,n){_(a,s),N(a,n),super(a,s.length,n.length),this.rowIndices=s,this.columnIndices=n}set(a,s,n){return this.matrix.set(this.rowIndices[a],this.columnIndices[s],n),this}get(a,s){return this.matrix.get(this.rowIndices[a],this.columnIndices[s])}}class so extends pe{constructor(a,s,n,o,l){C(a,s,n,o,l),super(a,n-s+1,l-o+1),this.startRow=s,this.startColumn=o}set(a,s,n){return this.matrix.set(this.startRow+a,this.startColumn+s,n),this}get(a,s){return this.matrix.get(this.startRow+a,this.startColumn+s)}}class oo extends pe{constructor(a){super(a,a.columns,a.rows)}set(a,s,n){return this.matrix.set(s,a,n),this}get(a,s){return this.matrix.get(s,a)}}class Fn extends et{constructor(a,s={}){let{rows:n=1}=s;if(a.length%n!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=n,this.columns=a.length/n,this.data=a}set(a,s,n){let o=this._calculateIndex(a,s);return this.data[o]=n,this}get(a,s){let n=this._calculateIndex(a,s);return this.data[n]}_calculateIndex(a,s){return a*this.columns+s}}class Jt extends et{constructor(a){super(),this.data=a,this.rows=a.length,this.columns=a[0].length}set(a,s,n){return this.data[a][s]=n,this}get(a,s){return this.data[a][s]}}function uo(g,a){if(r.isAnyArray(g))return g[0]&&r.isAnyArray(g[0])?new Jt(g):new Fn(g,a);throw new Error("the argument is not an array")}class fr{constructor(a){a=Jt.checkMatrix(a);let s=a.clone(),n=s.rows,o=s.columns,l=new Float64Array(n),w=1,y,m,b,I,S,A,W,$,R;for(y=0;yMath.abs($[I])&&(I=y);if(I!==m){for(b=0;b=0;b--){for(m=0;mw?o.set(l,w,a.get(l,w)):l===w?o.set(l,w,1):o.set(l,w,0);return o}get upperTriangularMatrix(){let a=this.LU,s=a.rows,n=a.columns,o=new B(s,n);for(let l=0;lMath.abs(a)?(s=a/g,Math.abs(g)*Math.sqrt(1+s*s)):a!==0?(s=g/a,Math.abs(a)*Math.sqrt(1+s*s)):0}class en{constructor(a){a=Jt.checkMatrix(a);let s=a.clone(),n=a.rows,o=a.columns,l=new Float64Array(o),w,y,m,b;for(m=0;m=0;b--){for(m=0;m=0;y--){for(l=0;l=0;D--)if($[D]!==0){for(let G=D+1;G=0;D--){if(D0;){let D,G;for(D=Z-2;D>=-1&&D!==-1;D--){let X=Number.MIN_VALUE+wt*Math.abs($[D]+Math.abs($[D+1]));if(Math.abs(k[D])<=X||Number.isNaN(k[D])){k[D]=0;break}}if(D===Z-2)G=4;else{let X;for(X=Z-1;X>=D&&X!==D;X--){let F=(X!==Z?Math.abs(k[X]):0)+(X!==D+1?Math.abs(k[X-1]):0);if(Math.abs($[X])<=wt*F){$[X]=0;break}}X===D?G=3:X===Z-1?G=1:(G=2,D=X)}switch(D++,G){case 1:{let X=k[Z-2];k[Z-2]=0;for(let F=Z-2;F>=D;F--){let vt=we($[F],X),dt=$[F]/vt,bt=X/vt;if($[F]=vt,F!==D&&(X=-bt*k[F-1],k[F-1]=dt*k[F-1]),b)for(let xt=0;xt=$[D+1]);){let X=$[D];if($[D]=$[D+1],$[D+1]=X,b&&Ds&&l.set(I,S,a.get(I,S)/this.s[S]);let w=this.U,y=w.rows,m=w.columns,b=new B(n,y);for(let I=0;Ia&&s++;return s}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return B.diag(this.s)}}function ao(g,a=!1){return g=Jt.checkMatrix(g),a?new Ge(g).inverse():zn(g,B.eye(g.rows))}function zn(g,a,s=!1){return g=Jt.checkMatrix(g),a=Jt.checkMatrix(a),s?new Ge(g).solve(a):g.isSquare()?new fr(g).solve(a):new en(g).solve(a)}function dr(g){if(g=B.checkMatrix(g),g.isSquare()){if(g.columns===0)return 1;let a,s,n,o;if(g.columns===2)return a=g.get(0,0),s=g.get(0,1),n=g.get(1,0),o=g.get(1,1),a*o-s*n;if(g.columns===3){let l,w,y;return l=new lr(g,[1,2],[1,2]),w=new lr(g,[1,2],[0,2]),y=new lr(g,[1,2],[0,1]),a=g.get(0,0),s=g.get(0,1),n=g.get(0,2),a*dr(l)-s*dr(w)+n*dr(y)}else return new fr(g).determinant}else throw Error("determinant can only be calculated for a square matrix")}function ho(g,a){let s=[];for(let n=0;no)return new Array(a.rows+1).fill(0);{let l=a.addRow(s,[0]);for(let w=0;wa?l[w]=1/l[w]:l[w]=0;return o.mmul(B.diag(l).mmul(n.transpose()))}function go(g,a=g,s={}){g=new B(g);let n=!1;if(typeof a=="object"&&!B.isMatrix(a)&&!r.isAnyArray(a)?(s=a,a=g,n=!0):a=new B(a),g.rows!==a.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:o=!0}=s;o&&(g=g.center("column"),n||(a=a.center("column")));let l=g.transpose().mmul(a);for(let w=0;w0?o.set(l,l+1,s[l]):s[l]<0&&o.set(l,l-1,s[l])}return o}}function wo(g,a,s,n){let o,l,w,y,m,b,I,S;for(m=0;m0;y--){for(S=0,w=0,b=0;b0&&(l=-l),a[y]=S*l,w=w-o*l,s[y-1]=o-l,m=0;mb)do{for(o=s[b],S=(s[b+1]-o)/(2*a[b]),A=we(S,1),S<0&&(A=-A),s[b]=a[b]/(S+A),s[b+1]=a[b]*(S+A),W=s[b+1],l=o-s[b],w=b+2;w=b;w--)for(Y=R,R=$,J=U,o=$*a[w],l=$*S,A=we(S,a[w]),a[w+1]=U*A,U=a[w]/A,$=S/A,S=$*s[w]-U*o,s[w+1]=l+U*($*o+U*s[w]),m=0;mEt*st);s[b]=s[b]+nt,a[b]=0}for(w=0;w=S;b--)s[b]=a.get(b,S-1)/A,m+=s[b]*s[b];for(y=Math.sqrt(m),s[S]>0&&(y=-y),m=m-s[S]*y,s[S]=s[S]-y,I=S;I=S;b--)w+=s[b]*a.get(b,I);for(w=w/m,b=S;b<=l;b++)a.set(b,I,a.get(b,I)-w*s[b])}for(b=0;b<=l;b++){for(w=0,I=l;I>=S;I--)w+=s[I]*a.get(b,I);for(w=w/m,I=S;I<=l;I++)a.set(b,I,a.get(b,I)-w*s[I])}s[S]=A*s[S],a.set(S,S-1,A*y)}}for(b=0;b=o+1;S--)if(a.get(S,S-1)!==0){for(b=S+1;b<=l;b++)s[b]=a.get(b,S-1);for(I=S;I<=l;I++){for(y=0,b=S;b<=l;b++)y+=s[b]*n.get(b,I);for(y=y/s[S]/a.get(S,S-1),b=S;b<=l;b++)n.set(b,I,n.get(b,I)+y*s[b])}}}function bo(g,a,s,n,o){let l=g-1,w=0,y=g-1,m=Number.EPSILON,b=0,I=0,S=0,A=0,W=0,$=0,R=0,Y=0,k,U,J,nt,st,Et,Z,H,wt,D,G,X,F,vt,dt;for(k=0;ky)&&(s[k]=o.get(k,k),a[k]=0),U=Math.max(k-1,0);U=w;){for(nt=l;nt>w&&($=Math.abs(o.get(nt-1,nt-1))+Math.abs(o.get(nt,nt)),$===0&&($=I),!(Math.abs(o.get(nt,nt-1))=0){for(R=S>=0?S+R:S-R,s[l-1]=H+R,s[l]=s[l-1],R!==0&&(s[l]=H-Z/R),a[l-1]=0,a[l]=0,H=o.get(l,l-1),$=Math.abs(H)+Math.abs(R),S=H/$,A=R/$,W=Math.sqrt(S*S+A*A),S=S/W,A=A/W,U=l-1;U0)){for($=Math.sqrt($),wt=nt&&(R=o.get(st,st),W=H-R,$=wt-R,S=(W*$-Z)/o.get(st+1,st)+o.get(st,st+1),A=o.get(st+1,st+1)-R-W-$,W=o.get(st+2,st+1),$=Math.abs(S)+Math.abs(A)+Math.abs(W),S=S/$,A=A/$,W=W/$,!(st===nt||Math.abs(o.get(st,st-1))*(Math.abs(A)+Math.abs(W))st+2&&o.set(k,k-3,0);for(J=st;J<=l-1&&(vt=J!==l-1,J!==st&&(S=o.get(J,J-1),A=o.get(J+1,J-1),W=vt?o.get(J+2,J-1):0,H=Math.abs(S)+Math.abs(A)+Math.abs(W),H!==0&&(S=S/H,A=A/H,W=W/H)),H!==0);J++)if($=Math.sqrt(S*S+A*A+W*W),S<0&&($=-$),$!==0){for(J!==st?o.set(J,J-1,-$*H):nt!==st&&o.set(J,J-1,-o.get(J,J-1)),S=S+$,H=S/$,wt=A/$,R=W/$,A=A/S,W=W/S,U=J;U=0;l--)if(S=s[l],A=a[l],A===0)for(nt=l,o.set(l,l,1),k=l-1;k>=0;k--){for(Z=o.get(k,k)-S,W=0,U=nt;U<=l;U++)W=W+o.get(k,U)*o.get(U,l);if(a[k]<0)R=Z,$=W;else if(nt=k,a[k]===0?o.set(k,l,Z!==0?-W/Z:-W/(m*I)):(H=o.get(k,k+1),wt=o.get(k+1,k),A=(s[k]-S)*(s[k]-S)+a[k]*a[k],Et=(H*$-R*W)/A,o.set(k,l,Et),o.set(k+1,l,Math.abs(H)>Math.abs(R)?(-W-Z*Et)/H:(-$-wt*Et)/R)),Et=Math.abs(o.get(k,l)),m*Et*Et>1)for(U=k;U<=l;U++)o.set(U,l,o.get(U,l)/Et)}else if(A<0)for(nt=l-1,Math.abs(o.get(l,l-1))>Math.abs(o.get(l-1,l))?(o.set(l-1,l-1,A/o.get(l,l-1)),o.set(l-1,l,-(o.get(l,l)-S)/o.get(l,l-1))):(dt=gr(0,-o.get(l-1,l),o.get(l-1,l-1)-S,A),o.set(l-1,l-1,dt[0]),o.set(l-1,l,dt[1])),o.set(l,l-1,0),o.set(l,l,1),k=l-2;k>=0;k--){for(D=0,G=0,U=nt;U<=l;U++)D=D+o.get(k,U)*o.get(U,l-1),G=G+o.get(k,U)*o.get(U,l);if(Z=o.get(k,k)-S,a[k]<0)R=Z,W=D,$=G;else if(nt=k,a[k]===0?(dt=gr(-D,-G,Z,A),o.set(k,l-1,dt[0]),o.set(k,l,dt[1])):(H=o.get(k,k+1),wt=o.get(k+1,k),X=(s[k]-S)*(s[k]-S)+a[k]*a[k]-A*A,F=(s[k]-S)*2*A,X===0&&F===0&&(X=m*I*(Math.abs(Z)+Math.abs(A)+Math.abs(H)+Math.abs(wt)+Math.abs(R))),dt=gr(H*W-R*D+A*G,H*$-R*G-A*D,X,F),o.set(k,l-1,dt[0]),o.set(k,l,dt[1]),Math.abs(H)>Math.abs(R)+Math.abs(A)?(o.set(k+1,l-1,(-D-Z*o.get(k,l-1)+A*o.get(k,l))/H),o.set(k+1,l,(-G-Z*o.get(k,l)-A*o.get(k,l-1))/H)):(dt=gr(-W-wt*o.get(k,l-1),-$-wt*o.get(k,l),R,A),o.set(k+1,l-1,dt[0]),o.set(k+1,l,dt[1]))),Et=Math.max(Math.abs(o.get(k,l-1)),Math.abs(o.get(k,l))),m*Et*Et>1)for(U=k;U<=l;U++)o.set(U,l-1,o.get(U,l-1)/Et),o.set(U,l,o.get(U,l)/Et)}for(k=0;ky)for(U=k;U=w;U--)for(k=w;k<=y;k++){for(R=0,J=w;J<=Math.min(U,y);J++)R=R+n.get(k,J)*o.get(J,U);n.set(k,U,R)}}}function gr(g,a,s,n){let o,l;return Math.abs(s)>Math.abs(n)?(o=n/s,l=s+o*n,[(g+o*a)/l,(a-o*g)/l]):(o=s/n,l=n+o*s,[(o*g+a)/l,(o*a-g)/l])}class qn{constructor(a){if(a=Jt.checkMatrix(a),!a.isSymmetric())throw new Error("Matrix is not symmetric");let s=a,n=s.rows,o=new B(n,n),l=!0,w,y,m;for(y=0;y0),o.set(y,y,Math.sqrt(Math.max(b,0))),m=y+1;m=0;m--)for(y=0;yw;W++)S=a.transpose().mmul(y).div(y.transpose().mmul(y).get(0,0)),S=S.div(S.norm()),b=a.mmul(S).div(S.transpose().mmul(S).get(0,0)),W>0&&(m=b.clone().sub(A).pow(2).sum()),A=b.clone(),n?(I=n.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0)),I=I.div(I.norm()),y=n.mmul(I).div(I.transpose().mmul(I).get(0,0))):y=b;if(n){let W=a.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0));W=W.div(W.norm());let $=a.clone().sub(b.clone().mmul(W.transpose())),R=y.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0)),Y=n.clone().sub(b.clone().mulS(R.get(0,0)).mmul(I.transpose()));this.t=b,this.p=W.transpose(),this.w=S.transpose(),this.q=I,this.u=y,this.s=b.transpose().mmul(b),this.xResidual=$,this.yResidual=Y,this.betas=R}else this.w=S.transpose(),this.s=b.transpose().mmul(b).sqrt(),o?this.t=b.clone().div(this.s.get(0,0)):this.t=b,this.xResidual=a.sub(b.mmul(S.transpose()))}}return ut.AbstractMatrix=et,ut.CHO=qn,ut.CholeskyDecomposition=qn,ut.DistanceMatrix=cr,ut.EVD=Un,ut.EigenvalueDecomposition=Un,ut.LU=fr,ut.LuDecomposition=fr,ut.Matrix=B,ut.MatrixColumnSelectionView=to,ut.MatrixColumnView=Hs,ut.MatrixFlipColumnView=eo,ut.MatrixFlipRowView=ro,ut.MatrixRowSelectionView=io,ut.MatrixRowView=no,ut.MatrixSelectionView=lr,ut.MatrixSubView=so,ut.MatrixTransposeView=oo,ut.NIPALS=Wn,ut.Nipals=Wn,ut.QR=en,ut.QrDecomposition=en,ut.SVD=Ge,ut.SingularValueDecomposition=Ge,ut.SymmetricMatrix=$e,ut.WrapperMatrix1D=Fn,ut.WrapperMatrix2D=Jt,ut.correlation=po,ut.covariance=go,ut.default=B,ut.determinant=dr,ut.inverse=ao,ut.linearDependencies=lo,ut.pseudoInverse=fo,ut.solve=zn,ut.wrap=uo,ut}var sr=Os(),In=As(sr);var jn=sr.Matrix,Cs=sr.SingularValueDecomposition;In.Matrix?In.Matrix:sr.Matrix;var qr=(r,t)=>{let e=r.nodeCount(),i=Array.from({length:e},()=>[]),u={},h=0;return r.forEachNode(c=>{u[c.id]=h++}),r.forEachEdge(c=>{let f=u[c.source],p=u[c.target];f==null||p==null||(i[f].push(p),t||i[p].push(f))}),i},Ps=(r,t)=>{let e=r.length,i=new Array(e);for(let u=0;unew Array(t).fill(1/0));for(let i=0;i0&&(this.data[0]=e,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let e=this.data;for(;t>0;){let i=t-1>>1;if(e[i][0]<=e[t][0])break;[e[i],e[t]]=[e[t],e[i]],t=i}}bubbleDown(t){let e=this.data,i=e.length;for(;;){let u=t*2+1,h=t*2+2,c=t;if(u{let v=f[p++];d.x=v[0]+e[0],d.y=v[1]+e[1]})})}},nh=r=>{let t=Number.NEGATIVE_INFINITY,e=[],i=r.length;for(let u=0;u{try{let i=r.length,u=new jn(i,i);for(let M=0;M{let e=Object.assign(Object.assign({},Fs),t),{maxIteration:i,width:u,k:h,speed:c=Fs.speed,strictRadial:f,focusNode:p,radiiMap:d,nodeSizeFunc:v}=e,x=h*.002,E=new Map,M=u/10;for(let _=0;_{E.set(C.id,{x:0,y:0})}),ih(r,E,h,d,v),!(sh(r,E,c,f,p,M,d){let h=0;r.forEachNode(c=>{let f=0;r.forEachNode(p=>{if(f<=h){f++;return}if(c.id===p.id||i.get(c.id)!==i.get(p.id))return;let d=c.x-p.x,v=c.y-p.y,x=Math.sqrt(d*d+v*v);if(x===0){x=1;let _=h>f?1:-1;d=.01*_,v=.01*_}let E=Math.max(...u(c._original)),M=Math.max(...u(p._original));if(x{i&&r.forEachNode(d=>{let v=d.x-u.x,x=d.y-u.y,E=Math.sqrt(v*v+x*x),M=x/E,_=-v/E,N=t.get(d.id),C=Math.sqrt(N.x*N.x+N.y*N.y),q=Math.acos((M*N.x+_*N.y)/C);q>Math.PI/2&&(q-=Math.PI/2,M*=-1,_*=-1);let L=Math.cos(q)*C;t.set(d.id,{x:M*L,y:_*L})});let f=0,p=0;return r.forEachNode(d=>{if(d.id===u.id)return;let v=t.get(d.id),x=Math.sqrt(v.x*v.x+v.y*v.y);if(x>0){let E=Math.min(h*(e/800),x);if(d.x+=v.x/x*E,d.y+=v.y/x*E,i){let M=d.x-u.x,_=d.y-u.y,N=Math.sqrt(M*M+_*_);M=M/N*c.get(d.id),_=_/N*c.get(d.id),d.x=u.x+M,d.y=u.y+_}f+=E,p++}}),p>0?f/p:0};var Ne={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},Br=class extends ke{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return Ne}layout(){return ne(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=Be(this.options),u=this.model.nodeCount();if(!u||u===1)return Ve(this.model,i);let{focusNode:h,linkDistance:c=Ne.linkDistance,maxIteration:f=Ne.maxIteration,maxPreventOverlapIteration:p=Ne.maxPreventOverlapIteration,nodeSize:d,nodeSpacing:v,preventOverlap:x,sortBy:E,sortStrength:M=Ne.sortStrength,strictRadial:_,unitRadius:N}=this.options,C=h&&this.model.node(h)||this.model.firstNode(),q=this.model.nodeIndexOf(C.id),L=qr(this.model,!1),z=Wr(L),K=hh(z,q);ah(z,q,K+1);let P=z[q],it=(t-i[0]>i[0]?i[0]:t-i[0])||t/2,T=(e-i[1]>i[1]?i[1]:e-i[1])||e/2,O=Math.min(it,T),j=Math.max(...P),rt=[],at=new Map,pt=N??O/j;P.forEach((Ut,Qt)=>{let ge=Ut*pt;rt.push(ge),at.set(this.model.nodeAt(Qt).id,ge)});let _t=oh(this.model,z,c,rt,pt,E,M),$t=An(_t,2,c),Yt=$t[q],Xt=0;if(this.model.forEachNode(Ut=>{let Qt=$t[Xt];Ut.x=Qt[0]-Yt[0],Ut.y=Qt[1]-Yt[1],Xt++}),this.run(f,_t,rt,q),this.model.forEachNode(Ut=>{Ut.x+=i[0],Ut.y+=i[1]}),x){let Qt={nodeSizeFunc:Ar(d,v,Ne.nodeSize,Ne.nodeSpacing),radiiMap:at,width:t,strictRadial:!!_,focusNode:C,maxIteration:p,k:u/4.5};zs(this.model,Qt)}})}run(t,e,i,u){let h=uh(e),c=this.model.nodeCount(),f=this.model.nodes(),p=new Float64Array(c),d=new Float64Array(c);for(let v=0;v{let f=t.length,p=new Array(f),d=new Array(f);for(let _=0;_{let t=r.length,e=r[0].length,i=[];for(let u=0;u{let i=r.length;for(let u=0;u{let e=r[t],i=0;for(let u=0;uKe,BubbleSets:()=>Hr,Circle:()=>hr,Line:()=>Gt,PointPath:()=>de,Rectangle:()=>Vt,addPadding:()=>On,boundingBox:()=>Bs,calculatePotentialOutline:()=>Qs,calculateVirtualEdges:()=>Ys,circle:()=>wh,createGenericInfluenceArea:()=>Cn,createLineInfluenceArea:()=>Nn,createOutline:()=>$h,createRectangleInfluenceArea:()=>Ks,default:()=>Hr,defaultOptions:()=>Pn,line:()=>yh,lineBoundingBox:()=>Gn,point:()=>mt,rect:()=>ph,unionBoundingBox:()=>Js});function Tn(r,t,e,i,u,h){let c=r,f=t,p=e-c,d=i-f,v=u-c,x=h-f,E=v*p+x*d,M=0;E<=0?M=0:(v=p-v,x=d-x,E=v*p+x*d,E<=0?M=0:M=E*E/(p*p+d*d));let _=v*v+x*x-M;return _<0?0:_}function Ie(r,t,e,i){return(r-e)*(r-e)+(t-i)*(t-i)}function Us(r,t,e,i,u){return Ie(r,t,e,i)e;if(r===0)return Math.round;let t=Math.pow(10,r);return e=>Math.round(e*t)/t}function Gn(r){let t=Math.min(r.x1,r.x2),e=Math.max(r.x1,r.x2),i=Math.min(r.y1,r.y2),u=Math.max(r.y1,r.y2);return{x:t,y:i,x2:e,y2:u,width:e-t,height:u-i}}var Gt=class r{constructor(t,e,i,u){this.x1=t,this.y1=e,this.x2=i,this.y2=u}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new r(t.x1,t.y1,t.x2,t.y2)}cuts(t,e){if(this.y1===this.y2||ethis.y1&&e>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+i)return!1}else if(tthis.x1+i)return!1;if(this.y1this.y2+i)return!1}else if(ethis.y1+i)return!1;return!0}},It;(function(r){r[r.POINT=1]="POINT",r[r.PARALLEL=2]="PARALLEL",r[r.COINCIDENT=3]="COINCIDENT",r[r.NONE=4]="NONE"})(It||(It={}));var ur=class{constructor(t,e=0,i=0){this.state=t,this.x=e,this.y=i}};function Kr(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;return 0<=h&&h<=1&&0<=c&&c<=1?new ur(It.POINT,r.x1+h*(r.x2-r.x1),r.y1+h*(r.y2-r.y1)):new ur(It.NONE)}return new ur(e===0||i===0?It.COINCIDENT:It.PARALLEL)}function Ws(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;if(0<=h&&h<=1&&0<=c&&c<=1)return h}return Number.POSITIVE_INFINITY}function lh(r,t){function e(u,h,c,f){let p=Ws(t,new Gt(u,h,c,f));return p=Math.abs(p-.5),p>=0&&p<=1?1:0}let i=e(r.x,r.y,r.x2,r.y);return i+=e(r.x,r.y,r.x,r.y2),i>1||(i+=e(r.x,r.y2,r.x2,r.y2),i>1)?!0:(i+=e(r.x2,r.y,r.x2,r.y2),i>0)}var jt;(function(r){r[r.LEFT=0]="LEFT",r[r.TOP=1]="TOP",r[r.RIGHT=2]="RIGHT",r[r.BOTTOM=3]="BOTTOM"})(jt||(jt={}));function Zr(r,t,e){let i=new Set;return r.width<=0?(i.add(jt.LEFT),i.add(jt.RIGHT)):tr.x+r.width&&i.add(jt.RIGHT),r.height<=0?(i.add(jt.TOP),i.add(jt.BOTTOM)):er.y+r.height&&i.add(jt.BOTTOM),i}function Vs(r,t){let e=t.x1,i=t.y1,u=t.x2,h=t.y2,c=Array.from(Zr(r,u,h));if(c.length===0)return!0;let f=Zr(r,e,i);for(;f.size!==0;){for(let p of c)if(f.has(p))return!1;if(f.has(jt.RIGHT)||f.has(jt.LEFT)){let p=r.x;f.has(jt.RIGHT)&&(p+=r.width),i=i+(p-e)*(h-i)/(u-e),e=p}else{let p=r.y;f.has(jt.BOTTOM)&&(p+=r.height),e=e+(p-i)*(u-e)/(h-i),i=p}f=Zr(r,e,i)}return!0}function fh(r,t){let e=Number.POSITIVE_INFINITY,i=0;function u(h,c,f,p){let d=Ws(t,new Gt(h,c,f,p));d=Math.abs(d-.5),d>=0&&d<=1&&(i++,d1||(u(r.x,r.y2,r.x2,r.y2),i>1)?e:(u(r.x2,r.y,r.x2,r.y2),i===0?-1:e)}function dh(r,t){let e=0,i=Kr(r,new Gt(t.x,t.y,t.x2,t.y));e+=i.state===It.POINT?1:0;let u=Kr(r,new Gt(t.x,t.y,t.x,t.y2));e+=u.state===It.POINT?1:0;let h=Kr(r,new Gt(t.x,t.y2,t.x2,t.y2));e+=h.state===It.POINT?1:0;let c=Kr(r,new Gt(t.x2,t.y,t.x2,t.y2));return e+=c.state===It.POINT?1:0,{top:i,left:u,bottom:h,right:c,count:e}}var Vt=class r{constructor(t,e,i,u){this.x=t,this.y=e,this.width=i,this.height=u}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new r(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new r(this.x,this.y,this.width,this.height)}add(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x+t.width),h=Math.max(this.y2,t.y+t.height);this.x=e,this.y=i,this.width=u-e,this.height=h-i}addPoint(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x),h=Math.max(this.y2,t.y);this.x=e,this.y=i,this.width=u-e,this.height=h-i}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let e=this.scaleX(t.x),i=this.scaleY(t.y),u=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),h=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),c=u-e,f=h-i;return new Vt(e,i,c,f)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){let i=Math.ceil(e/this.pixelGroup),u=this.boundX(t.x-i),h=this.boundY(t.y-i),c=this.boundX(t.x2+i),f=this.boundY(t.y2+i),p=c-u,d=f-h;return new Vt(u,h,p,d)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=i)}set(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=i)}incArea(t,e){if(t.width<=0||t.height<=0||e===0)return;let i=this.width,u=t.width,h=Math.max(0,t.i),c=Math.max(0,t.j),f=Math.min(t.i+t.width,i),p=Math.min(t.j+t.height,this.height);if(!(p<=0||f<=0||h>=i||p>=this.height))for(let d=c;dMath.min(c,f),Number.POSITIVE_INFINITY),u=this.area.reduce((c,f)=>Math.max(c,f),Number.NEGATIVE_INFINITY),h=c=>(c-i)/(u-i);t.scale(this.pixelGroup,this.pixelGroup);for(let c=0;ce?"black":"white",t.fillRect(u,h,1,1)}t.restore()}}};function On(r,t){let e=i=>({x:i.x-t,y:i.y-t,width:i.width+2*t,height:i.height+2*t});return Array.isArray(r)?r.map(e):e(r)}function Nn(r,t,e){return Cn(Object.assign(Gn(r),{distSquare:(i,u)=>Tn(r.x1,r.y1,r.x2,r.y2,i,u)}),t,e)}function Cn(r,t,e){let i=On(r,e),u=t.scale(i),h=t.createSub(u,i);return gh(h,t,e,(c,f)=>r.distSquare(c,f)),h}function gh(r,t,e,i){let u=e*e;for(let h=0;h{let f=u.slice(0,c);return mh(t,h,f,e,i)}).flat()}function mh(r,t,e,i,u){let h=mt(t.cx,t.cy),c=vh(h,e,r);if(c==null)return[];let f=new Gt(h.x,h.y,c.cx,c.cy),p=bh(f,r,i,u);return Eh(p,r)}function bh(r,t,e,i){let u=[],h=[];h.push(r);let c=!0;for(let f=0;f0;){let p=h.pop(),d=Xs(t,p),v=d?dh(p,d):null;if(!d||!v||v.count!==2){c||u.push(p);continue}let x=i,E=Xr(d,x,v,!0),M=De(E,h)||De(E,u),_=Yr(E,t);for(;!M&&_&&x>=1;)x/=1.5,E=Xr(d,x,v,!0),M=De(E,h)||De(E,u),_=Yr(E,t);if(E&&!M&&!_&&(h.push(new Gt(p.x1,p.y1,E.x,E.y)),h.push(new Gt(E.x,E.y,p.x2,p.y2)),c=!0),c)continue;x=i,E=Xr(d,x,v,!1);let N=De(E,h)||De(E,u);for(_=Yr(E,t);!N&&_&&x>=1;)x/=1.5,E=Xr(d,x,v,!1),N=De(E,h)||De(E,u),_=Yr(E,t);E&&!N&&(h.push(new Gt(p.x1,p.y1,E.x,E.y)),h.push(new Gt(E.x,E.y,p.x2,p.y2)),c=!0),c||u.push(p)}for(;h.length>0;)u.push(h.pop());return u}function Eh(r,t){let e=[];for(;r.length>0;){let i=r.pop();if(r.length===0){e.push(i);break}let u=r.pop(),h=new Gt(i.x1,i.y1,u.x2,u.y2);Xs(t,h)?(e.push(i),r.push(u)):r.push(h)}return e}function vh(r,t,e){let i=Number.POSITIVE_INFINITY;return t.reduce((u,h)=>{let c=Ie(r.x,r.y,h.cx,h.cy);if(c>i)return u;let f=new Gt(r.x,r.y,h.cx,h.cy),p=Sh(e,f);return c*(p+1)*(p+1){t+=i.cx,e+=i.cy}),t/=r.length,e/=r.length,r.map(i=>{let u=t-i.cx,h=e-i.cy,c=u*u+h*h;return[i,c]}).sort((i,u)=>i[1]-u[1]).map(i=>i[0])}function Yr(r,t){return t.some(e=>e.containsPt(r.x,r.y))}function De(r,t){return t.some(e=>!!(Us(e.x1,e.y1,r.x,r.y,.001)||Us(e.x2,e.y2,r.x,r.y,.001)))}function Xs(r,t){let e=Number.POSITIVE_INFINITY,i=null;for(let u of r){if(!Vs(u,t))continue;let h=fh(u,t);h>=0&&hVs(i,t)&&lh(i,t)?e+1:e,0)}function Xr(r,t,e,i){let u=e.top,h=e.left,c=e.bottom,f=e.right;if(i){if(h.state===It.POINT){if(u.state===It.POINT)return mt(r.x-t,r.y-t);if(c.state===It.POINT)return mt(r.x-t,r.y2+t);let E=r.width*r.height;return r.width*((h.y-r.y+(f.y-r.y))*.5)f.y?mt(r.x-t,r.y-t):mt(r.x2+t,r.y-t):h.yc.x?mt(r.x-t,r.y-t):mt(r.x-t,r.y2+t):u.xf.y?mt(r.x2+t,r.y2+t):mt(r.x-t,r.y2+t):h.yc.x?mt(r.x2+t,r.y2+t):mt(r.x2+t,r.y-t):u.xi)return!1}return!0}function Mh(r=0){return t=>{if(r<0||t.length<3)return t;let e=[],i=0,u=r*r;for(;i{if(c.length<3)return c;let f=[],p=c.closed,d=c.length+3-1+(p?0:2);f.push(h(c,2-(p?0:2),0));for(let v=2-(p?0:2);v{let e=r,i=t.length;if(e>1)for(i=Math.floor(t.length/e);i<3&&e>1;)e-=1,i=Math.floor(t.length/e);let u=[];for(let h=0,c=0;c=i?this.closed?this.get(t-i):this.points[i-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){let e=this.points;if(e.length===0)return"";let i=typeof t=="function"?t:ch(t),u="M";for(let h of e)u+=`${i(h.x)},${i(h.y)} L`;return u=u.slice(0,-1),this.closed&&(u+=" Z"),u}draw(t){let e=this.points;if(e.length!==0){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let i of e)t.lineTo(i.x,i.y);this.closed&&t.closePath()}}sample(t){return jh(t)(this)}simplify(t){return Mh(t)(this)}bSplines(t){return Ih(t)(this)}apply(t){return t(this)}containsElements(t){let e=Bs(this.points);return e?t.every(i=>e.containsPt(i.cx,i.cy)&&this.withinArea(i.cx,i.cy)):!1}withinArea(t,e){if(this.length===0)return!1;let i=0,u=this.points[0],h=new Gt(u.x,u.y,u.x,u.y);for(let c=1;ct?v+x:v}function h(p,d){let v=or;return v=u(p,d,v,1),v=u(p+1,d,v,2),v=u(p,d+1,v,4),v=u(p+1,d+1,v,8),Number.isNaN(v)?-1:v}let c=Qr;function f(p,d){let v=p,x=d,E=r.invertScaleX(v),M=r.invertScaleY(x);for(let _=0;_qs(i.raw,t));return e<0?!1:(this.members.splice(e,1),this.dirty.add(he.MEMBERS),!0)}removeNonMember(t){let e=this.nonMembers.findIndex(i=>qs(i.raw,t));return e<0?!1:(this.nonMembers.splice(e,1),this.dirty.add(he.NON_MEMBERS),!0)}removeEdge(t){let e=this.edges.findIndex(i=>i.obj.equals(t));return e<0?!1:(this.edges.splice(e,1),this.dirty.add(he.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(he.NON_MEMBERS);for(let e of t)this.nonMembers.push({raw:e,obj:ar(e)?hr.from(e):Vt.from(e),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(he.EDGES);for(let e of t)this.edges.push({raw:e,obj:Gt.from(e),area:null})}}update(){let t=this.dirty.has(he.MEMBERS),e=this.dirty.has(he.NON_MEMBERS),i=this.dirty.has(he.EDGES);this.dirty.clear();let u=this.members.map(d=>d.obj);if(this.o.virtualEdges&&(t||e)){let d=this.nonMembers.map(E=>E.obj),v=Ys(u,d,this.o.maxRoutingIterations,this.o.morphBuffer),x=new Map(this.virtualEdges.map(E=>[E.obj.toString(),E.area]));this.virtualEdges=v.map(E=>{var M;return{raw:E,obj:E,area:(M=x.get(E.toString()))!==null&&M!==void 0?M:null}}),i=!0}let h=!1;if(t||i){let d=this.virtualEdges.concat(this.edges).map(M=>M.obj),v=Js(u,d),x=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,E=Vt.from(On(v,x));E.equals(this.activeRegion)||(h=!0,this.activeRegion=E)}if(h){let d=Math.ceil(this.activeRegion.width/this.o.pixelGroup),v=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=Ke.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(x=>x.area=null),this.nonMembers.forEach(x=>x.area=null),this.edges.forEach(x=>x.area=null),this.virtualEdges.forEach(x=>x.area=null)):(d!==this.potentialArea.width||v!==this.potentialArea.height)&&(this.potentialArea=Ke.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let c=new Map,f=d=>{if(d.area){let v=`${d.obj.width}x${d.obj.height}x${d.obj instanceof Vt?"R":"C"}`;c.set(v,d.area)}},p=d=>{if(d.area)return;let v=`${d.obj.width}x${d.obj.height}x${d.obj instanceof Vt?"R":"C"}`;if(c.has(v)){let E=c.get(v);d.area=this.potentialArea.copy(E,{x:d.obj.x-this.o.nodeR1,y:d.obj.y-this.o.nodeR1});return}let x=d.obj instanceof Vt?Ks(d.obj,this.potentialArea,this.o.nodeR1):Cn(d.obj,this.potentialArea,this.o.nodeR1);d.area=x,c.set(v,x)};this.members.forEach(f),this.nonMembers.forEach(f),this.members.forEach(p),this.nonMembers.forEach(d=>{this.activeRegion.intersects(d.obj)?p(d):d.area=null}),this.edges.forEach(d=>{d.area||(d.area=Nn(d.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(d=>{d.area||(d.area=Nn(d.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let e of this.members)e.obj.draw(t)}drawNonMembers(t){for(let e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(let e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(this.members.length===0)return new de([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:e}=this,i=this.members.map(f=>f.area),u=this.virtualEdges.concat(this.edges).map(f=>f.area),h=this.nonMembers.filter(f=>f.area!=null).map(f=>f.area),c=this.members.map(f=>f.obj);return Qs(e,i,u,h,f=>f.containsElements(c),t)}};function Qs(r,t,e,i,u,h={}){let c=Object.assign({},Pn,h),f=c.threshold,p=c.memberInfluenceFactor,d=c.edgeInfluenceFactor,v=c.nonMemberInfluenceFactor,x=(c.nodeR0-c.nodeR1)*(c.nodeR0-c.nodeR1),E=(c.edgeR0-c.edgeR1)*(c.edgeR0-c.edgeR1);for(let M=0;M0)v*=.8;else break}return new de([])}function Js(r,t){if(r.length===0)return new Vt(0,0,0,0);let e=Vt.from(r[0]);for(let i of r)e.add(i);for(let i of t)e.add(Gn(i));return e}function $h(r,t=[],e=[],i={}){if(r.length===0)return new de([]);let u=new Hr(i);return u.pushMember(...r),u.pushNonMember(...t),u.pushEdge(...e),u.compute()}var export_circlepack=tn.circlepack;var export_circular=tn.circular;var export_forceAtlas2=Ah.default;var export_random=tn.random;var export_rotation=tn.rotation;export{zr as ConcentricLayout,yt as Graph,Vr as MDSLayout,Br as RadialLayout,Zs as bubblesets,export_circlepack as circlepack,export_circular as circular,export_forceAtlas2 as forceAtlas2,export_random as random,export_rotation as rotation}; +${e}rows: ${p.rows} +${e}columns: ${p.columns} +}`}function c(p,a,s,n,o){let{rows:l,columns:w}=p,y=Math.min(l,a),E=Math.min(w,s),S=[];if(o==="auto"){o=!1;t:for(let R=0;R=0&&s?` ${g(p,a-1)}`:g(p,a)).padEnd(a)}function g(p,a){let s=p.toString();if(s.length<=a)return s;let n=p.toFixed(a);if(n.length>a&&(n=p.toFixed(Math.max(0,a-(n.length-a)))),n.length<=a&&!n.startsWith("0.000")&&!n.startsWith("-0.000"))return n;let o=p.toExponential(a);return o.length>a&&(o=p.toExponential(Math.max(0,a-(o.length-a)))),o.slice(0)}function d(p,a){p.prototype.add=function(n){return typeof n=="number"?this.addS(n):this.addM(n)},p.prototype.addS=function(n){for(let o=0;o>n);return this},p.prototype.signPropagatingRightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>n.get(o,l));return this},p.signPropagatingRightShift=function(n,o){return new a(n).signPropagatingRightShift(o)},p.prototype.rightShift=function(n){return typeof n=="number"?this.rightShiftS(n):this.rightShiftM(n)},p.prototype.rightShiftS=function(n){for(let o=0;o>>n);return this},p.prototype.rightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>>n.get(o,l));return this},p.rightShift=function(n,o){return new a(n).rightShift(o)},p.prototype.zeroFillRightShift=p.prototype.rightShift,p.prototype.zeroFillRightShiftS=p.prototype.rightShiftS,p.prototype.zeroFillRightShiftM=p.prototype.rightShiftM,p.zeroFillRightShift=p.rightShift,p.prototype.not=function(){for(let n=0;nn)throw new RangeError("Row index out of range")}function m(p,a,s){let n=s?p.columns:p.columns-1;if(a<0||a>n)throw new RangeError("Column index out of range")}function v(p,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==p.columns)throw new RangeError("vector size must be the same as the number of columns");return a}function D(p,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==p.rows)throw new RangeError("vector size must be the same as the number of rows");return a}function $(p,a){if(!r.isAnyArray(a))throw new TypeError("row indices must be an array");for(let s=0;s=p.rows)throw new RangeError("row indices are out of range")}function P(p,a){if(!r.isAnyArray(a))throw new TypeError("column indices must be an array");for(let s=0;s=p.columns)throw new RangeError("column indices are out of range")}function q(p,a,s,n,o){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(G("startRow",a),G("endRow",s),G("startColumn",n),G("endColumn",o),a>s||n>o||a<0||a>=p.rows||s<0||s>=p.rows||n<0||n>=p.columns||o<0||o>=p.columns)throw new RangeError("Submatrix indices are out of range")}function B(p,a=0){let s=[];for(let n=0;n=l)throw new RangeError("min must be smaller than max");let y=l-o,E=new X(a,s);for(let S=0;Sn?(l=!0,n=s):(o=!1,l=!0);a++}return o}isReducedEchelonForm(){let a=0,s=0,n=-1,o=!0,l=!1;for(;an?(l=!0,n=s):(o=!1,l=!0);for(let w=s+1;wa.get(o,n)&&(o=l);if(a.get(o,n)===0)n++;else{a.swapRows(s,o);let l=a.get(s,n);for(let w=n;w=0;)if(a.maxRow(o)===0)o--;else{let l=0,w=!1;for(;ls[n]&&(s[n]=this.get(n,o));return s}case"column":{let s=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let n=0;ns[o]&&(s[o]=this.get(n,o));return s}case void 0:{let s=this.get(0,0);for(let n=0;ns&&(s=this.get(n,o));return s}default:throw new Error(`invalid option: ${a}`)}}maxIndex(){F(this);let a=this.get(0,0),s=[0,0];for(let n=0;na&&(a=this.get(n,o),s[0]=n,s[1]=o);return s}min(a){if(this.isEmpty())return NaN;switch(a){case"row":{let s=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let n=0;ns&&(s=this.get(a,n));return s}maxRowIndex(a){b(this,a),F(this);let s=this.get(a,0),n=[a,0];for(let o=1;os&&(s=this.get(a,o),n[1]=o);return n}minRow(a){if(b(this,a),this.isEmpty())return NaN;let s=this.get(a,0);for(let n=1;ns&&(s=this.get(n,a));return s}maxColumnIndex(a){m(this,a),F(this);let s=this.get(0,a),n=[0,a];for(let o=1;os&&(s=this.get(o,a),n[0]=o);return n}minColumn(a){if(m(this,a),this.isEmpty())return NaN;let s=this.get(0,a);for(let n=1;n=1;o/=2)(o&1)!==0&&(s=s.mmul(n)),n=n.mmul(n);return s}strassen2x2(a){a=X.checkMatrix(a);let s=new X(2,2),n=this.get(0,0),o=a.get(0,0),l=this.get(0,1),w=a.get(0,1),y=this.get(1,0),E=a.get(1,0),S=this.get(1,1),R=a.get(1,1),x=(n+S)*(o+R),L=(y+S)*o,Y=n*(w-R),T=S*(E-o),C=(n+l)*R,J=(y-n)*(o+w),k=(l-S)*(E+R),K=x+T-C+k,et=Y+C,ct=L+T,lt=x-L+Y+J;return s.set(0,0,K),s.set(0,1,et),s.set(1,0,ct),s.set(1,1,lt),s}strassen3x3(a){a=X.checkMatrix(a);let s=new X(3,3),n=this.get(0,0),o=this.get(0,1),l=this.get(0,2),w=this.get(1,0),y=this.get(1,1),E=this.get(1,2),S=this.get(2,0),R=this.get(2,1),x=this.get(2,2),L=a.get(0,0),Y=a.get(0,1),T=a.get(0,2),C=a.get(1,0),J=a.get(1,1),k=a.get(1,2),K=a.get(2,0),et=a.get(2,1),ct=a.get(2,2),lt=(n+o+l-w-y-R-x)*J,Lt=(n-w)*(-Y+J),it=y*(-L+Y+C-J-k-K+ct),ht=(-n+w+y)*(L-Y+J),jt=(w+y)*(-L+Y),_=n*L,U=(-n+S+R)*(L-T+k),H=(-n+S)*(T-k),W=(S+R)*(-L+T),Gt=(n+o+l-y-E-S-R)*k,Dt=R*(-L+T+C-J-k-K+et),Tt=(-l+R+x)*(J+K-et),Ot=(l-x)*(J-et),Jt=l*K,xe=(R+x)*(-K+et),Vt=(-l+y+E)*(k+K-ct),$e=(l-E)*(k-ct),Oe=(y+E)*(-K+ct),mt=o*C,Ht=E*et,de=w*T,ge=S*Y,Bt=x*ct,Io=_+Jt+mt,_o=lt+ht+jt+_+Tt+Jt+xe,Ro=_+U+W+Gt+Jt+Vt+Oe,jo=Lt+it+ht+_+Jt+Vt+$e,Ao=Lt+ht+jt+_+Ht,$o=Jt+Vt+$e+Oe+de,To=_+U+H+Dt+Tt+Ot+Jt,Lo=Tt+Ot+Jt+xe+ge,Go=_+U+H+W+Bt;return s.set(0,0,Io),s.set(0,1,_o),s.set(0,2,Ro),s.set(1,0,jo),s.set(1,1,Ao),s.set(1,2,$o),s.set(2,0,To),s.set(2,1,Lo),s.set(2,2,Go),s}mmulStrassen(a){a=X.checkMatrix(a);let s=this.clone(),n=s.rows,o=s.columns,l=a.rows,w=a.columns;o!==l&&console.warn(`Multiplying ${n} x ${o} and ${l} x ${w} matrix: dimensions do not match.`);function y(x,L,Y){let T=x.rows,C=x.columns;if(T===L&&C===Y)return x;{let J=I.zeros(L,Y);return J=J.setSubMatrix(x,0,0),J}}let E=Math.max(n,l),S=Math.max(o,w);s=y(s,E,S),a=y(a,E,S);function R(x,L,Y,T){if(Y<=512||T<=512)return x.mmul(L);Y%2===1&&T%2===1?(x=y(x,Y+1,T+1),L=y(L,Y+1,T+1)):Y%2===1?(x=y(x,Y+1,T),L=y(L,Y+1,T)):T%2===1&&(x=y(x,Y,T+1),L=y(L,Y,T+1));let C=parseInt(x.rows/2,10),J=parseInt(x.columns/2,10),k=x.subMatrix(0,C-1,0,J-1),K=L.subMatrix(0,C-1,0,J-1),et=x.subMatrix(0,C-1,J,x.columns-1),ct=L.subMatrix(0,C-1,J,L.columns-1),lt=x.subMatrix(C,x.rows-1,0,J-1),Lt=L.subMatrix(C,L.rows-1,0,J-1),it=x.subMatrix(C,x.rows-1,J,x.columns-1),ht=L.subMatrix(C,L.rows-1,J,L.columns-1),jt=R(I.add(k,it),I.add(K,ht),C,J),_=R(I.add(lt,it),K,C,J),U=R(k,I.sub(ct,ht),C,J),H=R(it,I.sub(Lt,K),C,J),W=R(I.add(k,et),ht,C,J),Gt=R(I.sub(lt,k),I.add(K,ct),C,J),Dt=R(I.sub(et,it),I.add(Lt,ht),C,J),Tt=I.add(jt,H);Tt.sub(W),Tt.add(Dt);let Ot=I.add(U,W),Jt=I.add(_,H),xe=I.sub(jt,_);xe.add(U),xe.add(Gt);let Vt=I.zeros(2*Tt.rows,2*Tt.columns);return Vt=Vt.setSubMatrix(Tt,0,0),Vt=Vt.setSubMatrix(Ot,Tt.rows,0),Vt=Vt.setSubMatrix(Jt,0,Tt.columns),Vt=Vt.setSubMatrix(xe,Tt.rows,Tt.columns),Vt.subMatrix(0,Y-1,0,T-1)}return R(s,a,E,S)}scaleRows(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new X(this.rows,this.columns);for(let l=0;l0&&t(w,{min:s,max:n,output:w}),o.setRow(l,w)}return o}scaleColumns(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new X(this.rows,this.columns);for(let l=0;ln||s<0||s>=this.columns||n<0||n>=this.columns)throw new RangeError("Argument out of range");let o=new X(a.length,n-s+1);for(let l=0;l=this.rows)throw new RangeError(`Row index out of range: ${a[l]}`);o.set(l,w-s,this.get(a[l],w))}return o}subMatrixColumn(a,s,n){if(s===void 0&&(s=0),n===void 0&&(n=this.rows-1),s>n||s<0||s>=this.rows||n<0||n>=this.rows)throw new RangeError("Argument out of range");let o=new X(n-s+1,a.length);for(let l=0;l=this.columns)throw new RangeError(`Column index out of range: ${a[l]}`);o.set(w-s,l,this.get(w,a[l]))}return o}setSubMatrix(a,s,n){if(a=X.checkMatrix(a),a.isEmpty())return this;let o=s+a.rows-1,l=n+a.columns-1;q(this,s,o,n,l);for(let w=0;wtypeof a=="number")}I.random=I.rand,I.randomInt=I.randInt,I.diagonal=I.diag,I.prototype.diagonal=I.prototype.diag,I.identity=I.eye,I.prototype.negate=I.prototype.neg,I.prototype.tensorProduct=I.prototype.kroneckerProduct;let Cr=class Cr extends I{constructor(s,n){super();jn(this,Er);pi(this,"data");if(Cr.isMatrix(s))An(this,Er,Jn).call(this,s.rows,s.columns),Cr.copy(s,this);else if(Number.isInteger(s)&&s>=0)An(this,Er,Jn).call(this,s,n);else if(r.isAnyArray(s)){let o=s;if(s=o.length,n=s?o[0].length:0,typeof n!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let l=0;l"u"&&(n=s,s=this.columns),m(this,s,!0),n=D(this,n);for(let o=0;o=0)for(let o=0;o=0)zr(this,re,new X(s,s));else if(zr(this,re,new X(s)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return ke(this,re).size}get rows(){return ke(this,re).rows}get columns(){return ke(this,re).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(s){return X.isMatrix(s)&&s.klassType==="SymmetricMatrix"}static zeros(s){return new this(s)}static ones(s){return new this(s).fill(1)}clone(){let s=new Pr(this.diagonalSize);for(let[n,o,l]of this.upperRightEntries())s.set(n,o,l);return s}toMatrix(){return new X(this)}get(s,n){return ke(this,re).get(s,n)}set(s,n,o){return ke(this,re).set(s,n,o),ke(this,re).set(n,s,o),this}removeCross(s){return ke(this,re).removeRow(s),ke(this,re).removeColumn(s),this}addCross(s,n){n===void 0&&(n=s,s=this.diagonalSize);let o=n.slice();return o.splice(s,1),ke(this,re).addRow(s,o),ke(this,re).addColumn(s,n),this}applyMask(s){if(s.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let n=[];for(let[o,l]of s.entries())l||n.push(o);n.reverse();for(let o of n)this.removeCross(o);return this}toCompact(){let{diagonalSize:s}=this,n=new Array(s*(s+1)/2);for(let o=0,l=0,w=0;w=s&&(o=++l);return n}static fromCompact(s){let n=s.length,o=(Math.sqrt(8*n+1)-1)/2;if(!Number.isInteger(o))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(s)}`);let l=new Pr(o);for(let w=0,y=0,E=0;E=o&&(w=++y);return l}*upperRightEntries(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}}*upperRightValues(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}};re=new WeakMap;let ae=Pr;ae.prototype.klassType="SymmetricMatrix";class qt extends ae{static isDistanceMatrix(a){return ae.isSymmetricMatrix(a)&&a.klassSubType==="DistanceMatrix"}constructor(a){if(super(a),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(a,s,n){return a===s&&(n=0),super.set(a,s,n)}addCross(a,s){return s===void 0&&(s=a,a=this.diagonalSize),s=s.slice(),s[a]=0,super.addCross(a,s)}toSymmetricMatrix(){return new ae(this)}clone(){let a=new qt(this.diagonalSize);for(let[s,n,o]of this.upperRightEntries())s!==n&&a.set(s,n,o);return a}toCompact(){let{diagonalSize:a}=this,s=(a-1)*a/2,n=new Array(s);for(let o=1,l=0,w=0;w=a&&(o=++l+1);return n}static fromCompact(a){let s=a.length;if(s===0)return new this(0);let n=(Math.sqrt(8*s+1)+1)/2;if(!Number.isInteger(n))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(a)}`);let o=new this(n);for(let l=1,w=0,y=0;y=n&&(l=++w+1);return o}}qt.prototype.klassSubType="DistanceMatrix";class st extends I{constructor(a,s,n){super(),this.matrix=a,this.rows=s,this.columns=n}}class mr extends st{constructor(a,s){m(a,s),super(a,a.rows,1),this.column=s}set(a,s,n){return this.matrix.set(a,this.column,n),this}get(a){return this.matrix.get(a,this.column)}}class pe extends st{constructor(a,s){P(a,s),super(a,a.rows,s.length),this.columnIndices=s}set(a,s,n){return this.matrix.set(a,this.columnIndices[s],n),this}get(a,s){return this.matrix.get(a,this.columnIndices[s])}}class Dn extends st{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(a,this.columns-s-1,n),this}get(a,s){return this.matrix.get(a,this.columns-s-1)}}class Ye extends st{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(this.rows-a-1,s,n),this}get(a,s){return this.matrix.get(this.rows-a-1,s)}}class In extends st{constructor(a,s){b(a,s),super(a,1,a.columns),this.row=s}set(a,s,n){return this.matrix.set(this.row,s,n),this}get(a,s){return this.matrix.get(this.row,s)}}class tr extends st{constructor(a,s){$(a,s),super(a,s.length,a.columns),this.rowIndices=s}set(a,s,n){return this.matrix.set(this.rowIndices[a],s,n),this}get(a,s){return this.matrix.get(this.rowIndices[a],s)}}class _t extends st{constructor(a,s,n){$(a,s),P(a,n),super(a,s.length,n.length),this.rowIndices=s,this.columnIndices=n}set(a,s,n){return this.matrix.set(this.rowIndices[a],this.columnIndices[s],n),this}get(a,s){return this.matrix.get(this.rowIndices[a],this.columnIndices[s])}}class Et extends st{constructor(a,s,n,o,l){q(a,s,n,o,l),super(a,n-s+1,l-o+1),this.startRow=s,this.startColumn=o}set(a,s,n){return this.matrix.set(this.startRow+a,this.startColumn+s,n),this}get(a,s){return this.matrix.get(this.startRow+a,this.startColumn+s)}}class vt extends st{constructor(a){super(a,a.columns,a.rows)}set(a,s,n){return this.matrix.set(s,a,n),this}get(a,s){return this.matrix.get(s,a)}}class we extends I{constructor(a,s={}){let{rows:n=1}=s;if(a.length%n!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=n,this.columns=a.length/n,this.data=a}set(a,s,n){let o=this._calculateIndex(a,s);return this.data[o]=n,this}get(a,s){let n=this._calculateIndex(a,s);return this.data[n]}_calculateIndex(a,s){return a*this.columns+s}}class rt extends I{constructor(a){super(),this.data=a,this.rows=a.length,this.columns=a[0].length}set(a,s,n){return this.data[a][s]=n,this}get(a,s){return this.data[a][s]}}function ut(p,a){if(r.isAnyArray(p))return p[0]&&r.isAnyArray(p[0])?new rt(p):new we(p,a);throw new Error("the argument is not an array")}class M{constructor(a){a=rt.checkMatrix(a);let s=a.clone(),n=s.rows,o=s.columns,l=new Float64Array(n),w=1,y,E,S,R,x,L,Y,T,C;for(y=0;yMath.abs(T[R])&&(R=y);if(R!==E){for(S=0;S=0;S--){for(E=0;Ew?o.set(l,w,a.get(l,w)):l===w?o.set(l,w,1):o.set(l,w,0);return o}get upperTriangularMatrix(){let a=this.LU,s=a.rows,n=a.columns,o=new X(s,n);for(let l=0;lMath.abs(a)?(s=a/p,Math.abs(p)*Math.sqrt(1+s*s)):a!==0?(s=p/a,Math.abs(a)*Math.sqrt(1+s*s)):0}class je{constructor(a){a=rt.checkMatrix(a);let s=a.clone(),n=a.rows,o=a.columns,l=new Float64Array(o),w,y,E,S;for(E=0;E=0;S--){for(E=0;E=0;y--){for(l=0;l=0;_--)if(T[_]!==0){for(let U=_+1;U=0;_--){if(_0;){let _,U;for(_=it-2;_>=-1&&_!==-1;_--){let H=Number.MIN_VALUE+jt*Math.abs(T[_]+Math.abs(T[_+1]));if(Math.abs(k[_])<=H||Number.isNaN(k[_])){k[_]=0;break}}if(_===it-2)U=4;else{let H;for(H=it-1;H>=_&&H!==_;H--){let W=(H!==it?Math.abs(k[H]):0)+(H!==_+1?Math.abs(k[H-1]):0);if(Math.abs(T[H])<=jt*W){T[H]=0;break}}H===_?U=3:H===it-1?U=1:(U=2,_=H)}switch(_++,U){case 1:{let H=k[it-2];k[it-2]=0;for(let W=it-2;W>=_;W--){let Gt=Zt(T[W],H),Dt=T[W]/Gt,Tt=H/Gt;if(T[W]=Gt,W!==_&&(H=-Tt*k[W-1],k[W-1]=Dt*k[W-1]),S)for(let Ot=0;Ot=T[_+1]);){let H=T[_];if(T[_]=T[_+1],T[_+1]=H,S&&_s&&l.set(R,x,a.get(R,x)/this.s[x]);let w=this.U,y=w.rows,E=w.columns,S=new X(n,y);for(let R=0;Ra&&s++;return s}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return X.diag(this.s)}}function Fe(p,a=!1){return p=rt.checkMatrix(p),a?new ce(p).inverse():ie(p,X.eye(p.rows))}function ie(p,a,s=!1){return p=rt.checkMatrix(p),a=rt.checkMatrix(a),s?new ce(p).solve(a):p.isSquare()?new M(p).solve(a):new je(p).solve(a)}function Se(p){if(p=X.checkMatrix(p),p.isSquare()){if(p.columns===0)return 1;let a,s,n,o;if(p.columns===2)return a=p.get(0,0),s=p.get(0,1),n=p.get(1,0),o=p.get(1,1),a*o-s*n;if(p.columns===3){let l,w,y;return l=new _t(p,[1,2],[1,2]),w=new _t(p,[1,2],[0,2]),y=new _t(p,[1,2],[0,1]),a=p.get(0,0),s=p.get(0,1),n=p.get(0,2),a*Se(l)-s*Se(w)+n*Se(y)}else return new M(p).determinant}else throw Error("determinant can only be calculated for a square matrix")}function br(p,a){let s=[];for(let n=0;no)return new Array(a.rows+1).fill(0);{let l=a.addRow(s,[0]);for(let w=0;wa?l[w]=1/l[w]:l[w]=0;return o.mmul(X.diag(l).mmul(n.transpose()))}function Xe(p,a=p,s={}){p=new X(p);let n=!1;if(typeof a=="object"&&!X.isMatrix(a)&&!r.isAnyArray(a)?(s=a,a=p,n=!0):a=new X(a),p.rows!==a.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:o=!0}=s;o&&(p=p.center("column"),n||(a=a.center("column")));let l=p.transpose().mmul(a);for(let w=0;w0?o.set(l,l+1,s[l]):s[l]<0&&o.set(l,l-1,s[l])}return o}}function sr(p,a,s,n){let o,l,w,y,E,S,R,x;for(E=0;E0;y--){for(x=0,w=0,S=0;S0&&(l=-l),a[y]=x*l,w=w-o*l,s[y-1]=o-l,E=0;ES)do{for(o=s[S],x=(s[S+1]-o)/(2*a[S]),L=Zt(x,1),x<0&&(L=-L),s[S]=a[S]/(x+L),s[S+1]=a[S]*(x+L),Y=s[S+1],l=o-s[S],w=S+2;w=S;w--)for(J=C,C=T,et=K,o=T*a[w],l=T*x,L=Zt(x,a[w]),a[w+1]=K*L,K=a[w]/L,T=x/L,x=T*s[w]-K*o,s[w+1]=l+K*(T*o+K*s[w]),E=0;ELt*lt);s[S]=s[S]+ct,a[S]=0}for(w=0;w=x;S--)s[S]=a.get(S,x-1)/L,E+=s[S]*s[S];for(y=Math.sqrt(E),s[x]>0&&(y=-y),E=E-s[x]*y,s[x]=s[x]-y,R=x;R=x;S--)w+=s[S]*a.get(S,R);for(w=w/E,S=x;S<=l;S++)a.set(S,R,a.get(S,R)-w*s[S])}for(S=0;S<=l;S++){for(w=0,R=l;R>=x;R--)w+=s[R]*a.get(S,R);for(w=w/E,R=x;R<=l;R++)a.set(S,R,a.get(S,R)-w*s[R])}s[x]=L*s[x],a.set(x,x-1,L*y)}}for(S=0;S=o+1;x--)if(a.get(x,x-1)!==0){for(S=x+1;S<=l;S++)s[S]=a.get(S,x-1);for(R=x;R<=l;R++){for(y=0,S=x;S<=l;S++)y+=s[S]*n.get(S,R);for(y=y/s[x]/a.get(x,x-1),S=x;S<=l;S++)n.set(S,R,n.get(S,R)+y*s[S])}}}function Do(p,a,s,n,o){let l=p-1,w=0,y=p-1,E=Number.EPSILON,S=0,R=0,x=0,L=0,Y=0,T=0,C=0,J=0,k,K,et,ct,lt,Lt,it,ht,jt,_,U,H,W,Gt,Dt;for(k=0;ky)&&(s[k]=o.get(k,k),a[k]=0),K=Math.max(k-1,0);K=w;){for(ct=l;ct>w&&(T=Math.abs(o.get(ct-1,ct-1))+Math.abs(o.get(ct,ct)),T===0&&(T=R),!(Math.abs(o.get(ct,ct-1))=0){for(C=x>=0?x+C:x-C,s[l-1]=ht+C,s[l]=s[l-1],C!==0&&(s[l]=ht-it/C),a[l-1]=0,a[l]=0,ht=o.get(l,l-1),T=Math.abs(ht)+Math.abs(C),x=ht/T,L=C/T,Y=Math.sqrt(x*x+L*L),x=x/Y,L=L/Y,K=l-1;K0)){for(T=Math.sqrt(T),jt=ct&&(C=o.get(lt,lt),Y=ht-C,T=jt-C,x=(Y*T-it)/o.get(lt+1,lt)+o.get(lt,lt+1),L=o.get(lt+1,lt+1)-C-Y-T,Y=o.get(lt+2,lt+1),T=Math.abs(x)+Math.abs(L)+Math.abs(Y),x=x/T,L=L/T,Y=Y/T,!(lt===ct||Math.abs(o.get(lt,lt-1))*(Math.abs(L)+Math.abs(Y))lt+2&&o.set(k,k-3,0);for(et=lt;et<=l-1&&(Gt=et!==l-1,et!==lt&&(x=o.get(et,et-1),L=o.get(et+1,et-1),Y=Gt?o.get(et+2,et-1):0,ht=Math.abs(x)+Math.abs(L)+Math.abs(Y),ht!==0&&(x=x/ht,L=L/ht,Y=Y/ht)),ht!==0);et++)if(T=Math.sqrt(x*x+L*L+Y*Y),x<0&&(T=-T),T!==0){for(et!==lt?o.set(et,et-1,-T*ht):ct!==lt&&o.set(et,et-1,-o.get(et,et-1)),x=x+T,ht=x/T,jt=L/T,C=Y/T,L=L/x,Y=Y/x,K=et;K=0;l--)if(x=s[l],L=a[l],L===0)for(ct=l,o.set(l,l,1),k=l-1;k>=0;k--){for(it=o.get(k,k)-x,Y=0,K=ct;K<=l;K++)Y=Y+o.get(k,K)*o.get(K,l);if(a[k]<0)C=it,T=Y;else if(ct=k,a[k]===0?o.set(k,l,it!==0?-Y/it:-Y/(E*R)):(ht=o.get(k,k+1),jt=o.get(k+1,k),L=(s[k]-x)*(s[k]-x)+a[k]*a[k],Lt=(ht*T-C*Y)/L,o.set(k,l,Lt),o.set(k+1,l,Math.abs(ht)>Math.abs(C)?(-Y-it*Lt)/ht:(-T-jt*Lt)/C)),Lt=Math.abs(o.get(k,l)),E*Lt*Lt>1)for(K=k;K<=l;K++)o.set(K,l,o.get(K,l)/Lt)}else if(L<0)for(ct=l-1,Math.abs(o.get(l,l-1))>Math.abs(o.get(l-1,l))?(o.set(l-1,l-1,L/o.get(l,l-1)),o.set(l-1,l,-(o.get(l,l)-x)/o.get(l,l-1))):(Dt=Mr(0,-o.get(l-1,l),o.get(l-1,l-1)-x,L),o.set(l-1,l-1,Dt[0]),o.set(l-1,l,Dt[1])),o.set(l,l-1,0),o.set(l,l,1),k=l-2;k>=0;k--){for(_=0,U=0,K=ct;K<=l;K++)_=_+o.get(k,K)*o.get(K,l-1),U=U+o.get(k,K)*o.get(K,l);if(it=o.get(k,k)-x,a[k]<0)C=it,Y=_,T=U;else if(ct=k,a[k]===0?(Dt=Mr(-_,-U,it,L),o.set(k,l-1,Dt[0]),o.set(k,l,Dt[1])):(ht=o.get(k,k+1),jt=o.get(k+1,k),H=(s[k]-x)*(s[k]-x)+a[k]*a[k]-L*L,W=(s[k]-x)*2*L,H===0&&W===0&&(H=E*R*(Math.abs(it)+Math.abs(L)+Math.abs(ht)+Math.abs(jt)+Math.abs(C))),Dt=Mr(ht*Y-C*_+L*U,ht*T-C*U-L*_,H,W),o.set(k,l-1,Dt[0]),o.set(k,l,Dt[1]),Math.abs(ht)>Math.abs(C)+Math.abs(L)?(o.set(k+1,l-1,(-_-it*o.get(k,l-1)+L*o.get(k,l))/ht),o.set(k+1,l,(-U-it*o.get(k,l)-L*o.get(k,l-1))/ht)):(Dt=Mr(-Y-jt*o.get(k,l-1),-T-jt*o.get(k,l),C,L),o.set(k+1,l-1,Dt[0]),o.set(k+1,l,Dt[1]))),Lt=Math.max(Math.abs(o.get(k,l-1)),Math.abs(o.get(k,l))),E*Lt*Lt>1)for(K=k;K<=l;K++)o.set(K,l-1,o.get(K,l-1)/Lt),o.set(K,l,o.get(K,l)/Lt)}for(k=0;ky)for(K=k;K=w;K--)for(k=w;k<=y;k++){for(C=0,et=w;et<=Math.min(K,y);et++)C=C+n.get(k,et)*o.get(et,K);n.set(k,K,C)}}}function Mr(p,a,s,n){let o,l;return Math.abs(s)>Math.abs(n)?(o=n/s,l=s+o*n,[(p+o*a)/l,(a-o*p)/l]):(o=s/n,l=n+o*s,[(o*p+a)/l,(o*a-p)/l])}class fi{constructor(a){if(a=rt.checkMatrix(a),!a.isSymmetric())throw new Error("Matrix is not symmetric");let s=a,n=s.rows,o=new X(n,n),l=!0,w,y,E;for(y=0;y0),o.set(y,y,Math.sqrt(Math.max(S,0))),E=y+1;E=0;E--)for(y=0;yw;Y++)x=a.transpose().mmul(y).div(y.transpose().mmul(y).get(0,0)),x=x.div(x.norm()),S=a.mmul(x).div(x.transpose().mmul(x).get(0,0)),Y>0&&(E=S.clone().sub(L).pow(2).sum()),L=S.clone(),n?(R=n.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),R=R.div(R.norm()),y=n.mmul(R).div(R.transpose().mmul(R).get(0,0))):y=S;if(n){let Y=a.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0));Y=Y.div(Y.norm());let T=a.clone().sub(S.clone().mmul(Y.transpose())),C=y.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),J=n.clone().sub(S.clone().mulS(C.get(0,0)).mmul(R.transpose()));this.t=S,this.p=Y.transpose(),this.w=x.transpose(),this.q=R,this.u=y,this.s=S.transpose().mmul(S),this.xResidual=T,this.yResidual=J,this.betas=C}else this.w=x.transpose(),this.s=S.transpose().mmul(S).sqrt(),o?this.t=S.clone().div(this.s.get(0,0)):this.t=S,this.xResidual=a.sub(S.mmul(x.transpose()))}}return pt.AbstractMatrix=I,pt.CHO=fi,pt.CholeskyDecomposition=fi,pt.DistanceMatrix=qt,pt.EVD=Ae,pt.EigenvalueDecomposition=Ae,pt.LU=M,pt.LuDecomposition=M,pt.Matrix=X,pt.MatrixColumnSelectionView=pe,pt.MatrixColumnView=mr,pt.MatrixFlipColumnView=Dn,pt.MatrixFlipRowView=Ye,pt.MatrixRowSelectionView=tr,pt.MatrixRowView=In,pt.MatrixSelectionView=_t,pt.MatrixSubView=Et,pt.MatrixTransposeView=vt,pt.NIPALS=di,pt.Nipals=di,pt.QR=je,pt.QrDecomposition=je,pt.SVD=ce,pt.SingularValueDecomposition=ce,pt.SymmetricMatrix=ae,pt.WrapperMatrix1D=we,pt.WrapperMatrix2D=rt,pt.correlation=ir,pt.covariance=Xe,pt.default=X,pt.determinant=Se,pt.inverse=Fe,pt.linearDependencies=rr,pt.pseudoInverse=nr,pt.solve=ie,pt.wrap=ut,pt}var $r=uo(),Hn=eo($r);var ti=$r.Matrix,ho=$r.SingularValueDecomposition;Hn.Matrix?Hn.Matrix:$r.Matrix;var dn=(r,t)=>{let e=r.nodeCount(),i=Array.from({length:e},()=>[]),u={},h=0;return r.forEachNode(c=>{u[c.id]=h++}),r.forEachEdge(c=>{let f=u[c.source],g=u[c.target];f==null||g==null||(i[f].push(g),t||i[g].push(f))}),i},ao=(r,t)=>{let e=r.length,i=new Array(e);for(let u=0;unew Array(t).fill(1/0));for(let i=0;i0&&(this.data[0]=e,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let e=this.data;for(;t>0;){let i=t-1>>1;if(e[i][0]<=e[t][0])break;[e[i],e[t]]=[e[t],e[i]],t=i}}bubbleDown(t){let e=this.data,i=e.length;for(;;){let u=t*2+1,h=t*2+2,c=t;if(u{let b=f[g++];d.x=b[0]+e[0],d.y=b[1]+e[1]})})}},da=r=>{let t=Number.NEGATIVE_INFINITY,e=[],i=r.length;for(let u=0;u{try{let i=r.length,u=new ti(i,i);for(let D=0;D{let e=Object.assign(Object.assign({},co),t),{maxIteration:i,width:u,k:h,speed:c=co.speed,strictRadial:f,focusNode:g,radiiMap:d,nodeSizeFunc:b}=e,m=h*.002,v=new Map,D=u/10;for(let $=0;${v.set(q.id,{x:0,y:0})}),ga(r,v,h,d,b),!(pa(r,v,c,f,g,D,d){let h=0;r.forEachNode(c=>{let f=0;r.forEachNode(g=>{if(f<=h){f++;return}if(c.id===g.id||i.get(c.id)!==i.get(g.id))return;let d=c.x-g.x,b=c.y-g.y,m=Math.sqrt(d*d+b*b);if(m===0){m=1;let $=h>f?1:-1;d=.01*$,b=.01*$}let v=Math.max(...u(c._original)),D=Math.max(...u(g._original));if(m{i&&r.forEachNode(d=>{let b=d.x-u.x,m=d.y-u.y,v=Math.sqrt(b*b+m*m),D=m/v,$=-b/v,P=t.get(d.id),q=Math.sqrt(P.x*P.x+P.y*P.y),B=Math.acos((D*P.x+$*P.y)/q);B>Math.PI/2&&(B-=Math.PI/2,D*=-1,$*=-1);let G=Math.cos(B)*q;t.set(d.id,{x:D*G,y:$*G})});let f=0,g=0;return r.forEachNode(d=>{if(d.id===u.id)return;let b=t.get(d.id),m=Math.sqrt(b.x*b.x+b.y*b.y);if(m>0){let v=Math.min(h*(e/800),m);if(d.x+=b.x/m*v,d.y+=b.y/m*v,i){let D=d.x-u.x,$=d.y-u.y,P=Math.sqrt(D*D+$*$);D=D/P*c.get(d.id),$=$/P*c.get(d.id),d.x=u.x+D,d.y=u.y+$}f+=v,g++}}),g>0?f/g:0};var He={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},wn=class extends We{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return He}layout(){return Ee(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=wr(this.options),u=this.model.nodeCount();if(!u||u===1)return pr(this.model,i);let{focusNode:h,linkDistance:c=He.linkDistance,maxIteration:f=He.maxIteration,maxPreventOverlapIteration:g=He.maxPreventOverlapIteration,nodeSize:d,nodeSpacing:b,preventOverlap:m,sortBy:v,sortStrength:D=He.sortStrength,strictRadial:$,unitRadius:P}=this.options,q=h&&this.model.node(h)||this.model.firstNode(),B=this.model.nodeIndexOf(q.id),G=dn(this.model,!1),F=gn(G),V=ba(F,B);ma(F,B,V+1);let z=F[B],ot=(t-i[0]>i[0]?i[0]:t-i[0])||t/2,O=(e-i[1]>i[1]?i[1]:e-i[1])||e/2,N=Math.min(ot,O),A=Math.max(...z),nt=[],dt=new Map,wt=P??N/A;z.forEach((gt,j)=>{let he=gt*wt;nt.push(he),dt.set(this.model.nodeAt(j).id,he)});let Pt=wa(this.model,F,c,nt,wt,v,D),yt=ni(Pt,2,c),Qt=yt[B],ue=0;if(this.model.forEachNode(gt=>{let j=yt[ue];gt.x=j[0]-Qt[0],gt.y=j[1]-Qt[1],ue++}),this.run(f,Pt,nt,B),this.model.forEachNode(gt=>{gt.x+=i[0],gt.y+=i[1]}),m){let j={nodeSizeFunc:tn(d,b,He.nodeSize,He.nodeSpacing),radiiMap:dt,width:t,strictRadial:!!$,focusNode:q,maxIteration:g,k:u/4.5};lo(this.model,j)}})}run(t,e,i,u){let h=ya(e),c=this.model.nodeCount(),f=this.model.nodes(),g=new Float64Array(c),d=new Float64Array(c);for(let b=0;b{let f=t.length,g=new Array(f),d=new Array(f);for(let $=0;${let t=r.length,e=r[0].length,i=[];for(let u=0;u{let i=r.length;for(let u=0;u{let e=r[t],i=0;for(let u=0;uyr,BubbleSets:()=>xn,Circle:()=>Or,Line:()=>Xt,PointPath:()=>Ge,Rectangle:()=>oe,addPadding:()=>ai,boundingBox:()=>yo,calculatePotentialOutline:()=>vo,calculateVirtualEdges:()=>bo,circle:()=>Ia,createGenericInfluenceArea:()=>ci,createLineInfluenceArea:()=>si,createOutline:()=>Fa,createRectangleInfluenceArea:()=>mo,default:()=>xn,defaultOptions:()=>li,line:()=>_a,lineBoundingBox:()=>hi,point:()=>$t,rect:()=>Da,unionBoundingBox:()=>So});function ui(r,t,e,i,u,h){let c=r,f=t,g=e-c,d=i-f,b=u-c,m=h-f,v=b*g+m*d,D=0;v<=0?D=0:(b=g-b,m=d-m,v=b*g+m*d,v<=0?D=0:D=v*v/(g*g+d*d));let $=b*b+m*m-D;return $<0?0:$}function Ke(r,t,e,i){return(r-e)*(r-e)+(t-i)*(t-i)}function fo(r,t,e,i,u){return Ke(r,t,e,i)e;if(r===0)return Math.round;let t=Math.pow(10,r);return e=>Math.round(e*t)/t}function hi(r){let t=Math.min(r.x1,r.x2),e=Math.max(r.x1,r.x2),i=Math.min(r.y1,r.y2),u=Math.max(r.y1,r.y2);return{x:t,y:i,x2:e,y2:u,width:e-t,height:u-i}}var Xt=class r{constructor(t,e,i,u){this.x1=t,this.y1=e,this.x2=i,this.y2=u}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new r(t.x1,t.y1,t.x2,t.y2)}cuts(t,e){if(this.y1===this.y2||ethis.y1&&e>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+i)return!1}else if(tthis.x1+i)return!1;if(this.y1this.y2+i)return!1}else if(ethis.y1+i)return!1;return!0}},zt;(function(r){r[r.POINT=1]="POINT",r[r.PARALLEL=2]="PARALLEL",r[r.COINCIDENT=3]="COINCIDENT",r[r.NONE=4]="NONE"})(zt||(zt={}));var Lr=class{constructor(t,e=0,i=0){this.state=t,this.x=e,this.y=i}};function yn(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;return 0<=h&&h<=1&&0<=c&&c<=1?new Lr(zt.POINT,r.x1+h*(r.x2-r.x1),r.y1+h*(r.y2-r.y1)):new Lr(zt.NONE)}return new Lr(e===0||i===0?zt.COINCIDENT:zt.PARALLEL)}function po(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;if(0<=h&&h<=1&&0<=c&&c<=1)return h}return Number.POSITIVE_INFINITY}function va(r,t){function e(u,h,c,f){let g=po(t,new Xt(u,h,c,f));return g=Math.abs(g-.5),g>=0&&g<=1?1:0}let i=e(r.x,r.y,r.x2,r.y);return i+=e(r.x,r.y,r.x,r.y2),i>1||(i+=e(r.x,r.y2,r.x2,r.y2),i>1)?!0:(i+=e(r.x2,r.y,r.x2,r.y2),i>0)}var Ut;(function(r){r[r.LEFT=0]="LEFT",r[r.TOP=1]="TOP",r[r.RIGHT=2]="RIGHT",r[r.BOTTOM=3]="BOTTOM"})(Ut||(Ut={}));function Sn(r,t,e){let i=new Set;return r.width<=0?(i.add(Ut.LEFT),i.add(Ut.RIGHT)):tr.x+r.width&&i.add(Ut.RIGHT),r.height<=0?(i.add(Ut.TOP),i.add(Ut.BOTTOM)):er.y+r.height&&i.add(Ut.BOTTOM),i}function wo(r,t){let e=t.x1,i=t.y1,u=t.x2,h=t.y2,c=Array.from(Sn(r,u,h));if(c.length===0)return!0;let f=Sn(r,e,i);for(;f.size!==0;){for(let g of c)if(f.has(g))return!1;if(f.has(Ut.RIGHT)||f.has(Ut.LEFT)){let g=r.x;f.has(Ut.RIGHT)&&(g+=r.width),i=i+(g-e)*(h-i)/(u-e),e=g}else{let g=r.y;f.has(Ut.BOTTOM)&&(g+=r.height),e=e+(g-i)*(u-e)/(h-i),i=g}f=Sn(r,e,i)}return!0}function Sa(r,t){let e=Number.POSITIVE_INFINITY,i=0;function u(h,c,f,g){let d=po(t,new Xt(h,c,f,g));d=Math.abs(d-.5),d>=0&&d<=1&&(i++,d1||(u(r.x,r.y2,r.x2,r.y2),i>1)?e:(u(r.x2,r.y,r.x2,r.y2),i===0?-1:e)}function xa(r,t){let e=0,i=yn(r,new Xt(t.x,t.y,t.x2,t.y));e+=i.state===zt.POINT?1:0;let u=yn(r,new Xt(t.x,t.y,t.x,t.y2));e+=u.state===zt.POINT?1:0;let h=yn(r,new Xt(t.x,t.y2,t.x2,t.y2));e+=h.state===zt.POINT?1:0;let c=yn(r,new Xt(t.x2,t.y,t.x2,t.y2));return e+=c.state===zt.POINT?1:0,{top:i,left:u,bottom:h,right:c,count:e}}var oe=class r{constructor(t,e,i,u){this.x=t,this.y=e,this.width=i,this.height=u}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new r(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new r(this.x,this.y,this.width,this.height)}add(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x+t.width),h=Math.max(this.y2,t.y+t.height);this.x=e,this.y=i,this.width=u-e,this.height=h-i}addPoint(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x),h=Math.max(this.y2,t.y);this.x=e,this.y=i,this.width=u-e,this.height=h-i}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let e=this.scaleX(t.x),i=this.scaleY(t.y),u=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),h=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),c=u-e,f=h-i;return new oe(e,i,c,f)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){let i=Math.ceil(e/this.pixelGroup),u=this.boundX(t.x-i),h=this.boundY(t.y-i),c=this.boundX(t.x2+i),f=this.boundY(t.y2+i),g=c-u,d=f-h;return new oe(u,h,g,d)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=i)}set(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=i)}incArea(t,e){if(t.width<=0||t.height<=0||e===0)return;let i=this.width,u=t.width,h=Math.max(0,t.i),c=Math.max(0,t.j),f=Math.min(t.i+t.width,i),g=Math.min(t.j+t.height,this.height);if(!(g<=0||f<=0||h>=i||g>=this.height))for(let d=c;dMath.min(c,f),Number.POSITIVE_INFINITY),u=this.area.reduce((c,f)=>Math.max(c,f),Number.NEGATIVE_INFINITY),h=c=>(c-i)/(u-i);t.scale(this.pixelGroup,this.pixelGroup);for(let c=0;ce?"black":"white",t.fillRect(u,h,1,1)}t.restore()}}};function ai(r,t){let e=i=>({x:i.x-t,y:i.y-t,width:i.width+2*t,height:i.height+2*t});return Array.isArray(r)?r.map(e):e(r)}function si(r,t,e){return ci(Object.assign(hi(r),{distSquare:(i,u)=>ui(r.x1,r.y1,r.x2,r.y2,i,u)}),t,e)}function ci(r,t,e){let i=ai(r,e),u=t.scale(i),h=t.createSub(u,i);return ka(h,t,e,(c,f)=>r.distSquare(c,f)),h}function ka(r,t,e,i){let u=e*e;for(let h=0;h{let f=u.slice(0,c);return Ra(t,h,f,e,i)}).flat()}function Ra(r,t,e,i,u){let h=$t(t.cx,t.cy),c=$a(h,e,r);if(c==null)return[];let f=new Xt(h.x,h.y,c.cx,c.cy),g=ja(f,r,i,u);return Aa(g,r)}function ja(r,t,e,i){let u=[],h=[];h.push(r);let c=!0;for(let f=0;f0;){let g=h.pop(),d=Eo(t,g),b=d?xa(g,d):null;if(!d||!b||b.count!==2){c||u.push(g);continue}let m=i,v=bn(d,m,b,!0),D=Be(v,h)||Be(v,u),$=mn(v,t);for(;!D&&$&&m>=1;)m/=1.5,v=bn(d,m,b,!0),D=Be(v,h)||Be(v,u),$=mn(v,t);if(v&&!D&&!$&&(h.push(new Xt(g.x1,g.y1,v.x,v.y)),h.push(new Xt(v.x,v.y,g.x2,g.y2)),c=!0),c)continue;m=i,v=bn(d,m,b,!1);let P=Be(v,h)||Be(v,u);for($=mn(v,t);!P&&$&&m>=1;)m/=1.5,v=bn(d,m,b,!1),P=Be(v,h)||Be(v,u),$=mn(v,t);v&&!P&&(h.push(new Xt(g.x1,g.y1,v.x,v.y)),h.push(new Xt(v.x,v.y,g.x2,g.y2)),c=!0),c||u.push(g)}for(;h.length>0;)u.push(h.pop());return u}function Aa(r,t){let e=[];for(;r.length>0;){let i=r.pop();if(r.length===0){e.push(i);break}let u=r.pop(),h=new Xt(i.x1,i.y1,u.x2,u.y2);Eo(t,h)?(e.push(i),r.push(u)):r.push(h)}return e}function $a(r,t,e){let i=Number.POSITIVE_INFINITY;return t.reduce((u,h)=>{let c=Ke(r.x,r.y,h.cx,h.cy);if(c>i)return u;let f=new Xt(r.x,r.y,h.cx,h.cy),g=La(e,f);return c*(g+1)*(g+1){t+=i.cx,e+=i.cy}),t/=r.length,e/=r.length,r.map(i=>{let u=t-i.cx,h=e-i.cy,c=u*u+h*h;return[i,c]}).sort((i,u)=>i[1]-u[1]).map(i=>i[0])}function mn(r,t){return t.some(e=>e.containsPt(r.x,r.y))}function Be(r,t){return t.some(e=>!!(fo(e.x1,e.y1,r.x,r.y,.001)||fo(e.x2,e.y2,r.x,r.y,.001)))}function Eo(r,t){let e=Number.POSITIVE_INFINITY,i=null;for(let u of r){if(!wo(u,t))continue;let h=Sa(u,t);h>=0&&hwo(i,t)&&va(i,t)?e+1:e,0)}function bn(r,t,e,i){let u=e.top,h=e.left,c=e.bottom,f=e.right;if(i){if(h.state===zt.POINT){if(u.state===zt.POINT)return $t(r.x-t,r.y-t);if(c.state===zt.POINT)return $t(r.x-t,r.y2+t);let v=r.width*r.height;return r.width*((h.y-r.y+(f.y-r.y))*.5)f.y?$t(r.x-t,r.y-t):$t(r.x2+t,r.y-t):h.yc.x?$t(r.x-t,r.y-t):$t(r.x-t,r.y2+t):u.xf.y?$t(r.x2+t,r.y2+t):$t(r.x-t,r.y2+t):h.yc.x?$t(r.x2+t,r.y2+t):$t(r.x2+t,r.y-t):u.xi)return!1}return!0}function Oa(r=0){return t=>{if(r<0||t.length<3)return t;let e=[],i=0,u=r*r;for(;i{if(c.length<3)return c;let f=[],g=c.closed,d=c.length+3-1+(g?0:2);f.push(h(c,2-(g?0:2),0));for(let b=2-(g?0:2);b{let e=r,i=t.length;if(e>1)for(i=Math.floor(t.length/e);i<3&&e>1;)e-=1,i=Math.floor(t.length/e);let u=[];for(let h=0,c=0;c=i?this.closed?this.get(t-i):this.points[i-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){let e=this.points;if(e.length===0)return"";let i=typeof t=="function"?t:Ea(t),u="M";for(let h of e)u+=`${i(h.x)},${i(h.y)} L`;return u=u.slice(0,-1),this.closed&&(u+=" Z"),u}draw(t){let e=this.points;if(e.length!==0){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let i of e)t.lineTo(i.x,i.y);this.closed&&t.closePath()}}sample(t){return Pa(t)(this)}simplify(t){return Oa(t)(this)}bSplines(t){return Ca(t)(this)}apply(t){return t(this)}containsElements(t){let e=yo(this.points);return e?t.every(i=>e.containsPt(i.cx,i.cy)&&this.withinArea(i.cx,i.cy)):!1}withinArea(t,e){if(this.length===0)return!1;let i=0,u=this.points[0],h=new Xt(u.x,u.y,u.x,u.y);for(let c=1;ct?b+m:b}function h(g,d){let b=Tr;return b=u(g,d,b,1),b=u(g+1,d,b,2),b=u(g,d+1,b,4),b=u(g+1,d+1,b,8),Number.isNaN(b)?-1:b}let c=En;function f(g,d){let b=g,m=d,v=r.invertScaleX(b),D=r.invertScaleY(m);for(let $=0;$go(i.raw,t));return e<0?!1:(this.members.splice(e,1),this.dirty.add(Re.MEMBERS),!0)}removeNonMember(t){let e=this.nonMembers.findIndex(i=>go(i.raw,t));return e<0?!1:(this.nonMembers.splice(e,1),this.dirty.add(Re.NON_MEMBERS),!0)}removeEdge(t){let e=this.edges.findIndex(i=>i.obj.equals(t));return e<0?!1:(this.edges.splice(e,1),this.dirty.add(Re.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(Re.NON_MEMBERS);for(let e of t)this.nonMembers.push({raw:e,obj:Gr(e)?Or.from(e):oe.from(e),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(Re.EDGES);for(let e of t)this.edges.push({raw:e,obj:Xt.from(e),area:null})}}update(){let t=this.dirty.has(Re.MEMBERS),e=this.dirty.has(Re.NON_MEMBERS),i=this.dirty.has(Re.EDGES);this.dirty.clear();let u=this.members.map(d=>d.obj);if(this.o.virtualEdges&&(t||e)){let d=this.nonMembers.map(v=>v.obj),b=bo(u,d,this.o.maxRoutingIterations,this.o.morphBuffer),m=new Map(this.virtualEdges.map(v=>[v.obj.toString(),v.area]));this.virtualEdges=b.map(v=>{var D;return{raw:v,obj:v,area:(D=m.get(v.toString()))!==null&&D!==void 0?D:null}}),i=!0}let h=!1;if(t||i){let d=this.virtualEdges.concat(this.edges).map(D=>D.obj),b=So(u,d),m=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,v=oe.from(ai(b,m));v.equals(this.activeRegion)||(h=!0,this.activeRegion=v)}if(h){let d=Math.ceil(this.activeRegion.width/this.o.pixelGroup),b=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=yr.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(m=>m.area=null),this.nonMembers.forEach(m=>m.area=null),this.edges.forEach(m=>m.area=null),this.virtualEdges.forEach(m=>m.area=null)):(d!==this.potentialArea.width||b!==this.potentialArea.height)&&(this.potentialArea=yr.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let c=new Map,f=d=>{if(d.area){let b=`${d.obj.width}x${d.obj.height}x${d.obj instanceof oe?"R":"C"}`;c.set(b,d.area)}},g=d=>{if(d.area)return;let b=`${d.obj.width}x${d.obj.height}x${d.obj instanceof oe?"R":"C"}`;if(c.has(b)){let v=c.get(b);d.area=this.potentialArea.copy(v,{x:d.obj.x-this.o.nodeR1,y:d.obj.y-this.o.nodeR1});return}let m=d.obj instanceof oe?mo(d.obj,this.potentialArea,this.o.nodeR1):ci(d.obj,this.potentialArea,this.o.nodeR1);d.area=m,c.set(b,m)};this.members.forEach(f),this.nonMembers.forEach(f),this.members.forEach(g),this.nonMembers.forEach(d=>{this.activeRegion.intersects(d.obj)?g(d):d.area=null}),this.edges.forEach(d=>{d.area||(d.area=si(d.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(d=>{d.area||(d.area=si(d.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let e of this.members)e.obj.draw(t)}drawNonMembers(t){for(let e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(let e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(this.members.length===0)return new Ge([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:e}=this,i=this.members.map(f=>f.area),u=this.virtualEdges.concat(this.edges).map(f=>f.area),h=this.nonMembers.filter(f=>f.area!=null).map(f=>f.area),c=this.members.map(f=>f.obj);return vo(e,i,u,h,f=>f.containsElements(c),t)}};function vo(r,t,e,i,u,h={}){let c=Object.assign({},li,h),f=c.threshold,g=c.memberInfluenceFactor,d=c.edgeInfluenceFactor,b=c.nonMemberInfluenceFactor,m=(c.nodeR0-c.nodeR1)*(c.nodeR0-c.nodeR1),v=(c.edgeR0-c.edgeR1)*(c.edgeR0-c.edgeR1);for(let D=0;D0)b*=.8;else break}return new Ge([])}function So(r,t){if(r.length===0)return new oe(0,0,0,0);let e=oe.from(r[0]);for(let i of r)e.add(i);for(let i of t)e.add(hi(i));return e}function Fa(r,t=[],e=[],i={}){if(r.length===0)return new Ge([]);let u=new xn(i);return u.pushMember(...r),u.pushNonMember(...t),u.pushEdge(...e),u.compute()}var export_FA2Layout=Ua.default;var export_circlepack=kn.circlepack;var export_circular=kn.circular;var export_forceAtlas2=za.default;var export_random=kn.random;var export_rotation=kn.rotation;export{ln as ConcentricLayout,export_FA2Layout as FA2Layout,At as Graph,pn as MDSLayout,wn as RadialLayout,xo as bubblesets,export_circlepack as circlepack,export_circular as circular,export_forceAtlas2 as forceAtlas2,export_random as random,export_rotation as rotation}; /*! Bundled license information: comlink/dist/esm/comlink.js: diff --git a/src/package/vendor_entry_graphology.mjs b/src/package/vendor_entry_graphology.mjs index 84a93b0..2c7d288 100644 --- a/src/package/vendor_entry_graphology.mjs +++ b/src/package/vendor_entry_graphology.mjs @@ -6,5 +6,8 @@ export {default as Graph} from 'graphology'; export {circular, random, circlepack, rotation} from 'graphology-layout'; export {default as forceAtlas2} from 'graphology-layout-forceatlas2'; +// Worker supervisor (live FA2 animation). Node-safe at module scope: it only +// touches Worker/window.URL when instantiated, never at import time. +export {default as FA2Layout} from 'graphology-layout-forceatlas2/worker'; export {RadialLayout, ConcentricLayout, MDSLayout} from '@antv/layout'; export * as bubblesets from 'bubblesets-js'; diff --git a/tests/layout-algorithms.test.js b/tests/layout-algorithms.test.js index 3b03121..0e44628 100644 --- a/tests/layout-algorithms.test.js +++ b/tests/layout-algorithms.test.js @@ -1,5 +1,5 @@ -import { describe, it, expect } from "vitest"; -import { Graph } from "../src/lib/graphology.bundle.mjs"; +import { describe, it, expect, vi, afterEach } from "vitest"; +import { Graph, forceAtlas2 } from "../src/lib/graphology.bundle.mjs"; import { executeLayout } from "../src/graph/layout_algorithms.js"; import { DEFAULTS } from "../src/config.js"; @@ -157,6 +157,126 @@ describe("executeLayout — concentric", () => { }); }); +describe("executeLayout — force worker supervisor (browser path)", () => { + // Star graph order 12 → budget = min(5000, 500 + 12*2) = 524 ms. + const STAR_BUDGET_MS = 524; + + /** Fake FA2Layout recording lifecycle calls; never touches Worker. */ + function makeFakeSupervisor(calls, { startThrows = false } = {}) { + return class FakeSupervisor { + constructor(_graph, params) { + calls.push(["construct", params]); + } + start() { + calls.push(["start"]); + if (startThrows) throw new Error("start failed"); + } + stop() { + calls.push(["stop"]); + } + kill() { + calls.push(["kill"]); + } + }; + } + + afterEach(() => { + vi.useRealTimers(); + }); + + it("node fallback: without Worker and without override, force runs synchronously", async () => { + // Arrange: vitest runs under node — no Worker global. + expect(typeof Worker).toBe("undefined"); + const graph = starGraph(); + const before = positions(graph); + + // Act: fake timers prove the sync path schedules no animation window. + vi.useFakeTimers(); + await executeLayout(graph, specFor("force")); + + // Assert: positions moved without any timer ever firing. + expect(vi.getTimerCount()).toBe(0); + const after = positions(graph); + const moved = after.filter((p, i) => distance(p, before[i]) > 0); + expect(moved.length).toBeGreaterThan(0); + }); + + it("worker path: constructs supervisor with inferred settings, start→stop→kill, resolves after budget", async () => { + // Arrange + vi.useFakeTimers(); + const graph = starGraph(); + const calls = []; + const FakeSupervisor = makeFakeSupervisor(calls); + + // Act + const pending = executeLayout(graph, specFor("force"), { ForceSupervisor: FakeSupervisor }); + await vi.advanceTimersByTimeAsync(STAR_BUDGET_MS); + await pending; + + // Assert: full lifecycle, in order, with FA2 settings passed through. + expect(calls.map(([name]) => name)).toEqual(["construct", "start", "stop", "kill"]); + expect(calls[0][1].settings).toEqual(forceAtlas2.inferSettings(graph)); + }); + + it("worker path: stop and kill still run when start throws", async () => { + // Arrange + const graph = starGraph(); + const calls = []; + const FakeSupervisor = makeFakeSupervisor(calls, { startThrows: true }); + + // Act + Assert + await expect( + executeLayout(graph, specFor("force"), { ForceSupervisor: FakeSupervisor }), + ).rejects.toThrow("start failed"); + expect(calls.map(([name]) => name)).toEqual(["construct", "start", "stop", "kill"]); + }); + + it("double-run guard: re-entrant force on the same graph is a no-op while animating", async () => { + // Arrange + vi.useFakeTimers(); + const graph = starGraph(); + const calls = []; + const FakeSupervisor = makeFakeSupervisor(calls); + + // Act: second call lands while the first animation window is open. + const first = executeLayout(graph, specFor("force"), { ForceSupervisor: FakeSupervisor }); + const second = executeLayout(graph, specFor("force"), { ForceSupervisor: FakeSupervisor }); + await second; // resolves immediately — no second supervisor + await vi.advanceTimersByTimeAsync(STAR_BUDGET_MS); + await first; + + // Assert: only one supervisor was ever constructed; guard released after. + expect(calls.filter(([name]) => name === "construct")).toHaveLength(1); + const rerun = executeLayout(graph, specFor("force"), { ForceSupervisor: FakeSupervisor }); + await vi.advanceTimersByTimeAsync(STAR_BUDGET_MS); + await rerun; + expect(calls.filter(([name]) => name === "construct")).toHaveLength(2); + }); + + it("guard is released when the supervisor constructor throws", async () => { + // Arrange + const graph = starGraph(); + class ThrowingSupervisor { + constructor() { + throw new Error("no worker"); + } + } + + // Act + Assert: rejection does not leave the graph marked as animating. + await expect( + executeLayout(graph, specFor("force"), { ForceSupervisor: ThrowingSupervisor }), + ).rejects.toThrow("no worker"); + vi.useFakeTimers(); + const calls = []; + const pending = executeLayout(graph, specFor("force"), { + ForceSupervisor: makeFakeSupervisor(calls), + }); + await vi.advanceTimersByTimeAsync(STAR_BUDGET_MS); + await pending; + expect(calls.map(([name]) => name)).toEqual(["construct", "start", "stop", "kill"]); + }); +}); + describe("executeLayout — edge cases", () => { it.each(LAYOUT_TYPES)("%s: empty graph is a no-op", async (type) => { // Arrange From bd51a3b3479151662bff02cc0d89fc771123332e Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 07:50:45 +0200 Subject: [PATCH 14/69] feat(metrics): replace hand-rolled centralities with graphology-metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add graphology-metrics@2.4.0 to the node-safe graphology vendor bundle - build a temp undirected multigraph from the visible subgraph and run library betweenness/closeness/eigenvector/pagerank/degree on it; result contract (scores/nodeValues/graphLevelMetrics/popups) preserved - value fixes vs hand-rolled: eigenvector now truly converges on bipartite graphs ((I+A)x iteration), Graph Density genuinely computed, n<=2 betweenness no longer NaN - new graph-level metrics: density (degree panel), diameter (closeness panel, '∞ (disconnected)' when infinite) - eigenvector non-convergence caught and surfaced via ui.error; loading overlay protected by try/finally in updateMetricUI/ensureMetricValues - review fixes: uniform n<=1 early exit in all five calculators, max||1 guard against '(NaN %)' score texts, self-loop degree semantics pinned - metrics.js 963→~800 LOC; tests/metrics.test.js 30→58 tests (846 total green); perf gates green --- package-lock.json | 51 +++ package.json | 1 + src/lib/graphology.bundle.mjs | 10 +- src/managers/metrics.js | 542 +++++++++--------------- src/package/vendor_entry_graphology.mjs | 9 + src/package/vendor_libs.js | 2 +- tests/metrics.test.js | 265 +++++++++++- 7 files changed, 516 insertions(+), 364 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5f6c9c..6189ae2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "graphology": "^0.26.0", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-metrics": "^2.4.0", "marked": "^18.0.2", "sigma": "^3.0.3" }, @@ -2391,6 +2392,12 @@ "node": ">=10.0.0" } }, + "node_modules/@yomguithereal/helpers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz", + "integrity": "sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==", + "license": "MIT" + }, "node_modules/7zip-bin": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", @@ -5329,6 +5336,19 @@ "graphology-types": ">=0.24.0" } }, + "node_modules/graphology-indices": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz", + "integrity": "sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.4.2", + "mnemonist": "^0.39.0" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, "node_modules/graphology-layout": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/graphology-layout/-/graphology-layout-0.6.1.tgz", @@ -5354,6 +5374,37 @@ "graphology-types": ">=0.19.0" } }, + "node_modules/graphology-metrics": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/graphology-metrics/-/graphology-metrics-2.4.0.tgz", + "integrity": "sha512-7WOfOP+mFLCaTJx55Qg4eY+211vr1/b3D/R3biz3SXGhAaCVcWYkfabnmO4O4WBNWANEHtVnFrGgJ0kj6MM6xw==", + "license": "MIT", + "dependencies": { + "graphology-indices": "^0.17.0", + "graphology-shortest-path": "^2.0.0", + "graphology-utils": "^2.4.4", + "mnemonist": "^0.39.0", + "pandemonium": "2.4.1" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, + "node_modules/graphology-shortest-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/graphology-shortest-path/-/graphology-shortest-path-2.1.0.tgz", + "integrity": "sha512-KbT9CTkP/u72vGEJzyRr24xFC7usI9Es3LMmCPHGwQ1KTsoZjxwA9lMKxfU0syvT/w+7fZUdB/Hu2wWYcJBm6Q==", + "license": "MIT", + "dependencies": { + "@yomguithereal/helpers": "^1.1.1", + "graphology-indices": "^0.17.0", + "graphology-utils": "^2.4.3", + "mnemonist": "^0.39.0" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, "node_modules/graphology-types": { "version": "0.24.8", "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz", diff --git a/package.json b/package.json index 218e8d3..459e71f 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "graphology": "^0.26.0", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-metrics": "^2.4.0", "marked": "^18.0.2", "sigma": "^3.0.3" } diff --git a/src/lib/graphology.bundle.mjs b/src/lib/graphology.bundle.mjs index 2b82936..13f80e5 100644 --- a/src/lib/graphology.bundle.mjs +++ b/src/lib/graphology.bundle.mjs @@ -1,12 +1,12 @@ -var Oo=Object.create;var Nr=Object.defineProperty;var Mo=Object.getOwnPropertyDescriptor;var Co=Object.getOwnPropertyNames;var Po=Object.getPrototypeOf,No=Object.prototype.hasOwnProperty;var gi=r=>{throw TypeError(r)};var Fo=(r,t,e)=>t in r?Nr(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var te=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports),_n=(r,t)=>{for(var e in t)Nr(r,e,{get:t[e],enumerable:!0})},zo=(r,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of Co(t))!No.call(r,u)&&u!==e&&Nr(r,u,{get:()=>t[u],enumerable:!(i=Mo(t,u))||i.enumerable});return r};var Fr=(r,t,e)=>(e=r!=null?Oo(Po(r)):{},zo(t||!r||!r.__esModule?Nr(e,"default",{value:r,enumerable:!0}):e,r));var pi=(r,t,e)=>Fo(r,typeof t!="symbol"?t+"":t,e),Rn=(r,t,e)=>t.has(r)||gi("Cannot "+e);var ke=(r,t,e)=>(Rn(r,t,"read from private field"),e?e.call(r):t.get(r)),jn=(r,t,e)=>t.has(r)?gi("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),zr=(r,t,e,i)=>(Rn(r,t,"write to private field"),i?i.call(r,e):t.set(r,e),e),An=(r,t,e)=>(Rn(r,t,"access private method"),e);var Ii=te((Wa,$n)=>{"use strict";var ur=typeof Reflect=="object"?Reflect:null,wi=ur&&typeof ur.apply=="function"?ur.apply:function(t,e,i){return Function.prototype.apply.call(t,e,i)},Ur;ur&&typeof ur.ownKeys=="function"?Ur=ur.ownKeys:Object.getOwnPropertySymbols?Ur=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:Ur=function(t){return Object.getOwnPropertyNames(t)};function Uo(r){console&&console.warn&&console.warn(r)}var mi=Number.isNaN||function(t){return t!==t};function Rt(){Rt.init.call(this)}$n.exports=Rt;$n.exports.once=Bo;Rt.EventEmitter=Rt;Rt.prototype._events=void 0;Rt.prototype._eventsCount=0;Rt.prototype._maxListeners=void 0;var yi=10;function qr(r){if(typeof r!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof r)}Object.defineProperty(Rt,"defaultMaxListeners",{enumerable:!0,get:function(){return yi},set:function(r){if(typeof r!="number"||r<0||mi(r))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+r+".");yi=r}});Rt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};Rt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||mi(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function bi(r){return r._maxListeners===void 0?Rt.defaultMaxListeners:r._maxListeners}Rt.prototype.getMaxListeners=function(){return bi(this)};Rt.prototype.emit=function(t){for(var e=[],i=1;i0&&(c=e[0]),c instanceof Error)throw c;var f=new Error("Unhandled error."+(c?" ("+c.message+")":""));throw f.context=c,f}var g=h[t];if(g===void 0)return!1;if(typeof g=="function")wi(g,this,e);else for(var d=g.length,b=ki(g,d),i=0;i0&&c.length>u&&!c.warned){c.warned=!0;var f=new Error("Possible EventEmitter memory leak detected. "+c.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");f.name="MaxListenersExceededWarning",f.emitter=r,f.type=t,f.count=c.length,Uo(f)}return r}Rt.prototype.addListener=function(t,e){return Ei(this,t,e,!1)};Rt.prototype.on=Rt.prototype.addListener;Rt.prototype.prependListener=function(t,e){return Ei(this,t,e,!0)};function qo(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function vi(r,t,e){var i={fired:!1,wrapFn:void 0,target:r,type:t,listener:e},u=qo.bind(i);return u.listener=e,i.wrapFn=u,u}Rt.prototype.once=function(t,e){return qr(e),this.on(t,vi(this,t,e)),this};Rt.prototype.prependOnceListener=function(t,e){return qr(e),this.prependListener(t,vi(this,t,e)),this};Rt.prototype.removeListener=function(t,e){var i,u,h,c,f;if(qr(e),u=this._events,u===void 0)return this;if(i=u[t],i===void 0)return this;if(i===e||i.listener===e)--this._eventsCount===0?this._events=Object.create(null):(delete u[t],u.removeListener&&this.emit("removeListener",t,i.listener||e));else if(typeof i!="function"){for(h=-1,c=i.length-1;c>=0;c--)if(i[c]===e||i[c].listener===e){f=i[c].listener,h=c;break}if(h<0)return this;h===0?i.shift():Wo(i,h),i.length===1&&(u[t]=i[0]),u.removeListener!==void 0&&this.emit("removeListener",t,f||e)}return this};Rt.prototype.off=Rt.prototype.removeListener;Rt.prototype.removeAllListeners=function(t){var e,i,u;if(i=this._events,i===void 0)return this;if(i.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):i[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete i[t]),this;if(arguments.length===0){var h=Object.keys(i),c;for(u=0;u=0;u--)this.removeListener(t,e[u]);return this};function Si(r,t,e){var i=r._events;if(i===void 0)return[];var u=i[t];return u===void 0?[]:typeof u=="function"?e?[u.listener||u]:[u]:e?Vo(u):ki(u,u.length)}Rt.prototype.listeners=function(t){return Si(this,t,!0)};Rt.prototype.rawListeners=function(t){return Si(this,t,!1)};Rt.listenerCount=function(r,t){return typeof r.listenerCount=="function"?r.listenerCount(t):xi.call(r,t)};Rt.prototype.listenerCount=xi;function xi(r){var t=this._events;if(t!==void 0){var e=t[r];if(typeof e=="function")return 1;if(e!==void 0)return e.length}return 0}Rt.prototype.eventNames=function(){return this._eventsCount>0?Ur(this._events):[]};function ki(r,t){for(var e=new Array(t),i=0;i{function Hu(r){return!r||typeof r!="object"||typeof r=="function"||Array.isArray(r)||r instanceof Set||r instanceof Map||r instanceof RegExp||r instanceof Date}function Fi(r,t){r=r||{};var e={};for(var i in t){var u=r[i],h=t[i];if(!Hu(h)){e[i]=Fi(u,h);continue}u===void 0?e[i]=h:e[i]=u}return e}zi.exports=Fi});var Qe=te((Ka,Ui)=>{Ui.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var Bi=te((Ya,Vi)=>{function qi(r){return function(t,e){return t+Math.floor(r()*(e-t+1))}}var Wi=qi(Math.random);Wi.createRandom=qi;Vi.exports=Wi});var Qi=te((Xa,Xi)=>{var th=Bi().createRandom;function Ki(r){var t=th(r);return function(e){for(var i=e.length,u=i-1,h=-1;++h{var eh=kr(),rh=Qe(),nh=Qi(),ih={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function le(r,t,e,i,u){this.wrappedCircle=u||null,this.children={},this.countChildren=0,this.id=r||null,this.next=null,this.previous=null,this.x=t||null,this.y=e||null,u?this.r=1010101:this.r=i||999}le.prototype.hasChildren=function(){return this.countChildren>0};le.prototype.addChild=function(r,t){this.children[r]=t,++this.countChildren};le.prototype.getChild=function(r){if(!this.children.hasOwnProperty(r)){var t=new le;this.children[r]=t,++this.countChildren}return this.children[r]};le.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var r=this;for(var t in r.children){var e=r.children[t];e.x+=r.x,e.y+=r.y,e.applyPositionToChildren()}}};function ts(r,t,e){for(var i in t.children){var u=t.children[i];u.hasChildren()?ts(r,u,e):e[u.id]={x:u.x,y:u.y}}}function Zr(r,t){var e=r.r-t.r,i=t.x-r.x,u=t.y-r.y;return e<0||e*e0&&e*e>i*i+u*u}function Cn(r,t){for(var e=0;eg?(u=(d+g-h)/(2*d),f=Math.sqrt(Math.max(0,g/d-u*u)),e.x=r.x-u*i-f*c,e.y=r.y-u*c+f*i):(u=(d+h-g)/(2*d),f=Math.sqrt(Math.max(0,h/d-u*u)),e.x=t.x+u*i-f*c,e.y=t.y+u*c+f*i)):(e.x=t.x+e.r,e.y=t.y)}function Hi(r,t){var e=r.r+t.r-1e-6,i=t.x-r.x,u=t.y-r.y;return e>0&&e*e>i*i+u*u}function ah(r,t){var e=r.length;if(e===0)return 0;var i,u,h,c,f,g,d,b,m,v;if(i=r[0],i.x=0,i.y=0,e<=1)return i.r;if(u=r[1],i.x=-u.r,u.x=i.r,u.y=0,e<=2)return i.r+u.r;h=r[2],Ji(u,i,h),i=new le(null,null,null,null,i),u=new le(null,null,null,null,u),h=new le(null,null,null,null,h),i.next=h.previous=u,u.next=i.previous=h,h.next=u.previous=i;t:for(g=3;g{var lh=kr(),fh=Qe(),dh={dimensions:["x","y"],center:.5,scale:1};function hs(r,t,e){if(!fh(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=lh(e,dh);var i=e.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=e.center,h=e.scale,c=Math.PI*2,f=(u-.5)*h,g=t.order,d=i[0],b=i[1];function m($,P){return P[d]=h*Math.cos($*c/g)+f,P[b]=h*Math.sin($*c/g)+f,P}var v=0;if(!r){var D={};return t.forEachNode(function($){D[$]=m(v++,{})}),D}t.updateEachNodeAttributes(function($,P){return m(v++,P),P},{attributes:i})}var as=hs.bind(null,!1);as.assign=hs.bind(null,!0);cs.exports=as});var ps=te((Ja,gs)=>{var gh=kr(),ph=Qe(),wh={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function fs(r,t,e){if(!ph(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=gh(e,wh);var i=e.dimensions;if(!Array.isArray(i)||i.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var u=i.length,h=e.center,c=e.rng,f=e.scale,g=(h-.5)*f;function d(m){for(var v=0;v{var yh=kr(),mh=Qe(),bh=Math.PI/180,Eh={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function ws(r,t,e,i){if(!mh(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");i=yh(i,Eh),i.degrees&&(e*=bh);var u=i.dimensions;if(!Array.isArray(u)||u.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return r?void 0:{};var h=u[0],c=u[1],f=0,g=0;if(!i.centeredOnZero){var d=1/0,b=-1/0,m=1/0,v=-1/0;t.forEachNode(function(B,G){var F=G[h],V=G[c];Fb&&(b=F),Vv&&(v=V)}),f=(d+b)/2,g=(m+v)/2}var D=Math.cos(e),$=Math.sin(e);function P(B){var G=B[h],F=B[c];return B[h]=f+(G-f)*D-(F-g)*$,B[c]=g+(G-f)*$+(F-g)*D,B}if(!r){var q={};return t.forEachNode(function(B,G){var F={};F[h]=G[h],F[c]=G[c],q[B]=P(F)}),q}t.updateEachNodeAttributes(function(B,G){return P(G),G},{attributes:u})}var ys=ws.bind(null,!1);ys.assign=ws.bind(null,!0);ms.exports=ys});var Es=te(Ir=>{Ir.circlepack=us();Ir.circular=ls();Ir.random=ps();Ir.rotation=bs()});var Pn=te(Jr=>{function vh(r){return typeof r!="number"||isNaN(r)?1:r}function Sh(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getNodeAttributes(f))},e.fromEntry=function(c,f){return u(f)}):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){return i(r(f,c.getNodeAttributes(f)))},e.fromEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h),e}function vs(r,t){var e={},i=function(c){return typeof c>"u"?t:c};typeof t=="function"&&(i=t);var u=function(c){return i(c[r])},h=function(){return i(void 0)};return typeof r=="string"?(e.fromAttributes=u,e.fromGraph=function(c,f){return u(c.getEdgeAttributes(f))},e.fromEntry=function(c,f){return u(f)},e.fromPartialEntry=e.fromEntry,e.fromMinimalEntry=e.fromEntry):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},e.fromGraph=function(c,f){var g=c.extremities(f);return i(r(f,c.getEdgeAttributes(f),g[0],g[1],c.getNodeAttributes(g[0]),c.getNodeAttributes(g[1]),c.isUndirected(f)))},e.fromEntry=function(c,f,g,d,b,m,v){return i(r(c,f,g,d,b,m,v))},e.fromPartialEntry=function(c,f,g,d){return i(r(c,f,g,d))},e.fromMinimalEntry=function(c,f){return i(r(c,f))}):(e.fromAttributes=h,e.fromGraph=h,e.fromEntry=h,e.fromMinimalEntry=h),e}Jr.createNodeValueGetter=Sh;Jr.createEdgeValueGetter=vs;Jr.createEdgeWeightGetter=function(r){return vs(r,vh)}});var Is=te((rc,Ds)=>{var Wt=0,Mt=1,St=2,xt=3,Pe=4,Ne=5,kt=6,Ss=7,Hr=8,xs=9,xh=0,kh=1,Dh=2,Yt=0,be=1,se=2,Ze=3,ze=4,Nt=5,fe=6,Te=7,Le=8,ks=3,Ie=10,Ih=3,ne=9,Nn=10;Ds.exports=function(t,e,i){var u,h,c,f,g,d,b,m,v,D,$=e.length,P=i.length,q=t.adjustSizes,B=t.barnesHutTheta*t.barnesHutTheta,G,F,V,z,ot,O,N,A=[];for(c=0;c<$;c+=Ie)e[c+Pe]=e[c+St],e[c+Ne]=e[c+xt],e[c+St]=0,e[c+xt]=0;if(t.outboundAttractionDistribution){for(G=0,c=0;c<$;c+=Ie)G+=e[c+kt];G/=$/Ie}if(t.barnesHutOptimize){var nt=1/0,dt=-1/0,wt=1/0,Pt=-1/0,yt,Qt,ue;for(c=0;c<$;c+=Ie)nt=Math.min(nt,e[c+Wt]),dt=Math.max(dt,e[c+Wt]),wt=Math.min(wt,e[c+Mt]),Pt=Math.max(Pt,e[c+Mt]);var gt=dt-nt,j=Pt-wt;for(gt>j?(wt-=(gt-j)/2,Pt=wt+gt):(nt-=(j-gt)/2,dt=nt+j),A[0+Yt]=-1,A[0+be]=(nt+dt)/2,A[0+se]=(wt+Pt)/2,A[0+Ze]=Math.max(dt-nt,Pt-wt),A[0+ze]=-1,A[0+Nt]=-1,A[0+fe]=0,A[0+Te]=0,A[0+Le]=0,u=1,c=0;c<$;c+=Ie)for(h=0,ue=ks;;)if(A[h+Nt]>=0){e[c+Wt]=0)if(O=Math.pow(e[c+Wt]-A[h+Te],2)+Math.pow(e[c+Mt]-A[h+Le],2),D=A[h+Ze],4*D*D/O0?(N=F*e[c+kt]*A[h+fe]/O,e[c+St]+=V*N,e[c+xt]+=z*N):O<0&&(N=-F*e[c+kt]*A[h+fe]/Math.sqrt(O),e[c+St]+=V*N,e[c+xt]+=z*N):O>0&&(N=F*e[c+kt]*A[h+fe]/O,e[c+St]+=V*N,e[c+xt]+=z*N),h=A[h+ze],h<0)break;continue}else{h=A[h+Nt];continue}else{if(d=A[h+Yt],d>=0&&d!==c&&(V=e[c+Wt]-e[d+Wt],z=e[c+Mt]-e[d+Mt],O=V*V+z*z,q===!0?O>0?(N=F*e[c+kt]*e[d+kt]/O,e[c+St]+=V*N,e[c+xt]+=z*N):O<0&&(N=-F*e[c+kt]*e[d+kt]/Math.sqrt(O),e[c+St]+=V*N,e[c+xt]+=z*N):O>0&&(N=F*e[c+kt]*e[d+kt]/O,e[c+St]+=V*N,e[c+xt]+=z*N)),h=A[h+ze],h<0)break;continue}else for(F=t.scalingRatio,f=0;f<$;f+=Ie)for(g=0;g0?(N=F*e[f+kt]*e[g+kt]/O/O,e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N):O<0&&(N=100*F*e[f+kt]*e[g+kt],e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N)):(O=Math.sqrt(V*V+z*z),O>0&&(N=F*e[f+kt]*e[g+kt]/O/O,e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N));for(v=t.gravity/t.scalingRatio,F=t.scalingRatio,c=0;c<$;c+=Ie)N=0,V=e[c+Wt],z=e[c+Mt],O=Math.sqrt(Math.pow(V,2)+Math.pow(z,2)),t.strongGravityMode?O>0&&(N=F*e[c+kt]*v):O>0&&(N=F*e[c+kt]*v/O),e[c+St]-=V*N,e[c+xt]-=z*N;for(F=1*(t.outboundAttractionDistribution?G:1),b=0;b0&&(N=-F*ot*Math.log(1+O)/O/e[f+kt]):O>0&&(N=-F*ot*Math.log(1+O)/O):t.outboundAttractionDistribution?O>0&&(N=-F*ot/e[f+kt]):O>0&&(N=-F*ot)):(O=Math.sqrt(Math.pow(V,2)+Math.pow(z,2)),t.linLogMode?t.outboundAttractionDistribution?O>0&&(N=-F*ot*Math.log(1+O)/O/e[f+kt]):O>0&&(N=-F*ot*Math.log(1+O)/O):t.outboundAttractionDistribution?(O=1,N=-F*ot/e[f+kt]):(O=1,N=-F*ot)),O>0&&(e[f+St]+=V*N,e[f+xt]+=z*N,e[g+St]-=V*N,e[g+xt]-=z*N);var he,ve,Q,I,bt,It;if(q===!0)for(c=0;c<$;c+=Ie)e[c+xs]!==1&&(he=Math.sqrt(Math.pow(e[c+St],2)+Math.pow(e[c+xt],2)),he>Nn&&(e[c+St]=e[c+St]*Nn/he,e[c+xt]=e[c+xt]*Nn/he),ve=e[c+kt]*Math.sqrt((e[c+Pe]-e[c+St])*(e[c+Pe]-e[c+St])+(e[c+Ne]-e[c+xt])*(e[c+Ne]-e[c+xt])),Q=Math.sqrt((e[c+Pe]+e[c+St])*(e[c+Pe]+e[c+St])+(e[c+Ne]+e[c+xt])*(e[c+Ne]+e[c+xt]))/2,I=.1*Math.log(1+Q)/(1+Math.sqrt(ve)),bt=e[c+Wt]+e[c+St]*(I/t.slowDown),e[c+Wt]=bt,It=e[c+Mt]+e[c+xt]*(I/t.slowDown),e[c+Mt]=It);else for(c=0;c<$;c+=Ie)e[c+xs]!==1&&(ve=e[c+kt]*Math.sqrt((e[c+Pe]-e[c+St])*(e[c+Pe]-e[c+St])+(e[c+Ne]-e[c+xt])*(e[c+Ne]-e[c+xt])),Q=Math.sqrt((e[c+Pe]+e[c+St])*(e[c+Pe]+e[c+St])+(e[c+Ne]+e[c+xt])*(e[c+Ne]+e[c+xt]))/2,I=e[c+Ss]*Math.log(1+Q)/(1+Math.sqrt(ve)),e[c+Ss]=Math.min(1,Math.sqrt(I*(Math.pow(e[c+St],2)+Math.pow(e[c+xt],2))/(1+Math.sqrt(ve)))),bt=e[c+Wt]+e[c+St]*(I/t.slowDown),e[c+Wt]=bt,It=e[c+Mt]+e[c+xt]*(I/t.slowDown),e[c+Mt]=It);return{}}});var Fn=te(Ue=>{var _r=10,_s=3;Ue.assign=function(r){r=r||{};var t=Array.prototype.slice.call(arguments).slice(1),e,i,u;for(e=0,u=t.length;e=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in r&&typeof r.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in r&&!(typeof r.gravity=="number"&&r.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in r&&!(typeof r.slowDown=="number"||r.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in r&&typeof r.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in r&&!(typeof r.barnesHutTheta=="number"&&r.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};Ue.graphToByteArrays=function(r,t){var e=r.order,i=r.size,u={},h,c=new Float32Array(e*_r),f=new Float32Array(i*_s);return h=0,r.forEachNode(function(g,d){u[g]=h,c[h]=d.x,c[h+1]=d.y,c[h+2]=0,c[h+3]=0,c[h+4]=0,c[h+5]=0,c[h+6]=1,c[h+7]=1,c[h+8]=d.size||1,c[h+9]=d.fixed?1:0,h+=_r}),h=0,r.forEachEdge(function(g,d,b,m,v,D,$){var P=u[b],q=u[m],B=t(g,d,b,m,v,D,$);c[P+6]+=B,c[q+6]+=B,f[h]=P,f[h+1]=q,f[h+2]=B,h+=_s}),{nodes:c,edges:f}};Ue.assignLayoutChanges=function(r,t,e){var i=0;r.updateEachNodeAttributes(function(u,h){return h.x=t[i],h.y=t[i+1],i+=_r,e?e(u,h):h})};Ue.readGraphPositions=function(r,t){var e=0;r.forEachNode(function(i,u){t[e]=u.x,t[e+1]=u.y,e+=_r})};Ue.collectLayoutChanges=function(r,t,e){for(var i=r.nodes(),u={},h=0,c=0,f=t.length;h{Rs.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var $s=te((sc,As)=>{var _h=Qe(),Rh=Pn().createEdgeWeightGetter,jh=Is(),Rr=Fn(),Ah=zn();function js(r,t,e){if(!_h(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof e=="number"&&(e={iterations:e});var i=e.iterations;if(typeof i!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(i<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var u=Rh("getEdgeWeight"in e?e.getEdgeWeight:"weight").fromEntry,h=typeof e.outputReducer=="function"?e.outputReducer:null,c=Rr.assign({},Ah,e.settings),f=Rr.validateSettings(c);if(f)throw new Error("graphology-layout-forceatlas2: "+f.message);var g=Rr.graphToByteArrays(t,u),d;for(d=0;d2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var Un=js.bind(null,!1);Un.assign=js.bind(null,!0);Un.inferSettings=$h;As.exports=Un});var Ls=te((oc,Ts)=>{Ts.exports=function(){var t,e,i={};(function(){var h=0,c=1,f=2,g=3,d=4,b=5,m=6,v=7,D=8,$=9,P=0,q=1,B=2,G=0,F=1,V=2,z=3,ot=4,O=5,N=6,A=7,nt=8,dt=3,wt=10,Pt=3,yt=9,Qt=10;i.exports=function(gt,j,he){var ve,Q,I,bt,It,X,ae,qt,st,mr,pe=j.length,Dn=he.length,Ye=gt.adjustSizes,In=gt.barnesHutTheta*gt.barnesHutTheta,tr,_t,Et,vt,we,rt,ut,M=[];for(I=0;Irr?(ce-=(er-rr)/2,Fe=ce+er):(Zt-=(rr-er)/2,je=Zt+rr),M[0+G]=-1,M[0+F]=(Zt+je)/2,M[0+V]=(ce+Fe)/2,M[0+z]=Math.max(je-Zt,Fe-ce),M[0+ot]=-1,M[0+O]=-1,M[0+N]=0,M[0+A]=0,M[0+nt]=0,ve=1,I=0;I=0){j[I+h]=0)if(rt=Math.pow(j[I+h]-M[Q+A],2)+Math.pow(j[I+c]-M[Q+nt],2),mr=M[Q+z],4*mr*mr/rt0?(ut=_t*j[I+m]*M[Q+N]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt<0&&(ut=-_t*j[I+m]*M[Q+N]/Math.sqrt(rt),j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt>0&&(ut=_t*j[I+m]*M[Q+N]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut),Q=M[Q+ot],Q<0)break;continue}else{Q=M[Q+O];continue}else{if(X=M[Q+G],X>=0&&X!==I&&(Et=j[I+h]-j[X+h],vt=j[I+c]-j[X+c],rt=Et*Et+vt*vt,Ye===!0?rt>0?(ut=_t*j[I+m]*j[X+m]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt<0&&(ut=-_t*j[I+m]*j[X+m]/Math.sqrt(rt),j[I+f]+=Et*ut,j[I+g]+=vt*ut):rt>0&&(ut=_t*j[I+m]*j[X+m]/rt,j[I+f]+=Et*ut,j[I+g]+=vt*ut)),Q=M[Q+ot],Q<0)break;continue}else for(_t=gt.scalingRatio,bt=0;bt0?(ut=_t*j[bt+m]*j[It+m]/rt/rt,j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut):rt<0&&(ut=100*_t*j[bt+m]*j[It+m],j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut)):(rt=Math.sqrt(Et*Et+vt*vt),rt>0&&(ut=_t*j[bt+m]*j[It+m]/rt/rt,j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut));for(st=gt.gravity/gt.scalingRatio,_t=gt.scalingRatio,I=0;I0&&(ut=_t*j[I+m]*st):rt>0&&(ut=_t*j[I+m]*st/rt),j[I+f]-=Et*ut,j[I+g]-=vt*ut;for(_t=1*(gt.outboundAttractionDistribution?tr:1),ae=0;ae0&&(ut=-_t*we*Math.log(1+rt)/rt/j[bt+m]):rt>0&&(ut=-_t*we*Math.log(1+rt)/rt):gt.outboundAttractionDistribution?rt>0&&(ut=-_t*we/j[bt+m]):rt>0&&(ut=-_t*we)):(rt=Math.sqrt(Math.pow(Et,2)+Math.pow(vt,2)),gt.linLogMode?gt.outboundAttractionDistribution?rt>0&&(ut=-_t*we*Math.log(1+rt)/rt/j[bt+m]):rt>0&&(ut=-_t*we*Math.log(1+rt)/rt):gt.outboundAttractionDistribution?(rt=1,ut=-_t*we/j[bt+m]):(rt=1,ut=-_t*we)),rt>0&&(j[bt+f]+=Et*ut,j[bt+g]+=vt*ut,j[It+f]-=Et*ut,j[It+g]-=vt*ut);var nr,Xe,ir,Ae,sr,or;if(Ye===!0)for(I=0;IQt&&(j[I+f]=j[I+f]*Qt/nr,j[I+g]=j[I+g]*Qt/nr),Xe=j[I+m]*Math.sqrt((j[I+d]-j[I+f])*(j[I+d]-j[I+f])+(j[I+b]-j[I+g])*(j[I+b]-j[I+g])),ir=Math.sqrt((j[I+d]+j[I+f])*(j[I+d]+j[I+f])+(j[I+b]+j[I+g])*(j[I+b]+j[I+g]))/2,Ae=.1*Math.log(1+ir)/(1+Math.sqrt(Xe)),sr=j[I+h]+j[I+f]*(Ae/gt.slowDown),j[I+h]=sr,or=j[I+c]+j[I+g]*(Ae/gt.slowDown),j[I+c]=or);else for(I=0;I{var Th=Ls(),Lh=Qe(),Gh=Pn().createEdgeWeightGetter,fr=Fn(),Oh=zn();function qe(r,t){if(t=t||{},!Lh(r))throw new Error("graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.");var e=Gh("getEdgeWeight"in t?t.getEdgeWeight:"weight").fromEntry,i=fr.assign({},Oh,t.settings),u=fr.validateSettings(i);if(u)throw new Error("graphology-layout-forceatlas2/worker: "+u.message);this.worker=null,this.graph=r,this.settings=i,this.getEdgeWeight=e,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer=="function"?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var h=void 0,c=this;this.handleGraphUpdate=function(){c.worker&&c.worker.terminate(),h&&clearTimeout(h),h=setTimeout(function(){h=void 0,c.spawnWorker()},0)},r.on("nodeAdded",this.handleGraphUpdate),r.on("edgeAdded",this.handleGraphUpdate),r.on("nodeDropped",this.handleGraphUpdate),r.on("edgeDropped",this.handleGraphUpdate),this.spawnWorker()}qe.prototype.isRunning=function(){return this.running};qe.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=fr.createWorker(Th),this.worker.addEventListener("message",this.handleMessage),this.running&&(this.running=!1,this.start())};qe.prototype.handleMessage=function(r){if(this.running){var t=new Float32Array(r.data.nodes);fr.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&fr.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}};qe.prototype.askForIterations=function(r){var t=this.matrices,e={settings:this.settings,nodes:t.nodes.buffer},i=[t.nodes.buffer];return r&&(e.edges=t.edges.buffer,i.push(t.edges.buffer)),this.worker.postMessage(e,i),this};qe.prototype.start=function(){if(this.killed)throw new Error("graphology-layout-forceatlas2/worker.start: layout was killed.");return this.running?this:(this.matrices=fr.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)};qe.prototype.stop=function(){return this.running=!1,this};qe.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener("nodeAdded",this.handleGraphUpdate),this.graph.removeListener("edgeAdded",this.handleGraphUpdate),this.graph.removeListener("nodeDropped",this.handleGraphUpdate),this.graph.removeListener("edgeDropped",this.handleGraphUpdate)};Gs.exports=qe});var Ai=Fr(Ii(),1);function Yo(){let r=arguments[0];for(let t=1,e=arguments.length;tr++}function Me(){let r=arguments,t=null,e=-1;return{[Symbol.iterator](){return this},next(){let i=null;do{if(t===null){if(e++,e>=r.length)return{done:!0};t=r[e][Symbol.iterator]()}if(i=t.next(),i.done){t=null;continue}break}while(!0);return i}}}function ar(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var xr=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},tt=class r extends xr{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},Z=class r extends xr{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},at=class r extends xr{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}};function Ti(r,t){this.key=r,this.attributes=t,this.clear()}Ti.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function Li(r,t){this.key=r,this.attributes=t,this.clear()}Li.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Gi(r,t){this.key=r,this.attributes=t,this.clear()}Gi.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function cr(r,t,e,i,u){this.key=t,this.attributes=u,this.undirected=r,this.source=e,this.target=i}cr.prototype.attach=function(){let r="out",t="in";this.undirected&&(r=t="undirected");let e=this.source.key,i=this.target.key;this.source[r][i]=this,!(this.undirected&&e===i)&&(this.target[t][e]=this)};cr.prototype.attachMulti=function(){let r="out",t="in",e=this.source.key,i=this.target.key;this.undirected&&(r=t="undirected");let u=this.source[r],h=u[i];if(typeof h>"u"){u[i]=this,this.undirected&&e===i||(this.target[t][e]=this);return}h.previous=this,this.next=h,u[i]=this,this.target[t][e]=this};cr.prototype.detach=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),delete this.source[e][t],delete this.target[i][r]};cr.prototype.detachMulti=function(){let r=this.source.key,t=this.target.key,e="out",i="in";this.undirected&&(e=i="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[e][t],delete this.target[i][r]):(this.next.previous=void 0,this.source[e][t]=this.next,this.target[i][r]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var Oi=0,Mi=1,Qo=2,Ci=3;function Ce(r,t,e,i,u,h,c){let f,g,d,b;if(i=""+i,e===Oi){if(f=r._nodes.get(i),!f)throw new Z(`Graph.${t}: could not find the "${i}" node in the graph.`);d=u,b=h}else if(e===Ci){if(u=""+u,g=r._edges.get(u),!g)throw new Z(`Graph.${t}: could not find the "${u}" edge in the graph.`);let m=g.source.key,v=g.target.key;if(i===m)f=g.target;else if(i===v)f=g.source;else throw new Z(`Graph.${t}: the "${i}" node is not attached to the "${u}" edge (${m}, ${v}).`);d=h,b=c}else{if(g=r._edges.get(i),!g)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`);e===Mi?f=g.source:f=g.target,d=u,b=h}return[f,d,b]}function Zo(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return c.attributes[f]}}function Jo(r,t,e){r.prototype[t]=function(i,u){let[h]=Ce(this,t,e,i,u);return h.attributes}}function Ho(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return c.attributes.hasOwnProperty(f)}}function tu(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,g,d]=Ce(this,t,e,i,u,h,c);return f.attributes[g]=d,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:g}),this}}function eu(r,t,e){r.prototype[t]=function(i,u,h,c){let[f,g,d]=Ce(this,t,e,i,u,h,c);if(typeof d!="function")throw new tt(`Graph.${t}: updater should be a function.`);let b=f.attributes,m=d(b[g]);return b[g]=m,this.emit("nodeAttributesUpdated",{key:f.key,type:"set",attributes:f.attributes,name:g}),this}}function ru(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);return delete c.attributes[f],this.emit("nodeAttributesUpdated",{key:c.key,type:"remove",attributes:c.attributes,name:f}),this}}function nu(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(!ee(f))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return c.attributes=f,this.emit("nodeAttributesUpdated",{key:c.key,type:"replace",attributes:c.attributes}),this}}function iu(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(!ee(f))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Kt(c.attributes,f),this.emit("nodeAttributesUpdated",{key:c.key,type:"merge",attributes:c.attributes,data:f}),this}}function su(r,t,e){r.prototype[t]=function(i,u,h){let[c,f]=Ce(this,t,e,i,u,h);if(typeof f!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return c.attributes=f(c.attributes),this.emit("nodeAttributesUpdated",{key:c.key,type:"update",attributes:c.attributes}),this}}var ou=[{name:r=>`get${r}Attribute`,attacher:Zo},{name:r=>`get${r}Attributes`,attacher:Jo},{name:r=>`has${r}Attribute`,attacher:Ho},{name:r=>`set${r}Attribute`,attacher:tu},{name:r=>`update${r}Attribute`,attacher:eu},{name:r=>`remove${r}Attribute`,attacher:ru},{name:r=>`replace${r}Attributes`,attacher:nu},{name:r=>`merge${r}Attributes`,attacher:iu},{name:r=>`update${r}Attributes`,attacher:su}];function uu(r){ou.forEach(function({name:t,attacher:e}){e(r,t("Node"),Oi),e(r,t("Source"),Mi),e(r,t("Target"),Qo),e(r,t("Opposite"),Ci)})}function hu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes[u]}}function au(r,t,e){r.prototype[t]=function(i){let u;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let h=""+i,c=""+arguments[1];if(u=me(this,h,c,e),!u)throw new Z(`Graph.${t}: could not find an edge for the given path ("${h}" - "${c}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,u=this._edges.get(i),!u)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return u.attributes}}function cu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return h.attributes.hasOwnProperty(u)}}function lu(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,g=""+u;if(u=arguments[2],h=arguments[3],c=me(this,f,g,e),!c)throw new Z(`Graph.${t}: could not find an edge for the given path ("${f}" - "${g}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return c.attributes[u]=h,this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function fu(r,t,e){r.prototype[t]=function(i,u,h){let c;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let f=""+i,g=""+u;if(u=arguments[2],h=arguments[3],c=me(this,f,g,e),!c)throw new Z(`Graph.${t}: could not find an edge for the given path ("${f}" - "${g}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,c=this._edges.get(i),!c)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof h!="function")throw new tt(`Graph.${t}: updater should be a function.`);return c.attributes[u]=h(c.attributes[u]),this.emit("edgeAttributesUpdated",{key:c.key,type:"set",attributes:c.attributes,name:u}),this}}function du(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}return delete h.attributes[u],this.emit("edgeAttributesUpdated",{key:h.key,type:"remove",attributes:h.attributes,name:u}),this}}function gu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!ee(u))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return h.attributes=u,this.emit("edgeAttributesUpdated",{key:h.key,type:"replace",attributes:h.attributes}),this}}function pu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(!ee(u))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Kt(h.attributes,u),this.emit("edgeAttributesUpdated",{key:h.key,type:"merge",attributes:h.attributes,data:u}),this}}function wu(r,t,e){r.prototype[t]=function(i,u){let h;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new at(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new at(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let c=""+i,f=""+u;if(u=arguments[2],h=me(this,c,f,e),!h)throw new Z(`Graph.${t}: could not find an edge for the given path ("${c}" - "${f}").`)}else{if(e!=="mixed")throw new at(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(i=""+i,h=this._edges.get(i),!h)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`)}if(typeof u!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return h.attributes=u(h.attributes),this.emit("edgeAttributesUpdated",{key:h.key,type:"update",attributes:h.attributes}),this}}var yu=[{name:r=>`get${r}Attribute`,attacher:hu},{name:r=>`get${r}Attributes`,attacher:au},{name:r=>`has${r}Attribute`,attacher:cu},{name:r=>`set${r}Attribute`,attacher:lu},{name:r=>`update${r}Attribute`,attacher:fu},{name:r=>`remove${r}Attribute`,attacher:du},{name:r=>`replace${r}Attributes`,attacher:gu},{name:r=>`merge${r}Attributes`,attacher:pu},{name:r=>`update${r}Attributes`,attacher:wu}];function mu(r){yu.forEach(function({name:t,attacher:e}){e(r,t("Edge"),"mixed"),e(r,t("DirectedEdge"),"directed"),e(r,t("UndirectedEdge"),"undirected")})}var bu=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function Eu(r,t,e,i){let u=!1;for(let h in t){if(h===i)continue;let c=t[h];if(u=e(c.key,c.attributes,c.source.key,c.target.key,c.source.attributes,c.target.attributes,c.undirected),r&&u)return c.key}}function vu(r,t,e,i){let u,h,c,f=!1;for(let g in t)if(g!==i){u=t[g];do{if(h=u.source,c=u.target,f=e(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected),r&&f)return u.key;u=u.next}while(u!==void 0)}}function Tn(r,t){let e=Object.keys(r),i=e.length,u,h=0;return{[Symbol.iterator](){return this},next(){do if(u)u=u.next;else{if(h>=i)return{done:!0};let c=e[h++];if(c===t){u=void 0;continue}u=r[c]}while(!u);return{done:!1,value:{edge:u.key,attributes:u.attributes,source:u.source.key,target:u.target.key,sourceAttributes:u.source.attributes,targetAttributes:u.target.attributes,undirected:u.undirected}}}}}function Su(r,t,e,i){let u=t[e];if(!u)return;let h=u.source,c=u.target;if(i(u.key,u.attributes,h.key,c.key,h.attributes,c.attributes,u.undirected)&&r)return u.key}function xu(r,t,e,i){let u=t[e];if(!u)return;let h=!1;do{if(h=i(u.key,u.attributes,u.source.key,u.target.key,u.source.attributes,u.target.attributes,u.undirected),r&&h)return u.key;u=u.next}while(u!==void 0)}function Ln(r,t){let e=r[t];if(e.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!e)return{done:!0};let u={edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected};return e=e.next,{done:!1,value:u}}};let i=!1;return{[Symbol.iterator](){return this},next(){return i===!0?{done:!0}:(i=!0,{done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}})}}}function ku(r,t){if(r.size===0)return[];if(t==="mixed"||t===r.type)return Array.from(r._edges.keys());let e=t==="undirected"?r.undirectedSize:r.directedSize,i=new Array(e),u=t==="undirected",h=r._edges.values(),c=0,f,g;for(;f=h.next(),f.done!==!0;)g=f.value,g.undirected===u&&(i[c++]=g.key);return i}function Pi(r,t,e,i){if(t.size===0)return;let u=e!=="mixed"&&e!==t.type,h=e==="undirected",c,f,g=!1,d=t._edges.values();for(;c=d.next(),c.done!==!0;){if(f=c.value,u&&f.undirected!==h)continue;let{key:b,attributes:m,source:v,target:D}=f;if(g=i(b,m,v.key,D.key,v.attributes,D.attributes,f.undirected),r&&g)return b}}function Du(r,t){if(r.size===0)return ar();let e=t!=="mixed"&&t!==r.type,i=t==="undirected",u=r._edges.values();return{[Symbol.iterator](){return this},next(){let h,c;for(;;){if(h=u.next(),h.done)return h;if(c=h.value,!(e&&c.undirected!==i))break}return{value:{edge:c.key,attributes:c.attributes,source:c.source.key,target:c.target.key,sourceAttributes:c.source.attributes,targetAttributes:c.target.attributes,undirected:c.undirected},done:!1}}}}function Gn(r,t,e,i,u,h){let c=t?vu:Eu,f;if(e!=="undirected"&&(i!=="out"&&(f=c(r,u.in,h),r&&f)||i!=="in"&&(f=c(r,u.out,h,i?void 0:u.key),r&&f))||e!=="directed"&&(f=c(r,u.undirected,h),r&&f))return f}function Iu(r,t,e,i){let u=[];return Gn(!1,r,t,e,i,function(h){u.push(h)}),u}function _u(r,t,e){let i=ar();return r!=="undirected"&&(t!=="out"&&typeof e.in<"u"&&(i=Me(i,Tn(e.in))),t!=="in"&&typeof e.out<"u"&&(i=Me(i,Tn(e.out,t?void 0:e.key)))),r!=="directed"&&typeof e.undirected<"u"&&(i=Me(i,Tn(e.undirected))),i}function On(r,t,e,i,u,h,c){let f=e?xu:Su,g;if(t!=="undirected"&&(typeof u.in<"u"&&i!=="out"&&(g=f(r,u.in,h,c),r&&g)||typeof u.out<"u"&&i!=="in"&&(i||u.key!==h)&&(g=f(r,u.out,h,c),r&&g))||t!=="directed"&&typeof u.undirected<"u"&&(g=f(r,u.undirected,h,c),r&&g))return g}function Ru(r,t,e,i,u){let h=[];return On(!1,r,t,e,i,u,function(c){h.push(c)}),h}function ju(r,t,e,i){let u=ar();return r!=="undirected"&&(typeof e.in<"u"&&t!=="out"&&i in e.in&&(u=Me(u,Ln(e.in,i))),typeof e.out<"u"&&t!=="in"&&i in e.out&&(t||e.key!==i)&&(u=Me(u,Ln(e.out,i)))),r!=="directed"&&typeof e.undirected<"u"&&i in e.undirected&&(u=Me(u,Ln(e.undirected,i))),u}function Au(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h,c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];if(!arguments.length)return ku(this,i);if(arguments.length===1){h=""+h;let f=this._nodes.get(h);if(typeof f>"u")throw new Z(`Graph.${e}: could not find the "${h}" node in the graph.`);return Iu(this.multi,i==="mixed"?this.type:i,u,f)}if(arguments.length===2){h=""+h,c=""+c;let f=this._nodes.get(h);if(!f)throw new Z(`Graph.${e}: could not find the "${h}" source node in the graph.`);if(!this._nodes.has(c))throw new Z(`Graph.${e}: could not find the "${c}" target node in the graph.`);return Ru(i,this.multi,u,f,c)}throw new tt(`Graph.${e}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function $u(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,b,m){if(!(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)){if(arguments.length===1)return m=d,Pi(!1,this,i,m);if(arguments.length===2){d=""+d,m=b;let v=this._nodes.get(d);if(typeof v>"u")throw new Z(`Graph.${h}: could not find the "${d}" node in the graph.`);return Gn(!1,this.multi,i==="mixed"?this.type:i,u,v,m)}if(arguments.length===3){d=""+d,b=""+b;let v=this._nodes.get(d);if(!v)throw new Z(`Graph.${h}: could not find the "${d}" source node in the graph.`);if(!this._nodes.has(b))throw new Z(`Graph.${h}: could not find the "${b}" target node in the graph.`);return On(!1,i,this.multi,u,v,b,m)}throw new tt(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(){let d=Array.prototype.slice.call(arguments),b=d.pop(),m;if(d.length===0){let v=0;i!=="directed"&&(v+=this.undirectedSize),i!=="undirected"&&(v+=this.directedSize),m=new Array(v);let D=0;d.push(($,P,q,B,G,F,V)=>{m[D++]=b($,P,q,B,G,F,V)})}else m=[],d.push((v,D,$,P,q,B,G)=>{m.push(b(v,D,$,P,q,B,G))});return this[h].apply(this,d),m};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(){let d=Array.prototype.slice.call(arguments),b=d.pop(),m=[];return d.push((v,D,$,P,q,B,G)=>{b(v,D,$,P,q,B,G)&&m.push(v)}),this[h].apply(this,d),m};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(){let d=Array.prototype.slice.call(arguments);if(d.length<2||d.length>4)throw new tt(`Graph.${g}: invalid number of arguments (expecting 2, 3 or 4 and got ${d.length}).`);if(typeof d[d.length-1]=="function"&&typeof d[d.length-2]!="function")throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let b,m;d.length===2?(b=d[0],m=d[1],d=[]):d.length===3?(b=d[1],m=d[2],d=[d[0]]):d.length===4&&(b=d[2],m=d[3],d=[d[0],d[1]]);let v=m;return d.push((D,$,P,q,B,G,F)=>{v=b(v,D,$,P,q,B,G,F)}),this[h].apply(this,d),v}}function Tu(r,t){let{name:e,type:i,direction:u}=t,h="find"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(g,d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return!1;if(arguments.length===1)return b=g,Pi(!0,this,i,b);if(arguments.length===2){g=""+g,b=d;let m=this._nodes.get(g);if(typeof m>"u")throw new Z(`Graph.${h}: could not find the "${g}" node in the graph.`);return Gn(!0,this.multi,i==="mixed"?this.type:i,u,m,b)}if(arguments.length===3){g=""+g,d=""+d;let m=this._nodes.get(g);if(!m)throw new Z(`Graph.${h}: could not find the "${g}" source node in the graph.`);if(!this._nodes.has(d))throw new Z(`Graph.${h}: could not find the "${d}" target node in the graph.`);return On(!0,i,this.multi,u,m,d,b)}throw new tt(`Graph.${h}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let c="some"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[c]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((m,v,D,$,P,q,B)=>d(m,v,D,$,P,q,B)),!!this[h].apply(this,g)};let f="every"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[f]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((m,v,D,$,P,q,B)=>!d(m,v,D,$,P,q,B)),!this[h].apply(this,g)}}function Lu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c,f){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return ar();if(!arguments.length)return Du(this,i);if(arguments.length===1){c=""+c;let g=this._nodes.get(c);if(!g)throw new Z(`Graph.${h}: could not find the "${c}" node in the graph.`);return _u(i,u,g)}if(arguments.length===2){c=""+c,f=""+f;let g=this._nodes.get(c);if(!g)throw new Z(`Graph.${h}: could not find the "${c}" source node in the graph.`);if(!this._nodes.has(f))throw new Z(`Graph.${h}: could not find the "${f}" target node in the graph.`);return ju(i,u,g,f)}throw new tt(`Graph.${h}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Gu(r){bu.forEach(t=>{Au(r,t),$u(r,t),Tu(r,t),Lu(r,t)})}var Ou=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function Qr(){this.A=null,this.B=null}Qr.prototype.wrap=function(r){this.A===null?this.A=r:this.B===null&&(this.B=r)};Qr.prototype.has=function(r){return this.A!==null&&r in this.A||this.B!==null&&r in this.B};function vr(r,t,e,i,u){for(let h in i){let c=i[h],f=c.source,g=c.target,d=f===e?g:f;if(t&&t.has(d.key))continue;let b=u(d.key,d.attributes);if(r&&b)return d.key}}function Mn(r,t,e,i,u){if(t!=="mixed"){if(t==="undirected")return vr(r,null,i,i.undirected,u);if(typeof e=="string")return vr(r,null,i,i[e],u)}let h=new Qr,c;if(t!=="undirected"){if(e!=="out"){if(c=vr(r,null,i,i.in,u),r&&c)return c;h.wrap(i.in)}if(e!=="in"){if(c=vr(r,h,i,i.out,u),r&&c)return c;h.wrap(i.out)}}if(t!=="directed"&&(c=vr(r,h,i,i.undirected,u),r&&c))return c}function Mu(r,t,e){if(r!=="mixed"){if(r==="undirected")return Object.keys(e.undirected);if(typeof t=="string")return Object.keys(e[t])}let i=[];return Mn(!1,r,t,e,function(u){i.push(u)}),i}function Sr(r,t,e){let i=Object.keys(e),u=i.length,h=0;return{[Symbol.iterator](){return this},next(){let c=null;do{if(h>=u)return r&&r.wrap(e),{done:!0};let f=e[i[h++]],g=f.source,d=f.target;if(c=g===t?d:g,r&&r.has(c.key)){c=null;continue}}while(c===null);return{done:!1,value:{neighbor:c.key,attributes:c.attributes}}}}}function Cu(r,t,e){if(r!=="mixed"){if(r==="undirected")return Sr(null,e,e.undirected);if(typeof t=="string")return Sr(null,e,e[t])}let i=ar(),u=new Qr;return r!=="undirected"&&(t!=="out"&&(i=Me(i,Sr(u,e,e.in))),t!=="in"&&(i=Me(i,Sr(u,e,e.out)))),r!=="directed"&&(i=Me(i,Sr(u,e,e.undirected))),i}function Pu(r,t){let{name:e,type:i,direction:u}=t;r.prototype[e]=function(h){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return[];h=""+h;let c=this._nodes.get(h);if(typeof c>"u")throw new Z(`Graph.${e}: could not find the "${h}" node in the graph.`);return Mu(i==="mixed"?this.type:i,u,c)}}function Nu(r,t){let{name:e,type:i,direction:u}=t,h="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[h]=function(d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let m=this._nodes.get(d);if(typeof m>"u")throw new Z(`Graph.${h}: could not find the "${d}" node in the graph.`);Mn(!1,i==="mixed"?this.type:i,u,m,b)};let c="map"+e[0].toUpperCase()+e.slice(1);r.prototype[c]=function(d,b){let m=[];return this[h](d,(v,D)=>{m.push(b(v,D))}),m};let f="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[f]=function(d,b){let m=[];return this[h](d,(v,D)=>{b(v,D)&&m.push(v)}),m};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(d,b,m){if(arguments.length<3)throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let v=m;return this[h](d,(D,$)=>{v=b(v,D,$)}),v}}function Fu(r,t){let{name:e,type:i,direction:u}=t,h=e[0].toUpperCase()+e.slice(1,-1),c="find"+h;r.prototype[c]=function(d,b){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return;d=""+d;let m=this._nodes.get(d);if(typeof m>"u")throw new Z(`Graph.${c}: could not find the "${d}" node in the graph.`);return Mn(!0,i==="mixed"?this.type:i,u,m,b)};let f="some"+h;r.prototype[f]=function(d,b){return!!this[c](d,b)};let g="every"+h;r.prototype[g]=function(d,b){return!this[c](d,(v,D)=>!b(v,D))}}function zu(r,t){let{name:e,type:i,direction:u}=t,h=e.slice(0,-1)+"Entries";r.prototype[h]=function(c){if(i!=="mixed"&&this.type!=="mixed"&&i!==this.type)return ar();c=""+c;let f=this._nodes.get(c);if(typeof f>"u")throw new Z(`Graph.${h}: could not find the "${c}" node in the graph.`);return Cu(i==="mixed"?this.type:i,u,f)}}function Uu(r){Ou.forEach(t=>{Pu(r,t),Nu(r,t),Fu(r,t),zu(r,t)})}function Wr(r,t,e,i,u){let h=i._nodes.values(),c=i.type,f,g,d,b,m,v,D;for(;f=h.next(),f.done!==!0;){let $=!1;if(g=f.value,c!=="undirected"){b=g.out;for(d in b){m=b[d];do{if(v=m.target,$=!0,D=u(g.key,v.key,g.attributes,v.attributes,m.key,m.attributes,m.undirected),r&&D)return m;m=m.next}while(m)}}if(c!=="directed"){b=g.undirected;for(d in b)if(!(t&&g.key>d)){m=b[d];do{if(v=m.target,v.key!==d&&(v=m.source),$=!0,D=u(g.key,v.key,g.attributes,v.attributes,m.key,m.attributes,m.undirected),r&&D)return m;m=m.next}while(m)}}if(e&&!$&&(D=u(g.key,null,g.attributes,null,null,null,null),r&&D))return null}}function qu(r,t){let e={key:r};return $i(t.attributes)||(e.attributes=Kt({},t.attributes)),e}function Wu(r,t,e){let i={key:t,source:e.source.key,target:e.target.key};return $i(e.attributes)||(i.attributes=Kt({},e.attributes)),r==="mixed"&&e.undirected&&(i.undirected=!0),i}function Vu(r){if(!ee(r))throw new tt('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in r))throw new tt("Graph.import: serialized node is missing its key.");if("attributes"in r&&(!ee(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function Bu(r){if(!ee(r))throw new tt('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in r))throw new tt("Graph.import: serialized edge is missing its source.");if(!("target"in r))throw new tt("Graph.import: serialized edge is missing its target.");if("attributes"in r&&(!ee(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in r&&typeof r.undirected!="boolean")throw new tt("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var Ku=Xo(),Yu=new Set(["directed","undirected","mixed"]),Ri=new Set(["domain","_events","_eventsCount","_maxListeners"]),Xu=[{name:r=>`${r}Edge`,generateKey:!0},{name:r=>`${r}DirectedEdge`,generateKey:!0,type:"directed"},{name:r=>`${r}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:r=>`${r}EdgeWithKey`},{name:r=>`${r}DirectedEdgeWithKey`,type:"directed"},{name:r=>`${r}UndirectedEdgeWithKey`,type:"undirected"}],Qu={allowSelfLoops:!0,multi:!1,type:"mixed"};function Zu(r,t,e){if(e&&!ee(e))throw new tt(`Graph.addNode: invalid attributes. Expecting an object but got "${e}"`);if(t=""+t,e=e||{},r._nodes.has(t))throw new at(`Graph.addNode: the "${t}" node already exist in the graph.`);let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function ji(r,t,e){let i=new r.NodeDataClass(t,e);return r._nodes.set(t,i),r.emit("nodeAdded",{key:t,attributes:e}),i}function Ni(r,t,e,i,u,h,c,f){if(!i&&r.type==="undirected")throw new at(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new at(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(f&&!ee(f))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`);if(h=""+h,c=""+c,f=f||{},!r.allowSelfLoops&&h===c)throw new at(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let g=r._nodes.get(h),d=r._nodes.get(c);if(!g)throw new Z(`Graph.${t}: source node "${h}" not found.`);if(!d)throw new Z(`Graph.${t}: target node "${c}" not found.`);let b={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new at(`Graph.${t}: the "${u}" edge already exists in the graph.`);if(!r.multi&&(i?typeof g.undirected[c]<"u":typeof g.out[c]<"u"))throw new at(`Graph.${t}: an edge linking "${h}" to "${c}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let m=new cr(i,u,g,d,f);r._edges.set(u,m);let v=h===c;return i?(g.undirectedDegree++,d.undirectedDegree++,v&&(g.undirectedLoops++,r._undirectedSelfLoopCount++)):(g.outDegree++,d.inDegree++,v&&(g.directedLoops++,r._directedSelfLoopCount++)),r.multi?m.attachMulti():m.attach(),i?r._undirectedSize++:r._directedSize++,b.key=u,r.emit("edgeAdded",b),u}function Ju(r,t,e,i,u,h,c,f,g){if(!i&&r.type==="undirected")throw new at(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(i&&r.type==="directed")throw new at(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(f){if(g){if(typeof f!="function")throw new tt(`Graph.${t}: invalid updater function. Expecting a function but got "${f}"`)}else if(!ee(f))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${f}"`)}h=""+h,c=""+c;let d;if(g&&(d=f,f=void 0),!r.allowSelfLoops&&h===c)throw new at(`Graph.${t}: source & target are the same ("${h}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let b=r._nodes.get(h),m=r._nodes.get(c),v,D;if(!e&&(v=r._edges.get(u),v)){if((v.source.key!==h||v.target.key!==c)&&(!i||v.source.key!==c||v.target.key!==h))throw new at(`Graph.${t}: inconsistency detected when attempting to merge the "${u}" edge with "${h}" source & "${c}" target vs. ("${v.source.key}", "${v.target.key}").`);D=v}if(!D&&!r.multi&&b&&(D=i?b.undirected[c]:b.out[c]),D){let G=[D.key,!1,!1,!1];if(g?!d:!f)return G;if(g){let F=D.attributes;D.attributes=d(F),r.emit("edgeAttributesUpdated",{type:"replace",key:D.key,attributes:D.attributes})}else Kt(D.attributes,f),r.emit("edgeAttributesUpdated",{type:"merge",key:D.key,attributes:D.attributes,data:f});return G}f=f||{},g&&d&&(f=d(f));let $={key:null,undirected:i,source:h,target:c,attributes:f};if(e)u=r._edgeKeyGenerator();else if(u=""+u,r._edges.has(u))throw new at(`Graph.${t}: the "${u}" edge already exists in the graph.`);let P=!1,q=!1;b||(b=ji(r,h,{}),P=!0,h===c&&(m=b,q=!0)),m||(m=ji(r,c,{}),q=!0),v=new cr(i,u,b,m,f),r._edges.set(u,v);let B=h===c;return i?(b.undirectedDegree++,m.undirectedDegree++,B&&(b.undirectedLoops++,r._undirectedSelfLoopCount++)):(b.outDegree++,m.inDegree++,B&&(b.directedLoops++,r._directedSelfLoopCount++)),r.multi?v.attachMulti():v.attach(),i?r._undirectedSize++:r._directedSize++,$.key=u,r.emit("edgeAdded",$),[u,!0,P,q]}function hr(r,t){r._edges.delete(t.key);let{source:e,target:i,attributes:u}=t,h=t.undirected,c=e===i;h?(e.undirectedDegree--,i.undirectedDegree--,c&&(e.undirectedLoops--,r._undirectedSelfLoopCount--)):(e.outDegree--,i.inDegree--,c&&(e.directedLoops--,r._directedSelfLoopCount--)),r.multi?t.detachMulti():t.detach(),h?r._undirectedSize--:r._directedSize--,r.emit("edgeDropped",{key:t.key,attributes:u,source:e.key,target:i.key,undirected:h})}var At=class r extends Ai.EventEmitter{constructor(t){if(super(),t=Kt({},Qu,t),typeof t.multi!="boolean")throw new tt(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Yu.has(t.type))throw new tt(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new tt(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let e=t.type==="mixed"?Ti:t.type==="directed"?Li:Gi;ye(this,"NodeDataClass",e);let i="geid_"+Ku()+"_",u=0,h=()=>{let c;do c=i+u++;while(this._edges.has(c));return c};ye(this,"_attributes",{}),ye(this,"_nodes",new Map),ye(this,"_edges",new Map),ye(this,"_directedSize",0),ye(this,"_undirectedSize",0),ye(this,"_directedSelfLoopCount",0),ye(this,"_undirectedSelfLoopCount",0),ye(this,"_edgeKeyGenerator",h),ye(this,"_options",t),Ri.forEach(c=>ye(this,c,this[c])),De(this,"order",()=>this._nodes.size),De(this,"size",()=>this._edges.size),De(this,"directedSize",()=>this._directedSize),De(this,"undirectedSize",()=>this._undirectedSize),De(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),De(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),De(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),De(this,"multi",this._options.multi),De(this,"type",this._options.type),De(this,"allowSelfLoops",this._options.allowSelfLoops),De(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,e){if(this.type==="undirected")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&!u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.out.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,e){if(this.type==="directed")return!1;if(arguments.length===1){let i=""+t,u=this._edges.get(i);return!!u&&u.undirected}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?i.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,e){if(arguments.length===1){let i=""+t;return this._edges.has(i)}else if(arguments.length===2){t=""+t,e=""+e;let i=this._nodes.get(t);return i?typeof i.out<"u"&&i.out.hasOwnProperty(e)||typeof i.undirected<"u"&&i.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,e){if(this.type==="undirected")return;if(t=""+t,e=""+e,this.multi)throw new at("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let i=this._nodes.get(t);if(!i)throw new Z(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.directedEdge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||void 0;if(u)return u.key}undirectedEdge(t,e){if(this.type==="directed")return;if(t=""+t,e=""+e,this.multi)throw new at("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let i=this._nodes.get(t);if(!i)throw new Z(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.undirectedEdge: could not find the "${e}" target node in the graph.`);let u=i.undirected&&i.undirected[e]||void 0;if(u)return u.key}edge(t,e){if(this.multi)throw new at("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new Z(`Graph.edge: could not find the "${e}" target node in the graph.`);let u=i.out&&i.out[e]||i.undirected&&i.undirected[e]||void 0;if(u)return u.key}areDirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in||e in i.out}areOutNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.out}areInNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in i.in}areUndirectedNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:e in i.undirected}areNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(e in i.in||e in i.out)||this.type!=="directed"&&e in i.undirected}areInboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.in||this.type!=="directed"&&e in i.undirected}areOutboundNeighbors(t,e){t=""+t,e=""+e;let i=this._nodes.get(t);if(!i)throw new Z(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in i.out||this.type!=="directed"&&e in i.undirected}inDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree}outDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree}directedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree}undirectedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree}inboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree),i}outboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.outDegree),i}degree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.degree: could not find the "${t}" node in the graph.`);let i=0;return this.type!=="directed"&&(i+=e.undirectedDegree),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree),i}inDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree-e.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree-e.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree-e.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree-e.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree,u+=e.directedLoops),i-u}outboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.outDegree,u+=e.directedLoops),i-u}degreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let i=0,u=0;return this.type!=="directed"&&(i+=e.undirectedDegree,u+=e.undirectedLoops*2),this.type!=="undirected"&&(i+=e.inDegree+e.outDegree,u+=e.directedLoops*2),i-u}source(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.source: could not find the "${t}" edge in the graph.`);return e.source.key}target(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.target: could not find the "${t}" edge in the graph.`);return e.target.key}extremities(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[e.source.key,e.target.key]}opposite(t,e){t=""+t,e=""+e;let i=this._edges.get(e);if(!i)throw new Z(`Graph.opposite: could not find the "${e}" edge in the graph.`);let u=i.source.key,h=i.target.key;if(t===u)return h;if(t===h)return u;throw new Z(`Graph.opposite: the "${t}" node is not attached to the "${e}" edge (${u}, ${h}).`)}hasExtremity(t,e){t=""+t,e=""+e;let i=this._edges.get(t);if(!i)throw new Z(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return i.source.key===e||i.target.key===e}isUndirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return e.undirected}isDirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!e.undirected}isSelfLoop(t){t=""+t;let e=this._edges.get(t);if(!e)throw new Z(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return e.source===e.target}addNode(t,e){return Zu(this,t,e).key}mergeNode(t,e){if(e&&!ee(e))throw new tt(`Graph.mergeNode: invalid attributes. Expecting an object but got "${e}"`);t=""+t,e=e||{};let i=this._nodes.get(t);return i?(e&&(Kt(i.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:i.attributes,data:e})),[t,!1]):(i=new this.NodeDataClass(t,e),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])}updateNode(t,e){if(e&&typeof e!="function")throw new tt(`Graph.updateNode: invalid updater function. Expecting a function but got "${e}"`);t=""+t;let i=this._nodes.get(t);if(i){if(e){let h=i.attributes;i.attributes=e(h),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:i.attributes})}return[t,!1]}let u=e?e({}):{};return i=new this.NodeDataClass(t,u),this._nodes.set(t,i),this.emit("nodeAdded",{key:t,attributes:u}),[t,!0]}dropNode(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new Z(`Graph.dropNode: could not find the "${t}" node in the graph.`);let i;if(this.type!=="undirected"){for(let u in e.out){i=e.out[u];do hr(this,i),i=i.next;while(i)}for(let u in e.in){i=e.in[u];do hr(this,i),i=i.next;while(i)}}if(this.type!=="directed")for(let u in e.undirected){i=e.undirected[u];do hr(this,i),i=i.next;while(i)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:e.attributes})}dropEdge(t){let e;if(arguments.length>1){let i=""+arguments[0],u=""+arguments[1];if(e=me(this,i,u,this.type),!e)throw new Z(`Graph.dropEdge: could not find the "${i}" -> "${u}" edge in the graph.`)}else if(t=""+t,e=this._edges.get(t),!e)throw new Z(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return hr(this,e),this}dropDirectedEdge(t,e){if(arguments.length<2)throw new at("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new at("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,e=""+e;let i=me(this,t,e,"directed");if(!i)throw new Z(`Graph.dropDirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return hr(this,i),this}dropUndirectedEdge(t,e){if(arguments.length<2)throw new at("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new at("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let i=me(this,t,e,"undirected");if(!i)throw new Z(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return hr(this,i),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),e;for(;e=t.next(),e.done!==!0;)e.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,e){if(typeof e!="function")throw new tt("Graph.updateAttribute: updater should be a function.");let i=this._attributes[t];return this._attributes[t]=e(i),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!ee(t))throw new tt("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!ee(t))throw new tt("Graph.mergeAttributes: provided attributes are not a plain object.");return Kt(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new tt("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!_i(e))throw new tt("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._nodes.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,h.attributes=t(h.key,h.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})}updateEachEdgeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!_i(e))throw new tt("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let i=this._edges.values(),u,h,c,f;for(;u=i.next(),u.done!==!0;)h=u.value,c=h.source,f=h.target,h.attributes=t(h.key,h.attributes,c.key,f.key,c.attributes,f.attributes,h.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntry: expecting a callback.");Wr(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");Wr(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");Wr(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");Wr(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new tt("Graph.forEachNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)}findNode(t){if(typeof t!="function")throw new tt("Graph.findNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return u.key}mapNodes(t){if(typeof t!="function")throw new tt("Graph.mapNode: expecting a callback.");let e=this._nodes.values(),i,u,h=new Array(this.order),c=0;for(;i=e.next(),i.done!==!0;)u=i.value,h[c++]=t(u.key,u.attributes);return h}someNode(t){if(typeof t!="function")throw new tt("Graph.someNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,t(u.key,u.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new tt("Graph.everyNode: expecting a callback.");let e=this._nodes.values(),i,u;for(;i=e.next(),i.done!==!0;)if(u=i.value,!t(u.key,u.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new tt("Graph.filterNodes: expecting a callback.");let e=this._nodes.values(),i,u,h=[];for(;i=e.next(),i.done!==!0;)u=i.value,t(u.key,u.attributes)&&h.push(u.key);return h}reduceNodes(t,e){if(typeof t!="function")throw new tt("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new tt("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let i=e,u=this._nodes.values(),h,c;for(;h=u.next(),h.done!==!0;)c=h.value,i=t(i,c.key,c.attributes);return i}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let e=t.next();if(e.done)return e;let i=e.value;return{value:{node:i.key,attributes:i.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),e=0;this._nodes.forEach((u,h)=>{t[e++]=qu(h,u)});let i=new Array(this._edges.size);return e=0,this._edges.forEach((u,h)=>{i[e++]=Wu(this.type,h,u)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:i}}import(t,e=!1){if(t instanceof r)return t.forEachNode((g,d)=>{e?this.mergeNode(g,d):this.addNode(g,d)}),t.forEachEdge((g,d,b,m,v,D,$)=>{e?$?this.mergeUndirectedEdgeWithKey(g,b,m,d):this.mergeDirectedEdgeWithKey(g,b,m,d):$?this.addUndirectedEdgeWithKey(g,b,m,d):this.addDirectedEdgeWithKey(g,b,m,d)}),this;if(!ee(t))throw new tt("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!ee(t.attributes))throw new tt("Graph.import: invalid attributes. Expecting a plain object.");e?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let i,u,h,c,f;if(t.nodes){if(h=t.nodes,!Array.isArray(h))throw new tt("Graph.import: invalid nodes. Expecting an array.");for(i=0,u=h.length;i{let h=Kt({},i.attributes);i=new e.NodeDataClass(u,h),e._nodes.set(u,i)}),e}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new at(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new at("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new at("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let e=this.emptyCopy(t),i=this._edges.values(),u,h;for(;u=i.next(),u.done!==!0;)h=u.value,Ni(e,"copy",!1,h.undirected,h.key,h.source.key,h.target.key,Kt({},h.attributes));return e}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((h,c)=>{t[c]=h.attributes});let e={},i={};this._edges.forEach((h,c)=>{let f=h.undirected?"--":"->",g="",d=h.source.key,b=h.target.key,m;h.undirected&&d>b&&(m=d,d=b,b=m);let v=`(${d})${f}(${b})`;c.startsWith("geid_")?this.multi&&(typeof i[v]>"u"?i[v]=0:i[v]++,g+=`${i[v]}. `):g+=`[${c}]: `,g+=v,e[g]=h.attributes});let u={};for(let h in this)this.hasOwnProperty(h)&&!Ri.has(h)&&typeof this[h]!="function"&&typeof h!="symbol"&&(u[h]=this[h]);return u.attributes=this._attributes,u.nodes=t,u.edges=e,ye(u,"constructor",this.constructor),u}};typeof Symbol<"u"&&(At.prototype[Symbol.for("nodejs.util.inspect.custom")]=At.prototype.inspect);Xu.forEach(r=>{["add","merge","update"].forEach(t=>{let e=r.name(t),i=t==="add"?Ni:Ju;r.generateKey?At.prototype[e]=function(u,h,c){return i(this,e,!0,(r.type||this.type)==="undirected",null,u,h,c,t==="update")}:At.prototype[e]=function(u,h,c,f){return i(this,e,!1,(r.type||this.type)==="undirected",u,h,c,f,t==="update")}})});uu(At);mu(At);Gu(At);Uu(At);var Vr=class extends At{constructor(t){let e=Kt({type:"directed"},t);if("multi"in e&&e.multi!==!1)throw new tt("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="directed")throw new tt('DirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Br=class extends At{constructor(t){let e=Kt({type:"undirected"},t);if("multi"in e&&e.multi!==!1)throw new tt("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="undirected")throw new tt('UndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Kr=class extends At{constructor(t){let e=Kt({multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(e)}},Yr=class extends At{constructor(t){let e=Kt({type:"directed",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="directed")throw new tt('MultiDirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},Xr=class extends At{constructor(t){let e=Kt({type:"undirected",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="undirected")throw new tt('MultiUndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}};function lr(r){r.from=function(t,e){let i=Kt({},t.options,e),u=new r(i);return u.import(t),u}}lr(At);lr(Vr);lr(Br);lr(Kr);lr(Yr);lr(Xr);At.Graph=At;At.DirectedGraph=Vr;At.UndirectedGraph=Br;At.MultiGraph=Kr;At.MultiDirectedGraph=Yr;At.MultiUndirectedGraph=Xr;At.InvalidArgumentsGraphError=tt;At.NotFoundGraphError=Z;At.UsageGraphError=at;var kn=Fr(Es(),1),za=Fr($s(),1),Ua=Fr(Os(),1);function Ee(r,t,e,i){function u(h){return h instanceof e?h:new e(function(c){c(h)})}return new(e||(e=Promise))(function(h,c){function f(b){try{d(i.next(b))}catch(m){c(m)}}function g(b){try{d(i.throw(b))}catch(m){c(m)}}function d(b){b.done?h(b.value):u(b.value).then(f,g)}d((i=i.apply(r,t||[])).next())})}var Mh={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},Ft=class extends Error{constructor(t,e,i){super(t),this.position=e,this.token=i,this.name="ExpressionError"}},ft;(function(r){r[r.STRING=0]="STRING",r[r.NUMBER=1]="NUMBER",r[r.BOOLEAN=2]="BOOLEAN",r[r.NULL=3]="NULL",r[r.IDENTIFIER=4]="IDENTIFIER",r[r.OPERATOR=5]="OPERATOR",r[r.FUNCTION=6]="FUNCTION",r[r.DOT=7]="DOT",r[r.BRACKET_LEFT=8]="BRACKET_LEFT",r[r.BRACKET_RIGHT=9]="BRACKET_RIGHT",r[r.PAREN_LEFT=10]="PAREN_LEFT",r[r.PAREN_RIGHT=11]="PAREN_RIGHT",r[r.COMMA=12]="COMMA",r[r.QUESTION=13]="QUESTION",r[r.COLON=14]="COLON",r[r.DOLLAR=15]="DOLLAR"})(ft||(ft={}));var Ch=new Set([32,9,10,13]),Ph=new Set([43,45,42,47,37,33,38,124,61,60,62]),Nh=new Map([["true",ft.BOOLEAN],["false",ft.BOOLEAN],["null",ft.NULL]]),qn=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),Fh=new Map([[46,ft.DOT],[91,ft.BRACKET_LEFT],[93,ft.BRACKET_RIGHT],[40,ft.PAREN_LEFT],[41,ft.PAREN_RIGHT],[44,ft.COMMA],[63,ft.QUESTION],[58,ft.COLON],[36,ft.DOLLAR]]),Cs=new Map;for(let[r,t]of Fh.entries())Cs.set(r,{type:t,value:String.fromCharCode(r)});function jr(r){return r>=48&&r<=57}function Wn(r){return r>=97&&r<=122||r>=65&&r<=90||r===95}function Ms(r){return Wn(r)||jr(r)}function zh(r){return Ph.has(r)}var Ct;(function(r){r[r.Program=0]="Program",r[r.Literal=1]="Literal",r[r.Identifier=2]="Identifier",r[r.MemberExpression=3]="MemberExpression",r[r.CallExpression=4]="CallExpression",r[r.BinaryExpression=5]="BinaryExpression",r[r.UnaryExpression=6]="UnaryExpression",r[r.ConditionalExpression=7]="ConditionalExpression"})(Ct||(Ct={}));var Uh=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),qh={type:Ct.Literal,value:null},Wh={type:Ct.Literal,value:!0},Vh={type:Ct.Literal,value:!1},Bh=r=>{let t=0,e=r.length,i=()=>t>=e?null:r[t],u=()=>r[t++],h=m=>{let v=i();return v!==null&&v.type===m},c=m=>m.type===ft.OPERATOR?Uh.get(m.value)||-1:m.type===ft.DOT||m.type===ft.BRACKET_LEFT?9:m.type===ft.QUESTION?1:-1,f=m=>{let v,D;if(u().type===ft.DOT){if(!h(ft.IDENTIFIER)){let P=i();throw new Ft("Expected property name",t,P?P.value:"")}let $=u();v={type:Ct.Identifier,name:$.value},D=!1}else{if(v=d(0),!h(ft.BRACKET_RIGHT)){let $=i();throw new Ft("Expected closing bracket",t,$?$.value:"")}u(),D=!0}return{type:Ct.MemberExpression,object:m,property:v,computed:D}},g=()=>{let m=i();if(!m)throw new Ft("Unexpected end of input",t,"");if(m.type===ft.OPERATOR&&(m.value==="!"||m.value==="-")){u();let v=g();return{type:Ct.UnaryExpression,operator:m.value,argument:v,prefix:!0}}switch(m.type){case ft.NUMBER:return u(),{type:Ct.Literal,value:Number(m.value)};case ft.STRING:return u(),{type:Ct.Literal,value:m.value};case ft.BOOLEAN:return u(),m.value==="true"?Wh:Vh;case ft.NULL:return u(),qh;case ft.IDENTIFIER:return u(),{type:Ct.Identifier,name:m.value};case ft.FUNCTION:return(()=>{let v=u(),D=[];if(!h(ft.PAREN_LEFT)){let $=i();throw new Ft("Expected opening parenthesis after function name",t,$?$.value:"")}for(u();;){if(h(ft.PAREN_RIGHT)){u();break}if(!i()){let P=i();throw new Ft("Expected closing parenthesis",t,P?P.value:"")}if(D.length>0){if(!h(ft.COMMA)){let P=i();throw new Ft("Expected comma between function arguments",t,P?P.value:"")}u()}let $=d(0);D.push($)}return{type:Ct.CallExpression,callee:{type:Ct.Identifier,name:v.value},arguments:D}})();case ft.PAREN_LEFT:{u();let v=d(0);if(!h(ft.PAREN_RIGHT)){let D=i();throw new Ft("Expected closing parenthesis",t,D?D.value:"")}return u(),v}default:throw new Ft(`Unexpected token: ${m.type}`,t,m.value)}},d=(m=0)=>{let v=g();for(;t")}u();let q=d(0);v={type:Ct.ConditionalExpression,test:v,consequent:P,alternate:q}}}return v},b=d();return{type:Ct.Program,body:b}},Kh=(r,t,e)=>{let i=t;e&&(i={...t,context:{...t.context,...e}});let u=h=>{switch(h.type){case Ct.Literal:return(c=>c.value)(h);case Ct.Identifier:return(c=>{if(!(c.name in i.context))throw new Ft(`Undefined variable: ${c.name}`);return i.context[c.name]})(h);case Ct.MemberExpression:return(c=>{let f=u(c.object);if(f==null)throw new Ft("Cannot access property of null or undefined");return f[c.computed?u(c.property):c.property.name]})(h);case Ct.CallExpression:return(c=>{let f=i.functions[c.callee.name];if(!f)throw new Ft(`Undefined function: ${c.callee.name}`);return f(...c.arguments.map((g=>u(g))))})(h);case Ct.BinaryExpression:return(c=>{if(c.operator==="&&"){let d=u(c.left);return d&&u(c.right)}if(c.operator==="||")return u(c.left)||u(c.right);let f=u(c.left),g=u(c.right);switch(c.operator){case"+":return f+g;case"-":return f-g;case"*":return f*g;case"/":return f/g;case"%":return f%g;case"===":return f===g;case"!==":return f!==g;case">":return f>g;case">=":return f>=g;case"<":return f{let f=u(c.argument);if(c.prefix)switch(c.operator){case"!":return!f;case"-":if(typeof f!="number")throw new Ft(`Cannot apply unary - to non-number: ${f}`);return-f;default:throw new Ft(`Unknown operator: ${c.operator}`)}throw new Ft(`Postfix operators are not supported: ${c.operator}`)})(h);case Ct.ConditionalExpression:return(c=>{let f=u(c.test);return u(f?c.consequent:c.alternate)})(h);default:throw new Ft(`Evaluation error: Unsupported node type: ${h.type}`)}};return u(r.body)};function Vn(r){let t=(u=>{let h=u,c=h.length,f=new Array(Math.ceil(c/3)),g=0,d=0;function b(q){let B=d+1;d++;let G="",F=!1;for(;d({context:u,functions:h}))({},Mh);return(u={})=>Kh(e,i,u)}function Ps(r,t={}){return Vn(r)(t)}function Ns(r,t){if(typeof r!="string")return;let e=r.trim();if(e)try{return Vn(e),Ps(e,t)}catch{return}}function dr(r){return typeof r=="number"}function Bn(r){if(!r)return[0,0,0];if(dr(r))return[r,r,r];if(Array.isArray(r)&&r.length===0)return[0,0,0];let[t,e=t,i=t]=r;return[t,e,i]}function Fs(r){return dr(r)?!0:Array.isArray(r)?r.every(t=>dr(t)):!1}function _e(r){return r==null}function zs(r){return typeof r=="string"}function Us(r){return typeof r=="function"}function Ar(r,t){if(typeof r=="function")return r;if(typeof r=="string"){let e=r;return(...i)=>{let u={};for(let h=0;hr}function qs(r,t=10,e="node"){if(_e(r))return()=>t;if(zs(r)){let i=Ar(r,[e]);return u=>{let h=i(u);return Fs(h)?h:t}}return Us(r)?r:dr(r)?()=>r:Array.isArray(r)?()=>r:()=>t}var tn=(r,t,e=10,i=0)=>{let u=qs(t,i),h=qs(r,e);return c=>{let[f,g,d]=Bn(h(c)),[b,m,v]=Bn(u(c));return[f+b,g+m,d+v]}};var en=class{constructor(t,e={}){this.edgeIdCounter=new Map,this.nodeMap=Qh(t.nodes,e.node),this.edgeMap=Zh(t.edges||[],e.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let e=this.indexNodeCache.get(t);return e?this.nodeMap.get(e):void 0}nodeIndexOf(t){var e;return this.nodeIndexCache||this.buildNodeIndexCache(),(e=this.nodeIndexCache.get(t))!==null&&e!==void 0?e:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let e=0;this.nodeMap.forEach(i=>t(i,e++))}originalNode(t){let e=this.nodeMap.get(t);return e?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let e=0;this.edgeMap.forEach(i=>t(i,e++))}originalEdge(t){let e=this.edgeMap.get(t);return e?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let e=`${t.source}-${t.target}`,i=this.edgeIdCounter.get(e)||0,u=i===0?e:`${e}-${i}`;return this.edgeIdCounter.set(e,i+1),u}degree(t,e="both"){this.degreeCache||this.buildDegreeCache();let i=this.degreeCache.get(t);return i?i[e]:0}neighbors(t,e="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),e==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(e==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let i=this.inAdjacencyCache.get(t),u=this.outAdjacencyCache.get(t);if(!i&&!u)return[];if(!i)return Array.from(u);if(!u)return Array.from(i);let h=new Set;return i.forEach(c=>h.add(c)),u.forEach(c=>h.add(c)),Array.from(h)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let e=new Map;for(let i of t)e.set(i.id,i);this.nodeMap=e,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:e,target:i}=t;if(t.source===t.target)continue;this.degreeCache.has(e)||this.degreeCache.set(e,{in:0,out:0,both:0});let u=this.degreeCache.get(t.source);u&&(u.out++,u.both++),this.degreeCache.has(i)||this.degreeCache.set(i,{in:0,out:0,both:0});let h=this.degreeCache.get(t.target);h&&(h.in++,h.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((e,i)=>{this.nodeIndexCache.set(i,t),this.indexNodeCache.set(t,i),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Yh=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],Xh=["id","source","target","points"];function Qh(r,t){if(!r)throw new Error("Data.nodes is required");let e=new Map;for(let i of r){let u={_original:i};for(let h of Yh){let c=i[h];_e(c)||(u[h]=c)}if(t){let h=t(i);for(let c in h){let f=h[c];_e(f)||(u[c]=f)}}if(_e(u.id))throw new Error("Node is missing id field");e.set(u.id,u)}return e}function Zh(r,t,e){let i=new Map;for(let u of r){let h={_original:u};for(let c of Xh){let f=u[c];_e(f)||(h[c]=f)}if(t){let c=t(u);for(let f in c){let g=c[f];_e(g)||(h[f]=g)}}if(_e(h.source)||_e(h.target))throw new Error("Edge is missing source or target field");_e(h.id)&&(h.id=e?.(u)),i.set(h.id,h)}return i}var rn=class{constructor(t,e={}){this.graph=new en(t,e)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((e,i)=>{e.sourceNode=this.graph.node(e.source),e.targetNode=this.graph.node(e.target),t(e,i)})}destroy(){this.graph.destroy()}};var Vs=Symbol("Comlink.proxy"),Jh=Symbol("Comlink.endpoint"),Hh=Symbol("Comlink.releaseProxy"),Kn=Symbol("Comlink.finalizer"),sn=Symbol("Comlink.thrown"),Bs=r=>typeof r=="object"&&r!==null||typeof r=="function",ta={canHandle:r=>Bs(r)&&r[Vs],serialize(r){let{port1:t,port2:e}=new MessageChannel;return Ys(r,t),[e,[e]]},deserialize(r){return r.start(),Xn(r)}},ea={canHandle:r=>Bs(r)&&sn in r,serialize({value:r}){let t;return r instanceof Error?t={isError:!0,value:{message:r.message,name:r.name,stack:r.stack}}:t={isError:!1,value:r},[t,[]]},deserialize(r){throw r.isError?Object.assign(new Error(r.value.message),r.value):r.value}},Ks=new Map([["proxy",ta],["throw",ea]]);function ra(r,t){for(let e of r)if(t===e||e==="*"||e instanceof RegExp&&e.test(t))return!0;return!1}function Ys(r,t=globalThis,e=["*"]){t.addEventListener("message",function i(u){if(!u||!u.data)return;if(!ra(e,u.origin)){console.warn(`Invalid origin '${u.origin}' for comlink proxy`);return}let{id:h,type:c,path:f}=Object.assign({path:[]},u.data),g=(u.data.argumentList||[]).map(Je),d;try{let b=f.slice(0,-1).reduce((v,D)=>v[D],r),m=f.reduce((v,D)=>v[D],r);switch(c){case"GET":d=m;break;case"SET":b[f.slice(-1)[0]]=Je(u.data.value),d=!0;break;case"APPLY":d=m.apply(b,g);break;case"CONSTRUCT":{let v=new m(...g);d=ha(v)}break;case"ENDPOINT":{let{port1:v,port2:D}=new MessageChannel;Ys(r,D),d=ua(v,[v])}break;case"RELEASE":d=void 0;break;default:return}}catch(b){d={value:b,[sn]:0}}Promise.resolve(d).catch(b=>({value:b,[sn]:0})).then(b=>{let[m,v]=hn(b);t.postMessage(Object.assign(Object.assign({},m),{id:h}),v),c==="RELEASE"&&(t.removeEventListener("message",i),Xs(t),Kn in r&&typeof r[Kn]=="function"&&r[Kn]())}).catch(b=>{let[m,v]=hn({value:new TypeError("Unserializable return value"),[sn]:0});t.postMessage(Object.assign(Object.assign({},m),{id:h}),v)})}),t.start&&t.start()}function na(r){return r.constructor.name==="MessagePort"}function Xs(r){na(r)&&r.close()}function Xn(r,t){let e=new Map;return r.addEventListener("message",function(u){let{data:h}=u;if(!h||!h.id)return;let c=e.get(h.id);if(c)try{c(h)}finally{e.delete(h.id)}}),Yn(r,e,[],t)}function nn(r){if(r)throw new Error("Proxy has been released and is not useable")}function Qs(r){return gr(r,new Map,{type:"RELEASE"}).then(()=>{Xs(r)})}var on=new WeakMap,un="FinalizationRegistry"in globalThis&&new FinalizationRegistry(r=>{let t=(on.get(r)||0)-1;on.set(r,t),t===0&&Qs(r)});function ia(r,t){let e=(on.get(t)||0)+1;on.set(t,e),un&&un.register(r,t,r)}function sa(r){un&&un.unregister(r)}function Yn(r,t,e=[],i=function(){}){let u=!1,h=new Proxy(i,{get(c,f){if(nn(u),f===Hh)return()=>{sa(h),Qs(r),t.clear(),u=!0};if(f==="then"){if(e.length===0)return{then:()=>h};let g=gr(r,t,{type:"GET",path:e.map(d=>d.toString())}).then(Je);return g.then.bind(g)}return Yn(r,t,[...e,f])},set(c,f,g){nn(u);let[d,b]=hn(g);return gr(r,t,{type:"SET",path:[...e,f].map(m=>m.toString()),value:d},b).then(Je)},apply(c,f,g){nn(u);let d=e[e.length-1];if(d===Jh)return gr(r,t,{type:"ENDPOINT"}).then(Je);if(d==="bind")return Yn(r,t,e.slice(0,-1));let[b,m]=Ws(g);return gr(r,t,{type:"APPLY",path:e.map(v=>v.toString()),argumentList:b},m).then(Je)},construct(c,f){nn(u);let[g,d]=Ws(f);return gr(r,t,{type:"CONSTRUCT",path:e.map(b=>b.toString()),argumentList:g},d).then(Je)}});return ia(h,r),h}function oa(r){return Array.prototype.concat.apply([],r)}function Ws(r){let t=r.map(hn);return[t.map(e=>e[0]),oa(t.map(e=>e[1]))]}var Zs=new WeakMap;function ua(r,t){return Zs.set(r,t),r}function ha(r){return Object.assign(r,{[Vs]:!0})}function hn(r){for(let[t,e]of Ks)if(e.canHandle(r)){let[i,u]=e.serialize(r);return[{type:"HANDLER",name:t,value:i},u]}return[{type:"RAW",value:r},Zs.get(r)||[]]}function Je(r){switch(r.type){case"HANDLER":return Ks.get(r.name).deserialize(r.value);case"RAW":return r.value}}function gr(r,t,e,i){return new Promise(u=>{let h=aa();t.set(h,u),r.start&&r.start(),r.postMessage(Object.assign({id:h},e),i)})}function aa(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var an=class{constructor(){this.worker=null,this.workerApi=null}execute(t,e,i){return Ee(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,e,i)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return Ee(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),i=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:i}),this.workerApi=Xn(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let e=document.currentScript;if(e?.src)return e.src;let i=document.getElementsByTagName("script");for(let u=i.length-1;u>=0;u--){let h=i[u].src;if(h&&(h.includes("index.js")||h.includes("index.min.js")))return h}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let u=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(u!==t)return u}let e=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(e!==t)return e;let i=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(i!==t)return i}return"./worker.js"}};var We=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,e){return Object.assign({},t,e||{})}execute(t,e){return Ee(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,e);let{node:i,edge:u,enableWorker:h}=this.runtimeOptions;this.context=new rn(t,{node:i,edge:u}),this.model=this.context.graph,h&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,e){var i;return Ee(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new an);let u=yield this.supervisor.execute(this.id,t,e);(i=this.context)===null||i===void 0||i.replace(u)}catch(u){console.error("Layout in worker failed, fallback to main thread layout.",u),yield this.layout(e)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function pr(r,t,e=2){if(r.nodeCount()===1){let u=r.firstNode();u.x=t[0],u.y=t[1],e===3&&(u.z=t[2]||0)}}function Js(r,t){let e=r.nodes();return e.sort(t),r.setNodeOrder(e),r}function Hs(r,t="desc"){return Js(r,(e,i)=>{let u=r.degree(e.id),h=r.degree(i.id);return t==="asc"?u-h:h-u})}function to(r,t){return Js(r,(e,i)=>{let u=r.originalNode(e.id),h=r.originalNode(i.id);return t(u,h)})}var wr=r=>{let{width:t,height:e,center:i}=r,u=t??(typeof window<"u"?window.innerWidth:0),h=e??(typeof window<"u"?window.innerHeight:0),c=i??[u/2,h/2];return{width:u,height:h,center:c}};var cn={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},ln=class extends We{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return cn}layout(){return Ee(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=wr(this.options),u=this.model.nodeCount();if(!u||u===1){pr(this.model,i);return}let{sortBy:h,maxLevelDiff:c,sweep:f,clockwise:g,equidistant:d,preventOverlap:b,startAngle:m=cn.startAngle,nodeSize:v,nodeSpacing:D}=this.options,$=!h||h==="degree"?"degree":Ar(h,["node"]);if($==="degree")Hs(this.model);else{let O=(N,A)=>{let nt=$(N),dt=$(A);return nt===dt?0:nt>dt?-1:1};to(this.model,O)}let P=this.model.nodes(),q=new Map;for(let O of P){let N=$==="degree"?this.model.degree(O.id):$(O._original);q.set(O.id,N)}let B=this.model.firstNode(),G=c||q.get(B.id)/4,F=tn(v,D,cn.nodeSize,cn.nodeSpacing),V=new Map;for(let O of P)V.set(O.id,Math.max(...F(O._original)));let z=[{nodes:[]}],ot=z[0];for(let O=0;O0){let A=ot.nodes[0],nt=Math.abs(q.get(A.id)-q.get(N.id));G&&nt>=G&&(ot={nodes:[]},z.push(ot))}ot.nodes.push(N)}for(let O of z){let N=O.nodes.map(A=>V.get(A.id));O.nodeSizes=N,O.maxNodeSize=Math.max(...N)}if(z.forEach(O=>{let N=f===void 0?2*Math.PI-2*Math.PI/O.nodes.length:f;O.dTheta=N/Math.max(1,O.nodes.length-1)}),b){let O=0;for(let N=0;N1){let nt=A.nodeSizes||[],dt=0;for(let ue=0;ue0?dt/yt:0;O=Math.max(Qt,O)}if(A.r=O,N{nt===0&&(N=A.r||0),A.r=N,N+=O})}z.forEach(O=>{let N=O.dTheta||0,A=O.r||0;O.nodes.forEach((nt,dt)=>{let wt=m+(g?1:-1)*N*dt;nt.x=i[0]+A*Math.cos(wt),nt.y=i[1]+A*Math.sin(wt)})})})}};function eo(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function fn(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var t=r.default;if(typeof t=="function"){var e=function i(){var u=!1;try{u=this instanceof i}catch{}return u?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};e.prototype=t.prototype}else e={};return Object.defineProperty(e,"__esModule",{value:!0}),Object.keys(r).forEach(function(i){var u=Object.getOwnPropertyDescriptor(r,i);Object.defineProperty(e,i,u.get?u:{enumerable:!0,get:function(){return r[i]}})}),e}var pt={};var Qn={};_n(Qn,{isAnyArray:()=>Ve});var ca=Object.prototype.toString;function Ve(r){let t=ca.call(r);return t.endsWith("Array]")&&!t.includes("Big")}var ro=fn(Qn);var Zn={};_n(Zn,{default:()=>la});function no(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Ve(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;fc&&(c=r[f]);return c}function io(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Ve(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,i=e===void 0?0:e,u=t.toIndex,h=u===void 0?r.length:u;if(i<0||i>=r.length||!Number.isInteger(i))throw new Error("fromIndex must be a positive integer smaller than length");if(h<=i||h>r.length||!Number.isInteger(h))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var c=r[i],f=i+1;f1&&arguments[1]!==void 0?arguments[1]:{};if(Ve(r)){if(r.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var e;if(t.output!==void 0){if(!Ve(t.output))throw new TypeError("output option must be an array if specified");e=t.output}else e=new Array(r.length);var i=io(r),u=no(r);if(i===u)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var h=t.min,c=h===void 0?t.autoMinMax?i:0:h,f=t.max,g=f===void 0?t.autoMinMax?u:1:f;if(c>=g)throw new RangeError("min option must be smaller than max option");for(var d=(g-c)/(u-i),b=0;b{throw TypeError(r)};var Gu=(r,t,e)=>t in r?hn(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var dt=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports),ni=(r,t)=>{for(var e in t)hn(r,e,{get:t[e],enumerable:!0})},Ou=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ju(t))!Lu.call(r,s)&&s!==e&&hn(r,s,{get:()=>t[s],enumerable:!(n=Ru(t,s))||n.enumerable});return r};var je=(r,t,e)=>(e=r!=null?_u(Tu(r)):{},Ou(t||!r||!r.__esModule?hn(e,"default",{value:r,enumerable:!0}):e,r));var rs=(r,t,e)=>Gu(r,typeof t!="symbol"?t+"":t,e),ii=(r,t,e)=>t.has(r)||es("Cannot "+e);var Te=(r,t,e)=>(ii(r,t,"read from private field"),e?e.call(r):t.get(r)),si=(r,t,e)=>t.has(r)?es("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),cn=(r,t,e,n)=>(ii(r,t,"write to private field"),n?n.call(r,e):t.set(r,e),e),oi=(r,t,e)=>(ii(r,t,"access private method"),e);var ds=dt((rd,ai)=>{"use strict";var Er=typeof Reflect=="object"?Reflect:null,ns=Er&&typeof Er.apply=="function"?Er.apply:function(t,e,n){return Function.prototype.apply.call(t,e,n)},fn;Er&&typeof Er.ownKeys=="function"?fn=Er.ownKeys:Object.getOwnPropertySymbols?fn=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:fn=function(t){return Object.getOwnPropertyNames(t)};function $u(r){console&&console.warn&&console.warn(r)}var ss=Number.isNaN||function(t){return t!==t};function jt(){jt.init.call(this)}ai.exports=jt;ai.exports.once=Nu;jt.EventEmitter=jt;jt.prototype._events=void 0;jt.prototype._eventsCount=0;jt.prototype._maxListeners=void 0;var is=10;function ln(r){if(typeof r!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof r)}Object.defineProperty(jt,"defaultMaxListeners",{enumerable:!0,get:function(){return is},set:function(r){if(typeof r!="number"||r<0||ss(r))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+r+".");is=r}});jt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};jt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||ss(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function os(r){return r._maxListeners===void 0?jt.defaultMaxListeners:r._maxListeners}jt.prototype.getMaxListeners=function(){return os(this)};jt.prototype.emit=function(t){for(var e=[],n=1;n0&&(u=e[0]),u instanceof Error)throw u;var l=new Error("Unhandled error."+(u?" ("+u.message+")":""));throw l.context=u,l}var g=o[t];if(g===void 0)return!1;if(typeof g=="function")ns(g,this,e);else for(var d=g.length,y=fs(g,d),n=0;n0&&u.length>s&&!u.warned){u.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+u.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=r,l.type=t,l.count=u.length,$u(l)}return r}jt.prototype.addListener=function(t,e){return as(this,t,e,!1)};jt.prototype.on=jt.prototype.addListener;jt.prototype.prependListener=function(t,e){return as(this,t,e,!0)};function Mu(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function us(r,t,e){var n={fired:!1,wrapFn:void 0,target:r,type:t,listener:e},s=Mu.bind(n);return s.listener=e,n.wrapFn=s,s}jt.prototype.once=function(t,e){return ln(e),this.on(t,us(this,t,e)),this};jt.prototype.prependOnceListener=function(t,e){return ln(e),this.prependListener(t,us(this,t,e)),this};jt.prototype.removeListener=function(t,e){var n,s,o,u,l;if(ln(e),s=this._events,s===void 0)return this;if(n=s[t],n===void 0)return this;if(n===e||n.listener===e)--this._eventsCount===0?this._events=Object.create(null):(delete s[t],s.removeListener&&this.emit("removeListener",t,n.listener||e));else if(typeof n!="function"){for(o=-1,u=n.length-1;u>=0;u--)if(n[u]===e||n[u].listener===e){l=n[u].listener,o=u;break}if(o<0)return this;o===0?n.shift():Cu(n,o),n.length===1&&(s[t]=n[0]),s.removeListener!==void 0&&this.emit("removeListener",t,l||e)}return this};jt.prototype.off=jt.prototype.removeListener;jt.prototype.removeAllListeners=function(t){var e,n,s;if(n=this._events,n===void 0)return this;if(n.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):n[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete n[t]),this;if(arguments.length===0){var o=Object.keys(n),u;for(s=0;s=0;s--)this.removeListener(t,e[s]);return this};function hs(r,t,e){var n=r._events;if(n===void 0)return[];var s=n[t];return s===void 0?[]:typeof s=="function"?e?[s.listener||s]:[s]:e?Pu(s):fs(s,s.length)}jt.prototype.listeners=function(t){return hs(this,t,!0)};jt.prototype.rawListeners=function(t){return hs(this,t,!1)};jt.listenerCount=function(r,t){return typeof r.listenerCount=="function"?r.listenerCount(t):cs.call(r,t)};jt.prototype.listenerCount=cs;function cs(r){var t=this._events;if(t!==void 0){var e=t[r];if(typeof e=="function")return 1;if(e!==void 0)return e.length}return 0}jt.prototype.eventNames=function(){return this._eventsCount>0?fn(this._events):[]};function fs(r,t){for(var e=new Array(t),n=0;n{function Vh(r){return!r||typeof r!="object"||typeof r=="function"||Array.isArray(r)||r instanceof Set||r instanceof Map||r instanceof RegExp||r instanceof Date}function Ds(r,t){r=r||{};var e={};for(var n in t){var s=r[n],o=t[n];if(!Vh(o)){e[n]=Ds(s,o);continue}s===void 0?e[n]=o:e[n]=s}return e}_s.exports=Ds});var oe=dt((sd,Rs)=>{Rs.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var Gs=dt((od,Ls)=>{function js(r){return function(t,e){return t+Math.floor(r()*(e-t+1))}}var Ts=js(Math.random);Ts.createRandom=js;Ls.exports=Ts});var Cs=dt((ad,Ms)=>{var Kh=Gs().createRandom;function Os(r){var t=Kh(r);return function(e){for(var n=e.length,s=n-1,o=-1;++o{var Yh=Ye(),Xh=oe(),Qh=Cs(),Jh={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function ye(r,t,e,n,s){this.wrappedCircle=s||null,this.children={},this.countChildren=0,this.id=r||null,this.next=null,this.previous=null,this.x=t||null,this.y=e||null,s?this.r=1010101:this.r=n||999}ye.prototype.hasChildren=function(){return this.countChildren>0};ye.prototype.addChild=function(r,t){this.children[r]=t,++this.countChildren};ye.prototype.getChild=function(r){if(!this.children.hasOwnProperty(r)){var t=new ye;this.children[r]=t,++this.countChildren}return this.children[r]};ye.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var r=this;for(var t in r.children){var e=r.children[t];e.x+=r.x,e.y+=r.y,e.applyPositionToChildren()}}};function Fs(r,t,e){for(var n in t.children){var s=t.children[n];s.hasChildren()?Fs(r,s,e):e[s.id]={x:s.x,y:s.y}}}function bn(r,t){var e=r.r-t.r,n=t.x-r.x,s=t.y-r.y;return e<0||e*e0&&e*e>n*n+s*s}function di(r,t){for(var e=0;eg?(s=(d+g-o)/(2*d),l=Math.sqrt(Math.max(0,g/d-s*s)),e.x=r.x-s*n-l*u,e.y=r.y-s*u+l*n):(s=(d+o-g)/(2*d),l=Math.sqrt(Math.max(0,o/d-s*s)),e.x=t.x+s*n-l*u,e.y=t.y+s*u+l*n)):(e.x=t.x+e.r,e.y=t.y)}function zs(r,t){var e=r.r+t.r-1e-6,n=t.x-r.x,s=t.y-r.y;return e>0&&e*e>n*n+s*s}function rc(r,t){var e=r.length;if(e===0)return 0;var n,s,o,u,l,g,d,y,w,m;if(n=r[0],n.x=0,n.y=0,e<=1)return n.r;if(s=r[1],n.x=-s.r,s.x=n.r,s.y=0,e<=2)return n.r+s.r;o=r[2],Ns(s,n,o),n=new ye(null,null,null,null,n),s=new ye(null,null,null,null,s),o=new ye(null,null,null,null,o),n.next=o.previous=s,s.next=n.previous=o,o.next=s.previous=n;t:for(g=3;g{var ic=Ye(),sc=oe(),oc={dimensions:["x","y"],center:.5,scale:1};function Xs(r,t,e){if(!sc(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=ic(e,oc);var n=e.dimensions;if(!Array.isArray(n)||n.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var s=e.center,o=e.scale,u=Math.PI*2,l=(s-.5)*o,g=t.order,d=n[0],y=n[1];function w(_,G){return G[d]=o*Math.cos(_*u/g)+l,G[y]=o*Math.sin(_*u/g)+l,G}var m=0;if(!r){var x={};return t.forEachNode(function(_){x[_]=w(m++,{})}),x}t.updateEachNodeAttributes(function(_,G){return w(m++,G),G},{attributes:n})}var Qs=Xs.bind(null,!1);Qs.assign=Xs.bind(null,!0);Js.exports=Qs});var ro=dt((cd,eo)=>{var ac=Ye(),uc=oe(),hc={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function Hs(r,t,e){if(!uc(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");e=ac(e,hc);var n=e.dimensions;if(!Array.isArray(n)||n.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var s=n.length,o=e.center,u=e.rng,l=e.scale,g=(o-.5)*l;function d(w){for(var m=0;m{var cc=Ye(),fc=oe(),lc=Math.PI/180,dc={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function no(r,t,e,n){if(!fc(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");n=cc(n,dc),n.degrees&&(e*=lc);var s=n.dimensions;if(!Array.isArray(s)||s.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return r?void 0:{};var o=s[0],u=s[1],l=0,g=0;if(!n.centeredOnZero){var d=1/0,y=-1/0,w=1/0,m=-1/0;t.forEachNode(function(q,L){var P=L[o],B=L[u];Py&&(y=P),Bm&&(m=B)}),l=(d+y)/2,g=(w+m)/2}var x=Math.cos(e),_=Math.sin(e);function G(q){var L=q[o],P=q[u];return q[o]=l+(L-l)*x-(P-g)*_,q[u]=g+(L-l)*_+(P-g)*x,q}if(!r){var M={};return t.forEachNode(function(q,L){var P={};P[o]=L[o],P[u]=L[u],M[q]=G(P)}),M}t.updateEachNodeAttributes(function(q,L){return G(L),L},{attributes:s})}var io=no.bind(null,!1);io.assign=no.bind(null,!0);so.exports=io});var ao=dt(qr=>{qr.circlepack=Ys();qr.circular=Zs();qr.random=ro();qr.rotation=oo()});var Sn=dt(En=>{function gc(r){return typeof r!="number"||isNaN(r)?1:r}function pc(r,t){var e={},n=function(u){return typeof u>"u"?t:u};typeof t=="function"&&(n=t);var s=function(u){return n(u[r])},o=function(){return n(void 0)};return typeof r=="string"?(e.fromAttributes=s,e.fromGraph=function(u,l){return s(u.getNodeAttributes(l))},e.fromEntry=function(u,l){return s(l)}):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},e.fromGraph=function(u,l){return n(r(l,u.getNodeAttributes(l)))},e.fromEntry=function(u,l){return n(r(u,l))}):(e.fromAttributes=o,e.fromGraph=o,e.fromEntry=o),e}function uo(r,t){var e={},n=function(u){return typeof u>"u"?t:u};typeof t=="function"&&(n=t);var s=function(u){return n(u[r])},o=function(){return n(void 0)};return typeof r=="string"?(e.fromAttributes=s,e.fromGraph=function(u,l){return s(u.getEdgeAttributes(l))},e.fromEntry=function(u,l){return s(l)},e.fromPartialEntry=e.fromEntry,e.fromMinimalEntry=e.fromEntry):typeof r=="function"?(e.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},e.fromGraph=function(u,l){var g=u.extremities(l);return n(r(l,u.getEdgeAttributes(l),g[0],g[1],u.getNodeAttributes(g[0]),u.getNodeAttributes(g[1]),u.isUndirected(l)))},e.fromEntry=function(u,l,g,d,y,w,m){return n(r(u,l,g,d,y,w,m))},e.fromPartialEntry=function(u,l,g,d){return n(r(u,l,g,d))},e.fromMinimalEntry=function(u,l){return n(r(u,l))}):(e.fromAttributes=o,e.fromGraph=o,e.fromEntry=o,e.fromMinimalEntry=o),e}En.createNodeValueGetter=pc;En.createEdgeValueGetter=uo;En.createEdgeWeightGetter=function(r){return uo(r,gc)}});var go=dt((gd,lo)=>{var Yt=0,Pt=1,xt=2,At=3,Xe=4,Qe=5,kt=6,ho=7,xn=8,co=9,yc=0,wc=1,mc=2,Ht=0,ke=1,ce=2,cr=3,tr=4,Ft=5,we=6,Ne=7,ze=8,fo=3,Ge=10,vc=3,ue=9,gi=10;lo.exports=function(t,e,n){var s,o,u,l,g,d,y,w,m,x,_=e.length,G=n.length,M=t.adjustSizes,q=t.barnesHutTheta*t.barnesHutTheta,L,P,B,U,rt,O,N,T=[];for(u=0;u<_;u+=Ge)e[u+Xe]=e[u+xt],e[u+Qe]=e[u+At],e[u+xt]=0,e[u+At]=0;if(t.outboundAttractionDistribution){for(L=0,u=0;u<_;u+=Ge)L+=e[u+kt];L/=_/Ge}if(t.barnesHutOptimize){var it=1/0,gt=-1/0,wt=1/0,zt=-1/0,mt,ee,le;for(u=0;u<_;u+=Ge)it=Math.min(it,e[u+Yt]),gt=Math.max(gt,e[u+Yt]),wt=Math.min(wt,e[u+Pt]),zt=Math.max(zt,e[u+Pt]);var pt=gt-it,j=zt-wt;for(pt>j?(wt-=(pt-j)/2,zt=wt+pt):(it-=(j-pt)/2,gt=it+j),T[0+Ht]=-1,T[0+ke]=(it+gt)/2,T[0+ce]=(wt+zt)/2,T[0+cr]=Math.max(gt-it,zt-wt),T[0+tr]=-1,T[0+Ft]=-1,T[0+we]=0,T[0+Ne]=0,T[0+ze]=0,s=1,u=0;u<_;u+=Ge)for(o=0,le=fo;;)if(T[o+Ft]>=0){e[u+Yt]=0)if(O=Math.pow(e[u+Yt]-T[o+Ne],2)+Math.pow(e[u+Pt]-T[o+ze],2),x=T[o+cr],4*x*x/O0?(N=P*e[u+kt]*T[o+we]/O,e[u+xt]+=B*N,e[u+At]+=U*N):O<0&&(N=-P*e[u+kt]*T[o+we]/Math.sqrt(O),e[u+xt]+=B*N,e[u+At]+=U*N):O>0&&(N=P*e[u+kt]*T[o+we]/O,e[u+xt]+=B*N,e[u+At]+=U*N),o=T[o+tr],o<0)break;continue}else{o=T[o+Ft];continue}else{if(d=T[o+Ht],d>=0&&d!==u&&(B=e[u+Yt]-e[d+Yt],U=e[u+Pt]-e[d+Pt],O=B*B+U*U,M===!0?O>0?(N=P*e[u+kt]*e[d+kt]/O,e[u+xt]+=B*N,e[u+At]+=U*N):O<0&&(N=-P*e[u+kt]*e[d+kt]/Math.sqrt(O),e[u+xt]+=B*N,e[u+At]+=U*N):O>0&&(N=P*e[u+kt]*e[d+kt]/O,e[u+xt]+=B*N,e[u+At]+=U*N)),o=T[o+tr],o<0)break;continue}else for(P=t.scalingRatio,l=0;l<_;l+=Ge)for(g=0;g0?(N=P*e[l+kt]*e[g+kt]/O/O,e[l+xt]+=B*N,e[l+At]+=U*N,e[g+xt]-=B*N,e[g+At]-=U*N):O<0&&(N=100*P*e[l+kt]*e[g+kt],e[l+xt]+=B*N,e[l+At]+=U*N,e[g+xt]-=B*N,e[g+At]-=U*N)):(O=Math.sqrt(B*B+U*U),O>0&&(N=P*e[l+kt]*e[g+kt]/O/O,e[l+xt]+=B*N,e[l+At]+=U*N,e[g+xt]-=B*N,e[g+At]-=U*N));for(m=t.gravity/t.scalingRatio,P=t.scalingRatio,u=0;u<_;u+=Ge)N=0,B=e[u+Yt],U=e[u+Pt],O=Math.sqrt(Math.pow(B,2)+Math.pow(U,2)),t.strongGravityMode?O>0&&(N=P*e[u+kt]*m):O>0&&(N=P*e[u+kt]*m/O),e[u+xt]-=B*N,e[u+At]-=U*N;for(P=1*(t.outboundAttractionDistribution?L:1),y=0;y0&&(N=-P*rt*Math.log(1+O)/O/e[l+kt]):O>0&&(N=-P*rt*Math.log(1+O)/O):t.outboundAttractionDistribution?O>0&&(N=-P*rt/e[l+kt]):O>0&&(N=-P*rt)):(O=Math.sqrt(Math.pow(B,2)+Math.pow(U,2)),t.linLogMode?t.outboundAttractionDistribution?O>0&&(N=-P*rt*Math.log(1+O)/O/e[l+kt]):O>0&&(N=-P*rt*Math.log(1+O)/O):t.outboundAttractionDistribution?(O=1,N=-P*rt/e[l+kt]):(O=1,N=-P*rt)),O>0&&(e[l+xt]+=B*N,e[l+At]+=U*N,e[g+xt]-=B*N,e[g+At]-=U*N);var de,De,Q,I,bt,_t;if(M===!0)for(u=0;u<_;u+=Ge)e[u+co]!==1&&(de=Math.sqrt(Math.pow(e[u+xt],2)+Math.pow(e[u+At],2)),de>gi&&(e[u+xt]=e[u+xt]*gi/de,e[u+At]=e[u+At]*gi/de),De=e[u+kt]*Math.sqrt((e[u+Xe]-e[u+xt])*(e[u+Xe]-e[u+xt])+(e[u+Qe]-e[u+At])*(e[u+Qe]-e[u+At])),Q=Math.sqrt((e[u+Xe]+e[u+xt])*(e[u+Xe]+e[u+xt])+(e[u+Qe]+e[u+At])*(e[u+Qe]+e[u+At]))/2,I=.1*Math.log(1+Q)/(1+Math.sqrt(De)),bt=e[u+Yt]+e[u+xt]*(I/t.slowDown),e[u+Yt]=bt,_t=e[u+Pt]+e[u+At]*(I/t.slowDown),e[u+Pt]=_t);else for(u=0;u<_;u+=Ge)e[u+co]!==1&&(De=e[u+kt]*Math.sqrt((e[u+Xe]-e[u+xt])*(e[u+Xe]-e[u+xt])+(e[u+Qe]-e[u+At])*(e[u+Qe]-e[u+At])),Q=Math.sqrt((e[u+Xe]+e[u+xt])*(e[u+Xe]+e[u+xt])+(e[u+Qe]+e[u+At])*(e[u+Qe]+e[u+At]))/2,I=e[u+ho]*Math.log(1+Q)/(1+Math.sqrt(De)),e[u+ho]=Math.min(1,Math.sqrt(I*(Math.pow(e[u+xt],2)+Math.pow(e[u+At],2))/(1+Math.sqrt(De)))),bt=e[u+Yt]+e[u+xt]*(I/t.slowDown),e[u+Yt]=bt,_t=e[u+Pt]+e[u+At]*(I/t.slowDown),e[u+Pt]=_t);return{}}});var pi=dt(er=>{var Ur=10,po=3;er.assign=function(r){r=r||{};var t=Array.prototype.slice.call(arguments).slice(1),e,n,s;for(e=0,s=t.length;e=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in r&&typeof r.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in r&&!(typeof r.gravity=="number"&&r.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in r&&!(typeof r.slowDown=="number"||r.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in r&&typeof r.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in r&&!(typeof r.barnesHutTheta=="number"&&r.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};er.graphToByteArrays=function(r,t){var e=r.order,n=r.size,s={},o,u=new Float32Array(e*Ur),l=new Float32Array(n*po);return o=0,r.forEachNode(function(g,d){s[g]=o,u[o]=d.x,u[o+1]=d.y,u[o+2]=0,u[o+3]=0,u[o+4]=0,u[o+5]=0,u[o+6]=1,u[o+7]=1,u[o+8]=d.size||1,u[o+9]=d.fixed?1:0,o+=Ur}),o=0,r.forEachEdge(function(g,d,y,w,m,x,_){var G=s[y],M=s[w],q=t(g,d,y,w,m,x,_);u[G+6]+=q,u[M+6]+=q,l[o]=G,l[o+1]=M,l[o+2]=q,o+=po}),{nodes:u,edges:l}};er.assignLayoutChanges=function(r,t,e){var n=0;r.updateEachNodeAttributes(function(s,o){return o.x=t[n],o.y=t[n+1],n+=Ur,e?e(s,o):o})};er.readGraphPositions=function(r,t){var e=0;r.forEachNode(function(n,s){t[e]=s.x,t[e+1]=s.y,e+=Ur})};er.collectLayoutChanges=function(r,t,e){for(var n=r.nodes(),s={},o=0,u=0,l=t.length;o{yo.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var vo=dt((wd,mo)=>{var bc=oe(),Ec=Sn().createEdgeWeightGetter,Sc=go(),Wr=pi(),xc=yi();function wo(r,t,e){if(!bc(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof e=="number"&&(e={iterations:e});var n=e.iterations;if(typeof n!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(n<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var s=Ec("getEdgeWeight"in e?e.getEdgeWeight:"weight").fromEntry,o=typeof e.outputReducer=="function"?e.outputReducer:null,u=Wr.assign({},xc,e.settings),l=Wr.validateSettings(u);if(l)throw new Error("graphology-layout-forceatlas2: "+l.message);var g=Wr.graphToByteArrays(t,s),d;for(d=0;d2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var wi=wo.bind(null,!1);wi.assign=wo.bind(null,!0);wi.inferSettings=Ac;mo.exports=wi});var Eo=dt((md,bo)=>{bo.exports=function(){var t,e,n={};(function(){var o=0,u=1,l=2,g=3,d=4,y=5,w=6,m=7,x=8,_=9,G=0,M=1,q=2,L=0,P=1,B=2,U=3,rt=4,O=5,N=6,T=7,it=8,gt=3,wt=10,zt=3,mt=9,ee=10;n.exports=function(pt,j,de){var De,Q,I,bt,_t,X,ge,Kt,ot,$r,Ee=j.length,ei=de.length,ur=pt.adjustSizes,ri=pt.barnesHutTheta*pt.barnesHutTheta,gr,Rt,Et,St,Se,nt,at,z=[];for(I=0;Iyr?(pe-=(pr-yr)/2,He=pe+pr):(re-=(yr-pr)/2,Me=re+yr),z[0+L]=-1,z[0+P]=(re+Me)/2,z[0+B]=(pe+He)/2,z[0+U]=Math.max(Me-re,He-pe),z[0+rt]=-1,z[0+O]=-1,z[0+N]=0,z[0+T]=0,z[0+it]=0,De=1,I=0;I=0){j[I+o]=0)if(nt=Math.pow(j[I+o]-z[Q+T],2)+Math.pow(j[I+u]-z[Q+it],2),$r=z[Q+U],4*$r*$r/nt0?(at=Rt*j[I+w]*z[Q+N]/nt,j[I+l]+=Et*at,j[I+g]+=St*at):nt<0&&(at=-Rt*j[I+w]*z[Q+N]/Math.sqrt(nt),j[I+l]+=Et*at,j[I+g]+=St*at):nt>0&&(at=Rt*j[I+w]*z[Q+N]/nt,j[I+l]+=Et*at,j[I+g]+=St*at),Q=z[Q+rt],Q<0)break;continue}else{Q=z[Q+O];continue}else{if(X=z[Q+L],X>=0&&X!==I&&(Et=j[I+o]-j[X+o],St=j[I+u]-j[X+u],nt=Et*Et+St*St,ur===!0?nt>0?(at=Rt*j[I+w]*j[X+w]/nt,j[I+l]+=Et*at,j[I+g]+=St*at):nt<0&&(at=-Rt*j[I+w]*j[X+w]/Math.sqrt(nt),j[I+l]+=Et*at,j[I+g]+=St*at):nt>0&&(at=Rt*j[I+w]*j[X+w]/nt,j[I+l]+=Et*at,j[I+g]+=St*at)),Q=z[Q+rt],Q<0)break;continue}else for(Rt=pt.scalingRatio,bt=0;bt0?(at=Rt*j[bt+w]*j[_t+w]/nt/nt,j[bt+l]+=Et*at,j[bt+g]+=St*at,j[_t+l]-=Et*at,j[_t+g]-=St*at):nt<0&&(at=100*Rt*j[bt+w]*j[_t+w],j[bt+l]+=Et*at,j[bt+g]+=St*at,j[_t+l]-=Et*at,j[_t+g]-=St*at)):(nt=Math.sqrt(Et*Et+St*St),nt>0&&(at=Rt*j[bt+w]*j[_t+w]/nt/nt,j[bt+l]+=Et*at,j[bt+g]+=St*at,j[_t+l]-=Et*at,j[_t+g]-=St*at));for(ot=pt.gravity/pt.scalingRatio,Rt=pt.scalingRatio,I=0;I0&&(at=Rt*j[I+w]*ot):nt>0&&(at=Rt*j[I+w]*ot/nt),j[I+l]-=Et*at,j[I+g]-=St*at;for(Rt=1*(pt.outboundAttractionDistribution?gr:1),ge=0;ge0&&(at=-Rt*Se*Math.log(1+nt)/nt/j[bt+w]):nt>0&&(at=-Rt*Se*Math.log(1+nt)/nt):pt.outboundAttractionDistribution?nt>0&&(at=-Rt*Se/j[bt+w]):nt>0&&(at=-Rt*Se)):(nt=Math.sqrt(Math.pow(Et,2)+Math.pow(St,2)),pt.linLogMode?pt.outboundAttractionDistribution?nt>0&&(at=-Rt*Se*Math.log(1+nt)/nt/j[bt+w]):nt>0&&(at=-Rt*Se*Math.log(1+nt)/nt):pt.outboundAttractionDistribution?(nt=1,at=-Rt*Se/j[bt+w]):(nt=1,at=-Rt*Se)),nt>0&&(j[bt+l]+=Et*at,j[bt+g]+=St*at,j[_t+l]-=Et*at,j[_t+g]-=St*at);var wr,hr,mr,Ce,vr,br;if(ur===!0)for(I=0;Iee&&(j[I+l]=j[I+l]*ee/wr,j[I+g]=j[I+g]*ee/wr),hr=j[I+w]*Math.sqrt((j[I+d]-j[I+l])*(j[I+d]-j[I+l])+(j[I+y]-j[I+g])*(j[I+y]-j[I+g])),mr=Math.sqrt((j[I+d]+j[I+l])*(j[I+d]+j[I+l])+(j[I+y]+j[I+g])*(j[I+y]+j[I+g]))/2,Ce=.1*Math.log(1+mr)/(1+Math.sqrt(hr)),vr=j[I+o]+j[I+l]*(Ce/pt.slowDown),j[I+o]=vr,br=j[I+u]+j[I+g]*(Ce/pt.slowDown),j[I+u]=br);else for(I=0;I{var kc=Eo(),Ic=oe(),Dc=Sn().createEdgeWeightGetter,Ir=pi(),_c=yi();function rr(r,t){if(t=t||{},!Ic(r))throw new Error("graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.");var e=Dc("getEdgeWeight"in t?t.getEdgeWeight:"weight").fromEntry,n=Ir.assign({},_c,t.settings),s=Ir.validateSettings(n);if(s)throw new Error("graphology-layout-forceatlas2/worker: "+s.message);this.worker=null,this.graph=r,this.settings=n,this.getEdgeWeight=e,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer=="function"?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var o=void 0,u=this;this.handleGraphUpdate=function(){u.worker&&u.worker.terminate(),o&&clearTimeout(o),o=setTimeout(function(){o=void 0,u.spawnWorker()},0)},r.on("nodeAdded",this.handleGraphUpdate),r.on("edgeAdded",this.handleGraphUpdate),r.on("nodeDropped",this.handleGraphUpdate),r.on("edgeDropped",this.handleGraphUpdate),this.spawnWorker()}rr.prototype.isRunning=function(){return this.running};rr.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=Ir.createWorker(kc),this.worker.addEventListener("message",this.handleMessage),this.running&&(this.running=!1,this.start())};rr.prototype.handleMessage=function(r){if(this.running){var t=new Float32Array(r.data.nodes);Ir.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&Ir.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}};rr.prototype.askForIterations=function(r){var t=this.matrices,e={settings:this.settings,nodes:t.nodes.buffer},n=[t.nodes.buffer];return r&&(e.edges=t.edges.buffer,n.push(t.edges.buffer)),this.worker.postMessage(e,n),this};rr.prototype.start=function(){if(this.killed)throw new Error("graphology-layout-forceatlas2/worker.start: layout was killed.");return this.running?this:(this.matrices=Ir.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)};rr.prototype.stop=function(){return this.running=!1,this};rr.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener("nodeAdded",this.handleGraphUpdate),this.graph.removeListener("edgeAdded",this.handleGraphUpdate),this.graph.removeListener("nodeDropped",this.handleGraphUpdate),this.graph.removeListener("edgeDropped",this.handleGraphUpdate)};So.exports=rr});var ga=dt(Kn=>{var $f=oe();function Lr(r,t,e,n){var s=t+"Centrality";if(!$f(e))throw new Error("graphology-centrality/"+s+": the given graph is not a valid graphology instance.");if(t!=="degree"&&e.type==="undirected")throw new Error("graphology-centrality/"+s+": cannot compute "+t+" centrality on an undirected graph.");n=n||{};var o=n.nodeCentralityAttribute||s,u=e.order-1,l=e[t].bind(e);if(r){e.updateEachNodeAttributes(function(d,y){return y[o]=l(d)/u,y},{attributes:[o]});return}var g={};return e.forEachNode(function(d){g[d]=l(d)/u}),g}var fa=Lr.bind(null,!1,"degree"),la=Lr.bind(null,!1,"inDegree"),da=Lr.bind(null,!1,"outDegree");fa.assign=Lr.bind(null,!0,"degree");la.assign=Lr.bind(null,!0,"inDegree");da.assign=Lr.bind(null,!0,"outDegree");Kn.degreeCentrality=fa;Kn.inDegreeCentrality=la;Kn.outDegreeCentrality=da});var pa=dt(Fi=>{Fi.ARRAY_BUFFER_SUPPORT=typeof ArrayBuffer<"u";Fi.SYMBOL_SUPPORT=typeof Symbol<"u"});var Yn=dt((Zg,wa)=>{var ya=pa(),Mf=ya.ARRAY_BUFFER_SUPPORT,Cf=ya.SYMBOL_SUPPORT;wa.exports=function(t,e){var n,s,o,u,l;if(!t)throw new Error("obliterator/forEach: invalid iterable.");if(typeof e!="function")throw new Error("obliterator/forEach: expecting a callback.");if(Array.isArray(t)||Mf&&ArrayBuffer.isView(t)||typeof t=="string"||t.toString()==="[object Arguments]"){for(o=0,u=t.length;o{var Pf=Math.pow(2,8)-1,Nf=Math.pow(2,16)-1,zf=Math.pow(2,32)-1,Ff=Math.pow(2,7)-1,qf=Math.pow(2,15)-1,Uf=Math.pow(2,31)-1;qe.getPointerArray=function(r){var t=r-1;if(t<=Pf)return Uint8Array;if(t<=Nf)return Uint16Array;if(t<=zf)return Uint32Array;throw new Error("mnemonist: Pointer Array of size > 4294967295 is not supported.")};qe.getSignedPointerArray=function(r){var t=r-1;return t<=Ff?Int8Array:t<=qf?Int16Array:t<=Uf?Int32Array:Float64Array};qe.getNumberType=function(r){return r===(r|0)?Math.sign(r)===-1?r<=127&&r>=-128?Int8Array:r<=32767&&r>=-32768?Int16Array:Int32Array:r<=255?Uint8Array:r<=65535?Uint16Array:Uint32Array:Float64Array};var Wf={Uint8Array:1,Int8Array:2,Uint16Array:3,Int16Array:4,Uint32Array:5,Int32Array:6,Float32Array:7,Float64Array:8};qe.getMinimalRepresentation=function(r,t){var e=null,n=0,s,o,u,l,g;for(l=0,g=r.length;ln&&(n=s,e=o);return e};qe.isTypedArray=function(r){return typeof ArrayBuffer<"u"&&ArrayBuffer.isView(r)};qe.concat=function(){var r=0,t,e,n;for(t=0,n=arguments.length;t{var ma=Yn(),va=Zr();function Bf(r){return Array.isArray(r)||va.isTypedArray(r)}function qi(r){if(typeof r.length=="number")return r.length;if(typeof r.size=="number")return r.size}function Vf(r){var t=qi(r),e=typeof t=="number"?new Array(t):[],n=0;return ma(r,function(s){e[n++]=s}),e}function Kf(r){var t=qi(r),e=typeof t=="number"?va.getPointerArray(t):Array,n=typeof t=="number"?new Array(t):[],s=typeof t=="number"?new e(t):[],o=0;return ma(r,function(u){n[o]=u,s[o]=o++}),[n,s]}Hr.isArrayLike=Bf;Hr.guessLength=qi;Hr.toArray=Vf;Hr.toArrayWithIndices=Kf});var tn=dt((ep,ba)=>{function Ue(r){if(typeof r!="function")throw new Error("obliterator/iterator: expecting a function!");this.next=r}typeof Symbol<"u"&&(Ue.prototype[Symbol.iterator]=function(){return this});Ue.of=function(){var r=arguments,t=r.length,e=0;return new Ue(function(){return e>=t?{done:!0}:{done:!1,value:r[e++]}})};Ue.empty=function(){var r=new Ue(function(){return{done:!0}});return r};Ue.fromSequence=function(r){var t=0,e=r.length;return new Ue(function(){return t>=e?{done:!0}:{done:!1,value:r[t++]}})};Ue.is=function(r){return r instanceof Ue?!0:typeof r=="object"&&r!==null&&typeof r.next=="function"};ba.exports=Ue});var Wi=dt((rp,Sa)=>{var Ui=Xn(),Ea=tn();function Bt(r,t){if(arguments.length<2)throw new Error("mnemonist/fixed-deque: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-deque: `capacity` should be a positive number.");this.ArrayClass=r,this.capacity=t,this.items=new r(this.capacity),this.clear()}Bt.prototype.clear=function(){this.start=0,this.size=0};Bt.prototype.push=function(r){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.push: deque capacity ("+this.capacity+") exceeded!");var t=this.start+this.size;return t>=this.capacity&&(t-=this.capacity),this.items[t]=r,++this.size};Bt.prototype.unshift=function(r){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.unshift: deque capacity ("+this.capacity+") exceeded!");var t=this.start-1;return this.start===0&&(t=this.capacity-1),this.items[t]=r,this.start=t,++this.size};Bt.prototype.pop=function(){if(this.size!==0){this.size--;var r=this.start+this.size;return r>=this.capacity&&(r-=this.capacity),this.items[r]}};Bt.prototype.shift=function(){if(this.size!==0){var r=this.start;return this.size--,this.start++,this.start===this.capacity&&(this.start=0),this.items[r]}};Bt.prototype.peekFirst=function(){if(this.size!==0)return this.items[this.start]};Bt.prototype.peekLast=function(){if(this.size!==0){var r=this.start+this.size-1;return r>=this.capacity&&(r-=this.capacity),this.items[r]}};Bt.prototype.get=function(r){if(!(this.size===0||r>=this.capacity))return r=this.start+r,r>=this.capacity&&(r-=this.capacity),this.items[r]};Bt.prototype.forEach=function(r,t){t=arguments.length>1?t:this;for(var e=this.capacity,n=this.size,s=this.start,o=0;o=e)return{done:!0};var o=r[n];return n++,s++,n===t&&(n=0),{value:o,done:!1}})};Bt.prototype.entries=function(){var r=this.items,t=this.capacity,e=this.size,n=this.start,s=0;return new Ea(function(){if(s>=e)return{done:!0};var o=r[n];return n++,n===t&&(n=0),{value:[s++,o],done:!1}})};typeof Symbol<"u"&&(Bt.prototype[Symbol.iterator]=Bt.prototype.values);Bt.prototype.inspect=function(){var r=this.toArray();return r.type=this.ArrayClass.name,r.capacity=this.capacity,Object.defineProperty(r,"constructor",{value:Bt,enumerable:!1}),r};typeof Symbol<"u"&&(Bt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Bt.prototype.inspect);Bt.from=function(r,t,e){if(arguments.length<3&&(e=Ui.guessLength(r),typeof e!="number"))throw new Error("mnemonist/fixed-deque.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new Bt(t,e);if(Ui.isArrayLike(r)){var s,o;for(s=0,o=r.length;s{var xa=tn(),Bi=Xn();function Zt(r,t){if(arguments.length<2)throw new Error("mnemonist/fixed-stack: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-stack: `capacity` should be a positive number.");this.capacity=t,this.ArrayClass=r,this.items=new this.ArrayClass(this.capacity),this.clear()}Zt.prototype.clear=function(){this.size=0};Zt.prototype.push=function(r){if(this.size===this.capacity)throw new Error("mnemonist/fixed-stack.push: stack capacity ("+this.capacity+") exceeded!");return this.items[this.size++]=r,this.size};Zt.prototype.pop=function(){if(this.size!==0)return this.items[--this.size]};Zt.prototype.peek=function(){return this.items[this.size-1]};Zt.prototype.forEach=function(r,t){t=arguments.length>1?t:this;for(var e=0,n=this.items.length;e=t)return{done:!0};var n=r[t-e-1];return e++,{value:n,done:!1}})};Zt.prototype.entries=function(){var r=this.items,t=this.size,e=0;return new xa(function(){if(e>=t)return{done:!0};var n=r[t-e-1];return{value:[e++,n],done:!1}})};typeof Symbol<"u"&&(Zt.prototype[Symbol.iterator]=Zt.prototype.values);Zt.prototype.toString=function(){return this.toArray().join(",")};Zt.prototype.toJSON=function(){return this.toArray()};Zt.prototype.inspect=function(){var r=this.toArray();return r.type=this.ArrayClass.name,r.capacity=this.capacity,Object.defineProperty(r,"constructor",{value:Zt,enumerable:!1}),r};typeof Symbol<"u"&&(Zt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Zt.prototype.inspect);Zt.from=function(r,t,e){if(arguments.length<3&&(e=Bi.guessLength(r),typeof e!="number"))throw new Error("mnemonist/fixed-stack.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new Zt(t,e);if(Bi.isArrayLike(r)){var s,o;for(s=0,o=r.length;s{var Yf=function(r,t){return rt?1:0},Xf=function(r,t){return rt?-1:0};function Qf(r){return function(t,e){return r(e,t)}}function Jf(r){return r===2?function(t,e){return t[0]e[0]?1:t[1]e[1]?1:0}:function(t,e){for(var n=0;ne[n])return 1;n++}return 0}}en.DEFAULT_COMPARATOR=Yf;en.DEFAULT_REVERSE_COMPARATOR=Xf;en.reverseComparator=Qf;en.createTupleComparator=Jf});var Ta=dt((sp,ja)=>{var Qn=Yn(),Da=Ia(),We=Xn(),Zn=Da.DEFAULT_COMPARATOR,Vi=Da.reverseComparator;function Ki(r,t,e,n){for(var s=t[n],o,u;n>e;){if(o=n-1>>1,u=t[o],r(s,u)<0){t[n]=u,n=o;continue}break}t[n]=s}function rn(r,t,e){for(var n=t.length,s=e,o=t[e],u=2*e+1,l;u=0&&(u=l),t[e]=t[u],e=u,u=2*e+1;t[e]=o,Ki(r,t,s,e)}function _a(r,t,e){t.push(e),Ki(r,t,0,t.length-1)}function Yi(r,t){var e=t.pop();if(t.length!==0){var n=t[0];return t[0]=e,rn(r,t,0),n}return e}function Gr(r,t,e){if(t.length===0)throw new Error("mnemonist/heap.replace: cannot pop an empty heap.");var n=t[0];return t[0]=e,rn(r,t,0),n}function Ra(r,t,e){var n;return t.length!==0&&r(t[0],e)<0&&(n=t[0],t[0]=e,e=n,rn(r,t,0)),e}function dr(r,t){for(var e=t.length,n=e>>1,s=n;--s>=0;)rn(r,t,s)}function Xi(r,t){for(var e=t.length,n=0,s=new Array(e);n=e.length)return e.slice().sort(r);for(g=e.slice(0,t),dr(n,g),s=t,o=e.length;s0&&Gr(n,g,e[s]);return g.sort(r)}var d=We.guessLength(e);return d!==null&&d0&&Gr(n,g,y)),s++}),g.length>s&&(g.length=s),g.sort(r)}function Hf(r,t,e){arguments.length===2&&(e=t,t=r,r=Zn);var n=Vi(r),s,o,u,l=-1/0,g;if(t===1){if(We.isArrayLike(e)){for(s=0,o=e.length;s0)&&(l=u);return g=new e.constructor(1),g[0]=l,g}return Qn(e,function(y){(l===-1/0||r(y,l)>0)&&(l=y)}),[l]}if(We.isArrayLike(e)){if(t>=e.length)return e.slice().sort(n);for(g=e.slice(0,t),dr(r,g),s=t,o=e.length;s0&&Gr(r,g,e[s]);return g.sort(n)}var d=We.guessLength(e);return d!==null&&d0&&Gr(r,g,y)),s++}),g.length>s&&(g.length=s),g.sort(n)}function Dt(r){if(this.clear(),this.comparator=r||Zn,typeof this.comparator!="function")throw new Error("mnemonist/Heap.constructor: given comparator should be a function.")}Dt.prototype.clear=function(){this.items=[],this.size=0};Dt.prototype.push=function(r){return _a(this.comparator,this.items,r),++this.size};Dt.prototype.peek=function(){return this.items[0]};Dt.prototype.pop=function(){return this.size!==0&&this.size--,Yi(this.comparator,this.items)};Dt.prototype.replace=function(r){return Gr(this.comparator,this.items,r)};Dt.prototype.pushpop=function(r){return Ra(this.comparator,this.items,r)};Dt.prototype.consume=function(){return this.size=0,Xi(this.comparator,this.items)};Dt.prototype.toArray=function(){return Xi(this.comparator,this.items.slice())};Dt.prototype.inspect=function(){var r=this.toArray();return Object.defineProperty(r,"constructor",{value:Dt,enumerable:!1}),r};typeof Symbol<"u"&&(Dt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Dt.prototype.inspect);function Jn(r){if(this.clear(),this.comparator=r||Zn,typeof this.comparator!="function")throw new Error("mnemonist/MaxHeap.constructor: given comparator should be a function.");this.comparator=Vi(this.comparator)}Jn.prototype=Dt.prototype;Dt.from=function(r,t){var e=new Dt(t),n;return We.isArrayLike(r)?n=r.slice():n=We.toArray(r),dr(e.comparator,n),e.items=n,e.size=n.length,e};Jn.from=function(r,t){var e=new Jn(t),n;return We.isArrayLike(r)?n=r.slice():n=We.toArray(r),dr(e.comparator,n),e.items=n,e.size=n.length,e};Dt.siftUp=rn;Dt.siftDown=Ki;Dt.push=_a;Dt.pop=Yi;Dt.replace=Gr;Dt.pushpop=Ra;Dt.heapify=dr;Dt.consume=Xi;Dt.nsmallest=Zf;Dt.nlargest=Hf;Dt.MinHeap=Dt;Dt.MaxHeap=Jn;ja.exports=Dt});var sn=dt(Qi=>{var Hn=Zr(),tl=Sn().createEdgeWeightGetter;function La(r,t){return r==="outbound"||r==="inbound"?t.directedSize+t.undirectedSize*2:r==="in"||r==="out"||r==="directed"?t.directedSize:t.undirectedSize*2}function Je(r,t){t=t||"outbound";var e=r[t+"Neighbors"].bind(r),n=La(t,r),s=Hn.getPointerArray(n),o=Hn.getPointerArray(r.order);this.graph=r,this.neighborhood=new o(n),this.starts=new s(r.order+1),this.nodes=r.nodes();var u={},l,g,d,y,w,m,x=0;for(l=0,g=r.order;l{var el=Wi(),Ga=ka(),rl=Ta(),Oa=Zr(),$a=sn(),nl=$a.NeighborhoodIndex,il=$a.WeightedNeighborhoodIndex;Ji.createUnweightedIndexedBrandes=function(t){var e=new nl(t),n=e.neighborhood,s=e.starts,o=t.order,u=new Ga(Oa.getPointerArray(o),o),l=new Uint32Array(o),g=new Array(o),d=new Int32Array(o),y=new el(Uint32Array,o),w=function(m){var x,_,G,M,q,L,P;for(L=0;Lt[0]?1:r[0]t[1]?1:r[1]t[2]?1:r[2]t[3]?1:r[3]{var ol=oe(),Ca=Ma(),al=Ye(),ul=Ca.createUnweightedIndexedBrandes,hl=Ca.createDijkstraIndexedBrandes,cl={nodeCentralityAttribute:"betweennessCentrality",getEdgeWeight:"weight",normalized:!0};function Pa(r,t,e){if(!ol(t))throw new Error("graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.");e=al(e,cl);var n=e.nodeCentralityAttribute,s=e.normalized,o=e.getEdgeWeight?hl(t,e.getEdgeWeight):ul(t),u=t.order,l,g,d,y,w,m,x,_,G,M,q=new Float64Array(u),L=new Float64Array(u);for(m=0;m{var fl=tn(),ll=Zr().getPointerArray;function be(r){var t=ll(r);this.size=0,this.length=r,this.dense=new t(r),this.sparse=new t(r)}be.prototype.clear=function(){this.size=0};be.prototype.has=function(r){var t=this.sparse[r];return t=this.size||this.dense[t]!==r?!1:(t=this.dense[this.size-1],this.dense[this.sparse[r]]=t,this.sparse[t]=this.sparse[r],this.size--,!0)};be.prototype.forEach=function(r,t){t=arguments.length>1?t:this;for(var e,n=0;n{var dl=oe(),gl=Ye(),pl=Wi(),yl=Ua(),wl=sn().NeighborhoodIndex,ml={nodeCentralityAttribute:"closenessCentrality",wassermanFaust:!1};function Wa(r){this.index=new wl(r,"inbound"),this.queue=new pl(Array,r.order),this.seen=new yl(r.order)}Wa.prototype.fromNode=function(r){var t=this.index,e=this.queue,n=this.seen;n.clear(),e.clear(),n.add(r),e.push([r,0]);for(var s,o,u,l,g,d,y=0,w=0;e.size!==0;)for(s=e.shift(),o=s[0],u=s[1],u!==0&&(y+=u,w+=1),g=t.starts[o+1],l=t.starts[o];l0&&o>1&&(y=g/d,n&&(y*=g/(o-1))),w[u]=y;return r?s.index.assign(e.nodeCentralityAttribute,w):s.index.collect(w)}var Va=Ba.bind(null,!1);Va.assign=Ba.bind(null,!0);Ka.exports=Va});var Za=dt((fp,Ja)=>{var vl=oe(),bl=Ye(),El=sn().WeightedNeighborhoodIndex,Sl={nodeCentralityAttribute:"eigenvectorCentrality",getEdgeWeight:"weight",maxIterations:100,tolerance:1e-6};function xl(r){for(var t=0,e=0,n=0,s=r.length;nt&&(e*=t/o*(t/o),t=o),e+=o===0&&t===0?0:o/t*(o/t)}return t===1/0?1:t*Math.sqrt(e)}function Xa(r,t,e){if(!vl(t))throw new Error("graphology-metrics/centrality/eigenvector: the given graph is not a valid graphology instance.");e=bl(e,Sl);var n=e.maxIterations,s=e.tolerance,o=t.order,u=new El(t,e.getEdgeWeight),l,g,d,y,w=new Float64Array(t.order);for(l=0;l{var Al=oe(),kl=Ye(),Il=sn().WeightedNeighborhoodIndex,Dl={nodePagerankAttribute:"pagerank",getEdgeWeight:"weight",alpha:.85,maxIterations:100,tolerance:1e-6};function Ha(r,t,e){if(!Al(t))throw new Error("graphology-metrics/centrality/pagerank: the given graph is not a valid graphology instance.");e=kl(e,Dl);var n=e.alpha,s=e.maxIterations,o=e.tolerance,u=e.nodePagerankAttribute,l=t.order,g=1/l,d=new Il(t,e.getEdgeWeight),y,w,m,x,_=new Float64Array(t.order),G=new Float64Array(d.weights.length),M=[];for(y=0;y{var _l=oe();nu.exports=function(t){if(!_l(t))throw new Error("graphology-metrics/simple-size: the given graph is not a valid graphology instance.");if(!t.multi)return t.size;var e=0,n=0;function s(){e++}function o(){n++}return t.forEachNode(function(u){t.type!=="directed"&&t.forEachUndirectedNeighbor(u,s),t.type!=="undirected"&&t.forEachOutNeighbor(u,o)}),e/2+n}});var su=dt(Ze=>{var Rl=oe(),jl=iu();function Tl(r,t){return 2*t/(r*(r-1))}function Ll(r,t){return t/(r*(r-1))}function Gl(r,t){var e=r*(r-1);return t/(e+e/2)}function ar(r,t,e){var n,s;if(arguments.length>3){if(n=e,s=arguments[3],typeof n!="number"||n<0)throw new Error("graphology-metrics/density: given order is not a valid number.");if(typeof s!="number"||s<0)throw new Error("graphology-metrics/density: given size is not a valid number.")}else{if(!Rl(e))throw new Error("graphology-metrics/density: given graph is not a valid graphology instance.");n=e.order,s=e.size,e.multi&&t===!1&&(s=jl(e))}if(n<2)return 0;r===null&&(r=e.type),t===null&&(t=e.multi);var o;return r==="undirected"?o=Tl:r==="directed"?o=Ll:o=Gl,o(n,s)}Ze.abstractDensity=ar;Ze.density=ar.bind(null,null,null);Ze.directedDensity=ar.bind(null,"directed",!1);Ze.undirectedDensity=ar.bind(null,"undirected",!1);Ze.mixedDensity=ar.bind(null,"mixed",!1);Ze.multiDirectedDensity=ar.bind(null,"directed",!0);Ze.multiUndirectedDensity=ar.bind(null,"undirected",!0);Ze.multiMixedDensity=ar.bind(null,"mixed",!0)});var uu=dt((pp,au)=>{var ou=tn(),Ol=Yn();function Vt(){this.clear()}Vt.prototype.clear=function(){this.items=[],this.offset=0,this.size=0};Vt.prototype.enqueue=function(r){return this.items.push(r),++this.size};Vt.prototype.dequeue=function(){if(this.size){var r=this.items[this.offset];return++this.offset*2>=this.items.length&&(this.items=this.items.slice(this.offset),this.offset=0),this.size--,r}};Vt.prototype.peek=function(){if(this.size)return this.items[this.offset]};Vt.prototype.forEach=function(r,t){t=arguments.length>1?t:this;for(var e=this.offset,n=0,s=this.items.length;e=r.length)return{done:!0};var e=r[t];return t++,{value:e,done:!1}})};Vt.prototype.entries=function(){var r=this.items,t=this.offset,e=0;return new ou(function(){if(t>=r.length)return{done:!0};var n=r[t];return t++,{value:[e++,n],done:!1}})};typeof Symbol<"u"&&(Vt.prototype[Symbol.iterator]=Vt.prototype.values);Vt.prototype.toString=function(){return this.toArray().join(",")};Vt.prototype.toJSON=function(){return this.toArray()};Vt.prototype.inspect=function(){var r=this.toArray();return Object.defineProperty(r,"constructor",{value:Vt,enumerable:!1}),r};typeof Symbol<"u"&&(Vt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Vt.prototype.inspect);Vt.from=function(r){var t=new Vt;return Ol(r,function(e){t.enqueue(e)}),t};Vt.of=function(){return Vt.from(arguments)};au.exports=Vt});var cu=dt((yp,hu)=>{hu.exports=function(t,e){var n=e.length;if(n!==0){var s=t.length;t.length+=n;for(var o=0;o{var Zi=oe(),$l=uu(),Ml=cu();function Cl(r,t,e){if(!Zi(r))throw new Error("graphology-shortest-path: invalid graphology instance.");if(arguments.length<3)throw new Error("graphology-shortest-path: invalid number of arguments. Expecting at least 3.");if(!r.hasNode(t))throw new Error('graphology-shortest-path: the "'+t+'" source node does not exist in the given graph.');if(!r.hasNode(e))throw new Error('graphology-shortest-path: the "'+e+'" target node does not exist in the given graph.');if(t=""+t,e=""+e,t===e)return[t];var n=r.inboundNeighbors.bind(r),s=r.outboundNeighbors.bind(r),o={},u={};o[t]=null,u[e]=null;var l=[t],g=[e],d,y,w,m,x,_,G,M,q=!1;t:for(;l.length&&g.length;)if(l.length<=g.length){for(d=l,l=[],x=0,G=d.length;x{var ql=oe(),Ul=lu().singleSourceLength;du.exports=function(t,e){if(!ql(t))throw new Error("graphology-metrics/eccentricity: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var n=-1/0,s=Ul(t,e),o,u,l=0;for(o in s)u=s[o],u>n&&(n=u),l++;return l{var Wl=oe(),Bl=gu();pu.exports=function(t){if(!Wl(t))throw new Error("graphology-metrics/diameter: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var e=-1/0;return t.someNode(function(n){var s=Bl(t,n);return s>e&&(e=s),e===1/0}),e}});var ws=je(ds(),1);function Fu(){let r=arguments[0];for(let t=1,e=arguments.length;tr++}function Ve(){let r=arguments,t=null,e=-1;return{[Symbol.iterator](){return this},next(){let n=null;do{if(t===null){if(e++,e>=r.length)return{done:!0};t=r[e][Symbol.iterator]()}if(n=t.next(),n.done){t=null;continue}break}while(!0);return n}}}function xr(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var zr=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},tt=class r extends zr{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},J=class r extends zr{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}},ht=class r extends zr{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,r.prototype.constructor)}};function vs(r,t){this.key=r,this.attributes=t,this.clear()}vs.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function bs(r,t){this.key=r,this.attributes=t,this.clear()}bs.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Es(r,t){this.key=r,this.attributes=t,this.clear()}Es.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function Ar(r,t,e,n,s){this.key=t,this.attributes=s,this.undirected=r,this.source=e,this.target=n}Ar.prototype.attach=function(){let r="out",t="in";this.undirected&&(r=t="undirected");let e=this.source.key,n=this.target.key;this.source[r][n]=this,!(this.undirected&&e===n)&&(this.target[t][e]=this)};Ar.prototype.attachMulti=function(){let r="out",t="in",e=this.source.key,n=this.target.key;this.undirected&&(r=t="undirected");let s=this.source[r],o=s[n];if(typeof o>"u"){s[n]=this,this.undirected&&e===n||(this.target[t][e]=this);return}o.previous=this,this.next=o,s[n]=this,this.target[t][e]=this};Ar.prototype.detach=function(){let r=this.source.key,t=this.target.key,e="out",n="in";this.undirected&&(e=n="undirected"),delete this.source[e][t],delete this.target[n][r]};Ar.prototype.detachMulti=function(){let r=this.source.key,t=this.target.key,e="out",n="in";this.undirected&&(e=n="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[e][t],delete this.target[n][r]):(this.next.previous=void 0,this.source[e][t]=this.next,this.target[n][r]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var Ss=0,xs=1,Uu=2,As=3;function Ke(r,t,e,n,s,o,u){let l,g,d,y;if(n=""+n,e===Ss){if(l=r._nodes.get(n),!l)throw new J(`Graph.${t}: could not find the "${n}" node in the graph.`);d=s,y=o}else if(e===As){if(s=""+s,g=r._edges.get(s),!g)throw new J(`Graph.${t}: could not find the "${s}" edge in the graph.`);let w=g.source.key,m=g.target.key;if(n===w)l=g.target;else if(n===m)l=g.source;else throw new J(`Graph.${t}: the "${n}" node is not attached to the "${s}" edge (${w}, ${m}).`);d=o,y=u}else{if(g=r._edges.get(n),!g)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`);e===xs?l=g.source:l=g.target,d=s,y=o}return[l,d,y]}function Wu(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);return u.attributes[l]}}function Bu(r,t,e){r.prototype[t]=function(n,s){let[o]=Ke(this,t,e,n,s);return o.attributes}}function Vu(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);return u.attributes.hasOwnProperty(l)}}function Ku(r,t,e){r.prototype[t]=function(n,s,o,u){let[l,g,d]=Ke(this,t,e,n,s,o,u);return l.attributes[g]=d,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function Yu(r,t,e){r.prototype[t]=function(n,s,o,u){let[l,g,d]=Ke(this,t,e,n,s,o,u);if(typeof d!="function")throw new tt(`Graph.${t}: updater should be a function.`);let y=l.attributes,w=d(y[g]);return y[g]=w,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function Xu(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);return delete u.attributes[l],this.emit("nodeAttributesUpdated",{key:u.key,type:"remove",attributes:u.attributes,name:l}),this}}function Qu(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);if(!se(l))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return u.attributes=l,this.emit("nodeAttributesUpdated",{key:u.key,type:"replace",attributes:u.attributes}),this}}function Ju(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);if(!se(l))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Jt(u.attributes,l),this.emit("nodeAttributesUpdated",{key:u.key,type:"merge",attributes:u.attributes,data:l}),this}}function Zu(r,t,e){r.prototype[t]=function(n,s,o){let[u,l]=Ke(this,t,e,n,s,o);if(typeof l!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return u.attributes=l(u.attributes),this.emit("nodeAttributesUpdated",{key:u.key,type:"update",attributes:u.attributes}),this}}var Hu=[{name:r=>`get${r}Attribute`,attacher:Wu},{name:r=>`get${r}Attributes`,attacher:Bu},{name:r=>`has${r}Attribute`,attacher:Vu},{name:r=>`set${r}Attribute`,attacher:Ku},{name:r=>`update${r}Attribute`,attacher:Yu},{name:r=>`remove${r}Attribute`,attacher:Xu},{name:r=>`replace${r}Attributes`,attacher:Qu},{name:r=>`merge${r}Attributes`,attacher:Ju},{name:r=>`update${r}Attributes`,attacher:Zu}];function th(r){Hu.forEach(function({name:t,attacher:e}){e(r,t("Node"),Ss),e(r,t("Source"),xs),e(r,t("Target"),Uu),e(r,t("Opposite"),As)})}function eh(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return o.attributes[s]}}function rh(r,t,e){r.prototype[t]=function(n){let s;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+n,u=""+arguments[1];if(s=Ae(this,o,u,e),!s)throw new J(`Graph.${t}: could not find an edge for the given path ("${o}" - "${u}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return s.attributes}}function nh(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return o.attributes.hasOwnProperty(s)}}function ih(r,t,e){r.prototype[t]=function(n,s,o){let u;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+s;if(s=arguments[2],o=arguments[3],u=Ae(this,l,g,e),!u)throw new J(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,u=this._edges.get(n),!u)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return u.attributes[s]=o,this.emit("edgeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:s}),this}}function sh(r,t,e){r.prototype[t]=function(n,s,o){let u;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+s;if(s=arguments[2],o=arguments[3],u=Ae(this,l,g,e),!u)throw new J(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,u=this._edges.get(n),!u)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof o!="function")throw new tt(`Graph.${t}: updater should be a function.`);return u.attributes[s]=o(u.attributes[s]),this.emit("edgeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:s}),this}}function oh(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return delete o.attributes[s],this.emit("edgeAttributesUpdated",{key:o.key,type:"remove",attributes:o.attributes,name:s}),this}}function ah(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!se(s))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return o.attributes=s,this.emit("edgeAttributesUpdated",{key:o.key,type:"replace",attributes:o.attributes}),this}}function uh(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!se(s))throw new tt(`Graph.${t}: provided attributes are not a plain object.`);return Jt(o.attributes,s),this.emit("edgeAttributesUpdated",{key:o.key,type:"merge",attributes:o.attributes,data:s}),this}}function hh(r,t,e){r.prototype[t]=function(n,s){let o;if(this.type!=="mixed"&&e!=="mixed"&&e!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let u=""+n,l=""+s;if(s=arguments[2],o=Ae(this,u,l,e),!o)throw new J(`Graph.${t}: could not find an edge for the given path ("${u}" - "${l}").`)}else{if(e!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new J(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof s!="function")throw new tt(`Graph.${t}: provided updater is not a function.`);return o.attributes=s(o.attributes),this.emit("edgeAttributesUpdated",{key:o.key,type:"update",attributes:o.attributes}),this}}var ch=[{name:r=>`get${r}Attribute`,attacher:eh},{name:r=>`get${r}Attributes`,attacher:rh},{name:r=>`has${r}Attribute`,attacher:nh},{name:r=>`set${r}Attribute`,attacher:ih},{name:r=>`update${r}Attribute`,attacher:sh},{name:r=>`remove${r}Attribute`,attacher:oh},{name:r=>`replace${r}Attributes`,attacher:ah},{name:r=>`merge${r}Attributes`,attacher:uh},{name:r=>`update${r}Attributes`,attacher:hh}];function fh(r){ch.forEach(function({name:t,attacher:e}){e(r,t("Edge"),"mixed"),e(r,t("DirectedEdge"),"directed"),e(r,t("UndirectedEdge"),"undirected")})}var lh=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function dh(r,t,e,n){let s=!1;for(let o in t){if(o===n)continue;let u=t[o];if(s=e(u.key,u.attributes,u.source.key,u.target.key,u.source.attributes,u.target.attributes,u.undirected),r&&s)return u.key}}function gh(r,t,e,n){let s,o,u,l=!1;for(let g in t)if(g!==n){s=t[g];do{if(o=s.source,u=s.target,l=e(s.key,s.attributes,o.key,u.key,o.attributes,u.attributes,s.undirected),r&&l)return s.key;s=s.next}while(s!==void 0)}}function ui(r,t){let e=Object.keys(r),n=e.length,s,o=0;return{[Symbol.iterator](){return this},next(){do if(s)s=s.next;else{if(o>=n)return{done:!0};let u=e[o++];if(u===t){s=void 0;continue}s=r[u]}while(!s);return{done:!1,value:{edge:s.key,attributes:s.attributes,source:s.source.key,target:s.target.key,sourceAttributes:s.source.attributes,targetAttributes:s.target.attributes,undirected:s.undirected}}}}}function ph(r,t,e,n){let s=t[e];if(!s)return;let o=s.source,u=s.target;if(n(s.key,s.attributes,o.key,u.key,o.attributes,u.attributes,s.undirected)&&r)return s.key}function yh(r,t,e,n){let s=t[e];if(!s)return;let o=!1;do{if(o=n(s.key,s.attributes,s.source.key,s.target.key,s.source.attributes,s.target.attributes,s.undirected),r&&o)return s.key;s=s.next}while(s!==void 0)}function hi(r,t){let e=r[t];if(e.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!e)return{done:!0};let s={edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected};return e=e.next,{done:!1,value:s}}};let n=!1;return{[Symbol.iterator](){return this},next(){return n===!0?{done:!0}:(n=!0,{done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}})}}}function wh(r,t){if(r.size===0)return[];if(t==="mixed"||t===r.type)return Array.from(r._edges.keys());let e=t==="undirected"?r.undirectedSize:r.directedSize,n=new Array(e),s=t==="undirected",o=r._edges.values(),u=0,l,g;for(;l=o.next(),l.done!==!0;)g=l.value,g.undirected===s&&(n[u++]=g.key);return n}function ks(r,t,e,n){if(t.size===0)return;let s=e!=="mixed"&&e!==t.type,o=e==="undirected",u,l,g=!1,d=t._edges.values();for(;u=d.next(),u.done!==!0;){if(l=u.value,s&&l.undirected!==o)continue;let{key:y,attributes:w,source:m,target:x}=l;if(g=n(y,w,m.key,x.key,m.attributes,x.attributes,l.undirected),r&&g)return y}}function mh(r,t){if(r.size===0)return xr();let e=t!=="mixed"&&t!==r.type,n=t==="undirected",s=r._edges.values();return{[Symbol.iterator](){return this},next(){let o,u;for(;;){if(o=s.next(),o.done)return o;if(u=o.value,!(e&&u.undirected!==n))break}return{value:{edge:u.key,attributes:u.attributes,source:u.source.key,target:u.target.key,sourceAttributes:u.source.attributes,targetAttributes:u.target.attributes,undirected:u.undirected},done:!1}}}}function ci(r,t,e,n,s,o){let u=t?gh:dh,l;if(e!=="undirected"&&(n!=="out"&&(l=u(r,s.in,o),r&&l)||n!=="in"&&(l=u(r,s.out,o,n?void 0:s.key),r&&l))||e!=="directed"&&(l=u(r,s.undirected,o),r&&l))return l}function vh(r,t,e,n){let s=[];return ci(!1,r,t,e,n,function(o){s.push(o)}),s}function bh(r,t,e){let n=xr();return r!=="undirected"&&(t!=="out"&&typeof e.in<"u"&&(n=Ve(n,ui(e.in))),t!=="in"&&typeof e.out<"u"&&(n=Ve(n,ui(e.out,t?void 0:e.key)))),r!=="directed"&&typeof e.undirected<"u"&&(n=Ve(n,ui(e.undirected))),n}function fi(r,t,e,n,s,o,u){let l=e?yh:ph,g;if(t!=="undirected"&&(typeof s.in<"u"&&n!=="out"&&(g=l(r,s.in,o,u),r&&g)||typeof s.out<"u"&&n!=="in"&&(n||s.key!==o)&&(g=l(r,s.out,o,u),r&&g))||t!=="directed"&&typeof s.undirected<"u"&&(g=l(r,s.undirected,o,u),r&&g))return g}function Eh(r,t,e,n,s){let o=[];return fi(!1,r,t,e,n,s,function(u){o.push(u)}),o}function Sh(r,t,e,n){let s=xr();return r!=="undirected"&&(typeof e.in<"u"&&t!=="out"&&n in e.in&&(s=Ve(s,hi(e.in,n))),typeof e.out<"u"&&t!=="in"&&n in e.out&&(t||e.key!==n)&&(s=Ve(s,hi(e.out,n)))),r!=="directed"&&typeof e.undirected<"u"&&n in e.undirected&&(s=Ve(s,hi(e.undirected,n))),s}function xh(r,t){let{name:e,type:n,direction:s}=t;r.prototype[e]=function(o,u){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];if(!arguments.length)return wh(this,n);if(arguments.length===1){o=""+o;let l=this._nodes.get(o);if(typeof l>"u")throw new J(`Graph.${e}: could not find the "${o}" node in the graph.`);return vh(this.multi,n==="mixed"?this.type:n,s,l)}if(arguments.length===2){o=""+o,u=""+u;let l=this._nodes.get(o);if(!l)throw new J(`Graph.${e}: could not find the "${o}" source node in the graph.`);if(!this._nodes.has(u))throw new J(`Graph.${e}: could not find the "${u}" target node in the graph.`);return Eh(n,this.multi,s,l,u)}throw new tt(`Graph.${e}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Ah(r,t){let{name:e,type:n,direction:s}=t,o="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[o]=function(d,y,w){if(!(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)){if(arguments.length===1)return w=d,ks(!1,this,n,w);if(arguments.length===2){d=""+d,w=y;let m=this._nodes.get(d);if(typeof m>"u")throw new J(`Graph.${o}: could not find the "${d}" node in the graph.`);return ci(!1,this.multi,n==="mixed"?this.type:n,s,m,w)}if(arguments.length===3){d=""+d,y=""+y;let m=this._nodes.get(d);if(!m)throw new J(`Graph.${o}: could not find the "${d}" source node in the graph.`);if(!this._nodes.has(y))throw new J(`Graph.${o}: could not find the "${y}" target node in the graph.`);return fi(!1,n,this.multi,s,m,y,w)}throw new tt(`Graph.${o}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let u="map"+e[0].toUpperCase()+e.slice(1);r.prototype[u]=function(){let d=Array.prototype.slice.call(arguments),y=d.pop(),w;if(d.length===0){let m=0;n!=="directed"&&(m+=this.undirectedSize),n!=="undirected"&&(m+=this.directedSize),w=new Array(m);let x=0;d.push((_,G,M,q,L,P,B)=>{w[x++]=y(_,G,M,q,L,P,B)})}else w=[],d.push((m,x,_,G,M,q,L)=>{w.push(y(m,x,_,G,M,q,L))});return this[o].apply(this,d),w};let l="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[l]=function(){let d=Array.prototype.slice.call(arguments),y=d.pop(),w=[];return d.push((m,x,_,G,M,q,L)=>{y(m,x,_,G,M,q,L)&&w.push(m)}),this[o].apply(this,d),w};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(){let d=Array.prototype.slice.call(arguments);if(d.length<2||d.length>4)throw new tt(`Graph.${g}: invalid number of arguments (expecting 2, 3 or 4 and got ${d.length}).`);if(typeof d[d.length-1]=="function"&&typeof d[d.length-2]!="function")throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let y,w;d.length===2?(y=d[0],w=d[1],d=[]):d.length===3?(y=d[1],w=d[2],d=[d[0]]):d.length===4&&(y=d[2],w=d[3],d=[d[0],d[1]]);let m=w;return d.push((x,_,G,M,q,L,P)=>{m=y(m,x,_,G,M,q,L,P)}),this[o].apply(this,d),m}}function kh(r,t){let{name:e,type:n,direction:s}=t,o="find"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[o]=function(g,d,y){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return!1;if(arguments.length===1)return y=g,ks(!0,this,n,y);if(arguments.length===2){g=""+g,y=d;let w=this._nodes.get(g);if(typeof w>"u")throw new J(`Graph.${o}: could not find the "${g}" node in the graph.`);return ci(!0,this.multi,n==="mixed"?this.type:n,s,w,y)}if(arguments.length===3){g=""+g,d=""+d;let w=this._nodes.get(g);if(!w)throw new J(`Graph.${o}: could not find the "${g}" source node in the graph.`);if(!this._nodes.has(d))throw new J(`Graph.${o}: could not find the "${d}" target node in the graph.`);return fi(!0,n,this.multi,s,w,d,y)}throw new tt(`Graph.${o}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let u="some"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[u]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((w,m,x,_,G,M,q)=>d(w,m,x,_,G,M,q)),!!this[o].apply(this,g)};let l="every"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[l]=function(){let g=Array.prototype.slice.call(arguments),d=g.pop();return g.push((w,m,x,_,G,M,q)=>!d(w,m,x,_,G,M,q)),!this[o].apply(this,g)}}function Ih(r,t){let{name:e,type:n,direction:s}=t,o=e.slice(0,-1)+"Entries";r.prototype[o]=function(u,l){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return xr();if(!arguments.length)return mh(this,n);if(arguments.length===1){u=""+u;let g=this._nodes.get(u);if(!g)throw new J(`Graph.${o}: could not find the "${u}" node in the graph.`);return bh(n,s,g)}if(arguments.length===2){u=""+u,l=""+l;let g=this._nodes.get(u);if(!g)throw new J(`Graph.${o}: could not find the "${u}" source node in the graph.`);if(!this._nodes.has(l))throw new J(`Graph.${o}: could not find the "${l}" target node in the graph.`);return Sh(n,s,g,l)}throw new tt(`Graph.${o}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Dh(r){lh.forEach(t=>{xh(r,t),Ah(r,t),kh(r,t),Ih(r,t)})}var _h=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function vn(){this.A=null,this.B=null}vn.prototype.wrap=function(r){this.A===null?this.A=r:this.B===null&&(this.B=r)};vn.prototype.has=function(r){return this.A!==null&&r in this.A||this.B!==null&&r in this.B};function Pr(r,t,e,n,s){for(let o in n){let u=n[o],l=u.source,g=u.target,d=l===e?g:l;if(t&&t.has(d.key))continue;let y=s(d.key,d.attributes);if(r&&y)return d.key}}function li(r,t,e,n,s){if(t!=="mixed"){if(t==="undirected")return Pr(r,null,n,n.undirected,s);if(typeof e=="string")return Pr(r,null,n,n[e],s)}let o=new vn,u;if(t!=="undirected"){if(e!=="out"){if(u=Pr(r,null,n,n.in,s),r&&u)return u;o.wrap(n.in)}if(e!=="in"){if(u=Pr(r,o,n,n.out,s),r&&u)return u;o.wrap(n.out)}}if(t!=="directed"&&(u=Pr(r,o,n,n.undirected,s),r&&u))return u}function Rh(r,t,e){if(r!=="mixed"){if(r==="undirected")return Object.keys(e.undirected);if(typeof t=="string")return Object.keys(e[t])}let n=[];return li(!1,r,t,e,function(s){n.push(s)}),n}function Nr(r,t,e){let n=Object.keys(e),s=n.length,o=0;return{[Symbol.iterator](){return this},next(){let u=null;do{if(o>=s)return r&&r.wrap(e),{done:!0};let l=e[n[o++]],g=l.source,d=l.target;if(u=g===t?d:g,r&&r.has(u.key)){u=null;continue}}while(u===null);return{done:!1,value:{neighbor:u.key,attributes:u.attributes}}}}}function jh(r,t,e){if(r!=="mixed"){if(r==="undirected")return Nr(null,e,e.undirected);if(typeof t=="string")return Nr(null,e,e[t])}let n=xr(),s=new vn;return r!=="undirected"&&(t!=="out"&&(n=Ve(n,Nr(s,e,e.in))),t!=="in"&&(n=Ve(n,Nr(s,e,e.out)))),r!=="directed"&&(n=Ve(n,Nr(s,e,e.undirected))),n}function Th(r,t){let{name:e,type:n,direction:s}=t;r.prototype[e]=function(o){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];o=""+o;let u=this._nodes.get(o);if(typeof u>"u")throw new J(`Graph.${e}: could not find the "${o}" node in the graph.`);return Rh(n==="mixed"?this.type:n,s,u)}}function Lh(r,t){let{name:e,type:n,direction:s}=t,o="forEach"+e[0].toUpperCase()+e.slice(1,-1);r.prototype[o]=function(d,y){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;d=""+d;let w=this._nodes.get(d);if(typeof w>"u")throw new J(`Graph.${o}: could not find the "${d}" node in the graph.`);li(!1,n==="mixed"?this.type:n,s,w,y)};let u="map"+e[0].toUpperCase()+e.slice(1);r.prototype[u]=function(d,y){let w=[];return this[o](d,(m,x)=>{w.push(y(m,x))}),w};let l="filter"+e[0].toUpperCase()+e.slice(1);r.prototype[l]=function(d,y){let w=[];return this[o](d,(m,x)=>{y(m,x)&&w.push(m)}),w};let g="reduce"+e[0].toUpperCase()+e.slice(1);r.prototype[g]=function(d,y,w){if(arguments.length<3)throw new tt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let m=w;return this[o](d,(x,_)=>{m=y(m,x,_)}),m}}function Gh(r,t){let{name:e,type:n,direction:s}=t,o=e[0].toUpperCase()+e.slice(1,-1),u="find"+o;r.prototype[u]=function(d,y){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;d=""+d;let w=this._nodes.get(d);if(typeof w>"u")throw new J(`Graph.${u}: could not find the "${d}" node in the graph.`);return li(!0,n==="mixed"?this.type:n,s,w,y)};let l="some"+o;r.prototype[l]=function(d,y){return!!this[u](d,y)};let g="every"+o;r.prototype[g]=function(d,y){return!this[u](d,(m,x)=>!y(m,x))}}function Oh(r,t){let{name:e,type:n,direction:s}=t,o=e.slice(0,-1)+"Entries";r.prototype[o]=function(u){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return xr();u=""+u;let l=this._nodes.get(u);if(typeof l>"u")throw new J(`Graph.${o}: could not find the "${u}" node in the graph.`);return jh(n==="mixed"?this.type:n,s,l)}}function $h(r){_h.forEach(t=>{Th(r,t),Lh(r,t),Gh(r,t),Oh(r,t)})}function dn(r,t,e,n,s){let o=n._nodes.values(),u=n.type,l,g,d,y,w,m,x;for(;l=o.next(),l.done!==!0;){let _=!1;if(g=l.value,u!=="undirected"){y=g.out;for(d in y){w=y[d];do{if(m=w.target,_=!0,x=s(g.key,m.key,g.attributes,m.attributes,w.key,w.attributes,w.undirected),r&&x)return w;w=w.next}while(w)}}if(u!=="directed"){y=g.undirected;for(d in y)if(!(t&&g.key>d)){w=y[d];do{if(m=w.target,m.key!==d&&(m=w.source),_=!0,x=s(g.key,m.key,g.attributes,m.attributes,w.key,w.attributes,w.undirected),r&&x)return w;w=w.next}while(w)}}if(e&&!_&&(x=s(g.key,null,g.attributes,null,null,null,null),r&&x))return null}}function Mh(r,t){let e={key:r};return ms(t.attributes)||(e.attributes=Jt({},t.attributes)),e}function Ch(r,t,e){let n={key:t,source:e.source.key,target:e.target.key};return ms(e.attributes)||(n.attributes=Jt({},e.attributes)),r==="mixed"&&e.undirected&&(n.undirected=!0),n}function Ph(r){if(!se(r))throw new tt('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in r))throw new tt("Graph.import: serialized node is missing its key.");if("attributes"in r&&(!se(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function Nh(r){if(!se(r))throw new tt('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in r))throw new tt("Graph.import: serialized edge is missing its source.");if(!("target"in r))throw new tt("Graph.import: serialized edge is missing its target.");if("attributes"in r&&(!se(r.attributes)||r.attributes===null))throw new tt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in r&&typeof r.undirected!="boolean")throw new tt("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var zh=qu(),Fh=new Set(["directed","undirected","mixed"]),ps=new Set(["domain","_events","_eventsCount","_maxListeners"]),qh=[{name:r=>`${r}Edge`,generateKey:!0},{name:r=>`${r}DirectedEdge`,generateKey:!0,type:"directed"},{name:r=>`${r}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:r=>`${r}EdgeWithKey`},{name:r=>`${r}DirectedEdgeWithKey`,type:"directed"},{name:r=>`${r}UndirectedEdgeWithKey`,type:"undirected"}],Uh={allowSelfLoops:!0,multi:!1,type:"mixed"};function Wh(r,t,e){if(e&&!se(e))throw new tt(`Graph.addNode: invalid attributes. Expecting an object but got "${e}"`);if(t=""+t,e=e||{},r._nodes.has(t))throw new ht(`Graph.addNode: the "${t}" node already exist in the graph.`);let n=new r.NodeDataClass(t,e);return r._nodes.set(t,n),r.emit("nodeAdded",{key:t,attributes:e}),n}function ys(r,t,e){let n=new r.NodeDataClass(t,e);return r._nodes.set(t,n),r.emit("nodeAdded",{key:t,attributes:e}),n}function Is(r,t,e,n,s,o,u,l){if(!n&&r.type==="undirected")throw new ht(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(n&&r.type==="directed")throw new ht(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(l&&!se(l))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`);if(o=""+o,u=""+u,l=l||{},!r.allowSelfLoops&&o===u)throw new ht(`Graph.${t}: source & target are the same ("${o}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let g=r._nodes.get(o),d=r._nodes.get(u);if(!g)throw new J(`Graph.${t}: source node "${o}" not found.`);if(!d)throw new J(`Graph.${t}: target node "${u}" not found.`);let y={key:null,undirected:n,source:o,target:u,attributes:l};if(e)s=r._edgeKeyGenerator();else if(s=""+s,r._edges.has(s))throw new ht(`Graph.${t}: the "${s}" edge already exists in the graph.`);if(!r.multi&&(n?typeof g.undirected[u]<"u":typeof g.out[u]<"u"))throw new ht(`Graph.${t}: an edge linking "${o}" to "${u}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let w=new Ar(n,s,g,d,l);r._edges.set(s,w);let m=o===u;return n?(g.undirectedDegree++,d.undirectedDegree++,m&&(g.undirectedLoops++,r._undirectedSelfLoopCount++)):(g.outDegree++,d.inDegree++,m&&(g.directedLoops++,r._directedSelfLoopCount++)),r.multi?w.attachMulti():w.attach(),n?r._undirectedSize++:r._directedSize++,y.key=s,r.emit("edgeAdded",y),s}function Bh(r,t,e,n,s,o,u,l,g){if(!n&&r.type==="undirected")throw new ht(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(n&&r.type==="directed")throw new ht(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(l){if(g){if(typeof l!="function")throw new tt(`Graph.${t}: invalid updater function. Expecting a function but got "${l}"`)}else if(!se(l))throw new tt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`)}o=""+o,u=""+u;let d;if(g&&(d=l,l=void 0),!r.allowSelfLoops&&o===u)throw new ht(`Graph.${t}: source & target are the same ("${o}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let y=r._nodes.get(o),w=r._nodes.get(u),m,x;if(!e&&(m=r._edges.get(s),m)){if((m.source.key!==o||m.target.key!==u)&&(!n||m.source.key!==u||m.target.key!==o))throw new ht(`Graph.${t}: inconsistency detected when attempting to merge the "${s}" edge with "${o}" source & "${u}" target vs. ("${m.source.key}", "${m.target.key}").`);x=m}if(!x&&!r.multi&&y&&(x=n?y.undirected[u]:y.out[u]),x){let L=[x.key,!1,!1,!1];if(g?!d:!l)return L;if(g){let P=x.attributes;x.attributes=d(P),r.emit("edgeAttributesUpdated",{type:"replace",key:x.key,attributes:x.attributes})}else Jt(x.attributes,l),r.emit("edgeAttributesUpdated",{type:"merge",key:x.key,attributes:x.attributes,data:l});return L}l=l||{},g&&d&&(l=d(l));let _={key:null,undirected:n,source:o,target:u,attributes:l};if(e)s=r._edgeKeyGenerator();else if(s=""+s,r._edges.has(s))throw new ht(`Graph.${t}: the "${s}" edge already exists in the graph.`);let G=!1,M=!1;y||(y=ys(r,o,{}),G=!0,o===u&&(w=y,M=!0)),w||(w=ys(r,u,{}),M=!0),m=new Ar(n,s,y,w,l),r._edges.set(s,m);let q=o===u;return n?(y.undirectedDegree++,w.undirectedDegree++,q&&(y.undirectedLoops++,r._undirectedSelfLoopCount++)):(y.outDegree++,w.inDegree++,q&&(y.directedLoops++,r._directedSelfLoopCount++)),r.multi?m.attachMulti():m.attach(),n?r._undirectedSize++:r._directedSize++,_.key=s,r.emit("edgeAdded",_),[s,!0,G,M]}function Sr(r,t){r._edges.delete(t.key);let{source:e,target:n,attributes:s}=t,o=t.undirected,u=e===n;o?(e.undirectedDegree--,n.undirectedDegree--,u&&(e.undirectedLoops--,r._undirectedSelfLoopCount--)):(e.outDegree--,n.inDegree--,u&&(e.directedLoops--,r._directedSelfLoopCount--)),r.multi?t.detachMulti():t.detach(),o?r._undirectedSize--:r._directedSize--,r.emit("edgeDropped",{key:t.key,attributes:s,source:e.key,target:n.key,undirected:o})}var Lt=class r extends ws.EventEmitter{constructor(t){if(super(),t=Jt({},Uh,t),typeof t.multi!="boolean")throw new tt(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Fh.has(t.type))throw new tt(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new tt(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let e=t.type==="mixed"?vs:t.type==="directed"?bs:Es;xe(this,"NodeDataClass",e);let n="geid_"+zh()+"_",s=0,o=()=>{let u;do u=n+s++;while(this._edges.has(u));return u};xe(this,"_attributes",{}),xe(this,"_nodes",new Map),xe(this,"_edges",new Map),xe(this,"_directedSize",0),xe(this,"_undirectedSize",0),xe(this,"_directedSelfLoopCount",0),xe(this,"_undirectedSelfLoopCount",0),xe(this,"_edgeKeyGenerator",o),xe(this,"_options",t),ps.forEach(u=>xe(this,u,this[u])),Le(this,"order",()=>this._nodes.size),Le(this,"size",()=>this._edges.size),Le(this,"directedSize",()=>this._directedSize),Le(this,"undirectedSize",()=>this._undirectedSize),Le(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),Le(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),Le(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),Le(this,"multi",this._options.multi),Le(this,"type",this._options.type),Le(this,"allowSelfLoops",this._options.allowSelfLoops),Le(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,e){if(this.type==="undirected")return!1;if(arguments.length===1){let n=""+t,s=this._edges.get(n);return!!s&&!s.undirected}else if(arguments.length===2){t=""+t,e=""+e;let n=this._nodes.get(t);return n?n.out.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,e){if(this.type==="directed")return!1;if(arguments.length===1){let n=""+t,s=this._edges.get(n);return!!s&&s.undirected}else if(arguments.length===2){t=""+t,e=""+e;let n=this._nodes.get(t);return n?n.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,e){if(arguments.length===1){let n=""+t;return this._edges.has(n)}else if(arguments.length===2){t=""+t,e=""+e;let n=this._nodes.get(t);return n?typeof n.out<"u"&&n.out.hasOwnProperty(e)||typeof n.undirected<"u"&&n.undirected.hasOwnProperty(e):!1}throw new tt(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,e){if(this.type==="undirected")return;if(t=""+t,e=""+e,this.multi)throw new ht("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let n=this._nodes.get(t);if(!n)throw new J(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new J(`Graph.directedEdge: could not find the "${e}" target node in the graph.`);let s=n.out&&n.out[e]||void 0;if(s)return s.key}undirectedEdge(t,e){if(this.type==="directed")return;if(t=""+t,e=""+e,this.multi)throw new ht("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let n=this._nodes.get(t);if(!n)throw new J(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new J(`Graph.undirectedEdge: could not find the "${e}" target node in the graph.`);let s=n.undirected&&n.undirected[e]||void 0;if(s)return s.key}edge(t,e){if(this.multi)throw new ht("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(e))throw new J(`Graph.edge: could not find the "${e}" target node in the graph.`);let s=n.out&&n.out[e]||n.undirected&&n.undirected[e]||void 0;if(s)return s.key}areDirectedNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in n.in||e in n.out}areOutNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in n.out}areInNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:e in n.in}areUndirectedNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:e in n.undirected}areNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(e in n.in||e in n.out)||this.type!=="directed"&&e in n.undirected}areInboundNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in n.in||this.type!=="directed"&&e in n.undirected}areOutboundNeighbors(t,e){t=""+t,e=""+e;let n=this._nodes.get(t);if(!n)throw new J(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&e in n.out||this.type!=="directed"&&e in n.undirected}inDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree}outDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree}directedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree}undirectedDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree}inboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=e.undirectedDegree),this.type!=="undirected"&&(n+=e.inDegree),n}outboundDegree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=e.undirectedDegree),this.type!=="undirected"&&(n+=e.outDegree),n}degree(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.degree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=e.undirectedDegree),this.type!=="undirected"&&(n+=e.inDegree+e.outDegree),n}inDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree-e.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.outDegree-e.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:e.inDegree+e.outDegree-e.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:e.undirectedDegree-e.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,s=0;return this.type!=="directed"&&(n+=e.undirectedDegree,s+=e.undirectedLoops*2),this.type!=="undirected"&&(n+=e.inDegree,s+=e.directedLoops),n-s}outboundDegreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,s=0;return this.type!=="directed"&&(n+=e.undirectedDegree,s+=e.undirectedLoops*2),this.type!=="undirected"&&(n+=e.outDegree,s+=e.directedLoops),n-s}degreeWithoutSelfLoops(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,s=0;return this.type!=="directed"&&(n+=e.undirectedDegree,s+=e.undirectedLoops*2),this.type!=="undirected"&&(n+=e.inDegree+e.outDegree,s+=e.directedLoops*2),n-s}source(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.source: could not find the "${t}" edge in the graph.`);return e.source.key}target(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.target: could not find the "${t}" edge in the graph.`);return e.target.key}extremities(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[e.source.key,e.target.key]}opposite(t,e){t=""+t,e=""+e;let n=this._edges.get(e);if(!n)throw new J(`Graph.opposite: could not find the "${e}" edge in the graph.`);let s=n.source.key,o=n.target.key;if(t===s)return o;if(t===o)return s;throw new J(`Graph.opposite: the "${t}" node is not attached to the "${e}" edge (${s}, ${o}).`)}hasExtremity(t,e){t=""+t,e=""+e;let n=this._edges.get(t);if(!n)throw new J(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return n.source.key===e||n.target.key===e}isUndirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return e.undirected}isDirected(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!e.undirected}isSelfLoop(t){t=""+t;let e=this._edges.get(t);if(!e)throw new J(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return e.source===e.target}addNode(t,e){return Wh(this,t,e).key}mergeNode(t,e){if(e&&!se(e))throw new tt(`Graph.mergeNode: invalid attributes. Expecting an object but got "${e}"`);t=""+t,e=e||{};let n=this._nodes.get(t);return n?(e&&(Jt(n.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:n.attributes,data:e})),[t,!1]):(n=new this.NodeDataClass(t,e),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])}updateNode(t,e){if(e&&typeof e!="function")throw new tt(`Graph.updateNode: invalid updater function. Expecting a function but got "${e}"`);t=""+t;let n=this._nodes.get(t);if(n){if(e){let o=n.attributes;n.attributes=e(o),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:n.attributes})}return[t,!1]}let s=e?e({}):{};return n=new this.NodeDataClass(t,s),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:s}),[t,!0]}dropNode(t){t=""+t;let e=this._nodes.get(t);if(!e)throw new J(`Graph.dropNode: could not find the "${t}" node in the graph.`);let n;if(this.type!=="undirected"){for(let s in e.out){n=e.out[s];do Sr(this,n),n=n.next;while(n)}for(let s in e.in){n=e.in[s];do Sr(this,n),n=n.next;while(n)}}if(this.type!=="directed")for(let s in e.undirected){n=e.undirected[s];do Sr(this,n),n=n.next;while(n)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:e.attributes})}dropEdge(t){let e;if(arguments.length>1){let n=""+arguments[0],s=""+arguments[1];if(e=Ae(this,n,s,this.type),!e)throw new J(`Graph.dropEdge: could not find the "${n}" -> "${s}" edge in the graph.`)}else if(t=""+t,e=this._edges.get(t),!e)throw new J(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return Sr(this,e),this}dropDirectedEdge(t,e){if(arguments.length<2)throw new ht("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new ht("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,e=""+e;let n=Ae(this,t,e,"directed");if(!n)throw new J(`Graph.dropDirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Sr(this,n),this}dropUndirectedEdge(t,e){if(arguments.length<2)throw new ht("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new ht("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let n=Ae(this,t,e,"undirected");if(!n)throw new J(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${e}" edge in the graph.`);return Sr(this,n),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),e;for(;e=t.next(),e.done!==!0;)e.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,e){if(typeof e!="function")throw new tt("Graph.updateAttribute: updater should be a function.");let n=this._attributes[t];return this._attributes[t]=e(n),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!se(t))throw new tt("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!se(t))throw new tt("Graph.mergeAttributes: provided attributes are not a plain object.");return Jt(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new tt("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!gs(e))throw new tt("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._nodes.values(),s,o;for(;s=n.next(),s.done!==!0;)o=s.value,o.attributes=t(o.key,o.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})}updateEachEdgeAttributes(t,e){if(typeof t!="function")throw new tt("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!gs(e))throw new tt("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._edges.values(),s,o,u,l;for(;s=n.next(),s.done!==!0;)o=s.value,u=o.source,l=o.target,o.attributes=t(o.key,o.attributes,u.key,l.key,u.attributes,l.attributes,o.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntry: expecting a callback.");dn(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");dn(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");dn(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new tt("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");dn(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new tt("Graph.forEachNode: expecting a callback.");let e=this._nodes.values(),n,s;for(;n=e.next(),n.done!==!0;)s=n.value,t(s.key,s.attributes)}findNode(t){if(typeof t!="function")throw new tt("Graph.findNode: expecting a callback.");let e=this._nodes.values(),n,s;for(;n=e.next(),n.done!==!0;)if(s=n.value,t(s.key,s.attributes))return s.key}mapNodes(t){if(typeof t!="function")throw new tt("Graph.mapNode: expecting a callback.");let e=this._nodes.values(),n,s,o=new Array(this.order),u=0;for(;n=e.next(),n.done!==!0;)s=n.value,o[u++]=t(s.key,s.attributes);return o}someNode(t){if(typeof t!="function")throw new tt("Graph.someNode: expecting a callback.");let e=this._nodes.values(),n,s;for(;n=e.next(),n.done!==!0;)if(s=n.value,t(s.key,s.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new tt("Graph.everyNode: expecting a callback.");let e=this._nodes.values(),n,s;for(;n=e.next(),n.done!==!0;)if(s=n.value,!t(s.key,s.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new tt("Graph.filterNodes: expecting a callback.");let e=this._nodes.values(),n,s,o=[];for(;n=e.next(),n.done!==!0;)s=n.value,t(s.key,s.attributes)&&o.push(s.key);return o}reduceNodes(t,e){if(typeof t!="function")throw new tt("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new tt("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let n=e,s=this._nodes.values(),o,u;for(;o=s.next(),o.done!==!0;)u=o.value,n=t(n,u.key,u.attributes);return n}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let e=t.next();if(e.done)return e;let n=e.value;return{value:{node:n.key,attributes:n.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),e=0;this._nodes.forEach((s,o)=>{t[e++]=Mh(o,s)});let n=new Array(this._edges.size);return e=0,this._edges.forEach((s,o)=>{n[e++]=Ch(this.type,o,s)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:n}}import(t,e=!1){if(t instanceof r)return t.forEachNode((g,d)=>{e?this.mergeNode(g,d):this.addNode(g,d)}),t.forEachEdge((g,d,y,w,m,x,_)=>{e?_?this.mergeUndirectedEdgeWithKey(g,y,w,d):this.mergeDirectedEdgeWithKey(g,y,w,d):_?this.addUndirectedEdgeWithKey(g,y,w,d):this.addDirectedEdgeWithKey(g,y,w,d)}),this;if(!se(t))throw new tt("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!se(t.attributes))throw new tt("Graph.import: invalid attributes. Expecting a plain object.");e?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let n,s,o,u,l;if(t.nodes){if(o=t.nodes,!Array.isArray(o))throw new tt("Graph.import: invalid nodes. Expecting an array.");for(n=0,s=o.length;n{let o=Jt({},n.attributes);n=new e.NodeDataClass(s,o),e._nodes.set(s,n)}),e}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new ht(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new ht("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new ht("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let e=this.emptyCopy(t),n=this._edges.values(),s,o;for(;s=n.next(),s.done!==!0;)o=s.value,Is(e,"copy",!1,o.undirected,o.key,o.source.key,o.target.key,Jt({},o.attributes));return e}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((o,u)=>{t[u]=o.attributes});let e={},n={};this._edges.forEach((o,u)=>{let l=o.undirected?"--":"->",g="",d=o.source.key,y=o.target.key,w;o.undirected&&d>y&&(w=d,d=y,y=w);let m=`(${d})${l}(${y})`;u.startsWith("geid_")?this.multi&&(typeof n[m]>"u"?n[m]=0:n[m]++,g+=`${n[m]}. `):g+=`[${u}]: `,g+=m,e[g]=o.attributes});let s={};for(let o in this)this.hasOwnProperty(o)&&!ps.has(o)&&typeof this[o]!="function"&&typeof o!="symbol"&&(s[o]=this[o]);return s.attributes=this._attributes,s.nodes=t,s.edges=e,xe(s,"constructor",this.constructor),s}};typeof Symbol<"u"&&(Lt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Lt.prototype.inspect);qh.forEach(r=>{["add","merge","update"].forEach(t=>{let e=r.name(t),n=t==="add"?Is:Bh;r.generateKey?Lt.prototype[e]=function(s,o,u){return n(this,e,!0,(r.type||this.type)==="undirected",null,s,o,u,t==="update")}:Lt.prototype[e]=function(s,o,u,l){return n(this,e,!1,(r.type||this.type)==="undirected",s,o,u,l,t==="update")}})});th(Lt);fh(Lt);Dh(Lt);$h(Lt);var gn=class extends Lt{constructor(t){let e=Jt({type:"directed"},t);if("multi"in e&&e.multi!==!1)throw new tt("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="directed")throw new tt('DirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},pn=class extends Lt{constructor(t){let e=Jt({type:"undirected"},t);if("multi"in e&&e.multi!==!1)throw new tt("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(e.type!=="undirected")throw new tt('UndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},yn=class extends Lt{constructor(t){let e=Jt({multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(e)}},wn=class extends Lt{constructor(t){let e=Jt({type:"directed",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="directed")throw new tt('MultiDirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}},mn=class extends Lt{constructor(t){let e=Jt({type:"undirected",multi:!0},t);if("multi"in e&&e.multi!==!0)throw new tt("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(e.type!=="undirected")throw new tt('MultiUndirectedGraph.from: inconsistent "'+e.type+'" type in given options!');super(e)}};function kr(r){r.from=function(t,e){let n=Jt({},t.options,e),s=new r(n);return s.import(t),s}}kr(Lt);kr(gn);kr(pn);kr(yn);kr(wn);kr(mn);Lt.Graph=Lt;Lt.DirectedGraph=gn;Lt.UndirectedGraph=pn;Lt.MultiGraph=yn;Lt.MultiDirectedGraph=wn;Lt.MultiUndirectedGraph=mn;Lt.InvalidArgumentsGraphError=tt;Lt.NotFoundGraphError=J;Lt.UsageGraphError=ht;var ti=je(ao(),1),Vl=je(vo(),1),Kl=je(xo(),1);function Ie(r,t,e,n){function s(o){return o instanceof e?o:new e(function(u){u(o)})}return new(e||(e=Promise))(function(o,u){function l(y){try{d(n.next(y))}catch(w){u(w)}}function g(y){try{d(n.throw(y))}catch(w){u(w)}}function d(y){y.done?o(y.value):s(y.value).then(l,g)}d((n=n.apply(r,t||[])).next())})}var Rc={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},qt=class extends Error{constructor(t,e,n){super(t),this.position=e,this.token=n,this.name="ExpressionError"}},lt;(function(r){r[r.STRING=0]="STRING",r[r.NUMBER=1]="NUMBER",r[r.BOOLEAN=2]="BOOLEAN",r[r.NULL=3]="NULL",r[r.IDENTIFIER=4]="IDENTIFIER",r[r.OPERATOR=5]="OPERATOR",r[r.FUNCTION=6]="FUNCTION",r[r.DOT=7]="DOT",r[r.BRACKET_LEFT=8]="BRACKET_LEFT",r[r.BRACKET_RIGHT=9]="BRACKET_RIGHT",r[r.PAREN_LEFT=10]="PAREN_LEFT",r[r.PAREN_RIGHT=11]="PAREN_RIGHT",r[r.COMMA=12]="COMMA",r[r.QUESTION=13]="QUESTION",r[r.COLON=14]="COLON",r[r.DOLLAR=15]="DOLLAR"})(lt||(lt={}));var jc=new Set([32,9,10,13]),Tc=new Set([43,45,42,47,37,33,38,124,61,60,62]),Lc=new Map([["true",lt.BOOLEAN],["false",lt.BOOLEAN],["null",lt.NULL]]),mi=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),Gc=new Map([[46,lt.DOT],[91,lt.BRACKET_LEFT],[93,lt.BRACKET_RIGHT],[40,lt.PAREN_LEFT],[41,lt.PAREN_RIGHT],[44,lt.COMMA],[63,lt.QUESTION],[58,lt.COLON],[36,lt.DOLLAR]]),ko=new Map;for(let[r,t]of Gc.entries())ko.set(r,{type:t,value:String.fromCharCode(r)});function Br(r){return r>=48&&r<=57}function vi(r){return r>=97&&r<=122||r>=65&&r<=90||r===95}function Ao(r){return vi(r)||Br(r)}function Oc(r){return Tc.has(r)}var Nt;(function(r){r[r.Program=0]="Program",r[r.Literal=1]="Literal",r[r.Identifier=2]="Identifier",r[r.MemberExpression=3]="MemberExpression",r[r.CallExpression=4]="CallExpression",r[r.BinaryExpression=5]="BinaryExpression",r[r.UnaryExpression=6]="UnaryExpression",r[r.ConditionalExpression=7]="ConditionalExpression"})(Nt||(Nt={}));var $c=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),Mc={type:Nt.Literal,value:null},Cc={type:Nt.Literal,value:!0},Pc={type:Nt.Literal,value:!1},Nc=r=>{let t=0,e=r.length,n=()=>t>=e?null:r[t],s=()=>r[t++],o=w=>{let m=n();return m!==null&&m.type===w},u=w=>w.type===lt.OPERATOR?$c.get(w.value)||-1:w.type===lt.DOT||w.type===lt.BRACKET_LEFT?9:w.type===lt.QUESTION?1:-1,l=w=>{let m,x;if(s().type===lt.DOT){if(!o(lt.IDENTIFIER)){let G=n();throw new qt("Expected property name",t,G?G.value:"")}let _=s();m={type:Nt.Identifier,name:_.value},x=!1}else{if(m=d(0),!o(lt.BRACKET_RIGHT)){let _=n();throw new qt("Expected closing bracket",t,_?_.value:"")}s(),x=!0}return{type:Nt.MemberExpression,object:w,property:m,computed:x}},g=()=>{let w=n();if(!w)throw new qt("Unexpected end of input",t,"");if(w.type===lt.OPERATOR&&(w.value==="!"||w.value==="-")){s();let m=g();return{type:Nt.UnaryExpression,operator:w.value,argument:m,prefix:!0}}switch(w.type){case lt.NUMBER:return s(),{type:Nt.Literal,value:Number(w.value)};case lt.STRING:return s(),{type:Nt.Literal,value:w.value};case lt.BOOLEAN:return s(),w.value==="true"?Cc:Pc;case lt.NULL:return s(),Mc;case lt.IDENTIFIER:return s(),{type:Nt.Identifier,name:w.value};case lt.FUNCTION:return(()=>{let m=s(),x=[];if(!o(lt.PAREN_LEFT)){let _=n();throw new qt("Expected opening parenthesis after function name",t,_?_.value:"")}for(s();;){if(o(lt.PAREN_RIGHT)){s();break}if(!n()){let G=n();throw new qt("Expected closing parenthesis",t,G?G.value:"")}if(x.length>0){if(!o(lt.COMMA)){let G=n();throw new qt("Expected comma between function arguments",t,G?G.value:"")}s()}let _=d(0);x.push(_)}return{type:Nt.CallExpression,callee:{type:Nt.Identifier,name:m.value},arguments:x}})();case lt.PAREN_LEFT:{s();let m=d(0);if(!o(lt.PAREN_RIGHT)){let x=n();throw new qt("Expected closing parenthesis",t,x?x.value:"")}return s(),m}default:throw new qt(`Unexpected token: ${w.type}`,t,w.value)}},d=(w=0)=>{let m=g();for(;t")}s();let M=d(0);m={type:Nt.ConditionalExpression,test:m,consequent:G,alternate:M}}}return m},y=d();return{type:Nt.Program,body:y}},zc=(r,t,e)=>{let n=t;e&&(n={...t,context:{...t.context,...e}});let s=o=>{switch(o.type){case Nt.Literal:return(u=>u.value)(o);case Nt.Identifier:return(u=>{if(!(u.name in n.context))throw new qt(`Undefined variable: ${u.name}`);return n.context[u.name]})(o);case Nt.MemberExpression:return(u=>{let l=s(u.object);if(l==null)throw new qt("Cannot access property of null or undefined");return l[u.computed?s(u.property):u.property.name]})(o);case Nt.CallExpression:return(u=>{let l=n.functions[u.callee.name];if(!l)throw new qt(`Undefined function: ${u.callee.name}`);return l(...u.arguments.map((g=>s(g))))})(o);case Nt.BinaryExpression:return(u=>{if(u.operator==="&&"){let d=s(u.left);return d&&s(u.right)}if(u.operator==="||")return s(u.left)||s(u.right);let l=s(u.left),g=s(u.right);switch(u.operator){case"+":return l+g;case"-":return l-g;case"*":return l*g;case"/":return l/g;case"%":return l%g;case"===":return l===g;case"!==":return l!==g;case">":return l>g;case">=":return l>=g;case"<":return l{let l=s(u.argument);if(u.prefix)switch(u.operator){case"!":return!l;case"-":if(typeof l!="number")throw new qt(`Cannot apply unary - to non-number: ${l}`);return-l;default:throw new qt(`Unknown operator: ${u.operator}`)}throw new qt(`Postfix operators are not supported: ${u.operator}`)})(o);case Nt.ConditionalExpression:return(u=>{let l=s(u.test);return s(l?u.consequent:u.alternate)})(o);default:throw new qt(`Evaluation error: Unsupported node type: ${o.type}`)}};return s(r.body)};function bi(r){let t=(s=>{let o=s,u=o.length,l=new Array(Math.ceil(u/3)),g=0,d=0;function y(M){let q=d+1;d++;let L="",P=!1;for(;d({context:s,functions:o}))({},Rc);return(s={})=>zc(e,n,s)}function Io(r,t={}){return bi(r)(t)}function Do(r,t){if(typeof r!="string")return;let e=r.trim();if(e)try{return bi(e),Io(e,t)}catch{return}}function Dr(r){return typeof r=="number"}function Ei(r){if(!r)return[0,0,0];if(Dr(r))return[r,r,r];if(Array.isArray(r)&&r.length===0)return[0,0,0];let[t,e=t,n=t]=r;return[t,e,n]}function _o(r){return Dr(r)?!0:Array.isArray(r)?r.every(t=>Dr(t)):!1}function Oe(r){return r==null}function Ro(r){return typeof r=="string"}function jo(r){return typeof r=="function"}function Vr(r,t){if(typeof r=="function")return r;if(typeof r=="string"){let e=r;return(...n)=>{let s={};for(let o=0;or}function To(r,t=10,e="node"){if(Oe(r))return()=>t;if(Ro(r)){let n=Vr(r,[e]);return s=>{let o=n(s);return _o(o)?o:t}}return jo(r)?r:Dr(r)?()=>r:Array.isArray(r)?()=>r:()=>t}var An=(r,t,e=10,n=0)=>{let s=To(t,n),o=To(r,e);return u=>{let[l,g,d]=Ei(o(u)),[y,w,m]=Ei(s(u));return[l+y,g+w,d+m]}};var kn=class{constructor(t,e={}){this.edgeIdCounter=new Map,this.nodeMap=Uc(t.nodes,e.node),this.edgeMap=Wc(t.edges||[],e.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let e=this.indexNodeCache.get(t);return e?this.nodeMap.get(e):void 0}nodeIndexOf(t){var e;return this.nodeIndexCache||this.buildNodeIndexCache(),(e=this.nodeIndexCache.get(t))!==null&&e!==void 0?e:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let e=0;this.nodeMap.forEach(n=>t(n,e++))}originalNode(t){let e=this.nodeMap.get(t);return e?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let e=0;this.edgeMap.forEach(n=>t(n,e++))}originalEdge(t){let e=this.edgeMap.get(t);return e?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let e=`${t.source}-${t.target}`,n=this.edgeIdCounter.get(e)||0,s=n===0?e:`${e}-${n}`;return this.edgeIdCounter.set(e,n+1),s}degree(t,e="both"){this.degreeCache||this.buildDegreeCache();let n=this.degreeCache.get(t);return n?n[e]:0}neighbors(t,e="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),e==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(e==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let n=this.inAdjacencyCache.get(t),s=this.outAdjacencyCache.get(t);if(!n&&!s)return[];if(!n)return Array.from(s);if(!s)return Array.from(n);let o=new Set;return n.forEach(u=>o.add(u)),s.forEach(u=>o.add(u)),Array.from(o)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let e=new Map;for(let n of t)e.set(n.id,n);this.nodeMap=e,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:e,target:n}=t;if(t.source===t.target)continue;this.degreeCache.has(e)||this.degreeCache.set(e,{in:0,out:0,both:0});let s=this.degreeCache.get(t.source);s&&(s.out++,s.both++),this.degreeCache.has(n)||this.degreeCache.set(n,{in:0,out:0,both:0});let o=this.degreeCache.get(t.target);o&&(o.in++,o.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((e,n)=>{this.nodeIndexCache.set(n,t),this.indexNodeCache.set(t,n),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Fc=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],qc=["id","source","target","points"];function Uc(r,t){if(!r)throw new Error("Data.nodes is required");let e=new Map;for(let n of r){let s={_original:n};for(let o of Fc){let u=n[o];Oe(u)||(s[o]=u)}if(t){let o=t(n);for(let u in o){let l=o[u];Oe(l)||(s[u]=l)}}if(Oe(s.id))throw new Error("Node is missing id field");e.set(s.id,s)}return e}function Wc(r,t,e){let n=new Map;for(let s of r){let o={_original:s};for(let u of qc){let l=s[u];Oe(l)||(o[u]=l)}if(t){let u=t(s);for(let l in u){let g=u[l];Oe(g)||(o[l]=g)}}if(Oe(o.source)||Oe(o.target))throw new Error("Edge is missing source or target field");Oe(o.id)&&(o.id=e?.(s)),n.set(o.id,o)}return n}var In=class{constructor(t,e={}){this.graph=new kn(t,e)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((e,n)=>{e.sourceNode=this.graph.node(e.source),e.targetNode=this.graph.node(e.target),t(e,n)})}destroy(){this.graph.destroy()}};var Go=Symbol("Comlink.proxy"),Bc=Symbol("Comlink.endpoint"),Vc=Symbol("Comlink.releaseProxy"),Si=Symbol("Comlink.finalizer"),_n=Symbol("Comlink.thrown"),Oo=r=>typeof r=="object"&&r!==null||typeof r=="function",Kc={canHandle:r=>Oo(r)&&r[Go],serialize(r){let{port1:t,port2:e}=new MessageChannel;return Mo(r,t),[e,[e]]},deserialize(r){return r.start(),Ai(r)}},Yc={canHandle:r=>Oo(r)&&_n in r,serialize({value:r}){let t;return r instanceof Error?t={isError:!0,value:{message:r.message,name:r.name,stack:r.stack}}:t={isError:!1,value:r},[t,[]]},deserialize(r){throw r.isError?Object.assign(new Error(r.value.message),r.value):r.value}},$o=new Map([["proxy",Kc],["throw",Yc]]);function Xc(r,t){for(let e of r)if(t===e||e==="*"||e instanceof RegExp&&e.test(t))return!0;return!1}function Mo(r,t=globalThis,e=["*"]){t.addEventListener("message",function n(s){if(!s||!s.data)return;if(!Xc(e,s.origin)){console.warn(`Invalid origin '${s.origin}' for comlink proxy`);return}let{id:o,type:u,path:l}=Object.assign({path:[]},s.data),g=(s.data.argumentList||[]).map(fr),d;try{let y=l.slice(0,-1).reduce((m,x)=>m[x],r),w=l.reduce((m,x)=>m[x],r);switch(u){case"GET":d=w;break;case"SET":y[l.slice(-1)[0]]=fr(s.data.value),d=!0;break;case"APPLY":d=w.apply(y,g);break;case"CONSTRUCT":{let m=new w(...g);d=ef(m)}break;case"ENDPOINT":{let{port1:m,port2:x}=new MessageChannel;Mo(r,x),d=tf(m,[m])}break;case"RELEASE":d=void 0;break;default:return}}catch(y){d={value:y,[_n]:0}}Promise.resolve(d).catch(y=>({value:y,[_n]:0})).then(y=>{let[w,m]=Tn(y);t.postMessage(Object.assign(Object.assign({},w),{id:o}),m),u==="RELEASE"&&(t.removeEventListener("message",n),Co(t),Si in r&&typeof r[Si]=="function"&&r[Si]())}).catch(y=>{let[w,m]=Tn({value:new TypeError("Unserializable return value"),[_n]:0});t.postMessage(Object.assign(Object.assign({},w),{id:o}),m)})}),t.start&&t.start()}function Qc(r){return r.constructor.name==="MessagePort"}function Co(r){Qc(r)&&r.close()}function Ai(r,t){let e=new Map;return r.addEventListener("message",function(s){let{data:o}=s;if(!o||!o.id)return;let u=e.get(o.id);if(u)try{u(o)}finally{e.delete(o.id)}}),xi(r,e,[],t)}function Dn(r){if(r)throw new Error("Proxy has been released and is not useable")}function Po(r){return _r(r,new Map,{type:"RELEASE"}).then(()=>{Co(r)})}var Rn=new WeakMap,jn="FinalizationRegistry"in globalThis&&new FinalizationRegistry(r=>{let t=(Rn.get(r)||0)-1;Rn.set(r,t),t===0&&Po(r)});function Jc(r,t){let e=(Rn.get(t)||0)+1;Rn.set(t,e),jn&&jn.register(r,t,r)}function Zc(r){jn&&jn.unregister(r)}function xi(r,t,e=[],n=function(){}){let s=!1,o=new Proxy(n,{get(u,l){if(Dn(s),l===Vc)return()=>{Zc(o),Po(r),t.clear(),s=!0};if(l==="then"){if(e.length===0)return{then:()=>o};let g=_r(r,t,{type:"GET",path:e.map(d=>d.toString())}).then(fr);return g.then.bind(g)}return xi(r,t,[...e,l])},set(u,l,g){Dn(s);let[d,y]=Tn(g);return _r(r,t,{type:"SET",path:[...e,l].map(w=>w.toString()),value:d},y).then(fr)},apply(u,l,g){Dn(s);let d=e[e.length-1];if(d===Bc)return _r(r,t,{type:"ENDPOINT"}).then(fr);if(d==="bind")return xi(r,t,e.slice(0,-1));let[y,w]=Lo(g);return _r(r,t,{type:"APPLY",path:e.map(m=>m.toString()),argumentList:y},w).then(fr)},construct(u,l){Dn(s);let[g,d]=Lo(l);return _r(r,t,{type:"CONSTRUCT",path:e.map(y=>y.toString()),argumentList:g},d).then(fr)}});return Jc(o,r),o}function Hc(r){return Array.prototype.concat.apply([],r)}function Lo(r){let t=r.map(Tn);return[t.map(e=>e[0]),Hc(t.map(e=>e[1]))]}var No=new WeakMap;function tf(r,t){return No.set(r,t),r}function ef(r){return Object.assign(r,{[Go]:!0})}function Tn(r){for(let[t,e]of $o)if(e.canHandle(r)){let[n,s]=e.serialize(r);return[{type:"HANDLER",name:t,value:n},s]}return[{type:"RAW",value:r},No.get(r)||[]]}function fr(r){switch(r.type){case"HANDLER":return $o.get(r.name).deserialize(r.value);case"RAW":return r.value}}function _r(r,t,e,n){return new Promise(s=>{let o=rf();t.set(o,s),r.start&&r.start(),r.postMessage(Object.assign({id:o},e),n)})}function rf(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var Ln=class{constructor(){this.worker=null,this.workerApi=null}execute(t,e,n){return Ie(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,e,n)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return Ie(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),n=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:n}),this.workerApi=Ai(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let e=document.currentScript;if(e?.src)return e.src;let n=document.getElementsByTagName("script");for(let s=n.length-1;s>=0;s--){let o=n[s].src;if(o&&(o.includes("index.js")||o.includes("index.min.js")))return o}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let s=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(s!==t)return s}let e=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(e!==t)return e;let n=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(n!==t)return n}return"./worker.js"}};var nr=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,e){return Object.assign({},t,e||{})}execute(t,e){return Ie(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,e);let{node:n,edge:s,enableWorker:o}=this.runtimeOptions;this.context=new In(t,{node:n,edge:s}),this.model=this.context.graph,o&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,e){var n;return Ie(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new Ln);let s=yield this.supervisor.execute(this.id,t,e);(n=this.context)===null||n===void 0||n.replace(s)}catch(s){console.error("Layout in worker failed, fallback to main thread layout.",s),yield this.layout(e)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function Rr(r,t,e=2){if(r.nodeCount()===1){let s=r.firstNode();s.x=t[0],s.y=t[1],e===3&&(s.z=t[2]||0)}}function zo(r,t){let e=r.nodes();return e.sort(t),r.setNodeOrder(e),r}function Fo(r,t="desc"){return zo(r,(e,n)=>{let s=r.degree(e.id),o=r.degree(n.id);return t==="asc"?s-o:o-s})}function qo(r,t){return zo(r,(e,n)=>{let s=r.originalNode(e.id),o=r.originalNode(n.id);return t(s,o)})}var jr=r=>{let{width:t,height:e,center:n}=r,s=t??(typeof window<"u"?window.innerWidth:0),o=e??(typeof window<"u"?window.innerHeight:0),u=n??[s/2,o/2];return{width:s,height:o,center:u}};var Gn={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},On=class extends nr{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return Gn}layout(){return Ie(this,void 0,void 0,function*(){let{width:t,height:e,center:n}=jr(this.options),s=this.model.nodeCount();if(!s||s===1){Rr(this.model,n);return}let{sortBy:o,maxLevelDiff:u,sweep:l,clockwise:g,equidistant:d,preventOverlap:y,startAngle:w=Gn.startAngle,nodeSize:m,nodeSpacing:x}=this.options,_=!o||o==="degree"?"degree":Vr(o,["node"]);if(_==="degree")Fo(this.model);else{let O=(N,T)=>{let it=_(N),gt=_(T);return it===gt?0:it>gt?-1:1};qo(this.model,O)}let G=this.model.nodes(),M=new Map;for(let O of G){let N=_==="degree"?this.model.degree(O.id):_(O._original);M.set(O.id,N)}let q=this.model.firstNode(),L=u||M.get(q.id)/4,P=An(m,x,Gn.nodeSize,Gn.nodeSpacing),B=new Map;for(let O of G)B.set(O.id,Math.max(...P(O._original)));let U=[{nodes:[]}],rt=U[0];for(let O=0;O0){let T=rt.nodes[0],it=Math.abs(M.get(T.id)-M.get(N.id));L&&it>=L&&(rt={nodes:[]},U.push(rt))}rt.nodes.push(N)}for(let O of U){let N=O.nodes.map(T=>B.get(T.id));O.nodeSizes=N,O.maxNodeSize=Math.max(...N)}if(U.forEach(O=>{let N=l===void 0?2*Math.PI-2*Math.PI/O.nodes.length:l;O.dTheta=N/Math.max(1,O.nodes.length-1)}),y){let O=0;for(let N=0;N1){let it=T.nodeSizes||[],gt=0;for(let le=0;le0?gt/mt:0;O=Math.max(ee,O)}if(T.r=O,N{it===0&&(N=T.r||0),T.r=N,N+=O})}U.forEach(O=>{let N=O.dTheta||0,T=O.r||0;O.nodes.forEach((it,gt)=>{let wt=w+(g?1:-1)*N*gt;it.x=n[0]+T*Math.cos(wt),it.y=n[1]+T*Math.sin(wt)})})})}};function Uo(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function $n(r){if(Object.prototype.hasOwnProperty.call(r,"__esModule"))return r;var t=r.default;if(typeof t=="function"){var e=function n(){var s=!1;try{s=this instanceof n}catch{}return s?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};e.prototype=t.prototype}else e={};return Object.defineProperty(e,"__esModule",{value:!0}),Object.keys(r).forEach(function(n){var s=Object.getOwnPropertyDescriptor(r,n);Object.defineProperty(e,n,s.get?s:{enumerable:!0,get:function(){return r[n]}})}),e}var yt={};var ki={};ni(ki,{isAnyArray:()=>ir});var nf=Object.prototype.toString;function ir(r){let t=nf.call(r);return t.endsWith("Array]")&&!t.includes("Big")}var Wo=$n(ki);var Ii={};ni(Ii,{default:()=>sf});function Bo(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!ir(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,n=e===void 0?0:e,s=t.toIndex,o=s===void 0?r.length:s;if(n<0||n>=r.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=n||o>r.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var u=r[n],l=n+1;lu&&(u=r[l]);return u}function Vo(r){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!ir(r))throw new TypeError("input must be an array");if(r.length===0)throw new TypeError("input must not be empty");var e=t.fromIndex,n=e===void 0?0:e,s=t.toIndex,o=s===void 0?r.length:s;if(n<0||n>=r.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=n||o>r.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var u=r[n],l=n+1;l1&&arguments[1]!==void 0?arguments[1]:{};if(ir(r)){if(r.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var e;if(t.output!==void 0){if(!ir(t.output))throw new TypeError("output option must be an array if specified");e=t.output}else e=new Array(r.length);var n=Vo(r),s=Bo(r);if(n===s)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var o=t.min,u=o===void 0?t.autoMinMax?n:0:o,l=t.max,g=l===void 0?t.autoMinMax?s:1:l;if(u>=g)throw new RangeError("min option must be smaller than max option");for(var d=(g-u)/(s-n),y=0;y=0&&s?` ${g(p,a-1)}`:g(p,a)).padEnd(a)}function g(p,a){let s=p.toString();if(s.length<=a)return s;let n=p.toFixed(a);if(n.length>a&&(n=p.toFixed(Math.max(0,a-(n.length-a)))),n.length<=a&&!n.startsWith("0.000")&&!n.startsWith("-0.000"))return n;let o=p.toExponential(a);return o.length>a&&(o=p.toExponential(Math.max(0,a-(o.length-a)))),o.slice(0)}function d(p,a){p.prototype.add=function(n){return typeof n=="number"?this.addS(n):this.addM(n)},p.prototype.addS=function(n){for(let o=0;o>n);return this},p.prototype.signPropagatingRightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>n.get(o,l));return this},p.signPropagatingRightShift=function(n,o){return new a(n).signPropagatingRightShift(o)},p.prototype.rightShift=function(n){return typeof n=="number"?this.rightShiftS(n):this.rightShiftM(n)},p.prototype.rightShiftS=function(n){for(let o=0;o>>n);return this},p.prototype.rightShiftM=function(n){if(n=a.checkMatrix(n),this.rows!==n.rows||this.columns!==n.columns)throw new RangeError("Matrices dimensions must be equal");for(let o=0;o>>n.get(o,l));return this},p.rightShift=function(n,o){return new a(n).rightShift(o)},p.prototype.zeroFillRightShift=p.prototype.rightShift,p.prototype.zeroFillRightShiftS=p.prototype.rightShiftS,p.prototype.zeroFillRightShiftM=p.prototype.rightShiftM,p.zeroFillRightShift=p.rightShift,p.prototype.not=function(){for(let n=0;nn)throw new RangeError("Row index out of range")}function m(p,a,s){let n=s?p.columns:p.columns-1;if(a<0||a>n)throw new RangeError("Column index out of range")}function v(p,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==p.columns)throw new RangeError("vector size must be the same as the number of columns");return a}function D(p,a){if(a.to1DArray&&(a=a.to1DArray()),a.length!==p.rows)throw new RangeError("vector size must be the same as the number of rows");return a}function $(p,a){if(!r.isAnyArray(a))throw new TypeError("row indices must be an array");for(let s=0;s=p.rows)throw new RangeError("row indices are out of range")}function P(p,a){if(!r.isAnyArray(a))throw new TypeError("column indices must be an array");for(let s=0;s=p.columns)throw new RangeError("column indices are out of range")}function q(p,a,s,n,o){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(G("startRow",a),G("endRow",s),G("startColumn",n),G("endColumn",o),a>s||n>o||a<0||a>=p.rows||s<0||s>=p.rows||n<0||n>=p.columns||o<0||o>=p.columns)throw new RangeError("Submatrix indices are out of range")}function B(p,a=0){let s=[];for(let n=0;n=l)throw new RangeError("min must be smaller than max");let y=l-o,E=new X(a,s);for(let S=0;Sn?(l=!0,n=s):(o=!1,l=!0);a++}return o}isReducedEchelonForm(){let a=0,s=0,n=-1,o=!0,l=!1;for(;an?(l=!0,n=s):(o=!1,l=!0);for(let w=s+1;wa.get(o,n)&&(o=l);if(a.get(o,n)===0)n++;else{a.swapRows(s,o);let l=a.get(s,n);for(let w=n;w=0;)if(a.maxRow(o)===0)o--;else{let l=0,w=!1;for(;ls[n]&&(s[n]=this.get(n,o));return s}case"column":{let s=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let n=0;ns[o]&&(s[o]=this.get(n,o));return s}case void 0:{let s=this.get(0,0);for(let n=0;ns&&(s=this.get(n,o));return s}default:throw new Error(`invalid option: ${a}`)}}maxIndex(){F(this);let a=this.get(0,0),s=[0,0];for(let n=0;na&&(a=this.get(n,o),s[0]=n,s[1]=o);return s}min(a){if(this.isEmpty())return NaN;switch(a){case"row":{let s=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let n=0;ns&&(s=this.get(a,n));return s}maxRowIndex(a){b(this,a),F(this);let s=this.get(a,0),n=[a,0];for(let o=1;os&&(s=this.get(a,o),n[1]=o);return n}minRow(a){if(b(this,a),this.isEmpty())return NaN;let s=this.get(a,0);for(let n=1;ns&&(s=this.get(n,a));return s}maxColumnIndex(a){m(this,a),F(this);let s=this.get(0,a),n=[0,a];for(let o=1;os&&(s=this.get(o,a),n[0]=o);return n}minColumn(a){if(m(this,a),this.isEmpty())return NaN;let s=this.get(0,a);for(let n=1;n=1;o/=2)(o&1)!==0&&(s=s.mmul(n)),n=n.mmul(n);return s}strassen2x2(a){a=X.checkMatrix(a);let s=new X(2,2),n=this.get(0,0),o=a.get(0,0),l=this.get(0,1),w=a.get(0,1),y=this.get(1,0),E=a.get(1,0),S=this.get(1,1),R=a.get(1,1),x=(n+S)*(o+R),L=(y+S)*o,Y=n*(w-R),T=S*(E-o),C=(n+l)*R,J=(y-n)*(o+w),k=(l-S)*(E+R),K=x+T-C+k,et=Y+C,ct=L+T,lt=x-L+Y+J;return s.set(0,0,K),s.set(0,1,et),s.set(1,0,ct),s.set(1,1,lt),s}strassen3x3(a){a=X.checkMatrix(a);let s=new X(3,3),n=this.get(0,0),o=this.get(0,1),l=this.get(0,2),w=this.get(1,0),y=this.get(1,1),E=this.get(1,2),S=this.get(2,0),R=this.get(2,1),x=this.get(2,2),L=a.get(0,0),Y=a.get(0,1),T=a.get(0,2),C=a.get(1,0),J=a.get(1,1),k=a.get(1,2),K=a.get(2,0),et=a.get(2,1),ct=a.get(2,2),lt=(n+o+l-w-y-R-x)*J,Lt=(n-w)*(-Y+J),it=y*(-L+Y+C-J-k-K+ct),ht=(-n+w+y)*(L-Y+J),jt=(w+y)*(-L+Y),_=n*L,U=(-n+S+R)*(L-T+k),H=(-n+S)*(T-k),W=(S+R)*(-L+T),Gt=(n+o+l-y-E-S-R)*k,Dt=R*(-L+T+C-J-k-K+et),Tt=(-l+R+x)*(J+K-et),Ot=(l-x)*(J-et),Jt=l*K,xe=(R+x)*(-K+et),Vt=(-l+y+E)*(k+K-ct),$e=(l-E)*(k-ct),Oe=(y+E)*(-K+ct),mt=o*C,Ht=E*et,de=w*T,ge=S*Y,Bt=x*ct,Io=_+Jt+mt,_o=lt+ht+jt+_+Tt+Jt+xe,Ro=_+U+W+Gt+Jt+Vt+Oe,jo=Lt+it+ht+_+Jt+Vt+$e,Ao=Lt+ht+jt+_+Ht,$o=Jt+Vt+$e+Oe+de,To=_+U+H+Dt+Tt+Ot+Jt,Lo=Tt+Ot+Jt+xe+ge,Go=_+U+H+W+Bt;return s.set(0,0,Io),s.set(0,1,_o),s.set(0,2,Ro),s.set(1,0,jo),s.set(1,1,Ao),s.set(1,2,$o),s.set(2,0,To),s.set(2,1,Lo),s.set(2,2,Go),s}mmulStrassen(a){a=X.checkMatrix(a);let s=this.clone(),n=s.rows,o=s.columns,l=a.rows,w=a.columns;o!==l&&console.warn(`Multiplying ${n} x ${o} and ${l} x ${w} matrix: dimensions do not match.`);function y(x,L,Y){let T=x.rows,C=x.columns;if(T===L&&C===Y)return x;{let J=I.zeros(L,Y);return J=J.setSubMatrix(x,0,0),J}}let E=Math.max(n,l),S=Math.max(o,w);s=y(s,E,S),a=y(a,E,S);function R(x,L,Y,T){if(Y<=512||T<=512)return x.mmul(L);Y%2===1&&T%2===1?(x=y(x,Y+1,T+1),L=y(L,Y+1,T+1)):Y%2===1?(x=y(x,Y+1,T),L=y(L,Y+1,T)):T%2===1&&(x=y(x,Y,T+1),L=y(L,Y,T+1));let C=parseInt(x.rows/2,10),J=parseInt(x.columns/2,10),k=x.subMatrix(0,C-1,0,J-1),K=L.subMatrix(0,C-1,0,J-1),et=x.subMatrix(0,C-1,J,x.columns-1),ct=L.subMatrix(0,C-1,J,L.columns-1),lt=x.subMatrix(C,x.rows-1,0,J-1),Lt=L.subMatrix(C,L.rows-1,0,J-1),it=x.subMatrix(C,x.rows-1,J,x.columns-1),ht=L.subMatrix(C,L.rows-1,J,L.columns-1),jt=R(I.add(k,it),I.add(K,ht),C,J),_=R(I.add(lt,it),K,C,J),U=R(k,I.sub(ct,ht),C,J),H=R(it,I.sub(Lt,K),C,J),W=R(I.add(k,et),ht,C,J),Gt=R(I.sub(lt,k),I.add(K,ct),C,J),Dt=R(I.sub(et,it),I.add(Lt,ht),C,J),Tt=I.add(jt,H);Tt.sub(W),Tt.add(Dt);let Ot=I.add(U,W),Jt=I.add(_,H),xe=I.sub(jt,_);xe.add(U),xe.add(Gt);let Vt=I.zeros(2*Tt.rows,2*Tt.columns);return Vt=Vt.setSubMatrix(Tt,0,0),Vt=Vt.setSubMatrix(Ot,Tt.rows,0),Vt=Vt.setSubMatrix(Jt,0,Tt.columns),Vt=Vt.setSubMatrix(xe,Tt.rows,Tt.columns),Vt.subMatrix(0,Y-1,0,T-1)}return R(s,a,E,S)}scaleRows(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new X(this.rows,this.columns);for(let l=0;l0&&t(w,{min:s,max:n,output:w}),o.setRow(l,w)}return o}scaleColumns(a={}){if(typeof a!="object")throw new TypeError("options must be an object");let{min:s=0,max:n=1}=a;if(!Number.isFinite(s))throw new TypeError("min must be a number");if(!Number.isFinite(n))throw new TypeError("max must be a number");if(s>=n)throw new RangeError("min must be smaller than max");let o=new X(this.rows,this.columns);for(let l=0;ln||s<0||s>=this.columns||n<0||n>=this.columns)throw new RangeError("Argument out of range");let o=new X(a.length,n-s+1);for(let l=0;l=this.rows)throw new RangeError(`Row index out of range: ${a[l]}`);o.set(l,w-s,this.get(a[l],w))}return o}subMatrixColumn(a,s,n){if(s===void 0&&(s=0),n===void 0&&(n=this.rows-1),s>n||s<0||s>=this.rows||n<0||n>=this.rows)throw new RangeError("Argument out of range");let o=new X(n-s+1,a.length);for(let l=0;l=this.columns)throw new RangeError(`Column index out of range: ${a[l]}`);o.set(w-s,l,this.get(w,a[l]))}return o}setSubMatrix(a,s,n){if(a=X.checkMatrix(a),a.isEmpty())return this;let o=s+a.rows-1,l=n+a.columns-1;q(this,s,o,n,l);for(let w=0;wtypeof a=="number")}I.random=I.rand,I.randomInt=I.randInt,I.diagonal=I.diag,I.prototype.diagonal=I.prototype.diag,I.identity=I.eye,I.prototype.negate=I.prototype.neg,I.prototype.tensorProduct=I.prototype.kroneckerProduct;let Cr=class Cr extends I{constructor(s,n){super();jn(this,Er);pi(this,"data");if(Cr.isMatrix(s))An(this,Er,Jn).call(this,s.rows,s.columns),Cr.copy(s,this);else if(Number.isInteger(s)&&s>=0)An(this,Er,Jn).call(this,s,n);else if(r.isAnyArray(s)){let o=s;if(s=o.length,n=s?o[0].length:0,typeof n!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let l=0;l"u"&&(n=s,s=this.columns),m(this,s,!0),n=D(this,n);for(let o=0;o=0)for(let o=0;o=0)zr(this,re,new X(s,s));else if(zr(this,re,new X(s)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return ke(this,re).size}get rows(){return ke(this,re).rows}get columns(){return ke(this,re).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(s){return X.isMatrix(s)&&s.klassType==="SymmetricMatrix"}static zeros(s){return new this(s)}static ones(s){return new this(s).fill(1)}clone(){let s=new Pr(this.diagonalSize);for(let[n,o,l]of this.upperRightEntries())s.set(n,o,l);return s}toMatrix(){return new X(this)}get(s,n){return ke(this,re).get(s,n)}set(s,n,o){return ke(this,re).set(s,n,o),ke(this,re).set(n,s,o),this}removeCross(s){return ke(this,re).removeRow(s),ke(this,re).removeColumn(s),this}addCross(s,n){n===void 0&&(n=s,s=this.diagonalSize);let o=n.slice();return o.splice(s,1),ke(this,re).addRow(s,o),ke(this,re).addColumn(s,n),this}applyMask(s){if(s.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let n=[];for(let[o,l]of s.entries())l||n.push(o);n.reverse();for(let o of n)this.removeCross(o);return this}toCompact(){let{diagonalSize:s}=this,n=new Array(s*(s+1)/2);for(let o=0,l=0,w=0;w=s&&(o=++l);return n}static fromCompact(s){let n=s.length,o=(Math.sqrt(8*n+1)-1)/2;if(!Number.isInteger(o))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(s)}`);let l=new Pr(o);for(let w=0,y=0,E=0;E=o&&(w=++y);return l}*upperRightEntries(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}}*upperRightValues(){for(let s=0,n=0;s=this.diagonalSize&&(n=++s)}};re=new WeakMap;let ae=Pr;ae.prototype.klassType="SymmetricMatrix";class qt extends ae{static isDistanceMatrix(a){return ae.isSymmetricMatrix(a)&&a.klassSubType==="DistanceMatrix"}constructor(a){if(super(a),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(a,s,n){return a===s&&(n=0),super.set(a,s,n)}addCross(a,s){return s===void 0&&(s=a,a=this.diagonalSize),s=s.slice(),s[a]=0,super.addCross(a,s)}toSymmetricMatrix(){return new ae(this)}clone(){let a=new qt(this.diagonalSize);for(let[s,n,o]of this.upperRightEntries())s!==n&&a.set(s,n,o);return a}toCompact(){let{diagonalSize:a}=this,s=(a-1)*a/2,n=new Array(s);for(let o=1,l=0,w=0;w=a&&(o=++l+1);return n}static fromCompact(a){let s=a.length;if(s===0)return new this(0);let n=(Math.sqrt(8*s+1)+1)/2;if(!Number.isInteger(n))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(a)}`);let o=new this(n);for(let l=1,w=0,y=0;y=n&&(l=++w+1);return o}}qt.prototype.klassSubType="DistanceMatrix";class st extends I{constructor(a,s,n){super(),this.matrix=a,this.rows=s,this.columns=n}}class mr extends st{constructor(a,s){m(a,s),super(a,a.rows,1),this.column=s}set(a,s,n){return this.matrix.set(a,this.column,n),this}get(a){return this.matrix.get(a,this.column)}}class pe extends st{constructor(a,s){P(a,s),super(a,a.rows,s.length),this.columnIndices=s}set(a,s,n){return this.matrix.set(a,this.columnIndices[s],n),this}get(a,s){return this.matrix.get(a,this.columnIndices[s])}}class Dn extends st{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(a,this.columns-s-1,n),this}get(a,s){return this.matrix.get(a,this.columns-s-1)}}class Ye extends st{constructor(a){super(a,a.rows,a.columns)}set(a,s,n){return this.matrix.set(this.rows-a-1,s,n),this}get(a,s){return this.matrix.get(this.rows-a-1,s)}}class In extends st{constructor(a,s){b(a,s),super(a,1,a.columns),this.row=s}set(a,s,n){return this.matrix.set(this.row,s,n),this}get(a,s){return this.matrix.get(this.row,s)}}class tr extends st{constructor(a,s){$(a,s),super(a,s.length,a.columns),this.rowIndices=s}set(a,s,n){return this.matrix.set(this.rowIndices[a],s,n),this}get(a,s){return this.matrix.get(this.rowIndices[a],s)}}class _t extends st{constructor(a,s,n){$(a,s),P(a,n),super(a,s.length,n.length),this.rowIndices=s,this.columnIndices=n}set(a,s,n){return this.matrix.set(this.rowIndices[a],this.columnIndices[s],n),this}get(a,s){return this.matrix.get(this.rowIndices[a],this.columnIndices[s])}}class Et extends st{constructor(a,s,n,o,l){q(a,s,n,o,l),super(a,n-s+1,l-o+1),this.startRow=s,this.startColumn=o}set(a,s,n){return this.matrix.set(this.startRow+a,this.startColumn+s,n),this}get(a,s){return this.matrix.get(this.startRow+a,this.startColumn+s)}}class vt extends st{constructor(a){super(a,a.columns,a.rows)}set(a,s,n){return this.matrix.set(s,a,n),this}get(a,s){return this.matrix.get(s,a)}}class we extends I{constructor(a,s={}){let{rows:n=1}=s;if(a.length%n!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=n,this.columns=a.length/n,this.data=a}set(a,s,n){let o=this._calculateIndex(a,s);return this.data[o]=n,this}get(a,s){let n=this._calculateIndex(a,s);return this.data[n]}_calculateIndex(a,s){return a*this.columns+s}}class rt extends I{constructor(a){super(),this.data=a,this.rows=a.length,this.columns=a[0].length}set(a,s,n){return this.data[a][s]=n,this}get(a,s){return this.data[a][s]}}function ut(p,a){if(r.isAnyArray(p))return p[0]&&r.isAnyArray(p[0])?new rt(p):new we(p,a);throw new Error("the argument is not an array")}class M{constructor(a){a=rt.checkMatrix(a);let s=a.clone(),n=s.rows,o=s.columns,l=new Float64Array(n),w=1,y,E,S,R,x,L,Y,T,C;for(y=0;yMath.abs(T[R])&&(R=y);if(R!==E){for(S=0;S=0;S--){for(E=0;Ew?o.set(l,w,a.get(l,w)):l===w?o.set(l,w,1):o.set(l,w,0);return o}get upperTriangularMatrix(){let a=this.LU,s=a.rows,n=a.columns,o=new X(s,n);for(let l=0;lMath.abs(a)?(s=a/p,Math.abs(p)*Math.sqrt(1+s*s)):a!==0?(s=p/a,Math.abs(a)*Math.sqrt(1+s*s)):0}class je{constructor(a){a=rt.checkMatrix(a);let s=a.clone(),n=a.rows,o=a.columns,l=new Float64Array(o),w,y,E,S;for(E=0;E=0;S--){for(E=0;E=0;y--){for(l=0;l=0;_--)if(T[_]!==0){for(let U=_+1;U=0;_--){if(_0;){let _,U;for(_=it-2;_>=-1&&_!==-1;_--){let H=Number.MIN_VALUE+jt*Math.abs(T[_]+Math.abs(T[_+1]));if(Math.abs(k[_])<=H||Number.isNaN(k[_])){k[_]=0;break}}if(_===it-2)U=4;else{let H;for(H=it-1;H>=_&&H!==_;H--){let W=(H!==it?Math.abs(k[H]):0)+(H!==_+1?Math.abs(k[H-1]):0);if(Math.abs(T[H])<=jt*W){T[H]=0;break}}H===_?U=3:H===it-1?U=1:(U=2,_=H)}switch(_++,U){case 1:{let H=k[it-2];k[it-2]=0;for(let W=it-2;W>=_;W--){let Gt=Zt(T[W],H),Dt=T[W]/Gt,Tt=H/Gt;if(T[W]=Gt,W!==_&&(H=-Tt*k[W-1],k[W-1]=Dt*k[W-1]),S)for(let Ot=0;Ot=T[_+1]);){let H=T[_];if(T[_]=T[_+1],T[_+1]=H,S&&_s&&l.set(R,x,a.get(R,x)/this.s[x]);let w=this.U,y=w.rows,E=w.columns,S=new X(n,y);for(let R=0;Ra&&s++;return s}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return X.diag(this.s)}}function Fe(p,a=!1){return p=rt.checkMatrix(p),a?new ce(p).inverse():ie(p,X.eye(p.rows))}function ie(p,a,s=!1){return p=rt.checkMatrix(p),a=rt.checkMatrix(a),s?new ce(p).solve(a):p.isSquare()?new M(p).solve(a):new je(p).solve(a)}function Se(p){if(p=X.checkMatrix(p),p.isSquare()){if(p.columns===0)return 1;let a,s,n,o;if(p.columns===2)return a=p.get(0,0),s=p.get(0,1),n=p.get(1,0),o=p.get(1,1),a*o-s*n;if(p.columns===3){let l,w,y;return l=new _t(p,[1,2],[1,2]),w=new _t(p,[1,2],[0,2]),y=new _t(p,[1,2],[0,1]),a=p.get(0,0),s=p.get(0,1),n=p.get(0,2),a*Se(l)-s*Se(w)+n*Se(y)}else return new M(p).determinant}else throw Error("determinant can only be calculated for a square matrix")}function br(p,a){let s=[];for(let n=0;no)return new Array(a.rows+1).fill(0);{let l=a.addRow(s,[0]);for(let w=0;wa?l[w]=1/l[w]:l[w]=0;return o.mmul(X.diag(l).mmul(n.transpose()))}function Xe(p,a=p,s={}){p=new X(p);let n=!1;if(typeof a=="object"&&!X.isMatrix(a)&&!r.isAnyArray(a)?(s=a,a=p,n=!0):a=new X(a),p.rows!==a.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:o=!0}=s;o&&(p=p.center("column"),n||(a=a.center("column")));let l=p.transpose().mmul(a);for(let w=0;w0?o.set(l,l+1,s[l]):s[l]<0&&o.set(l,l-1,s[l])}return o}}function sr(p,a,s,n){let o,l,w,y,E,S,R,x;for(E=0;E0;y--){for(x=0,w=0,S=0;S0&&(l=-l),a[y]=x*l,w=w-o*l,s[y-1]=o-l,E=0;ES)do{for(o=s[S],x=(s[S+1]-o)/(2*a[S]),L=Zt(x,1),x<0&&(L=-L),s[S]=a[S]/(x+L),s[S+1]=a[S]*(x+L),Y=s[S+1],l=o-s[S],w=S+2;w=S;w--)for(J=C,C=T,et=K,o=T*a[w],l=T*x,L=Zt(x,a[w]),a[w+1]=K*L,K=a[w]/L,T=x/L,x=T*s[w]-K*o,s[w+1]=l+K*(T*o+K*s[w]),E=0;ELt*lt);s[S]=s[S]+ct,a[S]=0}for(w=0;w=x;S--)s[S]=a.get(S,x-1)/L,E+=s[S]*s[S];for(y=Math.sqrt(E),s[x]>0&&(y=-y),E=E-s[x]*y,s[x]=s[x]-y,R=x;R=x;S--)w+=s[S]*a.get(S,R);for(w=w/E,S=x;S<=l;S++)a.set(S,R,a.get(S,R)-w*s[S])}for(S=0;S<=l;S++){for(w=0,R=l;R>=x;R--)w+=s[R]*a.get(S,R);for(w=w/E,R=x;R<=l;R++)a.set(S,R,a.get(S,R)-w*s[R])}s[x]=L*s[x],a.set(x,x-1,L*y)}}for(S=0;S=o+1;x--)if(a.get(x,x-1)!==0){for(S=x+1;S<=l;S++)s[S]=a.get(S,x-1);for(R=x;R<=l;R++){for(y=0,S=x;S<=l;S++)y+=s[S]*n.get(S,R);for(y=y/s[x]/a.get(x,x-1),S=x;S<=l;S++)n.set(S,R,n.get(S,R)+y*s[S])}}}function Do(p,a,s,n,o){let l=p-1,w=0,y=p-1,E=Number.EPSILON,S=0,R=0,x=0,L=0,Y=0,T=0,C=0,J=0,k,K,et,ct,lt,Lt,it,ht,jt,_,U,H,W,Gt,Dt;for(k=0;ky)&&(s[k]=o.get(k,k),a[k]=0),K=Math.max(k-1,0);K=w;){for(ct=l;ct>w&&(T=Math.abs(o.get(ct-1,ct-1))+Math.abs(o.get(ct,ct)),T===0&&(T=R),!(Math.abs(o.get(ct,ct-1))=0){for(C=x>=0?x+C:x-C,s[l-1]=ht+C,s[l]=s[l-1],C!==0&&(s[l]=ht-it/C),a[l-1]=0,a[l]=0,ht=o.get(l,l-1),T=Math.abs(ht)+Math.abs(C),x=ht/T,L=C/T,Y=Math.sqrt(x*x+L*L),x=x/Y,L=L/Y,K=l-1;K0)){for(T=Math.sqrt(T),jt=ct&&(C=o.get(lt,lt),Y=ht-C,T=jt-C,x=(Y*T-it)/o.get(lt+1,lt)+o.get(lt,lt+1),L=o.get(lt+1,lt+1)-C-Y-T,Y=o.get(lt+2,lt+1),T=Math.abs(x)+Math.abs(L)+Math.abs(Y),x=x/T,L=L/T,Y=Y/T,!(lt===ct||Math.abs(o.get(lt,lt-1))*(Math.abs(L)+Math.abs(Y))lt+2&&o.set(k,k-3,0);for(et=lt;et<=l-1&&(Gt=et!==l-1,et!==lt&&(x=o.get(et,et-1),L=o.get(et+1,et-1),Y=Gt?o.get(et+2,et-1):0,ht=Math.abs(x)+Math.abs(L)+Math.abs(Y),ht!==0&&(x=x/ht,L=L/ht,Y=Y/ht)),ht!==0);et++)if(T=Math.sqrt(x*x+L*L+Y*Y),x<0&&(T=-T),T!==0){for(et!==lt?o.set(et,et-1,-T*ht):ct!==lt&&o.set(et,et-1,-o.get(et,et-1)),x=x+T,ht=x/T,jt=L/T,C=Y/T,L=L/x,Y=Y/x,K=et;K=0;l--)if(x=s[l],L=a[l],L===0)for(ct=l,o.set(l,l,1),k=l-1;k>=0;k--){for(it=o.get(k,k)-x,Y=0,K=ct;K<=l;K++)Y=Y+o.get(k,K)*o.get(K,l);if(a[k]<0)C=it,T=Y;else if(ct=k,a[k]===0?o.set(k,l,it!==0?-Y/it:-Y/(E*R)):(ht=o.get(k,k+1),jt=o.get(k+1,k),L=(s[k]-x)*(s[k]-x)+a[k]*a[k],Lt=(ht*T-C*Y)/L,o.set(k,l,Lt),o.set(k+1,l,Math.abs(ht)>Math.abs(C)?(-Y-it*Lt)/ht:(-T-jt*Lt)/C)),Lt=Math.abs(o.get(k,l)),E*Lt*Lt>1)for(K=k;K<=l;K++)o.set(K,l,o.get(K,l)/Lt)}else if(L<0)for(ct=l-1,Math.abs(o.get(l,l-1))>Math.abs(o.get(l-1,l))?(o.set(l-1,l-1,L/o.get(l,l-1)),o.set(l-1,l,-(o.get(l,l)-x)/o.get(l,l-1))):(Dt=Mr(0,-o.get(l-1,l),o.get(l-1,l-1)-x,L),o.set(l-1,l-1,Dt[0]),o.set(l-1,l,Dt[1])),o.set(l,l-1,0),o.set(l,l,1),k=l-2;k>=0;k--){for(_=0,U=0,K=ct;K<=l;K++)_=_+o.get(k,K)*o.get(K,l-1),U=U+o.get(k,K)*o.get(K,l);if(it=o.get(k,k)-x,a[k]<0)C=it,Y=_,T=U;else if(ct=k,a[k]===0?(Dt=Mr(-_,-U,it,L),o.set(k,l-1,Dt[0]),o.set(k,l,Dt[1])):(ht=o.get(k,k+1),jt=o.get(k+1,k),H=(s[k]-x)*(s[k]-x)+a[k]*a[k]-L*L,W=(s[k]-x)*2*L,H===0&&W===0&&(H=E*R*(Math.abs(it)+Math.abs(L)+Math.abs(ht)+Math.abs(jt)+Math.abs(C))),Dt=Mr(ht*Y-C*_+L*U,ht*T-C*U-L*_,H,W),o.set(k,l-1,Dt[0]),o.set(k,l,Dt[1]),Math.abs(ht)>Math.abs(C)+Math.abs(L)?(o.set(k+1,l-1,(-_-it*o.get(k,l-1)+L*o.get(k,l))/ht),o.set(k+1,l,(-U-it*o.get(k,l)-L*o.get(k,l-1))/ht)):(Dt=Mr(-Y-jt*o.get(k,l-1),-T-jt*o.get(k,l),C,L),o.set(k+1,l-1,Dt[0]),o.set(k+1,l,Dt[1]))),Lt=Math.max(Math.abs(o.get(k,l-1)),Math.abs(o.get(k,l))),E*Lt*Lt>1)for(K=k;K<=l;K++)o.set(K,l-1,o.get(K,l-1)/Lt),o.set(K,l,o.get(K,l)/Lt)}for(k=0;ky)for(K=k;K=w;K--)for(k=w;k<=y;k++){for(C=0,et=w;et<=Math.min(K,y);et++)C=C+n.get(k,et)*o.get(et,K);n.set(k,K,C)}}}function Mr(p,a,s,n){let o,l;return Math.abs(s)>Math.abs(n)?(o=n/s,l=s+o*n,[(p+o*a)/l,(a-o*p)/l]):(o=s/n,l=n+o*s,[(o*p+a)/l,(o*a-p)/l])}class fi{constructor(a){if(a=rt.checkMatrix(a),!a.isSymmetric())throw new Error("Matrix is not symmetric");let s=a,n=s.rows,o=new X(n,n),l=!0,w,y,E;for(y=0;y0),o.set(y,y,Math.sqrt(Math.max(S,0))),E=y+1;E=0;E--)for(y=0;yw;Y++)x=a.transpose().mmul(y).div(y.transpose().mmul(y).get(0,0)),x=x.div(x.norm()),S=a.mmul(x).div(x.transpose().mmul(x).get(0,0)),Y>0&&(E=S.clone().sub(L).pow(2).sum()),L=S.clone(),n?(R=n.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),R=R.div(R.norm()),y=n.mmul(R).div(R.transpose().mmul(R).get(0,0))):y=S;if(n){let Y=a.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0));Y=Y.div(Y.norm());let T=a.clone().sub(S.clone().mmul(Y.transpose())),C=y.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),J=n.clone().sub(S.clone().mulS(C.get(0,0)).mmul(R.transpose()));this.t=S,this.p=Y.transpose(),this.w=x.transpose(),this.q=R,this.u=y,this.s=S.transpose().mmul(S),this.xResidual=T,this.yResidual=J,this.betas=C}else this.w=x.transpose(),this.s=S.transpose().mmul(S).sqrt(),o?this.t=S.clone().div(this.s.get(0,0)):this.t=S,this.xResidual=a.sub(S.mmul(x.transpose()))}}return pt.AbstractMatrix=I,pt.CHO=fi,pt.CholeskyDecomposition=fi,pt.DistanceMatrix=qt,pt.EVD=Ae,pt.EigenvalueDecomposition=Ae,pt.LU=M,pt.LuDecomposition=M,pt.Matrix=X,pt.MatrixColumnSelectionView=pe,pt.MatrixColumnView=mr,pt.MatrixFlipColumnView=Dn,pt.MatrixFlipRowView=Ye,pt.MatrixRowSelectionView=tr,pt.MatrixRowView=In,pt.MatrixSelectionView=_t,pt.MatrixSubView=Et,pt.MatrixTransposeView=vt,pt.NIPALS=di,pt.Nipals=di,pt.QR=je,pt.QrDecomposition=je,pt.SVD=ce,pt.SingularValueDecomposition=ce,pt.SymmetricMatrix=ae,pt.WrapperMatrix1D=we,pt.WrapperMatrix2D=rt,pt.correlation=ir,pt.covariance=Xe,pt.default=X,pt.determinant=Se,pt.inverse=Fe,pt.linearDependencies=rr,pt.pseudoInverse=nr,pt.solve=ie,pt.wrap=ut,pt}var $r=uo(),Hn=eo($r);var ti=$r.Matrix,ho=$r.SingularValueDecomposition;Hn.Matrix?Hn.Matrix:$r.Matrix;var dn=(r,t)=>{let e=r.nodeCount(),i=Array.from({length:e},()=>[]),u={},h=0;return r.forEachNode(c=>{u[c.id]=h++}),r.forEachEdge(c=>{let f=u[c.source],g=u[c.target];f==null||g==null||(i[f].push(g),t||i[g].push(f))}),i},ao=(r,t)=>{let e=r.length,i=new Array(e);for(let u=0;unew Array(t).fill(1/0));for(let i=0;i0&&(this.data[0]=e,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let e=this.data;for(;t>0;){let i=t-1>>1;if(e[i][0]<=e[t][0])break;[e[i],e[t]]=[e[t],e[i]],t=i}}bubbleDown(t){let e=this.data,i=e.length;for(;;){let u=t*2+1,h=t*2+2,c=t;if(u{let b=f[g++];d.x=b[0]+e[0],d.y=b[1]+e[1]})})}},da=r=>{let t=Number.NEGATIVE_INFINITY,e=[],i=r.length;for(let u=0;u{try{let i=r.length,u=new ti(i,i);for(let D=0;D{let e=Object.assign(Object.assign({},co),t),{maxIteration:i,width:u,k:h,speed:c=co.speed,strictRadial:f,focusNode:g,radiiMap:d,nodeSizeFunc:b}=e,m=h*.002,v=new Map,D=u/10;for(let $=0;${v.set(q.id,{x:0,y:0})}),ga(r,v,h,d,b),!(pa(r,v,c,f,g,D,d){let h=0;r.forEachNode(c=>{let f=0;r.forEachNode(g=>{if(f<=h){f++;return}if(c.id===g.id||i.get(c.id)!==i.get(g.id))return;let d=c.x-g.x,b=c.y-g.y,m=Math.sqrt(d*d+b*b);if(m===0){m=1;let $=h>f?1:-1;d=.01*$,b=.01*$}let v=Math.max(...u(c._original)),D=Math.max(...u(g._original));if(m{i&&r.forEachNode(d=>{let b=d.x-u.x,m=d.y-u.y,v=Math.sqrt(b*b+m*m),D=m/v,$=-b/v,P=t.get(d.id),q=Math.sqrt(P.x*P.x+P.y*P.y),B=Math.acos((D*P.x+$*P.y)/q);B>Math.PI/2&&(B-=Math.PI/2,D*=-1,$*=-1);let G=Math.cos(B)*q;t.set(d.id,{x:D*G,y:$*G})});let f=0,g=0;return r.forEachNode(d=>{if(d.id===u.id)return;let b=t.get(d.id),m=Math.sqrt(b.x*b.x+b.y*b.y);if(m>0){let v=Math.min(h*(e/800),m);if(d.x+=b.x/m*v,d.y+=b.y/m*v,i){let D=d.x-u.x,$=d.y-u.y,P=Math.sqrt(D*D+$*$);D=D/P*c.get(d.id),$=$/P*c.get(d.id),d.x=u.x+D,d.y=u.y+$}f+=v,g++}}),g>0?f/g:0};var He={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},wn=class extends We{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return He}layout(){return Ee(this,void 0,void 0,function*(){let{width:t,height:e,center:i}=wr(this.options),u=this.model.nodeCount();if(!u||u===1)return pr(this.model,i);let{focusNode:h,linkDistance:c=He.linkDistance,maxIteration:f=He.maxIteration,maxPreventOverlapIteration:g=He.maxPreventOverlapIteration,nodeSize:d,nodeSpacing:b,preventOverlap:m,sortBy:v,sortStrength:D=He.sortStrength,strictRadial:$,unitRadius:P}=this.options,q=h&&this.model.node(h)||this.model.firstNode(),B=this.model.nodeIndexOf(q.id),G=dn(this.model,!1),F=gn(G),V=ba(F,B);ma(F,B,V+1);let z=F[B],ot=(t-i[0]>i[0]?i[0]:t-i[0])||t/2,O=(e-i[1]>i[1]?i[1]:e-i[1])||e/2,N=Math.min(ot,O),A=Math.max(...z),nt=[],dt=new Map,wt=P??N/A;z.forEach((gt,j)=>{let he=gt*wt;nt.push(he),dt.set(this.model.nodeAt(j).id,he)});let Pt=wa(this.model,F,c,nt,wt,v,D),yt=ni(Pt,2,c),Qt=yt[B],ue=0;if(this.model.forEachNode(gt=>{let j=yt[ue];gt.x=j[0]-Qt[0],gt.y=j[1]-Qt[1],ue++}),this.run(f,Pt,nt,B),this.model.forEachNode(gt=>{gt.x+=i[0],gt.y+=i[1]}),m){let j={nodeSizeFunc:tn(d,b,He.nodeSize,He.nodeSpacing),radiiMap:dt,width:t,strictRadial:!!$,focusNode:q,maxIteration:g,k:u/4.5};lo(this.model,j)}})}run(t,e,i,u){let h=ya(e),c=this.model.nodeCount(),f=this.model.nodes(),g=new Float64Array(c),d=new Float64Array(c);for(let b=0;b{let f=t.length,g=new Array(f),d=new Array(f);for(let $=0;${let t=r.length,e=r[0].length,i=[];for(let u=0;u{let i=r.length;for(let u=0;u{let e=r[t],i=0;for(let u=0;uyr,BubbleSets:()=>xn,Circle:()=>Or,Line:()=>Xt,PointPath:()=>Ge,Rectangle:()=>oe,addPadding:()=>ai,boundingBox:()=>yo,calculatePotentialOutline:()=>vo,calculateVirtualEdges:()=>bo,circle:()=>Ia,createGenericInfluenceArea:()=>ci,createLineInfluenceArea:()=>si,createOutline:()=>Fa,createRectangleInfluenceArea:()=>mo,default:()=>xn,defaultOptions:()=>li,line:()=>_a,lineBoundingBox:()=>hi,point:()=>$t,rect:()=>Da,unionBoundingBox:()=>So});function ui(r,t,e,i,u,h){let c=r,f=t,g=e-c,d=i-f,b=u-c,m=h-f,v=b*g+m*d,D=0;v<=0?D=0:(b=g-b,m=d-m,v=b*g+m*d,v<=0?D=0:D=v*v/(g*g+d*d));let $=b*b+m*m-D;return $<0?0:$}function Ke(r,t,e,i){return(r-e)*(r-e)+(t-i)*(t-i)}function fo(r,t,e,i,u){return Ke(r,t,e,i)e;if(r===0)return Math.round;let t=Math.pow(10,r);return e=>Math.round(e*t)/t}function hi(r){let t=Math.min(r.x1,r.x2),e=Math.max(r.x1,r.x2),i=Math.min(r.y1,r.y2),u=Math.max(r.y1,r.y2);return{x:t,y:i,x2:e,y2:u,width:e-t,height:u-i}}var Xt=class r{constructor(t,e,i,u){this.x1=t,this.y1=e,this.x2=i,this.y2=u}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new r(t.x1,t.y1,t.x2,t.y2)}cuts(t,e){if(this.y1===this.y2||ethis.y1&&e>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+i)return!1}else if(tthis.x1+i)return!1;if(this.y1this.y2+i)return!1}else if(ethis.y1+i)return!1;return!0}},zt;(function(r){r[r.POINT=1]="POINT",r[r.PARALLEL=2]="PARALLEL",r[r.COINCIDENT=3]="COINCIDENT",r[r.NONE=4]="NONE"})(zt||(zt={}));var Lr=class{constructor(t,e=0,i=0){this.state=t,this.x=e,this.y=i}};function yn(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;return 0<=h&&h<=1&&0<=c&&c<=1?new Lr(zt.POINT,r.x1+h*(r.x2-r.x1),r.y1+h*(r.y2-r.y1)):new Lr(zt.NONE)}return new Lr(e===0||i===0?zt.COINCIDENT:zt.PARALLEL)}function po(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),i=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),u=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(u){let h=e/u,c=i/u;if(0<=h&&h<=1&&0<=c&&c<=1)return h}return Number.POSITIVE_INFINITY}function va(r,t){function e(u,h,c,f){let g=po(t,new Xt(u,h,c,f));return g=Math.abs(g-.5),g>=0&&g<=1?1:0}let i=e(r.x,r.y,r.x2,r.y);return i+=e(r.x,r.y,r.x,r.y2),i>1||(i+=e(r.x,r.y2,r.x2,r.y2),i>1)?!0:(i+=e(r.x2,r.y,r.x2,r.y2),i>0)}var Ut;(function(r){r[r.LEFT=0]="LEFT",r[r.TOP=1]="TOP",r[r.RIGHT=2]="RIGHT",r[r.BOTTOM=3]="BOTTOM"})(Ut||(Ut={}));function Sn(r,t,e){let i=new Set;return r.width<=0?(i.add(Ut.LEFT),i.add(Ut.RIGHT)):tr.x+r.width&&i.add(Ut.RIGHT),r.height<=0?(i.add(Ut.TOP),i.add(Ut.BOTTOM)):er.y+r.height&&i.add(Ut.BOTTOM),i}function wo(r,t){let e=t.x1,i=t.y1,u=t.x2,h=t.y2,c=Array.from(Sn(r,u,h));if(c.length===0)return!0;let f=Sn(r,e,i);for(;f.size!==0;){for(let g of c)if(f.has(g))return!1;if(f.has(Ut.RIGHT)||f.has(Ut.LEFT)){let g=r.x;f.has(Ut.RIGHT)&&(g+=r.width),i=i+(g-e)*(h-i)/(u-e),e=g}else{let g=r.y;f.has(Ut.BOTTOM)&&(g+=r.height),e=e+(g-i)*(u-e)/(h-i),i=g}f=Sn(r,e,i)}return!0}function Sa(r,t){let e=Number.POSITIVE_INFINITY,i=0;function u(h,c,f,g){let d=po(t,new Xt(h,c,f,g));d=Math.abs(d-.5),d>=0&&d<=1&&(i++,d1||(u(r.x,r.y2,r.x2,r.y2),i>1)?e:(u(r.x2,r.y,r.x2,r.y2),i===0?-1:e)}function xa(r,t){let e=0,i=yn(r,new Xt(t.x,t.y,t.x2,t.y));e+=i.state===zt.POINT?1:0;let u=yn(r,new Xt(t.x,t.y,t.x,t.y2));e+=u.state===zt.POINT?1:0;let h=yn(r,new Xt(t.x,t.y2,t.x2,t.y2));e+=h.state===zt.POINT?1:0;let c=yn(r,new Xt(t.x2,t.y,t.x2,t.y2));return e+=c.state===zt.POINT?1:0,{top:i,left:u,bottom:h,right:c,count:e}}var oe=class r{constructor(t,e,i,u){this.x=t,this.y=e,this.width=i,this.height=u}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new r(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new r(this.x,this.y,this.width,this.height)}add(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x+t.width),h=Math.max(this.y2,t.y+t.height);this.x=e,this.y=i,this.width=u-e,this.height=h-i}addPoint(t){let e=Math.min(this.x,t.x),i=Math.min(this.y,t.y),u=Math.max(this.x2,t.x),h=Math.max(this.y2,t.y);this.x=e,this.y=i,this.width=u-e,this.height=h-i}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let e=this.scaleX(t.x),i=this.scaleY(t.y),u=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),h=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),c=u-e,f=h-i;return new oe(e,i,c,f)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){let i=Math.ceil(e/this.pixelGroup),u=this.boundX(t.x-i),h=this.boundY(t.y-i),c=this.boundX(t.x2+i),f=this.boundY(t.y2+i),g=c-u,d=f-h;return new oe(u,h,g,d)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=i)}set(t,e,i){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=i)}incArea(t,e){if(t.width<=0||t.height<=0||e===0)return;let i=this.width,u=t.width,h=Math.max(0,t.i),c=Math.max(0,t.j),f=Math.min(t.i+t.width,i),g=Math.min(t.j+t.height,this.height);if(!(g<=0||f<=0||h>=i||g>=this.height))for(let d=c;dMath.min(c,f),Number.POSITIVE_INFINITY),u=this.area.reduce((c,f)=>Math.max(c,f),Number.NEGATIVE_INFINITY),h=c=>(c-i)/(u-i);t.scale(this.pixelGroup,this.pixelGroup);for(let c=0;ce?"black":"white",t.fillRect(u,h,1,1)}t.restore()}}};function ai(r,t){let e=i=>({x:i.x-t,y:i.y-t,width:i.width+2*t,height:i.height+2*t});return Array.isArray(r)?r.map(e):e(r)}function si(r,t,e){return ci(Object.assign(hi(r),{distSquare:(i,u)=>ui(r.x1,r.y1,r.x2,r.y2,i,u)}),t,e)}function ci(r,t,e){let i=ai(r,e),u=t.scale(i),h=t.createSub(u,i);return ka(h,t,e,(c,f)=>r.distSquare(c,f)),h}function ka(r,t,e,i){let u=e*e;for(let h=0;h{let f=u.slice(0,c);return Ra(t,h,f,e,i)}).flat()}function Ra(r,t,e,i,u){let h=$t(t.cx,t.cy),c=$a(h,e,r);if(c==null)return[];let f=new Xt(h.x,h.y,c.cx,c.cy),g=ja(f,r,i,u);return Aa(g,r)}function ja(r,t,e,i){let u=[],h=[];h.push(r);let c=!0;for(let f=0;f0;){let g=h.pop(),d=Eo(t,g),b=d?xa(g,d):null;if(!d||!b||b.count!==2){c||u.push(g);continue}let m=i,v=bn(d,m,b,!0),D=Be(v,h)||Be(v,u),$=mn(v,t);for(;!D&&$&&m>=1;)m/=1.5,v=bn(d,m,b,!0),D=Be(v,h)||Be(v,u),$=mn(v,t);if(v&&!D&&!$&&(h.push(new Xt(g.x1,g.y1,v.x,v.y)),h.push(new Xt(v.x,v.y,g.x2,g.y2)),c=!0),c)continue;m=i,v=bn(d,m,b,!1);let P=Be(v,h)||Be(v,u);for($=mn(v,t);!P&&$&&m>=1;)m/=1.5,v=bn(d,m,b,!1),P=Be(v,h)||Be(v,u),$=mn(v,t);v&&!P&&(h.push(new Xt(g.x1,g.y1,v.x,v.y)),h.push(new Xt(v.x,v.y,g.x2,g.y2)),c=!0),c||u.push(g)}for(;h.length>0;)u.push(h.pop());return u}function Aa(r,t){let e=[];for(;r.length>0;){let i=r.pop();if(r.length===0){e.push(i);break}let u=r.pop(),h=new Xt(i.x1,i.y1,u.x2,u.y2);Eo(t,h)?(e.push(i),r.push(u)):r.push(h)}return e}function $a(r,t,e){let i=Number.POSITIVE_INFINITY;return t.reduce((u,h)=>{let c=Ke(r.x,r.y,h.cx,h.cy);if(c>i)return u;let f=new Xt(r.x,r.y,h.cx,h.cy),g=La(e,f);return c*(g+1)*(g+1){t+=i.cx,e+=i.cy}),t/=r.length,e/=r.length,r.map(i=>{let u=t-i.cx,h=e-i.cy,c=u*u+h*h;return[i,c]}).sort((i,u)=>i[1]-u[1]).map(i=>i[0])}function mn(r,t){return t.some(e=>e.containsPt(r.x,r.y))}function Be(r,t){return t.some(e=>!!(fo(e.x1,e.y1,r.x,r.y,.001)||fo(e.x2,e.y2,r.x,r.y,.001)))}function Eo(r,t){let e=Number.POSITIVE_INFINITY,i=null;for(let u of r){if(!wo(u,t))continue;let h=Sa(u,t);h>=0&&hwo(i,t)&&va(i,t)?e+1:e,0)}function bn(r,t,e,i){let u=e.top,h=e.left,c=e.bottom,f=e.right;if(i){if(h.state===zt.POINT){if(u.state===zt.POINT)return $t(r.x-t,r.y-t);if(c.state===zt.POINT)return $t(r.x-t,r.y2+t);let v=r.width*r.height;return r.width*((h.y-r.y+(f.y-r.y))*.5)f.y?$t(r.x-t,r.y-t):$t(r.x2+t,r.y-t):h.yc.x?$t(r.x-t,r.y-t):$t(r.x-t,r.y2+t):u.xf.y?$t(r.x2+t,r.y2+t):$t(r.x-t,r.y2+t):h.yc.x?$t(r.x2+t,r.y2+t):$t(r.x2+t,r.y-t):u.xi)return!1}return!0}function Oa(r=0){return t=>{if(r<0||t.length<3)return t;let e=[],i=0,u=r*r;for(;i{if(c.length<3)return c;let f=[],g=c.closed,d=c.length+3-1+(g?0:2);f.push(h(c,2-(g?0:2),0));for(let b=2-(g?0:2);b{let e=r,i=t.length;if(e>1)for(i=Math.floor(t.length/e);i<3&&e>1;)e-=1,i=Math.floor(t.length/e);let u=[];for(let h=0,c=0;c=i?this.closed?this.get(t-i):this.points[i-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){let e=this.points;if(e.length===0)return"";let i=typeof t=="function"?t:Ea(t),u="M";for(let h of e)u+=`${i(h.x)},${i(h.y)} L`;return u=u.slice(0,-1),this.closed&&(u+=" Z"),u}draw(t){let e=this.points;if(e.length!==0){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let i of e)t.lineTo(i.x,i.y);this.closed&&t.closePath()}}sample(t){return Pa(t)(this)}simplify(t){return Oa(t)(this)}bSplines(t){return Ca(t)(this)}apply(t){return t(this)}containsElements(t){let e=yo(this.points);return e?t.every(i=>e.containsPt(i.cx,i.cy)&&this.withinArea(i.cx,i.cy)):!1}withinArea(t,e){if(this.length===0)return!1;let i=0,u=this.points[0],h=new Xt(u.x,u.y,u.x,u.y);for(let c=1;ct?b+m:b}function h(g,d){let b=Tr;return b=u(g,d,b,1),b=u(g+1,d,b,2),b=u(g,d+1,b,4),b=u(g+1,d+1,b,8),Number.isNaN(b)?-1:b}let c=En;function f(g,d){let b=g,m=d,v=r.invertScaleX(b),D=r.invertScaleY(m);for(let $=0;$go(i.raw,t));return e<0?!1:(this.members.splice(e,1),this.dirty.add(Re.MEMBERS),!0)}removeNonMember(t){let e=this.nonMembers.findIndex(i=>go(i.raw,t));return e<0?!1:(this.nonMembers.splice(e,1),this.dirty.add(Re.NON_MEMBERS),!0)}removeEdge(t){let e=this.edges.findIndex(i=>i.obj.equals(t));return e<0?!1:(this.edges.splice(e,1),this.dirty.add(Re.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(Re.NON_MEMBERS);for(let e of t)this.nonMembers.push({raw:e,obj:Gr(e)?Or.from(e):oe.from(e),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(Re.EDGES);for(let e of t)this.edges.push({raw:e,obj:Xt.from(e),area:null})}}update(){let t=this.dirty.has(Re.MEMBERS),e=this.dirty.has(Re.NON_MEMBERS),i=this.dirty.has(Re.EDGES);this.dirty.clear();let u=this.members.map(d=>d.obj);if(this.o.virtualEdges&&(t||e)){let d=this.nonMembers.map(v=>v.obj),b=bo(u,d,this.o.maxRoutingIterations,this.o.morphBuffer),m=new Map(this.virtualEdges.map(v=>[v.obj.toString(),v.area]));this.virtualEdges=b.map(v=>{var D;return{raw:v,obj:v,area:(D=m.get(v.toString()))!==null&&D!==void 0?D:null}}),i=!0}let h=!1;if(t||i){let d=this.virtualEdges.concat(this.edges).map(D=>D.obj),b=So(u,d),m=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,v=oe.from(ai(b,m));v.equals(this.activeRegion)||(h=!0,this.activeRegion=v)}if(h){let d=Math.ceil(this.activeRegion.width/this.o.pixelGroup),b=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=yr.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(m=>m.area=null),this.nonMembers.forEach(m=>m.area=null),this.edges.forEach(m=>m.area=null),this.virtualEdges.forEach(m=>m.area=null)):(d!==this.potentialArea.width||b!==this.potentialArea.height)&&(this.potentialArea=yr.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let c=new Map,f=d=>{if(d.area){let b=`${d.obj.width}x${d.obj.height}x${d.obj instanceof oe?"R":"C"}`;c.set(b,d.area)}},g=d=>{if(d.area)return;let b=`${d.obj.width}x${d.obj.height}x${d.obj instanceof oe?"R":"C"}`;if(c.has(b)){let v=c.get(b);d.area=this.potentialArea.copy(v,{x:d.obj.x-this.o.nodeR1,y:d.obj.y-this.o.nodeR1});return}let m=d.obj instanceof oe?mo(d.obj,this.potentialArea,this.o.nodeR1):ci(d.obj,this.potentialArea,this.o.nodeR1);d.area=m,c.set(b,m)};this.members.forEach(f),this.nonMembers.forEach(f),this.members.forEach(g),this.nonMembers.forEach(d=>{this.activeRegion.intersects(d.obj)?g(d):d.area=null}),this.edges.forEach(d=>{d.area||(d.area=si(d.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(d=>{d.area||(d.area=si(d.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let e of this.members)e.obj.draw(t)}drawNonMembers(t){for(let e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(let e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(this.members.length===0)return new Ge([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:e}=this,i=this.members.map(f=>f.area),u=this.virtualEdges.concat(this.edges).map(f=>f.area),h=this.nonMembers.filter(f=>f.area!=null).map(f=>f.area),c=this.members.map(f=>f.obj);return vo(e,i,u,h,f=>f.containsElements(c),t)}};function vo(r,t,e,i,u,h={}){let c=Object.assign({},li,h),f=c.threshold,g=c.memberInfluenceFactor,d=c.edgeInfluenceFactor,b=c.nonMemberInfluenceFactor,m=(c.nodeR0-c.nodeR1)*(c.nodeR0-c.nodeR1),v=(c.edgeR0-c.edgeR1)*(c.edgeR0-c.edgeR1);for(let D=0;D0)b*=.8;else break}return new Ge([])}function So(r,t){if(r.length===0)return new oe(0,0,0,0);let e=oe.from(r[0]);for(let i of r)e.add(i);for(let i of t)e.add(hi(i));return e}function Fa(r,t=[],e=[],i={}){if(r.length===0)return new Ge([]);let u=new xn(i);return u.pushMember(...r),u.pushNonMember(...t),u.pushEdge(...e),u.compute()}var export_FA2Layout=Ua.default;var export_circlepack=kn.circlepack;var export_circular=kn.circular;var export_forceAtlas2=za.default;var export_random=kn.random;var export_rotation=kn.rotation;export{ln as ConcentricLayout,export_FA2Layout as FA2Layout,At as Graph,pn as MDSLayout,wn as RadialLayout,xo as bubblesets,export_circlepack as circlepack,export_circular as circular,export_forceAtlas2 as forceAtlas2,export_random as random,export_rotation as rotation}; +}`}function u(p,c,a,i,h){let{rows:f,columns:v}=p,b=Math.min(f,c),E=Math.min(v,a),S=[];if(h==="auto"){h=!1;t:for(let R=0;R=0&&a?` ${g(p,c-1)}`:g(p,c)).padEnd(c)}function g(p,c){let a=p.toString();if(a.length<=c)return a;let i=p.toFixed(c);if(i.length>c&&(i=p.toFixed(Math.max(0,c-(i.length-c)))),i.length<=c&&!i.startsWith("0.000")&&!i.startsWith("-0.000"))return i;let h=p.toExponential(c);return h.length>c&&(h=p.toExponential(Math.max(0,c-(h.length-c)))),h.slice(0)}function d(p,c){p.prototype.add=function(i){return typeof i=="number"?this.addS(i):this.addM(i)},p.prototype.addS=function(i){for(let h=0;h>i);return this},p.prototype.signPropagatingRightShiftM=function(i){if(i=c.checkMatrix(i),this.rows!==i.rows||this.columns!==i.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>i.get(h,f));return this},p.signPropagatingRightShift=function(i,h){return new c(i).signPropagatingRightShift(h)},p.prototype.rightShift=function(i){return typeof i=="number"?this.rightShiftS(i):this.rightShiftM(i)},p.prototype.rightShiftS=function(i){for(let h=0;h>>i);return this},p.prototype.rightShiftM=function(i){if(i=c.checkMatrix(i),this.rows!==i.rows||this.columns!==i.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>>i.get(h,f));return this},p.rightShift=function(i,h){return new c(i).rightShift(h)},p.prototype.zeroFillRightShift=p.prototype.rightShift,p.prototype.zeroFillRightShiftS=p.prototype.rightShiftS,p.prototype.zeroFillRightShiftM=p.prototype.rightShiftM,p.zeroFillRightShift=p.rightShift,p.prototype.not=function(){for(let i=0;ii)throw new RangeError("Row index out of range")}function w(p,c,a){let i=a?p.columns:p.columns-1;if(c<0||c>i)throw new RangeError("Column index out of range")}function m(p,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==p.columns)throw new RangeError("vector size must be the same as the number of columns");return c}function x(p,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==p.rows)throw new RangeError("vector size must be the same as the number of rows");return c}function _(p,c){if(!r.isAnyArray(c))throw new TypeError("row indices must be an array");for(let a=0;a=p.rows)throw new RangeError("row indices are out of range")}function G(p,c){if(!r.isAnyArray(c))throw new TypeError("column indices must be an array");for(let a=0;a=p.columns)throw new RangeError("column indices are out of range")}function M(p,c,a,i,h){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(L("startRow",c),L("endRow",a),L("startColumn",i),L("endColumn",h),c>a||i>h||c<0||c>=p.rows||a<0||a>=p.rows||i<0||i>=p.columns||h<0||h>=p.columns)throw new RangeError("Submatrix indices are out of range")}function q(p,c=0){let a=[];for(let i=0;i=f)throw new RangeError("min must be smaller than max");let b=f-h,E=new X(c,a);for(let S=0;Si?(f=!0,i=a):(h=!1,f=!0);c++}return h}isReducedEchelonForm(){let c=0,a=0,i=-1,h=!0,f=!1;for(;ci?(f=!0,i=a):(h=!1,f=!0);for(let v=a+1;vc.get(h,i)&&(h=f);if(c.get(h,i)===0)i++;else{c.swapRows(a,h);let f=c.get(a,i);for(let v=i;v=0;)if(c.maxRow(h)===0)h--;else{let f=0,v=!1;for(;fa[i]&&(a[i]=this.get(i,h));return a}case"column":{let a=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let i=0;ia[h]&&(a[h]=this.get(i,h));return a}case void 0:{let a=this.get(0,0);for(let i=0;ia&&(a=this.get(i,h));return a}default:throw new Error(`invalid option: ${c}`)}}maxIndex(){P(this);let c=this.get(0,0),a=[0,0];for(let i=0;ic&&(c=this.get(i,h),a[0]=i,a[1]=h);return a}min(c){if(this.isEmpty())return NaN;switch(c){case"row":{let a=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let i=0;ia&&(a=this.get(c,i));return a}maxRowIndex(c){y(this,c),P(this);let a=this.get(c,0),i=[c,0];for(let h=1;ha&&(a=this.get(c,h),i[1]=h);return i}minRow(c){if(y(this,c),this.isEmpty())return NaN;let a=this.get(c,0);for(let i=1;ia&&(a=this.get(i,c));return a}maxColumnIndex(c){w(this,c),P(this);let a=this.get(0,c),i=[0,c];for(let h=1;ha&&(a=this.get(h,c),i[0]=h);return i}minColumn(c){if(w(this,c),this.isEmpty())return NaN;let a=this.get(0,c);for(let i=1;i=1;h/=2)(h&1)!==0&&(a=a.mmul(i)),i=i.mmul(i);return a}strassen2x2(c){c=X.checkMatrix(c);let a=new X(2,2),i=this.get(0,0),h=c.get(0,0),f=this.get(0,1),v=c.get(0,1),b=this.get(1,0),E=c.get(1,0),S=this.get(1,1),R=c.get(1,1),A=(i+S)*(h+R),C=(b+S)*h,Y=i*(v-R),$=S*(E-h),F=(i+f)*R,Z=(b-i)*(h+v),k=(f-S)*(E+R),K=A+$-F+k,et=Y+F,ct=C+$,ft=A-C+Y+Z;return a.set(0,0,K),a.set(0,1,et),a.set(1,0,ct),a.set(1,1,ft),a}strassen3x3(c){c=X.checkMatrix(c);let a=new X(3,3),i=this.get(0,0),h=this.get(0,1),f=this.get(0,2),v=this.get(1,0),b=this.get(1,1),E=this.get(1,2),S=this.get(2,0),R=this.get(2,1),A=this.get(2,2),C=c.get(0,0),Y=c.get(0,1),$=c.get(0,2),F=c.get(1,0),Z=c.get(1,1),k=c.get(1,2),K=c.get(2,0),et=c.get(2,1),ct=c.get(2,2),ft=(i+h+f-v-b-R-A)*Z,$t=(i-v)*(-Y+Z),st=b*(-C+Y+F-Z-k-K+ct),ut=(-i+v+b)*(C-Y+Z),Tt=(v+b)*(-C+Y),D=i*C,W=(-i+S+R)*(C-$+k),H=(-i+S)*($-k),V=(S+R)*(-C+$),Mt=(i+h+f-b-E-S-R)*k,It=R*(-C+$+F-Z-k-K+et),Ot=(-f+R+A)*(Z+K-et),Ct=(f-A)*(Z-et),ne=f*K,Re=(R+A)*(-K+et),Xt=(-f+b+E)*(k+K-ct),Pe=(f-E)*(k-ct),Be=(b+E)*(-K+ct),vt=h*F,ie=E*et,me=v*$,ve=S*Y,Qt=A*ct,vu=D+ne+vt,bu=ft+ut+Tt+D+Ot+ne+Re,Eu=D+W+V+Mt+ne+Xt+Be,Su=$t+st+ut+D+ne+Xt+Pe,xu=$t+ut+Tt+D+ie,Au=ne+Xt+Pe+Be+me,ku=D+W+H+It+Ot+Ct+ne,Iu=Ot+Ct+ne+Re+ve,Du=D+W+H+V+Qt;return a.set(0,0,vu),a.set(0,1,bu),a.set(0,2,Eu),a.set(1,0,Su),a.set(1,1,xu),a.set(1,2,Au),a.set(2,0,ku),a.set(2,1,Iu),a.set(2,2,Du),a}mmulStrassen(c){c=X.checkMatrix(c);let a=this.clone(),i=a.rows,h=a.columns,f=c.rows,v=c.columns;h!==f&&console.warn(`Multiplying ${i} x ${h} and ${f} x ${v} matrix: dimensions do not match.`);function b(A,C,Y){let $=A.rows,F=A.columns;if($===C&&F===Y)return A;{let Z=I.zeros(C,Y);return Z=Z.setSubMatrix(A,0,0),Z}}let E=Math.max(i,f),S=Math.max(h,v);a=b(a,E,S),c=b(c,E,S);function R(A,C,Y,$){if(Y<=512||$<=512)return A.mmul(C);Y%2===1&&$%2===1?(A=b(A,Y+1,$+1),C=b(C,Y+1,$+1)):Y%2===1?(A=b(A,Y+1,$),C=b(C,Y+1,$)):$%2===1&&(A=b(A,Y,$+1),C=b(C,Y,$+1));let F=parseInt(A.rows/2,10),Z=parseInt(A.columns/2,10),k=A.subMatrix(0,F-1,0,Z-1),K=C.subMatrix(0,F-1,0,Z-1),et=A.subMatrix(0,F-1,Z,A.columns-1),ct=C.subMatrix(0,F-1,Z,C.columns-1),ft=A.subMatrix(F,A.rows-1,0,Z-1),$t=C.subMatrix(F,C.rows-1,0,Z-1),st=A.subMatrix(F,A.rows-1,Z,A.columns-1),ut=C.subMatrix(F,C.rows-1,Z,C.columns-1),Tt=R(I.add(k,st),I.add(K,ut),F,Z),D=R(I.add(ft,st),K,F,Z),W=R(k,I.sub(ct,ut),F,Z),H=R(st,I.sub($t,K),F,Z),V=R(I.add(k,et),ut,F,Z),Mt=R(I.sub(ft,k),I.add(K,ct),F,Z),It=R(I.sub(et,st),I.add($t,ut),F,Z),Ot=I.add(Tt,H);Ot.sub(V),Ot.add(It);let Ct=I.add(W,V),ne=I.add(D,H),Re=I.sub(Tt,D);Re.add(W),Re.add(Mt);let Xt=I.zeros(2*Ot.rows,2*Ot.columns);return Xt=Xt.setSubMatrix(Ot,0,0),Xt=Xt.setSubMatrix(Ct,Ot.rows,0),Xt=Xt.setSubMatrix(ne,0,Ot.columns),Xt=Xt.setSubMatrix(Re,Ot.rows,Ot.columns),Xt.subMatrix(0,Y-1,0,$-1)}return R(a,c,E,S)}scaleRows(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:a=0,max:i=1}=c;if(!Number.isFinite(a))throw new TypeError("min must be a number");if(!Number.isFinite(i))throw new TypeError("max must be a number");if(a>=i)throw new RangeError("min must be smaller than max");let h=new X(this.rows,this.columns);for(let f=0;f0&&t(v,{min:a,max:i,output:v}),h.setRow(f,v)}return h}scaleColumns(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:a=0,max:i=1}=c;if(!Number.isFinite(a))throw new TypeError("min must be a number");if(!Number.isFinite(i))throw new TypeError("max must be a number");if(a>=i)throw new RangeError("min must be smaller than max");let h=new X(this.rows,this.columns);for(let f=0;fi||a<0||a>=this.columns||i<0||i>=this.columns)throw new RangeError("Argument out of range");let h=new X(c.length,i-a+1);for(let f=0;f=this.rows)throw new RangeError(`Row index out of range: ${c[f]}`);h.set(f,v-a,this.get(c[f],v))}return h}subMatrixColumn(c,a,i){if(a===void 0&&(a=0),i===void 0&&(i=this.rows-1),a>i||a<0||a>=this.rows||i<0||i>=this.rows)throw new RangeError("Argument out of range");let h=new X(i-a+1,c.length);for(let f=0;f=this.columns)throw new RangeError(`Column index out of range: ${c[f]}`);h.set(v-a,f,this.get(v,c[f]))}return h}setSubMatrix(c,a,i){if(c=X.checkMatrix(c),c.isEmpty())return this;let h=a+c.rows-1,f=i+c.columns-1;M(this,a,h,i,f);for(let v=0;vtypeof c=="number")}I.random=I.rand,I.randomInt=I.randInt,I.diagonal=I.diag,I.prototype.diagonal=I.prototype.diag,I.identity=I.eye,I.prototype.negate=I.prototype.neg,I.prototype.tensorProduct=I.prototype.kroneckerProduct;let an=class an extends I{constructor(a,i){super();si(this,Cr);rs(this,"data");if(an.isMatrix(a))oi(this,Cr,Di).call(this,a.rows,a.columns),an.copy(a,this);else if(Number.isInteger(a)&&a>=0)oi(this,Cr,Di).call(this,a,i);else if(r.isAnyArray(a)){let h=a;if(a=h.length,i=a?h[0].length:0,typeof i!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let f=0;f"u"&&(i=a,a=this.columns),w(this,a,!0),i=x(this,i);for(let h=0;h=0)for(let h=0;h=0)cn(this,ae,new X(a,a));else if(cn(this,ae,new X(a)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return Te(this,ae).size}get rows(){return Te(this,ae).rows}get columns(){return Te(this,ae).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(a){return X.isMatrix(a)&&a.klassType==="SymmetricMatrix"}static zeros(a){return new this(a)}static ones(a){return new this(a).fill(1)}clone(){let a=new un(this.diagonalSize);for(let[i,h,f]of this.upperRightEntries())a.set(i,h,f);return a}toMatrix(){return new X(this)}get(a,i){return Te(this,ae).get(a,i)}set(a,i,h){return Te(this,ae).set(a,i,h),Te(this,ae).set(i,a,h),this}removeCross(a){return Te(this,ae).removeRow(a),Te(this,ae).removeColumn(a),this}addCross(a,i){i===void 0&&(i=a,a=this.diagonalSize);let h=i.slice();return h.splice(a,1),Te(this,ae).addRow(a,h),Te(this,ae).addColumn(a,i),this}applyMask(a){if(a.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let i=[];for(let[h,f]of a.entries())f||i.push(h);i.reverse();for(let h of i)this.removeCross(h);return this}toCompact(){let{diagonalSize:a}=this,i=new Array(a*(a+1)/2);for(let h=0,f=0,v=0;v=a&&(h=++f);return i}static fromCompact(a){let i=a.length,h=(Math.sqrt(8*i+1)-1)/2;if(!Number.isInteger(h))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(a)}`);let f=new un(h);for(let v=0,b=0,E=0;E=h&&(v=++b);return f}*upperRightEntries(){for(let a=0,i=0;a=this.diagonalSize&&(i=++a)}}*upperRightValues(){for(let a=0,i=0;a=this.diagonalSize&&(i=++a)}};ae=new WeakMap;let ge=un;ge.prototype.klassType="SymmetricMatrix";class Kt extends ge{static isDistanceMatrix(c){return ge.isSymmetricMatrix(c)&&c.klassSubType==="DistanceMatrix"}constructor(c){if(super(c),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(c,a,i){return c===a&&(i=0),super.set(c,a,i)}addCross(c,a){return a===void 0&&(a=c,c=this.diagonalSize),a=a.slice(),a[c]=0,super.addCross(c,a)}toSymmetricMatrix(){return new ge(this)}clone(){let c=new Kt(this.diagonalSize);for(let[a,i,h]of this.upperRightEntries())a!==i&&c.set(a,i,h);return c}toCompact(){let{diagonalSize:c}=this,a=(c-1)*c/2,i=new Array(a);for(let h=1,f=0,v=0;v=c&&(h=++f+1);return i}static fromCompact(c){let a=c.length;if(a===0)return new this(0);let i=(Math.sqrt(8*a+1)+1)/2;if(!Number.isInteger(i))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(c)}`);let h=new this(i);for(let f=1,v=0,b=0;b=i&&(f=++v+1);return h}}Kt.prototype.klassSubType="DistanceMatrix";class ot extends I{constructor(c,a,i){super(),this.matrix=c,this.rows=a,this.columns=i}}class $r extends ot{constructor(c,a){w(c,a),super(c,c.rows,1),this.column=a}set(c,a,i){return this.matrix.set(c,this.column,i),this}get(c){return this.matrix.get(c,this.column)}}class Ee extends ot{constructor(c,a){G(c,a),super(c,c.rows,a.length),this.columnIndices=a}set(c,a,i){return this.matrix.set(c,this.columnIndices[a],i),this}get(c,a){return this.matrix.get(c,this.columnIndices[a])}}class ei extends ot{constructor(c){super(c,c.rows,c.columns)}set(c,a,i){return this.matrix.set(c,this.columns-a-1,i),this}get(c,a){return this.matrix.get(c,this.columns-a-1)}}class ur extends ot{constructor(c){super(c,c.rows,c.columns)}set(c,a,i){return this.matrix.set(this.rows-c-1,a,i),this}get(c,a){return this.matrix.get(this.rows-c-1,a)}}class ri extends ot{constructor(c,a){y(c,a),super(c,1,c.columns),this.row=a}set(c,a,i){return this.matrix.set(this.row,a,i),this}get(c,a){return this.matrix.get(this.row,a)}}class gr extends ot{constructor(c,a){_(c,a),super(c,a.length,c.columns),this.rowIndices=a}set(c,a,i){return this.matrix.set(this.rowIndices[c],a,i),this}get(c,a){return this.matrix.get(this.rowIndices[c],a)}}class Rt extends ot{constructor(c,a,i){_(c,a),G(c,i),super(c,a.length,i.length),this.rowIndices=a,this.columnIndices=i}set(c,a,i){return this.matrix.set(this.rowIndices[c],this.columnIndices[a],i),this}get(c,a){return this.matrix.get(this.rowIndices[c],this.columnIndices[a])}}class Et extends ot{constructor(c,a,i,h,f){M(c,a,i,h,f),super(c,i-a+1,f-h+1),this.startRow=a,this.startColumn=h}set(c,a,i){return this.matrix.set(this.startRow+c,this.startColumn+a,i),this}get(c,a){return this.matrix.get(this.startRow+c,this.startColumn+a)}}class St extends ot{constructor(c){super(c,c.columns,c.rows)}set(c,a,i){return this.matrix.set(a,c,i),this}get(c,a){return this.matrix.get(a,c)}}class Se extends I{constructor(c,a={}){let{rows:i=1}=a;if(c.length%i!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=i,this.columns=c.length/i,this.data=c}set(c,a,i){let h=this._calculateIndex(c,a);return this.data[h]=i,this}get(c,a){let i=this._calculateIndex(c,a);return this.data[i]}_calculateIndex(c,a){return c*this.columns+a}}class nt extends I{constructor(c){super(),this.data=c,this.rows=c.length,this.columns=c[0].length}set(c,a,i){return this.data[c][a]=i,this}get(c,a){return this.data[c][a]}}function at(p,c){if(r.isAnyArray(p))return p[0]&&r.isAnyArray(p[0])?new nt(p):new Se(p,c);throw new Error("the argument is not an array")}class z{constructor(c){c=nt.checkMatrix(c);let a=c.clone(),i=a.rows,h=a.columns,f=new Float64Array(i),v=1,b,E,S,R,A,C,Y,$,F;for(b=0;bMath.abs($[R])&&(R=b);if(R!==E){for(S=0;S=0;S--){for(E=0;Ev?h.set(f,v,c.get(f,v)):f===v?h.set(f,v,1):h.set(f,v,0);return h}get upperTriangularMatrix(){let c=this.LU,a=c.rows,i=c.columns,h=new X(a,i);for(let f=0;fMath.abs(c)?(a=c/p,Math.abs(p)*Math.sqrt(1+a*a)):c!==0?(a=p/c,Math.abs(c)*Math.sqrt(1+a*a)):0}class Me{constructor(c){c=nt.checkMatrix(c);let a=c.clone(),i=c.rows,h=c.columns,f=new Float64Array(h),v,b,E,S;for(E=0;E=0;S--){for(E=0;E=0;b--){for(f=0;f=0;D--)if($[D]!==0){for(let W=D+1;W=0;D--){if(D0;){let D,W;for(D=st-2;D>=-1&&D!==-1;D--){let H=Number.MIN_VALUE+Tt*Math.abs($[D]+Math.abs($[D+1]));if(Math.abs(k[D])<=H||Number.isNaN(k[D])){k[D]=0;break}}if(D===st-2)W=4;else{let H;for(H=st-1;H>=D&&H!==D;H--){let V=(H!==st?Math.abs(k[H]):0)+(H!==D+1?Math.abs(k[H-1]):0);if(Math.abs($[H])<=Tt*V){$[H]=0;break}}H===D?W=3:H===st-1?W=1:(W=2,D=H)}switch(D++,W){case 1:{let H=k[st-2];k[st-2]=0;for(let V=st-2;V>=D;V--){let Mt=re($[V],H),It=$[V]/Mt,Ot=H/Mt;if($[V]=Mt,V!==D&&(H=-Ot*k[V-1],k[V-1]=It*k[V-1]),S)for(let Ct=0;Ct=$[D+1]);){let H=$[D];if($[D]=$[D+1],$[D+1]=H,S&&Da&&f.set(R,A,c.get(R,A)/this.s[A]);let v=this.U,b=v.rows,E=v.columns,S=new X(i,b);for(let R=0;Rc&&a++;return a}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return X.diag(this.s)}}function He(p,c=!1){return p=nt.checkMatrix(p),c?new pe(p).inverse():he(p,X.eye(p.rows))}function he(p,c,a=!1){return p=nt.checkMatrix(p),c=nt.checkMatrix(c),a?new pe(p).solve(c):p.isSquare()?new z(p).solve(c):new Me(p).solve(c)}function _e(p){if(p=X.checkMatrix(p),p.isSquare()){if(p.columns===0)return 1;let c,a,i,h;if(p.columns===2)return c=p.get(0,0),a=p.get(0,1),i=p.get(1,0),h=p.get(1,1),c*h-a*i;if(p.columns===3){let f,v,b;return f=new Rt(p,[1,2],[1,2]),v=new Rt(p,[1,2],[0,2]),b=new Rt(p,[1,2],[0,1]),c=p.get(0,0),a=p.get(0,1),i=p.get(0,2),c*_e(f)-a*_e(v)+i*_e(b)}else return new z(p).determinant}else throw Error("determinant can only be calculated for a square matrix")}function Mr(p,c){let a=[];for(let i=0;ih)return new Array(c.rows+1).fill(0);{let f=c.addRow(a,[0]);for(let v=0;vc?f[v]=1/f[v]:f[v]=0;return h.mmul(X.diag(f).mmul(i.transpose()))}function hr(p,c=p,a={}){p=new X(p);let i=!1;if(typeof c=="object"&&!X.isMatrix(c)&&!r.isAnyArray(c)?(a=c,c=p,i=!0):c=new X(c),p.rows!==c.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:h=!0}=a;h&&(p=p.center("column"),i||(c=c.center("column")));let f=p.transpose().mmul(c);for(let v=0;v0?h.set(f,f+1,a[f]):a[f]<0&&h.set(f,f-1,a[f])}return h}}function vr(p,c,a,i){let h,f,v,b,E,S,R,A;for(E=0;E0;b--){for(A=0,v=0,S=0;S0&&(f=-f),c[b]=A*f,v=v-h*f,a[b-1]=h-f,E=0;ES)do{for(h=a[S],A=(a[S+1]-h)/(2*c[S]),C=re(A,1),A<0&&(C=-C),a[S]=c[S]/(A+C),a[S+1]=c[S]*(A+C),Y=a[S+1],f=h-a[S],v=S+2;v=S;v--)for(Z=F,F=$,et=K,h=$*c[v],f=$*A,C=re(A,c[v]),c[v+1]=K*C,K=c[v]/C,$=A/C,A=$*a[v]-K*h,a[v+1]=f+K*($*h+K*a[v]),E=0;E$t*ft);a[S]=a[S]+ct,c[S]=0}for(v=0;v=A;S--)a[S]=c.get(S,A-1)/C,E+=a[S]*a[S];for(b=Math.sqrt(E),a[A]>0&&(b=-b),E=E-a[A]*b,a[A]=a[A]-b,R=A;R=A;S--)v+=a[S]*c.get(S,R);for(v=v/E,S=A;S<=f;S++)c.set(S,R,c.get(S,R)-v*a[S])}for(S=0;S<=f;S++){for(v=0,R=f;R>=A;R--)v+=a[R]*c.get(S,R);for(v=v/E,R=A;R<=f;R++)c.set(S,R,c.get(S,R)-v*a[R])}a[A]=C*a[A],c.set(A,A-1,C*b)}}for(S=0;S=h+1;A--)if(c.get(A,A-1)!==0){for(S=A+1;S<=f;S++)a[S]=c.get(S,A-1);for(R=A;R<=f;R++){for(b=0,S=A;S<=f;S++)b+=a[S]*i.get(S,R);for(b=b/a[A]/c.get(A,A-1),S=A;S<=f;S++)i.set(S,R,i.get(S,R)+b*a[S])}}}function mu(p,c,a,i,h){let f=p-1,v=0,b=p-1,E=Number.EPSILON,S=0,R=0,A=0,C=0,Y=0,$=0,F=0,Z=0,k,K,et,ct,ft,$t,st,ut,Tt,D,W,H,V,Mt,It;for(k=0;kb)&&(a[k]=h.get(k,k),c[k]=0),K=Math.max(k-1,0);K=v;){for(ct=f;ct>v&&($=Math.abs(h.get(ct-1,ct-1))+Math.abs(h.get(ct,ct)),$===0&&($=R),!(Math.abs(h.get(ct,ct-1))=0){for(F=A>=0?A+F:A-F,a[f-1]=ut+F,a[f]=a[f-1],F!==0&&(a[f]=ut-st/F),c[f-1]=0,c[f]=0,ut=h.get(f,f-1),$=Math.abs(ut)+Math.abs(F),A=ut/$,C=F/$,Y=Math.sqrt(A*A+C*C),A=A/Y,C=C/Y,K=f-1;K0)){for($=Math.sqrt($),Tt=ct&&(F=h.get(ft,ft),Y=ut-F,$=Tt-F,A=(Y*$-st)/h.get(ft+1,ft)+h.get(ft,ft+1),C=h.get(ft+1,ft+1)-F-Y-$,Y=h.get(ft+2,ft+1),$=Math.abs(A)+Math.abs(C)+Math.abs(Y),A=A/$,C=C/$,Y=Y/$,!(ft===ct||Math.abs(h.get(ft,ft-1))*(Math.abs(C)+Math.abs(Y))ft+2&&h.set(k,k-3,0);for(et=ft;et<=f-1&&(Mt=et!==f-1,et!==ft&&(A=h.get(et,et-1),C=h.get(et+1,et-1),Y=Mt?h.get(et+2,et-1):0,ut=Math.abs(A)+Math.abs(C)+Math.abs(Y),ut!==0&&(A=A/ut,C=C/ut,Y=Y/ut)),ut!==0);et++)if($=Math.sqrt(A*A+C*C+Y*Y),A<0&&($=-$),$!==0){for(et!==ft?h.set(et,et-1,-$*ut):ct!==ft&&h.set(et,et-1,-h.get(et,et-1)),A=A+$,ut=A/$,Tt=C/$,F=Y/$,C=C/A,Y=Y/A,K=et;K=0;f--)if(A=a[f],C=c[f],C===0)for(ct=f,h.set(f,f,1),k=f-1;k>=0;k--){for(st=h.get(k,k)-A,Y=0,K=ct;K<=f;K++)Y=Y+h.get(k,K)*h.get(K,f);if(c[k]<0)F=st,$=Y;else if(ct=k,c[k]===0?h.set(k,f,st!==0?-Y/st:-Y/(E*R)):(ut=h.get(k,k+1),Tt=h.get(k+1,k),C=(a[k]-A)*(a[k]-A)+c[k]*c[k],$t=(ut*$-F*Y)/C,h.set(k,f,$t),h.set(k+1,f,Math.abs(ut)>Math.abs(F)?(-Y-st*$t)/ut:(-$-Tt*$t)/F)),$t=Math.abs(h.get(k,f)),E*$t*$t>1)for(K=k;K<=f;K++)h.set(K,f,h.get(K,f)/$t)}else if(C<0)for(ct=f-1,Math.abs(h.get(f,f-1))>Math.abs(h.get(f-1,f))?(h.set(f-1,f-1,C/h.get(f,f-1)),h.set(f-1,f,-(h.get(f,f)-A)/h.get(f,f-1))):(It=on(0,-h.get(f-1,f),h.get(f-1,f-1)-A,C),h.set(f-1,f-1,It[0]),h.set(f-1,f,It[1])),h.set(f,f-1,0),h.set(f,f,1),k=f-2;k>=0;k--){for(D=0,W=0,K=ct;K<=f;K++)D=D+h.get(k,K)*h.get(K,f-1),W=W+h.get(k,K)*h.get(K,f);if(st=h.get(k,k)-A,c[k]<0)F=st,Y=D,$=W;else if(ct=k,c[k]===0?(It=on(-D,-W,st,C),h.set(k,f-1,It[0]),h.set(k,f,It[1])):(ut=h.get(k,k+1),Tt=h.get(k+1,k),H=(a[k]-A)*(a[k]-A)+c[k]*c[k]-C*C,V=(a[k]-A)*2*C,H===0&&V===0&&(H=E*R*(Math.abs(st)+Math.abs(C)+Math.abs(ut)+Math.abs(Tt)+Math.abs(F))),It=on(ut*Y-F*D+C*W,ut*$-F*W-C*D,H,V),h.set(k,f-1,It[0]),h.set(k,f,It[1]),Math.abs(ut)>Math.abs(F)+Math.abs(C)?(h.set(k+1,f-1,(-D-st*h.get(k,f-1)+C*h.get(k,f))/ut),h.set(k+1,f,(-W-st*h.get(k,f)-C*h.get(k,f-1))/ut)):(It=on(-Y-Tt*h.get(k,f-1),-$-Tt*h.get(k,f),F,C),h.set(k+1,f-1,It[0]),h.set(k+1,f,It[1]))),$t=Math.max(Math.abs(h.get(k,f-1)),Math.abs(h.get(k,f))),E*$t*$t>1)for(K=k;K<=f;K++)h.set(K,f-1,h.get(K,f-1)/$t),h.set(K,f,h.get(K,f)/$t)}for(k=0;kb)for(K=k;K=v;K--)for(k=v;k<=b;k++){for(F=0,et=v;et<=Math.min(K,b);et++)F=F+i.get(k,et)*h.get(et,K);i.set(k,K,F)}}}function on(p,c,a,i){let h,f;return Math.abs(a)>Math.abs(i)?(h=i/a,f=a+h*i,[(p+h*c)/f,(c-h*p)/f]):(h=a/i,f=i+h*a,[(h*p+c)/f,(h*c-p)/f])}class Hi{constructor(c){if(c=nt.checkMatrix(c),!c.isSymmetric())throw new Error("Matrix is not symmetric");let a=c,i=a.rows,h=new X(i,i),f=!0,v,b,E;for(b=0;b0),h.set(b,b,Math.sqrt(Math.max(S,0))),E=b+1;E=0;E--)for(b=0;bv;Y++)A=c.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0)),A=A.div(A.norm()),S=c.mmul(A).div(A.transpose().mmul(A).get(0,0)),Y>0&&(E=S.clone().sub(C).pow(2).sum()),C=S.clone(),i?(R=i.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),R=R.div(R.norm()),b=i.mmul(R).div(R.transpose().mmul(R).get(0,0))):b=S;if(i){let Y=c.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0));Y=Y.div(Y.norm());let $=c.clone().sub(S.clone().mmul(Y.transpose())),F=b.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),Z=i.clone().sub(S.clone().mulS(F.get(0,0)).mmul(R.transpose()));this.t=S,this.p=Y.transpose(),this.w=A.transpose(),this.q=R,this.u=b,this.s=S.transpose().mmul(S),this.xResidual=$,this.yResidual=Z,this.betas=F}else this.w=A.transpose(),this.s=S.transpose().mmul(S).sqrt(),h?this.t=S.clone().div(this.s.get(0,0)):this.t=S,this.xResidual=c.sub(S.mmul(A.transpose()))}}return yt.AbstractMatrix=I,yt.CHO=Hi,yt.CholeskyDecomposition=Hi,yt.DistanceMatrix=Kt,yt.EVD=Ce,yt.EigenvalueDecomposition=Ce,yt.LU=z,yt.LuDecomposition=z,yt.Matrix=X,yt.MatrixColumnSelectionView=Ee,yt.MatrixColumnView=$r,yt.MatrixFlipColumnView=ei,yt.MatrixFlipRowView=ur,yt.MatrixRowSelectionView=gr,yt.MatrixRowView=ri,yt.MatrixSelectionView=Rt,yt.MatrixSubView=Et,yt.MatrixTransposeView=St,yt.NIPALS=ts,yt.Nipals=ts,yt.QR=Me,yt.QrDecomposition=Me,yt.SVD=pe,yt.SingularValueDecomposition=pe,yt.SymmetricMatrix=ge,yt.WrapperMatrix1D=Se,yt.WrapperMatrix2D=nt,yt.correlation=mr,yt.covariance=hr,yt.default=X,yt.determinant=_e,yt.inverse=He,yt.linearDependencies=yr,yt.pseudoInverse=wr,yt.solve=he,yt.wrap=at,yt}var Kr=Xo(),_i=Uo(Kr);var Ri=Kr.Matrix,Qo=Kr.SingularValueDecomposition;_i.Matrix?_i.Matrix:Kr.Matrix;var Mn=(r,t)=>{let e=r.nodeCount(),n=Array.from({length:e},()=>[]),s={},o=0;return r.forEachNode(u=>{s[u.id]=o++}),r.forEachEdge(u=>{let l=s[u.source],g=s[u.target];l==null||g==null||(n[l].push(g),t||n[g].push(l))}),n},Jo=(r,t)=>{let e=r.length,n=new Array(e);for(let s=0;snew Array(t).fill(1/0));for(let n=0;n0&&(this.data[0]=e,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let e=this.data;for(;t>0;){let n=t-1>>1;if(e[n][0]<=e[t][0])break;[e[n],e[t]]=[e[t],e[n]],t=n}}bubbleDown(t){let e=this.data,n=e.length;for(;;){let s=t*2+1,o=t*2+2,u=t;if(s{let y=l[g++];d.x=y[0]+e[0],d.y=y[1]+e[1]})})}},af=r=>{let t=Number.NEGATIVE_INFINITY,e=[],n=r.length;for(let s=0;s{try{let n=r.length,s=new Ri(n,n);for(let x=0;x{let e=Object.assign(Object.assign({},Zo),t),{maxIteration:n,width:s,k:o,speed:u=Zo.speed,strictRadial:l,focusNode:g,radiiMap:d,nodeSizeFunc:y}=e,w=o*.002,m=new Map,x=s/10;for(let _=0;_{m.set(M.id,{x:0,y:0})}),uf(r,m,o,d,y),!(hf(r,m,u,l,g,x,d){let o=0;r.forEachNode(u=>{let l=0;r.forEachNode(g=>{if(l<=o){l++;return}if(u.id===g.id||n.get(u.id)!==n.get(g.id))return;let d=u.x-g.x,y=u.y-g.y,w=Math.sqrt(d*d+y*y);if(w===0){w=1;let _=o>l?1:-1;d=.01*_,y=.01*_}let m=Math.max(...s(u._original)),x=Math.max(...s(g._original));if(w{n&&r.forEachNode(d=>{let y=d.x-s.x,w=d.y-s.y,m=Math.sqrt(y*y+w*w),x=w/m,_=-y/m,G=t.get(d.id),M=Math.sqrt(G.x*G.x+G.y*G.y),q=Math.acos((x*G.x+_*G.y)/M);q>Math.PI/2&&(q-=Math.PI/2,x*=-1,_*=-1);let L=Math.cos(q)*M;t.set(d.id,{x:x*L,y:_*L})});let l=0,g=0;return r.forEachNode(d=>{if(d.id===s.id)return;let y=t.get(d.id),w=Math.sqrt(y.x*y.x+y.y*y.y);if(w>0){let m=Math.min(o*(e/800),w);if(d.x+=y.x/w*m,d.y+=y.y/w*m,n){let x=d.x-s.x,_=d.y-s.y,G=Math.sqrt(x*x+_*_);x=x/G*u.get(d.id),_=_/G*u.get(d.id),d.x=s.x+x,d.y=s.y+_}l+=m,g++}}),g>0?l/g:0};var lr={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},Nn=class extends nr{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return lr}layout(){return Ie(this,void 0,void 0,function*(){let{width:t,height:e,center:n}=jr(this.options),s=this.model.nodeCount();if(!s||s===1)return Rr(this.model,n);let{focusNode:o,linkDistance:u=lr.linkDistance,maxIteration:l=lr.maxIteration,maxPreventOverlapIteration:g=lr.maxPreventOverlapIteration,nodeSize:d,nodeSpacing:y,preventOverlap:w,sortBy:m,sortStrength:x=lr.sortStrength,strictRadial:_,unitRadius:G}=this.options,M=o&&this.model.node(o)||this.model.firstNode(),q=this.model.nodeIndexOf(M.id),L=Mn(this.model,!1),P=Cn(L),B=df(P,q);lf(P,q,B+1);let U=P[q],rt=(t-n[0]>n[0]?n[0]:t-n[0])||t/2,O=(e-n[1]>n[1]?n[1]:e-n[1])||e/2,N=Math.min(rt,O),T=Math.max(...U),it=[],gt=new Map,wt=G??N/T;U.forEach((pt,j)=>{let de=pt*wt;it.push(de),gt.set(this.model.nodeAt(j).id,de)});let zt=cf(this.model,P,u,it,wt,m,x),mt=Li(zt,2,u),ee=mt[q],le=0;if(this.model.forEachNode(pt=>{let j=mt[le];pt.x=j[0]-ee[0],pt.y=j[1]-ee[1],le++}),this.run(l,zt,it,q),this.model.forEachNode(pt=>{pt.x+=n[0],pt.y+=n[1]}),w){let j={nodeSizeFunc:An(d,y,lr.nodeSize,lr.nodeSpacing),radiiMap:gt,width:t,strictRadial:!!_,focusNode:M,maxIteration:g,k:s/4.5};Ho(this.model,j)}})}run(t,e,n,s){let o=ff(e),u=this.model.nodeCount(),l=this.model.nodes(),g=new Float64Array(u),d=new Float64Array(u);for(let y=0;y{let l=t.length,g=new Array(l),d=new Array(l);for(let _=0;_{let t=r.length,e=r[0].length,n=[];for(let s=0;s{let n=r.length;for(let s=0;s{let e=r[t],n=0;for(let s=0;sTr,BubbleSets:()=>Vn,Circle:()=>Jr,Line:()=>te,PointPath:()=>Fe,Rectangle:()=>fe,addPadding:()=>Pi,boundingBox:()=>ia,calculatePotentialOutline:()=>ua,calculateVirtualEdges:()=>oa,circle:()=>bf,createGenericInfluenceArea:()=>Ni,createLineInfluenceArea:()=>Oi,createOutline:()=>Of,createRectangleInfluenceArea:()=>sa,default:()=>Vn,defaultOptions:()=>zi,line:()=>Ef,lineBoundingBox:()=>Ci,point:()=>Gt,rect:()=>vf,unionBoundingBox:()=>ha});function Mi(r,t,e,n,s,o){let u=r,l=t,g=e-u,d=n-l,y=s-u,w=o-l,m=y*g+w*d,x=0;m<=0?x=0:(y=g-y,w=d-w,m=y*g+w*d,m<=0?x=0:x=m*m/(g*g+d*d));let _=y*y+w*w-x;return _<0?0:_}function or(r,t,e,n){return(r-e)*(r-e)+(t-n)*(t-n)}function ta(r,t,e,n,s){return or(r,t,e,n)e;if(r===0)return Math.round;let t=Math.pow(10,r);return e=>Math.round(e*t)/t}function Ci(r){let t=Math.min(r.x1,r.x2),e=Math.max(r.x1,r.x2),n=Math.min(r.y1,r.y2),s=Math.max(r.y1,r.y2);return{x:t,y:n,x2:e,y2:s,width:e-t,height:s-n}}var te=class r{constructor(t,e,n,s){this.x1=t,this.y1=e,this.x2=n,this.y2=s}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new r(t.x1,t.y1,t.x2,t.y2)}cuts(t,e){if(this.y1===this.y2||ethis.y1&&e>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+n)return!1}else if(tthis.x1+n)return!1;if(this.y1this.y2+n)return!1}else if(ethis.y1+n)return!1;return!0}},Ut;(function(r){r[r.POINT=1]="POINT",r[r.PARALLEL=2]="PARALLEL",r[r.COINCIDENT=3]="COINCIDENT",r[r.NONE=4]="NONE"})(Ut||(Ut={}));var Xr=class{constructor(t,e=0,n=0){this.state=t,this.x=e,this.y=n}};function zn(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),n=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),s=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(s){let o=e/s,u=n/s;return 0<=o&&o<=1&&0<=u&&u<=1?new Xr(Ut.POINT,r.x1+o*(r.x2-r.x1),r.y1+o*(r.y2-r.y1)):new Xr(Ut.NONE)}return new Xr(e===0||n===0?Ut.COINCIDENT:Ut.PARALLEL)}function ra(r,t){let e=(t.x2-t.x1)*(r.y1-t.y1)-(t.y2-t.y1)*(r.x1-t.x1),n=(r.x2-r.x1)*(r.y1-t.y1)-(r.y2-r.y1)*(r.x1-t.x1),s=(t.y2-t.y1)*(r.x2-r.x1)-(t.x2-t.x1)*(r.y2-r.y1);if(s){let o=e/s,u=n/s;if(0<=o&&o<=1&&0<=u&&u<=1)return o}return Number.POSITIVE_INFINITY}function pf(r,t){function e(s,o,u,l){let g=ra(t,new te(s,o,u,l));return g=Math.abs(g-.5),g>=0&&g<=1?1:0}let n=e(r.x,r.y,r.x2,r.y);return n+=e(r.x,r.y,r.x,r.y2),n>1||(n+=e(r.x,r.y2,r.x2,r.y2),n>1)?!0:(n+=e(r.x2,r.y,r.x2,r.y2),n>0)}var Wt;(function(r){r[r.LEFT=0]="LEFT",r[r.TOP=1]="TOP",r[r.RIGHT=2]="RIGHT",r[r.BOTTOM=3]="BOTTOM"})(Wt||(Wt={}));function Bn(r,t,e){let n=new Set;return r.width<=0?(n.add(Wt.LEFT),n.add(Wt.RIGHT)):tr.x+r.width&&n.add(Wt.RIGHT),r.height<=0?(n.add(Wt.TOP),n.add(Wt.BOTTOM)):er.y+r.height&&n.add(Wt.BOTTOM),n}function na(r,t){let e=t.x1,n=t.y1,s=t.x2,o=t.y2,u=Array.from(Bn(r,s,o));if(u.length===0)return!0;let l=Bn(r,e,n);for(;l.size!==0;){for(let g of u)if(l.has(g))return!1;if(l.has(Wt.RIGHT)||l.has(Wt.LEFT)){let g=r.x;l.has(Wt.RIGHT)&&(g+=r.width),n=n+(g-e)*(o-n)/(s-e),e=g}else{let g=r.y;l.has(Wt.BOTTOM)&&(g+=r.height),e=e+(g-n)*(s-e)/(o-n),n=g}l=Bn(r,e,n)}return!0}function yf(r,t){let e=Number.POSITIVE_INFINITY,n=0;function s(o,u,l,g){let d=ra(t,new te(o,u,l,g));d=Math.abs(d-.5),d>=0&&d<=1&&(n++,d1||(s(r.x,r.y2,r.x2,r.y2),n>1)?e:(s(r.x2,r.y,r.x2,r.y2),n===0?-1:e)}function wf(r,t){let e=0,n=zn(r,new te(t.x,t.y,t.x2,t.y));e+=n.state===Ut.POINT?1:0;let s=zn(r,new te(t.x,t.y,t.x,t.y2));e+=s.state===Ut.POINT?1:0;let o=zn(r,new te(t.x,t.y2,t.x2,t.y2));e+=o.state===Ut.POINT?1:0;let u=zn(r,new te(t.x2,t.y,t.x2,t.y2));return e+=u.state===Ut.POINT?1:0,{top:n,left:s,bottom:o,right:u,count:e}}var fe=class r{constructor(t,e,n,s){this.x=t,this.y=e,this.width=n,this.height=s}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new r(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new r(this.x,this.y,this.width,this.height)}add(t){let e=Math.min(this.x,t.x),n=Math.min(this.y,t.y),s=Math.max(this.x2,t.x+t.width),o=Math.max(this.y2,t.y+t.height);this.x=e,this.y=n,this.width=s-e,this.height=o-n}addPoint(t){let e=Math.min(this.x,t.x),n=Math.min(this.y,t.y),s=Math.max(this.x2,t.x),o=Math.max(this.y2,t.y);this.x=e,this.y=n,this.width=s-e,this.height=o-n}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,e){return t>=this.x&&t<=this.x2&&e>=this.y&&e<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let e=this.scaleX(t.x),n=this.scaleY(t.y),s=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),o=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),u=s-e,l=o-n;return new fe(e,n,u,l)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,e){let n=Math.ceil(e/this.pixelGroup),s=this.boundX(t.x-n),o=this.boundY(t.y-n),u=this.boundX(t.x2+n),l=this.boundY(t.y2+n),g=u-s,d=l-o;return new fe(s,o,g,d)}get(t,e){return t<0||e<0||t>=this.width||e>=this.height?Number.NaN:this.area[t+e*this.width]}inc(t,e,n){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]+=n)}set(t,e,n){t<0||e<0||t>=this.width||e>=this.height||(this.area[t+e*this.width]=n)}incArea(t,e){if(t.width<=0||t.height<=0||e===0)return;let n=this.width,s=t.width,o=Math.max(0,t.i),u=Math.max(0,t.j),l=Math.min(t.i+t.width,n),g=Math.min(t.j+t.height,this.height);if(!(g<=0||l<=0||o>=n||g>=this.height))for(let d=u;dMath.min(u,l),Number.POSITIVE_INFINITY),s=this.area.reduce((u,l)=>Math.max(u,l),Number.NEGATIVE_INFINITY),o=u=>(u-n)/(s-n);t.scale(this.pixelGroup,this.pixelGroup);for(let u=0;ue?"black":"white",t.fillRect(s,o,1,1)}t.restore()}}};function Pi(r,t){let e=n=>({x:n.x-t,y:n.y-t,width:n.width+2*t,height:n.height+2*t});return Array.isArray(r)?r.map(e):e(r)}function Oi(r,t,e){return Ni(Object.assign(Ci(r),{distSquare:(n,s)=>Mi(r.x1,r.y1,r.x2,r.y2,n,s)}),t,e)}function Ni(r,t,e){let n=Pi(r,e),s=t.scale(n),o=t.createSub(s,n);return mf(o,t,e,(u,l)=>r.distSquare(u,l)),o}function mf(r,t,e,n){let s=e*e;for(let o=0;o{let l=s.slice(0,u);return Sf(t,o,l,e,n)}).flat()}function Sf(r,t,e,n,s){let o=Gt(t.cx,t.cy),u=kf(o,e,r);if(u==null)return[];let l=new te(o.x,o.y,u.cx,u.cy),g=xf(l,r,n,s);return Af(g,r)}function xf(r,t,e,n){let s=[],o=[];o.push(r);let u=!0;for(let l=0;l0;){let g=o.pop(),d=aa(t,g),y=d?wf(g,d):null;if(!d||!y||y.count!==2){u||s.push(g);continue}let w=n,m=qn(d,w,y,!0),x=sr(m,o)||sr(m,s),_=Fn(m,t);for(;!x&&_&&w>=1;)w/=1.5,m=qn(d,w,y,!0),x=sr(m,o)||sr(m,s),_=Fn(m,t);if(m&&!x&&!_&&(o.push(new te(g.x1,g.y1,m.x,m.y)),o.push(new te(m.x,m.y,g.x2,g.y2)),u=!0),u)continue;w=n,m=qn(d,w,y,!1);let G=sr(m,o)||sr(m,s);for(_=Fn(m,t);!G&&_&&w>=1;)w/=1.5,m=qn(d,w,y,!1),G=sr(m,o)||sr(m,s),_=Fn(m,t);m&&!G&&(o.push(new te(g.x1,g.y1,m.x,m.y)),o.push(new te(m.x,m.y,g.x2,g.y2)),u=!0),u||s.push(g)}for(;o.length>0;)s.push(o.pop());return s}function Af(r,t){let e=[];for(;r.length>0;){let n=r.pop();if(r.length===0){e.push(n);break}let s=r.pop(),o=new te(n.x1,n.y1,s.x2,s.y2);aa(t,o)?(e.push(n),r.push(s)):r.push(o)}return e}function kf(r,t,e){let n=Number.POSITIVE_INFINITY;return t.reduce((s,o)=>{let u=or(r.x,r.y,o.cx,o.cy);if(u>n)return s;let l=new te(r.x,r.y,o.cx,o.cy),g=Df(e,l);return u*(g+1)*(g+1){t+=n.cx,e+=n.cy}),t/=r.length,e/=r.length,r.map(n=>{let s=t-n.cx,o=e-n.cy,u=s*s+o*o;return[n,u]}).sort((n,s)=>n[1]-s[1]).map(n=>n[0])}function Fn(r,t){return t.some(e=>e.containsPt(r.x,r.y))}function sr(r,t){return t.some(e=>!!(ta(e.x1,e.y1,r.x,r.y,.001)||ta(e.x2,e.y2,r.x,r.y,.001)))}function aa(r,t){let e=Number.POSITIVE_INFINITY,n=null;for(let s of r){if(!na(s,t))continue;let o=yf(s,t);o>=0&&ona(n,t)&&pf(n,t)?e+1:e,0)}function qn(r,t,e,n){let s=e.top,o=e.left,u=e.bottom,l=e.right;if(n){if(o.state===Ut.POINT){if(s.state===Ut.POINT)return Gt(r.x-t,r.y-t);if(u.state===Ut.POINT)return Gt(r.x-t,r.y2+t);let m=r.width*r.height;return r.width*((o.y-r.y+(l.y-r.y))*.5)l.y?Gt(r.x-t,r.y-t):Gt(r.x2+t,r.y-t):o.yu.x?Gt(r.x-t,r.y-t):Gt(r.x-t,r.y2+t):s.xl.y?Gt(r.x2+t,r.y2+t):Gt(r.x-t,r.y2+t):o.yu.x?Gt(r.x2+t,r.y2+t):Gt(r.x2+t,r.y-t):s.xn)return!1}return!0}function Rf(r=0){return t=>{if(r<0||t.length<3)return t;let e=[],n=0,s=r*r;for(;n{if(u.length<3)return u;let l=[],g=u.closed,d=u.length+3-1+(g?0:2);l.push(o(u,2-(g?0:2),0));for(let y=2-(g?0:2);y{let e=r,n=t.length;if(e>1)for(n=Math.floor(t.length/e);n<3&&e>1;)e-=1,n=Math.floor(t.length/e);let s=[];for(let o=0,u=0;u=n?this.closed?this.get(t-n):this.points[n-1]:this.points[e]}get length(){return this.points.length}toString(t=1/0){let e=this.points;if(e.length===0)return"";let n=typeof t=="function"?t:gf(t),s="M";for(let o of e)s+=`${n(o.x)},${n(o.y)} L`;return s=s.slice(0,-1),this.closed&&(s+=" Z"),s}draw(t){let e=this.points;if(e.length!==0){t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let n of e)t.lineTo(n.x,n.y);this.closed&&t.closePath()}}sample(t){return Lf(t)(this)}simplify(t){return Rf(t)(this)}bSplines(t){return Tf(t)(this)}apply(t){return t(this)}containsElements(t){let e=ia(this.points);return e?t.every(n=>e.containsPt(n.cx,n.cy)&&this.withinArea(n.cx,n.cy)):!1}withinArea(t,e){if(this.length===0)return!1;let n=0,s=this.points[0],o=new te(s.x,s.y,s.x,s.y);for(let u=1;ut?y+w:y}function o(g,d){let y=Yr;return y=s(g,d,y,1),y=s(g+1,d,y,2),y=s(g,d+1,y,4),y=s(g+1,d+1,y,8),Number.isNaN(y)?-1:y}let u=Un;function l(g,d){let y=g,w=d,m=r.invertScaleX(y),x=r.invertScaleY(w);for(let _=0;_ea(n.raw,t));return e<0?!1:(this.members.splice(e,1),this.dirty.add($e.MEMBERS),!0)}removeNonMember(t){let e=this.nonMembers.findIndex(n=>ea(n.raw,t));return e<0?!1:(this.nonMembers.splice(e,1),this.dirty.add($e.NON_MEMBERS),!0)}removeEdge(t){let e=this.edges.findIndex(n=>n.obj.equals(t));return e<0?!1:(this.edges.splice(e,1),this.dirty.add($e.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add($e.NON_MEMBERS);for(let e of t)this.nonMembers.push({raw:e,obj:Qr(e)?Jr.from(e):fe.from(e),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add($e.EDGES);for(let e of t)this.edges.push({raw:e,obj:te.from(e),area:null})}}update(){let t=this.dirty.has($e.MEMBERS),e=this.dirty.has($e.NON_MEMBERS),n=this.dirty.has($e.EDGES);this.dirty.clear();let s=this.members.map(d=>d.obj);if(this.o.virtualEdges&&(t||e)){let d=this.nonMembers.map(m=>m.obj),y=oa(s,d,this.o.maxRoutingIterations,this.o.morphBuffer),w=new Map(this.virtualEdges.map(m=>[m.obj.toString(),m.area]));this.virtualEdges=y.map(m=>{var x;return{raw:m,obj:m,area:(x=w.get(m.toString()))!==null&&x!==void 0?x:null}}),n=!0}let o=!1;if(t||n){let d=this.virtualEdges.concat(this.edges).map(x=>x.obj),y=ha(s,d),w=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,m=fe.from(Pi(y,w));m.equals(this.activeRegion)||(o=!0,this.activeRegion=m)}if(o){let d=Math.ceil(this.activeRegion.width/this.o.pixelGroup),y=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=Tr.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(w=>w.area=null),this.nonMembers.forEach(w=>w.area=null),this.edges.forEach(w=>w.area=null),this.virtualEdges.forEach(w=>w.area=null)):(d!==this.potentialArea.width||y!==this.potentialArea.height)&&(this.potentialArea=Tr.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let u=new Map,l=d=>{if(d.area){let y=`${d.obj.width}x${d.obj.height}x${d.obj instanceof fe?"R":"C"}`;u.set(y,d.area)}},g=d=>{if(d.area)return;let y=`${d.obj.width}x${d.obj.height}x${d.obj instanceof fe?"R":"C"}`;if(u.has(y)){let m=u.get(y);d.area=this.potentialArea.copy(m,{x:d.obj.x-this.o.nodeR1,y:d.obj.y-this.o.nodeR1});return}let w=d.obj instanceof fe?sa(d.obj,this.potentialArea,this.o.nodeR1):Ni(d.obj,this.potentialArea,this.o.nodeR1);d.area=w,u.set(y,w)};this.members.forEach(l),this.nonMembers.forEach(l),this.members.forEach(g),this.nonMembers.forEach(d=>{this.activeRegion.intersects(d.obj)?g(d):d.area=null}),this.edges.forEach(d=>{d.area||(d.area=Oi(d.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(d=>{d.area||(d.area=Oi(d.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let e of this.members)e.obj.draw(t)}drawNonMembers(t){for(let e of this.nonMembers)e.obj.draw(t)}drawEdges(t){for(let e of this.edges)e.obj.draw(t)}drawPotentialArea(t,e=!0){this.potentialArea.draw(t,e)}compute(){if(this.members.length===0)return new Fe([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:e}=this,n=this.members.map(l=>l.area),s=this.virtualEdges.concat(this.edges).map(l=>l.area),o=this.nonMembers.filter(l=>l.area!=null).map(l=>l.area),u=this.members.map(l=>l.obj);return ua(e,n,s,o,l=>l.containsElements(u),t)}};function ua(r,t,e,n,s,o={}){let u=Object.assign({},zi,o),l=u.threshold,g=u.memberInfluenceFactor,d=u.edgeInfluenceFactor,y=u.nonMemberInfluenceFactor,w=(u.nodeR0-u.nodeR1)*(u.nodeR0-u.nodeR1),m=(u.edgeR0-u.edgeR1)*(u.edgeR0-u.edgeR1);for(let x=0;x0)y*=.8;else break}return new Fe([])}function ha(r,t){if(r.length===0)return new fe(0,0,0,0);let e=fe.from(r[0]);for(let n of r)e.add(n);for(let n of t)e.add(Ci(n));return e}function Of(r,t=[],e=[],n={}){if(r.length===0)return new Fe([]);let s=new Vn(n);return s.pushMember(...r),s.pushNonMember(...t),s.pushEdge(...e),s.compute()}var Yl=je(ga(),1),Xl=je(Fa(),1),Ql=je(Ya(),1),Jl=je(Za(),1),Zl=je(ru(),1),Hl=je(su(),1),td=je(yu(),1);var export_FA2Layout=Kl.default;var export_betweennessCentrality=Xl.default;var export_circlepack=ti.circlepack;var export_circular=ti.circular;var export_closenessCentrality=Ql.default;var export_degreeCentrality=Yl.degreeCentrality;var export_density=Hl.density;var export_diameter=td.default;var export_eigenvectorCentrality=Jl.default;var export_forceAtlas2=Vl.default;var export_pagerank=Zl.default;var export_random=ti.random;var export_rotation=ti.rotation;export{On as ConcentricLayout,export_FA2Layout as FA2Layout,Lt as Graph,Pn as MDSLayout,Nn as RadialLayout,export_betweennessCentrality as betweennessCentrality,ca as bubblesets,export_circlepack as circlepack,export_circular as circular,export_closenessCentrality as closenessCentrality,export_degreeCentrality as degreeCentrality,export_density as density,export_diameter as diameter,export_eigenvectorCentrality as eigenvectorCentrality,export_forceAtlas2 as forceAtlas2,export_pagerank as pagerank,export_random as random,export_rotation as rotation}; /*! Bundled license information: comlink/dist/esm/comlink.js: diff --git a/src/managers/metrics.js b/src/managers/metrics.js index aaeb6da..f343299 100644 --- a/src/managers/metrics.js +++ b/src/managers/metrics.js @@ -1,6 +1,17 @@ import {Popup} from "../utilities/popup.js"; +import { + Graph, + betweennessCentrality, + closenessCentrality, + degreeCentrality, + density, + diameter, + eigenvectorCentrality, + pagerank, +} from "../lib/graphology.bundle.mjs"; const NODE_CONNECTIVITY_METRICS_PRECISION = 5; +const POWER_ITERATION_OPTIONS = {maxIterations: 100, tolerance: 1e-6}; const METRIC_VALUE_LABELS = { centrality: "Centrality", betweenness: "Score", @@ -87,42 +98,47 @@ class NetworkMetrics { await this.cache.ui.showLoading("Calculating", `Network Metric: ${metricName}`); await new Promise(resolve => requestAnimationFrame(resolve)); - this.resetNodeToolTipMetricTexts(); - - const metricResult = await this.m[this.selected]?.calculate(this.cache); - this.storeMetricValues(this.selected, metricResult); - - /* multiselect */ - const selectedValues = Array.from(this.multiselect.selectedOptions, opt => opt.value); + // try/finally so a failing calculation (e.g. non-converging eigenvector) + // never leaves the loading overlay stuck on screen. + try { + this.resetNodeToolTipMetricTexts(); + + const metricResult = await this.m[this.selected]?.calculate(this.cache); + this.storeMetricValues(this.selected, metricResult); + + /* multiselect */ + const selectedValues = Array.from(this.multiselect.selectedOptions, opt => opt.value); + + this.multiselect.innerHTML = ''; + for (const ns of metricResult.scores) { + const opt = document.createElement('option'); + opt.value = ns.id; + opt.textContent = `${ns.id} | ${ns.text}`; + opt.selected = selectedValues.includes(ns.id); + this.updateNodeToolTipMetricText(ns.id, metricName, ns.text); + this.multiselect.appendChild(opt); + } - this.multiselect.innerHTML = ''; - for (const ns of metricResult.scores) { - const opt = document.createElement('option'); - opt.value = ns.id; - opt.textContent = `${ns.id} | ${ns.text}`; - opt.selected = selectedValues.includes(ns.id); - this.updateNodeToolTipMetricText(ns.id, metricName, ns.text); - this.multiselect.appendChild(opt); + /* graph-level table */ + this.table.innerHTML = ''; + Object.entries(metricResult.graphLevelMetrics).forEach(([label, value]) => { + const row = document.createElement('tr'); + const labelCell = document.createElement('td'); + labelCell.textContent = label; + const valueCell = document.createElement('td'); + valueCell.textContent = `${value}`; + row.append(labelCell, valueCell); + this.table.appendChild(row); + }); + + /* tooltip */ + document.getElementById("metricInfoBtn").onclick = () => { + this.cache.popup = new Popup(metricResult.popupContent, {title: metricResult.popupTitle, width: '400px'}); + }; + } finally { + await this.cache.ui.hideLoading(); + await new Promise(resolve => requestAnimationFrame(resolve)); } - - /* graph-level table */ - this.table.innerHTML = ''; - Object.entries(metricResult.graphLevelMetrics).forEach(([label, value]) => { - const row = document.createElement('tr'); - const labelCell = document.createElement('td'); - labelCell.textContent = label; - const valueCell = document.createElement('td'); - valueCell.textContent = `${value}`; - row.append(labelCell, valueCell); - this.table.appendChild(row); - }); - - /* tooltip */ - document.getElementById("metricInfoBtn").onclick = () => { - this.cache.popup = new Popup(metricResult.popupContent, {title: metricResult.popupTitle, width: '400px'}); - }; - await this.cache.ui.hideLoading(); - await new Promise(resolve => requestAnimationFrame(resolve)); } storeMetricValues(metricId, metricResult) { @@ -149,11 +165,13 @@ class NetworkMetrics { await this.cache.ui.showLoading("Calculating", `Network Metric: ${metricName}`); await new Promise(resolve => requestAnimationFrame(resolve)); - const metricResult = await metric.calculate(this.cache); - this.storeMetricValues(metricId, metricResult); - - await this.cache.ui.hideLoading(); - await new Promise(resolve => requestAnimationFrame(resolve)); + try { + const metricResult = await metric.calculate(this.cache); + this.storeMetricValues(metricId, metricResult); + } finally { + await this.cache.ui.hideLoading(); + await new Promise(resolve => requestAnimationFrame(resolve)); + } return this.metricValueCache.get(metricId) || null; } @@ -306,51 +324,64 @@ class NetworkMetrics { } } -async function calculateDegreeCentrality(cache) { +/** + * Builds a temporary undirected multigraph from the currently visible + * subgraph so graphology-metrics can run on it. Multi because every visible + * parallel edge counts toward degree, matching the previous behaviour. + * @param {object} cache + * @returns {Graph} + */ +function buildVisibleGraph(cache) { const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; + const graph = new Graph({type: 'undirected', multi: true}); - const n = nodes.size; - if (n === 0) { - return {scores: [], graphLevelMetrics: {}}; - } - - // 1. Degree accumulation - const degree = new Map(); - for (const id of nodes) degree.set(id, 0); - + for (const id of nodes) graph.addNode(id); for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId); - if (degree.has(source)) degree.set(source, degree.get(source) + 1); - if (degree.has(target)) degree.set(target, degree.get(target) + 1); + const {source, target} = edgeRef.get(edgeId) ?? {}; + if (graph.hasNode(source) && graph.hasNode(target)) { + graph.addEdgeWithKey(edgeId, source, target); + } } + return graph; +} - // 2. Centrality + statistics - const scores = []; - let sum = 0, min = Infinity, max = -Infinity; +/** Maps a graphology-metrics result object to [{id, value}] sorted desc. */ +function descendingScores(centralities) { + return Object.entries(centralities) + .map(([id, value]) => ({id, value})) + .sort((a, b) => b.value - a.value); +} - for (const [id, d] of degree) { - const c = d / (n - 1); // Freeman degree centrality - scores.push({id, degree: d, centrality: c}); - sum += c; - if (c < min) min = c; - if (c > max) max = c; +async function calculateDegreeCentrality(cache) { + const graph = buildVisibleGraph(cache); + const n = graph.order; + // Uniform n <= 1 guard across all five calculators: degreeCentrality + // divides by (n - 1) and returns NaN for a single node, and centrality of + // a lone node is meaningless anyway, so every metric returns the same + // empty shape instead of per-library edge-case values. + if (n <= 1) { + return {scores: [], graphLevelMetrics: {}}; } - scores.sort((a, b) => b.centrality - a.centrality); - const median = scores[Math.floor(n / 2)].centrality; + const scores = descendingScores(degreeCentrality(graph)); + const max = scores[0].value; + const min = scores[scores.length - 1].value; + const sum = scores.reduce((acc, s) => acc + s.value, 0); const mean = sum / n; + const median = scores[Math.floor(n / 2)].value; + // Avoid division by zero in percentage calculations (all-zero scores) + const maxForPercentage = max || 1; // Freeman network centralization (undirected) const centralization = (n > 2) - ? scores.reduce((acc, s) => acc + (max - s.centrality), 0) / - ((n - 1) * (n - 2)) + ? scores.reduce((acc, s) => acc + (max - s.value), 0) / ((n - 1) * (n - 2)) : 0; - const nodeValues = new Map(scores.map(s => [s.id, s.centrality])); + const nodeValues = new Map(scores.map(s => [s.id, s.value])); return { scores: scores.map(s => ({ id: s.id, - text: `Degree ${s.degree} | Centrality ${s.centrality.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.centrality / max) * 100)} %)` + text: `Degree ${graph.degree(s.id)} | Centrality ${s.value.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.value / maxForPercentage) * 100)} %)` })), nodeValues, graphLevelMetrics: { @@ -358,7 +389,7 @@ async function calculateDegreeCentrality(cache) { "Minimum Degree Centrality": min * (n - 1), "Average Degree Centrality": +(mean * (n - 1)).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Median Degree": +(median * (n - 1)).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), - "Graph Density": +(sum / n).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), + "Graph Density": +density(graph).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Centralization": +centralization.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION) }, popupTitle: 'Degree Centrality', @@ -405,103 +436,33 @@ Nodes with more connections are considered more central and receive a higher sco } async function calculateBetweennessCentrality(cache) { - const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; - - const n = nodes.size; - if (n === 0) { + const graph = buildVisibleGraph(cache); + const n = graph.order; + // Uniform n <= 1 guard — see calculateDegreeCentrality. + if (n <= 1) { return {scores: [], graphLevelMetrics: {}}; } - // Build adjacency map - const adjacencyMap = new Map(); - for (const id of nodes) adjacencyMap.set(id, new Set()); - for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId); - if (adjacencyMap.has(source)) adjacencyMap.get(source).add(target); - if (adjacencyMap.has(target)) adjacencyMap.get(target).add(source); - } - - // Initialize betweenness scores - const betweenness = new Map(); - for (const id of nodes) betweenness.set(id, 0); - - // Process each node as source - for (const source of nodes) { - // Initialize data structures for BFS - const distance = new Map(); - const paths = new Map(); - const queue = []; - const stack = []; // for dependency accumulation - - // Initialize source node - distance.set(source, 0); - paths.set(source, 1); - queue.push(source); - - // BFS phase - while (queue.length > 0) { - const node = queue.shift(); - stack.push(node); - - for (const neighbor of adjacencyMap.get(node)) { - // Node discovered for first time? - if (!distance.has(neighbor)) { - queue.push(neighbor); - distance.set(neighbor, distance.get(node) + 1); - paths.set(neighbor, paths.get(node)); - } - // Another shortest path found? - else if (distance.get(neighbor) === distance.get(node) + 1) { - paths.set(neighbor, paths.get(neighbor) + paths.get(node)); - } - } - } - - // Dependency accumulation phase - const dependency = new Map(); - for (const node of nodes) dependency.set(node, 0); - - // Process nodes in reverse order of discovery - while (stack.length > 0) { - const node = stack.pop(); - if (node === source) continue; - - for (const neighbor of adjacencyMap.get(node)) { - if (distance.get(neighbor) === distance.get(node) - 1) { - const coeff = (paths.get(neighbor) / paths.get(node)) * (1 + dependency.get(node)); - dependency.set(neighbor, dependency.get(neighbor) + coeff); - } - } - - betweenness.set(node, betweenness.get(node) + dependency.get(node) / 2); - } - } - - // Normalize scores and prepare results - const scores = []; - let max = -Infinity; - const normalizationFactor = ((n - 1) * (n - 2)) / 2; - - for (const [id, score] of betweenness) { - const normalizedScore = score / normalizationFactor; - scores.push({id, score: normalizedScore}); - if (normalizedScore > max) max = normalizedScore; - } - - scores.sort((a, b) => b.score - a.score); - - // Calculate graph level metrics - const centralityValues = scores.map(s => s.score); - const sum = centralityValues.reduce((a, b) => a + b, 0); + // Brandes' algorithm; normalized pair-count scaling 2/((n-1)(n-2)) matches + // the previous implementation. getEdgeWeight: null selects the unweighted + // BFS variant. + const centralities = betweennessCentrality(graph, {getEdgeWeight: null, normalized: true}); + const scores = descendingScores(centralities); + const max = scores[0].value; + const min = scores[scores.length - 1].value; + const sum = scores.reduce((acc, s) => acc + s.value, 0); const mean = sum / n; - const min = Math.min(...centralityValues); - const centralization = scores.reduce((acc, s) => acc + (max - s.score), 0) / ((n - 1) * (n - 2) / 2); + // Avoid division by zero in percentage calculations (all-zero scores) + const maxForPercentage = max || 1; + const centralization = (n > 2) + ? scores.reduce((acc, s) => acc + (max - s.value), 0) / ((n - 1) * (n - 2) / 2) + : 0; - const nodeValues = new Map(scores.map(s => [s.id, s.score])); + const nodeValues = new Map(scores.map(s => [s.id, s.value])); return { scores: scores.map(s => ({ id: s.id, - text: `Score: ${s.score.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.score / max) * 100)}%)` + text: `Score: ${s.value.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.value / maxForPercentage) * 100)}%)` })), nodeValues, graphLevelMetrics: { @@ -548,81 +509,40 @@ Nodes with high betweenness centrality are important controllers of information } async function calculateClosenessCentrality(cache) { - const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; - - const n = nodes.size; - if (n === 0) return {scores: [], graphLevelMetrics: {}}; - - // Build adjacency list - const graphMap = new Map(); - for (const id of nodes) graphMap.set(id, new Set()); - - for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId); - if (graphMap.has(source) && graphMap.has(target)) { - graphMap.get(source).add(target); - graphMap.get(target).add(source); - } - } - - // Calculate shortest paths using BFS - function bfs(start) { - const distances = new Map(); - const queue = [[start, 0]]; - distances.set(start, 0); - - while (queue.length > 0) { - const [node, dist] = queue.shift(); - for (const neighbor of graphMap.get(node)) { - if (!distances.has(neighbor)) { - distances.set(neighbor, dist + 1); - queue.push([neighbor, dist + 1]); - } - } - } - return distances; - } - - const scores = []; - let sum = 0, min = Infinity, max = -Infinity; - - for (const nodeId of nodes) { - const distances = bfs(nodeId); - const reachableNodes = distances.size; - - // Skip unreachable nodes in total distance calculation - const totalDistance = Array.from(distances.values()) - .filter(d => d > 0) // Exclude self-distance - .reduce((a, b) => a + b, 0); - - // Wasserman and Faust (1994) formula for disconnected graphs - const closeness = totalDistance > 0 ? - ((reachableNodes - 1) * (reachableNodes - 1)) / ((n - 1) * totalDistance) : 0; - - scores.push({id: nodeId, closeness}); - sum += closeness; - if (closeness < min) min = closeness; - if (closeness > max) max = closeness; - } - - scores.sort((a, b) => b.closeness - a.closeness); + const graph = buildVisibleGraph(cache); + const n = graph.order; + // Uniform n <= 1 guard — see calculateDegreeCentrality. + if (n <= 1) return {scores: [], graphLevelMetrics: {}}; + + // wassermanFaust keeps the disconnected-graph correction the previous + // implementation used: closeness scaled by reachable-fraction (count/(n-1)). + const centralities = closenessCentrality(graph, {wassermanFaust: true}); + const scores = descendingScores(centralities); + const max = scores[0].value; + const min = scores[scores.length - 1].value; + const sum = scores.reduce((acc, s) => acc + s.value, 0); const mean = sum / n; // Avoid division by zero in percentage calculations const maxForPercentage = max || 1; + const centralization = (n > 2) + ? (n * max - sum) / ((n - 1) * (n - 2) / (2 * n - 3)) + : 0; + const graphDiameter = diameter(graph); - const nodeValues = new Map(scores.map(s => [s.id, s.closeness])); + const nodeValues = new Map(scores.map(s => [s.id, s.value])); return { scores: scores.map(s => ({ id: s.id, - text: `Score: ${s.closeness.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.closeness / maxForPercentage) * 100)}%)` + text: `Score: ${s.value.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.value / maxForPercentage) * 100)}%)` })), nodeValues, graphLevelMetrics: { "Maximum Closeness Centrality": +max.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Minimum Closeness Centrality": +min.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Average Closeness Centrality": +mean.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), - "Centralization": +((n * max - sum) / ((n - 1) * (n - 2) / (2 * n - 3))).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION) + "Graph Diameter": Number.isFinite(graphDiameter) ? graphDiameter : "∞ (disconnected)", + "Centralization": +centralization.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION) }, popupTitle: 'Closeness Centrality', popupContent: `
    @@ -656,6 +576,9 @@ async function calculateClosenessCentrality(cache) {

    +Graph Diameter: Length of the longest shortest path between any two nodes; ∞ when the visible graph is disconnected. +

    +

    Centralization: Freeman closeness-centralization — degree to which one node is, on average, closer to all others than the rest of the network.

    ` @@ -663,67 +586,37 @@ async function calculateClosenessCentrality(cache) { } async function calculateEigenvectorCentrality(cache) { - const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; - - const n = nodes.size; - if (n === 0) return {scores: [], graphLevelMetrics: {}}; - - // Initialize adjacency matrix and eigenvector - const matrix = Array(n).fill().map(() => Array(n).fill(0)); - const nodeArray = Array.from(nodes); - const nodeIndex = new Map(nodeArray.map((id, i) => [id, i])); - - // Build adjacency matrix - for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId); - if (nodeIndex.has(source) && nodeIndex.has(target)) { - const i = nodeIndex.get(source), j = nodeIndex.get(target); - matrix[i][j] = matrix[j][i] = 1; - } - } - - // Power iteration method - let eigenVector = Array(n).fill(1 / n); - let prevEigenVector; - const maxIterations = 100; - const tolerance = 1e-6; - - for (let iter = 0; iter < maxIterations; iter++) { - prevEigenVector = [...eigenVector]; - eigenVector = Array(n).fill(0); - - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - eigenVector[i] += matrix[i][j] * prevEigenVector[j]; - } - } - - // Normalize - const norm = Math.sqrt(eigenVector.reduce((sum, x) => sum + x * x, 0)); - eigenVector = eigenVector.map(x => x / norm); - - // Check convergence - if (eigenVector.every((x, i) => Math.abs(x - prevEigenVector[i]) < tolerance)) break; + const graph = buildVisibleGraph(cache); + const n = graph.order; + // Uniform n <= 1 guard — see calculateDegreeCentrality. + if (n <= 1) return {scores: [], graphLevelMetrics: {}}; + + // graphology-metrics throws when the power iteration fails to converge + // (instead of silently returning a non-converged iterate like the previous + // implementation). Surface a clear message through the UI failure path. + let centralities; + try { + centralities = eigenvectorCentrality(graph, POWER_ITERATION_OPTIONS); + } catch { + throw new Error( + 'Eigenvector centrality did not converge for the visible graph — try a different metric or filter to a denser subgraph.' + ); } - // Prepare scores - const scores = eigenVector.map((score, i) => ({ - id: nodeArray[i], - centrality: score - })); - - scores.sort((a, b) => b.centrality - a.centrality); - const max = scores[0].centrality; - const min = scores[scores.length - 1].centrality; - - const mean = eigenVector.reduce((a, b) => a + b) / n; - const variance = eigenVector.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / n; + const scores = descendingScores(centralities); + const max = scores[0].value; + const min = scores[scores.length - 1].value; + const sum = scores.reduce((acc, s) => acc + s.value, 0); + const mean = sum / n; + const variance = scores.reduce((acc, s) => acc + Math.pow(s.value - mean, 2), 0) / n; + // Avoid division by zero in percentage calculations (all-zero scores) + const maxForPercentage = max || 1; - const nodeValues = new Map(scores.map(s => [s.id, s.centrality])); + const nodeValues = new Map(scores.map(s => [s.id, s.value])); return { scores: scores.map(s => ({ id: s.id, - text: `Score: ${s.centrality.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.centrality / max) * 100)}%)` + text: `Score: ${s.value.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.value / maxForPercentage) * 100)}%)` })), nodeValues, graphLevelMetrics: { @@ -731,7 +624,7 @@ async function calculateEigenvectorCentrality(cache) { "Minimum Eigenvector Centrality": +min.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Average Eigenvector Centrality": +mean.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), "Variance Eigenvector Centrality": +variance.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION), - "Centralization": +(scores.reduce((acc, s) => acc + (max - s.centrality), 0) / (n - 1)).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION) + "Centralization": +(scores.reduce((acc, s) => acc + (max - s.value), 0) / (n - 1)).toFixed(NODE_CONNECTIVITY_METRICS_PRECISION) }, popupTitle: 'Eigenvector Centrality', popupContent: `
    @@ -739,8 +632,10 @@ async function calculateEigenvectorCentrality(cache) { links to influential neighbours matter more than links to peripheral ones. Newman, 2010

    -

    Note: +

    Note: This implementation treats all graphs as undirected when calculating influence scores. + If the power iteration does not converge for the visible graph, an error is reported + instead of partial scores.

    Parameters: @@ -778,79 +673,36 @@ links to influential neighbours matter more than links to peripheral ones. } async function calculatePageRank(cache) { - const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; - - const n = nodes.size; - if (n === 0) return {scores: [], graphLevelMetrics: {}}; - - const nodeArray = Array.from(nodes); - const nodeIndex = new Map(nodeArray.map((id, i) => [id, i])); - const matrix = Array(n).fill().map(() => Array(n).fill(0)); - const degrees = Array(n).fill(0); - - // Build symmetric adjacency matrix for undirected graph - for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId); - if (nodeIndex.has(source) && nodeIndex.has(target)) { - const i = nodeIndex.get(source), j = nodeIndex.get(target); - // Add edges in both directions - matrix[j][i] = matrix[i][j] = 1; - degrees[i]++; - degrees[j]++; - } - } - - // Normalize the matrix - for (let i = 0; i < n; i++) { - if (degrees[i] > 0) { - for (let j = 0; j < n; j++) { - matrix[j][i] = matrix[j][i] / degrees[i]; - } - } else { - // For isolated nodes, distribute probability evenly - for (let j = 0; j < n; j++) { - matrix[j][i] = 1 / n; - } - } - } - - const d = 0.85; - let scores = Array(n).fill(1 / n); - let prevScores; - const maxIter = 100; - const tolerance = 1e-6; - - // Power iteration method remains the same - for (let iter = 0; iter < maxIter; iter++) { - prevScores = [...scores]; - scores = Array(n).fill((1 - d) / n); - - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - scores[i] += d * matrix[i][j] * prevScores[j]; - } - } - - if (scores.every((x, i) => Math.abs(x - prevScores[i]) < tolerance)) break; - } - - const sortedScores = scores.map((score, i) => ({ - id: nodeArray[i], - score - })).sort((a, b) => b.score - a.score); - - const maxScore = sortedScores[0].score; - const minScore = sortedScores[sortedScores.length - 1].score; - const meanScore = scores.reduce((a, b) => a + b) / n; - const minDegree = Math.min(...degrees); - const maxDegree = Math.max(...degrees); - const avgDegree = degrees.reduce((a, b) => a + b) / n; - - const nodeValues = new Map(sortedScores.map(s => [s.id, s.score])); + const graph = buildVisibleGraph(cache); + const n = graph.order; + // Uniform n <= 1 guard — see calculateDegreeCentrality. + if (n <= 1) return {scores: [], graphLevelMetrics: {}}; + + // Same convention as the previous implementation: undirected edges walked + // in both directions, dangling/isolated mass redistributed uniformly. + const ranks = pagerank(graph, {alpha: 0.85, ...POWER_ITERATION_OPTIONS}); + const sortedScores = descendingScores(ranks); + + const maxScore = sortedScores[0].value; + const minScore = sortedScores[sortedScores.length - 1].value; + const meanScore = sortedScores.reduce((acc, s) => acc + s.value, 0) / n; + + let minDegree = Infinity, maxDegree = -Infinity, degreeSum = 0; + graph.forEachNode((node) => { + const d = graph.degree(node); + if (d < minDegree) minDegree = d; + if (d > maxDegree) maxDegree = d; + degreeSum += d; + }); + const avgDegree = degreeSum / n; + // Avoid division by zero in percentage calculations (all-zero scores) + const maxForPercentage = maxScore || 1; + + const nodeValues = new Map(sortedScores.map(s => [s.id, s.value])); return { scores: sortedScores.map(s => ({ id: s.id, - text: `Score: ${s.score.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.score / maxScore) * 100)}%)` + text: `Score: ${s.value.toFixed(NODE_CONNECTIVITY_METRICS_PRECISION)} (${Math.round((s.value / maxForPercentage) * 100)}%)` })), nodeValues, graphLevelMetrics: { diff --git a/src/package/vendor_entry_graphology.mjs b/src/package/vendor_entry_graphology.mjs index 2c7d288..36a516b 100644 --- a/src/package/vendor_entry_graphology.mjs +++ b/src/package/vendor_entry_graphology.mjs @@ -11,3 +11,12 @@ export {default as forceAtlas2} from 'graphology-layout-forceatlas2'; export {default as FA2Layout} from 'graphology-layout-forceatlas2/worker'; export {RadialLayout, ConcentricLayout, MDSLayout} from '@antv/layout'; export * as bubblesets from 'bubblesets-js'; +// Network metrics (graphology-metrics; pure JS, node-safe). Subpath imports +// keep hits/modularity/layout-quality out of the bundle. +export {degreeCentrality} from 'graphology-metrics/centrality/degree.js'; +export {default as betweennessCentrality} from 'graphology-metrics/centrality/betweenness.js'; +export {default as closenessCentrality} from 'graphology-metrics/centrality/closeness.js'; +export {default as eigenvectorCentrality} from 'graphology-metrics/centrality/eigenvector.js'; +export {default as pagerank} from 'graphology-metrics/centrality/pagerank.js'; +export {density} from 'graphology-metrics/graph/density.js'; +export {default as diameter} from 'graphology-metrics/graph/diameter.js'; diff --git a/src/package/vendor_libs.js b/src/package/vendor_libs.js index 6409f1c..6a27fa1 100644 --- a/src/package/vendor_libs.js +++ b/src/package/vendor_libs.js @@ -58,7 +58,7 @@ const bundles = [ { entry: path.join(__dirname, 'vendor_entry_graphology.mjs'), out: path.join(libDir, 'graphology.bundle.mjs'), - pkgs: ['graphology', 'graphology-layout', 'graphology-layout-forceatlas2', '@antv/layout', 'bubblesets-js'], + pkgs: ['graphology', 'graphology-layout', 'graphology-layout-forceatlas2', 'graphology-metrics', '@antv/layout', 'bubblesets-js'], }, { entry: path.join(__dirname, 'vendor_entry_sigma.mjs'), diff --git a/tests/metrics.test.js b/tests/metrics.test.js index 0a59722..c1a9c0d 100644 --- a/tests/metrics.test.js +++ b/tests/metrics.test.js @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest' +import { describe, it, expect, vi } from 'vitest' import { calculateDegreeCentrality, calculateBetweennessCentrality, @@ -9,21 +9,23 @@ import { // ========================================================================== // Network metrics — unit tests with known graph topologies +// (algorithm cores delegated to graphology-metrics) // ========================================================================== const PRECISION = 5 -// Helper: build a minimal cache-like object for the metric functions +// Helper: build a minimal cache-like object for the metric functions. +// Edge ids carry an index suffix so parallel (multi) edges stay distinct. function makeCache(nodeIds, edges) { const nodeIDsToBeShown = new Set(nodeIds) const edgeRef = new Map() const edgeIDsToBeShown = new Set() - for (const [source, target] of edges) { - const id = `${source}::${target}` + edges.forEach(([source, target], i) => { + const id = `${source}::${target}::${i}` edgeIDsToBeShown.add(id) edgeRef.set(id, { source, target }) - } + }) return { nodeIDsToBeShown, edgeIDsToBeShown, edgeRef } } @@ -116,6 +118,62 @@ describe('Degree Centrality', () => { // B has degree 3 (highest) expect(glm['Maximum Degree Centrality']).toBe(3) }) + + it('counts parallel (multi) edges toward degree', async () => { + // A == B (two parallel edges), C connected once + const cache = makeCache( + ['A', 'B', 'C'], + [['A', 'B'], ['A', 'B'], ['B', 'C']] + ) + const result = await calculateDegreeCentrality(cache) + + // A has degree 2 of 2 possible → 1.0; B degree 3 → 1.5 + expect(result.nodeValues.get('A')).toBe(1.0) + expect(result.nodeValues.get('B')).toBe(1.5) + expect(result.nodeValues.get('C')).toBe(0.5) + expect(result.scores[0].text).toContain('Degree 3') + }) + + it('counts a visible self-loop twice toward degree (unchanged semantics)', async () => { + // Old accumulation (`if has(source) +1; if has(target) +1`) counted a + // self-loop twice — identical to graphology undirected multigraph degree. + const cache = makeCache(['A', 'B', 'C'], [['A', 'A'], ['A', 'B']]) + const result = await calculateDegreeCentrality(cache) + + // A: self-loop (2) + edge to B (1) = degree 3 → centrality 3/(n-1) = 1.5 + expect(result.nodeValues.get('A')).toBe(1.5) + expect(result.scores[0].text).toContain('Degree 3') + expect(result.nodeValues.get('B')).toBe(0.5) + }) + + it('ignores edges whose endpoint is not visible', async () => { + const cache = makeCache(['A', 'B'], [['A', 'B'], ['A', 'ghost']]) + const result = await calculateDegreeCentrality(cache) + + expect(result.nodeValues.get('A')).toBe(1.0) + expect(result.nodeValues.has('ghost')).toBe(false) + }) + + it('reports real graph density (2m / n(n-1))', async () => { + // Star K1,4: density = 2*4 / (5*4) = 0.4 + const star = makeCache( + ['center', 'A', 'B', 'C', 'D'], + [['center', 'A'], ['center', 'B'], ['center', 'C'], ['center', 'D']] + ) + const starResult = await calculateDegreeCentrality(star) + expect(starResult.graphLevelMetrics['Graph Density']).toBe(0.4) + + // Path A-B-C: density = 2*2 / (3*2) = 0.66667 + const path = makeCache(['A', 'B', 'C'], [['A', 'B'], ['B', 'C']]) + const pathResult = await calculateDegreeCentrality(path) + expect(pathResult.graphLevelMetrics['Graph Density']).toBeCloseTo(2 / 3, PRECISION) + }) + + it('formats score text with degree, centrality, and percent of max', async () => { + const cache = makeCache(['A', 'B', 'C'], [['A', 'B'], ['B', 'C']]) + const result = await calculateDegreeCentrality(cache) + expect(result.scores[0].text).toBe('Degree 2 | Centrality 1.00000 (100 %)') + }) }) // -------------------------------------------------------------------------- @@ -189,6 +247,36 @@ describe('Betweenness Centrality', () => { expect(result.nodeValues.get('A')).toBe(0) expect(result.nodeValues.get('E')).toBe(0) }) + + it('star center has exactly 1.0 normalized betweenness', async () => { + // K1,3: center lies on all 3 leaf pairs; normalization (n-1)(n-2)/2 = 3 + const cache = makeCache( + ['center', 'A', 'B', 'C'], + [['center', 'A'], ['center', 'B'], ['center', 'C']] + ) + const result = await calculateBetweennessCentrality(cache) + expect(result.nodeValues.get('center')).toBe(1.0) + }) + + it('computes exact normalized values on a 5-path', async () => { + // A-B-C-D-E: B(B)=3 pairs, B(C)=4 pairs, normalization (4*3)/2 = 6 + const cache = makeCache( + ['A', 'B', 'C', 'D', 'E'], + [['A', 'B'], ['B', 'C'], ['C', 'D'], ['D', 'E']] + ) + const result = await calculateBetweennessCentrality(cache) + expect(result.nodeValues.get('B')).toBeCloseTo(3 / 6, PRECISION) + expect(result.nodeValues.get('C')).toBeCloseTo(4 / 6, PRECISION) + }) + + it('returns finite zeros for two-node graphs (no NaN)', async () => { + // Previous hand-rolled code divided by ((n-1)(n-2))/2 = 0 → NaN here. + const cache = makeCache(['A', 'B'], [['A', 'B']]) + const result = await calculateBetweennessCentrality(cache) + expect(result.nodeValues.get('A')).toBe(0) + expect(result.nodeValues.get('B')).toBe(0) + expect(result.graphLevelMetrics['Centralization']).toBe(0) + }) }) // -------------------------------------------------------------------------- @@ -252,6 +340,50 @@ describe('Closeness Centrality', () => { const maxIdx = scores.indexOf(Math.max(...scores)) expect(maxIdx).toBe(2) }) + + it('computes exact Wasserman-Faust values on a 3-path', async () => { + // A-B-C: B reaches 2 nodes at total distance 2 → 2²/(2·2) = 1.0 + // A reaches 2 nodes at total distance 3 → 2²/(2·3) = 2/3 + const cache = makeCache(['A', 'B', 'C'], [['A', 'B'], ['B', 'C']]) + const result = await calculateClosenessCentrality(cache) + expect(result.nodeValues.get('B')).toBeCloseTo(1.0, PRECISION) + expect(result.nodeValues.get('A')).toBeCloseTo(2 / 3, PRECISION) + expect(result.nodeValues.get('C')).toBeCloseTo(2 / 3, PRECISION) + }) + + it('applies the reachable-fraction correction on disconnected graphs', async () => { + // A-B plus isolated C (n=3): A reaches 1 node at distance 1 + // → WF closeness = 1²/((3-1)·1) = 0.5 + const cache = makeCache(['A', 'B', 'C'], [['A', 'B']]) + const result = await calculateClosenessCentrality(cache) + expect(result.nodeValues.get('A')).toBeCloseTo(0.5, PRECISION) + expect(result.nodeValues.get('B')).toBeCloseTo(0.5, PRECISION) + expect(result.nodeValues.get('C')).toBe(0) + }) + + it('reports graph diameter for connected graphs', async () => { + // Path A..E: diameter 4 + const path = makeCache( + ['A', 'B', 'C', 'D', 'E'], + [['A', 'B'], ['B', 'C'], ['C', 'D'], ['D', 'E']] + ) + const pathResult = await calculateClosenessCentrality(path) + expect(pathResult.graphLevelMetrics['Graph Diameter']).toBe(4) + + // K4: diameter 1 + const k4 = makeCache( + ['A', 'B', 'C', 'D'], + [['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']] + ) + const k4Result = await calculateClosenessCentrality(k4) + expect(k4Result.graphLevelMetrics['Graph Diameter']).toBe(1) + }) + + it('reports infinite diameter for disconnected graphs', async () => { + const cache = makeCache(['A', 'B', 'C'], [['A', 'B']]) + const result = await calculateClosenessCentrality(cache) + expect(result.graphLevelMetrics['Graph Diameter']).toBe('∞ (disconnected)') + }) }) // -------------------------------------------------------------------------- @@ -313,6 +445,42 @@ describe('Eigenvector Centrality', () => { expect(result.graphLevelMetrics).toHaveProperty('Variance Eigenvector Centrality') expect(result.graphLevelMetrics).toHaveProperty('Centralization') }) + + it('converges to the exact principal eigenvector on a star (bipartite) graph', async () => { + // K1,4 principal eigenvector (L2-normalized): center 1/√2, leaves 1/(2√2). + // The old plain power iteration oscillated on bipartite graphs and + // silently returned a non-converged iterate after 100 iterations. + const cache = makeCache( + ['center', 'A', 'B', 'C', 'D'], + [['center', 'A'], ['center', 'B'], ['center', 'C'], ['center', 'D']] + ) + const result = await calculateEigenvectorCentrality(cache) + expect(result.nodeValues.get('center')).toBeCloseTo(Math.SQRT1_2, 4) + expect(result.nodeValues.get('A')).toBeCloseTo(1 / (2 * Math.SQRT2), 4) + }) + + it('surfaces a clear error when the power iteration fails to converge', async () => { + vi.resetModules() + vi.doMock('../src/lib/graphology.bundle.mjs', async (importOriginal) => { + const actual = await importOriginal() + return { + ...actual, + eigenvectorCentrality: () => { + throw new Error('graphology-metrics/centrality/eigenvector: failed to converge.') + }, + } + }) + + try { + const mocked = await import('../src/managers/metrics.js') + const cache = makeCache(['A', 'B'], [['A', 'B']]) + await expect(mocked.calculateEigenvectorCentrality(cache)) + .rejects.toThrow(/did not converge/) + } finally { + vi.doUnmock('../src/lib/graphology.bundle.mjs') + vi.resetModules() + } + }) }) // -------------------------------------------------------------------------- @@ -364,14 +532,6 @@ describe('PageRank', () => { expect(sum).toBeCloseTo(1.0, 2) }) - it('handles single isolated node', async () => { - const cache = makeCache(['A'], []) - const result = await calculatePageRank(cache) - - // Single node gets all the probability mass - expect(result.nodeValues.get('A')).toBeCloseTo(1.0, 4) - }) - it('returns correct graph-level metrics', async () => { const cache = makeCache( ['A', 'B', 'C'], @@ -395,6 +555,85 @@ describe('PageRank', () => { expect(result.nodeValues.get('A')).toBeCloseTo(result.nodeValues.get('C'), PRECISION) }) + + it('matches the reference value for a star graph hub', async () => { + // K1,4 with d=0.85 converges to hub ≈ 0.47568 (NetworkX reference) + const cache = makeCache( + ['center', 'A', 'B', 'C', 'D'], + [['center', 'A'], ['center', 'B'], ['center', 'C'], ['center', 'D']] + ) + const result = await calculatePageRank(cache) + expect(result.nodeValues.get('center')).toBeCloseTo(0.47568, 4) + }) + + it('reports degree statistics from the visible multigraph', async () => { + const cache = makeCache(['A', 'B', 'C'], [['A', 'B'], ['A', 'B'], ['B', 'C']]) + const result = await calculatePageRank(cache) + const glm = result.graphLevelMetrics + + expect(glm['Maximum Degree']).toBe(3) + expect(glm['Minimum Degree']).toBe(1) + expect(glm['Mean Degree']).toBe(2) + }) +}) + +// -------------------------------------------------------------------------- +// Degenerate visible graphs (n <= 1 guard, all-zero percentage guard) +// -------------------------------------------------------------------------- + +const ALL_METRICS = [ + ['degree', calculateDegreeCentrality], + ['betweenness', calculateBetweennessCentrality], + ['closeness', calculateClosenessCentrality], + ['eigenvector', calculateEigenvectorCentrality], + ['pagerank', calculatePageRank], +] + +describe('Single visible node (n <= 1 guard)', () => { + it.each(ALL_METRICS)('%s returns empty results for a single visible node', async (_name, calc) => { + const result = await calc(makeCache(['A'], [])) + expect(result.scores).toEqual([]) + expect(result.graphLevelMetrics).toEqual({}) + }) +}) + +describe('Isolated nodes (n >= 2, no visible edges)', () => { + it('degree renders "(0 %)" instead of NaN when all scores are zero', async () => { + const result = await calculateDegreeCentrality(makeCache(['A', 'B', 'C'], [])) + expect(result.scores).toHaveLength(3) + for (const s of result.scores) { + expect(s.text).toContain('(0 %)') + expect(s.text).not.toContain('NaN') + } + }) + + it('betweenness renders "(0%)" instead of NaN when all scores are zero', async () => { + const result = await calculateBetweennessCentrality(makeCache(['A', 'B', 'C'], [])) + expect(result.scores).toHaveLength(3) + for (const s of result.scores) { + expect(s.text).toContain('(0%)') + expect(s.text).not.toContain('NaN') + } + }) + + it('closeness renders "(0%)" instead of NaN when all scores are zero', async () => { + const result = await calculateClosenessCentrality(makeCache(['A', 'B', 'C'], [])) + expect(result.scores).toHaveLength(3) + for (const s of result.scores) { + expect(s.text).toContain('(0%)') + expect(s.text).not.toContain('NaN') + } + }) + + it.each(ALL_METRICS)('%s renders no NaN in score texts on edgeless graphs', async (_name, calc) => { + // eigenvector/pagerank distribute uniform non-zero mass here, so only + // the NaN absence is universal. + const result = await calc(makeCache(['A', 'B', 'C'], [])) + expect(result.scores).toHaveLength(3) + for (const s of result.scores) { + expect(s.text).not.toContain('NaN') + } + }) }) // -------------------------------------------------------------------------- From c75bcb6674945e319efbb111e3acad0924b0a9cd Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 08:01:01 +0200 Subject: [PATCH 15/69] feat(bubbles): detect Louvain communities into manual bubble groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add graphology-communities-louvain@2.0.2 to the node-safe vendor bundle, plus modularity from graphology-metrics - new node-safe src/graph/communities.js: detectCommunities builds the visible subgraph, runs seeded louvain.detailed (mulberry32, fixed seed → reproducible), buckets communities largest-first and maps the top 4 onto the bubble group keys; null guard when no visible edges - extract buildVisibleGraph from metrics.js into shared node-safe src/graph/visible_graph.js (pure move, reused by metrics + communities) - GraphBubbleSetManager.detectCommunities replaces the current layout's four ${group}ManualMembers sets and reruns the existing manual-group choreography; result toast reports community count + modularity - 🧩 button in the selected-nodes row (matches neighboring inline-onclick idiom) - 8 new node-safe tests in tests/communities.test.js (854 total green); perf gates green --- package-lock.json | 16 +++ package.json | 1 + src/graph/bubble_sets.js | 36 ++++++ src/graph/communities.js | 61 +++++++++ src/graph/visible_graph.js | 27 ++++ src/graph_lens_lite.html | 2 + src/lib/graphology.bundle.mjs | 18 +-- src/managers/metrics.js | 23 +--- src/package/vendor_entry_graphology.mjs | 3 + src/package/vendor_libs.js | 2 +- tests/communities.test.js | 164 ++++++++++++++++++++++++ 11 files changed, 321 insertions(+), 32 deletions(-) create mode 100644 src/graph/communities.js create mode 100644 src/graph/visible_graph.js create mode 100644 tests/communities.test.js diff --git a/package-lock.json b/package-lock.json index 6189ae2..ee0df1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "bubblesets-js": "^3.0.1", "dompurify": "^3.4.1", "graphology": "^0.26.0", + "graphology-communities-louvain": "^2.0.2", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", "graphology-metrics": "^2.4.0", @@ -5336,6 +5337,21 @@ "graphology-types": ">=0.24.0" } }, + "node_modules/graphology-communities-louvain": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/graphology-communities-louvain/-/graphology-communities-louvain-2.0.2.tgz", + "integrity": "sha512-zt+2hHVPYxjEquyecxWXoUoIuN/UvYzsvI7boDdMNz0rRvpESQ7+e+Ejv6wK7AThycbZXuQ6DkG8NPMCq6XwoA==", + "license": "MIT", + "dependencies": { + "graphology-indices": "^0.17.0", + "graphology-utils": "^2.4.4", + "mnemonist": "^0.39.0", + "pandemonium": "^2.4.1" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, "node_modules/graphology-indices": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz", diff --git a/package.json b/package.json index 459e71f..95a1335 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "bubblesets-js": "^3.0.1", "dompurify": "^3.4.1", "graphology": "^0.26.0", + "graphology-communities-louvain": "^2.0.2", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", "graphology-metrics": "^2.4.0", diff --git a/src/graph/bubble_sets.js b/src/graph/bubble_sets.js index 9a9e53d..6ea5d4c 100644 --- a/src/graph/bubble_sets.js +++ b/src/graph/bubble_sets.js @@ -1,4 +1,5 @@ import {StaticUtilities} from "../utilities/static.js"; +import {detectCommunities as computeCommunityAssignments} from "./communities.js"; class GraphBubbleSetManager { constructor(cache) { @@ -323,6 +324,41 @@ class GraphBubbleSetManager { await this.redrawBubbleSets(); } + async detectCommunities() { + const groups = [...this.traverseBubbleSets()]; + const result = computeCommunityAssignments(this.cache, groups); + + if (!result) { + this.cache.ui.warning("Community detection needs at least one visible edge"); + return; + } + + // Replace the manual members of all groups for the current layout with + // the detected communities (largest community → first group). + const currentLayout = this.cache.data.layouts[this.cache.data.selectedLayout]; + for (const group of groups) { + currentLayout[`${group}ManualMembers`] = result.assignments.get(group) ?? new Set(); + } + + // Same post-change choreography as toggleSelectedNodesInManualGroup + this.updateManualGroupButtonState(); + this.updateManualGroupStatus(); + this.refreshBubbleStyleElements(); + + this.cache.bubbleSetChanged = true; + await this.updateBubbleSetIfChanged(); + await this.cache.graph.draw(); + await this.redrawBubbleSets(); + + const assignedText = result.communityCount <= groups.length + ? `all ${result.communityCount}` + : `largest ${groups.length}`; + this.cache.ui.info( + `Detected ${result.communityCount} communities (modularity ${result.modularity.toFixed(2)}); ` + + `assigned ${assignedText} to bubble groups` + ); + } + updateManualGroupButtonState() { const button = document.getElementById('manualBubbleGroupButton'); if (!button) return; diff --git a/src/graph/communities.js b/src/graph/communities.js new file mode 100644 index 0000000..d6481b3 --- /dev/null +++ b/src/graph/communities.js @@ -0,0 +1,61 @@ +// Node-safe (no DOM): Louvain community detection over the visible subgraph. +// The pure algorithm lives here so it can be unit-tested; the DOM-bound +// application path (manual bubble-group members) lives in bubble_sets.js. +import {louvain} from "../lib/graphology.bundle.mjs"; +import {buildVisibleGraph} from "./visible_graph.js"; + +// Fixed seed: Louvain is non-deterministic by default (random node visit +// order), so a seeded PRNG keeps results reproducible and testable. +const LOUVAIN_RNG_SEED = 42; + +/** Mulberry32 — tiny seeded PRNG returning floats in [0, 1). */ +function mulberry32(seed) { + let state = seed >>> 0; + return function () { + state = (state + 0x6D2B79F5) >>> 0; + let t = state; + t = Math.imul(t ^ (t >>> 15), t | 1); + t ^= t + Math.imul(t ^ (t >>> 7), t | 61); + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; +} + +/** + * Runs Louvain community detection on the visible subgraph and maps the + * largest communities onto the given bubble groups (largest community → + * first group). Communities beyond the available groups stay unassigned. + * + * @param {{nodeIDsToBeShown: Set, edgeIDsToBeShown: Set, edgeRef: Map}} cache + * @param {string[]} groups bubble-group keys in assignment order + * @returns {{assignments: Map>, communityCount: number, modularity: number} | null} + * null when the visible graph has no edges (Louvain needs at least one). + */ +function detectCommunities(cache, groups) { + const graph = buildVisibleGraph(cache); + if (graph.size === 0) return null; + + const result = louvain.detailed(graph, { + rng: mulberry32(LOUVAIN_RNG_SEED), + getEdgeWeight: null, + }); + + // Group node ids by community index, preserving the community index for a + // deterministic tie-break when sizes are equal. + const byCommunity = new Map(); + for (const [node, community] of Object.entries(result.communities)) { + if (!byCommunity.has(community)) byCommunity.set(community, new Set()); + byCommunity.get(community).add(node); + } + + const ordered = [...byCommunity.entries()] + .sort((a, b) => (b[1].size - a[1].size) || (a[0] - b[0])) + .map(([, members]) => members); + + const assignments = new Map( + groups.map((group, i) => [group, ordered[i] ?? new Set()]) + ); + + return {assignments, communityCount: result.count, modularity: result.modularity}; +} + +export {detectCommunities, LOUVAIN_RNG_SEED}; diff --git a/src/graph/visible_graph.js b/src/graph/visible_graph.js new file mode 100644 index 0000000..1070e92 --- /dev/null +++ b/src/graph/visible_graph.js @@ -0,0 +1,27 @@ +// Node-safe (no DOM): shared by managers/metrics.js (centrality calculators) +// and graph/communities.js (Louvain community detection). +import {Graph} from "../lib/graphology.bundle.mjs"; + +/** + * Builds a temporary undirected multigraph from the currently visible + * subgraph so graphology algorithms can run on it. Multi because every + * visible parallel edge counts toward degree, matching the previous + * behaviour. + * @param {{nodeIDsToBeShown: Set, edgeIDsToBeShown: Set, edgeRef: Map}} cache + * @returns {Graph} + */ +function buildVisibleGraph(cache) { + const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; + const graph = new Graph({type: 'undirected', multi: true}); + + for (const id of nodes) graph.addNode(id); + for (const edgeId of edges) { + const {source, target} = edgeRef.get(edgeId) ?? {}; + if (graph.hasNode(source) && graph.hasNode(target)) { + graph.addEdgeWithKey(edgeId, source, target); + } + } + return graph; +} + +export {buildVisibleGraph}; diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index d2e5263..63be635 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -137,6 +137,8 @@

    Shown: +
    Selected edges:
    +
    diff --git a/src/lib/graphology.bundle.mjs b/src/lib/graphology.bundle.mjs index 9c1535c..1124fba 100644 --- a/src/lib/graphology.bundle.mjs +++ b/src/lib/graphology.bundle.mjs @@ -1,12 +1,12 @@ -var yh=Object.create;var wn=Object.defineProperty;var wh=Object.getOwnPropertyDescriptor;var mh=Object.getOwnPropertyNames;var vh=Object.getPrototypeOf,bh=Object.prototype.hasOwnProperty;var ps=e=>{throw TypeError(e)};var Eh=(e,t,r)=>t in e?wn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var dt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),di=(e,t)=>{for(var r in t)wn(e,r,{get:t[r],enumerable:!0})},xh=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of mh(t))!bh.call(e,i)&&i!==r&&wn(e,i,{get:()=>t[i],enumerable:!(n=wh(t,i))||n.enumerable});return e};var Se=(e,t,r)=>(r=e!=null?yh(vh(e)):{},xh(t||!e||!e.__esModule?wn(r,"default",{value:e,enumerable:!0}):r,e));var ys=(e,t,r)=>Eh(e,typeof t!="symbol"?t+"":t,r),gi=(e,t,r)=>t.has(e)||ps("Cannot "+r);var Ge=(e,t,r)=>(gi(e,t,"read from private field"),r?r.call(e):t.get(e)),pi=(e,t,r)=>t.has(e)?ps("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),mn=(e,t,r,n)=>(gi(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),yi=(e,t,r)=>(gi(e,t,"access private method"),r);var ks=dt((pg,wi)=>{"use strict";var Cr=typeof Reflect=="object"?Reflect:null,ws=Cr&&typeof Cr.apply=="function"?Cr.apply:function(t,r,n){return Function.prototype.apply.call(t,r,n)},vn;Cr&&typeof Cr.ownKeys=="function"?vn=Cr.ownKeys:Object.getOwnPropertySymbols?vn=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:vn=function(t){return Object.getOwnPropertyNames(t)};function Sh(e){console&&console.warn&&console.warn(e)}var vs=Number.isNaN||function(t){return t!==t};function Rt(){Rt.init.call(this)}wi.exports=Rt;wi.exports.once=kh;Rt.EventEmitter=Rt;Rt.prototype._events=void 0;Rt.prototype._eventsCount=0;Rt.prototype._maxListeners=void 0;var ms=10;function bn(e){if(typeof e!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}Object.defineProperty(Rt,"defaultMaxListeners",{enumerable:!0,get:function(){return ms},set:function(e){if(typeof e!="number"||e<0||vs(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");ms=e}});Rt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};Rt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||vs(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function bs(e){return e._maxListeners===void 0?Rt.defaultMaxListeners:e._maxListeners}Rt.prototype.getMaxListeners=function(){return bs(this)};Rt.prototype.emit=function(t){for(var r=[],n=1;n0&&(a=r[0]),a instanceof Error)throw a;var l=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw l.context=a,l}var g=o[t];if(g===void 0)return!1;if(typeof g=="function")ws(g,this,r);else for(var f=g.length,p=Ds(g,f),n=0;n0&&a.length>i&&!a.warned){a.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=e,l.type=t,l.count=a.length,Sh(l)}return e}Rt.prototype.addListener=function(t,r){return Es(this,t,r,!1)};Rt.prototype.on=Rt.prototype.addListener;Rt.prototype.prependListener=function(t,r){return Es(this,t,r,!0)};function Ah(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function xs(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},i=Ah.bind(n);return i.listener=r,n.wrapFn=i,i}Rt.prototype.once=function(t,r){return bn(r),this.on(t,xs(this,t,r)),this};Rt.prototype.prependOnceListener=function(t,r){return bn(r),this.prependListener(t,xs(this,t,r)),this};Rt.prototype.removeListener=function(t,r){var n,i,o,a,l;if(bn(r),i=this._events,i===void 0)return this;if(n=i[t],n===void 0)return this;if(n===r||n.listener===r)--this._eventsCount===0?this._events=Object.create(null):(delete i[t],i.removeListener&&this.emit("removeListener",t,n.listener||r));else if(typeof n!="function"){for(o=-1,a=n.length-1;a>=0;a--)if(n[a]===r||n[a].listener===r){l=n[a].listener,o=a;break}if(o<0)return this;o===0?n.shift():Dh(n,o),n.length===1&&(i[t]=n[0]),i.removeListener!==void 0&&this.emit("removeListener",t,l||r)}return this};Rt.prototype.off=Rt.prototype.removeListener;Rt.prototype.removeAllListeners=function(t){var r,n,i;if(n=this._events,n===void 0)return this;if(n.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):n[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete n[t]),this;if(arguments.length===0){var o=Object.keys(n),a;for(i=0;i=0;i--)this.removeListener(t,r[i]);return this};function Ss(e,t,r){var n=e._events;if(n===void 0)return[];var i=n[t];return i===void 0?[]:typeof i=="function"?r?[i.listener||i]:[i]:r?Ih(i):Ds(i,i.length)}Rt.prototype.listeners=function(t){return Ss(this,t,!0)};Rt.prototype.rawListeners=function(t){return Ss(this,t,!1)};Rt.listenerCount=function(e,t){return typeof e.listenerCount=="function"?e.listenerCount(t):As.call(e,t)};Rt.prototype.listenerCount=As;function As(e){var t=this._events;if(t!==void 0){var r=t[e];if(typeof r=="function")return 1;if(r!==void 0)return r.length}return 0}Rt.prototype.eventNames=function(){return this._eventsCount>0?vn(this._events):[]};function Ds(e,t){for(var r=new Array(t),n=0;n{function Mc(e){return!e||typeof e!="object"||typeof e=="function"||Array.isArray(e)||e instanceof Set||e instanceof Map||e instanceof RegExp||e instanceof Date}function Ws(e,t){e=e||{};var r={};for(var n in t){var i=e[n],o=t[n];if(!Mc(o)){r[n]=Ws(i,o);continue}i===void 0?r[n]=o:r[n]=i}return r}Fs.exports=Ws});var Qt=dt((mg,qs)=>{qs.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var Ks=dt((vg,Vs)=>{function Us(e){return function(t,r){return t+Math.floor(e()*(r-t+1))}}var Bs=Us(Math.random);Bs.createRandom=Us;Vs.exports=Bs});var Js=dt((bg,Qs)=>{var Oc=Ks().createRandom;function Ys(e){var t=Oc(e);return function(r){for(var n=r.length,i=n-1,o=-1;++o{var Gc=_e(),$c=Qt(),zc=Js(),Nc={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function ve(e,t,r,n,i){this.wrappedCircle=i||null,this.children={},this.countChildren=0,this.id=e||null,this.next=null,this.previous=null,this.x=t||null,this.y=r||null,i?this.r=1010101:this.r=n||999}ve.prototype.hasChildren=function(){return this.countChildren>0};ve.prototype.addChild=function(e,t){this.children[e]=t,++this.countChildren};ve.prototype.getChild=function(e){if(!this.children.hasOwnProperty(e)){var t=new ve;this.children[e]=t,++this.countChildren}return this.children[e]};ve.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var e=this;for(var t in e.children){var r=e.children[t];r.x+=e.x,r.y+=e.y,r.applyPositionToChildren()}}};function eo(e,t,r){for(var n in t.children){var i=t.children[n];i.hasChildren()?eo(e,i,r):r[i.id]={x:i.x,y:i.y}}}function jn(e,t){var r=e.r-t.r,n=t.x-e.x,i=t.y-e.y;return r<0||r*r0&&r*r>n*n+i*i}function Si(e,t){for(var r=0;rg?(i=(f+g-o)/(2*f),l=Math.sqrt(Math.max(0,g/f-i*i)),r.x=e.x-i*n-l*a,r.y=e.y-i*a+l*n):(i=(f+o-g)/(2*f),l=Math.sqrt(Math.max(0,o/f-i*i)),r.x=t.x+i*n-l*a,r.y=t.y+i*a+l*n)):(r.x=t.x+r.r,r.y=t.y)}function to(e,t){var r=e.r+t.r-1e-6,n=t.x-e.x,i=t.y-e.y;return r>0&&r*r>n*n+i*i}function Uc(e,t){var r=e.length;if(r===0)return 0;var n,i,o,a,l,g,f,p,y,w;if(n=e[0],n.x=0,n.y=0,r<=1)return n.r;if(i=e[1],n.x=-i.r,i.x=n.r,i.y=0,r<=2)return n.r+i.r;o=e[2],Hs(i,n,o),n=new ve(null,null,null,null,n),i=new ve(null,null,null,null,i),o=new ve(null,null,null,null,o),n.next=o.previous=i,i.next=n.previous=o,o.next=i.previous=n;t:for(g=3;g{var Vc=_e(),Kc=Qt(),Yc={dimensions:["x","y"],center:.5,scale:1};function ho(e,t,r){if(!Kc(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");r=Vc(r,Yc);var n=r.dimensions;if(!Array.isArray(n)||n.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var i=r.center,o=r.scale,a=Math.PI*2,l=(i-.5)*o,g=t.order,f=n[0],p=n[1];function y(A,I){return I[f]=o*Math.cos(A*a/g)+l,I[p]=o*Math.sin(A*a/g)+l,I}var w=0;if(!e){var S={};return t.forEachNode(function(A){S[A]=y(w++,{})}),S}t.updateEachNodeAttributes(function(A,I){return y(w++,I),I},{attributes:n})}var co=ho.bind(null,!1);co.assign=ho.bind(null,!0);lo.exports=co});var wo=dt((Sg,yo)=>{var Xc=_e(),Qc=Qt(),Jc={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function go(e,t,r){if(!Qc(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");r=Xc(r,Jc);var n=r.dimensions;if(!Array.isArray(n)||n.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var i=n.length,o=r.center,a=r.rng,l=r.scale,g=(o-.5)*l;function f(y){for(var w=0;w{var Zc=_e(),Hc=Qt(),tl=Math.PI/180,el={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function mo(e,t,r,n){if(!Hc(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");n=Zc(n,el),n.degrees&&(r*=tl);var i=n.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return e?void 0:{};var o=i[0],a=i[1],l=0,g=0;if(!n.centeredOnZero){var f=1/0,p=-1/0,y=1/0,w=-1/0;t.forEachNode(function($,j){var M=j[o],W=j[a];Mp&&(p=M),Ww&&(w=W)}),l=(f+p)/2,g=(y+w)/2}var S=Math.cos(r),A=Math.sin(r);function I($){var j=$[o],M=$[a];return $[o]=l+(j-l)*S-(M-g)*A,$[a]=g+(j-l)*A+(M-g)*S,$}if(!e){var L={};return t.forEachNode(function($,j){var M={};M[o]=j[o],M[a]=j[a],L[$]=I(M)}),L}t.updateEachNodeAttributes(function($,j){return I(j),j},{attributes:i})}var vo=mo.bind(null,!1);vo.assign=mo.bind(null,!0);bo.exports=vo});var xo=dt(Jr=>{Jr.circlepack=uo();Jr.circular=fo();Jr.random=wo();Jr.rotation=Eo()});var Mr=dt(Cn=>{function rl(e){return typeof e!="number"||isNaN(e)?1:e}function nl(e,t){var r={},n=function(a){return typeof a>"u"?t:a};typeof t=="function"&&(n=t);var i=function(a){return n(a[e])},o=function(){return n(void 0)};return typeof e=="string"?(r.fromAttributes=i,r.fromGraph=function(a,l){return i(a.getNodeAttributes(l))},r.fromEntry=function(a,l){return i(l)}):typeof e=="function"?(r.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},r.fromGraph=function(a,l){return n(e(l,a.getNodeAttributes(l)))},r.fromEntry=function(a,l){return n(e(a,l))}):(r.fromAttributes=o,r.fromGraph=o,r.fromEntry=o),r}function So(e,t){var r={},n=function(a){return typeof a>"u"?t:a};typeof t=="function"&&(n=t);var i=function(a){return n(a[e])},o=function(){return n(void 0)};return typeof e=="string"?(r.fromAttributes=i,r.fromGraph=function(a,l){return i(a.getEdgeAttributes(l))},r.fromEntry=function(a,l){return i(l)},r.fromPartialEntry=r.fromEntry,r.fromMinimalEntry=r.fromEntry):typeof e=="function"?(r.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},r.fromGraph=function(a,l){var g=a.extremities(l);return n(e(l,a.getEdgeAttributes(l),g[0],g[1],a.getNodeAttributes(g[0]),a.getNodeAttributes(g[1]),a.isUndirected(l)))},r.fromEntry=function(a,l,g,f,p,y,w){return n(e(a,l,g,f,p,y,w))},r.fromPartialEntry=function(a,l,g,f){return n(e(a,l,g,f))},r.fromMinimalEntry=function(a,l){return n(e(a,l))}):(r.fromAttributes=o,r.fromGraph=o,r.fromEntry=o,r.fromMinimalEntry=o),r}Cn.createNodeValueGetter=nl;Cn.createEdgeValueGetter=So;Cn.createEdgeWeightGetter=function(e){return So(e,rl)}});var jo=dt((kg,ko)=>{var Jt=0,Pt=1,St=2,At=3,He=4,tr=5,It=6,Ao=7,_n=8,Do=9,il=0,sl=1,ol=2,ie=0,Re=1,ge=2,wr=3,ir=4,Ft=5,be=6,Ue=7,Be=8,Io=3,ze=10,al=3,le=9,Ai=10;ko.exports=function(t,r,n){var i,o,a,l,g,f,p,y,w,S,A=r.length,I=n.length,L=t.adjustSizes,$=t.barnesHutTheta*t.barnesHutTheta,j,M,W,N,K,G,P,C=[];for(a=0;aO?(ct-=(gt-O)/2,Dt=ct+gt):(et-=(O-gt)/2,lt=et+O),C[0+ie]=-1,C[0+Re]=(et+lt)/2,C[0+ge]=(ct+Dt)/2,C[0+wr]=Math.max(lt-et,Dt-ct),C[0+ir]=-1,C[0+Ft]=-1,C[0+be]=0,C[0+Ue]=0,C[0+Be]=0,i=1,a=0;a=0){r[a+Jt]=0)if(G=Math.pow(r[a+Jt]-C[o+Ue],2)+Math.pow(r[a+Pt]-C[o+Be],2),S=C[o+wr],4*S*S/G<$){if(W=r[a+Jt]-C[o+Ue],N=r[a+Pt]-C[o+Be],L===!0?G>0?(P=M*r[a+It]*C[o+be]/G,r[a+St]+=W*P,r[a+At]+=N*P):G<0&&(P=-M*r[a+It]*C[o+be]/Math.sqrt(G),r[a+St]+=W*P,r[a+At]+=N*P):G>0&&(P=M*r[a+It]*C[o+be]/G,r[a+St]+=W*P,r[a+At]+=N*P),o=C[o+ir],o<0)break;continue}else{o=C[o+Ft];continue}else{if(f=C[o+ie],f>=0&&f!==a&&(W=r[a+Jt]-r[f+Jt],N=r[a+Pt]-r[f+Pt],G=W*W+N*N,L===!0?G>0?(P=M*r[a+It]*r[f+It]/G,r[a+St]+=W*P,r[a+At]+=N*P):G<0&&(P=-M*r[a+It]*r[f+It]/Math.sqrt(G),r[a+St]+=W*P,r[a+At]+=N*P):G>0&&(P=M*r[a+It]*r[f+It]/G,r[a+St]+=W*P,r[a+At]+=N*P)),o=C[o+ir],o<0)break;continue}else for(M=t.scalingRatio,l=0;l0?(P=M*r[l+It]*r[g+It]/G/G,r[l+St]+=W*P,r[l+At]+=N*P,r[g+St]-=W*P,r[g+At]-=N*P):G<0&&(P=100*M*r[l+It]*r[g+It],r[l+St]+=W*P,r[l+At]+=N*P,r[g+St]-=W*P,r[g+At]-=N*P)):(G=Math.sqrt(W*W+N*N),G>0&&(P=M*r[l+It]*r[g+It]/G/G,r[l+St]+=W*P,r[l+At]+=N*P,r[g+St]-=W*P,r[g+At]-=N*P));for(w=t.gravity/t.scalingRatio,M=t.scalingRatio,a=0;a0&&(P=M*r[a+It]*w):G>0&&(P=M*r[a+It]*w/G),r[a+St]-=W*P,r[a+At]-=N*P;for(M=1*(t.outboundAttractionDistribution?j:1),p=0;p0&&(P=-M*K*Math.log(1+G)/G/r[l+It]):G>0&&(P=-M*K*Math.log(1+G)/G):t.outboundAttractionDistribution?G>0&&(P=-M*K/r[l+It]):G>0&&(P=-M*K)):(G=Math.sqrt(Math.pow(W,2)+Math.pow(N,2)),t.linLogMode?t.outboundAttractionDistribution?G>0&&(P=-M*K*Math.log(1+G)/G/r[l+It]):G>0&&(P=-M*K*Math.log(1+G)/G):t.outboundAttractionDistribution?(G=1,P=-M*K/r[l+It]):(G=1,P=-M*K)),G>0&&(r[l+St]+=W*P,r[l+At]+=N*P,r[g+St]-=W*P,r[g+At]-=N*P);var ye,Te,J,_,bt,Ct;if(L===!0)for(a=0;aAi&&(r[a+St]=r[a+St]*Ai/ye,r[a+At]=r[a+At]*Ai/ye),Te=r[a+It]*Math.sqrt((r[a+He]-r[a+St])*(r[a+He]-r[a+St])+(r[a+tr]-r[a+At])*(r[a+tr]-r[a+At])),J=Math.sqrt((r[a+He]+r[a+St])*(r[a+He]+r[a+St])+(r[a+tr]+r[a+At])*(r[a+tr]+r[a+At]))/2,_=.1*Math.log(1+J)/(1+Math.sqrt(Te)),bt=r[a+Jt]+r[a+St]*(_/t.slowDown),r[a+Jt]=bt,Ct=r[a+Pt]+r[a+At]*(_/t.slowDown),r[a+Pt]=Ct);else for(a=0;a{var Zr=10,Co=3;sr.assign=function(e){e=e||{};var t=Array.prototype.slice.call(arguments).slice(1),r,n,i;for(r=0,i=t.length;r=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in e&&typeof e.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in e&&!(typeof e.gravity=="number"&&e.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in e&&!(typeof e.slowDown=="number"||e.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in e&&typeof e.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in e&&!(typeof e.barnesHutTheta=="number"&&e.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};sr.graphToByteArrays=function(e,t){var r=e.order,n=e.size,i={},o,a=new Float32Array(r*Zr),l=new Float32Array(n*Co);return o=0,e.forEachNode(function(g,f){i[g]=o,a[o]=f.x,a[o+1]=f.y,a[o+2]=0,a[o+3]=0,a[o+4]=0,a[o+5]=0,a[o+6]=1,a[o+7]=1,a[o+8]=f.size||1,a[o+9]=f.fixed?1:0,o+=Zr}),o=0,e.forEachEdge(function(g,f,p,y,w,S,A){var I=i[p],L=i[y],$=t(g,f,p,y,w,S,A);a[I+6]+=$,a[L+6]+=$,l[o]=I,l[o+1]=L,l[o+2]=$,o+=Co}),{nodes:a,edges:l}};sr.assignLayoutChanges=function(e,t,r){var n=0;e.updateEachNodeAttributes(function(i,o){return o.x=t[n],o.y=t[n+1],n+=Zr,r?r(i,o):o})};sr.readGraphPositions=function(e,t){var r=0;e.forEachNode(function(n,i){t[r]=i.x,t[r+1]=i.y,r+=Zr})};sr.collectLayoutChanges=function(e,t,r){for(var n=e.nodes(),i={},o=0,a=0,l=t.length;o{_o.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var To=dt((_g,Lo)=>{var ul=Qt(),hl=Mr().createEdgeWeightGetter,cl=jo(),Hr=Di(),ll=Ii();function Ro(e,t,r){if(!ul(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof r=="number"&&(r={iterations:r});var n=r.iterations;if(typeof n!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(n<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var i=hl("getEdgeWeight"in r?r.getEdgeWeight:"weight").fromEntry,o=typeof r.outputReducer=="function"?r.outputReducer:null,a=Hr.assign({},ll,r.settings),l=Hr.validateSettings(a);if(l)throw new Error("graphology-layout-forceatlas2: "+l.message);var g=Hr.graphToByteArrays(t,i),f;for(f=0;f2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var ki=Ro.bind(null,!1);ki.assign=Ro.bind(null,!0);ki.inferSettings=fl;Lo.exports=ki});var Oo=dt((Rg,Mo)=>{Mo.exports=function(){var t,r,n={};(function(){var o=0,a=1,l=2,g=3,f=4,p=5,y=6,w=7,S=8,A=9,I=0,L=1,$=2,j=0,M=1,W=2,N=3,K=4,G=5,P=6,C=7,et=8,lt=3,ct=10,Dt=3,ft=9,Nt=10;n.exports=function(gt,O,ye){var Te,J,_,bt,Ct,Q,we,Xt,ot,Ur,Ie=O.length,li=ye.length,pr=gt.adjustSizes,fi=gt.barnesHutTheta*gt.barnesHutTheta,xr,_t,Et,xt,ke,it,at,q=[];for(_=0;_Ar?(me-=(Sr-Ar)/2,nr=me+Sr):(oe-=(Ar-Sr)/2,We=oe+Ar),q[0+j]=-1,q[0+M]=(oe+We)/2,q[0+W]=(me+nr)/2,q[0+N]=Math.max(We-oe,nr-me),q[0+K]=-1,q[0+G]=-1,q[0+P]=0,q[0+C]=0,q[0+et]=0,Te=1,_=0;_=0){O[_+o]=0)if(it=Math.pow(O[_+o]-q[J+C],2)+Math.pow(O[_+a]-q[J+et],2),Ur=q[J+N],4*Ur*Ur/it0?(at=_t*O[_+y]*q[J+P]/it,O[_+l]+=Et*at,O[_+g]+=xt*at):it<0&&(at=-_t*O[_+y]*q[J+P]/Math.sqrt(it),O[_+l]+=Et*at,O[_+g]+=xt*at):it>0&&(at=_t*O[_+y]*q[J+P]/it,O[_+l]+=Et*at,O[_+g]+=xt*at),J=q[J+K],J<0)break;continue}else{J=q[J+G];continue}else{if(Q=q[J+j],Q>=0&&Q!==_&&(Et=O[_+o]-O[Q+o],xt=O[_+a]-O[Q+a],it=Et*Et+xt*xt,pr===!0?it>0?(at=_t*O[_+y]*O[Q+y]/it,O[_+l]+=Et*at,O[_+g]+=xt*at):it<0&&(at=-_t*O[_+y]*O[Q+y]/Math.sqrt(it),O[_+l]+=Et*at,O[_+g]+=xt*at):it>0&&(at=_t*O[_+y]*O[Q+y]/it,O[_+l]+=Et*at,O[_+g]+=xt*at)),J=q[J+K],J<0)break;continue}else for(_t=gt.scalingRatio,bt=0;bt0?(at=_t*O[bt+y]*O[Ct+y]/it/it,O[bt+l]+=Et*at,O[bt+g]+=xt*at,O[Ct+l]-=Et*at,O[Ct+g]-=xt*at):it<0&&(at=100*_t*O[bt+y]*O[Ct+y],O[bt+l]+=Et*at,O[bt+g]+=xt*at,O[Ct+l]-=Et*at,O[Ct+g]-=xt*at)):(it=Math.sqrt(Et*Et+xt*xt),it>0&&(at=_t*O[bt+y]*O[Ct+y]/it/it,O[bt+l]+=Et*at,O[bt+g]+=xt*at,O[Ct+l]-=Et*at,O[Ct+g]-=xt*at));for(ot=gt.gravity/gt.scalingRatio,_t=gt.scalingRatio,_=0;_0&&(at=_t*O[_+y]*ot):it>0&&(at=_t*O[_+y]*ot/it),O[_+l]-=Et*at,O[_+g]-=xt*at;for(_t=1*(gt.outboundAttractionDistribution?xr:1),we=0;we0&&(at=-_t*ke*Math.log(1+it)/it/O[bt+y]):it>0&&(at=-_t*ke*Math.log(1+it)/it):gt.outboundAttractionDistribution?it>0&&(at=-_t*ke/O[bt+y]):it>0&&(at=-_t*ke)):(it=Math.sqrt(Math.pow(Et,2)+Math.pow(xt,2)),gt.linLogMode?gt.outboundAttractionDistribution?it>0&&(at=-_t*ke*Math.log(1+it)/it/O[bt+y]):it>0&&(at=-_t*ke*Math.log(1+it)/it):gt.outboundAttractionDistribution?(it=1,at=-_t*ke/O[bt+y]):(it=1,at=-_t*ke)),it>0&&(O[bt+l]+=Et*at,O[bt+g]+=xt*at,O[Ct+l]-=Et*at,O[Ct+g]-=xt*at);var Dr,yr,Ir,Fe,kr,jr;if(pr===!0)for(_=0;_Nt&&(O[_+l]=O[_+l]*Nt/Dr,O[_+g]=O[_+g]*Nt/Dr),yr=O[_+y]*Math.sqrt((O[_+f]-O[_+l])*(O[_+f]-O[_+l])+(O[_+p]-O[_+g])*(O[_+p]-O[_+g])),Ir=Math.sqrt((O[_+f]+O[_+l])*(O[_+f]+O[_+l])+(O[_+p]+O[_+g])*(O[_+p]+O[_+g]))/2,Fe=.1*Math.log(1+Ir)/(1+Math.sqrt(yr)),kr=O[_+o]+O[_+l]*(Fe/gt.slowDown),O[_+o]=kr,jr=O[_+a]+O[_+g]*(Fe/gt.slowDown),O[_+a]=jr);else for(_=0;_{var dl=Oo(),gl=Qt(),pl=Mr().createEdgeWeightGetter,Or=Di(),yl=Ii();function or(e,t){if(t=t||{},!gl(e))throw new Error("graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.");var r=pl("getEdgeWeight"in t?t.getEdgeWeight:"weight").fromEntry,n=Or.assign({},yl,t.settings),i=Or.validateSettings(n);if(i)throw new Error("graphology-layout-forceatlas2/worker: "+i.message);this.worker=null,this.graph=e,this.settings=n,this.getEdgeWeight=r,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer=="function"?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var o=void 0,a=this;this.handleGraphUpdate=function(){a.worker&&a.worker.terminate(),o&&clearTimeout(o),o=setTimeout(function(){o=void 0,a.spawnWorker()},0)},e.on("nodeAdded",this.handleGraphUpdate),e.on("edgeAdded",this.handleGraphUpdate),e.on("nodeDropped",this.handleGraphUpdate),e.on("edgeDropped",this.handleGraphUpdate),this.spawnWorker()}or.prototype.isRunning=function(){return this.running};or.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=Or.createWorker(dl),this.worker.addEventListener("message",this.handleMessage),this.running&&(this.running=!1,this.start())};or.prototype.handleMessage=function(e){if(this.running){var t=new Float32Array(e.data.nodes);Or.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&Or.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}};or.prototype.askForIterations=function(e){var t=this.matrices,r={settings:this.settings,nodes:t.nodes.buffer},n=[t.nodes.buffer];return e&&(r.edges=t.edges.buffer,n.push(t.edges.buffer)),this.worker.postMessage(r,n),this};or.prototype.start=function(){if(this.killed)throw new Error("graphology-layout-forceatlas2/worker.start: layout was killed.");return this.running?this:(this.matrices=Or.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)};or.prototype.stop=function(){return this.running=!1,this};or.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener("nodeAdded",this.handleGraphUpdate),this.graph.removeListener("edgeAdded",this.handleGraphUpdate),this.graph.removeListener("nodeDropped",this.handleGraphUpdate),this.graph.removeListener("edgeDropped",this.handleGraphUpdate)};Go.exports=or});var ja=dt(ti=>{var Sf=Qt();function Wr(e,t,r,n){var i=t+"Centrality";if(!Sf(r))throw new Error("graphology-centrality/"+i+": the given graph is not a valid graphology instance.");if(t!=="degree"&&r.type==="undirected")throw new Error("graphology-centrality/"+i+": cannot compute "+t+" centrality on an undirected graph.");n=n||{};var o=n.nodeCentralityAttribute||i,a=r.order-1,l=r[t].bind(r);if(e){r.updateEachNodeAttributes(function(f,p){return p[o]=l(f)/a,p},{attributes:[o]});return}var g={};return r.forEachNode(function(f){g[f]=l(f)/a}),g}var Da=Wr.bind(null,!1,"degree"),Ia=Wr.bind(null,!1,"inDegree"),ka=Wr.bind(null,!1,"outDegree");Da.assign=Wr.bind(null,!0,"degree");Ia.assign=Wr.bind(null,!0,"inDegree");ka.assign=Wr.bind(null,!0,"outDegree");ti.degreeCentrality=Da;ti.inDegreeCentrality=Ia;ti.outDegreeCentrality=ka});var Ca=dt(Ji=>{Ji.ARRAY_BUFFER_SUPPORT=typeof ArrayBuffer<"u";Ji.SYMBOL_SUPPORT=typeof Symbol<"u"});var ei=dt((ly,Ra)=>{var _a=Ca(),Af=_a.ARRAY_BUFFER_SUPPORT,Df=_a.SYMBOL_SUPPORT;Ra.exports=function(t,r){var n,i,o,a,l;if(!t)throw new Error("obliterator/forEach: invalid iterable.");if(typeof r!="function")throw new Error("obliterator/forEach: expecting a callback.");if(Array.isArray(t)||Af&&ArrayBuffer.isView(t)||typeof t=="string"||t.toString()==="[object Arguments]"){for(o=0,a=t.length;o{var If=Math.pow(2,8)-1,kf=Math.pow(2,16)-1,jf=Math.pow(2,32)-1,Cf=Math.pow(2,7)-1,_f=Math.pow(2,15)-1,Rf=Math.pow(2,31)-1;Ke.getPointerArray=function(e){var t=e-1;if(t<=If)return Uint8Array;if(t<=kf)return Uint16Array;if(t<=jf)return Uint32Array;throw new Error("mnemonist: Pointer Array of size > 4294967295 is not supported.")};Ke.getSignedPointerArray=function(e){var t=e-1;return t<=Cf?Int8Array:t<=_f?Int16Array:t<=Rf?Int32Array:Float64Array};Ke.getNumberType=function(e){return e===(e|0)?Math.sign(e)===-1?e<=127&&e>=-128?Int8Array:e<=32767&&e>=-32768?Int16Array:Int32Array:e<=255?Uint8Array:e<=65535?Uint16Array:Uint32Array:Float64Array};var Lf={Uint8Array:1,Int8Array:2,Uint16Array:3,Int16Array:4,Uint32Array:5,Int32Array:6,Float32Array:7,Float64Array:8};Ke.getMinimalRepresentation=function(e,t){var r=null,n=0,i,o,a,l,g;for(l=0,g=e.length;ln&&(n=i,r=o);return r};Ke.isTypedArray=function(e){return typeof ArrayBuffer<"u"&&ArrayBuffer.isView(e)};Ke.concat=function(){var e=0,t,r,n;for(t=0,n=arguments.length;t{var La=ei(),Ta=lr();function Tf(e){return Array.isArray(e)||Ta.isTypedArray(e)}function Zi(e){if(typeof e.length=="number")return e.length;if(typeof e.size=="number")return e.size}function Mf(e){var t=Zi(e),r=typeof t=="number"?new Array(t):[],n=0;return La(e,function(i){r[n++]=i}),r}function Of(e){var t=Zi(e),r=typeof t=="number"?Ta.getPointerArray(t):Array,n=typeof t=="number"?new Array(t):[],i=typeof t=="number"?new r(t):[],o=0;return La(e,function(a){n[o]=a,i[o]=o++}),[n,i]}un.isArrayLike=Tf;un.guessLength=Zi;un.toArray=Mf;un.toArrayWithIndices=Of});var br=dt((gy,Ma)=>{function Ye(e){if(typeof e!="function")throw new Error("obliterator/iterator: expecting a function!");this.next=e}typeof Symbol<"u"&&(Ye.prototype[Symbol.iterator]=function(){return this});Ye.of=function(){var e=arguments,t=e.length,r=0;return new Ye(function(){return r>=t?{done:!0}:{done:!1,value:e[r++]}})};Ye.empty=function(){var e=new Ye(function(){return{done:!0}});return e};Ye.fromSequence=function(e){var t=0,r=e.length;return new Ye(function(){return t>=r?{done:!0}:{done:!1,value:e[t++]}})};Ye.is=function(e){return e instanceof Ye?!0:typeof e=="object"&&e!==null&&typeof e.next=="function"};Ma.exports=Ye});var ts=dt((py,Ga)=>{var Hi=ri(),Oa=br();function Kt(e,t){if(arguments.length<2)throw new Error("mnemonist/fixed-deque: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-deque: `capacity` should be a positive number.");this.ArrayClass=e,this.capacity=t,this.items=new e(this.capacity),this.clear()}Kt.prototype.clear=function(){this.start=0,this.size=0};Kt.prototype.push=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.push: deque capacity ("+this.capacity+") exceeded!");var t=this.start+this.size;return t>=this.capacity&&(t-=this.capacity),this.items[t]=e,++this.size};Kt.prototype.unshift=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.unshift: deque capacity ("+this.capacity+") exceeded!");var t=this.start-1;return this.start===0&&(t=this.capacity-1),this.items[t]=e,this.start=t,++this.size};Kt.prototype.pop=function(){if(this.size!==0){this.size--;var e=this.start+this.size;return e>=this.capacity&&(e-=this.capacity),this.items[e]}};Kt.prototype.shift=function(){if(this.size!==0){var e=this.start;return this.size--,this.start++,this.start===this.capacity&&(this.start=0),this.items[e]}};Kt.prototype.peekFirst=function(){if(this.size!==0)return this.items[this.start]};Kt.prototype.peekLast=function(){if(this.size!==0){var e=this.start+this.size-1;return e>=this.capacity&&(e-=this.capacity),this.items[e]}};Kt.prototype.get=function(e){if(!(this.size===0||e>=this.capacity))return e=this.start+e,e>=this.capacity&&(e-=this.capacity),this.items[e]};Kt.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=this.capacity,n=this.size,i=this.start,o=0;o=r)return{done:!0};var o=e[n];return n++,i++,n===t&&(n=0),{value:o,done:!1}})};Kt.prototype.entries=function(){var e=this.items,t=this.capacity,r=this.size,n=this.start,i=0;return new Oa(function(){if(i>=r)return{done:!0};var o=e[n];return n++,n===t&&(n=0),{value:[i++,o],done:!1}})};typeof Symbol<"u"&&(Kt.prototype[Symbol.iterator]=Kt.prototype.values);Kt.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,"constructor",{value:Kt,enumerable:!1}),e};typeof Symbol<"u"&&(Kt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Kt.prototype.inspect);Kt.from=function(e,t,r){if(arguments.length<3&&(r=Hi.guessLength(e),typeof r!="number"))throw new Error("mnemonist/fixed-deque.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new Kt(t,r);if(Hi.isArrayLike(e)){var i,o;for(i=0,o=e.length;i{var $a=br(),es=ri();function re(e,t){if(arguments.length<2)throw new Error("mnemonist/fixed-stack: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-stack: `capacity` should be a positive number.");this.capacity=t,this.ArrayClass=e,this.items=new this.ArrayClass(this.capacity),this.clear()}re.prototype.clear=function(){this.size=0};re.prototype.push=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-stack.push: stack capacity ("+this.capacity+") exceeded!");return this.items[this.size++]=e,this.size};re.prototype.pop=function(){if(this.size!==0)return this.items[--this.size]};re.prototype.peek=function(){return this.items[this.size-1]};re.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=0,n=this.items.length;r=t)return{done:!0};var n=e[t-r-1];return r++,{value:n,done:!1}})};re.prototype.entries=function(){var e=this.items,t=this.size,r=0;return new $a(function(){if(r>=t)return{done:!0};var n=e[t-r-1];return{value:[r++,n],done:!1}})};typeof Symbol<"u"&&(re.prototype[Symbol.iterator]=re.prototype.values);re.prototype.toString=function(){return this.toArray().join(",")};re.prototype.toJSON=function(){return this.toArray()};re.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,"constructor",{value:re,enumerable:!1}),e};typeof Symbol<"u"&&(re.prototype[Symbol.for("nodejs.util.inspect.custom")]=re.prototype.inspect);re.from=function(e,t,r){if(arguments.length<3&&(r=es.guessLength(e),typeof r!="number"))throw new Error("mnemonist/fixed-stack.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new re(t,r);if(es.isArrayLike(e)){var i,o;for(i=0,o=e.length;i{var Gf=function(e,t){return et?1:0},$f=function(e,t){return et?-1:0};function zf(e){return function(t,r){return e(r,t)}}function Nf(e){return e===2?function(t,r){return t[0]r[0]?1:t[1]r[1]?1:0}:function(t,r){for(var n=0;nr[n])return 1;n++}return 0}}hn.DEFAULT_COMPARATOR=Gf;hn.DEFAULT_REVERSE_COMPARATOR=$f;hn.reverseComparator=zf;hn.createTupleComparator=Nf});var Ba=dt((my,Ua)=>{var ni=ei(),Wa=Pa(),Xe=ri(),si=Wa.DEFAULT_COMPARATOR,rs=Wa.reverseComparator;function ns(e,t,r,n){for(var i=t[n],o,a;n>r;){if(o=n-1>>1,a=t[o],e(i,a)<0){t[n]=a,n=o;continue}break}t[n]=i}function cn(e,t,r){for(var n=t.length,i=r,o=t[r],a=2*r+1,l;a=0&&(a=l),t[r]=t[a],r=a,a=2*r+1;t[r]=o,ns(e,t,i,r)}function Fa(e,t,r){t.push(r),ns(e,t,0,t.length-1)}function is(e,t){var r=t.pop();if(t.length!==0){var n=t[0];return t[0]=r,cn(e,t,0),n}return r}function Fr(e,t,r){if(t.length===0)throw new Error("mnemonist/heap.replace: cannot pop an empty heap.");var n=t[0];return t[0]=r,cn(e,t,0),n}function qa(e,t,r){var n;return t.length!==0&&e(t[0],r)<0&&(n=t[0],t[0]=r,r=n,cn(e,t,0)),r}function Er(e,t){for(var r=t.length,n=r>>1,i=n;--i>=0;)cn(e,t,i)}function ss(e,t){for(var r=t.length,n=0,i=new Array(r);n=r.length)return r.slice().sort(e);for(g=r.slice(0,t),Er(n,g),i=t,o=r.length;i0&&Fr(n,g,r[i]);return g.sort(e)}var f=Xe.guessLength(r);return f!==null&&f0&&Fr(n,g,p)),i++}),g.length>i&&(g.length=i),g.sort(e)}function Wf(e,t,r){arguments.length===2&&(r=t,t=e,e=si);var n=rs(e),i,o,a,l=-1/0,g;if(t===1){if(Xe.isArrayLike(r)){for(i=0,o=r.length;i0)&&(l=a);return g=new r.constructor(1),g[0]=l,g}return ni(r,function(p){(l===-1/0||e(p,l)>0)&&(l=p)}),[l]}if(Xe.isArrayLike(r)){if(t>=r.length)return r.slice().sort(n);for(g=r.slice(0,t),Er(e,g),i=t,o=r.length;i0&&Fr(e,g,r[i]);return g.sort(n)}var f=Xe.guessLength(r);return f!==null&&f0&&Fr(e,g,p)),i++}),g.length>i&&(g.length=i),g.sort(n)}function jt(e){if(this.clear(),this.comparator=e||si,typeof this.comparator!="function")throw new Error("mnemonist/Heap.constructor: given comparator should be a function.")}jt.prototype.clear=function(){this.items=[],this.size=0};jt.prototype.push=function(e){return Fa(this.comparator,this.items,e),++this.size};jt.prototype.peek=function(){return this.items[0]};jt.prototype.pop=function(){return this.size!==0&&this.size--,is(this.comparator,this.items)};jt.prototype.replace=function(e){return Fr(this.comparator,this.items,e)};jt.prototype.pushpop=function(e){return qa(this.comparator,this.items,e)};jt.prototype.consume=function(){return this.size=0,ss(this.comparator,this.items)};jt.prototype.toArray=function(){return ss(this.comparator,this.items.slice())};jt.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,"constructor",{value:jt,enumerable:!1}),e};typeof Symbol<"u"&&(jt.prototype[Symbol.for("nodejs.util.inspect.custom")]=jt.prototype.inspect);function ii(e){if(this.clear(),this.comparator=e||si,typeof this.comparator!="function")throw new Error("mnemonist/MaxHeap.constructor: given comparator should be a function.");this.comparator=rs(this.comparator)}ii.prototype=jt.prototype;jt.from=function(e,t){var r=new jt(t),n;return Xe.isArrayLike(e)?n=e.slice():n=Xe.toArray(e),Er(r.comparator,n),r.items=n,r.size=n.length,r};ii.from=function(e,t){var r=new ii(t),n;return Xe.isArrayLike(e)?n=e.slice():n=Xe.toArray(e),Er(r.comparator,n),r.items=n,r.size=n.length,r};jt.siftUp=cn;jt.siftDown=ns;jt.push=Fa;jt.pop=is;jt.replace=Fr;jt.pushpop=qa;jt.heapify=Er;jt.consume=ss;jt.nsmallest=Pf;jt.nlargest=Wf;jt.MinHeap=jt;jt.MaxHeap=ii;Ua.exports=jt});var fn=dt(os=>{var oi=lr(),Ff=Mr().createEdgeWeightGetter;function Va(e,t){return e==="outbound"||e==="inbound"?t.directedSize+t.undirectedSize*2:e==="in"||e==="out"||e==="directed"?t.directedSize:t.undirectedSize*2}function er(e,t){t=t||"outbound";var r=e[t+"Neighbors"].bind(e),n=Va(t,e),i=oi.getPointerArray(n),o=oi.getPointerArray(e.order);this.graph=e,this.neighborhood=new o(n),this.starts=new i(e.order+1),this.nodes=e.nodes();var a={},l,g,f,p,y,w,S=0;for(l=0,g=e.order;l{var qf=ts(),Ka=Na(),Uf=Ba(),Ya=lr(),Xa=fn(),Bf=Xa.NeighborhoodIndex,Vf=Xa.WeightedNeighborhoodIndex;as.createUnweightedIndexedBrandes=function(t){var r=new Bf(t),n=r.neighborhood,i=r.starts,o=t.order,a=new Ka(Ya.getPointerArray(o),o),l=new Uint32Array(o),g=new Array(o),f=new Int32Array(o),p=new qf(Uint32Array,o),y=function(w){var S,A,I,L,$,j,M;for(j=0;jt[0]?1:e[0]t[1]?1:e[1]t[2]?1:e[2]t[3]?1:e[3]{var Yf=Qt(),Ja=Qa(),Xf=_e(),Qf=Ja.createUnweightedIndexedBrandes,Jf=Ja.createDijkstraIndexedBrandes,Zf={nodeCentralityAttribute:"betweennessCentrality",getEdgeWeight:"weight",normalized:!0};function Za(e,t,r){if(!Yf(t))throw new Error("graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.");r=Xf(r,Zf);var n=r.nodeCentralityAttribute,i=r.normalized,o=r.getEdgeWeight?Jf(t,r.getEdgeWeight):Qf(t),a=t.order,l,g,f,p,y,w,S,A,I,L,$=new Float64Array(a),j=new Float64Array(a);for(w=0;w{var Hf=br(),td=lr().getPointerArray;function Ae(e){var t=td(e);this.size=0,this.length=e,this.dense=new t(e),this.sparse=new t(e)}Ae.prototype.clear=function(){this.size=0};Ae.prototype.has=function(e){var t=this.sparse[e];return t=this.size||this.dense[t]!==e?!1:(t=this.dense[this.size-1],this.dense[this.sparse[e]]=t,this.sparse[t]=this.sparse[e],this.size--,!0)};Ae.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r,n=0;n{var ed=Qt(),rd=_e(),nd=ts(),id=nu(),sd=fn().NeighborhoodIndex,od={nodeCentralityAttribute:"closenessCentrality",wassermanFaust:!1};function iu(e){this.index=new sd(e,"inbound"),this.queue=new nd(Array,e.order),this.seen=new id(e.order)}iu.prototype.fromNode=function(e){var t=this.index,r=this.queue,n=this.seen;n.clear(),r.clear(),n.add(e),r.push([e,0]);for(var i,o,a,l,g,f,p=0,y=0;r.size!==0;)for(i=r.shift(),o=i[0],a=i[1],a!==0&&(p+=a,y+=1),g=t.starts[o+1],l=t.starts[o];l0&&o>1&&(p=g/f,n&&(p*=g/(o-1))),y[a]=p;return e?i.index.assign(r.nodeCentralityAttribute,y):i.index.collect(y)}var ou=su.bind(null,!1);ou.assign=su.bind(null,!0);au.exports=ou});var fu=dt((Ay,lu)=>{var ad=Qt(),ud=_e(),hd=fn().WeightedNeighborhoodIndex,cd={nodeCentralityAttribute:"eigenvectorCentrality",getEdgeWeight:"weight",maxIterations:100,tolerance:1e-6};function ld(e){for(var t=0,r=0,n=0,i=e.length;nt&&(r*=t/o*(t/o),t=o),r+=o===0&&t===0?0:o/t*(o/t)}return t===1/0?1:t*Math.sqrt(r)}function hu(e,t,r){if(!ad(t))throw new Error("graphology-metrics/centrality/eigenvector: the given graph is not a valid graphology instance.");r=ud(r,cd);var n=r.maxIterations,i=r.tolerance,o=t.order,a=new hd(t,r.getEdgeWeight),l,g,f,p,y=new Float64Array(t.order);for(l=0;l{var fd=Qt(),dd=_e(),gd=fn().WeightedNeighborhoodIndex,pd={nodePagerankAttribute:"pagerank",getEdgeWeight:"weight",alpha:.85,maxIterations:100,tolerance:1e-6};function du(e,t,r){if(!fd(t))throw new Error("graphology-metrics/centrality/pagerank: the given graph is not a valid graphology instance.");r=dd(r,pd);var n=r.alpha,i=r.maxIterations,o=r.tolerance,a=r.nodePagerankAttribute,l=t.order,g=1/l,f=new gd(t,r.getEdgeWeight),p,y,w,S,A=new Float64Array(t.order),I=new Float64Array(f.weights.length),L=[];for(p=0;p{var yd=Qt();wu.exports=function(t){if(!yd(t))throw new Error("graphology-metrics/simple-size: the given graph is not a valid graphology instance.");if(!t.multi)return t.size;var r=0,n=0;function i(){r++}function o(){n++}return t.forEachNode(function(a){t.type!=="directed"&&t.forEachUndirectedNeighbor(a,i),t.type!=="undirected"&&t.forEachOutNeighbor(a,o)}),r/2+n}});var vu=dt(rr=>{var wd=Qt(),md=mu();function vd(e,t){return 2*t/(e*(e-1))}function bd(e,t){return t/(e*(e-1))}function Ed(e,t){var r=e*(e-1);return t/(r+r/2)}function fr(e,t,r){var n,i;if(arguments.length>3){if(n=r,i=arguments[3],typeof n!="number"||n<0)throw new Error("graphology-metrics/density: given order is not a valid number.");if(typeof i!="number"||i<0)throw new Error("graphology-metrics/density: given size is not a valid number.")}else{if(!wd(r))throw new Error("graphology-metrics/density: given graph is not a valid graphology instance.");n=r.order,i=r.size,r.multi&&t===!1&&(i=md(r))}if(n<2)return 0;e===null&&(e=r.type),t===null&&(t=r.multi);var o;return e==="undirected"?o=vd:e==="directed"?o=bd:o=Ed,o(n,i)}rr.abstractDensity=fr;rr.density=fr.bind(null,null,null);rr.directedDensity=fr.bind(null,"directed",!1);rr.undirectedDensity=fr.bind(null,"undirected",!1);rr.mixedDensity=fr.bind(null,"mixed",!1);rr.multiDirectedDensity=fr.bind(null,"directed",!0);rr.multiUndirectedDensity=fr.bind(null,"undirected",!0);rr.multiMixedDensity=fr.bind(null,"mixed",!0)});var xu=dt((jy,Eu)=>{var bu=br(),xd=ei();function Yt(){this.clear()}Yt.prototype.clear=function(){this.items=[],this.offset=0,this.size=0};Yt.prototype.enqueue=function(e){return this.items.push(e),++this.size};Yt.prototype.dequeue=function(){if(this.size){var e=this.items[this.offset];return++this.offset*2>=this.items.length&&(this.items=this.items.slice(this.offset),this.offset=0),this.size--,e}};Yt.prototype.peek=function(){if(this.size)return this.items[this.offset]};Yt.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=this.offset,n=0,i=this.items.length;r=e.length)return{done:!0};var r=e[t];return t++,{value:r,done:!1}})};Yt.prototype.entries=function(){var e=this.items,t=this.offset,r=0;return new bu(function(){if(t>=e.length)return{done:!0};var n=e[t];return t++,{value:[r++,n],done:!1}})};typeof Symbol<"u"&&(Yt.prototype[Symbol.iterator]=Yt.prototype.values);Yt.prototype.toString=function(){return this.toArray().join(",")};Yt.prototype.toJSON=function(){return this.toArray()};Yt.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,"constructor",{value:Yt,enumerable:!1}),e};typeof Symbol<"u"&&(Yt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Yt.prototype.inspect);Yt.from=function(e){var t=new Yt;return xd(e,function(r){t.enqueue(r)}),t};Yt.of=function(){return Yt.from(arguments)};Eu.exports=Yt});var Au=dt((Cy,Su)=>{Su.exports=function(t,r){var n=r.length;if(n!==0){var i=t.length;t.length+=n;for(var o=0;o{var us=Qt(),Sd=xu(),Ad=Au();function Dd(e,t,r){if(!us(e))throw new Error("graphology-shortest-path: invalid graphology instance.");if(arguments.length<3)throw new Error("graphology-shortest-path: invalid number of arguments. Expecting at least 3.");if(!e.hasNode(t))throw new Error('graphology-shortest-path: the "'+t+'" source node does not exist in the given graph.');if(!e.hasNode(r))throw new Error('graphology-shortest-path: the "'+r+'" target node does not exist in the given graph.');if(t=""+t,r=""+r,t===r)return[t];var n=e.inboundNeighbors.bind(e),i=e.outboundNeighbors.bind(e),o={},a={};o[t]=null,a[r]=null;var l=[t],g=[r],f,p,y,w,S,A,I,L,$=!1;t:for(;l.length&&g.length;)if(l.length<=g.length){for(f=l,l=[],S=0,I=f.length;S{var _d=Qt(),Rd=Iu().singleSourceLength;ku.exports=function(t,r){if(!_d(t))throw new Error("graphology-metrics/eccentricity: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var n=-1/0,i=Rd(t,r),o,a,l=0;for(o in i)a=i[o],a>n&&(n=a),l++;return l{var Ld=Qt(),Td=ju();Cu.exports=function(t){if(!Ld(t))throw new Error("graphology-metrics/diameter: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var r=-1/0;return t.someNode(function(n){var i=Td(t,n);return i>r&&(r=i),r===1/0}),r}});var hs=dt((Ty,Ru)=>{var Md=Qt();Ru.exports=function(t){if(!Md(t))throw new Error("graphology-utils/infer-type: expecting a valid graphology instance.");var r=t.type;return r!=="mixed"?r:t.directedSize===0&&t.undirectedSize===0||t.directedSize>0&&t.undirectedSize>0?"mixed":t.directedSize>0?"directed":"undirected"}});var zu=dt((My,$u)=>{var Lu=_e(),Tu=Qt(),Mu=hs(),dr=Mr(),Ou={getNodeCommunity:"community",getEdgeWeight:"weight",resolution:1};function Od(e,t){var r=new Array(e.order),n=new Float64Array(e.order),i={},o=0,a=dr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry,l=dr.createNodeValueGetter(t.getNodeCommunity).fromEntry,g=0,f={};return e.forEachNode(function(p,y){f[p]=g,r[g++]=l(p,y)}),e.forEachUndirectedEdge(function(p,y,w,S,A,I,L){var $=a(p,y,w,S,A,I,L);o+=$,i[p]=$,n[f[w]]+=$,w!==S&&(n[f[S]]+=$)}),{weights:i,communities:r,weightedDegrees:n,M:o}}function Gd(e,t){var r=new Array(e.order),n=new Float64Array(e.order),i=new Float64Array(e.order),o={},a=0,l=dr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry,g=dr.createNodeValueGetter(t.getNodeCommunity).fromEntry,f=0,p={};return e.forEachNode(function(y,w){p[y]=f,r[f++]=g(y,w)}),e.forEachDirectedEdge(function(y,w,S,A,I,L,$){var j=l(y,w,S,A,I,L,$);a+=j,o[y]=j,i[p[S]]+=j,n[p[A]]+=j}),{weights:o,communities:r,weightedInDegrees:n,weightedOutDegrees:i,M:a}}function $d(e,t){var r=t.resolution,n=Od(e,t),i=n.communities,o=n.weightedDegrees,a=n.M,l=e.nodes(),g,f,p,y,w,S,A=0,I=a*2;for(g=0,p=e.order;g"u")throw new Error('graphology-metrics/modularity: the "'+a+'" node is not in the partition.');n[g]=0,i[g]=0}),{communities:r,totalWeights:n,internalWeights:i}}function Pd(e,t){var r={},n={},i={},o={},a=dr.createNodeValueGetter(t.getNodeCommunity).fromEntry;return e.forEachNode(function(l,g){var f=a(l,g);if(r[l]=f,typeof f>"u")throw new Error('graphology-metrics/modularity: the "'+l+'" node is not in the partition.');n[f]=0,i[f]=0,o[f]=0}),{communities:r,totalInWeights:n,totalOutWeights:i,internalWeights:o}}function Wd(e,t){var r=t.resolution,n=Nd(e,t),i=0,o=n.totalWeights,a=n.internalWeights,l=n.communities,g=dr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry;e.forEachUndirectedEdge(function(w,S,A,I,L,$,j){var M=g(w,S,A,I,L,$,j);i+=M;var W=l[A],N=l[I];o[W]+=M,o[N]+=M,W===N&&(a[W]+=M*2)});var f=0,p=i*2;for(var y in a)f+=a[y]/p-Math.pow(o[y]/p,2)*r;return f}function Fd(e,t){var r=t.resolution,n=Pd(e,t),i=0,o=n.totalInWeights,a=n.totalOutWeights,l=n.internalWeights,g=n.communities,f=dr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry;e.forEachDirectedEdge(function(w,S,A,I,L,$,j){var M=f(w,S,A,I,L,$,j);i+=M;var W=g[A],N=g[I];a[W]+=M,o[N]+=M,W===N&&(l[W]+=M)});var p=0;for(var y in l)p+=l[y]/i-o[y]*a[y]/Math.pow(i,2)*r;return p}function qd(e,t,r,n){return n/(2*e)-t*r/(2*(e*e))}function Ud(e,t,r,n,i,o){return o/e-(i*t+n*r)/(e*e)}function Bd(e,t){if(!Tu(e))throw new Error("graphology-metrics/modularity: given graph is not a valid graphology instance.");if(e.size===0)throw new Error("graphology-metrics/modularity: cannot compute modularity of an empty graph.");if(e.multi)throw new Error("graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.");var r=Mu(e);if(r==="mixed")throw new Error("graphology-metrics/modularity: cannot compute modularity of a mixed graph.");return t=Lu(t,Ou),r==="directed"?zd(e,t):$d(e,t)}function Gu(e,t){if(!Tu(e))throw new Error("graphology-metrics/modularity: given graph is not a valid graphology instance.");if(e.size===0)throw new Error("graphology-metrics/modularity: cannot compute modularity of an empty graph.");if(e.multi)throw new Error("graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.");var r=Mu(e);if(r==="mixed")throw new Error("graphology-metrics/modularity: cannot compute modularity of a mixed graph.");return t=Lu(t,Ou),r==="directed"?Fd(e,t):Wd(e,t)}var dn=Gu;dn.sparse=Gu;dn.dense=Bd;dn.undirectedDelta=qd;dn.directedDelta=Ud;$u.exports=dn});var Pu=dt((Oy,Nu)=>{var cs=br(),Vd=lr().getPointerArray;function fe(e,t){arguments.length<2&&(t=e,e=Array);var r=Vd(t);this.size=0,this.length=t,this.dense=new r(t),this.sparse=new r(t),this.vals=new e(t)}fe.prototype.clear=function(){this.size=0};fe.prototype.has=function(e){var t=this.sparse[e];return t=this.size||this.dense[t]!==e?!1:(t=this.dense[this.size-1],this.dense[this.sparse[e]]=t,this.sparse[t]=this.sparse[e],this.size--,!0)};fe.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=0;r{var Kd=br(),Yd=lr().getPointerArray;function De(e){var t=Yd(e);this.start=0,this.size=0,this.capacity=e,this.dense=new t(e),this.sparse=new t(e)}De.prototype.clear=function(){this.start=0,this.size=0};De.prototype.has=function(e){if(this.size===0)return!1;var t=this.sparse[e],r=t=this.start&&t=this.start&&t1?t:this;for(var r=this.capacity,n=this.size,i=this.start,o=0;o=r)return{done:!0};var o=e[n];return n++,i++,n===t&&(n=0),{value:o,done:!1}})};typeof Symbol<"u"&&(De.prototype[Symbol.iterator]=De.prototype.values);De.prototype.inspect=function(){var e=[];return this.forEach(function(t){e.push(t)}),Object.defineProperty(e,"constructor",{value:De,enumerable:!1}),e.capacity=this.capacity,e};typeof Symbol<"u"&&(De.prototype[Symbol.for("nodejs.util.inspect.custom")]=De.prototype.inspect);Wu.exports=De});var Vu=dt(($y,Bu)=>{function qu(e){return function(t){return typeof t!="number"&&(t=t.length),Math.floor(e()*t)}}var Uu=qu(Math.random);Uu.createRandomIndex=qu;Bu.exports=Uu});var Ju=dt(ls=>{var gr=lr(),Ku=_e(),Yu=Mr().createEdgeWeightGetter,Xu=Symbol.for("nodejs.util.inspect.custom"),Qu={getEdgeWeight:"weight",keepDendrogram:!1,resolution:1};function Vt(e,t){t=Ku(t,Qu);var r=t.resolution,n=Yu(t.getEdgeWeight).fromEntry,i=(e.size-e.selfLoopCount)*2,o=gr.getPointerArray(i),a=gr.getPointerArray(e.order+1),l=t.getEdgeWeight?Float64Array:gr.getPointerArray(e.size*2);this.C=e.order,this.M=0,this.E=i,this.U=0,this.resolution=r,this.level=0,this.graph=e,this.nodes=new Array(e.order),this.keepDendrogram=t.keepDendrogram,this.neighborhood=new a(i),this.weights=new l(i),this.loops=new l(e.order),this.starts=new o(e.order+1),this.belongings=new a(e.order),this.dendrogram=[],this.mapping=null,this.counts=new a(e.order),this.unused=new a(e.order),this.totalWeights=new l(e.order);var g={},f,p=0,y=0,w=this;e.forEachNode(function(S){w.nodes[p]=S,g[S]=p,y+=e.undirectedDegreeWithoutSelfLoops(S),w.starts[p]=y,w.belongings[p]=p,w.counts[p]=1,p++}),e.forEachEdge(function(S,A,I,L,$,j,M){if(f=n(S,A,I,L,$,j,M),I=g[I],L=g[L],w.M+=f,I===L)w.totalWeights[I]+=f*2,w.loops[I]=f*2;else{w.totalWeights[I]+=f,w.totalWeights[L]+=f;var W=--w.starts[I],N=--w.starts[L];w.neighborhood[W]=L,w.neighborhood[N]=I,w.weights[W]=f,w.weights[N]=f}}),this.starts[p]=this.E,this.keepDendrogram?this.dendrogram.push(this.belongings.slice()):this.mapping=this.belongings.slice()}Vt.prototype.isolate=function(e,t){var r=this.belongings[e];if(this.counts[r]===1)return r;var n=this.unused[--this.U],i=this.loops[e];return this.totalWeights[r]-=t+i,this.totalWeights[n]+=t+i,this.belongings[e]=n,this.counts[r]--,this.counts[n]++,n};Vt.prototype.move=function(e,t,r){var n=this.belongings[e],i=this.loops[e];this.totalWeights[n]-=t+i,this.totalWeights[r]+=t+i,this.belongings[e]=r;var o=this.counts[n]--===1;this.counts[r]++,o&&(this.unused[this.U++]=n)};Vt.prototype.computeNodeDegree=function(e){var t,r,n,i=0;for(t=this.starts[e],r=this.starts[e+1];t{var Xd=_e(),Qd=Qt(),Jd=hs(),Zu=Pu(),Hu=Fu(),th=Vu().createRandomIndex,eh=Ju(),Zd=eh.UndirectedLouvainIndex,Hd=eh.DirectedLouvainIndex,rh={nodeCommunityAttribute:"community",getEdgeWeight:"weight",fastLocalMoves:!0,randomWalk:!0,resolution:1,rng:Math.random};function ai(e,t,r){var n=e.get(t);typeof n>"u"&&(n=0),n+=r,e.set(t,n)}var tg=1e-10;function ui(e,t,r,n,i){return Math.abs(n-i)e:n>i}function eg(e,t,r){var n=new Zd(t,{getEdgeWeight:r.getEdgeWeight,keepDendrogram:e,resolution:r.resolution}),i=th(r.rng),o=!0,a=!0,l,g,f=new Zu(Float64Array,n.C),p,y,w,S,A,I,L,$,j,M,W,N,K,G,P,C,et=0,lt=0,ct=[],Dt,ft;for(r.fastLocalMoves&&(p=new Hu(n.C));o;){if(M=n.C,o=!1,a=!0,r.fastLocalMoves){for(ft=0,I=r.randomWalk?i(M):0,L=0;Le++}function Je(){let e=arguments,t=null,r=-1;return{[Symbol.iterator](){return this},next(){let n=null;do{if(t===null){if(r++,r>=e.length)return{done:!0};t=e[r][Symbol.iterator]()}if(n=t.next(),n.done){t=null;continue}break}while(!0);return n}}}function Rr(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var Xr=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},rt=class e extends Xr{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}},Z=class e extends Xr{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}},ht=class e extends Xr{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}};function Ts(e,t){this.key=e,this.attributes=t,this.clear()}Ts.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function Ms(e,t){this.key=e,this.attributes=t,this.clear()}Ms.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Os(e,t){this.key=e,this.attributes=t,this.clear()}Os.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function Lr(e,t,r,n,i){this.key=t,this.attributes=i,this.undirected=e,this.source=r,this.target=n}Lr.prototype.attach=function(){let e="out",t="in";this.undirected&&(e=t="undirected");let r=this.source.key,n=this.target.key;this.source[e][n]=this,!(this.undirected&&r===n)&&(this.target[t][r]=this)};Lr.prototype.attachMulti=function(){let e="out",t="in",r=this.source.key,n=this.target.key;this.undirected&&(e=t="undirected");let i=this.source[e],o=i[n];if(typeof o>"u"){i[n]=this,this.undirected&&r===n||(this.target[t][r]=this);return}o.previous=this,this.next=o,i[n]=this,this.target[t][r]=this};Lr.prototype.detach=function(){let e=this.source.key,t=this.target.key,r="out",n="in";this.undirected&&(r=n="undirected"),delete this.source[r][t],delete this.target[n][e]};Lr.prototype.detachMulti=function(){let e=this.source.key,t=this.target.key,r="out",n="in";this.undirected&&(r=n="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[r][t],delete this.target[n][e]):(this.next.previous=void 0,this.source[r][t]=this.next,this.target[n][e]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var Gs=0,$s=1,Rh=2,zs=3;function Ze(e,t,r,n,i,o,a){let l,g,f,p;if(n=""+n,r===Gs){if(l=e._nodes.get(n),!l)throw new Z(`Graph.${t}: could not find the "${n}" node in the graph.`);f=i,p=o}else if(r===zs){if(i=""+i,g=e._edges.get(i),!g)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`);let y=g.source.key,w=g.target.key;if(n===y)l=g.target;else if(n===w)l=g.source;else throw new Z(`Graph.${t}: the "${n}" node is not attached to the "${i}" edge (${y}, ${w}).`);f=o,p=a}else{if(g=e._edges.get(n),!g)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`);r===$s?l=g.source:l=g.target,f=i,p=o}return[l,f,p]}function Lh(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);return a.attributes[l]}}function Th(e,t,r){e.prototype[t]=function(n,i){let[o]=Ze(this,t,r,n,i);return o.attributes}}function Mh(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);return a.attributes.hasOwnProperty(l)}}function Oh(e,t,r){e.prototype[t]=function(n,i,o,a){let[l,g,f]=Ze(this,t,r,n,i,o,a);return l.attributes[g]=f,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function Gh(e,t,r){e.prototype[t]=function(n,i,o,a){let[l,g,f]=Ze(this,t,r,n,i,o,a);if(typeof f!="function")throw new rt(`Graph.${t}: updater should be a function.`);let p=l.attributes,y=f(p[g]);return p[g]=y,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function $h(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);return delete a.attributes[l],this.emit("nodeAttributesUpdated",{key:a.key,type:"remove",attributes:a.attributes,name:l}),this}}function zh(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);if(!he(l))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return a.attributes=l,this.emit("nodeAttributesUpdated",{key:a.key,type:"replace",attributes:a.attributes}),this}}function Nh(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);if(!he(l))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return ee(a.attributes,l),this.emit("nodeAttributesUpdated",{key:a.key,type:"merge",attributes:a.attributes,data:l}),this}}function Ph(e,t,r){e.prototype[t]=function(n,i,o){let[a,l]=Ze(this,t,r,n,i,o);if(typeof l!="function")throw new rt(`Graph.${t}: provided updater is not a function.`);return a.attributes=l(a.attributes),this.emit("nodeAttributesUpdated",{key:a.key,type:"update",attributes:a.attributes}),this}}var Wh=[{name:e=>`get${e}Attribute`,attacher:Lh},{name:e=>`get${e}Attributes`,attacher:Th},{name:e=>`has${e}Attribute`,attacher:Mh},{name:e=>`set${e}Attribute`,attacher:Oh},{name:e=>`update${e}Attribute`,attacher:Gh},{name:e=>`remove${e}Attribute`,attacher:$h},{name:e=>`replace${e}Attributes`,attacher:zh},{name:e=>`merge${e}Attributes`,attacher:Nh},{name:e=>`update${e}Attributes`,attacher:Ph}];function Fh(e){Wh.forEach(function({name:t,attacher:r}){r(e,t("Node"),Gs),r(e,t("Source"),$s),r(e,t("Target"),Rh),r(e,t("Opposite"),zs)})}function qh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return o.attributes[i]}}function Uh(e,t,r){e.prototype[t]=function(n){let i;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let o=""+n,a=""+arguments[1];if(i=Ce(this,o,a,r),!i)throw new Z(`Graph.${t}: could not find an edge for the given path ("${o}" - "${a}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,i=this._edges.get(n),!i)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return i.attributes}}function Bh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return o.attributes.hasOwnProperty(i)}}function Vh(e,t,r){e.prototype[t]=function(n,i,o){let a;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+i;if(i=arguments[2],o=arguments[3],a=Ce(this,l,g,r),!a)throw new Z(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,a=this._edges.get(n),!a)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return a.attributes[i]=o,this.emit("edgeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:i}),this}}function Kh(e,t,r){e.prototype[t]=function(n,i,o){let a;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+i;if(i=arguments[2],o=arguments[3],a=Ce(this,l,g,r),!a)throw new Z(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,a=this._edges.get(n),!a)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof o!="function")throw new rt(`Graph.${t}: updater should be a function.`);return a.attributes[i]=o(a.attributes[i]),this.emit("edgeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:i}),this}}function Yh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return delete o.attributes[i],this.emit("edgeAttributesUpdated",{key:o.key,type:"remove",attributes:o.attributes,name:i}),this}}function Xh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!he(i))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return o.attributes=i,this.emit("edgeAttributesUpdated",{key:o.key,type:"replace",attributes:o.attributes}),this}}function Qh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!he(i))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return ee(o.attributes,i),this.emit("edgeAttributesUpdated",{key:o.key,type:"merge",attributes:o.attributes,data:i}),this}}function Jh(e,t,r){e.prototype[t]=function(n,i){let o;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new ht(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new ht(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],o=Ce(this,a,l,r),!o)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new ht(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,o=this._edges.get(n),!o)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof i!="function")throw new rt(`Graph.${t}: provided updater is not a function.`);return o.attributes=i(o.attributes),this.emit("edgeAttributesUpdated",{key:o.key,type:"update",attributes:o.attributes}),this}}var Zh=[{name:e=>`get${e}Attribute`,attacher:qh},{name:e=>`get${e}Attributes`,attacher:Uh},{name:e=>`has${e}Attribute`,attacher:Bh},{name:e=>`set${e}Attribute`,attacher:Vh},{name:e=>`update${e}Attribute`,attacher:Kh},{name:e=>`remove${e}Attribute`,attacher:Yh},{name:e=>`replace${e}Attributes`,attacher:Xh},{name:e=>`merge${e}Attributes`,attacher:Qh},{name:e=>`update${e}Attributes`,attacher:Jh}];function Hh(e){Zh.forEach(function({name:t,attacher:r}){r(e,t("Edge"),"mixed"),r(e,t("DirectedEdge"),"directed"),r(e,t("UndirectedEdge"),"undirected")})}var tc=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function ec(e,t,r,n){let i=!1;for(let o in t){if(o===n)continue;let a=t[o];if(i=r(a.key,a.attributes,a.source.key,a.target.key,a.source.attributes,a.target.attributes,a.undirected),e&&i)return a.key}}function rc(e,t,r,n){let i,o,a,l=!1;for(let g in t)if(g!==n){i=t[g];do{if(o=i.source,a=i.target,l=r(i.key,i.attributes,o.key,a.key,o.attributes,a.attributes,i.undirected),e&&l)return i.key;i=i.next}while(i!==void 0)}}function mi(e,t){let r=Object.keys(e),n=r.length,i,o=0;return{[Symbol.iterator](){return this},next(){do if(i)i=i.next;else{if(o>=n)return{done:!0};let a=r[o++];if(a===t){i=void 0;continue}i=e[a]}while(!i);return{done:!1,value:{edge:i.key,attributes:i.attributes,source:i.source.key,target:i.target.key,sourceAttributes:i.source.attributes,targetAttributes:i.target.attributes,undirected:i.undirected}}}}}function nc(e,t,r,n){let i=t[r];if(!i)return;let o=i.source,a=i.target;if(n(i.key,i.attributes,o.key,a.key,o.attributes,a.attributes,i.undirected)&&e)return i.key}function ic(e,t,r,n){let i=t[r];if(!i)return;let o=!1;do{if(o=n(i.key,i.attributes,i.source.key,i.target.key,i.source.attributes,i.target.attributes,i.undirected),e&&o)return i.key;i=i.next}while(i!==void 0)}function vi(e,t){let r=e[t];if(r.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!r)return{done:!0};let i={edge:r.key,attributes:r.attributes,source:r.source.key,target:r.target.key,sourceAttributes:r.source.attributes,targetAttributes:r.target.attributes,undirected:r.undirected};return r=r.next,{done:!1,value:i}}};let n=!1;return{[Symbol.iterator](){return this},next(){return n===!0?{done:!0}:(n=!0,{done:!1,value:{edge:r.key,attributes:r.attributes,source:r.source.key,target:r.target.key,sourceAttributes:r.source.attributes,targetAttributes:r.target.attributes,undirected:r.undirected}})}}}function sc(e,t){if(e.size===0)return[];if(t==="mixed"||t===e.type)return Array.from(e._edges.keys());let r=t==="undirected"?e.undirectedSize:e.directedSize,n=new Array(r),i=t==="undirected",o=e._edges.values(),a=0,l,g;for(;l=o.next(),l.done!==!0;)g=l.value,g.undirected===i&&(n[a++]=g.key);return n}function Ns(e,t,r,n){if(t.size===0)return;let i=r!=="mixed"&&r!==t.type,o=r==="undirected",a,l,g=!1,f=t._edges.values();for(;a=f.next(),a.done!==!0;){if(l=a.value,i&&l.undirected!==o)continue;let{key:p,attributes:y,source:w,target:S}=l;if(g=n(p,y,w.key,S.key,w.attributes,S.attributes,l.undirected),e&&g)return p}}function oc(e,t){if(e.size===0)return Rr();let r=t!=="mixed"&&t!==e.type,n=t==="undirected",i=e._edges.values();return{[Symbol.iterator](){return this},next(){let o,a;for(;;){if(o=i.next(),o.done)return o;if(a=o.value,!(r&&a.undirected!==n))break}return{value:{edge:a.key,attributes:a.attributes,source:a.source.key,target:a.target.key,sourceAttributes:a.source.attributes,targetAttributes:a.target.attributes,undirected:a.undirected},done:!1}}}}function bi(e,t,r,n,i,o){let a=t?rc:ec,l;if(r!=="undirected"&&(n!=="out"&&(l=a(e,i.in,o),e&&l)||n!=="in"&&(l=a(e,i.out,o,n?void 0:i.key),e&&l))||r!=="directed"&&(l=a(e,i.undirected,o),e&&l))return l}function ac(e,t,r,n){let i=[];return bi(!1,e,t,r,n,function(o){i.push(o)}),i}function uc(e,t,r){let n=Rr();return e!=="undirected"&&(t!=="out"&&typeof r.in<"u"&&(n=Je(n,mi(r.in))),t!=="in"&&typeof r.out<"u"&&(n=Je(n,mi(r.out,t?void 0:r.key)))),e!=="directed"&&typeof r.undirected<"u"&&(n=Je(n,mi(r.undirected))),n}function Ei(e,t,r,n,i,o,a){let l=r?ic:nc,g;if(t!=="undirected"&&(typeof i.in<"u"&&n!=="out"&&(g=l(e,i.in,o,a),e&&g)||typeof i.out<"u"&&n!=="in"&&(n||i.key!==o)&&(g=l(e,i.out,o,a),e&&g))||t!=="directed"&&typeof i.undirected<"u"&&(g=l(e,i.undirected,o,a),e&&g))return g}function hc(e,t,r,n,i){let o=[];return Ei(!1,e,t,r,n,i,function(a){o.push(a)}),o}function cc(e,t,r,n){let i=Rr();return e!=="undirected"&&(typeof r.in<"u"&&t!=="out"&&n in r.in&&(i=Je(i,vi(r.in,n))),typeof r.out<"u"&&t!=="in"&&n in r.out&&(t||r.key!==n)&&(i=Je(i,vi(r.out,n)))),e!=="directed"&&typeof r.undirected<"u"&&n in r.undirected&&(i=Je(i,vi(r.undirected,n))),i}function lc(e,t){let{name:r,type:n,direction:i}=t;e.prototype[r]=function(o,a){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];if(!arguments.length)return sc(this,n);if(arguments.length===1){o=""+o;let l=this._nodes.get(o);if(typeof l>"u")throw new Z(`Graph.${r}: could not find the "${o}" node in the graph.`);return ac(this.multi,n==="mixed"?this.type:n,i,l)}if(arguments.length===2){o=""+o,a=""+a;let l=this._nodes.get(o);if(!l)throw new Z(`Graph.${r}: could not find the "${o}" source node in the graph.`);if(!this._nodes.has(a))throw new Z(`Graph.${r}: could not find the "${a}" target node in the graph.`);return hc(n,this.multi,i,l,a)}throw new rt(`Graph.${r}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function fc(e,t){let{name:r,type:n,direction:i}=t,o="forEach"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[o]=function(f,p,y){if(!(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)){if(arguments.length===1)return y=f,Ns(!1,this,n,y);if(arguments.length===2){f=""+f,y=p;let w=this._nodes.get(f);if(typeof w>"u")throw new Z(`Graph.${o}: could not find the "${f}" node in the graph.`);return bi(!1,this.multi,n==="mixed"?this.type:n,i,w,y)}if(arguments.length===3){f=""+f,p=""+p;let w=this._nodes.get(f);if(!w)throw new Z(`Graph.${o}: could not find the "${f}" source node in the graph.`);if(!this._nodes.has(p))throw new Z(`Graph.${o}: could not find the "${p}" target node in the graph.`);return Ei(!1,n,this.multi,i,w,p,y)}throw new rt(`Graph.${o}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let a="map"+r[0].toUpperCase()+r.slice(1);e.prototype[a]=function(){let f=Array.prototype.slice.call(arguments),p=f.pop(),y;if(f.length===0){let w=0;n!=="directed"&&(w+=this.undirectedSize),n!=="undirected"&&(w+=this.directedSize),y=new Array(w);let S=0;f.push((A,I,L,$,j,M,W)=>{y[S++]=p(A,I,L,$,j,M,W)})}else y=[],f.push((w,S,A,I,L,$,j)=>{y.push(p(w,S,A,I,L,$,j))});return this[o].apply(this,f),y};let l="filter"+r[0].toUpperCase()+r.slice(1);e.prototype[l]=function(){let f=Array.prototype.slice.call(arguments),p=f.pop(),y=[];return f.push((w,S,A,I,L,$,j)=>{p(w,S,A,I,L,$,j)&&y.push(w)}),this[o].apply(this,f),y};let g="reduce"+r[0].toUpperCase()+r.slice(1);e.prototype[g]=function(){let f=Array.prototype.slice.call(arguments);if(f.length<2||f.length>4)throw new rt(`Graph.${g}: invalid number of arguments (expecting 2, 3 or 4 and got ${f.length}).`);if(typeof f[f.length-1]=="function"&&typeof f[f.length-2]!="function")throw new rt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let p,y;f.length===2?(p=f[0],y=f[1],f=[]):f.length===3?(p=f[1],y=f[2],f=[f[0]]):f.length===4&&(p=f[2],y=f[3],f=[f[0],f[1]]);let w=y;return f.push((S,A,I,L,$,j,M)=>{w=p(w,S,A,I,L,$,j,M)}),this[o].apply(this,f),w}}function dc(e,t){let{name:r,type:n,direction:i}=t,o="find"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[o]=function(g,f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return!1;if(arguments.length===1)return p=g,Ns(!0,this,n,p);if(arguments.length===2){g=""+g,p=f;let y=this._nodes.get(g);if(typeof y>"u")throw new Z(`Graph.${o}: could not find the "${g}" node in the graph.`);return bi(!0,this.multi,n==="mixed"?this.type:n,i,y,p)}if(arguments.length===3){g=""+g,f=""+f;let y=this._nodes.get(g);if(!y)throw new Z(`Graph.${o}: could not find the "${g}" source node in the graph.`);if(!this._nodes.has(f))throw new Z(`Graph.${o}: could not find the "${f}" target node in the graph.`);return Ei(!0,n,this.multi,i,y,f,p)}throw new rt(`Graph.${o}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let a="some"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[a]=function(){let g=Array.prototype.slice.call(arguments),f=g.pop();return g.push((y,w,S,A,I,L,$)=>f(y,w,S,A,I,L,$)),!!this[o].apply(this,g)};let l="every"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[l]=function(){let g=Array.prototype.slice.call(arguments),f=g.pop();return g.push((y,w,S,A,I,L,$)=>!f(y,w,S,A,I,L,$)),!this[o].apply(this,g)}}function gc(e,t){let{name:r,type:n,direction:i}=t,o=r.slice(0,-1)+"Entries";e.prototype[o]=function(a,l){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return Rr();if(!arguments.length)return oc(this,n);if(arguments.length===1){a=""+a;let g=this._nodes.get(a);if(!g)throw new Z(`Graph.${o}: could not find the "${a}" node in the graph.`);return uc(n,i,g)}if(arguments.length===2){a=""+a,l=""+l;let g=this._nodes.get(a);if(!g)throw new Z(`Graph.${o}: could not find the "${a}" source node in the graph.`);if(!this._nodes.has(l))throw new Z(`Graph.${o}: could not find the "${l}" target node in the graph.`);return cc(n,i,g,l)}throw new rt(`Graph.${o}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function pc(e){tc.forEach(t=>{lc(e,t),fc(e,t),dc(e,t),gc(e,t)})}var yc=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function kn(){this.A=null,this.B=null}kn.prototype.wrap=function(e){this.A===null?this.A=e:this.B===null&&(this.B=e)};kn.prototype.has=function(e){return this.A!==null&&e in this.A||this.B!==null&&e in this.B};function Kr(e,t,r,n,i){for(let o in n){let a=n[o],l=a.source,g=a.target,f=l===r?g:l;if(t&&t.has(f.key))continue;let p=i(f.key,f.attributes);if(e&&p)return f.key}}function xi(e,t,r,n,i){if(t!=="mixed"){if(t==="undirected")return Kr(e,null,n,n.undirected,i);if(typeof r=="string")return Kr(e,null,n,n[r],i)}let o=new kn,a;if(t!=="undirected"){if(r!=="out"){if(a=Kr(e,null,n,n.in,i),e&&a)return a;o.wrap(n.in)}if(r!=="in"){if(a=Kr(e,o,n,n.out,i),e&&a)return a;o.wrap(n.out)}}if(t!=="directed"&&(a=Kr(e,o,n,n.undirected,i),e&&a))return a}function wc(e,t,r){if(e!=="mixed"){if(e==="undirected")return Object.keys(r.undirected);if(typeof t=="string")return Object.keys(r[t])}let n=[];return xi(!1,e,t,r,function(i){n.push(i)}),n}function Yr(e,t,r){let n=Object.keys(r),i=n.length,o=0;return{[Symbol.iterator](){return this},next(){let a=null;do{if(o>=i)return e&&e.wrap(r),{done:!0};let l=r[n[o++]],g=l.source,f=l.target;if(a=g===t?f:g,e&&e.has(a.key)){a=null;continue}}while(a===null);return{done:!1,value:{neighbor:a.key,attributes:a.attributes}}}}}function mc(e,t,r){if(e!=="mixed"){if(e==="undirected")return Yr(null,r,r.undirected);if(typeof t=="string")return Yr(null,r,r[t])}let n=Rr(),i=new kn;return e!=="undirected"&&(t!=="out"&&(n=Je(n,Yr(i,r,r.in))),t!=="in"&&(n=Je(n,Yr(i,r,r.out)))),e!=="directed"&&(n=Je(n,Yr(i,r,r.undirected))),n}function vc(e,t){let{name:r,type:n,direction:i}=t;e.prototype[r]=function(o){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];o=""+o;let a=this._nodes.get(o);if(typeof a>"u")throw new Z(`Graph.${r}: could not find the "${o}" node in the graph.`);return wc(n==="mixed"?this.type:n,i,a)}}function bc(e,t){let{name:r,type:n,direction:i}=t,o="forEach"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[o]=function(f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;f=""+f;let y=this._nodes.get(f);if(typeof y>"u")throw new Z(`Graph.${o}: could not find the "${f}" node in the graph.`);xi(!1,n==="mixed"?this.type:n,i,y,p)};let a="map"+r[0].toUpperCase()+r.slice(1);e.prototype[a]=function(f,p){let y=[];return this[o](f,(w,S)=>{y.push(p(w,S))}),y};let l="filter"+r[0].toUpperCase()+r.slice(1);e.prototype[l]=function(f,p){let y=[];return this[o](f,(w,S)=>{p(w,S)&&y.push(w)}),y};let g="reduce"+r[0].toUpperCase()+r.slice(1);e.prototype[g]=function(f,p,y){if(arguments.length<3)throw new rt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let w=y;return this[o](f,(S,A)=>{w=p(w,S,A)}),w}}function Ec(e,t){let{name:r,type:n,direction:i}=t,o=r[0].toUpperCase()+r.slice(1,-1),a="find"+o;e.prototype[a]=function(f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;f=""+f;let y=this._nodes.get(f);if(typeof y>"u")throw new Z(`Graph.${a}: could not find the "${f}" node in the graph.`);return xi(!0,n==="mixed"?this.type:n,i,y,p)};let l="some"+o;e.prototype[l]=function(f,p){return!!this[a](f,p)};let g="every"+o;e.prototype[g]=function(f,p){return!this[a](f,(w,S)=>!p(w,S))}}function xc(e,t){let{name:r,type:n,direction:i}=t,o=r.slice(0,-1)+"Entries";e.prototype[o]=function(a){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return Rr();a=""+a;let l=this._nodes.get(a);if(typeof l>"u")throw new Z(`Graph.${o}: could not find the "${a}" node in the graph.`);return mc(n==="mixed"?this.type:n,i,l)}}function Sc(e){yc.forEach(t=>{vc(e,t),bc(e,t),Ec(e,t),xc(e,t)})}function En(e,t,r,n,i){let o=n._nodes.values(),a=n.type,l,g,f,p,y,w,S;for(;l=o.next(),l.done!==!0;){let A=!1;if(g=l.value,a!=="undirected"){p=g.out;for(f in p){y=p[f];do{if(w=y.target,A=!0,S=i(g.key,w.key,g.attributes,w.attributes,y.key,y.attributes,y.undirected),e&&S)return y;y=y.next}while(y)}}if(a!=="directed"){p=g.undirected;for(f in p)if(!(t&&g.key>f)){y=p[f];do{if(w=y.target,w.key!==f&&(w=y.source),A=!0,S=i(g.key,w.key,g.attributes,w.attributes,y.key,y.attributes,y.undirected),e&&S)return y;y=y.next}while(y)}}if(r&&!A&&(S=i(g.key,null,g.attributes,null,null,null,null),e&&S))return null}}function Ac(e,t){let r={key:e};return Ls(t.attributes)||(r.attributes=ee({},t.attributes)),r}function Dc(e,t,r){let n={key:t,source:r.source.key,target:r.target.key};return Ls(r.attributes)||(n.attributes=ee({},r.attributes)),e==="mixed"&&r.undirected&&(n.undirected=!0),n}function Ic(e){if(!he(e))throw new rt('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in e))throw new rt("Graph.import: serialized node is missing its key.");if("attributes"in e&&(!he(e.attributes)||e.attributes===null))throw new rt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function kc(e){if(!he(e))throw new rt('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in e))throw new rt("Graph.import: serialized edge is missing its source.");if(!("target"in e))throw new rt("Graph.import: serialized edge is missing its target.");if("attributes"in e&&(!he(e.attributes)||e.attributes===null))throw new rt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in e&&typeof e.undirected!="boolean")throw new rt("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var jc=_h(),Cc=new Set(["directed","undirected","mixed"]),Cs=new Set(["domain","_events","_eventsCount","_maxListeners"]),_c=[{name:e=>`${e}Edge`,generateKey:!0},{name:e=>`${e}DirectedEdge`,generateKey:!0,type:"directed"},{name:e=>`${e}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:e=>`${e}EdgeWithKey`},{name:e=>`${e}DirectedEdgeWithKey`,type:"directed"},{name:e=>`${e}UndirectedEdgeWithKey`,type:"undirected"}],Rc={allowSelfLoops:!0,multi:!1,type:"mixed"};function Lc(e,t,r){if(r&&!he(r))throw new rt(`Graph.addNode: invalid attributes. Expecting an object but got "${r}"`);if(t=""+t,r=r||{},e._nodes.has(t))throw new ht(`Graph.addNode: the "${t}" node already exist in the graph.`);let n=new e.NodeDataClass(t,r);return e._nodes.set(t,n),e.emit("nodeAdded",{key:t,attributes:r}),n}function _s(e,t,r){let n=new e.NodeDataClass(t,r);return e._nodes.set(t,n),e.emit("nodeAdded",{key:t,attributes:r}),n}function Ps(e,t,r,n,i,o,a,l){if(!n&&e.type==="undirected")throw new ht(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(n&&e.type==="directed")throw new ht(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(l&&!he(l))throw new rt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`);if(o=""+o,a=""+a,l=l||{},!e.allowSelfLoops&&o===a)throw new ht(`Graph.${t}: source & target are the same ("${o}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let g=e._nodes.get(o),f=e._nodes.get(a);if(!g)throw new Z(`Graph.${t}: source node "${o}" not found.`);if(!f)throw new Z(`Graph.${t}: target node "${a}" not found.`);let p={key:null,undirected:n,source:o,target:a,attributes:l};if(r)i=e._edgeKeyGenerator();else if(i=""+i,e._edges.has(i))throw new ht(`Graph.${t}: the "${i}" edge already exists in the graph.`);if(!e.multi&&(n?typeof g.undirected[a]<"u":typeof g.out[a]<"u"))throw new ht(`Graph.${t}: an edge linking "${o}" to "${a}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let y=new Lr(n,i,g,f,l);e._edges.set(i,y);let w=o===a;return n?(g.undirectedDegree++,f.undirectedDegree++,w&&(g.undirectedLoops++,e._undirectedSelfLoopCount++)):(g.outDegree++,f.inDegree++,w&&(g.directedLoops++,e._directedSelfLoopCount++)),e.multi?y.attachMulti():y.attach(),n?e._undirectedSize++:e._directedSize++,p.key=i,e.emit("edgeAdded",p),i}function Tc(e,t,r,n,i,o,a,l,g){if(!n&&e.type==="undirected")throw new ht(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(n&&e.type==="directed")throw new ht(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(l){if(g){if(typeof l!="function")throw new rt(`Graph.${t}: invalid updater function. Expecting a function but got "${l}"`)}else if(!he(l))throw new rt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`)}o=""+o,a=""+a;let f;if(g&&(f=l,l=void 0),!e.allowSelfLoops&&o===a)throw new ht(`Graph.${t}: source & target are the same ("${o}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let p=e._nodes.get(o),y=e._nodes.get(a),w,S;if(!r&&(w=e._edges.get(i),w)){if((w.source.key!==o||w.target.key!==a)&&(!n||w.source.key!==a||w.target.key!==o))throw new ht(`Graph.${t}: inconsistency detected when attempting to merge the "${i}" edge with "${o}" source & "${a}" target vs. ("${w.source.key}", "${w.target.key}").`);S=w}if(!S&&!e.multi&&p&&(S=n?p.undirected[a]:p.out[a]),S){let j=[S.key,!1,!1,!1];if(g?!f:!l)return j;if(g){let M=S.attributes;S.attributes=f(M),e.emit("edgeAttributesUpdated",{type:"replace",key:S.key,attributes:S.attributes})}else ee(S.attributes,l),e.emit("edgeAttributesUpdated",{type:"merge",key:S.key,attributes:S.attributes,data:l});return j}l=l||{},g&&f&&(l=f(l));let A={key:null,undirected:n,source:o,target:a,attributes:l};if(r)i=e._edgeKeyGenerator();else if(i=""+i,e._edges.has(i))throw new ht(`Graph.${t}: the "${i}" edge already exists in the graph.`);let I=!1,L=!1;p||(p=_s(e,o,{}),I=!0,o===a&&(y=p,L=!0)),y||(y=_s(e,a,{}),L=!0),w=new Lr(n,i,p,y,l),e._edges.set(i,w);let $=o===a;return n?(p.undirectedDegree++,y.undirectedDegree++,$&&(p.undirectedLoops++,e._undirectedSelfLoopCount++)):(p.outDegree++,y.inDegree++,$&&(p.directedLoops++,e._directedSelfLoopCount++)),e.multi?w.attachMulti():w.attach(),n?e._undirectedSize++:e._directedSize++,A.key=i,e.emit("edgeAdded",A),[i,!0,I,L]}function _r(e,t){e._edges.delete(t.key);let{source:r,target:n,attributes:i}=t,o=t.undirected,a=r===n;o?(r.undirectedDegree--,n.undirectedDegree--,a&&(r.undirectedLoops--,e._undirectedSelfLoopCount--)):(r.outDegree--,n.inDegree--,a&&(r.directedLoops--,e._directedSelfLoopCount--)),e.multi?t.detachMulti():t.detach(),o?e._undirectedSize--:e._directedSize--,e.emit("edgeDropped",{key:t.key,attributes:i,source:r.key,target:n.key,undirected:o})}var Tt=class e extends Rs.EventEmitter{constructor(t){if(super(),t=ee({},Rc,t),typeof t.multi!="boolean")throw new rt(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Cc.has(t.type))throw new rt(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new rt(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let r=t.type==="mixed"?Ts:t.type==="directed"?Ms:Os;je(this,"NodeDataClass",r);let n="geid_"+jc()+"_",i=0,o=()=>{let a;do a=n+i++;while(this._edges.has(a));return a};je(this,"_attributes",{}),je(this,"_nodes",new Map),je(this,"_edges",new Map),je(this,"_directedSize",0),je(this,"_undirectedSize",0),je(this,"_directedSelfLoopCount",0),je(this,"_undirectedSelfLoopCount",0),je(this,"_edgeKeyGenerator",o),je(this,"_options",t),Cs.forEach(a=>je(this,a,this[a])),$e(this,"order",()=>this._nodes.size),$e(this,"size",()=>this._edges.size),$e(this,"directedSize",()=>this._directedSize),$e(this,"undirectedSize",()=>this._undirectedSize),$e(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),$e(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),$e(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),$e(this,"multi",this._options.multi),$e(this,"type",this._options.type),$e(this,"allowSelfLoops",this._options.allowSelfLoops),$e(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,r){if(this.type==="undirected")return!1;if(arguments.length===1){let n=""+t,i=this._edges.get(n);return!!i&&!i.undirected}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?n.out.hasOwnProperty(r):!1}throw new rt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,r){if(this.type==="directed")return!1;if(arguments.length===1){let n=""+t,i=this._edges.get(n);return!!i&&i.undirected}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?n.undirected.hasOwnProperty(r):!1}throw new rt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,r){if(arguments.length===1){let n=""+t;return this._edges.has(n)}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?typeof n.out<"u"&&n.out.hasOwnProperty(r)||typeof n.undirected<"u"&&n.undirected.hasOwnProperty(r):!1}throw new rt(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,r){if(this.type==="undirected")return;if(t=""+t,r=""+r,this.multi)throw new ht("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let n=this._nodes.get(t);if(!n)throw new Z(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.directedEdge: could not find the "${r}" target node in the graph.`);let i=n.out&&n.out[r]||void 0;if(i)return i.key}undirectedEdge(t,r){if(this.type==="directed")return;if(t=""+t,r=""+r,this.multi)throw new ht("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let n=this._nodes.get(t);if(!n)throw new Z(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.undirectedEdge: could not find the "${r}" target node in the graph.`);let i=n.undirected&&n.undirected[r]||void 0;if(i)return i.key}edge(t,r){if(this.multi)throw new ht("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.edge: could not find the "${r}" target node in the graph.`);let i=n.out&&n.out[r]||n.undirected&&n.undirected[r]||void 0;if(i)return i.key}areDirectedNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.in||r in n.out}areOutNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.out}areInNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.in}areUndirectedNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:r in n.undirected}areNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(r in n.in||r in n.out)||this.type!=="directed"&&r in n.undirected}areInboundNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&r in n.in||this.type!=="directed"&&r in n.undirected}areOutboundNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&r in n.out||this.type!=="directed"&&r in n.undirected}inDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree}outDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.outDegree}directedDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree+r.outDegree}undirectedDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:r.undirectedDegree}inboundDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.inDegree),n}outboundDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.outDegree),n}degree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.degree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.inDegree+r.outDegree),n}inDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree-r.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.outDegree-r.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree+r.outDegree-r.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:r.undirectedDegree-r.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.inDegree,i+=r.directedLoops),n-i}outboundDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.outDegree,i+=r.directedLoops),n-i}degreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.inDegree+r.outDegree,i+=r.directedLoops*2),n-i}source(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.source: could not find the "${t}" edge in the graph.`);return r.source.key}target(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.target: could not find the "${t}" edge in the graph.`);return r.target.key}extremities(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[r.source.key,r.target.key]}opposite(t,r){t=""+t,r=""+r;let n=this._edges.get(r);if(!n)throw new Z(`Graph.opposite: could not find the "${r}" edge in the graph.`);let i=n.source.key,o=n.target.key;if(t===i)return o;if(t===o)return i;throw new Z(`Graph.opposite: the "${t}" node is not attached to the "${r}" edge (${i}, ${o}).`)}hasExtremity(t,r){t=""+t,r=""+r;let n=this._edges.get(t);if(!n)throw new Z(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return n.source.key===r||n.target.key===r}isUndirected(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return r.undirected}isDirected(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!r.undirected}isSelfLoop(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return r.source===r.target}addNode(t,r){return Lc(this,t,r).key}mergeNode(t,r){if(r&&!he(r))throw new rt(`Graph.mergeNode: invalid attributes. Expecting an object but got "${r}"`);t=""+t,r=r||{};let n=this._nodes.get(t);return n?(r&&(ee(n.attributes,r),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:n.attributes,data:r})),[t,!1]):(n=new this.NodeDataClass(t,r),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:r}),[t,!0])}updateNode(t,r){if(r&&typeof r!="function")throw new rt(`Graph.updateNode: invalid updater function. Expecting a function but got "${r}"`);t=""+t;let n=this._nodes.get(t);if(n){if(r){let o=n.attributes;n.attributes=r(o),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:n.attributes})}return[t,!1]}let i=r?r({}):{};return n=new this.NodeDataClass(t,i),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:i}),[t,!0]}dropNode(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.dropNode: could not find the "${t}" node in the graph.`);let n;if(this.type!=="undirected"){for(let i in r.out){n=r.out[i];do _r(this,n),n=n.next;while(n)}for(let i in r.in){n=r.in[i];do _r(this,n),n=n.next;while(n)}}if(this.type!=="directed")for(let i in r.undirected){n=r.undirected[i];do _r(this,n),n=n.next;while(n)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:r.attributes})}dropEdge(t){let r;if(arguments.length>1){let n=""+arguments[0],i=""+arguments[1];if(r=Ce(this,n,i,this.type),!r)throw new Z(`Graph.dropEdge: could not find the "${n}" -> "${i}" edge in the graph.`)}else if(t=""+t,r=this._edges.get(t),!r)throw new Z(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return _r(this,r),this}dropDirectedEdge(t,r){if(arguments.length<2)throw new ht("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new ht("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,r=""+r;let n=Ce(this,t,r,"directed");if(!n)throw new Z(`Graph.dropDirectedEdge: could not find a "${t}" -> "${r}" edge in the graph.`);return _r(this,n),this}dropUndirectedEdge(t,r){if(arguments.length<2)throw new ht("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new ht("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let n=Ce(this,t,r,"undirected");if(!n)throw new Z(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${r}" edge in the graph.`);return _r(this,n),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),r;for(;r=t.next(),r.done!==!0;)r.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,r){return this._attributes[t]=r,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,r){if(typeof r!="function")throw new rt("Graph.updateAttribute: updater should be a function.");let n=this._attributes[t];return this._attributes[t]=r(n),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!he(t))throw new rt("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!he(t))throw new rt("Graph.mergeAttributes: provided attributes are not a plain object.");return ee(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new rt("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,r){if(typeof t!="function")throw new rt("Graph.updateEachNodeAttributes: expecting an updater function.");if(r&&!js(r))throw new rt("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._nodes.values(),i,o;for(;i=n.next(),i.done!==!0;)o=i.value,o.attributes=t(o.key,o.attributes);this.emit("eachNodeAttributesUpdated",{hints:r||null})}updateEachEdgeAttributes(t,r){if(typeof t!="function")throw new rt("Graph.updateEachEdgeAttributes: expecting an updater function.");if(r&&!js(r))throw new rt("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._edges.values(),i,o,a,l;for(;i=n.next(),i.done!==!0;)o=i.value,a=o.source,l=o.target,o.attributes=t(o.key,o.attributes,a.key,l.key,a.attributes,l.attributes,o.undirected);this.emit("eachEdgeAttributesUpdated",{hints:r||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new rt("Graph.forEachAdjacencyEntry: expecting a callback.");En(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new rt("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");En(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new rt("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");En(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new rt("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");En(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new rt("Graph.forEachNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)i=n.value,t(i.key,i.attributes)}findNode(t){if(typeof t!="function")throw new rt("Graph.findNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,t(i.key,i.attributes))return i.key}mapNodes(t){if(typeof t!="function")throw new rt("Graph.mapNode: expecting a callback.");let r=this._nodes.values(),n,i,o=new Array(this.order),a=0;for(;n=r.next(),n.done!==!0;)i=n.value,o[a++]=t(i.key,i.attributes);return o}someNode(t){if(typeof t!="function")throw new rt("Graph.someNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,t(i.key,i.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new rt("Graph.everyNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,!t(i.key,i.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new rt("Graph.filterNodes: expecting a callback.");let r=this._nodes.values(),n,i,o=[];for(;n=r.next(),n.done!==!0;)i=n.value,t(i.key,i.attributes)&&o.push(i.key);return o}reduceNodes(t,r){if(typeof t!="function")throw new rt("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new rt("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let n=r,i=this._nodes.values(),o,a;for(;o=i.next(),o.done!==!0;)a=o.value,n=t(n,a.key,a.attributes);return n}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let r=t.next();if(r.done)return r;let n=r.value;return{value:{node:n.key,attributes:n.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),r=0;this._nodes.forEach((i,o)=>{t[r++]=Ac(o,i)});let n=new Array(this._edges.size);return r=0,this._edges.forEach((i,o)=>{n[r++]=Dc(this.type,o,i)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:n}}import(t,r=!1){if(t instanceof e)return t.forEachNode((g,f)=>{r?this.mergeNode(g,f):this.addNode(g,f)}),t.forEachEdge((g,f,p,y,w,S,A)=>{r?A?this.mergeUndirectedEdgeWithKey(g,p,y,f):this.mergeDirectedEdgeWithKey(g,p,y,f):A?this.addUndirectedEdgeWithKey(g,p,y,f):this.addDirectedEdgeWithKey(g,p,y,f)}),this;if(!he(t))throw new rt("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!he(t.attributes))throw new rt("Graph.import: invalid attributes. Expecting a plain object.");r?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let n,i,o,a,l;if(t.nodes){if(o=t.nodes,!Array.isArray(o))throw new rt("Graph.import: invalid nodes. Expecting an array.");for(n=0,i=o.length;n{let o=ee({},n.attributes);n=new r.NodeDataClass(i,o),r._nodes.set(i,n)}),r}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new ht(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new ht("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new ht("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let r=this.emptyCopy(t),n=this._edges.values(),i,o;for(;i=n.next(),i.done!==!0;)o=i.value,Ps(r,"copy",!1,o.undirected,o.key,o.source.key,o.target.key,ee({},o.attributes));return r}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((o,a)=>{t[a]=o.attributes});let r={},n={};this._edges.forEach((o,a)=>{let l=o.undirected?"--":"->",g="",f=o.source.key,p=o.target.key,y;o.undirected&&f>p&&(y=f,f=p,p=y);let w=`(${f})${l}(${p})`;a.startsWith("geid_")?this.multi&&(typeof n[w]>"u"?n[w]=0:n[w]++,g+=`${n[w]}. `):g+=`[${a}]: `,g+=w,r[g]=o.attributes});let i={};for(let o in this)this.hasOwnProperty(o)&&!Cs.has(o)&&typeof this[o]!="function"&&typeof o!="symbol"&&(i[o]=this[o]);return i.attributes=this._attributes,i.nodes=t,i.edges=r,je(i,"constructor",this.constructor),i}};typeof Symbol<"u"&&(Tt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Tt.prototype.inspect);_c.forEach(e=>{["add","merge","update"].forEach(t=>{let r=e.name(t),n=t==="add"?Ps:Tc;e.generateKey?Tt.prototype[r]=function(i,o,a){return n(this,r,!0,(e.type||this.type)==="undirected",null,i,o,a,t==="update")}:Tt.prototype[r]=function(i,o,a,l){return n(this,r,!1,(e.type||this.type)==="undirected",i,o,a,l,t==="update")}})});Fh(Tt);Hh(Tt);pc(Tt);Sc(Tt);var xn=class extends Tt{constructor(t){let r=ee({type:"directed"},t);if("multi"in r&&r.multi!==!1)throw new rt("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(r.type!=="directed")throw new rt('DirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},Sn=class extends Tt{constructor(t){let r=ee({type:"undirected"},t);if("multi"in r&&r.multi!==!1)throw new rt("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(r.type!=="undirected")throw new rt('UndirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},An=class extends Tt{constructor(t){let r=ee({multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(r)}},Dn=class extends Tt{constructor(t){let r=ee({type:"directed",multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(r.type!=="directed")throw new rt('MultiDirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},In=class extends Tt{constructor(t){let r=ee({type:"undirected",multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(r.type!=="undirected")throw new rt('MultiUndirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}};function Tr(e){e.from=function(t,r){let n=ee({},t.options,r),i=new e(n);return i.import(t),i}}Tr(Tt);Tr(xn);Tr(Sn);Tr(An);Tr(Dn);Tr(In);Tt.Graph=Tt;Tt.DirectedGraph=xn;Tt.UndirectedGraph=Sn;Tt.MultiGraph=An;Tt.MultiDirectedGraph=Dn;Tt.MultiUndirectedGraph=In;Tt.InvalidArgumentsGraphError=rt;Tt.NotFoundGraphError=Z;Tt.UsageGraphError=ht;var ci=Se(xo(),1),ng=Se(To(),1),ig=Se($o(),1);function Le(e,t,r,n){function i(o){return o instanceof r?o:new r(function(a){a(o)})}return new(r||(r=Promise))(function(o,a){function l(p){try{f(n.next(p))}catch(y){a(y)}}function g(p){try{f(n.throw(p))}catch(y){a(y)}}function f(p){p.done?o(p.value):i(p.value).then(l,g)}f((n=n.apply(e,t||[])).next())})}var wl={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},qt=class extends Error{constructor(t,r,n){super(t),this.position=r,this.token=n,this.name="ExpressionError"}},wt;(function(e){e[e.STRING=0]="STRING",e[e.NUMBER=1]="NUMBER",e[e.BOOLEAN=2]="BOOLEAN",e[e.NULL=3]="NULL",e[e.IDENTIFIER=4]="IDENTIFIER",e[e.OPERATOR=5]="OPERATOR",e[e.FUNCTION=6]="FUNCTION",e[e.DOT=7]="DOT",e[e.BRACKET_LEFT=8]="BRACKET_LEFT",e[e.BRACKET_RIGHT=9]="BRACKET_RIGHT",e[e.PAREN_LEFT=10]="PAREN_LEFT",e[e.PAREN_RIGHT=11]="PAREN_RIGHT",e[e.COMMA=12]="COMMA",e[e.QUESTION=13]="QUESTION",e[e.COLON=14]="COLON",e[e.DOLLAR=15]="DOLLAR"})(wt||(wt={}));var ml=new Set([32,9,10,13]),vl=new Set([43,45,42,47,37,33,38,124,61,60,62]),bl=new Map([["true",wt.BOOLEAN],["false",wt.BOOLEAN],["null",wt.NULL]]),ji=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),El=new Map([[46,wt.DOT],[91,wt.BRACKET_LEFT],[93,wt.BRACKET_RIGHT],[40,wt.PAREN_LEFT],[41,wt.PAREN_RIGHT],[44,wt.COMMA],[63,wt.QUESTION],[58,wt.COLON],[36,wt.DOLLAR]]),No=new Map;for(let[e,t]of El.entries())No.set(e,{type:t,value:String.fromCharCode(e)});function tn(e){return e>=48&&e<=57}function Ci(e){return e>=97&&e<=122||e>=65&&e<=90||e===95}function zo(e){return Ci(e)||tn(e)}function xl(e){return vl.has(e)}var Wt;(function(e){e[e.Program=0]="Program",e[e.Literal=1]="Literal",e[e.Identifier=2]="Identifier",e[e.MemberExpression=3]="MemberExpression",e[e.CallExpression=4]="CallExpression",e[e.BinaryExpression=5]="BinaryExpression",e[e.UnaryExpression=6]="UnaryExpression",e[e.ConditionalExpression=7]="ConditionalExpression"})(Wt||(Wt={}));var Sl=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),Al={type:Wt.Literal,value:null},Dl={type:Wt.Literal,value:!0},Il={type:Wt.Literal,value:!1},kl=e=>{let t=0,r=e.length,n=()=>t>=r?null:e[t],i=()=>e[t++],o=y=>{let w=n();return w!==null&&w.type===y},a=y=>y.type===wt.OPERATOR?Sl.get(y.value)||-1:y.type===wt.DOT||y.type===wt.BRACKET_LEFT?9:y.type===wt.QUESTION?1:-1,l=y=>{let w,S;if(i().type===wt.DOT){if(!o(wt.IDENTIFIER)){let I=n();throw new qt("Expected property name",t,I?I.value:"")}let A=i();w={type:Wt.Identifier,name:A.value},S=!1}else{if(w=f(0),!o(wt.BRACKET_RIGHT)){let A=n();throw new qt("Expected closing bracket",t,A?A.value:"")}i(),S=!0}return{type:Wt.MemberExpression,object:y,property:w,computed:S}},g=()=>{let y=n();if(!y)throw new qt("Unexpected end of input",t,"");if(y.type===wt.OPERATOR&&(y.value==="!"||y.value==="-")){i();let w=g();return{type:Wt.UnaryExpression,operator:y.value,argument:w,prefix:!0}}switch(y.type){case wt.NUMBER:return i(),{type:Wt.Literal,value:Number(y.value)};case wt.STRING:return i(),{type:Wt.Literal,value:y.value};case wt.BOOLEAN:return i(),y.value==="true"?Dl:Il;case wt.NULL:return i(),Al;case wt.IDENTIFIER:return i(),{type:Wt.Identifier,name:y.value};case wt.FUNCTION:return(()=>{let w=i(),S=[];if(!o(wt.PAREN_LEFT)){let A=n();throw new qt("Expected opening parenthesis after function name",t,A?A.value:"")}for(i();;){if(o(wt.PAREN_RIGHT)){i();break}if(!n()){let I=n();throw new qt("Expected closing parenthesis",t,I?I.value:"")}if(S.length>0){if(!o(wt.COMMA)){let I=n();throw new qt("Expected comma between function arguments",t,I?I.value:"")}i()}let A=f(0);S.push(A)}return{type:Wt.CallExpression,callee:{type:Wt.Identifier,name:w.value},arguments:S}})();case wt.PAREN_LEFT:{i();let w=f(0);if(!o(wt.PAREN_RIGHT)){let S=n();throw new qt("Expected closing parenthesis",t,S?S.value:"")}return i(),w}default:throw new qt(`Unexpected token: ${y.type}`,t,y.value)}},f=(y=0)=>{let w=g();for(;t")}i();let L=f(0);w={type:Wt.ConditionalExpression,test:w,consequent:I,alternate:L}}}return w},p=f();return{type:Wt.Program,body:p}},jl=(e,t,r)=>{let n=t;r&&(n={...t,context:{...t.context,...r}});let i=o=>{switch(o.type){case Wt.Literal:return(a=>a.value)(o);case Wt.Identifier:return(a=>{if(!(a.name in n.context))throw new qt(`Undefined variable: ${a.name}`);return n.context[a.name]})(o);case Wt.MemberExpression:return(a=>{let l=i(a.object);if(l==null)throw new qt("Cannot access property of null or undefined");return l[a.computed?i(a.property):a.property.name]})(o);case Wt.CallExpression:return(a=>{let l=n.functions[a.callee.name];if(!l)throw new qt(`Undefined function: ${a.callee.name}`);return l(...a.arguments.map((g=>i(g))))})(o);case Wt.BinaryExpression:return(a=>{if(a.operator==="&&"){let f=i(a.left);return f&&i(a.right)}if(a.operator==="||")return i(a.left)||i(a.right);let l=i(a.left),g=i(a.right);switch(a.operator){case"+":return l+g;case"-":return l-g;case"*":return l*g;case"/":return l/g;case"%":return l%g;case"===":return l===g;case"!==":return l!==g;case">":return l>g;case">=":return l>=g;case"<":return l{let l=i(a.argument);if(a.prefix)switch(a.operator){case"!":return!l;case"-":if(typeof l!="number")throw new qt(`Cannot apply unary - to non-number: ${l}`);return-l;default:throw new qt(`Unknown operator: ${a.operator}`)}throw new qt(`Postfix operators are not supported: ${a.operator}`)})(o);case Wt.ConditionalExpression:return(a=>{let l=i(a.test);return i(l?a.consequent:a.alternate)})(o);default:throw new qt(`Evaluation error: Unsupported node type: ${o.type}`)}};return i(e.body)};function _i(e){let t=(i=>{let o=i,a=o.length,l=new Array(Math.ceil(a/3)),g=0,f=0;function p(L){let $=f+1;f++;let j="",M=!1;for(;f({context:i,functions:o}))({},wl);return(i={})=>jl(r,n,i)}function Po(e,t={}){return _i(e)(t)}function Wo(e,t){if(typeof e!="string")return;let r=e.trim();if(r)try{return _i(r),Po(r,t)}catch{return}}function Gr(e){return typeof e=="number"}function Ri(e){if(!e)return[0,0,0];if(Gr(e))return[e,e,e];if(Array.isArray(e)&&e.length===0)return[0,0,0];let[t,r=t,n=t]=e;return[t,r,n]}function Fo(e){return Gr(e)?!0:Array.isArray(e)?e.every(t=>Gr(t)):!1}function Ne(e){return e==null}function qo(e){return typeof e=="string"}function Uo(e){return typeof e=="function"}function en(e,t){if(typeof e=="function")return e;if(typeof e=="string"){let r=e;return(...n)=>{let i={};for(let o=0;oe}function Bo(e,t=10,r="node"){if(Ne(e))return()=>t;if(qo(e)){let n=en(e,[r]);return i=>{let o=n(i);return Fo(o)?o:t}}return Uo(e)?e:Gr(e)?()=>e:Array.isArray(e)?()=>e:()=>t}var Rn=(e,t,r=10,n=0)=>{let i=Bo(t,n),o=Bo(e,r);return a=>{let[l,g,f]=Ri(o(a)),[p,y,w]=Ri(i(a));return[l+p,g+y,f+w]}};var Ln=class{constructor(t,r={}){this.edgeIdCounter=new Map,this.nodeMap=Rl(t.nodes,r.node),this.edgeMap=Ll(t.edges||[],r.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let r=this.indexNodeCache.get(t);return r?this.nodeMap.get(r):void 0}nodeIndexOf(t){var r;return this.nodeIndexCache||this.buildNodeIndexCache(),(r=this.nodeIndexCache.get(t))!==null&&r!==void 0?r:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let r=0;this.nodeMap.forEach(n=>t(n,r++))}originalNode(t){let r=this.nodeMap.get(t);return r?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let r=0;this.edgeMap.forEach(n=>t(n,r++))}originalEdge(t){let r=this.edgeMap.get(t);return r?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let r=`${t.source}-${t.target}`,n=this.edgeIdCounter.get(r)||0,i=n===0?r:`${r}-${n}`;return this.edgeIdCounter.set(r,n+1),i}degree(t,r="both"){this.degreeCache||this.buildDegreeCache();let n=this.degreeCache.get(t);return n?n[r]:0}neighbors(t,r="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),r==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(r==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let n=this.inAdjacencyCache.get(t),i=this.outAdjacencyCache.get(t);if(!n&&!i)return[];if(!n)return Array.from(i);if(!i)return Array.from(n);let o=new Set;return n.forEach(a=>o.add(a)),i.forEach(a=>o.add(a)),Array.from(o)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let r=new Map;for(let n of t)r.set(n.id,n);this.nodeMap=r,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:r,target:n}=t;if(t.source===t.target)continue;this.degreeCache.has(r)||this.degreeCache.set(r,{in:0,out:0,both:0});let i=this.degreeCache.get(t.source);i&&(i.out++,i.both++),this.degreeCache.has(n)||this.degreeCache.set(n,{in:0,out:0,both:0});let o=this.degreeCache.get(t.target);o&&(o.in++,o.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((r,n)=>{this.nodeIndexCache.set(n,t),this.indexNodeCache.set(t,n),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Cl=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],_l=["id","source","target","points"];function Rl(e,t){if(!e)throw new Error("Data.nodes is required");let r=new Map;for(let n of e){let i={_original:n};for(let o of Cl){let a=n[o];Ne(a)||(i[o]=a)}if(t){let o=t(n);for(let a in o){let l=o[a];Ne(l)||(i[a]=l)}}if(Ne(i.id))throw new Error("Node is missing id field");r.set(i.id,i)}return r}function Ll(e,t,r){let n=new Map;for(let i of e){let o={_original:i};for(let a of _l){let l=i[a];Ne(l)||(o[a]=l)}if(t){let a=t(i);for(let l in a){let g=a[l];Ne(g)||(o[l]=g)}}if(Ne(o.source)||Ne(o.target))throw new Error("Edge is missing source or target field");Ne(o.id)&&(o.id=r?.(i)),n.set(o.id,o)}return n}var Tn=class{constructor(t,r={}){this.graph=new Ln(t,r)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((r,n)=>{r.sourceNode=this.graph.node(r.source),r.targetNode=this.graph.node(r.target),t(r,n)})}destroy(){this.graph.destroy()}};var Ko=Symbol("Comlink.proxy"),Tl=Symbol("Comlink.endpoint"),Ml=Symbol("Comlink.releaseProxy"),Li=Symbol("Comlink.finalizer"),On=Symbol("Comlink.thrown"),Yo=e=>typeof e=="object"&&e!==null||typeof e=="function",Ol={canHandle:e=>Yo(e)&&e[Ko],serialize(e){let{port1:t,port2:r}=new MessageChannel;return Qo(e,t),[r,[r]]},deserialize(e){return e.start(),Mi(e)}},Gl={canHandle:e=>Yo(e)&&On in e,serialize({value:e}){let t;return e instanceof Error?t={isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:t={isError:!1,value:e},[t,[]]},deserialize(e){throw e.isError?Object.assign(new Error(e.value.message),e.value):e.value}},Xo=new Map([["proxy",Ol],["throw",Gl]]);function $l(e,t){for(let r of e)if(t===r||r==="*"||r instanceof RegExp&&r.test(t))return!0;return!1}function Qo(e,t=globalThis,r=["*"]){t.addEventListener("message",function n(i){if(!i||!i.data)return;if(!$l(r,i.origin)){console.warn(`Invalid origin '${i.origin}' for comlink proxy`);return}let{id:o,type:a,path:l}=Object.assign({path:[]},i.data),g=(i.data.argumentList||[]).map(mr),f;try{let p=l.slice(0,-1).reduce((w,S)=>w[S],e),y=l.reduce((w,S)=>w[S],e);switch(a){case"GET":f=y;break;case"SET":p[l.slice(-1)[0]]=mr(i.data.value),f=!0;break;case"APPLY":f=y.apply(p,g);break;case"CONSTRUCT":{let w=new y(...g);f=ql(w)}break;case"ENDPOINT":{let{port1:w,port2:S}=new MessageChannel;Qo(e,S),f=Fl(w,[w])}break;case"RELEASE":f=void 0;break;default:return}}catch(p){f={value:p,[On]:0}}Promise.resolve(f).catch(p=>({value:p,[On]:0})).then(p=>{let[y,w]=zn(p);t.postMessage(Object.assign(Object.assign({},y),{id:o}),w),a==="RELEASE"&&(t.removeEventListener("message",n),Jo(t),Li in e&&typeof e[Li]=="function"&&e[Li]())}).catch(p=>{let[y,w]=zn({value:new TypeError("Unserializable return value"),[On]:0});t.postMessage(Object.assign(Object.assign({},y),{id:o}),w)})}),t.start&&t.start()}function zl(e){return e.constructor.name==="MessagePort"}function Jo(e){zl(e)&&e.close()}function Mi(e,t){let r=new Map;return e.addEventListener("message",function(i){let{data:o}=i;if(!o||!o.id)return;let a=r.get(o.id);if(a)try{a(o)}finally{r.delete(o.id)}}),Ti(e,r,[],t)}function Mn(e){if(e)throw new Error("Proxy has been released and is not useable")}function Zo(e){return $r(e,new Map,{type:"RELEASE"}).then(()=>{Jo(e)})}var Gn=new WeakMap,$n="FinalizationRegistry"in globalThis&&new FinalizationRegistry(e=>{let t=(Gn.get(e)||0)-1;Gn.set(e,t),t===0&&Zo(e)});function Nl(e,t){let r=(Gn.get(t)||0)+1;Gn.set(t,r),$n&&$n.register(e,t,e)}function Pl(e){$n&&$n.unregister(e)}function Ti(e,t,r=[],n=function(){}){let i=!1,o=new Proxy(n,{get(a,l){if(Mn(i),l===Ml)return()=>{Pl(o),Zo(e),t.clear(),i=!0};if(l==="then"){if(r.length===0)return{then:()=>o};let g=$r(e,t,{type:"GET",path:r.map(f=>f.toString())}).then(mr);return g.then.bind(g)}return Ti(e,t,[...r,l])},set(a,l,g){Mn(i);let[f,p]=zn(g);return $r(e,t,{type:"SET",path:[...r,l].map(y=>y.toString()),value:f},p).then(mr)},apply(a,l,g){Mn(i);let f=r[r.length-1];if(f===Tl)return $r(e,t,{type:"ENDPOINT"}).then(mr);if(f==="bind")return Ti(e,t,r.slice(0,-1));let[p,y]=Vo(g);return $r(e,t,{type:"APPLY",path:r.map(w=>w.toString()),argumentList:p},y).then(mr)},construct(a,l){Mn(i);let[g,f]=Vo(l);return $r(e,t,{type:"CONSTRUCT",path:r.map(p=>p.toString()),argumentList:g},f).then(mr)}});return Nl(o,e),o}function Wl(e){return Array.prototype.concat.apply([],e)}function Vo(e){let t=e.map(zn);return[t.map(r=>r[0]),Wl(t.map(r=>r[1]))]}var Ho=new WeakMap;function Fl(e,t){return Ho.set(e,t),e}function ql(e){return Object.assign(e,{[Ko]:!0})}function zn(e){for(let[t,r]of Xo)if(r.canHandle(e)){let[n,i]=r.serialize(e);return[{type:"HANDLER",name:t,value:n},i]}return[{type:"RAW",value:e},Ho.get(e)||[]]}function mr(e){switch(e.type){case"HANDLER":return Xo.get(e.name).deserialize(e.value);case"RAW":return e.value}}function $r(e,t,r,n){return new Promise(i=>{let o=Ul();t.set(o,i),e.start&&e.start(),e.postMessage(Object.assign({id:o},r),n)})}function Ul(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var Nn=class{constructor(){this.worker=null,this.workerApi=null}execute(t,r,n){return Le(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,r,n)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return Le(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),n=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:n}),this.workerApi=Mi(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let r=document.currentScript;if(r?.src)return r.src;let n=document.getElementsByTagName("script");for(let i=n.length-1;i>=0;i--){let o=n[i].src;if(o&&(o.includes("index.js")||o.includes("index.min.js")))return o}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let i=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(i!==t)return i}let r=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(r!==t)return r;let n=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(n!==t)return n}return"./worker.js"}};var ar=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,r){return Object.assign({},t,r||{})}execute(t,r){return Le(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,r);let{node:n,edge:i,enableWorker:o}=this.runtimeOptions;this.context=new Tn(t,{node:n,edge:i}),this.model=this.context.graph,o&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,r){var n;return Le(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new Nn);let i=yield this.supervisor.execute(this.id,t,r);(n=this.context)===null||n===void 0||n.replace(i)}catch(i){console.error("Layout in worker failed, fallback to main thread layout.",i),yield this.layout(r)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function zr(e,t,r=2){if(e.nodeCount()===1){let i=e.firstNode();i.x=t[0],i.y=t[1],r===3&&(i.z=t[2]||0)}}function ta(e,t){let r=e.nodes();return r.sort(t),e.setNodeOrder(r),e}function ea(e,t="desc"){return ta(e,(r,n)=>{let i=e.degree(r.id),o=e.degree(n.id);return t==="asc"?i-o:o-i})}function ra(e,t){return ta(e,(r,n)=>{let i=e.originalNode(r.id),o=e.originalNode(n.id);return t(i,o)})}var Nr=e=>{let{width:t,height:r,center:n}=e,i=t??(typeof window<"u"?window.innerWidth:0),o=r??(typeof window<"u"?window.innerHeight:0),a=n??[i/2,o/2];return{width:i,height:o,center:a}};var Pn={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},Wn=class extends ar{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return Pn}layout(){return Le(this,void 0,void 0,function*(){let{width:t,height:r,center:n}=Nr(this.options),i=this.model.nodeCount();if(!i||i===1){zr(this.model,n);return}let{sortBy:o,maxLevelDiff:a,sweep:l,clockwise:g,equidistant:f,preventOverlap:p,startAngle:y=Pn.startAngle,nodeSize:w,nodeSpacing:S}=this.options,A=!o||o==="degree"?"degree":en(o,["node"]);if(A==="degree")ea(this.model);else{let G=(P,C)=>{let et=A(P),lt=A(C);return et===lt?0:et>lt?-1:1};ra(this.model,G)}let I=this.model.nodes(),L=new Map;for(let G of I){let P=A==="degree"?this.model.degree(G.id):A(G._original);L.set(G.id,P)}let $=this.model.firstNode(),j=a||L.get($.id)/4,M=Rn(w,S,Pn.nodeSize,Pn.nodeSpacing),W=new Map;for(let G of I)W.set(G.id,Math.max(...M(G._original)));let N=[{nodes:[]}],K=N[0];for(let G=0;G0){let C=K.nodes[0],et=Math.abs(L.get(C.id)-L.get(P.id));j&&et>=j&&(K={nodes:[]},N.push(K))}K.nodes.push(P)}for(let G of N){let P=G.nodes.map(C=>W.get(C.id));G.nodeSizes=P,G.maxNodeSize=Math.max(...P)}if(N.forEach(G=>{let P=l===void 0?2*Math.PI-2*Math.PI/G.nodes.length:l;G.dTheta=P/Math.max(1,G.nodes.length-1)}),p){let G=0;for(let P=0;P1){let et=C.nodeSizes||[],lt=0;for(let ne=0;ne0?lt/ft:0;G=Math.max(Nt,G)}if(C.r=G,P{et===0&&(P=C.r||0),C.r=P,P+=G})}N.forEach(G=>{let P=G.dTheta||0,C=G.r||0;G.nodes.forEach((et,lt)=>{let ct=y+(g?1:-1)*P*lt;et.x=n[0]+C*Math.cos(ct),et.y=n[1]+C*Math.sin(ct)})})})}};function na(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Fn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if(typeof t=="function"){var r=function n(){var i=!1;try{i=this instanceof n}catch{}return i?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}),r}var mt={};var Oi={};di(Oi,{isAnyArray:()=>ur});var Bl=Object.prototype.toString;function ur(e){let t=Bl.call(e);return t.endsWith("Array]")&&!t.includes("Big")}var ia=Fn(Oi);var Gi={};di(Gi,{default:()=>Vl});function sa(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!ur(e))throw new TypeError("input must be an array");if(e.length===0)throw new TypeError("input must not be empty");var r=t.fromIndex,n=r===void 0?0:r,i=t.toIndex,o=i===void 0?e.length:i;if(n<0||n>=e.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=n||o>e.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=e[n],l=n+1;la&&(a=e[l]);return a}function oa(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!ur(e))throw new TypeError("input must be an array");if(e.length===0)throw new TypeError("input must not be empty");var r=t.fromIndex,n=r===void 0?0:r,i=t.toIndex,o=i===void 0?e.length:i;if(n<0||n>=e.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(o<=n||o>e.length||!Number.isInteger(o))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=e[n],l=n+1;l1&&arguments[1]!==void 0?arguments[1]:{};if(ur(e)){if(e.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var r;if(t.output!==void 0){if(!ur(t.output))throw new TypeError("output option must be an array if specified");r=t.output}else r=new Array(e.length);var n=oa(e),i=sa(e);if(n===i)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var o=t.min,a=o===void 0?t.autoMinMax?n:0:o,l=t.max,g=l===void 0?t.autoMinMax?i:1:l;if(a>=g)throw new RangeError("min option must be smaller than max option");for(var f=(g-a)/(i-n),p=0;p{throw TypeError(e)};var zh=(e,t,r)=>t in e?Sn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var lt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),bi=(e,t)=>{for(var r in t)Sn(e,r,{get:t[r],enumerable:!0})},Ph=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Oh(t))!$h.call(e,i)&&i!==r&&Sn(e,i,{get:()=>t[i],enumerable:!(n=Mh(t,i))||n.enumerable});return e};var xe=(e,t,r)=>(r=e!=null?Th(Gh(e)):{},Ph(t||!e||!e.__esModule?Sn(r,"default",{value:e,enumerable:!0}):r,e));var Ss=(e,t,r)=>zh(e,typeof t!="symbol"?t+"":t,r),Ei=(e,t,r)=>t.has(e)||xs("Cannot "+r);var $e=(e,t,r)=>(Ei(e,t,"read from private field"),r?r.call(e):t.get(e)),xi=(e,t,r)=>t.has(e)?xs("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,r),An=(e,t,r,n)=>(Ei(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),Si=(e,t,r)=>(Ei(e,t,"access private method"),r);var Ms=lt((zg,Ai)=>{"use strict";var Rr=typeof Reflect=="object"?Reflect:null,As=Rr&&typeof Rr.apply=="function"?Rr.apply:function(t,r,n){return Function.prototype.apply.call(t,r,n)},Dn;Rr&&typeof Rr.ownKeys=="function"?Dn=Rr.ownKeys:Object.getOwnPropertySymbols?Dn=function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:Dn=function(t){return Object.getOwnPropertyNames(t)};function Nh(e){console&&console.warn&&console.warn(e)}var Is=Number.isNaN||function(t){return t!==t};function Rt(){Rt.init.call(this)}Ai.exports=Rt;Ai.exports.once=Uh;Rt.EventEmitter=Rt;Rt.prototype._events=void 0;Rt.prototype._eventsCount=0;Rt.prototype._maxListeners=void 0;var Ds=10;function In(e){if(typeof e!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}Object.defineProperty(Rt,"defaultMaxListeners",{enumerable:!0,get:function(){return Ds},set:function(e){if(typeof e!="number"||e<0||Is(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");Ds=e}});Rt.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};Rt.prototype.setMaxListeners=function(t){if(typeof t!="number"||t<0||Is(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this};function ks(e){return e._maxListeners===void 0?Rt.defaultMaxListeners:e._maxListeners}Rt.prototype.getMaxListeners=function(){return ks(this)};Rt.prototype.emit=function(t){for(var r=[],n=1;n0&&(a=r[0]),a instanceof Error)throw a;var l=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw l.context=a,l}var g=s[t];if(g===void 0)return!1;if(typeof g=="function")As(g,this,r);else for(var f=g.length,p=Rs(g,f),n=0;n0&&a.length>i&&!a.warned){a.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=e,l.type=t,l.count=a.length,Nh(l)}return e}Rt.prototype.addListener=function(t,r){return js(this,t,r,!1)};Rt.prototype.on=Rt.prototype.addListener;Rt.prototype.prependListener=function(t,r){return js(this,t,r,!0)};function Wh(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Cs(e,t,r){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:r},i=Wh.bind(n);return i.listener=r,n.wrapFn=i,i}Rt.prototype.once=function(t,r){return In(r),this.on(t,Cs(this,t,r)),this};Rt.prototype.prependOnceListener=function(t,r){return In(r),this.prependListener(t,Cs(this,t,r)),this};Rt.prototype.removeListener=function(t,r){var n,i,s,a,l;if(In(r),i=this._events,i===void 0)return this;if(n=i[t],n===void 0)return this;if(n===r||n.listener===r)--this._eventsCount===0?this._events=Object.create(null):(delete i[t],i.removeListener&&this.emit("removeListener",t,n.listener||r));else if(typeof n!="function"){for(s=-1,a=n.length-1;a>=0;a--)if(n[a]===r||n[a].listener===r){l=n[a].listener,s=a;break}if(s<0)return this;s===0?n.shift():Fh(n,s),n.length===1&&(i[t]=n[0]),i.removeListener!==void 0&&this.emit("removeListener",t,l||r)}return this};Rt.prototype.off=Rt.prototype.removeListener;Rt.prototype.removeAllListeners=function(t){var r,n,i;if(n=this._events,n===void 0)return this;if(n.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):n[t]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete n[t]),this;if(arguments.length===0){var s=Object.keys(n),a;for(i=0;i=0;i--)this.removeListener(t,r[i]);return this};function Ls(e,t,r){var n=e._events;if(n===void 0)return[];var i=n[t];return i===void 0?[]:typeof i=="function"?r?[i.listener||i]:[i]:r?qh(i):Rs(i,i.length)}Rt.prototype.listeners=function(t){return Ls(this,t,!0)};Rt.prototype.rawListeners=function(t){return Ls(this,t,!1)};Rt.listenerCount=function(e,t){return typeof e.listenerCount=="function"?e.listenerCount(t):_s.call(e,t)};Rt.prototype.listenerCount=_s;function _s(e){var t=this._events;if(t!==void 0){var r=t[e];if(typeof r=="function")return 1;if(r!==void 0)return r.length}return 0}Rt.prototype.eventNames=function(){return this._eventsCount>0?Dn(this._events):[]};function Rs(e,t){for(var r=new Array(t),n=0;n{function Jc(e){return!e||typeof e!="object"||typeof e=="function"||Array.isArray(e)||e instanceof Set||e instanceof Map||e instanceof RegExp||e instanceof Date}function Ks(e,t){e=e||{};var r={};for(var n in t){var i=e[n],s=t[n];if(!Jc(s)){r[n]=Ks(i,s);continue}i===void 0?r[n]=s:r[n]=i}return r}Xs.exports=Ks});var Xt=lt((Wg,Qs)=>{Qs.exports=function(t){return t!==null&&typeof t=="object"&&typeof t.addUndirectedEdgeWithKey=="function"&&typeof t.dropNode=="function"&&typeof t.multi=="boolean"}});var to=lt((Fg,Hs)=>{function Js(e){return function(t,r){return t+Math.floor(e()*(r-t+1))}}var Zs=Js(Math.random);Zs.createRandom=Js;Hs.exports=Zs});var io=lt((qg,no)=>{var Zc=to().createRandom;function eo(e){var t=Zc(e);return function(r){for(var n=r.length,i=n-1,s=-1;++s{var Hc=Re(),tl=Xt(),el=io(),rl={attributes:{x:"x",y:"y"},center:0,hierarchyAttributes:[],rng:Math.random,scale:1};function Se(e,t,r,n,i){this.wrappedCircle=i||null,this.children={},this.countChildren=0,this.id=e||null,this.next=null,this.previous=null,this.x=t||null,this.y=r||null,i?this.r=1010101:this.r=n||999}Se.prototype.hasChildren=function(){return this.countChildren>0};Se.prototype.addChild=function(e,t){this.children[e]=t,++this.countChildren};Se.prototype.getChild=function(e){if(!this.children.hasOwnProperty(e)){var t=new Se;this.children[e]=t,++this.countChildren}return this.children[e]};Se.prototype.applyPositionToChildren=function(){if(this.hasChildren()){var e=this;for(var t in e.children){var r=e.children[t];r.x+=e.x,r.y+=e.y,r.applyPositionToChildren()}}};function uo(e,t,r){for(var n in t.children){var i=t.children[n];i.hasChildren()?uo(e,i,r):r[i.id]={x:i.x,y:i.y}}}function Mn(e,t){var r=e.r-t.r,n=t.x-e.x,i=t.y-e.y;return r<0||r*r0&&r*r>n*n+i*i}function Li(e,t){for(var r=0;rg?(i=(f+g-s)/(2*f),l=Math.sqrt(Math.max(0,g/f-i*i)),r.x=e.x-i*n-l*a,r.y=e.y-i*a+l*n):(i=(f+s-g)/(2*f),l=Math.sqrt(Math.max(0,s/f-i*i)),r.x=t.x+i*n-l*a,r.y=t.y+i*a+l*n)):(r.x=t.x+r.r,r.y=t.y)}function ao(e,t){var r=e.r+t.r-1e-6,n=t.x-e.x,i=t.y-e.y;return r>0&&r*r>n*n+i*i}function al(e,t){var r=e.length;if(r===0)return 0;var n,i,s,a,l,g,f,p,y,w;if(n=e[0],n.x=0,n.y=0,r<=1)return n.r;if(i=e[1],n.x=-i.r,i.x=n.r,i.y=0,r<=2)return n.r+i.r;s=e[2],oo(i,n,s),n=new Se(null,null,null,null,n),i=new Se(null,null,null,null,i),s=new Se(null,null,null,null,s),n.next=s.previous=i,i.next=n.previous=s,s.next=i.previous=n;t:for(g=3;g{var hl=Re(),cl=Xt(),ll={dimensions:["x","y"],center:.5,scale:1};function wo(e,t,r){if(!cl(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");r=hl(r,ll);var n=r.dimensions;if(!Array.isArray(n)||n.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");var i=r.center,s=r.scale,a=Math.PI*2,l=(i-.5)*s,g=t.order,f=n[0],p=n[1];function y(A,I){return I[f]=s*Math.cos(A*a/g)+l,I[p]=s*Math.sin(A*a/g)+l,I}var w=0;if(!e){var E={};return t.forEachNode(function(A){E[A]=y(w++,{})}),E}t.updateEachNodeAttributes(function(A,I){return y(w++,I),I},{attributes:n})}var mo=wo.bind(null,!1);mo.assign=wo.bind(null,!0);vo.exports=mo});var Ao=lt((Vg,So)=>{var fl=Re(),dl=Xt(),gl={dimensions:["x","y"],center:.5,rng:Math.random,scale:1};function Eo(e,t,r){if(!dl(t))throw new Error("graphology-layout/random: the given graph is not a valid graphology instance.");r=fl(r,gl);var n=r.dimensions;if(!Array.isArray(n)||n.length<1)throw new Error("graphology-layout/random: given dimensions are invalid.");var i=n.length,s=r.center,a=r.rng,l=r.scale,g=(s-.5)*l;function f(y){for(var w=0;w{var pl=Re(),yl=Xt(),wl=Math.PI/180,ml={dimensions:["x","y"],centeredOnZero:!1,degrees:!1};function Do(e,t,r,n){if(!yl(t))throw new Error("graphology-layout/rotation: the given graph is not a valid graphology instance.");n=pl(n,ml),n.degrees&&(r*=wl);var i=n.dimensions;if(!Array.isArray(i)||i.length!==2)throw new Error("graphology-layout/random: given dimensions are invalid.");if(t.order===0)return e?void 0:{};var s=i[0],a=i[1],l=0,g=0;if(!n.centeredOnZero){var f=1/0,p=-1/0,y=1/0,w=-1/0;t.forEachNode(function($,j){var R=j[s],W=j[a];Rp&&(p=R),Ww&&(w=W)}),l=(f+p)/2,g=(y+w)/2}var E=Math.cos(r),A=Math.sin(r);function I($){var j=$[s],R=$[a];return $[s]=l+(j-l)*E-(R-g)*A,$[a]=g+(j-l)*A+(R-g)*E,$}if(!e){var _={};return t.forEachNode(function($,j){var R={};R[s]=j[s],R[a]=j[a],_[$]=I(R)}),_}t.updateEachNodeAttributes(function($,j){return I(j),j},{attributes:i})}var Io=Do.bind(null,!1);Io.assign=Do.bind(null,!0);ko.exports=Io});var Co=lt(tn=>{tn.circlepack=yo();tn.circular=bo();tn.random=Ao();tn.rotation=jo()});var $r=lt(On=>{function vl(e){return typeof e!="number"||isNaN(e)?1:e}function bl(e,t){var r={},n=function(a){return typeof a>"u"?t:a};typeof t=="function"&&(n=t);var i=function(a){return n(a[e])},s=function(){return n(void 0)};return typeof e=="string"?(r.fromAttributes=i,r.fromGraph=function(a,l){return i(a.getNodeAttributes(l))},r.fromEntry=function(a,l){return i(l)}):typeof e=="function"?(r.fromAttributes=function(){throw new Error("graphology-utils/getters/createNodeValueGetter: irrelevant usage.")},r.fromGraph=function(a,l){return n(e(l,a.getNodeAttributes(l)))},r.fromEntry=function(a,l){return n(e(a,l))}):(r.fromAttributes=s,r.fromGraph=s,r.fromEntry=s),r}function Lo(e,t){var r={},n=function(a){return typeof a>"u"?t:a};typeof t=="function"&&(n=t);var i=function(a){return n(a[e])},s=function(){return n(void 0)};return typeof e=="string"?(r.fromAttributes=i,r.fromGraph=function(a,l){return i(a.getEdgeAttributes(l))},r.fromEntry=function(a,l){return i(l)},r.fromPartialEntry=r.fromEntry,r.fromMinimalEntry=r.fromEntry):typeof e=="function"?(r.fromAttributes=function(){throw new Error("graphology-utils/getters/createEdgeValueGetter: irrelevant usage.")},r.fromGraph=function(a,l){var g=a.extremities(l);return n(e(l,a.getEdgeAttributes(l),g[0],g[1],a.getNodeAttributes(g[0]),a.getNodeAttributes(g[1]),a.isUndirected(l)))},r.fromEntry=function(a,l,g,f,p,y,w){return n(e(a,l,g,f,p,y,w))},r.fromPartialEntry=function(a,l,g,f){return n(e(a,l,g,f))},r.fromMinimalEntry=function(a,l){return n(e(a,l))}):(r.fromAttributes=s,r.fromGraph=s,r.fromEntry=s,r.fromMinimalEntry=s),r}On.createNodeValueGetter=bl;On.createEdgeValueGetter=Lo;On.createEdgeWeightGetter=function(e){return Lo(e,vl)}});var Oo=lt((Qg,Mo)=>{var Ht=0,Wt=1,kt=2,jt=3,er=4,rr=5,Ct=6,_o=7,Gn=8,Ro=9,El=0,xl=1,Sl=2,se=0,Te=1,me=2,vr=3,ar=4,qt=5,Ae=6,Ve=7,Ye=8,To=3,Pe=10,Al=3,de=9,_i=10;Mo.exports=function(t,r,n){var i,s,a,l,g,f,p,y,w,E,A=r.length,I=n.length,_=t.adjustSizes,$=t.barnesHutTheta*t.barnesHutTheta,j,R,W,z,V,G,P,C=[];for(a=0;aM?(at-=(gt-M)/2,vt=at+gt):(H-=(M-gt)/2,ut=H+M),C[0+se]=-1,C[0+Te]=(H+ut)/2,C[0+me]=(at+vt)/2,C[0+vr]=Math.max(ut-H,vt-at),C[0+ar]=-1,C[0+qt]=-1,C[0+Ae]=0,C[0+Ve]=0,C[0+Ye]=0,i=1,a=0;a=0){r[a+Ht]=0)if(G=Math.pow(r[a+Ht]-C[s+Ve],2)+Math.pow(r[a+Wt]-C[s+Ye],2),E=C[s+vr],4*E*E/G<$){if(W=r[a+Ht]-C[s+Ve],z=r[a+Wt]-C[s+Ye],_===!0?G>0?(P=R*r[a+Ct]*C[s+Ae]/G,r[a+kt]+=W*P,r[a+jt]+=z*P):G<0&&(P=-R*r[a+Ct]*C[s+Ae]/Math.sqrt(G),r[a+kt]+=W*P,r[a+jt]+=z*P):G>0&&(P=R*r[a+Ct]*C[s+Ae]/G,r[a+kt]+=W*P,r[a+jt]+=z*P),s=C[s+ar],s<0)break;continue}else{s=C[s+qt];continue}else{if(f=C[s+se],f>=0&&f!==a&&(W=r[a+Ht]-r[f+Ht],z=r[a+Wt]-r[f+Wt],G=W*W+z*z,_===!0?G>0?(P=R*r[a+Ct]*r[f+Ct]/G,r[a+kt]+=W*P,r[a+jt]+=z*P):G<0&&(P=-R*r[a+Ct]*r[f+Ct]/Math.sqrt(G),r[a+kt]+=W*P,r[a+jt]+=z*P):G>0&&(P=R*r[a+Ct]*r[f+Ct]/G,r[a+kt]+=W*P,r[a+jt]+=z*P)),s=C[s+ar],s<0)break;continue}else for(R=t.scalingRatio,l=0;l0?(P=R*r[l+Ct]*r[g+Ct]/G/G,r[l+kt]+=W*P,r[l+jt]+=z*P,r[g+kt]-=W*P,r[g+jt]-=z*P):G<0&&(P=100*R*r[l+Ct]*r[g+Ct],r[l+kt]+=W*P,r[l+jt]+=z*P,r[g+kt]-=W*P,r[g+jt]-=z*P)):(G=Math.sqrt(W*W+z*z),G>0&&(P=R*r[l+Ct]*r[g+Ct]/G/G,r[l+kt]+=W*P,r[l+jt]+=z*P,r[g+kt]-=W*P,r[g+jt]-=z*P));for(w=t.gravity/t.scalingRatio,R=t.scalingRatio,a=0;a0&&(P=R*r[a+Ct]*w):G>0&&(P=R*r[a+Ct]*w/G),r[a+kt]-=W*P,r[a+jt]-=z*P;for(R=1*(t.outboundAttractionDistribution?j:1),p=0;p0&&(P=-R*V*Math.log(1+G)/G/r[l+Ct]):G>0&&(P=-R*V*Math.log(1+G)/G):t.outboundAttractionDistribution?G>0&&(P=-R*V/r[l+Ct]):G>0&&(P=-R*V)):(G=Math.sqrt(Math.pow(W,2)+Math.pow(z,2)),t.linLogMode?t.outboundAttractionDistribution?G>0&&(P=-R*V*Math.log(1+G)/G/r[l+Ct]):G>0&&(P=-R*V*Math.log(1+G)/G):t.outboundAttractionDistribution?(G=1,P=-R*V/r[l+Ct]):(G=1,P=-R*V)),G>0&&(r[l+kt]+=W*P,r[l+jt]+=z*P,r[g+kt]-=W*P,r[g+jt]-=z*P);var ae,be,J,L,bt,At;if(_===!0)for(a=0;a_i&&(r[a+kt]=r[a+kt]*_i/ae,r[a+jt]=r[a+jt]*_i/ae),be=r[a+Ct]*Math.sqrt((r[a+er]-r[a+kt])*(r[a+er]-r[a+kt])+(r[a+rr]-r[a+jt])*(r[a+rr]-r[a+jt])),J=Math.sqrt((r[a+er]+r[a+kt])*(r[a+er]+r[a+kt])+(r[a+rr]+r[a+jt])*(r[a+rr]+r[a+jt]))/2,L=.1*Math.log(1+J)/(1+Math.sqrt(be)),bt=r[a+Ht]+r[a+kt]*(L/t.slowDown),r[a+Ht]=bt,At=r[a+Wt]+r[a+jt]*(L/t.slowDown),r[a+Wt]=At);else for(a=0;a{var en=10,Go=3;ur.assign=function(e){e=e||{};var t=Array.prototype.slice.call(arguments).slice(1),r,n,i;for(r=0,i=t.length;r=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:"strongGravityMode"in e&&typeof e.strongGravityMode!="boolean"?{message:"the `strongGravityMode` setting should be a boolean."}:"gravity"in e&&!(typeof e.gravity=="number"&&e.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:"slowDown"in e&&!(typeof e.slowDown=="number"||e.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:"barnesHutOptimize"in e&&typeof e.barnesHutOptimize!="boolean"?{message:"the `barnesHutOptimize` setting should be a boolean."}:"barnesHutTheta"in e&&!(typeof e.barnesHutTheta=="number"&&e.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null};ur.graphToByteArrays=function(e,t){var r=e.order,n=e.size,i={},s,a=new Float32Array(r*en),l=new Float32Array(n*Go);return s=0,e.forEachNode(function(g,f){i[g]=s,a[s]=f.x,a[s+1]=f.y,a[s+2]=0,a[s+3]=0,a[s+4]=0,a[s+5]=0,a[s+6]=1,a[s+7]=1,a[s+8]=f.size||1,a[s+9]=f.fixed?1:0,s+=en}),s=0,e.forEachEdge(function(g,f,p,y,w,E,A){var I=i[p],_=i[y],$=t(g,f,p,y,w,E,A);a[I+6]+=$,a[_+6]+=$,l[s]=I,l[s+1]=_,l[s+2]=$,s+=Go}),{nodes:a,edges:l}};ur.assignLayoutChanges=function(e,t,r){var n=0;e.updateEachNodeAttributes(function(i,s){return s.x=t[n],s.y=t[n+1],n+=en,r?r(i,s):s})};ur.readGraphPositions=function(e,t){var r=0;e.forEachNode(function(n,i){t[r]=i.x,t[r+1]=i.y,r+=en})};ur.collectLayoutChanges=function(e,t,r){for(var n=e.nodes(),i={},s=0,a=0,l=t.length;s{$o.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}});var No=lt((Hg,Po)=>{var Dl=Xt(),Il=$r().createEdgeWeightGetter,kl=Oo(),rn=Ri(),jl=Ti();function zo(e,t,r){if(!Dl(t))throw new Error("graphology-layout-forceatlas2: the given graph is not a valid graphology instance.");typeof r=="number"&&(r={iterations:r});var n=r.iterations;if(typeof n!="number")throw new Error("graphology-layout-forceatlas2: invalid number of iterations.");if(n<=0)throw new Error("graphology-layout-forceatlas2: you should provide a positive number of iterations.");var i=Il("getEdgeWeight"in r?r.getEdgeWeight:"weight").fromEntry,s=typeof r.outputReducer=="function"?r.outputReducer:null,a=rn.assign({},jl,r.settings),l=rn.validateSettings(a);if(l)throw new Error("graphology-layout-forceatlas2: "+l.message);var g=rn.graphToByteArrays(t,i),f;for(f=0;f2e3,strongGravityMode:!0,gravity:.05,scalingRatio:10,slowDown:1+Math.log(t)}}var Mi=zo.bind(null,!1);Mi.assign=zo.bind(null,!0);Mi.inferSettings=Cl;Po.exports=Mi});var Fo=lt((tp,Wo)=>{Wo.exports=function(){var t,r,n={};(function(){var s=0,a=1,l=2,g=3,f=4,p=5,y=6,w=7,E=8,A=9,I=0,_=1,$=2,j=0,R=1,W=2,z=3,V=4,G=5,P=6,C=7,H=8,ut=3,at=10,vt=3,ft=9,Ot=10;n.exports=function(gt,M,ae){var be,J,L,bt,At,K,Zt,It,st,sr,pe=M.length,Ar=ae.length,Ce=gt.adjustSizes,Dr=gt.barnesHutTheta*gt.barnesHutTheta,Fe,Dt,xt,Et,ye,it,ht,q=[];for(L=0;Lkr?(Ee-=(Ir-kr)/2,or=Ee+Ir):(ue-=(kr-Ir)/2,qe=ue+kr),q[0+j]=-1,q[0+R]=(ue+qe)/2,q[0+W]=(Ee+or)/2,q[0+z]=Math.max(qe-ue,or-Ee),q[0+V]=-1,q[0+G]=-1,q[0+P]=0,q[0+C]=0,q[0+H]=0,be=1,L=0;L=0){M[L+s]=0)if(it=Math.pow(M[L+s]-q[J+C],2)+Math.pow(M[L+a]-q[J+H],2),sr=q[J+z],4*sr*sr/it0?(ht=Dt*M[L+y]*q[J+P]/it,M[L+l]+=xt*ht,M[L+g]+=Et*ht):it<0&&(ht=-Dt*M[L+y]*q[J+P]/Math.sqrt(it),M[L+l]+=xt*ht,M[L+g]+=Et*ht):it>0&&(ht=Dt*M[L+y]*q[J+P]/it,M[L+l]+=xt*ht,M[L+g]+=Et*ht),J=q[J+V],J<0)break;continue}else{J=q[J+G];continue}else{if(K=q[J+j],K>=0&&K!==L&&(xt=M[L+s]-M[K+s],Et=M[L+a]-M[K+a],it=xt*xt+Et*Et,Ce===!0?it>0?(ht=Dt*M[L+y]*M[K+y]/it,M[L+l]+=xt*ht,M[L+g]+=Et*ht):it<0&&(ht=-Dt*M[L+y]*M[K+y]/Math.sqrt(it),M[L+l]+=xt*ht,M[L+g]+=Et*ht):it>0&&(ht=Dt*M[L+y]*M[K+y]/it,M[L+l]+=xt*ht,M[L+g]+=Et*ht)),J=q[J+V],J<0)break;continue}else for(Dt=gt.scalingRatio,bt=0;bt0?(ht=Dt*M[bt+y]*M[At+y]/it/it,M[bt+l]+=xt*ht,M[bt+g]+=Et*ht,M[At+l]-=xt*ht,M[At+g]-=Et*ht):it<0&&(ht=100*Dt*M[bt+y]*M[At+y],M[bt+l]+=xt*ht,M[bt+g]+=Et*ht,M[At+l]-=xt*ht,M[At+g]-=Et*ht)):(it=Math.sqrt(xt*xt+Et*Et),it>0&&(ht=Dt*M[bt+y]*M[At+y]/it/it,M[bt+l]+=xt*ht,M[bt+g]+=Et*ht,M[At+l]-=xt*ht,M[At+g]-=Et*ht));for(st=gt.gravity/gt.scalingRatio,Dt=gt.scalingRatio,L=0;L0&&(ht=Dt*M[L+y]*st):it>0&&(ht=Dt*M[L+y]*st/it),M[L+l]-=xt*ht,M[L+g]-=Et*ht;for(Dt=1*(gt.outboundAttractionDistribution?Fe:1),Zt=0;Zt0&&(ht=-Dt*ye*Math.log(1+it)/it/M[bt+y]):it>0&&(ht=-Dt*ye*Math.log(1+it)/it):gt.outboundAttractionDistribution?it>0&&(ht=-Dt*ye/M[bt+y]):it>0&&(ht=-Dt*ye)):(it=Math.sqrt(Math.pow(xt,2)+Math.pow(Et,2)),gt.linLogMode?gt.outboundAttractionDistribution?it>0&&(ht=-Dt*ye*Math.log(1+it)/it/M[bt+y]):it>0&&(ht=-Dt*ye*Math.log(1+it)/it):gt.outboundAttractionDistribution?(it=1,ht=-Dt*ye/M[bt+y]):(it=1,ht=-Dt*ye)),it>0&&(M[bt+l]+=xt*ht,M[bt+g]+=Et*ht,M[At+l]-=xt*ht,M[At+g]-=Et*ht);var jr,mr,Cr,Ue,Lr,_r;if(Ce===!0)for(L=0;LOt&&(M[L+l]=M[L+l]*Ot/jr,M[L+g]=M[L+g]*Ot/jr),mr=M[L+y]*Math.sqrt((M[L+f]-M[L+l])*(M[L+f]-M[L+l])+(M[L+p]-M[L+g])*(M[L+p]-M[L+g])),Cr=Math.sqrt((M[L+f]+M[L+l])*(M[L+f]+M[L+l])+(M[L+p]+M[L+g])*(M[L+p]+M[L+g]))/2,Ue=.1*Math.log(1+Cr)/(1+Math.sqrt(mr)),Lr=M[L+s]+M[L+l]*(Ue/gt.slowDown),M[L+s]=Lr,_r=M[L+a]+M[L+g]*(Ue/gt.slowDown),M[L+a]=_r);else for(L=0;L{var Ll=Fo(),_l=Xt(),Rl=$r().createEdgeWeightGetter,zr=Ri(),Tl=Ti();function hr(e,t){if(t=t||{},!_l(e))throw new Error("graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.");var r=Rl("getEdgeWeight"in t?t.getEdgeWeight:"weight").fromEntry,n=zr.assign({},Tl,t.settings),i=zr.validateSettings(n);if(i)throw new Error("graphology-layout-forceatlas2/worker: "+i.message);this.worker=null,this.graph=e,this.settings=n,this.getEdgeWeight=r,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer=="function"?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var s=void 0,a=this;this.handleGraphUpdate=function(){a.worker&&a.worker.terminate(),s&&clearTimeout(s),s=setTimeout(function(){s=void 0,a.spawnWorker()},0)},e.on("nodeAdded",this.handleGraphUpdate),e.on("edgeAdded",this.handleGraphUpdate),e.on("nodeDropped",this.handleGraphUpdate),e.on("edgeDropped",this.handleGraphUpdate),this.spawnWorker()}hr.prototype.isRunning=function(){return this.running};hr.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=zr.createWorker(Ll),this.worker.addEventListener("message",this.handleMessage),this.running&&(this.running=!1,this.start())};hr.prototype.handleMessage=function(e){if(this.running){var t=new Float32Array(e.data.nodes);zr.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&zr.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}};hr.prototype.askForIterations=function(e){var t=this.matrices,r={settings:this.settings,nodes:t.nodes.buffer},n=[t.nodes.buffer];return e&&(r.edges=t.edges.buffer,n.push(t.edges.buffer)),this.worker.postMessage(r,n),this};hr.prototype.start=function(){if(this.killed)throw new Error("graphology-layout-forceatlas2/worker.start: layout was killed.");return this.running?this:(this.matrices=zr.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)};hr.prototype.stop=function(){return this.running=!1,this};hr.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener("nodeAdded",this.handleGraphUpdate),this.graph.removeListener("edgeAdded",this.handleGraphUpdate),this.graph.removeListener("nodeDropped",this.handleGraphUpdate),this.graph.removeListener("edgeDropped",this.handleGraphUpdate)};qo.exports=hr});var Yo=lt((rp,Vo)=>{var nn=0,sn=1,$n=2,on=3;function Ml(e,t){return e+"\xA7"+t}function Bo(){return .01*(.5-Math.random())}Vo.exports=function(t,r){var n=t.margin,i=t.ratio,s=t.expansion,a=t.gridSize,l=t.speed,g,f,p,y,w,E,A=!0,I=r.length,_=I/on|0,$=new Float32Array(_),j=new Float32Array(_),R=1/0,W=1/0,z=-1/0,V=-1/0;for(g=0;g1&&K.has(Fe))&&(at>1&&K.add(Fe),sr=r[It+nn],Ar=r[It+sn],Dr=r[It+$n],Dt=sr-st,xt=Ar-pe,Et=Math.sqrt(Dt*Dt+xt*xt),ye=Et0?($[It]+=Dt/Et*(1+Ce),j[It]+=xt/Et*(1+Ce)):($[It]+=G*Bo(),j[It]+=P*Bo())));for(g=0,f=0;g{var zn=3;Pr.validateSettings=function(e){return"gridSize"in e&&typeof e.gridSize!="number"||e.gridSize<=0?{message:"the `gridSize` setting should be a positive number."}:"margin"in e&&typeof e.margin!="number"||e.margin<0?{message:"the `margin` setting should be 0 or a positive number."}:"expansion"in e&&typeof e.expansion!="number"||e.expansion<=0?{message:"the `expansion` setting should be a positive number."}:"ratio"in e&&typeof e.ratio!="number"||e.ratio<=0?{message:"the `ratio` setting should be a positive number."}:"speed"in e&&typeof e.speed!="number"||e.speed<=0?{message:"the `speed` setting should be a positive number."}:null};Pr.graphToByteArray=function(e,t){var r=e.order,n=new Float32Array(r*zn),i=0;return e.forEachNode(function(s,a){typeof t=="function"&&(a=t(s,a)),n[i]=a.x,n[i+1]=a.y,n[i+2]=a.size||1,i+=zn}),n};Pr.assignLayoutChanges=function(e,t,r){var n=0;e.forEachNode(function(i){var s={x:t[n],y:t[n+1]};typeof r=="function"&&(s=r(i,s)),e.mergeNodeAttributes(i,s),n+=zn})};Pr.collectLayoutChanges=function(e,t,r){var n={},i=0;return e.forEachNode(function(s){var a={x:t[i],y:t[i+1]};typeof r=="function"&&(a=r(s,a)),n[s]=a,i+=zn}),n};Pr.createWorker=function(t){var r=window.URL||window.webkitURL,n=t.toString(),i=r.createObjectURL(new Blob(["("+n+").call(this);"],{type:"text/javascript"})),s=new Worker(i);return r.revokeObjectURL(i),s}});var Qo=lt((ip,Xo)=>{Xo.exports={gridSize:20,margin:5,expansion:1.1,ratio:1,speed:3}});var ta=lt((sp,Ho)=>{var Ol=Xt(),Gl=Yo(),Pn=Ko(),$l=Qo(),zl=500;function Jo(e,t,r){if(!Ol(t))throw new Error("graphology-layout-noverlap: the given graph is not a valid graphology instance.");typeof r=="number"?r={maxIterations:r}:r=r||{};var n=r.maxIterations||zl;if(typeof n!="number"||n<=0)throw new Error("graphology-layout-force: you should provide a positive number of maximum iterations.");var i=Object.assign({},$l,r.settings),s=Pn.validateSettings(i);if(s)throw new Error("graphology-layout-noverlap: "+s.message);var a=Pn.graphToByteArray(t,r.inputReducer),l=!1,g;for(g=0;g{var Bf=Xt();function Br(e,t,r,n){var i=t+"Centrality";if(!Bf(r))throw new Error("graphology-centrality/"+i+": the given graph is not a valid graphology instance.");if(t!=="degree"&&r.type==="undirected")throw new Error("graphology-centrality/"+i+": cannot compute "+t+" centrality on an undirected graph.");n=n||{};var s=n.nodeCentralityAttribute||i,a=r.order-1,l=r[t].bind(r);if(e){r.updateEachNodeAttributes(function(f,p){return p[s]=l(f)/a,p},{attributes:[s]});return}var g={};return r.forEachNode(function(f){g[f]=l(f)/a}),g}var Fa=Br.bind(null,!1,"degree"),qa=Br.bind(null,!1,"inDegree"),Ua=Br.bind(null,!1,"outDegree");Fa.assign=Br.bind(null,!0,"degree");qa.assign=Br.bind(null,!0,"inDegree");Ua.assign=Br.bind(null,!0,"outDegree");hi.degreeCentrality=Fa;hi.inDegreeCentrality=qa;hi.outDegreeCentrality=Ua});var Va=lt(is=>{is.ARRAY_BUFFER_SUPPORT=typeof ArrayBuffer<"u";is.SYMBOL_SUPPORT=typeof Symbol<"u"});var ci=lt((zy,Ka)=>{var Ya=Va(),Vf=Ya.ARRAY_BUFFER_SUPPORT,Yf=Ya.SYMBOL_SUPPORT;Ka.exports=function(t,r){var n,i,s,a,l;if(!t)throw new Error("obliterator/forEach: invalid iterable.");if(typeof r!="function")throw new Error("obliterator/forEach: expecting a callback.");if(Array.isArray(t)||Vf&&ArrayBuffer.isView(t)||typeof t=="string"||t.toString()==="[object Arguments]"){for(s=0,a=t.length;s{var Kf=Math.pow(2,8)-1,Xf=Math.pow(2,16)-1,Qf=Math.pow(2,32)-1,Jf=Math.pow(2,7)-1,Zf=Math.pow(2,15)-1,Hf=Math.pow(2,31)-1;Xe.getPointerArray=function(e){var t=e-1;if(t<=Kf)return Uint8Array;if(t<=Xf)return Uint16Array;if(t<=Qf)return Uint32Array;throw new Error("mnemonist: Pointer Array of size > 4294967295 is not supported.")};Xe.getSignedPointerArray=function(e){var t=e-1;return t<=Jf?Int8Array:t<=Zf?Int16Array:t<=Hf?Int32Array:Float64Array};Xe.getNumberType=function(e){return e===(e|0)?Math.sign(e)===-1?e<=127&&e>=-128?Int8Array:e<=32767&&e>=-32768?Int16Array:Int32Array:e<=255?Uint8Array:e<=65535?Uint16Array:Uint32Array:Float64Array};var td={Uint8Array:1,Int8Array:2,Uint16Array:3,Int16Array:4,Uint32Array:5,Int32Array:6,Float32Array:7,Float64Array:8};Xe.getMinimalRepresentation=function(e,t){var r=null,n=0,i,s,a,l,g;for(l=0,g=e.length;ln&&(n=i,r=s);return r};Xe.isTypedArray=function(e){return typeof ArrayBuffer<"u"&&ArrayBuffer.isView(e)};Xe.concat=function(){var e=0,t,r,n;for(t=0,n=arguments.length;t{var Xa=ci(),Qa=gr();function ed(e){return Array.isArray(e)||Qa.isTypedArray(e)}function ss(e){if(typeof e.length=="number")return e.length;if(typeof e.size=="number")return e.size}function rd(e){var t=ss(e),r=typeof t=="number"?new Array(t):[],n=0;return Xa(e,function(i){r[n++]=i}),r}function nd(e){var t=ss(e),r=typeof t=="number"?Qa.getPointerArray(t):Array,n=typeof t=="number"?new Array(t):[],i=typeof t=="number"?new r(t):[],s=0;return Xa(e,function(a){n[s]=a,i[s]=s++}),[n,i]}gn.isArrayLike=ed;gn.guessLength=ss;gn.toArray=rd;gn.toArrayWithIndices=nd});var xr=lt((Wy,Ja)=>{function Qe(e){if(typeof e!="function")throw new Error("obliterator/iterator: expecting a function!");this.next=e}typeof Symbol<"u"&&(Qe.prototype[Symbol.iterator]=function(){return this});Qe.of=function(){var e=arguments,t=e.length,r=0;return new Qe(function(){return r>=t?{done:!0}:{done:!1,value:e[r++]}})};Qe.empty=function(){var e=new Qe(function(){return{done:!0}});return e};Qe.fromSequence=function(e){var t=0,r=e.length;return new Qe(function(){return t>=r?{done:!0}:{done:!1,value:e[t++]}})};Qe.is=function(e){return e instanceof Qe?!0:typeof e=="object"&&e!==null&&typeof e.next=="function"};Ja.exports=Qe});var as=lt((Fy,Ha)=>{var os=li(),Za=xr();function Qt(e,t){if(arguments.length<2)throw new Error("mnemonist/fixed-deque: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-deque: `capacity` should be a positive number.");this.ArrayClass=e,this.capacity=t,this.items=new e(this.capacity),this.clear()}Qt.prototype.clear=function(){this.start=0,this.size=0};Qt.prototype.push=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.push: deque capacity ("+this.capacity+") exceeded!");var t=this.start+this.size;return t>=this.capacity&&(t-=this.capacity),this.items[t]=e,++this.size};Qt.prototype.unshift=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-deque.unshift: deque capacity ("+this.capacity+") exceeded!");var t=this.start-1;return this.start===0&&(t=this.capacity-1),this.items[t]=e,this.start=t,++this.size};Qt.prototype.pop=function(){if(this.size!==0){this.size--;var e=this.start+this.size;return e>=this.capacity&&(e-=this.capacity),this.items[e]}};Qt.prototype.shift=function(){if(this.size!==0){var e=this.start;return this.size--,this.start++,this.start===this.capacity&&(this.start=0),this.items[e]}};Qt.prototype.peekFirst=function(){if(this.size!==0)return this.items[this.start]};Qt.prototype.peekLast=function(){if(this.size!==0){var e=this.start+this.size-1;return e>=this.capacity&&(e-=this.capacity),this.items[e]}};Qt.prototype.get=function(e){if(!(this.size===0||e>=this.capacity))return e=this.start+e,e>=this.capacity&&(e-=this.capacity),this.items[e]};Qt.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=this.capacity,n=this.size,i=this.start,s=0;s=r)return{done:!0};var s=e[n];return n++,i++,n===t&&(n=0),{value:s,done:!1}})};Qt.prototype.entries=function(){var e=this.items,t=this.capacity,r=this.size,n=this.start,i=0;return new Za(function(){if(i>=r)return{done:!0};var s=e[n];return n++,n===t&&(n=0),{value:[i++,s],done:!1}})};typeof Symbol<"u"&&(Qt.prototype[Symbol.iterator]=Qt.prototype.values);Qt.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,"constructor",{value:Qt,enumerable:!1}),e};typeof Symbol<"u"&&(Qt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Qt.prototype.inspect);Qt.from=function(e,t,r){if(arguments.length<3&&(r=os.guessLength(e),typeof r!="number"))throw new Error("mnemonist/fixed-deque.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new Qt(t,r);if(os.isArrayLike(e)){var i,s;for(i=0,s=e.length;i{var tu=xr(),us=li();function ie(e,t){if(arguments.length<2)throw new Error("mnemonist/fixed-stack: expecting an Array class and a capacity.");if(typeof t!="number"||t<=0)throw new Error("mnemonist/fixed-stack: `capacity` should be a positive number.");this.capacity=t,this.ArrayClass=e,this.items=new this.ArrayClass(this.capacity),this.clear()}ie.prototype.clear=function(){this.size=0};ie.prototype.push=function(e){if(this.size===this.capacity)throw new Error("mnemonist/fixed-stack.push: stack capacity ("+this.capacity+") exceeded!");return this.items[this.size++]=e,this.size};ie.prototype.pop=function(){if(this.size!==0)return this.items[--this.size]};ie.prototype.peek=function(){return this.items[this.size-1]};ie.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=0,n=this.items.length;r=t)return{done:!0};var n=e[t-r-1];return r++,{value:n,done:!1}})};ie.prototype.entries=function(){var e=this.items,t=this.size,r=0;return new tu(function(){if(r>=t)return{done:!0};var n=e[t-r-1];return{value:[r++,n],done:!1}})};typeof Symbol<"u"&&(ie.prototype[Symbol.iterator]=ie.prototype.values);ie.prototype.toString=function(){return this.toArray().join(",")};ie.prototype.toJSON=function(){return this.toArray()};ie.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,"constructor",{value:ie,enumerable:!1}),e};typeof Symbol<"u"&&(ie.prototype[Symbol.for("nodejs.util.inspect.custom")]=ie.prototype.inspect);ie.from=function(e,t,r){if(arguments.length<3&&(r=us.guessLength(e),typeof r!="number"))throw new Error("mnemonist/fixed-stack.from: could not guess iterable length. Please provide desired capacity as last argument.");var n=new ie(t,r);if(us.isArrayLike(e)){var i,s;for(i=0,s=e.length;i{var id=function(e,t){return et?1:0},sd=function(e,t){return et?-1:0};function od(e){return function(t,r){return e(r,t)}}function ad(e){return e===2?function(t,r){return t[0]r[0]?1:t[1]r[1]?1:0}:function(t,r){for(var n=0;nr[n])return 1;n++}return 0}}pn.DEFAULT_COMPARATOR=id;pn.DEFAULT_REVERSE_COMPARATOR=sd;pn.reverseComparator=od;pn.createTupleComparator=ad});var uu=lt((By,au)=>{var fi=ci(),iu=nu(),Je=li(),gi=iu.DEFAULT_COMPARATOR,hs=iu.reverseComparator;function cs(e,t,r,n){for(var i=t[n],s,a;n>r;){if(s=n-1>>1,a=t[s],e(i,a)<0){t[n]=a,n=s;continue}break}t[n]=i}function yn(e,t,r){for(var n=t.length,i=r,s=t[r],a=2*r+1,l;a=0&&(a=l),t[r]=t[a],r=a,a=2*r+1;t[r]=s,cs(e,t,i,r)}function su(e,t,r){t.push(r),cs(e,t,0,t.length-1)}function ls(e,t){var r=t.pop();if(t.length!==0){var n=t[0];return t[0]=r,yn(e,t,0),n}return r}function Vr(e,t,r){if(t.length===0)throw new Error("mnemonist/heap.replace: cannot pop an empty heap.");var n=t[0];return t[0]=r,yn(e,t,0),n}function ou(e,t,r){var n;return t.length!==0&&e(t[0],r)<0&&(n=t[0],t[0]=r,r=n,yn(e,t,0)),r}function Sr(e,t){for(var r=t.length,n=r>>1,i=n;--i>=0;)yn(e,t,i)}function fs(e,t){for(var r=t.length,n=0,i=new Array(r);n=r.length)return r.slice().sort(e);for(g=r.slice(0,t),Sr(n,g),i=t,s=r.length;i0&&Vr(n,g,r[i]);return g.sort(e)}var f=Je.guessLength(r);return f!==null&&f0&&Vr(n,g,p)),i++}),g.length>i&&(g.length=i),g.sort(e)}function hd(e,t,r){arguments.length===2&&(r=t,t=e,e=gi);var n=hs(e),i,s,a,l=-1/0,g;if(t===1){if(Je.isArrayLike(r)){for(i=0,s=r.length;i0)&&(l=a);return g=new r.constructor(1),g[0]=l,g}return fi(r,function(p){(l===-1/0||e(p,l)>0)&&(l=p)}),[l]}if(Je.isArrayLike(r)){if(t>=r.length)return r.slice().sort(n);for(g=r.slice(0,t),Sr(e,g),i=t,s=r.length;i0&&Vr(e,g,r[i]);return g.sort(n)}var f=Je.guessLength(r);return f!==null&&f0&&Vr(e,g,p)),i++}),g.length>i&&(g.length=i),g.sort(n)}function _t(e){if(this.clear(),this.comparator=e||gi,typeof this.comparator!="function")throw new Error("mnemonist/Heap.constructor: given comparator should be a function.")}_t.prototype.clear=function(){this.items=[],this.size=0};_t.prototype.push=function(e){return su(this.comparator,this.items,e),++this.size};_t.prototype.peek=function(){return this.items[0]};_t.prototype.pop=function(){return this.size!==0&&this.size--,ls(this.comparator,this.items)};_t.prototype.replace=function(e){return Vr(this.comparator,this.items,e)};_t.prototype.pushpop=function(e){return ou(this.comparator,this.items,e)};_t.prototype.consume=function(){return this.size=0,fs(this.comparator,this.items)};_t.prototype.toArray=function(){return fs(this.comparator,this.items.slice())};_t.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,"constructor",{value:_t,enumerable:!1}),e};typeof Symbol<"u"&&(_t.prototype[Symbol.for("nodejs.util.inspect.custom")]=_t.prototype.inspect);function di(e){if(this.clear(),this.comparator=e||gi,typeof this.comparator!="function")throw new Error("mnemonist/MaxHeap.constructor: given comparator should be a function.");this.comparator=hs(this.comparator)}di.prototype=_t.prototype;_t.from=function(e,t){var r=new _t(t),n;return Je.isArrayLike(e)?n=e.slice():n=Je.toArray(e),Sr(r.comparator,n),r.items=n,r.size=n.length,r};di.from=function(e,t){var r=new di(t),n;return Je.isArrayLike(e)?n=e.slice():n=Je.toArray(e),Sr(r.comparator,n),r.items=n,r.size=n.length,r};_t.siftUp=yn;_t.siftDown=cs;_t.push=su;_t.pop=ls;_t.replace=Vr;_t.pushpop=ou;_t.heapify=Sr;_t.consume=fs;_t.nsmallest=ud;_t.nlargest=hd;_t.MinHeap=_t;_t.MaxHeap=di;au.exports=_t});var mn=lt(ds=>{var pi=gr(),cd=$r().createEdgeWeightGetter;function hu(e,t){return e==="outbound"||e==="inbound"?t.directedSize+t.undirectedSize*2:e==="in"||e==="out"||e==="directed"?t.directedSize:t.undirectedSize*2}function nr(e,t){t=t||"outbound";var r=e[t+"Neighbors"].bind(e),n=hu(t,e),i=pi.getPointerArray(n),s=pi.getPointerArray(e.order);this.graph=e,this.neighborhood=new s(n),this.starts=new i(e.order+1),this.nodes=e.nodes();var a={},l,g,f,p,y,w,E=0;for(l=0,g=e.order;l{var ld=as(),cu=ru(),fd=uu(),lu=gr(),fu=mn(),dd=fu.NeighborhoodIndex,gd=fu.WeightedNeighborhoodIndex;gs.createUnweightedIndexedBrandes=function(t){var r=new dd(t),n=r.neighborhood,i=r.starts,s=t.order,a=new cu(lu.getPointerArray(s),s),l=new Uint32Array(s),g=new Array(s),f=new Int32Array(s),p=new ld(Uint32Array,s),y=function(w){var E,A,I,_,$,j,R;for(j=0;jt[0]?1:e[0]t[1]?1:e[1]t[2]?1:e[2]t[3]?1:e[3]{var yd=Xt(),gu=du(),wd=Re(),md=gu.createUnweightedIndexedBrandes,vd=gu.createDijkstraIndexedBrandes,bd={nodeCentralityAttribute:"betweennessCentrality",getEdgeWeight:"weight",normalized:!0};function pu(e,t,r){if(!yd(t))throw new Error("graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.");r=wd(r,bd);var n=r.nodeCentralityAttribute,i=r.normalized,s=r.getEdgeWeight?vd(t,r.getEdgeWeight):md(t),a=t.order,l,g,f,p,y,w,E,A,I,_,$=new Float64Array(a),j=new Float64Array(a);for(w=0;w{var Ed=xr(),xd=gr().getPointerArray;function ke(e){var t=xd(e);this.size=0,this.length=e,this.dense=new t(e),this.sparse=new t(e)}ke.prototype.clear=function(){this.size=0};ke.prototype.has=function(e){var t=this.sparse[e];return t=this.size||this.dense[t]!==e?!1:(t=this.dense[this.size-1],this.dense[this.sparse[e]]=t,this.sparse[t]=this.sparse[e],this.size--,!0)};ke.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r,n=0;n{var Sd=Xt(),Ad=Re(),Dd=as(),Id=bu(),kd=mn().NeighborhoodIndex,jd={nodeCentralityAttribute:"closenessCentrality",wassermanFaust:!1};function Eu(e){this.index=new kd(e,"inbound"),this.queue=new Dd(Array,e.order),this.seen=new Id(e.order)}Eu.prototype.fromNode=function(e){var t=this.index,r=this.queue,n=this.seen;n.clear(),r.clear(),n.add(e),r.push([e,0]);for(var i,s,a,l,g,f,p=0,y=0;r.size!==0;)for(i=r.shift(),s=i[0],a=i[1],a!==0&&(p+=a,y+=1),g=t.starts[s+1],l=t.starts[s];l0&&s>1&&(p=g/f,n&&(p*=g/(s-1))),y[a]=p;return e?i.index.assign(r.nodeCentralityAttribute,y):i.index.collect(y)}var Su=xu.bind(null,!1);Su.assign=xu.bind(null,!0);Au.exports=Su});var Cu=lt((Jy,ju)=>{var Cd=Xt(),Ld=Re(),_d=mn().WeightedNeighborhoodIndex,Rd={nodeCentralityAttribute:"eigenvectorCentrality",getEdgeWeight:"weight",maxIterations:100,tolerance:1e-6};function Td(e){for(var t=0,r=0,n=0,i=e.length;nt&&(r*=t/s*(t/s),t=s),r+=s===0&&t===0?0:s/t*(s/t)}return t===1/0?1:t*Math.sqrt(r)}function Iu(e,t,r){if(!Cd(t))throw new Error("graphology-metrics/centrality/eigenvector: the given graph is not a valid graphology instance.");r=Ld(r,Rd);var n=r.maxIterations,i=r.tolerance,s=t.order,a=new _d(t,r.getEdgeWeight),l,g,f,p,y=new Float64Array(t.order);for(l=0;l{var Md=Xt(),Od=Re(),Gd=mn().WeightedNeighborhoodIndex,$d={nodePagerankAttribute:"pagerank",getEdgeWeight:"weight",alpha:.85,maxIterations:100,tolerance:1e-6};function Lu(e,t,r){if(!Md(t))throw new Error("graphology-metrics/centrality/pagerank: the given graph is not a valid graphology instance.");r=Od(r,$d);var n=r.alpha,i=r.maxIterations,s=r.tolerance,a=r.nodePagerankAttribute,l=t.order,g=1/l,f=new Gd(t,r.getEdgeWeight),p,y,w,E,A=new Float64Array(t.order),I=new Float64Array(f.weights.length),_=[];for(p=0;p{var zd=Xt();Mu.exports=function(t){if(!zd(t))throw new Error("graphology-metrics/simple-size: the given graph is not a valid graphology instance.");if(!t.multi)return t.size;var r=0,n=0;function i(){r++}function s(){n++}return t.forEachNode(function(a){t.type!=="directed"&&t.forEachUndirectedNeighbor(a,i),t.type!=="undirected"&&t.forEachOutNeighbor(a,s)}),r/2+n}});var Gu=lt(ir=>{var Pd=Xt(),Nd=Ou();function Wd(e,t){return 2*t/(e*(e-1))}function Fd(e,t){return t/(e*(e-1))}function qd(e,t){var r=e*(e-1);return t/(r+r/2)}function pr(e,t,r){var n,i;if(arguments.length>3){if(n=r,i=arguments[3],typeof n!="number"||n<0)throw new Error("graphology-metrics/density: given order is not a valid number.");if(typeof i!="number"||i<0)throw new Error("graphology-metrics/density: given size is not a valid number.")}else{if(!Pd(r))throw new Error("graphology-metrics/density: given graph is not a valid graphology instance.");n=r.order,i=r.size,r.multi&&t===!1&&(i=Nd(r))}if(n<2)return 0;e===null&&(e=r.type),t===null&&(t=r.multi);var s;return e==="undirected"?s=Wd:e==="directed"?s=Fd:s=qd,s(n,i)}ir.abstractDensity=pr;ir.density=pr.bind(null,null,null);ir.directedDensity=pr.bind(null,"directed",!1);ir.undirectedDensity=pr.bind(null,"undirected",!1);ir.mixedDensity=pr.bind(null,"mixed",!1);ir.multiDirectedDensity=pr.bind(null,"directed",!0);ir.multiUndirectedDensity=pr.bind(null,"undirected",!0);ir.multiMixedDensity=pr.bind(null,"mixed",!0)});var Pu=lt((ew,zu)=>{var $u=xr(),Ud=ci();function Jt(){this.clear()}Jt.prototype.clear=function(){this.items=[],this.offset=0,this.size=0};Jt.prototype.enqueue=function(e){return this.items.push(e),++this.size};Jt.prototype.dequeue=function(){if(this.size){var e=this.items[this.offset];return++this.offset*2>=this.items.length&&(this.items=this.items.slice(this.offset),this.offset=0),this.size--,e}};Jt.prototype.peek=function(){if(this.size)return this.items[this.offset]};Jt.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=this.offset,n=0,i=this.items.length;r=e.length)return{done:!0};var r=e[t];return t++,{value:r,done:!1}})};Jt.prototype.entries=function(){var e=this.items,t=this.offset,r=0;return new $u(function(){if(t>=e.length)return{done:!0};var n=e[t];return t++,{value:[r++,n],done:!1}})};typeof Symbol<"u"&&(Jt.prototype[Symbol.iterator]=Jt.prototype.values);Jt.prototype.toString=function(){return this.toArray().join(",")};Jt.prototype.toJSON=function(){return this.toArray()};Jt.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,"constructor",{value:Jt,enumerable:!1}),e};typeof Symbol<"u"&&(Jt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Jt.prototype.inspect);Jt.from=function(e){var t=new Jt;return Ud(e,function(r){t.enqueue(r)}),t};Jt.of=function(){return Jt.from(arguments)};zu.exports=Jt});var Wu=lt((rw,Nu)=>{Nu.exports=function(t,r){var n=r.length;if(n!==0){var i=t.length;t.length+=n;for(var s=0;s{var ps=Xt(),Bd=Pu(),Vd=Wu();function Yd(e,t,r){if(!ps(e))throw new Error("graphology-shortest-path: invalid graphology instance.");if(arguments.length<3)throw new Error("graphology-shortest-path: invalid number of arguments. Expecting at least 3.");if(!e.hasNode(t))throw new Error('graphology-shortest-path: the "'+t+'" source node does not exist in the given graph.');if(!e.hasNode(r))throw new Error('graphology-shortest-path: the "'+r+'" target node does not exist in the given graph.');if(t=""+t,r=""+r,t===r)return[t];var n=e.inboundNeighbors.bind(e),i=e.outboundNeighbors.bind(e),s={},a={};s[t]=null,a[r]=null;var l=[t],g=[r],f,p,y,w,E,A,I,_,$=!1;t:for(;l.length&&g.length;)if(l.length<=g.length){for(f=l,l=[],E=0,I=f.length;E{var Zd=Xt(),Hd=qu().singleSourceLength;Uu.exports=function(t,r){if(!Zd(t))throw new Error("graphology-metrics/eccentricity: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var n=-1/0,i=Hd(t,r),s,a,l=0;for(s in i)a=i[s],a>n&&(n=a),l++;return l{var tg=Xt(),eg=Bu();Vu.exports=function(t){if(!tg(t))throw new Error("graphology-metrics/diameter: given graph is not a valid graphology instance.");if(t.size===0)return 1/0;var r=-1/0;return t.someNode(function(n){var i=eg(t,n);return i>r&&(r=i),r===1/0}),r}});var ys=lt((ow,Ku)=>{var rg=Xt();Ku.exports=function(t){if(!rg(t))throw new Error("graphology-utils/infer-type: expecting a valid graphology instance.");var r=t.type;return r!=="mixed"?r:t.directedSize===0&&t.undirectedSize===0||t.directedSize>0&&t.undirectedSize>0?"mixed":t.directedSize>0?"directed":"undirected"}});var eh=lt((aw,th)=>{var Xu=Re(),Qu=Xt(),Ju=ys(),yr=$r(),Zu={getNodeCommunity:"community",getEdgeWeight:"weight",resolution:1};function ng(e,t){var r=new Array(e.order),n=new Float64Array(e.order),i={},s=0,a=yr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry,l=yr.createNodeValueGetter(t.getNodeCommunity).fromEntry,g=0,f={};return e.forEachNode(function(p,y){f[p]=g,r[g++]=l(p,y)}),e.forEachUndirectedEdge(function(p,y,w,E,A,I,_){var $=a(p,y,w,E,A,I,_);s+=$,i[p]=$,n[f[w]]+=$,w!==E&&(n[f[E]]+=$)}),{weights:i,communities:r,weightedDegrees:n,M:s}}function ig(e,t){var r=new Array(e.order),n=new Float64Array(e.order),i=new Float64Array(e.order),s={},a=0,l=yr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry,g=yr.createNodeValueGetter(t.getNodeCommunity).fromEntry,f=0,p={};return e.forEachNode(function(y,w){p[y]=f,r[f++]=g(y,w)}),e.forEachDirectedEdge(function(y,w,E,A,I,_,$){var j=l(y,w,E,A,I,_,$);a+=j,s[y]=j,i[p[E]]+=j,n[p[A]]+=j}),{weights:s,communities:r,weightedInDegrees:n,weightedOutDegrees:i,M:a}}function sg(e,t){var r=t.resolution,n=ng(e,t),i=n.communities,s=n.weightedDegrees,a=n.M,l=e.nodes(),g,f,p,y,w,E,A=0,I=a*2;for(g=0,p=e.order;g"u")throw new Error('graphology-metrics/modularity: the "'+a+'" node is not in the partition.');n[g]=0,i[g]=0}),{communities:r,totalWeights:n,internalWeights:i}}function ug(e,t){var r={},n={},i={},s={},a=yr.createNodeValueGetter(t.getNodeCommunity).fromEntry;return e.forEachNode(function(l,g){var f=a(l,g);if(r[l]=f,typeof f>"u")throw new Error('graphology-metrics/modularity: the "'+l+'" node is not in the partition.');n[f]=0,i[f]=0,s[f]=0}),{communities:r,totalInWeights:n,totalOutWeights:i,internalWeights:s}}function hg(e,t){var r=t.resolution,n=ag(e,t),i=0,s=n.totalWeights,a=n.internalWeights,l=n.communities,g=yr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry;e.forEachUndirectedEdge(function(w,E,A,I,_,$,j){var R=g(w,E,A,I,_,$,j);i+=R;var W=l[A],z=l[I];s[W]+=R,s[z]+=R,W===z&&(a[W]+=R*2)});var f=0,p=i*2;for(var y in a)f+=a[y]/p-Math.pow(s[y]/p,2)*r;return f}function cg(e,t){var r=t.resolution,n=ug(e,t),i=0,s=n.totalInWeights,a=n.totalOutWeights,l=n.internalWeights,g=n.communities,f=yr.createEdgeWeightGetter(t.getEdgeWeight).fromEntry;e.forEachDirectedEdge(function(w,E,A,I,_,$,j){var R=f(w,E,A,I,_,$,j);i+=R;var W=g[A],z=g[I];a[W]+=R,s[z]+=R,W===z&&(l[W]+=R)});var p=0;for(var y in l)p+=l[y]/i-s[y]*a[y]/Math.pow(i,2)*r;return p}function lg(e,t,r,n){return n/(2*e)-t*r/(2*(e*e))}function fg(e,t,r,n,i,s){return s/e-(i*t+n*r)/(e*e)}function dg(e,t){if(!Qu(e))throw new Error("graphology-metrics/modularity: given graph is not a valid graphology instance.");if(e.size===0)throw new Error("graphology-metrics/modularity: cannot compute modularity of an empty graph.");if(e.multi)throw new Error("graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.");var r=Ju(e);if(r==="mixed")throw new Error("graphology-metrics/modularity: cannot compute modularity of a mixed graph.");return t=Xu(t,Zu),r==="directed"?og(e,t):sg(e,t)}function Hu(e,t){if(!Qu(e))throw new Error("graphology-metrics/modularity: given graph is not a valid graphology instance.");if(e.size===0)throw new Error("graphology-metrics/modularity: cannot compute modularity of an empty graph.");if(e.multi)throw new Error("graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.");var r=Ju(e);if(r==="mixed")throw new Error("graphology-metrics/modularity: cannot compute modularity of a mixed graph.");return t=Xu(t,Zu),r==="directed"?cg(e,t):hg(e,t)}var vn=Hu;vn.sparse=Hu;vn.dense=dg;vn.undirectedDelta=lg;vn.directedDelta=fg;th.exports=vn});var nh=lt((uw,rh)=>{var ws=xr(),gg=gr().getPointerArray;function ge(e,t){arguments.length<2&&(t=e,e=Array);var r=gg(t);this.size=0,this.length=t,this.dense=new r(t),this.sparse=new r(t),this.vals=new e(t)}ge.prototype.clear=function(){this.size=0};ge.prototype.has=function(e){var t=this.sparse[e];return t=this.size||this.dense[t]!==e?!1:(t=this.dense[this.size-1],this.dense[this.sparse[e]]=t,this.sparse[t]=this.sparse[e],this.size--,!0)};ge.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var r=0;r{var pg=xr(),yg=gr().getPointerArray;function je(e){var t=yg(e);this.start=0,this.size=0,this.capacity=e,this.dense=new t(e),this.sparse=new t(e)}je.prototype.clear=function(){this.start=0,this.size=0};je.prototype.has=function(e){if(this.size===0)return!1;var t=this.sparse[e],r=t=this.start&&t=this.start&&t1?t:this;for(var r=this.capacity,n=this.size,i=this.start,s=0;s=r)return{done:!0};var s=e[n];return n++,i++,n===t&&(n=0),{value:s,done:!1}})};typeof Symbol<"u"&&(je.prototype[Symbol.iterator]=je.prototype.values);je.prototype.inspect=function(){var e=[];return this.forEach(function(t){e.push(t)}),Object.defineProperty(e,"constructor",{value:je,enumerable:!1}),e.capacity=this.capacity,e};typeof Symbol<"u"&&(je.prototype[Symbol.for("nodejs.util.inspect.custom")]=je.prototype.inspect);ih.exports=je});var hh=lt((cw,uh)=>{function oh(e){return function(t){return typeof t!="number"&&(t=t.length),Math.floor(e()*t)}}var ah=oh(Math.random);ah.createRandomIndex=oh;uh.exports=ah});var gh=lt(ms=>{var wr=gr(),ch=Re(),lh=$r().createEdgeWeightGetter,fh=Symbol.for("nodejs.util.inspect.custom"),dh={getEdgeWeight:"weight",keepDendrogram:!1,resolution:1};function Yt(e,t){t=ch(t,dh);var r=t.resolution,n=lh(t.getEdgeWeight).fromEntry,i=(e.size-e.selfLoopCount)*2,s=wr.getPointerArray(i),a=wr.getPointerArray(e.order+1),l=t.getEdgeWeight?Float64Array:wr.getPointerArray(e.size*2);this.C=e.order,this.M=0,this.E=i,this.U=0,this.resolution=r,this.level=0,this.graph=e,this.nodes=new Array(e.order),this.keepDendrogram=t.keepDendrogram,this.neighborhood=new a(i),this.weights=new l(i),this.loops=new l(e.order),this.starts=new s(e.order+1),this.belongings=new a(e.order),this.dendrogram=[],this.mapping=null,this.counts=new a(e.order),this.unused=new a(e.order),this.totalWeights=new l(e.order);var g={},f,p=0,y=0,w=this;e.forEachNode(function(E){w.nodes[p]=E,g[E]=p,y+=e.undirectedDegreeWithoutSelfLoops(E),w.starts[p]=y,w.belongings[p]=p,w.counts[p]=1,p++}),e.forEachEdge(function(E,A,I,_,$,j,R){if(f=n(E,A,I,_,$,j,R),I=g[I],_=g[_],w.M+=f,I===_)w.totalWeights[I]+=f*2,w.loops[I]=f*2;else{w.totalWeights[I]+=f,w.totalWeights[_]+=f;var W=--w.starts[I],z=--w.starts[_];w.neighborhood[W]=_,w.neighborhood[z]=I,w.weights[W]=f,w.weights[z]=f}}),this.starts[p]=this.E,this.keepDendrogram?this.dendrogram.push(this.belongings.slice()):this.mapping=this.belongings.slice()}Yt.prototype.isolate=function(e,t){var r=this.belongings[e];if(this.counts[r]===1)return r;var n=this.unused[--this.U],i=this.loops[e];return this.totalWeights[r]-=t+i,this.totalWeights[n]+=t+i,this.belongings[e]=n,this.counts[r]--,this.counts[n]++,n};Yt.prototype.move=function(e,t,r){var n=this.belongings[e],i=this.loops[e];this.totalWeights[n]-=t+i,this.totalWeights[r]+=t+i,this.belongings[e]=r;var s=this.counts[n]--===1;this.counts[r]++,s&&(this.unused[this.U++]=n)};Yt.prototype.computeNodeDegree=function(e){var t,r,n,i=0;for(t=this.starts[e],r=this.starts[e+1];t{var wg=Re(),mg=Xt(),vg=ys(),ph=nh(),yh=sh(),wh=hh().createRandomIndex,mh=gh(),bg=mh.UndirectedLouvainIndex,Eg=mh.DirectedLouvainIndex,vh={nodeCommunityAttribute:"community",getEdgeWeight:"weight",fastLocalMoves:!0,randomWalk:!0,resolution:1,rng:Math.random};function yi(e,t,r){var n=e.get(t);typeof n>"u"&&(n=0),n+=r,e.set(t,n)}var xg=1e-10;function wi(e,t,r,n,i){return Math.abs(n-i)e:n>i}function Sg(e,t,r){var n=new bg(t,{getEdgeWeight:r.getEdgeWeight,keepDendrogram:e,resolution:r.resolution}),i=wh(r.rng),s=!0,a=!0,l,g,f=new ph(Float64Array,n.C),p,y,w,E,A,I,_,$,j,R,W,z,V,G,P,C,H=0,ut=0,at=[],vt,ft;for(r.fastLocalMoves&&(p=new yh(n.C));s;){if(R=n.C,s=!1,a=!0,r.fastLocalMoves){for(ft=0,I=r.randomWalk?i(R):0,_=0;_e++}function He(){let e=arguments,t=null,r=-1;return{[Symbol.iterator](){return this},next(){let n=null;do{if(t===null){if(r++,r>=e.length)return{done:!0};t=e[r][Symbol.iterator]()}if(n=t.next(),n.done){t=null;continue}break}while(!0);return n}}}function Mr(){return{[Symbol.iterator](){return this},next(){return{done:!0}}}}var Zr=class extends Error{constructor(t){super(),this.name="GraphError",this.message=t}},rt=class e extends Zr{constructor(t){super(t),this.name="InvalidArgumentsGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}},Z=class e extends Zr{constructor(t){super(t),this.name="NotFoundGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}},dt=class e extends Zr{constructor(t){super(t),this.name="UsageGraphError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,e.prototype.constructor)}};function Ns(e,t){this.key=e,this.attributes=t,this.clear()}Ns.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.undirectedLoops=0,this.directedLoops=0,this.in={},this.out={},this.undirected={}};function Ws(e,t){this.key=e,this.attributes=t,this.clear()}Ws.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedLoops=0,this.in={},this.out={}};function Fs(e,t){this.key=e,this.attributes=t,this.clear()}Fs.prototype.clear=function(){this.undirectedDegree=0,this.undirectedLoops=0,this.undirected={}};function Or(e,t,r,n,i){this.key=t,this.attributes=i,this.undirected=e,this.source=r,this.target=n}Or.prototype.attach=function(){let e="out",t="in";this.undirected&&(e=t="undirected");let r=this.source.key,n=this.target.key;this.source[e][n]=this,!(this.undirected&&r===n)&&(this.target[t][r]=this)};Or.prototype.attachMulti=function(){let e="out",t="in",r=this.source.key,n=this.target.key;this.undirected&&(e=t="undirected");let i=this.source[e],s=i[n];if(typeof s>"u"){i[n]=this,this.undirected&&r===n||(this.target[t][r]=this);return}s.previous=this,this.next=s,i[n]=this,this.target[t][r]=this};Or.prototype.detach=function(){let e=this.source.key,t=this.target.key,r="out",n="in";this.undirected&&(r=n="undirected"),delete this.source[r][t],delete this.target[n][e]};Or.prototype.detachMulti=function(){let e=this.source.key,t=this.target.key,r="out",n="in";this.undirected&&(r=n="undirected"),this.previous===void 0?this.next===void 0?(delete this.source[r][t],delete this.target[n][e]):(this.next.previous=void 0,this.source[r][t]=this.next,this.target[n][e]=this.next):(this.previous.next=this.next,this.next!==void 0&&(this.next.previous=this.previous))};var qs=0,Us=1,Kh=2,Bs=3;function tr(e,t,r,n,i,s,a){let l,g,f,p;if(n=""+n,r===qs){if(l=e._nodes.get(n),!l)throw new Z(`Graph.${t}: could not find the "${n}" node in the graph.`);f=i,p=s}else if(r===Bs){if(i=""+i,g=e._edges.get(i),!g)throw new Z(`Graph.${t}: could not find the "${i}" edge in the graph.`);let y=g.source.key,w=g.target.key;if(n===y)l=g.target;else if(n===w)l=g.source;else throw new Z(`Graph.${t}: the "${n}" node is not attached to the "${i}" edge (${y}, ${w}).`);f=s,p=a}else{if(g=e._edges.get(n),!g)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`);r===Us?l=g.source:l=g.target,f=i,p=s}return[l,f,p]}function Xh(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);return a.attributes[l]}}function Qh(e,t,r){e.prototype[t]=function(n,i){let[s]=tr(this,t,r,n,i);return s.attributes}}function Jh(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);return a.attributes.hasOwnProperty(l)}}function Zh(e,t,r){e.prototype[t]=function(n,i,s,a){let[l,g,f]=tr(this,t,r,n,i,s,a);return l.attributes[g]=f,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function Hh(e,t,r){e.prototype[t]=function(n,i,s,a){let[l,g,f]=tr(this,t,r,n,i,s,a);if(typeof f!="function")throw new rt(`Graph.${t}: updater should be a function.`);let p=l.attributes,y=f(p[g]);return p[g]=y,this.emit("nodeAttributesUpdated",{key:l.key,type:"set",attributes:l.attributes,name:g}),this}}function tc(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);return delete a.attributes[l],this.emit("nodeAttributesUpdated",{key:a.key,type:"remove",attributes:a.attributes,name:l}),this}}function ec(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);if(!le(l))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return a.attributes=l,this.emit("nodeAttributesUpdated",{key:a.key,type:"replace",attributes:a.attributes}),this}}function rc(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);if(!le(l))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return ne(a.attributes,l),this.emit("nodeAttributesUpdated",{key:a.key,type:"merge",attributes:a.attributes,data:l}),this}}function nc(e,t,r){e.prototype[t]=function(n,i,s){let[a,l]=tr(this,t,r,n,i,s);if(typeof l!="function")throw new rt(`Graph.${t}: provided updater is not a function.`);return a.attributes=l(a.attributes),this.emit("nodeAttributesUpdated",{key:a.key,type:"update",attributes:a.attributes}),this}}var ic=[{name:e=>`get${e}Attribute`,attacher:Xh},{name:e=>`get${e}Attributes`,attacher:Qh},{name:e=>`has${e}Attribute`,attacher:Jh},{name:e=>`set${e}Attribute`,attacher:Zh},{name:e=>`update${e}Attribute`,attacher:Hh},{name:e=>`remove${e}Attribute`,attacher:tc},{name:e=>`replace${e}Attributes`,attacher:ec},{name:e=>`merge${e}Attributes`,attacher:rc},{name:e=>`update${e}Attributes`,attacher:nc}];function sc(e){ic.forEach(function({name:t,attacher:r}){r(e,t("Node"),qs),r(e,t("Source"),Us),r(e,t("Target"),Kh),r(e,t("Opposite"),Bs)})}function oc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return s.attributes[i]}}function ac(e,t,r){e.prototype[t]=function(n){let i;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>1){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let s=""+n,a=""+arguments[1];if(i=_e(this,s,a,r),!i)throw new Z(`Graph.${t}: could not find an edge for the given path ("${s}" - "${a}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,i=this._edges.get(n),!i)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return i.attributes}}function uc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return s.attributes.hasOwnProperty(i)}}function hc(e,t,r){e.prototype[t]=function(n,i,s){let a;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+i;if(i=arguments[2],s=arguments[3],a=_e(this,l,g,r),!a)throw new Z(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,a=this._edges.get(n),!a)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return a.attributes[i]=s,this.emit("edgeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:i}),this}}function cc(e,t,r){e.prototype[t]=function(n,i,s){let a;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>3){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let l=""+n,g=""+i;if(i=arguments[2],s=arguments[3],a=_e(this,l,g,r),!a)throw new Z(`Graph.${t}: could not find an edge for the given path ("${l}" - "${g}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,a=this._edges.get(n),!a)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof s!="function")throw new rt(`Graph.${t}: updater should be a function.`);return a.attributes[i]=s(a.attributes[i]),this.emit("edgeAttributesUpdated",{key:a.key,type:"set",attributes:a.attributes,name:i}),this}}function lc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}return delete s.attributes[i],this.emit("edgeAttributesUpdated",{key:s.key,type:"remove",attributes:s.attributes,name:i}),this}}function fc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!le(i))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return s.attributes=i,this.emit("edgeAttributesUpdated",{key:s.key,type:"replace",attributes:s.attributes}),this}}function dc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(!le(i))throw new rt(`Graph.${t}: provided attributes are not a plain object.`);return ne(s.attributes,i),this.emit("edgeAttributesUpdated",{key:s.key,type:"merge",attributes:s.attributes,data:i}),this}}function gc(e,t,r){e.prototype[t]=function(n,i){let s;if(this.type!=="mixed"&&r!=="mixed"&&r!==this.type)throw new dt(`Graph.${t}: cannot find this type of edges in your ${this.type} graph.`);if(arguments.length>2){if(this.multi)throw new dt(`Graph.${t}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.`);let a=""+n,l=""+i;if(i=arguments[2],s=_e(this,a,l,r),!s)throw new Z(`Graph.${t}: could not find an edge for the given path ("${a}" - "${l}").`)}else{if(r!=="mixed")throw new dt(`Graph.${t}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.`);if(n=""+n,s=this._edges.get(n),!s)throw new Z(`Graph.${t}: could not find the "${n}" edge in the graph.`)}if(typeof i!="function")throw new rt(`Graph.${t}: provided updater is not a function.`);return s.attributes=i(s.attributes),this.emit("edgeAttributesUpdated",{key:s.key,type:"update",attributes:s.attributes}),this}}var pc=[{name:e=>`get${e}Attribute`,attacher:oc},{name:e=>`get${e}Attributes`,attacher:ac},{name:e=>`has${e}Attribute`,attacher:uc},{name:e=>`set${e}Attribute`,attacher:hc},{name:e=>`update${e}Attribute`,attacher:cc},{name:e=>`remove${e}Attribute`,attacher:lc},{name:e=>`replace${e}Attributes`,attacher:fc},{name:e=>`merge${e}Attributes`,attacher:dc},{name:e=>`update${e}Attributes`,attacher:gc}];function yc(e){pc.forEach(function({name:t,attacher:r}){r(e,t("Edge"),"mixed"),r(e,t("DirectedEdge"),"directed"),r(e,t("UndirectedEdge"),"undirected")})}var wc=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function mc(e,t,r,n){let i=!1;for(let s in t){if(s===n)continue;let a=t[s];if(i=r(a.key,a.attributes,a.source.key,a.target.key,a.source.attributes,a.target.attributes,a.undirected),e&&i)return a.key}}function vc(e,t,r,n){let i,s,a,l=!1;for(let g in t)if(g!==n){i=t[g];do{if(s=i.source,a=i.target,l=r(i.key,i.attributes,s.key,a.key,s.attributes,a.attributes,i.undirected),e&&l)return i.key;i=i.next}while(i!==void 0)}}function Di(e,t){let r=Object.keys(e),n=r.length,i,s=0;return{[Symbol.iterator](){return this},next(){do if(i)i=i.next;else{if(s>=n)return{done:!0};let a=r[s++];if(a===t){i=void 0;continue}i=e[a]}while(!i);return{done:!1,value:{edge:i.key,attributes:i.attributes,source:i.source.key,target:i.target.key,sourceAttributes:i.source.attributes,targetAttributes:i.target.attributes,undirected:i.undirected}}}}}function bc(e,t,r,n){let i=t[r];if(!i)return;let s=i.source,a=i.target;if(n(i.key,i.attributes,s.key,a.key,s.attributes,a.attributes,i.undirected)&&e)return i.key}function Ec(e,t,r,n){let i=t[r];if(!i)return;let s=!1;do{if(s=n(i.key,i.attributes,i.source.key,i.target.key,i.source.attributes,i.target.attributes,i.undirected),e&&s)return i.key;i=i.next}while(i!==void 0)}function Ii(e,t){let r=e[t];if(r.next!==void 0)return{[Symbol.iterator](){return this},next(){if(!r)return{done:!0};let i={edge:r.key,attributes:r.attributes,source:r.source.key,target:r.target.key,sourceAttributes:r.source.attributes,targetAttributes:r.target.attributes,undirected:r.undirected};return r=r.next,{done:!1,value:i}}};let n=!1;return{[Symbol.iterator](){return this},next(){return n===!0?{done:!0}:(n=!0,{done:!1,value:{edge:r.key,attributes:r.attributes,source:r.source.key,target:r.target.key,sourceAttributes:r.source.attributes,targetAttributes:r.target.attributes,undirected:r.undirected}})}}}function xc(e,t){if(e.size===0)return[];if(t==="mixed"||t===e.type)return Array.from(e._edges.keys());let r=t==="undirected"?e.undirectedSize:e.directedSize,n=new Array(r),i=t==="undirected",s=e._edges.values(),a=0,l,g;for(;l=s.next(),l.done!==!0;)g=l.value,g.undirected===i&&(n[a++]=g.key);return n}function Vs(e,t,r,n){if(t.size===0)return;let i=r!=="mixed"&&r!==t.type,s=r==="undirected",a,l,g=!1,f=t._edges.values();for(;a=f.next(),a.done!==!0;){if(l=a.value,i&&l.undirected!==s)continue;let{key:p,attributes:y,source:w,target:E}=l;if(g=n(p,y,w.key,E.key,w.attributes,E.attributes,l.undirected),e&&g)return p}}function Sc(e,t){if(e.size===0)return Mr();let r=t!=="mixed"&&t!==e.type,n=t==="undirected",i=e._edges.values();return{[Symbol.iterator](){return this},next(){let s,a;for(;;){if(s=i.next(),s.done)return s;if(a=s.value,!(r&&a.undirected!==n))break}return{value:{edge:a.key,attributes:a.attributes,source:a.source.key,target:a.target.key,sourceAttributes:a.source.attributes,targetAttributes:a.target.attributes,undirected:a.undirected},done:!1}}}}function ki(e,t,r,n,i,s){let a=t?vc:mc,l;if(r!=="undirected"&&(n!=="out"&&(l=a(e,i.in,s),e&&l)||n!=="in"&&(l=a(e,i.out,s,n?void 0:i.key),e&&l))||r!=="directed"&&(l=a(e,i.undirected,s),e&&l))return l}function Ac(e,t,r,n){let i=[];return ki(!1,e,t,r,n,function(s){i.push(s)}),i}function Dc(e,t,r){let n=Mr();return e!=="undirected"&&(t!=="out"&&typeof r.in<"u"&&(n=He(n,Di(r.in))),t!=="in"&&typeof r.out<"u"&&(n=He(n,Di(r.out,t?void 0:r.key)))),e!=="directed"&&typeof r.undirected<"u"&&(n=He(n,Di(r.undirected))),n}function ji(e,t,r,n,i,s,a){let l=r?Ec:bc,g;if(t!=="undirected"&&(typeof i.in<"u"&&n!=="out"&&(g=l(e,i.in,s,a),e&&g)||typeof i.out<"u"&&n!=="in"&&(n||i.key!==s)&&(g=l(e,i.out,s,a),e&&g))||t!=="directed"&&typeof i.undirected<"u"&&(g=l(e,i.undirected,s,a),e&&g))return g}function Ic(e,t,r,n,i){let s=[];return ji(!1,e,t,r,n,i,function(a){s.push(a)}),s}function kc(e,t,r,n){let i=Mr();return e!=="undirected"&&(typeof r.in<"u"&&t!=="out"&&n in r.in&&(i=He(i,Ii(r.in,n))),typeof r.out<"u"&&t!=="in"&&n in r.out&&(t||r.key!==n)&&(i=He(i,Ii(r.out,n)))),e!=="directed"&&typeof r.undirected<"u"&&n in r.undirected&&(i=He(i,Ii(r.undirected,n))),i}function jc(e,t){let{name:r,type:n,direction:i}=t;e.prototype[r]=function(s,a){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];if(!arguments.length)return xc(this,n);if(arguments.length===1){s=""+s;let l=this._nodes.get(s);if(typeof l>"u")throw new Z(`Graph.${r}: could not find the "${s}" node in the graph.`);return Ac(this.multi,n==="mixed"?this.type:n,i,l)}if(arguments.length===2){s=""+s,a=""+a;let l=this._nodes.get(s);if(!l)throw new Z(`Graph.${r}: could not find the "${s}" source node in the graph.`);if(!this._nodes.has(a))throw new Z(`Graph.${r}: could not find the "${a}" target node in the graph.`);return Ic(n,this.multi,i,l,a)}throw new rt(`Graph.${r}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Cc(e,t){let{name:r,type:n,direction:i}=t,s="forEach"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[s]=function(f,p,y){if(!(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)){if(arguments.length===1)return y=f,Vs(!1,this,n,y);if(arguments.length===2){f=""+f,y=p;let w=this._nodes.get(f);if(typeof w>"u")throw new Z(`Graph.${s}: could not find the "${f}" node in the graph.`);return ki(!1,this.multi,n==="mixed"?this.type:n,i,w,y)}if(arguments.length===3){f=""+f,p=""+p;let w=this._nodes.get(f);if(!w)throw new Z(`Graph.${s}: could not find the "${f}" source node in the graph.`);if(!this._nodes.has(p))throw new Z(`Graph.${s}: could not find the "${p}" target node in the graph.`);return ji(!1,n,this.multi,i,w,p,y)}throw new rt(`Graph.${s}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)}};let a="map"+r[0].toUpperCase()+r.slice(1);e.prototype[a]=function(){let f=Array.prototype.slice.call(arguments),p=f.pop(),y;if(f.length===0){let w=0;n!=="directed"&&(w+=this.undirectedSize),n!=="undirected"&&(w+=this.directedSize),y=new Array(w);let E=0;f.push((A,I,_,$,j,R,W)=>{y[E++]=p(A,I,_,$,j,R,W)})}else y=[],f.push((w,E,A,I,_,$,j)=>{y.push(p(w,E,A,I,_,$,j))});return this[s].apply(this,f),y};let l="filter"+r[0].toUpperCase()+r.slice(1);e.prototype[l]=function(){let f=Array.prototype.slice.call(arguments),p=f.pop(),y=[];return f.push((w,E,A,I,_,$,j)=>{p(w,E,A,I,_,$,j)&&y.push(w)}),this[s].apply(this,f),y};let g="reduce"+r[0].toUpperCase()+r.slice(1);e.prototype[g]=function(){let f=Array.prototype.slice.call(arguments);if(f.length<2||f.length>4)throw new rt(`Graph.${g}: invalid number of arguments (expecting 2, 3 or 4 and got ${f.length}).`);if(typeof f[f.length-1]=="function"&&typeof f[f.length-2]!="function")throw new rt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let p,y;f.length===2?(p=f[0],y=f[1],f=[]):f.length===3?(p=f[1],y=f[2],f=[f[0]]):f.length===4&&(p=f[2],y=f[3],f=[f[0],f[1]]);let w=y;return f.push((E,A,I,_,$,j,R)=>{w=p(w,E,A,I,_,$,j,R)}),this[s].apply(this,f),w}}function Lc(e,t){let{name:r,type:n,direction:i}=t,s="find"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[s]=function(g,f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return!1;if(arguments.length===1)return p=g,Vs(!0,this,n,p);if(arguments.length===2){g=""+g,p=f;let y=this._nodes.get(g);if(typeof y>"u")throw new Z(`Graph.${s}: could not find the "${g}" node in the graph.`);return ki(!0,this.multi,n==="mixed"?this.type:n,i,y,p)}if(arguments.length===3){g=""+g,f=""+f;let y=this._nodes.get(g);if(!y)throw new Z(`Graph.${s}: could not find the "${g}" source node in the graph.`);if(!this._nodes.has(f))throw new Z(`Graph.${s}: could not find the "${f}" target node in the graph.`);return ji(!0,n,this.multi,i,y,f,p)}throw new rt(`Graph.${s}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).`)};let a="some"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[a]=function(){let g=Array.prototype.slice.call(arguments),f=g.pop();return g.push((y,w,E,A,I,_,$)=>f(y,w,E,A,I,_,$)),!!this[s].apply(this,g)};let l="every"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[l]=function(){let g=Array.prototype.slice.call(arguments),f=g.pop();return g.push((y,w,E,A,I,_,$)=>!f(y,w,E,A,I,_,$)),!this[s].apply(this,g)}}function _c(e,t){let{name:r,type:n,direction:i}=t,s=r.slice(0,-1)+"Entries";e.prototype[s]=function(a,l){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return Mr();if(!arguments.length)return Sc(this,n);if(arguments.length===1){a=""+a;let g=this._nodes.get(a);if(!g)throw new Z(`Graph.${s}: could not find the "${a}" node in the graph.`);return Dc(n,i,g)}if(arguments.length===2){a=""+a,l=""+l;let g=this._nodes.get(a);if(!g)throw new Z(`Graph.${s}: could not find the "${a}" source node in the graph.`);if(!this._nodes.has(l))throw new Z(`Graph.${s}: could not find the "${l}" target node in the graph.`);return kc(n,i,g,l)}throw new rt(`Graph.${s}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).`)}}function Rc(e){wc.forEach(t=>{jc(e,t),Cc(e,t),Lc(e,t),_c(e,t)})}var Tc=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function Tn(){this.A=null,this.B=null}Tn.prototype.wrap=function(e){this.A===null?this.A=e:this.B===null&&(this.B=e)};Tn.prototype.has=function(e){return this.A!==null&&e in this.A||this.B!==null&&e in this.B};function Qr(e,t,r,n,i){for(let s in n){let a=n[s],l=a.source,g=a.target,f=l===r?g:l;if(t&&t.has(f.key))continue;let p=i(f.key,f.attributes);if(e&&p)return f.key}}function Ci(e,t,r,n,i){if(t!=="mixed"){if(t==="undirected")return Qr(e,null,n,n.undirected,i);if(typeof r=="string")return Qr(e,null,n,n[r],i)}let s=new Tn,a;if(t!=="undirected"){if(r!=="out"){if(a=Qr(e,null,n,n.in,i),e&&a)return a;s.wrap(n.in)}if(r!=="in"){if(a=Qr(e,s,n,n.out,i),e&&a)return a;s.wrap(n.out)}}if(t!=="directed"&&(a=Qr(e,s,n,n.undirected,i),e&&a))return a}function Mc(e,t,r){if(e!=="mixed"){if(e==="undirected")return Object.keys(r.undirected);if(typeof t=="string")return Object.keys(r[t])}let n=[];return Ci(!1,e,t,r,function(i){n.push(i)}),n}function Jr(e,t,r){let n=Object.keys(r),i=n.length,s=0;return{[Symbol.iterator](){return this},next(){let a=null;do{if(s>=i)return e&&e.wrap(r),{done:!0};let l=r[n[s++]],g=l.source,f=l.target;if(a=g===t?f:g,e&&e.has(a.key)){a=null;continue}}while(a===null);return{done:!1,value:{neighbor:a.key,attributes:a.attributes}}}}}function Oc(e,t,r){if(e!=="mixed"){if(e==="undirected")return Jr(null,r,r.undirected);if(typeof t=="string")return Jr(null,r,r[t])}let n=Mr(),i=new Tn;return e!=="undirected"&&(t!=="out"&&(n=He(n,Jr(i,r,r.in))),t!=="in"&&(n=He(n,Jr(i,r,r.out)))),e!=="directed"&&(n=He(n,Jr(i,r,r.undirected))),n}function Gc(e,t){let{name:r,type:n,direction:i}=t;e.prototype[r]=function(s){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return[];s=""+s;let a=this._nodes.get(s);if(typeof a>"u")throw new Z(`Graph.${r}: could not find the "${s}" node in the graph.`);return Mc(n==="mixed"?this.type:n,i,a)}}function $c(e,t){let{name:r,type:n,direction:i}=t,s="forEach"+r[0].toUpperCase()+r.slice(1,-1);e.prototype[s]=function(f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;f=""+f;let y=this._nodes.get(f);if(typeof y>"u")throw new Z(`Graph.${s}: could not find the "${f}" node in the graph.`);Ci(!1,n==="mixed"?this.type:n,i,y,p)};let a="map"+r[0].toUpperCase()+r.slice(1);e.prototype[a]=function(f,p){let y=[];return this[s](f,(w,E)=>{y.push(p(w,E))}),y};let l="filter"+r[0].toUpperCase()+r.slice(1);e.prototype[l]=function(f,p){let y=[];return this[s](f,(w,E)=>{p(w,E)&&y.push(w)}),y};let g="reduce"+r[0].toUpperCase()+r.slice(1);e.prototype[g]=function(f,p,y){if(arguments.length<3)throw new rt(`Graph.${g}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.`);let w=y;return this[s](f,(E,A)=>{w=p(w,E,A)}),w}}function zc(e,t){let{name:r,type:n,direction:i}=t,s=r[0].toUpperCase()+r.slice(1,-1),a="find"+s;e.prototype[a]=function(f,p){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return;f=""+f;let y=this._nodes.get(f);if(typeof y>"u")throw new Z(`Graph.${a}: could not find the "${f}" node in the graph.`);return Ci(!0,n==="mixed"?this.type:n,i,y,p)};let l="some"+s;e.prototype[l]=function(f,p){return!!this[a](f,p)};let g="every"+s;e.prototype[g]=function(f,p){return!this[a](f,(w,E)=>!p(w,E))}}function Pc(e,t){let{name:r,type:n,direction:i}=t,s=r.slice(0,-1)+"Entries";e.prototype[s]=function(a){if(n!=="mixed"&&this.type!=="mixed"&&n!==this.type)return Mr();a=""+a;let l=this._nodes.get(a);if(typeof l>"u")throw new Z(`Graph.${s}: could not find the "${a}" node in the graph.`);return Oc(n==="mixed"?this.type:n,i,l)}}function Nc(e){Tc.forEach(t=>{Gc(e,t),$c(e,t),zc(e,t),Pc(e,t)})}function kn(e,t,r,n,i){let s=n._nodes.values(),a=n.type,l,g,f,p,y,w,E;for(;l=s.next(),l.done!==!0;){let A=!1;if(g=l.value,a!=="undirected"){p=g.out;for(f in p){y=p[f];do{if(w=y.target,A=!0,E=i(g.key,w.key,g.attributes,w.attributes,y.key,y.attributes,y.undirected),e&&E)return y;y=y.next}while(y)}}if(a!=="directed"){p=g.undirected;for(f in p)if(!(t&&g.key>f)){y=p[f];do{if(w=y.target,w.key!==f&&(w=y.source),A=!0,E=i(g.key,w.key,g.attributes,w.attributes,y.key,y.attributes,y.undirected),e&&E)return y;y=y.next}while(y)}}if(r&&!A&&(E=i(g.key,null,g.attributes,null,null,null,null),e&&E))return null}}function Wc(e,t){let r={key:e};return Ps(t.attributes)||(r.attributes=ne({},t.attributes)),r}function Fc(e,t,r){let n={key:t,source:r.source.key,target:r.target.key};return Ps(r.attributes)||(n.attributes=ne({},r.attributes)),e==="mixed"&&r.undirected&&(n.undirected=!0),n}function qc(e){if(!le(e))throw new rt('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in e))throw new rt("Graph.import: serialized node is missing its key.");if("attributes"in e&&(!le(e.attributes)||e.attributes===null))throw new rt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function Uc(e){if(!le(e))throw new rt('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in e))throw new rt("Graph.import: serialized edge is missing its source.");if(!("target"in e))throw new rt("Graph.import: serialized edge is missing its target.");if("attributes"in e&&(!le(e.attributes)||e.attributes===null))throw new rt("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in e&&typeof e.undirected!="boolean")throw new rt("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}var Bc=Yh(),Vc=new Set(["directed","undirected","mixed"]),Gs=new Set(["domain","_events","_eventsCount","_maxListeners"]),Yc=[{name:e=>`${e}Edge`,generateKey:!0},{name:e=>`${e}DirectedEdge`,generateKey:!0,type:"directed"},{name:e=>`${e}UndirectedEdge`,generateKey:!0,type:"undirected"},{name:e=>`${e}EdgeWithKey`},{name:e=>`${e}DirectedEdgeWithKey`,type:"directed"},{name:e=>`${e}UndirectedEdgeWithKey`,type:"undirected"}],Kc={allowSelfLoops:!0,multi:!1,type:"mixed"};function Xc(e,t,r){if(r&&!le(r))throw new rt(`Graph.addNode: invalid attributes. Expecting an object but got "${r}"`);if(t=""+t,r=r||{},e._nodes.has(t))throw new dt(`Graph.addNode: the "${t}" node already exist in the graph.`);let n=new e.NodeDataClass(t,r);return e._nodes.set(t,n),e.emit("nodeAdded",{key:t,attributes:r}),n}function $s(e,t,r){let n=new e.NodeDataClass(t,r);return e._nodes.set(t,n),e.emit("nodeAdded",{key:t,attributes:r}),n}function Ys(e,t,r,n,i,s,a,l){if(!n&&e.type==="undirected")throw new dt(`Graph.${t}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.`);if(n&&e.type==="directed")throw new dt(`Graph.${t}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.`);if(l&&!le(l))throw new rt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`);if(s=""+s,a=""+a,l=l||{},!e.allowSelfLoops&&s===a)throw new dt(`Graph.${t}: source & target are the same ("${s}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let g=e._nodes.get(s),f=e._nodes.get(a);if(!g)throw new Z(`Graph.${t}: source node "${s}" not found.`);if(!f)throw new Z(`Graph.${t}: target node "${a}" not found.`);let p={key:null,undirected:n,source:s,target:a,attributes:l};if(r)i=e._edgeKeyGenerator();else if(i=""+i,e._edges.has(i))throw new dt(`Graph.${t}: the "${i}" edge already exists in the graph.`);if(!e.multi&&(n?typeof g.undirected[a]<"u":typeof g.out[a]<"u"))throw new dt(`Graph.${t}: an edge linking "${s}" to "${a}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.`);let y=new Or(n,i,g,f,l);e._edges.set(i,y);let w=s===a;return n?(g.undirectedDegree++,f.undirectedDegree++,w&&(g.undirectedLoops++,e._undirectedSelfLoopCount++)):(g.outDegree++,f.inDegree++,w&&(g.directedLoops++,e._directedSelfLoopCount++)),e.multi?y.attachMulti():y.attach(),n?e._undirectedSize++:e._directedSize++,p.key=i,e.emit("edgeAdded",p),i}function Qc(e,t,r,n,i,s,a,l,g){if(!n&&e.type==="undirected")throw new dt(`Graph.${t}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.`);if(n&&e.type==="directed")throw new dt(`Graph.${t}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.`);if(l){if(g){if(typeof l!="function")throw new rt(`Graph.${t}: invalid updater function. Expecting a function but got "${l}"`)}else if(!le(l))throw new rt(`Graph.${t}: invalid attributes. Expecting an object but got "${l}"`)}s=""+s,a=""+a;let f;if(g&&(f=l,l=void 0),!e.allowSelfLoops&&s===a)throw new dt(`Graph.${t}: source & target are the same ("${s}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.`);let p=e._nodes.get(s),y=e._nodes.get(a),w,E;if(!r&&(w=e._edges.get(i),w)){if((w.source.key!==s||w.target.key!==a)&&(!n||w.source.key!==a||w.target.key!==s))throw new dt(`Graph.${t}: inconsistency detected when attempting to merge the "${i}" edge with "${s}" source & "${a}" target vs. ("${w.source.key}", "${w.target.key}").`);E=w}if(!E&&!e.multi&&p&&(E=n?p.undirected[a]:p.out[a]),E){let j=[E.key,!1,!1,!1];if(g?!f:!l)return j;if(g){let R=E.attributes;E.attributes=f(R),e.emit("edgeAttributesUpdated",{type:"replace",key:E.key,attributes:E.attributes})}else ne(E.attributes,l),e.emit("edgeAttributesUpdated",{type:"merge",key:E.key,attributes:E.attributes,data:l});return j}l=l||{},g&&f&&(l=f(l));let A={key:null,undirected:n,source:s,target:a,attributes:l};if(r)i=e._edgeKeyGenerator();else if(i=""+i,e._edges.has(i))throw new dt(`Graph.${t}: the "${i}" edge already exists in the graph.`);let I=!1,_=!1;p||(p=$s(e,s,{}),I=!0,s===a&&(y=p,_=!0)),y||(y=$s(e,a,{}),_=!0),w=new Or(n,i,p,y,l),e._edges.set(i,w);let $=s===a;return n?(p.undirectedDegree++,y.undirectedDegree++,$&&(p.undirectedLoops++,e._undirectedSelfLoopCount++)):(p.outDegree++,y.inDegree++,$&&(p.directedLoops++,e._directedSelfLoopCount++)),e.multi?w.attachMulti():w.attach(),n?e._undirectedSize++:e._directedSize++,A.key=i,e.emit("edgeAdded",A),[i,!0,I,_]}function Tr(e,t){e._edges.delete(t.key);let{source:r,target:n,attributes:i}=t,s=t.undirected,a=r===n;s?(r.undirectedDegree--,n.undirectedDegree--,a&&(r.undirectedLoops--,e._undirectedSelfLoopCount--)):(r.outDegree--,n.inDegree--,a&&(r.directedLoops--,e._directedSelfLoopCount--)),e.multi?t.detachMulti():t.detach(),s?e._undirectedSize--:e._directedSize--,e.emit("edgeDropped",{key:t.key,attributes:i,source:r.key,target:n.key,undirected:s})}var Mt=class e extends zs.EventEmitter{constructor(t){if(super(),t=ne({},Kc,t),typeof t.multi!="boolean")throw new rt(`Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${t.multi}".`);if(!Vc.has(t.type))throw new rt(`Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${t.type}".`);if(typeof t.allowSelfLoops!="boolean")throw new rt(`Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${t.allowSelfLoops}".`);let r=t.type==="mixed"?Ns:t.type==="directed"?Ws:Fs;Le(this,"NodeDataClass",r);let n="geid_"+Bc()+"_",i=0,s=()=>{let a;do a=n+i++;while(this._edges.has(a));return a};Le(this,"_attributes",{}),Le(this,"_nodes",new Map),Le(this,"_edges",new Map),Le(this,"_directedSize",0),Le(this,"_undirectedSize",0),Le(this,"_directedSelfLoopCount",0),Le(this,"_undirectedSelfLoopCount",0),Le(this,"_edgeKeyGenerator",s),Le(this,"_options",t),Gs.forEach(a=>Le(this,a,this[a])),ze(this,"order",()=>this._nodes.size),ze(this,"size",()=>this._edges.size),ze(this,"directedSize",()=>this._directedSize),ze(this,"undirectedSize",()=>this._undirectedSize),ze(this,"selfLoopCount",()=>this._directedSelfLoopCount+this._undirectedSelfLoopCount),ze(this,"directedSelfLoopCount",()=>this._directedSelfLoopCount),ze(this,"undirectedSelfLoopCount",()=>this._undirectedSelfLoopCount),ze(this,"multi",this._options.multi),ze(this,"type",this._options.type),ze(this,"allowSelfLoops",this._options.allowSelfLoops),ze(this,"implementation",()=>"graphology")}_resetInstanceCounters(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0}hasNode(t){return this._nodes.has(""+t)}hasDirectedEdge(t,r){if(this.type==="undirected")return!1;if(arguments.length===1){let n=""+t,i=this._edges.get(n);return!!i&&!i.undirected}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?n.out.hasOwnProperty(r):!1}throw new rt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasUndirectedEdge(t,r){if(this.type==="directed")return!1;if(arguments.length===1){let n=""+t,i=this._edges.get(n);return!!i&&i.undirected}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?n.undirected.hasOwnProperty(r):!1}throw new rt(`Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}hasEdge(t,r){if(arguments.length===1){let n=""+t;return this._edges.has(n)}else if(arguments.length===2){t=""+t,r=""+r;let n=this._nodes.get(t);return n?typeof n.out<"u"&&n.out.hasOwnProperty(r)||typeof n.undirected<"u"&&n.undirected.hasOwnProperty(r):!1}throw new rt(`Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.`)}directedEdge(t,r){if(this.type==="undirected")return;if(t=""+t,r=""+r,this.multi)throw new dt("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");let n=this._nodes.get(t);if(!n)throw new Z(`Graph.directedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.directedEdge: could not find the "${r}" target node in the graph.`);let i=n.out&&n.out[r]||void 0;if(i)return i.key}undirectedEdge(t,r){if(this.type==="directed")return;if(t=""+t,r=""+r,this.multi)throw new dt("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");let n=this._nodes.get(t);if(!n)throw new Z(`Graph.undirectedEdge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.undirectedEdge: could not find the "${r}" target node in the graph.`);let i=n.undirected&&n.undirected[r]||void 0;if(i)return i.key}edge(t,r){if(this.multi)throw new dt("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.edge: could not find the "${t}" source node in the graph.`);if(!this._nodes.has(r))throw new Z(`Graph.edge: could not find the "${r}" target node in the graph.`);let i=n.out&&n.out[r]||n.undirected&&n.undirected[r]||void 0;if(i)return i.key}areDirectedNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areDirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.in||r in n.out}areOutNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areOutNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.out}areInNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areInNeighbors: could not find the "${t}" node in the graph.`);return this.type==="undirected"?!1:r in n.in}areUndirectedNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areUndirectedNeighbors: could not find the "${t}" node in the graph.`);return this.type==="directed"?!1:r in n.undirected}areNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&(r in n.in||r in n.out)||this.type!=="directed"&&r in n.undirected}areInboundNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areInboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&r in n.in||this.type!=="directed"&&r in n.undirected}areOutboundNeighbors(t,r){t=""+t,r=""+r;let n=this._nodes.get(t);if(!n)throw new Z(`Graph.areOutboundNeighbors: could not find the "${t}" node in the graph.`);return this.type!=="undirected"&&r in n.out||this.type!=="directed"&&r in n.undirected}inDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree}outDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.outDegree}directedDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.directedDegree: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree+r.outDegree}undirectedDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.undirectedDegree: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:r.undirectedDegree}inboundDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.inDegree),n}outboundDegree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outboundDegree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.outDegree),n}degree(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.degree: could not find the "${t}" node in the graph.`);let n=0;return this.type!=="directed"&&(n+=r.undirectedDegree),this.type!=="undirected"&&(n+=r.inDegree+r.outDegree),n}inDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree-r.directedLoops}outDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.outDegree-r.directedLoops}directedDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.directedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="undirected"?0:r.inDegree+r.outDegree-r.directedLoops*2}undirectedDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.undirectedDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);return this.type==="directed"?0:r.undirectedDegree-r.undirectedLoops*2}inboundDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.inboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.inDegree,i+=r.directedLoops),n-i}outboundDegreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.outboundDegreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.outDegree,i+=r.directedLoops),n-i}degreeWithoutSelfLoops(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.degreeWithoutSelfLoops: could not find the "${t}" node in the graph.`);let n=0,i=0;return this.type!=="directed"&&(n+=r.undirectedDegree,i+=r.undirectedLoops*2),this.type!=="undirected"&&(n+=r.inDegree+r.outDegree,i+=r.directedLoops*2),n-i}source(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.source: could not find the "${t}" edge in the graph.`);return r.source.key}target(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.target: could not find the "${t}" edge in the graph.`);return r.target.key}extremities(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.extremities: could not find the "${t}" edge in the graph.`);return[r.source.key,r.target.key]}opposite(t,r){t=""+t,r=""+r;let n=this._edges.get(r);if(!n)throw new Z(`Graph.opposite: could not find the "${r}" edge in the graph.`);let i=n.source.key,s=n.target.key;if(t===i)return s;if(t===s)return i;throw new Z(`Graph.opposite: the "${t}" node is not attached to the "${r}" edge (${i}, ${s}).`)}hasExtremity(t,r){t=""+t,r=""+r;let n=this._edges.get(t);if(!n)throw new Z(`Graph.hasExtremity: could not find the "${t}" edge in the graph.`);return n.source.key===r||n.target.key===r}isUndirected(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isUndirected: could not find the "${t}" edge in the graph.`);return r.undirected}isDirected(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isDirected: could not find the "${t}" edge in the graph.`);return!r.undirected}isSelfLoop(t){t=""+t;let r=this._edges.get(t);if(!r)throw new Z(`Graph.isSelfLoop: could not find the "${t}" edge in the graph.`);return r.source===r.target}addNode(t,r){return Xc(this,t,r).key}mergeNode(t,r){if(r&&!le(r))throw new rt(`Graph.mergeNode: invalid attributes. Expecting an object but got "${r}"`);t=""+t,r=r||{};let n=this._nodes.get(t);return n?(r&&(ne(n.attributes,r),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:n.attributes,data:r})),[t,!1]):(n=new this.NodeDataClass(t,r),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:r}),[t,!0])}updateNode(t,r){if(r&&typeof r!="function")throw new rt(`Graph.updateNode: invalid updater function. Expecting a function but got "${r}"`);t=""+t;let n=this._nodes.get(t);if(n){if(r){let s=n.attributes;n.attributes=r(s),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:n.attributes})}return[t,!1]}let i=r?r({}):{};return n=new this.NodeDataClass(t,i),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:i}),[t,!0]}dropNode(t){t=""+t;let r=this._nodes.get(t);if(!r)throw new Z(`Graph.dropNode: could not find the "${t}" node in the graph.`);let n;if(this.type!=="undirected"){for(let i in r.out){n=r.out[i];do Tr(this,n),n=n.next;while(n)}for(let i in r.in){n=r.in[i];do Tr(this,n),n=n.next;while(n)}}if(this.type!=="directed")for(let i in r.undirected){n=r.undirected[i];do Tr(this,n),n=n.next;while(n)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:r.attributes})}dropEdge(t){let r;if(arguments.length>1){let n=""+arguments[0],i=""+arguments[1];if(r=_e(this,n,i,this.type),!r)throw new Z(`Graph.dropEdge: could not find the "${n}" -> "${i}" edge in the graph.`)}else if(t=""+t,r=this._edges.get(t),!r)throw new Z(`Graph.dropEdge: could not find the "${t}" edge in the graph.`);return Tr(this,r),this}dropDirectedEdge(t,r){if(arguments.length<2)throw new dt("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new dt("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");t=""+t,r=""+r;let n=_e(this,t,r,"directed");if(!n)throw new Z(`Graph.dropDirectedEdge: could not find a "${t}" -> "${r}" edge in the graph.`);return Tr(this,n),this}dropUndirectedEdge(t,r){if(arguments.length<2)throw new dt("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new dt("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");let n=_e(this,t,r,"undirected");if(!n)throw new Z(`Graph.dropUndirectedEdge: could not find a "${t}" -> "${r}" edge in the graph.`);return Tr(this,n),this}clear(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")}clearEdges(){let t=this._nodes.values(),r;for(;r=t.next(),r.done!==!0;)r.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")}getAttribute(t){return this._attributes[t]}getAttributes(){return this._attributes}hasAttribute(t){return this._attributes.hasOwnProperty(t)}setAttribute(t,r){return this._attributes[t]=r,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}updateAttribute(t,r){if(typeof r!="function")throw new rt("Graph.updateAttribute: updater should be a function.");let n=this._attributes[t];return this._attributes[t]=r(n),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this}removeAttribute(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this}replaceAttributes(t){if(!le(t))throw new rt("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this}mergeAttributes(t){if(!le(t))throw new rt("Graph.mergeAttributes: provided attributes are not a plain object.");return ne(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this}updateAttributes(t){if(typeof t!="function")throw new rt("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this}updateEachNodeAttributes(t,r){if(typeof t!="function")throw new rt("Graph.updateEachNodeAttributes: expecting an updater function.");if(r&&!Os(r))throw new rt("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._nodes.values(),i,s;for(;i=n.next(),i.done!==!0;)s=i.value,s.attributes=t(s.key,s.attributes);this.emit("eachNodeAttributesUpdated",{hints:r||null})}updateEachEdgeAttributes(t,r){if(typeof t!="function")throw new rt("Graph.updateEachEdgeAttributes: expecting an updater function.");if(r&&!Os(r))throw new rt("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");let n=this._edges.values(),i,s,a,l;for(;i=n.next(),i.done!==!0;)s=i.value,a=s.source,l=s.target,s.attributes=t(s.key,s.attributes,a.key,l.key,a.attributes,l.attributes,s.undirected);this.emit("eachEdgeAttributesUpdated",{hints:r||null})}forEachAdjacencyEntry(t){if(typeof t!="function")throw new rt("Graph.forEachAdjacencyEntry: expecting a callback.");kn(!1,!1,!1,this,t)}forEachAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new rt("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");kn(!1,!1,!0,this,t)}forEachAssymetricAdjacencyEntry(t){if(typeof t!="function")throw new rt("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");kn(!1,!0,!1,this,t)}forEachAssymetricAdjacencyEntryWithOrphans(t){if(typeof t!="function")throw new rt("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");kn(!1,!0,!0,this,t)}nodes(){return Array.from(this._nodes.keys())}forEachNode(t){if(typeof t!="function")throw new rt("Graph.forEachNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)i=n.value,t(i.key,i.attributes)}findNode(t){if(typeof t!="function")throw new rt("Graph.findNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,t(i.key,i.attributes))return i.key}mapNodes(t){if(typeof t!="function")throw new rt("Graph.mapNode: expecting a callback.");let r=this._nodes.values(),n,i,s=new Array(this.order),a=0;for(;n=r.next(),n.done!==!0;)i=n.value,s[a++]=t(i.key,i.attributes);return s}someNode(t){if(typeof t!="function")throw new rt("Graph.someNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,t(i.key,i.attributes))return!0;return!1}everyNode(t){if(typeof t!="function")throw new rt("Graph.everyNode: expecting a callback.");let r=this._nodes.values(),n,i;for(;n=r.next(),n.done!==!0;)if(i=n.value,!t(i.key,i.attributes))return!1;return!0}filterNodes(t){if(typeof t!="function")throw new rt("Graph.filterNodes: expecting a callback.");let r=this._nodes.values(),n,i,s=[];for(;n=r.next(),n.done!==!0;)i=n.value,t(i.key,i.attributes)&&s.push(i.key);return s}reduceNodes(t,r){if(typeof t!="function")throw new rt("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new rt("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");let n=r,i=this._nodes.values(),s,a;for(;s=i.next(),s.done!==!0;)a=s.value,n=t(n,a.key,a.attributes);return n}nodeEntries(){let t=this._nodes.values();return{[Symbol.iterator](){return this},next(){let r=t.next();if(r.done)return r;let n=r.value;return{value:{node:n.key,attributes:n.attributes},done:!1}}}}export(){let t=new Array(this._nodes.size),r=0;this._nodes.forEach((i,s)=>{t[r++]=Wc(s,i)});let n=new Array(this._edges.size);return r=0,this._edges.forEach((i,s)=>{n[r++]=Fc(this.type,s,i)}),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:n}}import(t,r=!1){if(t instanceof e)return t.forEachNode((g,f)=>{r?this.mergeNode(g,f):this.addNode(g,f)}),t.forEachEdge((g,f,p,y,w,E,A)=>{r?A?this.mergeUndirectedEdgeWithKey(g,p,y,f):this.mergeDirectedEdgeWithKey(g,p,y,f):A?this.addUndirectedEdgeWithKey(g,p,y,f):this.addDirectedEdgeWithKey(g,p,y,f)}),this;if(!le(t))throw new rt("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!le(t.attributes))throw new rt("Graph.import: invalid attributes. Expecting a plain object.");r?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}let n,i,s,a,l;if(t.nodes){if(s=t.nodes,!Array.isArray(s))throw new rt("Graph.import: invalid nodes. Expecting an array.");for(n=0,i=s.length;n{let s=ne({},n.attributes);n=new r.NodeDataClass(i,s),r._nodes.set(i,n)}),r}copy(t){if(t=t||{},typeof t.type=="string"&&t.type!==this.type&&t.type!=="mixed")throw new dt(`Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${t.type}" because this would mean losing information about the current graph.`);if(typeof t.multi=="boolean"&&t.multi!==this.multi&&t.multi!==!0)throw new dt("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if(typeof t.allowSelfLoops=="boolean"&&t.allowSelfLoops!==this.allowSelfLoops&&t.allowSelfLoops!==!0)throw new dt("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");let r=this.emptyCopy(t),n=this._edges.values(),i,s;for(;i=n.next(),i.done!==!0;)s=i.value,Ys(r,"copy",!1,s.undirected,s.key,s.source.key,s.target.key,ne({},s.attributes));return r}toJSON(){return this.export()}toString(){return"[object Graph]"}inspect(){let t={};this._nodes.forEach((s,a)=>{t[a]=s.attributes});let r={},n={};this._edges.forEach((s,a)=>{let l=s.undirected?"--":"->",g="",f=s.source.key,p=s.target.key,y;s.undirected&&f>p&&(y=f,f=p,p=y);let w=`(${f})${l}(${p})`;a.startsWith("geid_")?this.multi&&(typeof n[w]>"u"?n[w]=0:n[w]++,g+=`${n[w]}. `):g+=`[${a}]: `,g+=w,r[g]=s.attributes});let i={};for(let s in this)this.hasOwnProperty(s)&&!Gs.has(s)&&typeof this[s]!="function"&&typeof s!="symbol"&&(i[s]=this[s]);return i.attributes=this._attributes,i.nodes=t,i.edges=r,Le(i,"constructor",this.constructor),i}};typeof Symbol<"u"&&(Mt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Mt.prototype.inspect);Yc.forEach(e=>{["add","merge","update"].forEach(t=>{let r=e.name(t),n=t==="add"?Ys:Qc;e.generateKey?Mt.prototype[r]=function(i,s,a){return n(this,r,!0,(e.type||this.type)==="undirected",null,i,s,a,t==="update")}:Mt.prototype[r]=function(i,s,a,l){return n(this,r,!1,(e.type||this.type)==="undirected",i,s,a,l,t==="update")}})});sc(Mt);yc(Mt);Rc(Mt);Nc(Mt);var jn=class extends Mt{constructor(t){let r=ne({type:"directed"},t);if("multi"in r&&r.multi!==!1)throw new rt("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(r.type!=="directed")throw new rt('DirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},Cn=class extends Mt{constructor(t){let r=ne({type:"undirected"},t);if("multi"in r&&r.multi!==!1)throw new rt("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if(r.type!=="undirected")throw new rt('UndirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},Ln=class extends Mt{constructor(t){let r=ne({multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");super(r)}},_n=class extends Mt{constructor(t){let r=ne({type:"directed",multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(r.type!=="directed")throw new rt('MultiDirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}},Rn=class extends Mt{constructor(t){let r=ne({type:"undirected",multi:!0},t);if("multi"in r&&r.multi!==!0)throw new rt("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if(r.type!=="undirected")throw new rt('MultiUndirectedGraph.from: inconsistent "'+r.type+'" type in given options!');super(r)}};function Gr(e){e.from=function(t,r){let n=ne({},t.options,r),i=new e(n);return i.import(t),i}}Gr(Mt);Gr(jn);Gr(Cn);Gr(Ln);Gr(_n);Gr(Rn);Mt.Graph=Mt;Mt.DirectedGraph=jn;Mt.UndirectedGraph=Cn;Mt.MultiGraph=Ln;Mt.MultiDirectedGraph=_n;Mt.MultiUndirectedGraph=Rn;Mt.InvalidArgumentsGraphError=rt;Mt.NotFoundGraphError=Z;Mt.UsageGraphError=dt;var vi=xe(Co(),1),Dg=xe(No(),1),Ig=xe(Uo(),1),kg=xe(ta(),1);function Me(e,t,r,n){function i(s){return s instanceof r?s:new r(function(a){a(s)})}return new(r||(r=Promise))(function(s,a){function l(p){try{f(n.next(p))}catch(y){a(y)}}function g(p){try{f(n.throw(p))}catch(y){a(y)}}function f(p){p.done?s(p.value):i(p.value).then(l,g)}f((n=n.apply(e,t||[])).next())})}var Pl={abs:Math.abs,ceil:Math.ceil,floor:Math.floor,max:Math.max,min:Math.min,round:Math.round,sqrt:Math.sqrt,pow:Math.pow},Ut=class extends Error{constructor(t,r,n){super(t),this.position=r,this.token=n,this.name="ExpressionError"}},wt;(function(e){e[e.STRING=0]="STRING",e[e.NUMBER=1]="NUMBER",e[e.BOOLEAN=2]="BOOLEAN",e[e.NULL=3]="NULL",e[e.IDENTIFIER=4]="IDENTIFIER",e[e.OPERATOR=5]="OPERATOR",e[e.FUNCTION=6]="FUNCTION",e[e.DOT=7]="DOT",e[e.BRACKET_LEFT=8]="BRACKET_LEFT",e[e.BRACKET_RIGHT=9]="BRACKET_RIGHT",e[e.PAREN_LEFT=10]="PAREN_LEFT",e[e.PAREN_RIGHT=11]="PAREN_RIGHT",e[e.COMMA=12]="COMMA",e[e.QUESTION=13]="QUESTION",e[e.COLON=14]="COLON",e[e.DOLLAR=15]="DOLLAR"})(wt||(wt={}));var Nl=new Set([32,9,10,13]),Wl=new Set([43,45,42,47,37,33,38,124,61,60,62]),Fl=new Map([["true",wt.BOOLEAN],["false",wt.BOOLEAN],["null",wt.NULL]]),Oi=new Map([["===",!0],["!==",!0],["<=",!0],[">=",!0],["&&",!0],["||",!0],["+",!0],["-",!0],["*",!0],["/",!0],["%",!0],["!",!0],["<",!0],[">",!0]]),ql=new Map([[46,wt.DOT],[91,wt.BRACKET_LEFT],[93,wt.BRACKET_RIGHT],[40,wt.PAREN_LEFT],[41,wt.PAREN_RIGHT],[44,wt.COMMA],[63,wt.QUESTION],[58,wt.COLON],[36,wt.DOLLAR]]),ra=new Map;for(let[e,t]of ql.entries())ra.set(e,{type:t,value:String.fromCharCode(e)});function an(e){return e>=48&&e<=57}function Gi(e){return e>=97&&e<=122||e>=65&&e<=90||e===95}function ea(e){return Gi(e)||an(e)}function Ul(e){return Wl.has(e)}var Ft;(function(e){e[e.Program=0]="Program",e[e.Literal=1]="Literal",e[e.Identifier=2]="Identifier",e[e.MemberExpression=3]="MemberExpression",e[e.CallExpression=4]="CallExpression",e[e.BinaryExpression=5]="BinaryExpression",e[e.UnaryExpression=6]="UnaryExpression",e[e.ConditionalExpression=7]="ConditionalExpression"})(Ft||(Ft={}));var Bl=new Map([["||",2],["&&",3],["===",4],["!==",4],[">",5],[">=",5],["<",5],["<=",5],["+",6],["-",6],["*",7],["/",7],["%",7],["!",8]]),Vl={type:Ft.Literal,value:null},Yl={type:Ft.Literal,value:!0},Kl={type:Ft.Literal,value:!1},Xl=e=>{let t=0,r=e.length,n=()=>t>=r?null:e[t],i=()=>e[t++],s=y=>{let w=n();return w!==null&&w.type===y},a=y=>y.type===wt.OPERATOR?Bl.get(y.value)||-1:y.type===wt.DOT||y.type===wt.BRACKET_LEFT?9:y.type===wt.QUESTION?1:-1,l=y=>{let w,E;if(i().type===wt.DOT){if(!s(wt.IDENTIFIER)){let I=n();throw new Ut("Expected property name",t,I?I.value:"")}let A=i();w={type:Ft.Identifier,name:A.value},E=!1}else{if(w=f(0),!s(wt.BRACKET_RIGHT)){let A=n();throw new Ut("Expected closing bracket",t,A?A.value:"")}i(),E=!0}return{type:Ft.MemberExpression,object:y,property:w,computed:E}},g=()=>{let y=n();if(!y)throw new Ut("Unexpected end of input",t,"");if(y.type===wt.OPERATOR&&(y.value==="!"||y.value==="-")){i();let w=g();return{type:Ft.UnaryExpression,operator:y.value,argument:w,prefix:!0}}switch(y.type){case wt.NUMBER:return i(),{type:Ft.Literal,value:Number(y.value)};case wt.STRING:return i(),{type:Ft.Literal,value:y.value};case wt.BOOLEAN:return i(),y.value==="true"?Yl:Kl;case wt.NULL:return i(),Vl;case wt.IDENTIFIER:return i(),{type:Ft.Identifier,name:y.value};case wt.FUNCTION:return(()=>{let w=i(),E=[];if(!s(wt.PAREN_LEFT)){let A=n();throw new Ut("Expected opening parenthesis after function name",t,A?A.value:"")}for(i();;){if(s(wt.PAREN_RIGHT)){i();break}if(!n()){let I=n();throw new Ut("Expected closing parenthesis",t,I?I.value:"")}if(E.length>0){if(!s(wt.COMMA)){let I=n();throw new Ut("Expected comma between function arguments",t,I?I.value:"")}i()}let A=f(0);E.push(A)}return{type:Ft.CallExpression,callee:{type:Ft.Identifier,name:w.value},arguments:E}})();case wt.PAREN_LEFT:{i();let w=f(0);if(!s(wt.PAREN_RIGHT)){let E=n();throw new Ut("Expected closing parenthesis",t,E?E.value:"")}return i(),w}default:throw new Ut(`Unexpected token: ${y.type}`,t,y.value)}},f=(y=0)=>{let w=g();for(;t")}i();let _=f(0);w={type:Ft.ConditionalExpression,test:w,consequent:I,alternate:_}}}return w},p=f();return{type:Ft.Program,body:p}},Ql=(e,t,r)=>{let n=t;r&&(n={...t,context:{...t.context,...r}});let i=s=>{switch(s.type){case Ft.Literal:return(a=>a.value)(s);case Ft.Identifier:return(a=>{if(!(a.name in n.context))throw new Ut(`Undefined variable: ${a.name}`);return n.context[a.name]})(s);case Ft.MemberExpression:return(a=>{let l=i(a.object);if(l==null)throw new Ut("Cannot access property of null or undefined");return l[a.computed?i(a.property):a.property.name]})(s);case Ft.CallExpression:return(a=>{let l=n.functions[a.callee.name];if(!l)throw new Ut(`Undefined function: ${a.callee.name}`);return l(...a.arguments.map((g=>i(g))))})(s);case Ft.BinaryExpression:return(a=>{if(a.operator==="&&"){let f=i(a.left);return f&&i(a.right)}if(a.operator==="||")return i(a.left)||i(a.right);let l=i(a.left),g=i(a.right);switch(a.operator){case"+":return l+g;case"-":return l-g;case"*":return l*g;case"/":return l/g;case"%":return l%g;case"===":return l===g;case"!==":return l!==g;case">":return l>g;case">=":return l>=g;case"<":return l{let l=i(a.argument);if(a.prefix)switch(a.operator){case"!":return!l;case"-":if(typeof l!="number")throw new Ut(`Cannot apply unary - to non-number: ${l}`);return-l;default:throw new Ut(`Unknown operator: ${a.operator}`)}throw new Ut(`Postfix operators are not supported: ${a.operator}`)})(s);case Ft.ConditionalExpression:return(a=>{let l=i(a.test);return i(l?a.consequent:a.alternate)})(s);default:throw new Ut(`Evaluation error: Unsupported node type: ${s.type}`)}};return i(e.body)};function $i(e){let t=(i=>{let s=i,a=s.length,l=new Array(Math.ceil(a/3)),g=0,f=0;function p(_){let $=f+1;f++;let j="",R=!1;for(;f({context:i,functions:s}))({},Pl);return(i={})=>Ql(r,n,i)}function na(e,t={}){return $i(e)(t)}function ia(e,t){if(typeof e!="string")return;let r=e.trim();if(r)try{return $i(r),na(r,t)}catch{return}}function Nr(e){return typeof e=="number"}function zi(e){if(!e)return[0,0,0];if(Nr(e))return[e,e,e];if(Array.isArray(e)&&e.length===0)return[0,0,0];let[t,r=t,n=t]=e;return[t,r,n]}function sa(e){return Nr(e)?!0:Array.isArray(e)?e.every(t=>Nr(t)):!1}function Ne(e){return e==null}function oa(e){return typeof e=="string"}function aa(e){return typeof e=="function"}function un(e,t){if(typeof e=="function")return e;if(typeof e=="string"){let r=e;return(...n)=>{let i={};for(let s=0;se}function ua(e,t=10,r="node"){if(Ne(e))return()=>t;if(oa(e)){let n=un(e,[r]);return i=>{let s=n(i);return sa(s)?s:t}}return aa(e)?e:Nr(e)?()=>e:Array.isArray(e)?()=>e:()=>t}var Nn=(e,t,r=10,n=0)=>{let i=ua(t,n),s=ua(e,r);return a=>{let[l,g,f]=zi(s(a)),[p,y,w]=zi(i(a));return[l+p,g+y,f+w]}};var Wn=class{constructor(t,r={}){this.edgeIdCounter=new Map,this.nodeMap=Hl(t.nodes,r.node),this.edgeMap=tf(t.edges||[],r.edge,this.getEdgeId.bind(this))}data(){return{nodes:this.nodeMap,edges:this.edgeMap}}replace(t){this.nodeMap=t.nodes,this.edgeMap=t.edges,this.clearCache()}nodes(){return Array.from(this.nodeMap.values())}node(t){return this.nodeMap.get(t)}nodeAt(t){this.indexNodeCache||this.buildNodeIndexCache();let r=this.indexNodeCache.get(t);return r?this.nodeMap.get(r):void 0}nodeIndexOf(t){var r;return this.nodeIndexCache||this.buildNodeIndexCache(),(r=this.nodeIndexCache.get(t))!==null&&r!==void 0?r:-1}firstNode(){return this.nodeMap.values().next().value}forEachNode(t){let r=0;this.nodeMap.forEach(n=>t(n,r++))}originalNode(t){let r=this.nodeMap.get(t);return r?._original}nodeCount(){return this.nodeMap.size}edges(){return Array.from(this.edgeMap.values())}edge(t){return this.edgeMap.get(t)}firstEdge(){return this.edgeMap.values().next().value}forEachEdge(t){let r=0;this.edgeMap.forEach(n=>t(n,r++))}originalEdge(t){let r=this.edgeMap.get(t);return r?._original}edgeCount(){return this.edgeMap.size}getEdgeId(t){if(t.id)return t.id;let r=`${t.source}-${t.target}`,n=this.edgeIdCounter.get(r)||0,i=n===0?r:`${r}-${n}`;return this.edgeIdCounter.set(r,n+1),i}degree(t,r="both"){this.degreeCache||this.buildDegreeCache();let n=this.degreeCache.get(t);return n?n[r]:0}neighbors(t,r="both"){if((!this.outAdjacencyCache||!this.inAdjacencyCache)&&this.buildAdjacencyCache(),r==="out")return Array.from(this.outAdjacencyCache.get(t)||[]);if(r==="in")return Array.from(this.inAdjacencyCache.get(t)||[]);if(this.bothAdjacencyCache)return Array.from(this.bothAdjacencyCache.get(t)||[]);let n=this.inAdjacencyCache.get(t),i=this.outAdjacencyCache.get(t);if(!n&&!i)return[];if(!n)return Array.from(i);if(!i)return Array.from(n);let s=new Set;return n.forEach(a=>s.add(a)),i.forEach(a=>s.add(a)),Array.from(s)}successors(t){return this.neighbors(t,"out")}predecessors(t){return this.neighbors(t,"in")}setNodeOrder(t){let r=new Map;for(let n of t)r.set(n.id,n);this.nodeMap=r,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}clearCache(){this.degreeCache=void 0,this.inAdjacencyCache=void 0,this.outAdjacencyCache=void 0,this.bothAdjacencyCache=void 0,this.nodeIndexCache=void 0,this.indexNodeCache=void 0}buildDegreeCache(){this.degreeCache=new Map;for(let t of this.edges()){let{source:r,target:n}=t;if(t.source===t.target)continue;this.degreeCache.has(r)||this.degreeCache.set(r,{in:0,out:0,both:0});let i=this.degreeCache.get(t.source);i&&(i.out++,i.both++),this.degreeCache.has(n)||this.degreeCache.set(n,{in:0,out:0,both:0});let s=this.degreeCache.get(t.target);s&&(s.in++,s.both++)}}buildAdjacencyCache(){this.inAdjacencyCache=new Map,this.outAdjacencyCache=new Map;for(let t of this.edges())!this.nodeMap.has(t.source)||!this.nodeMap.has(t.target)||(this.outAdjacencyCache.has(t.source)||this.outAdjacencyCache.set(t.source,new Set),this.outAdjacencyCache.get(t.source).add(t.target),this.inAdjacencyCache.has(t.target)||this.inAdjacencyCache.set(t.target,new Set),this.inAdjacencyCache.get(t.target).add(t.source))}buildNodeIndexCache(){this.nodeIndexCache=new Map,this.indexNodeCache=new Map;let t=0;this.nodeMap.forEach((r,n)=>{this.nodeIndexCache.set(n,t),this.indexNodeCache.set(t,n),t++})}destroy(){this.clearCache(),this.nodeMap.clear(),this.edgeMap.clear(),this.edgeIdCounter.clear()}},Jl=["id","x","y","z","vx","vy","vz","fx","fy","fz","parentId"],Zl=["id","source","target","points"];function Hl(e,t){if(!e)throw new Error("Data.nodes is required");let r=new Map;for(let n of e){let i={_original:n};for(let s of Jl){let a=n[s];Ne(a)||(i[s]=a)}if(t){let s=t(n);for(let a in s){let l=s[a];Ne(l)||(i[a]=l)}}if(Ne(i.id))throw new Error("Node is missing id field");r.set(i.id,i)}return r}function tf(e,t,r){let n=new Map;for(let i of e){let s={_original:i};for(let a of Zl){let l=i[a];Ne(l)||(s[a]=l)}if(t){let a=t(i);for(let l in a){let g=a[l];Ne(g)||(s[l]=g)}}if(Ne(s.source)||Ne(s.target))throw new Error("Edge is missing source or target field");Ne(s.id)&&(s.id=r?.(i)),n.set(s.id,s)}return n}var Fn=class{constructor(t,r={}){this.graph=new Wn(t,r)}export(){return this.graph.data()}replace(t){this.graph.replace(t)}forEachNode(t){this.graph.forEachNode(t)}forEachEdge(t){this.graph.forEachEdge((r,n)=>{r.sourceNode=this.graph.node(r.source),r.targetNode=this.graph.node(r.target),t(r,n)})}destroy(){this.graph.destroy()}};var ca=Symbol("Comlink.proxy"),ef=Symbol("Comlink.endpoint"),rf=Symbol("Comlink.releaseProxy"),Pi=Symbol("Comlink.finalizer"),Un=Symbol("Comlink.thrown"),la=e=>typeof e=="object"&&e!==null||typeof e=="function",nf={canHandle:e=>la(e)&&e[ca],serialize(e){let{port1:t,port2:r}=new MessageChannel;return da(e,t),[r,[r]]},deserialize(e){return e.start(),Wi(e)}},sf={canHandle:e=>la(e)&&Un in e,serialize({value:e}){let t;return e instanceof Error?t={isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:t={isError:!1,value:e},[t,[]]},deserialize(e){throw e.isError?Object.assign(new Error(e.value.message),e.value):e.value}},fa=new Map([["proxy",nf],["throw",sf]]);function of(e,t){for(let r of e)if(t===r||r==="*"||r instanceof RegExp&&r.test(t))return!0;return!1}function da(e,t=globalThis,r=["*"]){t.addEventListener("message",function n(i){if(!i||!i.data)return;if(!of(r,i.origin)){console.warn(`Invalid origin '${i.origin}' for comlink proxy`);return}let{id:s,type:a,path:l}=Object.assign({path:[]},i.data),g=(i.data.argumentList||[]).map(br),f;try{let p=l.slice(0,-1).reduce((w,E)=>w[E],e),y=l.reduce((w,E)=>w[E],e);switch(a){case"GET":f=y;break;case"SET":p[l.slice(-1)[0]]=br(i.data.value),f=!0;break;case"APPLY":f=y.apply(p,g);break;case"CONSTRUCT":{let w=new y(...g);f=ff(w)}break;case"ENDPOINT":{let{port1:w,port2:E}=new MessageChannel;da(e,E),f=lf(w,[w])}break;case"RELEASE":f=void 0;break;default:return}}catch(p){f={value:p,[Un]:0}}Promise.resolve(f).catch(p=>({value:p,[Un]:0})).then(p=>{let[y,w]=Yn(p);t.postMessage(Object.assign(Object.assign({},y),{id:s}),w),a==="RELEASE"&&(t.removeEventListener("message",n),ga(t),Pi in e&&typeof e[Pi]=="function"&&e[Pi]())}).catch(p=>{let[y,w]=Yn({value:new TypeError("Unserializable return value"),[Un]:0});t.postMessage(Object.assign(Object.assign({},y),{id:s}),w)})}),t.start&&t.start()}function af(e){return e.constructor.name==="MessagePort"}function ga(e){af(e)&&e.close()}function Wi(e,t){let r=new Map;return e.addEventListener("message",function(i){let{data:s}=i;if(!s||!s.id)return;let a=r.get(s.id);if(a)try{a(s)}finally{r.delete(s.id)}}),Ni(e,r,[],t)}function qn(e){if(e)throw new Error("Proxy has been released and is not useable")}function pa(e){return Wr(e,new Map,{type:"RELEASE"}).then(()=>{ga(e)})}var Bn=new WeakMap,Vn="FinalizationRegistry"in globalThis&&new FinalizationRegistry(e=>{let t=(Bn.get(e)||0)-1;Bn.set(e,t),t===0&&pa(e)});function uf(e,t){let r=(Bn.get(t)||0)+1;Bn.set(t,r),Vn&&Vn.register(e,t,e)}function hf(e){Vn&&Vn.unregister(e)}function Ni(e,t,r=[],n=function(){}){let i=!1,s=new Proxy(n,{get(a,l){if(qn(i),l===rf)return()=>{hf(s),pa(e),t.clear(),i=!0};if(l==="then"){if(r.length===0)return{then:()=>s};let g=Wr(e,t,{type:"GET",path:r.map(f=>f.toString())}).then(br);return g.then.bind(g)}return Ni(e,t,[...r,l])},set(a,l,g){qn(i);let[f,p]=Yn(g);return Wr(e,t,{type:"SET",path:[...r,l].map(y=>y.toString()),value:f},p).then(br)},apply(a,l,g){qn(i);let f=r[r.length-1];if(f===ef)return Wr(e,t,{type:"ENDPOINT"}).then(br);if(f==="bind")return Ni(e,t,r.slice(0,-1));let[p,y]=ha(g);return Wr(e,t,{type:"APPLY",path:r.map(w=>w.toString()),argumentList:p},y).then(br)},construct(a,l){qn(i);let[g,f]=ha(l);return Wr(e,t,{type:"CONSTRUCT",path:r.map(p=>p.toString()),argumentList:g},f).then(br)}});return uf(s,e),s}function cf(e){return Array.prototype.concat.apply([],e)}function ha(e){let t=e.map(Yn);return[t.map(r=>r[0]),cf(t.map(r=>r[1]))]}var ya=new WeakMap;function lf(e,t){return ya.set(e,t),e}function ff(e){return Object.assign(e,{[ca]:!0})}function Yn(e){for(let[t,r]of fa)if(r.canHandle(e)){let[n,i]=r.serialize(e);return[{type:"HANDLER",name:t,value:n},i]}return[{type:"RAW",value:e},ya.get(e)||[]]}function br(e){switch(e.type){case"HANDLER":return fa.get(e.name).deserialize(e.value);case"RAW":return e.value}}function Wr(e,t,r,n){return new Promise(i=>{let s=df();t.set(s,i),e.start&&e.start(),e.postMessage(Object.assign({id:s},r),n)})}function df(){return new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")}var Kn=class{constructor(){this.worker=null,this.workerApi=null}execute(t,r,n){return Me(this,void 0,void 0,function*(){if(this.worker||(yield this.initWorker()),!this.workerApi)throw new Error("Worker API not initialized");return yield this.workerApi.execute(t,r,n)})}destroy(){this.workerApi&&this.workerApi.destroy(),this.worker&&(this.worker.terminate(),this.worker=null,this.workerApi=null)}initWorker(){return Me(this,void 0,void 0,function*(){let t=this.resolveWorkerPath(),n=t.includes("/lib/")||t.endsWith(".mjs")?"module":"classic";this.worker=new Worker(t,{type:n}),this.workerApi=Wi(this.worker)})}resolveWorkerPath(){let t=(()=>{if(typeof document>"u")return null;let r=document.currentScript;if(r?.src)return r.src;let n=document.getElementsByTagName("script");for(let i=n.length-1;i>=0;i--){let s=n[i].src;if(s&&(s.includes("index.js")||s.includes("index.min.js")))return s}return null})();if(t){if(t.includes("index.js")||t.includes("index.min.js")){let i=t.replace(/index(\.min)?\.(m?js)(\?.*)?$/,"worker.js");if(i!==t)return i}let r=t.replace(/\/runtime\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(r!==t)return r;let n=t.replace(/\/[^/]+\.(m?js)(\?.*)?$/,"/worker.js");if(n!==t)return n}return"./worker.js"}};var cr=class{constructor(t){this.supervisor=null,this.initialOptions=this.mergeOptions(this.getDefaultOptions(),t)}get options(){return this.runtimeOptions||this.initialOptions}mergeOptions(t,r){return Object.assign({},t,r||{})}execute(t,r){return Me(this,void 0,void 0,function*(){this.runtimeOptions=this.mergeOptions(this.initialOptions,r);let{node:n,edge:i,enableWorker:s}=this.runtimeOptions;this.context=new Fn(t,{node:n,edge:i}),this.model=this.context.graph,s&&typeof Worker<"u"?yield this.layoutInWorker(t,this.runtimeOptions):yield this.layout(this.runtimeOptions)})}layoutInWorker(t,r){var n;return Me(this,void 0,void 0,function*(){try{this.supervisor||(this.supervisor=new Kn);let i=yield this.supervisor.execute(this.id,t,r);(n=this.context)===null||n===void 0||n.replace(i)}catch(i){console.error("Layout in worker failed, fallback to main thread layout.",i),yield this.layout(r)}})}forEachNode(t){this.context.forEachNode(t)}forEachEdge(t){this.context.forEachEdge(t)}destroy(){var t;(t=this.context)===null||t===void 0||t.destroy(),this.model=null,this.context=null,this.supervisor&&(this.supervisor.destroy(),this.supervisor=null)}};function Fr(e,t,r=2){if(e.nodeCount()===1){let i=e.firstNode();i.x=t[0],i.y=t[1],r===3&&(i.z=t[2]||0)}}function wa(e,t){let r=e.nodes();return r.sort(t),e.setNodeOrder(r),e}function ma(e,t="desc"){return wa(e,(r,n)=>{let i=e.degree(r.id),s=e.degree(n.id);return t==="asc"?i-s:s-i})}function va(e,t){return wa(e,(r,n)=>{let i=e.originalNode(r.id),s=e.originalNode(n.id);return t(i,s)})}var qr=e=>{let{width:t,height:r,center:n}=e,i=t??(typeof window<"u"?window.innerWidth:0),s=r??(typeof window<"u"?window.innerHeight:0),a=n??[i/2,s/2];return{width:i,height:s,center:a}};var Xn={nodeSize:30,nodeSpacing:10,preventOverlap:!1,sweep:void 0,equidistant:!1,startAngle:3/2*Math.PI,clockwise:!0,maxLevelDiff:void 0,sortBy:"degree"},Qn=class extends cr{constructor(){super(...arguments),this.id="concentric"}getDefaultOptions(){return Xn}layout(){return Me(this,void 0,void 0,function*(){let{width:t,height:r,center:n}=qr(this.options),i=this.model.nodeCount();if(!i||i===1){Fr(this.model,n);return}let{sortBy:s,maxLevelDiff:a,sweep:l,clockwise:g,equidistant:f,preventOverlap:p,startAngle:y=Xn.startAngle,nodeSize:w,nodeSpacing:E}=this.options,A=!s||s==="degree"?"degree":un(s,["node"]);if(A==="degree")ma(this.model);else{let G=(P,C)=>{let H=A(P),ut=A(C);return H===ut?0:H>ut?-1:1};va(this.model,G)}let I=this.model.nodes(),_=new Map;for(let G of I){let P=A==="degree"?this.model.degree(G.id):A(G._original);_.set(G.id,P)}let $=this.model.firstNode(),j=a||_.get($.id)/4,R=Nn(w,E,Xn.nodeSize,Xn.nodeSpacing),W=new Map;for(let G of I)W.set(G.id,Math.max(...R(G._original)));let z=[{nodes:[]}],V=z[0];for(let G=0;G0){let C=V.nodes[0],H=Math.abs(_.get(C.id)-_.get(P.id));j&&H>=j&&(V={nodes:[]},z.push(V))}V.nodes.push(P)}for(let G of z){let P=G.nodes.map(C=>W.get(C.id));G.nodeSizes=P,G.maxNodeSize=Math.max(...P)}if(z.forEach(G=>{let P=l===void 0?2*Math.PI-2*Math.PI/G.nodes.length:l;G.dTheta=P/Math.max(1,G.nodes.length-1)}),p){let G=0;for(let P=0;P1){let H=C.nodeSizes||[],ut=0;for(let Kt=0;Kt0?ut/ft:0;G=Math.max(Ot,G)}if(C.r=G,P{H===0&&(P=C.r||0),C.r=P,P+=G})}z.forEach(G=>{let P=G.dTheta||0,C=G.r||0;G.nodes.forEach((H,ut)=>{let at=y+(g?1:-1)*P*ut;H.x=n[0]+C*Math.cos(at),H.y=n[1]+C*Math.sin(at)})})})}};function ba(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Jn(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if(typeof t=="function"){var r=function n(){var i=!1;try{i=this instanceof n}catch{}return i?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}),r}var mt={};var Fi={};bi(Fi,{isAnyArray:()=>lr});var gf=Object.prototype.toString;function lr(e){let t=gf.call(e);return t.endsWith("Array]")&&!t.includes("Big")}var Ea=Jn(Fi);var qi={};bi(qi,{default:()=>pf});function xa(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!lr(e))throw new TypeError("input must be an array");if(e.length===0)throw new TypeError("input must not be empty");var r=t.fromIndex,n=r===void 0?0:r,i=t.toIndex,s=i===void 0?e.length:i;if(n<0||n>=e.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(s<=n||s>e.length||!Number.isInteger(s))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=e[n],l=n+1;la&&(a=e[l]);return a}function Sa(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!lr(e))throw new TypeError("input must be an array");if(e.length===0)throw new TypeError("input must not be empty");var r=t.fromIndex,n=r===void 0?0:r,i=t.toIndex,s=i===void 0?e.length:i;if(n<0||n>=e.length||!Number.isInteger(n))throw new Error("fromIndex must be a positive integer smaller than length");if(s<=n||s>e.length||!Number.isInteger(s))throw new Error("toIndex must be an integer greater than fromIndex and at most equal to length");for(var a=e[n],l=n+1;l1&&arguments[1]!==void 0?arguments[1]:{};if(lr(e)){if(e.length===0)throw new TypeError("input must not be empty")}else throw new TypeError("input must be an array");var r;if(t.output!==void 0){if(!lr(t.output))throw new TypeError("output option must be an array if specified");r=t.output}else r=new Array(e.length);var n=Sa(e),i=xa(e);if(n===i)throw new RangeError("minimum and maximum input values are equal. Cannot rescale a constant array");var s=t.min,a=s===void 0?t.autoMinMax?n:0:s,l=t.max,g=l===void 0?t.autoMinMax?i:1:l;if(a>=g)throw new RangeError("min option must be smaller than max option");for(var f=(g-a)/(i-n),p=0;p=0&&u?` ${g(m,c-1)}`:g(m,c)).padEnd(c)}function g(m,c){let u=m.toString();if(u.length<=c)return u;let s=m.toFixed(c);if(s.length>c&&(s=m.toFixed(Math.max(0,c-(s.length-c)))),s.length<=c&&!s.startsWith("0.000")&&!s.startsWith("-0.000"))return s;let h=m.toExponential(c);return h.length>c&&(h=m.toExponential(Math.max(0,c-(h.length-c)))),h.slice(0)}function f(m,c){m.prototype.add=function(s){return typeof s=="number"?this.addS(s):this.addM(s)},m.prototype.addS=function(s){for(let h=0;h>s);return this},m.prototype.signPropagatingRightShiftM=function(s){if(s=c.checkMatrix(s),this.rows!==s.rows||this.columns!==s.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>s.get(h,d));return this},m.signPropagatingRightShift=function(s,h){return new c(s).signPropagatingRightShift(h)},m.prototype.rightShift=function(s){return typeof s=="number"?this.rightShiftS(s):this.rightShiftM(s)},m.prototype.rightShiftS=function(s){for(let h=0;h>>s);return this},m.prototype.rightShiftM=function(s){if(s=c.checkMatrix(s),this.rows!==s.rows||this.columns!==s.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>>s.get(h,d));return this},m.rightShift=function(s,h){return new c(s).rightShift(h)},m.prototype.zeroFillRightShift=m.prototype.rightShift,m.prototype.zeroFillRightShiftS=m.prototype.rightShiftS,m.prototype.zeroFillRightShiftM=m.prototype.rightShiftM,m.zeroFillRightShift=m.rightShift,m.prototype.not=function(){for(let s=0;ss)throw new RangeError("Row index out of range")}function y(m,c,u){let s=u?m.columns:m.columns-1;if(c<0||c>s)throw new RangeError("Column index out of range")}function w(m,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==m.columns)throw new RangeError("vector size must be the same as the number of columns");return c}function S(m,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==m.rows)throw new RangeError("vector size must be the same as the number of rows");return c}function A(m,c){if(!e.isAnyArray(c))throw new TypeError("row indices must be an array");for(let u=0;u=m.rows)throw new RangeError("row indices are out of range")}function I(m,c){if(!e.isAnyArray(c))throw new TypeError("column indices must be an array");for(let u=0;u=m.columns)throw new RangeError("column indices are out of range")}function L(m,c,u,s,h){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(j("startRow",c),j("endRow",u),j("startColumn",s),j("endColumn",h),c>u||s>h||c<0||c>=m.rows||u<0||u>=m.rows||s<0||s>=m.columns||h<0||h>=m.columns)throw new RangeError("Submatrix indices are out of range")}function $(m,c=0){let u=[];for(let s=0;s=d)throw new RangeError("min must be smaller than max");let b=d-h,E=new Q(c,u);for(let x=0;xs?(d=!0,s=u):(h=!1,d=!0);c++}return h}isReducedEchelonForm(){let c=0,u=0,s=-1,h=!0,d=!1;for(;cs?(d=!0,s=u):(h=!1,d=!0);for(let v=u+1;vc.get(h,s)&&(h=d);if(c.get(h,s)===0)s++;else{c.swapRows(u,h);let d=c.get(u,s);for(let v=s;v=0;)if(c.maxRow(h)===0)h--;else{let d=0,v=!1;for(;du[s]&&(u[s]=this.get(s,h));return u}case"column":{let u=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let s=0;su[h]&&(u[h]=this.get(s,h));return u}case void 0:{let u=this.get(0,0);for(let s=0;su&&(u=this.get(s,h));return u}default:throw new Error(`invalid option: ${c}`)}}maxIndex(){M(this);let c=this.get(0,0),u=[0,0];for(let s=0;sc&&(c=this.get(s,h),u[0]=s,u[1]=h);return u}min(c){if(this.isEmpty())return NaN;switch(c){case"row":{let u=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let s=0;su&&(u=this.get(c,s));return u}maxRowIndex(c){p(this,c),M(this);let u=this.get(c,0),s=[c,0];for(let h=1;hu&&(u=this.get(c,h),s[1]=h);return s}minRow(c){if(p(this,c),this.isEmpty())return NaN;let u=this.get(c,0);for(let s=1;su&&(u=this.get(s,c));return u}maxColumnIndex(c){y(this,c),M(this);let u=this.get(0,c),s=[0,c];for(let h=1;hu&&(u=this.get(h,c),s[0]=h);return s}minColumn(c){if(y(this,c),this.isEmpty())return NaN;let u=this.get(0,c);for(let s=1;s=1;h/=2)(h&1)!==0&&(u=u.mmul(s)),s=s.mmul(s);return u}strassen2x2(c){c=Q.checkMatrix(c);let u=new Q(2,2),s=this.get(0,0),h=c.get(0,0),d=this.get(0,1),v=c.get(0,1),b=this.get(1,0),E=c.get(1,0),x=this.get(1,1),T=c.get(1,1),D=(s+x)*(h+T),F=(b+x)*h,X=s*(v-T),z=x*(E-h),U=(s+d)*T,H=(b-s)*(h+v),k=(d-x)*(E+T),Y=D+z-U+k,nt=X+U,pt=F+z,yt=D-F+X+H;return u.set(0,0,Y),u.set(0,1,nt),u.set(1,0,pt),u.set(1,1,yt),u}strassen3x3(c){c=Q.checkMatrix(c);let u=new Q(3,3),s=this.get(0,0),h=this.get(0,1),d=this.get(0,2),v=this.get(1,0),b=this.get(1,1),E=this.get(1,2),x=this.get(2,0),T=this.get(2,1),D=this.get(2,2),F=c.get(0,0),X=c.get(0,1),z=c.get(0,2),U=c.get(1,0),H=c.get(1,1),k=c.get(1,2),Y=c.get(2,0),nt=c.get(2,1),pt=c.get(2,2),yt=(s+h+d-v-b-T-D)*H,Gt=(s-v)*(-X+H),st=b*(-F+X+U-H-k-Y+pt),ut=(-s+v+b)*(F-X+H),Lt=(v+b)*(-F+X),R=s*F,B=(-s+x+T)*(F-z+k),tt=(-s+x)*(z-k),V=(x+T)*(-F+z),$t=(s+h+d-b-E-x-T)*k,kt=T*(-F+z+U-H-k-Y+nt),Ot=(-d+T+D)*(H+Y-nt),zt=(d-D)*(H-nt),ae=d*Y,Oe=(T+D)*(-Y+nt),Ht=(-d+b+E)*(k+Y-pt),qe=(d-E)*(k-pt),Qe=(b+E)*(-Y+pt),vt=h*U,ue=E*nt,Ee=v*z,xe=x*X,te=D*pt,ah=R+ae+vt,uh=yt+ut+Lt+R+Ot+ae+Oe,hh=R+B+V+$t+ae+Ht+Qe,ch=Gt+st+ut+R+ae+Ht+qe,lh=Gt+ut+Lt+R+ue,fh=ae+Ht+qe+Qe+Ee,dh=R+B+tt+kt+Ot+zt+ae,gh=Ot+zt+ae+Oe+xe,ph=R+B+tt+V+te;return u.set(0,0,ah),u.set(0,1,uh),u.set(0,2,hh),u.set(1,0,ch),u.set(1,1,lh),u.set(1,2,fh),u.set(2,0,dh),u.set(2,1,gh),u.set(2,2,ph),u}mmulStrassen(c){c=Q.checkMatrix(c);let u=this.clone(),s=u.rows,h=u.columns,d=c.rows,v=c.columns;h!==d&&console.warn(`Multiplying ${s} x ${h} and ${d} x ${v} matrix: dimensions do not match.`);function b(D,F,X){let z=D.rows,U=D.columns;if(z===F&&U===X)return D;{let H=_.zeros(F,X);return H=H.setSubMatrix(D,0,0),H}}let E=Math.max(s,d),x=Math.max(h,v);u=b(u,E,x),c=b(c,E,x);function T(D,F,X,z){if(X<=512||z<=512)return D.mmul(F);X%2===1&&z%2===1?(D=b(D,X+1,z+1),F=b(F,X+1,z+1)):X%2===1?(D=b(D,X+1,z),F=b(F,X+1,z)):z%2===1&&(D=b(D,X,z+1),F=b(F,X,z+1));let U=parseInt(D.rows/2,10),H=parseInt(D.columns/2,10),k=D.subMatrix(0,U-1,0,H-1),Y=F.subMatrix(0,U-1,0,H-1),nt=D.subMatrix(0,U-1,H,D.columns-1),pt=F.subMatrix(0,U-1,H,F.columns-1),yt=D.subMatrix(U,D.rows-1,0,H-1),Gt=F.subMatrix(U,F.rows-1,0,H-1),st=D.subMatrix(U,D.rows-1,H,D.columns-1),ut=F.subMatrix(U,F.rows-1,H,F.columns-1),Lt=T(_.add(k,st),_.add(Y,ut),U,H),R=T(_.add(yt,st),Y,U,H),B=T(k,_.sub(pt,ut),U,H),tt=T(st,_.sub(Gt,Y),U,H),V=T(_.add(k,nt),ut,U,H),$t=T(_.sub(yt,k),_.add(Y,pt),U,H),kt=T(_.sub(nt,st),_.add(Gt,ut),U,H),Ot=_.add(Lt,tt);Ot.sub(V),Ot.add(kt);let zt=_.add(B,V),ae=_.add(R,tt),Oe=_.sub(Lt,R);Oe.add(B),Oe.add($t);let Ht=_.zeros(2*Ot.rows,2*Ot.columns);return Ht=Ht.setSubMatrix(Ot,0,0),Ht=Ht.setSubMatrix(zt,Ot.rows,0),Ht=Ht.setSubMatrix(ae,0,Ot.columns),Ht=Ht.setSubMatrix(Oe,Ot.rows,Ot.columns),Ht.subMatrix(0,X-1,0,z-1)}return T(u,c,E,x)}scaleRows(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:u=0,max:s=1}=c;if(!Number.isFinite(u))throw new TypeError("min must be a number");if(!Number.isFinite(s))throw new TypeError("max must be a number");if(u>=s)throw new RangeError("min must be smaller than max");let h=new Q(this.rows,this.columns);for(let d=0;d0&&t(v,{min:u,max:s,output:v}),h.setRow(d,v)}return h}scaleColumns(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:u=0,max:s=1}=c;if(!Number.isFinite(u))throw new TypeError("min must be a number");if(!Number.isFinite(s))throw new TypeError("max must be a number");if(u>=s)throw new RangeError("min must be smaller than max");let h=new Q(this.rows,this.columns);for(let d=0;ds||u<0||u>=this.columns||s<0||s>=this.columns)throw new RangeError("Argument out of range");let h=new Q(c.length,s-u+1);for(let d=0;d=this.rows)throw new RangeError(`Row index out of range: ${c[d]}`);h.set(d,v-u,this.get(c[d],v))}return h}subMatrixColumn(c,u,s){if(u===void 0&&(u=0),s===void 0&&(s=this.rows-1),u>s||u<0||u>=this.rows||s<0||s>=this.rows)throw new RangeError("Argument out of range");let h=new Q(s-u+1,c.length);for(let d=0;d=this.columns)throw new RangeError(`Column index out of range: ${c[d]}`);h.set(v-u,d,this.get(v,c[d]))}return h}setSubMatrix(c,u,s){if(c=Q.checkMatrix(c),c.isEmpty())return this;let h=u+c.rows-1,d=s+c.columns-1;L(this,u,h,s,d);for(let v=0;vtypeof c=="number")}_.random=_.rand,_.randomInt=_.randInt,_.diagonal=_.diag,_.prototype.diagonal=_.prototype.diag,_.identity=_.eye,_.prototype.negate=_.prototype.neg,_.prototype.tensorProduct=_.prototype.kroneckerProduct;let pn=class pn extends _{constructor(u,s){super();pi(this,Vr);ys(this,"data");if(pn.isMatrix(u))yi(this,Vr,$i).call(this,u.rows,u.columns),pn.copy(u,this);else if(Number.isInteger(u)&&u>=0)yi(this,Vr,$i).call(this,u,s);else if(e.isAnyArray(u)){let h=u;if(u=h.length,s=u?h[0].length:0,typeof s!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let d=0;d"u"&&(s=u,u=this.columns),y(this,u,!0),s=S(this,s);for(let h=0;h=0)for(let h=0;h=0)mn(this,ce,new Q(u,u));else if(mn(this,ce,new Q(u)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return Ge(this,ce).size}get rows(){return Ge(this,ce).rows}get columns(){return Ge(this,ce).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(u){return Q.isMatrix(u)&&u.klassType==="SymmetricMatrix"}static zeros(u){return new this(u)}static ones(u){return new this(u).fill(1)}clone(){let u=new yn(this.diagonalSize);for(let[s,h,d]of this.upperRightEntries())u.set(s,h,d);return u}toMatrix(){return new Q(this)}get(u,s){return Ge(this,ce).get(u,s)}set(u,s,h){return Ge(this,ce).set(u,s,h),Ge(this,ce).set(s,u,h),this}removeCross(u){return Ge(this,ce).removeRow(u),Ge(this,ce).removeColumn(u),this}addCross(u,s){s===void 0&&(s=u,u=this.diagonalSize);let h=s.slice();return h.splice(u,1),Ge(this,ce).addRow(u,h),Ge(this,ce).addColumn(u,s),this}applyMask(u){if(u.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let s=[];for(let[h,d]of u.entries())d||s.push(h);s.reverse();for(let h of s)this.removeCross(h);return this}toCompact(){let{diagonalSize:u}=this,s=new Array(u*(u+1)/2);for(let h=0,d=0,v=0;v=u&&(h=++d);return s}static fromCompact(u){let s=u.length,h=(Math.sqrt(8*s+1)-1)/2;if(!Number.isInteger(h))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(u)}`);let d=new yn(h);for(let v=0,b=0,E=0;E=h&&(v=++b);return d}*upperRightEntries(){for(let u=0,s=0;u=this.diagonalSize&&(s=++u)}}*upperRightValues(){for(let u=0,s=0;u=this.diagonalSize&&(s=++u)}};ce=new WeakMap;let we=yn;we.prototype.klassType="SymmetricMatrix";class Xt extends we{static isDistanceMatrix(c){return we.isSymmetricMatrix(c)&&c.klassSubType==="DistanceMatrix"}constructor(c){if(super(c),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(c,u,s){return c===u&&(s=0),super.set(c,u,s)}addCross(c,u){return u===void 0&&(u=c,c=this.diagonalSize),u=u.slice(),u[c]=0,super.addCross(c,u)}toSymmetricMatrix(){return new we(this)}clone(){let c=new Xt(this.diagonalSize);for(let[u,s,h]of this.upperRightEntries())u!==s&&c.set(u,s,h);return c}toCompact(){let{diagonalSize:c}=this,u=(c-1)*c/2,s=new Array(u);for(let h=1,d=0,v=0;v=c&&(h=++d+1);return s}static fromCompact(c){let u=c.length;if(u===0)return new this(0);let s=(Math.sqrt(8*u+1)+1)/2;if(!Number.isInteger(s))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(c)}`);let h=new this(s);for(let d=1,v=0,b=0;b=s&&(d=++v+1);return h}}Xt.prototype.klassSubType="DistanceMatrix";class ot extends _{constructor(c,u,s){super(),this.matrix=c,this.rows=u,this.columns=s}}class Ur extends ot{constructor(c,u){y(c,u),super(c,c.rows,1),this.column=u}set(c,u,s){return this.matrix.set(c,this.column,s),this}get(c){return this.matrix.get(c,this.column)}}class Ie extends ot{constructor(c,u){I(c,u),super(c,c.rows,u.length),this.columnIndices=u}set(c,u,s){return this.matrix.set(c,this.columnIndices[u],s),this}get(c,u){return this.matrix.get(c,this.columnIndices[u])}}class li extends ot{constructor(c){super(c,c.rows,c.columns)}set(c,u,s){return this.matrix.set(c,this.columns-u-1,s),this}get(c,u){return this.matrix.get(c,this.columns-u-1)}}class pr extends ot{constructor(c){super(c,c.rows,c.columns)}set(c,u,s){return this.matrix.set(this.rows-c-1,u,s),this}get(c,u){return this.matrix.get(this.rows-c-1,u)}}class fi extends ot{constructor(c,u){p(c,u),super(c,1,c.columns),this.row=u}set(c,u,s){return this.matrix.set(this.row,u,s),this}get(c,u){return this.matrix.get(this.row,u)}}class xr extends ot{constructor(c,u){A(c,u),super(c,u.length,c.columns),this.rowIndices=u}set(c,u,s){return this.matrix.set(this.rowIndices[c],u,s),this}get(c,u){return this.matrix.get(this.rowIndices[c],u)}}class _t extends ot{constructor(c,u,s){A(c,u),I(c,s),super(c,u.length,s.length),this.rowIndices=u,this.columnIndices=s}set(c,u,s){return this.matrix.set(this.rowIndices[c],this.columnIndices[u],s),this}get(c,u){return this.matrix.get(this.rowIndices[c],this.columnIndices[u])}}class Et extends ot{constructor(c,u,s,h,d){L(c,u,s,h,d),super(c,s-u+1,d-h+1),this.startRow=u,this.startColumn=h}set(c,u,s){return this.matrix.set(this.startRow+c,this.startColumn+u,s),this}get(c,u){return this.matrix.get(this.startRow+c,this.startColumn+u)}}class xt extends ot{constructor(c){super(c,c.columns,c.rows)}set(c,u,s){return this.matrix.set(u,c,s),this}get(c,u){return this.matrix.get(u,c)}}class ke extends _{constructor(c,u={}){let{rows:s=1}=u;if(c.length%s!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=s,this.columns=c.length/s,this.data=c}set(c,u,s){let h=this._calculateIndex(c,u);return this.data[h]=s,this}get(c,u){let s=this._calculateIndex(c,u);return this.data[s]}_calculateIndex(c,u){return c*this.columns+u}}class it extends _{constructor(c){super(),this.data=c,this.rows=c.length,this.columns=c[0].length}set(c,u,s){return this.data[c][u]=s,this}get(c,u){return this.data[c][u]}}function at(m,c){if(e.isAnyArray(m))return m[0]&&e.isAnyArray(m[0])?new it(m):new ke(m,c);throw new Error("the argument is not an array")}class q{constructor(c){c=it.checkMatrix(c);let u=c.clone(),s=u.rows,h=u.columns,d=new Float64Array(s),v=1,b,E,x,T,D,F,X,z,U;for(b=0;bMath.abs(z[T])&&(T=b);if(T!==E){for(x=0;x=0;x--){for(E=0;Ev?h.set(d,v,c.get(d,v)):d===v?h.set(d,v,1):h.set(d,v,0);return h}get upperTriangularMatrix(){let c=this.LU,u=c.rows,s=c.columns,h=new Q(u,s);for(let d=0;dMath.abs(c)?(u=c/m,Math.abs(m)*Math.sqrt(1+u*u)):c!==0?(u=m/c,Math.abs(c)*Math.sqrt(1+u*u)):0}class We{constructor(c){c=it.checkMatrix(c);let u=c.clone(),s=c.rows,h=c.columns,d=new Float64Array(h),v,b,E,x;for(E=0;E=0;x--){for(E=0;E=0;b--){for(d=0;d=0;R--)if(z[R]!==0){for(let B=R+1;B=0;R--){if(R0;){let R,B;for(R=st-2;R>=-1&&R!==-1;R--){let tt=Number.MIN_VALUE+Lt*Math.abs(z[R]+Math.abs(z[R+1]));if(Math.abs(k[R])<=tt||Number.isNaN(k[R])){k[R]=0;break}}if(R===st-2)B=4;else{let tt;for(tt=st-1;tt>=R&&tt!==R;tt--){let V=(tt!==st?Math.abs(k[tt]):0)+(tt!==R+1?Math.abs(k[tt-1]):0);if(Math.abs(z[tt])<=Lt*V){z[tt]=0;break}}tt===R?B=3:tt===st-1?B=1:(B=2,R=tt)}switch(R++,B){case 1:{let tt=k[st-2];k[st-2]=0;for(let V=st-2;V>=R;V--){let $t=oe(z[V],tt),kt=z[V]/$t,Ot=tt/$t;if(z[V]=$t,V!==R&&(tt=-Ot*k[V-1],k[V-1]=kt*k[V-1]),x)for(let zt=0;zt=z[R+1]);){let tt=z[R];if(z[R]=z[R+1],z[R+1]=tt,x&&Ru&&d.set(T,D,c.get(T,D)/this.s[D]);let v=this.U,b=v.rows,E=v.columns,x=new Q(s,b);for(let T=0;Tc&&u++;return u}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return Q.diag(this.s)}}function nr(m,c=!1){return m=it.checkMatrix(m),c?new me(m).inverse():de(m,Q.eye(m.rows))}function de(m,c,u=!1){return m=it.checkMatrix(m),c=it.checkMatrix(c),u?new me(m).solve(c):m.isSquare()?new q(m).solve(c):new We(m).solve(c)}function Me(m){if(m=Q.checkMatrix(m),m.isSquare()){if(m.columns===0)return 1;let c,u,s,h;if(m.columns===2)return c=m.get(0,0),u=m.get(0,1),s=m.get(1,0),h=m.get(1,1),c*h-u*s;if(m.columns===3){let d,v,b;return d=new _t(m,[1,2],[1,2]),v=new _t(m,[1,2],[0,2]),b=new _t(m,[1,2],[0,1]),c=m.get(0,0),u=m.get(0,1),s=m.get(0,2),c*Me(d)-u*Me(v)+s*Me(b)}else return new q(m).determinant}else throw Error("determinant can only be calculated for a square matrix")}function Br(m,c){let u=[];for(let s=0;sh)return new Array(c.rows+1).fill(0);{let d=c.addRow(u,[0]);for(let v=0;vc?d[v]=1/d[v]:d[v]=0;return h.mmul(Q.diag(d).mmul(s.transpose()))}function yr(m,c=m,u={}){m=new Q(m);let s=!1;if(typeof c=="object"&&!Q.isMatrix(c)&&!e.isAnyArray(c)?(u=c,c=m,s=!0):c=new Q(c),m.rows!==c.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:h=!0}=u;h&&(m=m.center("column"),s||(c=c.center("column")));let d=m.transpose().mmul(c);for(let v=0;v0?h.set(d,d+1,u[d]):u[d]<0&&h.set(d,d-1,u[d])}return h}}function kr(m,c,u,s){let h,d,v,b,E,x,T,D;for(E=0;E0;b--){for(D=0,v=0,x=0;x0&&(d=-d),c[b]=D*d,v=v-h*d,u[b-1]=h-d,E=0;Ex)do{for(h=u[x],D=(u[x+1]-h)/(2*c[x]),F=oe(D,1),D<0&&(F=-F),u[x]=c[x]/(D+F),u[x+1]=c[x]*(D+F),X=u[x+1],d=h-u[x],v=x+2;v=x;v--)for(H=U,U=z,nt=Y,h=z*c[v],d=z*D,F=oe(D,c[v]),c[v+1]=Y*F,Y=c[v]/F,z=D/F,D=z*u[v]-Y*h,u[v+1]=d+Y*(z*h+Y*u[v]),E=0;EGt*yt);u[x]=u[x]+pt,c[x]=0}for(v=0;v=D;x--)u[x]=c.get(x,D-1)/F,E+=u[x]*u[x];for(b=Math.sqrt(E),u[D]>0&&(b=-b),E=E-u[D]*b,u[D]=u[D]-b,T=D;T=D;x--)v+=u[x]*c.get(x,T);for(v=v/E,x=D;x<=d;x++)c.set(x,T,c.get(x,T)-v*u[x])}for(x=0;x<=d;x++){for(v=0,T=d;T>=D;T--)v+=u[T]*c.get(x,T);for(v=v/E,T=D;T<=d;T++)c.set(x,T,c.get(x,T)-v*u[T])}u[D]=F*u[D],c.set(D,D-1,F*b)}}for(x=0;x=h+1;D--)if(c.get(D,D-1)!==0){for(x=D+1;x<=d;x++)u[x]=c.get(x,D-1);for(T=D;T<=d;T++){for(b=0,x=D;x<=d;x++)b+=u[x]*s.get(x,T);for(b=b/u[D]/c.get(D,D-1),x=D;x<=d;x++)s.set(x,T,s.get(x,T)+b*u[x])}}}function oh(m,c,u,s,h){let d=m-1,v=0,b=m-1,E=Number.EPSILON,x=0,T=0,D=0,F=0,X=0,z=0,U=0,H=0,k,Y,nt,pt,yt,Gt,st,ut,Lt,R,B,tt,V,$t,kt;for(k=0;kb)&&(u[k]=h.get(k,k),c[k]=0),Y=Math.max(k-1,0);Y=v;){for(pt=d;pt>v&&(z=Math.abs(h.get(pt-1,pt-1))+Math.abs(h.get(pt,pt)),z===0&&(z=T),!(Math.abs(h.get(pt,pt-1))=0){for(U=D>=0?D+U:D-U,u[d-1]=ut+U,u[d]=u[d-1],U!==0&&(u[d]=ut-st/U),c[d-1]=0,c[d]=0,ut=h.get(d,d-1),z=Math.abs(ut)+Math.abs(U),D=ut/z,F=U/z,X=Math.sqrt(D*D+F*F),D=D/X,F=F/X,Y=d-1;Y0)){for(z=Math.sqrt(z),Lt=pt&&(U=h.get(yt,yt),X=ut-U,z=Lt-U,D=(X*z-st)/h.get(yt+1,yt)+h.get(yt,yt+1),F=h.get(yt+1,yt+1)-U-X-z,X=h.get(yt+2,yt+1),z=Math.abs(D)+Math.abs(F)+Math.abs(X),D=D/z,F=F/z,X=X/z,!(yt===pt||Math.abs(h.get(yt,yt-1))*(Math.abs(F)+Math.abs(X))yt+2&&h.set(k,k-3,0);for(nt=yt;nt<=d-1&&($t=nt!==d-1,nt!==yt&&(D=h.get(nt,nt-1),F=h.get(nt+1,nt-1),X=$t?h.get(nt+2,nt-1):0,ut=Math.abs(D)+Math.abs(F)+Math.abs(X),ut!==0&&(D=D/ut,F=F/ut,X=X/ut)),ut!==0);nt++)if(z=Math.sqrt(D*D+F*F+X*X),D<0&&(z=-z),z!==0){for(nt!==yt?h.set(nt,nt-1,-z*ut):pt!==yt&&h.set(nt,nt-1,-h.get(nt,nt-1)),D=D+z,ut=D/z,Lt=F/z,U=X/z,F=F/D,X=X/D,Y=nt;Y=0;d--)if(D=u[d],F=c[d],F===0)for(pt=d,h.set(d,d,1),k=d-1;k>=0;k--){for(st=h.get(k,k)-D,X=0,Y=pt;Y<=d;Y++)X=X+h.get(k,Y)*h.get(Y,d);if(c[k]<0)U=st,z=X;else if(pt=k,c[k]===0?h.set(k,d,st!==0?-X/st:-X/(E*T)):(ut=h.get(k,k+1),Lt=h.get(k+1,k),F=(u[k]-D)*(u[k]-D)+c[k]*c[k],Gt=(ut*z-U*X)/F,h.set(k,d,Gt),h.set(k+1,d,Math.abs(ut)>Math.abs(U)?(-X-st*Gt)/ut:(-z-Lt*Gt)/U)),Gt=Math.abs(h.get(k,d)),E*Gt*Gt>1)for(Y=k;Y<=d;Y++)h.set(Y,d,h.get(Y,d)/Gt)}else if(F<0)for(pt=d-1,Math.abs(h.get(d,d-1))>Math.abs(h.get(d-1,d))?(h.set(d-1,d-1,F/h.get(d,d-1)),h.set(d-1,d,-(h.get(d,d)-D)/h.get(d,d-1))):(kt=gn(0,-h.get(d-1,d),h.get(d-1,d-1)-D,F),h.set(d-1,d-1,kt[0]),h.set(d-1,d,kt[1])),h.set(d,d-1,0),h.set(d,d,1),k=d-2;k>=0;k--){for(R=0,B=0,Y=pt;Y<=d;Y++)R=R+h.get(k,Y)*h.get(Y,d-1),B=B+h.get(k,Y)*h.get(Y,d);if(st=h.get(k,k)-D,c[k]<0)U=st,X=R,z=B;else if(pt=k,c[k]===0?(kt=gn(-R,-B,st,F),h.set(k,d-1,kt[0]),h.set(k,d,kt[1])):(ut=h.get(k,k+1),Lt=h.get(k+1,k),tt=(u[k]-D)*(u[k]-D)+c[k]*c[k]-F*F,V=(u[k]-D)*2*F,tt===0&&V===0&&(tt=E*T*(Math.abs(st)+Math.abs(F)+Math.abs(ut)+Math.abs(Lt)+Math.abs(U))),kt=gn(ut*X-U*R+F*B,ut*z-U*B-F*R,tt,V),h.set(k,d-1,kt[0]),h.set(k,d,kt[1]),Math.abs(ut)>Math.abs(U)+Math.abs(F)?(h.set(k+1,d-1,(-R-st*h.get(k,d-1)+F*h.get(k,d))/ut),h.set(k+1,d,(-B-st*h.get(k,d)-F*h.get(k,d-1))/ut)):(kt=gn(-X-Lt*h.get(k,d-1),-z-Lt*h.get(k,d),U,F),h.set(k+1,d-1,kt[0]),h.set(k+1,d,kt[1]))),Gt=Math.max(Math.abs(h.get(k,d-1)),Math.abs(h.get(k,d))),E*Gt*Gt>1)for(Y=k;Y<=d;Y++)h.set(Y,d-1,h.get(Y,d-1)/Gt),h.set(Y,d,h.get(Y,d)/Gt)}for(k=0;kb)for(Y=k;Y=v;Y--)for(k=v;k<=b;k++){for(U=0,nt=v;nt<=Math.min(Y,b);nt++)U=U+s.get(k,nt)*h.get(nt,Y);s.set(k,Y,U)}}}function gn(m,c,u,s){let h,d;return Math.abs(u)>Math.abs(s)?(h=s/u,d=u+h*s,[(m+h*c)/d,(c-h*m)/d]):(h=u/s,d=s+h*u,[(h*m+c)/d,(h*c-m)/d])}class ds{constructor(c){if(c=it.checkMatrix(c),!c.isSymmetric())throw new Error("Matrix is not symmetric");let u=c,s=u.rows,h=new Q(s,s),d=!0,v,b,E;for(b=0;b0),h.set(b,b,Math.sqrt(Math.max(x,0))),E=b+1;E=0;E--)for(b=0;bv;X++)D=c.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0)),D=D.div(D.norm()),x=c.mmul(D).div(D.transpose().mmul(D).get(0,0)),X>0&&(E=x.clone().sub(F).pow(2).sum()),F=x.clone(),s?(T=s.transpose().mmul(x).div(x.transpose().mmul(x).get(0,0)),T=T.div(T.norm()),b=s.mmul(T).div(T.transpose().mmul(T).get(0,0))):b=x;if(s){let X=c.transpose().mmul(x).div(x.transpose().mmul(x).get(0,0));X=X.div(X.norm());let z=c.clone().sub(x.clone().mmul(X.transpose())),U=b.transpose().mmul(x).div(x.transpose().mmul(x).get(0,0)),H=s.clone().sub(x.clone().mulS(U.get(0,0)).mmul(T.transpose()));this.t=x,this.p=X.transpose(),this.w=D.transpose(),this.q=T,this.u=b,this.s=x.transpose().mmul(x),this.xResidual=z,this.yResidual=H,this.betas=U}else this.w=D.transpose(),this.s=x.transpose().mmul(x).sqrt(),h?this.t=x.clone().div(this.s.get(0,0)):this.t=x,this.xResidual=c.sub(x.mmul(D.transpose()))}}return mt.AbstractMatrix=_,mt.CHO=ds,mt.CholeskyDecomposition=ds,mt.DistanceMatrix=Xt,mt.EVD=Fe,mt.EigenvalueDecomposition=Fe,mt.LU=q,mt.LuDecomposition=q,mt.Matrix=Q,mt.MatrixColumnSelectionView=Ie,mt.MatrixColumnView=Ur,mt.MatrixFlipColumnView=li,mt.MatrixFlipRowView=pr,mt.MatrixRowSelectionView=xr,mt.MatrixRowView=fi,mt.MatrixSelectionView=_t,mt.MatrixSubView=Et,mt.MatrixTransposeView=xt,mt.NIPALS=gs,mt.Nipals=gs,mt.QR=We,mt.QrDecomposition=We,mt.SVD=me,mt.SingularValueDecomposition=me,mt.SymmetricMatrix=we,mt.WrapperMatrix1D=ke,mt.WrapperMatrix2D=it,mt.correlation=Ir,mt.covariance=yr,mt.default=Q,mt.determinant=Me,mt.inverse=nr,mt.linearDependencies=Ar,mt.pseudoInverse=Dr,mt.solve=de,mt.wrap=at,mt}var rn=ha(),zi=na(rn);var Ni=rn.Matrix,ca=rn.SingularValueDecomposition;zi.Matrix?zi.Matrix:rn.Matrix;var qn=(e,t)=>{let r=e.nodeCount(),n=Array.from({length:r},()=>[]),i={},o=0;return e.forEachNode(a=>{i[a.id]=o++}),e.forEachEdge(a=>{let l=i[a.source],g=i[a.target];l==null||g==null||(n[l].push(g),t||n[g].push(l))}),n},la=(e,t)=>{let r=e.length,n=new Array(r);for(let i=0;inew Array(t).fill(1/0));for(let n=0;n0&&(this.data[0]=r,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let r=this.data;for(;t>0;){let n=t-1>>1;if(r[n][0]<=r[t][0])break;[r[n],r[t]]=[r[t],r[n]],t=n}}bubbleDown(t){let r=this.data,n=r.length;for(;;){let i=t*2+1,o=t*2+2,a=t;if(i{let p=l[g++];f.x=p[0]+r[0],f.y=p[1]+r[1]})})}},Yl=e=>{let t=Number.NEGATIVE_INFINITY,r=[],n=e.length;for(let i=0;i{try{let n=e.length,i=new Ni(n,n);for(let S=0;S{let r=Object.assign(Object.assign({},fa),t),{maxIteration:n,width:i,k:o,speed:a=fa.speed,strictRadial:l,focusNode:g,radiiMap:f,nodeSizeFunc:p}=r,y=o*.002,w=new Map,S=i/10;for(let A=0;A{w.set(L.id,{x:0,y:0})}),Xl(e,w,o,f,p),!(Ql(e,w,a,l,g,S,f){let o=0;e.forEachNode(a=>{let l=0;e.forEachNode(g=>{if(l<=o){l++;return}if(a.id===g.id||n.get(a.id)!==n.get(g.id))return;let f=a.x-g.x,p=a.y-g.y,y=Math.sqrt(f*f+p*p);if(y===0){y=1;let A=o>l?1:-1;f=.01*A,p=.01*A}let w=Math.max(...i(a._original)),S=Math.max(...i(g._original));if(y{n&&e.forEachNode(f=>{let p=f.x-i.x,y=f.y-i.y,w=Math.sqrt(p*p+y*y),S=y/w,A=-p/w,I=t.get(f.id),L=Math.sqrt(I.x*I.x+I.y*I.y),$=Math.acos((S*I.x+A*I.y)/L);$>Math.PI/2&&($-=Math.PI/2,S*=-1,A*=-1);let j=Math.cos($)*L;t.set(f.id,{x:S*j,y:A*j})});let l=0,g=0;return e.forEachNode(f=>{if(f.id===i.id)return;let p=t.get(f.id),y=Math.sqrt(p.x*p.x+p.y*p.y);if(y>0){let w=Math.min(o*(r/800),y);if(f.x+=p.x/y*w,f.y+=p.y/y*w,n){let S=f.x-i.x,A=f.y-i.y,I=Math.sqrt(S*S+A*A);S=S/I*a.get(f.id),A=A/I*a.get(f.id),f.x=i.x+S,f.y=i.y+A}l+=w,g++}}),g>0?l/g:0};var vr={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},Vn=class extends ar{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return vr}layout(){return Le(this,void 0,void 0,function*(){let{width:t,height:r,center:n}=Nr(this.options),i=this.model.nodeCount();if(!i||i===1)return zr(this.model,n);let{focusNode:o,linkDistance:a=vr.linkDistance,maxIteration:l=vr.maxIteration,maxPreventOverlapIteration:g=vr.maxPreventOverlapIteration,nodeSize:f,nodeSpacing:p,preventOverlap:y,sortBy:w,sortStrength:S=vr.sortStrength,strictRadial:A,unitRadius:I}=this.options,L=o&&this.model.node(o)||this.model.firstNode(),$=this.model.nodeIndexOf(L.id),j=qn(this.model,!1),M=Un(j),W=tf(M,$);Hl(M,$,W+1);let N=M[$],K=(t-n[0]>n[0]?n[0]:t-n[0])||t/2,G=(r-n[1]>n[1]?n[1]:r-n[1])||r/2,P=Math.min(K,G),C=Math.max(...N),et=[],lt=new Map,ct=I??P/C;N.forEach((gt,O)=>{let ye=gt*ct;et.push(ye),lt.set(this.model.nodeAt(O).id,ye)});let Dt=Jl(this.model,M,a,et,ct,w,S),ft=Fi(Dt,2,a),Nt=ft[$],ne=0;if(this.model.forEachNode(gt=>{let O=ft[ne];gt.x=O[0]-Nt[0],gt.y=O[1]-Nt[1],ne++}),this.run(l,Dt,et,$),this.model.forEachNode(gt=>{gt.x+=n[0],gt.y+=n[1]}),y){let O={nodeSizeFunc:Rn(f,p,vr.nodeSize,vr.nodeSpacing),radiiMap:lt,width:t,strictRadial:!!A,focusNode:L,maxIteration:g,k:i/4.5};da(this.model,O)}})}run(t,r,n,i){let o=Zl(r),a=this.model.nodeCount(),l=this.model.nodes(),g=new Float64Array(a),f=new Float64Array(a);for(let p=0;p{let l=t.length,g=new Array(l),f=new Array(l);for(let A=0;A{let t=e.length,r=e[0].length,n=[];for(let i=0;i{let n=e.length;for(let i=0;i{let r=e[t],n=0;for(let i=0;iPr,BubbleSets:()=>Hn,Circle:()=>an,Line:()=>se,PointPath:()=>Ve,Rectangle:()=>pe,addPadding:()=>Yi,boundingBox:()=>ma,calculatePotentialOutline:()=>xa,calculateVirtualEdges:()=>ba,circle:()=>uf,createGenericInfluenceArea:()=>Xi,createLineInfluenceArea:()=>Ui,createOutline:()=>xf,createRectangleInfluenceArea:()=>va,default:()=>Hn,defaultOptions:()=>Qi,line:()=>hf,lineBoundingBox:()=>Ki,point:()=>Mt,rect:()=>af,unionBoundingBox:()=>Sa});function Vi(e,t,r,n,i,o){let a=e,l=t,g=r-a,f=n-l,p=i-a,y=o-l,w=p*g+y*f,S=0;w<=0?S=0:(p=g-p,y=f-y,w=p*g+y*f,w<=0?S=0:S=w*w/(g*g+f*f));let A=p*p+y*y-S;return A<0?0:A}function cr(e,t,r,n){return(e-r)*(e-r)+(t-n)*(t-n)}function ga(e,t,r,n,i){return cr(e,t,r,n)r;if(e===0)return Math.round;let t=Math.pow(10,e);return r=>Math.round(r*t)/t}function Ki(e){let t=Math.min(e.x1,e.x2),r=Math.max(e.x1,e.x2),n=Math.min(e.y1,e.y2),i=Math.max(e.y1,e.y2);return{x:t,y:n,x2:r,y2:i,width:r-t,height:i-n}}var se=class e{constructor(t,r,n,i){this.x1=t,this.y1=r,this.x2=n,this.y2=i}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new e(t.x1,t.y1,t.x2,t.y2)}cuts(t,r){if(this.y1===this.y2||rthis.y1&&r>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+n)return!1}else if(tthis.x1+n)return!1;if(this.y1this.y2+n)return!1}else if(rthis.y1+n)return!1;return!0}},Ut;(function(e){e[e.POINT=1]="POINT",e[e.PARALLEL=2]="PARALLEL",e[e.COINCIDENT=3]="COINCIDENT",e[e.NONE=4]="NONE"})(Ut||(Ut={}));var sn=class{constructor(t,r=0,n=0){this.state=t,this.x=r,this.y=n}};function Kn(e,t){let r=(t.x2-t.x1)*(e.y1-t.y1)-(t.y2-t.y1)*(e.x1-t.x1),n=(e.x2-e.x1)*(e.y1-t.y1)-(e.y2-e.y1)*(e.x1-t.x1),i=(t.y2-t.y1)*(e.x2-e.x1)-(t.x2-t.x1)*(e.y2-e.y1);if(i){let o=r/i,a=n/i;return 0<=o&&o<=1&&0<=a&&a<=1?new sn(Ut.POINT,e.x1+o*(e.x2-e.x1),e.y1+o*(e.y2-e.y1)):new sn(Ut.NONE)}return new sn(r===0||n===0?Ut.COINCIDENT:Ut.PARALLEL)}function ya(e,t){let r=(t.x2-t.x1)*(e.y1-t.y1)-(t.y2-t.y1)*(e.x1-t.x1),n=(e.x2-e.x1)*(e.y1-t.y1)-(e.y2-e.y1)*(e.x1-t.x1),i=(t.y2-t.y1)*(e.x2-e.x1)-(t.x2-t.x1)*(e.y2-e.y1);if(i){let o=r/i,a=n/i;if(0<=o&&o<=1&&0<=a&&a<=1)return o}return Number.POSITIVE_INFINITY}function rf(e,t){function r(i,o,a,l){let g=ya(t,new se(i,o,a,l));return g=Math.abs(g-.5),g>=0&&g<=1?1:0}let n=r(e.x,e.y,e.x2,e.y);return n+=r(e.x,e.y,e.x,e.y2),n>1||(n+=r(e.x,e.y2,e.x2,e.y2),n>1)?!0:(n+=r(e.x2,e.y,e.x2,e.y2),n>0)}var Bt;(function(e){e[e.LEFT=0]="LEFT",e[e.TOP=1]="TOP",e[e.RIGHT=2]="RIGHT",e[e.BOTTOM=3]="BOTTOM"})(Bt||(Bt={}));function Zn(e,t,r){let n=new Set;return e.width<=0?(n.add(Bt.LEFT),n.add(Bt.RIGHT)):te.x+e.width&&n.add(Bt.RIGHT),e.height<=0?(n.add(Bt.TOP),n.add(Bt.BOTTOM)):re.y+e.height&&n.add(Bt.BOTTOM),n}function wa(e,t){let r=t.x1,n=t.y1,i=t.x2,o=t.y2,a=Array.from(Zn(e,i,o));if(a.length===0)return!0;let l=Zn(e,r,n);for(;l.size!==0;){for(let g of a)if(l.has(g))return!1;if(l.has(Bt.RIGHT)||l.has(Bt.LEFT)){let g=e.x;l.has(Bt.RIGHT)&&(g+=e.width),n=n+(g-r)*(o-n)/(i-r),r=g}else{let g=e.y;l.has(Bt.BOTTOM)&&(g+=e.height),r=r+(g-n)*(i-r)/(o-n),n=g}l=Zn(e,r,n)}return!0}function nf(e,t){let r=Number.POSITIVE_INFINITY,n=0;function i(o,a,l,g){let f=ya(t,new se(o,a,l,g));f=Math.abs(f-.5),f>=0&&f<=1&&(n++,f1||(i(e.x,e.y2,e.x2,e.y2),n>1)?r:(i(e.x2,e.y,e.x2,e.y2),n===0?-1:r)}function sf(e,t){let r=0,n=Kn(e,new se(t.x,t.y,t.x2,t.y));r+=n.state===Ut.POINT?1:0;let i=Kn(e,new se(t.x,t.y,t.x,t.y2));r+=i.state===Ut.POINT?1:0;let o=Kn(e,new se(t.x,t.y2,t.x2,t.y2));r+=o.state===Ut.POINT?1:0;let a=Kn(e,new se(t.x2,t.y,t.x2,t.y2));return r+=a.state===Ut.POINT?1:0,{top:n,left:i,bottom:o,right:a,count:r}}var pe=class e{constructor(t,r,n,i){this.x=t,this.y=r,this.width=n,this.height=i}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new e(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new e(this.x,this.y,this.width,this.height)}add(t){let r=Math.min(this.x,t.x),n=Math.min(this.y,t.y),i=Math.max(this.x2,t.x+t.width),o=Math.max(this.y2,t.y+t.height);this.x=r,this.y=n,this.width=i-r,this.height=o-n}addPoint(t){let r=Math.min(this.x,t.x),n=Math.min(this.y,t.y),i=Math.max(this.x2,t.x),o=Math.max(this.y2,t.y);this.x=r,this.y=n,this.width=i-r,this.height=o-n}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,r){return t>=this.x&&t<=this.x2&&r>=this.y&&r<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let r=this.scaleX(t.x),n=this.scaleY(t.y),i=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),o=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),a=i-r,l=o-n;return new pe(r,n,a,l)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,r){let n=Math.ceil(r/this.pixelGroup),i=this.boundX(t.x-n),o=this.boundY(t.y-n),a=this.boundX(t.x2+n),l=this.boundY(t.y2+n),g=a-i,f=l-o;return new pe(i,o,g,f)}get(t,r){return t<0||r<0||t>=this.width||r>=this.height?Number.NaN:this.area[t+r*this.width]}inc(t,r,n){t<0||r<0||t>=this.width||r>=this.height||(this.area[t+r*this.width]+=n)}set(t,r,n){t<0||r<0||t>=this.width||r>=this.height||(this.area[t+r*this.width]=n)}incArea(t,r){if(t.width<=0||t.height<=0||r===0)return;let n=this.width,i=t.width,o=Math.max(0,t.i),a=Math.max(0,t.j),l=Math.min(t.i+t.width,n),g=Math.min(t.j+t.height,this.height);if(!(g<=0||l<=0||o>=n||g>=this.height))for(let f=a;fMath.min(a,l),Number.POSITIVE_INFINITY),i=this.area.reduce((a,l)=>Math.max(a,l),Number.NEGATIVE_INFINITY),o=a=>(a-n)/(i-n);t.scale(this.pixelGroup,this.pixelGroup);for(let a=0;ar?"black":"white",t.fillRect(i,o,1,1)}t.restore()}}};function Yi(e,t){let r=n=>({x:n.x-t,y:n.y-t,width:n.width+2*t,height:n.height+2*t});return Array.isArray(e)?e.map(r):r(e)}function Ui(e,t,r){return Xi(Object.assign(Ki(e),{distSquare:(n,i)=>Vi(e.x1,e.y1,e.x2,e.y2,n,i)}),t,r)}function Xi(e,t,r){let n=Yi(e,r),i=t.scale(n),o=t.createSub(i,n);return of(o,t,r,(a,l)=>e.distSquare(a,l)),o}function of(e,t,r,n){let i=r*r;for(let o=0;o{let l=i.slice(0,a);return cf(t,o,l,r,n)}).flat()}function cf(e,t,r,n,i){let o=Mt(t.cx,t.cy),a=df(o,r,e);if(a==null)return[];let l=new se(o.x,o.y,a.cx,a.cy),g=lf(l,e,n,i);return ff(g,e)}function lf(e,t,r,n){let i=[],o=[];o.push(e);let a=!0;for(let l=0;l0;){let g=o.pop(),f=Ea(t,g),p=f?sf(g,f):null;if(!f||!p||p.count!==2){a||i.push(g);continue}let y=n,w=Xn(f,y,p,!0),S=hr(w,o)||hr(w,i),A=Yn(w,t);for(;!S&&A&&y>=1;)y/=1.5,w=Xn(f,y,p,!0),S=hr(w,o)||hr(w,i),A=Yn(w,t);if(w&&!S&&!A&&(o.push(new se(g.x1,g.y1,w.x,w.y)),o.push(new se(w.x,w.y,g.x2,g.y2)),a=!0),a)continue;y=n,w=Xn(f,y,p,!1);let I=hr(w,o)||hr(w,i);for(A=Yn(w,t);!I&&A&&y>=1;)y/=1.5,w=Xn(f,y,p,!1),I=hr(w,o)||hr(w,i),A=Yn(w,t);w&&!I&&(o.push(new se(g.x1,g.y1,w.x,w.y)),o.push(new se(w.x,w.y,g.x2,g.y2)),a=!0),a||i.push(g)}for(;o.length>0;)i.push(o.pop());return i}function ff(e,t){let r=[];for(;e.length>0;){let n=e.pop();if(e.length===0){r.push(n);break}let i=e.pop(),o=new se(n.x1,n.y1,i.x2,i.y2);Ea(t,o)?(r.push(n),e.push(i)):e.push(o)}return r}function df(e,t,r){let n=Number.POSITIVE_INFINITY;return t.reduce((i,o)=>{let a=cr(e.x,e.y,o.cx,o.cy);if(a>n)return i;let l=new se(e.x,e.y,o.cx,o.cy),g=pf(r,l);return a*(g+1)*(g+1){t+=n.cx,r+=n.cy}),t/=e.length,r/=e.length,e.map(n=>{let i=t-n.cx,o=r-n.cy,a=i*i+o*o;return[n,a]}).sort((n,i)=>n[1]-i[1]).map(n=>n[0])}function Yn(e,t){return t.some(r=>r.containsPt(e.x,e.y))}function hr(e,t){return t.some(r=>!!(ga(r.x1,r.y1,e.x,e.y,.001)||ga(r.x2,r.y2,e.x,e.y,.001)))}function Ea(e,t){let r=Number.POSITIVE_INFINITY,n=null;for(let i of e){if(!wa(i,t))continue;let o=nf(i,t);o>=0&&owa(n,t)&&rf(n,t)?r+1:r,0)}function Xn(e,t,r,n){let i=r.top,o=r.left,a=r.bottom,l=r.right;if(n){if(o.state===Ut.POINT){if(i.state===Ut.POINT)return Mt(e.x-t,e.y-t);if(a.state===Ut.POINT)return Mt(e.x-t,e.y2+t);let w=e.width*e.height;return e.width*((o.y-e.y+(l.y-e.y))*.5)l.y?Mt(e.x-t,e.y-t):Mt(e.x2+t,e.y-t):o.ya.x?Mt(e.x-t,e.y-t):Mt(e.x-t,e.y2+t):i.xl.y?Mt(e.x2+t,e.y2+t):Mt(e.x-t,e.y2+t):o.ya.x?Mt(e.x2+t,e.y2+t):Mt(e.x2+t,e.y-t):i.xn)return!1}return!0}function wf(e=0){return t=>{if(e<0||t.length<3)return t;let r=[],n=0,i=e*e;for(;n{if(a.length<3)return a;let l=[],g=a.closed,f=a.length+3-1+(g?0:2);l.push(o(a,2-(g?0:2),0));for(let p=2-(g?0:2);p{let r=e,n=t.length;if(r>1)for(n=Math.floor(t.length/r);n<3&&r>1;)r-=1,n=Math.floor(t.length/r);let i=[];for(let o=0,a=0;a=n?this.closed?this.get(t-n):this.points[n-1]:this.points[r]}get length(){return this.points.length}toString(t=1/0){let r=this.points;if(r.length===0)return"";let n=typeof t=="function"?t:ef(t),i="M";for(let o of r)i+=`${n(o.x)},${n(o.y)} L`;return i=i.slice(0,-1),this.closed&&(i+=" Z"),i}draw(t){let r=this.points;if(r.length!==0){t.beginPath(),t.moveTo(r[0].x,r[0].y);for(let n of r)t.lineTo(n.x,n.y);this.closed&&t.closePath()}}sample(t){return bf(t)(this)}simplify(t){return wf(t)(this)}bSplines(t){return vf(t)(this)}apply(t){return t(this)}containsElements(t){let r=ma(this.points);return r?t.every(n=>r.containsPt(n.cx,n.cy)&&this.withinArea(n.cx,n.cy)):!1}withinArea(t,r){if(this.length===0)return!1;let n=0,i=this.points[0],o=new se(i.x,i.y,i.x,i.y);for(let a=1;at?p+y:p}function o(g,f){let p=nn;return p=i(g,f,p,1),p=i(g+1,f,p,2),p=i(g,f+1,p,4),p=i(g+1,f+1,p,8),Number.isNaN(p)?-1:p}let a=Qn;function l(g,f){let p=g,y=f,w=e.invertScaleX(p),S=e.invertScaleY(y);for(let A=0;Apa(n.raw,t));return r<0?!1:(this.members.splice(r,1),this.dirty.add(Pe.MEMBERS),!0)}removeNonMember(t){let r=this.nonMembers.findIndex(n=>pa(n.raw,t));return r<0?!1:(this.nonMembers.splice(r,1),this.dirty.add(Pe.NON_MEMBERS),!0)}removeEdge(t){let r=this.edges.findIndex(n=>n.obj.equals(t));return r<0?!1:(this.edges.splice(r,1),this.dirty.add(Pe.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(Pe.NON_MEMBERS);for(let r of t)this.nonMembers.push({raw:r,obj:on(r)?an.from(r):pe.from(r),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(Pe.EDGES);for(let r of t)this.edges.push({raw:r,obj:se.from(r),area:null})}}update(){let t=this.dirty.has(Pe.MEMBERS),r=this.dirty.has(Pe.NON_MEMBERS),n=this.dirty.has(Pe.EDGES);this.dirty.clear();let i=this.members.map(f=>f.obj);if(this.o.virtualEdges&&(t||r)){let f=this.nonMembers.map(w=>w.obj),p=ba(i,f,this.o.maxRoutingIterations,this.o.morphBuffer),y=new Map(this.virtualEdges.map(w=>[w.obj.toString(),w.area]));this.virtualEdges=p.map(w=>{var S;return{raw:w,obj:w,area:(S=y.get(w.toString()))!==null&&S!==void 0?S:null}}),n=!0}let o=!1;if(t||n){let f=this.virtualEdges.concat(this.edges).map(S=>S.obj),p=Sa(i,f),y=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,w=pe.from(Yi(p,y));w.equals(this.activeRegion)||(o=!0,this.activeRegion=w)}if(o){let f=Math.ceil(this.activeRegion.width/this.o.pixelGroup),p=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=Pr.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(y=>y.area=null),this.nonMembers.forEach(y=>y.area=null),this.edges.forEach(y=>y.area=null),this.virtualEdges.forEach(y=>y.area=null)):(f!==this.potentialArea.width||p!==this.potentialArea.height)&&(this.potentialArea=Pr.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let a=new Map,l=f=>{if(f.area){let p=`${f.obj.width}x${f.obj.height}x${f.obj instanceof pe?"R":"C"}`;a.set(p,f.area)}},g=f=>{if(f.area)return;let p=`${f.obj.width}x${f.obj.height}x${f.obj instanceof pe?"R":"C"}`;if(a.has(p)){let w=a.get(p);f.area=this.potentialArea.copy(w,{x:f.obj.x-this.o.nodeR1,y:f.obj.y-this.o.nodeR1});return}let y=f.obj instanceof pe?va(f.obj,this.potentialArea,this.o.nodeR1):Xi(f.obj,this.potentialArea,this.o.nodeR1);f.area=y,a.set(p,y)};this.members.forEach(l),this.nonMembers.forEach(l),this.members.forEach(g),this.nonMembers.forEach(f=>{this.activeRegion.intersects(f.obj)?g(f):f.area=null}),this.edges.forEach(f=>{f.area||(f.area=Ui(f.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(f=>{f.area||(f.area=Ui(f.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let r of this.members)r.obj.draw(t)}drawNonMembers(t){for(let r of this.nonMembers)r.obj.draw(t)}drawEdges(t){for(let r of this.edges)r.obj.draw(t)}drawPotentialArea(t,r=!0){this.potentialArea.draw(t,r)}compute(){if(this.members.length===0)return new Ve([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:r}=this,n=this.members.map(l=>l.area),i=this.virtualEdges.concat(this.edges).map(l=>l.area),o=this.nonMembers.filter(l=>l.area!=null).map(l=>l.area),a=this.members.map(l=>l.obj);return xa(r,n,i,o,l=>l.containsElements(a),t)}};function xa(e,t,r,n,i,o={}){let a=Object.assign({},Qi,o),l=a.threshold,g=a.memberInfluenceFactor,f=a.edgeInfluenceFactor,p=a.nonMemberInfluenceFactor,y=(a.nodeR0-a.nodeR1)*(a.nodeR0-a.nodeR1),w=(a.edgeR0-a.edgeR1)*(a.edgeR0-a.edgeR1);for(let S=0;S0)p*=.8;else break}return new Ve([])}function Sa(e,t){if(e.length===0)return new pe(0,0,0,0);let r=pe.from(e[0]);for(let n of e)r.add(n);for(let n of t)r.add(Ki(n));return r}function xf(e,t=[],r=[],n={}){if(e.length===0)return new Ve([]);let i=new Hn(n);return i.pushMember(...e),i.pushNonMember(...t),i.pushEdge(...r),i.compute()}var sg=Se(ja(),1),og=Se(eu(),1),ag=Se(uu(),1),ug=Se(fu(),1),hg=Se(yu(),1),cg=Se(vu(),1),lg=Se(_u(),1),fg=Se(zu(),1),dg=Se(ih(),1);var export_FA2Layout=ig.default;var export_betweennessCentrality=og.default;var export_circlepack=ci.circlepack;var export_circular=ci.circular;var export_closenessCentrality=ag.default;var export_degreeCentrality=sg.degreeCentrality;var export_density=cg.density;var export_diameter=lg.default;var export_eigenvectorCentrality=ug.default;var export_forceAtlas2=ng.default;var export_louvain=dg.default;var export_modularity=fg.default;var export_pagerank=hg.default;var export_random=ci.random;var export_rotation=ci.rotation;export{Wn as ConcentricLayout,export_FA2Layout as FA2Layout,Tt as Graph,Bn as MDSLayout,Vn as RadialLayout,export_betweennessCentrality as betweennessCentrality,Aa as bubblesets,export_circlepack as circlepack,export_circular as circular,export_closenessCentrality as closenessCentrality,export_degreeCentrality as degreeCentrality,export_density as density,export_diameter as diameter,export_eigenvectorCentrality as eigenvectorCentrality,export_forceAtlas2 as forceAtlas2,export_louvain as louvain,export_modularity as modularity,export_pagerank as pagerank,export_random as random,export_rotation as rotation}; +}`}function a(m,c,u,o,h){let{rows:d,columns:v}=m,b=Math.min(d,c),x=Math.min(v,u),S=[];if(h==="auto"){h=!1;t:for(let O=0;O=0&&u?` ${g(m,c-1)}`:g(m,c)).padEnd(c)}function g(m,c){let u=m.toString();if(u.length<=c)return u;let o=m.toFixed(c);if(o.length>c&&(o=m.toFixed(Math.max(0,c-(o.length-c)))),o.length<=c&&!o.startsWith("0.000")&&!o.startsWith("-0.000"))return o;let h=m.toExponential(c);return h.length>c&&(h=m.toExponential(Math.max(0,c-(h.length-c)))),h.slice(0)}function f(m,c){m.prototype.add=function(o){return typeof o=="number"?this.addS(o):this.addM(o)},m.prototype.addS=function(o){for(let h=0;h>o);return this},m.prototype.signPropagatingRightShiftM=function(o){if(o=c.checkMatrix(o),this.rows!==o.rows||this.columns!==o.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>o.get(h,d));return this},m.signPropagatingRightShift=function(o,h){return new c(o).signPropagatingRightShift(h)},m.prototype.rightShift=function(o){return typeof o=="number"?this.rightShiftS(o):this.rightShiftM(o)},m.prototype.rightShiftS=function(o){for(let h=0;h>>o);return this},m.prototype.rightShiftM=function(o){if(o=c.checkMatrix(o),this.rows!==o.rows||this.columns!==o.columns)throw new RangeError("Matrices dimensions must be equal");for(let h=0;h>>o.get(h,d));return this},m.rightShift=function(o,h){return new c(o).rightShift(h)},m.prototype.zeroFillRightShift=m.prototype.rightShift,m.prototype.zeroFillRightShiftS=m.prototype.rightShiftS,m.prototype.zeroFillRightShiftM=m.prototype.rightShiftM,m.zeroFillRightShift=m.rightShift,m.prototype.not=function(){for(let o=0;oo)throw new RangeError("Row index out of range")}function y(m,c,u){let o=u?m.columns:m.columns-1;if(c<0||c>o)throw new RangeError("Column index out of range")}function w(m,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==m.columns)throw new RangeError("vector size must be the same as the number of columns");return c}function E(m,c){if(c.to1DArray&&(c=c.to1DArray()),c.length!==m.rows)throw new RangeError("vector size must be the same as the number of rows");return c}function A(m,c){if(!e.isAnyArray(c))throw new TypeError("row indices must be an array");for(let u=0;u=m.rows)throw new RangeError("row indices are out of range")}function I(m,c){if(!e.isAnyArray(c))throw new TypeError("column indices must be an array");for(let u=0;u=m.columns)throw new RangeError("column indices are out of range")}function _(m,c,u,o,h){if(arguments.length!==5)throw new RangeError("expected 4 arguments");if(j("startRow",c),j("endRow",u),j("startColumn",o),j("endColumn",h),c>u||o>h||c<0||c>=m.rows||u<0||u>=m.rows||o<0||o>=m.columns||h<0||h>=m.columns)throw new RangeError("Submatrix indices are out of range")}function $(m,c=0){let u=[];for(let o=0;o=d)throw new RangeError("min must be smaller than max");let b=d-h,x=new K(c,u);for(let S=0;So?(d=!0,o=u):(h=!1,d=!0);c++}return h}isReducedEchelonForm(){let c=0,u=0,o=-1,h=!0,d=!1;for(;co?(d=!0,o=u):(h=!1,d=!0);for(let v=u+1;vc.get(h,o)&&(h=d);if(c.get(h,o)===0)o++;else{c.swapRows(u,h);let d=c.get(u,o);for(let v=o;v=0;)if(c.maxRow(h)===0)h--;else{let d=0,v=!1;for(;du[o]&&(u[o]=this.get(o,h));return u}case"column":{let u=new Array(this.columns).fill(Number.NEGATIVE_INFINITY);for(let o=0;ou[h]&&(u[h]=this.get(o,h));return u}case void 0:{let u=this.get(0,0);for(let o=0;ou&&(u=this.get(o,h));return u}default:throw new Error(`invalid option: ${c}`)}}maxIndex(){R(this);let c=this.get(0,0),u=[0,0];for(let o=0;oc&&(c=this.get(o,h),u[0]=o,u[1]=h);return u}min(c){if(this.isEmpty())return NaN;switch(c){case"row":{let u=new Array(this.rows).fill(Number.POSITIVE_INFINITY);for(let o=0;ou&&(u=this.get(c,o));return u}maxRowIndex(c){p(this,c),R(this);let u=this.get(c,0),o=[c,0];for(let h=1;hu&&(u=this.get(c,h),o[1]=h);return o}minRow(c){if(p(this,c),this.isEmpty())return NaN;let u=this.get(c,0);for(let o=1;ou&&(u=this.get(o,c));return u}maxColumnIndex(c){y(this,c),R(this);let u=this.get(0,c),o=[0,c];for(let h=1;hu&&(u=this.get(h,c),o[0]=h);return o}minColumn(c){if(y(this,c),this.isEmpty())return NaN;let u=this.get(0,c);for(let o=1;o=1;h/=2)(h&1)!==0&&(u=u.mmul(o)),o=o.mmul(o);return u}strassen2x2(c){c=K.checkMatrix(c);let u=new K(2,2),o=this.get(0,0),h=c.get(0,0),d=this.get(0,1),v=c.get(0,1),b=this.get(1,0),x=c.get(1,0),S=this.get(1,1),O=c.get(1,1),D=(o+S)*(h+O),F=(b+S)*h,Q=o*(v-O),N=S*(x-h),U=(o+d)*O,tt=(b-o)*(h+v),k=(d-S)*(x+O),X=D+N-U+k,nt=Q+U,pt=F+N,yt=D-F+Q+tt;return u.set(0,0,X),u.set(0,1,nt),u.set(1,0,pt),u.set(1,1,yt),u}strassen3x3(c){c=K.checkMatrix(c);let u=new K(3,3),o=this.get(0,0),h=this.get(0,1),d=this.get(0,2),v=this.get(1,0),b=this.get(1,1),x=this.get(1,2),S=this.get(2,0),O=this.get(2,1),D=this.get(2,2),F=c.get(0,0),Q=c.get(0,1),N=c.get(0,2),U=c.get(1,0),tt=c.get(1,1),k=c.get(1,2),X=c.get(2,0),nt=c.get(2,1),pt=c.get(2,2),yt=(o+h+d-v-b-O-D)*tt,zt=(o-v)*(-Q+tt),ot=b*(-F+Q+U-tt-k-X+pt),ct=(-o+v+b)*(F-Q+tt),Tt=(v+b)*(-F+Q),T=o*F,B=(-o+S+O)*(F-N+k),et=(-o+S)*(N-k),Y=(S+O)*(-F+N),Pt=(o+h+d-b-x-S-O)*k,Lt=O*(-F+N+U-tt-k-X+nt),$t=(-d+O+D)*(tt+X-nt),Nt=(d-D)*(tt-nt),he=d*X,Ge=(O+D)*(-X+nt),ee=(-d+b+x)*(k+X-pt),Be=(d-x)*(k-pt),Ze=(b+x)*(-X+pt),St=h*U,ce=x*nt,De=v*N,Ie=S*Q,re=D*pt,Ah=T+he+St,Dh=yt+ct+Tt+T+$t+he+Ge,Ih=T+B+Y+Pt+he+ee+Ze,kh=zt+ot+ct+T+he+ee+Be,jh=zt+ct+Tt+T+ce,Ch=he+ee+Be+Ze+De,Lh=T+B+et+Lt+$t+Nt+he,_h=$t+Nt+he+Ge+Ie,Rh=T+B+et+Y+re;return u.set(0,0,Ah),u.set(0,1,Dh),u.set(0,2,Ih),u.set(1,0,kh),u.set(1,1,jh),u.set(1,2,Ch),u.set(2,0,Lh),u.set(2,1,_h),u.set(2,2,Rh),u}mmulStrassen(c){c=K.checkMatrix(c);let u=this.clone(),o=u.rows,h=u.columns,d=c.rows,v=c.columns;h!==d&&console.warn(`Multiplying ${o} x ${h} and ${d} x ${v} matrix: dimensions do not match.`);function b(D,F,Q){let N=D.rows,U=D.columns;if(N===F&&U===Q)return D;{let tt=L.zeros(F,Q);return tt=tt.setSubMatrix(D,0,0),tt}}let x=Math.max(o,d),S=Math.max(h,v);u=b(u,x,S),c=b(c,x,S);function O(D,F,Q,N){if(Q<=512||N<=512)return D.mmul(F);Q%2===1&&N%2===1?(D=b(D,Q+1,N+1),F=b(F,Q+1,N+1)):Q%2===1?(D=b(D,Q+1,N),F=b(F,Q+1,N)):N%2===1&&(D=b(D,Q,N+1),F=b(F,Q,N+1));let U=parseInt(D.rows/2,10),tt=parseInt(D.columns/2,10),k=D.subMatrix(0,U-1,0,tt-1),X=F.subMatrix(0,U-1,0,tt-1),nt=D.subMatrix(0,U-1,tt,D.columns-1),pt=F.subMatrix(0,U-1,tt,F.columns-1),yt=D.subMatrix(U,D.rows-1,0,tt-1),zt=F.subMatrix(U,F.rows-1,0,tt-1),ot=D.subMatrix(U,D.rows-1,tt,D.columns-1),ct=F.subMatrix(U,F.rows-1,tt,F.columns-1),Tt=O(L.add(k,ot),L.add(X,ct),U,tt),T=O(L.add(yt,ot),X,U,tt),B=O(k,L.sub(pt,ct),U,tt),et=O(ot,L.sub(zt,X),U,tt),Y=O(L.add(k,nt),ct,U,tt),Pt=O(L.sub(yt,k),L.add(X,pt),U,tt),Lt=O(L.sub(nt,ot),L.add(zt,ct),U,tt),$t=L.add(Tt,et);$t.sub(Y),$t.add(Lt);let Nt=L.add(B,Y),he=L.add(T,et),Ge=L.sub(Tt,T);Ge.add(B),Ge.add(Pt);let ee=L.zeros(2*$t.rows,2*$t.columns);return ee=ee.setSubMatrix($t,0,0),ee=ee.setSubMatrix(Nt,$t.rows,0),ee=ee.setSubMatrix(he,0,$t.columns),ee=ee.setSubMatrix(Ge,$t.rows,$t.columns),ee.subMatrix(0,Q-1,0,N-1)}return O(u,c,x,S)}scaleRows(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:u=0,max:o=1}=c;if(!Number.isFinite(u))throw new TypeError("min must be a number");if(!Number.isFinite(o))throw new TypeError("max must be a number");if(u>=o)throw new RangeError("min must be smaller than max");let h=new K(this.rows,this.columns);for(let d=0;d0&&t(v,{min:u,max:o,output:v}),h.setRow(d,v)}return h}scaleColumns(c={}){if(typeof c!="object")throw new TypeError("options must be an object");let{min:u=0,max:o=1}=c;if(!Number.isFinite(u))throw new TypeError("min must be a number");if(!Number.isFinite(o))throw new TypeError("max must be a number");if(u>=o)throw new RangeError("min must be smaller than max");let h=new K(this.rows,this.columns);for(let d=0;do||u<0||u>=this.columns||o<0||o>=this.columns)throw new RangeError("Argument out of range");let h=new K(c.length,o-u+1);for(let d=0;d=this.rows)throw new RangeError(`Row index out of range: ${c[d]}`);h.set(d,v-u,this.get(c[d],v))}return h}subMatrixColumn(c,u,o){if(u===void 0&&(u=0),o===void 0&&(o=this.rows-1),u>o||u<0||u>=this.rows||o<0||o>=this.rows)throw new RangeError("Argument out of range");let h=new K(o-u+1,c.length);for(let d=0;d=this.columns)throw new RangeError(`Column index out of range: ${c[d]}`);h.set(v-u,d,this.get(v,c[d]))}return h}setSubMatrix(c,u,o){if(c=K.checkMatrix(c),c.isEmpty())return this;let h=u+c.rows-1,d=o+c.columns-1;_(this,u,h,o,d);for(let v=0;vtypeof c=="number")}L.random=L.rand,L.randomInt=L.randInt,L.diagonal=L.diag,L.prototype.diagonal=L.prototype.diag,L.identity=L.eye,L.prototype.negate=L.prototype.neg,L.prototype.tensorProduct=L.prototype.kroneckerProduct;let En=class En extends L{constructor(u,o){super();xi(this,Xr);Ss(this,"data");if(En.isMatrix(u))Si(this,Xr,Ui).call(this,u.rows,u.columns),En.copy(u,this);else if(Number.isInteger(u)&&u>=0)Si(this,Xr,Ui).call(this,u,o);else if(e.isAnyArray(u)){let h=u;if(u=h.length,o=u?h[0].length:0,typeof o!="number")throw new TypeError("Data must be a 2D array with at least one element");this.data=[];for(let d=0;d"u"&&(o=u,u=this.columns),y(this,u,!0),o=E(this,o);for(let h=0;h=0)for(let h=0;h=0)An(this,fe,new K(u,u));else if(An(this,fe,new K(u)),!this.isSymmetric())throw new TypeError("not symmetric data")}get size(){return $e(this,fe).size}get rows(){return $e(this,fe).rows}get columns(){return $e(this,fe).columns}get diagonalSize(){return this.rows}static isSymmetricMatrix(u){return K.isMatrix(u)&&u.klassType==="SymmetricMatrix"}static zeros(u){return new this(u)}static ones(u){return new this(u).fill(1)}clone(){let u=new xn(this.diagonalSize);for(let[o,h,d]of this.upperRightEntries())u.set(o,h,d);return u}toMatrix(){return new K(this)}get(u,o){return $e(this,fe).get(u,o)}set(u,o,h){return $e(this,fe).set(u,o,h),$e(this,fe).set(o,u,h),this}removeCross(u){return $e(this,fe).removeRow(u),$e(this,fe).removeColumn(u),this}addCross(u,o){o===void 0&&(o=u,u=this.diagonalSize);let h=o.slice();return h.splice(u,1),$e(this,fe).addRow(u,h),$e(this,fe).addColumn(u,o),this}applyMask(u){if(u.length!==this.diagonalSize)throw new RangeError("Mask size do not match with matrix size");let o=[];for(let[h,d]of u.entries())d||o.push(h);o.reverse();for(let h of o)this.removeCross(h);return this}toCompact(){let{diagonalSize:u}=this,o=new Array(u*(u+1)/2);for(let h=0,d=0,v=0;v=u&&(h=++d);return o}static fromCompact(u){let o=u.length,h=(Math.sqrt(8*o+1)-1)/2;if(!Number.isInteger(h))throw new TypeError(`This array is not a compact representation of a Symmetric Matrix, ${JSON.stringify(u)}`);let d=new xn(h);for(let v=0,b=0,x=0;x=h&&(v=++b);return d}*upperRightEntries(){for(let u=0,o=0;u=this.diagonalSize&&(o=++u)}}*upperRightValues(){for(let u=0,o=0;u=this.diagonalSize&&(o=++u)}};fe=new WeakMap;let Zt=xn;Zt.prototype.klassType="SymmetricMatrix";class It extends Zt{static isDistanceMatrix(c){return Zt.isSymmetricMatrix(c)&&c.klassSubType==="DistanceMatrix"}constructor(c){if(super(c),!this.isDistance())throw new TypeError("Provided arguments do no produce a distance matrix")}set(c,u,o){return c===u&&(o=0),super.set(c,u,o)}addCross(c,u){return u===void 0&&(u=c,c=this.diagonalSize),u=u.slice(),u[c]=0,super.addCross(c,u)}toSymmetricMatrix(){return new Zt(this)}clone(){let c=new It(this.diagonalSize);for(let[u,o,h]of this.upperRightEntries())u!==o&&c.set(u,o,h);return c}toCompact(){let{diagonalSize:c}=this,u=(c-1)*c/2,o=new Array(u);for(let h=1,d=0,v=0;v=c&&(h=++d+1);return o}static fromCompact(c){let u=c.length;if(u===0)return new this(0);let o=(Math.sqrt(8*u+1)+1)/2;if(!Number.isInteger(o))throw new TypeError(`This array is not a compact representation of a DistanceMatrix, ${JSON.stringify(c)}`);let h=new this(o);for(let d=1,v=0,b=0;b=o&&(d=++v+1);return h}}It.prototype.klassSubType="DistanceMatrix";class st extends L{constructor(c,u,o){super(),this.matrix=c,this.rows=u,this.columns=o}}class sr extends st{constructor(c,u){y(c,u),super(c,c.rows,1),this.column=u}set(c,u,o){return this.matrix.set(c,this.column,o),this}get(c){return this.matrix.get(c,this.column)}}class pe extends st{constructor(c,u){I(c,u),super(c,c.rows,u.length),this.columnIndices=u}set(c,u,o){return this.matrix.set(c,this.columnIndices[u],o),this}get(c,u){return this.matrix.get(c,this.columnIndices[u])}}class Ar extends st{constructor(c){super(c,c.rows,c.columns)}set(c,u,o){return this.matrix.set(c,this.columns-u-1,o),this}get(c,u){return this.matrix.get(c,this.columns-u-1)}}class Ce extends st{constructor(c){super(c,c.rows,c.columns)}set(c,u,o){return this.matrix.set(this.rows-c-1,u,o),this}get(c,u){return this.matrix.get(this.rows-c-1,u)}}class Dr extends st{constructor(c,u){p(c,u),super(c,1,c.columns),this.row=u}set(c,u,o){return this.matrix.set(this.row,u,o),this}get(c,u){return this.matrix.get(this.row,u)}}class Fe extends st{constructor(c,u){A(c,u),super(c,u.length,c.columns),this.rowIndices=u}set(c,u,o){return this.matrix.set(this.rowIndices[c],u,o),this}get(c,u){return this.matrix.get(this.rowIndices[c],u)}}class Dt extends st{constructor(c,u,o){A(c,u),I(c,o),super(c,u.length,o.length),this.rowIndices=u,this.columnIndices=o}set(c,u,o){return this.matrix.set(this.rowIndices[c],this.columnIndices[u],o),this}get(c,u){return this.matrix.get(this.rowIndices[c],this.columnIndices[u])}}class xt extends st{constructor(c,u,o,h,d){_(c,u,o,h,d),super(c,o-u+1,d-h+1),this.startRow=u,this.startColumn=h}set(c,u,o){return this.matrix.set(this.startRow+c,this.startColumn+u,o),this}get(c,u){return this.matrix.get(this.startRow+c,this.startColumn+u)}}class Et extends st{constructor(c){super(c,c.columns,c.rows)}set(c,u,o){return this.matrix.set(u,c,o),this}get(c,u){return this.matrix.get(u,c)}}class ye extends L{constructor(c,u={}){let{rows:o=1}=u;if(c.length%o!==0)throw new Error("the data length is not divisible by the number of rows");super(),this.rows=o,this.columns=c.length/o,this.data=c}set(c,u,o){let h=this._calculateIndex(c,u);return this.data[h]=o,this}get(c,u){let o=this._calculateIndex(c,u);return this.data[o]}_calculateIndex(c,u){return c*this.columns+u}}class it extends L{constructor(c){super(),this.data=c,this.rows=c.length,this.columns=c[0].length}set(c,u,o){return this.data[c][u]=o,this}get(c,u){return this.data[c][u]}}function ht(m,c){if(e.isAnyArray(m))return m[0]&&e.isAnyArray(m[0])?new it(m):new ye(m,c);throw new Error("the argument is not an array")}class q{constructor(c){c=it.checkMatrix(c);let u=c.clone(),o=u.rows,h=u.columns,d=new Float64Array(o),v=1,b,x,S,O,D,F,Q,N,U;for(b=0;bMath.abs(N[O])&&(O=b);if(O!==x){for(S=0;S=0;S--){for(x=0;xv?h.set(d,v,c.get(d,v)):d===v?h.set(d,v,1):h.set(d,v,0);return h}get upperTriangularMatrix(){let c=this.LU,u=c.rows,o=c.columns,h=new K(u,o);for(let d=0;dMath.abs(c)?(u=c/m,Math.abs(m)*Math.sqrt(1+u*u)):c!==0?(u=m/c,Math.abs(c)*Math.sqrt(1+u*u)):0}class qe{constructor(c){c=it.checkMatrix(c);let u=c.clone(),o=c.rows,h=c.columns,d=new Float64Array(h),v,b,x,S;for(x=0;x=0;S--){for(x=0;x=0;b--){for(d=0;d=0;T--)if(N[T]!==0){for(let B=T+1;B=0;T--){if(T0;){let T,B;for(T=ot-2;T>=-1&&T!==-1;T--){let et=Number.MIN_VALUE+Tt*Math.abs(N[T]+Math.abs(N[T+1]));if(Math.abs(k[T])<=et||Number.isNaN(k[T])){k[T]=0;break}}if(T===ot-2)B=4;else{let et;for(et=ot-1;et>=T&&et!==T;et--){let Y=(et!==ot?Math.abs(k[et]):0)+(et!==T+1?Math.abs(k[et-1]):0);if(Math.abs(N[et])<=Tt*Y){N[et]=0;break}}et===T?B=3:et===ot-1?B=1:(B=2,T=et)}switch(T++,B){case 1:{let et=k[ot-2];k[ot-2]=0;for(let Y=ot-2;Y>=T;Y--){let Pt=ue(N[Y],et),Lt=N[Y]/Pt,$t=et/Pt;if(N[Y]=Pt,Y!==T&&(et=-$t*k[Y-1],k[Y-1]=Lt*k[Y-1]),S)for(let Nt=0;Nt=N[T+1]);){let et=N[T];if(N[T]=N[T+1],N[T+1]=et,S&&Tu&&d.set(O,D,c.get(O,D)/this.s[D]);let v=this.U,b=v.rows,x=v.columns,S=new K(o,b);for(let O=0;Oc&&u++;return u}get diagonal(){return Array.from(this.s)}get threshold(){return Number.EPSILON/2*Math.max(this.m,this.n)*this.s[0]}get leftSingularVectors(){return this.U}get rightSingularVectors(){return this.V}get diagonalMatrix(){return K.diag(this.s)}}function or(m,c=!1){return m=it.checkMatrix(m),c?new Ee(m).inverse():we(m,K.eye(m.rows))}function we(m,c,u=!1){return m=it.checkMatrix(m),c=it.checkMatrix(c),u?new Ee(m).solve(c):m.isSquare()?new q(m).solve(c):new qe(m).solve(c)}function Oe(m){if(m=K.checkMatrix(m),m.isSquare()){if(m.columns===0)return 1;let c,u,o,h;if(m.columns===2)return c=m.get(0,0),u=m.get(0,1),o=m.get(1,0),h=m.get(1,1),c*h-u*o;if(m.columns===3){let d,v,b;return d=new Dt(m,[1,2],[1,2]),v=new Dt(m,[1,2],[0,2]),b=new Dt(m,[1,2],[0,1]),c=m.get(0,0),u=m.get(0,1),o=m.get(0,2),c*Oe(d)-u*Oe(v)+o*Oe(b)}else return new q(m).determinant}else throw Error("determinant can only be calculated for a square matrix")}function Kr(m,c){let u=[];for(let o=0;oh)return new Array(c.rows+1).fill(0);{let d=c.addRow(u,[0]);for(let v=0;vc?d[v]=1/d[v]:d[v]=0;return h.mmul(K.diag(d).mmul(o.transpose()))}function mr(m,c=m,u={}){m=new K(m);let o=!1;if(typeof c=="object"&&!K.isMatrix(c)&&!e.isAnyArray(c)?(u=c,c=m,o=!0):c=new K(c),m.rows!==c.rows)throw new TypeError("Both matrices must have the same number of rows");let{center:h=!0}=u;h&&(m=m.center("column"),o||(c=c.center("column")));let d=m.transpose().mmul(c);for(let v=0;v0?h.set(d,d+1,u[d]):u[d]<0&&h.set(d,d-1,u[d])}return h}}function Lr(m,c,u,o){let h,d,v,b,x,S,O,D;for(x=0;x0;b--){for(D=0,v=0,S=0;S0&&(d=-d),c[b]=D*d,v=v-h*d,u[b-1]=h-d,x=0;xS)do{for(h=u[S],D=(u[S+1]-h)/(2*c[S]),F=ue(D,1),D<0&&(F=-F),u[S]=c[S]/(D+F),u[S+1]=c[S]*(D+F),Q=u[S+1],d=h-u[S],v=S+2;v=S;v--)for(tt=U,U=N,nt=X,h=N*c[v],d=N*D,F=ue(D,c[v]),c[v+1]=X*F,X=c[v]/F,N=D/F,D=N*u[v]-X*h,u[v+1]=d+X*(N*h+X*u[v]),x=0;xzt*yt);u[S]=u[S]+pt,c[S]=0}for(v=0;v=D;S--)u[S]=c.get(S,D-1)/F,x+=u[S]*u[S];for(b=Math.sqrt(x),u[D]>0&&(b=-b),x=x-u[D]*b,u[D]=u[D]-b,O=D;O=D;S--)v+=u[S]*c.get(S,O);for(v=v/x,S=D;S<=d;S++)c.set(S,O,c.get(S,O)-v*u[S])}for(S=0;S<=d;S++){for(v=0,O=d;O>=D;O--)v+=u[O]*c.get(S,O);for(v=v/x,O=D;O<=d;O++)c.set(S,O,c.get(S,O)-v*u[O])}u[D]=F*u[D],c.set(D,D-1,F*b)}}for(S=0;S=h+1;D--)if(c.get(D,D-1)!==0){for(S=D+1;S<=d;S++)u[S]=c.get(S,D-1);for(O=D;O<=d;O++){for(b=0,S=D;S<=d;S++)b+=u[S]*o.get(S,O);for(b=b/u[D]/c.get(D,D-1),S=D;S<=d;S++)o.set(S,O,o.get(S,O)+b*u[S])}}}function Sh(m,c,u,o,h){let d=m-1,v=0,b=m-1,x=Number.EPSILON,S=0,O=0,D=0,F=0,Q=0,N=0,U=0,tt=0,k,X,nt,pt,yt,zt,ot,ct,Tt,T,B,et,Y,Pt,Lt;for(k=0;kb)&&(u[k]=h.get(k,k),c[k]=0),X=Math.max(k-1,0);X=v;){for(pt=d;pt>v&&(N=Math.abs(h.get(pt-1,pt-1))+Math.abs(h.get(pt,pt)),N===0&&(N=O),!(Math.abs(h.get(pt,pt-1))=0){for(U=D>=0?D+U:D-U,u[d-1]=ct+U,u[d]=u[d-1],U!==0&&(u[d]=ct-ot/U),c[d-1]=0,c[d]=0,ct=h.get(d,d-1),N=Math.abs(ct)+Math.abs(U),D=ct/N,F=U/N,Q=Math.sqrt(D*D+F*F),D=D/Q,F=F/Q,X=d-1;X0)){for(N=Math.sqrt(N),Tt=pt&&(U=h.get(yt,yt),Q=ct-U,N=Tt-U,D=(Q*N-ot)/h.get(yt+1,yt)+h.get(yt,yt+1),F=h.get(yt+1,yt+1)-U-Q-N,Q=h.get(yt+2,yt+1),N=Math.abs(D)+Math.abs(F)+Math.abs(Q),D=D/N,F=F/N,Q=Q/N,!(yt===pt||Math.abs(h.get(yt,yt-1))*(Math.abs(F)+Math.abs(Q))yt+2&&h.set(k,k-3,0);for(nt=yt;nt<=d-1&&(Pt=nt!==d-1,nt!==yt&&(D=h.get(nt,nt-1),F=h.get(nt+1,nt-1),Q=Pt?h.get(nt+2,nt-1):0,ct=Math.abs(D)+Math.abs(F)+Math.abs(Q),ct!==0&&(D=D/ct,F=F/ct,Q=Q/ct)),ct!==0);nt++)if(N=Math.sqrt(D*D+F*F+Q*Q),D<0&&(N=-N),N!==0){for(nt!==yt?h.set(nt,nt-1,-N*ct):pt!==yt&&h.set(nt,nt-1,-h.get(nt,nt-1)),D=D+N,ct=D/N,Tt=F/N,U=Q/N,F=F/D,Q=Q/D,X=nt;X=0;d--)if(D=u[d],F=c[d],F===0)for(pt=d,h.set(d,d,1),k=d-1;k>=0;k--){for(ot=h.get(k,k)-D,Q=0,X=pt;X<=d;X++)Q=Q+h.get(k,X)*h.get(X,d);if(c[k]<0)U=ot,N=Q;else if(pt=k,c[k]===0?h.set(k,d,ot!==0?-Q/ot:-Q/(x*O)):(ct=h.get(k,k+1),Tt=h.get(k+1,k),F=(u[k]-D)*(u[k]-D)+c[k]*c[k],zt=(ct*N-U*Q)/F,h.set(k,d,zt),h.set(k+1,d,Math.abs(ct)>Math.abs(U)?(-Q-ot*zt)/ct:(-N-Tt*zt)/U)),zt=Math.abs(h.get(k,d)),x*zt*zt>1)for(X=k;X<=d;X++)h.set(X,d,h.get(X,d)/zt)}else if(F<0)for(pt=d-1,Math.abs(h.get(d,d-1))>Math.abs(h.get(d-1,d))?(h.set(d-1,d-1,F/h.get(d,d-1)),h.set(d-1,d,-(h.get(d,d)-D)/h.get(d,d-1))):(Lt=bn(0,-h.get(d-1,d),h.get(d-1,d-1)-D,F),h.set(d-1,d-1,Lt[0]),h.set(d-1,d,Lt[1])),h.set(d,d-1,0),h.set(d,d,1),k=d-2;k>=0;k--){for(T=0,B=0,X=pt;X<=d;X++)T=T+h.get(k,X)*h.get(X,d-1),B=B+h.get(k,X)*h.get(X,d);if(ot=h.get(k,k)-D,c[k]<0)U=ot,Q=T,N=B;else if(pt=k,c[k]===0?(Lt=bn(-T,-B,ot,F),h.set(k,d-1,Lt[0]),h.set(k,d,Lt[1])):(ct=h.get(k,k+1),Tt=h.get(k+1,k),et=(u[k]-D)*(u[k]-D)+c[k]*c[k]-F*F,Y=(u[k]-D)*2*F,et===0&&Y===0&&(et=x*O*(Math.abs(ot)+Math.abs(F)+Math.abs(ct)+Math.abs(Tt)+Math.abs(U))),Lt=bn(ct*Q-U*T+F*B,ct*N-U*B-F*T,et,Y),h.set(k,d-1,Lt[0]),h.set(k,d,Lt[1]),Math.abs(ct)>Math.abs(U)+Math.abs(F)?(h.set(k+1,d-1,(-T-ot*h.get(k,d-1)+F*h.get(k,d))/ct),h.set(k+1,d,(-B-ot*h.get(k,d)-F*h.get(k,d-1))/ct)):(Lt=bn(-Q-Tt*h.get(k,d-1),-N-Tt*h.get(k,d),U,F),h.set(k+1,d-1,Lt[0]),h.set(k+1,d,Lt[1]))),zt=Math.max(Math.abs(h.get(k,d-1)),Math.abs(h.get(k,d))),x*zt*zt>1)for(X=k;X<=d;X++)h.set(X,d-1,h.get(X,d-1)/zt),h.set(X,d,h.get(X,d)/zt)}for(k=0;kb)for(X=k;X=v;X--)for(k=v;k<=b;k++){for(U=0,nt=v;nt<=Math.min(X,b);nt++)U=U+o.get(k,nt)*h.get(nt,X);o.set(k,X,U)}}}function bn(m,c,u,o){let h,d;return Math.abs(u)>Math.abs(o)?(h=o/u,d=u+h*o,[(m+h*c)/d,(c-h*m)/d]):(h=u/o,d=o+h*u,[(h*m+c)/d,(h*c-m)/d])}class bs{constructor(c){if(c=it.checkMatrix(c),!c.isSymmetric())throw new Error("Matrix is not symmetric");let u=c,o=u.rows,h=new K(o,o),d=!0,v,b,x;for(b=0;b0),h.set(b,b,Math.sqrt(Math.max(S,0))),x=b+1;x=0;x--)for(b=0;bv;Q++)D=c.transpose().mmul(b).div(b.transpose().mmul(b).get(0,0)),D=D.div(D.norm()),S=c.mmul(D).div(D.transpose().mmul(D).get(0,0)),Q>0&&(x=S.clone().sub(F).pow(2).sum()),F=S.clone(),o?(O=o.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),O=O.div(O.norm()),b=o.mmul(O).div(O.transpose().mmul(O).get(0,0))):b=S;if(o){let Q=c.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0));Q=Q.div(Q.norm());let N=c.clone().sub(S.clone().mmul(Q.transpose())),U=b.transpose().mmul(S).div(S.transpose().mmul(S).get(0,0)),tt=o.clone().sub(S.clone().mulS(U.get(0,0)).mmul(O.transpose()));this.t=S,this.p=Q.transpose(),this.w=D.transpose(),this.q=O,this.u=b,this.s=S.transpose().mmul(S),this.xResidual=N,this.yResidual=tt,this.betas=U}else this.w=D.transpose(),this.s=S.transpose().mmul(S).sqrt(),h?this.t=S.clone().div(this.s.get(0,0)):this.t=S,this.xResidual=c.sub(S.mmul(D.transpose()))}}return mt.AbstractMatrix=L,mt.CHO=bs,mt.CholeskyDecomposition=bs,mt.DistanceMatrix=It,mt.EVD=Ue,mt.EigenvalueDecomposition=Ue,mt.LU=q,mt.LuDecomposition=q,mt.Matrix=K,mt.MatrixColumnSelectionView=pe,mt.MatrixColumnView=sr,mt.MatrixFlipColumnView=Ar,mt.MatrixFlipRowView=Ce,mt.MatrixRowSelectionView=Fe,mt.MatrixRowView=Dr,mt.MatrixSelectionView=Dt,mt.MatrixSubView=xt,mt.MatrixTransposeView=Et,mt.NIPALS=Es,mt.Nipals=Es,mt.QR=qe,mt.QrDecomposition=qe,mt.SVD=Ee,mt.SingularValueDecomposition=Ee,mt.SymmetricMatrix=Zt,mt.WrapperMatrix1D=ye,mt.WrapperMatrix2D=it,mt.correlation=Cr,mt.covariance=mr,mt.default=K,mt.determinant=Oe,mt.inverse=or,mt.linearDependencies=kr,mt.pseudoInverse=jr,mt.solve=we,mt.wrap=ht,mt}var hn=Ia(),Bi=ba(hn);var Vi=hn.Matrix,ka=hn.SingularValueDecomposition;Bi.Matrix?Bi.Matrix:hn.Matrix;var Zn=(e,t)=>{let r=e.nodeCount(),n=Array.from({length:r},()=>[]),i={},s=0;return e.forEachNode(a=>{i[a.id]=s++}),e.forEachEdge(a=>{let l=i[a.source],g=i[a.target];l==null||g==null||(n[l].push(g),t||n[g].push(l))}),n},ja=(e,t)=>{let r=e.length,n=new Array(r);for(let i=0;inew Array(t).fill(1/0));for(let n=0;n0&&(this.data[0]=r,this.bubbleDown(0)),t}empty(){return this.data.length===0}bubbleUp(t){let r=this.data;for(;t>0;){let n=t-1>>1;if(r[n][0]<=r[t][0])break;[r[n],r[t]]=[r[t],r[n]],t=n}}bubbleDown(t){let r=this.data,n=r.length;for(;;){let i=t*2+1,s=t*2+2,a=t;if(i{let p=l[g++];f.x=p[0]+r[0],f.y=p[1]+r[1]})})}},wf=e=>{let t=Number.NEGATIVE_INFINITY,r=[],n=e.length;for(let i=0;i{try{let n=e.length,i=new Vi(n,n);for(let E=0;E{let r=Object.assign(Object.assign({},Ca),t),{maxIteration:n,width:i,k:s,speed:a=Ca.speed,strictRadial:l,focusNode:g,radiiMap:f,nodeSizeFunc:p}=r,y=s*.002,w=new Map,E=i/10;for(let A=0;A{w.set(_.id,{x:0,y:0})}),mf(e,w,s,f,p),!(vf(e,w,a,l,g,E,f){let s=0;e.forEachNode(a=>{let l=0;e.forEachNode(g=>{if(l<=s){l++;return}if(a.id===g.id||n.get(a.id)!==n.get(g.id))return;let f=a.x-g.x,p=a.y-g.y,y=Math.sqrt(f*f+p*p);if(y===0){y=1;let A=s>l?1:-1;f=.01*A,p=.01*A}let w=Math.max(...i(a._original)),E=Math.max(...i(g._original));if(y{n&&e.forEachNode(f=>{let p=f.x-i.x,y=f.y-i.y,w=Math.sqrt(p*p+y*y),E=y/w,A=-p/w,I=t.get(f.id),_=Math.sqrt(I.x*I.x+I.y*I.y),$=Math.acos((E*I.x+A*I.y)/_);$>Math.PI/2&&($-=Math.PI/2,E*=-1,A*=-1);let j=Math.cos($)*_;t.set(f.id,{x:E*j,y:A*j})});let l=0,g=0;return e.forEachNode(f=>{if(f.id===i.id)return;let p=t.get(f.id),y=Math.sqrt(p.x*p.x+p.y*p.y);if(y>0){let w=Math.min(s*(r/800),y);if(f.x+=p.x/y*w,f.y+=p.y/y*w,n){let E=f.x-i.x,A=f.y-i.y,I=Math.sqrt(E*E+A*A);E=E/I*a.get(f.id),A=A/I*a.get(f.id),f.x=i.x+E,f.y=i.y+A}l+=w,g++}}),g>0?l/g:0};var Er={focusNode:null,linkDistance:50,maxIteration:1e3,maxPreventOverlapIteration:200,preventOverlap:!1,sortStrength:10,strictRadial:!0,unitRadius:null,nodeSize:10,nodeSpacing:0},ei=class extends cr{constructor(){super(...arguments),this.id="radial"}getDefaultOptions(){return Er}layout(){return Me(this,void 0,void 0,function*(){let{width:t,height:r,center:n}=qr(this.options),i=this.model.nodeCount();if(!i||i===1)return Fr(this.model,n);let{focusNode:s,linkDistance:a=Er.linkDistance,maxIteration:l=Er.maxIteration,maxPreventOverlapIteration:g=Er.maxPreventOverlapIteration,nodeSize:f,nodeSpacing:p,preventOverlap:y,sortBy:w,sortStrength:E=Er.sortStrength,strictRadial:A,unitRadius:I}=this.options,_=s&&this.model.node(s)||this.model.firstNode(),$=this.model.nodeIndexOf(_.id),j=Zn(this.model,!1),R=Hn(j),W=Sf(R,$);xf(R,$,W+1);let z=R[$],V=(t-n[0]>n[0]?n[0]:t-n[0])||t/2,G=(r-n[1]>n[1]?n[1]:r-n[1])||r/2,P=Math.min(V,G),C=Math.max(...z),H=[],ut=new Map,at=I??P/C;z.forEach((gt,M)=>{let ae=gt*at;H.push(ae),ut.set(this.model.nodeAt(M).id,ae)});let vt=bf(this.model,R,a,H,at,w,E),ft=Xi(vt,2,a),Ot=ft[$],Kt=0;if(this.model.forEachNode(gt=>{let M=ft[Kt];gt.x=M[0]-Ot[0],gt.y=M[1]-Ot[1],Kt++}),this.run(l,vt,H,$),this.model.forEachNode(gt=>{gt.x+=n[0],gt.y+=n[1]}),y){let M={nodeSizeFunc:Nn(f,p,Er.nodeSize,Er.nodeSpacing),radiiMap:ut,width:t,strictRadial:!!A,focusNode:_,maxIteration:g,k:i/4.5};La(this.model,M)}})}run(t,r,n,i){let s=Ef(r),a=this.model.nodeCount(),l=this.model.nodes(),g=new Float64Array(a),f=new Float64Array(a);for(let p=0;p{let l=t.length,g=new Array(l),f=new Array(l);for(let A=0;A{let t=e.length,r=e[0].length,n=[];for(let i=0;i{let n=e.length;for(let i=0;i{let r=e[t],n=0;for(let i=0;iUr,BubbleSets:()=>ui,Circle:()=>dn,Line:()=>oe,PointPath:()=>Ke,Rectangle:()=>ve,addPadding:()=>es,boundingBox:()=>Oa,calculatePotentialOutline:()=>Pa,calculateVirtualEdges:()=>$a,circle:()=>Lf,createGenericInfluenceArea:()=>rs,createLineInfluenceArea:()=>Ji,createOutline:()=>Uf,createRectangleInfluenceArea:()=>Ga,default:()=>ui,defaultOptions:()=>ns,line:()=>_f,lineBoundingBox:()=>ts,point:()=>Gt,rect:()=>Cf,unionBoundingBox:()=>Na});function Hi(e,t,r,n,i,s){let a=e,l=t,g=r-a,f=n-l,p=i-a,y=s-l,w=p*g+y*f,E=0;w<=0?E=0:(p=g-p,y=f-y,w=p*g+y*f,w<=0?E=0:E=w*w/(g*g+f*f));let A=p*p+y*y-E;return A<0?0:A}function dr(e,t,r,n){return(e-r)*(e-r)+(t-n)*(t-n)}function _a(e,t,r,n,i){return dr(e,t,r,n)r;if(e===0)return Math.round;let t=Math.pow(10,e);return r=>Math.round(r*t)/t}function ts(e){let t=Math.min(e.x1,e.x2),r=Math.max(e.x1,e.x2),n=Math.min(e.y1,e.y2),i=Math.max(e.y1,e.y2);return{x:t,y:n,x2:r,y2:i,width:r-t,height:i-n}}var oe=class e{constructor(t,r,n,i){this.x1=t,this.y1=r,this.x2=n,this.y2=i}equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2}draw(t){t.moveTo(this.x1,this.y1),t.lineTo(this.x2,this.y2)}toString(){return`Line(from=(${this.x1},${this.y1}),to=(${this.x2},${this.y2}))`}static from(t){return new e(t.x1,t.y1,t.x2,t.y2)}cuts(t,r){if(this.y1===this.y2||rthis.y1&&r>=this.y2||t>this.x1&&t>=this.x2)return!1;if(tthis.x2+n)return!1}else if(tthis.x1+n)return!1;if(this.y1this.y2+n)return!1}else if(rthis.y1+n)return!1;return!0}},Bt;(function(e){e[e.POINT=1]="POINT",e[e.PARALLEL=2]="PARALLEL",e[e.COINCIDENT=3]="COINCIDENT",e[e.NONE=4]="NONE"})(Bt||(Bt={}));var ln=class{constructor(t,r=0,n=0){this.state=t,this.x=r,this.y=n}};function ri(e,t){let r=(t.x2-t.x1)*(e.y1-t.y1)-(t.y2-t.y1)*(e.x1-t.x1),n=(e.x2-e.x1)*(e.y1-t.y1)-(e.y2-e.y1)*(e.x1-t.x1),i=(t.y2-t.y1)*(e.x2-e.x1)-(t.x2-t.x1)*(e.y2-e.y1);if(i){let s=r/i,a=n/i;return 0<=s&&s<=1&&0<=a&&a<=1?new ln(Bt.POINT,e.x1+s*(e.x2-e.x1),e.y1+s*(e.y2-e.y1)):new ln(Bt.NONE)}return new ln(r===0||n===0?Bt.COINCIDENT:Bt.PARALLEL)}function Ta(e,t){let r=(t.x2-t.x1)*(e.y1-t.y1)-(t.y2-t.y1)*(e.x1-t.x1),n=(e.x2-e.x1)*(e.y1-t.y1)-(e.y2-e.y1)*(e.x1-t.x1),i=(t.y2-t.y1)*(e.x2-e.x1)-(t.x2-t.x1)*(e.y2-e.y1);if(i){let s=r/i,a=n/i;if(0<=s&&s<=1&&0<=a&&a<=1)return s}return Number.POSITIVE_INFINITY}function Df(e,t){function r(i,s,a,l){let g=Ta(t,new oe(i,s,a,l));return g=Math.abs(g-.5),g>=0&&g<=1?1:0}let n=r(e.x,e.y,e.x2,e.y);return n+=r(e.x,e.y,e.x,e.y2),n>1||(n+=r(e.x,e.y2,e.x2,e.y2),n>1)?!0:(n+=r(e.x2,e.y,e.x2,e.y2),n>0)}var Vt;(function(e){e[e.LEFT=0]="LEFT",e[e.TOP=1]="TOP",e[e.RIGHT=2]="RIGHT",e[e.BOTTOM=3]="BOTTOM"})(Vt||(Vt={}));function ai(e,t,r){let n=new Set;return e.width<=0?(n.add(Vt.LEFT),n.add(Vt.RIGHT)):te.x+e.width&&n.add(Vt.RIGHT),e.height<=0?(n.add(Vt.TOP),n.add(Vt.BOTTOM)):re.y+e.height&&n.add(Vt.BOTTOM),n}function Ma(e,t){let r=t.x1,n=t.y1,i=t.x2,s=t.y2,a=Array.from(ai(e,i,s));if(a.length===0)return!0;let l=ai(e,r,n);for(;l.size!==0;){for(let g of a)if(l.has(g))return!1;if(l.has(Vt.RIGHT)||l.has(Vt.LEFT)){let g=e.x;l.has(Vt.RIGHT)&&(g+=e.width),n=n+(g-r)*(s-n)/(i-r),r=g}else{let g=e.y;l.has(Vt.BOTTOM)&&(g+=e.height),r=r+(g-n)*(i-r)/(s-n),n=g}l=ai(e,r,n)}return!0}function If(e,t){let r=Number.POSITIVE_INFINITY,n=0;function i(s,a,l,g){let f=Ta(t,new oe(s,a,l,g));f=Math.abs(f-.5),f>=0&&f<=1&&(n++,f1||(i(e.x,e.y2,e.x2,e.y2),n>1)?r:(i(e.x2,e.y,e.x2,e.y2),n===0?-1:r)}function kf(e,t){let r=0,n=ri(e,new oe(t.x,t.y,t.x2,t.y));r+=n.state===Bt.POINT?1:0;let i=ri(e,new oe(t.x,t.y,t.x,t.y2));r+=i.state===Bt.POINT?1:0;let s=ri(e,new oe(t.x,t.y2,t.x2,t.y2));r+=s.state===Bt.POINT?1:0;let a=ri(e,new oe(t.x2,t.y,t.x2,t.y2));return r+=a.state===Bt.POINT?1:0,{top:n,left:i,bottom:s,right:a,count:r}}var ve=class e{constructor(t,r,n,i){this.x=t,this.y=r,this.width=n,this.height=i}get x2(){return this.x+this.width}get y2(){return this.y+this.height}get cx(){return this.x+this.width/2}get cy(){return this.y+this.height/2}get radius(){return Math.max(this.width,this.height)/2}static from(t){return new e(t.x,t.y,t.width,t.height)}equals(t){return this.x===t.x&&this.y===t.y&&this.width===t.width&&this.height===t.height}clone(){return new e(this.x,this.y,this.width,this.height)}add(t){let r=Math.min(this.x,t.x),n=Math.min(this.y,t.y),i=Math.max(this.x2,t.x+t.width),s=Math.max(this.y2,t.y+t.height);this.x=r,this.y=n,this.width=i-r,this.height=s-n}addPoint(t){let r=Math.min(this.x,t.x),n=Math.min(this.y,t.y),i=Math.max(this.x2,t.x),s=Math.max(this.y2,t.y);this.x=r,this.y=n,this.width=i-r,this.height=s-n}toString(){return`Rectangle[x=${this.x}, y=${this.y}, w=${this.width}, h=${this.height}]`}draw(t){t.rect(this.x,this.y,this.width,this.height)}containsPt(t,r){return t>=this.x&&t<=this.x2&&r>=this.y&&r<=this.y2}get area(){return this.width*this.height}intersects(t){return this.area<=0||t.width<=0||t.height<=0?!1:t.x+t.width>this.x&&t.y+t.height>this.y&&t.x=this.width?this.width-1:t}boundY(t){return t=this.height?this.height-1:t}scaleX(t){return this.boundX(Math.floor((t-this.pixelX)/this.pixelGroup))}scaleY(t){return this.boundY(Math.floor((t-this.pixelY)/this.pixelGroup))}scale(t){let r=this.scaleX(t.x),n=this.scaleY(t.y),i=this.boundX(Math.ceil((t.x+t.width-this.pixelX)/this.pixelGroup)),s=this.boundY(Math.ceil((t.y+t.height-this.pixelY)/this.pixelGroup)),a=i-r,l=s-n;return new ve(r,n,a,l)}invertScaleX(t){return Math.round(t*this.pixelGroup+this.pixelX)}invertScaleY(t){return Math.round(t*this.pixelGroup+this.pixelY)}addPadding(t,r){let n=Math.ceil(r/this.pixelGroup),i=this.boundX(t.x-n),s=this.boundY(t.y-n),a=this.boundX(t.x2+n),l=this.boundY(t.y2+n),g=a-i,f=l-s;return new ve(i,s,g,f)}get(t,r){return t<0||r<0||t>=this.width||r>=this.height?Number.NaN:this.area[t+r*this.width]}inc(t,r,n){t<0||r<0||t>=this.width||r>=this.height||(this.area[t+r*this.width]+=n)}set(t,r,n){t<0||r<0||t>=this.width||r>=this.height||(this.area[t+r*this.width]=n)}incArea(t,r){if(t.width<=0||t.height<=0||r===0)return;let n=this.width,i=t.width,s=Math.max(0,t.i),a=Math.max(0,t.j),l=Math.min(t.i+t.width,n),g=Math.min(t.j+t.height,this.height);if(!(g<=0||l<=0||s>=n||g>=this.height))for(let f=a;fMath.min(a,l),Number.POSITIVE_INFINITY),i=this.area.reduce((a,l)=>Math.max(a,l),Number.NEGATIVE_INFINITY),s=a=>(a-n)/(i-n);t.scale(this.pixelGroup,this.pixelGroup);for(let a=0;ar?"black":"white",t.fillRect(i,s,1,1)}t.restore()}}};function es(e,t){let r=n=>({x:n.x-t,y:n.y-t,width:n.width+2*t,height:n.height+2*t});return Array.isArray(e)?e.map(r):r(e)}function Ji(e,t,r){return rs(Object.assign(ts(e),{distSquare:(n,i)=>Hi(e.x1,e.y1,e.x2,e.y2,n,i)}),t,r)}function rs(e,t,r){let n=es(e,r),i=t.scale(n),s=t.createSub(i,n);return jf(s,t,r,(a,l)=>e.distSquare(a,l)),s}function jf(e,t,r,n){let i=r*r;for(let s=0;s{let l=i.slice(0,a);return Rf(t,s,l,r,n)}).flat()}function Rf(e,t,r,n,i){let s=Gt(t.cx,t.cy),a=Of(s,r,e);if(a==null)return[];let l=new oe(s.x,s.y,a.cx,a.cy),g=Tf(l,e,n,i);return Mf(g,e)}function Tf(e,t,r,n){let i=[],s=[];s.push(e);let a=!0;for(let l=0;l0;){let g=s.pop(),f=za(t,g),p=f?kf(g,f):null;if(!f||!p||p.count!==2){a||i.push(g);continue}let y=n,w=ii(f,y,p,!0),E=fr(w,s)||fr(w,i),A=ni(w,t);for(;!E&&A&&y>=1;)y/=1.5,w=ii(f,y,p,!0),E=fr(w,s)||fr(w,i),A=ni(w,t);if(w&&!E&&!A&&(s.push(new oe(g.x1,g.y1,w.x,w.y)),s.push(new oe(w.x,w.y,g.x2,g.y2)),a=!0),a)continue;y=n,w=ii(f,y,p,!1);let I=fr(w,s)||fr(w,i);for(A=ni(w,t);!I&&A&&y>=1;)y/=1.5,w=ii(f,y,p,!1),I=fr(w,s)||fr(w,i),A=ni(w,t);w&&!I&&(s.push(new oe(g.x1,g.y1,w.x,w.y)),s.push(new oe(w.x,w.y,g.x2,g.y2)),a=!0),a||i.push(g)}for(;s.length>0;)i.push(s.pop());return i}function Mf(e,t){let r=[];for(;e.length>0;){let n=e.pop();if(e.length===0){r.push(n);break}let i=e.pop(),s=new oe(n.x1,n.y1,i.x2,i.y2);za(t,s)?(r.push(n),e.push(i)):e.push(s)}return r}function Of(e,t,r){let n=Number.POSITIVE_INFINITY;return t.reduce((i,s)=>{let a=dr(e.x,e.y,s.cx,s.cy);if(a>n)return i;let l=new oe(e.x,e.y,s.cx,s.cy),g=$f(r,l);return a*(g+1)*(g+1){t+=n.cx,r+=n.cy}),t/=e.length,r/=e.length,e.map(n=>{let i=t-n.cx,s=r-n.cy,a=i*i+s*s;return[n,a]}).sort((n,i)=>n[1]-i[1]).map(n=>n[0])}function ni(e,t){return t.some(r=>r.containsPt(e.x,e.y))}function fr(e,t){return t.some(r=>!!(_a(r.x1,r.y1,e.x,e.y,.001)||_a(r.x2,r.y2,e.x,e.y,.001)))}function za(e,t){let r=Number.POSITIVE_INFINITY,n=null;for(let i of e){if(!Ma(i,t))continue;let s=If(i,t);s>=0&&sMa(n,t)&&Df(n,t)?r+1:r,0)}function ii(e,t,r,n){let i=r.top,s=r.left,a=r.bottom,l=r.right;if(n){if(s.state===Bt.POINT){if(i.state===Bt.POINT)return Gt(e.x-t,e.y-t);if(a.state===Bt.POINT)return Gt(e.x-t,e.y2+t);let w=e.width*e.height;return e.width*((s.y-e.y+(l.y-e.y))*.5)l.y?Gt(e.x-t,e.y-t):Gt(e.x2+t,e.y-t):s.ya.x?Gt(e.x-t,e.y-t):Gt(e.x-t,e.y2+t):i.xl.y?Gt(e.x2+t,e.y2+t):Gt(e.x-t,e.y2+t):s.ya.x?Gt(e.x2+t,e.y2+t):Gt(e.x2+t,e.y-t):i.xn)return!1}return!0}function Pf(e=0){return t=>{if(e<0||t.length<3)return t;let r=[],n=0,i=e*e;for(;n{if(a.length<3)return a;let l=[],g=a.closed,f=a.length+3-1+(g?0:2);l.push(s(a,2-(g?0:2),0));for(let p=2-(g?0:2);p{let r=e,n=t.length;if(r>1)for(n=Math.floor(t.length/r);n<3&&r>1;)r-=1,n=Math.floor(t.length/r);let i=[];for(let s=0,a=0;a=n?this.closed?this.get(t-n):this.points[n-1]:this.points[r]}get length(){return this.points.length}toString(t=1/0){let r=this.points;if(r.length===0)return"";let n=typeof t=="function"?t:Af(t),i="M";for(let s of r)i+=`${n(s.x)},${n(s.y)} L`;return i=i.slice(0,-1),this.closed&&(i+=" Z"),i}draw(t){let r=this.points;if(r.length!==0){t.beginPath(),t.moveTo(r[0].x,r[0].y);for(let n of r)t.lineTo(n.x,n.y);this.closed&&t.closePath()}}sample(t){return Ff(t)(this)}simplify(t){return Pf(t)(this)}bSplines(t){return Wf(t)(this)}apply(t){return t(this)}containsElements(t){let r=Oa(this.points);return r?t.every(n=>r.containsPt(n.cx,n.cy)&&this.withinArea(n.cx,n.cy)):!1}withinArea(t,r){if(this.length===0)return!1;let n=0,i=this.points[0],s=new oe(i.x,i.y,i.x,i.y);for(let a=1;at?p+y:p}function s(g,f){let p=cn;return p=i(g,f,p,1),p=i(g+1,f,p,2),p=i(g,f+1,p,4),p=i(g+1,f+1,p,8),Number.isNaN(p)?-1:p}let a=si;function l(g,f){let p=g,y=f,w=e.invertScaleX(p),E=e.invertScaleY(y);for(let A=0;ARa(n.raw,t));return r<0?!1:(this.members.splice(r,1),this.dirty.add(We.MEMBERS),!0)}removeNonMember(t){let r=this.nonMembers.findIndex(n=>Ra(n.raw,t));return r<0?!1:(this.nonMembers.splice(r,1),this.dirty.add(We.NON_MEMBERS),!0)}removeEdge(t){let r=this.edges.findIndex(n=>n.obj.equals(t));return r<0?!1:(this.edges.splice(r,1),this.dirty.add(We.NON_MEMBERS),!0)}pushNonMember(...t){if(t.length!==0){this.dirty.add(We.NON_MEMBERS);for(let r of t)this.nonMembers.push({raw:r,obj:fn(r)?dn.from(r):ve.from(r),area:null})}}pushEdge(...t){if(t.length!==0){this.dirty.add(We.EDGES);for(let r of t)this.edges.push({raw:r,obj:oe.from(r),area:null})}}update(){let t=this.dirty.has(We.MEMBERS),r=this.dirty.has(We.NON_MEMBERS),n=this.dirty.has(We.EDGES);this.dirty.clear();let i=this.members.map(f=>f.obj);if(this.o.virtualEdges&&(t||r)){let f=this.nonMembers.map(w=>w.obj),p=$a(i,f,this.o.maxRoutingIterations,this.o.morphBuffer),y=new Map(this.virtualEdges.map(w=>[w.obj.toString(),w.area]));this.virtualEdges=p.map(w=>{var E;return{raw:w,obj:w,area:(E=y.get(w.toString()))!==null&&E!==void 0?E:null}}),n=!0}let s=!1;if(t||n){let f=this.virtualEdges.concat(this.edges).map(E=>E.obj),p=Na(i,f),y=Math.max(this.o.edgeR1,this.o.nodeR1)+this.o.morphBuffer,w=ve.from(es(p,y));w.equals(this.activeRegion)||(s=!0,this.activeRegion=w)}if(s){let f=Math.ceil(this.activeRegion.width/this.o.pixelGroup),p=Math.ceil(this.activeRegion.height/this.o.pixelGroup);this.activeRegion.x!==this.potentialArea.pixelX||this.activeRegion.y!==this.potentialArea.pixelY?(this.potentialArea=Ur.fromPixelRegion(this.activeRegion,this.o.pixelGroup),this.members.forEach(y=>y.area=null),this.nonMembers.forEach(y=>y.area=null),this.edges.forEach(y=>y.area=null),this.virtualEdges.forEach(y=>y.area=null)):(f!==this.potentialArea.width||p!==this.potentialArea.height)&&(this.potentialArea=Ur.fromPixelRegion(this.activeRegion,this.o.pixelGroup))}let a=new Map,l=f=>{if(f.area){let p=`${f.obj.width}x${f.obj.height}x${f.obj instanceof ve?"R":"C"}`;a.set(p,f.area)}},g=f=>{if(f.area)return;let p=`${f.obj.width}x${f.obj.height}x${f.obj instanceof ve?"R":"C"}`;if(a.has(p)){let w=a.get(p);f.area=this.potentialArea.copy(w,{x:f.obj.x-this.o.nodeR1,y:f.obj.y-this.o.nodeR1});return}let y=f.obj instanceof ve?Ga(f.obj,this.potentialArea,this.o.nodeR1):rs(f.obj,this.potentialArea,this.o.nodeR1);f.area=y,a.set(p,y)};this.members.forEach(l),this.nonMembers.forEach(l),this.members.forEach(g),this.nonMembers.forEach(f=>{this.activeRegion.intersects(f.obj)?g(f):f.area=null}),this.edges.forEach(f=>{f.area||(f.area=Ji(f.obj,this.potentialArea,this.o.edgeR1))}),this.virtualEdges.forEach(f=>{f.area||(f.area=Ji(f.obj,this.potentialArea,this.o.edgeR1))})}drawMembers(t){for(let r of this.members)r.obj.draw(t)}drawNonMembers(t){for(let r of this.nonMembers)r.obj.draw(t)}drawEdges(t){for(let r of this.edges)r.obj.draw(t)}drawPotentialArea(t,r=!0){this.potentialArea.draw(t,r)}compute(){if(this.members.length===0)return new Ke([]);this.dirty.size>0&&this.update();let{o:t,potentialArea:r}=this,n=this.members.map(l=>l.area),i=this.virtualEdges.concat(this.edges).map(l=>l.area),s=this.nonMembers.filter(l=>l.area!=null).map(l=>l.area),a=this.members.map(l=>l.obj);return Pa(r,n,i,s,l=>l.containsElements(a),t)}};function Pa(e,t,r,n,i,s={}){let a=Object.assign({},ns,s),l=a.threshold,g=a.memberInfluenceFactor,f=a.edgeInfluenceFactor,p=a.nonMemberInfluenceFactor,y=(a.nodeR0-a.nodeR1)*(a.nodeR0-a.nodeR1),w=(a.edgeR0-a.edgeR1)*(a.edgeR0-a.edgeR1);for(let E=0;E0)p*=.8;else break}return new Ke([])}function Na(e,t){if(e.length===0)return new ve(0,0,0,0);let r=ve.from(e[0]);for(let n of e)r.add(n);for(let n of t)r.add(ts(n));return r}function Uf(e,t=[],r=[],n={}){if(e.length===0)return new Ke([]);let i=new ui(n);return i.pushMember(...e),i.pushNonMember(...t),i.pushEdge(...r),i.compute()}var jg=xe(Ba(),1),Cg=xe(mu(),1),Lg=xe(Du(),1),_g=xe(Cu(),1),Rg=xe(Tu(),1),Tg=xe(Gu(),1),Mg=xe(Yu(),1),Og=xe(eh(),1),Gg=xe(Eh(),1);var export_FA2Layout=Ig.default;var export_betweennessCentrality=Cg.default;var export_circlepack=vi.circlepack;var export_circular=vi.circular;var export_closenessCentrality=Lg.default;var export_degreeCentrality=jg.degreeCentrality;var export_density=Tg.density;var export_diameter=Mg.default;var export_eigenvectorCentrality=_g.default;var export_forceAtlas2=Dg.default;var export_louvain=Gg.default;var export_modularity=Og.default;var export_noverlap=kg.default;var export_pagerank=Rg.default;var export_random=vi.random;var export_rotation=vi.rotation;export{Qn as ConcentricLayout,export_FA2Layout as FA2Layout,Mt as Graph,ti as MDSLayout,ei as RadialLayout,export_betweennessCentrality as betweennessCentrality,Wa as bubblesets,export_circlepack as circlepack,export_circular as circular,export_closenessCentrality as closenessCentrality,export_degreeCentrality as degreeCentrality,export_density as density,export_diameter as diameter,export_eigenvectorCentrality as eigenvectorCentrality,export_forceAtlas2 as forceAtlas2,export_louvain as louvain,export_modularity as modularity,export_noverlap as noverlap,export_pagerank as pagerank,export_random as random,export_rotation as rotation}; /*! Bundled license information: comlink/dist/esm/comlink.js: diff --git a/src/package/vendor_entry_graphology.mjs b/src/package/vendor_entry_graphology.mjs index 3aa4103..a9402df 100644 --- a/src/package/vendor_entry_graphology.mjs +++ b/src/package/vendor_entry_graphology.mjs @@ -9,6 +9,9 @@ export {default as forceAtlas2} from 'graphology-layout-forceatlas2'; // Worker supervisor (live FA2 animation). Node-safe at module scope: it only // touches Worker/window.URL when instantiated, never at import time. export {default as FA2Layout} from 'graphology-layout-forceatlas2/worker'; +// Anti-collision post-pass. Node-safe at module scope: the worker helper in +// the package only touches window/Worker when called, and we never call it. +export {default as noverlap} from 'graphology-layout-noverlap'; export {RadialLayout, ConcentricLayout, MDSLayout} from '@antv/layout'; export * as bubblesets from 'bubblesets-js'; // Network metrics (graphology-metrics; pure JS, node-safe). Subpath imports diff --git a/src/package/vendor_libs.js b/src/package/vendor_libs.js index 14472eb..d6bb47c 100644 --- a/src/package/vendor_libs.js +++ b/src/package/vendor_libs.js @@ -58,7 +58,7 @@ const bundles = [ { entry: path.join(__dirname, 'vendor_entry_graphology.mjs'), out: path.join(libDir, 'graphology.bundle.mjs'), - pkgs: ['graphology', 'graphology-layout', 'graphology-layout-forceatlas2', 'graphology-metrics', 'graphology-communities-louvain', '@antv/layout', 'bubblesets-js'], + pkgs: ['graphology', 'graphology-layout', 'graphology-layout-forceatlas2', 'graphology-layout-noverlap', 'graphology-metrics', 'graphology-communities-louvain', '@antv/layout', 'bubblesets-js'], }, { entry: path.join(__dirname, 'vendor_entry_sigma.mjs'), diff --git a/tests/layout-algorithms.test.js b/tests/layout-algorithms.test.js index 0e44628..5d6dc5b 100644 --- a/tests/layout-algorithms.test.js +++ b/tests/layout-algorithms.test.js @@ -1,6 +1,6 @@ import { describe, it, expect, vi, afterEach } from "vitest"; import { Graph, forceAtlas2 } from "../src/lib/graphology.bundle.mjs"; -import { executeLayout } from "../src/graph/layout_algorithms.js"; +import { applyNoverlap, executeLayout } from "../src/graph/layout_algorithms.js"; import { DEFAULTS } from "../src/config.js"; // ========================================================================== @@ -277,6 +277,125 @@ describe("executeLayout — force worker supervisor (browser path)", () => { }); }); +describe("noverlap post-pass (spec.noverlap)", () => { + const NOVERLAP_MARGIN = 5; // mirrors layout_algorithms.js + + /** Two nodes whose grid cells (100 px apart) leave them visually overlapping. */ + function overlappingPairGraph(size = 80) { + const graph = new Graph(); + graph.addNode("a", { x: 0, y: 0, size }); + graph.addNode("b", { x: 1, y: 1, size }); + graph.addEdge("a", "b"); + return graph; + } + + function pairDistance(graph) { + const a = graph.getNodeAttributes("a"); + const b = graph.getNodeAttributes("b"); + return distance(a, b); + } + + it("separates two perfectly overlapping nodes by ≥ combined size + margin", () => { + // Arrange: identical coordinates — the jitter branch of the algorithm. + const graph = new Graph(); + graph.addNode("a", { x: 50, y: 50, size: 10 }); + graph.addNode("b", { x: 50, y: 50, size: 10 }); + + // Act + applyNoverlap(graph); + + // Assert + expect(pairDistance(graph)).toBeGreaterThanOrEqual(10 + 10 + NOVERLAP_MARGIN); + }); + + it.each([false, undefined])("noverlap: %s leaves base-layout positions untouched", async (flag) => { + // Arrange: oversized nodes on the 100-px grid lattice WOULD overlap. + const graph = overlappingPairGraph(); + + // Act + await executeLayout(graph, { ...specFor("grid"), noverlap: flag }); + + // Assert: exact lattice coordinates — no post-pass displacement. + graph.forEachNode((_id, attrs) => { + expect(attrs.x % 100).toBe(0); + expect(attrs.y % 100).toBe(0); + }); + }); + + it.each(["grid", "circular"])("after %s: no node pair remains overlapping", async (type) => { + // Arrange: 8 size-80 nodes — the 100-px grid lattice and the circular + // ring gap (~76 px) both undercut the 80+80+margin clearance required. + const graph = new Graph(); + for (let i = 0; i < 8; i++) graph.addNode(`n${i}`, { x: i, y: -i, size: 80 }); + + // Act + await executeLayout(graph, { ...specFor(type), noverlap: true }); + + // Assert: every pair is clear of its combined radii + margin. + const pts = positions(graph); + const pairDistances = pts.flatMap((p, i) => pts.slice(i + 1).map((q) => distance(p, q))); + expect(Math.min(...pairDistances)).toBeGreaterThanOrEqual(80 + 80 + NOVERLAP_MARGIN); + }); + + it("runs after the animated-force (worker supervisor) path", async () => { + // Arrange: a supervisor that never moves nodes isolates the post-pass. + vi.useFakeTimers(); + const graph = overlappingPairGraph(10); + class InertSupervisor { + start() {} + stop() {} + kill() {} + } + + // Act: 2-node budget = min(5000, 500 + 2*2) = 504 ms. + const pending = executeLayout(graph, { ...specFor("force"), noverlap: true }, { + ForceSupervisor: InertSupervisor, + }); + await vi.advanceTimersByTimeAsync(504); + await pending; + vi.useRealTimers(); + + // Assert + expect(pairDistance(graph)).toBeGreaterThanOrEqual(10 + 10 + NOVERLAP_MARGIN); + }); + + it("respects node size: bigger nodes are pushed further apart", () => { + // Arrange: identical geometry, only the size attribute differs. + const makePair = (size) => { + const graph = new Graph(); + graph.addNode("a", { x: 0, y: 0, size }); + graph.addNode("b", { x: 1, y: 0, size }); + return graph; + }; + const small = makePair(5); + const big = makePair(20); + + // Act + applyNoverlap(small); + applyNoverlap(big); + + // Assert + expect(pairDistance(small)).toBeGreaterThanOrEqual(5 + 5 + NOVERLAP_MARGIN); + expect(pairDistance(big)).toBeGreaterThanOrEqual(20 + 20 + NOVERLAP_MARGIN); + expect(pairDistance(big)).toBeGreaterThan(pairDistance(small)); + }); + + it("empty and single-node graphs are no-ops", () => { + // Arrange + const empty = new Graph(); + const single = new Graph(); + single.addNode("only", { x: 7, y: 9, size: 12 }); + + // Act + applyNoverlap(empty); + applyNoverlap(single); + + // Assert + expect(empty.order).toBe(0); + expect(single.getNodeAttributes("only")).toMatchObject({ x: 7, y: 9 }); + }); +}); + describe("executeLayout — edge cases", () => { it.each(LAYOUT_TYPES)("%s: empty graph is a no-op", async (type) => { // Arrange diff --git a/tests/layout-selected-nodes.test.js b/tests/layout-selected-nodes.test.js index 1f3015e..8f69f96 100644 --- a/tests/layout-selected-nodes.test.js +++ b/tests/layout-selected-nodes.test.js @@ -1,4 +1,5 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; +import { Graph } from "../src/lib/graphology.bundle.mjs"; // ========================================================================== // Regression: Arrange Selection actions must push the mutated node positions @@ -114,3 +115,67 @@ describe("layoutSelectedNodes — syncs positions to the graph", () => { expect(cache.gcm.decideToRenderOrDraw).not.toHaveBeenCalled(); }); }); + +describe("removeNodeOverlaps — noverlap on the live graphology model", () => { + let cache, lm; + + /** Mirror the adapter: getNodeData syncs nodeRef styles from graphology. */ + function wireGraphData(nodes, graphData) { + cache.graphData = graphData; + cache.graph.getNodeData = async () => { + for (const node of nodes) { + const attrs = graphData.getNodeAttributes(node.id); + node.style.x = attrs.x; + node.style.y = attrs.y; + } + return nodes; + }; + } + + beforeEach(() => { + cache = createMockCache([makeNode("a", 0, 0), makeNode("b", 0, 0)]); + lm = new GraphLayoutManager(cache); + }); + + it("separates overlapping nodes, persists positions and redraws", async () => { + // Arrange: two same-spot nodes on the live graphology instance. + const graphData = new Graph(); + graphData.addNode("a", { x: 0, y: 0, size: 10 }); + graphData.addNode("b", { x: 0, y: 0, size: 10 }); + wireGraphData([...cache.nodeRef.values()], graphData); + + // Act + await lm.removeNodeOverlaps(); + + // Assert: graphology positions separated by ≥ combined size + margin. + const a = graphData.getNodeAttributes("a"); + const b = graphData.getNodeAttributes("b"); + expect(Math.hypot(a.x - b.x, a.y - b.y)).toBeGreaterThanOrEqual(10 + 10 + 5); + + // Moved positions are persisted to the active layout's position map. + const stored = cache.data.layouts.default.positions; + expect(stored.get("a").style).toEqual({ x: a.x, y: a.y }); + expect(stored.get("b").style).toEqual({ x: b.x, y: b.y }); + + // And the standard layout-change pipeline ran. + expect(cache.gcm.decideToRenderOrDraw).toHaveBeenCalledTimes(1); + expect(cache.layoutChanged).toBe(true); + }); + + it("is a no-op without a graph model or with fewer than two nodes", async () => { + // Arrange + Act: no graphData at all. + cache.graphData = null; + await lm.removeNodeOverlaps(); + + // Arrange + Act: single-node graph. + const single = new Graph(); + single.addNode("a", { x: 3, y: 4, size: 10 }); + wireGraphData([cache.nodeRef.get("a")], single); + await lm.removeNodeOverlaps(); + + // Assert: untouched position, no persist, no redraw. + expect(single.getNodeAttributes("a")).toMatchObject({ x: 3, y: 4 }); + expect(cache.data.layouts.default.positions.size).toBe(0); + expect(cache.gcm.decideToRenderOrDraw).not.toHaveBeenCalled(); + }); +}); From fb9f74c0c58f79a253a3713f4db0dd9aecbf1bf3 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 08:29:08 +0200 Subject: [PATCH 17/69] feat(renderer): GLSL borders for circles via @sigma/node-border MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add @sigma/node-border@3.0.0 to the browser-only sigma vendor bundle - bordered circles render through a new borderCircle program (outer ring reads borderColor + relative borderRatio = min(lineWidth/radius, 1), inner fill ring consumes the rest) — crisp at all zooms, no texture atlas churn; non-circle shapes and bordered rects stay on the SVG texture program - nodeProgramAttributes is now a three-branch dispatch (texture / borderCircle / native) where every branch writes the full merge-hygiene attr set; native branch unconditionally clears borderColor/borderSize so lineWidth-only deltas can't leak a stale stroke into halo textures (review fix) - selection halos deliberately stay on the texture path for all shapes: a GLSL halo would duplicate the halo implementation for circles only and expand the state/program matrix; dim on bordered circles now takes the cheap native branch - no hover guard needed (program has no instance drawHover → falls through to guarded drawDiscNodeHover); PNG export inherits the program registry via sigma.getSettings() - 13 new attribute-level tests incl. 6-case transition merge matrix (877 total green); perf gates green --- package-lock.json | 10 ++ package.json | 1 + src/graph/graph_model.js | 58 +++++++-- src/graph/sigma_adapter.js | 21 +++- src/lib/sigma.bundle.mjs | 156 +++++++++++++++++++---- src/package/vendor_entry_sigma.mjs | 1 + src/package/vendor_libs.js | 2 +- tests/graph-model.test.js | 193 ++++++++++++++++++++++++++++- 8 files changed, 400 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac8f193..1213587 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@antv/layout": "^2.0.0", "@sigma/edge-curve": "^3.1.0", "@sigma/export-image": "^3.0.0", + "@sigma/node-border": "^3.0.0", "@sigma/node-image": "^3.0.0", "@sigma/node-square": "^3.0.0", "bubblesets-js": "^3.0.1", @@ -2062,6 +2063,15 @@ "sigma": ">=3.0.0-beta.10" } }, + "node_modules/@sigma/node-border": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigma/node-border/-/node-border-3.0.0.tgz", + "integrity": "sha512-mE3zUfjvJVuAMhSjiP/zdlkqe0OVTETxd04XHUwof01YqdzTk0OB4ACJIhWrwgsBXl7tTd9lPuKoroafLh8MtQ==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.17" + } + }, "node_modules/@sigma/node-image": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sigma/node-image/-/node-image-3.0.0.tgz", diff --git a/package.json b/package.json index 49fa4c9..940621b 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "@antv/layout": "^2.0.0", "@sigma/edge-curve": "^3.1.0", "@sigma/export-image": "^3.0.0", + "@sigma/node-border": "^3.0.0", "@sigma/node-image": "^3.0.0", "@sigma/node-square": "^3.0.0", "bubblesets-js": "^3.0.1", diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index 10a7caf..ef49305 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -34,9 +34,10 @@ function flipY(y) { * Map a G6 node style + type to sigma node attributes. * Only emits keys that are actually present on the style; shape-program * attributes (`type`/`shape`/`image`/...) are only emitted when `type` is - * given. Shapes without a native sigma program — and any shape with a - * border, which the native circle/square programs cannot draw — render - * through the SVG texture program ("shape"). + * given. Shapes without a native sigma program — and any non-circle shape + * with a border, which the native circle/square programs cannot draw — + * render through the SVG texture program ("shape"); bordered circles render + * through the @sigma/node-border GLSL program ("borderCircle"). * * @param {object} style G6 node style ({x, y, size, fill, stroke, lineWidth, label*, visibility, ...}) * @param {string} [type] G6 node type (circle|diamond|hexagon|rect|triangle|star) @@ -93,16 +94,28 @@ function badgeAttributes(style) { /** * Shape-program attributes for a node: which sigma program draws it, plus * the texture data-URI when the SVG shape program is needed. + * + * Three programs and their attribute sets (the adapter applies updates via + * mergeNodeAttributes, so every branch must overwrite/clear exactly what the + * other branches set — a stale fillColor corrupts state textures on hover, a + * stale TRANSPARENT color makes the node invisible, a stale image would + * matter if the texture program saw it; the image program skips non-string + * images, so null is safe): + * - "shape" texture (fillColor, TRANSPARENT color, image, borderRatio 0) + * - "borderCircle" @sigma/node-border GLSL rings — bordered circles only + * (color=fill, borderRatio, fillColor/image cleared) + * - native circle/square (color=fill, fillColor/image cleared, borderRatio 0) */ function nodeProgramAttributes(style = {}, type) { const fill = style.fill ?? DEFAULTS.NODE.FILL_COLOR; const stroke = style.stroke ?? null; const lineWidth = style.lineWidth ?? 0; const hasBorder = Boolean(stroke) && lineWidth > 0; + const size = Array.isArray(style.size) ? style.size[0] : style.size; + const radius = (size ?? DEFAULTS.NODE.SIZE) / 2; const attrs = { shape: type }; - if (isTextureOnlyShape(type) || hasBorder) { - const size = Array.isArray(style.size) ? style.size[0] : style.size; + if (isTextureOnlyShape(type) || (hasBorder && type !== "circle")) { attrs.type = "shape"; attrs.fillColor = fill; attrs.color = TRANSPARENT; @@ -111,18 +124,33 @@ function nodeProgramAttributes(style = {}, type) { fill, stroke: hasBorder ? stroke : null, lineWidth: hasBorder ? lineWidth : 0, - size: (size ?? DEFAULTS.NODE.SIZE) / 2, + size: radius, }); + attrs.borderRatio = 0; + } else if (hasBorder) { + // Bordered circle: the node-border program draws border + fill as GLSL + // rings (crisp at all zooms, no texture atlas churn). The border ring is + // a fraction of the radius so it scales with zoom exactly like the baked + // textures (and G6) did. State halos still go through the texture path — + // applyNodeState reads fillColor ?? color / borderColor / borderSize, + // all coherent here. + attrs.type = "borderCircle"; + attrs.color = fill; + attrs.fillColor = null; + attrs.image = null; + attrs.borderRatio = radius > 0 ? Math.min(lineWidth / radius, 1) : 1; } else { attrs.type = type === "rect" ? "square" : "circle"; - // Texture→native transitions (e.g. border removed) merge over the old - // attrs, so clear exactly what the shape branch sets: a stale fillColor - // corrupts state textures on hover and a stale TRANSPARENT color makes - // the node invisible. The image program skips non-string images, so - // null is safe. attrs.color = fill; attrs.fillColor = null; attrs.image = null; + attrs.borderRatio = 0; + // Unconditionally clear border attrs: a style delta that drops the border + // without an explicit stroke key (e.g. {lineWidth: 0} on the no-nodeRef + // fallback path) would otherwise leave a stale borderColor in graphology, + // which applyNodeState bakes into halo textures. + attrs.borderColor = null; + attrs.borderSize = 0; } return attrs; } @@ -249,7 +277,13 @@ function buildGraphologyGraph(cache) { * dim → dim fill * Halo states render through the texture program (the only sigma mechanism * that draws a ring around non-circular shapes); the node grows by - * HALO_EXTRA_PX so the halo bleeds outward like G6's did. + * HALO_EXTRA_PX so the halo bleeds outward like G6's did. Halos stay on the + * texture path for ALL shapes — including borderCircle nodes — so there is a + * single halo implementation; a node-border halo ring for circles would have + * to visually match the SVG halo on the other five shapes forever. This works + * unchanged for borderCircle data because its branch keeps fillColor ?? color, + * borderColor and borderSize coherent (reducers never write to graphology, so + * the transient type switch needs no merge hygiene). */ function applyNodeState(data, state) { const res = { ...data }; diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 8828a1d..3876aef 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -17,6 +17,7 @@ import { createEdgeCompoundProgram, drawDiscNodeHover, NodeSquareProgram, + createNodeBorderProgram, nodeImage, edgeCurve, } from "../lib/sigma.bundle.mjs"; @@ -60,8 +61,9 @@ function guardHoverDrawer(drawer, getDraggedNode) { /** * Node/edge program registry (G6 type vocabulary → sigma programs). - * Nodes: circle native, square via @sigma/node-square; every other shape — - * and any bordered/haloed node — uses the SVG texture program ("shape"). + * Nodes: circle native, square via @sigma/node-square, bordered circles via + * @sigma/node-border ("borderCircle"); every other shape — and any bordered + * non-circle or haloed node — uses the SVG texture program ("shape"). * Edges: straight programs are sigma built-ins; curved ones come from * @sigma/edge-curve (cubic/quadratic/polyline all map to one curve type). * @@ -101,6 +103,20 @@ function buildProgramRegistry(getDraggedNode) { this.drawHover = guardHoverDrawer(this.drawHover, getDraggedNode); } } + // Bordered circles: outer ring reads borderColor/borderRatio (graph_model + // emits borderRatio = lineWidth / radius so the border scales with zoom + // like the baked textures did), the rest is filled with the node color. + // No hover guard needed: the program leaves its instance drawHover + // undefined, so sigma falls back to the guarded defaultDrawNodeHover. + const borderCircleProgram = createNodeBorderProgram({ + borders: [ + { + size: { attribute: "borderRatio", defaultValue: 0, mode: "relative" }, + color: { attribute: "borderColor" }, + }, + { size: { fill: true }, color: { attribute: "color" } }, + ], + }); const curveOptions = (extremity) => ({ arrowHead: extremity ? { ...edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS.arrowHead, extremity } @@ -111,6 +127,7 @@ function buildProgramRegistry(getDraggedNode) { nodeProgramClasses: { square: GuardedSquareProgram, shape: shapeProgram, + borderCircle: borderCircleProgram, }, edgeProgramClasses: { line: EdgeRectangleProgram, diff --git a/src/lib/sigma.bundle.mjs b/src/lib/sigma.bundle.mjs index a8e4170..c8c4771 100644 --- a/src/lib/sigma.bundle.mjs +++ b/src/lib/sigma.bundle.mjs @@ -1,8 +1,8 @@ -var ii=Object.create;var ft=Object.defineProperty;var ai=Object.getOwnPropertyDescriptor;var oi=Object.getOwnPropertyNames;var si=Object.getPrototypeOf,ui=Object.prototype.hasOwnProperty;var vt=(t,r)=>()=>(r||t((r={exports:{}}).exports,r),r.exports),gt=(t,r)=>{for(var n in r)ft(t,n,{get:r[n],enumerable:!0})},li=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oi(r))!ui.call(t,i)&&i!==n&&ft(t,i,{get:()=>r[i],enumerable:!(e=ai(r,i))||e.enumerable});return t};var fe=(t,r,n)=>(n=t!=null?ii(si(t)):{},li(r||!t||!t.__esModule?ft(n,"default",{value:t,enumerable:!0}):n,t));var $e=vt((Uo,St)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,kr=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ye;we&&typeof we.ownKeys=="function"?Ye=we.ownKeys:Object.getOwnPropertySymbols?Ye=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ye=function(r){return Object.getOwnPropertyNames(r)};function Mi(t){console&&console.warn&&console.warn(t)}var Or=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}St.exports=B;St.exports.once=ji;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var Nr=10;function qe(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return Nr},set:function(t){if(typeof t!="number"||t<0||Or(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");Nr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Or(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Dr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Dr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")kr(u,this,n);else for(var l=u.length,c=Mr(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,Mi(s)}return t}B.prototype.addListener=function(r,n){return Fr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Fr(this,r,n,!0)};function Ui(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Ir(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=Ui.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return qe(n),this.on(r,Ir(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return qe(n),this.prependListener(r,Ir(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(qe(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():Bi(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function zr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?Hi(i):Mr(i,i.length)}B.prototype.listeners=function(r){return zr(this,r,!0)};B.prototype.rawListeners=function(r){return zr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):Gr.call(t,r)};B.prototype.listenerCount=Gr;function Gr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ye(this._events):[]};function Mr(t,r){for(var n=new Array(r),e=0;e{Hr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var qn=vt((Jt,er)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof Jt<"u"?r():(r(),t.FileSaver={})})(Jt,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,f=document.createElement("a");u=u||s.name||"download",f.download=u,f.rel="noopener",typeof s=="string"?(f.href=s,f.origin===location.origin?e(f):n(f.href)?r(s,u,l):e(f,f.target="_blank")):(f.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(f.href)},4e4),setTimeout(function(){e(f)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var f=s.type==="application/octet-stream",m=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||f&&m||a)&&typeof FileReader<"u"){var E=new FileReader;E.onloadend=function(){var _=E.result;_=y?_:_.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=_:location=_,c=null},E.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof er<"u"&&(er.exports=o)})});function ci(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ge(t){var r=ci(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function lr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>>16,n=(t&65280)>>>8,e=t&255,i=255,a=_t(r,n,e,i,!0);return yt[t]=a,a}function Me(t,r,n,e){return n+(r<<8)+(t<<16)}function Ue(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ue(u,4),c=l[0],f=l[1],m=l[2],y=l[3];return[c,f,m,y]}function x(t,r,n){return(r=ge(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function fr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function L(t){for(var r=1;r()=>(r||t((r={exports:{}}).exports,r),r.exports),_t=(t,r)=>{for(var n in r)yt(t,n,{get:r[n],enumerable:!0})},Ai=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of xi(r))!Si.call(t,i)&&i!==n&&yt(t,i,{get:()=>r[i],enumerable:!(e=wi(r,i))||e.enumerable});return t};var ve=(t,r,n)=>(n=t!=null?Ri(Ci(t)):{},Ai(r||!t||!t.__esModule?yt(n,"default",{value:t,enumerable:!0}):n,t));var Qe=bt((Ts,Nt)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,Br=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ke;we&&typeof we.ownKeys=="function"?Ke=we.ownKeys:Object.getOwnPropertySymbols?Ke=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ke=function(r){return Object.getOwnPropertyNames(r)};function na(t){console&&console.warn&&console.warn(t)}var Hr=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}Nt.exports=B;Nt.exports.once=sa;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var jr=10;function Ze(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return jr},set:function(t){if(typeof t!="number"||t<0||Hr(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");jr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Hr(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Vr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Vr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")Br(u,this,n);else for(var l=u.length,c=$r(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,na(s)}return t}B.prototype.addListener=function(r,n){return Wr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Wr(this,r,n,!0)};function ia(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Xr(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=ia.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return Ze(n),this.on(r,Xr(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return Ze(n),this.prependListener(r,Xr(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(Ze(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():aa(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function Yr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?oa(i):$r(i,i.length)}B.prototype.listeners=function(r){return Yr(this,r,!0)};B.prototype.rawListeners=function(r){return Yr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):qr.call(t,r)};B.prototype.listenerCount=qr;function qr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ke(this._events):[]};function $r(t,r){for(var n=new Array(r),e=0;e{Qr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var di=bt((ur,lr)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof ur<"u"?r():(r(),t.FileSaver={})})(ur,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,h=document.createElement("a");u=u||s.name||"download",h.download=u,h.rel="noopener",typeof s=="string"?(h.href=s,h.origin===location.origin?e(h):n(h.href)?r(s,u,l):e(h,h.target="_blank")):(h.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(h.href)},4e4),setTimeout(function(){e(h)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var h=s.type==="application/octet-stream",v=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||h&&v||a)&&typeof FileReader<"u"){var _=new FileReader;_.onloadend=function(){var E=_.result;E=y?E:E.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=E:location=E,c=null},_.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof lr<"u"&&(lr.exports=o)})});function Li(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function me(t){var r=Li(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function yr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>8&255,a=n>>16&255,o=n>>24&255;return[e,i,a,o]}var Tt={};function Ue(t){if(typeof Tt[t]<"u")return Tt[t];var r=(t&16711680)>>>16,n=(t&65280)>>>8,e=t&255,i=255,a=wt(r,n,e,i,!0);return Tt[t]=a,a}function Be(t,r,n,e){return n+(r<<8)+(t<<16)}function je(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=le(u,4),c=l[0],h=l[1],v=l[2],y=l[3];return[c,h,v,y]}function x(t,r,n){return(r=me(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Rr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function P(t){for(var r=1;rw){var P="\u2026";for(l=l+P,k=t.measureText(l).width;k>w&&l.length>1;)l=l.slice(0,-2)+P,k=t.measureText(l).width;if(l.length<4)return}var C;b>0?g>0?C=Math.acos(b/w):C=Math.asin(g/w):g>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,_),t.rotate(C),t.fillText(l,-k/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function je(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,f=Math.asin(l/2/c),m=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+m,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+m,r.y-l/2),t.arc(r.x,r.y,c,f,-f),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Ei=` +`).concat(n))}return i}function Nr(t,r){return Or("VERTEX",t,r)}function kr(t,r){return Or("FRAGMENT",t,r)}function Dr(t,r){var n=t.createProgram();if(n===null)throw new Error("loadProgram: error while creating the program.");var e,i;for(e=0,i=r.length;ew){var A="\u2026";for(l=l+A,O=t.measureText(l).width;O>w&&l.length>1;)l=l.slice(0,-2)+A,O=t.measureText(l).width;if(l.length<4)return}var C;b>0?m>0?C=Math.acos(b/w):C=Math.asin(m/w):m>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,E),t.rotate(C),t.fillText(l,-O/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function Xe(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,h=Math.asin(l/2/c),v=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+v,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+v,r.y-l/2),t.arc(r.x,r.y,c,h,-h),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Mi=` precision highp float; varying vec4 v_color; @@ -34,7 +34,7 @@ void main(void) { gl_FragColor = mix(v_color, transparent, t); #endif } -`,Ti=Ei,Ri=` +`,Ui=Mi,Bi=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_position; @@ -75,7 +75,7 @@ void main() { v_color.a *= bias; } -`,wi=Ri,xr=WebGLRenderingContext,gr=xr.UNSIGNED_BYTE,Et=xr.FLOAT,xi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:wi,FRAGMENT_SHADER_SOURCE:Ti,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:xi,ATTRIBUTES:[{name:"a_position",size:2,type:Et},{name:"a_size",size:1,type:Et},{name:"a_color",size:4,type:gr,normalized:!0},{name:"a_id",size:4,type:gr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Et}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Q(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(pe);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Ci=` +`,ji=Bi,Fr=WebGLRenderingContext,xr=Fr.UNSIGNED_BYTE,Ct=Fr.FLOAT,Hi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:ji,FRAGMENT_SHADER_SOURCE:Ui,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Hi,ATTRIBUTES:[{name:"a_position",size:2,type:Ct},{name:"a_size",size:1,type:Ct},{name:"a_color",size:4,type:xr,normalized:!0},{name:"a_id",size:4,type:xr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Ct}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Y(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(ie);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Vi=` precision mediump float; varying vec4 v_color; @@ -83,7 +83,7 @@ varying vec4 v_color; void main(void) { gl_FragColor = v_color; } -`,Si=Ci,Ai=` +`,Wi=Vi,Xi=` attribute vec2 a_position; attribute vec2 a_normal; attribute float a_radius; @@ -149,7 +149,7 @@ void main() { v_color.a *= bias; } -`,Li=Ai,Cr=WebGLRenderingContext,mr=Cr.UNSIGNED_BYTE,Be=Cr.FLOAT,Pi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],ce={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function ye(t){var r=L(L({},ce),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Li,FRAGMENT_SHADER_SOURCE:Si,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Pi,ATTRIBUTES:[{name:"a_position",size:2,type:Be},{name:"a_normal",size:2,type:Be},{name:"a_radius",size:1,type:Be},{name:"a_color",size:4,type:mr,normalized:!0},{name:"a_id",size:4,type:mr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:Be}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var f=l.size||1,m=u.size||1,y=s.x,E=s.y,p=u.x,T=u.y,_=Q(l.color),b=p-y,g=T-E,w=b*b+g*g,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-g*w*f,P=b*w*f);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-k,C[o++]=-P,C[o++]=m,C[o++]=_,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,f=u.u_correctionRatio,m=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,E=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(f,a.correctionRatio),s.uniform1f(m,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(E,r.widenessToThicknessRatio)}}])})(le)}var zo=ye();var ki=` +`,Yi=Xi,Ir=WebGLRenderingContext,Cr=Ir.UNSIGNED_BYTE,He=Ir.FLOAT,qi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],he={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function ye(t){var r=P(P({},he),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Yi,FRAGMENT_SHADER_SOURCE:Wi,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:qi,ATTRIBUTES:[{name:"a_position",size:2,type:He},{name:"a_normal",size:2,type:He},{name:"a_radius",size:1,type:He},{name:"a_color",size:4,type:Cr,normalized:!0},{name:"a_id",size:4,type:Cr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:He}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var h=l.size||1,v=u.size||1,y=s.x,_=s.y,p=u.x,T=u.y,E=Y(l.color),b=p-y,m=T-_,w=b*b+m*m,O=0,A=0;w&&(w=1/Math.sqrt(w),O=-m*w*h,A=b*w*h);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-O,C[o++]=-A,C[o++]=v,C[o++]=E,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,h=u.u_correctionRatio,v=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,_=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(h,a.correctionRatio),s.uniform1f(v,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(_,r.widenessToThicknessRatio)}}])})(ce)}var bs=ye();var $i=` precision mediump float; varying vec4 v_color; @@ -175,7 +175,7 @@ void main(void) { gl_FragColor = mix(v_color, transparent, t); #endif } -`,Ve=ki,Ni=` +`,Ye=$i,Ki=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -243,7 +243,7 @@ void main() { v_color.a *= bias; } -`,Oi=Ni,Sr=WebGLRenderingContext,pr=Sr.UNSIGNED_BYTE,me=Sr.FLOAT,Di=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ar={lengthToThicknessRatio:ce.lengthToThicknessRatio};function Ct(t){var r=L(L({},Ar),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Oi,FRAGMENT_SHADER_SOURCE:Ve,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Di,ATTRIBUTES:[{name:"a_positionStart",size:2,type:me},{name:"a_positionEnd",size:2,type:me},{name:"a_normal",size:2,type:me},{name:"a_color",size:4,type:pr,normalized:!0},{name:"a_id",size:4,type:pr,normalized:!0},{name:"a_radius",size:1,type:me}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:me},{name:"a_normalCoef",size:1,type:me},{name:"a_radiusCoef",size:1,type:me}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=u.size||1,g=T*T+_*_,w=0,k=0;g&&(g=1/Math.sqrt(g),w=-_*g*c,k=T*g*c);var P=this.array;P[o++]=f,P[o++]=m,P[o++]=y,P[o++]=E,P[o++]=w,P[o++]=k,P[o++]=p,P[o++]=a,P[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var Go=Ct();function Lr(t){return ke([Ct(t),ye(t)])}var Fi=Lr(),We=Fi,Ii=` +`,Zi=Ki,zr=WebGLRenderingContext,Sr=zr.UNSIGNED_BYTE,pe=zr.FLOAT,Qi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Gr={lengthToThicknessRatio:he.lengthToThicknessRatio};function Ot(t){var r=P(P({},Gr),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Zi,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Qi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:pe},{name:"a_positionEnd",size:2,type:pe},{name:"a_normal",size:2,type:pe},{name:"a_color",size:4,type:Sr,normalized:!0},{name:"a_id",size:4,type:Sr,normalized:!0},{name:"a_radius",size:1,type:pe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:pe},{name:"a_normalCoef",size:1,type:pe},{name:"a_radiusCoef",size:1,type:pe}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,h=s.x,v=s.y,y=u.x,_=u.y,p=Y(l.color),T=y-h,E=_-v,b=u.size||1,m=T*T+E*E,w=0,O=0;m&&(m=1/Math.sqrt(m),w=-E*m*c,O=T*m*c);var A=this.array;A[o++]=h,A[o++]=v,A[o++]=y,A[o++]=_,A[o++]=w,A[o++]=O,A[o++]=p,A[o++]=a,A[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,h=u.u_feather,v=u.u_pixelRatio,y=u.u_correctionRatio,_=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(_,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(v,a.pixelRatio),s.uniform1f(h,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(ce)}var _s=Ot();function Mr(t){return Ne([Ot(t),ye(t)])}var Ji=Mr(),qe=Ji,ea=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -308,8 +308,8 @@ void main() { v_color.a *= bias; } -`,zi=Ii,Pr=WebGLRenderingContext,yr=Pr.UNSIGNED_BYTE,Pe=Pr.FLOAT,Gi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],Xe=(function(t){function r(){return W(this,r),q(this,r,arguments)}return $(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:zi,FRAGMENT_SHADER_SOURCE:Ve,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Gi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Pe},{name:"a_positionEnd",size:2,type:Pe},{name:"a_normal",size:2,type:Pe},{name:"a_color",size:4,type:yr,normalized:!0},{name:"a_id",size:4,type:yr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Pe},{name:"a_normalCoef",size:1,type:Pe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,f=o.x,m=o.y,y=Q(s.color),E=f-l,p=m-c,T=E*E+p*p,_=0,b=0;T&&(T=1/Math.sqrt(T),_=-p*T*u,b=E*T*u);var g=this.array;g[i++]=l,g[i++]=c,g[i++]=f,g[i++]=m,g[i++]=_,g[i++]=b,g[i++]=y,g[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,f=o.u_correctionRatio,m=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(m,e.sizeRatio),a.uniform1f(f,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(le);var Br=fe($e()),Ze=(function(t){function r(){var n;return W(this,r),n=q(this,r),n.rawEmitter=n,n}return $(r,t),X(r)})(Br.EventEmitter);var Wr=fe(Ke());var Wi=function(r){return r},Xi=function(r){return r*r},Yi=function(r){return r*(2-r)},qi=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},$i=function(r){return r*r*r},Zi=function(r){return--r*r*r+1},Ki=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},Xr={linear:Wi,quadraticIn:Xi,quadraticOut:Yi,quadraticInOut:qi,cubicIn:$i,cubicOut:Zi,cubicInOut:Ki},Yr={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function Qe(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function Vr(t,r,n){return t[6]=r,t[7]=n,t}function he(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],f=r[0],m=r[1],y=r[2],E=r[3],p=r[4],T=r[5],_=r[6],b=r[7],g=r[8];return t[0]=f*n+m*a+y*u,t[1]=f*e+m*o+y*l,t[2]=f*i+m*s+y*c,t[3]=E*n+p*a+T*u,t[4]=E*e+p*o+T*l,t[5]=E*i+p*s+T*c,t[6]=_*n+b*a+g*u,t[7]=_*e+b*o+g*l,t[8]=_*i+b*s+g*c,t}function Je(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function Qi(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,f=te(),m=Math.min(l,c)-2*e,y=Qi(r,n);return i?(he(f,Vr(te(),s,u)),he(f,Qe(te(),o)),he(f,jr(te(),a)),he(f,Qe(te(),l/m/2/y,c/m/2/y))):(he(f,Qe(te(),2*(m/l)*y,2*(m/c)*y)),he(f,jr(te(),-a)),he(f,Qe(te(),1/o)),he(f,Vr(te(),-s,-u))),f}function qr(t,r,n){var e=Je(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function $r(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function Zr(t){if(!(0,Wr.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function Kr(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function At(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Lt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Pt(t){var r=ue(t.x,2),n=r[0],e=r[1],i=ue(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(m){return{x:.5+(m.x-u)/s,y:.5+(m.y-l)/s}};return c.applyTo=function(f){f.x=.5+(f.x-u)/s,f.y=.5+(f.y-l)/s},c.inverse=function(f){return{x:u+s*(f.x-.5),y:l+s*(f.y-.5)}},c.ratio=s,c}function et(t){"@babel/helpers - typeof";return et=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},et(t)}function kt(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function tt(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=L(L({},Yr),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:Xr[s.easing],c=Date.now(),f=this.getState(),m=function(){var E=(Date.now()-c)/s.duration;if(E>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(E),T={};typeof u.x=="number"&&(T.x=f.x+(u.x-f.x)*p),typeof u.y=="number"&&(T.y=f.y+(u.y-f.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=f.angle+(u.angle-f.angle)*p),typeof u.ratio=="number"&&(T.ratio=f.ratio+(u.ratio-f.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(m)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(m)):m(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||it)},e):this.animate({ratio:this.ratio/it})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||it)},e):this.animate({ratio:this.ratio*it})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Ze);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ie(t,r){var n=L(L({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function Ne(t){var r="x"in t?t:L(L({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ta(t,r){return L(L({},ie(t,r)),{},{delta:an(t)})}var ra=2;function at(t){for(var r=[],n=0,e=Math.min(t.length,ra);n0;i.draggedEvents=0,f&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ie(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ie(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),f=this.renderer.viewportToFramedGraph({x:u,y:l}),m=c.x-f.x,y=c.y-f.y,E=o.getState(),p=E.x+m,T=E.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ie(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ie(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=an(e);if(o){var s=ta(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),f=o>0?1:-1,m=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===f&&this.lastWheelTriggerTime&&m-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),tn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new en(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(en.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],f=0;f2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=q(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new tn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Pt({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",At()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=Qr(a),nt(i.settings),Zr(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Ot,i.bindCameraHandlers(),i.mouseCaptor=new sn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new sa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return $(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=Nt(s,[e].map(ge));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=Nt(i,[e].map(ge));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=Ue(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Me.apply(void 0,Jr(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",L(L({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",L(L({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",L(L({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=Ne(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",L(L({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",L(L({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",L({},s))},this.activeListeners.handleEnter=function(a){var o=Ne(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",L({},s))};var i=function(o){return function(s){var u=Ne(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),L(L({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var f=e.getEdgeAtPoint(u.x,u.y);if(f)return e.emit("".concat(o,"Edge"),L(L({},l),{},{edge:f}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=Ue(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Me.apply(void 0,Jr(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=$r(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,f=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(f[0]+f[1])/2-u/2,(f[0]+f[1])/2+u/2]}}this.normalizationFunction=Pt(this.customBBox||this.nodeExtent);var m=new Ot,y=xe(m.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var E={},p={},T={},_={},b=1,g=i.nodes(),w=0,k=g.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=L({},e),l=s||this.nodeExtent,c=ue(l.x,2),f=c[0],m=c[1],y=ue(l.y,2),E=y[0],p=y[1],T=[this.graphToViewport({x:f,y:E},{cameraState:e}),this.graphToViewport({x:m,y:E},{cameraState:e}),this.graphToViewport({x:f,y:p},{cameraState:e}),this.graphToViewport({x:m,y:p},{cameraState:e})],_=1/0,b=-1/0,g=1/0,w=-1/0;T.forEach(function(U){var j=U.x,h=U.y;_=Math.min(_,j),b=Math.max(b,j),g=Math.min(g,h),w=Math.max(w,h)});var k=b-_,P=w-g,C=this.getDimensions(),D=C.width,O=C.height,I=0,z=0;if(k>=D?bo&&(I=_-o):b>D+o?I=b-(D+o):_<-o&&(I=_+o),P>=O?wo&&(z=g-o):w>O+o?z=w-(O+o):g<-o&&(z=g+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),H=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=H.x-G.x,z=H.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);kt(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+rn||m<-nn||m>this.height+nn)){this.displayedNodeLabels.add(u);var E=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||E;T(a,L(L({key:u},l),{},{size:y,x:f,y:m}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=da({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});kt(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=va(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new tn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=Kr(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=L({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return L({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=L({},this.settings);return this.settings[e]=i,nt(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=L({},this.settings);return this.settings=L(L({},this.settings),e),nt(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=At(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var f=this.textures[l];f&&c.deleteTexture(f)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],f=0,m=c?.length||0;f1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=Je(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=Je(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Ze),ln=un;var hn=WebGLRenderingContext,ms=hn.UNSIGNED_BYTE,ps=hn.FLOAT;var ga=` +`,ta=ea,Ur=WebGLRenderingContext,Ar=Ur.UNSIGNED_BYTE,Oe=Ur.FLOAT,ra=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],$e=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ta,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ra,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Oe},{name:"a_positionEnd",size:2,type:Oe},{name:"a_normal",size:2,type:Oe},{name:"a_color",size:4,type:Ar,normalized:!0},{name:"a_id",size:4,type:Ar,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Oe},{name:"a_normalCoef",size:1,type:Oe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,h=o.x,v=o.y,y=Y(s.color),_=h-l,p=v-c,T=_*_+p*p,E=0,b=0;T&&(T=1/Math.sqrt(T),E=-p*T*u,b=_*T*u);var m=this.array;m[i++]=l,m[i++]=c,m[i++]=h,m[i++]=v,m[i++]=E,m[i++]=b,m[i++]=y,m[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,h=o.u_correctionRatio,v=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(v,e.sizeRatio),a.uniform1f(h,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(ce);var Zr=ve(Qe()),Je=(function(t){function r(){var n;return W(this,r),n=$(this,r),n.rawEmitter=n,n}return K(r,t),X(r)})(Zr.EventEmitter);var tn=ve(et());var la=function(r){return r},ca=function(r){return r*r},ha=function(r){return r*(2-r)},fa=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},da=function(r){return r*r*r},va=function(r){return--r*r*r+1},ga=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},rn={linear:la,quadraticIn:ca,quadraticOut:ha,quadraticInOut:fa,cubicIn:da,cubicOut:va,cubicInOut:ga},nn={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function tt(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function Jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function en(t,r,n){return t[6]=r,t[7]=n,t}function fe(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],h=r[0],v=r[1],y=r[2],_=r[3],p=r[4],T=r[5],E=r[6],b=r[7],m=r[8];return t[0]=h*n+v*a+y*u,t[1]=h*e+v*o+y*l,t[2]=h*i+v*s+y*c,t[3]=_*n+p*a+T*u,t[4]=_*e+p*o+T*l,t[5]=_*i+p*s+T*c,t[6]=E*n+b*a+m*u,t[7]=E*e+b*o+m*l,t[8]=E*i+b*s+m*c,t}function rt(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function ma(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,h=te(),v=Math.min(l,c)-2*e,y=ma(r,n);return i?(fe(h,en(te(),s,u)),fe(h,tt(te(),o)),fe(h,Jr(te(),a)),fe(h,tt(te(),l/v/2/y,c/v/2/y))):(fe(h,tt(te(),2*(v/l)*y,2*(v/c)*y)),fe(h,Jr(te(),-a)),fe(h,tt(te(),1/o)),fe(h,en(te(),-s,-u))),h}function an(t,r,n){var e=rt(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function on(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function sn(t){if(!(0,tn.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function un(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function kt(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Dt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Ft(t){var r=le(t.x,2),n=r[0],e=r[1],i=le(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(v){return{x:.5+(v.x-u)/s,y:.5+(v.y-l)/s}};return c.applyTo=function(h){h.x=.5+(h.x-u)/s,h.y=.5+(h.y-l)/s},c.inverse=function(h){return{x:u+s*(h.x-.5),y:l+s*(h.y-.5)}},c.ratio=s,c}function nt(t){"@babel/helpers - typeof";return nt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},nt(t)}function It(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function it(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=P(P({},nn),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:rn[s.easing],c=Date.now(),h=this.getState(),v=function(){var _=(Date.now()-c)/s.duration;if(_>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(_),T={};typeof u.x=="number"&&(T.x=h.x+(u.x-h.x)*p),typeof u.y=="number"&&(T.y=h.y+(u.y-h.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=h.angle+(u.angle-h.angle)*p),typeof u.ratio=="number"&&(T.ratio=h.ratio+(u.ratio-h.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(v)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(v)):v(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||st)},e):this.animate({ratio:this.ratio/st})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||st)},e):this.animate({ratio:this.ratio*st})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Je);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ae(t,r){var n=P(P({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function ke(t){var r="x"in t?t:P(P({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ba(t,r){return P(P({},ae(t,r)),{},{delta:gn(t)})}var _a=2;function ut(t){for(var r=[],n=0,e=Math.min(t.length,_a);n0;i.draggedEvents=0,h&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ae(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ae(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),h=this.renderer.viewportToFramedGraph({x:u,y:l}),v=c.x-h.x,y=c.y-h.y,_=o.getState(),p=_.x+v,T=_.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ae(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ae(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=gn(e);if(o){var s=ba(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),h=o>0?1:-1,v=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===h&&this.lastWheelTriggerTime&&v-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),fn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new hn(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(hn.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],h=0;h2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=$(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new fn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Ft({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",kt()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=ln(a),ot(i.settings),sn(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Gt,i.bindCameraHandlers(),i.mouseCaptor=new pn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new xa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return K(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=zt(s,[e].map(me));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=je(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Be.apply(void 0,cn(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",P(P({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",P(P({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",P(P({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=ke(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",P({},s))},this.activeListeners.handleEnter=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",P({},s))};var i=function(o){return function(s){var u=ke(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),P(P({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var h=e.getEdgeAtPoint(u.x,u.y);if(h)return e.emit("".concat(o,"Edge"),P(P({},l),{},{edge:h}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=je(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Be.apply(void 0,cn(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=on(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,h=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(h[0]+h[1])/2-u/2,(h[0]+h[1])/2+u/2]}}this.normalizationFunction=Ft(this.customBBox||this.nodeExtent);var v=new Gt,y=xe(v.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var _={},p={},T={},E={},b=1,m=i.nodes(),w=0,O=m.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=P({},e),l=s||this.nodeExtent,c=le(l.x,2),h=c[0],v=c[1],y=le(l.y,2),_=y[0],p=y[1],T=[this.graphToViewport({x:h,y:_},{cameraState:e}),this.graphToViewport({x:v,y:_},{cameraState:e}),this.graphToViewport({x:h,y:p},{cameraState:e}),this.graphToViewport({x:v,y:p},{cameraState:e})],E=1/0,b=-1/0,m=1/0,w=-1/0;T.forEach(function(U){var H=U.x,f=U.y;E=Math.min(E,H),b=Math.max(b,H),m=Math.min(m,f),w=Math.max(w,f)});var O=b-E,A=w-m,C=this.getDimensions(),D=C.width,k=C.height,I=0,z=0;if(O>=D?bo&&(I=E-o):b>D+o?I=b-(D+o):E<-o&&(I=E+o),A>=k?wo&&(z=m-o):w>k+o?z=w-(k+o):m<-o&&(z=m+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),j=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=j.x-G.x,z=j.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);It(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+dn||v<-vn||v>this.height+vn)){this.displayedNodeLabels.add(u);var _=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||_;T(a,P(P({key:u},l),{},{size:y,x:h,y:v}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=Pa({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});It(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=Na(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new fn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=un(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=P({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return P({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=P({},this.settings);return this.settings[e]=i,ot(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=P({},this.settings);return this.settings=P(P({},this.settings),e),ot(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=kt(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var h=this.textures[l];h&&c.deleteTexture(h)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],h=0,v=c?.length||0;h1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=rt(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=rt(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Je),bn=yn;var En=WebGLRenderingContext,Zs=En.UNSIGNED_BYTE,Qs=En.FLOAT;var ka=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -390,7 +390,7 @@ void main() { v_color.a *= bias; } -`,ma=ga,dn=WebGLRenderingContext,cn=dn.UNSIGNED_BYTE,oe=dn.FLOAT,pa=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],ya={lengthToThicknessRatio:ce.lengthToThicknessRatio};function fn(t){var r=L(L({},ya),t||{});return(function(n){function e(){return W(this,e),q(this,e,arguments)}return $(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ma,FRAGMENT_SHADER_SOURCE:Ve,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:pa,ATTRIBUTES:[{name:"a_positionStart",size:2,type:oe},{name:"a_positionEnd",size:2,type:oe},{name:"a_normal",size:2,type:oe},{name:"a_color",size:4,type:cn,normalized:!0},{name:"a_id",size:4,type:cn,normalized:!0},{name:"a_sourceRadius",size:1,type:oe},{name:"a_targetRadius",size:1,type:oe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:oe},{name:"a_normalCoef",size:1,type:oe},{name:"a_sourceRadiusCoef",size:1,type:oe},{name:"a_targetRadiusCoef",size:1,type:oe}],CONSTANT_DATA:[[0,1,-1,0],[0,-1,1,0],[1,1,0,1],[1,1,0,1],[0,-1,1,0],[1,-1,0,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,f=s.x,m=s.y,y=u.x,E=u.y,p=Q(l.color),T=y-f,_=E-m,b=s.size||1,g=u.size||1,w=T*T+_*_,k=0,P=0;w&&(w=1/Math.sqrt(w),k=-_*w*c,P=T*w*c);var C=this.array;C[o++]=f,C[o++]=m,C[o++]=y,C[o++]=E,C[o++]=k,C[o++]=P,C[o++]=p,C[o++]=a,C[o++]=b,C[o++]=g}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,f=u.u_feather,m=u.u_pixelRatio,y=u.u_correctionRatio,E=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(E,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(m,a.pixelRatio),s.uniform1f(f,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(le)}var ys=fn();function ba(t){return ke([fn(t),ye(t),ye(L(L({},t),{},{extremity:"source"}))])}var _a=ba(),Ea=_a;var vn=WebGLRenderingContext,bs=vn.UNSIGNED_BYTE,_s=vn.FLOAT;var gn=WebGLRenderingContext,Es=gn.UNSIGNED_BYTE,Ts=gn.FLOAT;var Ss=fe(Ke());function bn(t,r,n){return Te(t,r,n)}function Ta(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o;t.beginPath(),t.moveTo(r.x+c,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+c,r.y-l/2),t.lineTo(r.x+c,r.y-c),t.lineTo(r.x-c,r.y-c),t.lineTo(r.x-c,r.y+c),t.lineTo(r.x+c,r.y+c),t.moveTo(r.x+c,r.y+l/2),t.closePath(),t.fill()}else{var f=r.size+o;t.fillRect(r.x-f,r.y-f,f*2,f*2)}t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,bn(t,r,n)}function Ra(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function wa(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function _n(t){var r=wa(t,"string");return typeof r=="symbol"?r:r+""}function mn(t,r){for(var n=0;nno,NodePictogramProgram:()=>io,createNodeImageProgram:()=>qt});var An=fe($e());function zt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);nt.length)&&(r=t.length);for(var n=0,e=Array(r);n v_radius) + gl_FragColor = transparent; + else { + gl_FragColor = v_color; + gl_FragColor.a *= bias; + } + #else + // Sizes: +`).concat(r.flatMap(function(i,a){var o=i.size;if("fill"in o)return[];o=o;var s="attribute"in o?"v_borderSize_".concat(a+1):We(o.value),u=(o.mode||fo)==="pixels"?"u_correctionRatio":"v_radius";return[" float borderSize_".concat(a+1," = ").concat(u," * ").concat(s,";")]}).join(` +`),` + // Now, let's split the remaining space between "fill" borders: + float fillBorderSize = (v_radius - (`).concat(r.flatMap(function(i,a){var o=i.size;return"fill"in o?[]:["borderSize_".concat(a+1)]}).join(" + "),") ) / ").concat(n,`; +`).concat(r.flatMap(function(i,a){var o=i.size;return"fill"in o?[" float borderSize_".concat(a+1," = fillBorderSize;")]:[]}).join(` +`),` + + // Finally, normalize all border sizes, to start from the full size and to end with the smallest: + float adjustedBorderSize_0 = v_radius; +`).concat(r.map(function(i,a){return" float adjustedBorderSize_".concat(a+1," = adjustedBorderSize_").concat(a," - borderSize_").concat(a+1,";")}).join(` +`),` + + // Colors: + vec4 borderColor_0 = transparent; +`).concat(r.map(function(i,a){var o=i.color,s=[];return"attribute"in o?s.push(" vec4 borderColor_".concat(a+1," = v_borderColor_").concat(a+1,";")):"transparent"in o?s.push(" vec4 borderColor_".concat(a+1," = vec4(0.0, 0.0, 0.0, 0.0);")):s.push(" vec4 borderColor_".concat(a+1," = u_borderColor_").concat(a+1,";")),s.push(" borderColor_".concat(a+1,".a *= bias;")),s.push(" if (borderSize_".concat(a+1," <= 1.0 * u_correctionRatio) { borderColor_").concat(a+1," = borderColor_").concat(a,"; }")),s.join(` +`)}).join(` +`),` + if (dist > adjustedBorderSize_0) { + gl_FragColor = borderColor_0; + } else `).concat(r.map(function(i,a){return"if (dist > adjustedBorderSize_".concat(a,` - aaBorder) { + gl_FragColor = mix(borderColor_`).concat(a+1,", borderColor_").concat(a,", (dist - adjustedBorderSize_").concat(a,` + aaBorder) / aaBorder); + } else if (dist > adjustedBorderSize_`).concat(a+1,`) { + gl_FragColor = borderColor_`).concat(a+1,`; + } else `)}).join(""),` { /* Nothing to add here */ } + #endif +} +`);return e}function po(t){var r=t.borders,n=` +attribute vec2 a_position; +attribute float a_size; +attribute float a_angle; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; + +varying vec2 v_diffVector; +varying float v_radius; + +#ifdef PICKING_MODE +attribute vec4 a_id; +varying vec4 v_color; +#else +`.concat(r.flatMap(function(e,i){var a=e.size;return"attribute"in a?["attribute float a_borderSize_".concat(i+1,";"),"varying float v_borderSize_".concat(i+1,";")]:[]}).join(` +`),` +`).concat(r.flatMap(function(e,i){var a=e.color;return"attribute"in a?["attribute vec4 a_borderColor_".concat(i+1,";"),"varying vec4 v_borderColor_".concat(i+1,";")]:[]}).join(` +`),` +#endif + +const float bias = 255.0 / 254.0; +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main() { + float size = a_size * u_correctionRatio / u_sizeRatio * 4.0; + vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle)); + vec2 position = a_position + diffVector; + gl_Position = vec4( + (u_matrix * vec3(position, 1)).xy, + 0, + 1 + ); + + v_radius = size / 2.0; + v_diffVector = diffVector; + + #ifdef PICKING_MODE + v_color = a_id; + #else +`).concat(r.flatMap(function(e,i){var a=e.size;return"attribute"in a?[" v_borderSize_".concat(i+1," = a_borderSize_").concat(i+1,";")]:[]}).join(` +`),` +`).concat(r.flatMap(function(e,i){var a=e.color;return"attribute"in a?[" v_borderColor_".concat(i+1," = a_borderColor_").concat(i+1,";")]:[]}).join(` +`),` + #endif +} +`);return n}var Un=WebGLRenderingContext,In=Un.UNSIGNED_BYTE,ct=Un.FLOAT;function Bn(t){var r,n=Fn(Fn({},vo),t||{}),e=n.borders,i=n.drawLabel,a=n.drawHover,o=["u_sizeRatio","u_correctionRatio","u_matrix"].concat(jt(e.flatMap(function(s,u){var l=s.color;return"value"in l?["u_borderColor_".concat(u+1)]:[]})));return r=(function(s){uo(u,s);function u(){var l;no(this,u);for(var c=arguments.length,h=new Array(c),v=0;vUo,NodePictogramProgram:()=>Bo,createNodeImageProgram:()=>nr});var Yn=ve(Qe());function Xt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);n=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Cn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function Xt(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Cn(a,e,i,o,s,"next",u)}function s(u){Cn(a,e,i,o,s,"throw",u)}o(void 0)})}}var Yt={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Ya=1;function Ut(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function qa(t){return Bt.apply(this,arguments)}function Bt(){return Bt=Xt(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,f,m,y,E,p=arguments;return be().wrap(function(_){for(;;)switch(_.prev=_.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){_.next=7;break}return _.next=4,fetch(r,{credentials:"include"});case 4:a=_.sent,_.next=10;break;case 7:return _.next=9,fetch(r);case 9:a=_.sent;case 10:return _.next=12,a.text();case 12:if(o=_.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){_.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),f=new XMLSerializer().serializeToString(s),m=new Blob([f],{type:"image/svg+xml"}),y=URL.createObjectURL(m),E=Ut(y),E.finally(function(){return URL.revokeObjectURL(y)}),_.abrupt("return",E);case 26:case"end":return _.stop()}},t)})),Bt.apply(this,arguments)}function $a(t){return Ht.apply(this,arguments)}function Ht(){return Ht=Xt(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,qa(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,Ut(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,Ut(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Ht.apply(this,arguments)}function Za(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Ka(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,f={},m=0,y=t.length;ma||s+k>i&&u+k+l>a||(s+k>i&&(c=Math.max(c,s),s=0,u+=l,l=k),o.push({key:p,image:T,sourceX:b,sourceY:g,sourceSize:_,destinationX:s,destinationY:u,destinationSize:w}),f[p]={x:s,y:u,size:w},s+=k,l=Math.max(l,k))}c=Math.max(c,s);for(var P=c,C=u+l,D=0,O=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Vt(this,r),n=kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Ja),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},Yt),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return Wt(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Qa({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=Xt(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,$a(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},Za(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(An.EventEmitter);Z(st,"NEW_TEXTURE_EVENT","newTexture");var eo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],On=WebGLRenderingContext,Sn=On.UNSIGNED_BYTE,De=On.FLOAT,to=ee(ee({},Yt),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),ro=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function qt(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),Yt.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},to),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,f=i.imageAttribute,m=ja(i,eo),y=new st(m);return r=(function(E){Nn(p,E);function p(T,_,b){var g;return Vt(this,p),g=kn(this,p,[T,_,b]),Z(ne(g),"drawLabel",o),Z(ne(g),"drawHover",a),Z(ne(g),"textureManagerCallback",null),g.textureManagerCallback=function(w){var k=w.atlas,P=w.textures,C=P.length!==g.textures.length;g.atlas=k,g.textureImages=P,C&&g.upgradeShaders(),g.bindTextures(),g.latestRenderParams&&g.render(g.latestRenderParams),g.renderer&&g.renderer.refresh&&g.renderer.refresh()},y.on(st.NEW_TEXTURE_EVENT,g.textureManagerCallback),g.atlas=y.getAtlas(),g.textureImages=y.getTextures(),g.textures=g.textureImages.map(function(){return T.createTexture()}),g.bindTextures(),g}return Wt(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Xa,FRAGMENT_SHADER_SOURCE:Va({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ro,ATTRIBUTES:[{name:"a_position",size:2,type:De},{name:"a_size",size:1,type:De},{name:"a_color",size:4,type:Sn,normalized:!0},{name:"a_id",size:4,type:Sn,normalized:!0},{name:"a_texture",size:4,type:De},{name:"a_textureIndex",size:1,type:De}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:De}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var _=this.getDefinition(),b=this.normalProgram,g=b.program,w=b.buffer,k=b.vertexShader,P=b.fragmentShader,C=b.gl;C.deleteProgram(g),C.deleteBuffer(w),C.deleteShader(k),C.deleteShader(P),this.normalProgram=this.getProgramInfo("normal",C,_.VERTEX_SHADER_SOURCE,_.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var _,b=(_=this.normalProgram)===null||_===void 0?void 0:_.gl;if(b)for(var g=0;g=this.textures.length){var g=_.createTexture();g&&this.textures.push(g)}_.activeTexture(_.TEXTURE0+b),_.bindTexture(_.TEXTURE_2D,this.textures[b]),_.texImage2D(_.TEXTURE_2D,0,_.RGBA,_.RGBA,_.UNSIGNED_BYTE,this.textureImages[b]),_.generateMipmap(_.TEXTURE_2D)}}},{key:"renderProgram",value:function(_,b){if(!b.isPicking)for(var g=b.gl,w=0;wQt,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>Vn,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>Wn,EdgeCurvedArrowProgram:()=>Eo,EdgeCurvedDoubleArrowProgram:()=>To,createDrawCurvedEdgeLabel:()=>jn,createEdgeCurveProgram:()=>lt,default:()=>_o,indexParallelEdgesIndex:()=>bo});function ao(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Gn(t){var r=ao(t,"string");return typeof r=="symbol"?r:r+""}function Mn(t,r,n){return(r=Gn(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Fn(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Ae(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},K=0,Y=p.length;K=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function Wn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function tr(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Wn(a,e,i,o,s,"next",u)}function s(u){Wn(a,e,i,o,s,"throw",u)}o(void 0)})}}var rr={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Po=1;function $t(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function Oo(t){return Kt.apply(this,arguments)}function Kt(){return Kt=tr(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,h,v,y,_,p=arguments;return be().wrap(function(E){for(;;)switch(E.prev=E.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){E.next=7;break}return E.next=4,fetch(r,{credentials:"include"});case 4:a=E.sent,E.next=10;break;case 7:return E.next=9,fetch(r);case 9:a=E.sent;case 10:return E.next=12,a.text();case 12:if(o=E.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){E.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),h=new XMLSerializer().serializeToString(s),v=new Blob([h],{type:"image/svg+xml"}),y=URL.createObjectURL(v),_=$t(y),_.finally(function(){return URL.revokeObjectURL(y)}),E.abrupt("return",_);case 26:case"end":return E.stop()}},t)})),Kt.apply(this,arguments)}function No(t){return Zt.apply(this,arguments)}function Zt(){return Zt=tr(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,Oo(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,$t(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,$t(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Zt.apply(this,arguments)}function ko(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Do(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,h={},v=0,y=t.length;va||s+O>i&&u+O+l>a||(s+O>i&&(c=Math.max(c,s),s=0,u+=l,l=O),o.push({key:p,image:T,sourceX:b,sourceY:m,sourceSize:E,destinationX:s,destinationY:u,destinationSize:w}),h[p]={x:s,y:u,size:w},s+=O,l=Math.max(l,O))}c=Math.max(c,s);for(var A=c,C=u+l,D=0,k=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Jt(this,r),n=Kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Io),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},rr),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return er(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Fo({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=tr(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,No(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},ko(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(Yn.EventEmitter);Z(ft,"NEW_TEXTURE_EVENT","newTexture");var zo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],Qn=WebGLRenderingContext,Xn=Qn.UNSIGNED_BYTE,Fe=Qn.FLOAT,Go=ee(ee({},rr),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),Mo=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function nr(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),rr.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},Go),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,h=i.imageAttribute,v=Co(i,zo),y=new ft(v);return r=(function(_){Zn(p,_);function p(T,E,b){var m;return Jt(this,p),m=Kn(this,p,[T,E,b]),Z(ne(m),"drawLabel",o),Z(ne(m),"drawHover",a),Z(ne(m),"textureManagerCallback",null),m.textureManagerCallback=function(w){var O=w.atlas,A=w.textures,C=A.length!==m.textures.length;m.atlas=O,m.textureImages=A,C&&m.upgradeShaders(),m.bindTextures(),m.latestRenderParams&&m.render(m.latestRenderParams),m.renderer&&m.renderer.refresh&&m.renderer.refresh()},y.on(ft.NEW_TEXTURE_EVENT,m.textureManagerCallback),m.atlas=y.getAtlas(),m.textureImages=y.getTextures(),m.textures=m.textureImages.map(function(){return T.createTexture()}),m.bindTextures(),m}return er(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Lo,FRAGMENT_SHADER_SOURCE:So({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Mo,ATTRIBUTES:[{name:"a_position",size:2,type:Fe},{name:"a_size",size:1,type:Fe},{name:"a_color",size:4,type:Xn,normalized:!0},{name:"a_id",size:4,type:Xn,normalized:!0},{name:"a_texture",size:4,type:Fe},{name:"a_textureIndex",size:1,type:Fe}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Fe}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var E=this.getDefinition(),b=this.normalProgram,m=b.program,w=b.buffer,O=b.vertexShader,A=b.fragmentShader,C=b.gl;C.deleteProgram(m),C.deleteBuffer(w),C.deleteShader(O),C.deleteShader(A),this.normalProgram=this.getProgramInfo("normal",C,E.VERTEX_SHADER_SOURCE,E.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var E,b=(E=this.normalProgram)===null||E===void 0?void 0:E.gl;if(b)for(var m=0;m=this.textures.length){var m=E.createTexture();m&&this.textures.push(m)}E.activeTexture(E.TEXTURE0+b),E.bindTexture(E.TEXTURE_2D,this.textures[b]),E.texImage2D(E.TEXTURE_2D,0,E.RGBA,E.RGBA,E.UNSIGNED_BYTE,this.textureImages[b]),E.generateMipmap(E.TEXTURE_2D)}}},{key:"renderProgram",value:function(E,b){if(!b.isPicking)for(var m=b.gl,w=0;wsr,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>li,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>ci,EdgeCurvedArrowProgram:()=>ns,EdgeCurvedDoubleArrowProgram:()=>is,createDrawCurvedEdgeLabel:()=>ui,createEdgeCurveProgram:()=>vt,default:()=>rs,indexParallelEdgesIndex:()=>ts});function jo(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ni(t){var r=jo(t,"string");return typeof r=="symbol"?r:r+""}function ii(t,r,n){return(r=ni(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function ei(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Le(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},Q=0,q=p.length;QFe,downloadAsImage:()=>or,downloadAsJPEG:()=>ko,downloadAsPNG:()=>Po,drawOnCanvas:()=>Qn,toBlob:()=>ar,toFile:()=>Lo});var Kn=fe(qn()),Fe={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function se(){se=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(h,d,v){h[d]=v.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(h,d,v){return Object.defineProperty(h,d,{value:v,enumerable:!0,configurable:!0,writable:!0}),h[d]}try{l({},"")}catch{l=function(d,v,S){return d[v]=S}}function c(h,d,v,S){var R=d&&d.prototype instanceof _?d:_,A=Object.create(R.prototype),N=new U(S||[]);return i(A,"_invoke",{value:I(h,v,N)}),A}function f(h,d,v){try{return{type:"normal",arg:h.call(d,v)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var m="suspendedStart",y="suspendedYield",E="executing",p="completed",T={};function _(){}function b(){}function g(){}var w={};l(w,o,function(){return this});var k=Object.getPrototypeOf,P=k&&k(k(j([])));P&&P!==n&&e.call(P,o)&&(w=P);var C=g.prototype=_.prototype=Object.create(w);function D(h){["next","throw","return"].forEach(function(d){l(h,d,function(v){return this._invoke(d,v)})})}function O(h,d){function v(R,A,N,F){var M=f(h[R],h,A);if(M.type!=="throw"){var V=M.arg,K=V.value;return K&&typeof K=="object"&&e.call(K,"__await")?d.resolve(K.__await).then(function(Y){v("next",Y,N,F)},function(Y){v("throw",Y,N,F)}):d.resolve(K).then(function(Y){V.value=Y,N(V)},function(Y){return v("throw",Y,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,A){function N(){return new d(function(F,M){v(R,A,F,M)})}return S=S?S.then(N,N):N()}})}function I(h,d,v){var S=m;return function(R,A){if(S===E)throw Error("Generator is already running");if(S===p){if(R==="throw")throw A;return{value:t,done:!0}}for(v.method=R,v.arg=A;;){var N=v.delegate;if(N){var F=z(N,v);if(F){if(F===T)continue;return F}}if(v.method==="next")v.sent=v._sent=v.arg;else if(v.method==="throw"){if(S===m)throw S=p,v.arg;v.dispatchException(v.arg)}else v.method==="return"&&v.abrupt("return",v.arg);S=E;var M=f(h,d,v);if(M.type==="normal"){if(S=v.done?p:y,M.arg===T)continue;return{value:M.arg,done:v.done}}M.type==="throw"&&(S=p,v.method="throw",v.arg=M.arg)}}}function z(h,d){var v=d.method,S=h.iterator[v];if(S===t)return d.delegate=null,v==="throw"&&h.iterator.return&&(d.method="return",d.arg=t,z(h,d),d.method==="throw")||v!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+v+"' method")),T;var R=f(S,h.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var A=R.arg;return A?A.done?(d[h.resultName]=A.value,d.next=h.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):A:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(h){var d={tryLoc:h[0]};1 in h&&(d.catchLoc=h[1]),2 in h&&(d.finallyLoc=h[2],d.afterLoc=h[3]),this.tryEntries.push(d)}function H(h){var d=h.completion||{};d.type="normal",delete d.arg,h.completion=d}function U(h){this.tryEntries=[{tryLoc:"root"}],h.forEach(G,this),this.reset(!0)}function j(h){if(h||h===""){var d=h[o];if(d)return d.call(h);if(typeof h.next=="function")return h;if(!isNaN(h.length)){var v=-1,S=function R(){for(;++v=0;--S){var R=this.tryEntries[S],A=R.completion;if(R.tryLoc==="root")return v("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--v){var S=this.tryEntries[v];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var v=this.tryEntries[d];if(v.finallyLoc===h)return this.complete(v.completion,v.afterLoc),H(v),T}},catch:function(h){for(var d=this.tryEntries.length-1;d>=0;--d){var v=this.tryEntries[d];if(v.tryLoc===h){var S=v.completion;if(S.type==="throw"){var R=S.arg;H(v)}return R}}throw Error("illegal catch attempt")},delegateYield:function(h,d,v){return this.delegate={iterator:j(h),resultName:d,nextLoc:v},this.method==="next"&&(this.arg=t),T}},r}function Ro(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function wo(t){var r=Ro(t,"string");return typeof r=="symbol"?r:r+""}function xo(t,r,n){return(r=wo(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function $n(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&k[1]!==void 0?k[1]:{},e=J(J({},Fe),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,f=r.getDimensions(),m=window.devicePixelRatio||1,y=typeof o!="number"?f.width:o,E=typeof s!="number"?f.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(E,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new ln(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),_=document.createElement("CANVAS"),_.setAttribute("width",y*m+""),_.setAttribute("height",E*m+""),b=_.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*m,E*m),!c){C.next=26;break}return C.next=26,c(T);case 26:return g=T.getCanvases(),w=i?i.filter(function(D){return!!g[D]}):Object.keys(g),w.forEach(function(D){b.drawImage(g[D],0,0,y*m,E*m,0,0,y*m,E*m)}),T.kill(),p.remove(),C.abrupt("return",_);case 32:case"end":return C.stop()}},t)})),tr.apply(this,arguments)}function Co(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function So(t,r){if(t==null)return{};var n,e,i=Co(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.format,a=So(e,Ao),l.next=4,Qn(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,f){o.toBlob(function(m){m?c(m):f(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),rr.apply(this,arguments)}function Lo(t){return nr.apply(this,arguments)}function nr(){return nr=ct(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),nr.apply(this,arguments)}function or(t){return ir.apply(this,arguments)}function ir(){return ir=ct(se().mark(function t(r){var n,e,i,a,o,s=arguments;return se().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Fe),n),i=e.fileName,a=e.format,l.next=4,ar(r,n);case 4:o=l.sent,Kn.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),ir.apply(this,arguments)}function Po(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"png"}))}function ko(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return or(t,J(J({},r),{},{format:"jpeg"}))}export{Ot as Camera,We as EdgeArrowProgram,Ea as EdgeDoubleArrowProgram,Xe as EdgeRectangleProgram,sn as MouseCaptor,Da as NodeSquareProgram,un as Sigma,ye as createEdgeArrowHeadProgram,ke as createEdgeCompoundProgram,je as drawDiscNodeHover,Yn as edgeCurve,Jn as exportImage,Dn as nodeImage}; +`);return i}var sr=.25,li={arrowHead:null,curvatureAttribute:"curvature",defaultCurvature:sr},ci={edgeIndexAttribute:"parallelIndex",edgeMinIndexAttribute:"parallelMinIndex",edgeMaxIndexAttribute:"parallelMaxIndex"};function ts(t,r){var n=Le(Le({},ci),r||{}),e={},i={},a={},o=0;t.forEachNode(function(A){e[A]=++o+""}),t.forEachEdge(function(A,C,D,k){var I=e[D],z=e[k],G=[I,z].join("-");i[A]=G,a[G]=[I,z].sort().join("-")});var s={},u={};t.forEachEdge(function(A){var C=i[A],D=a[C];s[C]=s[C]||[],s[C].push(A),u[D]=u[D]||[],u[D].push(A)});for(var l in s){var c=s[l],h=c.length,v=u[a[l]].length;if(h===1&&v===1){var y=c[0];t.setEdgeAttribute(y,n.edgeIndexAttribute,null),t.setEdgeAttribute(y,n.edgeMaxIndexAttribute,null)}else if(h===1){var _=c[0];t.setEdgeAttribute(_,n.edgeIndexAttribute,1),t.setEdgeAttribute(_,n.edgeMaxIndexAttribute,1)}else if(h===v)for(var p=(h-1)/2,T=-p,E=0;EIe,downloadAsImage:()=>gr,downloadAsJPEG:()=>ds,downloadAsPNG:()=>fs,drawOnCanvas:()=>pi,toBlob:()=>vr,toFile:()=>hs});var mi=ve(di()),Ie={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function ue(){ue=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(f,d,g){f[d]=g.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(f,d,g){return Object.defineProperty(f,d,{value:g,enumerable:!0,configurable:!0,writable:!0}),f[d]}try{l({},"")}catch{l=function(d,g,S){return d[g]=S}}function c(f,d,g,S){var R=d&&d.prototype instanceof E?d:E,L=Object.create(R.prototype),N=new U(S||[]);return i(L,"_invoke",{value:I(f,g,N)}),L}function h(f,d,g){try{return{type:"normal",arg:f.call(d,g)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var v="suspendedStart",y="suspendedYield",_="executing",p="completed",T={};function E(){}function b(){}function m(){}var w={};l(w,o,function(){return this});var O=Object.getPrototypeOf,A=O&&O(O(H([])));A&&A!==n&&e.call(A,o)&&(w=A);var C=m.prototype=E.prototype=Object.create(w);function D(f){["next","throw","return"].forEach(function(d){l(f,d,function(g){return this._invoke(d,g)})})}function k(f,d){function g(R,L,N,F){var M=h(f[R],f,L);if(M.type!=="throw"){var V=M.arg,Q=V.value;return Q&&typeof Q=="object"&&e.call(Q,"__await")?d.resolve(Q.__await).then(function(q){g("next",q,N,F)},function(q){g("throw",q,N,F)}):d.resolve(Q).then(function(q){V.value=q,N(V)},function(q){return g("throw",q,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,L){function N(){return new d(function(F,M){g(R,L,F,M)})}return S=S?S.then(N,N):N()}})}function I(f,d,g){var S=v;return function(R,L){if(S===_)throw Error("Generator is already running");if(S===p){if(R==="throw")throw L;return{value:t,done:!0}}for(g.method=R,g.arg=L;;){var N=g.delegate;if(N){var F=z(N,g);if(F){if(F===T)continue;return F}}if(g.method==="next")g.sent=g._sent=g.arg;else if(g.method==="throw"){if(S===v)throw S=p,g.arg;g.dispatchException(g.arg)}else g.method==="return"&&g.abrupt("return",g.arg);S=_;var M=h(f,d,g);if(M.type==="normal"){if(S=g.done?p:y,M.arg===T)continue;return{value:M.arg,done:g.done}}M.type==="throw"&&(S=p,g.method="throw",g.arg=M.arg)}}}function z(f,d){var g=d.method,S=f.iterator[g];if(S===t)return d.delegate=null,g==="throw"&&f.iterator.return&&(d.method="return",d.arg=t,z(f,d),d.method==="throw")||g!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+g+"' method")),T;var R=h(S,f.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var L=R.arg;return L?L.done?(d[f.resultName]=L.value,d.next=f.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):L:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(f){var d={tryLoc:f[0]};1 in f&&(d.catchLoc=f[1]),2 in f&&(d.finallyLoc=f[2],d.afterLoc=f[3]),this.tryEntries.push(d)}function j(f){var d=f.completion||{};d.type="normal",delete d.arg,f.completion=d}function U(f){this.tryEntries=[{tryLoc:"root"}],f.forEach(G,this),this.reset(!0)}function H(f){if(f||f===""){var d=f[o];if(d)return d.call(f);if(typeof f.next=="function")return f;if(!isNaN(f.length)){var g=-1,S=function R(){for(;++g=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function as(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function os(t){var r=as(t,"string");return typeof r=="symbol"?r:r+""}function ss(t,r,n){return(r=os(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function vi(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&O[1]!==void 0?O[1]:{},e=J(J({},Ie),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,h=r.getDimensions(),v=window.devicePixelRatio||1,y=typeof o!="number"?h.width:o,_=typeof s!="number"?h.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(_,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new bn(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),E=document.createElement("CANVAS"),E.setAttribute("width",y*v+""),E.setAttribute("height",_*v+""),b=E.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*v,_*v),!c){C.next=26;break}return C.next=26,c(T);case 26:return m=T.getCanvases(),w=i?i.filter(function(D){return!!m[D]}):Object.keys(m),w.forEach(function(D){b.drawImage(m[D],0,0,y*v,_*v,0,0,y*v,_*v)}),T.kill(),p.remove(),C.abrupt("return",E);case 32:case"end":return C.stop()}},t)})),cr.apply(this,arguments)}function us(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function ls(t,r){if(t==null)return{};var n,e,i=us(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.format,a=ls(e,cs),l.next=4,pi(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,h){o.toBlob(function(v){v?c(v):h(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),hr.apply(this,arguments)}function hs(t){return fr.apply(this,arguments)}function fr(){return fr=gt(ue().mark(function t(r){var n,e,i,a,o,s=arguments;return ue().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),fr.apply(this,arguments)}function gr(t){return dr.apply(this,arguments)}function dr(){return dr=gt(ue().mark(function t(r){var n,e,i,a,o,s=arguments;return ue().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:o=l.sent,mi.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),dr.apply(this,arguments)}function fs(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"png"}))}function ds(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"jpeg"}))}export{Gt as Camera,qe as EdgeArrowProgram,Ma as EdgeDoubleArrowProgram,$e as EdgeRectangleProgram,pn as MouseCaptor,Qa as NodeSquareProgram,yn as Sigma,ye as createEdgeArrowHeadProgram,Ne as createEdgeCompoundProgram,Bn as createNodeBorderProgram,Xe as drawDiscNodeHover,fi as edgeCurve,yi as exportImage,Jn as nodeImage}; diff --git a/src/package/vendor_entry_sigma.mjs b/src/package/vendor_entry_sigma.mjs index 0d66e14..19ca575 100644 --- a/src/package/vendor_entry_sigma.mjs +++ b/src/package/vendor_entry_sigma.mjs @@ -12,6 +12,7 @@ export { drawDiscNodeHover, } from 'sigma/rendering'; export {NodeSquareProgram} from '@sigma/node-square'; +export {createNodeBorderProgram} from '@sigma/node-border'; export * as nodeImage from '@sigma/node-image'; export * as edgeCurve from '@sigma/edge-curve'; export * as exportImage from '@sigma/export-image'; diff --git a/src/package/vendor_libs.js b/src/package/vendor_libs.js index d6bb47c..e97f39c 100644 --- a/src/package/vendor_libs.js +++ b/src/package/vendor_libs.js @@ -63,7 +63,7 @@ const bundles = [ { entry: path.join(__dirname, 'vendor_entry_sigma.mjs'), out: path.join(libDir, 'sigma.bundle.mjs'), - pkgs: ['sigma', '@sigma/node-square', '@sigma/node-image', '@sigma/edge-curve', '@sigma/export-image'], + pkgs: ['sigma', '@sigma/node-square', '@sigma/node-image', '@sigma/node-border', '@sigma/edge-curve', '@sigma/export-image'], }, ]; diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index 45e521f..a550e16 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -219,6 +219,19 @@ describe("buildGraphologyGraph — population", () => { expect(graph.getNodeAttribute("h", "shape")).toBe("hexagon"); }); + it("propagates node-border attrs for bordered circles into the built graph", () => { + const cache = createMockCache({ + nodes: [makeNode("bc", { stroke: "#C33D35", lineWidth: 2 }, "circle")], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getNodeAttribute("bc", "type")).toBe("borderCircle"); + expect(graph.getNodeAttribute("bc", "borderColor")).toBe("#C33D35"); + expect(graph.getNodeAttribute("bc", "borderRatio")).toBe(0.2); + expect(graph.getNodeAttribute("bc", "image")).toBeNull(); + }); + it("assigns edge programs from the G6 type", () => { const cache = createMockCache({ nodes: [makeNode("a"), makeNode("b")], @@ -374,14 +387,143 @@ describe("attribute mapping helpers", () => { expect(attrs.color).toBe(DEFAULTS.NODE.FILL_COLOR); }); - it("bordered circle/rect route through the texture program (native programs cannot draw borders)", () => { + it("bordered circle routes through the node-border program with clean texture attrs", () => { const attrs = nodeAttributesFromStyle( { fill: "#403C53", stroke: "#C33D35", lineWidth: 2, size: 20 }, "circle", ); - expect(attrs.type).toBe("shape"); - expect(attrs.image).toContain(ACCENT_URI); + expect(attrs.type).toBe("borderCircle"); + expect(attrs.borderColor).toBe("#C33D35"); + expect(attrs.borderSize).toBe(2); + expect(attrs.borderRatio).toBe(2 / 10); // lineWidth / radius (size 20 diameter → 10) + expect(attrs.color).toBe("#403C53"); // fill layer reads `color` + expect(attrs.fillColor).toBeNull(); + expect(attrs.image).toBeNull(); + }); + + it("bordered circle uses the default node size for the border ratio when size is absent", () => { + const attrs = nodeAttributesFromStyle({ stroke: "#C33D35", lineWidth: 1 }, "circle"); + + expect(attrs.type).toBe("borderCircle"); + expect(attrs.borderRatio).toBe(1 / (DEFAULTS.NODE.SIZE / 2)); + }); + + it("clamps the border ratio to 1 when the border is wider than the radius", () => { + const attrs = nodeAttributesFromStyle( + { stroke: "#C33D35", lineWidth: 50, size: 20 }, + "circle", + ); + + expect(attrs.borderRatio).toBe(1); + expect(nodeAttributesFromStyle({ stroke: "#C33D35", lineWidth: 2, size: 0 }, "circle").borderRatio).toBe(1); + }); + + it("bordered rect (and texture-only shapes with borders) stay on the texture program", () => { + const style = { fill: "#403C53", stroke: "#C33D35", lineWidth: 2, size: 20 }; + for (const shape of ["rect", "diamond", "hexagon", "triangle", "star"]) { + const attrs = nodeAttributesFromStyle(style, shape); + expect(attrs.type).toBe("shape"); + expect(attrs.image).toContain(ACCENT_URI); + expect(attrs.borderRatio).toBe(0); + } + }); + + it("zero lineWidth or missing stroke keeps circles on the native program", () => { + expect(nodeAttributesFromStyle({ stroke: "#C33D35", lineWidth: 0 }, "circle").type).toBe("circle"); + expect(nodeAttributesFromStyle({ lineWidth: 2 }, "circle").type).toBe("circle"); + expect(nodeAttributesFromStyle({ stroke: null, lineWidth: 2 }, "circle").type).toBe("circle"); + }); + + // The adapter applies style updates via mergeNodeAttributes, so every + // program transition must overwrite/clear exactly what the previous branch + // set. Simulated here as a literal merge of the two attribute sets. + describe("program-transition attribute hygiene (merge matrix)", () => { + const BORDER = { stroke: "#C33D35", lineWidth: 2 }; + const BASE = { fill: "#403C53", size: 20 }; + const attrsFor = (style, type) => nodeAttributesFromStyle(style, type); + const merge = (from, to) => ({ ...from, ...to }); + + it("native circle → borderCircle (border added)", () => { + const res = merge(attrsFor(BASE, "circle"), attrsFor({ ...BASE, ...BORDER }, "circle")); + + expect(res.type).toBe("borderCircle"); + expect(res.color).toBe("#403C53"); + expect(res.fillColor).toBeNull(); + expect(res.image).toBeNull(); + expect(res.borderColor).toBe("#C33D35"); + expect(res.borderSize).toBe(2); + expect(res.borderRatio).toBe(0.2); + }); + + it("borderCircle → native circle (border removed) clears border attrs", () => { + const res = merge( + attrsFor({ ...BASE, ...BORDER }, "circle"), + attrsFor({ ...BASE, stroke: null, lineWidth: 0 }, "circle"), + ); + + expect(res.type).toBe("circle"); + expect(res.color).toBe("#403C53"); // never left at the texture TRANSPARENT + expect(res.fillColor).toBeNull(); + expect(res.image).toBeNull(); + expect(res.borderColor).toBeNull(); + expect(res.borderSize).toBe(0); + expect(res.borderRatio).toBe(0); + }); + + it("borderCircle → native circle via lineWidth-only delta clears stale borderColor", () => { + // No-nodeRef fallback path: the style delta drops the border without an + // explicit stroke key, so nodeAttributesFromStyle never emits + // borderColor — the program branch must clear it unconditionally or + // applyNodeState bakes the phantom stroke into halo textures. + const res = merge( + attrsFor({ ...BASE, ...BORDER }, "circle"), + attrsFor({ ...BASE, lineWidth: 0 }, "circle"), + ); + + expect(res.type).toBe("circle"); + expect(res.borderColor).toBeNull(); + expect(res.borderSize).toBe(0); + expect(res.borderRatio).toBe(0); + }); + + it("texture → borderCircle (bordered hexagon becomes bordered circle)", () => { + const res = merge( + attrsFor({ ...BASE, ...BORDER }, "hexagon"), + attrsFor({ ...BASE, ...BORDER }, "circle"), + ); + + expect(res.type).toBe("borderCircle"); + expect(res.shape).toBe("circle"); + expect(res.color).toBe("#403C53"); // stale TRANSPARENT would blank the fill ring + expect(res.fillColor).toBeNull(); // stale fillColor corrupts state textures + expect(res.image).toBeNull(); // stale texture cleared + expect(res.borderRatio).toBe(0.2); + }); + + it("borderCircle → texture (bordered circle becomes bordered hexagon)", () => { + const res = merge( + attrsFor({ ...BASE, ...BORDER }, "circle"), + attrsFor({ ...BASE, ...BORDER }, "hexagon"), + ); + + expect(res.type).toBe("shape"); + expect(res.shape).toBe("hexagon"); + expect(res.color).toBe("#00000000"); + expect(res.fillColor).toBe("#403C53"); + expect(res.image).toMatch(/^data:image\/svg\+xml,/); + expect(res.borderRatio).toBe(0); + }); + + it("borderCircle → borderCircle (restyle) recomputes the ratio", () => { + const res = merge( + attrsFor({ ...BASE, ...BORDER }, "circle"), + attrsFor({ ...BASE, ...BORDER, lineWidth: 4, size: 40 }, "circle"), + ); + + expect(res.borderRatio).toBe(4 / 20); + expect(res.borderSize).toBe(4); + }); }); it("sigmaEdgeType maps the full type × arrows matrix", () => { @@ -468,8 +610,8 @@ describe("badge attribute mapping", () => { }); describe("reducers — states and hidden handling", () => { - function reducerFixture({ nodeType } = {}) { - const nodes = [makeNode("a", {}, nodeType), makeNode("b", {}, nodeType)]; + function reducerFixture({ nodeType, nodeStyle = {} } = {}) { + const nodes = [makeNode("a", nodeStyle, nodeType), makeNode("b", nodeStyle, nodeType)]; const edges = [makeEdge("e1", "a", "b")]; const cache = createMockCache({ nodes, edges }); cache.graphData = buildGraphologyGraph(cache); @@ -550,6 +692,47 @@ describe("reducers — states and hidden handling", () => { expect(res.size).toBe(base.size); }); + // Halos stay on the texture path for ALL shapes (single halo + // implementation): borderCircle nodes switch to a halo texture transiently + // in the reducer output, with their own fill and border baked in. + it("node: selected borderCircle renders a halo texture keeping fill and border", () => { + const { cache, nodeReducer, elementStates } = reducerFixture({ + nodeType: "circle", + nodeStyle: { stroke: "#112233", lineWidth: 2 }, + }); + const base = { ...cache.graphData.getNodeAttributes("a") }; + expect(base.type).toBe("borderCircle"); + elementStates.set("a", ["selected"]); + + const res = nodeReducer("a", { ...base, zIndex: 0 }); + + expect(res.type).toBe("shape"); + expect(res.image).toContain(ACCENT_URI); // accent halo ring + expect(res.image).toContain(encodeURIComponent("#403C53")); // own fill kept + expect(res.image).toContain(encodeURIComponent("#112233")); // own border kept + expect(res.size).toBe(base.size + HALO_EXTRA_PX); + expect(res.color).toBe("#00000000"); + expect(res.zIndex).toBe(1); + }); + + it("node: dim borderCircle swaps the fill color only, border attrs untouched", () => { + const { cache, nodeReducer, elementStates } = reducerFixture({ + nodeType: "circle", + nodeStyle: { stroke: "#112233", lineWidth: 2 }, + }); + const base = { ...cache.graphData.getNodeAttributes("a") }; + elementStates.set("a", ["dim"]); + + const res = nodeReducer("a", { ...base }); + + expect(res.type).toBe("borderCircle"); // no texture round-trip for dim + expect(res.color).toBe(STATE_DIM_COLOR); + expect(res.borderColor).toBe("#112233"); // old G6 spec: dim keeps the border + expect(res.borderRatio).toBe(base.borderRatio); + expect(res.image).toBeNull(); + expect(res.size).toBe(base.size); + }); + it("node: selected takes precedence over dim", () => { const { nodeReducer, elementStates } = reducerFixture(); elementStates.set("a", ["dim", "selected"]); From 891f5b6f109a96400422b0569c848514ae98cea3 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 09:30:33 +0200 Subject: [PATCH 18/69] fix(renderer): WebGL2-unavailable guard and post-resize redraw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - new node-safe src/graph/webgl_support.js: webgl2 probe + persistent in-container error message; core.js imports SigmaAdapter lazily so the sigma bundle's module-scope WebGL probes can't kill app boot, probes before construction, and wraps it defensively — on failure cache.graph stays null (same state as 'no data loaded') and app chrome survives - createGraphInstance memoizes its in-flight promise (re-entrancy across the lazy-import await could construct two adapters, leaking a context) - silent null-graph no-op guards on the UI-reachable filter/selection entry points reachable when init failed - resize blank-graph fix: sigma.resize() clears the WebGL buffers but never schedules a render — the adapter facade resize() now calls sigma.scheduleRender() (render() resizes first); evidence + manual repro kept as scripts/resize_redraw_check.js - 24 new tests across webgl-support/graph-core-init/selection-null-graph/ filter-visibility (898 total green); perf gates green --- scripts/resize_redraw_check.js | 254 +++++++++++++++++++++++++++++ src/gll.js | 9 + src/graph/core.js | 111 +++++++++---- src/graph/filter.js | 4 + src/graph/selection.js | 19 +++ src/graph/sigma_adapter.js | 16 +- src/graph/webgl_support.js | 63 +++++++ src/style.css | 27 +++ src/utilities/data_editor.js | 4 + tests/filter-visibility.test.js | 9 + tests/graph-core-init.test.js | 102 ++++++++++++ tests/selection-null-graph.test.js | 79 +++++++++ tests/webgl-support.test.js | 89 ++++++++++ 13 files changed, 750 insertions(+), 36 deletions(-) create mode 100644 scripts/resize_redraw_check.js create mode 100644 src/graph/webgl_support.js create mode 100644 tests/graph-core-init.test.js create mode 100644 tests/selection-null-graph.test.js create mode 100644 tests/webgl-support.test.js diff --git a/scripts/resize_redraw_check.js b/scripts/resize_redraw_check.js new file mode 100644 index 0000000..8c17f90 --- /dev/null +++ b/scripts/resize_redraw_check.js @@ -0,0 +1,254 @@ +#!/usr/bin/env node +// Manual regression check: panel toggles must not blank the graph. +// +// Repro for the "graph disappears after sidebar/bottom-bar toggle until the +// next pan/zoom" bug: sigma.resize() resizes the WebGL canvases (which clears +// their drawing buffers) but never schedules a render, so a container-only +// resize (panel toggle — the window itself does not resize) left the scene +// blank until the next camera move triggered render(). The fix routes all +// container resizes through sigma.scheduleRender() (render() resizes first, +// then redraws). +// +// What it does: boots the app in headless chromium (same launch pattern as +// scripts/perf_benchmark.js), loads a tiny in-memory dataset via +// window.renderGraphData, opens/closes the bottom bar (#queryToggleBtn, rides +// the 0.3 s #mainContent height transition) and toggles the assistant panel, +// then after each settle samples the centre of #innerGraphContainer for +// non-background pixels and checks sigma's resize/afterRender event ordering. +// +// There is no wired e2e harness in this repo (perf_benchmark.js is the only +// browser script in package.json), so this stays a manual check: +// node scripts/resize_redraw_check.js +// Exit code 1 when any toggle leaves the graph blank. + +const fs = require("fs"); +const http = require("http"); +const path = require("path"); +const {spawnSync} = require("child_process"); +const {chromium} = require("playwright"); + +const ROOT = path.resolve(__dirname, ".."); +const SRC_DIR = path.join(ROOT, "src"); + +const TRANSITION_SETTLE_MS = 900; // 300 ms CSS transition + debounce + frames +const MIN_DRAWN_PIXELS = 200; // blank ≈ 0; a drawn 30-node scene ≈ thousands + +const MIME = { + ".html": "text/html", + ".js": "text/javascript", + ".mjs": "text/javascript", + ".css": "text/css", + ".json": "application/json", + ".png": "image/png", + ".svg": "image/svg+xml", + ".map": "application/json", +}; + +// Tiny dataset mirroring the native JSON export shape consumed by +// window.renderGraphData (see scripts/generate_benchmark_fixture.js). +function buildTinyDataset() { + const nodes = []; + const positions = {}; + const edges = []; + const COUNT = 30; + for (let i = 0; i < COUNT; i++) { + const id = `n${i}`; + nodes.push({ + id, + label: `Node-${i}`, + style: {labelText: `Node-${i}`}, + D4Data: {"Node filters": {Biology: {Score: i}}}, + }); + const angle = (2 * Math.PI * i) / COUNT; + positions[id] = {style: {x: Math.cos(angle) * 300, y: Math.sin(angle) * 300}}; + } + for (let i = 0; i < COUNT; i++) { + edges.push({ + id: `e${i}`, + source: `n${i}`, + target: `n${(i + 7) % COUNT}`, + D4Data: {"Edge filters": {Scores: {Weight: 1}}}, + }); + } + return { + nodes, + edges, + nodeDataHeaders: [{subGroup: "Biology", key: "Score"}], + edgeDataHeaders: [{subGroup: "Scores", key: "Weight"}], + selectedLayout: "Default", + layouts: {Default: {positions}}, + }; +} + +function ensurePreconditions() { + if (!fs.existsSync(path.join(SRC_DIR, "lib", "sigma.bundle.mjs"))) { + const res = spawnSync("node", [path.join(SRC_DIR, "package", "vendor_libs.js")], { + cwd: ROOT, + stdio: "inherit", + }); + if (res.status !== 0) { + console.error("[resize-check] vendor_libs.js failed"); + process.exit(1); + } + } +} + +function startServer() { + const server = http.createServer((req, res) => { + const urlPath = decodeURIComponent(new URL(req.url, "http://localhost").pathname); + if (urlPath === "/api/events") { + res.writeHead(200, {"Content-Type": "text/event-stream", "Cache-Control": "no-cache"}); + res.write(": resize-check stub\n\n"); + return; + } + const file = path.join(SRC_DIR, path.normalize(urlPath)); + if (!file.startsWith(SRC_DIR) || !fs.existsSync(file) || !fs.statSync(file).isFile()) { + res.writeHead(404); + res.end("not found"); + return; + } + res.writeHead(200, {"Content-Type": MIME[path.extname(file)] || "application/octet-stream"}); + fs.createReadStream(file).pipe(res); + }); + return new Promise((resolve) => server.listen(0, "127.0.0.1", () => resolve(server))); +} + +/** + * Count non-background pixels in the central 50% of #innerGraphContainer. + * Screenshots come from the compositor, so this sees what the user sees + * (WebGL canvases use preserveDrawingBuffer:false — readPixels would lie). + * The centre crop excludes the minimap (bottom-right) and the border. + */ +async function countDrawnPixels(page, screenshotFile) { + const box = await page.locator("#innerGraphContainer").boundingBox(); + const clip = { + x: box.x + box.width * 0.25, + y: box.y + box.height * 0.25, + width: box.width * 0.5, + height: box.height * 0.5, + }; + const buffer = await page.screenshot({clip}); + if (screenshotFile) fs.writeFileSync(screenshotFile, buffer); + return page.evaluate(async (base64) => { + const img = new Image(); + await new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = reject; + img.src = `data:image/png;base64,${base64}`; + }); + const canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + const {data} = ctx.getImageData(0, 0, canvas.width, canvas.height); + let drawn = 0; + for (let i = 0; i < data.length; i += 4) { + // background is white; count anything visibly non-white + if (255 * 3 - (data[i] + data[i + 1] + data[i + 2]) > 30) drawn++; + } + return drawn; + }, buffer.toString("base64")); +} + +/** Sigma-side evidence: dimension state + renders since the last resize. */ +async function installSigmaProbe(page) { + await page.evaluate(() => { + const sigma = window.cache.graph.sigma; + window.__probe = {resizes: 0, rendersSinceResize: 0}; + sigma.on("resize", () => { + window.__probe.resizes++; + window.__probe.rendersSinceResize = 0; + }); + sigma.on("afterRender", () => { + window.__probe.rendersSinceResize++; + }); + }); +} + +async function sampleSigmaState(page) { + return page.evaluate(() => { + const sigma = window.cache.graph.sigma; + const container = document.getElementById("innerGraphContainer"); + return { + ...window.__probe, + sigmaWidth: sigma.getDimensions().width, + sigmaHeight: sigma.getDimensions().height, + containerWidth: container.offsetWidth, + containerHeight: container.offsetHeight, + }; + }); +} + +async function main() { + ensurePreconditions(); + const server = await startServer(); + const baseUrl = `http://127.0.0.1:${server.address().port}`; + const browser = await chromium.launch({ + headless: true, + args: ["--enable-gpu", "--use-angle=vulkan", "--enable-features=Vulkan", "--ignore-gpu-blocklist"], + }); + const failures = []; + + try { + const page = await browser.newPage({viewport: {width: 1280, height: 800}}); + page.on("pageerror", (err) => console.error(`[resize-check] page error: ${err.message}`)); + + await page.goto(`${baseUrl}/graph_lens_lite.html`, {waitUntil: "load"}); + await page.waitForFunction(() => typeof window.renderGraphData === "function"); + await page.evaluate(async (data) => { + const ok = await window.renderGraphData(data); + if (!ok) throw new Error("renderGraphData reported failure"); + await new Promise((resolve) => requestAnimationFrame(resolve)); + }, buildTinyDataset()); + await installSigmaProbe(page); + + const baseline = await countDrawnPixels( + page, path.join(__dirname, "fixtures", "resize_check_baseline.png")); + console.log(`[resize-check] baseline drawn pixels: ${baseline}`); + if (baseline < MIN_DRAWN_PIXELS) { + throw new Error("graph not drawn after load — harness broken, aborting"); + } + + // Bottom-bar open/close exercises the shared SigmaAdapter.resize() path + // (ResizeObserver debounce); other panels route through the same seam. + // The assistant toggle is deliberately not driven here: with no API key + // configured it opens a modal overlay that blocks further clicks. + const steps = [ + {label: "open bottom bar", action: () => page.click("#queryToggleBtn")}, + {label: "close bottom bar", action: () => page.click("#queryToggleBtn")}, + ]; + + for (const [index, step] of steps.entries()) { + await step.action(); + await page.waitForTimeout(TRANSITION_SETTLE_MS); + const drawn = await countDrawnPixels( + page, path.join(__dirname, "fixtures", `resize_check_step${index + 1}.png`)); + const state = await sampleSigmaState(page); + const ok = drawn >= MIN_DRAWN_PIXELS; + console.log( + `[resize-check] ${step.label}: drawn=${drawn} ` + + `sigma=${state.sigmaWidth}x${state.sigmaHeight} ` + + `container=${state.containerWidth}x${state.containerHeight} ` + + `resizes=${state.resizes} rendersSinceResize=${state.rendersSinceResize} ` + + `=> ${ok ? "PASS" : "FAIL"}`, + ); + if (!ok) failures.push(step.label); + } + } finally { + await browser.close(); + server.close(); + } + + if (failures.length > 0) { + console.error(`[resize-check] FAILED: graph blank after: ${failures.join(", ")}`); + process.exitCode = 1; + } else { + console.log("[resize-check] all panel toggles kept the graph drawn"); + } +} + +main().catch((err) => { + console.error(`[resize-check] error: ${err.message}`); + process.exit(1); +}); diff --git a/src/gll.js b/src/gll.js index 39cd6d6..80ecd23 100644 --- a/src/gll.js +++ b/src/gll.js @@ -388,6 +388,11 @@ async function loadDemoData() { cache.ui.buildUI(); await cache.gcm.createGraphInstance(); + if (!cache.graph) { + await cache.ui.hideLoading(); + resolve(false); + return; + } await cache.graph.render(); resolve(true); } else { @@ -428,6 +433,10 @@ async function startTour() { cache.ui.buildUI(); await cache.gcm.createGraphInstance(); + if (!cache.graph) { + await cache.ui.hideLoading(); + return; + } await cache.graph.render(); await cache.ui.hideLoading(); diff --git a/src/graph/core.js b/src/graph/core.js index 8997a52..b7bf9d7 100644 --- a/src/graph/core.js +++ b/src/graph/core.js @@ -6,7 +6,16 @@ import { makeNodeReducer, makeEdgeReducer, } from "./graph_model.js"; -import { SigmaAdapter } from "./sigma_adapter.js"; +// NOTE: sigma_adapter.js is imported lazily in createGraphInstance(), never +// statically: the sigma vendor bundle probes WebGL at module scope +// (@sigma/node-image reads MAX_TEXTURE_SIZE from a throwaway context), so a +// static import kills the whole app boot when WebGL is unavailable — before +// the isWebGL2Available() check below could ever run. +import { + isWebGL2Available, + renderWebGLUnavailableMessage, + WEBGL2_ERROR_MESSAGE, +} from "./webgl_support.js"; // One-time listener registration guards. These must live at module scope: // the Cache singleton is reset *in place* on every file load (Cache.reset()), @@ -20,6 +29,8 @@ let globalEventsRegistered = false; class GraphCoreManager { constructor(cache) { this.cache = cache; + // In-flight createGraphInstance() memo — see the re-entrancy note there. + this.graphInitPromise = null; } *traverseD4Data(nodeOrEdge) { @@ -89,15 +100,46 @@ class GraphCoreManager { } async createGraphInstance() { - if (this.cache.graph === null) { - // Rebuild the graphology model from the current refs/positions; it is - // the single data source the sigma renderer reads from. - this.cache.graphData = buildGraphologyGraph(this.cache); - - const elementStates = new Map(); - // Hover layer (InteractionManager writes, reducers read) is separate - // from elementStates so hover can never corrupt selection state. - const hoverIds = new Set(); + if (this.cache.graph !== null) return; + + // The init body awaits (dynamic import, layout passes), so two rapid + // calls would both pass the null check above and construct two + // SigmaAdapters — the first one orphaned, leaking a WebGL context. + // Memoize the in-flight init; cleared in finally so a failed init + // (cache.graph stays null) can be retried by the next load. + if (this.graphInitPromise) return this.graphInitPromise; + + this.graphInitPromise = this.#initGraphInstance(); + try { + return await this.graphInitPromise; + } finally { + this.graphInitPromise = null; + } + } + + async #initGraphInstance() { + // Sigma v3 dies with an opaque TypeError when no WebGL context can be + // created (GPU blocklist, remote desktop, disabled flags). Probe first + // and leave cache.graph null — the same state as "no data loaded", so + // the rest of the app chrome keeps working; load paths already guard + // on a null graph after this call. + const containerEl = document.getElementById("innerGraphContainer"); + if (!isWebGL2Available()) { + renderWebGLUnavailableMessage(containerEl); + this.cache.ui.error(WEBGL2_ERROR_MESSAGE); + return; + } + + // Rebuild the graphology model from the current refs/positions; it is + // the single data source the sigma renderer reads from. + this.cache.graphData = buildGraphologyGraph(this.cache); + + const elementStates = new Map(); + // Hover layer (InteractionManager writes, reducers read) is separate + // from elementStates so hover can never corrupt selection state. + const hoverIds = new Set(); + try { + const { SigmaAdapter } = await import("./sigma_adapter.js"); this.cache.graph = new SigmaAdapter(this.cache, "innerGraphContainer", { nodeReducer: makeNodeReducer(this.cache, elementStates, hoverIds), edgeReducer: makeEdgeReducer(this.cache, elementStates, hoverIds), @@ -107,29 +149,36 @@ class GraphCoreManager { // on construction and on every render(). settings: {}, }); + } catch (err) { + // The probe can pass while sigma's own context creation still fails + // (e.g. context-count limits). Same dead-renderer handling. + this.cache.graph = null; + renderWebGLUnavailableMessage(containerEl); + this.cache.ui.error(`Graph renderer failed to initialize: ${err.message}`); + return; + } - const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; - - // Re-apply per-layout node/edge styles on every graph rebuild (data-editor - // apply, JSON load). buildGraphologyGraph does not merge layout.nodeStyles/ - // edgeStyles, and the only other applyLayoutStyles caller is changeLayout(). - // Runs before the layout algorithm below so freshly computed positions are - // never clobbered by the style reset. Skipped when the layout carries no - // custom styles: refs are already originalStyle right after a rebuild, and - // the full reset pass clones every element (~700 ms at 15k elements). - if (layout.nodeStyles?.size || layout.edgeStyles?.size) { - await this.cache.lm.applyLayoutStyles(layout); - } + const layout = this.cache.data.layouts[this.cache.data.selectedLayout]; + + // Re-apply per-layout node/edge styles on every graph rebuild (data-editor + // apply, JSON load). buildGraphologyGraph does not merge layout.nodeStyles/ + // edgeStyles, and the only other applyLayoutStyles caller is changeLayout(). + // Runs before the layout algorithm below so freshly computed positions are + // never clobbered by the style reset. Skipped when the layout carries no + // custom styles: refs are already originalStyle right after a rebuild, and + // the full reset pass clones every element (~700 ms at 15k elements). + if (layout.nodeStyles?.size || layout.edgeStyles?.size) { + await this.cache.lm.applyLayoutStyles(layout); + } - // If layout has no positions yet but has a layoutType, apply that layout algorithm once - if (layout.positions.size === 0 && layout.layoutType) { - const internals = - this.cache.DEFAULTS.LAYOUT_INTERNALS[layout.layoutType] || {}; - await this.cache.graph.setLayout({ - type: layout.layoutType, - ...internals, - }); - } + // If layout has no positions yet but has a layoutType, apply that layout algorithm once + if (layout.positions.size === 0 && layout.layoutType) { + const internals = + this.cache.DEFAULTS.LAYOUT_INTERNALS[layout.layoutType] || {}; + await this.cache.graph.setLayout({ + type: layout.layoutType, + ...internals, + }); } } diff --git a/src/graph/filter.js b/src/graph/filter.js index 48ee8a5..66bcdde 100644 --- a/src/graph/filter.js +++ b/src/graph/filter.js @@ -124,6 +124,10 @@ class GraphFilterManager { } async updateElementVisibility(idsToShow, idsToHide) { + // cache.graph is null both before any data is loaded and when WebGL init + // failed (dead renderer); either way there is nothing to show/hide. + if (!this.cache.graph) return; + this.cache.visibleElementsChanged = false; // Current visibility comes from the graphology `hidden` attrs, surfaced // as style.visibility by the renderer facade (sigma migration, Phase 1). diff --git a/src/graph/selection.js b/src/graph/selection.js index 7db0721..d01512b 100644 --- a/src/graph/selection.js +++ b/src/graph/selection.js @@ -17,6 +17,10 @@ class GraphSelectionManager { * Selects given element IDs while deselecting all others */ async selectElements(elementIDs, refMap, stateOverride = "selected") { + // cache.graph is null both before any data is loaded and when WebGL init + // failed (dead renderer); selection is a silent no-op in either state. + if (!this.cache.graph) return; + const visibility = {}; const elementIDsAsSet = new Set(elementIDs); @@ -35,6 +39,8 @@ class GraphSelectionManager { } async updateSelectedState(elemData, enable) { + if (!this.cache.graph) return; + await this.cache.ui.showLoading(enable ? "Selecting" : "Deselecting", `Modifying selection of ${elemData.length} elements`); await new Promise(resolve => requestAnimationFrame(resolve)); @@ -55,6 +61,8 @@ class GraphSelectionManager { } async getSelectedNodes() { + if (!this.cache.graph) return []; + return await this.cache.graph.getNodeData().filter(n => n.states?.includes("selected")); } @@ -71,11 +79,15 @@ class GraphSelectionManager { } async toggleSelectionForAllNodes(enable) { + if (!this.cache.graph) return; + const nodes = await this.cache.graph.getNodeData(); await this.updateSelectedState(nodes, enable); } async toggleSelectionForAllEdges(enable) { + if (!this.cache.graph) return; + const edges = await this.cache.graph.getEdgeData(); await this.updateSelectedState(edges, enable); } @@ -108,6 +120,11 @@ class GraphSelectionManager { } undoSelection() { + // Silent no-op without a renderer: syncSelectionCacheAndElementStates + // below reads cache.graph, and moving the memory index without syncing + // would desync the snapshot stack. + if (!this.cache.graph) return; + if (this.cache.selectedMemoryIndex > 0) { this.cache.selectedMemoryIndex--; this.syncSelectionCacheAndElementStates(); @@ -117,6 +134,8 @@ class GraphSelectionManager { } redoSelection() { + if (!this.cache.graph) return; + if (this.cache.selectionMemory.length > this.cache.selectedMemoryIndex + 1) { this.cache.selectedMemoryIndex++; this.syncSelectionCacheAndElementStates(); diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 3876aef..4cbfc26 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -35,7 +35,7 @@ const SHAPE_TEXTURE_RESOLUTION = 512; // after a miss; style changes left nodes invisible (transparent base color) // for that long. 50 ms keeps batching without visible flicker. const ATLAS_REGEN_DEBOUNCE_MS = 50; -// Trailing-edge debounce for container ResizeObserver → sigma.resize(); +// Trailing-edge debounce for container ResizeObserver → this.resize(); // rides out the 0.3 s CSS panel transitions without a resize per frame. const RESIZE_DEBOUNCE_MS = 50; @@ -214,9 +214,7 @@ class SigmaAdapter { this.resizeDebounce = null; this.resizeObserver = new ResizeObserver(() => { clearTimeout(this.resizeDebounce); - this.resizeDebounce = setTimeout(() => { - if (!this.killed) this.sigma.resize(); - }, RESIZE_DEBOUNCE_MS); + this.resizeDebounce = setTimeout(() => this.resize(), RESIZE_DEBOUNCE_MS); }); this.resizeObserver.observe(containerEl); this.interactions = new InteractionManager(this, cache, hoverIds, containerEl); @@ -297,8 +295,16 @@ class SigmaAdapter { this.sigma.kill(); } + /** + * Container-resize entry point (ResizeObserver debounce + panel-toggle + * callers). NOT sigma.resize(): that only resizes the canvases — clearing + * their WebGL buffers — and never schedules a render, leaving the graph + * blank until the next camera move (scripts/resize_redraw_check.js). + * render() starts by resizing, so scheduling a render covers both. + */ resize() { - this.sigma.resize(); + if (this.killed) return; + this.sigma.scheduleRender(); } /** diff --git a/src/graph/webgl_support.js b/src/graph/webgl_support.js new file mode 100644 index 0000000..5e1fdef --- /dev/null +++ b/src/graph/webgl_support.js @@ -0,0 +1,63 @@ +/** + * WebGL2 availability probe + persistent in-container fallback message. + * + * Sigma v3 needs a WebGL context; its createWebGLContext falls through + * webgl2 → webgl → experimental-webgl and then dereferences the result + * unchecked, so `new Sigma(...)` dies with an opaque TypeError ("Cannot read + * properties of null (reading 'blendFunc')") when none is available (GPU + * blocklist, remote desktop, disabled flags). We probe webgl2 specifically — + * sigma's shader programs assume it — and render a clear message instead. + * + * Node-safe: no sigma import; DOM access only inside the functions. + */ + +export const WEBGL2_ERROR_MESSAGE = + "Graph rendering requires WebGL2, which is not available in this browser or environment."; +export const WEBGL2_ERROR_HINT = + "Enable hardware acceleration in your browser settings (or update your GPU drivers), then reload."; + +/** + * Cheap pre-check before constructing the renderer. A passing probe does not + * guarantee sigma's own context creation succeeds (callers must still wrap + * construction), but a failing probe is definitive. + * + * @param {Document} [doc] injectable for tests; defaults to the global document + * @returns {boolean} + */ +export function isWebGL2Available(doc = globalThis.document) { + if (!doc) return false; + try { + const canvas = doc.createElement("canvas"); + return canvas.getContext("webgl2") != null; + } catch { + return false; + } +} + +/** + * Renders the WebGL2-unavailable message into the graph container. The + * renderer is permanently dead in this session, so a transient toast is not + * enough — the message must persist where the graph would be. Clears any + * half-initialized sigma canvases first. + * + * @param {HTMLElement|null} containerEl + */ +export function renderWebGLUnavailableMessage(containerEl) { + if (!containerEl) return; + const doc = containerEl.ownerDocument; + containerEl.replaceChildren(); + + const wrapper = doc.createElement("div"); + wrapper.className = "webgl-error"; + + const title = doc.createElement("p"); + title.className = "webgl-error-title"; + title.textContent = `⛔ ${WEBGL2_ERROR_MESSAGE}`; + + const hint = doc.createElement("p"); + hint.className = "webgl-error-hint"; + hint.textContent = WEBGL2_ERROR_HINT; + + wrapper.append(title, hint); + containerEl.appendChild(wrapper); +} diff --git a/src/style.css b/src/style.css index 1b086a5..6c6e444 100644 --- a/src/style.css +++ b/src/style.css @@ -302,6 +302,33 @@ body, html { position: relative; } +/* Persistent renderer-dead message (src/graph/webgl_support.js) — shown + where the graph would be when WebGL2 is unavailable */ +#innerGraphContainer .webgl-error { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 8px; + padding: 0 48px; + text-align: center; + background-color: #f4f4f4; + box-sizing: border-box; +} + +#innerGraphContainer .webgl-error-title { + margin: 0; + font-weight: bold; + color: #403C53; +} + +#innerGraphContainer .webgl-error-hint { + margin: 0; + font-size: 0.85rem; + color: #666; +} + /* Owned minimap (src/graph/minimap.js) — kept at the position the old G6 minimap was CSS-forced to (bottom-right, despite its "bottom-left" config) */ #innerGraphContainer .gll-minimap { diff --git a/src/utilities/data_editor.js b/src/utilities/data_editor.js index 137379e..444dfef 100644 --- a/src/utilities/data_editor.js +++ b/src/utilities/data_editor.js @@ -961,6 +961,10 @@ class DataTable { // this.fileData = structuredClone(updatedFileData); await this.cache.gcm.createGraphInstance(); + if (!this.cache.graph) { + this.cache.ui.error("Graph not initialized, aborting."); + return; + } await this.cache.graph.render(); // Refresh UI to update node/edge counts and filter availability diff --git a/tests/filter-visibility.test.js b/tests/filter-visibility.test.js index 2f2ab44..f18adb2 100644 --- a/tests/filter-visibility.test.js +++ b/tests/filter-visibility.test.js @@ -93,4 +93,13 @@ describe("GraphFilterManager.updateElementVisibility", () => { expect(cache.metrics.invalidateMetricValues).toHaveBeenCalledTimes(1); }); + + it("is a silent no-op when the renderer is unavailable (cache.graph null)", async () => { + // Same state as "no data loaded yet" — must not crash or invalidate. + cache.graph = null; + + await expect(fm.updateElementVisibility(["n1"], ["n2"])).resolves.toBeUndefined(); + expect(cache.metrics.invalidateMetricValues).not.toHaveBeenCalled(); + expect(cache.visibleElementsChanged).toBe(false); + }); }); diff --git a/tests/graph-core-init.test.js b/tests/graph-core-init.test.js new file mode 100644 index 0000000..6d8bed1 --- /dev/null +++ b/tests/graph-core-init.test.js @@ -0,0 +1,102 @@ +// @vitest-environment jsdom +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { GraphCoreManager } from "../src/graph/core.js"; + +// ========================================================================== +// createGraphInstance re-entrancy (WebGL2-probe rework). The init body has +// await points (lazy sigma_adapter import, layout passes), so two rapid +// calls used to race past the `cache.graph === null` check and construct +// two SigmaAdapters — the first one orphaned, leaking a WebGL context. +// The in-flight promise is memoized on `graphInitPromise` and cleared in +// finally so a failed init (cache.graph stays null) remains retryable. +// ========================================================================== + +// Hoisted, mutable adapter-construction state shared with the module mock. +const adapter = vi.hoisted(() => ({ constructions: 0, failuresLeft: 0 })); + +vi.mock("../src/graph/sigma_adapter.js", () => ({ + SigmaAdapter: class SigmaAdapter { + constructor() { + adapter.constructions++; + if (adapter.failuresLeft > 0) { + adapter.failuresLeft--; + throw new Error("context limit reached"); + } + } + }, +})); + +vi.mock("../src/graph/graph_model.js", () => ({ + buildGraphologyGraph: vi.fn(() => ({})), + makeNodeReducer: vi.fn(() => () => ({})), + makeEdgeReducer: vi.fn(() => () => ({})), +})); + +vi.mock("../src/graph/webgl_support.js", () => ({ + isWebGL2Available: vi.fn(() => true), + renderWebGLUnavailableMessage: vi.fn(), + WEBGL2_ERROR_MESSAGE: "no webgl2", +})); + +function createMockCache() { + return { + graph: null, + graphData: null, + data: { + selectedLayout: "default", + // Non-empty positions + no custom styles: skips applyLayoutStyles and + // setLayout, so the test exercises exactly the construction race. + layouts: { default: { positions: new Map([["n1", { x: 0, y: 0 }]]) } }, + }, + ui: { error: vi.fn() }, + }; +} + +describe("GraphCoreManager.createGraphInstance re-entrancy", () => { + let cache, gcm; + + beforeEach(() => { + adapter.constructions = 0; + adapter.failuresLeft = 0; + cache = createMockCache(); + gcm = new GraphCoreManager(cache); + }); + + it("constructs a single SigmaAdapter for two overlapping calls", async () => { + await Promise.all([gcm.createGraphInstance(), gcm.createGraphInstance()]); + + expect(adapter.constructions).toBe(1); + expect(cache.graph).not.toBeNull(); + }); + + it("returns immediately once a graph instance exists", async () => { + await gcm.createGraphInstance(); + await gcm.createGraphInstance(); + + expect(adapter.constructions).toBe(1); + }); + + it("clears the in-flight memo so a failed init can be retried", async () => { + adapter.failuresLeft = 1; + + await gcm.createGraphInstance(); + expect(cache.graph).toBeNull(); + expect(cache.ui.error).toHaveBeenCalledTimes(1); + expect(gcm.graphInitPromise).toBeNull(); + + await gcm.createGraphInstance(); + expect(adapter.constructions).toBe(2); + expect(cache.graph).not.toBeNull(); + }); + + it("shares one failing init between overlapping calls without throwing", async () => { + adapter.failuresLeft = 1; + + await expect( + Promise.all([gcm.createGraphInstance(), gcm.createGraphInstance()]), + ).resolves.toBeDefined(); + + expect(adapter.constructions).toBe(1); + expect(cache.graph).toBeNull(); + }); +}); diff --git a/tests/selection-null-graph.test.js b/tests/selection-null-graph.test.js new file mode 100644 index 0000000..d766e3e --- /dev/null +++ b/tests/selection-null-graph.test.js @@ -0,0 +1,79 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { GraphSelectionManager } from "../src/graph/selection.js"; + +// ========================================================================== +// Null-graph guards on the UI-reachable GraphSelectionManager entry points. +// cache.graph === null covers both "no data loaded yet" and "WebGL init +// failed" (dead renderer, chrome stays interactive) — in both states the +// selection handlers must be silent no-ops: no crash, no toast, no loading +// overlay, no selection-memory mutation. +// ========================================================================== + +function createMockCache() { + return { + graph: null, + nodeRef: new Map([["n1", { id: "n1" }]]), + edgeRef: new Map([["e1", { id: "e1" }]]), + selectedMemoryIndex: 1, + selectionMemory: [ + { nodes: [], edges: [] }, + { nodes: ["n1"], edges: [] }, + { nodes: ["n1"], edges: ["e1"] }, + ], + ui: { + showLoading: vi.fn(async () => {}), + hideLoading: vi.fn(async () => {}), + warning: vi.fn(), + error: vi.fn(), + }, + }; +} + +describe("GraphSelectionManager with cache.graph === null", () => { + let cache, sm; + + beforeEach(() => { + cache = createMockCache(); + sm = new GraphSelectionManager(cache); + }); + + it("selectElements is a silent no-op", async () => { + await expect(sm.selectElements(["n1"], cache.nodeRef)).resolves.toBeUndefined(); + expect(cache.ui.error).not.toHaveBeenCalled(); + }); + + it("selectNodes and selectEdges are silent no-ops", async () => { + await expect(sm.selectNodes(["n1"])).resolves.toBeUndefined(); + await expect(sm.selectEdges(["e1"])).resolves.toBeUndefined(); + expect(cache.ui.error).not.toHaveBeenCalled(); + }); + + it("updateSelectedState bails before showing the loading overlay", async () => { + await expect(sm.updateSelectedState([{ id: "n1" }], true)).resolves.toBeUndefined(); + expect(cache.ui.showLoading).not.toHaveBeenCalled(); + }); + + it("getSelectedNodes returns an empty array", async () => { + await expect(sm.getSelectedNodes()).resolves.toEqual([]); + }); + + it("toggleSelectionForAllNodes/Edges are silent no-ops", async () => { + await expect(sm.toggleSelectionForAllNodes(true)).resolves.toBeUndefined(); + await expect(sm.toggleSelectionForAllEdges(false)).resolves.toBeUndefined(); + expect(cache.ui.showLoading).not.toHaveBeenCalled(); + }); + + it("undoSelection does not move the memory index or toast", () => { + sm.undoSelection(); + + expect(cache.selectedMemoryIndex).toBe(1); + expect(cache.ui.warning).not.toHaveBeenCalled(); + }); + + it("redoSelection does not move the memory index or toast", () => { + sm.redoSelection(); + + expect(cache.selectedMemoryIndex).toBe(1); + expect(cache.ui.warning).not.toHaveBeenCalled(); + }); +}); diff --git a/tests/webgl-support.test.js b/tests/webgl-support.test.js new file mode 100644 index 0000000..402b8d3 --- /dev/null +++ b/tests/webgl-support.test.js @@ -0,0 +1,89 @@ +// @vitest-environment jsdom +import { describe, it, expect } from "vitest"; +import { + isWebGL2Available, + renderWebGLUnavailableMessage, + WEBGL2_ERROR_MESSAGE, + WEBGL2_ERROR_HINT, +} from "../src/graph/webgl_support.js"; + +// ========================================================================== +// WebGL2 probe + dead-renderer fallback message (src/graph/webgl_support.js). +// core.js runs the probe before constructing SigmaAdapter: sigma 3.0.3's +// createWebGLContext dereferences a null context unchecked, so an unavailable +// WebGL2 must be caught before (and around) `new Sigma(...)`. +// jsdom provides the DOM for the message renderer; jsdom canvases have no +// WebGL at all, so the probe's document-based paths use injected fakes. +// ========================================================================== + +function fakeDocument(getContext) { + return { createElement: () => ({ getContext }) }; +} + +describe("isWebGL2Available", () => { + it("returns true when the canvas yields a webgl2 context", () => { + const doc = fakeDocument((type) => (type === "webgl2" ? {} : null)); + expect(isWebGL2Available(doc)).toBe(true); + }); + + it("returns false when getContext('webgl2') returns null", () => { + const doc = fakeDocument(() => null); + expect(isWebGL2Available(doc)).toBe(false); + }); + + it("returns false when context creation throws", () => { + const doc = fakeDocument(() => { + throw new Error("context limit reached"); + }); + expect(isWebGL2Available(doc)).toBe(false); + }); + + it("returns false without a document (non-browser environment)", () => { + expect(isWebGL2Available(null)).toBe(false); + expect(isWebGL2Available(undefined)).toBe(false); + }); + + it("probes exactly the webgl2 context type (no webgl1 fallback)", () => { + const requested = []; + const doc = fakeDocument((type) => { + requested.push(type); + return type === "webgl" ? {} : null; // webgl1 present, webgl2 absent + }); + expect(isWebGL2Available(doc)).toBe(false); + expect(requested).toEqual(["webgl2"]); + }); +}); + +describe("renderWebGLUnavailableMessage", () => { + it("renders the persistent message and hint into the container", () => { + const container = document.createElement("div"); + renderWebGLUnavailableMessage(container); + + const wrapper = container.querySelector(".webgl-error"); + expect(wrapper).not.toBeNull(); + expect(container.querySelector(".webgl-error-title").textContent).toContain( + WEBGL2_ERROR_MESSAGE, + ); + expect(container.querySelector(".webgl-error-hint").textContent).toBe( + WEBGL2_ERROR_HINT, + ); + }); + + it("clears half-initialized renderer leftovers from the container", () => { + const container = document.createElement("div"); + container.appendChild(document.createElement("canvas")); // sigma leftover + renderWebGLUnavailableMessage(container); + + expect(container.querySelector("canvas")).toBeNull(); + expect(container.children).toHaveLength(1); + expect(container.firstElementChild.className).toBe("webgl-error"); + }); + + it("is a no-op on a missing container (does not throw)", () => { + expect(() => renderWebGLUnavailableMessage(null)).not.toThrow(); + }); + + it("mentions WebGL2 explicitly so users can act on the message", () => { + expect(WEBGL2_ERROR_MESSAGE).toContain("WebGL2"); + }); +}); From 4adf4f1d62095292ed331b913ba0fa123fb57a6a Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 10:04:47 +0200 Subject: [PATCH 19/69] feat(renderer): edge arrow markers and edge halos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - new src/graph/edge_programs.js: parametric SDF marker-head program (arrow/rect/diamond/circle/tee inhibition marker selected per edge end via float enum, per-end sizes in graph px, zero-area collapse for disabled ends), EdgeRectangleProgram-clone halo underdraw reading haloWidth/haloColor, curve halo via re-processed curve program - curved edges fully supported: marker heads orient along the quadratic-bezier tangent (edge-curve's baked arrowHead bypassed) - registry collapses to 4 keys: line/curve fast paths unchanged, styledLine/styledCurve compounds (halo → body → source head → target head); marker/halo are per-edge attributes so the vocabulary never grows the registry - start/end arrow size and type UI knobs now take effect; new marker vocabulary arrow/rect/diamond/circle/tee with legacy G6 names aliased at render time (files round-trip unchanged); Excel validators accept both; halo enable/color/width implemented; API.md updated - selection composes with user halos: post-reducer size widens line and halo together - 17 new attr-mapping/hygiene tests (915 total green); perf gates green (fixture edges route to the unchanged plain-line path); visual pixel probe script scripts/edge_markers_check.js 13/13 --- API.md | 14 +- scripts/edge_markers_check.js | 386 +++++++++++++++++++++++++ src/config.js | 7 +- src/graph/edge_programs.js | 427 ++++++++++++++++++++++++++++ src/graph/graph_model.js | 89 +++++- src/graph/sigma_adapter.js | 49 ++-- src/lib/sigma.bundle.mjs | 46 +-- src/managers/io.js | 6 +- src/managers/ui_style_div.js | 22 +- src/package/vendor_entry_sigma.mjs | 5 +- tests/excel-style-roundtrip.test.js | 2 +- tests/graph-model.test.js | 253 +++++++++++++++- 12 files changed, 1220 insertions(+), 86 deletions(-) create mode 100644 scripts/edge_markers_check.js create mode 100644 src/graph/edge_programs.js diff --git a/API.md b/API.md index cc8520b..d753d5a 100644 --- a/API.md +++ b/API.md @@ -207,13 +207,13 @@ An edge is an object. `source` and `target` are required and must match node | `stroke` | hex | `"#403C5390"` | Line colour (last 2 hex digits = alpha). | | `lineWidth` | number | `0.75` | Line thickness (px). | | `lineDash` | number | `0` | Dash length. **Note:** kept in the data model and round-trips through export, but the Sigma renderer draws all edges solid (dashes are not rendered in v1). | -| `startArrow` | boolean | `false` | Arrowhead at the source end. | -| `startArrowType` | string | `"triangle"` | `triangle`/`circle`/`diamond`/`vee`/`rect`/`simple`. Since the Sigma renderer all heads draw as triangles; the value is kept and round-trips. | -| `startArrowSize` | number | `8` | Source arrowhead size. | -| `endArrow` | boolean | `false` | Arrowhead at the target end. | -| `endArrowType` | string | `"triangle"` | Same enum as `startArrowType`. | -| `endArrowSize` | number | `8` | Target arrowhead size. | -| `halo` | boolean | `false` | Glow behind the edge. Since the Sigma renderer, per-edge halos are kept in the model (and round-trip) but are not drawn; selection halos still render. | +| `startArrow` | boolean | `false` | End marker at the source end. | +| `startArrowType` | string | `"arrow"` | `arrow`/`rect`/`diamond`/`circle`/`tee` (⊣ inhibition bar). Legacy G6 names still load and round-trip unchanged (`triangle`/`vee`/`simple` → arrow, `triangleRect`/`square` → rect). | +| `startArrowSize` | number | `8` | Source marker length (graph px). Unset/0 → sized proportionally to the line width. | +| `endArrow` | boolean | `false` | End marker at the target end. | +| `endArrowType` | string | `"arrow"` | Same enum as `startArrowType`. | +| `endArrowSize` | number | `8` | Target marker length (graph px). | +| `halo` | boolean | `false` | Glow drawn under the edge (total width = line + 2 × `haloLineWidth`), on straight and curved edges. Selecting an edge widens line and halo together. | | `haloStroke` | hex | `"#403C53"` | Halo colour. | | `haloLineWidth` | number | `3` | Halo thickness (px). | diff --git a/scripts/edge_markers_check.js b/scripts/edge_markers_check.js new file mode 100644 index 0000000..80b1d32 --- /dev/null +++ b/scripts/edge_markers_check.js @@ -0,0 +1,386 @@ +#!/usr/bin/env node +// Manual visual check: edge end markers + edge halos (feat/sigma-renderer). +// +// Verifies the parametric marker-head and halo edge programs +// (src/graph/edge_programs.js) actually put pixels on screen: +// - every marker type (arrow/rect/diamond/circle/tee) draws near the +// marked endpoint, wider than the line itself (off-axis probes); +// - start markers draw at the source end; +// - explicit marker SIZE takes effect (a small marker leaves the +// big-marker probe white); +// - halos draw in the halo color BESIDE the line, the line keeps its own +// color, and edges without halo stay white at the same offset; +// - curved styled edges draw markers near the target and a halo along the +// curve (unique halo color counted anywhere on screen). +// +// Same harness pattern as scripts/resize_redraw_check.js (static server + +// headless chromium + window.renderGraphData + compositor screenshots). +// There is no wired e2e harness in this repo, so this stays a manual check: +// node scripts/edge_markers_check.js +// Exit code 1 on any failed probe. + +const fs = require("fs"); +const http = require("http"); +const path = require("path"); +const {spawnSync} = require("child_process"); +const {chromium} = require("playwright"); + +const ROOT = path.resolve(__dirname, ".."); +const SRC_DIR = path.join(ROOT, "src"); + +const NODE_FILL = "#ABACBD"; // gray nodes +const EDGE_COLOR = "#C33D35"; // red edges + markers +const HALO_COLOR = "#8CA6D9"; // blue straight-edge halo +const CURVE_HALO_COLOR = "#4CAF50"; // green curve halo (unique on screen) + +const NODE_SIZE = 20; // G6 diameter -> sigma radius 10 +const NODE_RADIUS = NODE_SIZE / 2; +const LINE_WIDTH = 3; +const MARKER_SIZE = 18; +const SMALL_MARKER_SIZE = 6; +const HALO_WIDTH = 6; +const ROW_GAP = 70; +const EDGE_LEN = 300; + +const COLOR_TOLERANCE = 90; // euclidean rgb distance (AA blends toward white) +const WHITE_TOLERANCE = 30; // sum of channel deficits + +const MIME = { + ".html": "text/html", + ".js": "text/javascript", + ".mjs": "text/javascript", + ".css": "text/css", + ".json": "application/json", + ".png": "image/png", + ".svg": "image/svg+xml", + ".map": "application/json", +}; + +// One horizontal node pair per scenario, rows ROW_GAP apart (app y-down). +const ROWS = [ + {id: "arrow", style: {endArrow: true, endArrowType: "arrow", endArrowSize: MARKER_SIZE}}, + {id: "rect", style: {endArrow: true, endArrowType: "rect", endArrowSize: MARKER_SIZE}}, + {id: "diamond", style: {endArrow: true, endArrowType: "diamond", endArrowSize: MARKER_SIZE}}, + {id: "circle", style: {endArrow: true, endArrowType: "circle", endArrowSize: MARKER_SIZE}}, + {id: "tee", style: {endArrow: true, endArrowType: "tee", endArrowSize: MARKER_SIZE}}, + { + id: "start", + style: { + startArrow: true, startArrowType: "tee", startArrowSize: MARKER_SIZE, + endArrow: true, endArrowType: "arrow", endArrowSize: MARKER_SIZE, + }, + }, + {id: "halo", style: {halo: true, haloLineWidth: HALO_WIDTH, haloStroke: HALO_COLOR}}, + {id: "plain", style: {}}, + {id: "small", style: {endArrow: true, endArrowType: "arrow", endArrowSize: SMALL_MARKER_SIZE}}, + { + id: "curveStyled", + type: "cubic", + style: { + endArrow: true, endArrowType: "arrow", endArrowSize: MARKER_SIZE, + halo: true, haloLineWidth: HALO_WIDTH, haloStroke: CURVE_HALO_COLOR, + }, + }, + {id: "curvePlain", type: "cubic", style: {}}, +]; + +function buildDataset() { + const nodes = []; + const edges = []; + const positions = {}; + ROWS.forEach((row, i) => { + const y = i * ROW_GAP; + for (const [suffix, x] of [["s", 0], ["t", EDGE_LEN]]) { + const id = `${row.id}-${suffix}`; + nodes.push({ + id, + style: {size: NODE_SIZE, fill: NODE_FILL}, + D4Data: {"Node filters": {Biology: {Score: i}}}, + }); + positions[id] = {style: {x, y}}; + } + edges.push({ + id: `e-${row.id}`, + source: `${row.id}-s`, + target: `${row.id}-t`, + type: row.type ?? "line", + style: {lineWidth: LINE_WIDTH, stroke: EDGE_COLOR, ...row.style}, + D4Data: {"Edge filters": {Scores: {Weight: 1}}}, + }); + }); + return { + nodes, + edges, + nodeDataHeaders: [{subGroup: "Biology", key: "Score"}], + edgeDataHeaders: [{subGroup: "Scores", key: "Weight"}], + selectedLayout: "Default", + layouts: {Default: {positions}}, + }; +} + +function ensurePreconditions() { + if (!fs.existsSync(path.join(SRC_DIR, "lib", "sigma.bundle.mjs"))) { + const res = spawnSync("node", [path.join(SRC_DIR, "package", "vendor_libs.js")], { + cwd: ROOT, + stdio: "inherit", + }); + if (res.status !== 0) { + console.error("[markers-check] vendor_libs.js failed"); + process.exit(1); + } + } +} + +function startServer() { + const server = http.createServer((req, res) => { + const urlPath = decodeURIComponent(new URL(req.url, "http://localhost").pathname); + if (urlPath === "/api/events") { + res.writeHead(200, {"Content-Type": "text/event-stream", "Cache-Control": "no-cache"}); + res.write(": markers-check stub\n\n"); + return; + } + const file = path.join(SRC_DIR, path.normalize(urlPath)); + if (!file.startsWith(SRC_DIR) || !fs.existsSync(file) || !fs.statSync(file).isFile()) { + res.writeHead(404); + res.end("not found"); + return; + } + res.writeHead(200, {"Content-Type": MIME[path.extname(file)] || "application/octet-stream"}); + fs.createReadStream(file).pipe(res); + }); + return new Promise((resolve) => server.listen(0, "127.0.0.1", () => resolve(server))); +} + +function hexToRgb(hex) { + return { + r: parseInt(hex.slice(1, 3), 16), + g: parseInt(hex.slice(3, 5), 16), + b: parseInt(hex.slice(5, 7), 16), + }; +} + +function colorDistance(a, b) { + return Math.sqrt((a.r - b.r) ** 2 + (a.g - b.g) ** 2 + (a.b - b.b) ** 2); +} + +function isWhite(c) { + return 255 * 3 - (c.r + c.g + c.b) < WHITE_TOLERANCE; +} + +/** + * Marker probes in graph px relative to the marked node center: + * `along` toward the other endpoint, `perp` off-axis (sign irrelevant — + * everything is symmetric). Off-axis sampling separates marker pixels from + * the line underneath (line half-width is LINE_WIDTH/2 = 1.5 graph px). + */ +const MARKER_PROBES = { + arrow: {along: NODE_RADIUS + MARKER_SIZE * 0.5, perp: 3}, + rect: {along: NODE_RADIUS + MARKER_SIZE * 0.5, perp: 6}, + diamond: {along: NODE_RADIUS + MARKER_SIZE * 0.5, perp: 4}, + circle: {along: NODE_RADIUS + MARKER_SIZE * 0.5, perp: 6}, + tee: {along: NODE_RADIUS + MARKER_SIZE * 0.15, perp: 6}, +}; + +/** + * Compute screen-space probe points in-page. Positions go through + * sigma.graphToViewport (position scale), size-based offsets through + * sigma.scaleSize (zoom scale) — mirroring how the shaders compose them. + */ +async function computeProbePoints(page, probes) { + return page.evaluate((probeSpecs) => { + const sigma = window.cache.graph.sigma; + const graph = window.cache.graphData; + const points = {}; + for (const spec of probeSpecs) { + const anchorAttrs = graph.getNodeAttributes(spec.anchorNode); + const otherAttrs = graph.getNodeAttributes(spec.otherNode); + const anchor = sigma.graphToViewport({x: anchorAttrs.x, y: anchorAttrs.y}); + const other = sigma.graphToViewport({x: otherAttrs.x, y: otherAttrs.y}); + const dx = other.x - anchor.x; + const dy = other.y - anchor.y; + const len = Math.hypot(dx, dy) || 1; + const ux = dx / len; + const uy = dy / len; + points[spec.key] = { + x: anchor.x + ux * sigma.scaleSize(spec.along) - uy * sigma.scaleSize(spec.perp), + y: anchor.y + uy * sigma.scaleSize(spec.along) + ux * sigma.scaleSize(spec.perp), + }; + } + return points; + }, probes); +} + +/** Screenshot the container once; sample pixels + count colors in-page. */ +async function sampleScreenshot(page, points, countSpecs) { + const box = await page.locator("#innerGraphContainer").boundingBox(); + const buffer = await page.screenshot({ + clip: {x: box.x, y: box.y, width: box.width, height: box.height}, + }); + fs.writeFileSync(path.join(__dirname, "fixtures", "edge_markers_check.png"), buffer); + return page.evaluate( + async ({base64, points, countSpecs}) => { + const img = new Image(); + await new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = reject; + img.src = `data:image/png;base64,${base64}`; + }); + const canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + const {data, width, height} = ctx.getImageData(0, 0, img.width, img.height); + const pixelAt = (x, y) => { + const px = Math.round(x); + const py = Math.round(y); + if (px < 0 || py < 0 || px >= width || py >= height) return {r: 255, g: 255, b: 255}; + const i = (py * width + px) * 4; + return {r: data[i], g: data[i + 1], b: data[i + 2]}; + }; + const samples = {}; + for (const [key, p] of Object.entries(points)) samples[key] = pixelAt(p.x, p.y); + const counts = {}; + for (const spec of countSpecs) { + let count = 0; + const x0 = Math.max(0, Math.round(spec.x0)); + const y0 = Math.max(0, Math.round(spec.y0)); + const x1 = Math.min(width, Math.round(spec.x1)); + const y1 = Math.min(height, Math.round(spec.y1)); + for (let y = y0; y < y1; y++) { + for (let x = x0; x < x1; x++) { + const i = (y * width + x) * 4; + const dr = data[i] - spec.color.r; + const dg = data[i + 1] - spec.color.g; + const db = data[i + 2] - spec.color.b; + if (dr * dr + dg * dg + db * db < spec.tolerance * spec.tolerance) count++; + } + } + counts[spec.key] = count; + } + return {samples, counts}; + }, + {base64: buffer.toString("base64"), points, countSpecs}, + ); +} + +async function main() { + ensurePreconditions(); + const server = await startServer(); + const baseUrl = `http://127.0.0.1:${server.address().port}`; + const browser = await chromium.launch({ + headless: true, + args: ["--enable-gpu", "--use-angle=vulkan", "--enable-features=Vulkan", "--ignore-gpu-blocklist"], + }); + const failures = []; + const pass = (label, ok, detail) => { + console.log(`[markers-check] ${label}: ${detail} => ${ok ? "PASS" : "FAIL"}`); + if (!ok) failures.push(label); + }; + + try { + const page = await browser.newPage({viewport: {width: 1280, height: 900}}); + page.on("pageerror", (err) => console.error(`[markers-check] page error: ${err.message}`)); + + await page.goto(`${baseUrl}/graph_lens_lite.html`, {waitUntil: "load"}); + await page.waitForFunction(() => typeof window.renderGraphData === "function"); + await page.evaluate(async (data) => { + const ok = await window.renderGraphData(data); + if (!ok) throw new Error("renderGraphData reported failure"); + await new Promise((resolve) => requestAnimationFrame(resolve)); + await new Promise((resolve) => requestAnimationFrame(resolve)); + }, buildDataset()); + + // ---------------------------------------------------------- probe spec + const probes = []; + for (const marker of ["arrow", "rect", "diamond", "circle", "tee"]) { + probes.push({ + key: `marker-${marker}`, + anchorNode: `${marker}-t`, + otherNode: `${marker}-s`, + ...MARKER_PROBES[marker], + }); + } + probes.push({ + key: "start-tee", + anchorNode: "start-s", + otherNode: "start-t", + ...MARKER_PROBES.tee, + }); + // Absence controls: plain edge at the marker probe, small marker at the + // big-marker probe (explicit size must shrink the geometry). + probes.push({key: "plain-no-marker", anchorNode: "plain-t", otherNode: "plain-s", ...MARKER_PROBES.rect}); + probes.push({key: "small-size-effect", anchorNode: "small-t", otherNode: "small-s", ...MARKER_PROBES.arrow}); + // Halo probes at the edge midpoint: beside the line (halo), on the line + // (own color), and the same beside-offset on the plain edge (white). + const HALO_PERP = LINE_WIDTH / 2 + HALO_WIDTH / 2; // 4.5, inside the halo band (7.5 half-width) + probes.push({key: "halo-beside", anchorNode: "halo-s", otherNode: "halo-t", along: EDGE_LEN / 2, perp: HALO_PERP}); + probes.push({key: "halo-line", anchorNode: "halo-s", otherNode: "halo-t", along: EDGE_LEN / 2, perp: 0}); + probes.push({key: "plain-no-halo", anchorNode: "plain-s", otherNode: "plain-t", along: EDGE_LEN / 2, perp: HALO_PERP}); + + const points = await computeProbePoints(page, probes); + + // Count boxes near curve targets (marker presence on curved edges) and + // the unique green curve-halo color anywhere on screen. + const boxFor = await page.evaluate(({ids, half}) => { + const sigma = window.cache.graph.sigma; + const graph = window.cache.graphData; + const out = {}; + for (const id of ids) { + const attrs = graph.getNodeAttributes(id); + const p = sigma.graphToViewport({x: attrs.x, y: attrs.y}); + const h = sigma.scaleSize(half); + out[id] = {x0: p.x - h, y0: p.y - h, x1: p.x + h, y1: p.y + h}; + } + return out; + }, {ids: ["curveStyled-t", "curvePlain-t"], half: NODE_RADIUS + MARKER_SIZE + 6}); + + const edgeRgb = hexToRgb(EDGE_COLOR); + const countSpecs = [ + {key: "curve-styled-target", color: edgeRgb, tolerance: 80, ...boxFor["curveStyled-t"]}, + {key: "curve-plain-target", color: edgeRgb, tolerance: 80, ...boxFor["curvePlain-t"]}, + {key: "curve-halo-green", color: hexToRgb(CURVE_HALO_COLOR), tolerance: 80, x0: 0, y0: 0, x1: 10000, y1: 10000}, + ]; + + const {samples, counts} = await sampleScreenshot(page, points, countSpecs); + + // ---------------------------------------------------------- assertions + const fmt = (c) => `rgb(${c.r},${c.g},${c.b})`; + for (const key of ["marker-arrow", "marker-rect", "marker-diamond", "marker-circle", "marker-tee", "start-tee"]) { + const c = samples[key]; + pass(key, colorDistance(c, edgeRgb) < COLOR_TOLERANCE, `sampled ${fmt(c)}, want ~${EDGE_COLOR}`); + } + pass("plain-no-marker", isWhite(samples["plain-no-marker"]), + `sampled ${fmt(samples["plain-no-marker"])}, want white`); + pass("small-size-effect", isWhite(samples["small-size-effect"]), + `sampled ${fmt(samples["small-size-effect"])}, want white (size 6 must miss the size-18 probe)`); + + const haloRgb = hexToRgb(HALO_COLOR); + pass("halo-beside", colorDistance(samples["halo-beside"], haloRgb) < COLOR_TOLERANCE, + `sampled ${fmt(samples["halo-beside"])}, want ~${HALO_COLOR}`); + pass("halo-line", colorDistance(samples["halo-line"], edgeRgb) < COLOR_TOLERANCE, + `sampled ${fmt(samples["halo-line"])}, want ~${EDGE_COLOR}`); + pass("plain-no-halo", isWhite(samples["plain-no-halo"]), + `sampled ${fmt(samples["plain-no-halo"])}, want white`); + + pass("curve-marker", counts["curve-styled-target"] > counts["curve-plain-target"] + 40, + `styled box ${counts["curve-styled-target"]} px vs plain box ${counts["curve-plain-target"]} px`); + pass("curve-halo", counts["curve-halo-green"] > 100, + `${counts["curve-halo-green"]} green halo pixels on screen`); + } finally { + await browser.close(); + server.close(); + } + + if (failures.length > 0) { + console.error(`[markers-check] FAILED: ${failures.join(", ")}`); + process.exitCode = 1; + } else { + console.log("[markers-check] all marker and halo probes passed"); + } +} + +main().catch((err) => { + console.error(`[markers-check] error: ${err.message}`); + process.exit(1); +}); diff --git a/src/config.js b/src/config.js index db7d005..c88becc 100644 --- a/src/config.js +++ b/src/config.js @@ -17,7 +17,7 @@ const DEFAULTS = { }, EDGE: { COLOR: "#403C5390", LINE_WIDTH: 0.75, LINE_DASH: 0, TYPE: "line", - ARROWS: {START: false, END: false, START_SIZE: 8, START_TYPE: "triangle", END_SIZE: 8, END_TYPE: "triangle"}, + ARROWS: {START: false, END: false, START_SIZE: 8, START_TYPE: "arrow", END_SIZE: 8, END_TYPE: "arrow"}, LABEL: { TEXT: null, FOREGROUND_COLOR: "#000000", BACKGROUND: false, BACKGROUND_COLOR: null, BACKGROUND_CURSOR: "default", BACKGROUND_FILL_OPACITY: 1, BACKGROUND_RADIUS: 0, BACKGROUND_STROKE_OPACITY: 1, @@ -180,7 +180,10 @@ const DEFAULTS = { EDGE_LABEL_OFFSET_Y: {"-25": -25, "0": 0, "25": 25}, // EDGE_LABEL_AUTOROTATE: {enable: true, disable: false}, // EDGE_ARROW_SIZES: {sm: 8, md: 10, lg: 14}, - EDGE_ARROW_TYPES: ["triangle", "circle", "diamond", "vee", "rect", "triangleRect", "simple"], + // End-marker vocabulary (graph_model.EDGE_MARKERS): direction shapes + + // "tee" (⊣ inhibition bar). Legacy G6 names (triangle/vee/...) still load + // via aliases but are no longer offered in the UI. + EDGE_ARROW_TYPES: ["arrow", "rect", "diamond", "circle", "tee"], EDGE_HALO: {enable: true, disable: false}, EDGE_HALO_STROKE: {red: "#C33D35", purple: "#403C53", blue: "#8CA6D9"}, EDGE_HALO_WIDTH: {sm: 2, md: 3, lg: 5}, diff --git a/src/graph/edge_programs.js b/src/graph/edge_programs.js new file mode 100644 index 0000000..2906663 --- /dev/null +++ b/src/graph/edge_programs.js @@ -0,0 +1,427 @@ +/** + * Custom WebGL edge programs (browser-only — imports the sigma bundle, must + * never be loaded under node/vitest). + * + * Three building blocks, composed into the "styledLine"/"styledCurve" + * registry entries by sigma_adapter.buildProgramRegistry: + * + * - EdgeHaloProgram: a wider quad UNDER the straight edge body reading the + * per-edge `haloWidth`/`haloColor` attrs (graph_model). haloWidth 0 + * collapses the quad in the vertex shader → zero fragments, so disabled + * halos cost (almost) nothing. Total halo width = edge size + 2×haloWidth, + * computed from the POST-reducer size so selection-widening widens the + * halo with the line. + * + * - createCurveHaloProgram(CurveProgram): same underdraw for @sigma/edge-curve + * edges, by re-processing the curve program with substituted size/color. + * The curve shader clamps thickness up to minEdgeThickness, so "off" is a + * hairline fully-transparent band instead of a degenerate quad. + * + * - createEdgeMarkerHeadProgram({extremity, curved}): parametric end-marker + * head. ONE program draws every marker shape — a per-edge float enum + * (`startMarker`/`endMarker`, see EDGE_MARKERS in graph_model.js) selects + * the SDF in the fragment shader (arrow/rect/diamond/circle/tee), and + * `startMarkerSize`/`endMarkerSize` give an explicit length in graph px + * (0 → proportional to edge thickness, sigma stock-arrow ratios). The + * curved variant orients the head along the quadratic-bezier tangent that + * @sigma/edge-curve renders (control point = midpoint + perp(delta) × + * curvature — the graph→viewport map is a similarity transform, so the + * graph-space construction matches the shader's viewport-space one). + */ +import { EdgeProgram, EdgeRectangleProgram, floatColor } from "../lib/sigma.bundle.mjs"; + +const { UNSIGNED_BYTE, FLOAT } = WebGLRenderingContext; + +// Mirrors @sigma/edge-curve DEFAULT_EDGE_CURVATURE (the app sets no per-edge +// curvature, so every curved edge renders with this value). +const DEFAULT_EDGE_CURVATURE = 0.25; + +const TRANSPARENT = "#00000000"; + +// --------------------------------------------------------------------------- +// Straight-edge halo: EdgeRectangleProgram clone whose thickness/color come +// from the halo attrs. The vertex shader is sigma's edge.vert.glsl with two +// changes: a zero-normal guard that collapses disabled halos to a zero-area +// off-screen triangle, and NO minEdgeThickness clamp (the clamp would +// resurrect a zero-width halo as a minThickness-wide quad). +// --------------------------------------------------------------------------- + +// language=GLSL +const HALO_VERTEX_SHADER = /*glsl*/ ` +attribute vec4 a_id; +attribute vec4 a_color; +attribute vec2 a_normal; +attribute float a_normalCoef; +attribute vec2 a_positionStart; +attribute vec2 a_positionEnd; +attribute float a_positionCoef; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_zoomRatio; +uniform float u_pixelRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_feather; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const float bias = 255.0 / 254.0; + +void main() { + vec2 normal = a_normal * a_normalCoef; + float normalLength = length(normal); + + if (normalLength <= 0.0) { + // Halo disabled: zero-area triangle off-screen -> no fragments. + gl_Position = vec4(2.0, 2.0, 0.0, 1.0); + v_color = vec4(0.0); + v_normal = vec2(0.0); + v_thickness = 1.0; + v_feather = 1.0; + return; + } + + vec2 unitNormal = normal / normalLength; + float webGLThickness = normalLength * u_correctionRatio / u_sizeRatio; + + vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef; + gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness, 1)).xy, 0, 1); + + v_thickness = webGLThickness / u_zoomRatio; + v_normal = unitNormal; + v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0; + + #ifdef PICKING_MODE + v_color = a_id; + #else + v_color = a_color; + #endif + + v_color.a *= bias; +} +`; + +// language=GLSL +const HALO_FRAGMENT_SHADER = /*glsl*/ ` +precision mediump float; + +varying vec4 v_color; +varying vec2 v_normal; +varying float v_thickness; +varying float v_feather; + +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main(void) { + #ifdef PICKING_MODE + gl_FragColor = v_color; + #else + float dist = length(v_normal) * v_thickness; + float t = smoothstep(v_thickness - v_feather, v_thickness, dist); + gl_FragColor = mix(v_color, transparent, t); + #endif +} +`; + +class EdgeHaloProgram extends EdgeRectangleProgram { + getDefinition() { + return { + ...super.getDefinition(), + VERTEX_SHADER_SOURCE: HALO_VERTEX_SHADER, + FRAGMENT_SHADER_SOURCE: HALO_FRAGMENT_SHADER, + }; + } + + processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) { + const haloWidth = data.haloWidth > 0 ? data.haloWidth : 0; + // Post-reducer size: a selected (widened) edge widens its halo too. + const thickness = haloWidth > 0 ? (data.size || 1) + 2 * haloWidth : 0; + const color = floatColor(haloWidth > 0 ? (data.haloColor ?? data.color) : TRANSPARENT); + + const x1 = sourceData.x; + const y1 = sourceData.y; + const x2 = targetData.x; + const y2 = targetData.y; + const dx = x2 - x1; + const dy = y2 - y1; + let len = dx * dx + dy * dy; + let n1 = 0; + let n2 = 0; + if (len && thickness > 0) { + len = 1 / Math.sqrt(len); + n1 = -dy * len * thickness; + n2 = dx * len * thickness; + } + + const array = this.array; + array[startIndex++] = x1; + array[startIndex++] = y1; + array[startIndex++] = x2; + array[startIndex++] = y2; + array[startIndex++] = n1; + array[startIndex++] = n2; + array[startIndex++] = color; + array[startIndex++] = edgeIndex; + } +} + +// --------------------------------------------------------------------------- +// Curved-edge halo: re-process the curve program with halo size/color. +// --------------------------------------------------------------------------- + +/** @param {typeof EdgeProgram} CurveProgramClass a created @sigma/edge-curve program class */ +function createCurveHaloProgram(CurveProgramClass) { + return class CurveHaloProgram extends CurveProgramClass { + processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) { + const haloWidth = data.haloWidth > 0 ? data.haloWidth : 0; + // The curve shader clamps thickness up to minEdgeThickness, so a zero + // size cannot fully disable it — pair a hairline size with a fully + // transparent color instead (fragments blend to nothing). + const size = haloWidth > 0 ? (data.size || 1) + 2 * haloWidth : 0.001; + const color = haloWidth > 0 ? (data.haloColor ?? data.color) : TRANSPARENT; + super.processVisibleItem(edgeIndex, startIndex, sourceData, targetData, { + ...data, + size, + color, + }); + } + }; +} + +// --------------------------------------------------------------------------- +// Parametric marker head. +// +// Geometry: a quad anchored at the marked node's border, extending `length` +// back along the edge (straight) or along the bezier tangent (curved), tip +// side at the node. a_corner ∈ {-1,1}×{0,1} spans it as two triangles. +// All lengths are computed in graph px and converted with sigma's stock +// arrow-head convention (px → pre-matrix units = ×2·correctionRatio/sizeRatio). +// Default (markerSize 0) proportions match sigma's arrow: length 2.5×, full +// width 2× the edge thickness. +// --------------------------------------------------------------------------- + +// language=GLSL +const MARKER_VERTEX_SHADER = /*glsl*/ ` +attribute vec2 a_position; +attribute vec2 a_normal; +attribute float a_radius; +attribute float a_marker; +attribute float a_markerSize; +attribute vec2 a_corner; + +#ifdef PICKING_MODE +attribute vec4 a_id; +#else +attribute vec4 a_color; +#endif + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; +uniform float u_minEdgeThickness; +uniform float u_feather; + +varying vec4 v_color; +varying float v_marker; +varying vec2 v_uv; +varying vec2 v_dimPx; +varying float v_feather; + +const float bias = 255.0 / 254.0; +const float lengthToThicknessRatio = 2.5; +const float widenessToThicknessRatio = 2.0; + +void main() { + float normalLength = length(a_normal); + + if (a_marker < 0.5 || normalLength <= 0.0) { + // No marker on this end: zero-area triangle off-screen -> no fragments. + gl_Position = vec4(2.0, 2.0, 0.0, 1.0); + v_color = vec4(0.0); + v_marker = 0.0; + v_uv = vec2(0.0); + v_dimPx = vec2(1.0); + v_feather = 1.0; + return; + } + + vec2 unitNormal = a_normal / normalLength; + // a_normal = perp(unitAway): recover the direction pointing from the node + // center back along the edge. + vec2 unitAway = vec2(unitNormal.y, -unitNormal.x); + + // Graph-px sizing (normalLength carries the edge thickness). + float thickness = max(normalLength, u_minEdgeThickness * u_sizeRatio); + float len = a_markerSize > 0.0 ? a_markerSize : thickness * lengthToThicknessRatio; + float halfWidth = a_markerSize > 0.0 + ? a_markerSize * 0.5 + : thickness * widenessToThicknessRatio * 0.5; + + float toWebGL = 2.0 * u_correctionRatio / u_sizeRatio; + vec2 pos = a_position + + unitAway * (a_radius + a_corner.y * len) * toWebGL + + unitNormal * (a_corner.x * halfWidth) * toWebGL; + + gl_Position = vec4((u_matrix * vec3(pos, 1)).xy, 0, 1); + + v_uv = a_corner; + v_dimPx = vec2(2.0 * halfWidth, len) / u_sizeRatio; + v_marker = a_marker; + v_feather = u_feather; + + #ifdef PICKING_MODE + v_color = a_id; + #else + v_color = a_color; + #endif + + v_color.a *= bias; +} +`; + +// language=GLSL +const MARKER_FRAGMENT_SHADER = /*glsl*/ ` +precision mediump float; + +varying vec4 v_color; +varying float v_marker; +varying vec2 v_uv; +varying vec2 v_dimPx; +varying float v_feather; + +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +void main(void) { + float w = v_dimPx.x; // full width across the edge (screen px) + float l = v_dimPx.y; // length along the edge; y=0 at the node border + float x = abs(v_uv.x) * w * 0.5; + float y = v_uv.y * l; + float d = 0.0; // approx signed distance (px), positive inside + + if (v_marker < 1.5) { + // arrow: triangle, tip at the node border, base toward the line + d = min(y * 0.5 * w / l - x, l - y); + } else if (v_marker < 2.5) { + // rect + d = min(w * 0.5 - x, min(y, l - y)); + } else if (v_marker < 3.5) { + // diamond + float norm = x / (w * 0.5) + abs(y - l * 0.5) / (l * 0.5); + d = (1.0 - norm) * 0.25 * min(w, l); + } else if (v_marker < 4.5) { + // circle + d = 0.5 * min(w, l) - length(vec2(x, y - l * 0.5)); + } else { + // tee: inhibition bar (⊣) hugging the node border + float barLen = max(l * 0.3, 1.5); + d = min(min(y, barLen - y), w * 0.5 - x); + } + + #ifdef PICKING_MODE + gl_FragColor = d >= 0.0 ? v_color : transparent; + #else + float feather = max(v_feather, 0.001); + float t = smoothstep(-feather * 0.5, feather * 0.5, d); + gl_FragColor = mix(transparent, v_color, t); + #endif +} +`; + +/** + * @param {object} [options] + * @param {"source"|"target"} [options.extremity] + * @param {boolean} [options.curved] orient along the @sigma/edge-curve tangent + * @returns {typeof EdgeProgram} + */ +function createEdgeMarkerHeadProgram({ extremity = "target", curved = false } = {}) { + const isSource = extremity === "source"; + + return class EdgeMarkerHeadProgram extends EdgeProgram { + getDefinition() { + return { + VERTICES: 6, + VERTEX_SHADER_SOURCE: MARKER_VERTEX_SHADER, + FRAGMENT_SHADER_SOURCE: MARKER_FRAGMENT_SHADER, + METHOD: WebGLRenderingContext.TRIANGLES, + UNIFORMS: ["u_matrix", "u_sizeRatio", "u_correctionRatio", "u_minEdgeThickness", "u_feather"], + ATTRIBUTES: [ + { name: "a_position", size: 2, type: FLOAT }, + { name: "a_normal", size: 2, type: FLOAT }, + { name: "a_radius", size: 1, type: FLOAT }, + { name: "a_marker", size: 1, type: FLOAT }, + { name: "a_markerSize", size: 1, type: FLOAT }, + { name: "a_color", size: 4, type: UNSIGNED_BYTE, normalized: true }, + { name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true }, + ], + CONSTANT_ATTRIBUTES: [{ name: "a_corner", size: 2, type: FLOAT }], + CONSTANT_DATA: [ + [-1, 0], + [1, 0], + [1, 1], + [-1, 0], + [1, 1], + [-1, 1], + ], + }; + } + + processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) { + const marked = isSource ? sourceData : targetData; + const marker = (isSource ? data.startMarker : data.endMarker) || 0; + const markerSize = (isSource ? data.startMarkerSize : data.endMarkerSize) || 0; + const thickness = data.size || 1; + + // Direction from the marked node back along the edge. + let awayX; + let awayY; + if (curved) { + const curvature = data.curvature ?? DEFAULT_EDGE_CURVATURE; + const dx = targetData.x - sourceData.x; + const dy = targetData.y - sourceData.y; + // Quadratic control point as @sigma/edge-curve constructs it. + const cpX = (sourceData.x + targetData.x) / 2 - dy * curvature; + const cpY = (sourceData.y + targetData.y) / 2 + dx * curvature; + awayX = cpX - marked.x; + awayY = cpY - marked.y; + } else { + const other = isSource ? targetData : sourceData; + awayX = other.x - marked.x; + awayY = other.y - marked.y; + } + + const len = Math.sqrt(awayX * awayX + awayY * awayY); + let n1 = 0; + let n2 = 0; + if (len > 0) { + // a_normal = perp(unitAway) × thickness (the shader recovers both axes). + n1 = (-awayY / len) * thickness; + n2 = (awayX / len) * thickness; + } + + const array = this.array; + array[startIndex++] = marked.x; + array[startIndex++] = marked.y; + array[startIndex++] = n1; + array[startIndex++] = n2; + array[startIndex++] = marked.size || 1; + array[startIndex++] = marker; + array[startIndex++] = markerSize; + array[startIndex++] = floatColor(data.color); + array[startIndex++] = edgeIndex; + } + + setUniforms(params, { gl, uniformLocations }) { + gl.uniformMatrix3fv(uniformLocations.u_matrix, false, params.matrix); + gl.uniform1f(uniformLocations.u_sizeRatio, params.sizeRatio); + gl.uniform1f(uniformLocations.u_correctionRatio, params.correctionRatio); + gl.uniform1f(uniformLocations.u_minEdgeThickness, params.minEdgeThickness); + gl.uniform1f(uniformLocations.u_feather, params.antiAliasingFeather); + } + }; +} + +export { EdgeHaloProgram, createCurveHaloProgram, createEdgeMarkerHeadProgram }; diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index ef49305..f158f39 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -174,24 +174,82 @@ function labelStyleAttributes(style) { } /** - * Sigma edge program key for a G6 edge type + arrow flags. + * Edge end-marker vocabulary. The numeric codes are the `startMarker` / + * `endMarker` float attrs consumed by the WebGL marker-head program + * (edge_programs.js), which selects the SDF in its fragment shader: + * arrow (directional triangle), rect, diamond, circle, + * tee (⊣ inhibition bar, pharmacology-style). + * Legacy G6 arrow-type names map onto the nearest new marker so old files + * keep rendering; the original string still round-trips via the edge style. + */ +const EDGE_MARKERS = { arrow: 1, rect: 2, diamond: 3, circle: 4, tee: 5 }; +const LEGACY_MARKER_ALIASES = { + triangle: "arrow", + vee: "arrow", + simple: "arrow", + triangleRect: "rect", + square: "rect", +}; + +/** @returns {number} marker code for an arrow-type string (unknown → arrow) */ +function edgeMarkerCode(arrowType) { + const name = LEGACY_MARKER_ALIASES[arrowType] ?? arrowType; + return EDGE_MARKERS[name] ?? EDGE_MARKERS.arrow; +} + +/** Effective halo width in px: 0 unless halo is enabled with a positive width. */ +function edgeHaloWidth(style) { + const width = style.haloLineWidth ?? DEFAULTS.EDGE.HALO.WIDTH; + return style.halo && width > 0 ? width : 0; +} + +/** + * Sigma edge program key for a G6 edge type + marker/halo styling. + * Two parametric programs per curvature: the plain fast path ("line"/"curve") + * for the unstyled majority, and the compound halo+line+marker-heads program + * ("styledLine"/"styledCurve") whenever any end marker or halo is active — + * the per-edge attrs (start/endMarker, haloWidth, ...) parameterize it, so + * the registry never grows with the marker vocabulary. * Degradations (documented in API.md §5): `polyline` renders as a curve, - * `lineDash` is dropped, arrow head shapes all render as triangles. + * `lineDash` is dropped. */ function sigmaEdgeType(type, style = {}) { const curved = type === "cubic" || type === "quadratic" || type === "polyline"; - const start = Boolean(style.startArrow); - const end = Boolean(style.endArrow); - if (start && end) return curved ? "curvedDoubleArrow" : "doubleArrow"; - if (end) return curved ? "curvedArrow" : "arrow"; - if (start) return curved ? "curvedSourceArrow" : "sourceArrow"; - return curved ? "curve" : "line"; + const styled = Boolean(style.startArrow) || Boolean(style.endArrow) || edgeHaloWidth(style) > 0; + if (curved) return styled ? "styledCurve" : "curve"; + return styled ? "styledLine" : "line"; +} + +/** + * Marker + halo attrs read by the custom edge programs. Always emits the + * FULL set (off → 0/null): the adapter applies updates via + * mergeEdgeAttributes, so every toggle must overwrite what the previous + * style set or stale markers/halos survive a disable. Sizes are graph-space + * px (G6 arrow-size heritage); 0 means "derive from edge thickness" (sigma + * stock-arrow proportions). + */ +function edgeMarkerHaloAttributes(style) { + const haloWidth = edgeHaloWidth(style); + return { + startMarker: style.startArrow ? edgeMarkerCode(style.startArrowType) : 0, + startMarkerSize: + Number.isFinite(style.startArrowSize) && style.startArrowSize > 0 ? style.startArrowSize : 0, + endMarker: style.endArrow ? edgeMarkerCode(style.endArrowType) : 0, + endMarkerSize: + Number.isFinite(style.endArrowSize) && style.endArrowSize > 0 ? style.endArrowSize : 0, + haloWidth, + haloColor: haloWidth > 0 ? (style.haloStroke ?? DEFAULTS.EDGE.HALO.COLOR) : null, + }; } /** * Map a G6 edge style + type to sigma edge attributes. * - * @param {object} style G6 edge style ({lineWidth, stroke, *Arrow*, label*, visibility, ...}) + * Like the node mapper, the program-dependent attrs (type + marker/halo set) + * are only emitted when `type` is given — the adapter always maps from the + * merged ref (full style), so the set is complete and coherent there. + * + * @param {object} style G6 edge style ({lineWidth, stroke, *Arrow*, halo*, label*, visibility, ...}) * @param {string} [type] G6 edge type (line|cubic|quadratic|polyline) * @returns {object} partial sigma attrs */ @@ -208,7 +266,10 @@ function edgeAttributesFromStyle(style = {}, type = undefined) { if (style.visibility !== undefined) { attrs.hidden = style.visibility === "hidden"; } - if (type !== undefined) attrs.type = sigmaEdgeType(type, style); + if (type !== undefined) { + attrs.type = sigmaEdgeType(type, style); + Object.assign(attrs, edgeMarkerHaloAttributes(style)); + } return attrs; } @@ -373,8 +434,10 @@ function makeNodeReducer(cache, elementStates, hoverIds = new Set()) { /** * Sigma edgeReducer factory. An edge is hidden when its own `hidden` attr is * set OR either endpoint is hidden/filtered. States: selected = accent + - * widened (the halo budget — sigma edges have no underdraw), highlight = - * accent, dim = de-emphasis color. + * widened (the emphasis budget), highlight = accent, dim = de-emphasis color. + * User halos compose with selection by construction: the halo program derives + * its width from the post-reducer `size` (+ 2 × haloWidth), so a selected + * edge's halo widens with the line while keeping its own color. * * @param {object} cache needs edgeRef and graphData (the live graphology graph) * @param {Map} elementStates @@ -415,6 +478,8 @@ export { nodeAttributesFromStyle, edgeAttributesFromStyle, sigmaEdgeType, + edgeMarkerCode, + EDGE_MARKERS, flipY, hoverNeighborhood, makeNodeReducer, diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 4cbfc26..c9a1c49 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -11,9 +11,6 @@ import { Sigma, exportImage, EdgeRectangleProgram, - EdgeArrowProgram, - EdgeDoubleArrowProgram, - createEdgeArrowHeadProgram, createEdgeCompoundProgram, drawDiscNodeHover, NodeSquareProgram, @@ -21,6 +18,11 @@ import { nodeImage, edgeCurve, } from "../lib/sigma.bundle.mjs"; +import { + EdgeHaloProgram, + createCurveHaloProgram, + createEdgeMarkerHeadProgram, +} from "./edge_programs.js"; import { nodeAttributesFromStyle, edgeAttributesFromStyle, flipY } from "./graph_model.js"; import { executeLayout } from "./layout_algorithms.js"; import { drawNodeLabel, drawEdgeLabel } from "./label_renderers.js"; @@ -64,8 +66,13 @@ function guardHoverDrawer(drawer, getDraggedNode) { * Nodes: circle native, square via @sigma/node-square, bordered circles via * @sigma/node-border ("borderCircle"); every other shape — and any bordered * non-circle or haloed node — uses the SVG texture program ("shape"). - * Edges: straight programs are sigma built-ins; curved ones come from - * @sigma/edge-curve (cubic/quadratic/polyline all map to one curve type). + * Edges: two parametric programs per curvature (graph_model.sigmaEdgeType + * routes): "line"/"curve" are the plain fast paths for unstyled edges; + * "styledLine"/"styledCurve" compose halo-under → body → marker heads + * (compound programs draw in array order) and are fully parameterized by + * per-edge attrs (startMarker/endMarker enum + sizes, haloWidth/haloColor) — + * no registry growth per marker shape or halo toggle. Off states collapse to + * degenerate geometry in the custom programs (see edge_programs.js). * * @param {() => string|null} getDraggedNode hover-guard input (see * guardHoverDrawer); NodeSquareProgram carries its own instance drawHover @@ -117,10 +124,12 @@ function buildProgramRegistry(getDraggedNode) { { size: { fill: true }, color: { attribute: "color" } }, ], }); - const curveOptions = (extremity) => ({ - arrowHead: extremity - ? { ...edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS.arrowHead, extremity } - : null, + // One curve class serves both the plain "curve" type and the body/halo + // sub-programs of "styledCurve" (each gets its own instance + buffers). + // arrowHead stays null: end markers are drawn by the parametric marker-head + // sub-programs, oriented along the same bezier tangent. + const curveProgram = edgeCurve.createEdgeCurveProgram({ + arrowHead: null, drawLabel: drawCurvedEdgeLabelWithSize, }); return { @@ -131,16 +140,22 @@ function buildProgramRegistry(getDraggedNode) { }, edgeProgramClasses: { line: EdgeRectangleProgram, - arrow: EdgeArrowProgram, - sourceArrow: createEdgeCompoundProgram([ + styledLine: createEdgeCompoundProgram([ + EdgeHaloProgram, EdgeRectangleProgram, - createEdgeArrowHeadProgram({ extremity: "source" }), + createEdgeMarkerHeadProgram({ extremity: "source" }), + createEdgeMarkerHeadProgram({ extremity: "target" }), ]), - doubleArrow: EdgeDoubleArrowProgram, - curve: edgeCurve.createEdgeCurveProgram(curveOptions(null)), - curvedArrow: edgeCurve.createEdgeCurveProgram(curveOptions("target")), - curvedSourceArrow: edgeCurve.createEdgeCurveProgram(curveOptions("source")), - curvedDoubleArrow: edgeCurve.createEdgeCurveProgram(curveOptions("both")), + curve: curveProgram, + styledCurve: createEdgeCompoundProgram( + [ + createCurveHaloProgram(curveProgram), + curveProgram, + createEdgeMarkerHeadProgram({ extremity: "source", curved: true }), + createEdgeMarkerHeadProgram({ extremity: "target", curved: true }), + ], + drawCurvedEdgeLabelWithSize, + ), }, }; } diff --git a/src/lib/sigma.bundle.mjs b/src/lib/sigma.bundle.mjs index c8c4771..967310f 100644 --- a/src/lib/sigma.bundle.mjs +++ b/src/lib/sigma.bundle.mjs @@ -1,8 +1,8 @@ -var Ri=Object.create;var yt=Object.defineProperty;var wi=Object.getOwnPropertyDescriptor;var xi=Object.getOwnPropertyNames;var Ci=Object.getPrototypeOf,Si=Object.prototype.hasOwnProperty;var bt=(t,r)=>()=>(r||t((r={exports:{}}).exports,r),r.exports),_t=(t,r)=>{for(var n in r)yt(t,n,{get:r[n],enumerable:!0})},Ai=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of xi(r))!Si.call(t,i)&&i!==n&&yt(t,i,{get:()=>r[i],enumerable:!(e=wi(r,i))||e.enumerable});return t};var ve=(t,r,n)=>(n=t!=null?Ri(Ci(t)):{},Ai(r||!t||!t.__esModule?yt(n,"default",{value:t,enumerable:!0}):n,t));var Qe=bt((Ts,Nt)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,Br=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},Ke;we&&typeof we.ownKeys=="function"?Ke=we.ownKeys:Object.getOwnPropertySymbols?Ke=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:Ke=function(r){return Object.getOwnPropertyNames(r)};function na(t){console&&console.warn&&console.warn(t)}var Hr=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}Nt.exports=B;Nt.exports.once=sa;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var jr=10;function Ze(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return jr},set:function(t){if(typeof t!="number"||t<0||Hr(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");jr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Hr(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Vr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Vr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")Br(u,this,n);else for(var l=u.length,c=$r(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,na(s)}return t}B.prototype.addListener=function(r,n){return Wr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Wr(this,r,n,!0)};function ia(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Xr(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=ia.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return Ze(n),this.on(r,Xr(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return Ze(n),this.prependListener(r,Xr(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(Ze(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():aa(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function Yr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?oa(i):$r(i,i.length)}B.prototype.listeners=function(r){return Yr(this,r,!0)};B.prototype.rawListeners=function(r){return Yr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):qr.call(t,r)};B.prototype.listenerCount=qr;function qr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?Ke(this._events):[]};function $r(t,r){for(var n=new Array(r),e=0;e{Qr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var di=bt((ur,lr)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof ur<"u"?r():(r(),t.FileSaver={})})(ur,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,h=document.createElement("a");u=u||s.name||"download",h.download=u,h.rel="noopener",typeof s=="string"?(h.href=s,h.origin===location.origin?e(h):n(h.href)?r(s,u,l):e(h,h.target="_blank")):(h.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(h.href)},4e4),setTimeout(function(){e(h)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var h=s.type==="application/octet-stream",v=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||h&&v||a)&&typeof FileReader<"u"){var _=new FileReader;_.onloadend=function(){var E=_.result;E=y?E:E.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=E:location=E,c=null},_.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof lr<"u"&&(lr.exports=o)})});function Li(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function me(t){var r=Li(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function yr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>8&255,a=n>>16&255,o=n>>24&255;return[e,i,a,o]}var Tt={};function Ue(t){if(typeof Tt[t]<"u")return Tt[t];var r=(t&16711680)>>>16,n=(t&65280)>>>8,e=t&255,i=255,a=wt(r,n,e,i,!0);return Tt[t]=a,a}function Be(t,r,n,e){return n+(r<<8)+(t<<16)}function je(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=le(u,4),c=l[0],h=l[1],v=l[2],y=l[3];return[c,h,v,y]}function x(t,r,n){return(r=me(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Rr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function P(t){for(var r=1;r()=>(r||t((r={exports:{}}).exports,r),r.exports),bt=(t,r)=>{for(var n in r)pt(t,n,{get:r[n],enumerable:!0})},Ai=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of xi(r))!Si.call(t,i)&&i!==n&&pt(t,i,{get:()=>r[i],enumerable:!(e=wi(r,i))||e.enumerable});return t};var ve=(t,r,n)=>(n=t!=null?Ri(Ci(t)):{},Ai(r||!t||!t.__esModule?pt(n,"default",{value:t,enumerable:!0}):n,t));var Ze=yt((_s,Nt)=>{"use strict";var we=typeof Reflect=="object"?Reflect:null,Br=we&&typeof we.apply=="function"?we.apply:function(r,n,e){return Function.prototype.apply.call(r,n,e)},$e;we&&typeof we.ownKeys=="function"?$e=we.ownKeys:Object.getOwnPropertySymbols?$e=function(r){return Object.getOwnPropertyNames(r).concat(Object.getOwnPropertySymbols(r))}:$e=function(r){return Object.getOwnPropertyNames(r)};function na(t){console&&console.warn&&console.warn(t)}var Hr=Number.isNaN||function(r){return r!==r};function B(){B.init.call(this)}Nt.exports=B;Nt.exports.once=sa;B.EventEmitter=B;B.prototype._events=void 0;B.prototype._eventsCount=0;B.prototype._maxListeners=void 0;var jr=10;function Ke(t){if(typeof t!="function")throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}Object.defineProperty(B,"defaultMaxListeners",{enumerable:!0,get:function(){return jr},set:function(t){if(typeof t!="number"||t<0||Hr(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");jr=t}});B.init=function(){(this._events===void 0||this._events===Object.getPrototypeOf(this)._events)&&(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0};B.prototype.setMaxListeners=function(r){if(typeof r!="number"||r<0||Hr(r))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+r+".");return this._maxListeners=r,this};function Vr(t){return t._maxListeners===void 0?B.defaultMaxListeners:t._maxListeners}B.prototype.getMaxListeners=function(){return Vr(this)};B.prototype.emit=function(r){for(var n=[],e=1;e0&&(o=n[0]),o instanceof Error)throw o;var s=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw s.context=o,s}var u=a[r];if(u===void 0)return!1;if(typeof u=="function")Br(u,this,n);else for(var l=u.length,c=$r(u,l),e=0;e0&&o.length>i&&!o.warned){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(r)+" listeners added. Use emitter.setMaxListeners() to increase limit");s.name="MaxListenersExceededWarning",s.emitter=t,s.type=r,s.count=o.length,na(s)}return t}B.prototype.addListener=function(r,n){return Wr(this,r,n,!1)};B.prototype.on=B.prototype.addListener;B.prototype.prependListener=function(r,n){return Wr(this,r,n,!0)};function ia(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length===0?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function Xr(t,r,n){var e={fired:!1,wrapFn:void 0,target:t,type:r,listener:n},i=ia.bind(e);return i.listener=n,e.wrapFn=i,i}B.prototype.once=function(r,n){return Ke(n),this.on(r,Xr(this,r,n)),this};B.prototype.prependOnceListener=function(r,n){return Ke(n),this.prependListener(r,Xr(this,r,n)),this};B.prototype.removeListener=function(r,n){var e,i,a,o,s;if(Ke(n),i=this._events,i===void 0)return this;if(e=i[r],e===void 0)return this;if(e===n||e.listener===n)--this._eventsCount===0?this._events=Object.create(null):(delete i[r],i.removeListener&&this.emit("removeListener",r,e.listener||n));else if(typeof e!="function"){for(a=-1,o=e.length-1;o>=0;o--)if(e[o]===n||e[o].listener===n){s=e[o].listener,a=o;break}if(a<0)return this;a===0?e.shift():aa(e,a),e.length===1&&(i[r]=e[0]),i.removeListener!==void 0&&this.emit("removeListener",r,s||n)}return this};B.prototype.off=B.prototype.removeListener;B.prototype.removeAllListeners=function(r){var n,e,i;if(e=this._events,e===void 0)return this;if(e.removeListener===void 0)return arguments.length===0?(this._events=Object.create(null),this._eventsCount=0):e[r]!==void 0&&(--this._eventsCount===0?this._events=Object.create(null):delete e[r]),this;if(arguments.length===0){var a=Object.keys(e),o;for(i=0;i=0;i--)this.removeListener(r,n[i]);return this};function Yr(t,r,n){var e=t._events;if(e===void 0)return[];var i=e[r];return i===void 0?[]:typeof i=="function"?n?[i.listener||i]:[i]:n?oa(i):$r(i,i.length)}B.prototype.listeners=function(r){return Yr(this,r,!0)};B.prototype.rawListeners=function(r){return Yr(this,r,!1)};B.listenerCount=function(t,r){return typeof t.listenerCount=="function"?t.listenerCount(r):qr.call(t,r)};B.prototype.listenerCount=qr;function qr(t){var r=this._events;if(r!==void 0){var n=r[t];if(typeof n=="function")return 1;if(n!==void 0)return n.length}return 0}B.prototype.eventNames=function(){return this._eventsCount>0?$e(this._events):[]};function $r(t,r){for(var n=new Array(r),e=0;e{Qr.exports=function(r){return r!==null&&typeof r=="object"&&typeof r.addUndirectedEdgeWithKey=="function"&&typeof r.dropNode=="function"&&typeof r.multi=="boolean"}});var di=yt((ur,lr)=>{(function(t,r){typeof define=="function"&&define.amd?define([],r):typeof ur<"u"?r():(r(),t.FileSaver={})})(ur,function(){"use strict";function t(s,u){return typeof u>"u"?u={autoBom:!1}:typeof u!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),u={autoBom:!u}),u.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(s.type)?new Blob(["\uFEFF",s],{type:s.type}):s}function r(s,u,l){var c=new XMLHttpRequest;c.open("GET",s),c.responseType="blob",c.onload=function(){o(c.response,u,l)},c.onerror=function(){console.error("could not download file")},c.send()}function n(s){var u=new XMLHttpRequest;u.open("HEAD",s,!1);try{u.send()}catch{}return 200<=u.status&&299>=u.status}function e(s){try{s.dispatchEvent(new MouseEvent("click"))}catch{var u=document.createEvent("MouseEvents");u.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),s.dispatchEvent(u)}}var i=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,a=i.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=i.saveAs||(typeof window!="object"||window!==i?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(s,u,l){var c=i.URL||i.webkitURL,h=document.createElement("a");u=u||s.name||"download",h.download=u,h.rel="noopener",typeof s=="string"?(h.href=s,h.origin===location.origin?e(h):n(h.href)?r(s,u,l):e(h,h.target="_blank")):(h.href=c.createObjectURL(s),setTimeout(function(){c.revokeObjectURL(h.href)},4e4),setTimeout(function(){e(h)},0))}:"msSaveOrOpenBlob"in navigator?function(s,u,l){if(u=u||s.name||"download",typeof s!="string")navigator.msSaveOrOpenBlob(t(s,l),u);else if(n(s))r(s,u,l);else{var c=document.createElement("a");c.href=s,c.target="_blank",setTimeout(function(){e(c)})}}:function(s,u,l,c){if(c=c||open("","_blank"),c&&(c.document.title=c.document.body.innerText="downloading..."),typeof s=="string")return r(s,u,l);var h=s.type==="application/octet-stream",v=/constructor/i.test(i.HTMLElement)||i.safari,y=/CriOS\/[\d]+/.test(navigator.userAgent);if((y||h&&v||a)&&typeof FileReader<"u"){var _=new FileReader;_.onloadend=function(){var E=_.result;E=y?E:E.replace(/^data:[^;]*;/,"data:attachment/file;"),c?c.location.href=E:location=E,c=null},_.readAsDataURL(s)}else{var p=i.URL||i.webkitURL,T=p.createObjectURL(s);c?c.location=T:location.href=T,c=null,setTimeout(function(){p.revokeObjectURL(T)},4e4)}});i.saveAs=o.saveAs=o,typeof lr<"u"&&(lr.exports=o)})});function Li(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function me(t){var r=Li(t,"string");return typeof r=="symbol"?r:r+""}function W(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function yr(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);n>8&255,a=n>>16&255,o=n>>24&255;return[e,i,a,o]}var Et={};function Ue(t){if(typeof Et[t]<"u")return Et[t];var r=(t&16711680)>>>16,n=(t&65280)>>>8,e=t&255,i=255,a=Rt(r,n,e,i,!0);return Et[t]=a,a}function Be(t,r,n,e){return n+(r<<8)+(t<<16)}function je(t,r,n,e,i,a){var o=Math.floor(n/a*i),s=Math.floor(t.drawingBufferHeight/a-e/a*i),u=new Uint8Array(4);t.bindFramebuffer(t.FRAMEBUFFER,r),t.readPixels(o,s,1,1,t.RGBA,t.UNSIGNED_BYTE,u);var l=ce(u,4),c=l[0],h=l[1],v=l[2],y=l[3];return[c,h,v,y]}function x(t,r,n){return(r=me(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function Rr(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function P(t){for(var r=1;rw){var A="\u2026";for(l=l+A,O=t.measureText(l).width;O>w&&l.length>1;)l=l.slice(0,-2)+A,O=t.measureText(l).width;if(l.length<4)return}var C;b>0?m>0?C=Math.acos(b/w):C=Math.asin(m/w):m>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,E),t.rotate(C),t.fillText(l,-O/2,r.size/2+a),t.restore()}}}function Te(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function Xe(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,h=Math.asin(l/2/c),v=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+v,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+v,r.y-l/2),t.arc(r.x,r.y,c,h,-h),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Te(t,r,n)}var Mi=` +`).concat(n))}return i}function Nr(t,r){return Or("VERTEX",t,r)}function kr(t,r){return Or("FRAGMENT",t,r)}function Dr(t,r){var n=t.createProgram();if(n===null)throw new Error("loadProgram: error while creating the program.");var e,i;for(e=0,i=r.length;ew){var A="\u2026";for(l=l+A,O=t.measureText(l).width;O>w&&l.length>1;)l=l.slice(0,-2)+A,O=t.measureText(l).width;if(l.length<4)return}var C;b>0?m>0?C=Math.acos(b/w):C=Math.asin(m/w):m>0?C=Math.acos(b/w)+Math.PI:C=Math.asin(b/w)+Math.PI/2,t.save(),t.translate(T,E),t.rotate(C),t.fillText(l,-O/2,r.size/2+a),t.restore()}}}function Ee(t,r,n){if(r.label){var e=n.labelSize,i=n.labelFont,a=n.labelWeight,o=n.labelColor.attribute?r[n.labelColor.attribute]||n.labelColor.color||"#000":n.labelColor.color;t.fillStyle=o,t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillText(r.label,r.x+r.size+3,r.y+e/3)}}function Xe(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o,h=Math.asin(l/2/c),v=Math.sqrt(Math.abs(Math.pow(c,2)-Math.pow(l/2,2)));t.beginPath(),t.moveTo(r.x+v,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+v,r.y-l/2),t.arc(r.x,r.y,c,h,-h),t.closePath(),t.fill()}else t.beginPath(),t.arc(r.x,r.y,r.size+o,0,Math.PI*2),t.closePath(),t.fill();t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Ee(t,r,n)}var Mi=` precision highp float; varying vec4 v_color; @@ -75,7 +75,7 @@ void main() { v_color.a *= bias; } -`,ji=Bi,Fr=WebGLRenderingContext,xr=Fr.UNSIGNED_BYTE,Ct=Fr.FLOAT,Hi=["u_sizeRatio","u_correctionRatio","u_matrix"],Re=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:ji,FRAGMENT_SHADER_SOURCE:Ui,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Hi,ATTRIBUTES:[{name:"a_position",size:2,type:Ct},{name:"a_size",size:1,type:Ct},{name:"a_color",size:4,type:xr,normalized:!0},{name:"a_id",size:4,type:xr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Ct}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Y(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(ie);x(Re,"ANGLE_1",0);x(Re,"ANGLE_2",2*Math.PI/3);x(Re,"ANGLE_3",4*Math.PI/3);var Vi=` +`,ji=Bi,Fr=WebGLRenderingContext,xr=Fr.UNSIGNED_BYTE,xt=Fr.FLOAT,Hi=["u_sizeRatio","u_correctionRatio","u_matrix"],Te=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:ji,FRAGMENT_SHADER_SOURCE:Ui,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Hi,ATTRIBUTES:[{name:"a_position",size:2,type:xt},{name:"a_size",size:1,type:xt},{name:"a_color",size:4,type:xr,normalized:!0},{name:"a_id",size:4,type:xr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:xt}],CONSTANT_DATA:[[r.ANGLE_1],[r.ANGLE_2],[r.ANGLE_3]]}}},{key:"processVisibleItem",value:function(e,i,a){var o=this.array,s=Y(a.color);o[i++]=a.x,o[i++]=a.y,o[i++]=a.size,o[i++]=s,o[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_sizeRatio,u=o.u_correctionRatio,l=o.u_matrix;a.uniform1f(u,e.correctionRatio),a.uniform1f(s,e.sizeRatio),a.uniformMatrix3fv(l,!1,e.matrix)}}])})(ie);x(Te,"ANGLE_1",0);x(Te,"ANGLE_2",2*Math.PI/3);x(Te,"ANGLE_3",4*Math.PI/3);var Vi=` precision mediump float; varying vec4 v_color; @@ -149,7 +149,7 @@ void main() { v_color.a *= bias; } -`,Yi=Xi,Ir=WebGLRenderingContext,Cr=Ir.UNSIGNED_BYTE,He=Ir.FLOAT,qi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],he={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function ye(t){var r=P(P({},he),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Yi,FRAGMENT_SHADER_SOURCE:Wi,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:qi,ATTRIBUTES:[{name:"a_position",size:2,type:He},{name:"a_normal",size:2,type:He},{name:"a_radius",size:1,type:He},{name:"a_color",size:4,type:Cr,normalized:!0},{name:"a_id",size:4,type:Cr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:He}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var h=l.size||1,v=u.size||1,y=s.x,_=s.y,p=u.x,T=u.y,E=Y(l.color),b=p-y,m=T-_,w=b*b+m*m,O=0,A=0;w&&(w=1/Math.sqrt(w),O=-m*w*h,A=b*w*h);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-O,C[o++]=-A,C[o++]=v,C[o++]=E,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,h=u.u_correctionRatio,v=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,_=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(h,a.correctionRatio),s.uniform1f(v,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(_,r.widenessToThicknessRatio)}}])})(ce)}var bs=ye();var $i=` +`,Yi=Xi,Ir=WebGLRenderingContext,Cr=Ir.UNSIGNED_BYTE,He=Ir.FLOAT,qi=["u_matrix","u_sizeRatio","u_correctionRatio","u_minEdgeThickness","u_lengthToThicknessRatio","u_widenessToThicknessRatio"],he={extremity:"target",lengthToThicknessRatio:2.5,widenessToThicknessRatio:2};function Re(t){var r=P(P({},he),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Yi,FRAGMENT_SHADER_SOURCE:Wi,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:qi,ATTRIBUTES:[{name:"a_position",size:2,type:He},{name:"a_normal",size:2,type:He},{name:"a_radius",size:1,type:He},{name:"a_color",size:4,type:Cr,normalized:!0},{name:"a_id",size:4,type:Cr,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_barycentric",size:3,type:He}],CONSTANT_DATA:[[1,0,0],[0,1,0],[0,0,1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){if(r.extremity==="source"){var c=[u,s];s=c[0],u=c[1]}var h=l.size||1,v=u.size||1,y=s.x,_=s.y,p=u.x,T=u.y,E=Y(l.color),b=p-y,m=T-_,w=b*b+m*m,O=0,A=0;w&&(w=1/Math.sqrt(w),O=-m*w*h,A=b*w*h);var C=this.array;C[o++]=p,C[o++]=T,C[o++]=-O,C[o++]=-A,C[o++]=v,C[o++]=E,C[o++]=a}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_sizeRatio,h=u.u_correctionRatio,v=u.u_minEdgeThickness,y=u.u_lengthToThicknessRatio,_=u.u_widenessToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.sizeRatio),s.uniform1f(h,a.correctionRatio),s.uniform1f(v,a.minEdgeThickness),s.uniform1f(y,r.lengthToThicknessRatio),s.uniform1f(_,r.widenessToThicknessRatio)}}])})(ae)}var ps=Re();var $i=` precision mediump float; varying vec4 v_color; @@ -243,7 +243,7 @@ void main() { v_color.a *= bias; } -`,Zi=Ki,zr=WebGLRenderingContext,Sr=zr.UNSIGNED_BYTE,pe=zr.FLOAT,Qi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Gr={lengthToThicknessRatio:he.lengthToThicknessRatio};function Ot(t){var r=P(P({},Gr),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Zi,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Qi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:pe},{name:"a_positionEnd",size:2,type:pe},{name:"a_normal",size:2,type:pe},{name:"a_color",size:4,type:Sr,normalized:!0},{name:"a_id",size:4,type:Sr,normalized:!0},{name:"a_radius",size:1,type:pe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:pe},{name:"a_normalCoef",size:1,type:pe},{name:"a_radiusCoef",size:1,type:pe}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,h=s.x,v=s.y,y=u.x,_=u.y,p=Y(l.color),T=y-h,E=_-v,b=u.size||1,m=T*T+E*E,w=0,O=0;m&&(m=1/Math.sqrt(m),w=-E*m*c,O=T*m*c);var A=this.array;A[o++]=h,A[o++]=v,A[o++]=y,A[o++]=_,A[o++]=w,A[o++]=O,A[o++]=p,A[o++]=a,A[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,h=u.u_feather,v=u.u_pixelRatio,y=u.u_correctionRatio,_=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(_,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(v,a.pixelRatio),s.uniform1f(h,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(ce)}var _s=Ot();function Mr(t){return Ne([Ot(t),ye(t)])}var Ji=Mr(),qe=Ji,ea=` +`,Zi=Ki,zr=WebGLRenderingContext,Sr=zr.UNSIGNED_BYTE,pe=zr.FLOAT,Qi=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Gr={lengthToThicknessRatio:he.lengthToThicknessRatio};function Pt(t){var r=P(P({},Gr),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Zi,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Qi,ATTRIBUTES:[{name:"a_positionStart",size:2,type:pe},{name:"a_positionEnd",size:2,type:pe},{name:"a_normal",size:2,type:pe},{name:"a_color",size:4,type:Sr,normalized:!0},{name:"a_id",size:4,type:Sr,normalized:!0},{name:"a_radius",size:1,type:pe}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:pe},{name:"a_normalCoef",size:1,type:pe},{name:"a_radiusCoef",size:1,type:pe}],CONSTANT_DATA:[[0,1,0],[0,-1,0],[1,1,1],[1,1,1],[0,-1,0],[1,-1,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,h=s.x,v=s.y,y=u.x,_=u.y,p=Y(l.color),T=y-h,E=_-v,b=u.size||1,m=T*T+E*E,w=0,O=0;m&&(m=1/Math.sqrt(m),w=-E*m*c,O=T*m*c);var A=this.array;A[o++]=h,A[o++]=v,A[o++]=y,A[o++]=_,A[o++]=w,A[o++]=O,A[o++]=p,A[o++]=a,A[o++]=b}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,h=u.u_feather,v=u.u_pixelRatio,y=u.u_correctionRatio,_=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(_,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(v,a.pixelRatio),s.uniform1f(h,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(ae)}var ys=Pt();function Mr(t){return Ne([Pt(t),Re(t)])}var Ji=Mr(),Ot=Ji,ea=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -308,8 +308,8 @@ void main() { v_color.a *= bias; } -`,ta=ea,Ur=WebGLRenderingContext,Ar=Ur.UNSIGNED_BYTE,Oe=Ur.FLOAT,ra=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],$e=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ta,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ra,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Oe},{name:"a_positionEnd",size:2,type:Oe},{name:"a_normal",size:2,type:Oe},{name:"a_color",size:4,type:Ar,normalized:!0},{name:"a_id",size:4,type:Ar,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Oe},{name:"a_normalCoef",size:1,type:Oe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,h=o.x,v=o.y,y=Y(s.color),_=h-l,p=v-c,T=_*_+p*p,E=0,b=0;T&&(T=1/Math.sqrt(T),E=-p*T*u,b=_*T*u);var m=this.array;m[i++]=l,m[i++]=c,m[i++]=h,m[i++]=v,m[i++]=E,m[i++]=b,m[i++]=y,m[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,h=o.u_correctionRatio,v=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(v,e.sizeRatio),a.uniform1f(h,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(ce);var Zr=ve(Qe()),Je=(function(t){function r(){var n;return W(this,r),n=$(this,r),n.rawEmitter=n,n}return K(r,t),X(r)})(Zr.EventEmitter);var tn=ve(et());var la=function(r){return r},ca=function(r){return r*r},ha=function(r){return r*(2-r)},fa=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},da=function(r){return r*r*r},va=function(r){return--r*r*r+1},ga=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},rn={linear:la,quadraticIn:ca,quadraticOut:ha,quadraticInOut:fa,cubicIn:da,cubicOut:va,cubicInOut:ga},nn={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function tt(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function Jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function en(t,r,n){return t[6]=r,t[7]=n,t}function fe(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],h=r[0],v=r[1],y=r[2],_=r[3],p=r[4],T=r[5],E=r[6],b=r[7],m=r[8];return t[0]=h*n+v*a+y*u,t[1]=h*e+v*o+y*l,t[2]=h*i+v*s+y*c,t[3]=_*n+p*a+T*u,t[4]=_*e+p*o+T*l,t[5]=_*i+p*s+T*c,t[6]=E*n+b*a+m*u,t[7]=E*e+b*o+m*l,t[8]=E*i+b*s+m*c,t}function rt(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function ma(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,h=te(),v=Math.min(l,c)-2*e,y=ma(r,n);return i?(fe(h,en(te(),s,u)),fe(h,tt(te(),o)),fe(h,Jr(te(),a)),fe(h,tt(te(),l/v/2/y,c/v/2/y))):(fe(h,tt(te(),2*(v/l)*y,2*(v/c)*y)),fe(h,Jr(te(),-a)),fe(h,tt(te(),1/o)),fe(h,en(te(),-s,-u))),h}function an(t,r,n){var e=rt(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function on(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function sn(t){if(!(0,tn.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function un(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function kt(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Dt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Ft(t){var r=le(t.x,2),n=r[0],e=r[1],i=le(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(v){return{x:.5+(v.x-u)/s,y:.5+(v.y-l)/s}};return c.applyTo=function(h){h.x=.5+(h.x-u)/s,h.y=.5+(h.y-l)/s},c.inverse=function(h){return{x:u+s*(h.x-.5),y:l+s*(h.y-.5)}},c.ratio=s,c}function nt(t){"@babel/helpers - typeof";return nt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},nt(t)}function It(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function it(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=P(P({},nn),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:rn[s.easing],c=Date.now(),h=this.getState(),v=function(){var _=(Date.now()-c)/s.duration;if(_>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(_),T={};typeof u.x=="number"&&(T.x=h.x+(u.x-h.x)*p),typeof u.y=="number"&&(T.y=h.y+(u.y-h.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=h.angle+(u.angle-h.angle)*p),typeof u.ratio=="number"&&(T.ratio=h.ratio+(u.ratio-h.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(v)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(v)):v(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||st)},e):this.animate({ratio:this.ratio/st})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||st)},e):this.animate({ratio:this.ratio*st})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Je);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function ae(t,r){var n=P(P({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function ke(t){var r="x"in t?t:P(P({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ba(t,r){return P(P({},ae(t,r)),{},{delta:gn(t)})}var _a=2;function ut(t){for(var r=[],n=0,e=Math.min(t.length,_a);n0;i.draggedEvents=0,h&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",ae(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=ae(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),h=this.renderer.viewportToFramedGraph({x:u,y:l}),v=c.x-h.x,y=c.y-h.y,_=o.getState(),p=_.x+v,T=_.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",ae(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",ae(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=gn(e);if(o){var s=ba(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),h=o>0?1:-1,v=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===h&&this.lastWheelTriggerTime&&v-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),fn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new hn(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(hn.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],h=0;h2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=$(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new fn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Ft({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",kt()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=ln(a),ot(i.settings),sn(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Gt,i.bindCameraHandlers(),i.mouseCaptor=new pn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new xa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return K(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=zt(s,[e].map(me));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=je(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Be.apply(void 0,cn(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",P(P({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",P(P({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",P(P({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=ke(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",P({},s))},this.activeListeners.handleEnter=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",P({},s))};var i=function(o){return function(s){var u=ke(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),P(P({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var h=e.getEdgeAtPoint(u.x,u.y);if(h)return e.emit("".concat(o,"Edge"),P(P({},l),{},{edge:h}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=je(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Be.apply(void 0,cn(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=on(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,h=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(h[0]+h[1])/2-u/2,(h[0]+h[1])/2+u/2]}}this.normalizationFunction=Ft(this.customBBox||this.nodeExtent);var v=new Gt,y=xe(v.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var _={},p={},T={},E={},b=1,m=i.nodes(),w=0,O=m.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=P({},e),l=s||this.nodeExtent,c=le(l.x,2),h=c[0],v=c[1],y=le(l.y,2),_=y[0],p=y[1],T=[this.graphToViewport({x:h,y:_},{cameraState:e}),this.graphToViewport({x:v,y:_},{cameraState:e}),this.graphToViewport({x:h,y:p},{cameraState:e}),this.graphToViewport({x:v,y:p},{cameraState:e})],E=1/0,b=-1/0,m=1/0,w=-1/0;T.forEach(function(U){var H=U.x,f=U.y;E=Math.min(E,H),b=Math.max(b,H),m=Math.min(m,f),w=Math.max(w,f)});var O=b-E,A=w-m,C=this.getDimensions(),D=C.width,k=C.height,I=0,z=0;if(O>=D?bo&&(I=E-o):b>D+o?I=b-(D+o):E<-o&&(I=E+o),A>=k?wo&&(z=m-o):w>k+o?z=w-(k+o):m<-o&&(z=m+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),j=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=j.x-G.x,z=j.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);It(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+dn||v<-vn||v>this.height+vn)){this.displayedNodeLabels.add(u);var _=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||_;T(a,P(P({key:u},l),{},{size:y,x:h,y:v}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=Pa({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});It(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=Na(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new fn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=un(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=P({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return P({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=P({},this.settings);return this.settings[e]=i,ot(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=P({},this.settings);return this.settings=P(P({},this.settings),e),ot(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=kt(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var h=this.textures[l];h&&c.deleteTexture(h)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],h=0,v=c?.length||0;h1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=rt(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=rt(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Je),bn=yn;var En=WebGLRenderingContext,Zs=En.UNSIGNED_BYTE,Qs=En.FLOAT;var ka=` +`,ta=ea,Ur=WebGLRenderingContext,Ar=Ur.UNSIGNED_BYTE,Oe=Ur.FLOAT,ra=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness"],qe=(function(t){function r(){return W(this,r),$(this,r,arguments)}return K(r,t),X(r,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:ta,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:ra,ATTRIBUTES:[{name:"a_positionStart",size:2,type:Oe},{name:"a_positionEnd",size:2,type:Oe},{name:"a_normal",size:2,type:Oe},{name:"a_color",size:4,type:Ar,normalized:!0},{name:"a_id",size:4,type:Ar,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:Oe},{name:"a_normalCoef",size:1,type:Oe}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:"processVisibleItem",value:function(e,i,a,o,s){var u=s.size||1,l=a.x,c=a.y,h=o.x,v=o.y,y=Y(s.color),_=h-l,p=v-c,T=_*_+p*p,E=0,b=0;T&&(T=1/Math.sqrt(T),E=-p*T*u,b=_*T*u);var m=this.array;m[i++]=l,m[i++]=c,m[i++]=h,m[i++]=v,m[i++]=E,m[i++]=b,m[i++]=y,m[i++]=e}},{key:"setUniforms",value:function(e,i){var a=i.gl,o=i.uniformLocations,s=o.u_matrix,u=o.u_zoomRatio,l=o.u_feather,c=o.u_pixelRatio,h=o.u_correctionRatio,v=o.u_sizeRatio,y=o.u_minEdgeThickness;a.uniformMatrix3fv(s,!1,e.matrix),a.uniform1f(u,e.zoomRatio),a.uniform1f(v,e.sizeRatio),a.uniform1f(h,e.correctionRatio),a.uniform1f(c,e.pixelRatio),a.uniform1f(l,e.antiAliasingFeather),a.uniform1f(y,e.minEdgeThickness)}}])})(ae);var Zr=ve(Ze()),Qe=(function(t){function r(){var n;return W(this,r),n=$(this,r),n.rawEmitter=n,n}return K(r,t),X(r)})(Zr.EventEmitter);var tn=ve(Je());var la=function(r){return r},ca=function(r){return r*r},ha=function(r){return r*(2-r)},fa=function(r){return(r*=2)<1?.5*r*r:-.5*(--r*(r-2)-1)},da=function(r){return r*r*r},va=function(r){return--r*r*r+1},ga=function(r){return(r*=2)<1?.5*r*r*r:.5*((r-=2)*r*r+2)},rn={linear:la,quadraticIn:ca,quadraticOut:ha,quadraticInOut:fa,cubicIn:da,cubicOut:va,cubicInOut:ga},nn={easing:"quadraticInOut",duration:150};function te(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function et(t,r,n){return t[0]=r,t[4]=typeof n=="number"?n:r,t}function Jr(t,r){var n=Math.sin(r),e=Math.cos(r);return t[0]=e,t[1]=n,t[3]=-n,t[4]=e,t}function en(t,r,n){return t[6]=r,t[7]=n,t}function fe(t,r){var n=t[0],e=t[1],i=t[2],a=t[3],o=t[4],s=t[5],u=t[6],l=t[7],c=t[8],h=r[0],v=r[1],y=r[2],_=r[3],p=r[4],T=r[5],E=r[6],b=r[7],m=r[8];return t[0]=h*n+v*a+y*u,t[1]=h*e+v*o+y*l,t[2]=h*i+v*s+y*c,t[3]=_*n+p*a+T*u,t[4]=_*e+p*o+T*l,t[5]=_*i+p*s+T*c,t[6]=E*n+b*a+m*u,t[7]=E*e+b*o+m*l,t[8]=E*i+b*s+m*c,t}function tt(t,r){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,e=t[0],i=t[1],a=t[3],o=t[4],s=t[6],u=t[7],l=r.x,c=r.y;return{x:l*e+c*a+s*n,y:l*i+c*o+u*n}}function ma(t,r){var n=t.height/t.width,e=r.height/r.width;return n<1&&e>1||n>1&&e<1?1:Math.min(Math.max(e,1/e),Math.max(1/n,n))}function xe(t,r,n,e,i){var a=t.angle,o=t.ratio,s=t.x,u=t.y,l=r.width,c=r.height,h=te(),v=Math.min(l,c)-2*e,y=ma(r,n);return i?(fe(h,en(te(),s,u)),fe(h,et(te(),o)),fe(h,Jr(te(),a)),fe(h,et(te(),l/v/2/y,c/v/2/y))):(fe(h,et(te(),2*(v/l)*y,2*(v/c)*y)),fe(h,Jr(te(),-a)),fe(h,et(te(),1/o)),fe(h,en(te(),-s,-u))),h}function an(t,r,n){var e=tt(t,{x:Math.cos(r.angle),y:Math.sin(r.angle)},0),i=e.x,a=e.y;return 1/Math.sqrt(Math.pow(i,2)+Math.pow(a,2))/n.width}function on(t){if(!t.order)return{x:[0,1],y:[0,1]};var r=1/0,n=-1/0,e=1/0,i=-1/0;return t.forEachNode(function(a,o){var s=o.x,u=o.y;sn&&(n=s),ui&&(i=u)}),{x:[r,n],y:[e,i]}}function sn(t){if(!(0,tn.default)(t))throw new Error("Sigma: invalid graph instance.");t.forEachNode(function(r,n){if(!Number.isFinite(n.x)||!Number.isFinite(n.y))throw new Error("Sigma: Coordinates of node ".concat(r," are invalid. A node must have a numeric 'x' and 'y' attribute."))})}function un(t,r,n){var e=document.createElement(t);if(r)for(var i in r)e.style[i]=r[i];if(n)for(var a in n)e.setAttribute(a,n[a]);return e}function kt(){return typeof window.devicePixelRatio<"u"?window.devicePixelRatio:1}function Dt(t,r,n){return n.sort(function(e,i){var a=r(e)||0,o=r(i)||0;return ao?1:0})}function Ft(t){var r=ce(t.x,2),n=r[0],e=r[1],i=ce(t.y,2),a=i[0],o=i[1],s=Math.max(e-n,o-a),u=(e+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(u)&&(u=0),isNaN(l)&&(l=0);var c=function(v){return{x:.5+(v.x-u)/s,y:.5+(v.y-l)/s}};return c.applyTo=function(h){h.x=.5+(h.x-u)/s,h.y=.5+(h.y-l)/s},c.inverse=function(h){return{x:u+s*(h.x-.5),y:l+s*(h.y-.5)}},c.ratio=s,c}function rt(t){"@babel/helpers - typeof";return rt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},rt(t)}function It(t,r){var n=r.size;if(n!==0){var e=t.length;t.length+=n;var i=0;r.forEach(function(a){t[e+i]=a,i++})}}function nt(t){t=t||{};for(var r=0,n=arguments.length<=1?0:arguments.length-1;r1&&arguments[1]!==void 0?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;if(!o)return new Promise(function(y){return i.animate(e,a,y)});if(this.enabled){var s=P(P({},nn),a),u=this.validateState(e),l=typeof s.easing=="function"?s.easing:rn[s.easing],c=Date.now(),h=this.getState(),v=function(){var _=(Date.now()-c)/s.duration;if(_>=1){i.nextFrame=null,i.setState(u),i.animationCallback&&(i.animationCallback.call(null),i.animationCallback=void 0);return}var p=l(_),T={};typeof u.x=="number"&&(T.x=h.x+(u.x-h.x)*p),typeof u.y=="number"&&(T.y=h.y+(u.y-h.y)*p),i.enabledRotation&&typeof u.angle=="number"&&(T.angle=h.angle+(u.angle-h.angle)*p),typeof u.ratio=="number"&&(T.ratio=h.ratio+(u.ratio-h.ratio)*p),i.setState(T),i.nextFrame=requestAnimationFrame(v)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(v)):v(),this.animationCallback=o}}},{key:"animatedZoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||ot)},e):this.animate({ratio:this.ratio/ot})}},{key:"animatedUnzoom",value:function(e){return e?typeof e=="number"?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||ot)},e):this.animate({ratio:this.ratio*ot})}},{key:"animatedReset",value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:"copy",value:function(){return r.from(this.getState())}}],[{key:"from",value:function(e){var i=new r;return i.setState(e)}}])})(Qe);function re(t,r){var n=r.getBoundingClientRect();return{x:t.clientX-n.left,y:t.clientY-n.top}}function oe(t,r){var n=P(P({},re(t,r)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:t});return n}function ke(t){var r="x"in t?t:P(P({},t.touches[0]||t.previousTouches[0]),{},{original:t.original,sigmaDefaultPrevented:t.sigmaDefaultPrevented,preventSigmaDefault:function(){t.sigmaDefaultPrevented=!0,r.sigmaDefaultPrevented=!0}});return r}function ba(t,r){return P(P({},oe(t,r)),{},{delta:gn(t)})}var _a=2;function st(t){for(var r=[],n=0,e=Math.min(t.length,_a);n0;i.draggedEvents=0,h&&i.renderer.getSetting("hideEdgesOnMove")&&i.renderer.refresh()},0),this.emit("mouseup",oe(e,this.container))}}},{key:"handleMove",value:function(e){var i=this;if(this.enabled){var a=oe(e,this.container);if(this.emit("mousemovebody",a),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit("mousemove",a),!a.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout=="number"&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){i.movingTimeout=null,i.isMoving=!1},this.settings.dragTimeout);var o=this.renderer.getCamera(),s=re(e,this.container),u=s.x,l=s.y,c=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),h=this.renderer.viewportToFramedGraph({x:u,y:l}),v=c.x-h.x,y=c.y-h.y,_=o.getState(),p=_.x+v,T=_.y+y;o.setState({x:p,y:T}),this.lastMouseX=u,this.lastMouseY=l,e.preventDefault(),e.stopPropagation()}}}},{key:"handleLeave",value:function(e){this.emit("mouseleave",oe(e,this.container))}},{key:"handleEnter",value:function(e){this.emit("mouseenter",oe(e,this.container))}},{key:"handleWheel",value:function(e){var i=this,a=this.renderer.getCamera();if(!(!this.enabled||!a.enabledZooming)){var o=gn(e);if(o){var s=ba(e,this.container);if(this.emit("wheel",s),s.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var u=a.getState().ratio,l=o>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,c=a.getBoundedRatio(u*l),h=o>0?1:-1,v=Date.now();u!==c&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===h&&this.lastWheelTriggerTime&&v-this.lastWheelTriggerTimee.size?-1:n.sizee.key?1:-1}}])})(),fn=(function(){function t(){W(this,t),x(this,"width",0),x(this,"height",0),x(this,"cellSize",0),x(this,"columns",0),x(this,"rows",0),x(this,"cells",{})}return X(t,[{key:"resizeAndClear",value:function(n,e){this.width=n.width,this.height=n.height,this.cellSize=e,this.columns=Math.ceil(n.width/e),this.rows=Math.ceil(n.height/e),this.cells={}}},{key:"getIndex",value:function(n){var e=Math.floor(n.x/this.cellSize),i=Math.floor(n.y/this.cellSize);return i*this.columns+e}},{key:"add",value:function(n,e,i){var a=new hn(n,e),o=this.getIndex(i),s=this.cells[o];s||(s=[],this.cells[o]=s),s.push(a)}},{key:"organize",value:function(){for(var n in this.cells){var e=this.cells[n];e.sort(hn.compare)}}},{key:"getLabelsToDisplay",value:function(n,e){var i=this.cellSize*this.cellSize,a=i/n/n,o=a*e/i,s=Math.ceil(o),u=[];for(var l in this.cells)for(var c=this.cells[l],h=0;h2&&arguments[2]!==void 0?arguments[2]:{};if(W(this,r),i=$(this,r),x(i,"elements",{}),x(i,"canvasContexts",{}),x(i,"webGLContexts",{}),x(i,"pickingLayers",new Set),x(i,"textures",{}),x(i,"frameBuffers",{}),x(i,"activeListeners",{}),x(i,"labelGrid",new fn),x(i,"nodeDataCache",{}),x(i,"edgeDataCache",{}),x(i,"nodeProgramIndex",{}),x(i,"edgeProgramIndex",{}),x(i,"nodesWithForcedLabels",new Set),x(i,"edgesWithForcedLabels",new Set),x(i,"nodeExtent",{x:[0,1],y:[0,1]}),x(i,"nodeZExtent",[1/0,-1/0]),x(i,"edgeZExtent",[1/0,-1/0]),x(i,"matrix",te()),x(i,"invMatrix",te()),x(i,"correctionRatio",1),x(i,"customBBox",null),x(i,"normalizationFunction",Ft({x:[0,1],y:[0,1]})),x(i,"graphToViewportRatio",1),x(i,"itemIDsIndex",{}),x(i,"nodeIndices",{}),x(i,"edgeIndices",{}),x(i,"width",0),x(i,"height",0),x(i,"pixelRatio",kt()),x(i,"pickingDownSizingRatio",2*i.pixelRatio),x(i,"displayedNodeLabels",new Set),x(i,"displayedEdgeLabels",new Set),x(i,"highlightedNodes",new Set),x(i,"hoveredNode",null),x(i,"hoveredEdge",null),x(i,"renderFrame",null),x(i,"renderHighlightedNodesFrame",null),x(i,"needToProcess",!1),x(i,"checkEdgesEventsFrame",null),x(i,"nodePrograms",{}),x(i,"nodeHoverPrograms",{}),x(i,"edgePrograms",{}),i.settings=ln(a),at(i.settings),sn(n),!(e instanceof HTMLElement))throw new Error("Sigma: container should be an html element.");i.graph=n,i.container=e,i.createWebGLContext("edges",{picking:a.enableEdgeEvents}),i.createCanvasContext("edgeLabels"),i.createWebGLContext("nodes",{picking:!0}),i.createCanvasContext("labels"),i.createCanvasContext("hovers"),i.createWebGLContext("hoverNodes"),i.createCanvasContext("mouse",{style:{touchAction:"none",userSelect:"none"}}),i.resize();for(var o in i.settings.nodeProgramClasses)i.registerNodeProgram(o,i.settings.nodeProgramClasses[o],i.settings.nodeHoverProgramClasses[o]);for(var s in i.settings.edgeProgramClasses)i.registerEdgeProgram(s,i.settings.edgeProgramClasses[s]);return i.camera=new Gt,i.bindCameraHandlers(),i.mouseCaptor=new pn(i.elements.mouse,i),i.mouseCaptor.setSettings(i.settings),i.touchCaptor=new xa(i.elements.mouse,i),i.touchCaptor.setSettings(i.settings),i.bindEventHandlers(),i.bindGraphHandlers(),i.handleSettingsUpdate(),i.refresh(),i}return K(r,t),X(r,[{key:"registerNodeProgram",value:function(e,i,a){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new i(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(a||i)(this.webGLContexts.hoverNodes,null,this),this}},{key:"registerEdgeProgram",value:function(e,i){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new i(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:"unregisterNodeProgram",value:function(e){if(this.nodePrograms[e]){var i=this.nodePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.nodePrograms=o}if(this.nodeHoverPrograms[e]){var s=this.nodeHoverPrograms,u=s[e],l=zt(s,[e].map(me));u.kill(),this.nodePrograms=l}return this}},{key:"unregisterEdgeProgram",value:function(e){if(this.edgePrograms[e]){var i=this.edgePrograms,a=i[e],o=zt(i,[e].map(me));a.kill(),this.edgePrograms=o}return this}},{key:"resetWebGLTexture",value:function(e){var i=this.webGLContexts[e],a=this.frameBuffers[e],o=this.textures[e];o&&i.deleteTexture(o);var s=i.createTexture();return i.bindFramebuffer(i.FRAMEBUFFER,a),i.bindTexture(i.TEXTURE_2D,s),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,s,0),this.textures[e]=s,this}},{key:"bindCameraHandlers",value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on("updated",this.activeListeners.camera),this}},{key:"unbindCameraHandlers",value:function(){return this.camera.removeListener("updated",this.activeListeners.camera),this}},{key:"getNodeAtPosition",value:function(e){var i=e.x,a=e.y,o=je(this.webGLContexts.nodes,this.frameBuffers.nodes,i,a,this.pixelRatio,this.pickingDownSizingRatio),s=Be.apply(void 0,cn(o)),u=this.itemIDsIndex[s];return u&&u.type==="node"?u.id:null}},{key:"bindEventHandlers",value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener("resize",this.activeListeners.handleResize),this.activeListeners.handleMove=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}},u=e.getNodeAtPosition(o);if(u&&e.hoveredNode!==u&&!e.nodeDataCache[u].hidden){e.hoveredNode&&e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.hoveredNode=u,e.emit("enterNode",P(P({},s),{},{node:u})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(o)!==e.hoveredNode){var l=e.hoveredNode;e.hoveredNode=null,e.emit("leaveNode",P(P({},s),{},{node:l})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var c=e.hoveredNode?null:e.getEdgeAtPoint(s.event.x,s.event.y);c!==e.hoveredEdge&&(e.hoveredEdge&&e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),c&&e.emit("enterEdge",P(P({},s),{},{edge:c})),e.hoveredEdge=c)}},this.activeListeners.handleMoveBody=function(a){var o=ke(a);e.emit("moveBody",{event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.hoveredNode&&(e.emit("leaveNode",P(P({},s),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit("leaveEdge",P(P({},s),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit("leaveStage",P({},s))},this.activeListeners.handleEnter=function(a){var o=ke(a),s={event:o,preventSigmaDefault:function(){o.preventSigmaDefault()}};e.emit("enterStage",P({},s))};var i=function(o){return function(s){var u=ke(s),l={event:u,preventSigmaDefault:function(){u.preventSigmaDefault()}},c=e.getNodeAtPosition(u);if(c)return e.emit("".concat(o,"Node"),P(P({},l),{},{node:c}));if(e.settings.enableEdgeEvents){var h=e.getEdgeAtPoint(u.x,u.y);if(h)return e.emit("".concat(o,"Edge"),P(P({},l),{},{edge:h}))}return e.emit("".concat(o,"Stage"),l)}};return this.activeListeners.handleClick=i("click"),this.activeListeners.handleRightClick=i("rightClick"),this.activeListeners.handleDoubleClick=i("doubleClick"),this.activeListeners.handleWheel=i("wheel"),this.activeListeners.handleDown=i("down"),this.activeListeners.handleUp=i("up"),this.mouseCaptor.on("mousemove",this.activeListeners.handleMove),this.mouseCaptor.on("mousemovebody",this.activeListeners.handleMoveBody),this.mouseCaptor.on("click",this.activeListeners.handleClick),this.mouseCaptor.on("rightClick",this.activeListeners.handleRightClick),this.mouseCaptor.on("doubleClick",this.activeListeners.handleDoubleClick),this.mouseCaptor.on("wheel",this.activeListeners.handleWheel),this.mouseCaptor.on("mousedown",this.activeListeners.handleDown),this.mouseCaptor.on("mouseup",this.activeListeners.handleUp),this.mouseCaptor.on("mouseleave",this.activeListeners.handleLeave),this.mouseCaptor.on("mouseenter",this.activeListeners.handleEnter),this.touchCaptor.on("touchdown",this.activeListeners.handleDown),this.touchCaptor.on("touchdown",this.activeListeners.handleMove),this.touchCaptor.on("touchup",this.activeListeners.handleUp),this.touchCaptor.on("touchmove",this.activeListeners.handleMove),this.touchCaptor.on("tap",this.activeListeners.handleClick),this.touchCaptor.on("doubletap",this.activeListeners.handleDoubleClick),this.touchCaptor.on("touchmove",this.activeListeners.handleMoveBody),this}},{key:"bindGraphHandlers",value:function(){var e=this,i=this.graph,a=new Set(["x","y","zIndex","type"]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachNode(function(c){return e.updateNode(c)});var l=!u||u.some(function(c){return a.has(c)});e.refresh({partialGraph:{nodes:i.nodes()},skipIndexation:!l,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(o){var s,u=(s=o.hints)===null||s===void 0?void 0:s.attributes;e.graph.forEachEdge(function(c){return e.updateEdge(c)});var l=u&&["zIndex","type"].some(function(c){return u?.includes(c)});e.refresh({partialGraph:{edges:i.edges()},skipIndexation:!l,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(o){var s=o.key;e.addNode(s),e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{nodes:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(o){var s=o.key;e.removeNode(s),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(o){var s=o.key;e.addEdge(s),e.refresh({partialGraph:{edges:[s]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(o){var s=o.key;e.refresh({partialGraph:{edges:[s]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(o){var s=o.key;e.removeEdge(s),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},i.on("nodeAdded",this.activeListeners.addNodeGraphUpdate),i.on("nodeDropped",this.activeListeners.dropNodeGraphUpdate),i.on("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),i.on("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),i.on("edgeAdded",this.activeListeners.addEdgeGraphUpdate),i.on("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),i.on("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),i.on("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),i.on("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),i.on("cleared",this.activeListeners.clearGraphUpdate),this}},{key:"unbindGraphHandlers",value:function(){var e=this.graph;e.removeListener("nodeAdded",this.activeListeners.addNodeGraphUpdate),e.removeListener("nodeDropped",this.activeListeners.dropNodeGraphUpdate),e.removeListener("nodeAttributesUpdated",this.activeListeners.updateNodeGraphUpdate),e.removeListener("eachNodeAttributesUpdated",this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener("edgeAdded",this.activeListeners.addEdgeGraphUpdate),e.removeListener("edgeDropped",this.activeListeners.dropEdgeGraphUpdate),e.removeListener("edgeAttributesUpdated",this.activeListeners.updateEdgeGraphUpdate),e.removeListener("eachEdgeAttributesUpdated",this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener("edgesCleared",this.activeListeners.clearEdgesGraphUpdate),e.removeListener("cleared",this.activeListeners.clearGraphUpdate)}},{key:"getEdgeAtPoint",value:function(e,i){var a=je(this.webGLContexts.edges,this.frameBuffers.edges,e,i,this.pixelRatio,this.pickingDownSizingRatio),o=Be.apply(void 0,cn(a)),s=this.itemIDsIndex[o];return s&&s.type==="edge"?s.id:null}},{key:"process",value:function(){var e=this;this.emit("beforeProcess");var i=this.graph,a=this.settings,o=this.getDimensions();if(this.nodeExtent=on(this.graph),!this.settings.autoRescale){var s=o.width,u=o.height,l=this.nodeExtent,c=l.x,h=l.y;this.nodeExtent={x:[(c[0]+c[1])/2-s/2,(c[0]+c[1])/2+s/2],y:[(h[0]+h[1])/2-u/2,(h[0]+h[1])/2+u/2]}}this.normalizationFunction=Ft(this.customBBox||this.nodeExtent);var v=new Gt,y=xe(v.getState(),o,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(o,a.labelGridCellSize);for(var _={},p={},T={},E={},b=1,m=i.nodes(),w=0,O=m.length;w1&&arguments[1]!==void 0?arguments[1]:{},a=i.tolerance,o=a===void 0?0:a,s=i.boundaries,u=P({},e),l=s||this.nodeExtent,c=ce(l.x,2),h=c[0],v=c[1],y=ce(l.y,2),_=y[0],p=y[1],T=[this.graphToViewport({x:h,y:_},{cameraState:e}),this.graphToViewport({x:v,y:_},{cameraState:e}),this.graphToViewport({x:h,y:p},{cameraState:e}),this.graphToViewport({x:v,y:p},{cameraState:e})],E=1/0,b=-1/0,m=1/0,w=-1/0;T.forEach(function(U){var H=U.x,f=U.y;E=Math.min(E,H),b=Math.max(b,H),m=Math.min(m,f),w=Math.max(w,f)});var O=b-E,A=w-m,C=this.getDimensions(),D=C.width,k=C.height,I=0,z=0;if(O>=D?bo&&(I=E-o):b>D+o?I=b-(D+o):E<-o&&(I=E+o),A>=k?wo&&(z=m-o):w>k+o?z=w-(k+o):m<-o&&(z=m+o),I||z){var G=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),j=this.viewportToFramedGraph({x:I,y:z},{cameraState:e});I=j.x-G.x,z=j.y-G.y,u.x+=I,u.y+=z}return u}},{key:"renderLabels",value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),i=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);It(i,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var a=this.canvasContexts.labels,o=0,s=i.length;othis.width+dn||v<-vn||v>this.height+vn)){this.displayedNodeLabels.add(u);var _=this.settings.defaultDrawNodeLabel,p=this.nodePrograms[l.type],T=p?.drawLabel||_;T(a,P(P({key:u},l),{},{size:y,x:h,y:v}),this.settings)}}}return this}},{key:"renderEdgeLabels",value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var i=Pa({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});It(i,this.edgesWithForcedLabels);for(var a=new Set,o=0,s=i.length;othis.nodeZExtent[1]&&(this.nodeZExtent[1]=a.zIndex))}},{key:"updateNode",value:function(e){this.addNode(e);var i=this.nodeDataCache[e];this.normalizationFunction.applyTo(i)}},{key:"removeNode",value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:"addEdge",value:function(e){var i=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(i=this.settings.edgeReducer(e,i));var a=Na(this.settings,e,i);this.edgeDataCache[e]=a,this.edgesWithForcedLabels.delete(e),a.forceLabel&&!a.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(a.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=a.zIndex))}},{key:"updateEdge",value:function(e){this.addEdge(e)}},{key:"removeEdge",value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:"clearNodeIndices",value:function(){this.labelGrid=new fn,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:"clearEdgeIndices",value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:"clearIndices",value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:"clearNodeState",value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:"clearEdgeState",value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:"clearState",value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:"addNodeToProgram",value:function(e,i,a){var o=this.nodeDataCache[e],s=this.nodePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for node type "'.concat(o.type,'"!'));s.process(i,a,o),this.nodeProgramIndex[e]=a}},{key:"addEdgeToProgram",value:function(e,i,a){var o=this.edgeDataCache[e],s=this.edgePrograms[o.type];if(!s)throw new Error('Sigma: could not find a suitable program for edge type "'.concat(o.type,'"!'));var u=this.graph.extremities(e),l=this.nodeDataCache[u[0]],c=this.nodeDataCache[u[1]];s.process(i,a,l,c,o),this.edgeProgramIndex[e]=a}},{key:"getRenderParams",value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:"getStagePadding",value:function(){var e=this.settings,i=e.stagePadding,a=e.autoRescale;return a&&i||0}},{key:"createLayer",value:function(e,i){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw new Error('Sigma: a layer named "'.concat(e,'" already exists'));var o=un(i,{position:"absolute"},{class:"sigma-".concat(e)});return a.style&&Object.assign(o.style,a.style),this.elements[e]=o,"beforeLayer"in a&&a.beforeLayer?this.elements[a.beforeLayer].before(o):"afterLayer"in a&&a.afterLayer?this.elements[a.afterLayer].after(o):this.container.appendChild(o),o}},{key:"createCanvas",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,"canvas",i)}},{key:"createCanvasContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=this.createCanvas(e,i),o={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=a.getContext("2d",o),this}},{key:"createWebGLContext",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=i?.canvas||this.createCanvas(e,i);i.hidden&&a.remove();var o=P({preserveDrawingBuffer:!1,antialias:!1},i),s;s=a.getContext("webgl2",o),s||(s=a.getContext("webgl",o)),s||(s=a.getContext("experimental-webgl",o));var u=s;if(this.webGLContexts[e]=u,u.blendFunc(u.ONE,u.ONE_MINUS_SRC_ALPHA),i.picking){this.pickingLayers.add(e);var l=u.createFramebuffer();if(!l)throw new Error("Sigma: cannot create a new frame buffer for layer ".concat(e));this.frameBuffers[e]=l}return u}},{key:"killLayer",value:function(e){var i=this.elements[e];if(!i)throw new Error("Sigma: cannot kill layer ".concat(e,", which does not exist"));if(this.webGLContexts[e]){var a,o=this.webGLContexts[e];(a=o.getExtension("WEBGL_lose_context"))===null||a===void 0||a.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return i.remove(),delete this.elements[e],this}},{key:"getCamera",value:function(){return this.camera}},{key:"setCamera",value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:"getContainer",value:function(){return this.container}},{key:"getGraph",value:function(){return this.graph}},{key:"setGraph",value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:"getMouseCaptor",value:function(){return this.mouseCaptor}},{key:"getTouchCaptor",value:function(){return this.touchCaptor}},{key:"getDimensions",value:function(){return{width:this.width,height:this.height}}},{key:"getGraphDimensions",value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:"getNodeDisplayData",value:function(e){var i=this.nodeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getEdgeDisplayData",value:function(e){var i=this.edgeDataCache[e];return i?Object.assign({},i):void 0}},{key:"getNodeDisplayedLabels",value:function(){return new Set(this.displayedNodeLabels)}},{key:"getEdgeDisplayedLabels",value:function(){return new Set(this.displayedEdgeLabels)}},{key:"getSettings",value:function(){return P({},this.settings)}},{key:"getSetting",value:function(e){return this.settings[e]}},{key:"setSetting",value:function(e,i){var a=P({},this.settings);return this.settings[e]=i,at(this.settings),this.handleSettingsUpdate(a),this.scheduleRefresh(),this}},{key:"updateSetting",value:function(e,i){return this.setSetting(e,i(this.settings[e])),this}},{key:"setSettings",value:function(e){var i=P({},this.settings);return this.settings=P(P({},this.settings),e),at(this.settings),this.handleSettingsUpdate(i),this.scheduleRefresh(),this}},{key:"resize",value:function(e){var i=this.width,a=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=kt(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw new Error("Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw new Error("Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.");if(!e&&i===this.width&&a===this.height)return this;for(var o in this.elements){var s=this.elements[o];s.style.width=this.width+"px",s.style.height=this.height+"px"}for(var u in this.canvasContexts)this.elements[u].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[u].setAttribute("height",this.height*this.pixelRatio+"px"),this.pixelRatio!==1&&this.canvasContexts[u].scale(this.pixelRatio,this.pixelRatio);for(var l in this.webGLContexts){this.elements[l].setAttribute("width",this.width*this.pixelRatio+"px"),this.elements[l].setAttribute("height",this.height*this.pixelRatio+"px");var c=this.webGLContexts[l];if(c.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(l)){var h=this.textures[l];h&&c.deleteTexture(h)}}return this.emit("resize"),this}},{key:"clear",value:function(){return this.emit("beforeClear"),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit("afterClear"),this}},{key:"refresh",value:function(e){var i=this,a=e?.skipIndexation!==void 0?e?.skipIndexation:!1,o=e?.schedule!==void 0?e.schedule:!1,s=!e||!e.partialGraph;if(s)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(w){return i.addNode(w)}),this.graph.forEachEdge(function(w){return i.addEdge(w)});else{for(var u,l,c=((u=e.partialGraph)===null||u===void 0?void 0:u.nodes)||[],h=0,v=c?.length||0;h1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding()):this.matrix,s=tt(o,e);return{x:(1+s.x)*this.width/2,y:(1-s.y)*this.height/2}}},{key:"viewportToFramedGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},a=!!i.cameraState||!!i.viewportDimensions||!i.graphDimensions,o=i.matrix?i.matrix:a?xe(i.cameraState||this.camera.getState(),i.viewportDimensions||this.getDimensions(),i.graphDimensions||this.getGraphDimensions(),i.padding||this.getStagePadding(),!0):this.invMatrix,s=tt(o,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(s.x)&&(s.x=0),isNaN(s.y)&&(s.y=0),s}},{key:"viewportToGraph",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,i))}},{key:"graphToViewport",value:function(e){var i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),i)}},{key:"getGraphToViewportRatio",value:function(){var e={x:0,y:0},i={x:1,y:1},a=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),o=this.graphToViewport(e),s=this.graphToViewport(i),u=Math.sqrt(Math.pow(o.x-s.x,2)+Math.pow(o.y-s.y,2));return u/a}},{key:"getBBox",value:function(){return this.nodeExtent}},{key:"getCustomBBox",value:function(){return this.customBBox}},{key:"setCustomBBox",value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:"kill",value:function(){this.emit("kill"),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener("resize",this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&(cancelAnimationFrame(this.renderFrame),this.renderFrame=null),this.renderHighlightedNodesFrame&&(cancelAnimationFrame(this.renderHighlightedNodesFrame),this.renderHighlightedNodesFrame=null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var i in this.nodePrograms)this.nodePrograms[i].kill();for(var a in this.nodeHoverPrograms)this.nodeHoverPrograms[a].kill();for(var o in this.edgePrograms)this.edgePrograms[o].kill();this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={};for(var s in this.elements)this.killLayer(s);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:"scaleSize",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,i=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(i)*(this.getSetting("itemSizesReference")==="positions"?i*this.graphToViewportRatio:1)}},{key:"getCanvases",value:function(){var e={};for(var i in this.elements)this.elements[i]instanceof HTMLCanvasElement&&(e[i]=this.elements[i]);return e}}])})(Qe),bn=yn;var En=WebGLRenderingContext,$s=En.UNSIGNED_BYTE,Ks=En.FLOAT;var ka=` attribute vec4 a_id; attribute vec4 a_color; attribute vec2 a_normal; @@ -390,7 +390,7 @@ void main() { v_color.a *= bias; } -`,Da=ka,Tn=WebGLRenderingContext,_n=Tn.UNSIGNED_BYTE,se=Tn.FLOAT,Fa=["u_matrix","u_zoomRatio","u_sizeRatio","u_correctionRatio","u_pixelRatio","u_feather","u_minEdgeThickness","u_lengthToThicknessRatio"],Ia={lengthToThicknessRatio:he.lengthToThicknessRatio};function Rn(t){var r=P(P({},Ia),t||{});return(function(n){function e(){return W(this,e),$(this,e,arguments)}return K(e,n),X(e,[{key:"getDefinition",value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Da,FRAGMENT_SHADER_SOURCE:Ye,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Fa,ATTRIBUTES:[{name:"a_positionStart",size:2,type:se},{name:"a_positionEnd",size:2,type:se},{name:"a_normal",size:2,type:se},{name:"a_color",size:4,type:_n,normalized:!0},{name:"a_id",size:4,type:_n,normalized:!0},{name:"a_sourceRadius",size:1,type:se},{name:"a_targetRadius",size:1,type:se}],CONSTANT_ATTRIBUTES:[{name:"a_positionCoef",size:1,type:se},{name:"a_normalCoef",size:1,type:se},{name:"a_sourceRadiusCoef",size:1,type:se},{name:"a_targetRadiusCoef",size:1,type:se}],CONSTANT_DATA:[[0,1,-1,0],[0,-1,1,0],[1,1,0,1],[1,1,0,1],[0,-1,1,0],[1,-1,0,-1]]}}},{key:"processVisibleItem",value:function(a,o,s,u,l){var c=l.size||1,h=s.x,v=s.y,y=u.x,_=u.y,p=Y(l.color),T=y-h,E=_-v,b=s.size||1,m=u.size||1,w=T*T+E*E,O=0,A=0;w&&(w=1/Math.sqrt(w),O=-E*w*c,A=T*w*c);var C=this.array;C[o++]=h,C[o++]=v,C[o++]=y,C[o++]=_,C[o++]=O,C[o++]=A,C[o++]=p,C[o++]=a,C[o++]=b,C[o++]=m}},{key:"setUniforms",value:function(a,o){var s=o.gl,u=o.uniformLocations,l=u.u_matrix,c=u.u_zoomRatio,h=u.u_feather,v=u.u_pixelRatio,y=u.u_correctionRatio,_=u.u_sizeRatio,p=u.u_minEdgeThickness,T=u.u_lengthToThicknessRatio;s.uniformMatrix3fv(l,!1,a.matrix),s.uniform1f(c,a.zoomRatio),s.uniform1f(_,a.sizeRatio),s.uniform1f(y,a.correctionRatio),s.uniform1f(v,a.pixelRatio),s.uniform1f(h,a.antiAliasingFeather),s.uniform1f(p,a.minEdgeThickness),s.uniform1f(T,r.lengthToThicknessRatio)}}])})(ce)}var Js=Rn();function za(t){return Ne([Rn(t),ye(t),ye(P(P({},t),{},{extremity:"source"}))])}var Ga=za(),Ma=Ga;var wn=WebGLRenderingContext,eu=wn.UNSIGNED_BYTE,tu=wn.FLOAT;var xn=WebGLRenderingContext,ru=xn.UNSIGNED_BYTE,nu=xn.FLOAT;var su=ve(et());function Ln(t,r,n){return Te(t,r,n)}function Ua(t,r,n){var e=n.labelSize,i=n.labelFont,a=n.labelWeight;t.font="".concat(a," ").concat(e,"px ").concat(i),t.fillStyle="#FFF",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=8,t.shadowColor="#000";var o=2;if(typeof r.label=="string"){var s=t.measureText(r.label).width,u=Math.round(s+5),l=Math.round(e+2*o),c=Math.max(r.size,e/2)+o;t.beginPath(),t.moveTo(r.x+c,r.y+l/2),t.lineTo(r.x+c+u,r.y+l/2),t.lineTo(r.x+c+u,r.y-l/2),t.lineTo(r.x+c,r.y-l/2),t.lineTo(r.x+c,r.y-c),t.lineTo(r.x-c,r.y-c),t.lineTo(r.x-c,r.y+c),t.lineTo(r.x+c,r.y+c),t.moveTo(r.x+c,r.y+l/2),t.closePath(),t.fill()}else{var h=r.size+o;t.fillRect(r.x-h,r.y-h,h*2,h*2)}t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,Ln(t,r,n)}function Ba(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}function ja(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function Pn(t){var r=ja(t,"string");return typeof r=="symbol"?r:r+""}function Cn(t,r){for(var n=0;nt.length)&&(r=t.length);for(var n=0,e=Array(r);nt.length)&&(r=t.length);for(var n=0,e=Array(r);nUo,NodePictogramProgram:()=>Bo,createNodeImageProgram:()=>nr});var Yn=ve(Qe());function Xt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);nGo,NodePictogramProgram:()=>Mo,createNodeImageProgram:()=>nr});var Yn=ve(Ze());function Xt(t,r){(r==null||r>t.length)&&(r=t.length);for(var n=0,e=Array(r);n=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function Wn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function tr(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Wn(a,e,i,o,s,"next",u)}function s(u){Wn(a,e,i,o,s,"throw",u)}o(void 0)})}}var rr={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Po=1;function $t(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function Oo(t){return Kt.apply(this,arguments)}function Kt(){return Kt=tr(be().mark(function t(r){var n,e,i,a,o,s,u,l,c,h,v,y,_,p=arguments;return be().wrap(function(E){for(;;)switch(E.prev=E.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){E.next=7;break}return E.next=4,fetch(r,{credentials:"include"});case 4:a=E.sent,E.next=10;break;case 7:return E.next=9,fetch(r);case 9:a=E.sent;case 10:return E.next=12,a.text();case 12:if(o=E.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){E.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),h=new XMLSerializer().serializeToString(s),v=new Blob([h],{type:"image/svg+xml"}),y=URL.createObjectURL(v),_=$t(y),_.finally(function(){return URL.revokeObjectURL(y)}),E.abrupt("return",_);case 26:case"end":return E.stop()}},t)})),Kt.apply(this,arguments)}function No(t){return Zt.apply(this,arguments)}function Zt(){return Zt=tr(be().mark(function t(r){var n,e,i,a,o,s,u=arguments;return be().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,Oo(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,$t(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,$t(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Zt.apply(this,arguments)}function ko(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function Do(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,h={},v=0,y=t.length;va||s+O>i&&u+O+l>a||(s+O>i&&(c=Math.max(c,s),s=0,u+=l,l=O),o.push({key:p,image:T,sourceX:b,sourceY:m,sourceSize:E,destinationX:s,destinationY:u,destinationSize:w}),h[p]={x:s,y:u,size:w},s+=O,l=Math.max(l,O))}c=Math.max(c,s);for(var A=c,C=u+l,D=0,k=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Jt(this,r),n=Kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Io),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},rr),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return er(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=Fo({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=tr(be().mark(function i(a){var o,s;return be().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,No(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},ko(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(Yn.EventEmitter);Z(ft,"NEW_TEXTURE_EVENT","newTexture");var zo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],Qn=WebGLRenderingContext,Xn=Qn.UNSIGNED_BYTE,Fe=Qn.FLOAT,Go=ee(ee({},rr),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),Mo=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function nr(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),rr.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},Go),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,h=i.imageAttribute,v=Co(i,zo),y=new ft(v);return r=(function(_){Zn(p,_);function p(T,E,b){var m;return Jt(this,p),m=Kn(this,p,[T,E,b]),Z(ne(m),"drawLabel",o),Z(ne(m),"drawHover",a),Z(ne(m),"textureManagerCallback",null),m.textureManagerCallback=function(w){var O=w.atlas,A=w.textures,C=A.length!==m.textures.length;m.atlas=O,m.textureImages=A,C&&m.upgradeShaders(),m.bindTextures(),m.latestRenderParams&&m.render(m.latestRenderParams),m.renderer&&m.renderer.refresh&&m.renderer.refresh()},y.on(ft.NEW_TEXTURE_EVENT,m.textureManagerCallback),m.atlas=y.getAtlas(),m.textureImages=y.getTextures(),m.textures=m.textureImages.map(function(){return T.createTexture()}),m.bindTextures(),m}return er(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:Lo,FRAGMENT_SHADER_SOURCE:So({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:Mo,ATTRIBUTES:[{name:"a_position",size:2,type:Fe},{name:"a_size",size:1,type:Fe},{name:"a_color",size:4,type:Xn,normalized:!0},{name:"a_id",size:4,type:Xn,normalized:!0},{name:"a_texture",size:4,type:Fe},{name:"a_textureIndex",size:1,type:Fe}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Fe}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var E=this.getDefinition(),b=this.normalProgram,m=b.program,w=b.buffer,O=b.vertexShader,A=b.fragmentShader,C=b.gl;C.deleteProgram(m),C.deleteBuffer(w),C.deleteShader(O),C.deleteShader(A),this.normalProgram=this.getProgramInfo("normal",C,E.VERTEX_SHADER_SOURCE,E.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var E,b=(E=this.normalProgram)===null||E===void 0?void 0:E.gl;if(b)for(var m=0;m=this.textures.length){var m=E.createTexture();m&&this.textures.push(m)}E.activeTexture(E.TEXTURE0+b),E.bindTexture(E.TEXTURE_2D,this.textures[b]),E.texImage2D(E.TEXTURE_2D,0,E.RGBA,E.RGBA,E.UNSIGNED_BYTE,this.textureImages[b]),E.generateMipmap(E.TEXTURE_2D)}}},{key:"renderProgram",value:function(E,b){if(!b.isPicking)for(var m=b.gl,w=0;wsr,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>li,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>ci,EdgeCurvedArrowProgram:()=>ns,EdgeCurvedDoubleArrowProgram:()=>is,createDrawCurvedEdgeLabel:()=>ui,createEdgeCurveProgram:()=>vt,default:()=>rs,indexParallelEdgesIndex:()=>ts});function jo(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ni(t){var r=jo(t,"string");return typeof r=="symbol"?r:r+""}function ii(t,r,n){return(r=ni(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function ei(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Le(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},Q=0,q=p.length;Q=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function Wn(t,r,n,e,i,a,o){try{var s=t[a](o),u=s.value}catch(l){return void n(l)}s.done?r(u):Promise.resolve(u).then(e,i)}function tr(t){return function(){var r=this,n=arguments;return new Promise(function(e,i){var a=t.apply(r,n);function o(u){Wn(a,e,i,o,s,"next",u)}function s(u){Wn(a,e,i,o,s,"throw",u)}o(void 0)})}}var rr={size:{mode:"max",value:512},objectFit:"cover",correctCentering:!1,maxTextureSize:4096,debounceTimeout:500,crossOrigin:"anonymous"},Ao=1;function $t(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=r.crossOrigin;return new Promise(function(e,i){var a=new Image;a.addEventListener("load",function(){e(a)},{once:!0}),a.addEventListener("error",function(o){i(o.error)},{once:!0}),n&&a.setAttribute("crossOrigin",n),a.src=t})}function Lo(t){return Kt.apply(this,arguments)}function Kt(){return Kt=tr(ye().mark(function t(r){var n,e,i,a,o,s,u,l,c,h,v,y,_,p=arguments;return ye().wrap(function(E){for(;;)switch(E.prev=E.next){case 0:if(n=p.length>1&&p[1]!==void 0?p[1]:{},e=n.size,i=n.crossOrigin,i!=="use-credentials"){E.next=7;break}return E.next=4,fetch(r,{credentials:"include"});case 4:a=E.sent,E.next=10;break;case 7:return E.next=9,fetch(r);case 9:a=E.sent;case 10:return E.next=12,a.text();case 12:if(o=E.sent,s=new DOMParser().parseFromString(o,"image/svg+xml"),u=s.documentElement,l=u.getAttribute("width"),c=u.getAttribute("height"),!(!l||!c)){E.next=19;break}throw new Error("loadSVGImage: cannot use `size` if target SVG has no definite dimensions.");case 19:return typeof e=="number"&&(u.setAttribute("width",""+e),u.setAttribute("height",""+e)),h=new XMLSerializer().serializeToString(s),v=new Blob([h],{type:"image/svg+xml"}),y=URL.createObjectURL(v),_=$t(y),_.finally(function(){return URL.revokeObjectURL(y)}),E.abrupt("return",_);case 26:case"end":return E.stop()}},t)})),Kt.apply(this,arguments)}function Po(t){return Zt.apply(this,arguments)}function Zt(){return Zt=tr(ye().mark(function t(r){var n,e,i,a,o,s,u=arguments;return ye().wrap(function(c){for(;;)switch(c.prev=c.next){case 0:if(e=u.length>1&&u[1]!==void 0?u[1]:{},i=e.size,a=e.crossOrigin,o=((n=r.split(/[#?]/)[0].split(".").pop())===null||n===void 0?void 0:n.trim().toLowerCase())==="svg",!(o&&i)){c.next=16;break}return c.prev=3,c.next=6,Lo(r,{size:i,crossOrigin:a});case 6:s=c.sent,c.next=14;break;case 9:return c.prev=9,c.t0=c.catch(3),c.next=13,$t(r,{crossOrigin:a});case 13:s=c.sent;case 14:c.next=19;break;case 16:return c.next=18,$t(r,{crossOrigin:a});case 18:s=c.sent;case 19:return c.abrupt("return",s);case 20:case"end":return c.stop()}},t,null,[[3,9]])})),Zt.apply(this,arguments)}function Oo(t,r,n){var e=n.objectFit,i=n.size,a=n.correctCentering,o=e==="contain"?Math.max(t.width,t.height):Math.min(t.width,t.height),s=i.mode==="auto"?o:i.mode==="force"?i.value:Math.min(i.value,o),u=(t.width-o)/2,l=(t.height-o)/2;if(a){var c=r.getCorrectionOffset(t,o);u=c.x,l=c.y}return{sourceX:u,sourceY:l,sourceSize:o,destinationSize:s}}function No(t,r,n){for(var e=r.canvas,i=e.width,a=e.height,o=[],s=n.x,u=n.y,l=n.rowHeight,c=n.maxRowWidth,h={},v=0,y=t.length;va||s+O>i&&u+O+l>a||(s+O>i&&(c=Math.max(c,s),s=0,u+=l,l=O),o.push({key:p,image:T,sourceX:b,sourceY:m,sourceSize:E,destinationX:s,destinationY:u,destinationSize:w}),h[p]={x:s,y:u,size:w},s+=O,l=Math.max(l,O))}c=Math.max(c,s);for(var A=c,C=u+l,D=0,k=o.length;D0&&arguments[0]!==void 0?arguments[0]:{};return Jt(this,r),n=Kn(this,r),Z(ne(n),"canvas",document.createElement("canvas")),Z(ne(n),"ctx",n.canvas.getContext("2d",{willReadFrequently:!0})),Z(ne(n),"corrector",new Do),Z(ne(n),"imageStates",{}),Z(ne(n),"textures",[n.ctx.getImageData(0,0,1,1)]),Z(ne(n),"lastTextureCursor",{x:0,y:0,rowHeight:0,maxRowWidth:0}),Z(ne(n),"atlas",{}),n.options=ee(ee({},rr),e),n.canvas.width=n.options.maxTextureSize,n.canvas.height=n.options.maxTextureSize,n}return er(r,[{key:"scheduleGenerateTexture",value:function(){var e=this;typeof this.frameId!="number"&&(typeof this.options.debounceTimeout=="number"?this.frameId=window.setTimeout(function(){e.generateTextures(),e.frameId=void 0},this.options.debounceTimeout):this.generateTextures())}},{key:"generateTextures",value:function(){var e=ko({atlas:this.atlas,textures:this.textures,cursor:this.lastTextureCursor},this.imageStates,this.ctx),i=e.atlas,a=e.textures,o=e.cursor;this.atlas=i,this.textures=a,this.lastTextureCursor=o,this.emit(r.NEW_TEXTURE_EVENT,{atlas:i,textures:a})}},{key:"registerImage",value:(function(){var n=tr(ye().mark(function i(a){var o,s;return ye().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:if(!this.imageStates[a]){l.next=2;break}return l.abrupt("return");case 2:return this.imageStates[a]={status:"loading"},l.prev=3,o=this.options.size,l.next=7,Po(a,{size:o.mode==="force"?o.value:void 0,crossOrigin:this.options.crossOrigin||void 0});case 7:s=l.sent,this.imageStates[a]=ee({status:"ready",image:s},Oo(s,this.corrector,this.options)),this.scheduleGenerateTexture(),l.next=15;break;case 12:l.prev=12,l.t0=l.catch(3),this.imageStates[a]={status:"error"};case 15:case"end":return l.stop()}},i,this,[[3,12]])}));function e(i){return n.apply(this,arguments)}return e})()},{key:"getAtlas",value:function(){return this.atlas}},{key:"getTextures",value:function(){return this.textures}}]),r})(Yn.EventEmitter);Z(ht,"NEW_TEXTURE_EVENT","newTexture");var Fo=["drawHover","drawLabel","drawingMode","keepWithinCircle","padding","colorAttribute","imageAttribute"],Qn=WebGLRenderingContext,Xn=Qn.UNSIGNED_BYTE,Fe=Qn.FLOAT,Io=ee(ee({},rr),{},{drawingMode:"background",keepWithinCircle:!0,drawLabel:void 0,drawHover:void 0,padding:0,colorAttribute:"color",imageAttribute:"image"}),zo=["u_sizeRatio","u_correctionRatio","u_cameraAngle","u_percentagePadding","u_matrix","u_colorizeImages","u_keepWithinCircle","u_atlas"];function nr(t){var r,n=document.createElement("canvas").getContext("webgl"),e=Math.min(n.getParameter(n.MAX_TEXTURE_SIZE),rr.maxTextureSize);n.canvas.remove();var i=ee(ee(ee({},Io),{maxTextureSize:e}),t||{}),a=i.drawHover,o=i.drawLabel,s=i.drawingMode,u=i.keepWithinCircle,l=i.padding,c=i.colorAttribute,h=i.imageAttribute,v=wo(i,Fo),y=new ht(v);return r=(function(_){Zn(p,_);function p(T,E,b){var m;return Jt(this,p),m=Kn(this,p,[T,E,b]),Z(ne(m),"drawLabel",o),Z(ne(m),"drawHover",a),Z(ne(m),"textureManagerCallback",null),m.textureManagerCallback=function(w){var O=w.atlas,A=w.textures,C=A.length!==m.textures.length;m.atlas=O,m.textureImages=A,C&&m.upgradeShaders(),m.bindTextures(),m.latestRenderParams&&m.render(m.latestRenderParams),m.renderer&&m.renderer.refresh&&m.renderer.refresh()},y.on(ht.NEW_TEXTURE_EVENT,m.textureManagerCallback),m.atlas=y.getAtlas(),m.textureImages=y.getTextures(),m.textures=m.textureImages.map(function(){return T.createTexture()}),m.bindTextures(),m}return er(p,[{key:"getDefinition",value:function(){return{VERTICES:3,VERTEX_SHADER_SOURCE:So,FRAGMENT_SHADER_SOURCE:xo({texturesCount:y.getTextures().length}),METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:zo,ATTRIBUTES:[{name:"a_position",size:2,type:Fe},{name:"a_size",size:1,type:Fe},{name:"a_color",size:4,type:Xn,normalized:!0},{name:"a_id",size:4,type:Xn,normalized:!0},{name:"a_texture",size:4,type:Fe},{name:"a_textureIndex",size:1,type:Fe}],CONSTANT_ATTRIBUTES:[{name:"a_angle",size:1,type:Fe}],CONSTANT_DATA:[[p.ANGLE_1],[p.ANGLE_2],[p.ANGLE_3]]}}},{key:"upgradeShaders",value:function(){var E=this.getDefinition(),b=this.normalProgram,m=b.program,w=b.buffer,O=b.vertexShader,A=b.fragmentShader,C=b.gl;C.deleteProgram(m),C.deleteBuffer(w),C.deleteShader(O),C.deleteShader(A),this.normalProgram=this.getProgramInfo("normal",C,E.VERTEX_SHADER_SOURCE,E.FRAGMENT_SHADER_SOURCE,null)}},{key:"kill",value:function(){var E,b=(E=this.normalProgram)===null||E===void 0?void 0:E.gl;if(b)for(var m=0;m=this.textures.length){var m=E.createTexture();m&&this.textures.push(m)}E.activeTexture(E.TEXTURE0+b),E.bindTexture(E.TEXTURE_2D,this.textures[b]),E.texImage2D(E.TEXTURE_2D,0,E.RGBA,E.RGBA,E.UNSIGNED_BYTE,this.textureImages[b]),E.generateMipmap(E.TEXTURE_2D)}}},{key:"renderProgram",value:function(E,b){if(!b.isPicking)for(var m=b.gl,w=0;wsr,DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS:()=>li,DEFAULT_INDEX_PARALLEL_EDGES_OPTIONS:()=>ci,EdgeCurvedArrowProgram:()=>ts,EdgeCurvedDoubleArrowProgram:()=>rs,createDrawCurvedEdgeLabel:()=>ui,createEdgeCurveProgram:()=>dt,default:()=>es,indexParallelEdgesIndex:()=>Jo});function Uo(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function ni(t){var r=Uo(t,"string");return typeof r=="symbol"?r:r+""}function ii(t,r,n){return(r=ni(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function ei(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function Le(t){for(var r=1;rt.length)&&(r=t.length);for(var n=0,e=Array(r);nF){var M="\u2026";for(p=p+M,N=a.measureText(p).width;N>F&&p.length>1;)p=p.slice(0,-2)+M,N=a.measureText(p).width;if(p.length<4)return}for(var V={},Q=0,q=p.length;QIe,downloadAsImage:()=>gr,downloadAsJPEG:()=>ds,downloadAsPNG:()=>fs,drawOnCanvas:()=>pi,toBlob:()=>vr,toFile:()=>hs});var mi=ve(di()),Ie={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function ue(){ue=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(f,d,g){f[d]=g.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(f,d,g){return Object.defineProperty(f,d,{value:g,enumerable:!0,configurable:!0,writable:!0}),f[d]}try{l({},"")}catch{l=function(d,g,S){return d[g]=S}}function c(f,d,g,S){var R=d&&d.prototype instanceof E?d:E,L=Object.create(R.prototype),N=new U(S||[]);return i(L,"_invoke",{value:I(f,g,N)}),L}function h(f,d,g){try{return{type:"normal",arg:f.call(d,g)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var v="suspendedStart",y="suspendedYield",_="executing",p="completed",T={};function E(){}function b(){}function m(){}var w={};l(w,o,function(){return this});var O=Object.getPrototypeOf,A=O&&O(O(H([])));A&&A!==n&&e.call(A,o)&&(w=A);var C=m.prototype=E.prototype=Object.create(w);function D(f){["next","throw","return"].forEach(function(d){l(f,d,function(g){return this._invoke(d,g)})})}function k(f,d){function g(R,L,N,F){var M=h(f[R],f,L);if(M.type!=="throw"){var V=M.arg,Q=V.value;return Q&&typeof Q=="object"&&e.call(Q,"__await")?d.resolve(Q.__await).then(function(q){g("next",q,N,F)},function(q){g("throw",q,N,F)}):d.resolve(Q).then(function(q){V.value=q,N(V)},function(q){return g("throw",q,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,L){function N(){return new d(function(F,M){g(R,L,F,M)})}return S=S?S.then(N,N):N()}})}function I(f,d,g){var S=v;return function(R,L){if(S===_)throw Error("Generator is already running");if(S===p){if(R==="throw")throw L;return{value:t,done:!0}}for(g.method=R,g.arg=L;;){var N=g.delegate;if(N){var F=z(N,g);if(F){if(F===T)continue;return F}}if(g.method==="next")g.sent=g._sent=g.arg;else if(g.method==="throw"){if(S===v)throw S=p,g.arg;g.dispatchException(g.arg)}else g.method==="return"&&g.abrupt("return",g.arg);S=_;var M=h(f,d,g);if(M.type==="normal"){if(S=g.done?p:y,M.arg===T)continue;return{value:M.arg,done:g.done}}M.type==="throw"&&(S=p,g.method="throw",g.arg=M.arg)}}}function z(f,d){var g=d.method,S=f.iterator[g];if(S===t)return d.delegate=null,g==="throw"&&f.iterator.return&&(d.method="return",d.arg=t,z(f,d),d.method==="throw")||g!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+g+"' method")),T;var R=h(S,f.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var L=R.arg;return L?L.done?(d[f.resultName]=L.value,d.next=f.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):L:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(f){var d={tryLoc:f[0]};1 in f&&(d.catchLoc=f[1]),2 in f&&(d.finallyLoc=f[2],d.afterLoc=f[3]),this.tryEntries.push(d)}function j(f){var d=f.completion||{};d.type="normal",delete d.arg,f.completion=d}function U(f){this.tryEntries=[{tryLoc:"root"}],f.forEach(G,this),this.reset(!0)}function H(f){if(f||f===""){var d=f[o];if(d)return d.call(f);if(typeof f.next=="function")return f;if(!isNaN(f.length)){var g=-1,S=function R(){for(;++g=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function as(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function os(t){var r=as(t,"string");return typeof r=="symbol"?r:r+""}function ss(t,r,n){return(r=os(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function vi(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&O[1]!==void 0?O[1]:{},e=J(J({},Ie),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,h=r.getDimensions(),v=window.devicePixelRatio||1,y=typeof o!="number"?h.width:o,_=typeof s!="number"?h.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(_,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new bn(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),E=document.createElement("CANVAS"),E.setAttribute("width",y*v+""),E.setAttribute("height",_*v+""),b=E.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*v,_*v),!c){C.next=26;break}return C.next=26,c(T);case 26:return m=T.getCanvases(),w=i?i.filter(function(D){return!!m[D]}):Object.keys(m),w.forEach(function(D){b.drawImage(m[D],0,0,y*v,_*v,0,0,y*v,_*v)}),T.kill(),p.remove(),C.abrupt("return",E);case 32:case"end":return C.stop()}},t)})),cr.apply(this,arguments)}function us(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function ls(t,r){if(t==null)return{};var n,e,i=us(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.format,a=ls(e,cs),l.next=4,pi(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,h){o.toBlob(function(v){v?c(v):h(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),hr.apply(this,arguments)}function hs(t){return fr.apply(this,arguments)}function fr(){return fr=gt(ue().mark(function t(r){var n,e,i,a,o,s=arguments;return ue().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),fr.apply(this,arguments)}function gr(t){return dr.apply(this,arguments)}function dr(){return dr=gt(ue().mark(function t(r){var n,e,i,a,o,s=arguments;return ue().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:o=l.sent,mi.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),dr.apply(this,arguments)}function fs(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"png"}))}function ds(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"jpeg"}))}export{Gt as Camera,qe as EdgeArrowProgram,Ma as EdgeDoubleArrowProgram,$e as EdgeRectangleProgram,pn as MouseCaptor,Qa as NodeSquareProgram,yn as Sigma,ye as createEdgeArrowHeadProgram,Ne as createEdgeCompoundProgram,Bn as createNodeBorderProgram,Xe as drawDiscNodeHover,fi as edgeCurve,yi as exportImage,Jn as nodeImage}; +`);return i}var sr=.25,li={arrowHead:null,curvatureAttribute:"curvature",defaultCurvature:sr},ci={edgeIndexAttribute:"parallelIndex",edgeMinIndexAttribute:"parallelMinIndex",edgeMaxIndexAttribute:"parallelMaxIndex"};function Jo(t,r){var n=Le(Le({},ci),r||{}),e={},i={},a={},o=0;t.forEachNode(function(A){e[A]=++o+""}),t.forEachEdge(function(A,C,D,k){var I=e[D],z=e[k],G=[I,z].join("-");i[A]=G,a[G]=[I,z].sort().join("-")});var s={},u={};t.forEachEdge(function(A){var C=i[A],D=a[C];s[C]=s[C]||[],s[C].push(A),u[D]=u[D]||[],u[D].push(A)});for(var l in s){var c=s[l],h=c.length,v=u[a[l]].length;if(h===1&&v===1){var y=c[0];t.setEdgeAttribute(y,n.edgeIndexAttribute,null),t.setEdgeAttribute(y,n.edgeMaxIndexAttribute,null)}else if(h===1){var _=c[0];t.setEdgeAttribute(_,n.edgeIndexAttribute,1),t.setEdgeAttribute(_,n.edgeMaxIndexAttribute,1)}else if(h===v)for(var p=(h-1)/2,T=-p,E=0;EIe,downloadAsImage:()=>gr,downloadAsJPEG:()=>hs,downloadAsPNG:()=>cs,drawOnCanvas:()=>pi,toBlob:()=>vr,toFile:()=>ls});var mi=ve(di()),Ie={layers:null,width:null,height:null,fileName:"graph",format:"png",sigmaSettings:{},cameraState:null,backgroundColor:"transparent",withTempRenderer:null};function le(){le=function(){return r};var t,r={},n=Object.prototype,e=n.hasOwnProperty,i=Object.defineProperty||function(f,d,g){f[d]=g.value},a=typeof Symbol=="function"?Symbol:{},o=a.iterator||"@@iterator",s=a.asyncIterator||"@@asyncIterator",u=a.toStringTag||"@@toStringTag";function l(f,d,g){return Object.defineProperty(f,d,{value:g,enumerable:!0,configurable:!0,writable:!0}),f[d]}try{l({},"")}catch{l=function(d,g,S){return d[g]=S}}function c(f,d,g,S){var R=d&&d.prototype instanceof E?d:E,L=Object.create(R.prototype),N=new U(S||[]);return i(L,"_invoke",{value:I(f,g,N)}),L}function h(f,d,g){try{return{type:"normal",arg:f.call(d,g)}}catch(S){return{type:"throw",arg:S}}}r.wrap=c;var v="suspendedStart",y="suspendedYield",_="executing",p="completed",T={};function E(){}function b(){}function m(){}var w={};l(w,o,function(){return this});var O=Object.getPrototypeOf,A=O&&O(O(H([])));A&&A!==n&&e.call(A,o)&&(w=A);var C=m.prototype=E.prototype=Object.create(w);function D(f){["next","throw","return"].forEach(function(d){l(f,d,function(g){return this._invoke(d,g)})})}function k(f,d){function g(R,L,N,F){var M=h(f[R],f,L);if(M.type!=="throw"){var V=M.arg,Q=V.value;return Q&&typeof Q=="object"&&e.call(Q,"__await")?d.resolve(Q.__await).then(function(q){g("next",q,N,F)},function(q){g("throw",q,N,F)}):d.resolve(Q).then(function(q){V.value=q,N(V)},function(q){return g("throw",q,N,F)})}F(M.arg)}var S;i(this,"_invoke",{value:function(R,L){function N(){return new d(function(F,M){g(R,L,F,M)})}return S=S?S.then(N,N):N()}})}function I(f,d,g){var S=v;return function(R,L){if(S===_)throw Error("Generator is already running");if(S===p){if(R==="throw")throw L;return{value:t,done:!0}}for(g.method=R,g.arg=L;;){var N=g.delegate;if(N){var F=z(N,g);if(F){if(F===T)continue;return F}}if(g.method==="next")g.sent=g._sent=g.arg;else if(g.method==="throw"){if(S===v)throw S=p,g.arg;g.dispatchException(g.arg)}else g.method==="return"&&g.abrupt("return",g.arg);S=_;var M=h(f,d,g);if(M.type==="normal"){if(S=g.done?p:y,M.arg===T)continue;return{value:M.arg,done:g.done}}M.type==="throw"&&(S=p,g.method="throw",g.arg=M.arg)}}}function z(f,d){var g=d.method,S=f.iterator[g];if(S===t)return d.delegate=null,g==="throw"&&f.iterator.return&&(d.method="return",d.arg=t,z(f,d),d.method==="throw")||g!=="return"&&(d.method="throw",d.arg=new TypeError("The iterator does not provide a '"+g+"' method")),T;var R=h(S,f.iterator,d.arg);if(R.type==="throw")return d.method="throw",d.arg=R.arg,d.delegate=null,T;var L=R.arg;return L?L.done?(d[f.resultName]=L.value,d.next=f.nextLoc,d.method!=="return"&&(d.method="next",d.arg=t),d.delegate=null,T):L:(d.method="throw",d.arg=new TypeError("iterator result is not an object"),d.delegate=null,T)}function G(f){var d={tryLoc:f[0]};1 in f&&(d.catchLoc=f[1]),2 in f&&(d.finallyLoc=f[2],d.afterLoc=f[3]),this.tryEntries.push(d)}function j(f){var d=f.completion||{};d.type="normal",delete d.arg,f.completion=d}function U(f){this.tryEntries=[{tryLoc:"root"}],f.forEach(G,this),this.reset(!0)}function H(f){if(f||f===""){var d=f[o];if(d)return d.call(f);if(typeof f.next=="function")return f;if(!isNaN(f.length)){var g=-1,S=function R(){for(;++g=0;--S){var R=this.tryEntries[S],L=R.completion;if(R.tryLoc==="root")return g("end");if(R.tryLoc<=this.prev){var N=e.call(R,"catchLoc"),F=e.call(R,"finallyLoc");if(N&&F){if(this.prev=0;--g){var S=this.tryEntries[g];if(S.tryLoc<=this.prev&&e.call(S,"finallyLoc")&&this.prev=0;--d){var g=this.tryEntries[d];if(g.finallyLoc===f)return this.complete(g.completion,g.afterLoc),j(g),T}},catch:function(f){for(var d=this.tryEntries.length-1;d>=0;--d){var g=this.tryEntries[d];if(g.tryLoc===f){var S=g.completion;if(S.type==="throw"){var R=S.arg;j(g)}return R}}throw Error("illegal catch attempt")},delegateYield:function(f,d,g){return this.delegate={iterator:H(f),resultName:d,nextLoc:g},this.method==="next"&&(this.arg=t),T}},r}function ns(t,r){if(typeof t!="object"||!t)return t;var n=t[Symbol.toPrimitive];if(n!==void 0){var e=n.call(t,r||"default");if(typeof e!="object")return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return(r==="string"?String:Number)(t)}function is(t){var r=ns(t,"string");return typeof r=="symbol"?r:r+""}function as(t,r,n){return(r=is(r))in t?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n,t}function vi(t,r){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);r&&(e=e.filter(function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable})),n.push.apply(n,e)}return n}function J(t){for(var r=1;r1&&O[1]!==void 0?O[1]:{},e=J(J({},Ie),n),i=e.layers,a=e.backgroundColor,o=e.width,s=e.height,u=e.cameraState,l=e.sigmaSettings,c=e.withTempRenderer,h=r.getDimensions(),v=window.devicePixelRatio||1,y=typeof o!="number"?h.width:o,_=typeof s!="number"?h.height:s,p=document.createElement("DIV"),p.style.width="".concat(y,"px"),p.style.height="".concat(_,"px"),p.style.position="absolute",p.style.right="101%",p.style.bottom="101%",document.body.appendChild(p),T=new bn(r.getGraph(),p,J(J({},r.getSettings()),l)),T.getCamera().setState(u||r.getCamera().getState()),T.setCustomBBox(r.getCustomBBox()),T.refresh(),E=document.createElement("CANVAS"),E.setAttribute("width",y*v+""),E.setAttribute("height",_*v+""),b=E.getContext("2d"),b.fillStyle=a,b.fillRect(0,0,y*v,_*v),!c){C.next=26;break}return C.next=26,c(T);case 26:return m=T.getCanvases(),w=i?i.filter(function(D){return!!m[D]}):Object.keys(m),w.forEach(function(D){b.drawImage(m[D],0,0,y*v,_*v,0,0,y*v,_*v)}),T.kill(),p.remove(),C.abrupt("return",E);case 32:case"end":return C.stop()}},t)})),cr.apply(this,arguments)}function os(t,r){if(t==null)return{};var n={};for(var e in t)if({}.hasOwnProperty.call(t,e)){if(r.includes(e))continue;n[e]=t[e]}return n}function ss(t,r){if(t==null)return{};var n,e,i=os(t,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(e=0;e1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.format,a=ss(e,us),l.next=4,pi(r,a);case 4:return o=l.sent,l.abrupt("return",new Promise(function(c,h){o.toBlob(function(v){v?c(v):h(new Error('No actual blob was obtained by canvas.toBlob(..., "image/'.concat(i,'")')))},"image/".concat(i))}));case 6:case"end":return l.stop()}},t)})),hr.apply(this,arguments)}function ls(t){return fr.apply(this,arguments)}function fr(){return fr=vt(le().mark(function t(r){var n,e,i,a,o,s=arguments;return le().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:return o=l.sent,l.abrupt("return",new File([o],"".concat(i,".").concat(a)));case 6:case"end":return l.stop()}},t)})),fr.apply(this,arguments)}function gr(t){return dr.apply(this,arguments)}function dr(){return dr=vt(le().mark(function t(r){var n,e,i,a,o,s=arguments;return le().wrap(function(l){for(;;)switch(l.prev=l.next){case 0:return n=s.length>1&&s[1]!==void 0?s[1]:{},e=J(J({},Ie),n),i=e.fileName,a=e.format,l.next=4,vr(r,n);case 4:o=l.sent,mi.default.saveAs(o,"".concat(i,".").concat(a));case 6:case"end":return l.stop()}},t)})),dr.apply(this,arguments)}function cs(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"png"}))}function hs(t){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return gr(t,J(J({},r),{},{format:"jpeg"}))}export{Gt as Camera,ae as EdgeProgram,qe as EdgeRectangleProgram,pn as MouseCaptor,Ka as NodeSquareProgram,yn as Sigma,Ne as createEdgeCompoundProgram,Bn as createNodeBorderProgram,Xe as drawDiscNodeHover,fi as edgeCurve,yi as exportImage,Y as floatColor,Jn as nodeImage}; diff --git a/src/managers/io.js b/src/managers/io.js index 791ad3d..f2766a0 100644 --- a/src/managers/io.js +++ b/src/managers/io.js @@ -338,7 +338,9 @@ const EXCEL_EDGE_PROPERTIES = [ }, { column: "Start Arrow Type", - type: "oneOf:triangle|circle|diamond|vee|rect|triangleRect|simple", + // New marker vocabulary + legacy G6 names (alias-mapped at render time + // by graph_model.edgeMarkerCode) so old workbooks keep importing. + type: "oneOf:arrow|rect|diamond|circle|tee|triangle|vee|triangleRect|simple|square", apply: (e, v) => { e.style.startArrowType = v; }, @@ -368,7 +370,7 @@ const EXCEL_EDGE_PROPERTIES = [ }, { column: "End Arrow Type", - type: "oneOf:triangle|circle|diamond|vee|rect|triangleRect|simple", + type: "oneOf:arrow|rect|diamond|circle|tee|triangle|vee|triangleRect|simple|square", apply: (e, v) => { e.style.endArrowType = v; }, diff --git a/src/managers/ui_style_div.js b/src/managers/ui_style_div.js index f9f18d0..e6a8ff8 100644 --- a/src/managers/ui_style_div.js +++ b/src/managers/ui_style_div.js @@ -933,28 +933,32 @@ function createStyleDiv(cache) { createBooleanControls(rowThirteen, "Edge Start Arrow", "Enable/Disable the start arrow of the selected edges."); const rowFourteen = createNewRow(edgeDiv); - appendLabel(rowFourteen, "Start Arrow Size", "Define the size of the start arrow of the selected edges."); + appendLabel(rowFourteen, "Start Arrow Size", "Define the size of the start marker of the selected edges."); createNumericalSlider(rowFourteen, "Edge Start Arrow Size", cache.DEFAULTS.EDGE.ARROWS.START_SIZE, - {min: 10, max: 40, step: 1}, "Define the size of the start arrow of the selected edges.", true); + {min: 4, max: 40, step: 1}, "Define the size of the start marker of the selected edges.", true); const rowFifteen = createNewRow(edgeDiv); - appendLabel(rowFifteen, "Start Arrow Type", "Define the type of the start arrow of the selected edges."); + appendLabel(rowFifteen, "Start Arrow Type", + "Marker shape at the source end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); createCategoricalControls(rowFifteen, "Edge Start Arrow Type", cache.DEFAULTS.EDGE.ARROWS.START_TYPE, - cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, "Define the type of the start arrow of the selected edges."); + cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, + "Marker shape at the source end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); const rowSixteen = createNewRow(edgeDiv); appendLabel(rowSixteen, "End Arrow", "Enable/Disable the end arrow of the selected edges."); createBooleanControls(rowSixteen, "Edge End Arrow", "Enable/Disable the end arrow of the selected edges."); const rowEighteen = createNewRow(edgeDiv); - appendLabel(rowEighteen, "End Arrow Size", "Define the size of the end arrow of the selected edges."); + appendLabel(rowEighteen, "End Arrow Size", "Define the size of the end marker of the selected edges."); createNumericalSlider(rowEighteen, "Edge End Arrow Size", cache.DEFAULTS.EDGE.ARROWS.END_SIZE, - {min: 10, max: 40, step: 1}, "Define the size of the end arrow of the selected edges.", true); + {min: 4, max: 40, step: 1}, "Define the size of the end marker of the selected edges.", true); const rowNineteen = createNewRow(edgeDiv); - appendLabel(rowNineteen, "End Arrow Type", "Define the type of the end arrow of the selected edges."); + appendLabel(rowNineteen, "End Arrow Type", + "Marker shape at the target end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); createCategoricalControls(rowNineteen, "Edge End Arrow Type", cache.DEFAULTS.EDGE.ARROWS.END_TYPE, - cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, "Define the type of the end arrow of the selected edges."); + cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, + "Marker shape at the target end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); appendHorizontalRule(edgeDiv); @@ -964,7 +968,7 @@ function createStyleDiv(cache) { const rowTwentyOne = createNewRow(edgeDiv); appendLabel(rowTwentyOne, "Halo Color", "Define the color of the halo for the selected edges."); - createColorControls(rowTwentyOne, "Edge Halo Color", cache.DEFAULTS.EDGE.COLOR, + createColorControls(rowTwentyOne, "Edge Halo Color", cache.DEFAULTS.EDGE.HALO.COLOR, cache.DEFAULTS.STYLES.EDGE_COLORS); const rowTwentyTwo = createNewRow(edgeDiv); diff --git a/src/package/vendor_entry_sigma.mjs b/src/package/vendor_entry_sigma.mjs index 19ca575..09f6e24 100644 --- a/src/package/vendor_entry_sigma.mjs +++ b/src/package/vendor_entry_sigma.mjs @@ -4,13 +4,12 @@ // only. Bundled by src/package/vendor_libs.js via esbuild. export {Sigma, Camera, MouseCaptor} from 'sigma'; export { + EdgeProgram, EdgeRectangleProgram, - EdgeArrowProgram, - EdgeDoubleArrowProgram, - createEdgeArrowHeadProgram, createEdgeCompoundProgram, drawDiscNodeHover, } from 'sigma/rendering'; +export {floatColor} from 'sigma/utils'; export {NodeSquareProgram} from '@sigma/node-square'; export {createNodeBorderProgram} from '@sigma/node-border'; export * as nodeImage from '@sigma/node-image'; diff --git a/tests/excel-style-roundtrip.test.js b/tests/excel-style-roundtrip.test.js index b35a088..a54cc39 100644 --- a/tests/excel-style-roundtrip.test.js +++ b/tests/excel-style-roundtrip.test.js @@ -195,7 +195,7 @@ describe("Excel style round-trip — edges", () => { const attrsAfter = edgeAttributesFromStyle(reimported.style, reimported.type); expect(attrsAfter).toEqual(attrsBefore); - expect(attrsBefore.type).toBe("curvedDoubleArrow"); // cubic + both arrows + expect(attrsBefore.type).toBe("styledCurve"); // cubic + both arrows expect(attrsBefore.size).toBe(2); expect(attrsBefore.labelSize).toBe(14); expect(attrsBefore.labelAutoRotate).toBe(true); diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index a550e16..88645f1 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -4,6 +4,8 @@ import { nodeAttributesFromStyle, edgeAttributesFromStyle, sigmaEdgeType, + edgeMarkerCode, + EDGE_MARKERS, flipY, hoverNeighborhood, makeNodeReducer, @@ -246,7 +248,8 @@ describe("buildGraphologyGraph — population", () => { expect(graph.getEdgeAttribute("straight", "type")).toBe("line"); expect(graph.getEdgeAttribute("curved", "type")).toBe("curve"); - expect(graph.getEdgeAttribute("arrowed", "type")).toBe("arrow"); + expect(graph.getEdgeAttribute("arrowed", "type")).toBe("styledLine"); + expect(graph.getEdgeAttribute("arrowed", "endMarker")).toBe(EDGE_MARKERS.arrow); }); }); @@ -526,20 +529,250 @@ describe("attribute mapping helpers", () => { }); }); - it("sigmaEdgeType maps the full type × arrows matrix", () => { + it("sigmaEdgeType routes plain edges to the fast paths", () => { expect(sigmaEdgeType("line")).toBe("line"); - expect(sigmaEdgeType("line", { endArrow: true })).toBe("arrow"); - expect(sigmaEdgeType("line", { startArrow: true })).toBe("sourceArrow"); - expect(sigmaEdgeType("line", { startArrow: true, endArrow: true })).toBe("doubleArrow"); + expect(sigmaEdgeType("line", { startArrow: false, endArrow: false, halo: false })).toBe("line"); for (const curved of ["cubic", "quadratic", "polyline"]) { expect(sigmaEdgeType(curved)).toBe("curve"); - expect(sigmaEdgeType(curved, { endArrow: true })).toBe("curvedArrow"); - expect(sigmaEdgeType(curved, { startArrow: true })).toBe("curvedSourceArrow"); - expect(sigmaEdgeType(curved, { startArrow: true, endArrow: true })).toBe( - "curvedDoubleArrow", - ); } }); + + it("sigmaEdgeType routes any marker or halo to the styled compound programs", () => { + for (const style of [ + { endArrow: true }, + { startArrow: true }, + { startArrow: true, endArrow: true }, + { halo: true }, + { halo: true, haloLineWidth: 5 }, + ]) { + expect(sigmaEdgeType("line", style)).toBe("styledLine"); + for (const curved of ["cubic", "quadratic", "polyline"]) { + expect(sigmaEdgeType(curved, style)).toBe("styledCurve"); + } + } + }); + + it("sigmaEdgeType ignores a halo with zero width or disabled flag", () => { + expect(sigmaEdgeType("line", { halo: true, haloLineWidth: 0 })).toBe("line"); + expect(sigmaEdgeType("line", { halo: false, haloLineWidth: 5 })).toBe("line"); + expect(sigmaEdgeType("cubic", { halo: true, haloLineWidth: 0 })).toBe("curve"); + }); + + it("edgeMarkerCode maps the new vocabulary and legacy G6 aliases", () => { + expect(edgeMarkerCode("arrow")).toBe(EDGE_MARKERS.arrow); + expect(edgeMarkerCode("rect")).toBe(EDGE_MARKERS.rect); + expect(edgeMarkerCode("diamond")).toBe(EDGE_MARKERS.diamond); + expect(edgeMarkerCode("circle")).toBe(EDGE_MARKERS.circle); + expect(edgeMarkerCode("tee")).toBe(EDGE_MARKERS.tee); + // Legacy G6 arrow types degrade to the nearest marker, never to "none". + expect(edgeMarkerCode("triangle")).toBe(EDGE_MARKERS.arrow); + expect(edgeMarkerCode("vee")).toBe(EDGE_MARKERS.arrow); + expect(edgeMarkerCode("simple")).toBe(EDGE_MARKERS.arrow); + expect(edgeMarkerCode("triangleRect")).toBe(EDGE_MARKERS.rect); + expect(edgeMarkerCode("square")).toBe(EDGE_MARKERS.rect); + expect(edgeMarkerCode("unknown-future-type")).toBe(EDGE_MARKERS.arrow); + expect(edgeMarkerCode(undefined)).toBe(EDGE_MARKERS.arrow); + }); +}); + +describe("edge marker + halo attribute mapping", () => { + // The adapter applies updates via mergeEdgeAttributes, so the full + // marker/halo set must be emitted on every type-bearing mapping — off + // states as 0/null, never omitted. + const FULL_OFF = { + startMarker: 0, + startMarkerSize: 0, + endMarker: 0, + endMarkerSize: 0, + haloWidth: 0, + haloColor: null, + }; + + it("emits the full marker/halo set (all off) for a bare typed edge", () => { + const attrs = edgeAttributesFromStyle({}, "line"); + + expect(attrs).toEqual({ type: "line", ...FULL_OFF }); + }); + + it("omits marker/halo attrs when no type is given (delta-only mapping)", () => { + const attrs = edgeAttributesFromStyle({ stroke: "#112233" }); + + expect(attrs).toEqual({ color: "#112233" }); + }); + + it("maps enabled arrows to marker enums with per-end sizes", () => { + const attrs = edgeAttributesFromStyle( + { + startArrow: true, + startArrowType: "tee", + startArrowSize: 12, + endArrow: true, + endArrowType: "circle", + endArrowSize: 10, + }, + "line", + ); + + expect(attrs.type).toBe("styledLine"); + expect(attrs.startMarker).toBe(EDGE_MARKERS.tee); + expect(attrs.startMarkerSize).toBe(12); + expect(attrs.endMarker).toBe(EDGE_MARKERS.circle); + expect(attrs.endMarkerSize).toBe(10); + }); + + it("disabled arrow flag zeroes the marker even when a type string is set", () => { + const attrs = edgeAttributesFromStyle( + { startArrow: false, startArrowType: "diamond", endArrow: true, endArrowType: "diamond" }, + "line", + ); + + expect(attrs.startMarker).toBe(0); + expect(attrs.endMarker).toBe(EDGE_MARKERS.diamond); + }); + + it("non-finite or non-positive arrow sizes fall back to 0 (proportional sizing)", () => { + const attrs = edgeAttributesFromStyle( + { endArrow: true, endArrowSize: -3, startArrow: true, startArrowSize: "big" }, + "line", + ); + + expect(attrs.startMarkerSize).toBe(0); + expect(attrs.endMarkerSize).toBe(0); + }); + + it("maps an enabled halo to haloWidth/haloColor", () => { + const attrs = edgeAttributesFromStyle( + { halo: true, haloLineWidth: 4, haloStroke: "#8CA6D9" }, + "line", + ); + + expect(attrs.type).toBe("styledLine"); + expect(attrs.haloWidth).toBe(4); + expect(attrs.haloColor).toBe("#8CA6D9"); + }); + + it("halo without explicit width uses the config default width", () => { + const attrs = edgeAttributesFromStyle({ halo: true }, "line"); + + expect(attrs.haloWidth).toBe(DEFAULTS.EDGE.HALO.WIDTH); + expect(attrs.haloColor).toBe(DEFAULTS.EDGE.HALO.COLOR); + }); + + it("disabled halo clears width and color regardless of the other halo keys", () => { + const attrs = edgeAttributesFromStyle( + { halo: false, haloLineWidth: 9, haloStroke: "#8CA6D9" }, + "line", + ); + + expect(attrs.haloWidth).toBe(0); + expect(attrs.haloColor).toBeNull(); + }); + + describe("merge hygiene matrix (mergeEdgeAttributes semantics)", () => { + const merge = (from, to) => ({ ...from, ...to }); + const ARROWS_ON = { + startArrow: true, + startArrowType: "rect", + startArrowSize: 12, + endArrow: true, + endArrowType: "tee", + endArrowSize: 10, + }; + const HALO_ON = { halo: true, haloLineWidth: 5, haloStroke: "#C33D35" }; + + it("markers on → off clears both enums and routes back to the fast path", () => { + const res = merge( + edgeAttributesFromStyle(ARROWS_ON, "line"), + edgeAttributesFromStyle({ ...ARROWS_ON, startArrow: false, endArrow: false }, "line"), + ); + + expect(res.type).toBe("line"); + expect(res.startMarker).toBe(0); + expect(res.endMarker).toBe(0); + }); + + it("halo on → off clears width/color and routes back to the fast path", () => { + const res = merge( + edgeAttributesFromStyle(HALO_ON, "line"), + edgeAttributesFromStyle({ ...HALO_ON, halo: false }, "line"), + ); + + expect(res.type).toBe("line"); + expect(res.haloWidth).toBe(0); + expect(res.haloColor).toBeNull(); + }); + + it("halo toggles never disturb marker attrs (and vice versa)", () => { + const both = edgeAttributesFromStyle({ ...ARROWS_ON, ...HALO_ON }, "line"); + const haloOff = merge( + both, + edgeAttributesFromStyle({ ...ARROWS_ON, ...HALO_ON, halo: false }, "line"), + ); + + expect(haloOff.type).toBe("styledLine"); // markers still active + expect(haloOff.startMarker).toBe(EDGE_MARKERS.rect); + expect(haloOff.endMarker).toBe(EDGE_MARKERS.tee); + expect(haloOff.haloWidth).toBe(0); + + const markersOff = merge( + both, + edgeAttributesFromStyle( + { ...ARROWS_ON, ...HALO_ON, startArrow: false, endArrow: false }, + "line", + ), + ); + expect(markersOff.type).toBe("styledLine"); // halo still active + expect(markersOff.haloWidth).toBe(5); + expect(markersOff.startMarker).toBe(0); + expect(markersOff.endMarker).toBe(0); + }); + + it("marker type change overwrites the enum in place", () => { + const res = merge( + edgeAttributesFromStyle(ARROWS_ON, "line"), + edgeAttributesFromStyle({ ...ARROWS_ON, endArrowType: "circle" }, "line"), + ); + + expect(res.endMarker).toBe(EDGE_MARKERS.circle); + expect(res.startMarker).toBe(EDGE_MARKERS.rect); + }); + + it("straight ↔ curved type changes keep the marker/halo set coherent", () => { + const straight = edgeAttributesFromStyle({ ...ARROWS_ON, ...HALO_ON }, "line"); + const curved = merge( + straight, + edgeAttributesFromStyle({ ...ARROWS_ON, ...HALO_ON }, "cubic"), + ); + + expect(curved.type).toBe("styledCurve"); + expect(curved.startMarker).toBe(EDGE_MARKERS.rect); + expect(curved.haloWidth).toBe(5); + }); + }); + + it("propagates marker/halo attrs into the built graph", () => { + const cache = createMockCache({ + nodes: [makeNode("a"), makeNode("b")], + edges: [ + makeEdge( + "e1", + "a", + "b", + { endArrow: true, endArrowType: "tee", endArrowSize: 14, halo: true, haloLineWidth: 2 }, + "line", + ), + ], + }); + + const graph = buildGraphologyGraph(cache); + + expect(graph.getEdgeAttribute("e1", "type")).toBe("styledLine"); + expect(graph.getEdgeAttribute("e1", "endMarker")).toBe(EDGE_MARKERS.tee); + expect(graph.getEdgeAttribute("e1", "endMarkerSize")).toBe(14); + expect(graph.getEdgeAttribute("e1", "startMarker")).toBe(0); + expect(graph.getEdgeAttribute("e1", "haloWidth")).toBe(2); + expect(graph.getEdgeAttribute("e1", "haloColor")).toBe(DEFAULTS.EDGE.HALO.COLOR); + }); }); describe("badge attribute mapping", () => { From 67fd850e94615f015c32a7f937d98dda657d6584 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 12:14:20 +0200 Subject: [PATCH 20/69] feat(renderer): badge size control and scale-with-node option - new badgeScaleWithNode style prop (default off, preserves current behavior): zoom-independent factor nodeDiameter/DEFAULTS.NODE.SIZE is baked into badgeScaleFactor by graph_model so the renderer stays config-free; drawNodeBadges multiplies it into the badge font size - Badge Size slider (4-32, exposes the previously unreachable badgeFontSize) and Badge Scale With Node toggle in the node style card - badgeScaleWithNode normalized in style.js so it round-trips through Excel export like the other badge props - 6 new tests across graph-model/label-renderers (921 total green); perf gates green --- src/config.js | 2 +- src/graph/graph_model.js | 19 +++++++++++++ src/graph/label_renderers.js | 12 +++++++-- src/graph/style.js | 1 + src/managers/ui_style_div.js | 17 ++++++++++++ tests/excel-export.test.js | 1 + tests/excel-style-pipeline.test.js | 1 + tests/graph-model.test.js | 43 ++++++++++++++++++++++++++++++ tests/label-renderers.test.js | 40 +++++++++++++++++++++++++++ 9 files changed, 133 insertions(+), 3 deletions(-) diff --git a/src/config.js b/src/config.js index c88becc..f0024d4 100644 --- a/src/config.js +++ b/src/config.js @@ -7,7 +7,7 @@ const DEFAULTS = { NODE: { FILL_COLOR: "#C33D35", SIZE: 20, LINE_WIDTH: 1, TYPE: "hexagon", STROKE_COLOR: null, BADGE: { - FONT_SIZE: 8, COLOR: "#C33D35" + FONT_SIZE: 8, COLOR: "#C33D35", SCALE_WITH_NODE: false }, LABEL: { FOREGROUND_COLOR: "#000000", BACKGROUND: false, BACKGROUND_COLOR: null, BACKGROUND_RADIUS: 5, diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index f158f39..ae0c80f 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -87,10 +87,29 @@ function badgeAttributes(style) { }; if (badges.length > 0) { attrs.badgeFontSize = style.badgeFontSize ?? DEFAULTS.NODE.BADGE.FONT_SIZE; + attrs.badgeScaleFactor = badgeScaleFactor(style); } return attrs; } +/** + * Zoom-independent badge scale factor, baked here (not in the renderer, which + * only sees zoom-scaled display data and stays config-free). When + * `badgeScaleWithNode` is on, badges grow/shrink with the node's model size + * relative to the default node size; otherwise the factor is 1 (current + * behavior). Recomputed on every restyle because the merged ref style always + * carries `size` alongside the badge keys. + * + * @param {object} style G6 node style ({size, badgeScaleWithNode, ...}) + * @returns {number} multiplier applied to badgeFontSize by the renderer + */ +function badgeScaleFactor(style) { + const scaleWithNode = style.badgeScaleWithNode ?? DEFAULTS.NODE.BADGE.SCALE_WITH_NODE; + if (!scaleWithNode) return 1; + const diameter = Array.isArray(style.size) ? style.size[0] : style.size; + return Number.isFinite(diameter) && diameter > 0 ? diameter / DEFAULTS.NODE.SIZE : 1; +} + /** * Shape-program attributes for a node: which sigma program draws it, plus * the texture data-URI when the SVG shape program is needed. diff --git a/src/graph/label_renderers.js b/src/graph/label_renderers.js index b3153ec..39d4d37 100644 --- a/src/graph/label_renderers.js +++ b/src/graph/label_renderers.js @@ -75,15 +75,23 @@ const BADGE_PADDING = 2; * follow label visibility (v1 limitation). * * @param {CanvasRenderingContext2D} context - * @param {object} data node display data (x, y, size, badge, badges, badgePalette, badgeFontSize) + * @param {object} data node display data (x, y, size, badge, badges, badgePalette, + * badgeFontSize, badgeScaleFactor) * @param {object} settings sigma settings (labelFont) */ function drawNodeBadges(context, data, settings) { if (!data.badge || !Array.isArray(data.badges) || data.badges.length === 0) return; - const size = Number.isFinite(data.badgeFontSize) + const fontSize = Number.isFinite(data.badgeFontSize) ? data.badgeFontSize : FALLBACK_BADGE_FONT_SIZE; + // badgeScaleFactor (graph_model.js) is zoom-independent — like labels, + // badges keep a constant on-screen size; only the perimeter anchor + // (data.size) follows the camera. + const scale = Number.isFinite(data.badgeScaleFactor) && data.badgeScaleFactor > 0 + ? data.badgeScaleFactor + : 1; + const size = fontSize * scale; context.font = `bold ${size}px ${settings.labelFont}`; data.badges.forEach((badge, index) => { diff --git a/src/graph/style.js b/src/graph/style.js index fea4b42..629557b 100644 --- a/src/graph/style.js +++ b/src/graph/style.js @@ -56,6 +56,7 @@ class GraphStyleManager { badges : src.badges ?? [], badgePalette : src.badgePalette ?? [], badgeFontSize: src.badgeFontSize ?? d.BADGE.FONT_SIZE, + badgeScaleWithNode: src.badgeScaleWithNode ?? d.BADGE.SCALE_WITH_NODE, } }; diff --git a/src/managers/ui_style_div.js b/src/managers/ui_style_div.js index e6a8ff8..c973ff3 100644 --- a/src/managers/ui_style_div.js +++ b/src/managers/ui_style_div.js @@ -139,6 +139,12 @@ function createStyleDiv(cache) { case "Node Label Placement": await cache.gcm.updateNodes({style: {labelPlacement: value}}, commands); break; + case "Node Badge Font Size": + await cache.gcm.updateNodes({style: {badgeFontSize: value}}, commands); + break; + case "Node Badge Scale With Node": + await cache.gcm.updateNodes({style: {badgeScaleWithNode: value}}, commands); + break; case "Edge Color": await cache.gcm.updateEdges({style: {stroke: value}}, commands); break; @@ -857,6 +863,17 @@ function createStyleDiv(cache) { const rowEleven = createNewRow(nodeDiv); appendLabel(rowEleven, "Badges", "Add Badges to the selected nodes."); createNodeBadgeControls(rowEleven); + + const rowTwelve = createNewRow(nodeDiv); + appendLabel(rowTwelve, "Badge Size", "Defines the font size (and pill size) of the selected nodes badges."); + createNumericalSlider(rowTwelve, "Node Badge Font Size", cache.DEFAULTS.NODE.BADGE.FONT_SIZE, + {min: 4, max: 32, step: 1}, "Defines the font size (and pill size) of the selected nodes badges."); + + const rowThirteen = createNewRow(nodeDiv); + appendLabel(rowThirteen, "Badge Scale With Node", + "Scale badges proportionally with each node's size (relative to the default node size)."); + createBooleanControls(rowThirteen, "Node Badge Scale With Node", + "Scale badges proportionally with each node's size (relative to the default node size)."); } function createEdgeConfigCard() { diff --git a/tests/excel-export.test.js b/tests/excel-export.test.js index 48cfcfa..a4a9783 100644 --- a/tests/excel-export.test.js +++ b/tests/excel-export.test.js @@ -26,6 +26,7 @@ function getNodeStyleOrDefaults(node) { badges: src.badges ?? [], badgePalette: src.badgePalette ?? [], badgeFontSize: src.badgeFontSize ?? d.BADGE.FONT_SIZE, + badgeScaleWithNode: src.badgeScaleWithNode ?? d.BADGE.SCALE_WITH_NODE, }, }; diff --git a/tests/excel-style-pipeline.test.js b/tests/excel-style-pipeline.test.js index d01a4d5..9c7c8a3 100644 --- a/tests/excel-style-pipeline.test.js +++ b/tests/excel-style-pipeline.test.js @@ -73,6 +73,7 @@ function getNodeStyleOrDefaults(node) { badges: src.badges ?? [], badgePalette: src.badgePalette ?? [], badgeFontSize: src.badgeFontSize ?? d.BADGE.FONT_SIZE, + badgeScaleWithNode: src.badgeScaleWithNode ?? d.BADGE.SCALE_WITH_NODE, } } diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index 88645f1..07d4eaa 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -794,6 +794,7 @@ describe("badge attribute mapping", () => { badges: BADGES, badgePalette: ["#112233", "#445566"], badgeFontSize: 10, + badgeScaleFactor: 1, }); }); @@ -826,6 +827,48 @@ describe("badge attribute mapping", () => { expect(attrs.badgePalette).toEqual(["#112233", DEFAULTS.NODE.BADGE.COLOR]); expect(attrs.badgeFontSize).toBe(DEFAULTS.NODE.BADGE.FONT_SIZE); + expect(attrs.badgeScaleFactor).toBe(1); // scale-with-node defaults off + }); + + it("emits badgeScaleFactor from the node's model size when badgeScaleWithNode is on", () => { + const attrs = nodeAttributesFromStyle({ + badge: true, + badges: [BADGES[0]], + badgeScaleWithNode: true, + size: DEFAULTS.NODE.SIZE * 2, + }); + + expect(attrs.badgeScaleFactor).toBe(2); + }); + + it("supports [w, h] array sizes for badgeScaleFactor", () => { + const attrs = nodeAttributesFromStyle({ + badge: true, + badges: [BADGES[0]], + badgeScaleWithNode: true, + size: [DEFAULTS.NODE.SIZE / 2, DEFAULTS.NODE.SIZE / 2], + }); + + expect(attrs.badgeScaleFactor).toBe(0.5); + }); + + it("keeps badgeScaleFactor at 1 when badgeScaleWithNode is on but size is missing or invalid", () => { + const base = { badge: true, badges: [BADGES[0]], badgeScaleWithNode: true }; + + expect(nodeAttributesFromStyle(base).badgeScaleFactor).toBe(1); + expect(nodeAttributesFromStyle({ ...base, size: NaN }).badgeScaleFactor).toBe(1); + expect(nodeAttributesFromStyle({ ...base, size: 0 }).badgeScaleFactor).toBe(1); + }); + + it("keeps badgeScaleFactor at 1 when badgeScaleWithNode is explicitly off (toggle-off path)", () => { + const attrs = nodeAttributesFromStyle({ + badge: true, + badges: [BADGES[0]], + badgeScaleWithNode: false, + size: DEFAULTS.NODE.SIZE * 3, + }); + + expect(attrs.badgeScaleFactor).toBe(1); }); it("propagates badge attrs into the built graph", () => { diff --git a/tests/label-renderers.test.js b/tests/label-renderers.test.js index 52291b7..9925b2a 100644 --- a/tests/label-renderers.test.js +++ b/tests/label-renderers.test.js @@ -295,6 +295,46 @@ describe("drawNodeLabel — badges (G6 v5 parity: colored pill + white text)", ( expect(ctx.font).toBe("bold 8px Arial"); }); + + it("multiplies font and pill size by badgeScaleFactor (scale-with-node)", () => { + const ctx = stubContext(); + + drawNodeLabel( + ctx, + badged([{ text: "B", placement: "right" }], { badgeScaleFactor: 2 }), + SETTINGS, + ); + + const size = BADGE_FONT * 2; + expect(ctx.font).toBe(`bold ${size}px Arial`); + // Pill height scales with the effective font size; anchor stays on the + // node perimeter (unchanged by the factor). + const boxWidth = CHAR_W + 2 * BADGE_PAD; + const boxHeight = size + 2 * BADGE_PAD; + expect(findCall(ctx, "roundRect").slice(1)).toEqual([ + 110 - boxWidth / 2, + 100 - boxHeight / 2, + boxWidth, + boxHeight, + boxHeight / 2, + ]); + const [, , , by] = fillTexts(ctx)[1]; + expect(by).toBeCloseTo(100 + size * 0.35); + }); + + it("ignores non-finite or non-positive badgeScaleFactor (draws at base size)", () => { + for (const badgeScaleFactor of [NaN, 0, -1, undefined]) { + const ctx = stubContext(); + + drawNodeLabel( + ctx, + badged([{ text: "B", placement: "right" }], { badgeScaleFactor }), + SETTINGS, + ); + + expect(ctx.font).toBe(`bold ${BADGE_FONT}px Arial`); + } + }); }); describe("drawEdgeLabel", () => { From a8edbfe1087af833110a0ce35c0391cc2a33ad88 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 12:46:07 +0200 Subject: [PATCH 21/69] feat(ui): dark mode toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CSS custom-property tokens at the top of style.css (:root light set + [data-theme="dark"] overrides, color-scheme flip for native widgets); ~230 hardcoded colors converted across panels, sidebars, inputs, popups, tables, tooltips, overlays; brand purple/red kept as-is - new src/utilities/theme.js: resolveInitialTheme (stored pref wins, prefers-color-scheme as unstored default that keeps following the OS), applyTheme via data-theme on persisting to localStorage gllTheme - 🌙/☀️ toggle button; renderer default label color flips live via setSetting; stage/minimap/bubble canvases themed - label readability: io.js bakes labelFill #000000 into every labelled element, so exactly that baked default is treated as 'no explicit choice' and follows the theme; any other user-set label color is honored (deliberate trade-off: an explicit pure-#000000 label lights up in dark mode) - review fixes: hover-pill pins only the FALLBACK label color to #000 via the {attribute, color} form so explicit label colors survive hover; adapter construction resolves the theme via idempotent initTheme (no race with the DOMContentLoaded boot); toggleDarkMode de-async'd - 16 new tests (936 total green); perf gates green --- src/gll.js | 4 + src/graph/core.js | 16 +- src/graph/interactions.js | 2 +- src/graph/label_renderers.js | 21 +- src/graph/minimap.js | 4 +- src/graph/sigma_adapter.js | 24 +- src/graph_lens_lite.html | 1 + src/managers/ui.js | 24 ++ src/style.css | 540 +++++++++++++++++++--------------- src/utilities/popup.js | 4 +- src/utilities/theme.js | 78 +++++ tests/label-renderers.test.js | 21 ++ tests/theme.test.js | 129 ++++++++ 13 files changed, 614 insertions(+), 254 deletions(-) create mode 100644 src/utilities/theme.js create mode 100644 tests/theme.test.js diff --git a/src/gll.js b/src/gll.js index 80ecd23..c1f5ba9 100644 --- a/src/gll.js +++ b/src/gll.js @@ -23,6 +23,7 @@ import {Popup} from "./utilities/popup.js"; import {StaticUtilities} from "./utilities/static.js"; import {generateTourData, GuidedTour} from "./utilities/tour.js"; import {initApiClient} from "./managers/api_client.js"; +import {initTheme} from "./utilities/theme.js"; // Stores all reference objects @@ -464,7 +465,10 @@ window.addEventListener('resize', () => { }) window.addEventListener("DOMContentLoaded", () => { + // Stored preference wins; prefers-color-scheme is only the first-run default. + initTheme(document, window); cache.reset(); + cache.ui.updateDarkModeButton(); // cache.initialize(); // Display version info diff --git a/src/graph/core.js b/src/graph/core.js index b7bf9d7..0978ccd 100644 --- a/src/graph/core.js +++ b/src/graph/core.js @@ -1,6 +1,7 @@ import { StaticUtilities } from "../utilities/static.js"; import { replaceColorScale } from "../utilities/color_scale_picker.js"; import { replaceNumericScale } from "../utilities/numeric_scale_picker.js"; +import { initTheme, nodeLabelColorForTheme } from "../utilities/theme.js"; import { buildGraphologyGraph, makeNodeReducer, @@ -140,14 +141,25 @@ class GraphCoreManager { const hoverIds = new Set(); try { const { SigmaAdapter } = await import("./sigma_adapter.js"); + // initTheme (not currentTheme): re-resolves stored/OS preference so a + // graph constructed before the DOMContentLoaded theme boot still gets + // the right label colors. Idempotent after boot. + const theme = initTheme(document, window); this.cache.graph = new SigmaAdapter(this.cache, "innerGraphContainer", { nodeReducer: makeNodeReducer(this.cache, elementStates, hoverIds), edgeReducer: makeEdgeReducer(this.cache, elementStates, hoverIds), elementStates, hoverIds, // Label visibility (CFG.HIDE_LABELS) is synced live by the adapter - // on construction and on every render(). - settings: {}, + // on construction and on every render(). The labelColor fallback is + // theme-driven (ui.toggleDarkMode flips it live via setSetting). + settings: { + labelColor: { color: nodeLabelColorForTheme(theme) }, + // Same for edge labels: label_renderers falls back here whenever + // the per-edge labelColor is the baked #000000 default (in light + // mode this resolves to #000 — identical to the old baked render). + edgeLabelColor: { color: nodeLabelColorForTheme(theme) }, + }, }); } catch (err) { // The probe can pass while sigma's own context creation still fails diff --git a/src/graph/interactions.js b/src/graph/interactions.js index b136528..b95b6f5 100644 --- a/src/graph/interactions.js +++ b/src/graph/interactions.js @@ -375,7 +375,7 @@ class InteractionManager { // `.tooltip` element inside #innerGraphContainer with this structure. el.className = "tooltip"; el.style.visibility = "hidden"; - el.style.background = "#fff"; // the old G6 plugin supplied the backdrop + // Backdrop comes from the .tooltip CSS rule (theme-aware var(--input-bg)). // Delegated expand/close handling (sanitization strips inline onclick). el.addEventListener("click", (event) => { const expandBtn = event.target.closest(".tooltip-expand-btn"); diff --git a/src/graph/label_renderers.js b/src/graph/label_renderers.js index 39d4d37..6d29743 100644 --- a/src/graph/label_renderers.js +++ b/src/graph/label_renderers.js @@ -49,6 +49,21 @@ function resolveSettingsColor(settingsColor, data) { return settingsColor?.color ?? "#000"; } +// io.js bakes DEFAULTS.*.LABEL.FOREGROUND_COLOR ("#000000") into every +// labelled element's style, so the per-element labelColor attr always wins +// over the theme-driven sigma settings fallback. Treat that exact baked +// default as "no explicit choice" so dark mode can flip it (in light mode +// the fallback resolves to #000 — pixel-identical). Any other per-element +// label color is an explicit user choice and is honoured as-is. +const BAKED_DEFAULT_LABEL_COLOR = "#000000"; + +function resolveElementLabelColor(elementColor, settingsColor, data) { + if (elementColor != null && elementColor !== BAKED_DEFAULT_LABEL_COLOR) { + return elementColor; + } + return resolveSettingsColor(settingsColor, data); +} + function drawBackground(context, color, x, y, width, height, radius = BACKGROUND_RADIUS) { context.fillStyle = color; context.beginPath(); @@ -138,7 +153,7 @@ function drawNodeLabel(context, data, settings) { const size = finiteSize(data.labelSize, settings.labelSize); const font = settings.labelFont; const weight = settings.labelWeight; - const color = data.labelColor ?? resolveSettingsColor(settings.labelColor, data); + const color = resolveElementLabelColor(data.labelColor, settings.labelColor, data); const padding = data.labelPadding ?? 2; context.font = `${weight} ${size}px ${font}`; @@ -187,7 +202,7 @@ function drawEdgeLabel(context, edgeData, sourceData, targetData, settings) { const size = finiteSize(edgeData.labelSize, settings.edgeLabelSize); const font = settings.edgeLabelFont; const weight = settings.edgeLabelWeight; - const color = edgeData.labelColor ?? resolveSettingsColor(settings.edgeLabelColor, edgeData); + const color = resolveElementLabelColor(edgeData.labelColor, settings.edgeLabelColor, edgeData); const padding = edgeData.labelPadding ?? 1; context.font = `${weight} ${size}px ${font}`; @@ -226,4 +241,4 @@ function drawEdgeLabel(context, edgeData, sourceData, targetData, settings) { context.restore(); } -export { drawNodeLabel, drawEdgeLabel, placementVector }; +export { drawNodeLabel, drawEdgeLabel, placementVector, BAKED_DEFAULT_LABEL_COLOR }; diff --git a/src/graph/minimap.js b/src/graph/minimap.js index b162ab1..25d7872 100644 --- a/src/graph/minimap.js +++ b/src/graph/minimap.js @@ -13,6 +13,7 @@ const MINIMAP_HEIGHT = 120; const MINIMAP_PADDING = 8; const DOT_RADIUS = 1.5; const DOT_COLOR = "#403C53"; +const DOT_COLOR_DARK = "#AAA3C4"; // brand purple is invisible on the dark thumb const VIEWPORT_STROKE = "#C33D35"; class Minimap { @@ -113,7 +114,8 @@ class Minimap { if (!fit) return; const graph = this.adapter.graph; - ctx.fillStyle = DOT_COLOR; + const isDark = document.documentElement.dataset.theme === "dark"; + ctx.fillStyle = isDark ? DOT_COLOR_DARK : DOT_COLOR; graph.forEachNode((id, attrs) => { if (attrs.hidden) return; const p = this.#toThumb(fit, attrs.x, attrs.y); diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index c9a1c49..39df9b2 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -25,7 +25,7 @@ import { } from "./edge_programs.js"; import { nodeAttributesFromStyle, edgeAttributesFromStyle, flipY } from "./graph_model.js"; import { executeLayout } from "./layout_algorithms.js"; -import { drawNodeLabel, drawEdgeLabel } from "./label_renderers.js"; +import { drawNodeLabel, drawEdgeLabel, BAKED_DEFAULT_LABEL_COLOR } from "./label_renderers.js"; import { InteractionManager } from "./interactions.js"; import { BubbleSetLayer } from "./bubble_layer.js"; import { Minimap } from "./minimap.js"; @@ -57,7 +57,15 @@ function guardHoverDrawer(drawer, getDraggedNode) { return (context, data, settings) => { const dragged = getDraggedNode(); if (dragged && data.key !== dragged) return; - drawer(context, data, settings); + // Sigma's drawDiscNodeHover hardcodes a white pill behind the label, so + // pin the FALLBACK to dark regardless of the theme-driven labelColor + // setting (dark mode flips it to a light color, unreadable on the pill). + // The attribute form keeps explicit per-element labelColor choices + // (sigma resolves data[attribute] || color). + drawer(context, data, { + ...settings, + labelColor: { attribute: "labelColor", color: "#000" }, + }); }; } @@ -166,13 +174,19 @@ const drawCurvedEdgeLabelBase = edgeCurve.createDrawCurvedEdgeLabel( edgeCurve.DEFAULT_EDGE_CURVE_PROGRAM_OPTIONS, ); function drawCurvedEdgeLabelWithSize(context, edgeData, sourceData, targetData, settings) { + // The baked #000000 default counts as "no explicit color" so the + // theme-driven settings fallback applies (see label_renderers.js). + const explicitColor = + edgeData.labelColor && edgeData.labelColor !== BAKED_DEFAULT_LABEL_COLOR + ? edgeData.labelColor + : null; const effective = - edgeData.labelSize != null || edgeData.labelColor != null + edgeData.labelSize != null || explicitColor != null ? { ...settings, edgeLabelSize: edgeData.labelSize ?? settings.edgeLabelSize, - edgeLabelColor: edgeData.labelColor - ? { color: edgeData.labelColor } + edgeLabelColor: explicitColor + ? { color: explicitColor } : settings.edgeLabelColor, } : settings; diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index 5bebcf9..50daeb6 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -88,6 +88,7 @@

    +

    diff --git a/src/managers/ui.js b/src/managers/ui.js index ab345bb..e39dcb4 100644 --- a/src/managers/ui.js +++ b/src/managers/ui.js @@ -2,6 +2,7 @@ import {StaticUtilities} from "../utilities/static.js"; import {DropdownChecklist, InvertibleRangeSlider} from "./ui_components.js"; import {createStyleDiv} from "./ui_style_div.js"; import {Popup} from "../utilities/popup.js"; +import {applyTheme, currentTheme, nodeLabelColorForTheme} from "../utilities/theme.js"; class UIManager { constructor(cache, debugEnabled = false) { @@ -442,6 +443,29 @@ class UIManager { this.info(enable ? "Hover highlight effect enabled" : "Hover highlight effect disabled"); } + toggleDarkMode() { + const next = currentTheme(document) === "dark" ? "light" : "dark"; + applyTheme(document, next); + this.updateDarkModeButton(); + // Flip the renderer's default label color (per-element labelColor attrs + // set by the user/style pipeline are untouched). setSetting schedules a + // refresh; the minimap redraws via its afterRender hook. + const sigma = this.cache.graph?.sigma; + if (sigma) { + sigma.setSetting("labelColor", { color: nodeLabelColorForTheme(next) }); + sigma.setSetting("edgeLabelColor", { color: nodeLabelColorForTheme(next) }); + } + this.info(next === "dark" ? "Dark mode enabled" : "Light mode enabled"); + } + + updateDarkModeButton() { + const btn = document.getElementById("darkModeToggleBtn"); + if (!btn) return; + const isDark = currentTheme(document) === "dark"; + btn.textContent = isDark ? "☀️" : "🌙"; + btn.title = isDark ? "Switch to light mode" : "Switch to dark mode"; + } + updateHoverToggleButton() { const btn = document.getElementById("hoverToggleBtn"); if (!btn) return; diff --git a/src/style.css b/src/style.css index 6c6e444..910eb47 100644 --- a/src/style.css +++ b/src/style.css @@ -1,8 +1,61 @@ +/* ========================================================================== + Theme tokens — light defaults in :root, dark overrides via + (src/utilities/theme.js). Brand backgrounds + (#403C53 purple, #C33D35 red) stay fixed; surfaces/text/borders flip. + ========================================================================== */ +:root { + --bg: #ffffff; + --surface: #f4f4f4; + --surface-2: #f0eff4; + --surface-3: #e4e3ea; + --row-hover: #e6f3ff; + --surface-translucent: rgba(244, 244, 244, 0.85); + --input-bg: #ffffff; + --text: #000000; + --text-strong: #333333; + --text-muted: #666666; + --text-faint: #888888; + --border: #cccccc; + --border-soft: #dddbe2; + --border-strong: #000000; + --brand-text: #403C53; + --brand-border: #403C53; + --accent-text: #C33D35; + --success-text: #015C0C; + --danger-text: #8a2d2d; + color-scheme: light; +} + +[data-theme="dark"] { + --bg: #17161d; + --surface: #211f2b; + --surface-2: #262433; + --surface-3: #322f40; + --row-hover: #2c3a4f; + --surface-translucent: rgba(33, 31, 43, 0.88); + --input-bg: #2a2837; + --text: #e7e6ee; + --text-strong: #d2d0dd; + --text-muted: #a39fb3; + --text-faint: #8b879c; + --border: #454154; + --border-soft: #3a3748; + --border-strong: #5d5871; + --brand-text: #aaa3c4; + --brand-border: #6b6486; + --accent-text: #e0635b; + --success-text: #58c06a; + --danger-text: #d98a84; + color-scheme: dark; +} + body, html { margin: 0; padding: 0; height: 100%; font-family: sans-serif; + background-color: var(--bg); + color: var(--text); } #mainContent { @@ -21,7 +74,7 @@ body, html { #sidebar { min-width: 200px; width: 360px; - background-color: #f4f4f4; + background-color: var(--surface); padding-left: 10px; overflow-y: auto; overflow-x: hidden; @@ -51,7 +104,7 @@ body, html { top: 0; bottom: 0; background: rgba(64, 60, 83, 0.3); - border-right: 2px solid #403C53; + border-right: 2px solid var(--brand-border); pointer-events: none; z-index: 9999; display: none; @@ -61,21 +114,21 @@ body, html { #rightSidebar { min-width: 0; width: 0; - background-color: #f4f4f4; + background-color: var(--surface); padding-right: 0; overflow: hidden; transition: width 0.3s ease-in-out, min-width 0.3s ease-in-out, padding-right 0.3s ease-in-out; display: flex; flex-direction: column; flex-shrink: 0; - border-left: 0 solid #ccc; + border-left: 0 solid var(--border); position: relative; } #rightSidebar.active { min-width: 360px; width: 360px; - border-left: 1px solid #ccc; + border-left: 1px solid var(--border); } #rightSidebarContentContainer { @@ -103,7 +156,7 @@ body, html { flex: 1; overflow-y: auto; overflow-x: hidden; - border-bottom: 1px solid black; + border-bottom: 1px solid var(--border-strong); } #sidebarStatusContainer { @@ -119,7 +172,7 @@ body, html { max-width: 360px; overflow-y: auto; /* overflow-x: hidden; */ - border-top: 1px solid #ccc; + border-top: 1px solid var(--border); font-size: 0.8rem; white-space: pre-wrap; word-wrap: break-word; @@ -134,8 +187,8 @@ body, html { } #bottomBar.active { - background-color: #f4f4f4; - border-top: 1px solid #403C53; + background-color: var(--surface); + border-top: 1px solid var(--brand-border); display: flex; flex-direction: column; min-height: 50px; @@ -153,7 +206,7 @@ body, html { flex-shrink: 0; font-weight: 500; font-size: 13px; - border-bottom: 1px solid black; + border-bottom: 1px solid var(--border-strong); line-height: 1.2; display: flex; justify-content: space-between; @@ -168,9 +221,9 @@ body, html { /* Bottom bar header gets extra visual borders */ #bottomBar .panel-header { - border-left: 1px solid #403C53; - border-right: 1px solid #403C53; - border-top: 1px solid #403C53; + border-left: 1px solid var(--brand-border); + border-right: 1px solid var(--brand-border); + border-top: 1px solid var(--brand-border); } .panel-header-text { @@ -253,7 +306,7 @@ body, html { left: 0; right: 0; background: rgba(64, 60, 83, 0.3); - border-top: 2px solid #403C53; + border-top: 2px solid var(--brand-border); pointer-events: none; z-index: 9999; display: none; @@ -277,7 +330,7 @@ body, html { .popupQueryContainer { - outline: 1px solid #403C53; + outline: 1px solid var(--brand-border); border-radius: 5px; font-family: "Courier New", monospace; padding: 5px; @@ -297,7 +350,9 @@ body, html { #innerGraphContainer { width: 100%; height: 100%; - border: 1px solid #ccc; + border: 1px solid var(--border); + /* Sigma's WebGL canvases are transparent — this is the stage background */ + background-color: var(--bg); /* Anchor for the absolutely positioned tooltip and lasso overlay */ position: relative; } @@ -313,20 +368,20 @@ body, html { gap: 8px; padding: 0 48px; text-align: center; - background-color: #f4f4f4; + background-color: var(--surface); box-sizing: border-box; } #innerGraphContainer .webgl-error-title { margin: 0; font-weight: bold; - color: #403C53; + color: var(--brand-text); } #innerGraphContainer .webgl-error-hint { margin: 0; font-size: 0.85rem; - color: #666; + color: var(--text-muted); } /* Owned minimap (src/graph/minimap.js) — kept at the position the old G6 @@ -336,9 +391,9 @@ body, html { bottom: 10px; right: 10px; z-index: 500; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 5px; - background-color: rgba(244, 244, 244, 0.85); + background-color: var(--surface-translucent); cursor: pointer; } @@ -348,9 +403,9 @@ body, html { right: 10px !important; bottom: auto !important; left: auto !important; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 5px; - background-color: #f4f4f4; + background-color: var(--surface); transition: opacity 0.1s ease-in-out, right 0.3s ease-in-out, width 0.25s ease-in-out, max-width 0.25s ease-in-out, box-shadow 0.25s ease-in-out; text-align: center; padding: 2px; @@ -404,7 +459,7 @@ body, html { h4 { margin: 0.2rem; font-weight: 500; - color: #C33D35; + color: var(--accent-text); } h5 { @@ -442,7 +497,7 @@ h5 { } .q-property-wrapper { - color: black; + color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); outline: 1px solid rgba(0, 0, 0, 0.75); outline-offset: 1px; @@ -465,12 +520,12 @@ h5 { } .q-number { - color: #C33D35; + color: var(--accent-text); font-weight: bold; } .q-string { - color: #C33D35; + color: var(--accent-text); font-weight: bold; } @@ -483,7 +538,7 @@ h5 { } .q-bracket-open-lvl-1, .q-bracket-close-lvl-1 { - color: #C33D35; + color: var(--accent-text); } .q-bracket-open-lvl-2, .q-bracket-close-lvl-2 { @@ -503,31 +558,31 @@ h5 { } .q-comma { - color: #403C53; + color: var(--brand-text); } .q-kw-between { - color: #403C53; + color: var(--brand-text); } .q-kw-between-and { - color: #403C53; + color: var(--brand-text); } .q-lower-than { - color: #403C53; + color: var(--brand-text); } .q-or-greater-than { - color: #403C53; + color: var(--brand-text); } .q-in-cat-bracket-open { - color: #403C53; + color: var(--brand-text); } .q-cat-bracket-close { - color: #403C53; + color: var(--brand-text); } .q-connector-opening-bracket { @@ -626,7 +681,7 @@ h5 { .header-card { background-color: #C33D35; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 5px; color: white; padding-right: 4px; @@ -637,7 +692,7 @@ h5 { .sub-header-card { background-color: #403C53; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 5px; color: white; padding-right: 4px; @@ -653,7 +708,7 @@ h5 { /* use with:
    {CONTENT}
    */ .card-labeled { position: relative; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); padding: 20px 4px 4px; border-radius: 5px; margin-top: 8px; @@ -700,21 +755,21 @@ h5 { .bubble-set-tab { flex: 1; padding: 2px 4px; - background: #E4E3EA; - border: 1px solid #403C53; + background: var(--surface-3); + border: 1px solid var(--brand-border); border-bottom: 2px solid var(--tab-color, #403C53); border-radius: 3px 3px 0 0; cursor: pointer; font-size: 11px; line-height: 14px; - color: #403C53; + color: var(--brand-text); transition: all 0.15s ease; text-align: center; white-space: nowrap; } .bubble-set-tab:hover { - background: #d6d4df; + background: var(--surface-3); } .bubble-set-tab.active { @@ -779,7 +834,7 @@ h5 { width: 100%; height: 100%; background: rgba(0, 0, 0, 0.2); - color: black; + color: var(--text); z-index: 10001; text-align: center; font-size: 30px; @@ -789,9 +844,9 @@ h5 { } #loadingInnerContent { - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 20px; - background: #ffffff; + background: var(--input-bg); padding: 20px 80px 20px 80px; } @@ -815,7 +870,7 @@ h5 { position: absolute; right: 0; z-index: 10; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 6px; } @@ -963,7 +1018,8 @@ h5 { width: 360px !important; max-height: 400px !important; overflow: auto !important; - border: 1px solid #403C53 !important; + background: var(--input-bg) !important; + border: 1px solid var(--brand-border) !important; border-radius: 5px !important; pointer-events: auto !important; min-width: 150px !important; @@ -1162,7 +1218,7 @@ hr { .tooltip-sub-section { background-color: #403C53; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 5px; color: white; padding: 1px 4px; @@ -1175,7 +1231,7 @@ hr { .tooltip-dummy-buttons { background-color: #403C53; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 5px; color: white; padding-left: 4px; @@ -1189,12 +1245,12 @@ hr { .tooltip-dummy-buttons.blue { background-color: #8CA6D9; - color: black; + color: var(--text); } .tooltip-dummy-buttons.pink { background-color: #EFB0AA; - color: black; + color: var(--text); } .tooltip-dummy-buttons.green { @@ -1203,7 +1259,7 @@ hr { } .black { - color: #000000; + color: var(--text); } .brown { @@ -1212,7 +1268,7 @@ hr { } .green { - color: #015C0C; + color: var(--success-text); } .grey { @@ -1228,7 +1284,7 @@ hr { } .red { - color: #C33D35; + color: var(--accent-text); } .red-background { @@ -1245,11 +1301,11 @@ hr { } .purple { - color: #403C53; + color: var(--brand-text); } .purple-border { - border: 1px solid #403C53 !important; + border: 1px solid var(--brand-border) !important; border-radius: 3px; } @@ -1271,7 +1327,7 @@ hr { text-align: center; line-height: 14px; font-size: 12px; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 3px; cursor: pointer; padding: 0; @@ -1284,7 +1340,7 @@ hr { text-align: center; line-height: 16px; font-size: 13px; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 3px; cursor: pointer; padding: 0; @@ -1335,7 +1391,7 @@ hr { .data-source-label { font-size: 0.7em; - color: #888; + color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -1350,7 +1406,7 @@ hr { .button-group { display: inline-flex; background: #403C5320; - outline: 1px solid #403C53; + outline: 1px solid var(--brand-border); border-radius: 6px; margin-right: 6px; gap: 1px; @@ -1378,20 +1434,20 @@ hr { } .info-btn:hover { - color: #C33D35; + color: var(--accent-text); } .toggle-section-btn { - background: #E4E3EA; + background: var(--surface-3); } .toggle-section-btn:hover { border-color: #C33D35; - color: #C33D35; + color: var(--accent-text); } .small-btn.red:hover { - border: 1px solid #403C53 !important; + border: 1px solid var(--brand-border) !important; } .small-text { @@ -1418,7 +1474,7 @@ hr { .disabled { opacity: 0.5; pointer-events: none; - color: black; + color: var(--text); cursor: default; } @@ -1499,7 +1555,7 @@ hr { width: 0; height: 14px; font-size: 10px; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 3px; background: transparent; cursor: pointer; @@ -1535,27 +1591,27 @@ hr { .checkbox-red, .checkbox-green { - color: #C33D35; + color: var(--accent-text); border: 1px solid #C33D35; border-radius: 3px; } .checkbox-red:hover, .checkbox-green:hover { - border-color: black; + border-color: var(--text); } input:checked + .checkbox-green { - color: #015C0C; + color: var(--success-text); border-color: #015C0C; } input:checked + .checkbox-green::after { - color: #015C0C; + color: var(--success-text); } input:checked + .checkbox-red::after { - color: #C33D35; + color: var(--accent-text); } input:checked + .checkbox-red::after, @@ -1620,11 +1676,11 @@ input:checked + .checkbox-green::after { margin-left: 1px; margin-right: 1px; box-sizing: border-box; - border: 0.08em solid black; + border: 0.08em solid var(--border-strong); border-radius: 999px; overflow: hidden; position: relative; - background: #E4E3EA; + background: var(--surface-3); transition: transform 140ms ease, border-color 140ms ease; transform-origin: right center; } @@ -1645,7 +1701,7 @@ input:checked + .checkbox-green::after { } .plus-minus-button + .plus-minus-button { - border-left: 1px solid #403C53; + border-left: 1px solid var(--brand-border); } .pm-group:hover { @@ -1655,7 +1711,7 @@ input:checked + .checkbox-green::after { } .pm-group:hover .plus-minus-button + .plus-minus-button { - border-left-color: #C33D35; + border-left-color: var(--accent-text); } .plus-minus-button:hover { @@ -1687,7 +1743,7 @@ input:checked + .checkbox-green::after { } .style-icon-button:hover { - border: 1px solid #403C53; + border: 1px solid var(--brand-border); cursor: pointer; } @@ -1732,14 +1788,14 @@ input:checked + .checkbox-green::after { text-overflow: ellipsis; line-height: 18px; font-size: 12px; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 3px; cursor: pointer; transition: border 0.2s ease-in-out, color 0.2s ease-in-out, opacity 0.1s ease-in-out; } .style-inner-button:hover { - color: #C33D35; + color: var(--accent-text); border: 1px solid #C33D35; } @@ -1823,7 +1879,7 @@ input:checked + .checkbox-green::after { height: 14px; border-radius: 50%; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); - background: #EEEEEE; + background: var(--surface-3); cursor: pointer; transition: background 0.2s ease-in-out; } @@ -1835,7 +1891,7 @@ input:checked + .checkbox-green::after { .style-slider::-moz-range-thumb { width: 14px; height: 14px; - background: #EEEEEE; + background: var(--surface-3); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); border-radius: 50%; cursor: pointer; @@ -1872,7 +1928,7 @@ input:checked + .checkbox-green::after { left: 0; height: 8px; border-radius: 10px; - background-color: #CCC; + background-color: var(--border); margin: 0; } @@ -1881,7 +1937,7 @@ input:checked + .checkbox-green::after { right: 0; height: 8px; border-radius: 10px; - background-color: #CCC; + background-color: var(--border); margin: 0; } @@ -1903,7 +1959,7 @@ input:checked + .checkbox-green::after { margin-left: -9px; cursor: pointer; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4); - background-color: #EEEEEE; + background-color: var(--surface-3); border-radius: 50%; outline: none; } @@ -1993,7 +2049,7 @@ div[slider] > input[type=range]::-ms-tooltip { top: -8px; z-index: 3; background-color: #C33D35; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); color: #E4E3EA; width: 32px; height: 24px; @@ -2034,7 +2090,7 @@ div[slider] > input[type=range]::-ms-tooltip { transform: translateY(-50%); border-top: 6px solid transparent; border-bottom: 6px solid transparent; - border-left: 8px solid #403C53; + border-left: 8px solid var(--brand-border); } [slider] > div > [sign].right:after { @@ -2045,7 +2101,7 @@ div[slider] > input[type=range]::-ms-tooltip { transform: translateY(-50%); border-top: 6px solid transparent; border-bottom: 6px solid transparent; - border-right: 8px solid #403C53; + border-right: 8px solid var(--brand-border); } [slider] > div > [sign].left.flipped:after { @@ -2100,7 +2156,7 @@ div[slider] > input[type=range]::-ms-tooltip { left: 0; right: 0; bottom: 0; - background-color: #ccc; + background-color: var(--border); -webkit-transition: .2s; transition: .2s; } @@ -2112,7 +2168,7 @@ div[slider] > input[type=range]::-ms-tooltip { width: 12px; left: 2px; bottom: 2px; - background-color: white; + background-color: var(--input-bg); -webkit-transition: .2s; transition: .2s; } @@ -2172,7 +2228,7 @@ input:checked + .slider:before { align-items: center; transition: transform 0.2s ease; vertical-align: middle; - border: 1px solid black; + border: 1px solid var(--border-strong); box-sizing: border-box; } @@ -2213,8 +2269,8 @@ input:checked + .slider:before { } :root { - --groupOne-color: #403C53; - --groupTwo-color: #C33D35; + --groupOne-color: var(--brand-text); + --groupTwo-color: var(--accent-text); --groupThree-color: #EFB0AA; --groupFour-color: #8CA6D9; } @@ -2226,13 +2282,13 @@ input:checked + .slider:before { border-width: 0.125rem; border-left-color: var(--quadrant-color); border-top-color: var(--quadrant-color); - background-color: #E4E3EA; + background-color: var(--surface-3); } .top-left.active { background-color: var(--quadrant-color); - border-left-color: #000000; - border-top-color: #000000; + border-left-color: var(--border-strong); + border-top-color: var(--border-strong); } .top-right { @@ -2242,13 +2298,13 @@ input:checked + .slider:before { border-top-right-radius: 50%; border-right-color: var(--quadrant-color); border-top-color: var(--quadrant-color); - background-color: #E4E3EA; + background-color: var(--surface-3); } .top-right.active { background-color: var(--quadrant-color); - border-right-color: #000000; - border-top-color: #000000; + border-right-color: var(--border-strong); + border-top-color: var(--border-strong); } .bottom-left { @@ -2258,13 +2314,13 @@ input:checked + .slider:before { border-bottom-left-radius: 50%; border-left-color: var(--quadrant-color); border-bottom-color: var(--quadrant-color); - background-color: #E4E3EA; + background-color: var(--surface-3); } .bottom-left.active { background-color: var(--quadrant-color); - border-left-color: #000000; - border-bottom-color: #000000; + border-left-color: var(--border-strong); + border-bottom-color: var(--border-strong); } .bottom-right { @@ -2274,13 +2330,13 @@ input:checked + .slider:before { border-bottom-right-radius: 50%; border-right-color: var(--quadrant-color); border-bottom-color: var(--quadrant-color); - background-color: #E4E3EA; + background-color: var(--surface-3); } .bottom-right.active { background-color: var(--quadrant-color); - border-right-color: #000000; - border-bottom-color: #000000; + border-right-color: var(--border-strong); + border-bottom-color: var(--border-strong); } .top-left.compact, .top-right.compact, .bottom-left.compact, .bottom-right.compact { @@ -2316,7 +2372,7 @@ input:checked + .slider:before { cursor: pointer; display: inline-block; /*padding: 5px 5px 5px 10px;*/ - border: 1px solid #ccc; + border: 1px solid var(--border); width: 100%; height: 16px; line-height: 16px; @@ -2330,8 +2386,8 @@ input:checked + .slider:before { .dropdown-check-list .anchor:after { position: absolute; content: ""; - border-left: 2px solid black; - border-top: 2px solid black; + border-left: 2px solid var(--border-strong); + border-top: 2px solid var(--border-strong); padding: 2px; right: 5px; top: 25%; @@ -2343,10 +2399,10 @@ input:checked + .slider:before { padding: 2px; display: none; margin: 0 0 0 3px; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 3px; border-top: none; - background-color: white; + background-color: var(--input-bg); z-index: 1000; width: auto; list-style: none; @@ -2385,7 +2441,7 @@ input:checked + .slider:before { margin-right: 10px; border: 1px solid #C33D35; border-radius: 3px; - background-color: white; + background-color: var(--input-bg); vertical-align: middle; cursor: pointer; transition: background-color 0.3s ease, border-color 0.3s ease; @@ -2417,7 +2473,7 @@ input:checked + .slider:before { } .dropdown-check-list.visible .anchor { - color: #C33D35; + color: var(--accent-text); } .dropdown-buttons { @@ -2425,17 +2481,17 @@ input:checked + .slider:before { justify-content: center; gap: 10px; padding: 5px; - background-color: #f8f8f8; - border-bottom: 1px solid #ccc; + background-color: var(--surface); + border-bottom: 1px solid var(--border); } .dropdown-buttons.button { font-size: 12px; padding: 4px 8px; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 3px; cursor: pointer; - background-color: white; + background-color: var(--input-bg); transition: background-color 0.3s ease; } @@ -2497,7 +2553,7 @@ input:checked + .slider:before { min-height: 120px; overflow-y: auto; margin-bottom: 0.5em; - border: 1px solid #ccc; + border: 1px solid var(--border); } .nw-node-multiselect option { @@ -2512,7 +2568,7 @@ input:checked + .slider:before { } .nw-graph-metrics-table tr:hover { - background-color: #E4E3EA; + background-color: var(--surface-3); } .nw-graph-metrics-table td { @@ -2536,9 +2592,9 @@ input:checked + .slider:before { **************************/ .p-custom { position: fixed; - background: white; + background: var(--input-bg); border-radius: 8px; - border: 2px solid #403C53; + border: 2px solid var(--brand-border); box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25); z-index: 10002; max-width: 90vw; @@ -2555,8 +2611,8 @@ input:checked + .slider:before { display: flex; align-items: center; padding: 8px 12px; - background: #f0eff4; - border-bottom: 1px solid #dddbe2; + background: var(--surface-2); + border-bottom: 1px solid var(--border-soft); border-radius: 6px 6px 0 0; flex-shrink: 0; } @@ -2564,7 +2620,7 @@ input:checked + .slider:before { .p-title { font-size: 14px; font-weight: 600; - color: #403C53; + color: var(--brand-text); flex: 1; margin: 0; } @@ -2593,8 +2649,8 @@ input:checked + .slider:before { justify-content: flex-end; gap: 10px; padding: 10px 16px; - background: #f0eff4; - border-top: 1px solid #dddbe2; + background: var(--surface-2); + border-top: 1px solid var(--border-soft); border-radius: 0 0 6px 6px; flex-shrink: 0; } @@ -2619,11 +2675,11 @@ input:checked + .slider:before { height: 22px; line-height: 22px; text-align: center; - color: #403C53; + color: var(--brand-text); } .p-icon:hover { - color: #C33D35; + color: var(--accent-text); } .p-button { @@ -2632,7 +2688,7 @@ input:checked + .slider:before { background-color: #403C53; color: white; border-radius: 4px; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); cursor: pointer; } @@ -2667,7 +2723,7 @@ input:checked + .slider:before { padding: 8px; margin-top: 10px; box-sizing: border-box; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 4px; } @@ -2677,32 +2733,32 @@ input:checked + .slider:before { .picker-dropdown { margin-top: 0; margin-bottom: 4px; - border-color: #403C53; + border-color: var(--brand-border); } .picker-info { padding: 12px 14px; - background-color: #f0eff4; - border: 1px solid #dddbe2; + background-color: var(--surface-2); + border: 1px solid var(--border-soft); border-radius: 4px; margin-top: 12px; } .picker-info-summary { font-size: 13px; - color: #403C53; + color: var(--brand-text); } .picker-info-range { font-size: 12px; - color: #666; + color: var(--text-muted); margin-top: 6px; } .picker-gradient { width: 100%; height: 36px; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 4px; margin-top: 14px; position: relative; @@ -2718,8 +2774,8 @@ input:checked + .slider:before { position: absolute; width: 12px; height: 20px; - background: white; - border: 1px solid #403C53; + background: var(--input-bg); + border: 1px solid var(--brand-border); border-radius: 3px; transform: translateX(-50%); z-index: 1; @@ -2743,7 +2799,7 @@ input:checked + .slider:before { left: 50%; transform: translateX(-50%); font-size: 11px; - color: #403C53; + color: var(--brand-text); white-space: nowrap; pointer-events: none; } @@ -2764,7 +2820,7 @@ input:checked + .slider:before { max-height: 300px; overflow-y: auto; margin-top: 12px; - border: 1px solid #dddbe2; + border: 1px solid var(--border-soft); border-radius: 4px; } @@ -2785,21 +2841,21 @@ input:checked + .slider:before { font-size: 13px; flex-grow: 1; margin-right: 12px; - color: #333; + color: var(--text-strong); } .picker-category-row input[type="color"] { width: 28px; height: 28px; padding: 0; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 4px; cursor: pointer; flex-shrink: 0; } .picker-category-row:hover { - background-color: #f0eff4; + background-color: var(--surface-2); } .picker-default-color-section { @@ -2812,14 +2868,14 @@ input:checked + .slider:before { border: 1px solid #f0dcc8; border-radius: 4px; font-size: 13px; - color: #666; + color: var(--text-muted); } .picker-color-swatch { width: 28px; height: 28px; padding: 0; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 4px; cursor: pointer; flex-shrink: 0; @@ -2828,14 +2884,14 @@ input:checked + .slider:before { .picker-range-config { margin-top: 12px; padding: 12px 14px; - background-color: #f0eff4; - border: 1px solid #dddbe2; + background-color: var(--surface-2); + border: 1px solid var(--border-soft); border-radius: 4px; } .picker-range-label { font-size: 13px; - color: #403C53; + color: var(--brand-text); margin-bottom: 8px; } @@ -2848,7 +2904,7 @@ input:checked + .slider:before { .picker-range-input { width: 80px; padding: 6px 8px; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 4px; font-size: 13px; box-sizing: border-box; @@ -2974,10 +3030,10 @@ input:checked + .slider:before { flex: 1; min-width: 0; height: 100%; - border: 1px solid #403C53; + border: 1px solid var(--brand-border); border-radius: 3px; box-sizing: border-box; - background: white; + background: var(--input-bg); } #dataTextArea { @@ -3039,7 +3095,7 @@ input:checked + .slider:before { background-color: #2a2733; cursor: not-allowed; opacity: 0.5; - color: #888; + color: var(--text-faint); box-shadow: none; transform: none; } @@ -3114,8 +3170,8 @@ input:checked + .slider:before { height: 100%; display: flex; flex-direction: column; - border: 1px solid #ccc; - background: white; + border: 1px solid var(--border); + background: var(--input-bg); overflow: hidden; } @@ -3171,8 +3227,8 @@ input:checked + .slider:before { } .data-table th { - background-color: #f0f0f0; - border: 1px solid #ddd; + background-color: var(--surface-3); + border: 1px solid var(--border); padding: 2px 4px; text-align: left; font-weight: bold; @@ -3184,7 +3240,7 @@ input:checked + .slider:before { } .data-table td { - border: 1px solid #ddd; + border: 1px solid var(--border); padding: 4px 8px; min-width: 80px; max-width: 200px; @@ -3194,13 +3250,13 @@ input:checked + .slider:before { } .data-table td:focus { - outline: 2px solid #403C53; - background-color: #E4E3EA; + outline: 2px solid var(--brand-border); + background-color: var(--surface-3); } .data-table td.editing { background-color: #fff9c4; - border: 2px solid #403C53; + border: 2px solid var(--brand-border); white-space: normal; text-overflow: clip; overflow: visible; @@ -3208,11 +3264,11 @@ input:checked + .slider:before { } .data-table tr:nth-child(even) { - background-color: #f9f9f9; + background-color: var(--surface); } .data-table tr:hover { - background-color: #e6f3ff; + background-color: var(--row-hover); } .data-table input { @@ -3229,13 +3285,13 @@ input:checked + .slider:before { } .data-table td.readonly { - background-color: #f8f8f8; - color: #666; + background-color: var(--surface); + color: var(--text-muted); cursor: not-allowed; } .data-table td.readonly:hover { - background-color: #f8f8f8; + background-color: var(--surface); } @@ -3249,7 +3305,7 @@ input:checked + .slider:before { } .data-table-sortable-header:hover { - background-color: #e0e0e0; + background-color: var(--surface-3); } .data-table-header-text { @@ -3259,7 +3315,7 @@ input:checked + .slider:before { .data-table-header-group-badge { background-color: #403c53; - border: 1px solid black; + border: 1px solid var(--border-strong); border-radius: 5px; color: white; padding: 2px 6px; @@ -3305,14 +3361,14 @@ input:checked + .slider:before { top: 2px; right: 2px; font-size: 10px; - color: #403c53; + color: var(--brand-text); width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; background: rgba(64, 60, 83, 0.1); - border: 1px solid #403c53; + border: 1px solid var(--brand-border); border-radius: 3px; font-weight: bold; transition: all 0.2s ease; @@ -3320,11 +3376,11 @@ input:checked + .slider:before { .data-table-sortable-header:hover .data-table-sort-indicator { background: rgba(64, 60, 83, 0.2); - border-color: #403c53; + border-color: var(--brand-border); } .data-table th:hover { - background-color: #e6e6e6; + background-color: var(--surface-3); } .data-table th.data-table-delete-row-column { @@ -3371,30 +3427,30 @@ input:checked + .slider:before { .data-table-tabs { display: flex; gap: 4px; - border-bottom: 2px solid #ddd; + border-bottom: 2px solid var(--border); flex-shrink: 0; overflow-x: auto; - background: white; + background: var(--input-bg); } .data-table-tab { padding: 8px 16px; - background: #f5f5f5; + background: var(--surface); border: none; border-top: 2px solid transparent; - border-left: 1px solid #ddd; - border-right: 1px solid #ddd; + border-left: 1px solid var(--border); + border-right: 1px solid var(--border); cursor: pointer; font-size: 14px; transition: all 0.2s ease; } .data-table-tab:hover { - background: #e8e8e8; + background: var(--surface-3); } .data-table-tab.active { - background: white; + background: var(--input-bg); border-top-color: #4CAF50; font-weight: bold; } @@ -3449,22 +3505,22 @@ input:checked + .slider:before { .tour-body { font-size: 14px; - color: #333; + color: var(--text-strong); flex: 1; padding: 14px 16px; } .tour-body code { - background: #f0eff4; + background: var(--surface-2); padding: 1px 5px; border-radius: 3px; font-size: 13px; - color: #403C53; + color: var(--brand-text); } .tour-query-example { font-family: "Courier New", monospace; - background: #f8f7fb; + background: var(--surface-2); border: 1px solid #e0dfe4; border-radius: 5px; padding: 8px 10px; @@ -3478,8 +3534,8 @@ input:checked + .slider:before { align-items: center; justify-content: flex-end; padding: 8px 16px; - background: #f0eff4; - border-top: 1px solid #dddbe2; + background: var(--surface-2); + border-top: 1px solid var(--border-soft); border-radius: 0 0 6px 6px; flex-shrink: 0; } @@ -3506,11 +3562,11 @@ input:checked + .slider:before { } .tour-green { - color: #015C0C; + color: var(--success-text); } .tour-red { - color: #C33D35; + color: var(--accent-text); } /* ── Landing Page ── */ @@ -3526,6 +3582,10 @@ input:checked + .slider:before { overflow-y: auto; } +[data-theme="dark"] #landingPage { + background: linear-gradient(160deg, #211f2b 0%, #17161d 40%, #241b1f 70%, #2e2226 100%); +} + .landing-bg-pattern { position: absolute; inset: 0; @@ -3556,19 +3616,19 @@ input:checked + .slider:before { .landing-title { font-size: 2.4em; font-weight: 700; - color: #403C53; + color: var(--brand-text); margin: 0 0 4px 0; letter-spacing: -0.01em; } .landing-version { font-size: 0.85em; - color: #999; + color: var(--text-faint); } .landing-subtitle { font-size: 1.05em; - color: #666; + color: var(--text-muted); margin: 16px auto 0; max-width: 440px; line-height: 1.5; @@ -3631,12 +3691,12 @@ input:checked + .slider:before { align-items: center; gap: 4px; padding: 16px 12px; - border: 1px solid #e0e0e0; + border: 1px solid var(--border-soft); border-radius: 10px; - background: #fff; + background: var(--input-bg); cursor: pointer; transition: all 0.2s ease; - color: #403C53; + color: var(--brand-text); font-family: inherit; } @@ -3657,7 +3717,7 @@ input:checked + .slider:before { .landing-card-desc { font-size: 0.75em; - color: #888; + color: var(--text-faint); line-height: 1.4; } @@ -3672,13 +3732,13 @@ input:checked + .slider:before { .landing-citation { font-size: 0.72em; - color: #999; + color: var(--text-faint); max-width: 520px; line-height: 1.5; padding: 10px 16px; - background: #f8f8f8; + background: var(--surface); border-radius: 6px; - border: 1px solid #eee; + border: 1px solid var(--border-soft); } .landing-links { @@ -3690,14 +3750,14 @@ input:checked + .slider:before { display: flex; align-items: center; gap: 6px; - color: #999; + color: var(--text-faint); text-decoration: none; font-size: 0.82em; transition: color 0.2s; } .landing-github:hover { - color: #403C53; + color: var(--brand-text); } #landingPage.hidden { @@ -3709,20 +3769,20 @@ input:checked + .slider:before { #assistantSidebar { min-width: 0; width: 0; - background-color: #f4f4f4; + background-color: var(--surface); overflow: hidden; transition: width 0.3s ease-in-out, min-width 0.3s ease-in-out; display: flex; flex-direction: column; flex-shrink: 0; - border-left: 0 solid #ccc; + border-left: 0 solid var(--border); position: relative; } #assistantSidebar.active { min-width: var(--assistant-width, 380px); width: var(--assistant-width, 380px); - border-left: 1px solid #ccc; + border-left: 1px solid var(--border); } .assistant-resize-handle { @@ -3779,7 +3839,7 @@ input:checked + .slider:before { } .assistant-bubble-assistant { - background-color: #e8e6f0; + background-color: var(--surface-3); color: #222; align-self: flex-start; border-bottom-left-radius: 2px; @@ -3974,7 +4034,7 @@ input:checked + .slider:before { margin: 0.3em 0; padding: 0.2em 0.6em; border-left: 3px solid #8b86a8; - color: #555; + color: var(--text-muted); background: rgba(0, 0, 0, 0.03); } @@ -4074,7 +4134,7 @@ input:checked + .slider:before { padding: 6px 8px; background-color: rgba(0, 0, 0, 0.04); border-radius: 4px; - color: #555; + color: var(--text-muted); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.74rem; line-height: 1.4; @@ -4100,7 +4160,7 @@ input:checked + .slider:before { } .assistant-bubble-queries { - background-color: #f0eef7; + background-color: var(--surface-2); color: #222; align-self: stretch; border: 1px solid #d8d4e8; @@ -4115,7 +4175,7 @@ input:checked + .slider:before { .assistant-queries-header { font-weight: 600; font-size: 0.8rem; - color: #403C53; + color: var(--brand-text); } .assistant-queries-body { @@ -4137,7 +4197,7 @@ input:checked + .slider:before { width: 12px; height: 12px; border: 2px solid #cfc9e0; - border-top-color: #403C53; + border-top-color: var(--brand-text); border-radius: 50%; display: inline-block; animation: assistant-spin 0.9s linear infinite; @@ -4148,7 +4208,7 @@ input:checked + .slider:before { } .assistant-query-card { - background-color: #fff; + background-color: var(--input-bg); border: 1px solid #d8d4e8; border-radius: 6px; padding: 6px 8px; @@ -4160,7 +4220,7 @@ input:checked + .slider:before { .assistant-query-title { font-size: 0.78rem; font-weight: 600; - color: #403C53; + color: var(--brand-text); } .assistant-query-text { @@ -4191,8 +4251,8 @@ input:checked + .slider:before { font-size: 0.72rem; font-weight: 500; line-height: 1.1; - color: #403C53; - background-color: #fff; + color: var(--brand-text); + background-color: var(--input-bg); border: 1px solid #c8c3d8; border-radius: 4px; cursor: pointer; @@ -4200,12 +4260,12 @@ input:checked + .slider:before { } .assistant-query-btn:hover { - background-color: #f0eef7; + background-color: var(--surface-2); border-color: #8b86a8; } .assistant-query-btn:active { - background-color: #e8e6f0; + background-color: var(--surface-3); } .assistant-query-btn.assistant-query-btn-done { @@ -4215,14 +4275,14 @@ input:checked + .slider:before { } .assistant-query-btn.assistant-query-btn-failed { - color: #8a2d2d; + color: var(--danger-text); background-color: #f7e4e4; border-color: #c38a8a; } .assistant-queries-error { font-size: 0.8rem; - color: #8a2d2d; + color: var(--danger-text); background-color: #f7e4e4; border: 1px solid #c38a8a; border-radius: 4px; @@ -4297,7 +4357,7 @@ input:checked + .slider:before { .assistant-budget.assistant-budget-danger { background-color: #f7e0e0; border-color: #c38a8a; - color: #8a2d2d; + color: var(--danger-text); } .assistant-budget.assistant-budget-danger .assistant-budget-dot { background-color: #c33d35; @@ -4312,7 +4372,7 @@ input:checked + .slider:before { font-weight: 600; } .assistant-budget.assistant-budget-over .assistant-budget-dot { - background-color: #fff; + background-color: var(--input-bg); animation: assistant-budget-pulse 1.2s ease-in-out infinite; } @keyframes assistant-budget-pulse { @@ -4385,10 +4445,10 @@ input:checked + .slider:before { .assistant-status-badge.assistant-status-badge-muted { background-color: #ececec; border-color: #cfcfcf; - color: #666; + color: var(--text-muted); } .assistant-status-badge.assistant-status-badge-muted .assistant-status-badge-dot { - background-color: #888; + background-color: var(--text-faint); } #assistantEmptyState { @@ -4399,7 +4459,7 @@ input:checked + .slider:before { align-items: center; text-align: center; padding: 24px 20px; - color: #888; + color: var(--text-faint); gap: 8px; } @@ -4412,7 +4472,7 @@ input:checked + .slider:before { .assistant-empty-state-title { font-size: 1rem; font-weight: 600; - color: #555; + color: var(--text-muted); } .assistant-empty-state-body { @@ -4439,8 +4499,8 @@ input:checked + .slider:before { font-size: 0.78rem; line-height: 1.3; padding: 6px 10px; - background-color: #fff; - color: #444; + background-color: var(--input-bg); + color: var(--text-strong); border: 1px solid #cfd4dc; border-radius: 999px; cursor: pointer; @@ -4485,8 +4545,8 @@ input:checked + .slider:before { flex-direction: column; gap: 4px; padding: 8px 10px; - border-top: 1px solid #ccc; - background-color: #f4f4f4; + border-top: 1px solid var(--border); + background-color: var(--surface); opacity: 0; transition: opacity 0.3s ease-in-out; flex-shrink: 0; @@ -4499,18 +4559,18 @@ input:checked + .slider:before { #assistantInput { width: 100%; resize: none; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 4px; padding: 6px 8px; font-size: 0.82rem; font-family: inherit; box-sizing: border-box; - background-color: #fff; + background-color: var(--input-bg); } #assistantInput:focus { outline: none; - border-color: #403C53; + border-color: var(--brand-border); } #assistantSendBtn { @@ -4543,7 +4603,7 @@ input:checked + .slider:before { .assistant-settings-intro { font-size: 0.82rem; line-height: 1.45; - color: #555; + color: var(--text-muted); background-color: #f5f7fb; border: 1px solid #dde2ec; border-radius: 4px; @@ -4567,7 +4627,7 @@ input:checked + .slider:before { .assistant-settings-step-title { font-size: 0.85rem; font-weight: 600; - color: #333; + color: var(--text-strong); } .assistant-settings-step-disabled { @@ -4575,7 +4635,7 @@ input:checked + .slider:before { } .assistant-settings-step-disabled .assistant-settings-step-title { - color: #888; + color: var(--text-faint); } .assistant-settings-endpoint-row { @@ -4587,7 +4647,7 @@ input:checked + .slider:before { .assistant-settings-input { flex: 1; padding: 6px 8px; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 3px; box-sizing: border-box; font: inherit; @@ -4611,7 +4671,7 @@ input:checked + .slider:before { } .assistant-settings-status[data-kind="checking"] { - color: #666; + color: var(--text-muted); } .assistant-settings-status[data-kind="ok"] { @@ -4639,7 +4699,7 @@ input:checked + .slider:before { .assistant-settings-listbox { width: 100%; padding: 0; - border: 1px solid #ccc; + border: 1px solid var(--border); border-radius: 3px; box-sizing: border-box; font: inherit; @@ -4647,7 +4707,7 @@ input:checked + .slider:before { .assistant-settings-hint { display: block; - color: #666; + color: var(--text-muted); font-size: 0.75rem; line-height: 1.3; } @@ -4663,7 +4723,7 @@ input:checked + .slider:before { cursor: pointer; font-size: 0.82rem; font-weight: 600; - color: #444; + color: var(--text-strong); padding: 2px 0; user-select: none; } @@ -4689,7 +4749,7 @@ input:checked + .slider:before { gap: 4px; font-size: 0.78rem; font-weight: 500; - color: #444; + color: var(--text-strong); } .assistant-settings-input-number { @@ -4718,7 +4778,7 @@ input:checked + .slider:before { .assistant-budget-modal-title { font-size: 0.95rem; font-weight: 600; - color: #8a2d2d; + color: var(--danger-text); } .assistant-budget-modal-detail { @@ -4745,18 +4805,18 @@ input:checked + .slider:before { .assistant-budget-modal-row-name { font-weight: 500; - color: #333; + color: var(--text-strong); } .assistant-budget-modal-row-count { - color: #555; + color: var(--text-muted); text-align: right; font-variant-numeric: tabular-nums; } .assistant-budget-modal-hint { font-size: 0.8rem; - color: #555; + color: var(--text-muted); font-style: italic; } @@ -4778,7 +4838,7 @@ input:checked + .slider:before { border-color: #e3b5b5; } .assistant-budget-details-modal .assistant-budget-modal-summary.is-over .assistant-budget-modal-title { - color: #8a2d2d; + color: var(--danger-text); } .assistant-budget-details-modal .assistant-budget-modal-summary.is-over .assistant-budget-modal-detail { color: #6b4040; @@ -4805,7 +4865,7 @@ input:checked + .slider:before { .assistant-budget-modal-action-explainer { font-size: 0.78rem; - color: #555; + color: var(--text-muted); line-height: 1.35; } diff --git a/src/utilities/popup.js b/src/utilities/popup.js index 1687cb8..5de7914 100644 --- a/src/utilities/popup.js +++ b/src/utilities/popup.js @@ -176,7 +176,7 @@ static async prompt(message) { const cloneDesc = document.createElement('p'); cloneDesc.textContent = 'Copies all settings: positions, filters, query, and bubble groups'; cloneDesc.style.fontSize = '12px'; - cloneDesc.style.color = '#666'; + cloneDesc.style.color = 'var(--text-muted)'; cloneDesc.style.marginLeft = '20px'; cloneDesc.style.marginTop = '5px'; cloneDesc.style.marginBottom = '0'; @@ -220,7 +220,7 @@ static async prompt(message) { const templateDesc = document.createElement('p'); templateDesc.textContent = 'Starts fresh with selected layout algorithm and default filters'; templateDesc.style.fontSize = '12px'; - templateDesc.style.color = '#666'; + templateDesc.style.color = 'var(--text-muted)'; templateDesc.style.marginLeft = '20px'; templateDesc.style.marginTop = '5px'; templateDesc.style.marginBottom = '10px'; diff --git a/src/utilities/theme.js b/src/utilities/theme.js new file mode 100644 index 0000000..65787a7 --- /dev/null +++ b/src/utilities/theme.js @@ -0,0 +1,78 @@ +/** + * Light/dark theme handling. + * + * The active theme is a `data-theme="dark"` attribute on (absent = + * light) driving the CSS custom-property overrides at the top of style.css. + * The choice persists under localStorage "gllTheme"; prefers-color-scheme is + * only the initial default while no stored choice exists. + */ + +const THEME_STORAGE_KEY = "gllTheme"; + +// Renderer fallback for node labels without a per-element labelColor +// (sigma settings.labelColor → label_renderers.js resolveSettingsColor). +// User-set label colors on nodes/edges are never touched. +const NODE_LABEL_COLORS = { light: "#000", dark: "#E7E6EE" }; + +/** + * @param {string|null} stored persisted preference ("light"|"dark"|null) + * @param {boolean} prefersDark matchMedia("(prefers-color-scheme: dark)") + * @returns {"light"|"dark"} + */ +function resolveInitialTheme(stored, prefersDark) { + if (stored === "dark" || stored === "light") return stored; + return prefersDark ? "dark" : "light"; +} + +/** + * Set/remove the data-theme attribute and (by default) persist the choice. + * @param {Document} doc + * @param {"light"|"dark"} theme + * @param {{persist?: boolean}} [opts] + */ +function applyTheme(doc, theme, { persist = true } = {}) { + if (theme === "dark") doc.documentElement.setAttribute("data-theme", "dark"); + else doc.documentElement.removeAttribute("data-theme"); + if (!persist) return; + try { + (doc.defaultView ?? globalThis).localStorage?.setItem(THEME_STORAGE_KEY, theme); + } catch { + // Storage unavailable (e.g. blocked) — theme stays session-only. + } +} + +/** @returns {"light"|"dark"} */ +function currentTheme(doc) { + return doc.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light"; +} + +function nodeLabelColorForTheme(theme) { + return NODE_LABEL_COLORS[theme] ?? NODE_LABEL_COLORS.light; +} + +/** + * Boot helper: resolve the stored preference (OS preference as fallback) + * and apply it. Only an explicit stored choice is (re-)persisted, so the + * OS-preference default keeps following the OS until the user toggles. + */ +function initTheme(doc, win) { + let stored = null; + try { + stored = win.localStorage?.getItem(THEME_STORAGE_KEY) ?? null; + } catch { + stored = null; + } + const prefersDark = win.matchMedia?.("(prefers-color-scheme: dark)")?.matches ?? false; + const theme = resolveInitialTheme(stored, prefersDark); + applyTheme(doc, theme, { persist: stored !== null }); + return theme; +} + +export { + THEME_STORAGE_KEY, + resolveInitialTheme, + applyTheme, + currentTheme, + nodeLabelColorForTheme, + initTheme, +}; diff --git a/tests/label-renderers.test.js b/tests/label-renderers.test.js index 9925b2a..4d43c25 100644 --- a/tests/label-renderers.test.js +++ b/tests/label-renderers.test.js @@ -116,6 +116,27 @@ describe("drawNodeLabel", () => { expect(ctx2.fillStyle).toBe("#C33D35"); }); + it("treats the baked #000000 default as themeable (settings fallback wins)", () => { + // io.js bakes labelFill #000000 into every labelled element; the + // renderer must let the theme-driven settings fallback replace it. + const dark = stubContext(); + drawNodeLabel( + dark, + { ...NODE, labelColor: "#000000" }, + { ...SETTINGS, labelColor: { color: "#E7E6EE" } }, + ); + expect(dark.fillStyle).toBe("#E7E6EE"); + + // An explicit non-default per-node color is honoured as-is. + const explicit = stubContext(); + drawNodeLabel( + explicit, + { ...NODE, labelColor: "#112233" }, + { ...SETTINGS, labelColor: { color: "#E7E6EE" } }, + ); + expect(explicit.fillStyle).toBe("#112233"); + }); + it("places the label below the node by default (G6 default placement)", () => { const ctx = stubContext(); drawNodeLabel(ctx, NODE, SETTINGS); diff --git a/tests/theme.test.js b/tests/theme.test.js new file mode 100644 index 0000000..112bacb --- /dev/null +++ b/tests/theme.test.js @@ -0,0 +1,129 @@ +// @vitest-environment jsdom +import { beforeEach, describe, expect, it } from "vitest"; +import { + THEME_STORAGE_KEY, + applyTheme, + currentTheme, + initTheme, + nodeLabelColorForTheme, + resolveInitialTheme, +} from "../src/utilities/theme.js"; + +// ========================================================================== +// Theme resolution + application (src/utilities/theme.js). The dark theme is +// a data-theme attribute on ; persistence under localStorage gllTheme; +// prefers-color-scheme is only the default while no stored choice exists. +// ========================================================================== + +beforeEach(() => { + document.documentElement.removeAttribute("data-theme"); + window.localStorage.clear(); +}); + +describe("resolveInitialTheme", () => { + it("falls back to prefers-color-scheme when nothing is stored", () => { + expect(resolveInitialTheme(null, true)).toBe("dark"); + expect(resolveInitialTheme(null, false)).toBe("light"); + }); + + it("stored preference wins over prefers-color-scheme", () => { + expect(resolveInitialTheme("light", true)).toBe("light"); + expect(resolveInitialTheme("dark", false)).toBe("dark"); + }); + + it("ignores invalid stored values", () => { + expect(resolveInitialTheme("blue", true)).toBe("dark"); + expect(resolveInitialTheme("", false)).toBe("light"); + expect(resolveInitialTheme(undefined, false)).toBe("light"); + }); +}); + +describe("applyTheme", () => { + it("sets data-theme=dark on and persists", () => { + applyTheme(document, "dark"); + expect(document.documentElement.getAttribute("data-theme")).toBe("dark"); + expect(window.localStorage.getItem(THEME_STORAGE_KEY)).toBe("dark"); + }); + + it("removes the attribute for light and persists", () => { + applyTheme(document, "dark"); + applyTheme(document, "light"); + expect(document.documentElement.hasAttribute("data-theme")).toBe(false); + expect(window.localStorage.getItem(THEME_STORAGE_KEY)).toBe("light"); + }); + + it("skips persistence when persist is false", () => { + applyTheme(document, "dark", { persist: false }); + expect(document.documentElement.getAttribute("data-theme")).toBe("dark"); + expect(window.localStorage.getItem(THEME_STORAGE_KEY)).toBeNull(); + }); + + it("survives an unavailable localStorage", () => { + const doc = { + documentElement: document.documentElement, + defaultView: { + get localStorage() { + throw new Error("denied"); + }, + }, + }; + expect(() => applyTheme(doc, "dark")).not.toThrow(); + expect(document.documentElement.getAttribute("data-theme")).toBe("dark"); + }); +}); + +describe("currentTheme", () => { + it("reflects the data-theme attribute", () => { + expect(currentTheme(document)).toBe("light"); + document.documentElement.setAttribute("data-theme", "dark"); + expect(currentTheme(document)).toBe("dark"); + }); +}); + +describe("nodeLabelColorForTheme", () => { + it("is dark text for light theme and light text for dark theme", () => { + expect(nodeLabelColorForTheme("light")).toBe("#000"); + expect(nodeLabelColorForTheme("dark")).toBe("#E7E6EE"); + }); + + it("falls back to the light color for unknown themes", () => { + expect(nodeLabelColorForTheme("mystery")).toBe("#000"); + }); +}); + +describe("initTheme", () => { + const win = (stored, prefersDark) => ({ + localStorage: { + getItem: () => stored, + setItem: (k, v) => window.localStorage.setItem(k, v), + }, + matchMedia: (q) => ({ + matches: q === "(prefers-color-scheme: dark)" ? prefersDark : false, + }), + }); + + it("applies the OS preference when nothing is stored, without persisting", () => { + expect(initTheme(document, win(null, true))).toBe("dark"); + expect(document.documentElement.getAttribute("data-theme")).toBe("dark"); + // OS-default keeps following the OS until the user explicitly toggles. + expect(window.localStorage.getItem(THEME_STORAGE_KEY)).toBeNull(); + }); + + it("applies light when nothing is stored and the OS prefers light", () => { + expect(initTheme(document, win(null, false))).toBe("light"); + expect(document.documentElement.hasAttribute("data-theme")).toBe(false); + }); + + it("stored preference wins over the OS preference", () => { + expect(initTheme(document, win("light", true))).toBe("light"); + expect(document.documentElement.hasAttribute("data-theme")).toBe(false); + + expect(initTheme(document, win("dark", false))).toBe("dark"); + expect(document.documentElement.getAttribute("data-theme")).toBe("dark"); + }); + + it("tolerates a window without matchMedia or localStorage", () => { + expect(initTheme(document, {})).toBe("light"); + expect(document.documentElement.hasAttribute("data-theme")).toBe(false); + }); +}); From 1d2795b011e506e8700f16c950152617d1eaf517 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 13:44:05 +0200 Subject: [PATCH 22/69] fix(renderer): keep node labels stable around hover and drag - suppress sigma's hover pill layer while a drag is in flight: the dragged node is permanently hovered and its white disc + label pill (drawn on the hovers canvas, above the labels canvas) invisibly blanked every label it passed over on light backgrounds - pin all on-screen labels (forceLabel) for the duration of a node drag so the rebuilt label grid cannot evict neighbours' labels from cells the dragged node passes through; pins release on mouseup - tune labelGridCellSize to 50 (sigma default 100): ~4x more labels shown and smaller label-competition zones between nearby nodes - add drag interaction tests (label pinning, group drag, position persistence) with a stub sigma + real graphology --- src/graph/interactions.js | 23 ++++- src/graph/sigma_adapter.js | 21 +++- tests/interactions-drag.test.js | 170 ++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 tests/interactions-drag.test.js diff --git a/src/graph/interactions.js b/src/graph/interactions.js index b95b6f5..440d3f5 100644 --- a/src/graph/interactions.js +++ b/src/graph/interactions.js @@ -33,6 +33,7 @@ class InteractionManager { this.draggedNode = null; this.dragGroup = null; this.dragMoved = false; + this.pinnedLabels = null; // Covers the click that ends a micro-drag (1-2 move events — sigma's // captor only swallows clicks after >=3 dragged events itself). this.suppressNextClick = false; @@ -121,8 +122,20 @@ class InteractionManager { // selection — new Set() tolerates both.) const selected = new Set(this.cache.selectedNodes ?? []); this.dragGroup = selected.has(node) ? selected : null; - // Pin the label so sigma's per-frame label grid can't drop it mid-drag. - this.adapter.graph.mergeNodeAttributes(node, { forceLabel: true }); + // Pin labels for the drag. Every position write rebuilds sigma's label + // grid, so the dragged node would evict neighbours' labels from any grid + // cell it passes through. Pin the dragged node's label (also keeps it up + // past labelRenderedSizeThreshold) AND every label currently on screen; + // all pins are released on mouseup and the grid re-settles. + // (displayedNodeLabels is a sigma internal — fall back to pinning just + // the dragged node if a future sigma drops it.) + this.pinnedLabels = new Set(this.adapter.sigma.displayedNodeLabels ?? []); + this.pinnedLabels.add(node); + for (const id of this.pinnedLabels) { + if (this.adapter.graph.hasNode(id)) { + this.adapter.graph.mergeNodeAttributes(id, { forceLabel: true }); + } + } // Pin the normalization bbox: without it every x/y write re-normalizes // the coordinate space and the graph swims under the cursor. const sigma = this.adapter.sigma; @@ -156,12 +169,14 @@ class InteractionManager { async #onMouseUp() { if (!this.draggedNode) return; const moved = this.dragMoved; - const dragged = this.draggedNode; this.draggedNode = null; this.dragGroup = null; this.dragMoved = false; const graph = this.adapter.graph; - if (graph.hasNode(dragged)) graph.mergeNodeAttributes(dragged, { forceLabel: false }); + for (const id of this.pinnedLabels ?? []) { + if (graph.hasNode(id)) graph.mergeNodeAttributes(id, { forceLabel: false }); + } + this.pinnedLabels = null; if (!moved) return; // Set synchronously before any await: sigma emits clickNode right after // mouseup with no microtask boundary, so the flag must already be up. diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 39df9b2..6bfdc84 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -42,9 +42,14 @@ const ATLAS_REGEN_DEBOUNCE_MS = 50; const RESIZE_DEBOUNCE_MS = 50; /** - * While a node drag is in flight, sigma's captor still updates hoveredNode on - * every mousemove, popping passed-over nodes' hover labels. Gate any hover - * drawer so only the dragged node may draw while a drag is active. + * Sigma's hover layer (drawDiscNodeHover and per-program drawHover) paints a + * white disc + label pill on the hovers canvas, which sits ABOVE the labels + * canvas — on light backgrounds the pill invisibly blanks every label + * underneath. Acceptable on a deliberate hover; NOT while dragging, where + * the dragged node is permanently hovered and would wipe labels along its + * whole path (the dragged node's own label stays visible via the forceLabel + * pin in InteractionManager, on the labels canvas). So: suppress ALL hover + * drawing while a drag is in flight, keep the native pill otherwise. * * @param {(context, data, settings) => void} drawer * @param {() => string|null} getDraggedNode @@ -55,8 +60,7 @@ function guardHoverDrawer(drawer, getDraggedNode) { // inside sigma's render loop (which would swallow the error silently). if (typeof drawer !== "function") return () => {}; return (context, data, settings) => { - const dragged = getDraggedNode(); - if (dragged && data.key !== dragged) return; + if (getDraggedNode()) return; // Sigma's drawDiscNodeHover hardcodes a white pill behind the label, so // pin the FALLBACK to dark regardless of the theme-driven labelColor // setting (dark mode flips it to a light color, unreadable on the pill). @@ -235,6 +239,13 @@ class SigmaAdapter { defaultDrawEdgeLabel: drawEdgeLabel, defaultDrawNodeHover: guardHoverDrawer(drawDiscNodeHover, getDraggedNode), renderEdgeLabels: true, + // Label-grid thinning stays on, tuned denser than sigma's default + // (1 label per 100px cell): 50px cells show ~4x the labels and shrink + // the zone where two nearby nodes compete for one label slot. Drags + // can't pop neighbours' labels regardless — InteractionManager pins + // all on-screen labels for the duration of a drag. CFG.HIDE_LABELS + // remains the guard for huge graphs (MAX_NODES_BEFORE_HIDING_LABELS). + labelGridCellSize: 50, ...settings, }); // Sigma only auto-resizes on window resize. Sidebar/bottom-bar toggles diff --git a/tests/interactions-drag.test.js b/tests/interactions-drag.test.js new file mode 100644 index 0000000..abb6be8 --- /dev/null +++ b/tests/interactions-drag.test.js @@ -0,0 +1,170 @@ +import { describe, it, expect, vi } from "vitest"; +import { Graph } from "../src/lib/graphology.bundle.mjs"; +import { InteractionManager } from "../src/graph/interactions.js"; + +// ========================================================================== +// Node drag behavior. Sigma's label grid rebuilds on every position write, +// so a dragged node would evict neighbours' labels from grid cells it +// passes through; the InteractionManager pins all on-screen labels +// (forceLabel) for the duration of a drag and releases them on mouseup. +// The drag also moves nodes (group drag follows the selection) and persists +// positions. Exercised with a stub sigma + real graphology. +// ========================================================================== + +function makeGraph(ids) { + const graph = new Graph({ multi: true, allowSelfLoops: true, type: "directed" }); + for (const id of ids) graph.addNode(id, { x: 0, y: 0, label: id }); + return graph; +} + +function makeSigma(displayedNodeLabels) { + const handlers = {}; + const captorHandlers = {}; + return { + handlers, + captorHandlers, + displayedNodeLabels, + on: (event, fn) => { + handlers[event] = fn; + }, + getMouseCaptor: () => ({ + on: (event, fn) => { + captorHandlers[event] = fn; + }, + }), + getCamera: () => ({ on: () => {} }), + getCustomBBox: () => null, + setCustomBBox: () => {}, + getBBox: () => ({ x: [0, 1], y: [0, 1] }), + refresh: () => {}, + viewportToGraph: (event) => ({ x: event.x, y: event.y }), + }; +} + +function makeManager({ + nodeIds = ["a", "b", "c"], + displayed = new Set(), + selectedNodes = [], +} = {}) { + const graph = makeGraph(nodeIds); + const sigma = makeSigma(displayed); + const cache = { + ui: { error: vi.fn() }, + selectedNodes, + CFG: {}, + lm: { persistNodePositions: vi.fn(async () => {}) }, + }; + const adapter = { sigma, graph }; + const container = { appendChild: () => {} }; + const manager = new InteractionManager(adapter, cache, new Set(), container); + return { manager, graph, sigma, cache }; +} + +function moveEvent(x, y) { + return { + x, + y, + preventSigmaDefault: () => {}, + original: { preventDefault: () => {}, stopPropagation: () => {} }, + }; +} + +describe("drag label pinning", () => { + it("pins the dragged node AND all currently displayed labels on downNode", () => { + const { graph, sigma } = makeManager({ displayed: new Set(["b", "c"]) }); + + sigma.handlers.downNode({ node: "a" }); + + expect(graph.getNodeAttribute("a", "forceLabel")).toBe(true); + expect(graph.getNodeAttribute("b", "forceLabel")).toBe(true); + expect(graph.getNodeAttribute("c", "forceLabel")).toBe(true); + }); + + it("releases every pinned label on mouseup, even without movement", async () => { + const { graph, sigma } = makeManager({ displayed: new Set(["b"]) }); + + sigma.handlers.downNode({ node: "a" }); + await sigma.captorHandlers.mouseup(); + + expect(graph.getNodeAttribute("a", "forceLabel")).toBe(false); + expect(graph.getNodeAttribute("b", "forceLabel")).toBe(false); + expect(graph.getNodeAttribute("c", "forceLabel")).toBeUndefined(); + }); + + it("pins only the dragged node when sigma stops exposing displayedNodeLabels", () => { + const { graph, sigma } = makeManager({ displayed: undefined }); + + sigma.handlers.downNode({ node: "a" }); + + expect(graph.getNodeAttribute("a", "forceLabel")).toBe(true); + expect(graph.getNodeAttribute("b", "forceLabel")).toBeUndefined(); + }); + + it("survives a pinned node being dropped from the graph mid-drag", async () => { + const { graph, sigma } = makeManager({ displayed: new Set(["b"]) }); + + sigma.handlers.downNode({ node: "a" }); + graph.dropNode("b"); + await sigma.captorHandlers.mouseup(); + + expect(graph.getNodeAttribute("a", "forceLabel")).toBe(false); + expect(graph.hasNode("b")).toBe(false); + }); + + it("does not pin anything while drag is disabled", () => { + const { manager, graph, sigma } = makeManager({ displayed: new Set(["b"]) }); + + manager.setEnabled("drag", false); + sigma.handlers.downNode({ node: "a" }); + + expect(graph.getNodeAttribute("a", "forceLabel")).toBeUndefined(); + expect(graph.getNodeAttribute("b", "forceLabel")).toBeUndefined(); + }); +}); + +describe("node drag movement", () => { + it("does not persist anything on mouseup without movement", async () => { + const { sigma, cache } = makeManager(); + + sigma.handlers.downNode({ node: "a" }); + await sigma.captorHandlers.mouseup(); + + expect(cache.lm.persistNodePositions).not.toHaveBeenCalled(); + }); + + it("moves the node, releases pins and persists after an actual drag", async () => { + const { graph, sigma, cache } = makeManager({ displayed: new Set(["b"]) }); + + sigma.handlers.downNode({ node: "a" }); + sigma.captorHandlers.mousemovebody(moveEvent(5, 7)); + await sigma.captorHandlers.mouseup(); + + expect(graph.getNodeAttributes("a")).toMatchObject({ x: 5, y: 7, forceLabel: false }); + expect(graph.getNodeAttribute("b", "forceLabel")).toBe(false); + expect(cache.lm.persistNodePositions).toHaveBeenCalledTimes(1); + }); + + it("drags the whole selection along when the dragged node is selected", async () => { + const { graph, sigma } = makeManager({ selectedNodes: ["a", "b"] }); + + sigma.handlers.downNode({ node: "a" }); + sigma.captorHandlers.mousemovebody(moveEvent(5, 7)); + await sigma.captorHandlers.mouseup(); + + expect(graph.getNodeAttributes("a")).toMatchObject({ x: 5, y: 7 }); + expect(graph.getNodeAttributes("b")).toMatchObject({ x: 5, y: 7 }); + expect(graph.getNodeAttributes("c")).toMatchObject({ x: 0, y: 0 }); + }); + + it("does nothing while drag is disabled", async () => { + const { manager, graph, sigma, cache } = makeManager(); + + manager.setEnabled("drag", false); + sigma.handlers.downNode({ node: "a" }); + sigma.captorHandlers.mousemovebody(moveEvent(5, 7)); + await sigma.captorHandlers.mouseup(); + + expect(graph.getNodeAttributes("a")).toMatchObject({ x: 0, y: 0 }); + expect(cache.lm.persistNodePositions).not.toHaveBeenCalled(); + }); +}); From 35e22c0b3250f93039ab60ebd182498d47fa8fa3 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 13:55:15 +0200 Subject: [PATCH 23/69] feat(ui): subtle top-center loading indicator card Replace the full-screen dimmed centered overlay with a compact status card docked top-center. - Drop the rgba(0,0,0,0.2) dimming; the full-screen layer stays at z-index 10001 to keep loading blocking, but is now transparent. - Top-center placement avoids the bottom-right minimap and the top-right selected-elements panel. - Inline 20px spinner beside a header + muted detail line; messages wrap (including long URLs) instead of truncating, so no info is lost. - Zero the .h7 margin on the detail text so it left-aligns under the header; add role=status/aria-live for screen-reader progress. --- src/graph_lens_lite.html | 8 ++-- src/style.css | 84 +++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index 50daeb6..174491b 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -63,10 +63,12 @@

    Graph Lens Lite

    -
    +
    -

    Loading ..

    - Please wait +
    +

    Loading ..

    + Please wait +
    diff --git a/src/style.css b/src/style.css index 910eb47..5bf71e2 100644 --- a/src/style.css +++ b/src/style.css @@ -824,30 +824,69 @@ h5 { } #loadingOverlay { - /* Initially shown */ - flex-direction: column; + /* Full-screen layer: transparent (no dimming) but blocks interaction + while loading. The visible indicator is a compact bottom-right card. */ position: fixed; + inset: 0; opacity: 0; display: none; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.2); + /* anchor the card to the top-center (clear of the bottom-right minimap + and the top-right selected-elements panel) */ + justify-content: center; + align-items: flex-start; + padding: 16px; + background: transparent; color: var(--text); z-index: 10001; - text-align: center; - font-size: 30px; - /*transition: opacity 0.2s ease;*/ - transition: none !important; - animation: none !important; + transition: opacity 0.18s ease; } #loadingInnerContent { + display: flex; + align-items: flex-start; + gap: 14px; + max-width: 440px; + padding: 14px 18px; border: 1px solid var(--border-strong); - border-radius: 20px; + border-radius: 12px; background: var(--input-bg); - padding: 20px 80px 20px 80px; + box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28); + text-align: left; + animation: loaderCardIn 0.2s ease both; +} + +#loadingTextGroup { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +#loadingHeader { + margin: 0; + font-size: 14px; + font-weight: 600; + line-height: 1.3; +} + +#loadingText { + margin: 0; + font-size: 12px; + color: var(--text-muted); + line-height: 1.4; + /* wrap long messages (incl. unbroken URLs) instead of truncating */ + overflow-wrap: anywhere; +} + +@keyframes loaderCardIn { + from { + opacity: 0; + transform: translateY(-12px); + } + to { + opacity: 1; + transform: translateY(0); + } } .container { @@ -1013,6 +1052,23 @@ h5 { } } +/* Compact inline spinner for the loading card */ +#loadingInnerContent .loader { + width: 20px; + margin: 0; + flex-shrink: 0; +} + +#loadingInnerContent .loader::before, +#loadingInnerContent .loader::after { + background-size: 5px 5px; +} + +#loadingInnerContent .loader::before { + margin: 2px; + background-size: 3px 3px; +} + .tooltip { font-family: sans-serif !important; width: 360px !important; From f33f6e33a609f7c0064916c1d0d43cdd3084ba31 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 14:32:46 +0200 Subject: [PATCH 24/69] feat(renderer): arrow fill, border color and border size controls Extend edge end-markers with per-end fill color, border color, and border size, threaded through the full styling pipeline: - config: arrow color/border-color (null = inherit edge color / no border) and border-size (0 = auto, scales with the marker) defaults + palettes - style/graph_model: map the new style keys to start/end marker attrs, emitting the full set so a disable overwrites stale values - edge_programs: add a_borderColor + a_borderSize to the marker-head WebGL program; draw an SDF border band (explicit px, else ~20% proportional) - ui_style_div: color pickers + border-size sliders for start/end arrows - io: Excel columns for round-trip of the new arrow style props - tests: marker color/size mapping + extended round-trip coverage --- src/config.js | 12 +++++- src/graph/edge_programs.js | 36 +++++++++++++++-- src/graph/graph_model.js | 14 +++++++ src/graph/style.js | 18 ++++++--- src/managers/io.js | 60 +++++++++++++++++++++++++++++ src/managers/ui_style_div.js | 60 +++++++++++++++++++++++++++++ tests/excel-style-roundtrip.test.js | 6 +++ tests/graph-model.test.js | 55 ++++++++++++++++++++++++++ 8 files changed, 251 insertions(+), 10 deletions(-) diff --git a/src/config.js b/src/config.js index f0024d4..4dd49d8 100644 --- a/src/config.js +++ b/src/config.js @@ -17,7 +17,13 @@ const DEFAULTS = { }, EDGE: { COLOR: "#403C5390", LINE_WIDTH: 0.75, LINE_DASH: 0, TYPE: "line", - ARROWS: {START: false, END: false, START_SIZE: 8, START_TYPE: "arrow", END_SIZE: 8, END_TYPE: "arrow"}, + ARROWS: { + START: false, END: false, START_SIZE: 8, START_TYPE: "arrow", END_SIZE: 8, END_TYPE: "arrow", + // null fill → marker inherits the edge stroke color; null border → no border (transparent). + START_COLOR: null, START_BORDER_COLOR: null, END_COLOR: null, END_BORDER_COLOR: null, + // Border band thickness in px; 0 → auto (scales with the marker, ~20%). + START_BORDER_SIZE: 0, END_BORDER_SIZE: 0, + }, LABEL: { TEXT: null, FOREGROUND_COLOR: "#000000", BACKGROUND: false, BACKGROUND_COLOR: null, BACKGROUND_CURSOR: "default", BACKGROUND_FILL_OPACITY: 1, BACKGROUND_RADIUS: 0, BACKGROUND_STROKE_OPACITY: 1, @@ -184,6 +190,10 @@ const DEFAULTS = { // "tee" (⊣ inhibition bar). Legacy G6 names (triangle/vee/...) still load // via aliases but are no longer offered in the UI. EDGE_ARROW_TYPES: ["arrow", "rect", "diamond", "circle", "tee"], + EDGE_ARROW_COLORS: {red: "#C33D35", purple: "#403C53", blue: "#8CA6D9", pink: "#EFB0AA", grey: "#ABACBD"}, + EDGE_ARROW_BORDER_COLORS: { + red: "#C33D35", purple: "#403C53", blue: "#8CA6D9", pink: "#EFB0AA", grey: "#ABACBD", none: "#00000000" + }, EDGE_HALO: {enable: true, disable: false}, EDGE_HALO_STROKE: {red: "#C33D35", purple: "#403C53", blue: "#8CA6D9"}, EDGE_HALO_WIDTH: {sm: 2, md: 3, lg: 5}, diff --git a/src/graph/edge_programs.js b/src/graph/edge_programs.js index 2906663..47938a0 100644 --- a/src/graph/edge_programs.js +++ b/src/graph/edge_programs.js @@ -211,12 +211,14 @@ attribute vec2 a_normal; attribute float a_radius; attribute float a_marker; attribute float a_markerSize; +attribute float a_borderSize; attribute vec2 a_corner; #ifdef PICKING_MODE attribute vec4 a_id; #else attribute vec4 a_color; +attribute vec4 a_borderColor; #endif uniform mat3 u_matrix; @@ -226,9 +228,11 @@ uniform float u_minEdgeThickness; uniform float u_feather; varying vec4 v_color; +varying vec4 v_borderColor; varying float v_marker; varying vec2 v_uv; varying vec2 v_dimPx; +varying float v_borderSizePx; varying float v_feather; const float bias = 255.0 / 254.0; @@ -242,9 +246,11 @@ void main() { // No marker on this end: zero-area triangle off-screen -> no fragments. gl_Position = vec4(2.0, 2.0, 0.0, 1.0); v_color = vec4(0.0); + v_borderColor = vec4(0.0); v_marker = 0.0; v_uv = vec2(0.0); v_dimPx = vec2(1.0); + v_borderSizePx = 0.0; v_feather = 1.0; return; } @@ -270,6 +276,8 @@ void main() { v_uv = a_corner; v_dimPx = vec2(2.0 * halfWidth, len) / u_sizeRatio; + // Explicit border thickness (graph px → screen px); 0 lets the fragment derive it. + v_borderSizePx = a_borderSize > 0.0 ? a_borderSize / u_sizeRatio : 0.0; v_marker = a_marker; v_feather = u_feather; @@ -277,6 +285,8 @@ void main() { v_color = a_id; #else v_color = a_color; + v_borderColor = a_borderColor; + v_borderColor.a *= bias; #endif v_color.a *= bias; @@ -288,12 +298,18 @@ const MARKER_FRAGMENT_SHADER = /*glsl*/ ` precision mediump float; varying vec4 v_color; +varying vec4 v_borderColor; varying float v_marker; varying vec2 v_uv; varying vec2 v_dimPx; +varying float v_borderSizePx; varying float v_feather; const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); +// Auto border band thickness as a fraction of the marker's smaller dimension; +// used when no explicit border size is set, so the outline scales with the +// marker and reads the same at any size/zoom. +const float borderFraction = 0.2; void main(void) { float w = v_dimPx.x; // full width across the edge (screen px) @@ -325,8 +341,14 @@ void main(void) { gl_FragColor = d >= 0.0 ? v_color : transparent; #else float feather = max(v_feather, 0.001); - float t = smoothstep(-feather * 0.5, feather * 0.5, d); - gl_FragColor = mix(transparent, v_color, t); + float coverage = smoothstep(-feather * 0.5, feather * 0.5, d); // 0 outside -> 1 inside + float borderPx = v_borderSizePx > 0.0 ? v_borderSizePx : min(v_dimPx.x, v_dimPx.y) * borderFraction; + // fillMix: 0 inside the border band (near the edge), 1 in the interior. + float fillMix = smoothstep(borderPx - feather * 0.5, borderPx + feather * 0.5, d); + // No border color (alpha ~0) -> the whole marker uses the fill color. + fillMix = max(fillMix, 1.0 - step(0.0039, v_borderColor.a)); + vec4 body = mix(v_borderColor, v_color, fillMix); + gl_FragColor = mix(transparent, body, coverage); #endif } `; @@ -354,7 +376,9 @@ function createEdgeMarkerHeadProgram({ extremity = "target", curved = false } = { name: "a_radius", size: 1, type: FLOAT }, { name: "a_marker", size: 1, type: FLOAT }, { name: "a_markerSize", size: 1, type: FLOAT }, + { name: "a_borderSize", size: 1, type: FLOAT }, { name: "a_color", size: 4, type: UNSIGNED_BYTE, normalized: true }, + { name: "a_borderColor", size: 4, type: UNSIGNED_BYTE, normalized: true }, { name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true }, ], CONSTANT_ATTRIBUTES: [{ name: "a_corner", size: 2, type: FLOAT }], @@ -373,7 +397,11 @@ function createEdgeMarkerHeadProgram({ extremity = "target", curved = false } = const marked = isSource ? sourceData : targetData; const marker = (isSource ? data.startMarker : data.endMarker) || 0; const markerSize = (isSource ? data.startMarkerSize : data.endMarkerSize) || 0; + const borderSize = (isSource ? data.startMarkerBorderSize : data.endMarkerBorderSize) || 0; const thickness = data.size || 1; + // Explicit arrow fill wins; null inherits the edge color. Border null -> none. + const fillColor = (isSource ? data.startMarkerColor : data.endMarkerColor) ?? data.color; + const borderColor = (isSource ? data.startMarkerBorderColor : data.endMarkerBorderColor) ?? TRANSPARENT; // Direction from the marked node back along the edge. let awayX; @@ -410,7 +438,9 @@ function createEdgeMarkerHeadProgram({ extremity = "target", curved = false } = array[startIndex++] = marked.size || 1; array[startIndex++] = marker; array[startIndex++] = markerSize; - array[startIndex++] = floatColor(data.color); + array[startIndex++] = borderSize; + array[startIndex++] = floatColor(fillColor); + array[startIndex++] = floatColor(borderColor); array[startIndex++] = edgeIndex; } diff --git a/src/graph/graph_model.js b/src/graph/graph_model.js index ae0c80f..ee9d3a3 100644 --- a/src/graph/graph_model.js +++ b/src/graph/graph_model.js @@ -253,9 +253,23 @@ function edgeMarkerHaloAttributes(style) { startMarker: style.startArrow ? edgeMarkerCode(style.startArrowType) : 0, startMarkerSize: Number.isFinite(style.startArrowSize) && style.startArrowSize > 0 ? style.startArrowSize : 0, + // null fill → marker program inherits the edge stroke color; null border → no border. + startMarkerColor: style.startArrow ? (style.startArrowColor ?? null) : null, + startMarkerBorderColor: style.startArrow ? (style.startArrowBorderColor ?? null) : null, + // Border band thickness in px; 0 → auto (proportional to the marker). + startMarkerBorderSize: + style.startArrow && Number.isFinite(style.startArrowBorderSize) && style.startArrowBorderSize > 0 + ? style.startArrowBorderSize + : 0, endMarker: style.endArrow ? edgeMarkerCode(style.endArrowType) : 0, endMarkerSize: Number.isFinite(style.endArrowSize) && style.endArrowSize > 0 ? style.endArrowSize : 0, + endMarkerColor: style.endArrow ? (style.endArrowColor ?? null) : null, + endMarkerBorderColor: style.endArrow ? (style.endArrowBorderColor ?? null) : null, + endMarkerBorderSize: + style.endArrow && Number.isFinite(style.endArrowBorderSize) && style.endArrowBorderSize > 0 + ? style.endArrowBorderSize + : 0, haloWidth, haloColor: haloWidth > 0 ? (style.haloStroke ?? DEFAULTS.EDGE.HALO.COLOR) : null, }; diff --git a/src/graph/style.js b/src/graph/style.js index 629557b..5287521 100644 --- a/src/graph/style.js +++ b/src/graph/style.js @@ -99,12 +99,18 @@ class GraphStyleManager { const defaultEdge = { type : edge.type ?? d.TYPE, style: { - startArrow : src.startArrow ?? d.ARROWS.START, - startArrowSize : src.startArrowSize ?? d.ARROWS.START_SIZE, - startArrowType : src.startArrowType ?? d.ARROWS.START_TYPE, - endArrow : src.endArrow ?? d.ARROWS.END, - endArrowSize : src.endArrowSize ?? d.ARROWS.END_SIZE, - endArrowType : src.endArrowType ?? d.ARROWS.END_TYPE, + startArrow : src.startArrow ?? d.ARROWS.START, + startArrowSize : src.startArrowSize ?? d.ARROWS.START_SIZE, + startArrowType : src.startArrowType ?? d.ARROWS.START_TYPE, + startArrowColor : src.startArrowColor ?? d.ARROWS.START_COLOR, + startArrowBorderColor: src.startArrowBorderColor?? d.ARROWS.START_BORDER_COLOR, + startArrowBorderSize : src.startArrowBorderSize ?? d.ARROWS.START_BORDER_SIZE, + endArrow : src.endArrow ?? d.ARROWS.END, + endArrowSize : src.endArrowSize ?? d.ARROWS.END_SIZE, + endArrowType : src.endArrowType ?? d.ARROWS.END_TYPE, + endArrowColor : src.endArrowColor ?? d.ARROWS.END_COLOR, + endArrowBorderColor : src.endArrowBorderColor ?? d.ARROWS.END_BORDER_COLOR, + endArrowBorderSize : src.endArrowBorderSize ?? d.ARROWS.END_BORDER_SIZE, lineWidth : src.lineWidth ?? d.LINE_WIDTH, lineDash : src.lineDash ?? d.LINE_DASH, diff --git a/src/managers/io.js b/src/managers/io.js index f2766a0..d3dfa4d 100644 --- a/src/managers/io.js +++ b/src/managers/io.js @@ -348,6 +348,36 @@ const EXCEL_EDGE_PROPERTIES = [ return e.style.startArrowType; }, }, + { + column: "Start Arrow Color", + type: "rgba", + apply: (e, v) => { + e.style.startArrowColor = v; + }, + get: (e) => { + return e.style.startArrow ? e.style.startArrowColor : undefined; + }, + }, + { + column: "Start Arrow Border Color", + type: "rgba", + apply: (e, v) => { + e.style.startArrowBorderColor = v; + }, + get: (e) => { + return e.style.startArrow ? e.style.startArrowBorderColor : undefined; + }, + }, + { + column: "Start Arrow Border Size", + type: "num", + apply: (e, v) => { + e.style.startArrowBorderSize = v; + }, + get: (e) => { + return e.style.startArrow ? e.style.startArrowBorderSize : undefined; + }, + }, { column: "End Arrow", type: "bool", @@ -378,6 +408,36 @@ const EXCEL_EDGE_PROPERTIES = [ return e.style.endArrowType; }, }, + { + column: "End Arrow Color", + type: "rgba", + apply: (e, v) => { + e.style.endArrowColor = v; + }, + get: (e) => { + return e.style.endArrow ? e.style.endArrowColor : undefined; + }, + }, + { + column: "End Arrow Border Color", + type: "rgba", + apply: (e, v) => { + e.style.endArrowBorderColor = v; + }, + get: (e) => { + return e.style.endArrow ? e.style.endArrowBorderColor : undefined; + }, + }, + { + column: "End Arrow Border Size", + type: "num", + apply: (e, v) => { + e.style.endArrowBorderSize = v; + }, + get: (e) => { + return e.style.endArrow ? e.style.endArrowBorderSize : undefined; + }, + }, { column: "Halo Color", type: "rgba", diff --git a/src/managers/ui_style_div.js b/src/managers/ui_style_div.js index c973ff3..c5a86e9 100644 --- a/src/managers/ui_style_div.js +++ b/src/managers/ui_style_div.js @@ -193,6 +193,24 @@ function createStyleDiv(cache) { case "Edge End Arrow Type": await cache.gcm.updateEdges({style: {endArrowType: value}}, commands); break; + case "Edge Start Arrow Color": + await cache.gcm.updateEdges({style: {startArrowColor: value}}, commands); + break; + case "Edge Start Arrow Border Color": + await cache.gcm.updateEdges({style: {startArrowBorderColor: value}}, commands); + break; + case "Edge Start Arrow Border Size": + await cache.gcm.updateEdges({style: {startArrowBorderSize: value}}, commands); + break; + case "Edge End Arrow Color": + await cache.gcm.updateEdges({style: {endArrowColor: value}}, commands); + break; + case "Edge End Arrow Border Color": + await cache.gcm.updateEdges({style: {endArrowBorderColor: value}}, commands); + break; + case "Edge End Arrow Border Size": + await cache.gcm.updateEdges({style: {endArrowBorderSize: value}}, commands); + break; case "Edge Halo": await cache.gcm.updateEdges({style: {halo: value}}, commands); break; @@ -961,6 +979,27 @@ function createStyleDiv(cache) { cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, "Marker shape at the source end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); + const rowFifteenColor = createNewRow(edgeDiv); + appendLabel(rowFifteenColor, "Start Arrow Color", + "Fill color of the start marker. Leave unset to inherit the edge color."); + createColorControls(rowFifteenColor, "Edge Start Arrow Color", cache.DEFAULTS.EDGE.COLOR, + cache.DEFAULTS.STYLES.EDGE_ARROW_COLORS, + "Fill color of the start marker. Leave unset to inherit the edge color."); + + const rowFifteenBorder = createNewRow(edgeDiv); + appendLabel(rowFifteenBorder, "Start Arrow Border Color", + "Outline color of the start marker. Set to none for no border."); + createColorControls(rowFifteenBorder, "Edge Start Arrow Border Color", cache.DEFAULTS.EDGE.HALO.COLOR, + cache.DEFAULTS.STYLES.EDGE_ARROW_BORDER_COLORS, + "Outline color of the start marker. Set to none for no border."); + + const rowFifteenBorderSize = createNewRow(edgeDiv); + appendLabel(rowFifteenBorderSize, "Start Arrow Border Size", + "Thickness of the start marker border in px. 0 = auto (scales with the arrow)."); + createNumericalSlider(rowFifteenBorderSize, "Edge Start Arrow Border Size", + cache.DEFAULTS.EDGE.ARROWS.START_BORDER_SIZE, {min: 0, max: 20, step: 1}, + "Thickness of the start marker border in px. 0 = auto (scales with the arrow).", true); + const rowSixteen = createNewRow(edgeDiv); appendLabel(rowSixteen, "End Arrow", "Enable/Disable the end arrow of the selected edges."); createBooleanControls(rowSixteen, "Edge End Arrow", "Enable/Disable the end arrow of the selected edges."); @@ -977,6 +1016,27 @@ function createStyleDiv(cache) { cache.DEFAULTS.STYLES.EDGE_ARROW_TYPES, "Marker shape at the target end: arrow/rect/diamond/circle encode direction, tee (⊣) encodes inhibition."); + const rowNineteenColor = createNewRow(edgeDiv); + appendLabel(rowNineteenColor, "End Arrow Color", + "Fill color of the end marker. Leave unset to inherit the edge color."); + createColorControls(rowNineteenColor, "Edge End Arrow Color", cache.DEFAULTS.EDGE.COLOR, + cache.DEFAULTS.STYLES.EDGE_ARROW_COLORS, + "Fill color of the end marker. Leave unset to inherit the edge color."); + + const rowNineteenBorder = createNewRow(edgeDiv); + appendLabel(rowNineteenBorder, "End Arrow Border Color", + "Outline color of the end marker. Set to none for no border."); + createColorControls(rowNineteenBorder, "Edge End Arrow Border Color", cache.DEFAULTS.EDGE.HALO.COLOR, + cache.DEFAULTS.STYLES.EDGE_ARROW_BORDER_COLORS, + "Outline color of the end marker. Set to none for no border."); + + const rowNineteenBorderSize = createNewRow(edgeDiv); + appendLabel(rowNineteenBorderSize, "End Arrow Border Size", + "Thickness of the end marker border in px. 0 = auto (scales with the arrow)."); + createNumericalSlider(rowNineteenBorderSize, "Edge End Arrow Border Size", + cache.DEFAULTS.EDGE.ARROWS.END_BORDER_SIZE, {min: 0, max: 20, step: 1}, + "Thickness of the end marker border in px. 0 = auto (scales with the arrow).", true); + appendHorizontalRule(edgeDiv); const rowTwenty = createNewRow(edgeDiv); diff --git a/tests/excel-style-roundtrip.test.js b/tests/excel-style-roundtrip.test.js index a54cc39..e2d295c 100644 --- a/tests/excel-style-roundtrip.test.js +++ b/tests/excel-style-roundtrip.test.js @@ -170,9 +170,15 @@ describe("Excel style round-trip — edges", () => { "Start Arrow": "true", "Start Arrow Size": "12", "Start Arrow Type": "vee", + "Start Arrow Color": "#C33D35", + "Start Arrow Border Color": "#000000", + "Start Arrow Border Size": "4", "End Arrow": "true", "End Arrow Size": "10", "End Arrow Type": "diamond", + "End Arrow Color": "#8CA6D9", + "End Arrow Border Color": "#00000000", + "End Arrow Border Size": "2", "Halo Color": "#FF0000", "Halo Width": "5", }; diff --git a/tests/graph-model.test.js b/tests/graph-model.test.js index 07d4eaa..1a77d74 100644 --- a/tests/graph-model.test.js +++ b/tests/graph-model.test.js @@ -582,8 +582,14 @@ describe("edge marker + halo attribute mapping", () => { const FULL_OFF = { startMarker: 0, startMarkerSize: 0, + startMarkerColor: null, + startMarkerBorderColor: null, + startMarkerBorderSize: 0, endMarker: 0, endMarkerSize: 0, + endMarkerColor: null, + endMarkerBorderColor: null, + endMarkerBorderSize: 0, haloWidth: 0, haloColor: null, }; @@ -620,6 +626,55 @@ describe("edge marker + halo attribute mapping", () => { expect(attrs.endMarkerSize).toBe(10); }); + it("emits explicit arrow fill + border colors when markers are enabled", () => { + const attrs = edgeAttributesFromStyle( + { + startArrow: true, + startArrowColor: "#C33D35", + startArrowBorderColor: "#000000", + endArrow: true, + endArrowColor: "#8CA6D9", + }, + "line", + ); + + expect(attrs.startMarkerColor).toBe("#C33D35"); + expect(attrs.startMarkerBorderColor).toBe("#000000"); + expect(attrs.endMarkerColor).toBe("#8CA6D9"); + // Border left unset -> null (no border) even with the marker enabled. + expect(attrs.endMarkerBorderColor).toBe(null); + }); + + it("maps an explicit arrow border size and zeroes it when the arrow is off", () => { + const on = edgeAttributesFromStyle({ startArrow: true, startArrowBorderSize: 6 }, "line"); + expect(on.startMarkerBorderSize).toBe(6); + + // Off arrow or non-positive size -> 0 (auto / proportional). + const off = edgeAttributesFromStyle({ startArrow: false, startArrowBorderSize: 6 }, "line"); + expect(off.startMarkerBorderSize).toBe(0); + const zero = edgeAttributesFromStyle({ endArrow: true, endArrowBorderSize: -2 }, "line"); + expect(zero.endMarkerBorderSize).toBe(0); + }); + + it("inherits the edge color (null marker color) when no arrow color is set", () => { + const attrs = edgeAttributesFromStyle({ startArrow: true, endArrow: true }, "line"); + + expect(attrs.startMarkerColor).toBe(null); + expect(attrs.endMarkerColor).toBe(null); + expect(attrs.startMarkerBorderColor).toBe(null); + expect(attrs.endMarkerBorderColor).toBe(null); + }); + + it("nulls arrow colors when the arrow flag is off (overwrites stale style)", () => { + const attrs = edgeAttributesFromStyle( + { startArrow: false, startArrowColor: "#C33D35", startArrowBorderColor: "#000000" }, + "line", + ); + + expect(attrs.startMarkerColor).toBe(null); + expect(attrs.startMarkerBorderColor).toBe(null); + }); + it("disabled arrow flag zeroes the marker even when a type string is set", () => { const attrs = edgeAttributesFromStyle( { startArrow: false, startArrowType: "diamond", endArrow: true, endArrowType: "diamond" }, From cdc7db7d93062c5d43c4d72a8c13b0e24b748bfd Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 14:32:59 +0200 Subject: [PATCH 25/69] perf(renderer): remove automatic hover-effect disabling on large graphs The node/edge-count cutoff that auto-disabled hover highlighting was a G6-era guard; sigma renders hover fast enough that it is no longer needed. Hover is now controlled solely by the manual toggle button. - config: drop MAX_NODES/EDGES_BEFORE_DISABLING_HOVER_EFFECT (keep the flag) - io: stop deriving DISABLE_HOVER_EFFECT from graph size in preProcessData - tests: drop the assertion on the removed constant --- src/config.js | 5 ++--- src/managers/io.js | 5 ----- tests/config.test.js | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/config.js b/src/config.js index 4dd49d8..fca2a6b 100644 --- a/src/config.js +++ b/src/config.js @@ -233,9 +233,8 @@ const CFG = { MAX_NODES_BEFORE_HIDING_LABELS: 1000, HIDE_LABELS: false, -// if network is greater than defined threshold, hover effects are disabled - MAX_NODES_BEFORE_DISABLING_HOVER_EFFECT: 200, - MAX_EDGES_BEFORE_DISABLING_HOVER_EFFECT: 500, +// Hover highlight effect. Controlled only by the manual toggle button (sigma +// renders hover fast enough that no automatic node/edge-count cutoff is needed). DISABLE_HOVER_EFFECT: false, // if network is greater than defined threshold, bubble groups may span across non-bubble group members. diff --git a/src/managers/io.js b/src/managers/io.js index d3dfa4d..93338b8 100644 --- a/src/managers/io.js +++ b/src/managers/io.js @@ -1205,11 +1205,6 @@ class IOManager { this.cache.CFG.HIDE_LABELS = fileData.nodes.length > this.cache.CFG.MAX_NODES_BEFORE_HIDING_LABELS; - this.cache.CFG.DISABLE_HOVER_EFFECT = - fileData.nodes.length > - this.cache.CFG.MAX_NODES_BEFORE_DISABLING_HOVER_EFFECT || - fileData.edges.length > - this.cache.CFG.MAX_EDGES_BEFORE_DISABLING_HOVER_EFFECT; this.cache.CFG.AVOID_MEMBERS_IN_BUBBLE_GROUPS = fileData.nodes.length > this.cache.CFG.MAX_NODES_BEFORE_DISABLING_AVOID_MEMBERS_IN_BUBBLE_GROUPS; diff --git a/tests/config.test.js b/tests/config.test.js index 07898da..d37dfaf 100644 --- a/tests/config.test.js +++ b/tests/config.test.js @@ -193,7 +193,6 @@ describe('DEFAULTS.BUBBLE_GROUP_STYLE', () => { describe('CFG', () => { it('has expected threshold settings', () => { expect(CFG.MAX_NODES_BEFORE_HIDING_LABELS).toBeGreaterThan(0) - expect(CFG.MAX_NODES_BEFORE_DISABLING_HOVER_EFFECT).toBeGreaterThan(0) expect(CFG.MAX_NODES_BEFORE_DISABLING_AVOID_MEMBERS_IN_BUBBLE_GROUPS).toBeGreaterThan(0) }) From 8a8f1a3419530676c83e618eea548471e8f60939 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 14:33:07 +0200 Subject: [PATCH 26/69] fix(ui): widen styling panel to 420px to fit arrow controls on one line The new arrow color/border controls (palette swatches + picker + hex input) wrapped to two lines at 360px. 420px keeps every row on a single line. The panel is a flexbox sibling, so the graph overlays (minimap, selection frame) and the tour popup follow the new width automatically. --- src/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/style.css b/src/style.css index 5bf71e2..a02a84e 100644 --- a/src/style.css +++ b/src/style.css @@ -126,8 +126,8 @@ body, html { } #rightSidebar.active { - min-width: 360px; - width: 360px; + min-width: 420px; + width: 420px; border-left: 1px solid var(--border); } From 4eec8bf300ae4a950f26945e2ada3b9a424fd06a Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 14:47:35 +0200 Subject: [PATCH 27/69] perf(metrics): compute network metrics lazily only while panel is open Network metric calculations (betweenness, eigenvector, etc.) ran on every filter change, even when the metrics panel was closed and nobody was viewing them. Gate computation on panel visibility instead: - updateMetricUI() early-returns while the panel is collapsed - toggleUI() triggers a compute when the panel opens - invalidateMetricValues() blanks stale per-node tooltip metric text on every visibility change, skipping the tooltip scan when no metric text is active (metricTooltipsActive flag) - fix collapsed init (false -> true) to match the default-closed CSS Tooltips now show either the current correct value (panel open) or nothing (panel closed) -- never a stale value. Metric-driven styling is unchanged (already a snapshot taken at apply-time). --- src/managers/metrics.js | 34 ++++++++++++- tests/metrics-gate.test.js | 102 ++++++++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 3 deletions(-) diff --git a/src/managers/metrics.js b/src/managers/metrics.js index 09839d7..a9e069d 100644 --- a/src/managers/metrics.js +++ b/src/managers/metrics.js @@ -51,9 +51,16 @@ class NetworkMetrics { this.multiselect = null; this.table = null; this.m = metrics; - this.collapsed = false; + // Panel starts visually closed (CSS .nw-root is max-height:0). Metrics are + // computed lazily — only while the panel is open — so this gate must start + // true to match the DOM and avoid an eager compute on first load. + this.collapsed = true; this.cache = cache; this.metricValueCache = new Map(); + // Tracks whether any node tooltip currently carries metric text, so + // invalidation can blank stale values without parsing every tooltip when + // metrics were never shown. + this.metricTooltipsActive = false; this.selectBtns = { 'Add to Selection': async () => this.updateSelectedNodes(true), @@ -85,9 +92,24 @@ class NetworkMetrics { } this.collapsed = !willOpen; + + // Compute on open: the panel and tooltips are only refreshed while visible, + // so opening is the trigger that fills (or refreshes) the selected metric. + if (willOpen) { + this.updateMetricUI().catch(err => + this.cache.ui.error(`Failed to update metrics: ${err.message}`) + ); + } } async updateMetricUI() { + // Lazy compute: skip the expensive graph algorithms while the panel is + // closed. Stale tooltip values can't linger because invalidateMetricValues + // blanks them on every visibility change; reopening the panel recomputes + // via toggleUI. This stops betweenness/eigenvector from running on every + // filter drag when nobody is looking at metrics. + if (this.collapsed) return; + // Recompute when visibility changed OR the selected metric was never // computed. Under sigma a fresh load produces no visibility diff (elements // start visible), so gating on the flag alone would block metrics forever. @@ -102,6 +124,7 @@ class NetworkMetrics { // never leaves the loading overlay stuck on screen. try { this.resetNodeToolTipMetricTexts(); + this.metricTooltipsActive = false; const metricResult = await this.m[this.selected]?.calculate(this.cache); this.storeMetricValues(this.selected, metricResult); @@ -118,6 +141,7 @@ class NetworkMetrics { this.updateNodeToolTipMetricText(ns.id, metricName, ns.text); this.multiselect.appendChild(opt); } + this.metricTooltipsActive = metricResult.scores.length > 0; /* graph-level table */ this.table.innerHTML = ''; @@ -152,6 +176,14 @@ class NetworkMetrics { invalidateMetricValues() { this.metricValueCache.clear(); + // Blank per-node tooltip metric text so a value computed for the previous + // subgraph is never shown after filtering. Cheap string work, and skipped + // entirely when no tooltip carries metric text (the common closed-panel + // case). Reopening the panel recomputes and repopulates. + if (this.metricTooltipsActive) { + this.resetNodeToolTipMetricTexts(); + this.metricTooltipsActive = false; + } } async ensureMetricValues(metricId) { diff --git a/tests/metrics-gate.test.js b/tests/metrics-gate.test.js index cc4c5ac..b53a5df 100644 --- a/tests/metrics-gate.test.js +++ b/tests/metrics-gate.test.js @@ -32,10 +32,18 @@ function makeCache({ visibleElementsChanged = false } = {}) { } } -// Helper: NetworkMetrics wired to a live DOM (multiselect, table, info button) -function makeMetrics(cache) { +// Helper: NetworkMetrics wired to a live DOM (multiselect, table, info button). +// Metrics now compute lazily — only while the panel is open — so the +// cache/visibility gating tests open the panel explicitly. Lazy-gate tests +// pass { open: false } to assert the closed-panel no-op. +function makeMetrics(cache, { open = true } = {}) { const metrics = new NetworkMetrics(cache) document.body.appendChild(metrics.buildMetricUI()) + // The toggle button toggleUI() reaches for; absent it would throw. + const btn = document.createElement('button') + btn.id = 'metricsToggleBtn' + document.body.appendChild(btn) + if (open) metrics.collapsed = false return metrics } @@ -111,3 +119,93 @@ describe('NetworkMetrics.updateMetricUI gating', () => { expect(metrics.multiselect.options.length).toBe(3) }) }) + +describe('NetworkMetrics lazy panel gate', () => { + it('does not compute while the panel is closed', async () => { + // Arrange: panel closed (default real-world state) + const cache = makeCache({ visibleElementsChanged: true }) + const metrics = makeMetrics(cache, { open: false }) + expect(metrics.collapsed).toBe(true) + + // Act + await metrics.updateMetricUI() + + // Assert: no compute, no loading UI, no cached values + expect(cache.ui.showLoading).not.toHaveBeenCalled() + expect(metrics.metricValueCache.size).toBe(0) + expect(metrics.multiselect.options.length).toBe(0) + }) + + it('triggers a compute and flips collapsed when the panel is opened', () => { + // Arrange + const cache = makeCache() + const metrics = makeMetrics(cache, { open: false }) + const spy = vi.spyOn(metrics, 'updateMetricUI').mockResolvedValue(undefined) + + // Act + metrics.toggleUI() + + // Assert + expect(metrics.collapsed).toBe(false) + expect(spy).toHaveBeenCalledTimes(1) + }) + + it('does not compute when the panel is collapsed via toggleUI', () => { + // Arrange: start open so the first toggle closes it + const cache = makeCache() + const metrics = makeMetrics(cache, { open: true }) + document.getElementById('networkMetricsContainer').classList.add('open') + const spy = vi.spyOn(metrics, 'updateMetricUI').mockResolvedValue(undefined) + + // Act: toggle → closes + metrics.toggleUI() + + // Assert + expect(metrics.collapsed).toBe(true) + expect(spy).not.toHaveBeenCalled() + }) +}) + +describe('NetworkMetrics.invalidateMetricValues tooltip blanking', () => { + const TOOLTIP_WITH_METRIC = + '
    ' + + 'Degree Centrality' + + '

    Degree 2

    ' + + function metricContentOf(tooltipHtml) { + const div = document.createElement('div') + div.innerHTML = tooltipHtml + return div.querySelector('.tooltip-metric-content')?.textContent + } + + it('blanks stale tooltip metric text when metrics were displayed', () => { + // Arrange + const cache = makeCache() + cache.toolTips = new Map([['A', TOOLTIP_WITH_METRIC]]) + const metrics = makeMetrics(cache) + metrics.metricValueCache.set('centrality', { values: new Map([['A', 2]]) }) + metrics.metricTooltipsActive = true + + // Act + metrics.invalidateMetricValues() + + // Assert: cache cleared, tooltip metric text blanked, flag reset + expect(metrics.metricValueCache.size).toBe(0) + expect(metricContentOf(cache.toolTips.get('A'))).toBe('') + expect(metrics.metricTooltipsActive).toBe(false) + }) + + it('leaves tooltips untouched when no metric text is active', () => { + // Arrange: metrics never shown → nothing to blank + const cache = makeCache() + cache.toolTips = new Map([['A', TOOLTIP_WITH_METRIC]]) + const metrics = makeMetrics(cache) + metrics.metricTooltipsActive = false + + // Act + metrics.invalidateMetricValues() + + // Assert: tooltip preserved verbatim + expect(cache.toolTips.get('A')).toBe(TOOLTIP_WITH_METRIC) + }) +}) From 0dfe2abb4314c46170b3a61bcbbdb26ca05c32a2 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 15:28:41 +0200 Subject: [PATCH 28/69] fix(bubbles): use integer outline sample stride so zoom never crashes bubblesets-js sample(step) treats step as an array index stride, and PointPath.get() returns undefined for a fractional index. The outline sampler passed OUTLINE_SAMPLE_PX * scale directly, so any zoom whose 1/sqrt(ratio) field factor made 8*scale fractional (e.g. 2.83) poisoned the sampled path with undefined points and crashed bSplines()/simplify(). The throw escaped the bubble layer's rAF paint, freezing the bubble canvas: zoom appeared to ignore the camera and snapped back only at the original zoom, re-detecting communities or modifying a zoomed graph drew nothing. Ratio 1 (integer stride 8) is why it always worked first. - Round the stride to an integer >= 1 (Math.round). - Guard the bubblesets-js call so a degenerate outline returns [] per the function's documented contract instead of throwing into the renderer. - Add a faithful BubbleSetLayer harness reproducing the zoom/clear/re-add paths and a fractional-step geometry regression. --- src/graph/bubble_geometry.js | 33 +++-- tests/bubble-geometry.test.js | 18 +++ tests/bubble-layer-repro.test.js | 211 +++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 8 deletions(-) create mode 100644 tests/bubble-layer-repro.test.js diff --git a/src/graph/bubble_geometry.js b/src/graph/bubble_geometry.js index fde2758..da2cdc4 100644 --- a/src/graph/bubble_geometry.js +++ b/src/graph/bubble_geometry.js @@ -10,12 +10,18 @@ import { bubblesets } from "../lib/graphology.bundle.mjs"; // PointPath post-processing per the bubblesets-js README: sample the raw -// marching-squares outline, B-spline it and drop collinear points. 8 px -// sampling is the library's own example default and keeps point counts in -// the low hundreds. Scaled with opts.scale (an 8 px step would flatten a -// zoomed-out outline whose features are ~2 px) but never below 1 px. -const OUTLINE_SAMPLE_PX = 8; -const OUTLINE_SAMPLE_MIN_PX = 1; +// marching-squares outline, B-spline it and drop collinear points. 8 is the +// library's own example default and keeps point counts in the low hundreds. +// Scaled with opts.scale (a step of 8 would flatten a zoomed-out outline +// whose features are ~2 points) but never below 1. +// +// NOTE: bubblesets-js sample(step) treats `step` as an array INDEX stride +// (points.get(i += step)), NOT a pixel distance. PointPath.get() does +// `this.points[step]`, so a FRACTIONAL stride indexes between elements and +// returns undefined, which then crashes bSplines()/simplify() with +// "Cannot read properties of undefined". The stride must stay an integer. +const OUTLINE_SAMPLE_STEP = 8; +const OUTLINE_SAMPLE_MIN_STEP = 1; // bubblesets-js influence-field defaults (the library's own pixel-tuned // constants). They are absolute pixel radii, so the caller must scale them @@ -72,8 +78,19 @@ function computeOutlinePoints(memberRects, avoidRects = [], opts = {}) { morphBuffer: FIELD_MORPH_BUFFER * s, pixelGroup: Math.max(FIELD_PIXEL_GROUP_MIN, FIELD_PIXEL_GROUP * s), }); - const samplePx = Math.max(OUTLINE_SAMPLE_MIN_PX, OUTLINE_SAMPLE_PX * s); - const sampled = path.sample(samplePx).simplify(0).bSplines().simplify(0); + // Integer stride only (see OUTLINE_SAMPLE_STEP note): Math.round keeps the + // ~8-point cadence proportional to zoom without ever passing a fractional + // index into bubblesets-js' PointPath.get(). + const sampleStep = Math.max(OUTLINE_SAMPLE_MIN_STEP, Math.round(OUTLINE_SAMPLE_STEP * s)); + let sampled; + try { + sampled = path.sample(sampleStep).simplify(0).bSplines().simplify(0); + } catch { + // Boundary guard for bubblesets-js: a degenerate/collapsed outline must + // resolve to "no outline" (this function's documented contract) rather + // than throwing into the render loop and freezing the bubble canvas. + return []; + } const points = []; for (let i = 0; i < sampled.length; i++) { const p = sampled.get(i); diff --git a/tests/bubble-geometry.test.js b/tests/bubble-geometry.test.js index f941bb4..e2d0aba 100644 --- a/tests/bubble-geometry.test.js +++ b/tests/bubble-geometry.test.js @@ -84,6 +84,24 @@ describe("computeOutlinePoints", () => { expect(pointInPolygon({ x: 150 * s, y: 100 * s }, outline)).toBe(false); }); + // Regression: bubblesets-js sample(step) uses `step` as an array index + // stride, so a fractional OUTLINE_SAMPLE_STEP * scale used to index between + // points and return undefined, crashing bSplines()/simplify() with + // "Cannot read properties of undefined". These scales are the real zoom + // field factors (1/sqrt(camera.ratio)) that produce fractional 8*scale + // strides (e.g. 8*0.354 = 2.83) — the exact ones that froze the bubble + // canvas on zoom. They must produce a valid outline, never throw. + it.each([0.354, 0.2, 0.7, 1.58, 2.3, 5])( + "does not throw and returns a hull at fractional-step scale %f", + (s) => { + const members = [rectAt(0, 0, 20 * s), rectAt(20 * s, 0, 20 * s), rectAt(10 * s, 20 * s, 20 * s)]; + let outline; + expect(() => { outline = computeOutlinePoints(members, [], { scale: s }); }).not.toThrow(); + expect(outline.length).toBeGreaterThan(3); + expect(outline.every((p) => Number.isFinite(p.x) && Number.isFinite(p.y))).toBe(true); + }, + ); + it("keeps a dense zoomed-out group intact where unscaled constants lose it", () => { // Zoomed-out screen geometry: two 1 px members 6 px apart inside two // rings of 32 avoid nodes (the dense-graph repro for the vanishing diff --git a/tests/bubble-layer-repro.test.js b/tests/bubble-layer-repro.test.js new file mode 100644 index 0000000..2c882cd --- /dev/null +++ b/tests/bubble-layer-repro.test.js @@ -0,0 +1,211 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { BubbleSetLayer } from "../src/graph/bubble_layer.js"; + +// ========================================================================== +// Reproduction harness for reported bubble-set clustering bugs: +// (1-3) after Louvain detect, zoom in/out does not move the bubbles; they +// snap back only at the original zoom +// (5) clear all manual groups, then re-detect -> nothing appears +// (6) on a modified graph the clustering tends not to show +// +// The bubblesets outline math is real (bubble_geometry.js). Only sigma + the +// 2d canvas are faked, with a FAITHFUL camera-aware coordinate model so the +// graph<->viewport round-trip behaves like the real renderer. +// ========================================================================== + +const K = 100; // graph->viewport scale at camera ratio 1 + +// --- faithful camera-aware coordinate model (exact inverses, y-flipped) ---- +function makeSigma(camera, dims) { + const handlers = new Map(); + const ctxOps = []; + const filledPaths = []; + const strokedPaths = []; + + const ctx = { + setTransform: () => {}, + clearRect: () => ctxOps.push(["clear"]), + save: () => {}, + restore: () => {}, + beginPath: () => {}, + roundRect: () => {}, + measureText: () => ({ width: 10 }), + fillText: () => {}, + translate: () => {}, + rotate: () => {}, + fill: (path) => { if (path) filledPaths.push(path.points.slice()); }, + stroke: (path) => { if (path) strokedPaths.push(path.points.slice()); }, + set fillStyle(_v) {}, get fillStyle() { return "#000"; }, + set strokeStyle(_v) {}, get strokeStyle() { return "#000"; }, + set lineWidth(_v) {}, get lineWidth() { return 1; }, + set globalAlpha(_v) {}, get globalAlpha() { return 1; }, + set font(_v) {}, get font() { return ""; }, + set textAlign(_v) {}, get textAlign() { return "center"; }, + set textBaseline(_v) {}, get textBaseline() { return "middle"; }, + }; + const canvas = { + width: 0, height: 0, + getContext: () => ctx, + remove: () => {}, + }; + + const sigma = { + pixelRatio: 1, + createCanvasContext: () => sigma, + getCanvases: () => ({ bubbleSets: canvas }), + getDimensions: () => ({ width: dims.width, height: dims.height }), + getCamera: () => ({ getState: () => ({ ...camera }) }), + graphToViewport: (g) => ({ + x: dims.width / 2 + (g.x - camera.x) / camera.ratio * K, + y: dims.height / 2 - (g.y - camera.y) / camera.ratio * K, + }), + viewportToGraph: (v) => ({ + x: camera.x + (v.x - dims.width / 2) * camera.ratio / K, + y: camera.y - (v.y - dims.height / 2) * camera.ratio / K, + }), + scaleSize: (s, ratio = camera.ratio) => s / Math.sqrt(ratio), + on: (ev, fn) => handlers.set(ev, fn), + off: () => {}, + emit: (ev) => handlers.get(ev)?.(), + }; + return { sigma, canvas, ctx, filledPaths, strokedPaths }; +} + +function makeGraph(nodes) { + const map = new Map(nodes.map((n) => [n.id, { size: 20, hidden: false, ...n }])); + return { + hasNode: (id) => map.has(id), + getNodeAttributes: (id) => map.get(id), + _map: map, + }; +} + +function makeCache() { + return { + DEFAULTS: { + BUBBLE_GROUP_STYLE: { + groupOne: { fill: "#e74c3c", stroke: "#e74c3c", fillOpacity: 0.25, strokeOpacity: 1, label: false }, + }, + }, + }; +} + +// Path2D stub that records its points so the test can inspect the drawn hull. +class FakePath2D { + constructor() { this.points = []; } + moveTo(x, y) { this.points.push({ x, y }); } + lineTo(x, y) { this.points.push({ x, y }); } + closePath() {} +} + +let rafQueue = []; +beforeEach(() => { + rafQueue = []; + globalThis.Path2D = FakePath2D; + globalThis.requestAnimationFrame = (cb) => { rafQueue.push(cb); return rafQueue.length; }; + globalThis.cancelAnimationFrame = () => {}; + if (!globalThis.window) globalThis.window = {}; + globalThis.window.devicePixelRatio = 1; +}); + +function flushRaf() { + // Drain the queue (a paint may schedule nothing further here). + const q = rafQueue; rafQueue = []; + q.forEach((cb) => cb()); +} + +// Triangle of three nodes around graph origin -> a real, non-empty hull. +const TRI = [ + { id: "a", x: 0, y: 0 }, + { id: "b", x: 2, y: 0 }, + { id: "c", x: 1, y: 2 }, +]; + +const STYLE = { fill: "#e74c3c", stroke: "#e74c3c", fillOpacity: 0.25, strokeOpacity: 1, label: false }; + +describe("BubbleSetLayer — zoom reprojection (symptoms 1-3)", () => { + it("reprojects the cached hull when the camera ratio changes", () => { + const camera = { x: 1, y: 1, ratio: 1, angle: 0 }; + const { sigma, filledPaths } = makeSigma(camera, { width: 800, height: 600 }); + const layer = new BubbleSetLayer({ sigma, graph: makeGraph(TRI) }, makeCache()); + + layer.getGroupHandle("groupOne").update({ members: ["a", "b", "c"], ...STYLE }); + flushRaf(); + + const cached = layer.outlines.get("groupOne"); + expect(cached, "outline should exist after members set").toBeTruthy(); + expect(cached.graphPoints.length).toBeGreaterThan(2); + expect(filledPaths.length, "a hull should be filled at ratio 1").toBeGreaterThan(0); + + const pointsAt1 = filledPaths.at(-1); + const centroid = (pts) => pts.reduce((a, p) => ({ x: a.x + p.x / pts.length, y: a.y + p.y / pts.length }), { x: 0, y: 0 }); + const c1 = centroid(pointsAt1); + + // Zoom in: ratio 1 -> 0.4. afterRender drives the repaint, as in the app. + // Before the fix this threw inside computeOutlinePoints (fractional sample + // step), the exception escaped the rAF paint and the canvas froze. + camera.ratio = 0.4; + sigma.emit("afterRender"); + flushRaf(); + + const pointsAt04 = filledPaths.at(-1); + + // The hull must grow away from the viewport center as we zoom in (a frozen + // canvas would leave the points unchanged) ... + const c04 = centroid(pointsAt04); + const spread = (pts, c) => Math.max(...pts.map((p) => Math.hypot(p.x - c.x, p.y - c.y))); + expect(spread(pointsAt04, c04)).toBeGreaterThan(spread(pointsAt1, c1) * 1.5); + + // ... and the drawn points must equal the CURRENT cached graph points + // reprojected at the new camera (the outline is re-fitted on a ratio-bucket + // crossing, so re-read the cache rather than the pre-zoom snapshot). + const expected = layer.outlines.get("groupOne").graphPoints.map((g) => sigma.graphToViewport(g)); + expect(pointsAt04.length).toBe(expected.length); + pointsAt04.forEach((p, i) => { + expect(p.x).toBeCloseTo(expected[i].x, 5); + expect(p.y).toBeCloseTo(expected[i].y, 5); + }); + }); +}); + +describe("BubbleSetLayer — re-add after clearing (symptom 5)", () => { + it("re-draws a hull when members are set, cleared, then set again", () => { + const camera = { x: 1, y: 1, ratio: 1, angle: 0 }; + const { sigma, filledPaths } = makeSigma(camera, { width: 800, height: 600 }); + const layer = new BubbleSetLayer({ sigma, graph: makeGraph(TRI) }, makeCache()); + const handle = layer.getGroupHandle("groupOne"); + + handle.update({ members: ["a", "b", "c"], ...STYLE }); + flushRaf(); + expect(layer.outlines.has("groupOne")).toBe(true); + const drawnFirst = filledPaths.length; + expect(drawnFirst).toBeGreaterThan(0); + + // Clear (mirrors clearAllManualGroups -> updateBubbleSet(group, [])). + handle.update({ members: [], fillOpacity: 0, strokeOpacity: 0, label: false }); + flushRaf(); + expect(layer.outlines.has("groupOne"), "outline gone after clear").toBe(false); + + // Re-detect (mirrors detectCommunities -> updateBubbleSet(group, members)). + handle.update({ members: ["a", "b", "c"], ...STYLE }); + flushRaf(); + expect(layer.outlines.has("groupOne"), "outline should come back after re-add").toBe(true); + expect(layer.outlines.get("groupOne").graphPoints.length).toBeGreaterThan(2); + expect(filledPaths.length, "a hull must be filled again after re-add").toBeGreaterThan(drawnFirst); + }); +}); + +describe("BubbleSetLayer — modified graph (symptom 6)", () => { + it("draws a hull at a deep zoom-out level (small influence fields)", () => { + const camera = { x: 1, y: 1, ratio: 8, angle: 0 }; + const { sigma, filledPaths } = makeSigma(camera, { width: 800, height: 600 }); + const layer = new BubbleSetLayer({ sigma, graph: makeGraph(TRI) }, makeCache()); + + layer.getGroupHandle("groupOne").update({ members: ["a", "b", "c"], ...STYLE }); + flushRaf(); + + expect(layer.outlines.get("groupOne")?.graphPoints.length ?? 0, + "hull should still be computed when zoomed far out").toBeGreaterThan(2); + expect(filledPaths.length).toBeGreaterThan(0); + }); +}); From 95a0fc582738880238141723cbc4880e688b2b32 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 15:38:55 +0200 Subject: [PATCH 29/69] fix(ui): use continuous step for float filter sliders so column max stays selectable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fixed absolute slider step (1e-6) floored the reachable max below a column's true max, so the node holding the maximum value (e.g. ADCY1 in the AOP208 column) was excluded from BETWEEN filters and bubble-set assignment — selectable only via the query editor. - Float columns now use step="any" (continuous): the exact max and any high-decimal value are reachable via both slider and number box, at any column magnitude. - Integer columns keep step=1 (discrete counts). - Drop the now-unused FILTER_STEP_SIZE_FLOAT constant. - Tests updated; add constructor-wiring tests asserting integer->1 and float->"any" with the full-precision AOP208 max preserved. --- src/config.js | 7 ++-- src/managers/ui_components.js | 9 +++-- tests/config.test.js | 5 ++- tests/filter-step-size.test.js | 61 ++++++++++++++++++++++++---------- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/config.js b/src/config.js index fca2a6b..9dec359 100644 --- a/src/config.js +++ b/src/config.js @@ -208,12 +208,11 @@ const CFG = { // Determines if filter sliders should be hidden when the minimum and maximum values are identical HIDE_SLIDERS_WITH_SAME_MIN_MAX_VALUES: true, -// Specifies the slider step size for integer-based properties +// Specifies the slider step size for integer-based properties. +// Float-based properties use a continuous slider (step="any"), so they have no +// configurable step — see InvertibleRangeSlider. FILTER_STEP_SIZE_INTEGER: 1, -// Specifies the slider step size for float-based properties - FILTER_STEP_SIZE_FLOAT: 0.000001, - // Specifies the slider thumb- and tooltip-values (only visually); internally, the full float precision is used FILTER_VISUAL_FLOAT_PRECISION: 3, diff --git a/src/managers/ui_components.js b/src/managers/ui_components.js index 7395426..ae9077d 100644 --- a/src/managers/ui_components.js +++ b/src/managers/ui_components.js @@ -237,9 +237,12 @@ class InvertibleRangeSlider { this.sliderMin = defaultFilterData.lowerThreshold; this.sliderMax = defaultFilterData.upperThreshold; const allInteger = StaticUtilities.isInteger(this.sliderMin) && StaticUtilities.isInteger(this.sliderMax) && !defaultFilterData.hasFloatValues; - this.stepSize = allInteger - ? this.cache.CFG.FILTER_STEP_SIZE_INTEGER - : this.cache.CFG.FILTER_STEP_SIZE_FLOAT; + // Integer columns step by whole units (discrete counts). Float columns use + // "any" — a continuous control with no value grid, so the column max (and + // any high-decimal value) stays exactly selectable via both the slider and + // the number box, at any column magnitude. A fixed absolute step floored + // the reachable max below the true max and broke selection of the top node. + this.stepSize = allInteger ? this.cache.CFG.FILTER_STEP_SIZE_INTEGER : "any"; this.initializeIds(); this.inputStart = null; this.inputEnd = null; diff --git a/tests/config.test.js b/tests/config.test.js index d37dfaf..8d666ee 100644 --- a/tests/config.test.js +++ b/tests/config.test.js @@ -200,10 +200,9 @@ describe('CFG', () => { expect(CFG.MAX_SELECTION_MEMORY).toBeGreaterThan(0) }) - it('has valid filter step sizes', () => { + it('has a valid integer filter step size (floats use a continuous step="any")', () => { expect(CFG.FILTER_STEP_SIZE_INTEGER).toBe(1) - expect(CFG.FILTER_STEP_SIZE_FLOAT).toBeGreaterThan(0) - expect(CFG.FILTER_STEP_SIZE_FLOAT).toBeLessThan(1) + expect(CFG.FILTER_STEP_SIZE_FLOAT).toBeUndefined() }) it('has required Excel header strings', () => { diff --git a/tests/filter-step-size.test.js b/tests/filter-step-size.test.js index 93bb2f2..c2e34c9 100644 --- a/tests/filter-step-size.test.js +++ b/tests/filter-step-size.test.js @@ -1,5 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest' import { IOManager } from '../src/managers/io.js' +import { InvertibleRangeSlider } from '../src/managers/ui_components.js' import { StaticUtilities } from '../src/utilities/static.js' import { CFG, DEFAULTS } from '../src/config.js' @@ -139,12 +140,13 @@ describe('populateFilterPropsLowsAndHighs — hasFloatValues flag', () => { }) describe('InvertibleRangeSlider step-size determination', () => { - // Mirrors the logic in the InvertibleRangeSlider constructor without needing DOM + // Mirrors the logic in the InvertibleRangeSlider constructor without needing DOM. + // Integer columns step by whole units; float columns use a continuous "any". function computeStepSize(filterDefault) { const sliderMin = filterDefault.lowerThreshold const sliderMax = filterDefault.upperThreshold const allInteger = StaticUtilities.isInteger(sliderMin) && StaticUtilities.isInteger(sliderMax) && !filterDefault.hasFloatValues - return allInteger ? CFG.FILTER_STEP_SIZE_INTEGER : CFG.FILTER_STEP_SIZE_FLOAT + return allInteger ? CFG.FILTER_STEP_SIZE_INTEGER : 'any' } it('uses integer step when all values are integers (min=0, max=10)', () => { @@ -152,19 +154,19 @@ describe('InvertibleRangeSlider step-size determination', () => { expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_INTEGER) }) - it('uses float step when intermediate floats exist between integer min/max', () => { + it('uses continuous step when intermediate floats exist between integer min/max', () => { const fd = { lowerThreshold: 0, upperThreshold: 1, hasFloatValues: true } - expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_FLOAT) + expect(computeStepSize(fd)).toBe('any') }) - it('uses float step when min is a float', () => { + it('uses continuous step when min is a float', () => { const fd = { lowerThreshold: 0.5, upperThreshold: 10, hasFloatValues: true } - expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_FLOAT) + expect(computeStepSize(fd)).toBe('any') }) - it('uses float step when max is a float', () => { + it('uses continuous step when max is a float', () => { const fd = { lowerThreshold: 0, upperThreshold: 10.5, hasFloatValues: true } - expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_FLOAT) + expect(computeStepSize(fd)).toBe('any') }) it('uses integer step for large integer range', () => { @@ -172,9 +174,9 @@ describe('InvertibleRangeSlider step-size determination', () => { expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_INTEGER) }) - it('uses float step when hasFloatValues is true even with same min/max', () => { + it('uses continuous step when hasFloatValues is true even with same min/max', () => { const fd = { lowerThreshold: 5, upperThreshold: 5, hasFloatValues: true } - expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_FLOAT) + expect(computeStepSize(fd)).toBe('any') }) it('uses integer step when hasFloatValues is undefined (backwards compat)', () => { @@ -182,15 +184,40 @@ describe('InvertibleRangeSlider step-size determination', () => { // undefined is falsy, so !undefined === true → treated as all-integer expect(computeStepSize(fd)).toBe(CFG.FILTER_STEP_SIZE_INTEGER) }) +}) + +describe('InvertibleRangeSlider — stepSize wiring (no DOM needed)', () => { + function makeCache(propID, filterDefault) { + return { + CFG, + DEFAULTS, + data: { + filterDefaults: new Map([[propID, { categories: new Set(), isInverted: false, ...filterDefault }]]), + layouts: { L: { filters: new Map() } }, + selectedLayout: 'L' + }, + propIDToInvertibleRangeSliders: new Map() + } + } - it('reproduces the original bug: min=0, max=1, no hasFloatValues flag', () => { - // Without the fix, this would yield integer step (the bug) - const fdBuggy = { lowerThreshold: 0, upperThreshold: 1, hasFloatValues: false } - expect(computeStepSize(fdBuggy)).toBe(CFG.FILTER_STEP_SIZE_INTEGER) + it('integer column → numeric step of 1', () => { + const propID = 'Node filters::Counts::drugs' + const slider = new InvertibleRangeSlider(propID, makeCache(propID, { lowerThreshold: 0, upperThreshold: 5, hasFloatValues: false })) + expect(slider.stepSize).toBe(1) + }) + + it('float column → continuous "any" so the exact column max stays selectable', () => { + // The reported AOP208 / ADCY1 case: full-precision float max. + const propID = 'Node filters::Interference Off Label::AOP208' + const slider = new InvertibleRangeSlider(propID, makeCache(propID, { lowerThreshold: 0, upperThreshold: 0.00339857993386777, hasFloatValues: true })) + expect(slider.stepSize).toBe('any') + expect(slider.sliderMax).toBe(0.00339857993386777) + }) - // With the fix, hasFloatValues=true yields float step - const fdFixed = { lowerThreshold: 0, upperThreshold: 1, hasFloatValues: true } - expect(computeStepSize(fdFixed)).toBe(CFG.FILTER_STEP_SIZE_FLOAT) + it('float column with integer-looking bounds still uses "any" (hasFloatValues wins)', () => { + const propID = 'Node filters::Evidence::score' + const slider = new InvertibleRangeSlider(propID, makeCache(propID, { lowerThreshold: 0, upperThreshold: 1, hasFloatValues: true })) + expect(slider.stepSize).toBe('any') }) }) From 59e52f7e43a3d3422122bce2863480d60e160650 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Thu, 11 Jun 2026 15:50:52 +0200 Subject: [PATCH 30/69] feat(bubbles): weighted + resolution-tunable Louvain community detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 🧩 button now opens a configurator instead of running immediately: pick a numeric edge property to weight by (or topology-only) and the Louvain resolution, then detect. Weighting lets community structure that is invisible to pure topology (e.g. STRING confidence scores) drive the grouping; resolution tunes community granularity. - communities.js: detectCommunities(cache, groups, {weightProperty, resolution}) -> getEdgeWeight + resolution. Fixed seed kept, so results stay reproducible. - visible_graph.js: optional {weightProperty} attaches a numeric weight per edge from edge.featureValues (fallback 1 for missing/non-finite). The metrics callers pass no options and are unchanged. - bubble_sets.js: enumerate numeric edge props from filterDefaults, build the popover, default to Combined Score when present (else topology), report weight + resolution + modularity. - Tests: weighting recovers structure invisible to topology, equal weights match unweighted, missing-value fallback, resolution raises community count, omitted resolution defaults to 1. --- src/graph/bubble_sets.js | 172 ++++++++++++++++++++++++++++++++++++- src/graph/communities.js | 16 +++- src/graph/visible_graph.js | 24 +++++- src/graph_lens_lite.html | 4 +- src/style.css | 49 +++++++++++ tests/communities.test.js | 73 +++++++++++++++- 6 files changed, 324 insertions(+), 14 deletions(-) diff --git a/src/graph/bubble_sets.js b/src/graph/bubble_sets.js index 6ea5d4c..9ad38af 100644 --- a/src/graph/bubble_sets.js +++ b/src/graph/bubble_sets.js @@ -4,6 +4,11 @@ import {detectCommunities as computeCommunityAssignments} from "./communities.js class GraphBubbleSetManager { constructor(cache) { this.cache = cache; + // Louvain detection prefs (transient UI state, not persisted/exported). + // weightProperty: undefined until first resolved (then a numeric edge + // prop hash, or null for topology-only); resolution: Louvain γ. + this.communityOptions = { weightProperty: undefined, resolution: 1 }; + this.communityPopover = null; this.redrawBubbleSets = debounce(async () => { if (!this.cache.EVENT_LOCKS.ONCE_AFTER_RENDER_COMPLETED) return; if (this.cache.EVENT_LOCKS.BUBBLE_GROUP_REDRAW_RUNNING) return; @@ -324,9 +329,41 @@ class GraphBubbleSetManager { await this.redrawBubbleSets(); } - async detectCommunities() { + /** + * Enumerate numeric edge properties available as Louvain edge weights. + * Source of truth is cache.data.filterDefaults (the same registry the + * filter UI uses): edge section, not categorical, finite min/max. + * @returns {Array<{propHash: string, prop: string, label: string}>} + */ + getNumericEdgeProperties() { + const props = []; + const filterDefaults = this.cache.data?.filterDefaults; + if (!filterDefaults) return props; + for (const [propHash, def] of filterDefaults) { + const [section, subSection, prop] = StaticUtilities.decodePropHashId(propHash); + if (section !== this.cache.CFG.EXCEL_EDGE_HEADER) continue; + if (def.isCategory) continue; + if (!Number.isFinite(def.lowerThreshold) || !Number.isFinite(def.upperThreshold)) continue; + props.push({ propHash, prop, label: subSection ? `${subSection} › ${prop}` : prop }); + } + return props; + } + + // Default weight: STRING's "Combined Score" when present, else topology-only + // (null) so generic graphs keep the original unweighted behaviour. + #defaultWeightProperty(numericProps) { + const combined = numericProps.find((p) => /combined\s*score/i.test(p.prop)); + return combined ? combined.propHash : null; + } + + async detectCommunities(options = {}) { + const weightProperty = options.weightProperty !== undefined + ? options.weightProperty + : (this.communityOptions.weightProperty ?? null); + const resolution = options.resolution ?? this.communityOptions.resolution ?? 1; + const groups = [...this.traverseBubbleSets()]; - const result = computeCommunityAssignments(this.cache, groups); + const result = computeCommunityAssignments(this.cache, groups, { weightProperty, resolution }); if (!result) { this.cache.ui.warning("Community detection needs at least one visible edge"); @@ -353,12 +390,141 @@ class GraphBubbleSetManager { const assignedText = result.communityCount <= groups.length ? `all ${result.communityCount}` : `largest ${groups.length}`; + const weightLabel = weightProperty + ? (this.getNumericEdgeProperties().find((p) => p.propHash === weightProperty)?.label ?? "edge weight") + : "topology"; this.cache.ui.info( - `Detected ${result.communityCount} communities (modularity ${result.modularity.toFixed(2)}); ` + + `Detected ${result.communityCount} communities ` + + `(weight: ${weightLabel}, resolution ${resolution}, modularity ${result.modularity.toFixed(2)}); ` + `assigned ${assignedText} to bubble groups` ); } + /** + * Toggle the Louvain configurator anchored to the 🧩 button: pick a numeric + * edge property to weight by (or topology-only) and the resolution, then run + * detection. Built lazily and repopulated on each open so it reflects the + * currently loaded data. + */ + toggleCommunityDetectionPopover() { + if (this.communityPopover && this.communityPopover.classList.contains("open")) { + this.#closeCommunityDetectionPopover(); + return; + } + this.#openCommunityDetectionPopover(); + } + + #closeCommunityDetectionPopover() { + this.communityPopover?.classList.remove("open"); + if (this._communityOutsideHandler) { + document.removeEventListener("pointerdown", this._communityOutsideHandler, true); + this._communityOutsideHandler = null; + } + } + + #openCommunityDetectionPopover() { + const anchor = document.getElementById("detectCommunitiesBtn"); + if (!anchor) return; + + const numericProps = this.getNumericEdgeProperties(); + // Resolve the default weight on first open, and re-default whenever the + // stored property is gone (data was reloaded) so the dropdown selection + // and the stored option never drift out of sync. + const stored = this.communityOptions.weightProperty; + const storedExists = stored === null || numericProps.some((p) => p.propHash === stored); + if (stored === undefined || !storedExists) { + this.communityOptions.weightProperty = this.#defaultWeightProperty(numericProps); + } + + const popover = this.#ensureCommunityDetectionPopover(); + this.#populateCommunityDetectionPopover(numericProps); + + // Anchor below the button, clamped to the viewport's right edge. + const rect = anchor.getBoundingClientRect(); + popover.style.top = `${rect.bottom + 6}px`; + popover.style.left = `${Math.min(rect.left, window.innerWidth - 260)}px`; + popover.classList.add("open"); + + // Close on outside click (capture so it beats inner handlers). + this._communityOutsideHandler = (e) => { + if (!popover.contains(e.target) && e.target !== anchor) this.#closeCommunityDetectionPopover(); + }; + document.addEventListener("pointerdown", this._communityOutsideHandler, true); + } + + #ensureCommunityDetectionPopover() { + if (this.communityPopover) return this.communityPopover; + const popover = document.createElement("div"); + popover.className = "community-detection-popover"; + popover.id = "communityDetectionPopover"; + document.body.appendChild(popover); + this.communityPopover = popover; + return popover; + } + + #populateCommunityDetectionPopover(numericProps) { + const popover = this.communityPopover; + popover.replaceChildren(); + + const title = document.createElement("div"); + title.className = "community-popover-title"; + title.textContent = "Detect communities (Louvain)"; + popover.appendChild(title); + + // Weight dropdown ------------------------------------------------------ + const weightLabel = document.createElement("label"); + weightLabel.className = "community-popover-row"; + weightLabel.textContent = "Weight by"; + const weightSelect = document.createElement("select"); + weightSelect.className = "community-popover-select"; + const topoOpt = document.createElement("option"); + topoOpt.value = ""; + topoOpt.textContent = "Unweighted (topology)"; + weightSelect.appendChild(topoOpt); + for (const p of numericProps) { + const opt = document.createElement("option"); + opt.value = p.propHash; + opt.textContent = p.label; + weightSelect.appendChild(opt); + } + weightSelect.value = this.communityOptions.weightProperty ?? ""; + weightSelect.addEventListener("change", (e) => { + this.communityOptions.weightProperty = e.target.value || null; + }); + weightLabel.appendChild(weightSelect); + popover.appendChild(weightLabel); + + // Resolution slider ---------------------------------------------------- + const resRow = document.createElement("label"); + resRow.className = "community-popover-row"; + const resText = document.createElement("span"); + const setResText = (v) => { resText.textContent = `Resolution: ${Number(v).toFixed(2)}`; }; + setResText(this.communityOptions.resolution); + const resSlider = document.createElement("input"); + resSlider.type = "range"; + resSlider.min = "0.25"; + resSlider.max = "4"; + resSlider.step = "0.05"; + resSlider.value = String(this.communityOptions.resolution); + resSlider.className = "community-popover-slider"; + resSlider.addEventListener("input", (e) => { + this.communityOptions.resolution = parseFloat(e.target.value); + setResText(e.target.value); + }); + resRow.append(resText, resSlider); + popover.appendChild(resRow); + + // Detect button -------------------------------------------------------- + const detectBtn = document.createElement("button"); + detectBtn.className = "community-popover-detect nw-button"; + detectBtn.textContent = "Detect"; + detectBtn.addEventListener("click", async () => { + this.#closeCommunityDetectionPopover(); + await this.detectCommunities(); + }); + popover.appendChild(detectBtn); + } + updateManualGroupButtonState() { const button = document.getElementById('manualBubbleGroupButton'); if (!button) return; diff --git a/src/graph/communities.js b/src/graph/communities.js index d6481b3..c86bc3b 100644 --- a/src/graph/communities.js +++ b/src/graph/communities.js @@ -27,16 +27,26 @@ function mulberry32(seed) { * * @param {{nodeIDsToBeShown: Set, edgeIDsToBeShown: Set, edgeRef: Map}} cache * @param {string[]} groups bubble-group keys in assignment order + * @param {{weightProperty?: string|null, resolution?: number}} [options] + * weightProperty: numeric edge property hash to weight edges by (null = + * topology only, the default). resolution: Louvain resolution γ (>1 yields + * more, smaller communities; <1 fewer, larger; default 1). * @returns {{assignments: Map>, communityCount: number, modularity: number} | null} * null when the visible graph has no edges (Louvain needs at least one). */ -function detectCommunities(cache, groups) { - const graph = buildVisibleGraph(cache); +function detectCommunities(cache, groups, options = {}) { + const weightProperty = options.weightProperty ?? null; + const resolution = options.resolution ?? 1; + + const graph = buildVisibleGraph(cache, {weightProperty}); if (graph.size === 0) return null; const result = louvain.detailed(graph, { rng: mulberry32(LOUVAIN_RNG_SEED), - getEdgeWeight: null, + // String attribute name when weighting (buildVisibleGraph sets `weight`); + // null keeps every edge at weight 1 (topology-only, the original behaviour). + getEdgeWeight: weightProperty !== null ? "weight" : null, + resolution, }); // Group node ids by community index, preserving the community index for a diff --git a/src/graph/visible_graph.js b/src/graph/visible_graph.js index 1070e92..598939c 100644 --- a/src/graph/visible_graph.js +++ b/src/graph/visible_graph.js @@ -7,17 +7,33 @@ import {Graph} from "../lib/graphology.bundle.mjs"; * subgraph so graphology algorithms can run on it. Multi because every * visible parallel edge counts toward degree, matching the previous * behaviour. - * @param {{nodeIDsToBeShown: Set, edgeIDsToBeShown: Set, edgeRef: Map}} cache + * + * @param {{nodeIDsToBeShown: Set, edgeIDsToBeShown: Set, edgeRef: Map}>}} cache + * @param {{weightProperty?: string|null}} [options] + * weightProperty: when set, each edge gets a numeric `weight` attribute read + * from edge.featureValues.get(weightProperty) so weighted algorithms + * (Louvain) can use it. A missing/non-finite value falls back to 1 (the + * edge still participates, just unweighted). Omit for the topology-only + * graph the centrality metrics rely on — that path is left untouched. * @returns {Graph} */ -function buildVisibleGraph(cache) { +function buildVisibleGraph(cache, options = {}) { const {nodeIDsToBeShown: nodes, edgeIDsToBeShown: edges, edgeRef} = cache; + const weightProperty = options.weightProperty ?? null; const graph = new Graph({type: 'undirected', multi: true}); for (const id of nodes) graph.addNode(id); for (const edgeId of edges) { - const {source, target} = edgeRef.get(edgeId) ?? {}; - if (graph.hasNode(source) && graph.hasNode(target)) { + const edge = edgeRef.get(edgeId); + if (!edge) continue; + const {source, target} = edge; + if (!graph.hasNode(source) || !graph.hasNode(target)) continue; + + if (weightProperty !== null) { + const raw = edge.featureValues?.get(weightProperty); + const weight = typeof raw === 'number' && Number.isFinite(raw) ? raw : 1; + graph.addEdgeWithKey(edgeId, source, target, {weight}); + } else { graph.addEdgeWithKey(edgeId, source, target); } } diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index 174491b..bdd829f 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -141,8 +141,8 @@
    Shown: - +
    Selected edges:
    -
    - - - - - - - -
    + +
    +
    + + + + + + + +
    Shown:

    -
    - -
    +
    - Selected nodes: - - - - -
    - Selected edges: - - -
    -
    -
    - -
    - - -
    - - - - - +
    + Selection + +
    + +
    +
    + + + + + +
    + +
    +
    Nothing selected
    +
    Click an element, drag a lasso (L), or open Tools to select by name or neighbours. A query can also select by property.
    +
    + +
    +
    + 0 nodes + + + + 0 edges + + +
    + +
    + + Add to group: + + + +
    +
    + +
    + + + +
    +
    @@ -178,6 +202,7 @@
    Shown: onclick="cache.ui.toggleStylingPanel()">×
    +
    Nothing selected — select nodes or edges to style them. Bubble-group styling below works without a selection.
    diff --git a/src/managers/ui.js b/src/managers/ui.js index e39dcb4..2245069 100644 --- a/src/managers/ui.js +++ b/src/managers/ui.js @@ -370,15 +370,6 @@ class UIManager { }); } - async toggleEditMode() { - const editBtn = document.getElementById("editBtn"); - if (!editBtn) return; - let editModeActive = editBtn.classList.contains("active"); - editModeActive ? editBtn.classList.remove("active") : editBtn.classList.add("active"); - - this.handleEditModeUIChanges(); - } - toggleStylingPanel() { const rightSidebar = document.getElementById("rightSidebar"); const styleBtn = document.getElementById("styleToggleBtn"); @@ -403,8 +394,10 @@ class UIManager { if (!container || !panel || !toggleBtn) return; const isExpanded = container.classList.toggle("expanded"); - toggleBtn.textContent = isExpanded ? "▴" : "▾"; - toggleBtn.title = isExpanded ? "Collapse selection editor" : "Expand selection editor"; + toggleBtn.textContent = isExpanded ? "Tools ▴" : "Tools ▾"; + toggleBtn.title = isExpanded + ? "Hide selection tools" + : "Show selection tools: select by name, neighbours, or arrange the selection"; toggleBtn.setAttribute("aria-expanded", isExpanded ? "true" : "false"); } @@ -480,50 +473,6 @@ class UIManager { } } - handleEditModeUIChanges() { - const editBtn = document.getElementById("editBtn"); - if (!editBtn) return; - const editModeActive = editBtn.classList.contains("active"); - - editModeActive ? editBtn.classList.add("highlight") : editBtn.classList.remove("highlight"); - - // handle all edit elements - const editElements = document.querySelectorAll('.show-on-edit, .show-on-edit-full-width'); - editElements.forEach(el => { - editModeActive ? el.classList.add("show") : el.classList.remove("show"); - el.style.height = editModeActive ? `${el.scrollHeight}px` : "0"; - }); - - const hideOnEditElements = document.querySelectorAll('.hide-on-edit'); - hideOnEditElements.forEach(el => { - el.style.display = editModeActive ? "none" : ""; - }); - - // 'collapse' all open style rows - if (!editModeActive) { - const styleRows = document.querySelectorAll('.style-row'); - styleRows.forEach(row => { - row.classList.remove("show"); - }); - } - - // handle filter row layouts - const filterRows = document.querySelectorAll('.filter-row'); - filterRows.forEach(row => { - const sliderCol = row.querySelector(".filter-row-col2"); - const hasRangeSlider = sliderCol.querySelector(".hide-on-edit"); - if (hasRangeSlider) { - sliderCol.style.display = editModeActive ? "flex" : ""; - sliderCol.style.alignItems = editModeActive ? "center" : ""; - sliderCol.style.gap = editModeActive ? "4px" : ""; - } else { - sliderCol.style.display = ""; - sliderCol.style.alignItems = ""; - sliderCol.style.gap = ""; - } - }); - } - buildUI() { this.cache.query.text = document.getElementById("queryTextArea"); this.cache.query.overlay = document.getElementById("queryOverlay"); @@ -565,14 +514,8 @@ class UIManager { buildFilterUI() { const div = document.getElementById("filterContainer"); - const editBtn = document.getElementById("editBtn"); div.innerHTML = ""; - // Re-append editBtn if it exists - if (editBtn) { - div.appendChild(editBtn); - } - // Always create lock status bar, show/hide based on lock state const statusBar = this.createFilterLockStatusBar(); statusBar.id = 'filterLockStatusBar'; @@ -654,7 +597,6 @@ class UIManager { } this.manageDynamicWidgets(); - this.handleEditModeUIChanges(); this.cache.qm.updateQueryTextArea(); } @@ -756,10 +698,10 @@ class UIManager { statusBar.innerHTML = `
    🔒 - Filters locked | Query manually edited + Filters are driven by your edited query. Unlock to control them here again.
    `; return statusBar; diff --git a/src/managers/ui_components.js b/src/managers/ui_components.js index ae9077d..5296160 100644 --- a/src/managers/ui_components.js +++ b/src/managers/ui_components.js @@ -308,8 +308,7 @@ class InvertibleRangeSlider { createSliderInput(id, initialValue, relatedSliderId) { const input = document.createElement("input"); input.id = id; - input.style.width = '80px'; - input.style.height = '16px'; + input.style.height = '18px'; input.style.boxSizing = 'border-box'; input.value = initialValue; input.addEventListener('keydown', (ev) => { @@ -349,29 +348,26 @@ class InvertibleRangeSlider { } this.isValidSlider = true; - const colLeft = document.createElement('div'); - colLeft.classList.add('show-on-edit'); - colLeft.style.transition = 'width 0.2s ease'; - this.inputStart = this.createSliderInput(this.sliderIdStartInput, this.currentMin, this.sliderIdStart); - colLeft.appendChild(this.inputStart); - - const colRight = document.createElement('div'); - colRight.classList.add('show-on-edit'); - colRight.style.transition = 'width 0.2s ease'; - this.inputEnd = this.createSliderInput(this.sliderIdEndInput, this.currentMax, this.sliderIdEnd); - colRight.appendChild(this.inputEnd); - const div = document.createElement("div"); div.innerHTML = this.createDivInnerHTML(); const slider = div.firstElementChild; - slider.classList.add('hide-on-edit'); slider.style.width = '100%'; slider.title = `Set the thresholds for the numeric property: ${StaticUtilities.formatPropsAsTree(this.propID)}\n---\n - Move handles to set min/max (≥ min ∧ ≤ max).\n - Swap handles to invert (≤ min ∨ ≥ max).\n - Double-click to reset.`; - parent.appendChild(div); - parent.appendChild(colLeft); + // Min/max number boxes are always visible directly under the slider, so + // exact thresholds can be typed without a hidden "edit mode". They stay in + // sync with the handles via handleThresholdOnInputEvent (writes their values). + const inputRow = document.createElement('div'); + inputRow.className = 'filter-input-row'; + this.inputStart = this.createSliderInput(this.sliderIdStartInput, this.currentMin, this.sliderIdStart); + this.inputStart.title = "Lower threshold — type an exact value and press Enter"; + this.inputEnd = this.createSliderInput(this.sliderIdEndInput, this.currentMax, this.sliderIdEnd); + this.inputEnd.title = "Upper threshold — type an exact value and press Enter"; + inputRow.appendChild(this.inputStart); + inputRow.appendChild(this.inputEnd); + parent.appendChild(slider); - parent.appendChild(colRight); + parent.appendChild(inputRow); } createDivInnerHTML() { diff --git a/src/managers/ui_style_div.js b/src/managers/ui_style_div.js index c5a86e9..ada63ed 100644 --- a/src/managers/ui_style_div.js +++ b/src/managers/ui_style_div.js @@ -320,7 +320,7 @@ function createStyleDiv(cache) { const scaleButton = document.createElement("button"); scaleButton.className = "style-inner-button style-numeric-scale-button"; scaleButton.textContent = "∿"; - scaleButton.title = `Scale ${property} based on a property's values`; + scaleButton.title = `Map by data: scale ${property} from a numeric property's values (e.g. larger nodes for higher degree)`; scaleButton.style.marginLeft = "2px"; scaleButton.dataset.property = property; scaleButton.onclick = async () => { @@ -409,7 +409,7 @@ function createStyleDiv(cache) { if (continuousScaleBtn) { const contScaleBtn = document.createElement("button"); contScaleBtn.className = "style-inner-button style-color-button style-color-gradient-button"; - contScaleBtn.title = `Set ${property} of the selected elements to a continuous scale.`; + contScaleBtn.title = `Map by data: colour ${property} on a continuous gradient from a property's values`; contScaleBtn.onclick = async () => { colorInput.value = ""; await handleStyleChangeEvent(property, "set_continuous_color_scale"); @@ -1207,6 +1207,38 @@ function createStyleDiv(cache) { } } + // Turn a config card into a collapsible section: replace the floating + // `::before` title with a real clickable header (so the panel reads as a + // set of foldable sections instead of one tall wall of controls). + function makeCollapsible(label, startCollapsed = false) { + const card = root.querySelector(`[data-label="${label}"]`); + if (!card) return; + card.classList.add("card-collapsible"); + + const header = document.createElement("button"); + header.type = "button"; + header.className = "card-collapse-header"; + header.setAttribute("aria-expanded", startCollapsed ? "false" : "true"); + + const title = document.createElement("span"); + title.className = "card-collapse-title"; + title.textContent = label; + + const chevron = document.createElement("span"); + chevron.className = "card-collapse-chevron"; + chevron.textContent = startCollapsed ? "▸" : "▾"; + + header.append(title, chevron); + header.addEventListener("click", () => { + const collapsed = card.classList.toggle("collapsed"); + chevron.textContent = collapsed ? "▸" : "▾"; + header.setAttribute("aria-expanded", collapsed ? "false" : "true"); + }); + + card.insertBefore(header, card.firstChild); + if (startCollapsed) card.classList.add("collapsed"); + } + createFocusCard(); createSelectCard(); createArrangeNodesCard(); @@ -1214,6 +1246,12 @@ function createStyleDiv(cache) { createEdgeConfigCard(); createBubbleSetConfigCard(); + // Node stays open (most common); Edge is the largest section so it starts + // folded; bubble styling only matters once groups exist, so fold it too. + makeCollapsible("Node Configuration"); + makeCollapsible("Edge Configuration", true); + makeCollapsible("Bubble Sets", true); + return root; } diff --git a/src/style.css b/src/style.css index a01177a..43126b1 100644 --- a/src/style.css +++ b/src/style.css @@ -397,18 +397,25 @@ body, html { cursor: pointer; } +/************************* + Selection HUD (on-graph) + **************************/ #selectedElementsContainer { position: absolute !important; top: 10px !important; - right: 10px !important; + left: 10px !important; + right: auto !important; bottom: auto !important; - left: auto !important; + width: 256px; + box-sizing: border-box; border: 1px solid var(--brand-border); - border-radius: 5px; - background-color: var(--surface); - transition: opacity 0.1s ease-in-out, right 0.3s ease-in-out, width 0.25s ease-in-out, max-width 0.25s ease-in-out, box-shadow 0.25s ease-in-out; - text-align: center; - padding: 2px; + border-radius: 8px; + background-color: var(--surface-translucent); + backdrop-filter: blur(6px); + box-shadow: 0 4px 14px rgba(64, 60, 83, 0.14); + transition: width 0.2s ease-in-out, box-shadow 0.2s ease-in-out, opacity 0.1s ease-in-out; + text-align: left; + padding: 8px 10px; font-size: 13px; z-index: 1000; max-width: calc(100% - 20px); @@ -423,11 +430,223 @@ body, html { #selectedElementsContainer.expanded { width: 360px; - box-shadow: 0 6px 12px rgba(64, 60, 83, 0.2); + box-shadow: 0 8px 20px rgba(64, 60, 83, 0.22); +} + +/* --- HUD header: title + tools toggle --- */ +.sel-hud-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.sel-hud-title { + font-weight: 700; + color: var(--brand-text); + letter-spacing: 0.02em; +} + +.sel-hud-tools-toggle { + font: inherit; + font-size: 12px; + color: var(--text-strong); + background: var(--surface-3); + border: 1px solid var(--border-soft); + border-radius: 6px; + padding: 2px 8px; + cursor: pointer; + white-space: nowrap; + transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease; +} + +.sel-hud-tools-toggle:hover { + border-color: var(--accent-text); + color: var(--accent-text); +} + +#selectedElementsContainer.expanded .sel-hud-tools-toggle { + background: var(--accent-text); + color: #fff; + border-color: var(--accent-text); +} + +/* --- shared HUD buttons --- */ +.sel-hud-btn { + font: inherit; + font-size: 12px; + color: var(--text-strong); + background: var(--input-bg); + border: 1px solid var(--border-soft); + border-radius: 6px; + padding: 3px 9px; + cursor: pointer; + white-space: nowrap; + display: inline-flex; + align-items: center; + gap: 4px; + transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease; +} + +.sel-hud-btn:hover { + border-color: var(--accent-text); + color: var(--accent-text); +} + +.sel-hud-icon-btn { + font: inherit; + font-size: 13px; + line-height: 1; + color: var(--text-strong); + background: var(--input-bg); + border: 1px solid var(--border-soft); + border-radius: 6px; + width: 22px; + height: 22px; + padding: 0; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease; +} + +.sel-hud-icon-btn:hover { + border-color: var(--accent-text); + color: var(--accent-text); +} + +.sel-hud-icon-btn.red:hover { + border-color: var(--accent-text); + color: var(--accent-text); +} + +/* --- toolbar row: lasso / style / undo / redo (always visible) --- */ +.sel-hud-toolbar { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + margin-top: 8px; +} + +.sel-hud-toolbar-spacer { + flex: 1 1 auto; +} + +#lassoWrapper { + display: inline-flex; + border-radius: 6px; +} + +#lassoWrapper.active { + box-shadow: 0 0 0 2px var(--accent-text); +} + +#lassoWrapper.active .sel-hud-btn { + border-color: var(--accent-text); + color: var(--accent-text); +} + +/* Inline lasso glyph reused by the guided tour (empty span + --size/--color). */ +.lasso-icon { + display: inline-block; + vertical-align: middle; +} + +.lasso-icon::before { + content: "➰"; + font-size: var(--size, 14px); + line-height: 1; +} + +/* --- empty state (no selection) --- */ +.sel-hud-empty { + margin-top: 8px; +} + +#selectedElementsContainer.has-selection .sel-hud-empty { + display: none; +} + +.sel-hud-empty-title { + font-weight: 600; + color: var(--text-muted); + margin-bottom: 3px; +} + +.sel-hud-empty-hint { + font-size: 12px; + line-height: 1.45; + color: var(--text-faint); +} + +.sel-hud-empty-hint strong { + color: var(--text-strong); +} + +/* --- active state (has selection) --- */ +.sel-hud-active { + display: none; + margin-top: 8px; +} + +#selectedElementsContainer.has-selection .sel-hud-active { + display: block; +} + +.sel-hud-counts { + display: flex; + align-items: center; + gap: 4px; + flex-wrap: wrap; } +.sel-count { + font-size: 13px; + color: var(--text); +} + +.sel-count strong { + font-size: 14px; +} + +.sel-count-sep { + width: 1px; + height: 16px; + background: var(--border-soft); + margin: 0 4px; +} + +.sel-hud-actions { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 6px; + margin-top: 8px; +} + +.sel-group-control { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.sel-group-label { + font-size: 12px; + color: var(--text-muted); +} + +.sel-hud-groups { + display: flex; + align-items: center; + gap: 5px; + margin-top: 6px; + min-height: 0; +} + +/* --- expandable tools panel (Focus / Select / Arrange cards) --- */ .selection-editor-panel { - width: 0; max-height: 0; opacity: 0; overflow: hidden; @@ -436,11 +655,12 @@ body, html { } #selectedElementsContainer.expanded .selection-editor-panel { - width: 100%; max-height: 420px; opacity: 1; - margin-top: 6px; + margin-top: 8px; overflow-y: auto; + border-top: 1px solid var(--border-soft); + padding-top: 8px; } #selectedElementsContainer .selection-editor-panel .card-labeled { @@ -792,6 +1012,71 @@ h5 { margin-top: 4px; } +/* Styling-panel selection status: replaces silently-greyed cards with a + plain-language line about what is (or isn't) being styled. */ +.styling-status { + font-size: 12px; + line-height: 1.4; + padding: 8px 10px; + margin-bottom: 4px; + border-radius: 6px; + background: var(--surface-3); + color: var(--text-strong); + border-left: 3px solid var(--accent-text); +} + +.styling-status.empty { + color: var(--text-muted); + border-left-color: var(--border-soft); +} + +/* Collapsible config sections (Node / Edge / Bubble) so the panel reads as + foldable sections instead of one tall wall of controls. */ +.card-labeled.card-collapsible { + padding: 4px; + text-align: left; +} + +.card-labeled.card-collapsible::before { + display: none; +} + +.card-collapse-header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + box-sizing: border-box; + background: var(--brand-border); + color: #fff; + border: none; + border-radius: 4px; + padding: 4px 8px; + cursor: pointer; + font: inherit; + font-weight: bold; + font-size: 13px; +} + +.card-collapse-header:hover { + background: var(--accent-text); +} + +.card-collapse-chevron { + font-size: 11px; + opacity: 0.85; +} + +.card-labeled.collapsed > :not(.card-collapse-header) { + display: none; +} + +/* Allow folding/unfolding a section even while its controls are disabled + (nothing selected), so the contents stay readable. */ +.card-labeled.card-collapsible.disabled .card-collapse-header { + pointer-events: auto; +} + .bubble-set-config-card-header::before { font-size: 12px; } @@ -954,14 +1239,6 @@ h5 { margin-right: 6px; } -#filterContainer #editBtn { - position: absolute; - right: 0; - z-index: 10; - border: 1px solid var(--border-strong); - border-radius: 6px; -} - .filter-row { display: flex; align-items: center; @@ -975,10 +1252,24 @@ h5 { .filter-row-col2 { flex: 0 0 180px; - text-align: right; + display: flex; + flex-direction: column; + gap: 3px; margin-right: 10px; } +/* Always-visible min/max threshold inputs under the range slider. */ +.filter-input-row { + display: flex; + justify-content: space-between; + gap: 4px; +} + +.filter-input-row input { + flex: 1 1 0; + min-width: 0; +} + .filter-row-col3 { flex: 0 0 auto; display: flex; @@ -1043,6 +1334,7 @@ h5 { #filterContainer.locked .filter-row-col2, #filterContainer.locked .slider-container, #filterContainer.locked input[type="number"], +#filterContainer.locked .filter-input-row, #filterContainer.locked .range-slider-thumb, #filterContainer.locked .range-slider, #filterContainer.locked .header-card, @@ -1059,9 +1351,8 @@ h5 { cursor: not-allowed !important; } -/* Keep "Add to Query" buttons in edit mode active - full opacity and interactive */ -#filterContainer.locked button.purple, -#filterContainer.locked .show-on-edit button.purple { +/* Keep "Add to Query" buttons active - full opacity and interactive */ +#filterContainer.locked button.purple { opacity: 1 !important; pointer-events: auto !important; cursor: pointer !important; @@ -1517,6 +1808,49 @@ hr { gap: 1px; } +/* Labeled app action toolbar (replaces the row of bare-emoji header buttons). */ +.app-toolbar { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 4px; + margin-bottom: 8px; +} + +.toolbar-pill { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: var(--text-strong); + background: var(--surface-3); + border: 1px solid var(--border-soft); + border-radius: 6px; + padding: 3px 8px; + cursor: pointer; + white-space: nowrap; + transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease; +} + +.toolbar-pill:hover { + border-color: var(--accent-text); + color: var(--accent-text); +} + +.toolbar-pill.highlight, +.toolbar-pill.active { + background: var(--accent-text); + color: #fff; + border-color: var(--accent-text); +} + +.toolbar-sep { + width: 1px; + height: 18px; + background: var(--border-soft); + margin: 0 2px; +} + .button-separator { display: inline-block; width: 1px; @@ -1750,26 +2084,6 @@ input:checked + .checkbox-green::after { height: auto !important; } -.show-on-edit { - display: none; -} - -.show-on-edit.show { - display: inline-block; - width: auto; - height: auto; -} - -.show-on-edit-full-width { - display: none; -} - -.show-on-edit-full-width.show { - display: block; - width: 100%; - height: auto; -} - /************************* +/- (add/remove) from selection buttons **************************/ @@ -3020,44 +3334,6 @@ input:checked + .slider:before { color: #878996; } -/************************* - Lasso select icon - **************************/ -.medium-btn:has(> button.lasso-icon), -.small-btn:has(> button.lasso-icon) { - /*border-top: 0;*/ - /*border-bottom: 0;*/ - padding: 0; - display: inline-block; - vertical-align: top; - width: 16px; - height: 16px; - line-height: 16px; - text-align: center; -} -#lassoWrapper.active { - box-shadow: 0 0 5px #C33D35; - border-radius: 6px; -} -#lassoWrapper.medium-btn.active { - height: 22px; -} -#lassoWrapper.small-btn.active { - height: 16px; -} -.lasso-icon { - cursor: pointer; - width: 16px; - height: 16px; - font-size: 14px; - line-height: 16px; - background: none; - border: none; - padding: 0; - margin: 0 auto; - display: block; -} - /************************* Query editor **************************/ diff --git a/src/utilities/tour.js b/src/utilities/tour.js index cde636c..0101c8c 100644 --- a/src/utilities/tour.js +++ b/src/utilities/tour.js @@ -398,7 +398,6 @@ const TOUR_STEPS = [
    M — Toggle metrics panel
    Y — Toggle styling panel
    A — Toggle Graph Assistant -
    E — Toggle edit mode
    P — Export as PNG
    S — Save as JSON

    From a084dc17af2eca9f38865536238f1e3cd023bff9 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 10:00:50 +0200 Subject: [PATCH 32/69] feat(ui): high-res export, compact header, snap-grid selection HUD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export image: 📷 button opens a 1×/2×/4×/8× resolution popover (choice persisted, reused by the P shortcut). New export_scale.js clamps the factor under canvas limits so large viewports never crash the render; toDataURL now re-renders at scale and returns the applied factor, warning on a clamp. Header: move 📷 Image / 💾 Model out of the toolbar into an icon-only group beside the dark-mode toggle, freeing a toolbar row. Selection HUD: drag the header to snap the panel to a 3×3 grid; the bottom- right corner is reserved for the minimap and instead offers two slots flanking it (above / left of). A dashed skeleton frame previews the landing slot during the drag. New ✕ hide toggle with a floating restore pill. Grid cell + hidden state persist. Logic in selection_hud.js, wired in gll.js. --- src/gll.js | 2 + src/graph/sigma_adapter.js | 22 +++- src/graph_lens_lite.html | 23 ++-- src/managers/io.js | 47 ++++++- src/managers/ui.js | 76 ++++++++++++ src/style.css | 165 ++++++++++++++++++++++++- src/utilities/export_scale.js | 50 ++++++++ src/utilities/selection_hud.js | 216 +++++++++++++++++++++++++++++++++ tests/export-scale.test.js | 79 ++++++++++++ tests/selection-hud.test.js | 170 ++++++++++++++++++++++++++ 10 files changed, 828 insertions(+), 22 deletions(-) create mode 100644 src/utilities/export_scale.js create mode 100644 src/utilities/selection_hud.js create mode 100644 tests/export-scale.test.js create mode 100644 tests/selection-hud.test.js diff --git a/src/gll.js b/src/gll.js index 68f80e9..3ec60ed 100644 --- a/src/gll.js +++ b/src/gll.js @@ -24,6 +24,7 @@ import {StaticUtilities} from "./utilities/static.js"; import {generateTourData, GuidedTour} from "./utilities/tour.js"; import {initApiClient} from "./managers/api_client.js"; import {initTheme} from "./utilities/theme.js"; +import {initSelectionHud} from "./utilities/selection_hud.js"; // Stores all reference objects @@ -467,6 +468,7 @@ window.addEventListener("DOMContentLoaded", () => { initTheme(document, window); cache.reset(); cache.ui.updateDarkModeButton(); + initSelectionHud(); // cache.initialize(); // Display version info diff --git a/src/graph/sigma_adapter.js b/src/graph/sigma_adapter.js index 6bfdc84..aa97ecd 100644 --- a/src/graph/sigma_adapter.js +++ b/src/graph/sigma_adapter.js @@ -23,6 +23,7 @@ import { createCurveHaloProgram, createEdgeMarkerHeadProgram, } from "./edge_programs.js"; +import { clampExportScale } from "../utilities/export_scale.js"; import { nodeAttributesFromStyle, edgeAttributesFromStyle, flipY } from "./graph_model.js"; import { executeLayout } from "./layout_algorithms.js"; import { drawNodeLabel, drawEdgeLabel, BAKED_DEFAULT_LABEL_COLOR } from "./label_renderers.js"; @@ -698,9 +699,24 @@ class SigmaAdapter { * bubble-set canvas is composited UNDER it here (matching its on-screen * z-order; export-image's default transparent background lets it show * through). The minimap is a viewport control and stays out of exports. + * + * `scale` re-renders at a multiple of the viewport size for crisp high-res + * output (sigma redraws at the larger dimensions, so labels/nodes stay + * sharp). The factor is clamped to the canvas size limits. Returns the data + * URL plus the scale actually applied so callers can warn on a clamp. + * + * @param {{ scale?: number }} [opts] + * @returns {Promise<{ url: string, requestedScale: number, appliedScale: number }>} */ - async toDataURL() { - const blob = await exportImage.toBlob(this.sigma, { format: "png" }); + async toDataURL({ scale = 1 } = {}) { + const dims = this.sigma.getDimensions(); + const dpr = window.devicePixelRatio || 1; + const appliedScale = clampExportScale(scale, dims, dpr); + const blob = await exportImage.toBlob(this.sigma, { + format: "png", + width: dims.width * appliedScale, + height: dims.height * appliedScale, + }); const sigmaImage = await createImageBitmap(blob); try { const out = document.createElement("canvas"); @@ -716,7 +732,7 @@ class SigmaAdapter { ctx.drawImage(bubbleCanvas, 0, 0, out.width, out.height); } ctx.drawImage(sigmaImage, 0, 0); - return out.toDataURL("image/png"); + return { url: out.toDataURL("image/png"), requestedScale: scale, appliedScale }; } catch (error) { throw new Error(`Graph image export failed: ${error?.message ?? error}`); } finally { diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index 52aec7f..e1bdb7c 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -83,16 +83,17 @@

    - +
    + + + +
    - - -
    @@ -134,12 +135,15 @@
    Shown:
    -
    -
    +
    +
    Selection - + + + +
    @@ -193,6 +197,7 @@
    Shown:
    +
    -
    +
    ${StaticUtilities.formatNumber(this.currentMin, this.cache.CFG.FILTER_VISUAL_FLOAT_PRECISION)}
    -
    +
    ${StaticUtilities.formatNumber(this.currentMax, this.cache.CFG.FILTER_VISUAL_FLOAT_PRECISION)}
    @@ -399,6 +419,19 @@ class InvertibleRangeSlider { if (!this.isValidSlider) return; this.getDOMReferences(); + // Position the fixed value bubbles on hover; keep them pinned while the + // sidebar scrolls or the window resizes during the hover. + const reposition = () => this.positionSigns(); + this.slider.addEventListener('mouseenter', () => { + this.positionSigns(); + window.addEventListener('scroll', reposition, true); + window.addEventListener('resize', reposition); + }); + this.slider.addEventListener('mouseleave', () => { + window.removeEventListener('scroll', reposition, true); + window.removeEventListener('resize', reposition); + }); + this.slider.addEventListener('dblclick', () => { this.reset(); this.sliderEnd.dispatchEvent(new Event('change')); diff --git a/src/style.css b/src/style.css index 07394c5..f738146 100644 --- a/src/style.css +++ b/src/style.css @@ -1387,35 +1387,84 @@ h5 { margin-right: 6px; } +/* The sub-group body is a 3-column grid [label | control | actions]; each row + contributes its three cells via display:contents. This aligns every control + in a sub-group to the same x and gives them equal width (dropdowns, sliders, + and the slider's min/max inputs all line up). */ +.filter-subgroup-body { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + column-gap: 8px; + row-gap: 6px; + align-items: start; +} + .filter-row { - display: flex; - align-items: center; - margin-bottom: 4px; + display: contents; } .filter-row-col1 { - flex: 1 1 auto; + /* Label column: shared auto width across the sub-group. Nudged down to sit + level with the control's first line (slider / dropdown). */ min-width: 0; + padding-top: 2px; } .filter-row-col2 { - flex: 0 0 180px; + /* Control fills the 1fr column. In detail mode col3 reappears in the third + column and this one shrinks to make room. */ + min-width: 0; display: flex; flex-direction: column; gap: 3px; - margin-right: 10px; } -/* Always-visible min/max threshold inputs under the range slider. */ +/* Always-visible min/max threshold inputs under the range slider, styled as a + single paired control (lower – upper) instead of two bare full-width boxes. */ .filter-input-row { + position: relative; display: flex; - justify-content: space-between; - gap: 4px; + align-items: center; + gap: 14px; + margin-top: 2px; +} + +.filter-input-row::before { + content: "–"; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + color: var(--text-muted); + font-size: 11px; + pointer-events: none; } .filter-input-row input { flex: 1 1 0; min-width: 0; + height: 20px; + padding: 0 6px; + font-size: 11px; + border: 1px solid var(--border-soft); + border-radius: 4px; + background: var(--surface-3); + color: var(--text-strong); + box-sizing: border-box; +} + +.filter-input-row input:first-child { + text-align: left; +} + +.filter-input-row input:last-child { + text-align: right; +} + +.filter-input-row input:focus { + outline: none; + border-color: var(--accent-text); + box-shadow: 0 0 0 2px rgba(195, 61, 53, 0.25); } .filter-row-col3 { @@ -1424,6 +1473,85 @@ h5 { align-items: center; } +/* Panel-level "Details" toggle: compact-by-default keeps dense property sets + (30-50 properties) scannable; the exact value inputs and per-row group / + selection actions are revealed on demand. The toggle rides on the first + section header row, right-aligned. */ +.filter-section-headerrow { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 2px; +} + +.filter-details-toggle { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 2px 9px; + font-size: 11px; + font-weight: 600; + color: var(--text-strong); + background: var(--surface-3); + border: 1px solid var(--border-soft); + border-radius: 12px; + cursor: pointer; +} + +.filter-details-toggle:hover { + border-color: var(--accent-text); +} + +.filter-details-toggle.active { + background: var(--accent-text); + color: #fff; + border-color: var(--accent-text); +} + +/* Compact mode: numeric inputs and the circle / +- actions are hidden so the + control uses the full row width. Hiding col3 drops the grid to two columns + so the remaining cells stay aligned (a 3-col grid would pull the next row's + label into the empty third cell). The hover value bubbles overflow into the + canvas via position:fixed, so no right inset is needed. */ +#filterContainer:not(.show-details) .filter-subgroup-body { + grid-template-columns: auto minmax(0, 1fr); +} + +#filterContainer:not(.show-details) .filter-input-row, +#filterContainer:not(.show-details) .filter-row-col3 { + display: none; +} + +/* Collapsible filter sections and sub-groups (accordion). Properties within a + sub-group stay compact (grid row-gap); sub-groups get a bottom margin so + they read as distinct blocks. */ +.filter-section { + margin-bottom: 6px; +} + +.filter-subgroup { + margin-bottom: 12px; +} + +.collapsible-filter-header { + cursor: pointer; + user-select: none; +} + +.filter-group-chevron { + display: inline-block; + font-size: 9px; + margin-left: 4px; + margin-right: 1px; + opacity: 0.85; +} + +.filter-section.collapsed > .filter-section-body, +.filter-subgroup.collapsed > .filter-subgroup-body { + display: none; +} + /* Filter lock status bar */ .filter-lock-status-bar { background-color: #FFF3CD; @@ -2618,10 +2746,12 @@ div[slider] > input[type=range]::-ms-tooltip { [slider] > div > [sign] { opacity: 0; - position: absolute; - margin-left: -56px; /* controls horizontal position of left tooltip */ - top: -8px; - z-index: 3; + /* Fixed so the bubble escapes the sidebar's three overflow-clipping + ancestors and can extend into the canvas. JS (positionSigns) sets + top/left in viewport coordinates on hover. */ + position: fixed; + margin-left: 0; + z-index: 9999; background-color: #C33D35; border: 1px solid var(--brand-border); color: #E4E3EA; @@ -2638,12 +2768,10 @@ div[slider] > input[type=range]::-ms-tooltip { } [slider] > div > [sign].left { - position: absolute; white-space: nowrap; } [slider] > div > [sign].right { - position: absolute; white-space: nowrap; } diff --git a/tests/filter-details-toggle.test.js b/tests/filter-details-toggle.test.js new file mode 100644 index 0000000..a4b29ff --- /dev/null +++ b/tests/filter-details-toggle.test.js @@ -0,0 +1,110 @@ +// @vitest-environment jsdom +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { UIManager } from "../src/managers/ui.js"; + +// ========================================================================== +// Filter panel compact-by-default disclosure (Details toggle) + collapsible +// groups. These keep dense property sets (30-50 properties) scannable: exact +// numeric inputs and per-row group/selection actions hide behind one panel +// toggle, and each section/sub-group folds independently. +// ========================================================================== + +function makeUI() { + // Only debug() touches this.cache, and only on a storage error (not hit here). + return new UIManager({}, false); +} + +describe("UIManager.createFilterDetailsToggle", () => { + let ui, container; + + beforeEach(() => { + window.localStorage.clear(); + ui = makeUI(); + container = document.createElement("div"); + }); + + it("renders a labeled Details toggle button", () => { + const btn = ui.createFilterDetailsToggle(container); + + expect(btn).not.toBeNull(); + expect(btn.classList.contains("filter-details-toggle")).toBe(true); + expect(btn.textContent).toContain("Details"); + expect(btn.getAttribute("aria-pressed")).toBe("false"); + }); + + it("defaults to compact (no show-details) when nothing is stored", () => { + ui.createFilterDetailsToggle(container); + + expect(container.classList.contains("show-details")).toBe(false); + }); + + it("restores the on state from localStorage", () => { + window.localStorage.setItem("gll.filterDetails", "1"); + + const btn = ui.createFilterDetailsToggle(container); + + expect(container.classList.contains("show-details")).toBe(true); + expect(btn.classList.contains("active")).toBe(true); + expect(btn.getAttribute("aria-pressed")).toBe("true"); + }); + + it("toggles details on click and persists the choice", () => { + const btn = ui.createFilterDetailsToggle(container); + + btn.click(); + expect(container.classList.contains("show-details")).toBe(true); + expect(btn.classList.contains("active")).toBe(true); + expect(window.localStorage.getItem("gll.filterDetails")).toBe("1"); + + btn.click(); + expect(container.classList.contains("show-details")).toBe(false); + expect(btn.classList.contains("active")).toBe(false); + expect(window.localStorage.getItem("gll.filterDetails")).toBe("0"); + }); +}); + +describe("UIManager.makeFilterGroupCollapsible", () => { + let ui, wrapper, header, badge; + + beforeEach(() => { + ui = makeUI(); + wrapper = document.createElement("div"); + header = document.createElement("div"); + badge = document.createElement("button"); + badge.textContent = "✔"; + header.appendChild(badge); + wrapper.appendChild(header); + }); + + it("prepends an expanded chevron and marks the header clickable", () => { + ui.makeFilterGroupCollapsible(wrapper, header); + const chevron = header.querySelector(".filter-group-chevron"); + + expect(chevron).not.toBeNull(); + expect(chevron.textContent).toBe("▾"); + expect(header.classList.contains("collapsible-filter-header")).toBe(true); + // chevron is prepended before the existing action badge + expect(header.firstChild).toBe(chevron); + }); + + it("folds and unfolds the group when the header is clicked", () => { + ui.makeFilterGroupCollapsible(wrapper, header); + const chevron = header.querySelector(".filter-group-chevron"); + + chevron.dispatchEvent(new window.MouseEvent("click", { bubbles: true })); + expect(wrapper.classList.contains("collapsed")).toBe(true); + expect(chevron.textContent).toBe("▸"); + + chevron.dispatchEvent(new window.MouseEvent("click", { bubbles: true })); + expect(wrapper.classList.contains("collapsed")).toBe(false); + expect(chevron.textContent).toBe("▾"); + }); + + it("does not fold when an action badge in the header is clicked", () => { + ui.makeFilterGroupCollapsible(wrapper, header); + + badge.dispatchEvent(new window.MouseEvent("click", { bubbles: true })); + + expect(wrapper.classList.contains("collapsed")).toBe(false); + }); +}); From 79ee96d1142fc985407416e910df3ac478cc6bb0 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 13:21:45 +0200 Subject: [PATCH 34/69] feat(ui): rework selection grouping + selection-driven styling cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename '🧩 Detect' → '🧩 Auto' and move it from the selection-mode toolbar into a labeled 'Groups:' row beside the group badges, since Louvain runs on the whole graph (not the selection). - Per-group bubble clearing: each ●N badge is now a button with a hover ✕ that clears just that group; 'Clear all' relabeled from icon. - Styling cards expand to match the selection (additive, never auto- collapse): nodes open Node Config, edges open Edge Config, groups open Bubble Sets. - Styling status spacing: flush top, wider gap to the config stack. - Empty-state hint shortened; lasso/Tools/query editor are now clickable links that open their respective tools. - Add tests/selection-styling-ux.test.js (14 tests). --- src/graph/bubble_sets.js | 43 ++++++- src/graph/selection.js | 2 + src/graph_lens_lite.html | 13 +- src/managers/ui.js | 21 +++ src/style.css | 75 ++++++++++- tests/selection-styling-ux.test.js | 199 +++++++++++++++++++++++++++++ 6 files changed, 341 insertions(+), 12 deletions(-) create mode 100644 tests/selection-styling-ux.test.js diff --git a/src/graph/bubble_sets.js b/src/graph/bubble_sets.js index 9ad38af..27dfb6a 100644 --- a/src/graph/bubble_sets.js +++ b/src/graph/bubble_sets.js @@ -569,24 +569,57 @@ class GraphBubbleSetManager { if (visibleMembers.length > 0) { const color = this.cache.data.layouts[this.cache.data.selectedLayout].bubbleSetStyle[group].fill; - activeGroups.push(`●${visibleMembers.length}`); + activeGroups.push(this.buildManualGroupBadge(group, visibleMembers.length, color)); } } // Show/hide elements based on active groups if (activeGroups.length > 0) { - statusSpan.innerHTML = activeGroups.join(' '); - statusSpan.style.display = 'inline'; - if (clearButton) clearButton.style.display = 'inline'; + statusSpan.replaceChildren(...activeGroups); + statusSpan.style.display = 'inline-flex'; + if (clearButton) clearButton.style.display = 'inline-flex'; if (separator) separator.style.display = 'inline-block'; + // A group now exists worth styling — surface the Bubble Sets card. + this.cache.ui?.expandStylingCard?.('Bubble Sets'); } else { - statusSpan.innerHTML = ''; + statusSpan.replaceChildren(); statusSpan.style.display = 'none'; if (clearButton) clearButton.style.display = 'none'; if (separator) separator.style.display = 'none'; } } + // One clickable badge per active group: shows the colored ●count and clears + // just that group on click (✕ revealed on hover). Lets users drop a single + // group without nuking all of them via "Clear all". + buildManualGroupBadge(group, count, color) { + const badge = document.createElement('button'); + badge.type = 'button'; + badge.className = 'manual-group-badge'; + badge.style.color = color; + badge.title = `Clear this group (${count} node${count === 1 ? '' : 's'})`; + const dot = document.createElement('span'); + dot.textContent = `●${count}`; + const x = document.createElement('span'); + x.className = 'mg-badge-x'; + x.textContent = '✕'; + badge.append(dot, x); + badge.addEventListener('click', () => this.clearManualGroup(group)); + return badge; + } + + async clearManualGroup(group) { + const manualMembers = this.cache.data.layouts[this.cache.data.selectedLayout][`${group}ManualMembers`]; + if (manualMembers) manualMembers.clear(); + + this.updateManualGroupButtonState(); + this.updateManualGroupStatus(); + + this.cache.bubbleSetChanged = true; + await this.updateBubbleSetIfChanged(); + await this.cache.graph.draw(); + } + cleanupManualGroupMembers() { // Remove nodes from manual groups that are no longer visible (filtered out) for (let group of Object.keys(this.cache.DEFAULTS.BUBBLE_GROUP_STYLE)) { diff --git a/src/graph/selection.js b/src/graph/selection.js index 4e55920..fc51a5f 100644 --- a/src/graph/selection.js +++ b/src/graph/selection.js @@ -361,6 +361,8 @@ class GraphSelectionManager { if (selectedEdgesCount) parts.push(`${selectedEdgesCount} edge${selectedEdgesCount === 1 ? "" : "s"}`); stylingStatus.textContent = `Styling ${parts.join(" · ")}`; stylingStatus.classList.remove("empty"); + // Open the config card(s) matching the selection (additive). + this.cache.ui.syncStylingCardsToSelection(atLeastOneNodeSelected, atLeastOneEdgeSelected); } else { stylingStatus.textContent = "Nothing selected — select nodes or edges to style them. Bubble-group styling below works without a selection."; stylingStatus.classList.add("empty"); diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index e1bdb7c..1c28873 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -9,7 +9,7 @@ type="image/svg+xml"> - +
    @@ -149,8 +149,6 @@
    Shown:
    - @@ -160,7 +158,7 @@
    Shown:
    Nothing selected
    -
    Click an element, drag a lasso (L), or open Tools to select by name or neighbours. A query can also select by property.
    +
    Click an element, drag a (L), or use to select by name or neighbours. The allows selection by properties.
    @@ -189,10 +187,13 @@
    Shown:
    + Groups: + - +
    diff --git a/src/managers/ui.js b/src/managers/ui.js index e9c9956..0c0a69c 100644 --- a/src/managers/ui.js +++ b/src/managers/ui.js @@ -933,6 +933,27 @@ class UIManager { if (card) selectionPanel.appendChild(card); }); } + + // Additively open a collapsible styling card by its label (never closes one). + // Driven by the current selection so the relevant card is already open when + // the user reaches for it, without fighting cards they toggled themselves. + expandStylingCard(label) { + const content = document.getElementById("stylingPanelContent"); + const card = content?.querySelector(`[data-label="${label}"]`); + if (!card || !card.classList.contains("collapsed")) return; + card.classList.remove("collapsed"); + const header = card.querySelector(".card-collapse-header"); + const chevron = card.querySelector(".card-collapse-chevron"); + if (header) header.setAttribute("aria-expanded", "true"); + if (chevron) chevron.textContent = "▾"; + } + + // Mirror the live selection onto the styling cards: open Node/Edge config for + // whatever is selected. Additive only — see expandStylingCard. + syncStylingCardsToSelection(hasNodes, hasEdges) { + if (hasNodes) this.expandStylingCard("Node Configuration"); + if (hasEdges) this.expandStylingCard("Edge Configuration"); + } } export {UIManager}; diff --git a/src/style.css b/src/style.css index f738146..df1145e 100644 --- a/src/style.css +++ b/src/style.css @@ -680,6 +680,26 @@ body, html { color: var(--text-strong); } +/* Inline actionable words in the empty-state hint: clicking jumps straight to + the named tool (lasso mode / Tools drawer / query editor). */ +.sel-hud-link { + font: inherit; + font-weight: 600; + color: var(--accent-text); + background: none; + border: none; + padding: 0; + cursor: pointer; + text-decoration: underline; + text-underline-offset: 2px; +} + +.sel-hud-link:hover, +.sel-hud-link:focus-visible { + color: var(--text-strong); + text-decoration: none; +} + /* --- active state (has selection) --- */ .sel-hud-active { display: none; @@ -735,6 +755,7 @@ body, html { .sel-hud-groups { display: flex; align-items: center; + flex-wrap: wrap; gap: 5px; margin-top: 6px; min-height: 0; @@ -1166,7 +1187,10 @@ h5 { font-size: 12px; line-height: 1.4; padding: 8px 10px; - margin-bottom: 4px; + /* Flush to the panel header on top; a wide gap below sets the status apart + from the config stack, which is itself tightly spaced (cards: 8px). */ + margin-top: 0; + margin-bottom: 14px; border-radius: 6px; background: var(--surface-3); color: var(--text-strong); @@ -2948,6 +2972,55 @@ input:checked + .slider:before { } .manual-group-status { + display: inline-flex; + align-items: center; + gap: 4px; +} + +/* One clickable badge per active manual group: ●count in the group colour, + with an ✕ that fades in on hover to signal it clears just that group. */ +.manual-group-badge { + font: inherit; + font-size: 12px; + font-weight: bold; + line-height: 1; + display: inline-flex; + align-items: center; + gap: 2px; + padding: 2px 5px; + background: transparent; + border: 1px solid transparent; + border-radius: 6px; + cursor: pointer; + transition: border-color 0.15s ease, background 0.15s ease; +} + +.manual-group-badge:hover, +.manual-group-badge:focus-visible { + border-color: var(--border-soft); + background: var(--input-bg); +} + +.mg-badge-x { + font-size: 10px; + color: var(--text-muted); + opacity: 0; + transition: opacity 0.15s ease; +} + +.manual-group-badge:hover .mg-badge-x, +.manual-group-badge:focus-visible .mg-badge-x { + opacity: 1; +} + +/* Red text-button variant (e.g. "Clear all"). */ +.sel-hud-btn.red { + color: var(--danger-text); +} + +.sel-hud-btn.red:hover { + border-color: var(--danger-text); + color: var(--danger-text); } .quadrant { diff --git a/tests/selection-styling-ux.test.js b/tests/selection-styling-ux.test.js new file mode 100644 index 0000000..f750cd6 --- /dev/null +++ b/tests/selection-styling-ux.test.js @@ -0,0 +1,199 @@ +// @vitest-environment jsdom +import { describe, it, expect, beforeEach, vi } from "vitest"; +import { UIManager } from "../src/managers/ui.js"; +import { GraphBubbleSetManager } from "../src/graph/bubble_sets.js"; + +// ========================================================================== +// UX rework: selection-driven styling-card expansion + per-group bubble clear. +// These cover the wiring added when "Detect" became "Auto-group" and group +// clearing went from all-or-nothing to per-group badges. +// ========================================================================== + +// --- helpers --------------------------------------------------------------- + +// Build the styling panel DOM the way createStyleDiv/makeCollapsible leaves it: +// each card is [data-label] with a collapse header (chevron + aria-expanded). +function mountCard(parent, label, collapsed) { + const card = document.createElement("div"); + card.className = "card-labeled card-collapsible" + (collapsed ? " collapsed" : ""); + card.setAttribute("data-label", label); + const header = document.createElement("button"); + header.className = "card-collapse-header"; + header.setAttribute("aria-expanded", collapsed ? "false" : "true"); + const chevron = document.createElement("span"); + chevron.className = "card-collapse-chevron"; + chevron.textContent = collapsed ? "▸" : "▾"; + header.append(chevron); + card.append(header); + parent.append(card); + return card; +} + +function mountStylingPanel({ node = true, edge = false, bubble = false } = {}) { + document.body.innerHTML = ""; + const content = document.createElement("div"); + content.id = "stylingPanelContent"; + document.body.append(content); + return { + node: mountCard(content, "Node Configuration", !node), + edge: mountCard(content, "Edge Configuration", !edge), + bubble: mountCard(content, "Bubble Sets", !bubble), + }; +} + +function uiInstance() { + // Methods under test only touch document + this.expandStylingCard, so a + // prototype-only instance avoids the heavy UIManager constructor. + return Object.create(UIManager.prototype); +} + +const isOpen = (card) => !card.classList.contains("collapsed"); + +// --- expandStylingCard ----------------------------------------------------- + +describe("UIManager.expandStylingCard", () => { + beforeEach(() => { document.body.innerHTML = ""; }); + + it("opens a collapsed card and syncs chevron + aria", () => { + const cards = mountStylingPanel({ node: false }); // node starts collapsed + uiInstance().expandStylingCard("Node Configuration"); + expect(isOpen(cards.node)).toBe(true); + expect(cards.node.querySelector(".card-collapse-chevron").textContent).toBe("▾"); + expect(cards.node.querySelector(".card-collapse-header").getAttribute("aria-expanded")).toBe("true"); + }); + + it("is additive: leaves an already-open card untouched (never closes)", () => { + const cards = mountStylingPanel({ node: true }); + const chevron = cards.node.querySelector(".card-collapse-chevron"); + chevron.textContent = "CUSTOM"; // prove the method doesn't rewrite open cards + uiInstance().expandStylingCard("Node Configuration"); + expect(isOpen(cards.node)).toBe(true); + expect(chevron.textContent).toBe("CUSTOM"); + }); + + it("ignores an unknown label without throwing", () => { + mountStylingPanel(); + expect(() => uiInstance().expandStylingCard("Nope")).not.toThrow(); + }); + + it("no-ops when the styling panel is absent", () => { + document.body.innerHTML = ""; + expect(() => uiInstance().expandStylingCard("Node Configuration")).not.toThrow(); + }); +}); + +// --- syncStylingCardsToSelection ------------------------------------------- + +describe("UIManager.syncStylingCardsToSelection", () => { + beforeEach(() => { document.body.innerHTML = ""; }); + + it("opens only the Edge card when edges are selected and nodes are not", () => { + const cards = mountStylingPanel({ node: false, edge: false }); + uiInstance().syncStylingCardsToSelection(false, true); + expect(isOpen(cards.edge)).toBe(true); + expect(isOpen(cards.node)).toBe(false); + }); + + it("opens only the Node card when nodes are selected and edges are not", () => { + const cards = mountStylingPanel({ node: false, edge: false }); + uiInstance().syncStylingCardsToSelection(true, false); + expect(isOpen(cards.node)).toBe(true); + expect(isOpen(cards.edge)).toBe(false); + }); + + it("opens both cards when nodes and edges are selected", () => { + const cards = mountStylingPanel({ node: false, edge: false }); + uiInstance().syncStylingCardsToSelection(true, true); + expect(isOpen(cards.node)).toBe(true); + expect(isOpen(cards.edge)).toBe(true); + }); + + it("opens nothing when neither is selected", () => { + const cards = mountStylingPanel({ node: false, edge: false }); + uiInstance().syncStylingCardsToSelection(false, false); + expect(isOpen(cards.node)).toBe(false); + expect(isOpen(cards.edge)).toBe(false); + }); +}); + +// --- bubble group: per-group badge + clear --------------------------------- + +function bsInstance(layout) { + const bs = Object.create(GraphBubbleSetManager.prototype); + bs.cache = { + data: { selectedLayout: "L1", layouts: { L1: layout } }, + graph: { draw: vi.fn().mockResolvedValue(undefined) }, + bubbleSetChanged: false, + }; + // Stop the redraw pipeline at the manager boundary. + bs.updateBubbleSetIfChanged = vi.fn().mockResolvedValue(undefined); + return bs; +} + +describe("GraphBubbleSetManager.buildManualGroupBadge", () => { + beforeEach(() => { document.body.innerHTML = ""; }); + + it("renders ●count in the group colour with a hover ✕ affordance", () => { + const bs = bsInstance({}); + const badge = bs.buildManualGroupBadge("groupA", 3, "rgb(10, 20, 30)"); + expect(badge.tagName).toBe("BUTTON"); + expect(badge.textContent).toContain("●3"); + expect(badge.querySelector(".mg-badge-x").textContent).toBe("✕"); + expect(badge.style.color).toBe("rgb(10, 20, 30)"); + expect(badge.title).toContain("3 nodes"); + }); + + it("singularises the node count in the title", () => { + const badge = bsInstance({}).buildManualGroupBadge("groupA", 1, "#fff"); + expect(badge.title).toContain("1 node"); + expect(badge.title).not.toContain("1 nodes"); + }); + + it("clears only its own group when clicked", () => { + const bs = bsInstance({}); + const spy = vi.spyOn(bs, "clearManualGroup").mockResolvedValue(undefined); + const badge = bs.buildManualGroupBadge("groupB", 2, "#000"); + badge.click(); + expect(spy).toHaveBeenCalledWith("groupB"); + }); +}); + +describe("GraphBubbleSetManager.clearManualGroup", () => { + beforeEach(() => { document.body.innerHTML = ""; }); + + it("empties the targeted group and leaves the others intact", async () => { + const layout = { + groupAManualMembers: new Set(["n1", "n2"]), + groupBManualMembers: new Set(["n3"]), + }; + const bs = bsInstance(layout); + bs.updateManualGroupButtonState = vi.fn(); + bs.updateManualGroupStatus = vi.fn(); + + await bs.clearManualGroup("groupA"); + + expect(layout.groupAManualMembers.size).toBe(0); + expect(layout.groupBManualMembers.size).toBe(1); + }); + + it("marks bubble sets changed and redraws", async () => { + const layout = { groupAManualMembers: new Set(["n1"]) }; + const bs = bsInstance(layout); + bs.updateManualGroupButtonState = vi.fn(); + bs.updateManualGroupStatus = vi.fn(); + + await bs.clearManualGroup("groupA"); + + expect(bs.cache.bubbleSetChanged).toBe(true); + expect(bs.updateBubbleSetIfChanged).toHaveBeenCalled(); + expect(bs.cache.graph.draw).toHaveBeenCalled(); + }); + + it("tolerates a group that has no member set", async () => { + const bs = bsInstance({}); + bs.updateManualGroupButtonState = vi.fn(); + bs.updateManualGroupStatus = vi.fn(); + await expect(bs.clearManualGroup("ghost")).resolves.toBeUndefined(); + expect(bs.cache.graph.draw).toHaveBeenCalled(); + }); +}); From 58da0f6245be66c5fcb30b6aa4d87400e0d4dde7 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 13:22:41 +0200 Subject: [PATCH 35/69] fix(cache): eliminate stale assets in dev and web deployment Cache busting is a dev/prod correctness concern, not something to hand-manage via a manual `?v=` query. Address it at the right layer: - Electron dev: disable the HTTP cache when !app.isPackaged + clear any pre-switch entries, so reloads always pull fresh JS/CSS. Packaged builds keep the default cache untouched. - http-server dev: add -c-1 to the serve script to disable browser caching. - Web server (server/static.js): send Cache-Control: no-cache + ETag + Last-Modified and answer conditional GETs (If-None-Match/If-Modified-Since) with 304. Previously no cache headers were sent at all, leaving browsers to apply unpredictable heuristic caching. Adds tests/static-cache.test.js covering header presence, ETag 304s (incl. comma-separated If-None-Match), If-Modified-Since 304s, and validator fall-through. --- package.json | 2 +- server/static.js | 46 ++++++++++++++++ src/package/electron_app.js | 12 ++++ tests/static-cache.test.js | 106 ++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/static-cache.test.js diff --git a/package.json b/package.json index 940621b..9a42215 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "dist-linux": "npm run dist:prep:linux && electron-builder --linux --publish=never && npm run substitute-gll end", "dist-mac": "npm run dist:prep && electron-builder --mac --publish=never && npm run substitute-gll end", "dist": "npm run dist-linux && npm run dist-windows", - "serve": "npm run vendor-libs && npx http-server src -p 8000 --cors -o /graph_lens_lite.html ", + "serve": "npm run vendor-libs && npx http-server src -p 8000 --cors -c-1 -o /graph_lens_lite.html ", "serve:api": "npm run vendor-libs && node --env-file-if-exists=.env server/index.js", "version": "npm run inject-version && git add src/config.js", "test": "vitest run", diff --git a/server/static.js b/server/static.js index 3b56cc1..ac314d4 100644 --- a/server/static.js +++ b/server/static.js @@ -76,13 +76,59 @@ function serveStatic(req, res, rootDir) { res.end("Not Found"); return; } + + // Asset names are stable while their content changes between releases, so a + // long max-age would serve stale JS/CSS. `no-cache` makes the browser + // revalidate on every load; the validators below let that revalidation + // return a cheap 304 instead of refetching unchanged bytes. + const lastModified = stats.mtime.toUTCString(); + const etag = `W/"${stats.size.toString(16)}-${Math.floor(stats.mtimeMs).toString(16)}"`; + + if (isNotModified(req, etag, stats.mtimeMs)) { + res.writeHead(304, { + "Cache-Control": "no-cache", + ETag: etag, + "Last-Modified": lastModified, + }); + res.end(); + return; + } + res.writeHead(200, { "Content-Type": contentTypeFor(filePath), "Content-Length": stats.size, "X-Content-Type-Options": "nosniff", + "Cache-Control": "no-cache", + ETag: etag, + "Last-Modified": lastModified, }); fs.createReadStream(filePath).pipe(res); }); } +/** + * Decide whether a conditional GET can be answered with 304 Not Modified. + * Prefers the strong ETag match; falls back to If-Modified-Since (second + * resolution, matching HTTP date precision). + * + * @param {import('http').IncomingMessage} req + * @param {string} etag Current entity tag for the file. + * @param {number} mtimeMs File modification time in milliseconds. + * @returns {boolean} + */ +function isNotModified(req, etag, mtimeMs) { + const ifNoneMatch = req.headers["if-none-match"]; + if (ifNoneMatch) { + return ifNoneMatch.split(",").some((tag) => tag.trim() === etag); + } + const ifModifiedSince = req.headers["if-modified-since"]; + if (ifModifiedSince) { + const since = Date.parse(ifModifiedSince); + if (!Number.isNaN(since)) { + return Math.floor(mtimeMs / 1000) * 1000 <= since; + } + } + return false; +} + module.exports = { serveStatic, resolveStaticPath, contentTypeFor, DEFAULT_DOCUMENT }; diff --git a/src/package/electron_app.js b/src/package/electron_app.js index a635dde..db6f61e 100644 --- a/src/package/electron_app.js +++ b/src/package/electron_app.js @@ -1,6 +1,13 @@ const { app, BrowserWindow, shell, Menu } = require('electron'); const path = require('path'); +// In development the asset cache only ever serves stale JS/CSS — there is nothing +// worth caching from local files. Disable it so every reload pulls fresh bytes. +// Packaged builds are immutable, so they keep the default cache untouched. +if (!app.isPackaged) { + app.commandLine.appendSwitch('disable-http-cache'); +} + function createWindow() { const win = new BrowserWindow({ width: 1280, @@ -16,6 +23,11 @@ function createWindow() { win.loadFile(path.join(__dirname, '..', 'graph_lens_lite.html')); + // Clear any entries left over from a previous run before the switch took effect. + if (!app.isPackaged) { + win.webContents.session.clearCache(); + } + win.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); return { action: 'deny' }; diff --git a/tests/static-cache.test.js b/tests/static-cache.test.js new file mode 100644 index 0000000..3785d82 --- /dev/null +++ b/tests/static-cache.test.js @@ -0,0 +1,106 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import http from "node:http"; +import os from "node:os"; +import fs from "node:fs"; +import path from "node:path"; +import { createHandler } from "../server/handler.js"; +import { GraphStore } from "../server/graph_store.js"; + +// ========================================================================== +// Static asset caching — verifies the server tells browsers to revalidate +// (Cache-Control: no-cache) and answers conditional GETs with a cheap 304. +// This is the production half of "cache busting once and for all": no manual +// ?v= bumping, never stale, no full refetch when bytes are unchanged. +// ========================================================================== + +const TOKEN = "test-token-123"; +const ASSET_BODY = "body { color: rebeccapurple; }"; + +let server; +let baseUrl; +let staticDir; + +beforeAll(async () => { + staticDir = fs.mkdtempSync(path.join(os.tmpdir(), "gll-cache-")); + fs.writeFileSync(path.join(staticDir, "graph_lens_lite.html"), "GLL"); + fs.writeFileSync(path.join(staticDir, "style.css"), ASSET_BODY); + + const config = { token: TOKEN, maxBodyBytes: 1024, host: "127.0.0.1", port: 0 }; + const handler = createHandler({ store: new GraphStore(), config, staticDir, version: "9.9.9" }); + server = http.createServer(handler); + await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); + baseUrl = `http://127.0.0.1:${server.address().port}`; +}); + +afterAll(() => { + server.close(); + fs.rmSync(staticDir, { recursive: true, force: true }); +}); + +const getAsset = (headers = {}) => fetch(`${baseUrl}/style.css`, { headers }); + +describe("static cache headers", () => { + it("serves assets with no-cache and revalidation validators", async () => { + const res = await getAsset(); + expect(res.status).toBe(200); + expect(res.headers.get("cache-control")).toBe("no-cache"); + expect(res.headers.get("etag")).toMatch(/^W\/"[0-9a-f]+-[0-9a-f]+"$/); + expect(res.headers.get("last-modified")).toBeTruthy(); + expect(await res.text()).toBe(ASSET_BODY); + }); +}); + +describe("conditional GET via ETag", () => { + it("returns 304 with an empty body when the ETag matches", async () => { + const first = await getAsset(); + const etag = first.headers.get("etag"); + await first.text(); + + const res = await getAsset({ "If-None-Match": etag }); + expect(res.status).toBe(304); + expect(await res.text()).toBe(""); + expect(res.headers.get("cache-control")).toBe("no-cache"); + }); + + it("matches an ETag inside a comma-separated If-None-Match list", async () => { + const etag = (await getAsset()).headers.get("etag"); + const res = await getAsset({ "If-None-Match": `"stale-tag", ${etag}` }); + expect(res.status).toBe(304); + }); + + it("returns 200 with the body when the ETag does not match", async () => { + const res = await getAsset({ "If-None-Match": 'W/"deadbeef-1"' }); + expect(res.status).toBe(200); + expect(await res.text()).toBe(ASSET_BODY); + }); +}); + +describe("conditional GET via If-Modified-Since", () => { + it("returns 304 when the cached copy is current", async () => { + const lastModified = (await getAsset()).headers.get("last-modified"); + const res = await getAsset({ "If-Modified-Since": lastModified }); + expect(res.status).toBe(304); + expect(await res.text()).toBe(""); + }); + + it("returns 200 when the cached copy predates the file", async () => { + const past = new Date(0).toUTCString(); + const res = await getAsset({ "If-Modified-Since": past }); + expect(res.status).toBe(200); + expect(await res.text()).toBe(ASSET_BODY); + }); + + it("ignores ETag fall-through and serves 200 for an unparseable date", async () => { + const res = await getAsset({ "If-Modified-Since": "not-a-date" }); + expect(res.status).toBe(200); + }); + + it("prefers ETag over If-Modified-Since when both are present", async () => { + const future = new Date(Date.parse("2999-01-01")).toUTCString(); + const res = await getAsset({ + "If-None-Match": 'W/"deadbeef-1"', + "If-Modified-Since": future, + }); + expect(res.status).toBe(200); + }); +}); From 85db7da3266188b44a0c41723aa2926eba86778b Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 13:28:51 +0200 Subject: [PATCH 36/69] fix(ui): harmonize styling-panel status margins to 8px rhythm --- src/style.css | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/style.css b/src/style.css index df1145e..891fa9e 100644 --- a/src/style.css +++ b/src/style.css @@ -144,10 +144,6 @@ body, html { opacity: 1; } -#stylingPanelContent { - padding-top: 3px; -} - #closeStylingPanelBtn { margin-left: auto; } @@ -1187,10 +1183,10 @@ h5 { font-size: 12px; line-height: 1.4; padding: 8px 10px; - /* Flush to the panel header on top; a wide gap below sets the status apart - from the config stack, which is itself tightly spaced (cards: 8px). */ - margin-top: 0; - margin-bottom: 14px; + /* Match the 8px card rhythm on all sides so the status sits evenly within + the config stack instead of hugging the top and floating far above it. */ + margin-top: 8px; + margin-bottom: 8px; border-radius: 6px; background: var(--surface-3); color: var(--text-strong); From 3385056b5ffb0f4eb95b35683a2e8226e883374e Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 13:31:35 +0200 Subject: [PATCH 37/69] feat(ui): suppress tooltip on shift+click multi-select Shift+click toggles selection membership; it is a selection-building gesture, so a tooltip should not flash onto each clicked element. Plain click still selects-and-inspects. Adds interactions-click tests covering plain/shift/tooltip-disabled/drag-suppressed click paths. --- src/graph/interactions.js | 5 +- tests/interactions-click.test.js | 101 +++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/interactions-click.test.js diff --git a/src/graph/interactions.js b/src/graph/interactions.js index 440d3f5..d81d40e 100644 --- a/src/graph/interactions.js +++ b/src/graph/interactions.js @@ -213,7 +213,10 @@ class InteractionManager { await this.cache.sm.selectElements([id], this.#combinedRefMap()); } } - if (this.enabled.tooltip) this.showTooltip(id, isEdge); + // Tooltip means "inspect this one thing"; a shift+click is a + // selection-building gesture, so don't flash a tooltip on each one. + const shiftHeld = Boolean(event?.original?.shiftKey); + if (this.enabled.tooltip && !shiftHeld) this.showTooltip(id, isEdge); } async #onClickStage() { diff --git a/tests/interactions-click.test.js b/tests/interactions-click.test.js new file mode 100644 index 0000000..fb3c305 --- /dev/null +++ b/tests/interactions-click.test.js @@ -0,0 +1,101 @@ +import { describe, it, expect, vi } from "vitest"; +import { Graph } from "../src/lib/graphology.bundle.mjs"; +import { InteractionManager } from "../src/graph/interactions.js"; + +// ========================================================================== +// Click → selection → tooltip interaction. A plain click replaces the +// selection and opens the inspect tooltip; a shift+click is a +// selection-building gesture (toggle membership) and must NOT flash a +// tooltip on each clicked element. Exercised with a stub sigma. +// ========================================================================== + +function makeSigma() { + const handlers = {}; + const captorHandlers = {}; + return { + handlers, + captorHandlers, + on: (event, fn) => { handlers[event] = fn; }, + getMouseCaptor: () => ({ on: (event, fn) => { captorHandlers[event] = fn; } }), + getCamera: () => ({ on: () => {} }), + }; +} + +function makeManager() { + const graph = new Graph({ multi: true, allowSelfLoops: true, type: "directed" }); + graph.addNode("a", { x: 0, y: 0, label: "a" }); + const sigma = makeSigma(); + const cache = { + ui: { error: vi.fn() }, + CFG: {}, + nodeRef: new Map([["a", { ref: "a" }]]), + edgeRef: new Map(), + sm: { + selectElements: vi.fn(async () => {}), + updateSelectedState: vi.fn(async () => {}), + }, + }; + const adapter = { + sigma, + graph, + getElementState: vi.fn(() => []), // not "selected" → shift+click adds + }; + const manager = new InteractionManager(adapter, cache, new Set(), { appendChild: () => {} }); + return { manager, sigma, cache }; +} + +function clickEvent(shiftKey) { + return { node: "a", event: { original: { shiftKey } } }; +} + +// Let the async #onClickElement settle (selectElements await + sync tooltip call). +const flush = () => new Promise((resolve) => setTimeout(resolve, 0)); + +describe("click → tooltip interaction", () => { + it("plain click replaces selection and opens the tooltip", async () => { + const { manager, sigma, cache } = makeManager(); + const tooltip = vi.spyOn(manager, "showTooltip").mockImplementation(() => {}); + + sigma.handlers.clickNode(clickEvent(false)); + await flush(); + + expect(cache.sm.selectElements).toHaveBeenCalledTimes(1); + expect(cache.sm.updateSelectedState).not.toHaveBeenCalled(); + expect(tooltip).toHaveBeenCalledWith("a", false); + }); + + it("shift+click toggles membership WITHOUT opening the tooltip", async () => { + const { manager, sigma, cache } = makeManager(); + const tooltip = vi.spyOn(manager, "showTooltip").mockImplementation(() => {}); + + sigma.handlers.clickNode(clickEvent(true)); + await flush(); + + expect(cache.sm.updateSelectedState).toHaveBeenCalledTimes(1); + expect(cache.sm.selectElements).not.toHaveBeenCalled(); + expect(tooltip).not.toHaveBeenCalled(); + }); + + it("does not open the tooltip when the tooltip interaction is disabled", async () => { + const { manager, sigma } = makeManager(); + const tooltip = vi.spyOn(manager, "showTooltip").mockImplementation(() => {}); + manager.setEnabled("tooltip", false); + + sigma.handlers.clickNode(clickEvent(false)); + await flush(); + + expect(tooltip).not.toHaveBeenCalled(); + }); + + it("suppresses the click that follows a drag (no select, no tooltip)", async () => { + const { manager, sigma, cache } = makeManager(); + const tooltip = vi.spyOn(manager, "showTooltip").mockImplementation(() => {}); + manager.suppressNextClick = true; + + sigma.handlers.clickNode(clickEvent(false)); + await flush(); + + expect(cache.sm.selectElements).not.toHaveBeenCalled(); + expect(tooltip).not.toHaveBeenCalled(); + }); +}); From 700c491b9e24bda09b22d2a39efe1924c60276f3 Mon Sep 17 00:00:00 2001 From: Mnikley Date: Fri, 12 Jun 2026 13:31:41 +0200 Subject: [PATCH 38/69] feat(ui): default selection HUD to top-right corner New/unset users now get the selection panel in the top-right; users with a stored corner keep their choice. Updates the JS fallback, the initial paint classes on the container and restore button, and the two tests that pinned the old top-left default. --- src/graph_lens_lite.html | 4 ++-- src/utilities/selection_hud.js | 2 +- tests/selection-hud.test.js | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/graph_lens_lite.html b/src/graph_lens_lite.html index 1c28873..0abe361 100644 --- a/src/graph_lens_lite.html +++ b/src/graph_lens_lite.html @@ -135,7 +135,7 @@
    Shown:
    -
    +
    Selection @@ -198,7 +198,7 @@
    Shown:
    - +