@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.js';
22
- import { LoraWeights } from './lora.js';
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,414 +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
- /**
22
- * SafeTensors Writer
23
- *
24
- * Writes tensors in SafeTensors format for compatibility with
25
- * HuggingFace ecosystem.
26
- */
27
- export class SafeTensorsWriter {
28
- constructor() {
29
- this.tensors = new Map();
30
- this.metadata = {};
31
- }
32
- /**
33
- * Add a tensor
34
- */
35
- addTensor(name, data, shape) {
36
- this.tensors.set(name, { data, shape });
37
- return this;
38
- }
39
- /**
40
- * Add 2D tensor from number array
41
- */
42
- add2D(name, data) {
43
- const rows = data.length;
44
- const cols = data[0]?.length || 0;
45
- const flat = new Float32Array(rows * cols);
46
- for (let i = 0; i < rows; i++) {
47
- for (let j = 0; j < cols; j++) {
48
- flat[i * cols + j] = data[i][j];
49
- }
50
- }
51
- return this.addTensor(name, flat, [rows, cols]);
52
- }
53
- /**
54
- * Add 1D tensor from number array
55
- */
56
- add1D(name, data) {
57
- return this.addTensor(name, new Float32Array(data), [data.length]);
58
- }
59
- /**
60
- * Add metadata
61
- */
62
- addMetadata(key, value) {
63
- this.metadata[key] = value;
64
- return this;
65
- }
66
- /**
67
- * Build SafeTensors buffer
68
- */
69
- build() {
70
- // Build header
71
- const header = {};
72
- let offset = 0;
73
- const tensorData = [];
74
- for (const [name, { data, shape }] of this.tensors) {
75
- const bytes = new Uint8Array(data.buffer);
76
- const dataLength = bytes.length;
77
- header[name] = {
78
- dtype: 'F32',
79
- shape,
80
- data_offsets: [offset, offset + dataLength],
81
- };
82
- tensorData.push(bytes);
83
- offset += dataLength;
84
- }
85
- // Add metadata
86
- if (Object.keys(this.metadata).length > 0) {
87
- header['__metadata__'] = this.metadata;
88
- }
89
- // Encode header
90
- const headerJson = JSON.stringify(header);
91
- const headerBytes = new TextEncoder().encode(headerJson);
92
- // Pad header to 8-byte alignment
93
- const headerPadding = (8 - (headerBytes.length % 8)) % 8;
94
- const paddedHeaderLength = headerBytes.length + headerPadding;
95
- // Build final buffer
96
- const totalLength = 8 + paddedHeaderLength + offset;
97
- const buffer = new Uint8Array(totalLength);
98
- const view = new DataView(buffer.buffer);
99
- // Write header length (8 bytes, little-endian)
100
- view.setBigUint64(0, BigInt(paddedHeaderLength), true);
101
- // Write header
102
- buffer.set(headerBytes, 8);
103
- // Write tensor data
104
- let dataOffset = 8 + paddedHeaderLength;
105
- for (const data of tensorData) {
106
- buffer.set(data, dataOffset);
107
- dataOffset += data.length;
108
- }
109
- return buffer;
110
- }
111
- /**
112
- * Clear all tensors and metadata
113
- */
114
- clear() {
115
- this.tensors.clear();
116
- this.metadata = {};
117
- }
118
- }
119
- /**
120
- * SafeTensors Reader
121
- *
122
- * Reads tensors from SafeTensors format.
123
- */
124
- export class SafeTensorsReader {
125
- constructor(buffer) {
126
- this.header = {};
127
- this.dataOffset = 0;
128
- this.buffer = buffer;
129
- this.parseHeader();
130
- }
131
- /**
132
- * Get tensor names
133
- */
134
- getTensorNames() {
135
- return Object.keys(this.header).filter(k => k !== '__metadata__');
136
- }
137
- /**
138
- * Get tensor by name
139
- */
140
- getTensor(name) {
141
- const entry = this.header[name];
142
- if (!entry || typeof entry === 'object' && 'dtype' in entry === false) {
143
- return null;
144
- }
145
- const tensorHeader = entry;
146
- const [start, end] = tensorHeader.data_offsets;
147
- const bytes = this.buffer.slice(this.dataOffset + start, this.dataOffset + end);
148
- return {
149
- data: new Float32Array(bytes.buffer, bytes.byteOffset, bytes.length / 4),
150
- shape: tensorHeader.shape,
151
- };
152
- }
153
- /**
154
- * Get tensor as 2D array
155
- */
156
- getTensor2D(name) {
157
- const tensor = this.getTensor(name);
158
- if (!tensor || tensor.shape.length !== 2)
159
- return null;
160
- const [rows, cols] = tensor.shape;
161
- const result = [];
162
- for (let i = 0; i < rows; i++) {
163
- const row = [];
164
- for (let j = 0; j < cols; j++) {
165
- row.push(tensor.data[i * cols + j]);
166
- }
167
- result.push(row);
168
- }
169
- return result;
170
- }
171
- /**
172
- * Get tensor as 1D array
173
- */
174
- getTensor1D(name) {
175
- const tensor = this.getTensor(name);
176
- if (!tensor)
177
- return null;
178
- return Array.from(tensor.data);
179
- }
180
- /**
181
- * Get metadata
182
- */
183
- getMetadata() {
184
- const meta = this.header['__metadata__'];
185
- if (!meta || typeof meta !== 'object')
186
- return {};
187
- return meta;
188
- }
189
- parseHeader() {
190
- const view = new DataView(this.buffer.buffer, this.buffer.byteOffset);
191
- const headerLength = Number(view.getBigUint64(0, true));
192
- const headerBytes = this.buffer.slice(8, 8 + headerLength);
193
- const headerJson = new TextDecoder().decode(headerBytes);
194
- this.header = JSON.parse(headerJson.replace(/\0+$/, '')); // Remove padding nulls
195
- this.dataOffset = 8 + headerLength;
196
- }
197
- }
198
- /**
199
- * Model Exporter
200
- *
201
- * Unified export interface for SONA models.
202
- */
203
- export class ModelExporter {
204
- /**
205
- * Export to SafeTensors format
206
- */
207
- toSafeTensors(model) {
208
- const writer = new SafeTensorsWriter();
209
- // Add metadata
210
- writer.addMetadata('name', model.metadata.name);
211
- writer.addMetadata('version', model.metadata.version);
212
- writer.addMetadata('architecture', model.metadata.architecture);
213
- if (model.metadata.training) {
214
- writer.addMetadata('training_steps', String(model.metadata.training.steps));
215
- writer.addMetadata('training_loss', String(model.metadata.training.loss));
216
- }
217
- // Add LoRA weights
218
- if (model.loraWeights) {
219
- writer.add2D('lora.A', model.loraWeights.loraA);
220
- writer.add2D('lora.B', model.loraWeights.loraB);
221
- writer.add1D('lora.scaling', [model.loraWeights.scaling]);
222
- }
223
- // Add patterns as embeddings
224
- if (model.patterns && model.patterns.length > 0) {
225
- const embeddings = model.patterns.map(p => p.embedding);
226
- writer.add2D('patterns.embeddings', embeddings);
227
- const successRates = model.patterns.map(p => p.successRate);
228
- writer.add1D('patterns.success_rates', successRates);
229
- }
230
- // Add raw tensors
231
- if (model.tensors) {
232
- for (const [name, data] of model.tensors) {
233
- writer.addTensor(name, data, [data.length]);
234
- }
235
- }
236
- return writer.build();
237
- }
238
- /**
239
- * Export to JSON format
240
- */
241
- toJSON(model) {
242
- return JSON.stringify({
243
- metadata: model.metadata,
244
- loraConfig: model.loraConfig,
245
- loraWeights: model.loraWeights,
246
- patterns: model.patterns,
247
- ewcStats: model.ewcStats,
248
- }, null, 2);
249
- }
250
- /**
251
- * Export to compact binary format
252
- */
253
- toBinary(model) {
254
- const json = this.toJSON(model);
255
- const jsonBytes = new TextEncoder().encode(json);
256
- // Simple format: [4-byte length][json bytes]
257
- const buffer = new Uint8Array(4 + jsonBytes.length);
258
- const view = new DataView(buffer.buffer);
259
- view.setUint32(0, jsonBytes.length, true);
260
- buffer.set(jsonBytes, 4);
261
- return buffer;
262
- }
263
- /**
264
- * Export for HuggingFace Hub compatibility
265
- */
266
- toHuggingFace(model) {
267
- const safetensors = this.toSafeTensors(model);
268
- const config = JSON.stringify({
269
- model_type: 'sona-lora',
270
- ...model.metadata,
271
- lora_config: model.loraConfig,
272
- }, null, 2);
273
- const readme = `---
274
- license: mit
275
- tags:
276
- - sona
277
- - lora
278
- - ruvector
279
- ---
280
-
281
- # ${model.metadata.name}
282
-
283
- ${model.metadata.architecture} model trained with SONA adaptive learning.
284
-
285
- ## Usage
286
-
287
- \`\`\`typescript
288
- import { LoraAdapter, SafeTensorsReader } from '@ruvector/ruvllm';
289
-
290
- const reader = new SafeTensorsReader(buffer);
291
- const adapter = new LoraAdapter();
292
- adapter.setWeights({
293
- loraA: reader.getTensor2D('lora.A'),
294
- loraB: reader.getTensor2D('lora.B'),
295
- scaling: reader.getTensor1D('lora.scaling')[0],
296
- });
297
- \`\`\`
298
-
299
- ## Training Info
300
-
301
- - Steps: ${model.metadata.training?.steps || 'N/A'}
302
- - Final Loss: ${model.metadata.training?.loss || 'N/A'}
303
- `;
304
- return { safetensors, config, readme };
305
- }
306
- }
307
- /**
308
- * Model Importer
309
- *
310
- * Import models from various formats.
311
- */
312
- export class ModelImporter {
313
- /**
314
- * Import from SafeTensors format
315
- */
316
- fromSafeTensors(buffer) {
317
- const reader = new SafeTensorsReader(buffer);
318
- const metadata = reader.getMetadata();
319
- const result = {
320
- metadata: {
321
- name: metadata.name || 'unknown',
322
- version: metadata.version || '1.0.0',
323
- architecture: metadata.architecture || 'sona-lora',
324
- training: metadata.training_steps ? {
325
- steps: parseInt(metadata.training_steps),
326
- loss: parseFloat(metadata.training_loss || '0'),
327
- learningRate: 0,
328
- } : undefined,
329
- },
330
- };
331
- // Load LoRA weights
332
- const loraA = reader.getTensor2D('lora.A');
333
- const loraB = reader.getTensor2D('lora.B');
334
- const loraScaling = reader.getTensor1D('lora.scaling');
335
- if (loraA && loraB && loraScaling) {
336
- result.loraWeights = {
337
- loraA,
338
- loraB,
339
- scaling: loraScaling[0],
340
- };
341
- }
342
- // Load patterns
343
- const patternEmbeddings = reader.getTensor2D('patterns.embeddings');
344
- const patternRates = reader.getTensor1D('patterns.success_rates');
345
- if (patternEmbeddings && patternRates) {
346
- result.patterns = patternEmbeddings.map((embedding, i) => ({
347
- id: `imported-${i}`,
348
- type: 'query_response',
349
- embedding,
350
- successRate: patternRates[i] || 0,
351
- useCount: 0,
352
- lastUsed: new Date(),
353
- }));
354
- }
355
- return result;
356
- }
357
- /**
358
- * Import from JSON format
359
- */
360
- fromJSON(json) {
361
- return JSON.parse(json);
362
- }
363
- /**
364
- * Import from binary format
365
- */
366
- fromBinary(buffer) {
367
- const view = new DataView(buffer.buffer, buffer.byteOffset);
368
- const length = view.getUint32(0, true);
369
- const jsonBytes = buffer.slice(4, 4 + length);
370
- const json = new TextDecoder().decode(jsonBytes);
371
- return this.fromJSON(json);
372
- }
373
- }
374
- /**
375
- * Dataset Exporter
376
- *
377
- * Export training data in various formats.
378
- */
379
- export class DatasetExporter {
380
- /**
381
- * Export to JSONL format (one JSON per line)
382
- */
383
- toJSONL(data) {
384
- return data
385
- .map(item => JSON.stringify({
386
- input: item.input,
387
- output: item.output,
388
- quality: item.quality,
389
- }))
390
- .join('\n');
391
- }
392
- /**
393
- * Export to CSV format
394
- */
395
- toCSV(data) {
396
- const header = 'quality,input,output';
397
- const rows = data.map(item => `${item.quality},"${item.input.join(',')}","${item.output.join(',')}"`);
398
- return [header, ...rows].join('\n');
399
- }
400
- /**
401
- * Export patterns for pre-training
402
- */
403
- toPretrain(patterns) {
404
- return patterns
405
- .filter(p => p.successRate >= 0.7)
406
- .map(p => JSON.stringify({
407
- embedding: p.embedding,
408
- type: p.type,
409
- quality: p.successRate,
410
- }))
411
- .join('\n');
412
- }
413
- }
414
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2V4cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQWdDSDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxpQkFBaUI7SUFBOUI7UUFDVSxZQUFPLEdBQXlELElBQUksR0FBRyxFQUFFLENBQUM7UUFDMUUsYUFBUSxHQUEyQixFQUFFLENBQUM7SUEyR2hELENBQUM7SUF6R0M7O09BRUc7SUFDSCxTQUFTLENBQUMsSUFBWSxFQUFFLElBQWtCLEVBQUUsS0FBZTtRQUN6RCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN4QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFZLEVBQUUsSUFBZ0I7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN6QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFFM0MsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzlCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FB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dkIsQ0FBQyxDQUFDO2FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRXhwb3J0L1NlcmlhbGl6YXRpb24gZm9yIFNPTkEgTW9kZWxzXG4gKlxuICogU3VwcG9ydCBmb3IgU2FmZVRlbnNvcnMsIEpTT04sIGFuZCBvdGhlciBleHBvcnQgZm9ybWF0cy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgTW9kZWxFeHBvcnRlciwgU2FmZVRlbnNvcnNXcml0ZXIgfSBmcm9tICdAcnV2ZWN0b3IvcnV2bGxtJztcbiAqXG4gKiAvLyBFeHBvcnQgbW9kZWwgdG8gU2FmZVRlbnNvcnMgZm9ybWF0XG4gKiBjb25zdCBleHBvcnRlciA9IG5ldyBNb2RlbEV4cG9ydGVyKCk7XG4gKiBjb25zdCBidWZmZXIgPSBleHBvcnRlci50b1NhZmVUZW5zb3JzKHtcbiAqICAgd2VpZ2h0czogbG9yYUFkYXB0ZXIuZ2V0V2VpZ2h0cygpLFxuICogICBjb25maWc6IGxvcmFBZGFwdGVyLmdldENvbmZpZygpLFxuICogfSk7XG4gKlxuICogLy8gU2F2ZSB0byBmaWxlXG4gKiBmcy53cml0ZUZpbGVTeW5jKCdtb2RlbC5zYWZldGVuc29ycycsIGJ1ZmZlcik7XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgeyBMb1JBQ29uZmlnLCBMZWFybmVkUGF0dGVybiwgRXdjU3RhdHMsIEVtYmVkZGluZywgTW9kZWxNZXRhZGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgTG9yYVdlaWdodHMgfSBmcm9tICcuL2xvcmEnO1xuXG4vKipcbiAqIEV4cG9ydGFibGUgbW9kZWwgZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cG9ydGFibGVNb2RlbCB7XG4gIC8qKiBNb2RlbCBtZXRhZGF0YSAqL1xuICBtZXRhZGF0YTogTW9kZWxNZXRhZGF0YTtcbiAgLyoqIExvUkEgd2VpZ2h0cyAoaWYgYXBwbGljYWJsZSkgKi9cbiAgbG9yYVdlaWdodHM/OiBMb3JhV2VpZ2h0cztcbiAgLyoqIExvUkEgY29uZmlnICovXG4gIGxvcmFDb25maWc/OiBMb1JBQ29uZmlnO1xuICAvKiogTGVhcm5lZCBwYXR0ZXJucyAqL1xuICBwYXR0ZXJucz86IExlYXJuZWRQYXR0ZXJuW107XG4gIC8qKiBFV0Mgc3RhdGlzdGljcyAqL1xuICBld2NTdGF0cz86IEV3Y1N0YXRzO1xuICAvKiogUmF3IHRlbnNvcnMgKi9cbiAgdGVuc29ycz86IE1hcDxzdHJpbmcsIEZsb2F0MzJBcnJheT47XG59XG5cbi8qKlxuICogU2FmZVRlbnNvcnMgaGVhZGVyIGVudHJ5XG4gKi9cbmludGVyZmFjZSBTYWZlVGVuc29yc0hlYWRlciB7XG4gIGR0eXBlOiBzdHJpbmc7XG4gIHNoYXBlOiBudW1iZXJbXTtcbiAgZGF0YV9vZmZzZXRzOiBbbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKipcbiAqIFNhZmVUZW5zb3JzIFdyaXRlclxuICpcbiAqIFdyaXRlcyB0ZW5zb3JzIGluIFNhZmVUZW5zb3JzIGZvcm1hdCBmb3IgY29tcGF0aWJpbGl0eSB3aXRoXG4gKiBIdWdnaW5nRmFjZSBlY29zeXN0ZW0uXG4gKi9cbmV4cG9ydCBjbGFzcyBTYWZlVGVuc29yc1dyaXRlciB7XG4gIHByaXZhdGUgdGVuc29yczogTWFwPHN0cmluZywgeyBkYXRhOiBGbG9hdDMyQXJyYXk7IHNoYXBlOiBudW1iZXJbXSB9PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSB0ZW5zb3JcbiAgICovXG4gIGFkZFRlbnNvcihuYW1lOiBzdHJpbmcsIGRhdGE6IEZsb2F0MzJBcnJheSwgc2hhcGU6IG51bWJlcltdKTogdGhpcyB7XG4gICAgdGhpcy50ZW5zb3JzLnNldChuYW1lLCB7IGRhdGEsIHNoYXBlIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCAyRCB0ZW5zb3IgZnJvbSBudW1iZXIgYXJyYXlcbiAgICovXG4gIGFkZDJEKG5hbWU6IHN0cmluZywgZGF0YTogbnVtYmVyW11bXSk6IHRoaXMge1xuICAgIGNvbnN0IHJvd3MgPSBkYXRhLmxlbmd0aDtcbiAgICBjb25zdCBjb2xzID0gZGF0YVswXT8ubGVuZ3RoIHx8IDA7XG4gICAgY29uc3QgZmxhdCA9IG5ldyBGbG9hdDMyQXJyYXkocm93cyAqIGNvbHMpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sczsgaisrKSB7XG4gICAgICAgIGZsYXRbaSAqIGNvbHMgKyBqXSA9IGRhdGFbaV1bal07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRkVGVuc29yKG5hbWUsIGZsYXQsIFtyb3dzLCBjb2xzXSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIDFEIHRlbnNvciBmcm9tIG51bWJlciBhcnJheVxuICAgKi9cbiAgYWRkMUQobmFtZTogc3RyaW5nLCBkYXRhOiBudW1iZXJbXSk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzLmFkZFRlbnNvcihuYW1lLCBuZXcgRmxvYXQzMkFycmF5KGRhdGEpLCBbZGF0YS5sZW5ndGhdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgbWV0YWRhdGFcbiAgICovXG4gIGFkZE1ldGFkYXRhKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5tZXRhZGF0YVtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgU2FmZVRlbnNvcnMgYnVmZmVyXG4gICAqL1xuICBidWlsZCgpOiBVaW50OEFycmF5IHtcbiAgICAvLyBCdWlsZCBoZWFkZXJcbiAgICBjb25zdCBoZWFkZXI6IFJlY29yZDxzdHJpbmcsIFNhZmVUZW5zb3JzSGVhZGVyIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nPj4gPSB7fTtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcblxuICAgIGNvbnN0IHRlbnNvckRhdGE6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbbmFtZSwgeyBkYXRhLCBzaGFwZSB9XSBvZiB0aGlzLnRlbnNvcnMpIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIpO1xuICAgICAgY29uc3QgZGF0YUxlbmd0aCA9IGJ5dGVzLmxlbmd0aDtcblxuICAgICAgaGVhZGVyW25hbWVdID0ge1xuICAgICAgICBkdHlwZTogJ0YzMicsXG4gICAgICAgIHNoYXBlLFxuICAgICAgICBkYXRhX29mZnNldHM6IFtvZmZzZXQsIG9mZnNldCArIGRhdGFMZW5ndGhdLFxuICAgICAgfTtcblxuICAgICAgdGVuc29yRGF0YS5wdXNoKGJ5dGVzKTtcbiAgICAgIG9mZnNldCArPSBkYXRhTGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRhZGF0YVxuICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLm1ldGFkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgICBoZWFkZXJbJ19fbWV0YWRhdGFfXyddID0gdGhpcy5tZXRhZGF0YTtcbiAgICB9XG5cbiAgICAvLyBFbmNvZGUgaGVhZGVyXG4gICAgY29uc3QgaGVhZGVySnNvbiA9IEpTT04uc3RyaW5naWZ5KGhlYWRlcik7XG4gICAgY29uc3QgaGVhZGVyQnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoaGVhZGVySnNvbik7XG5cbiAgICAvLyBQYWQgaGVhZGVyIHRvIDgtYnl0ZSBhbGlnbm1lbnRcbiAgICBjb25zdCBoZWFkZXJQYWRkaW5nID0gKDggLSAoaGVhZGVyQnl0ZXMubGVuZ3RoICUgOCkpICUgODtcbiAgICBjb25zdCBwYWRkZWRIZWFkZXJMZW5ndGggPSBoZWFkZXJCeXRlcy5sZW5ndGggKyBoZWFkZXJQYWRkaW5nO1xuXG4gICAgLy8gQnVpbGQgZmluYWwgYnVmZmVyXG4gICAgY29uc3QgdG90YWxMZW5ndGggPSA4ICsgcGFkZGVkSGVhZGVyTGVuZ3RoICsgb2Zmc2V0O1xuICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KHRvdGFsTGVuZ3RoKTtcbiAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ1ZmZlci5idWZmZXIpO1xuXG4gICAgLy8gV3JpdGUgaGVhZGVyIGxlbmd0aCAoOCBieXRlcywgbGl0dGxlLWVuZGlhbilcbiAgICB2aWV3LnNldEJpZ1VpbnQ2NCgwLCBCaWdJbnQocGFkZGVkSGVhZGVyTGVuZ3RoKSwgdHJ1ZSk7XG5cbiAgICAvLyBXcml0ZSBoZWFkZXJcbiAgICBidWZmZXIuc2V0KGhlYWRlckJ5dGVzLCA4KTtcblxuICAgIC8vIFdyaXRlIHRlbnNvciBkYXRhXG4gICAgbGV0IGRhdGFPZmZzZXQgPSA4ICsgcGFkZGVkSGVhZGVyTGVuZ3RoO1xuICAgIGZvciAoY29uc3QgZGF0YSBvZiB0ZW5zb3JEYXRhKSB7XG4gICAgICBidWZmZXIuc2V0KGRhdGEsIGRhdGFPZmZzZXQpO1xuICAgICAgZGF0YU9mZnNldCArPSBkYXRhLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCB0ZW5zb3JzIGFuZCBtZXRhZGF0YVxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy50ZW5zb3JzLmNsZWFyKCk7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHt9O1xuICB9XG59XG5cbi8qKlxuICogU2FmZVRlbnNvcnMgUmVhZGVyXG4gKlxuICogUmVhZHMgdGVuc29ycyBmcm9tIFNhZmVUZW5zb3JzIGZvcm1hdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNhZmVUZW5zb3JzUmVhZGVyIHtcbiAgcHJpdmF0ZSBidWZmZXI6IFVpbnQ4QXJyYXk7XG4gIHByaXZhdGUgaGVhZGVyOiBSZWNvcmQ8c3RyaW5nLCBTYWZlVGVuc29yc0hlYWRlciB8IFJlY29yZDxzdHJpbmcsIHN0cmluZz4+ID0ge307XG4gIHByaXZhdGUgZGF0YU9mZnNldDogbnVtYmVyID0gMDtcblxuICBjb25zdHJ1Y3RvcihidWZmZXI6IFVpbnQ4QXJyYXkpIHtcbiAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICB0aGlzLnBhcnNlSGVhZGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRlbnNvciBuYW1lc1xuICAgKi9cbiAgZ2V0VGVuc29yTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmhlYWRlcikuZmlsdGVyKGsgPT4gayAhPT0gJ19fbWV0YWRhdGFfXycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0ZW5zb3IgYnkgbmFtZVxuICAgKi9cbiAgZ2V0VGVuc29yKG5hbWU6IHN0cmluZyk6IHsgZGF0YTogRmxvYXQzMkFycmF5OyBzaGFwZTogbnVtYmVyW10gfSB8IG51bGwge1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5oZWFkZXJbbmFtZV07XG4gICAgaWYgKCFlbnRyeSB8fCB0eXBlb2YgZW50cnkgPT09ICdvYmplY3QnICYmICdkdHlwZScgaW4gZW50cnkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW5zb3JIZWFkZXIgPSBlbnRyeSBhcyBTYWZlVGVuc29yc0hlYWRlcjtcbiAgICBjb25zdCBbc3RhcnQsIGVuZF0gPSB0ZW5zb3JIZWFkZXIuZGF0YV9vZmZzZXRzO1xuICAgIGNvbnN0IGJ5dGVzID0gdGhpcy5idWZmZXIuc2xpY2UodGhpcy5kYXRhT2Zmc2V0ICsgc3RhcnQsIHRoaXMuZGF0YU9mZnNldCArIGVuZCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbmV3IEZsb2F0MzJBcnJheShieXRlcy5idWZmZXIsIGJ5dGVzLmJ5dGVPZmZzZXQsIGJ5dGVzLmxlbmd0aCAvIDQpLFxuICAgICAgc2hhcGU6IHRlbnNvckhlYWRlci5zaGFwZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0ZW5zb3IgYXMgMkQgYXJyYXlcbiAgICovXG4gIGdldFRlbnNvcjJEKG5hbWU6IHN0cmluZyk6IG51bWJlcltdW10gfCBudWxsIHtcbiAgICBjb25zdCB0ZW5zb3IgPSB0aGlzLmdldFRlbnNvcihuYW1lKTtcbiAgICBpZiAoIXRlbnNvciB8fCB0ZW5zb3Iuc2hhcGUubGVuZ3RoICE9PSAyKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IFtyb3dzLCBjb2xzXSA9IHRlbnNvci5zaGFwZTtcbiAgICBjb25zdCByZXN1bHQ6IG51bWJlcltdW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93czsgaSsrKSB7XG4gICAgICBjb25zdCByb3c6IG51bWJlcltdID0gW107XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHM7IGorKykge1xuICAgICAgICByb3cucHVzaCh0ZW5zb3IuZGF0YVtpICogY29scyArIGpdKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wdXNoKHJvdyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGVuc29yIGFzIDFEIGFycmF5XG4gICAqL1xuICBnZXRUZW5zb3IxRChuYW1lOiBzdHJpbmcpOiBudW1iZXJbXSB8IG51bGwge1xuICAgIGNvbnN0IHRlbnNvciA9IHRoaXMuZ2V0VGVuc29yKG5hbWUpO1xuICAgIGlmICghdGVuc29yKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0ZW5zb3IuZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1ldGFkYXRhXG4gICAqL1xuICBnZXRNZXRhZGF0YSgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5oZWFkZXJbJ19fbWV0YWRhdGFfXyddO1xuICAgIGlmICghbWV0YSB8fCB0eXBlb2YgbWV0YSAhPT0gJ29iamVjdCcpIHJldHVybiB7fTtcbiAgICByZXR1cm4gbWV0YSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUhlYWRlcigpOiB2b2lkIHtcbiAgICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KHRoaXMuYnVmZmVyLmJ1ZmZlciwgdGhpcy5idWZmZXIuYnl0ZU9mZnNldCk7XG4gICAgY29uc3QgaGVhZGVyTGVuZ3RoID0gTnVtYmVyKHZpZXcuZ2V0QmlnVWludDY0KDAsIHRydWUpKTtcblxuICAgIGNvbnN0IGhlYWRlckJ5dGVzID0gdGhpcy5idWZmZXIuc2xpY2UoOCwgOCArIGhlYWRlckxlbmd0aCk7XG4gICAgY29uc3QgaGVhZGVySnNvbiA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShoZWFkZXJCeXRlcyk7XG4gICAgdGhpcy5oZWFkZXIgPSBKU09OLnBhcnNlKGhlYWRlckpzb24ucmVwbGFjZSgvXFwwKyQvLCAnJykpOyAvLyBSZW1vdmUgcGFkZGluZyBudWxsc1xuXG4gICAgdGhpcy5kYXRhT2Zmc2V0ID0gOCArIGhlYWRlckxlbmd0aDtcbiAgfVxufVxuXG4vKipcbiAqIE1vZGVsIEV4cG9ydGVyXG4gKlxuICogVW5pZmllZCBleHBvcnQgaW50ZXJmYWNlIGZvciBTT05BIG1vZGVscy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vZGVsRXhwb3J0ZXIge1xuICAvKipcbiAgICogRXhwb3J0IHRvIFNhZmVUZW5zb3JzIGZvcm1hdFxuICAgKi9cbiAgdG9TYWZlVGVuc29ycyhtb2RlbDogRXhwb3J0YWJsZU1vZGVsKTogVWludDhBcnJheSB7XG4gICAgY29uc3Qgd3JpdGVyID0gbmV3IFNhZmVUZW5zb3JzV3JpdGVyKCk7XG5cbiAgICAvLyBBZGQgbWV0YWRhdGFcbiAgICB3cml0ZXIuYWRkTWV0YWRhdGEoJ25hbWUnLCBtb2RlbC5tZXRhZGF0YS5uYW1lKTtcbiAgICB3cml0ZXIuYWRkTWV0YWRhdGEoJ3ZlcnNpb24nLCBtb2RlbC5tZXRhZGF0YS52ZXJzaW9uKTtcbiAgICB3cml0ZXIuYWRkTWV0YWRhdGEoJ2FyY2hpdGVjdHVyZScsIG1vZGVsLm1ldGFkYXRhLmFyY2hpdGVjdHVyZSk7XG5cbiAgICBpZiAobW9kZWwubWV0YWRhdGEudHJhaW5pbmcpIHtcbiAgICAgIHdyaXRlci5hZGRNZXRhZGF0YSgndHJhaW5pbmdfc3RlcHMnLCBTdHJpbmcobW9kZWwubWV0YWRhdGEudHJhaW5pbmcuc3RlcHMpKTtcbiAgICAgIHdyaXRlci5hZGRNZXRhZGF0YSgndHJhaW5pbmdfbG9zcycsIFN0cmluZyhtb2RlbC5tZXRhZGF0YS50cmFpbmluZy5sb3NzKSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIExvUkEgd2VpZ2h0c1xuICAgIGlmIChtb2RlbC5sb3JhV2VpZ2h0cykge1xuICAgICAgd3JpdGVyLmFkZDJEKCdsb3JhLkEnLCBtb2RlbC5sb3JhV2VpZ2h0cy5sb3JhQSk7XG4gICAgICB3cml0ZXIuYWRkMkQoJ2xvcmEuQicsIG1vZGVsLmxvcmFXZWlnaHRzLmxvcmFCKTtcbiAgICAgIHdyaXRlci5hZGQxRCgnbG9yYS5zY2FsaW5nJywgW21vZGVsLmxvcmFXZWlnaHRzLnNjYWxpbmddKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgcGF0dGVybnMgYXMgZW1iZWRkaW5nc1xuICAgIGlmIChtb2RlbC5wYXR0ZXJucyAmJiBtb2RlbC5wYXR0ZXJucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdID0gbW9kZWwucGF0dGVybnMubWFwKHAgPT4gcC5lbWJlZGRpbmcpO1xuICAgICAgd3JpdGVyLmFkZDJEKCdwYXR0ZXJucy5lbWJlZGRpbmdzJywgZW1iZWRkaW5ncyk7XG5cbiAgICAgIGNvbnN0IHN1Y2Nlc3NSYXRlcyA9IG1vZGVsLnBhdHRlcm5zLm1hcChwID0+IHAuc3VjY2Vzc1JhdGUpO1xuICAgICAgd3JpdGVyLmFkZDFEKCdwYXR0ZXJucy5zdWNjZXNzX3JhdGVzJywgc3VjY2Vzc1JhdGVzKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgcmF3IHRlbnNvcnNcbiAgICBpZiAobW9kZWwudGVuc29ycykge1xuICAgICAgZm9yIChjb25zdCBbbmFtZSwgZGF0YV0gb2YgbW9kZWwudGVuc29ycykge1xuICAgICAgICB3cml0ZXIuYWRkVGVuc29yKG5hbWUsIGRhdGEsIFtkYXRhLmxlbmd0aF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB3cml0ZXIuYnVpbGQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgdG8gSlNPTiBmb3JtYXRcbiAgICovXG4gIHRvSlNPTihtb2RlbDogRXhwb3J0YWJsZU1vZGVsKTogc3RyaW5nIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgbWV0YWRhdGE6IG1vZGVsLm1ldGFkYXRhLFxuICAgICAgbG9yYUNvbmZpZzogbW9kZWwubG9yYUNvbmZpZyxcbiAgICAgIGxvcmFXZWlnaHRzOiBtb2RlbC5sb3JhV2VpZ2h0cyxcbiAgICAgIHBhdHRlcm5zOiBtb2RlbC5wYXR0ZXJucyxcbiAgICAgIGV3Y1N0YXRzOiBtb2RlbC5ld2NTdGF0cyxcbiAgICB9LCBudWxsLCAyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgdG8gY29tcGFjdCBiaW5hcnkgZm9ybWF0XG4gICAqL1xuICB0b0JpbmFyeShtb2RlbDogRXhwb3J0YWJsZU1vZGVsKTogVWludDhBcnJheSB7XG4gICAgY29uc3QganNvbiA9IHRoaXMudG9KU09OKG1vZGVsKTtcbiAgICBjb25zdCBqc29uQnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoanNvbik7XG5cbiAgICAvLyBTaW1wbGUgZm9ybWF0OiBbNC1ieXRlIGxlbmd0aF1banNvbiBieXRlc11cbiAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSg0ICsganNvbkJ5dGVzLmxlbmd0aCk7XG4gICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIuYnVmZmVyKTtcbiAgICB2aWV3LnNldFVpbnQzMigwLCBqc29uQnl0ZXMubGVuZ3RoLCB0cnVlKTtcbiAgICBidWZmZXIuc2V0KGpzb25CeXRlcywgNCk7XG5cbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCBmb3IgSHVnZ2luZ0ZhY2UgSHViIGNvbXBhdGliaWxpdHlcbiAgICovXG4gIHRvSHVnZ2luZ0ZhY2UobW9kZWw6IEV4cG9ydGFibGVNb2RlbCk6IHtcbiAgICBzYWZldGVuc29yczogVWludDhBcnJheTtcbiAgICBjb25maWc6IHN0cmluZztcbiAgICByZWFkbWU6IHN0cmluZztcbiAgfSB7XG4gICAgY29uc3Qgc2FmZXRlbnNvcnMgPSB0aGlzLnRvU2FmZVRlbnNvcnMobW9kZWwpO1xuXG4gICAgY29uc3QgY29uZmlnID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgbW9kZWxfdHlwZTogJ3NvbmEtbG9yYScsXG4gICAgICAuLi5tb2RlbC5tZXRhZGF0YSxcbiAgICAgIGxvcmFfY29uZmlnOiBtb2RlbC5sb3JhQ29uZmlnLFxuICAgIH0sIG51bGwsIDIpO1xuXG4gICAgY29uc3QgcmVhZG1lID0gYC0tLVxubGljZW5zZTogbWl0XG50YWdzOlxuLSBzb25hXG4tIGxvcmFcbi0gcnV2ZWN0b3Jcbi0tLVxuXG4jICR7bW9kZWwubWV0YWRhdGEubmFtZX1cblxuJHttb2RlbC5tZXRhZGF0YS5hcmNoaXRlY3R1cmV9IG1vZGVsIHRyYWluZWQgd2l0aCBTT05BIGFkYXB0aXZlIGxlYXJuaW5nLlxuXG4jIyBVc2FnZVxuXG5cXGBcXGBcXGB0eXBlc2NyaXB0XG5pbXBvcnQgeyBMb3JhQWRhcHRlciwgU2FmZVRlbnNvcnNSZWFkZXIgfSBmcm9tICdAcnV2ZWN0b3IvcnV2bGxtJztcblxuY29uc3QgcmVhZGVyID0gbmV3IFNhZmVUZW5zb3JzUmVhZGVyKGJ1ZmZlcik7XG5jb25zdCBhZGFwdGVyID0gbmV3IExvcmFBZGFwdGVyKCk7XG5hZGFwdGVyLnNldFdlaWdodHMoe1xuICBsb3JhQTogcmVhZGVyLmdldFRlbnNvcjJEKCdsb3JhLkEnKSxcbiAgbG9yYUI6IHJlYWRlci5nZXRUZW5zb3IyRCgnbG9yYS5CJyksXG4gIHNjYWxpbmc6IHJlYWRlci5nZXRUZW5zb3IxRCgnbG9yYS5zY2FsaW5nJylbMF0sXG59KTtcblxcYFxcYFxcYFxuXG4jIyBUcmFpbmluZyBJbmZvXG5cbi0gU3RlcHM6ICR7bW9kZWwubWV0YWRhdGEudHJhaW5pbmc/LnN0ZXBzIHx8ICdOL0EnfVxuLSBGaW5hbCBMb3NzOiAke21vZGVsLm1ldGFkYXRhLnRyYWluaW5nPy5sb3NzIHx8ICdOL0EnfVxuYDtcblxuICAgIHJldHVybiB7IHNhZmV0ZW5zb3JzLCBjb25maWcsIHJlYWRtZSB9O1xuICB9XG59XG5cbi8qKlxuICogTW9kZWwgSW1wb3J0ZXJcbiAqXG4gKiBJbXBvcnQgbW9kZWxzIGZyb20gdmFyaW91cyBmb3JtYXRzLlxuICovXG5leHBvcnQgY2xhc3MgTW9kZWxJbXBvcnRlciB7XG4gIC8qKlxuICAgKiBJbXBvcnQgZnJvbSBTYWZlVGVuc29ycyBmb3JtYXRcbiAgICovXG4gIGZyb21TYWZlVGVuc29ycyhidWZmZXI6IFVpbnQ4QXJyYXkpOiBQYXJ0aWFsPEV4cG9ydGFibGVNb2RlbD4ge1xuICAgIGNvbnN0IHJlYWRlciA9IG5ldyBTYWZlVGVuc29yc1JlYWRlcihidWZmZXIpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gcmVhZGVyLmdldE1ldGFkYXRhKCk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFBhcnRpYWw8RXhwb3J0YWJsZU1vZGVsPiA9IHtcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIG5hbWU6IG1ldGFkYXRhLm5hbWUgfHwgJ3Vua25vd24nLFxuICAgICAgICB2ZXJzaW9uOiBtZXRhZGF0YS52ZXJzaW9uIHx8ICcxLjAuMCcsXG4gICAgICAgIGFyY2hpdGVjdHVyZTogbWV0YWRhdGEuYXJjaGl0ZWN0dXJlIHx8ICdzb25hLWxvcmEnLFxuICAgICAgICB0cmFpbmluZzogbWV0YWRhdGEudHJhaW5pbmdfc3RlcHMgPyB7XG4gICAgICAgICAgc3RlcHM6IHBhcnNlSW50KG1ldGFkYXRhLnRyYWluaW5nX3N0ZXBzKSxcbiAgICAgICAgICBsb3NzOiBwYXJzZUZsb2F0KG1ldGFkYXRhLnRyYWluaW5nX2xvc3MgfHwgJzAnKSxcbiAgICAgICAgICBsZWFybmluZ1JhdGU6IDAsXG4gICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICAvLyBMb2FkIExvUkEgd2VpZ2h0c1xuICAgIGNvbnN0IGxvcmFBID0gcmVhZGVyLmdldFRlbnNvcjJEKCdsb3JhLkEnKTtcbiAgICBjb25zdCBsb3JhQiA9IHJlYWRlci5nZXRUZW5zb3IyRCgnbG9yYS5CJyk7XG4gICAgY29uc3QgbG9yYVNjYWxpbmcgPSByZWFkZXIuZ2V0VGVuc29yMUQoJ2xvcmEuc2NhbGluZycpO1xuXG4gICAgaWYgKGxvcmFBICYmIGxvcmFCICYmIGxvcmFTY2FsaW5nKSB7XG4gICAgICByZXN1bHQubG9yYVdlaWdodHMgPSB7XG4gICAgICAgIGxvcmFBLFxuICAgICAgICBsb3JhQixcbiAgICAgICAgc2NhbGluZzogbG9yYVNjYWxpbmdbMF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIExvYWQgcGF0dGVybnNcbiAgICBjb25zdCBwYXR0ZXJuRW1iZWRkaW5ncyA9IHJlYWRlci5nZXRUZW5zb3IyRCgncGF0dGVybnMuZW1iZWRkaW5ncycpO1xuICAgIGNvbnN0IHBhdHRlcm5SYXRlcyA9IHJlYWRlci5nZXRUZW5zb3IxRCgncGF0dGVybnMuc3VjY2Vzc19yYXRlcycpO1xuXG4gICAgaWYgKHBhdHRlcm5FbWJlZGRpbmdzICYmIHBhdHRlcm5SYXRlcykge1xuICAgICAgcmVzdWx0LnBhdHRlcm5zID0gcGF0dGVybkVtYmVkZGluZ3MubWFwKChlbWJlZGRpbmcsIGkpID0+ICh7XG4gICAgICAgIGlkOiBgaW1wb3J0ZWQtJHtpfWAsXG4gICAgICAgIHR5cGU6ICdxdWVyeV9yZXNwb25zZScgYXMgY29uc3QsXG4gICAgICAgIGVtYmVkZGluZyxcbiAgICAgICAgc3VjY2Vzc1JhdGU6IHBhdHRlcm5SYXRlc1tpXSB8fCAwLFxuICAgICAgICB1c2VDb3VudDogMCxcbiAgICAgICAgbGFzdFVzZWQ6IG5ldyBEYXRlKCksXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgZnJvbSBKU09OIGZvcm1hdFxuICAgKi9cbiAgZnJvbUpTT04oanNvbjogc3RyaW5nKTogUGFydGlhbDxFeHBvcnRhYmxlTW9kZWw+IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgZnJvbSBiaW5hcnkgZm9ybWF0XG4gICAqL1xuICBmcm9tQmluYXJ5KGJ1ZmZlcjogVWludDhBcnJheSk6IFBhcnRpYWw8RXhwb3J0YWJsZU1vZGVsPiB7XG4gICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhidWZmZXIuYnVmZmVyLCBidWZmZXIuYnl0ZU9mZnNldCk7XG4gICAgY29uc3QgbGVuZ3RoID0gdmlldy5nZXRVaW50MzIoMCwgdHJ1ZSk7XG4gICAgY29uc3QganNvbkJ5dGVzID0gYnVmZmVyLnNsaWNlKDQsIDQgKyBsZW5ndGgpO1xuICAgIGNvbnN0IGpzb24gPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoanNvbkJ5dGVzKTtcbiAgICByZXR1cm4gdGhpcy5mcm9tSlNPTihqc29uKTtcbiAgfVxufVxuXG4vKipcbiAqIERhdGFzZXQgRXhwb3J0ZXJcbiAqXG4gKiBFeHBvcnQgdHJhaW5pbmcgZGF0YSBpbiB2YXJpb3VzIGZvcm1hdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhc2V0RXhwb3J0ZXIge1xuICAvKipcbiAgICogRXhwb3J0IHRvIEpTT05MIGZvcm1hdCAob25lIEpTT04gcGVyIGxpbmUpXG4gICAqL1xuICB0b0pTT05MKGRhdGE6IEFycmF5PHsgaW5wdXQ6IEVtYmVkZGluZzsgb3V0cHV0OiBFbWJlZGRpbmc7IHF1YWxpdHk6IG51bWJlciB9Pik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGRhdGFcbiAgICAgIC5tYXAoaXRlbSA9PiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGlucHV0OiBpdGVtLmlucHV0LFxuICAgICAgICBvdXRwdXQ6IGl0ZW0ub3V0cHV0LFxuICAgICAgICBxdWFsaXR5OiBpdGVtLnF1YWxpdHksXG4gICAgICB9KSlcbiAgICAgIC5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBvcnQgdG8gQ1NWIGZvcm1hdFxuICAgKi9cbiAgdG9DU1YoZGF0YTogQXJyYXk8eyBpbnB1dDogRW1iZWRkaW5nOyBvdXRwdXQ6IEVtYmVkZGluZzsgcXVhbGl0eTogbnVtYmVyIH0+KTogc3RyaW5nIHtcbiAgICBjb25zdCBoZWFkZXIgPSAncXVhbGl0eSxpbnB1dCxvdXRwdXQnO1xuICAgIGNvbnN0IHJvd3MgPSBkYXRhLm1hcChpdGVtID0+XG4gICAgICBgJHtpdGVtLnF1YWxpdHl9LFwiJHtpdGVtLmlucHV0LmpvaW4oJywnKX1cIixcIiR7aXRlbS5vdXRwdXQuam9pbignLCcpfVwiYFxuICAgICk7XG4gICAgcmV0dXJuIFtoZWFkZXIsIC4uLnJvd3NdLmpvaW4oJ1xcbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cG9ydCBwYXR0ZXJucyBmb3IgcHJlLXRyYWluaW5nXG4gICAqL1xuICB0b1ByZXRyYWluKHBhdHRlcm5zOiBMZWFybmVkUGF0dGVybltdKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcGF0dGVybnNcbiAgICAgIC5maWx0ZXIocCA9PiBwLnN1Y2Nlc3NSYXRlID49IDAuNylcbiAgICAgIC5tYXAocCA9PiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGVtYmVkZGluZzogcC5lbWJlZGRpbmcsXG4gICAgICAgIHR5cGU6IHAudHlwZSxcbiAgICAgICAgcXVhbGl0eTogcC5zdWNjZXNzUmF0ZSxcbiAgICAgIH0pKVxuICAgICAgLmpvaW4oJ1xcbicpO1xuICB9XG59XG4iXX0=