@ruvector/ruvllm 2.7.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/GPU-LOOP.md +229 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +9 -0
  4. package/README.md +157 -263
  5. package/examples/gpu-loop.example.json +26 -0
  6. package/package.json +50 -120
  7. package/src/adapters-cli.mjs +23 -0
  8. package/src/adapters.mjs +91 -0
  9. package/src/cli.mjs +30 -0
  10. package/src/engine.mjs +238 -0
  11. package/src/fixture.mjs +38 -0
  12. package/src/gpu-host.mjs +47 -0
  13. package/src/gpu-loop-cli.mjs +67 -0
  14. package/src/gpu-loop.mjs +184 -0
  15. package/src/gpu-spool-adapter.mjs +80 -0
  16. package/src/vast-host-adapter.mjs +274 -0
  17. package/bin/cli.js +0 -1020
  18. package/dist/cjs/benchmarks/embedding-benchmark.d.ts +0 -102
  19. package/dist/cjs/benchmarks/embedding-benchmark.d.ts.map +0 -1
  20. package/dist/cjs/benchmarks/embedding-benchmark.js +0 -436
  21. package/dist/cjs/benchmarks/index.d.ts +0 -34
  22. package/dist/cjs/benchmarks/index.d.ts.map +0 -1
  23. package/dist/cjs/benchmarks/index.js +0 -132
  24. package/dist/cjs/benchmarks/model-comparison.d.ts +0 -71
  25. package/dist/cjs/benchmarks/model-comparison.d.ts.map +0 -1
  26. package/dist/cjs/benchmarks/model-comparison.js +0 -476
  27. package/dist/cjs/benchmarks/routing-benchmark.d.ts +0 -70
  28. package/dist/cjs/benchmarks/routing-benchmark.d.ts.map +0 -1
  29. package/dist/cjs/benchmarks/routing-benchmark.js +0 -289
  30. package/dist/cjs/contrastive.d.ts +0 -229
  31. package/dist/cjs/contrastive.d.ts.map +0 -1
  32. package/dist/cjs/contrastive.js +0 -589
  33. package/dist/cjs/engine.d.ts +0 -95
  34. package/dist/cjs/engine.d.ts.map +0 -1
  35. package/dist/cjs/engine.js +0 -372
  36. package/dist/cjs/export.d.ts +0 -182
  37. package/dist/cjs/export.d.ts.map +0 -1
  38. package/dist/cjs/export.js +0 -422
  39. package/dist/cjs/federated.d.ts +0 -233
  40. package/dist/cjs/federated.d.ts.map +0 -1
  41. package/dist/cjs/federated.js +0 -525
  42. package/dist/cjs/index.d.ts +0 -68
  43. package/dist/cjs/index.d.ts.map +0 -1
  44. package/dist/cjs/index.js +0 -104
  45. package/dist/cjs/intelligence.d.ts +0 -136
  46. package/dist/cjs/intelligence.d.ts.map +0 -1
  47. package/dist/cjs/intelligence.js +0 -226
  48. package/dist/cjs/lora.d.ts +0 -251
  49. package/dist/cjs/lora.d.ts.map +0 -1
  50. package/dist/cjs/lora.js +0 -509
  51. package/dist/cjs/models.d.ts +0 -129
  52. package/dist/cjs/models.d.ts.map +0 -1
  53. package/dist/cjs/models.js +0 -323
  54. package/dist/cjs/native.d.ts +0 -92
  55. package/dist/cjs/native.d.ts.map +0 -1
  56. package/dist/cjs/native.js +0 -77
  57. package/dist/cjs/session.d.ts +0 -80
  58. package/dist/cjs/session.d.ts.map +0 -1
  59. package/dist/cjs/session.js +0 -203
  60. package/dist/cjs/simd.d.ts +0 -90
  61. package/dist/cjs/simd.d.ts.map +0 -1
  62. package/dist/cjs/simd.js +0 -209
  63. package/dist/cjs/sona.d.ts +0 -223
  64. package/dist/cjs/sona.d.ts.map +0 -1
  65. package/dist/cjs/sona.js +0 -562
  66. package/dist/cjs/streaming.d.ts +0 -55
  67. package/dist/cjs/streaming.d.ts.map +0 -1
  68. package/dist/cjs/streaming.js +0 -131
  69. package/dist/cjs/training.d.ts +0 -312
  70. package/dist/cjs/training.d.ts.map +0 -1
  71. package/dist/cjs/training.js +0 -610
  72. package/dist/cjs/types.d.ts +0 -615
  73. package/dist/cjs/types.d.ts.map +0 -1
  74. package/dist/cjs/types.js +0 -6
  75. package/dist/esm/benchmarks/embedding-benchmark.d.ts +0 -102
  76. package/dist/esm/benchmarks/embedding-benchmark.d.ts.map +0 -1
  77. package/dist/esm/benchmarks/embedding-benchmark.js +0 -427
  78. package/dist/esm/benchmarks/index.d.ts +0 -34
  79. package/dist/esm/benchmarks/index.d.ts.map +0 -1
  80. package/dist/esm/benchmarks/index.js +0 -110
  81. package/dist/esm/benchmarks/model-comparison.d.ts +0 -71
  82. package/dist/esm/benchmarks/model-comparison.d.ts.map +0 -1
  83. package/dist/esm/benchmarks/model-comparison.js +0 -434
  84. package/dist/esm/benchmarks/routing-benchmark.d.ts +0 -70
  85. package/dist/esm/benchmarks/routing-benchmark.d.ts.map +0 -1
  86. package/dist/esm/benchmarks/routing-benchmark.js +0 -283
  87. package/dist/esm/contrastive.d.ts +0 -229
  88. package/dist/esm/contrastive.d.ts.map +0 -1
  89. package/dist/esm/contrastive.js +0 -578
  90. package/dist/esm/engine.d.ts +0 -95
  91. package/dist/esm/engine.d.ts.map +0 -1
  92. package/dist/esm/engine.js +0 -368
  93. package/dist/esm/export.d.ts +0 -182
  94. package/dist/esm/export.d.ts.map +0 -1
  95. package/dist/esm/export.js +0 -414
  96. package/dist/esm/federated.d.ts +0 -233
  97. package/dist/esm/federated.d.ts.map +0 -1
  98. package/dist/esm/federated.js +0 -520
  99. package/dist/esm/index.d.ts +0 -68
  100. package/dist/esm/index.d.ts.map +0 -1
  101. package/dist/esm/index.js +0 -84
  102. package/dist/esm/intelligence.d.ts +0 -136
  103. package/dist/esm/intelligence.d.ts.map +0 -1
  104. package/dist/esm/intelligence.js +0 -188
  105. package/dist/esm/lora.d.ts +0 -251
  106. package/dist/esm/lora.d.ts.map +0 -1
  107. package/dist/esm/lora.js +0 -504
  108. package/dist/esm/models.d.ts +0 -129
  109. package/dist/esm/models.d.ts.map +0 -1
  110. package/dist/esm/models.js +0 -282
  111. package/dist/esm/native.d.ts +0 -92
  112. package/dist/esm/native.d.ts.map +0 -1
  113. package/dist/esm/native.js +0 -72
  114. package/dist/esm/session.d.ts +0 -80
  115. package/dist/esm/session.d.ts.map +0 -1
  116. package/dist/esm/session.js +0 -199
  117. package/dist/esm/simd.d.ts +0 -90
  118. package/dist/esm/simd.d.ts.map +0 -1
  119. package/dist/esm/simd.js +0 -205
  120. package/dist/esm/sona.d.ts +0 -223
  121. package/dist/esm/sona.d.ts.map +0 -1
  122. package/dist/esm/sona.js +0 -556
  123. package/dist/esm/streaming.d.ts +0 -55
  124. package/dist/esm/streaming.d.ts.map +0 -1
  125. package/dist/esm/streaming.js +0 -126
  126. package/dist/esm/training.d.ts +0 -312
  127. package/dist/esm/training.d.ts.map +0 -1
  128. package/dist/esm/training.js +0 -603
  129. package/dist/esm/types.d.ts +0 -615
  130. package/dist/esm/types.d.ts.map +0 -1
  131. package/dist/esm/types.js +0 -5
  132. package/scripts/ensemble-model-compare.js +0 -287
  133. package/scripts/fix-esm-extensions.mjs +0 -181
  134. package/scripts/huggingface/README.md +0 -537
  135. package/scripts/huggingface/publish.sh +0 -112
  136. package/scripts/hybrid-model-compare.js +0 -373
  137. package/scripts/improved-model-compare.js +0 -288
  138. package/scripts/optimized-model-compare.js +0 -364
  139. package/scripts/real-model-compare.js +0 -280
  140. package/scripts/smoke-esm.mjs +0 -82
  141. package/scripts/training/agentic-flow-capabilities.json +0 -329
  142. package/scripts/training/claude-code-synth.js +0 -505
  143. package/scripts/training/claude-flow-capabilities.json +0 -1322
  144. package/scripts/training/claude-hard-negatives.js +0 -222
  145. package/scripts/training/contrastive-finetune.js +0 -517
  146. package/scripts/training/ecosystem-triplets.jsonl +0 -1467
  147. package/scripts/training/generate-ecosystem-triplets.js +0 -1324
  148. package/scripts/training/routing-dataset.js +0 -634
  149. package/scripts/training/ruvector-capabilities.json +0 -798
  150. package/scripts/training/validate-ecosystem.js +0 -381
  151. package/scripts/training/validation-results.json +0 -23
@@ -1,182 +0,0 @@
1
- /**
2
- * Export/Serialization for SONA Models
3
- *
4
- * Support for SafeTensors, JSON, and other export formats.
5
- *
6
- * @example
7
- * ```typescript
8
- * import { ModelExporter, SafeTensorsWriter } from '@ruvector/ruvllm';
9
- *
10
- * // Export model to SafeTensors format
11
- * const exporter = new ModelExporter();
12
- * const buffer = exporter.toSafeTensors({
13
- * weights: loraAdapter.getWeights(),
14
- * config: loraAdapter.getConfig(),
15
- * });
16
- *
17
- * // Save to file
18
- * fs.writeFileSync('model.safetensors', buffer);
19
- * ```
20
- */
21
- import { LoRAConfig, LearnedPattern, EwcStats, Embedding, ModelMetadata } from './types';
22
- import { LoraWeights } from './lora';
23
- /**
24
- * Exportable model data
25
- */
26
- export interface ExportableModel {
27
- /** Model metadata */
28
- metadata: ModelMetadata;
29
- /** LoRA weights (if applicable) */
30
- loraWeights?: LoraWeights;
31
- /** LoRA config */
32
- loraConfig?: LoRAConfig;
33
- /** Learned patterns */
34
- patterns?: LearnedPattern[];
35
- /** EWC statistics */
36
- ewcStats?: EwcStats;
37
- /** Raw tensors */
38
- tensors?: Map<string, Float32Array>;
39
- }
40
- /**
41
- * SafeTensors Writer
42
- *
43
- * Writes tensors in SafeTensors format for compatibility with
44
- * HuggingFace ecosystem.
45
- */
46
- export declare class SafeTensorsWriter {
47
- private tensors;
48
- private metadata;
49
- /**
50
- * Add a tensor
51
- */
52
- addTensor(name: string, data: Float32Array, shape: number[]): this;
53
- /**
54
- * Add 2D tensor from number array
55
- */
56
- add2D(name: string, data: number[][]): this;
57
- /**
58
- * Add 1D tensor from number array
59
- */
60
- add1D(name: string, data: number[]): this;
61
- /**
62
- * Add metadata
63
- */
64
- addMetadata(key: string, value: string): this;
65
- /**
66
- * Build SafeTensors buffer
67
- */
68
- build(): Uint8Array;
69
- /**
70
- * Clear all tensors and metadata
71
- */
72
- clear(): void;
73
- }
74
- /**
75
- * SafeTensors Reader
76
- *
77
- * Reads tensors from SafeTensors format.
78
- */
79
- export declare class SafeTensorsReader {
80
- private buffer;
81
- private header;
82
- private dataOffset;
83
- constructor(buffer: Uint8Array);
84
- /**
85
- * Get tensor names
86
- */
87
- getTensorNames(): string[];
88
- /**
89
- * Get tensor by name
90
- */
91
- getTensor(name: string): {
92
- data: Float32Array;
93
- shape: number[];
94
- } | null;
95
- /**
96
- * Get tensor as 2D array
97
- */
98
- getTensor2D(name: string): number[][] | null;
99
- /**
100
- * Get tensor as 1D array
101
- */
102
- getTensor1D(name: string): number[] | null;
103
- /**
104
- * Get metadata
105
- */
106
- getMetadata(): Record<string, string>;
107
- private parseHeader;
108
- }
109
- /**
110
- * Model Exporter
111
- *
112
- * Unified export interface for SONA models.
113
- */
114
- export declare class ModelExporter {
115
- /**
116
- * Export to SafeTensors format
117
- */
118
- toSafeTensors(model: ExportableModel): Uint8Array;
119
- /**
120
- * Export to JSON format
121
- */
122
- toJSON(model: ExportableModel): string;
123
- /**
124
- * Export to compact binary format
125
- */
126
- toBinary(model: ExportableModel): Uint8Array;
127
- /**
128
- * Export for HuggingFace Hub compatibility
129
- */
130
- toHuggingFace(model: ExportableModel): {
131
- safetensors: Uint8Array;
132
- config: string;
133
- readme: string;
134
- };
135
- }
136
- /**
137
- * Model Importer
138
- *
139
- * Import models from various formats.
140
- */
141
- export declare class ModelImporter {
142
- /**
143
- * Import from SafeTensors format
144
- */
145
- fromSafeTensors(buffer: Uint8Array): Partial<ExportableModel>;
146
- /**
147
- * Import from JSON format
148
- */
149
- fromJSON(json: string): Partial<ExportableModel>;
150
- /**
151
- * Import from binary format
152
- */
153
- fromBinary(buffer: Uint8Array): Partial<ExportableModel>;
154
- }
155
- /**
156
- * Dataset Exporter
157
- *
158
- * Export training data in various formats.
159
- */
160
- export declare class DatasetExporter {
161
- /**
162
- * Export to JSONL format (one JSON per line)
163
- */
164
- toJSONL(data: Array<{
165
- input: Embedding;
166
- output: Embedding;
167
- quality: number;
168
- }>): string;
169
- /**
170
- * Export to CSV format
171
- */
172
- toCSV(data: Array<{
173
- input: Embedding;
174
- output: Embedding;
175
- quality: number;
176
- }>): string;
177
- /**
178
- * Export patterns for pre-training
179
- */
180
- toPretrain(patterns: LearnedPattern[]): string;
181
- }
182
- //# sourceMappingURL=export.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/export.ts"],"names":[],"mappings":"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"}
@@ -1,422 +0,0 @@
1
- "use strict";
2
- /**
3
- * Export/Serialization for SONA Models
4
- *
5
- * Support for SafeTensors, JSON, and other export formats.
6
- *
7
- * @example
8
- * ```typescript
9
- * import { ModelExporter, SafeTensorsWriter } from '@ruvector/ruvllm';
10
- *
11
- * // Export model to SafeTensors format
12
- * const exporter = new ModelExporter();
13
- * const buffer = exporter.toSafeTensors({
14
- * weights: loraAdapter.getWeights(),
15
- * config: loraAdapter.getConfig(),
16
- * });
17
- *
18
- * // Save to file
19
- * fs.writeFileSync('model.safetensors', buffer);
20
- * ```
21
- */
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.DatasetExporter = exports.ModelImporter = exports.ModelExporter = exports.SafeTensorsReader = exports.SafeTensorsWriter = void 0;
24
- /**
25
- * SafeTensors Writer
26
- *
27
- * Writes tensors in SafeTensors format for compatibility with
28
- * HuggingFace ecosystem.
29
- */
30
- class SafeTensorsWriter {
31
- constructor() {
32
- this.tensors = new Map();
33
- this.metadata = {};
34
- }
35
- /**
36
- * Add a tensor
37
- */
38
- addTensor(name, data, shape) {
39
- this.tensors.set(name, { data, shape });
40
- return this;
41
- }
42
- /**
43
- * Add 2D tensor from number array
44
- */
45
- add2D(name, data) {
46
- const rows = data.length;
47
- const cols = data[0]?.length || 0;
48
- const flat = new Float32Array(rows * cols);
49
- for (let i = 0; i < rows; i++) {
50
- for (let j = 0; j < cols; j++) {
51
- flat[i * cols + j] = data[i][j];
52
- }
53
- }
54
- return this.addTensor(name, flat, [rows, cols]);
55
- }
56
- /**
57
- * Add 1D tensor from number array
58
- */
59
- add1D(name, data) {
60
- return this.addTensor(name, new Float32Array(data), [data.length]);
61
- }
62
- /**
63
- * Add metadata
64
- */
65
- addMetadata(key, value) {
66
- this.metadata[key] = value;
67
- return this;
68
- }
69
- /**
70
- * Build SafeTensors buffer
71
- */
72
- build() {
73
- // Build header
74
- const header = {};
75
- let offset = 0;
76
- const tensorData = [];
77
- for (const [name, { data, shape }] of this.tensors) {
78
- const bytes = new Uint8Array(data.buffer);
79
- const dataLength = bytes.length;
80
- header[name] = {
81
- dtype: 'F32',
82
- shape,
83
- data_offsets: [offset, offset + dataLength],
84
- };
85
- tensorData.push(bytes);
86
- offset += dataLength;
87
- }
88
- // Add metadata
89
- if (Object.keys(this.metadata).length > 0) {
90
- header['__metadata__'] = this.metadata;
91
- }
92
- // Encode header
93
- const headerJson = JSON.stringify(header);
94
- const headerBytes = new TextEncoder().encode(headerJson);
95
- // Pad header to 8-byte alignment
96
- const headerPadding = (8 - (headerBytes.length % 8)) % 8;
97
- const paddedHeaderLength = headerBytes.length + headerPadding;
98
- // Build final buffer
99
- const totalLength = 8 + paddedHeaderLength + offset;
100
- const buffer = new Uint8Array(totalLength);
101
- const view = new DataView(buffer.buffer);
102
- // Write header length (8 bytes, little-endian)
103
- view.setBigUint64(0, BigInt(paddedHeaderLength), true);
104
- // Write header
105
- buffer.set(headerBytes, 8);
106
- // Write tensor data
107
- let dataOffset = 8 + paddedHeaderLength;
108
- for (const data of tensorData) {
109
- buffer.set(data, dataOffset);
110
- dataOffset += data.length;
111
- }
112
- return buffer;
113
- }
114
- /**
115
- * Clear all tensors and metadata
116
- */
117
- clear() {
118
- this.tensors.clear();
119
- this.metadata = {};
120
- }
121
- }
122
- exports.SafeTensorsWriter = SafeTensorsWriter;
123
- /**
124
- * SafeTensors Reader
125
- *
126
- * Reads tensors from SafeTensors format.
127
- */
128
- class SafeTensorsReader {
129
- constructor(buffer) {
130
- this.header = {};
131
- this.dataOffset = 0;
132
- this.buffer = buffer;
133
- this.parseHeader();
134
- }
135
- /**
136
- * Get tensor names
137
- */
138
- getTensorNames() {
139
- return Object.keys(this.header).filter(k => k !== '__metadata__');
140
- }
141
- /**
142
- * Get tensor by name
143
- */
144
- getTensor(name) {
145
- const entry = this.header[name];
146
- if (!entry || typeof entry === 'object' && 'dtype' in entry === false) {
147
- return null;
148
- }
149
- const tensorHeader = entry;
150
- const [start, end] = tensorHeader.data_offsets;
151
- const bytes = this.buffer.slice(this.dataOffset + start, this.dataOffset + end);
152
- return {
153
- data: new Float32Array(bytes.buffer, bytes.byteOffset, bytes.length / 4),
154
- shape: tensorHeader.shape,
155
- };
156
- }
157
- /**
158
- * Get tensor as 2D array
159
- */
160
- getTensor2D(name) {
161
- const tensor = this.getTensor(name);
162
- if (!tensor || tensor.shape.length !== 2)
163
- return null;
164
- const [rows, cols] = tensor.shape;
165
- const result = [];
166
- for (let i = 0; i < rows; i++) {
167
- const row = [];
168
- for (let j = 0; j < cols; j++) {
169
- row.push(tensor.data[i * cols + j]);
170
- }
171
- result.push(row);
172
- }
173
- return result;
174
- }
175
- /**
176
- * Get tensor as 1D array
177
- */
178
- getTensor1D(name) {
179
- const tensor = this.getTensor(name);
180
- if (!tensor)
181
- return null;
182
- return Array.from(tensor.data);
183
- }
184
- /**
185
- * Get metadata
186
- */
187
- getMetadata() {
188
- const meta = this.header['__metadata__'];
189
- if (!meta || typeof meta !== 'object')
190
- return {};
191
- return meta;
192
- }
193
- parseHeader() {
194
- const view = new DataView(this.buffer.buffer, this.buffer.byteOffset);
195
- const headerLength = Number(view.getBigUint64(0, true));
196
- const headerBytes = this.buffer.slice(8, 8 + headerLength);
197
- const headerJson = new TextDecoder().decode(headerBytes);
198
- this.header = JSON.parse(headerJson.replace(/\0+$/, '')); // Remove padding nulls
199
- this.dataOffset = 8 + headerLength;
200
- }
201
- }
202
- exports.SafeTensorsReader = SafeTensorsReader;
203
- /**
204
- * Model Exporter
205
- *
206
- * Unified export interface for SONA models.
207
- */
208
- class ModelExporter {
209
- /**
210
- * Export to SafeTensors format
211
- */
212
- toSafeTensors(model) {
213
- const writer = new SafeTensorsWriter();
214
- // Add metadata
215
- writer.addMetadata('name', model.metadata.name);
216
- writer.addMetadata('version', model.metadata.version);
217
- writer.addMetadata('architecture', model.metadata.architecture);
218
- if (model.metadata.training) {
219
- writer.addMetadata('training_steps', String(model.metadata.training.steps));
220
- writer.addMetadata('training_loss', String(model.metadata.training.loss));
221
- }
222
- // Add LoRA weights
223
- if (model.loraWeights) {
224
- writer.add2D('lora.A', model.loraWeights.loraA);
225
- writer.add2D('lora.B', model.loraWeights.loraB);
226
- writer.add1D('lora.scaling', [model.loraWeights.scaling]);
227
- }
228
- // Add patterns as embeddings
229
- if (model.patterns && model.patterns.length > 0) {
230
- const embeddings = model.patterns.map(p => p.embedding);
231
- writer.add2D('patterns.embeddings', embeddings);
232
- const successRates = model.patterns.map(p => p.successRate);
233
- writer.add1D('patterns.success_rates', successRates);
234
- }
235
- // Add raw tensors
236
- if (model.tensors) {
237
- for (const [name, data] of model.tensors) {
238
- writer.addTensor(name, data, [data.length]);
239
- }
240
- }
241
- return writer.build();
242
- }
243
- /**
244
- * Export to JSON format
245
- */
246
- toJSON(model) {
247
- return JSON.stringify({
248
- metadata: model.metadata,
249
- loraConfig: model.loraConfig,
250
- loraWeights: model.loraWeights,
251
- patterns: model.patterns,
252
- ewcStats: model.ewcStats,
253
- }, null, 2);
254
- }
255
- /**
256
- * Export to compact binary format
257
- */
258
- toBinary(model) {
259
- const json = this.toJSON(model);
260
- const jsonBytes = new TextEncoder().encode(json);
261
- // Simple format: [4-byte length][json bytes]
262
- const buffer = new Uint8Array(4 + jsonBytes.length);
263
- const view = new DataView(buffer.buffer);
264
- view.setUint32(0, jsonBytes.length, true);
265
- buffer.set(jsonBytes, 4);
266
- return buffer;
267
- }
268
- /**
269
- * Export for HuggingFace Hub compatibility
270
- */
271
- toHuggingFace(model) {
272
- const safetensors = this.toSafeTensors(model);
273
- const config = JSON.stringify({
274
- model_type: 'sona-lora',
275
- ...model.metadata,
276
- lora_config: model.loraConfig,
277
- }, null, 2);
278
- const readme = `---
279
- license: mit
280
- tags:
281
- - sona
282
- - lora
283
- - ruvector
284
- ---
285
-
286
- # ${model.metadata.name}
287
-
288
- ${model.metadata.architecture} model trained with SONA adaptive learning.
289
-
290
- ## Usage
291
-
292
- \`\`\`typescript
293
- import { LoraAdapter, SafeTensorsReader } from '@ruvector/ruvllm';
294
-
295
- const reader = new SafeTensorsReader(buffer);
296
- const adapter = new LoraAdapter();
297
- adapter.setWeights({
298
- loraA: reader.getTensor2D('lora.A'),
299
- loraB: reader.getTensor2D('lora.B'),
300
- scaling: reader.getTensor1D('lora.scaling')[0],
301
- });
302
- \`\`\`
303
-
304
- ## Training Info
305
-
306
- - Steps: ${model.metadata.training?.steps || 'N/A'}
307
- - Final Loss: ${model.metadata.training?.loss || 'N/A'}
308
- `;
309
- return { safetensors, config, readme };
310
- }
311
- }
312
- exports.ModelExporter = ModelExporter;
313
- /**
314
- * Model Importer
315
- *
316
- * Import models from various formats.
317
- */
318
- class ModelImporter {
319
- /**
320
- * Import from SafeTensors format
321
- */
322
- fromSafeTensors(buffer) {
323
- const reader = new SafeTensorsReader(buffer);
324
- const metadata = reader.getMetadata();
325
- const result = {
326
- metadata: {
327
- name: metadata.name || 'unknown',
328
- version: metadata.version || '1.0.0',
329
- architecture: metadata.architecture || 'sona-lora',
330
- training: metadata.training_steps ? {
331
- steps: parseInt(metadata.training_steps),
332
- loss: parseFloat(metadata.training_loss || '0'),
333
- learningRate: 0,
334
- } : undefined,
335
- },
336
- };
337
- // Load LoRA weights
338
- const loraA = reader.getTensor2D('lora.A');
339
- const loraB = reader.getTensor2D('lora.B');
340
- const loraScaling = reader.getTensor1D('lora.scaling');
341
- if (loraA && loraB && loraScaling) {
342
- result.loraWeights = {
343
- loraA,
344
- loraB,
345
- scaling: loraScaling[0],
346
- };
347
- }
348
- // Load patterns
349
- const patternEmbeddings = reader.getTensor2D('patterns.embeddings');
350
- const patternRates = reader.getTensor1D('patterns.success_rates');
351
- if (patternEmbeddings && patternRates) {
352
- result.patterns = patternEmbeddings.map((embedding, i) => ({
353
- id: `imported-${i}`,
354
- type: 'query_response',
355
- embedding,
356
- successRate: patternRates[i] || 0,
357
- useCount: 0,
358
- lastUsed: new Date(),
359
- }));
360
- }
361
- return result;
362
- }
363
- /**
364
- * Import from JSON format
365
- */
366
- fromJSON(json) {
367
- return JSON.parse(json);
368
- }
369
- /**
370
- * Import from binary format
371
- */
372
- fromBinary(buffer) {
373
- const view = new DataView(buffer.buffer, buffer.byteOffset);
374
- const length = view.getUint32(0, true);
375
- const jsonBytes = buffer.slice(4, 4 + length);
376
- const json = new TextDecoder().decode(jsonBytes);
377
- return this.fromJSON(json);
378
- }
379
- }
380
- exports.ModelImporter = ModelImporter;
381
- /**
382
- * Dataset Exporter
383
- *
384
- * Export training data in various formats.
385
- */
386
- class DatasetExporter {
387
- /**
388
- * Export to JSONL format (one JSON per line)
389
- */
390
- toJSONL(data) {
391
- return data
392
- .map(item => JSON.stringify({
393
- input: item.input,
394
- output: item.output,
395
- quality: item.quality,
396
- }))
397
- .join('\n');
398
- }
399
- /**
400
- * Export to CSV format
401
- */
402
- toCSV(data) {
403
- const header = 'quality,input,output';
404
- const rows = data.map(item => `${item.quality},"${item.input.join(',')}","${item.output.join(',')}"`);
405
- return [header, ...rows].join('\n');
406
- }
407
- /**
408
- * Export patterns for pre-training
409
- */
410
- toPretrain(patterns) {
411
- return patterns
412
- .filter(p => p.successRate >= 0.7)
413
- .map(p => JSON.stringify({
414
- embedding: p.embedding,
415
- type: p.type,
416
- quality: p.successRate,
417
- }))
418
- .join('\n');
419
- }
420
- }
421
- exports.DatasetExporter = DatasetExporter;
422
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2V4cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7OztBQWdDSDs7Ozs7R0FLRztBQUNILE1BQWEsaUJBQWlCO0lBQTlCO1FBQ1UsWUFBTyxHQUF5RCxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFFLGFBQVEsR0FBMkIsRUFBRSxDQUFDO0lBMkdoRCxDQUFDO0lBekdDOztPQUVHO0lBQ0gsU0FBUyxDQUFDLElBQVksRUFBRSxJQUFrQixFQUFFLEtBQWU7UUFDekQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBWSxFQUFFLElBQWdCO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBRTNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUM5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQyxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8s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WixPQUFPLEVBQUUsQ0FBQyxDQUFDLFdBQVc7U0FDdkIsQ0FBQyxDQUFDO2FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hCLENBQUM7Q0FDRjtBQXRDRCwwQ0FzQ0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4cG9ydC9TZXJpYWxpemF0aW9uIGZvciBTT05BIE1vZGVsc1xuICpcbiAqIFN1cHBvcnQgZm9yIFNhZmVUZW5zb3JzLCBKU09OLCBhbmQgb3RoZXIgZXhwb3J0IGZvcm1hdHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IE1vZGVsRXhwb3J0ZXIsIFNhZmVUZW5zb3JzV3JpdGVyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogLy8gRXhwb3J0IG1vZGVsIHRvIFNhZmVUZW5zb3JzIGZvcm1hdFxuICogY29uc3QgZXhwb3J0ZXIgPSBuZXcgTW9kZWxFeHBvcnRlcigpO1xuICogY29uc3QgYnVmZmVyID0gZXhwb3J0ZXIudG9TYWZlVGVuc29ycyh7XG4gKiAgIHdlaWdodHM6IGxvcmFBZGFwdGVyLmdldFdlaWdodHMoKSxcbiAqICAgY29uZmlnOiBsb3JhQWRhcHRlci5nZXRDb25maWcoKSxcbiAqIH0pO1xuICpcbiAqIC8vIFNhdmUgdG8gZmlsZVxuICogZnMud3JpdGVGaWxlU3luYygnbW9kZWwuc2FmZXRlbnNvcnMnLCBidWZmZXIpO1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHsgTG9SQUNvbmZpZywgTGVhcm5lZFBhdHRlcm4sIEV3Y1N0YXRzLCBFbWJlZGRpbmcsIE1vZGVsTWV0YWRhdGEgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IExvcmFXZWlnaHRzIH0gZnJvbSAnLi9sb3JhJztcblxuLyoqXG4gKiBFeHBvcnRhYmxlIG1vZGVsIGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRhYmxlTW9kZWwge1xuICAvKiogTW9kZWwgbWV0YWRhdGEgKi9cbiAgbWV0YWRhdGE6IE1vZGVsTWV0YWRhdGE7XG4gIC8qKiBMb1JBIHdlaWdodHMgKGlmIGFwcGxpY2FibGUpICovXG4gIGxvcmFXZWlnaHRzPzogTG9yYVdlaWdodHM7XG4gIC8qKiBMb1JBIGNvbmZpZyAqL1xuICBsb3JhQ29uZmlnPzogTG9SQUNvbmZpZztcbiAgLyoqIExlYXJuZWQgcGF0dGVybnMgKi9cbiAgcGF0dGVybnM/OiBMZWFybmVkUGF0dGVybltdO1xuICAvKiogRVdDIHN0YXRpc3RpY3MgKi9cbiAgZXdjU3RhdHM/OiBFd2NTdGF0cztcbiAgLyoqIFJhdyB0ZW5zb3JzICovXG4gIHRlbnNvcnM/OiBNYXA8c3RyaW5nLCBGbG9hdDMyQXJyYXk+O1xufVxuXG4vKipcbiAqIFNhZmVUZW5zb3JzIGhlYWRlciBlbnRyeVxuICovXG5pbnRlcmZhY2UgU2FmZVRlbnNvcnNIZWFkZXIge1xuICBkdHlwZTogc3RyaW5nO1xuICBzaGFwZTogbnVtYmVyW107XG4gIGRhdGFfb2Zmc2V0czogW251bWJlciwgbnVtYmVyXTtcbn1cblxuLyoqXG4gKiBTYWZlVGVuc29ycyBXcml0ZXJcbiAqXG4gKiBXcml0ZXMgdGVuc29ycyBpbiBTYWZlVGVuc29ycyBmb3JtYXQgZm9yIGNvbXBhdGliaWxpdHkgd2l0aFxuICogSHVnZ2luZ0ZhY2UgZWNvc3lzdGVtLlxuICovXG5leHBvcnQgY2xhc3MgU2FmZVRlbnNvcnNXcml0ZXIge1xuICBwcml2YXRlIHRlbnNvcnM6IE1hcDxzdHJpbmcsIHsgZGF0YTogRmxvYXQzMkFycmF5OyBzaGFwZTogbnVtYmVyW10gfT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAvKipcbiAgICogQWRkIGEgdGVuc29yXG4gICAqL1xuICBhZGRUZW5zb3IobmFtZTogc3RyaW5nLCBkYXRhOiBGbG9hdDMyQXJyYXksIHNoYXBlOiBudW1iZXJbXSk6IHRoaXMge1xuICAgIHRoaXMudGVuc29ycy5zZXQobmFtZSwgeyBkYXRhLCBzaGFwZSB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgMkQgdGVuc29yIGZyb20gbnVtYmVyIGFycmF5XG4gICAqL1xuICBhZGQyRChuYW1lOiBzdHJpbmcsIGRhdGE6IG51bWJlcltdW10pOiB0aGlzIHtcbiAgICBjb25zdCByb3dzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY29scyA9IGRhdGFbMF0/Lmxlbmd0aCB8fCAwO1xuICAgIGNvbnN0IGZsYXQgPSBuZXcgRmxvYXQzMkFycmF5KHJvd3MgKiBjb2xzKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93czsgaSsrKSB7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHM7IGorKykge1xuICAgICAgICBmbGF0W2kgKiBjb2xzICsgal0gPSBkYXRhW2ldW2pdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFkZFRlbnNvcihuYW1lLCBmbGF0LCBbcm93cywgY29sc10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCAxRCB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXlcbiAgICovXG4gIGFkZDFEKG5hbWU6IHN0cmluZywgZGF0YTogbnVtYmVyW10pOiB0aGlzIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUZW5zb3IobmFtZSwgbmV3IEZsb2F0MzJBcnJheShkYXRhKSwgW2RhdGEubGVuZ3RoXSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIG1ldGFkYXRhXG4gICAqL1xuICBhZGRNZXRhZGF0YShrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMubWV0YWRhdGFba2V5XSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIFNhZmVUZW5zb3JzIGJ1ZmZlclxuICAgKi9cbiAgYnVpbGQoKTogVWludDhBcnJheSB7XG4gICAgLy8gQnVpbGQgaGVhZGVyXG4gICAgY29uc3QgaGVhZGVyOiBSZWNvcmQ8c3RyaW5nLCBTYWZlVGVuc29yc0hlYWRlciB8IFJlY29yZDxzdHJpbmcsIHN0cmluZz4+ID0ge307XG4gICAgbGV0IG9mZnNldCA9IDA7XG5cbiAgICBjb25zdCB0ZW5zb3JEYXRhOiBVaW50OEFycmF5W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHsgZGF0YSwgc2hhcGUgfV0gb2YgdGhpcy50ZW5zb3JzKSB7XG4gICAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyKTtcbiAgICAgIGNvbnN0IGRhdGFMZW5ndGggPSBieXRlcy5sZW5ndGg7XG5cbiAgICAgIGhlYWRlcltuYW1lXSA9IHtcbiAgICAgICAgZHR5cGU6ICdGMzInLFxuICAgICAgICBzaGFwZSxcbiAgICAgICAgZGF0YV9vZmZzZXRzOiBbb2Zmc2V0LCBvZmZzZXQgKyBkYXRhTGVuZ3RoXSxcbiAgICAgIH07XG5cbiAgICAgIHRlbnNvckRhdGEucHVzaChieXRlcyk7XG4gICAgICBvZmZzZXQgKz0gZGF0YUxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0YWRhdGFcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5tZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgaGVhZGVyWydfX21ldGFkYXRhX18nXSA9IHRoaXMubWV0YWRhdGE7XG4gICAgfVxuXG4gICAgLy8gRW5jb2RlIGhlYWRlclxuICAgIGNvbnN0IGhlYWRlckpzb24gPSBKU09OLnN0cmluZ2lmeShoZWFkZXIpO1xuICAgIGNvbnN0IGhlYWRlckJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGhlYWRlckpzb24pO1xuXG4gICAgLy8gUGFkIGhlYWRlciB0byA4LWJ5dGUgYWxpZ25tZW50XG4gICAgY29uc3QgaGVhZGVyUGFkZGluZyA9ICg4IC0gKGhlYWRlckJ5dGVzLmxlbmd0aCAlIDgpKSAlIDg7XG4gICAgY29uc3QgcGFkZGVkSGVhZGVyTGVuZ3RoID0gaGVhZGVyQnl0ZXMubGVuZ3RoICsgaGVhZGVyUGFkZGluZztcblxuICAgIC8vIEJ1aWxkIGZpbmFsIGJ1ZmZlclxuICAgIGNvbnN0IHRvdGFsTGVuZ3RoID0gOCArIHBhZGRlZEhlYWRlckxlbmd0aCArIG9mZnNldDtcbiAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG4gICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIuYnVmZmVyKTtcblxuICAgIC8vIFdyaXRlIGhlYWRlciBsZW5ndGggKDggYnl0ZXMsIGxpdHRsZS1lbmRpYW4pXG4gICAgdmlldy5zZXRCaWdVaW50NjQoMCwgQmlnSW50KHBhZGRlZEhlYWRlckxlbmd0aCksIHRydWUpO1xuXG4gICAgLy8gV3JpdGUgaGVhZGVyXG4gICAgYnVmZmVyLnNldChoZWFkZXJCeXRlcywgOCk7XG5cbiAgICAvLyBXcml0ZSB0ZW5zb3IgZGF0YVxuICAgIGxldCBkYXRhT2Zmc2V0ID0gOCArIHBhZGRlZEhlYWRlckxlbmd0aDtcbiAgICBmb3IgKGNvbnN0IGRhdGEgb2YgdGVuc29yRGF0YSkge1xuICAgICAgYnVmZmVyLnNldChkYXRhLCBkYXRhT2Zmc2V0KTtcbiAgICAgIGRhdGFPZmZzZXQgKz0gZGF0YS5sZW5ndGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgdGVuc29ycyBhbmQgbWV0YWRhdGFcbiAgICovXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMudGVuc29ycy5jbGVhcigpO1xuICAgIHRoaXMubWV0YWRhdGEgPSB7fTtcbiAgfVxufVxuXG4vKipcbiAqIFNhZmVUZW5zb3JzIFJlYWRlclxuICpcbiAqIFJlYWRzIHRlbnNvcnMgZnJvbSBTYWZlVGVuc29ycyBmb3JtYXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTYWZlVGVuc29yc1JlYWRlciB7XG4gIHByaXZhdGUgYnVmZmVyOiBVaW50OEFycmF5O1xuICBwcml2YXRlIGhlYWRlcjogUmVjb3JkPHN0cmluZywgU2FmZVRlbnNvcnNIZWFkZXIgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiA9IHt9O1xuICBwcml2YXRlIGRhdGFPZmZzZXQ6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoYnVmZmVyOiBVaW50OEFycmF5KSB7XG4gICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XG4gICAgdGhpcy5wYXJzZUhlYWRlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0ZW5zb3IgbmFtZXNcbiAgICovXG4gIGdldFRlbnNvck5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5oZWFkZXIpLmZpbHRlcihrID0+IGsgIT09ICdfX21ldGFkYXRhX18nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGVuc29yIGJ5IG5hbWVcbiAgICovXG4gIGdldFRlbnNvcihuYW1lOiBzdHJpbmcpOiB7IGRhdGE6IEZsb2F0MzJBcnJheTsgc2hhcGU6IG51bWJlcltdIH0gfCBudWxsIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuaGVhZGVyW25hbWVdO1xuICAgIGlmICghZW50cnkgfHwgdHlwZW9mIGVudHJ5ID09PSAnb2JqZWN0JyAmJiAnZHR5cGUnIGluIGVudHJ5ID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgdGVuc29ySGVhZGVyID0gZW50cnkgYXMgU2FmZVRlbnNvcnNIZWFkZXI7XG4gICAgY29uc3QgW3N0YXJ0LCBlbmRdID0gdGVuc29ySGVhZGVyLmRhdGFfb2Zmc2V0cztcbiAgICBjb25zdCBieXRlcyA9IHRoaXMuYnVmZmVyLnNsaWNlKHRoaXMuZGF0YU9mZnNldCArIHN0YXJ0LCB0aGlzLmRhdGFPZmZzZXQgKyBlbmQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IG5ldyBGbG9hdDMyQXJyYXkoYnl0ZXMuYnVmZmVyLCBieXRlcy5ieXRlT2Zmc2V0LCBieXRlcy5sZW5ndGggLyA0KSxcbiAgICAgIHNoYXBlOiB0ZW5zb3JIZWFkZXIuc2hhcGUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGVuc29yIGFzIDJEIGFycmF5XG4gICAqL1xuICBnZXRUZW5zb3IyRChuYW1lOiBzdHJpbmcpOiBudW1iZXJbXVtdIHwgbnVsbCB7XG4gICAgY29uc3QgdGVuc29yID0gdGhpcy5nZXRUZW5zb3IobmFtZSk7XG4gICAgaWYgKCF0ZW5zb3IgfHwgdGVuc29yLnNoYXBlLmxlbmd0aCAhPT0gMikgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBbcm93cywgY29sc10gPSB0ZW5zb3Iuc2hhcGU7XG4gICAgY29uc3QgcmVzdWx0OiBudW1iZXJbXVtdID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd3M7IGkrKykge1xuICAgICAgY29uc3Qgcm93OiBudW1iZXJbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2xzOyBqKyspIHtcbiAgICAgICAgcm93LnB1c2godGVuc29yLmRhdGFbaSAqIGNvbHMgKyBqXSk7XG4gICAgICB9XG4gICAgICByZXN1bHQucHVzaChyb3cpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRlbnNvciBhcyAxRCBhcnJheVxuICAgKi9cbiAgZ2V0VGVuc29yMUQobmFtZTogc3RyaW5nKTogbnVtYmVyW10gfCBudWxsIHtcbiAgICBjb25zdCB0ZW5zb3IgPSB0aGlzLmdldFRlbnNvcihuYW1lKTtcbiAgICBpZiAoIXRlbnNvcikgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGVuc29yLmRhdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBtZXRhZGF0YVxuICAgKi9cbiAgZ2V0TWV0YWRhdGEoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuaGVhZGVyWydfX21ldGFkYXRhX18nXTtcbiAgICBpZiAoIW1ldGEgfHwgdHlwZW9mIG1ldGEgIT09ICdvYmplY3QnKSByZXR1cm4ge307XG4gICAgcmV0dXJuIG1ldGEgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VIZWFkZXIoKTogdm9pZCB7XG4gICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyh0aGlzLmJ1ZmZlci5idWZmZXIsIHRoaXMuYnVmZmVyLmJ5dGVPZmZzZXQpO1xuICAgIGNvbnN0IGhlYWRlckxlbmd0aCA9IE51bWJlcih2aWV3LmdldEJpZ1VpbnQ2NCgwLCB0cnVlKSk7XG5cbiAgICBjb25zdCBoZWFkZXJCeXRlcyA9IHRoaXMuYnVmZmVyLnNsaWNlKDgsIDggKyBoZWFkZXJMZW5ndGgpO1xuICAgIGNvbnN0IGhlYWRlckpzb24gPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoaGVhZGVyQnl0ZXMpO1xuICAgIHRoaXMuaGVhZGVyID0gSlNPTi5wYXJzZShoZWFkZXJKc29uLnJlcGxhY2UoL1xcMCskLywgJycpKTsgLy8gUmVtb3ZlIHBhZGRpbmcgbnVsbHNcblxuICAgIHRoaXMuZGF0YU9mZnNldCA9IDggKyBoZWFkZXJMZW5ndGg7XG4gIH1cbn1cblxuLyoqXG4gKiBNb2RlbCBFeHBvcnRlclxuICpcbiAqIFVuaWZpZWQgZXhwb3J0IGludGVyZmFjZSBmb3IgU09OQSBtb2RlbHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbEV4cG9ydGVyIHtcbiAgLyoqXG4gICAqIEV4cG9ydCB0byBTYWZlVGVuc29ycyBmb3JtYXRcbiAgICovXG4gIHRvU2FmZVRlbnNvcnMobW9kZWw6IEV4cG9ydGFibGVNb2RlbCk6IFVpbnQ4QXJyYXkge1xuICAgIGNvbnN0IHdyaXRlciA9IG5ldyBTYWZlVGVuc29yc1dyaXRlcigpO1xuXG4gICAgLy8gQWRkIG1ldGFkYXRhXG4gICAgd3JpdGVyLmFkZE1ldGFkYXRhKCduYW1lJywgbW9kZWwubWV0YWRhdGEubmFtZSk7XG4gICAgd3JpdGVyLmFkZE1ldGFkYXRhKCd2ZXJzaW9uJywgbW9kZWwubWV0YWRhdGEudmVyc2lvbik7XG4gICAgd3JpdGVyLmFkZE1ldGFkYXRhKCdhcmNoaXRlY3R1cmUnLCBtb2RlbC5tZXRhZGF0YS5hcmNoaXRlY3R1cmUpO1xuXG4gICAgaWYgKG1vZGVsLm1ldGFkYXRhLnRyYWluaW5nKSB7XG4gICAgICB3cml0ZXIuYWRkTWV0YWRhdGEoJ3RyYWluaW5nX3N0ZXBzJywgU3RyaW5nKG1vZGVsLm1ldGFkYXRhLnRyYWluaW5nLnN0ZXBzKSk7XG4gICAgICB3cml0ZXIuYWRkTWV0YWRhdGEoJ3RyYWluaW5nX2xvc3MnLCBTdHJpbmcobW9kZWwubWV0YWRhdGEudHJhaW5pbmcubG9zcykpO1xuICAgIH1cblxuICAgIC8vIEFkZCBMb1JBIHdlaWdodHNcbiAgICBpZiAobW9kZWwubG9yYVdlaWdodHMpIHtcbiAgICAgIHdyaXRlci5hZGQyRCgnbG9yYS5BJywgbW9kZWwubG9yYVdlaWdodHMubG9yYUEpO1xuICAgICAgd3JpdGVyLmFkZDJEKCdsb3JhLkInLCBtb2RlbC5sb3JhV2VpZ2h0cy5sb3JhQik7XG4gICAgICB3cml0ZXIuYWRkMUQoJ2xvcmEuc2NhbGluZycsIFttb2RlbC5sb3JhV2VpZ2h0cy5zY2FsaW5nXSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHBhdHRlcm5zIGFzIGVtYmVkZGluZ3NcbiAgICBpZiAobW9kZWwucGF0dGVybnMgJiYgbW9kZWwucGF0dGVybnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZW1iZWRkaW5nczogbnVtYmVyW11bXSA9IG1vZGVsLnBhdHRlcm5zLm1hcChwID0+IHAuZW1iZWRkaW5nKTtcbiAgICAgIHdyaXRlci5hZGQyRCgncGF0dGVybnMuZW1iZWRkaW5ncycsIGVtYmVkZGluZ3MpO1xuXG4gICAgICBjb25zdCBzdWNjZXNzUmF0ZXMgPSBtb2RlbC5wYXR0ZXJucy5tYXAocCA9PiBwLnN1Y2Nlc3NSYXRlKTtcbiAgICAgIHdyaXRlci5hZGQxRCgncGF0dGVybnMuc3VjY2Vzc19yYXRlcycsIHN1Y2Nlc3NSYXRlcyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHJhdyB0ZW5zb3JzXG4gICAgaWYgKG1vZGVsLnRlbnNvcnMpIHtcbiAgICAgIGZvciAoY29uc3QgW25hbWUsIGRhdGFdIG9mIG1vZGVsLnRlbnNvcnMpIHtcbiAgICAgICAgd3JpdGVyLmFkZFRlbnNvcihuYW1lLCBkYXRhLCBbZGF0YS5sZW5ndGhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gd3JpdGVyLmJ1aWxkKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IHRvIEpTT04gZm9ybWF0XG4gICAqL1xuICB0b0pTT04obW9kZWw6IEV4cG9ydGFibGVNb2RlbCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIG1ldGFkYXRhOiBtb2RlbC5tZXRhZGF0YSxcbiAgICAgIGxvcmFDb25maWc6IG1vZGVsLmxvcmFDb25maWcsXG4gICAgICBsb3JhV2VpZ2h0czogbW9kZWwubG9yYVdlaWdodHMsXG4gICAgICBwYXR0ZXJuczogbW9kZWwucGF0dGVybnMsXG4gICAgICBld2NTdGF0czogbW9kZWwuZXdjU3RhdHMsXG4gICAgfSwgbnVsbCwgMik7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IHRvIGNvbXBhY3QgYmluYXJ5IGZvcm1hdFxuICAgKi9cbiAgdG9CaW5hcnkobW9kZWw6IEV4cG9ydGFibGVNb2RlbCk6IFVpbnQ4QXJyYXkge1xuICAgIGNvbnN0IGpzb24gPSB0aGlzLnRvSlNPTihtb2RlbCk7XG4gICAgY29uc3QganNvbkJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGpzb24pO1xuXG4gICAgLy8gU2ltcGxlIGZvcm1hdDogWzQtYnl0ZSBsZW5ndGhdW2pzb24gYnl0ZXNdXG4gICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoNCArIGpzb25CeXRlcy5sZW5ndGgpO1xuICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoYnVmZmVyLmJ1ZmZlcik7XG4gICAgdmlldy5zZXRVaW50MzIoMCwganNvbkJ5dGVzLmxlbmd0aCwgdHJ1ZSk7XG4gICAgYnVmZmVyLnNldChqc29uQnl0ZXMsIDQpO1xuXG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgZm9yIEh1Z2dpbmdGYWNlIEh1YiBjb21wYXRpYmlsaXR5XG4gICAqL1xuICB0b0h1Z2dpbmdGYWNlKG1vZGVsOiBFeHBvcnRhYmxlTW9kZWwpOiB7XG4gICAgc2FmZXRlbnNvcnM6IFVpbnQ4QXJyYXk7XG4gICAgY29uZmlnOiBzdHJpbmc7XG4gICAgcmVhZG1lOiBzdHJpbmc7XG4gIH0ge1xuICAgIGNvbnN0IHNhZmV0ZW5zb3JzID0gdGhpcy50b1NhZmVUZW5zb3JzKG1vZGVsKTtcblxuICAgIGNvbnN0IGNvbmZpZyA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIG1vZGVsX3R5cGU6ICdzb25hLWxvcmEnLFxuICAgICAgLi4ubW9kZWwubWV0YWRhdGEsXG4gICAgICBsb3JhX2NvbmZpZzogbW9kZWwubG9yYUNvbmZpZyxcbiAgICB9LCBudWxsLCAyKTtcblxuICAgIGNvbnN0IHJlYWRtZSA9IGAtLS1cbmxpY2Vuc2U6IG1pdFxudGFnczpcbi0gc29uYVxuLSBsb3JhXG4tIHJ1dmVjdG9yXG4tLS1cblxuIyAke21vZGVsLm1ldGFkYXRhLm5hbWV9XG5cbiR7bW9kZWwubWV0YWRhdGEuYXJjaGl0ZWN0dXJlfSBtb2RlbCB0cmFpbmVkIHdpdGggU09OQSBhZGFwdGl2ZSBsZWFybmluZy5cblxuIyMgVXNhZ2VcblxuXFxgXFxgXFxgdHlwZXNjcmlwdFxuaW1wb3J0IHsgTG9yYUFkYXB0ZXIsIFNhZmVUZW5zb3JzUmVhZGVyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG5cbmNvbnN0IHJlYWRlciA9IG5ldyBTYWZlVGVuc29yc1JlYWRlcihidWZmZXIpO1xuY29uc3QgYWRhcHRlciA9IG5ldyBMb3JhQWRhcHRlcigpO1xuYWRhcHRlci5zZXRXZWlnaHRzKHtcbiAgbG9yYUE6IHJlYWRlci5nZXRUZW5zb3IyRCgnbG9yYS5BJyksXG4gIGxvcmFCOiByZWFkZXIuZ2V0VGVuc29yMkQoJ2xvcmEuQicpLFxuICBzY2FsaW5nOiByZWFkZXIuZ2V0VGVuc29yMUQoJ2xvcmEuc2NhbGluZycpWzBdLFxufSk7XG5cXGBcXGBcXGBcblxuIyMgVHJhaW5pbmcgSW5mb1xuXG4tIFN0ZXBzOiAke21vZGVsLm1ldGFkYXRhLnRyYWluaW5nPy5zdGVwcyB8fCAnTi9BJ31cbi0gRmluYWwgTG9zczogJHttb2RlbC5tZXRhZGF0YS50cmFpbmluZz8ubG9zcyB8fCAnTi9BJ31cbmA7XG5cbiAgICByZXR1cm4geyBzYWZldGVuc29ycywgY29uZmlnLCByZWFkbWUgfTtcbiAgfVxufVxuXG4vKipcbiAqIE1vZGVsIEltcG9ydGVyXG4gKlxuICogSW1wb3J0IG1vZGVscyBmcm9tIHZhcmlvdXMgZm9ybWF0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vZGVsSW1wb3J0ZXIge1xuICAvKipcbiAgICogSW1wb3J0IGZyb20gU2FmZVRlbnNvcnMgZm9ybWF0XG4gICAqL1xuICBmcm9tU2FmZVRlbnNvcnMoYnVmZmVyOiBVaW50OEFycmF5KTogUGFydGlhbDxFeHBvcnRhYmxlTW9kZWw+IHtcbiAgICBjb25zdCByZWFkZXIgPSBuZXcgU2FmZVRlbnNvcnNSZWFkZXIoYnVmZmVyKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHJlYWRlci5nZXRNZXRhZGF0YSgpO1xuXG4gICAgY29uc3QgcmVzdWx0OiBQYXJ0aWFsPEV4cG9ydGFibGVNb2RlbD4gPSB7XG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICBuYW1lOiBtZXRhZGF0YS5uYW1lIHx8ICd1bmtub3duJyxcbiAgICAgICAgdmVyc2lvbjogbWV0YWRhdGEudmVyc2lvbiB8fCAnMS4wLjAnLFxuICAgICAgICBhcmNoaXRlY3R1cmU6IG1ldGFkYXRhLmFyY2hpdGVjdHVyZSB8fCAnc29uYS1sb3JhJyxcbiAgICAgICAgdHJhaW5pbmc6IG1ldGFkYXRhLnRyYWluaW5nX3N0ZXBzID8ge1xuICAgICAgICAgIHN0ZXBzOiBwYXJzZUludChtZXRhZGF0YS50cmFpbmluZ19zdGVwcyksXG4gICAgICAgICAgbG9zczogcGFyc2VGbG9hdChtZXRhZGF0YS50cmFpbmluZ19sb3NzIHx8ICcwJyksXG4gICAgICAgICAgbGVhcm5pbmdSYXRlOiAwLFxuICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gTG9hZCBMb1JBIHdlaWdodHNcbiAgICBjb25zdCBsb3JhQSA9IHJlYWRlci5nZXRUZW5zb3IyRCgnbG9yYS5BJyk7XG4gICAgY29uc3QgbG9yYUIgPSByZWFkZXIuZ2V0VGVuc29yMkQoJ2xvcmEuQicpO1xuICAgIGNvbnN0IGxvcmFTY2FsaW5nID0gcmVhZGVyLmdldFRlbnNvcjFEKCdsb3JhLnNjYWxpbmcnKTtcblxuICAgIGlmIChsb3JhQSAmJiBsb3JhQiAmJiBsb3JhU2NhbGluZykge1xuICAgICAgcmVzdWx0LmxvcmFXZWlnaHRzID0ge1xuICAgICAgICBsb3JhQSxcbiAgICAgICAgbG9yYUIsXG4gICAgICAgIHNjYWxpbmc6IGxvcmFTY2FsaW5nWzBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBMb2FkIHBhdHRlcm5zXG4gICAgY29uc3QgcGF0dGVybkVtYmVkZGluZ3MgPSByZWFkZXIuZ2V0VGVuc29yMkQoJ3BhdHRlcm5zLmVtYmVkZGluZ3MnKTtcbiAgICBjb25zdCBwYXR0ZXJuUmF0ZXMgPSByZWFkZXIuZ2V0VGVuc29yMUQoJ3BhdHRlcm5zLnN1Y2Nlc3NfcmF0ZXMnKTtcblxuICAgIGlmIChwYXR0ZXJuRW1iZWRkaW5ncyAmJiBwYXR0ZXJuUmF0ZXMpIHtcbiAgICAgIHJlc3VsdC5wYXR0ZXJucyA9IHBhdHRlcm5FbWJlZGRpbmdzLm1hcCgoZW1iZWRkaW5nLCBpKSA9PiAoe1xuICAgICAgICBpZDogYGltcG9ydGVkLSR7aX1gLFxuICAgICAgICB0eXBlOiAncXVlcnlfcmVzcG9uc2UnIGFzIGNvbnN0LFxuICAgICAgICBlbWJlZGRpbmcsXG4gICAgICAgIHN1Y2Nlc3NSYXRlOiBwYXR0ZXJuUmF0ZXNbaV0gfHwgMCxcbiAgICAgICAgdXNlQ291bnQ6IDAsXG4gICAgICAgIGxhc3RVc2VkOiBuZXcgRGF0ZSgpLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGZyb20gSlNPTiBmb3JtYXRcbiAgICovXG4gIGZyb21KU09OKGpzb246IHN0cmluZyk6IFBhcnRpYWw8RXhwb3J0YWJsZU1vZGVsPiB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoanNvbik7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGZyb20gYmluYXJ5IGZvcm1hdFxuICAgKi9cbiAgZnJvbUJpbmFyeShidWZmZXI6IFVpbnQ4QXJyYXkpOiBQYXJ0aWFsPEV4cG9ydGFibGVNb2RlbD4ge1xuICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoYnVmZmVyLmJ1ZmZlciwgYnVmZmVyLmJ5dGVPZmZzZXQpO1xuICAgIGNvbnN0IGxlbmd0aCA9IHZpZXcuZ2V0VWludDMyKDAsIHRydWUpO1xuICAgIGNvbnN0IGpzb25CeXRlcyA9IGJ1ZmZlci5zbGljZSg0LCA0ICsgbGVuZ3RoKTtcbiAgICBjb25zdCBqc29uID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGpzb25CeXRlcyk7XG4gICAgcmV0dXJuIHRoaXMuZnJvbUpTT04oanNvbik7XG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhc2V0IEV4cG9ydGVyXG4gKlxuICogRXhwb3J0IHRyYWluaW5nIGRhdGEgaW4gdmFyaW91cyBmb3JtYXRzLlxuICovXG5leHBvcnQgY2xhc3MgRGF0YXNldEV4cG9ydGVyIHtcbiAgLyoqXG4gICAqIEV4cG9ydCB0byBKU09OTCBmb3JtYXQgKG9uZSBKU09OIHBlciBsaW5lKVxuICAgKi9cbiAgdG9KU09OTChkYXRhOiBBcnJheTx7IGlucHV0OiBFbWJlZGRpbmc7IG91dHB1dDogRW1iZWRkaW5nOyBxdWFsaXR5OiBudW1iZXIgfT4pOiBzdHJpbmcge1xuICAgIHJldHVybiBkYXRhXG4gICAgICAubWFwKGl0ZW0gPT4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBpbnB1dDogaXRlbS5pbnB1dCxcbiAgICAgICAgb3V0cHV0OiBpdGVtLm91dHB1dCxcbiAgICAgICAgcXVhbGl0eTogaXRlbS5xdWFsaXR5LFxuICAgICAgfSkpXG4gICAgICAuam9pbignXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IHRvIENTViBmb3JtYXRcbiAgICovXG4gIHRvQ1NWKGRhdGE6IEFycmF5PHsgaW5wdXQ6IEVtYmVkZGluZzsgb3V0cHV0OiBFbWJlZGRpbmc7IHF1YWxpdHk6IG51bWJlciB9Pik6IHN0cmluZyB7XG4gICAgY29uc3QgaGVhZGVyID0gJ3F1YWxpdHksaW5wdXQsb3V0cHV0JztcbiAgICBjb25zdCByb3dzID0gZGF0YS5tYXAoaXRlbSA9PlxuICAgICAgYCR7aXRlbS5xdWFsaXR5fSxcIiR7aXRlbS5pbnB1dC5qb2luKCcsJyl9XCIsXCIke2l0ZW0ub3V0cHV0LmpvaW4oJywnKX1cImBcbiAgICApO1xuICAgIHJldHVybiBbaGVhZGVyLCAuLi5yb3dzXS5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgcGF0dGVybnMgZm9yIHByZS10cmFpbmluZ1xuICAgKi9cbiAgdG9QcmV0cmFpbihwYXR0ZXJuczogTGVhcm5lZFBhdHRlcm5bXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBhdHRlcm5zXG4gICAgICAuZmlsdGVyKHAgPT4gcC5zdWNjZXNzUmF0ZSA+PSAwLjcpXG4gICAgICAubWFwKHAgPT4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBlbWJlZGRpbmc6IHAuZW1iZWRkaW5nLFxuICAgICAgICB0eXBlOiBwLnR5cGUsXG4gICAgICAgIHF1YWxpdHk6IHAuc3VjY2Vzc1JhdGUsXG4gICAgICB9KSlcbiAgICAgIC5qb2luKCdcXG4nKTtcbiAgfVxufVxuIl19