@graphty/cytoscape-extensions 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/algorithm-options.d.ts +5 -0
- package/dist/algorithm-options.d.ts.map +1 -0
- package/dist/algorithm-options.js +285 -0
- package/dist/algorithm-options.js.map +1 -0
- package/dist/algorithms.d.ts +489 -0
- package/dist/algorithms.d.ts.map +1 -0
- package/dist/algorithms.js +1184 -0
- package/dist/algorithms.js.map +1 -0
- package/dist/cdn/chunks/elements-DIunzJUl.js +1 -0
- package/dist/cdn/chunks/gpu-platform-browser-DnQwf3s0.js +2825 -0
- package/dist/cdn/chunks/index-C-jUF_Ve.js +1 -0
- package/dist/cdn/chunks/index-C4RZkds_.js +10 -0
- package/dist/cdn/chunks/io-D-Vr0j3W.js +269 -0
- package/dist/cdn/chunks/preload-helper-Crt_PPe8.js +1 -0
- package/dist/cdn/chunks/samples-Dja23zzq.js +1 -0
- package/dist/cdn/chunks/sigv4-BXwVbza3-DZCCNyQA.js +3 -0
- package/dist/cdn/chunks/sources-cypher-oj3S6pKb.js +5 -0
- package/dist/cdn/chunks/sources-ndex-BgZhxHsL.js +1 -0
- package/dist/cdn/chunks/sources-rest-E6On5P3z.js +1 -0
- package/dist/cdn/chunks/sources-sparql-BAxh1dw-.js +5 -0
- package/dist/cdn/cytoscape-extensions.js +1 -0
- package/dist/cdn/io.js +1 -0
- package/dist/cytoscape-extensions.bundle.js +2825 -0
- package/dist/elements.d.ts +69 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +343 -0
- package/dist/elements.js.map +1 -0
- package/dist/gpu-platform-browser.d.ts +11 -0
- package/dist/gpu-platform-browser.d.ts.map +1 -0
- package/dist/gpu-platform-browser.js +22 -0
- package/dist/gpu-platform-browser.js.map +1 -0
- package/dist/gpu-platform-node.d.ts +15 -0
- package/dist/gpu-platform-node.d.ts.map +1 -0
- package/dist/gpu-platform-node.js +27 -0
- package/dist/gpu-platform-node.js.map +1 -0
- package/dist/gpu.d.ts +149 -0
- package/dist/gpu.d.ts.map +1 -0
- package/dist/gpu.js +312 -0
- package/dist/gpu.js.map +1 -0
- package/dist/graph-data.d.ts +101 -0
- package/dist/graph-data.d.ts.map +1 -0
- package/dist/graph-data.js +147 -0
- package/dist/graph-data.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +111 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +258 -0
- package/dist/io.js.map +1 -0
- package/dist/layouts.d.ts +207 -0
- package/dist/layouts.d.ts.map +1 -0
- package/dist/layouts.js +615 -0
- package/dist/layouts.js.map +1 -0
- package/dist/lazy.d.ts +21 -0
- package/dist/lazy.d.ts.map +1 -0
- package/dist/lazy.js +32 -0
- package/dist/lazy.js.map +1 -0
- package/dist/samples.d.ts +115 -0
- package/dist/samples.d.ts.map +1 -0
- package/dist/samples.js +237 -0
- package/dist/samples.js.map +1 -0
- package/dist/snapshot.d.ts +81 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +225 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/webgpu-provider.d.ts +25 -0
- package/dist/webgpu-provider.d.ts.map +1 -0
- package/dist/webgpu-provider.js +53 -0
- package/dist/webgpu-provider.js.map +1 -0
- package/package.json +13 -9
package/dist/gpu.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGPU acceleration: detection, device acquisition, reuse, device-loss recovery and disposal, per Cytoscape core.
|
|
3
|
+
*
|
|
4
|
+
* The package @graphty/webgpu-graph-algorithms is a regular dependency, but nothing here imports it statically.
|
|
5
|
+
* The first call that could use a GPU, in a runtime that has WebGPU (or might: Node, where the optional `webgpu`
|
|
6
|
+
* package brings Dawn), loads it with a dynamic import of "#gpu-platform". The package's `imports` field maps that specifier to the Node
|
|
7
|
+
* build or the browser build, so a bundler puts the GPU code in a chunk of its own that a CPU-only page never
|
|
8
|
+
* fetches, and a browser bundle never sees the Node build's `import("webgpu")`.
|
|
9
|
+
*
|
|
10
|
+
* The rule the whole module follows: the GPU-or-CPU decision is made once, up front, before any work starts.
|
|
11
|
+
* A failure of work that already started on the GPU (a lost device, an out-of-memory) is thrown to the caller,
|
|
12
|
+
* never finished quietly on the CPU. The next call acquires a fresh device.
|
|
13
|
+
*/
|
|
14
|
+
import type { AlgorithmAccelerator } from "@graphty/algorithms";
|
|
15
|
+
import type { GraphSnapshot } from "@graphty/graph-format";
|
|
16
|
+
import type { LayoutAccelerator } from "@graphty/layout";
|
|
17
|
+
import type { Core } from "cytoscape";
|
|
18
|
+
/** The accelerator a provider hands over: both CPU packages' injection seams, plus snapshot release and disposal. */
|
|
19
|
+
export type GpuAccelerator = AlgorithmAccelerator & LayoutAccelerator & {
|
|
20
|
+
release(s: GraphSnapshot): void;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
};
|
|
23
|
+
/** A device a provider acquired. */
|
|
24
|
+
export interface AcquiredGpu {
|
|
25
|
+
readonly accelerator: GpuAccelerator;
|
|
26
|
+
/** "vendor / description", for the backend report. */
|
|
27
|
+
readonly device: string;
|
|
28
|
+
/** Resolves (with the reason) when the device is lost, including when it is destroyed by dispose(). */
|
|
29
|
+
readonly lost: Promise<string>;
|
|
30
|
+
}
|
|
31
|
+
/** Thrown by a provider that declined up front (no WebGPU, no adapter, a software-only or incorrect device). */
|
|
32
|
+
export declare class GpuUnavailableError extends Error {
|
|
33
|
+
/** E_NO_WEBGPU, E_NO_ADAPTER, E_SOFTWARE_ONLY, E_DEVICE_INCORRECT, ... */
|
|
34
|
+
readonly code: string;
|
|
35
|
+
/** What the user can change to get the GPU, when there is something; null when nothing they do would help. */
|
|
36
|
+
readonly fix: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Creates the error.
|
|
39
|
+
* @param code - the reason code
|
|
40
|
+
* @param message - the reason in words
|
|
41
|
+
* @param fix - what the user can change to get the GPU, or null
|
|
42
|
+
*/
|
|
43
|
+
constructor(code: string, message: string, fix?: string | null);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The error a call on a destroyed Cytoscape core rejects with, or a layout run started on one emits as layouterror.
|
|
47
|
+
* @returns the error, `code` "E_CORE_DESTROYED"
|
|
48
|
+
*/
|
|
49
|
+
export declare function coreDestroyedError(): Error & {
|
|
50
|
+
readonly code: "E_CORE_DESTROYED";
|
|
51
|
+
};
|
|
52
|
+
/** Probes, constructs and verifies a device, or throws GpuUnavailableError. */
|
|
53
|
+
export interface GpuProvider {
|
|
54
|
+
acquire(): Promise<AcquiredGpu>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Per call: "auto" (default) uses the GPU when one is available and runs the CPU otherwise; "off" always runs the CPU;
|
|
58
|
+
* "require" throws when no GPU is available instead of running the CPU.
|
|
59
|
+
*/
|
|
60
|
+
export type GpuMode = "auto" | "off" | "require";
|
|
61
|
+
/**
|
|
62
|
+
* Throws when a `gpu` option is not one of the modes, so a misspelled "require" cannot quietly run on the CPU.
|
|
63
|
+
* @param name - the method or layout, for the message
|
|
64
|
+
* @param mode - the caller's `gpu` option
|
|
65
|
+
* @throws TypeError when the option is set to anything but "auto", "off" or "require"
|
|
66
|
+
*/
|
|
67
|
+
export declare function checkGpuMode(name: string, mode: unknown): void;
|
|
68
|
+
/** Which implementation ran, and why the CPU when it was the CPU. */
|
|
69
|
+
export interface Backend {
|
|
70
|
+
readonly ran: "gpu" | "cpu";
|
|
71
|
+
/** Why the CPU ran; null when the GPU ran. */
|
|
72
|
+
readonly reason: string | null;
|
|
73
|
+
/** The GPU device, when one was acquired (also when the options kept the work on the CPU). */
|
|
74
|
+
readonly device: string | null;
|
|
75
|
+
}
|
|
76
|
+
/** Options of `configureWebGpu`, for every core. */
|
|
77
|
+
export interface WebGpuOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Accept a software adapter (llvmpipe, SwiftShader, WARP). Default false: a software adapter is usually slower
|
|
80
|
+
* than the CPU implementation, so the CPU runs and the result says why.
|
|
81
|
+
*/
|
|
82
|
+
readonly acceptSoftware?: boolean;
|
|
83
|
+
/** Node only: a substring of the Dawn adapter name to pick ("llvmpipe", "4070"). Ignored in a browser. */
|
|
84
|
+
readonly adapter?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Graphs with at least this many nodes are where the GPU is expected to pay off. One of them running on the CPU for
|
|
88
|
+
* a reason the user could fix logs a one-time console warning; smaller graphs never do.
|
|
89
|
+
*/
|
|
90
|
+
export declare const GPU_SIZE_FLOOR = 5000;
|
|
91
|
+
/** A core's GPU decision: an acquired device, or the reason there is none. */
|
|
92
|
+
interface Decision {
|
|
93
|
+
readonly gpu: AcquiredGpu | null;
|
|
94
|
+
readonly reason: string | null;
|
|
95
|
+
/** When the CPU was chosen for a reason the user could fix: the fix. */
|
|
96
|
+
readonly fix?: string | null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Sets the WebGPU options of every core. Each core disposes its device and decides again on its next call.
|
|
100
|
+
* @param o - see WebGpuOptions
|
|
101
|
+
*/
|
|
102
|
+
export declare function configureWebGpu(o?: WebGpuOptions): void;
|
|
103
|
+
/**
|
|
104
|
+
* Test seam: replaces the platform's provider.
|
|
105
|
+
* @param p - the provider; null disables WebGPU; undefined restores the platform's provider
|
|
106
|
+
*/
|
|
107
|
+
export declare function registerGpuProvider(p: GpuProvider | null | undefined): void;
|
|
108
|
+
/**
|
|
109
|
+
* Why a run in this mode takes the CPU without asking for a device, so it can stay synchronous.
|
|
110
|
+
* @param mode - the caller's mode
|
|
111
|
+
* @returns the decision when it is already known to be the CPU, or null when a device has to be asked for
|
|
112
|
+
*/
|
|
113
|
+
export declare function cpuWithoutAsking(mode?: GpuMode): Decision | null;
|
|
114
|
+
/**
|
|
115
|
+
* The core's device, acquiring one on first use and again after a loss. One device per core, reused by every call.
|
|
116
|
+
* The first call in the process loads @graphty/webgpu-graph-algorithms.
|
|
117
|
+
* @param cy - the core
|
|
118
|
+
* @param mode - the caller's mode
|
|
119
|
+
* @returns the device (null for the CPU) and the reason when null
|
|
120
|
+
* @throws Error under "require" when no device is available, and when the core was destroyed
|
|
121
|
+
*/
|
|
122
|
+
export declare function gpuFor(cy: Core, mode?: GpuMode): Promise<Decision>;
|
|
123
|
+
/**
|
|
124
|
+
* Warns once per configuration when a graph at or above GPU_SIZE_FLOOR runs on the CPU for a reason the user could
|
|
125
|
+
* fix. Small graphs, gpu: "off" and reasons nobody can fix stay quiet.
|
|
126
|
+
* @param d - the decision the run started with
|
|
127
|
+
* @param nodeCount - the graph's node count
|
|
128
|
+
*/
|
|
129
|
+
export declare function warnIfFixable(d: Decision, nodeCount: number): void;
|
|
130
|
+
/**
|
|
131
|
+
* An accelerator that records whether any of its methods was called, so the run can report which implementation
|
|
132
|
+
* answered. The CPU packages' dispatchers choose the CPU silently when the options or the graph need it.
|
|
133
|
+
* @param acc - the accelerator
|
|
134
|
+
* @returns the recording accelerator and the flag reader
|
|
135
|
+
*/
|
|
136
|
+
export declare function recording<T extends object>(acc: T): {
|
|
137
|
+
accelerator: T;
|
|
138
|
+
used(): boolean;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* The backend report of a finished run.
|
|
142
|
+
* @param d - the decision the run started with
|
|
143
|
+
* @param usedGpu - whether the dispatcher called the accelerator
|
|
144
|
+
* @param why - the reason the dispatcher kept the work on the CPU, when it did
|
|
145
|
+
* @returns the report
|
|
146
|
+
*/
|
|
147
|
+
export declare function backendOf(d: Decision, usedGpu: boolean, why: string): Backend;
|
|
148
|
+
export {};
|
|
149
|
+
//# sourceMappingURL=gpu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu.d.ts","sourceRoot":"","sources":["../src/gpu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKtC,qHAAqH;AACrH,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAC7C,iBAAiB,GAAG;IAChB,OAAO,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,OAAO,IAAI,IAAI,CAAC;CACnB,CAAC;AAEN,oCAAoC;AACpC,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uGAAuG;IACvG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,gHAAgH;AAChH,qBAAa,mBAAoB,SAAQ,KAAK;IAC1C,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8GAA8G;IAC9G,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B;;;;;OAKG;gBACS,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW;CAMvE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAElF;AAED,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IACxB,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAIjD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAQ9D;AAED,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACpB,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC1B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,0GAA0G;IAC1G,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,OAAQ,CAAC;AAEpC,8EAA8E;AAC9E,UAAU,QAAQ;IACd,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAsBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAE,aAAkB,GAAG,IAAI,CAK3D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAG3E;AAuID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,OAAgB,GAAG,QAAQ,GAAG,IAAI,CAcxE;AAED;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,GAAE,OAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA0BhF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CASlE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG;IAAE,WAAW,EAAE,CAAC,CAAC;IAAC,IAAI,IAAI,OAAO,CAAA;CAAE,CAevF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAO7E"}
|
package/dist/gpu.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGPU acceleration: detection, device acquisition, reuse, device-loss recovery and disposal, per Cytoscape core.
|
|
3
|
+
*
|
|
4
|
+
* The package @graphty/webgpu-graph-algorithms is a regular dependency, but nothing here imports it statically.
|
|
5
|
+
* The first call that could use a GPU, in a runtime that has WebGPU (or might: Node, where the optional `webgpu`
|
|
6
|
+
* package brings Dawn), loads it with a dynamic import of "#gpu-platform". The package's `imports` field maps that specifier to the Node
|
|
7
|
+
* build or the browser build, so a bundler puts the GPU code in a chunk of its own that a CPU-only page never
|
|
8
|
+
* fetches, and a browser bundle never sees the Node build's `import("webgpu")`.
|
|
9
|
+
*
|
|
10
|
+
* The rule the whole module follows: the GPU-or-CPU decision is made once, up front, before any work starts.
|
|
11
|
+
* A failure of work that already started on the GPU (a lost device, an out-of-memory) is thrown to the caller,
|
|
12
|
+
* never finished quietly on the CPU. The next call acquires a fresh device.
|
|
13
|
+
*/
|
|
14
|
+
import { loadPart } from "./lazy.js";
|
|
15
|
+
import { onSnapshotsDropped } from "./snapshot.js";
|
|
16
|
+
/** Thrown by a provider that declined up front (no WebGPU, no adapter, a software-only or incorrect device). */
|
|
17
|
+
export class GpuUnavailableError extends Error {
|
|
18
|
+
/**
|
|
19
|
+
* Creates the error.
|
|
20
|
+
* @param code - the reason code
|
|
21
|
+
* @param message - the reason in words
|
|
22
|
+
* @param fix - what the user can change to get the GPU, or null
|
|
23
|
+
*/
|
|
24
|
+
constructor(code, message, fix = null) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "GpuUnavailableError";
|
|
27
|
+
this.code = code;
|
|
28
|
+
this.fix = fix;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The error a call on a destroyed Cytoscape core rejects with, or a layout run started on one emits as layouterror.
|
|
33
|
+
* @returns the error, `code` "E_CORE_DESTROYED"
|
|
34
|
+
*/
|
|
35
|
+
export function coreDestroyedError() {
|
|
36
|
+
return Object.assign(new Error("graphty: the Cytoscape core was destroyed"), { code: "E_CORE_DESTROYED" });
|
|
37
|
+
}
|
|
38
|
+
const GPU_MODES = ["auto", "off", "require"];
|
|
39
|
+
/**
|
|
40
|
+
* Throws when a `gpu` option is not one of the modes, so a misspelled "require" cannot quietly run on the CPU.
|
|
41
|
+
* @param name - the method or layout, for the message
|
|
42
|
+
* @param mode - the caller's `gpu` option
|
|
43
|
+
* @throws TypeError when the option is set to anything but "auto", "off" or "require"
|
|
44
|
+
*/
|
|
45
|
+
export function checkGpuMode(name, mode) {
|
|
46
|
+
if (mode !== undefined && !GPU_MODES.includes(mode)) {
|
|
47
|
+
// a string quoted, so "require " shows its space; anything else by its value or its type
|
|
48
|
+
const plain = mode === null || typeof mode === "number" || typeof mode === "boolean";
|
|
49
|
+
const shown = plain ? String(mode) : `a value of type ${typeof mode}`;
|
|
50
|
+
const got = typeof mode === "string" ? JSON.stringify(mode) : shown;
|
|
51
|
+
throw new TypeError(`${name}: gpu must be "auto", "off" or "require"; got ${got}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Graphs with at least this many nodes are where the GPU is expected to pay off. One of them running on the CPU for
|
|
56
|
+
* a reason the user could fix logs a one-time console warning; smaller graphs never do.
|
|
57
|
+
*/
|
|
58
|
+
export const GPU_SIZE_FLOOR = 5000;
|
|
59
|
+
let options = {};
|
|
60
|
+
/** Set by tests in place of the platform's provider; null disables WebGPU, undefined restores the platform's. */
|
|
61
|
+
let override;
|
|
62
|
+
/** The provider being loaded or loaded, for the current options. */
|
|
63
|
+
let loading = null;
|
|
64
|
+
/** The same, once settled, so a run that cannot use the GPU can stay synchronous. */
|
|
65
|
+
let loaded = null;
|
|
66
|
+
let warned = false;
|
|
67
|
+
const cores = new WeakMap();
|
|
68
|
+
/**
|
|
69
|
+
* Sets the WebGPU options of every core. Each core disposes its device and decides again on its next call.
|
|
70
|
+
* @param o - see WebGpuOptions
|
|
71
|
+
*/
|
|
72
|
+
export function configureWebGpu(o = {}) {
|
|
73
|
+
options = { ...o };
|
|
74
|
+
loading = null;
|
|
75
|
+
loaded = null;
|
|
76
|
+
warned = false;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Test seam: replaces the platform's provider.
|
|
80
|
+
* @param p - the provider; null disables WebGPU; undefined restores the platform's provider
|
|
81
|
+
*/
|
|
82
|
+
export function registerGpuProvider(p) {
|
|
83
|
+
configureWebGpu(options);
|
|
84
|
+
override = p;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Why this runtime certainly has no WebGPU, without loading anything.
|
|
88
|
+
* @returns the reason, or null when it has WebGPU or might (Node, with the optional `webgpu` package)
|
|
89
|
+
*/
|
|
90
|
+
function noWebGpu() {
|
|
91
|
+
const nav = globalThis.navigator;
|
|
92
|
+
if (nav?.gpu !== undefined && nav.gpu !== null) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const proc = globalThis.process;
|
|
96
|
+
return proc?.versions?.node === undefined ? "this runtime has no WebGPU (navigator.gpu is undefined)" : null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The provider, loading the GPU package on first use.
|
|
100
|
+
* @returns the provider, or why there is none
|
|
101
|
+
*/
|
|
102
|
+
function source() {
|
|
103
|
+
if (loading === null) {
|
|
104
|
+
const none = noWebGpu();
|
|
105
|
+
if (override !== undefined || none !== null) {
|
|
106
|
+
// known without loading anything, so known synchronously
|
|
107
|
+
loaded = override ?? { reason: none ?? "WebGPU was disabled", fix: null };
|
|
108
|
+
loading = Promise.resolve(loaded);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const p = loadPart(import("#gpu-platform"), "an ...Async method or a simulation layout").then((m) => m.gpuProvider(options), (e) => ({
|
|
112
|
+
reason: `@graphty/webgpu-graph-algorithms did not load: ${messageOf(e)}`,
|
|
113
|
+
fix: "check that @graphty/webgpu-graph-algorithms is installed and that your bundler serves its chunk",
|
|
114
|
+
}));
|
|
115
|
+
loading = p;
|
|
116
|
+
void p.then((s) => {
|
|
117
|
+
if (loading === p) {
|
|
118
|
+
loaded = s;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return loading;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Whether a source is a provider.
|
|
127
|
+
* @param s - the source
|
|
128
|
+
* @returns true for a provider
|
|
129
|
+
*/
|
|
130
|
+
function isProvider(s) {
|
|
131
|
+
return "acquire" in s;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The message of a thrown value.
|
|
135
|
+
* @param e - what was thrown
|
|
136
|
+
* @returns its message
|
|
137
|
+
*/
|
|
138
|
+
function messageOf(e) {
|
|
139
|
+
return e instanceof Error ? e.message : String(e);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Disposes a decision's device once the decision settles. A decision that failed holds no device, and its error
|
|
143
|
+
* already reached the caller that awaited it.
|
|
144
|
+
* @param decision - the decision, or null when there is none
|
|
145
|
+
*/
|
|
146
|
+
function disposeWhenDecided(decision) {
|
|
147
|
+
decision?.then((d) => d.gpu?.accelerator.dispose(), () => undefined);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The per-core state; the first call subscribes to the core's destroy event.
|
|
151
|
+
* @param cy - the core
|
|
152
|
+
* @returns its state
|
|
153
|
+
*/
|
|
154
|
+
function coreGpu(cy) {
|
|
155
|
+
let g = cores.get(cy);
|
|
156
|
+
if (g === undefined) {
|
|
157
|
+
const created = { decision: null, by: null, destroyed: false };
|
|
158
|
+
cy.one("destroy", () => {
|
|
159
|
+
created.destroyed = true;
|
|
160
|
+
disposeWhenDecided(created.decision);
|
|
161
|
+
created.decision = null;
|
|
162
|
+
});
|
|
163
|
+
cores.set(cy, created);
|
|
164
|
+
g = created;
|
|
165
|
+
}
|
|
166
|
+
return g;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Acquires a device for a core: probe, construct, verify; wires loss, snapshot release and destroy.
|
|
170
|
+
* @param cy - the core
|
|
171
|
+
* @param g - its state
|
|
172
|
+
* @param p - the provider
|
|
173
|
+
* @returns the decision
|
|
174
|
+
*/
|
|
175
|
+
async function decide(cy, g, p) {
|
|
176
|
+
let gpu;
|
|
177
|
+
try {
|
|
178
|
+
gpu = await p.acquire();
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
// Up-front detection: nothing has run yet, so the CPU is the honest answer, with the reason
|
|
182
|
+
const fix = e instanceof GpuUnavailableError ? e.fix : null;
|
|
183
|
+
return { gpu: null, reason: `no usable WebGPU device: ${messageOf(e)}`, fix };
|
|
184
|
+
}
|
|
185
|
+
if (g.destroyed) {
|
|
186
|
+
gpu.accelerator.dispose();
|
|
187
|
+
return { gpu: null, reason: "the core was destroyed" };
|
|
188
|
+
}
|
|
189
|
+
const unsubscribe = onSnapshotsDropped(cy, (dropped) => {
|
|
190
|
+
for (const s of dropped) {
|
|
191
|
+
gpu.accelerator.release(s);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
const self = g.decision;
|
|
195
|
+
void gpu.lost.then(() => {
|
|
196
|
+
unsubscribe();
|
|
197
|
+
// The next call acquires a new device. A device the core's own destroy disposed also resolves `lost`, and
|
|
198
|
+
// a decision already replaced is left alone.
|
|
199
|
+
if (g.decision === self) {
|
|
200
|
+
g.decision = null;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
return { gpu, reason: null };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Why a run in this mode takes the CPU without asking for a device, so it can stay synchronous.
|
|
207
|
+
* @param mode - the caller's mode
|
|
208
|
+
* @returns the decision when it is already known to be the CPU, or null when a device has to be asked for
|
|
209
|
+
*/
|
|
210
|
+
export function cpuWithoutAsking(mode = "auto") {
|
|
211
|
+
if (mode === "off") {
|
|
212
|
+
return { gpu: null, reason: 'gpu: "off" was requested', fix: null };
|
|
213
|
+
}
|
|
214
|
+
if (override === null) {
|
|
215
|
+
return { gpu: null, reason: "WebGPU was disabled", fix: null };
|
|
216
|
+
}
|
|
217
|
+
if (loading === null && override === undefined) {
|
|
218
|
+
const none = noWebGpu();
|
|
219
|
+
if (none !== null) {
|
|
220
|
+
return { gpu: null, reason: none, fix: null };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return loaded === null || isProvider(loaded) ? null : { gpu: null, ...loaded };
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The core's device, acquiring one on first use and again after a loss. One device per core, reused by every call.
|
|
227
|
+
* The first call in the process loads @graphty/webgpu-graph-algorithms.
|
|
228
|
+
* @param cy - the core
|
|
229
|
+
* @param mode - the caller's mode
|
|
230
|
+
* @returns the device (null for the CPU) and the reason when null
|
|
231
|
+
* @throws Error under "require" when no device is available, and when the core was destroyed
|
|
232
|
+
*/
|
|
233
|
+
export async function gpuFor(cy, mode = "auto") {
|
|
234
|
+
let d = cpuWithoutAsking(mode);
|
|
235
|
+
if (d === null) {
|
|
236
|
+
// subscribed to the core's destroy before the first await, so a destroy during the wait is seen
|
|
237
|
+
const g = coreGpu(cy);
|
|
238
|
+
const pending = source();
|
|
239
|
+
const src = loaded ?? (await pending);
|
|
240
|
+
if (!isProvider(src)) {
|
|
241
|
+
d = { gpu: null, ...src };
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
if (g.destroyed) {
|
|
245
|
+
throw coreDestroyedError();
|
|
246
|
+
}
|
|
247
|
+
if (g.decision === null || g.by !== src) {
|
|
248
|
+
disposeWhenDecided(g.decision);
|
|
249
|
+
// deferred one tick so decide() sees its own promise in g.decision
|
|
250
|
+
g.decision = Promise.resolve().then(() => decide(cy, g, src));
|
|
251
|
+
g.by = src;
|
|
252
|
+
}
|
|
253
|
+
d = await g.decision;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (mode === "require" && d.gpu === null) {
|
|
257
|
+
throw new Error(`graphty: gpu: "require" but ${d.reason ?? "no device"}`);
|
|
258
|
+
}
|
|
259
|
+
return d;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Warns once per configuration when a graph at or above GPU_SIZE_FLOOR runs on the CPU for a reason the user could
|
|
263
|
+
* fix. Small graphs, gpu: "off" and reasons nobody can fix stay quiet.
|
|
264
|
+
* @param d - the decision the run started with
|
|
265
|
+
* @param nodeCount - the graph's node count
|
|
266
|
+
*/
|
|
267
|
+
export function warnIfFixable(d, nodeCount) {
|
|
268
|
+
if (warned || d.gpu !== null || d.fix === undefined || d.fix === null || nodeCount < GPU_SIZE_FLOOR) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
warned = true;
|
|
272
|
+
console.warn(`graphty: a ${nodeCount.toLocaleString("en-US")}-node graph ran on the CPU because ${d.reason ?? "no GPU"}. ` +
|
|
273
|
+
`To use the GPU: ${d.fix}. Pass gpu: "off" to run on the CPU without this warning.`);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* An accelerator that records whether any of its methods was called, so the run can report which implementation
|
|
277
|
+
* answered. The CPU packages' dispatchers choose the CPU silently when the options or the graph need it.
|
|
278
|
+
* @param acc - the accelerator
|
|
279
|
+
* @returns the recording accelerator and the flag reader
|
|
280
|
+
*/
|
|
281
|
+
export function recording(acc) {
|
|
282
|
+
let used = false;
|
|
283
|
+
const accelerator = new Proxy(acc, {
|
|
284
|
+
get(target, key, receiver) {
|
|
285
|
+
const v = Reflect.get(target, key, receiver);
|
|
286
|
+
if (typeof v !== "function" || key === "release" || key === "dispose") {
|
|
287
|
+
return v;
|
|
288
|
+
}
|
|
289
|
+
return (...args) => {
|
|
290
|
+
used = true;
|
|
291
|
+
return v.apply(target, args);
|
|
292
|
+
};
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
return { accelerator, used: () => used };
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* The backend report of a finished run.
|
|
299
|
+
* @param d - the decision the run started with
|
|
300
|
+
* @param usedGpu - whether the dispatcher called the accelerator
|
|
301
|
+
* @param why - the reason the dispatcher kept the work on the CPU, when it did
|
|
302
|
+
* @returns the report
|
|
303
|
+
*/
|
|
304
|
+
export function backendOf(d, usedGpu, why) {
|
|
305
|
+
if (d.gpu === null) {
|
|
306
|
+
return { ran: "cpu", reason: d.reason, device: null };
|
|
307
|
+
}
|
|
308
|
+
return usedGpu
|
|
309
|
+
? { ran: "gpu", reason: null, device: d.gpu.device }
|
|
310
|
+
: { ran: "cpu", reason: why, device: d.gpu.device };
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=gpu.js.map
|
package/dist/gpu.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu.js","sourceRoot":"","sources":["../src/gpu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The core methods that put graphs into Cytoscape and take them out: graphtyGenerate, graphtyDataset,
|
|
3
|
+
* graphtyImport and graphtyExport. Each loads its implementation (./samples.js or ./io.js, and with them the
|
|
4
|
+
* graph-samples or graph-io package) on its first call, so registering them costs a page nothing.
|
|
5
|
+
*/
|
|
6
|
+
import type { ImportInput, ImportReport } from "@graphty/graph-io";
|
|
7
|
+
import type { FetchDatasetOptions } from "@graphty/graph-samples";
|
|
8
|
+
import type { CollectionReturnValue } from "cytoscape";
|
|
9
|
+
import type { CytoscapeStylesheetRule, ExportFormat, ExportOptions, ImportFormat, ImportOptions } from "./io.js";
|
|
10
|
+
import type { GeneratorName, GeneratorOptions } from "./samples.js";
|
|
11
|
+
/** What graphtyGenerate and graphtyDataset add to the core. */
|
|
12
|
+
export interface AddedGraph {
|
|
13
|
+
/** The added nodes and edges. */
|
|
14
|
+
readonly elements: CollectionReturnValue;
|
|
15
|
+
/** Whether the graph is directed: pass it as `directed` to the algorithms. */
|
|
16
|
+
readonly directed: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** What graphtyImport adds to the core. */
|
|
19
|
+
export interface ImportedGraph extends AddedGraph {
|
|
20
|
+
/** The format the input was read as. */
|
|
21
|
+
readonly format: string;
|
|
22
|
+
/** graph-io's report: counts, warnings, and what could not be represented. */
|
|
23
|
+
readonly report: ImportReport;
|
|
24
|
+
/**
|
|
25
|
+
* With `styles: true`, the file's styles as a Cytoscape.js stylesheet whose every rule applies only to this
|
|
26
|
+
* import's elements (they hold its id in `data.graphty_import`). `applyStyles: true` has already appended it to
|
|
27
|
+
* the core's stylesheet; otherwise append it yourself, rule by rule:
|
|
28
|
+
* `for (const r of stylesheet) cy.style().selector(r.selector).style(r.style); cy.style().update()`.
|
|
29
|
+
* Absent without `styles`.
|
|
30
|
+
*/
|
|
31
|
+
readonly stylesheet?: CytoscapeStylesheetRule[];
|
|
32
|
+
}
|
|
33
|
+
/** The core methods `cytoscape.use(graphtyCytoscape)` adds for getting graphs in and out. */
|
|
34
|
+
export interface GraphtyGraphData {
|
|
35
|
+
/**
|
|
36
|
+
* Adds a generated graph: `cy.graphtyGenerate("barabasi-albert", { n: 500, m: 2, seed: 1 })`. Node ids are
|
|
37
|
+
* "0", "1", ... and edge ids "e0", "e1", ...; ground-truth columns (`community`, ...) become data fields and
|
|
38
|
+
* weights `data.weight`. Nodes are placed at the origin (run a layout next), except that a generator's
|
|
39
|
+
* coordinates (`positions: true` on the lattices; the geometric generators) become node positions, in the
|
|
40
|
+
* generator's own units. Throws, adding nothing, when the core already holds one of the graph's node ids.
|
|
41
|
+
*/
|
|
42
|
+
graphtyGenerate<N extends GeneratorName>(name: N, options: GeneratorOptions<N>): Promise<AddedGraph>;
|
|
43
|
+
/**
|
|
44
|
+
* Adds a sample dataset: `cy.graphtyDataset("karate")`, downloaded from graphty.app (`options.baseUrl` for a
|
|
45
|
+
* mirror of your own). Throws, adding nothing, when the core already holds one of the graph's node ids.
|
|
46
|
+
* `options.signal` cancels it: once aborted, it rejects with the signal's reason and adds nothing, whatever
|
|
47
|
+
* `options.fetch` does with the signal.
|
|
48
|
+
*/
|
|
49
|
+
graphtyDataset(name: string, options?: FetchDatasetOptions): Promise<AddedGraph>;
|
|
50
|
+
/**
|
|
51
|
+
* Adds the graph in a file: GEXF, GraphML, GML, DOT, Pajek, CSV, JSON, Neo4j, XGMML, CX2, CX, OBO or a
|
|
52
|
+
* Cytoscape session (`.cys`, as bytes). Every attribute becomes a data field, and positions in the file become
|
|
53
|
+
* node positions, the way up the program that wrote the file draws them (a yEd box's top-left corner is
|
|
54
|
+
* moved to its center). Throws, adding
|
|
55
|
+
* nothing, when the core already holds one of the graph's node ids.
|
|
56
|
+
* `{ styles: true }` also reads the file's colors, sizes, shapes, ... and returns them as `stylesheet`;
|
|
57
|
+
* `{ styles: true, applyStyles: true }` draws them too (the core needs `styleEnabled` when headless).
|
|
58
|
+
* Without `styles`, a GEXF `viz:color`, `viz:size`, `viz:shape` and `viz:thickness` also become data fields;
|
|
59
|
+
* these fields are deprecated and are removed in the next major release: use `styles: true`, which leaves
|
|
60
|
+
* them out of data and draws them through the stylesheet.
|
|
61
|
+
*/
|
|
62
|
+
graphtyImport(input: ImportInput | ArrayBuffer, format?: ImportFormat, options?: ImportOptions): Promise<ImportedGraph>;
|
|
63
|
+
/**
|
|
64
|
+
* Writes the graph as a file's text: every data field, each node's position and parent, and each edge's id, as
|
|
65
|
+
* far as the format holds them (`options.onLoss` hears about the rest). Hidden elements are written too. On a
|
|
66
|
+
* collection: its nodes, and those of its edges whose two ends are among them. `{ styles: true }` also writes
|
|
67
|
+
* how the core draws each element, so graphtyImport with `styles: true` draws the file the same.
|
|
68
|
+
*/
|
|
69
|
+
graphtyExport(format: ExportFormat, options?: ExportOptions): Promise<string>;
|
|
70
|
+
}
|
|
71
|
+
declare module "cytoscape" {
|
|
72
|
+
interface Core extends GraphtyGraphData {
|
|
73
|
+
}
|
|
74
|
+
interface CollectionAlgorithms {
|
|
75
|
+
/** Writes the collection's nodes, and its edges whose two ends are among them, as a file's text. */
|
|
76
|
+
graphtyExport: GraphtyGraphData["graphtyExport"];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
type Register = (type: string, name: string, registrant: unknown) => void;
|
|
80
|
+
/**
|
|
81
|
+
* Rejected by graphtyGenerate, graphtyDataset and graphtyImport when a node id of the new graph is already in the
|
|
82
|
+
* core; nothing is added. `name` is "IdTakenError", `code` is "E_ID_TAKEN" and `id` is the first clashing id.
|
|
83
|
+
*/
|
|
84
|
+
export declare class IdTakenError extends Error {
|
|
85
|
+
/** Always "E_ID_TAKEN". */
|
|
86
|
+
readonly code = "E_ID_TAKEN";
|
|
87
|
+
/** The first node id of the new graph that the core already holds. */
|
|
88
|
+
readonly id: string;
|
|
89
|
+
/**
|
|
90
|
+
* Creates the error.
|
|
91
|
+
* @param id - the clashing id
|
|
92
|
+
*/
|
|
93
|
+
constructor(id: string);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Registers graphtyGenerate, graphtyDataset, graphtyImport and graphtyExport.
|
|
97
|
+
* @param cytoscape - the cytoscape function
|
|
98
|
+
*/
|
|
99
|
+
export declare function registerGraphData(cytoscape: Register): void;
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=graph-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-data.d.ts","sourceRoot":"","sources":["../src/graph-data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAc,qBAAqB,EAA2B,MAAM,WAAW,CAAC;AAG5F,OAAO,KAAK,EAAE,uBAAuB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEjH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEpE,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACvB,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B;AAQD,2CAA2C;AAC3C,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC7C,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACnD;AAED,6FAA6F;AAC7F,MAAM,WAAW,gBAAgB;IAC7B;;;;;;OAMG;IACH,eAAe,CAAC,CAAC,SAAS,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACrG;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjF;;;;;;;;;;;OAWG;IACH,aAAa,CACT,KAAK,EAAE,WAAW,GAAG,WAAW,EAChC,MAAM,CAAC,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,aAAa,GACxB,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1B;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjF;AAED,OAAO,QAAQ,WAAW,CAAC;IAEvB,UAAU,IAAK,SAAQ,gBAAgB;KAAG;IAC1C,UAAU,oBAAoB;QAC1B,oGAAoG;QACpG,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;KACpD;CACJ;AAED,KAAK,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;AAE1E;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACnC,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;OAGG;gBACS,EAAE,EAAE,MAAM;CAQzB;AAuED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,GAAG,IAAI,CA8D3D"}
|