@sochdb/sochdb 0.4.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.
- package/LICENSE +201 -0
- package/README.md +3349 -0
- package/_bin/aarch64-apple-darwin/libsochdb_storage.dylib +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-bulk +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-grpc-server +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-server +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-bulk.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-grpc-server.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb_storage.dll +0 -0
- package/_bin/x86_64-unknown-linux-gnu/libsochdb_storage.so +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-bulk +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-grpc-server +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-server +0 -0
- package/bin/sochdb-bulk.js +80 -0
- package/bin/sochdb-grpc-server.js +80 -0
- package/bin/sochdb-server.js +84 -0
- package/dist/cjs/analytics.js +196 -0
- package/dist/cjs/database.js +929 -0
- package/dist/cjs/embedded/database.js +236 -0
- package/dist/cjs/embedded/ffi/bindings.js +113 -0
- package/dist/cjs/embedded/ffi/library-finder.js +135 -0
- package/dist/cjs/embedded/index.js +14 -0
- package/dist/cjs/embedded/transaction.js +172 -0
- package/dist/cjs/errors.js +71 -0
- package/dist/cjs/format.js +176 -0
- package/dist/cjs/grpc-client.js +328 -0
- package/dist/cjs/index.js +75 -0
- package/dist/cjs/ipc-client.js +504 -0
- package/dist/cjs/query.js +154 -0
- package/dist/cjs/server-manager.js +295 -0
- package/dist/cjs/sql-engine.js +874 -0
- package/dist/esm/analytics.js +196 -0
- package/dist/esm/database.js +931 -0
- package/dist/esm/embedded/database.js +239 -0
- package/dist/esm/embedded/ffi/bindings.js +142 -0
- package/dist/esm/embedded/ffi/library-finder.js +135 -0
- package/dist/esm/embedded/index.js +14 -0
- package/dist/esm/embedded/transaction.js +176 -0
- package/dist/esm/errors.js +71 -0
- package/dist/esm/format.js +179 -0
- package/dist/esm/grpc-client.js +333 -0
- package/dist/esm/index.js +75 -0
- package/dist/esm/ipc-client.js +505 -0
- package/dist/esm/query.js +159 -0
- package/dist/esm/server-manager.js +295 -0
- package/dist/esm/sql-engine.js +875 -0
- package/dist/types/analytics.d.ts +66 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/database.d.ts +523 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/embedded/database.d.ts +105 -0
- package/dist/types/embedded/database.d.ts.map +1 -0
- package/dist/types/embedded/ffi/bindings.d.ts +24 -0
- package/dist/types/embedded/ffi/bindings.d.ts.map +1 -0
- package/dist/types/embedded/ffi/library-finder.d.ts +17 -0
- package/dist/types/embedded/ffi/library-finder.d.ts.map +1 -0
- package/dist/types/embedded/index.d.ts +9 -0
- package/dist/types/embedded/index.d.ts.map +1 -0
- package/dist/types/embedded/transaction.d.ts +21 -0
- package/dist/types/embedded/transaction.d.ts.map +1 -0
- package/dist/types/errors.d.ts +36 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/format.d.ts +117 -0
- package/dist/types/format.d.ts.map +1 -0
- package/dist/types/grpc-client.d.ts +120 -0
- package/dist/types/grpc-client.d.ts.map +1 -0
- package/dist/types/index.d.ts +50 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/ipc-client.d.ts +177 -0
- package/dist/types/ipc-client.d.ts.map +1 -0
- package/dist/types/query.d.ts +85 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/server-manager.d.ts +29 -0
- package/dist/types/server-manager.d.ts.map +1 -0
- package/dist/types/sql-engine.d.ts +100 -0
- package/dist/types/sql-engine.d.ts.map +1 -0
- package/package.json +90 -0
- package/scripts/postinstall.js +50 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SochDB gRPC Client - Thin SDK Wrapper
|
|
4
|
+
*
|
|
5
|
+
* This module provides a thin gRPC client wrapper for the SochDB server.
|
|
6
|
+
* All business logic runs on the server (Thick Server / Thin Client architecture).
|
|
7
|
+
*
|
|
8
|
+
* The client is approximately ~250 lines of code, delegating all operations to the server.
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.GrpcClient = exports.SochDBClient = void 0;
|
|
45
|
+
exports.connect = connect;
|
|
46
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
47
|
+
const protoLoader = __importStar(require("@grpc/proto-loader"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
/**
|
|
50
|
+
* Thin gRPC client for SochDB.
|
|
51
|
+
*
|
|
52
|
+
* All operations are delegated to the SochDB gRPC server.
|
|
53
|
+
* This client provides a TypeScript interface over the gRPC protocol.
|
|
54
|
+
*
|
|
55
|
+
* Usage:
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const client = new SochDBClient({ address: 'localhost:50051' });
|
|
58
|
+
*
|
|
59
|
+
* // Create collection
|
|
60
|
+
* await client.createCollection('docs', { dimension: 384 });
|
|
61
|
+
*
|
|
62
|
+
* // Add documents
|
|
63
|
+
* await client.addDocuments('docs', [
|
|
64
|
+
* { id: '1', content: 'Hello', embedding: [...] }
|
|
65
|
+
* ]);
|
|
66
|
+
*
|
|
67
|
+
* // Search
|
|
68
|
+
* const results = await client.search('docs', queryVector, 5);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
class SochDBClient {
|
|
72
|
+
address;
|
|
73
|
+
credentials;
|
|
74
|
+
stubs = new Map();
|
|
75
|
+
protoPath;
|
|
76
|
+
packageDefinition;
|
|
77
|
+
proto;
|
|
78
|
+
constructor(options = {}) {
|
|
79
|
+
this.address = options.address || 'localhost:50051';
|
|
80
|
+
this.credentials = options.secure
|
|
81
|
+
? grpc.credentials.createSsl()
|
|
82
|
+
: grpc.credentials.createInsecure();
|
|
83
|
+
this.protoPath = options.protoPath || path.join(__dirname, '../../proto/sochdb.proto');
|
|
84
|
+
// Load proto definition
|
|
85
|
+
this.packageDefinition = protoLoader.loadSync(this.protoPath, {
|
|
86
|
+
keepCase: false,
|
|
87
|
+
longs: String,
|
|
88
|
+
enums: String,
|
|
89
|
+
defaults: true,
|
|
90
|
+
oneofs: true,
|
|
91
|
+
});
|
|
92
|
+
const loadedPackage = grpc.loadPackageDefinition(this.packageDefinition);
|
|
93
|
+
this.proto = loadedPackage?.sochdb?.v1;
|
|
94
|
+
}
|
|
95
|
+
getStub(serviceName) {
|
|
96
|
+
if (!this.stubs.has(serviceName)) {
|
|
97
|
+
const ServiceClass = this.proto?.[serviceName];
|
|
98
|
+
if (!ServiceClass) {
|
|
99
|
+
throw new Error(`Service ${serviceName} not found in proto definition`);
|
|
100
|
+
}
|
|
101
|
+
this.stubs.set(serviceName, new ServiceClass(this.address, this.credentials));
|
|
102
|
+
}
|
|
103
|
+
return this.stubs.get(serviceName);
|
|
104
|
+
}
|
|
105
|
+
promisify(stub, method, request) {
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
stub[method](request, (error, response) => {
|
|
108
|
+
if (error)
|
|
109
|
+
reject(error);
|
|
110
|
+
else
|
|
111
|
+
resolve(response);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Close all gRPC connections.
|
|
117
|
+
*/
|
|
118
|
+
close() {
|
|
119
|
+
for (const stub of this.stubs.values()) {
|
|
120
|
+
grpc.closeClient(stub);
|
|
121
|
+
}
|
|
122
|
+
this.stubs.clear();
|
|
123
|
+
}
|
|
124
|
+
// ===========================================================================
|
|
125
|
+
// Vector Index Operations (VectorIndexService)
|
|
126
|
+
// ===========================================================================
|
|
127
|
+
async createIndex(name, dimension, options = {}) {
|
|
128
|
+
const stub = this.getStub('VectorIndexService');
|
|
129
|
+
const response = await this.promisify(stub, 'createIndex', {
|
|
130
|
+
name,
|
|
131
|
+
dimension,
|
|
132
|
+
metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
|
|
133
|
+
config: {
|
|
134
|
+
maxConnections: options.m || 16,
|
|
135
|
+
efConstruction: options.efConstruction || 200,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
return response.success;
|
|
139
|
+
}
|
|
140
|
+
async insertVectors(indexName, ids, vectors) {
|
|
141
|
+
const stub = this.getStub('VectorIndexService');
|
|
142
|
+
const flatVectors = vectors.flat();
|
|
143
|
+
const response = await this.promisify(stub, 'insertBatch', {
|
|
144
|
+
indexName,
|
|
145
|
+
ids,
|
|
146
|
+
vectors: flatVectors,
|
|
147
|
+
});
|
|
148
|
+
return response.insertedCount;
|
|
149
|
+
}
|
|
150
|
+
async search(indexName, query, k = 10, ef = 50) {
|
|
151
|
+
const stub = this.getStub('VectorIndexService');
|
|
152
|
+
const response = await this.promisify(stub, 'search', {
|
|
153
|
+
indexName,
|
|
154
|
+
query,
|
|
155
|
+
k,
|
|
156
|
+
ef,
|
|
157
|
+
});
|
|
158
|
+
return (response.results || []).map((r) => ({
|
|
159
|
+
id: Number(r.id),
|
|
160
|
+
distance: r.distance,
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
// ===========================================================================
|
|
164
|
+
// Collection Operations (CollectionService)
|
|
165
|
+
// ===========================================================================
|
|
166
|
+
async createCollection(name, options) {
|
|
167
|
+
const stub = this.getStub('CollectionService');
|
|
168
|
+
const response = await this.promisify(stub, 'createCollection', {
|
|
169
|
+
name,
|
|
170
|
+
namespace: options.namespace || 'default',
|
|
171
|
+
dimension: options.dimension,
|
|
172
|
+
metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
|
|
173
|
+
});
|
|
174
|
+
return response.success;
|
|
175
|
+
}
|
|
176
|
+
async addDocuments(collectionName, documents, namespace = 'default') {
|
|
177
|
+
const stub = this.getStub('CollectionService');
|
|
178
|
+
const response = await this.promisify(stub, 'addDocuments', {
|
|
179
|
+
collectionName,
|
|
180
|
+
namespace,
|
|
181
|
+
documents: documents.map((d) => ({
|
|
182
|
+
id: d.id || '',
|
|
183
|
+
content: d.content || '',
|
|
184
|
+
embedding: d.embedding || [],
|
|
185
|
+
metadata: d.metadata || {},
|
|
186
|
+
})),
|
|
187
|
+
});
|
|
188
|
+
return response.ids || [];
|
|
189
|
+
}
|
|
190
|
+
async searchCollection(collectionName, query, k = 10, options = {}) {
|
|
191
|
+
const stub = this.getStub('CollectionService');
|
|
192
|
+
const response = await this.promisify(stub, 'searchCollection', {
|
|
193
|
+
collectionName,
|
|
194
|
+
namespace: options.namespace || 'default',
|
|
195
|
+
query,
|
|
196
|
+
k,
|
|
197
|
+
filter: options.filter || {},
|
|
198
|
+
});
|
|
199
|
+
return (response.results || []).map((r) => ({
|
|
200
|
+
id: r.document.id,
|
|
201
|
+
content: r.document.content,
|
|
202
|
+
embedding: r.document.embedding || [],
|
|
203
|
+
metadata: r.document.metadata || {},
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
// ===========================================================================
|
|
207
|
+
// Graph Operations (GraphService)
|
|
208
|
+
// ===========================================================================
|
|
209
|
+
async addNode(nodeId, nodeType, properties = {}, namespace = 'default') {
|
|
210
|
+
const stub = this.getStub('GraphService');
|
|
211
|
+
const response = await this.promisify(stub, 'addNode', {
|
|
212
|
+
namespace,
|
|
213
|
+
node: { id: nodeId, nodeType, properties },
|
|
214
|
+
});
|
|
215
|
+
return response.success;
|
|
216
|
+
}
|
|
217
|
+
async addEdge(fromId, edgeType, toId, properties = {}, namespace = 'default') {
|
|
218
|
+
const stub = this.getStub('GraphService');
|
|
219
|
+
const response = await this.promisify(stub, 'addEdge', {
|
|
220
|
+
namespace,
|
|
221
|
+
edge: { fromId, edgeType, toId, properties },
|
|
222
|
+
});
|
|
223
|
+
return response.success;
|
|
224
|
+
}
|
|
225
|
+
async traverse(startNode, options = {}) {
|
|
226
|
+
const stub = this.getStub('GraphService');
|
|
227
|
+
const response = await this.promisify(stub, 'traverse', {
|
|
228
|
+
namespace: options.namespace || 'default',
|
|
229
|
+
startNodeId: startNode,
|
|
230
|
+
order: options.order === 'dfs' ? 1 : 0,
|
|
231
|
+
maxDepth: options.maxDepth || 10,
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
nodes: (response.nodes || []).map((n) => ({
|
|
235
|
+
id: n.id,
|
|
236
|
+
nodeType: n.nodeType,
|
|
237
|
+
properties: n.properties || {},
|
|
238
|
+
})),
|
|
239
|
+
edges: (response.edges || []).map((e) => ({
|
|
240
|
+
fromId: e.fromId,
|
|
241
|
+
edgeType: e.edgeType,
|
|
242
|
+
toId: e.toId,
|
|
243
|
+
properties: e.properties || {},
|
|
244
|
+
})),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// ===========================================================================
|
|
248
|
+
// Semantic Cache Operations (SemanticCacheService)
|
|
249
|
+
// ===========================================================================
|
|
250
|
+
async cacheGet(cacheName, queryEmbedding, threshold = 0.85) {
|
|
251
|
+
const stub = this.getStub('SemanticCacheService');
|
|
252
|
+
const response = await this.promisify(stub, 'get', {
|
|
253
|
+
cacheName,
|
|
254
|
+
queryEmbedding,
|
|
255
|
+
similarityThreshold: threshold,
|
|
256
|
+
});
|
|
257
|
+
return response.hit ? response.cachedValue : null;
|
|
258
|
+
}
|
|
259
|
+
async cachePut(cacheName, key, value, keyEmbedding, ttlSeconds = 0) {
|
|
260
|
+
const stub = this.getStub('SemanticCacheService');
|
|
261
|
+
const response = await this.promisify(stub, 'put', {
|
|
262
|
+
cacheName,
|
|
263
|
+
key,
|
|
264
|
+
value,
|
|
265
|
+
keyEmbedding,
|
|
266
|
+
ttlSeconds,
|
|
267
|
+
});
|
|
268
|
+
return response.success;
|
|
269
|
+
}
|
|
270
|
+
// ===========================================================================
|
|
271
|
+
// Trace Operations (TraceService)
|
|
272
|
+
// ===========================================================================
|
|
273
|
+
async startTrace(name) {
|
|
274
|
+
const stub = this.getStub('TraceService');
|
|
275
|
+
const response = await this.promisify(stub, 'startTrace', { name });
|
|
276
|
+
return { traceId: response.traceId, rootSpanId: response.rootSpanId };
|
|
277
|
+
}
|
|
278
|
+
async startSpan(traceId, parentSpanId, name) {
|
|
279
|
+
const stub = this.getStub('TraceService');
|
|
280
|
+
const response = await this.promisify(stub, 'startSpan', {
|
|
281
|
+
traceId,
|
|
282
|
+
parentSpanId,
|
|
283
|
+
name,
|
|
284
|
+
});
|
|
285
|
+
return response.spanId;
|
|
286
|
+
}
|
|
287
|
+
async endSpan(traceId, spanId, status = 'ok') {
|
|
288
|
+
const stub = this.getStub('TraceService');
|
|
289
|
+
const statusMap = { unset: 0, ok: 1, error: 2 };
|
|
290
|
+
const response = await this.promisify(stub, 'endSpan', {
|
|
291
|
+
traceId,
|
|
292
|
+
spanId,
|
|
293
|
+
status: statusMap[status],
|
|
294
|
+
});
|
|
295
|
+
return Number(response.durationUs);
|
|
296
|
+
}
|
|
297
|
+
// ===========================================================================
|
|
298
|
+
// KV Operations (KvService)
|
|
299
|
+
// ===========================================================================
|
|
300
|
+
async get(key, namespace = 'default') {
|
|
301
|
+
const stub = this.getStub('KvService');
|
|
302
|
+
const response = await this.promisify(stub, 'get', { namespace, key });
|
|
303
|
+
return response.found ? Buffer.from(response.value) : null;
|
|
304
|
+
}
|
|
305
|
+
async put(key, value, namespace = 'default', ttlSeconds = 0) {
|
|
306
|
+
const stub = this.getStub('KvService');
|
|
307
|
+
const response = await this.promisify(stub, 'put', {
|
|
308
|
+
namespace,
|
|
309
|
+
key,
|
|
310
|
+
value,
|
|
311
|
+
ttlSeconds,
|
|
312
|
+
});
|
|
313
|
+
return response.success;
|
|
314
|
+
}
|
|
315
|
+
async delete(key, namespace = 'default') {
|
|
316
|
+
const stub = this.getStub('KvService');
|
|
317
|
+
const response = await this.promisify(stub, 'delete', { namespace, key });
|
|
318
|
+
return response.success;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
exports.SochDBClient = SochDBClient;
|
|
322
|
+
/**
|
|
323
|
+
* Connect to SochDB gRPC server.
|
|
324
|
+
*/
|
|
325
|
+
function connect(address = 'localhost:50051', options = {}) {
|
|
326
|
+
if (address.startsWith('grpc://')) {
|
|
327
|
+
address = address.slice(7);
|
|
328
|
+
}
|
|
329
|
+
return new SochDBClient({ address, ...options });
|
|
330
|
+
}
|
|
331
|
+
// Alias for backwards compatibility
|
|
332
|
+
exports.GrpcClient = SochDBClient;
|
|
333
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JwYy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ3JwYy1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7O0dBT0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1aSCwwQkFLQztBQXRaRCxvREFBc0M7QUFDdEMsZ0VBQWtEO0FBQ2xELDJDQUE2QjtBQWtDN0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsWUFBWTtJQUNmLE9BQU8sQ0FBUztJQUNoQixXQUFXLENBQTBCO0lBQ3JDLEtBQUssR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNwQyxTQUFTLENBQVM7SUFDbEIsaUJBQWlCLENBQU07SUFDdkIsS0FBSyxDQUFNO0lBRW5CLFlBQVksVUFBK0IsRUFBRTtRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksaUJBQWlCLENBQUM7UUFDcEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsTUFBTTtZQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUU7WUFDOUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFFdkYsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDNUQsUUFBUSxFQUFFLEtBQUs7WUFDZixLQUFLLEVBQUUsTUFBTTtZQUNiLEtBQUssRUFBRSxNQUFNO1lBQ2IsUUFBUSxFQUFFLElBQUk7WUFDZCxNQUFNLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQztRQUNILE1B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O0lBQzFCLENBQUM7Q0FDRjtBQWxWRCxvQ0FrVkM7QUFFRDs7R0FFRztBQUNILFNBQWdCLE9BQU8sQ0FBQyxVQUFrQixpQkFBaUIsRUFBRSxVQUFnRCxFQUFFO0lBQzdHLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE9BQU8sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFDRCxPQUFPLElBQUksWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsb0NBQW9DO0FBQ3ZCLFFBQUEsVUFBVSxHQUFHLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU29jaERCIGdSUEMgQ2xpZW50IC0gVGhpbiBTREsgV3JhcHBlclxuICpcbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgdGhpbiBnUlBDIGNsaWVudCB3cmFwcGVyIGZvciB0aGUgU29jaERCIHNlcnZlci5cbiAqIEFsbCBidXNpbmVzcyBsb2dpYyBydW5zIG9uIHRoZSBzZXJ2ZXIgKFRoaWNrIFNlcnZlciAvIFRoaW4gQ2xpZW50IGFyY2hpdGVjdHVyZSkuXG4gKlxuICogVGhlIGNsaWVudCBpcyBhcHByb3hpbWF0ZWx5IH4yNTAgbGluZXMgb2YgY29kZSwgZGVsZWdhdGluZyBhbGwgb3BlcmF0aW9ucyB0byB0aGUgc2VydmVyLlxuICovXG5cbmltcG9ydCAqIGFzIGdycGMgZnJvbSAnQGdycGMvZ3JwYy1qcyc7XG5pbXBvcnQgKiBhcyBwcm90b0xvYWRlciBmcm9tICdAZ3JwYy9wcm90by1sb2FkZXInO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLy8gVHlwZXNcbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoUmVzdWx0IHtcbiAgaWQ6IG51bWJlcjtcbiAgZGlzdGFuY2U6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEb2N1bWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgZW1iZWRkaW5nOiBudW1iZXJbXTtcbiAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGhOb2RlIHtcbiAgaWQ6IHN0cmluZztcbiAgbm9kZVR5cGU6IHN0cmluZztcbiAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaEVkZ2Uge1xuICBmcm9tSWQ6IHN0cmluZztcbiAgZWRnZVR5cGU6IHN0cmluZztcbiAgdG9JZDogc3RyaW5nO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvY2hEQkNsaWVudE9wdGlvbnMge1xuICBhZGRyZXNzPzogc3RyaW5nO1xuICBzZWN1cmU/OiBib29sZWFuO1xuICBwcm90b1BhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhpbiBnUlBDIGNsaWVudCBmb3IgU29jaERCLlxuICpcbiAqIEFsbCBvcGVyYXRpb25zIGFyZSBkZWxlZ2F0ZWQgdG8gdGhlIFNvY2hEQiBnUlBDIHNlcnZlci5cbiAqIFRoaXMgY2xpZW50IHByb3ZpZGVzIGEgVHlwZVNjcmlwdCBpbnRlcmZhY2Ugb3ZlciB0aGUgZ1JQQyBwcm90b2NvbC5cbiAqXG4gKiBVc2FnZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNsaWVudCA9IG5ldyBTb2NoREJDbGllbnQoeyBhZGRyZXNzOiAnbG9jYWxob3N0OjUwMDUxJyB9KTtcbiAqXG4gKiAvLyBDcmVhdGUgY29sbGVjdGlvblxuICogYXdhaXQgY2xpZW50LmNyZWF0ZUNvbGxlY3Rpb24oJ2RvY3MnLCB7IGRpbWVuc2lvbjogMzg0IH0pO1xuICpcbiAqIC8vIEFkZCBkb2N1bWVudHNcbiAqIGF3YWl0IGNsaWVudC5hZGREb2N1bWVudHMoJ2RvY3MnLCBbXG4gKiAgIHsgaWQ6ICcxJywgY29udGVudDogJ0hlbGxvJywgZW1iZWRkaW5nOiBbLi4uXSB9XG4gKiBdKTtcbiAqXG4gKiAvLyBTZWFyY2hcbiAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBjbGllbnQuc2VhcmNoKCdkb2NzJywgcXVlcnlWZWN0b3IsIDUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTb2NoREJDbGllbnQge1xuICBwcml2YXRlIGFkZHJlc3M6IHN0cmluZztcbiAgcHJpdmF0ZSBjcmVkZW50aWFsczogZ3JwYy5DaGFubmVsQ3JlZGVudGlhbHM7XG4gIHByaXZhdGUgc3R1YnM6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcHJvdG9QYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcGFja2FnZURlZmluaXRpb246IGFueTtcbiAgcHJpdmF0ZSBwcm90bzogYW55O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNvY2hEQkNsaWVudE9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuYWRkcmVzcyA9IG9wdGlvbnMuYWRkcmVzcyB8fCAnbG9jYWxob3N0OjUwMDUxJztcbiAgICB0aGlzLmNyZWRlbnRpYWxzID0gb3B0aW9ucy5zZWN1cmVcbiAgICAgID8gZ3JwYy5jcmVkZW50aWFscy5jcmVhdGVTc2woKVxuICAgICAgOiBncnBjLmNyZWRlbnRpYWxzLmNyZWF0ZUluc2VjdXJlKCk7XG4gICAgdGhpcy5wcm90b1BhdGggPSBvcHRpb25zLnByb3RvUGF0aCB8fCBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vcHJvdG8vc29jaGRiLnByb3RvJyk7XG5cbiAgICAvLyBMb2FkIHByb3RvIGRlZmluaXRpb25cbiAgICB0aGlzLnBhY2thZ2VEZWZpbml0aW9uID0gcHJvdG9Mb2FkZXIubG9hZFN5bmModGhpcy5wcm90b1BhdGgsIHtcbiAgICAgIGtlZXBDYXNlOiBmYWxzZSxcbiAgICAgIGxvbmdzOiBTdHJpbmcsXG4gICAgICBlbnVtczogU3RyaW5nLFxuICAgICAgZGVmYXVsdHM6IHRydWUsXG4gICAgICBvbmVvZnM6IHRydWUsXG4gICAgfSk7XG4gICAgY29uc3QgbG9hZGVkUGFja2FnZSA9IGdycGMubG9hZFBhY2thZ2VEZWZpbml0aW9uKHRoaXMucGFja2FnZURlZmluaXRpb24pIGFzIGFueTtcbiAgICB0aGlzLnByb3RvID0gbG9hZGVkUGFja2FnZT8uc29jaGRiPy52MTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3R1YihzZXJ2aWNlTmFtZTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXRoaXMuc3R1YnMuaGFzKHNlcnZpY2VOYW1lKSkge1xuICAgICAgY29uc3QgU2VydmljZUNsYXNzID0gdGhpcy5wcm90bz8uW3NlcnZpY2VOYW1lXTtcbiAgICAgIGlmICghU2VydmljZUNsYXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmljZSAke3NlcnZpY2VOYW1lfSBub3QgZm91bmQgaW4gcHJvdG8gZGVmaW5pdGlvbmApO1xuICAgICAgfVxuICAgICAgdGhpcy5zdHVicy5zZXQoc2VydmljZU5hbWUsIG5ldyBTZXJ2aWNlQ2xhc3ModGhpcy5hZGRyZXNzLCB0aGlzLmNyZWRlbnRpYWxzKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0dWJzLmdldChzZXJ2aWNlTmFtZSkhO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9taXNpZnk8VD4oc3R1YjogYW55LCBtZXRob2Q6IHN0cmluZywgcmVxdWVzdDogYW55KTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHN0dWJbbWV0aG9kXShyZXF1ZXN0LCAoZXJyb3I6IGFueSwgcmVzcG9uc2U6IFQpID0+IHtcbiAgICAgICAgaWYgKGVycm9yKSByZWplY3QoZXJyb3IpO1xuICAgICAgICBlbHNlIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgYWxsIGdSUEMgY29ubmVjdGlvbnMuXG4gICAqL1xuICBjbG9zZSgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHN0dWIgb2YgdGhpcy5zdHVicy52YWx1ZXMoKSkge1xuICAgICAgZ3JwYy5jbG9zZUNsaWVudChzdHViKTtcbiAgICB9XG4gICAgdGhpcy5zdHVicy5jbGVhcigpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFZlY3RvciBJbmRleCBPcGVyYXRpb25zIChWZWN0b3JJbmRleFNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBkaW1lbnNpb246IG51bWJlcixcbiAgICBvcHRpb25zOiB7IG1ldHJpYz86IHN0cmluZzsgbT86IG51bWJlcjsgZWZDb25zdHJ1Y3Rpb24/OiBudW1iZXIgfSA9IHt9XG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1ZlY3RvckluZGV4U2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnY3JlYXRlSW5kZXgnLCB7XG4gICAgICBuYW1lLFxuICAgICAgZGltZW5zaW9uLFxuICAgICAgbWV0cmljOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2wyJyA/IDEgOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2RvdCcgPyAzIDogMixcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtYXhDb25uZWN0aW9uczogb3B0aW9ucy5tIHx8IDE2LFxuICAgICAgICBlZkNvbnN0cnVjdGlvbjogb3B0aW9ucy5lZkNvbnN0cnVjdGlvbiB8fCAyMDAsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgYXN5bmMgaW5zZXJ0VmVjdG9ycyhcbiAgICBpbmRleE5hbWU6IHN0cmluZyxcbiAgICBpZHM6IG51bWJlcltdLFxuICAgIHZlY3RvcnM6IG51bWJlcltdW11cbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdWZWN0b3JJbmRleFNlcnZpY2UnKTtcbiAgICBjb25zdCBmbGF0VmVjdG9ycyA9IHZlY3RvcnMuZmxhdCgpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnaW5zZXJ0QmF0Y2gnLCB7XG4gICAgICBpbmRleE5hbWUsXG4gICAgICBpZHMsXG4gICAgICB2ZWN0b3JzOiBmbGF0VmVjdG9ycyxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuaW5zZXJ0ZWRDb3VudDtcbiAgfVxuXG4gIGFzeW5jIHNlYXJjaChcbiAgICBpbmRleE5hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogbnVtYmVyW10sXG4gICAgazogbnVtYmVyID0gMTAsXG4gICAgZWY6IG51bWJlciA9IDUwXG4gICk6IFByb21pc2U8U2VhcmNoUmVzdWx0W10+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdWZWN0b3JJbmRleFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3NlYXJjaCcsIHtcbiAgICAgIGluZGV4TmFtZSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgayxcbiAgICAgIGVmLFxuICAgIH0pO1xuICAgIHJldHVybiAocmVzcG9uc2UucmVzdWx0cyB8fCBbXSkubWFwKChyOiBhbnkpID0+ICh7XG4gICAgICBpZDogTnVtYmVyKHIuaWQpLFxuICAgICAgZGlzdGFuY2U6IHIuZGlzdGFuY2UsXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIENvbGxlY3Rpb24gT3BlcmF0aW9ucyAoQ29sbGVjdGlvblNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGNyZWF0ZUNvbGxlY3Rpb24oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHsgZGltZW5zaW9uOiBudW1iZXI7IG5hbWVzcGFjZT86IHN0cmluZzsgbWV0cmljPzogc3RyaW5nIH1cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignQ29sbGVjdGlvblNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2NyZWF0ZUNvbGxlY3Rpb24nLCB7XG4gICAgICBuYW1lLFxuICAgICAgbmFtZXNwYWNlOiBvcHRpb25zLm5hbWVzcGFjZSB8fCAnZGVmYXVsdCcsXG4gICAgICBkaW1lbnNpb246IG9wdGlvbnMuZGltZW5zaW9uLFxuICAgICAgbWV0cmljOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2wyJyA/IDEgOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2RvdCcgPyAzIDogMixcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIGFzeW5jIGFkZERvY3VtZW50cyhcbiAgICBjb2xsZWN0aW9uTmFtZTogc3RyaW5nLFxuICAgIGRvY3VtZW50czogQXJyYXk8e1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICBjb250ZW50Pzogc3RyaW5nO1xuICAgICAgZW1iZWRkaW5nPzogbnVtYmVyW107XG4gICAgICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgfT4sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0NvbGxlY3Rpb25TZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGREb2N1bWVudHMnLCB7XG4gICAgICBjb2xsZWN0aW9uTmFtZSxcbiAgICAgIG5hbWVzcGFjZSxcbiAgICAgIGRvY3VtZW50czogZG9jdW1lbnRzLm1hcCgoZCkgPT4gKHtcbiAgICAgICAgaWQ6IGQuaWQgfHwgJycsXG4gICAgICAgIGNvbnRlbnQ6IGQuY29udGVudCB8fCAnJyxcbiAgICAgICAgZW1iZWRkaW5nOiBkLmVtYmVkZGluZyB8fCBbXSxcbiAgICAgICAgbWV0YWRhdGE6IGQubWV0YWRhdGEgfHwge30sXG4gICAgICB9KSksXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmlkcyB8fCBbXTtcbiAgfVxuXG4gIGFzeW5jIHNlYXJjaENvbGxlY3Rpb24oXG4gICAgY29sbGVjdGlvbk5hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogbnVtYmVyW10sXG4gICAgazogbnVtYmVyID0gMTAsXG4gICAgb3B0aW9uczogeyBuYW1lc3BhY2U/OiBzdHJpbmc7IGZpbHRlcj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSA9IHt9XG4gICk6IFByb21pc2U8RG9jdW1lbnRbXT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0NvbGxlY3Rpb25TZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdzZWFyY2hDb2xsZWN0aW9uJywge1xuICAgICAgY29sbGVjdGlvbk5hbWUsXG4gICAgICBuYW1lc3BhY2U6IG9wdGlvbnMubmFtZXNwYWNlIHx8ICdkZWZhdWx0JyxcbiAgICAgIHF1ZXJ5LFxuICAgICAgayxcbiAgICAgIGZpbHRlcjogb3B0aW9ucy5maWx0ZXIgfHwge30sXG4gICAgfSk7XG4gICAgcmV0dXJuIChyZXNwb25zZS5yZXN1bHRzIHx8IFtdKS5tYXAoKHI6IGFueSkgPT4gKHtcbiAgICAgIGlkOiByLmRvY3VtZW50LmlkLFxuICAgICAgY29udGVudDogci5kb2N1bWVudC5jb250ZW50LFxuICAgICAgZW1iZWRkaW5nOiByLmRvY3VtZW50LmVtYmVkZGluZyB8fCBbXSxcbiAgICAgIG1ldGFkYXRhOiByLmRvY3VtZW50Lm1ldGFkYXRhIHx8IHt9LFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBHcmFwaCBPcGVyYXRpb25zIChHcmFwaFNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGFkZE5vZGUoXG4gICAgbm9kZUlkOiBzdHJpbmcsXG4gICAgbm9kZVR5cGU6IHN0cmluZyxcbiAgICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignR3JhcGhTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGROb2RlJywge1xuICAgICAgbmFtZXNwYWNlLFxuICAgICAgbm9kZTogeyBpZDogbm9kZUlkLCBub2RlVHlwZSwgcHJvcGVydGllcyB9LFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgYXN5bmMgYWRkRWRnZShcbiAgICBmcm9tSWQ6IHN0cmluZyxcbiAgICBlZGdlVHlwZTogc3RyaW5nLFxuICAgIHRvSWQ6IHN0cmluZyxcbiAgICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignR3JhcGhTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGRFZGdlJywge1xuICAgICAgbmFtZXNwYWNlLFxuICAgICAgZWRnZTogeyBmcm9tSWQsIGVkZ2VUeXBlLCB0b0lkLCBwcm9wZXJ0aWVzIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyB0cmF2ZXJzZShcbiAgICBzdGFydE5vZGU6IHN0cmluZyxcbiAgICBvcHRpb25zOiB7IG1heERlcHRoPzogbnVtYmVyOyBvcmRlcj86ICdiZnMnIHwgJ2Rmcyc7IG5hbWVzcGFjZT86IHN0cmluZyB9ID0ge31cbiAgKTogUHJvbWlzZTx7IG5vZGVzOiBHcmFwaE5vZGVbXTsgZWRnZXM6IEdyYXBoRWRnZVtdIH0+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdHcmFwaFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3RyYXZlcnNlJywge1xuICAgICAgbmFtZXNwYWNlOiBvcHRpb25zLm5hbWVzcGFjZSB8fCAnZGVmYXVsdCcsXG4gICAgICBzdGFydE5vZGVJZDogc3RhcnROb2RlLFxuICAgICAgb3JkZXI6IG9wdGlvbnMub3JkZXIgPT09ICdkZnMnID8gMSA6IDAsXG4gICAgICBtYXhEZXB0aDogb3B0aW9ucy5tYXhEZXB0aCB8fCAxMCxcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgbm9kZXM6IChyZXNwb25zZS5ub2RlcyB8fCBbXSkubWFwKChuOiBhbnkpID0+ICh7XG4gICAgICAgIGlkOiBuLmlkLFxuICAgICAgICBub2RlVHlwZTogbi5ub2RlVHlwZSxcbiAgICAgICAgcHJvcGVydGllczogbi5wcm9wZXJ0aWVzIHx8IHt9LFxuICAgICAgfSkpLFxuICAgICAgZWRnZXM6IChyZXNwb25zZS5lZGdlcyB8fCBbXSkubWFwKChlOiBhbnkpID0+ICh7XG4gICAgICAgIGZyb21JZDogZS5mcm9tSWQsXG4gICAgICAgIGVkZ2VUeXBlOiBlLmVkZ2VUeXBlLFxuICAgICAgICB0b0lkOiBlLnRvSWQsXG4gICAgICAgIHByb3BlcnRpZXM6IGUucHJvcGVydGllcyB8fCB7fSxcbiAgICAgIH0pKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNlbWFudGljIENhY2hlIE9wZXJhdGlvbnMgKFNlbWFudGljQ2FjaGVTZXJ2aWNlKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBhc3luYyBjYWNoZUdldChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBxdWVyeUVtYmVkZGluZzogbnVtYmVyW10sXG4gICAgdGhyZXNob2xkOiBudW1iZXIgPSAwLjg1XG4gICk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1NlbWFudGljQ2FjaGVTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdnZXQnLCB7XG4gICAgICBjYWNoZU5hbWUsXG4gICAgICBxdWVyeUVtYmVkZGluZyxcbiAgICAgIHNpbWlsYXJpdHlUaHJlc2hvbGQ6IHRocmVzaG9sZCxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuaGl0ID8gcmVzcG9uc2UuY2FjaGVkVmFsdWUgOiBudWxsO1xuICB9XG5cbiAgYXN5bmMgY2FjaGVQdXQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBrZXlFbWJlZGRpbmc6IG51bWJlcltdLFxuICAgIHR0bFNlY29uZHM6IG51bWJlciA9IDBcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignU2VtYW50aWNDYWNoZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3B1dCcsIHtcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlLFxuICAgICAga2V5RW1iZWRkaW5nLFxuICAgICAgdHRsU2Vjb25kcyxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBUcmFjZSBPcGVyYXRpb25zIChUcmFjZVNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIHN0YXJ0VHJhY2UobmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHRyYWNlSWQ6IHN0cmluZzsgcm9vdFNwYW5JZDogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdUcmFjZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3N0YXJ0VHJhY2UnLCB7IG5hbWUgfSk7XG4gICAgcmV0dXJuIHsgdHJhY2VJZDogcmVzcG9uc2UudHJhY2VJZCwgcm9vdFNwYW5JZDogcmVzcG9uc2Uucm9vdFNwYW5JZCB9O1xuICB9XG5cbiAgYXN5bmMgc3RhcnRTcGFuKHRyYWNlSWQ6IHN0cmluZywgcGFyZW50U3BhbklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignVHJhY2VTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdzdGFydFNwYW4nLCB7XG4gICAgICB0cmFjZUlkLFxuICAgICAgcGFyZW50U3BhbklkLFxuICAgICAgbmFtZSxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3BhbklkO1xuICB9XG5cbiAgYXN5bmMgZW5kU3BhbihcbiAgICB0cmFjZUlkOiBzdHJpbmcsXG4gICAgc3BhbklkOiBzdHJpbmcsXG4gICAgc3RhdHVzOiAnb2snIHwgJ2Vycm9yJyB8ICd1bnNldCcgPSAnb2snXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignVHJhY2VTZXJ2aWNlJyk7XG4gICAgY29uc3Qgc3RhdHVzTWFwID0geyB1bnNldDogMCwgb2s6IDEsIGVycm9yOiAyIH07XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdlbmRTcGFuJywge1xuICAgICAgdHJhY2VJZCxcbiAgICAgIHNwYW5JZCxcbiAgICAgIHN0YXR1czogc3RhdHVzTWFwW3N0YXR1c10sXG4gICAgfSk7XG4gICAgcmV0dXJuIE51bWJlcihyZXNwb25zZS5kdXJhdGlvblVzKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBLViBPcGVyYXRpb25zIChLdlNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGdldChrZXk6IEJ1ZmZlciwgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCcpOiBQcm9taXNlPEJ1ZmZlciB8IG51bGw+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdLdlNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2dldCcsIHsgbmFtZXNwYWNlLCBrZXkgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmZvdW5kID8gQnVmZmVyLmZyb20ocmVzcG9uc2UudmFsdWUpIDogbnVsbDtcbiAgfVxuXG4gIGFzeW5jIHB1dChcbiAgICBrZXk6IEJ1ZmZlcixcbiAgICB2YWx1ZTogQnVmZmVyLFxuICAgIG5hbWVzcGFjZTogc3RyaW5nID0gJ2RlZmF1bHQnLFxuICAgIHR0bFNlY29uZHM6IG51bWJlciA9IDBcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignS3ZTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdwdXQnLCB7XG4gICAgICBuYW1lc3BhY2UsXG4gICAgICBrZXksXG4gICAgICB2YWx1ZSxcbiAgICAgIHR0bFNlY29uZHMsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyBkZWxldGUoa2V5OiBCdWZmZXIsIG5hbWVzcGFjZTogc3RyaW5nID0gJ2RlZmF1bHQnKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignS3ZTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdkZWxldGUnLCB7IG5hbWVzcGFjZSwga2V5IH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG59XG5cbi8qKlxuICogQ29ubmVjdCB0byBTb2NoREIgZ1JQQyBzZXJ2ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0KGFkZHJlc3M6IHN0cmluZyA9ICdsb2NhbGhvc3Q6NTAwNTEnLCBvcHRpb25zOiBPbWl0PFNvY2hEQkNsaWVudE9wdGlvbnMsICdhZGRyZXNzJz4gPSB7fSk6IFNvY2hEQkNsaWVudCB7XG4gIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoJ2dycGM6Ly8nKSkge1xuICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDcpO1xuICB9XG4gIHJldHVybiBuZXcgU29jaERCQ2xpZW50KHsgYWRkcmVzcywgLi4ub3B0aW9ucyB9KTtcbn1cblxuLy8gQWxpYXMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5leHBvcnQgY29uc3QgR3JwY0NsaWVudCA9IFNvY2hEQkNsaWVudDtcbiJdfQ==
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SochDB Node.js SDK v0.4.0
|
|
4
|
+
*
|
|
5
|
+
* Dual-mode architecture: Embedded (FFI) + Server (gRPC/IPC)
|
|
6
|
+
*
|
|
7
|
+
* Architecture: Flexible Deployment
|
|
8
|
+
* ==================================
|
|
9
|
+
* This SDK supports BOTH modes:
|
|
10
|
+
*
|
|
11
|
+
* 1. Embedded Mode (FFI) - For single-process apps:
|
|
12
|
+
* - Direct FFI bindings to Rust libraries
|
|
13
|
+
* - No server required - just npm install and run
|
|
14
|
+
* - Best for: Local development, simple apps
|
|
15
|
+
*
|
|
16
|
+
* 2. Server Mode (gRPC/IPC) - For distributed systems:
|
|
17
|
+
* - Thin client connecting to sochdb-grpc server
|
|
18
|
+
* - Best for: Production, multi-language, scalability
|
|
19
|
+
*
|
|
20
|
+
* @example Embedded Mode
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { Database } from '@sochdb/sochdb';
|
|
23
|
+
*
|
|
24
|
+
* // Direct FFI - no server needed
|
|
25
|
+
* const db = await Database.open('./mydb');
|
|
26
|
+
* await db.put(Buffer.from('key'), Buffer.from('value'));
|
|
27
|
+
* await db.close();
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Server Mode
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { SochDBClient } from '@sochdb/sochdb';
|
|
33
|
+
*
|
|
34
|
+
* // Connect to server
|
|
35
|
+
* const client = new SochDBClient({ address: 'localhost:50051' });
|
|
36
|
+
* await client.putKv('key', Buffer.from('value'));
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.GrpcClient = exports.DatabaseError = exports.ProtocolError = exports.TransactionError = exports.ConnectionError = exports.SochDBError = exports.Query = exports.FormatConversionError = exports.FormatCapabilities = exports.CanonicalFormat = exports.ContextFormat = exports.WireFormat = exports.IpcClient = exports.SochDBClient = exports.Database = exports.EmbeddedTransaction = exports.EmbeddedDatabase = exports.VERSION = void 0;
|
|
41
|
+
// Version
|
|
42
|
+
exports.VERSION = '0.4.0';
|
|
43
|
+
// Embedded mode (FFI) - NEW
|
|
44
|
+
var embedded_1 = require("./embedded");
|
|
45
|
+
Object.defineProperty(exports, "EmbeddedDatabase", { enumerable: true, get: function () { return embedded_1.EmbeddedDatabase; } });
|
|
46
|
+
var embedded_2 = require("./embedded");
|
|
47
|
+
Object.defineProperty(exports, "EmbeddedTransaction", { enumerable: true, get: function () { return embedded_2.EmbeddedTransaction; } });
|
|
48
|
+
// Embedded mode (FFI) - Convenience alias
|
|
49
|
+
var embedded_3 = require("./embedded");
|
|
50
|
+
Object.defineProperty(exports, "Database", { enumerable: true, get: function () { return embedded_3.EmbeddedDatabase; } });
|
|
51
|
+
// Server mode (gRPC/IPC)
|
|
52
|
+
var grpc_client_1 = require("./grpc-client");
|
|
53
|
+
Object.defineProperty(exports, "SochDBClient", { enumerable: true, get: function () { return grpc_client_1.SochDBClient; } });
|
|
54
|
+
var ipc_client_1 = require("./ipc-client");
|
|
55
|
+
Object.defineProperty(exports, "IpcClient", { enumerable: true, get: function () { return ipc_client_1.IpcClient; } });
|
|
56
|
+
// Format utilities
|
|
57
|
+
var format_1 = require("./format");
|
|
58
|
+
Object.defineProperty(exports, "WireFormat", { enumerable: true, get: function () { return format_1.WireFormat; } });
|
|
59
|
+
Object.defineProperty(exports, "ContextFormat", { enumerable: true, get: function () { return format_1.ContextFormat; } });
|
|
60
|
+
Object.defineProperty(exports, "CanonicalFormat", { enumerable: true, get: function () { return format_1.CanonicalFormat; } });
|
|
61
|
+
Object.defineProperty(exports, "FormatCapabilities", { enumerable: true, get: function () { return format_1.FormatCapabilities; } });
|
|
62
|
+
Object.defineProperty(exports, "FormatConversionError", { enumerable: true, get: function () { return format_1.FormatConversionError; } });
|
|
63
|
+
// Type definitions
|
|
64
|
+
var query_1 = require("./query");
|
|
65
|
+
Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return query_1.Query; } });
|
|
66
|
+
var errors_1 = require("./errors");
|
|
67
|
+
Object.defineProperty(exports, "SochDBError", { enumerable: true, get: function () { return errors_1.SochDBError; } });
|
|
68
|
+
Object.defineProperty(exports, "ConnectionError", { enumerable: true, get: function () { return errors_1.ConnectionError; } });
|
|
69
|
+
Object.defineProperty(exports, "TransactionError", { enumerable: true, get: function () { return errors_1.TransactionError; } });
|
|
70
|
+
Object.defineProperty(exports, "ProtocolError", { enumerable: true, get: function () { return errors_1.ProtocolError; } });
|
|
71
|
+
Object.defineProperty(exports, "DatabaseError", { enumerable: true, get: function () { return errors_1.DatabaseError; } });
|
|
72
|
+
// Convenience alias
|
|
73
|
+
var grpc_client_2 = require("./grpc-client");
|
|
74
|
+
Object.defineProperty(exports, "GrpcClient", { enumerable: true, get: function () { return grpc_client_2.SochDBClient; } });
|
|
75
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQ0c7OztBQUVILFVBQVU7QUFDRyxRQUFBLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFFL0IsNEJBQTRCO0FBQzVCLHVDQUFzRTtBQUE3RCw0R0FBQSxnQkFBZ0IsT0FBQTtBQUN6Qix1Q0FBaUQ7QUFBeEMsK0dBQUEsbUJBQW1CLE9BQUE7QUFFNUIsMENBQTBDO0FBQzFDLHVDQUEwRDtBQUFqRCxvR0FBQSxnQkFBZ0IsT0FBWTtBQUVyQyx5QkFBeUI7QUFDekIsNkNBQTZDO0FBQXBDLDJHQUFBLFlBQVksT0FBQTtBQVFyQiwyQ0FBeUM7QUFBaEMsdUdBQUEsU0FBUyxPQUFBO0FBRWxCLG1CQUFtQjtBQUNuQixtQ0FNa0I7QUFMaEIsb0dBQUEsVUFBVSxPQUFBO0FBQ1YsdUdBQUEsYUFBYSxPQUFBO0FBQ2IseUdBQUEsZUFBZSxPQUFBO0FBQ2YsNEdBQUEsa0JBQWtCLE9BQUE7QUFDbEIsK0dBQUEscUJBQXFCLE9BQUE7QUFHdkIsbUJBQW1CO0FBQ25CLGlDQUFnQztBQUF2Qiw4RkFBQSxLQUFLLE9BQUE7QUFHZCxtQ0FNa0I7QUFMaEIscUdBQUEsV0FBVyxPQUFBO0FBQ1gseUdBQUEsZUFBZSxPQUFBO0FBQ2YsMEdBQUEsZ0JBQWdCLE9BQUE7QUFDaEIsdUdBQUEsYUFBYSxPQUFBO0FBQ2IsdUdBQUEsYUFBYSxPQUFBO0FBR2Ysb0JBQW9CO0FBQ3BCLDZDQUEyRDtBQUFsRCx5R0FBQSxZQUFZLE9BQWMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNvY2hEQiBOb2RlLmpzIFNESyB2MC40LjBcbiAqIFxuICogRHVhbC1tb2RlIGFyY2hpdGVjdHVyZTogRW1iZWRkZWQgKEZGSSkgKyBTZXJ2ZXIgKGdSUEMvSVBDKVxuICogXG4gKiBBcmNoaXRlY3R1cmU6IEZsZXhpYmxlIERlcGxveW1lbnRcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFRoaXMgU0RLIHN1cHBvcnRzIEJPVEggbW9kZXM6XG4gKiBcbiAqIDEuIEVtYmVkZGVkIE1vZGUgKEZGSSkgLSBGb3Igc2luZ2xlLXByb2Nlc3MgYXBwczpcbiAqICAgIC0gRGlyZWN0IEZGSSBiaW5kaW5ncyB0byBSdXN0IGxpYnJhcmllc1xuICogICAgLSBObyBzZXJ2ZXIgcmVxdWlyZWQgLSBqdXN0IG5wbSBpbnN0YWxsIGFuZCBydW5cbiAqICAgIC0gQmVzdCBmb3I6IExvY2FsIGRldmVsb3BtZW50LCBzaW1wbGUgYXBwc1xuICogXG4gKiAyLiBTZXJ2ZXIgTW9kZSAoZ1JQQy9JUEMpIC0gRm9yIGRpc3RyaWJ1dGVkIHN5c3RlbXM6XG4gKiAgICAtIFRoaW4gY2xpZW50IGNvbm5lY3RpbmcgdG8gc29jaGRiLWdycGMgc2VydmVyXG4gKiAgICAtIEJlc3QgZm9yOiBQcm9kdWN0aW9uLCBtdWx0aS1sYW5ndWFnZSwgc2NhbGFiaWxpdHlcbiAqIFxuICogQGV4YW1wbGUgRW1iZWRkZWQgTW9kZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgRGF0YWJhc2UgfSBmcm9tICdAc29jaGRiL3NvY2hkYic7XG4gKiBcbiAqIC8vIERpcmVjdCBGRkkgLSBubyBzZXJ2ZXIgbmVlZGVkXG4gKiBjb25zdCBkYiA9IGF3YWl0IERhdGFiYXNlLm9wZW4oJy4vbXlkYicpO1xuICogYXdhaXQgZGIucHV0KEJ1ZmZlci5mcm9tKCdrZXknKSwgQnVmZmVyLmZyb20oJ3ZhbHVlJykpO1xuICogYXdhaXQgZGIuY2xvc2UoKTtcbiAqIGBgYFxuICogXG4gKiBAZXhhbXBsZSBTZXJ2ZXIgTW9kZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgU29jaERCQ2xpZW50IH0gZnJvbSAnQHNvY2hkYi9zb2NoZGInO1xuICogXG4gKiAvLyBDb25uZWN0IHRvIHNlcnZlclxuICogY29uc3QgY2xpZW50ID0gbmV3IFNvY2hEQkNsaWVudCh7IGFkZHJlc3M6ICdsb2NhbGhvc3Q6NTAwNTEnIH0pO1xuICogYXdhaXQgY2xpZW50LnB1dEt2KCdrZXknLCBCdWZmZXIuZnJvbSgndmFsdWUnKSk7XG4gKiBgYGBcbiAqL1xuXG4vLyBWZXJzaW9uXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9ICcwLjQuMCc7XG5cbi8vIEVtYmVkZGVkIG1vZGUgKEZGSSkgLSBORVdcbmV4cG9ydCB7IEVtYmVkZGVkRGF0YWJhc2UsIEVtYmVkZGVkRGF0YWJhc2VDb25maWcgfSBmcm9tICcuL2VtYmVkZGVkJztcbmV4cG9ydCB7IEVtYmVkZGVkVHJhbnNhY3Rpb24gfSBmcm9tICcuL2VtYmVkZGVkJztcblxuLy8gRW1iZWRkZWQgbW9kZSAoRkZJKSAtIENvbnZlbmllbmNlIGFsaWFzXG5leHBvcnQgeyBFbWJlZGRlZERhdGFiYXNlIGFzIERhdGFiYXNlIH0gZnJvbSAnLi9lbWJlZGRlZCc7XG5cbi8vIFNlcnZlciBtb2RlIChnUlBDL0lQQylcbmV4cG9ydCB7IFNvY2hEQkNsaWVudCB9IGZyb20gJy4vZ3JwYy1jbGllbnQnO1xuZXhwb3J0IHR5cGUge1xuICBTZWFyY2hSZXN1bHQsXG4gIERvY3VtZW50LFxuICBHcmFwaE5vZGUsXG4gIEdyYXBoRWRnZSxcbn0gZnJvbSAnLi9ncnBjLWNsaWVudCc7XG5cbmV4cG9ydCB7IElwY0NsaWVudCB9IGZyb20gJy4vaXBjLWNsaWVudCc7XG5cbi8vIEZvcm1hdCB1dGlsaXRpZXNcbmV4cG9ydCB7XG4gIFdpcmVGb3JtYXQsXG4gIENvbnRleHRGb3JtYXQsXG4gIENhbm9uaWNhbEZvcm1hdCxcbiAgRm9ybWF0Q2FwYWJpbGl0aWVzLFxuICBGb3JtYXRDb252ZXJzaW9uRXJyb3IsXG59IGZyb20gJy4vZm9ybWF0JztcblxuLy8gVHlwZSBkZWZpbml0aW9uc1xuZXhwb3J0IHsgUXVlcnkgfSBmcm9tICcuL3F1ZXJ5JztcbmV4cG9ydCB0eXBlIHsgUXVlcnlSZXN1bHQgfSBmcm9tICcuL3F1ZXJ5JztcblxuZXhwb3J0IHtcbiAgU29jaERCRXJyb3IsXG4gIENvbm5lY3Rpb25FcnJvcixcbiAgVHJhbnNhY3Rpb25FcnJvcixcbiAgUHJvdG9jb2xFcnJvcixcbiAgRGF0YWJhc2VFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMnO1xuXG4vLyBDb252ZW5pZW5jZSBhbGlhc1xuZXhwb3J0IHsgU29jaERCQ2xpZW50IGFzIEdycGNDbGllbnQgfSBmcm9tICcuL2dycGMtY2xpZW50JztcbiJdfQ==
|