@flaxia/node 0.3.7 → 0.5.1

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.
Files changed (113) hide show
  1. package/README.md +43 -19
  2. package/dist/__tests__/consent-policy.test.d.ts +2 -0
  3. package/dist/__tests__/consent-policy.test.d.ts.map +1 -0
  4. package/dist/assets/VectorStoreEngine.js +140 -85
  5. package/dist/assets/ai-inference.js +336 -40
  6. package/dist/assets/container.js +368 -260
  7. package/dist/assets/egress-guard.js +174 -0
  8. package/dist/assets/image-process.js +184 -19
  9. package/dist/assets/nudenet.js +2 -2
  10. package/dist/assets/webgpuProbe.js +357 -0
  11. package/dist/client/SignalingClient.d.ts +6 -0
  12. package/dist/client/SignalingClient.d.ts.map +1 -1
  13. package/dist/client/__tests__/mobile-lifecycle.test.d.ts +2 -0
  14. package/dist/client/__tests__/mobile-lifecycle.test.d.ts.map +1 -0
  15. package/dist/client/mobile-lifecycle.d.ts +20 -0
  16. package/dist/client/mobile-lifecycle.d.ts.map +1 -0
  17. package/dist/consent/ConsentUI.d.ts +44 -5
  18. package/dist/consent/ConsentUI.d.ts.map +1 -1
  19. package/dist/consent/notice.d.ts +29 -0
  20. package/dist/consent/notice.d.ts.map +1 -0
  21. package/dist/consent/storage.d.ts +91 -7
  22. package/dist/consent/storage.d.ts.map +1 -1
  23. package/dist/executor/WorkerPool.d.ts +42 -2
  24. package/dist/executor/WorkerPool.d.ts.map +1 -1
  25. package/dist/executor/__tests__/WorkerPool.swarm.test.d.ts +13 -0
  26. package/dist/executor/__tests__/WorkerPool.swarm.test.d.ts.map +1 -0
  27. package/dist/executor/__tests__/container-executor.test.d.ts +2 -0
  28. package/dist/executor/__tests__/container-executor.test.d.ts.map +1 -0
  29. package/dist/executor/__tests__/egress-guard.test.d.ts +2 -0
  30. package/dist/executor/__tests__/egress-guard.test.d.ts.map +1 -0
  31. package/dist/executor/__tests__/resourceReporter.test.d.ts +2 -0
  32. package/dist/executor/__tests__/resourceReporter.test.d.ts.map +1 -0
  33. package/dist/executor/__tests__/webgpuProbe.test.d.ts +2 -0
  34. package/dist/executor/__tests__/webgpuProbe.test.d.ts.map +1 -0
  35. package/dist/executor/container-executor.d.ts +49 -1
  36. package/dist/executor/container-executor.d.ts.map +1 -1
  37. package/dist/executor/egress-guard.d.ts +105 -0
  38. package/dist/executor/egress-guard.d.ts.map +1 -0
  39. package/dist/executor/memoryProbe.d.ts +30 -0
  40. package/dist/executor/memoryProbe.d.ts.map +1 -1
  41. package/dist/executor/resourceReporter.d.ts +15 -0
  42. package/dist/executor/resourceReporter.d.ts.map +1 -0
  43. package/dist/executor/throttle.d.ts +62 -4
  44. package/dist/executor/throttle.d.ts.map +1 -1
  45. package/dist/executor/webgpuProbe.d.ts +20 -0
  46. package/dist/executor/webgpuProbe.d.ts.map +1 -0
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +1423 -235
  50. package/dist/swarm/__tests__/adapter.test.d.ts +2 -0
  51. package/dist/swarm/__tests__/adapter.test.d.ts.map +1 -0
  52. package/dist/swarm/__tests__/controller.test.d.ts +2 -0
  53. package/dist/swarm/__tests__/controller.test.d.ts.map +1 -0
  54. package/dist/swarm/__tests__/defects.test.d.ts +16 -0
  55. package/dist/swarm/__tests__/defects.test.d.ts.map +1 -0
  56. package/dist/swarm/__tests__/hardening.test.d.ts +2 -0
  57. package/dist/swarm/__tests__/hardening.test.d.ts.map +1 -0
  58. package/dist/swarm/__tests__/peer-quality.test.d.ts +2 -0
  59. package/dist/swarm/__tests__/peer-quality.test.d.ts.map +1 -0
  60. package/dist/swarm/__tests__/peer-transport.test.d.ts +2 -0
  61. package/dist/swarm/__tests__/peer-transport.test.d.ts.map +1 -0
  62. package/dist/swarm/__tests__/runtime.test.d.ts +2 -0
  63. package/dist/swarm/__tests__/runtime.test.d.ts.map +1 -0
  64. package/dist/swarm/__tests__/session.test.d.ts +2 -0
  65. package/dist/swarm/__tests__/session.test.d.ts.map +1 -0
  66. package/dist/swarm/adapter.d.ts +115 -0
  67. package/dist/swarm/adapter.d.ts.map +1 -0
  68. package/dist/swarm/controller.d.ts +91 -0
  69. package/dist/swarm/controller.d.ts.map +1 -0
  70. package/dist/swarm/messages.d.ts +41 -0
  71. package/dist/swarm/messages.d.ts.map +1 -0
  72. package/dist/swarm/peer-quality.d.ts +14 -0
  73. package/dist/swarm/peer-quality.d.ts.map +1 -0
  74. package/dist/swarm/peer-transport.d.ts +81 -0
  75. package/dist/swarm/peer-transport.d.ts.map +1 -0
  76. package/dist/swarm/runtime.d.ts +20 -0
  77. package/dist/swarm/runtime.d.ts.map +1 -0
  78. package/dist/swarm/session.d.ts +73 -0
  79. package/dist/swarm/session.d.ts.map +1 -0
  80. package/dist/swarm-engine.js +7496 -0
  81. package/dist/vector-store/HNSWIndex.d.ts +30 -0
  82. package/dist/vector-store/HNSWIndex.d.ts.map +1 -1
  83. package/dist/vector-store/VectorStoreEngine.d.ts +43 -0
  84. package/dist/vector-store/VectorStoreEngine.d.ts.map +1 -1
  85. package/dist/vector-store/__tests__/HNSWIndex.test.d.ts +2 -0
  86. package/dist/vector-store/__tests__/HNSWIndex.test.d.ts.map +1 -0
  87. package/dist/vector-store/__tests__/VectorStoreEngine.test.d.ts +2 -0
  88. package/dist/vector-store/__tests__/VectorStoreEngine.test.d.ts.map +1 -0
  89. package/dist/worker/__tests__/main.worker.abort.test.d.ts +2 -0
  90. package/dist/worker/__tests__/main.worker.abort.test.d.ts.map +1 -0
  91. package/dist/worker/__tests__/main.worker.control.test.d.ts +2 -0
  92. package/dist/worker/__tests__/main.worker.control.test.d.ts.map +1 -0
  93. package/dist/worker.js +766 -67
  94. package/dist/workloads/__tests__/model-pipeline-cache.test.d.ts +2 -0
  95. package/dist/workloads/__tests__/model-pipeline-cache.test.d.ts.map +1 -0
  96. package/dist/workloads/__tests__/nudenet.test.d.ts +2 -0
  97. package/dist/workloads/__tests__/nudenet.test.d.ts.map +1 -0
  98. package/dist/workloads/ai-inference.d.ts +8 -1
  99. package/dist/workloads/ai-inference.d.ts.map +1 -1
  100. package/dist/workloads/ai-model-registry.d.ts +72 -0
  101. package/dist/workloads/ai-model-registry.d.ts.map +1 -0
  102. package/dist/workloads/container.d.ts +1 -1
  103. package/dist/workloads/container.d.ts.map +1 -1
  104. package/dist/workloads/image-process.d.ts +27 -0
  105. package/dist/workloads/image-process.d.ts.map +1 -1
  106. package/dist/workloads/model-pipeline-cache.d.ts +48 -0
  107. package/dist/workloads/model-pipeline-cache.d.ts.map +1 -0
  108. package/dist/workloads/nudenet.d.ts +8 -0
  109. package/dist/workloads/nudenet.d.ts.map +1 -1
  110. package/package.json +3 -2
  111. package/dist/assets/memoryProbe.js +0 -28
  112. package/dist/client/WebRTCPeer.d.ts +0 -8
  113. package/dist/client/WebRTCPeer.d.ts.map +0 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/adapter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=controller.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/controller.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Regression tests for the swarm node runtime, written from the
3
+ * feature/swarm-inference quality review and kept after the fixes landed.
4
+ *
5
+ * Every test here encodes the behaviour we WANT. Do not weaken a test in this
6
+ * file to make the suite green — if one of these starts failing, the defect it
7
+ * documents has come back.
8
+ *
9
+ * H2 the engine / GPU device must be disposed when a session ends
10
+ * M1 `maxNewTokens` and the prompt are validated against the model
11
+ * M2 a coordinator `swarm-error` settles the local session
12
+ * M4 the host result conforms to `SwarmInferenceResult`
13
+ * M6 malformed or stray hidden-state frames are never trusted
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=defects.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defects.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/defects.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hardening.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardening.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/hardening.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=peer-quality.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-quality.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/peer-quality.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=peer-transport.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-transport.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/peer-transport.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/runtime.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.test.d.ts","sourceRoot":"","sources":["../../../src/swarm/__tests__/session.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Minimal surface of one Pooled (SwarmLLM) engine slice that a swarm session
3
+ * drives. It mirrors the methods `Qwen35Engine` exposes in the vendored engine
4
+ * (`vendor/pooled/engine/qwen35.js`) so the same adapter works for a host slice
5
+ * (`hasEmbed`/`hasHead`) and a middle slice.
6
+ */
7
+ export interface SwarmEngineAdapter {
8
+ readonly dim: number;
9
+ readonly nc: number;
10
+ /** KV cache length of this slice; the session may not exceed it. */
11
+ readonly maxSeq?: number;
12
+ reset(): void;
13
+ /** Embed a single token into a hidden state (host slices only). */
14
+ embedRun(token: number, pos: number): Promise<Float32Array>;
15
+ /** Run a hidden state through this slice's layers. */
16
+ runHidden(hidden: Float32Array, pos: number): Promise<Float32Array>;
17
+ /** Final norm + LM head + logits (host slices only). */
18
+ headFromHidden(hidden: Float32Array): Promise<Float32Array>;
19
+ setHidden(hidden: Float32Array): void;
20
+ dispose(): void;
21
+ }
22
+ /** Config passed straight through to `Qwen35Engine.create`. */
23
+ export interface PooledEngineSliceConfig {
24
+ device: unknown;
25
+ meta: Record<string, unknown>;
26
+ layerRange: [number, number];
27
+ hasEmbed: boolean;
28
+ hasHead: boolean;
29
+ vocab: number;
30
+ maxSeq?: number;
31
+ batchCols?: number;
32
+ weights: unknown;
33
+ }
34
+ export interface RawPooledEngine {
35
+ dims: {
36
+ dim: number;
37
+ };
38
+ NC: number;
39
+ maxSeq?: number;
40
+ reset(): void;
41
+ embedRun(token: number, pos: number): Promise<Float32Array>;
42
+ runHidden(hidden: Float32Array, pos: number): Promise<Float32Array>;
43
+ headFromHidden(hidden: Float32Array): Promise<Float32Array>;
44
+ setHidden(hidden: Float32Array): void;
45
+ dispose?(): void;
46
+ }
47
+ export interface PooledTensorInfo {
48
+ shape: number[];
49
+ byteOffset: number;
50
+ byteLength: number;
51
+ ggmlType: number;
52
+ }
53
+ export interface PooledGguf {
54
+ meta: Record<string, unknown>;
55
+ tensors: Record<string, PooledTensorInfo>;
56
+ /** Set to stream Q4_0/Q8_0 matrices straight into GPU buffers. */
57
+ streamEntry?: (info: PooledTensorInfo) => Promise<unknown>;
58
+ }
59
+ export interface PooledTokenizer {
60
+ vocab: Record<string, number>;
61
+ encode(text: string): number[];
62
+ decode(ids: number[]): string;
63
+ }
64
+ export interface PooledEngineModule {
65
+ Qwen35Engine: {
66
+ create(config: PooledEngineSliceConfig): Promise<RawPooledEngine>;
67
+ };
68
+ parseGGUFHeader(buffer: ArrayBuffer, options?: {
69
+ skipTokenizer?: boolean;
70
+ }): PooledGguf;
71
+ qwen35Weights(gguf: PooledGguf, bytesOf: (info: PooledTensorInfo) => Promise<Uint8Array>, options: {
72
+ lo: number;
73
+ hi: number;
74
+ hasEmbed: boolean;
75
+ hasHead: boolean;
76
+ mtp?: boolean;
77
+ }, onProgress?: (bytes: number) => void, onEntry?: (entry: unknown, name: string) => void): Promise<unknown>;
78
+ tokenizerFromGGUF(meta: Record<string, unknown>): unknown;
79
+ makeTokenizer(vocab: unknown): PooledTokenizer;
80
+ argmax(logits: Float32Array): number;
81
+ f32ToF16(value: number): number;
82
+ f16ToF32(value: number): number;
83
+ /** Upload one converted entry with writeBuffer (large matrices cannot use mappedAtCreation). */
84
+ gpuUploadEntry(device: unknown, entry: unknown, keepCpu?: boolean): unknown;
85
+ /** Stream a Q4_0/Q8_0 tensor from a fetch Response straight into GPU buffers. */
86
+ streamEntryToGPU(device: unknown, info: PooledTensorInfo, openRange: (info: PooledTensorInfo) => Promise<Response>, options?: {
87
+ staging?: number;
88
+ }): Promise<unknown>;
89
+ GGML_EMBED: string;
90
+ }
91
+ export type EngineModuleImporter = (url: string) => Promise<unknown>;
92
+ export declare class SwarmEngineUnavailableError extends Error {
93
+ constructor(message: string);
94
+ }
95
+ /**
96
+ * Load the vendored engine module for a node's swarm slice. Fails fast with
97
+ * {@link SwarmEngineUnavailableError} when the context has no WebGPU adapter or
98
+ * the module does not look like the Pooled engine, so a node can report a clean
99
+ * capability failure instead of throwing deep inside an inference loop.
100
+ *
101
+ * The module URL is a runtime string (the engine ships as its own chunk), so the
102
+ * bundler must not try to resolve it statically; the injected importer keeps it
103
+ * testable without a browser.
104
+ */
105
+ export declare function loadPooledEngineModule(moduleUrl: string, importer?: EngineModuleImporter): Promise<PooledEngineModule>;
106
+ /**
107
+ * Wrap a raw Pooled engine slice in the stable adapter surface.
108
+ *
109
+ * `dispose()` releases the slice's own buffers *and* the GPU device it was
110
+ * created on: the runtime requests a fresh device per session, so leaving it
111
+ * alive would keep the whole model resident in the GPU on a worker that is
112
+ * reused for the next task. Calling it twice is a no-op.
113
+ */
114
+ export declare function wrapPooledEngine(engine: RawPooledEngine, device?: unknown, onDisposed?: () => void, checkDevice?: () => void): SwarmEngineAdapter;
115
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/swarm/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { type SwarmChainNode, type SwarmInitMessage, type SwarmMember, type SwarmSlice, type SwarmSliceMessage } from '@flaxia/sdk';
2
+ import type { SwarmEngineAdapter } from './adapter';
3
+ import { type SwarmSemantics } from './session';
4
+ import type { SwarmControlMessage } from './messages';
5
+ /**
6
+ * Model and tokenizer access the controller needs. `plan` runs on the host
7
+ * (it owns the metadata); `load` builds this node's engine slice. Both are
8
+ * injected so the controller is testable without a GPU or a model server.
9
+ */
10
+ export interface SwarmRuntime {
11
+ plan(members: SwarmMember[], model: string): Promise<SwarmChainNode[]>;
12
+ load(slice: SwarmSlice, model: string): Promise<{
13
+ engine: SwarmEngineAdapter;
14
+ semantics: SwarmSemantics;
15
+ warm?: boolean;
16
+ }>;
17
+ }
18
+ export interface SwarmControllerOptions {
19
+ /** First control message: `swarm-init` on the host, `swarm-slice` on a worker. */
20
+ initial: SwarmInitMessage | SwarmSliceMessage;
21
+ runtime: SwarmRuntime;
22
+ /** Worker -> main: a JSON control message for the coordinator. */
23
+ sendControl: (message: unknown) => void;
24
+ /** Worker -> main: a binary hidden-state frame for the coordinator. */
25
+ sendFrame: (frame: ArrayBuffer) => void;
26
+ /** Worker -> main: a streamed token. */
27
+ emitToken: (token: string) => unknown;
28
+ onDone: (result: unknown) => void;
29
+ onError: (error: string) => void;
30
+ }
31
+ /**
32
+ * Drives one node's part of a swarm session inside the Web Worker: the host
33
+ * plans the split then generates; a worker loads its slice and forwards frames.
34
+ * All I/O is through injected callbacks, so `self` never leaks in here.
35
+ *
36
+ * The controller owns one engine for the life of the session and disposes it
37
+ * when the session ends either way: a worker is reused for the next task, so an
38
+ * undisposed slice would keep its GPU buffers (and device) resident.
39
+ */
40
+ export declare class SwarmController {
41
+ private readonly options;
42
+ private frameHandler;
43
+ private engine;
44
+ private semantics;
45
+ private sessionId;
46
+ private model;
47
+ private chainLength;
48
+ private chain;
49
+ private slice;
50
+ private hostWarm;
51
+ private prompt;
52
+ private maxNewTokens;
53
+ private sliceLoaded;
54
+ private generationStarted;
55
+ private settled;
56
+ private flowPaused;
57
+ private flowWaiters;
58
+ constructor(options: SwarmControllerOptions);
59
+ start(): Promise<void>;
60
+ handleControl(message: SwarmControlMessage): Promise<void>;
61
+ handleFrame(frame: ArrayBuffer): void;
62
+ /**
63
+ * Stop the session because the coordinator settled the task elsewhere. Exactly
64
+ * like a failure this disposes the engine, so the GPU buffers and device do
65
+ * not stay resident on a device the scheduler has already moved on from.
66
+ */
67
+ abort(reason: string): void;
68
+ private link;
69
+ /**
70
+ * A slice message decides how much of the model this device materialises, so
71
+ * validate it even when it arrived through a path that already validated it:
72
+ * a hostile host must not be able to ask for a slice like `end = 1e9` (whole
73
+ * model in GPU memory) or claim a role/position that is not its own.
74
+ */
75
+ private validateSlice;
76
+ private loadSlice;
77
+ private startHost;
78
+ /**
79
+ * The chain this node planned (or, for a node that never saw the plan, its own
80
+ * slice) as `SwarmInferenceNodeInfo`s. Only this node can report its own
81
+ * warmth, so `warm` is filled in for the host entry alone.
82
+ */
83
+ private nodeInfos;
84
+ /** Release the engine (and its GPU device) exactly once, at session end. */
85
+ private teardown;
86
+ private finish;
87
+ private fail;
88
+ private waitForFlow;
89
+ private releaseFlowWaiters;
90
+ }
91
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/swarm/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAEnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAsE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACpH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACvE,IAAI,CACF,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,cAAc,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvF;AAED,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IAC9C,OAAO,EAAE,YAAY,CAAC;IACtB,kEAAkE;IAClE,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,uEAAuE;IACvE,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,wCAAwC;IACxC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAkBd,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBpC,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAO;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAyB;gBAEf,OAAO,EAAE,sBAAsB;IAEtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BtB,aAAa,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhE,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAKrC;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,IAAI;IASZ;;;;;OAKG;IACH,OAAO,CAAC,aAAa;YAuBP,SAAS;YA6BT,SAAS;IAsDvB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAcjB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,kBAAkB;CAI3B"}
@@ -0,0 +1,41 @@
1
+ import { type SwarmErrorMessage, type SwarmFlowMessage, type SwarmInitMessage, type SwarmSliceMessage, type SwarmStartMessage, type SwarmTransportMessage } from '@flaxia/sdk';
2
+ /** Swarm control messages the coordinator sends to a node. */
3
+ export type SwarmControlMessage = SwarmInitMessage | SwarmSliceMessage | SwarmStartMessage | SwarmErrorMessage | SwarmFlowMessage | SwarmTransportMessage;
4
+ /** Messages from the main thread into the swarm worker. */
5
+ export type SwarmWorkerInbound = {
6
+ id: string;
7
+ type: 'swarm-control';
8
+ message: SwarmControlMessage;
9
+ } | {
10
+ id: string;
11
+ type: 'swarm-frame';
12
+ frame: ArrayBuffer;
13
+ };
14
+ /** Messages the swarm worker sends back to the main thread. */
15
+ export type SwarmWorkerOutbound = {
16
+ id: string;
17
+ type: 'swarm-message';
18
+ message: unknown;
19
+ } | {
20
+ id: string;
21
+ type: 'swarm-frame';
22
+ frame: ArrayBuffer;
23
+ };
24
+ /**
25
+ * Structural validation for every control message a node accepts. The SDK
26
+ * validators check the fields the node relies on (slice bounds, chain position,
27
+ * hop keys, ids), so a malformed or hostile message is dropped before it can
28
+ * reach the engine or the layer loader.
29
+ */
30
+ export declare function isSwarmControlMessage(value: unknown): value is SwarmControlMessage;
31
+ export declare function isSwarmFrameMessage(value: unknown): value is {
32
+ id: string;
33
+ type: 'swarm-frame';
34
+ frame: ArrayBuffer;
35
+ };
36
+ export declare function isSwarmControlEnvelope(value: unknown): value is {
37
+ id: string;
38
+ type: 'swarm-control';
39
+ message: SwarmControlMessage;
40
+ };
41
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/swarm/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AAErB,8DAA8D;AAC9D,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,GACnE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5D,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CASlF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAIpH;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,CAI9E"}
@@ -0,0 +1,14 @@
1
+ import { type PeerQualityValue, type PeerQualityValues, type SwarmPeerQualityReport } from '@flaxia/sdk';
2
+ export declare const SWARM_PEER_QUALITY_SAMPLE_INTERVAL_MS = 15000;
3
+ export declare const SWARM_PEER_QUALITY_SAMPLE_WINDOW = 5;
4
+ /** Keep a short median window and ignore extreme high spikes before smoothing. */
5
+ export declare function smoothPeerQualitySamples(samples: readonly number[]): number[];
6
+ /** Convert counter deltas to decimal megabits per second. */
7
+ export declare function bytesPerSecondToMbps(bytes: number, elapsedMs: number): number | null;
8
+ export declare function createPeerQualityValue(samples: readonly number[], sampledAt: number): PeerQualityValue;
9
+ export declare function createUnknownPeerQualityValues(sampledAt: number): PeerQualityValues;
10
+ export declare function createSwarmPeerQualityReport(peerNodeId: string, sampledAt: number, webRtcSamples: Partial<Record<keyof PeerQualityValues, readonly number[]>>, applicationSamples: Partial<Record<keyof PeerQualityValues, readonly number[]>>, sampleTimes?: {
11
+ webRtc: Partial<Record<keyof PeerQualityValues, number>>;
12
+ application: Partial<Record<keyof PeerQualityValues, number>>;
13
+ }): SwarmPeerQualityReport;
14
+ //# sourceMappingURL=peer-quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-quality.d.ts","sourceRoot":"","sources":["../../src/swarm/peer-quality.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,qCAAqC,QAAS,CAAC;AAC5D,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAElD,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ7E;AAED,6DAA6D;AAC7D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,EAAE,MAAM,GAChB,gBAAgB,CASlB;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAGnF;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,EAC1E,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,EAC/E,WAAW,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,GACxI,sBAAsB,CAmBxB"}
@@ -0,0 +1,81 @@
1
+ import type { SwarmPeerQualityReport, SwarmPeerSignal, SwarmPeerSignalMessage } from '@flaxia/sdk';
2
+ export declare const SWARM_PEER_CONNECT_TIMEOUT_MS = 5000;
3
+ export declare const SWARM_PEER_FRAME_CHUNK_BYTES: number;
4
+ export declare const MAX_SWARM_PEER_FRAME_BYTES: number;
5
+ export declare const MAX_SWARM_PEER_BUFFERED_BYTES: number;
6
+ /** Split one ordered frame into bounded DataChannel packets. */
7
+ export declare function encodeSwarmPeerFrame(frame: ArrayBuffer, messageId: number): ArrayBuffer[];
8
+ /** Reassemble ordered or out-of-order chunks while bounding untrusted peer memory. */
9
+ export declare class SwarmPeerFrameReassembler {
10
+ private assemblies;
11
+ accept(packet: ArrayBuffer, now?: number): ArrayBuffer | null;
12
+ clear(): void;
13
+ private expire;
14
+ }
15
+ export interface SwarmPeerTransportOptions {
16
+ sessionId: string;
17
+ taskId: string;
18
+ attemptId: string;
19
+ nodeId: string;
20
+ previousNodeId?: string;
21
+ nextNodeId?: string;
22
+ onSignal: (toNodeId: string, signal: SwarmPeerSignal) => void;
23
+ onFrame: (frame: ArrayBuffer) => void;
24
+ onQuality?: (reports: SwarmPeerQualityReport[]) => void;
25
+ onFailure: (error: Error) => void;
26
+ createPeerConnection?: (configuration: RTCConfiguration) => RTCPeerConnection;
27
+ connectTimeoutMs?: number;
28
+ now?: () => number;
29
+ monotonicNow?: () => number;
30
+ }
31
+ /**
32
+ * One session's adjacent WebRTC data links. Each chain edge has one offerer;
33
+ * an open ordered DataChannel carries hidden frames in both directions. The
34
+ * coordinator selects relay globally if any member cannot open all of its links.
35
+ */
36
+ export declare class SwarmPeerTransport {
37
+ private readonly options;
38
+ private peers;
39
+ private reassembler;
40
+ private nextMessageId;
41
+ private mode;
42
+ private closed;
43
+ private failed;
44
+ private readyPromise;
45
+ private readyResolve;
46
+ private readyTimer;
47
+ private qualityTimer;
48
+ private samplingQuality;
49
+ constructor(options: SwarmPeerTransportOptions);
50
+ get selectedMode(): 'undecided' | 'peer' | 'relay';
51
+ start(): Promise<void>;
52
+ handleSignal(fromNodeId: string, signal: SwarmPeerSignal): Promise<void>;
53
+ waitUntilReady(timeoutMs?: number): Promise<boolean>;
54
+ selectMode(mode: 'peer' | 'relay'): void;
55
+ sendFrame(frame: ArrayBuffer): Promise<boolean>;
56
+ close(): void;
57
+ private bindChannel;
58
+ private allPeersOpen;
59
+ private resolveReadyIfOpen;
60
+ private resolveReady;
61
+ private unavailable;
62
+ private waitForBuffer;
63
+ private closePeerConnections;
64
+ private startQualitySampling;
65
+ private stopQualitySampling;
66
+ private wallNow;
67
+ private monotonicNow;
68
+ private recordQuality;
69
+ private sendQualityProbe;
70
+ private handleQualityProbe;
71
+ private samplePeerQuality;
72
+ private sampleWebRtc;
73
+ }
74
+ export declare function isCurrentSwarmPeerSignal(message: unknown, expected: {
75
+ taskId: string;
76
+ sessionId: string;
77
+ attemptId: string;
78
+ nodeId: string;
79
+ peers: string[];
80
+ }): message is SwarmPeerSignalMessage;
81
+ //# sourceMappingURL=peer-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-transport.d.ts","sourceRoot":"","sources":["../../src/swarm/peer-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type ModelCacheEntryStatus, type NodeModelCacheSnapshot, type SwarmSlice } from '@flaxia/sdk';
2
+ import { type PooledEngineModule, type PooledTokenizer } from './adapter';
3
+ import type { SwarmRuntime } from './controller';
4
+ import { type SwarmSemantics } from './session';
5
+ /** Describe the executable swarm slice; persistent CacheStorage weights are tracked separately. */
6
+ export declare function createSwarmModelCacheEntryStatus(modelId: string, slice: SwarmSlice, state: ModelCacheEntryStatus['state'], referenceCount: number): ModelCacheEntryStatus;
7
+ export declare function getSwarmModelCacheSnapshot(now?: number): NodeModelCacheSnapshot;
8
+ /**
9
+ * Resolve a task payload's `model` to the GGUF it loads.
10
+ *
11
+ * The payload is unvalidated API input: it must only ever match the registry
12
+ * above, never a caller-supplied URL, or every opted-in node could be made to
13
+ * range-fetch an arbitrary host of the submitter's choosing.
14
+ */
15
+ export declare function resolveModelUrl(model: string): string;
16
+ /** Range-fetch bytes, caching complete entries so a second start skips the network. */
17
+ export declare function rangeFetch(url: string, lo: number, hi: number): Promise<Uint8Array>;
18
+ export declare function buildSemantics(mod: PooledEngineModule, tok: PooledTokenizer): SwarmSemantics;
19
+ export declare function createSwarmRuntime(moduleLoader?: () => Promise<PooledEngineModule>): SwarmRuntime;
20
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/swarm/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAK3B,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,KAAK,kBAAkB,EAGvB,KAAK,eAAe,EACrB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAqCjE,mGAAmG;AACnG,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,EACrC,cAAc,EAAE,MAAM,GACrB,qBAAqB,CAavB;AAED,wBAAgB,0BAA0B,CAAC,GAAG,SAAa,GAAG,sBAAsB,CAenF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrD;AAuBD,uFAAuF;AACvF,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAMzF;AAoFD,wBAAgB,cAAc,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,eAAe,GAAG,cAAc,CA0C5F;AAED,wBAAgB,kBAAkB,CAChC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,GAC/C,YAAY,CAkHd"}
@@ -0,0 +1,73 @@
1
+ import type { SwarmEngineAdapter } from './adapter';
2
+ /**
3
+ * One swarm node's hidden-state link to the coordinator. Frames are opaque
4
+ * ArrayBuffers (see `encodeSwarmFrame`); the coordinator relays them around the
5
+ * chain without touching the payload.
6
+ */
7
+ export interface SwarmFrameLink {
8
+ send(frame: ArrayBuffer): void;
9
+ onFrame(handler: (frame: ArrayBuffer) => void): void;
10
+ }
11
+ /**
12
+ * The bits that depend on the model/tokenizer, injected so the session logic
13
+ * stays testable without a GPU: how to pack a hidden state to bytes, how to
14
+ * unpack it, and how to pick the next token from logits.
15
+ */
16
+ export interface SwarmSemantics {
17
+ /** Pack a hidden state to the f16 payload bytes carried by a frame. */
18
+ packHidden(hidden: Float32Array): Uint8Array;
19
+ /** Unpack a frame payload back to a hidden state. */
20
+ unpackHidden(payload: Uint8Array): Float32Array;
21
+ argmax(logits: Float32Array): number;
22
+ /** Tokenize the prompt (host only). */
23
+ encodePrompt?(text: string | string[]): number[];
24
+ /** Detokenize generated ids (host only). */
25
+ decodeTokens?(ids: number[]): string;
26
+ /** Stop as soon as this id is sampled (host only). */
27
+ eosIds?: Set<number>;
28
+ }
29
+ /**
30
+ * Ceiling on prompt + generated tokens a session may use. Enough context for
31
+ * chat prompts; KV memory grows with this on the attention layers the node
32
+ * holds, so keep it modest for crowd devices. A model with a smaller native
33
+ * context lowers it further when the slice is created.
34
+ */
35
+ export declare const SESSION_MAX_SEQ = 4096;
36
+ export interface SwarmHostOptions {
37
+ /** Number of nodes in the chain, including this host. */
38
+ chainLength: number;
39
+ /** Prompt token ids; the host tokenizes before starting. */
40
+ promptTokens: number[];
41
+ /** Maximum tokens to generate. */
42
+ maxNewTokens: number;
43
+ engine: SwarmEngineAdapter;
44
+ link: SwarmFrameLink;
45
+ semantics: SwarmSemantics;
46
+ /** Stop as soon as this id is sampled (it is not emitted). */
47
+ eosIds?: Set<number>;
48
+ /** Called with each generated token id as it is produced. */
49
+ onToken?: (id: number) => unknown;
50
+ }
51
+ export interface SwarmHostResult {
52
+ tokens: number[];
53
+ }
54
+ /**
55
+ * Drive a generation across the chain. The host embeds each token, ships the
56
+ * hidden state around the ring (each worker runs its slice and forwards), then
57
+ * runs the LM head and samples locally. With `chainLength === 1` the host is the
58
+ * whole model and no frames are sent.
59
+ */
60
+ export declare function runSwarmHost(options: SwarmHostOptions): Promise<SwarmHostResult>;
61
+ export interface SwarmWorkerOptions {
62
+ engine: SwarmEngineAdapter;
63
+ link: SwarmFrameLink;
64
+ semantics: SwarmSemantics;
65
+ }
66
+ /**
67
+ * Run one middle slice until the host's stop frame arrives. Each hidden frame
68
+ * is unpacked, run through this node's layers and forwarded around the ring.
69
+ * Resolves once the stop frame has been forwarded; rejects if a frame cannot be
70
+ * decoded, so a corrupt stream fails the session instead of hanging it.
71
+ */
72
+ export declare function runSwarmWorker(options: SwarmWorkerOptions): Promise<void>;
73
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/swarm/session.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAAC;IAC7C,qDAAqD;IACrD,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC;IACrC,uCAAuC;IACvC,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACjD,4CAA4C;IAC5C,YAAY,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACrC,sDAAsD;IACtD,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AA2EpC,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;IAC1B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyDtF;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCzE"}