@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.
Files changed (78) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3349 -0
  3. package/_bin/aarch64-apple-darwin/libsochdb_storage.dylib +0 -0
  4. package/_bin/aarch64-apple-darwin/sochdb-bulk +0 -0
  5. package/_bin/aarch64-apple-darwin/sochdb-grpc-server +0 -0
  6. package/_bin/aarch64-apple-darwin/sochdb-server +0 -0
  7. package/_bin/x86_64-pc-windows-msvc/sochdb-bulk.exe +0 -0
  8. package/_bin/x86_64-pc-windows-msvc/sochdb-grpc-server.exe +0 -0
  9. package/_bin/x86_64-pc-windows-msvc/sochdb_storage.dll +0 -0
  10. package/_bin/x86_64-unknown-linux-gnu/libsochdb_storage.so +0 -0
  11. package/_bin/x86_64-unknown-linux-gnu/sochdb-bulk +0 -0
  12. package/_bin/x86_64-unknown-linux-gnu/sochdb-grpc-server +0 -0
  13. package/_bin/x86_64-unknown-linux-gnu/sochdb-server +0 -0
  14. package/bin/sochdb-bulk.js +80 -0
  15. package/bin/sochdb-grpc-server.js +80 -0
  16. package/bin/sochdb-server.js +84 -0
  17. package/dist/cjs/analytics.js +196 -0
  18. package/dist/cjs/database.js +929 -0
  19. package/dist/cjs/embedded/database.js +236 -0
  20. package/dist/cjs/embedded/ffi/bindings.js +113 -0
  21. package/dist/cjs/embedded/ffi/library-finder.js +135 -0
  22. package/dist/cjs/embedded/index.js +14 -0
  23. package/dist/cjs/embedded/transaction.js +172 -0
  24. package/dist/cjs/errors.js +71 -0
  25. package/dist/cjs/format.js +176 -0
  26. package/dist/cjs/grpc-client.js +328 -0
  27. package/dist/cjs/index.js +75 -0
  28. package/dist/cjs/ipc-client.js +504 -0
  29. package/dist/cjs/query.js +154 -0
  30. package/dist/cjs/server-manager.js +295 -0
  31. package/dist/cjs/sql-engine.js +874 -0
  32. package/dist/esm/analytics.js +196 -0
  33. package/dist/esm/database.js +931 -0
  34. package/dist/esm/embedded/database.js +239 -0
  35. package/dist/esm/embedded/ffi/bindings.js +142 -0
  36. package/dist/esm/embedded/ffi/library-finder.js +135 -0
  37. package/dist/esm/embedded/index.js +14 -0
  38. package/dist/esm/embedded/transaction.js +176 -0
  39. package/dist/esm/errors.js +71 -0
  40. package/dist/esm/format.js +179 -0
  41. package/dist/esm/grpc-client.js +333 -0
  42. package/dist/esm/index.js +75 -0
  43. package/dist/esm/ipc-client.js +505 -0
  44. package/dist/esm/query.js +159 -0
  45. package/dist/esm/server-manager.js +295 -0
  46. package/dist/esm/sql-engine.js +875 -0
  47. package/dist/types/analytics.d.ts +66 -0
  48. package/dist/types/analytics.d.ts.map +1 -0
  49. package/dist/types/database.d.ts +523 -0
  50. package/dist/types/database.d.ts.map +1 -0
  51. package/dist/types/embedded/database.d.ts +105 -0
  52. package/dist/types/embedded/database.d.ts.map +1 -0
  53. package/dist/types/embedded/ffi/bindings.d.ts +24 -0
  54. package/dist/types/embedded/ffi/bindings.d.ts.map +1 -0
  55. package/dist/types/embedded/ffi/library-finder.d.ts +17 -0
  56. package/dist/types/embedded/ffi/library-finder.d.ts.map +1 -0
  57. package/dist/types/embedded/index.d.ts +9 -0
  58. package/dist/types/embedded/index.d.ts.map +1 -0
  59. package/dist/types/embedded/transaction.d.ts +21 -0
  60. package/dist/types/embedded/transaction.d.ts.map +1 -0
  61. package/dist/types/errors.d.ts +36 -0
  62. package/dist/types/errors.d.ts.map +1 -0
  63. package/dist/types/format.d.ts +117 -0
  64. package/dist/types/format.d.ts.map +1 -0
  65. package/dist/types/grpc-client.d.ts +120 -0
  66. package/dist/types/grpc-client.d.ts.map +1 -0
  67. package/dist/types/index.d.ts +50 -0
  68. package/dist/types/index.d.ts.map +1 -0
  69. package/dist/types/ipc-client.d.ts +177 -0
  70. package/dist/types/ipc-client.d.ts.map +1 -0
  71. package/dist/types/query.d.ts +85 -0
  72. package/dist/types/query.d.ts.map +1 -0
  73. package/dist/types/server-manager.d.ts +29 -0
  74. package/dist/types/server-manager.d.ts.map +1 -0
  75. package/dist/types/sql-engine.d.ts +100 -0
  76. package/dist/types/sql-engine.d.ts.map +1 -0
  77. package/package.json +90 -0
  78. package/scripts/postinstall.js +50 -0
@@ -0,0 +1,505 @@
1
+ "use strict";
2
+ /**
3
+ * SochDB IPC Client
4
+ *
5
+ * Connects to a SochDB IPC server via Unix domain socket.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.IpcClient = exports.OpCode = void 0;
44
+ // Copyright 2025 Sushanth (https://github.com/sushanthpy)
45
+ //
46
+ // Licensed under the Apache License, Version 2.0 (the "License");
47
+ // you may not use this file except in compliance with the License.
48
+ // You may obtain a copy of the License at
49
+ //
50
+ // http://www.apache.org/licenses/LICENSE-2.0
51
+ const net = __importStar(require("net"));
52
+ const errors_1 = require("./errors");
53
+ const query_1 = require("./query");
54
+ /**
55
+ * Wire protocol opcodes.
56
+ */
57
+ exports.OpCode = {
58
+ // Client → Server (must match sochdb-storage/src/ipc_server.rs)
59
+ Put: 0x01,
60
+ Get: 0x02,
61
+ Delete: 0x03,
62
+ BeginTxn: 0x04,
63
+ CommitTxn: 0x05,
64
+ AbortTxn: 0x06,
65
+ Query: 0x07,
66
+ CreateTable: 0x08,
67
+ PutPath: 0x09,
68
+ GetPath: 0x0A,
69
+ Scan: 0x0B,
70
+ Checkpoint: 0x0C,
71
+ Stats: 0x0D,
72
+ Ping: 0x0E,
73
+ // Server → Client
74
+ OK: 0x80,
75
+ Error: 0x81,
76
+ Value: 0x82,
77
+ TxnId: 0x83,
78
+ Row: 0x84,
79
+ EndStream: 0x85,
80
+ StatsResp: 0x86,
81
+ Pong: 0x87,
82
+ };
83
+ // Internal OpCode map for backwards compatibility
84
+ const InternalOpCode = {
85
+ PUT: exports.OpCode.Put,
86
+ GET: exports.OpCode.Get,
87
+ DELETE: exports.OpCode.Delete,
88
+ BEGIN_TXN: exports.OpCode.BeginTxn,
89
+ COMMIT_TXN: exports.OpCode.CommitTxn,
90
+ ABORT_TXN: exports.OpCode.AbortTxn,
91
+ QUERY: exports.OpCode.Query,
92
+ PUT_PATH: exports.OpCode.PutPath,
93
+ GET_PATH: exports.OpCode.GetPath,
94
+ SCAN: exports.OpCode.Scan,
95
+ CHECKPOINT: exports.OpCode.Checkpoint,
96
+ STATS: exports.OpCode.Stats,
97
+ PING: exports.OpCode.Ping,
98
+ OK: exports.OpCode.OK,
99
+ ERROR: exports.OpCode.Error,
100
+ VALUE: exports.OpCode.Value,
101
+ TXN_ID: exports.OpCode.TxnId,
102
+ ROW: exports.OpCode.Row,
103
+ END_STREAM: exports.OpCode.EndStream,
104
+ STATS_RESP: exports.OpCode.StatsResp,
105
+ PONG: exports.OpCode.Pong,
106
+ };
107
+ const MAX_MESSAGE_SIZE = 16 * 1024 * 1024; // 16 MB
108
+ /**
109
+ * IPC Client for SochDB.
110
+ *
111
+ * Connects to a SochDB server via Unix domain socket.
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * import { IpcClient } from '@sushanth/sochdb';
116
+ *
117
+ * const client = await IpcClient.connect('/tmp/sochdb.sock');
118
+ *
119
+ * await client.put(Buffer.from('key'), Buffer.from('value'));
120
+ * const value = await client.get(Buffer.from('key'));
121
+ *
122
+ * await client.close();
123
+ * ```
124
+ */
125
+ class IpcClient {
126
+ _socket = null;
127
+ _config;
128
+ _pendingReads = [];
129
+ _readBuffer = Buffer.alloc(0);
130
+ _closed = false;
131
+ constructor(config) {
132
+ this._config = {
133
+ connectTimeout: 5000,
134
+ readTimeout: 30000,
135
+ ...config,
136
+ };
137
+ }
138
+ /**
139
+ * Connect to a SochDB IPC server.
140
+ *
141
+ * @param socketPath - Path to the Unix domain socket
142
+ * @returns A connected IpcClient instance
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const client = await IpcClient.connect('/tmp/sochdb.sock');
147
+ * ```
148
+ */
149
+ static async connect(socketPath) {
150
+ const client = new IpcClient({ socketPath });
151
+ await client._connect();
152
+ return client;
153
+ }
154
+ async _connect() {
155
+ return new Promise((resolve, reject) => {
156
+ const socket = net.createConnection({ path: this._config.socketPath }, () => {
157
+ this._socket = socket;
158
+ resolve();
159
+ });
160
+ socket.setTimeout(this._config.connectTimeout);
161
+ socket.on('timeout', () => {
162
+ socket.destroy();
163
+ reject(new errors_1.ConnectionError('Connection timeout'));
164
+ });
165
+ socket.on('error', (err) => {
166
+ reject(new errors_1.ConnectionError(`Connection failed: ${err.message}`));
167
+ });
168
+ socket.on('data', (data) => {
169
+ this._readBuffer = Buffer.concat([this._readBuffer, data]);
170
+ this._processBuffer();
171
+ });
172
+ socket.on('close', () => {
173
+ this._closed = true;
174
+ for (const pending of this._pendingReads) {
175
+ pending.reject(new errors_1.ConnectionError('Connection closed'));
176
+ }
177
+ this._pendingReads = [];
178
+ });
179
+ });
180
+ }
181
+ _processBuffer() {
182
+ // Process complete messages from the buffer
183
+ while (this._readBuffer.length >= 5 && this._pendingReads.length > 0) {
184
+ const length = this._readBuffer.readUInt32LE(1);
185
+ const totalLength = 5 + length;
186
+ if (this._readBuffer.length >= totalLength) {
187
+ const message = this._readBuffer.subarray(0, totalLength);
188
+ this._readBuffer = this._readBuffer.subarray(totalLength);
189
+ const pending = this._pendingReads.shift();
190
+ if (pending) {
191
+ pending.resolve(message);
192
+ }
193
+ }
194
+ else {
195
+ break;
196
+ }
197
+ }
198
+ }
199
+ async _send(opcode, payload = Buffer.alloc(0)) {
200
+ if (this._closed || !this._socket) {
201
+ throw new errors_1.ConnectionError('Not connected');
202
+ }
203
+ // Encode message: opcode (1) + length (4 LE) + payload
204
+ const message = Buffer.alloc(5 + payload.length);
205
+ message.writeUInt8(opcode, 0);
206
+ message.writeUInt32LE(payload.length, 1);
207
+ payload.copy(message, 5);
208
+ return new Promise((resolve, reject) => {
209
+ this._pendingReads.push({ resolve, reject });
210
+ this._socket.write(message, (err) => {
211
+ if (err) {
212
+ this._pendingReads.pop();
213
+ reject(new errors_1.ConnectionError(`Write failed: ${err.message}`));
214
+ }
215
+ });
216
+ // Set timeout for response
217
+ setTimeout(() => {
218
+ const idx = this._pendingReads.findIndex((p) => p.resolve === resolve);
219
+ if (idx !== -1) {
220
+ this._pendingReads.splice(idx, 1);
221
+ reject(new errors_1.ConnectionError('Read timeout'));
222
+ }
223
+ }, this._config.readTimeout);
224
+ });
225
+ }
226
+ _parseResponse(response) {
227
+ const opcode = response.readUInt8(0);
228
+ const length = response.readUInt32LE(1);
229
+ const payload = response.subarray(5, 5 + length);
230
+ if (opcode === InternalOpCode.ERROR) {
231
+ throw new errors_1.ProtocolError(payload.toString('utf8'));
232
+ }
233
+ return { opcode, payload };
234
+ }
235
+ /**
236
+ * Encode a key for the wire protocol.
237
+ * @internal
238
+ */
239
+ static encodeKey(key) {
240
+ // Format: [length:4][op:1][key_len:4][key:...]
241
+ const msgLen = 1 + 4 + key.length;
242
+ const msg = Buffer.alloc(4 + msgLen);
243
+ msg.writeUInt32BE(msgLen, 0);
244
+ msg.writeUInt8(InternalOpCode.GET, 4);
245
+ msg.writeUInt32BE(key.length, 5);
246
+ key.copy(msg, 9);
247
+ return msg;
248
+ }
249
+ /**
250
+ * Encode a key-value pair for the wire protocol.
251
+ * @internal
252
+ */
253
+ static encodeKeyValue(key, value) {
254
+ // Format: [length:4][op:1][key_len:4][key:...][value_len:4][value:...]
255
+ const msgLen = 1 + 4 + key.length + 4 + value.length;
256
+ const msg = Buffer.alloc(4 + msgLen);
257
+ msg.writeUInt32BE(msgLen, 0);
258
+ msg.writeUInt8(InternalOpCode.PUT, 4);
259
+ msg.writeUInt32BE(key.length, 5);
260
+ key.copy(msg, 9);
261
+ msg.writeUInt32BE(value.length, 9 + key.length);
262
+ value.copy(msg, 13 + key.length);
263
+ return msg;
264
+ }
265
+ /**
266
+ * Get a value by key.
267
+ */
268
+ async get(key) {
269
+ const response = await this._send(InternalOpCode.GET, key);
270
+ const { opcode, payload } = this._parseResponse(response);
271
+ if (opcode === InternalOpCode.VALUE) {
272
+ // If payload is empty, the key doesn't exist
273
+ if (payload.length === 0) {
274
+ return null;
275
+ }
276
+ return payload;
277
+ }
278
+ return null;
279
+ }
280
+ /**
281
+ * Put a key-value pair.
282
+ */
283
+ async put(key, value) {
284
+ // Encode: key_len (4 LE) + key + value
285
+ const payload = Buffer.alloc(4 + key.length + value.length);
286
+ payload.writeUInt32LE(key.length, 0);
287
+ key.copy(payload, 4);
288
+ value.copy(payload, 4 + key.length);
289
+ const response = await this._send(InternalOpCode.PUT, payload);
290
+ this._parseResponse(response);
291
+ }
292
+ /**
293
+ * Delete a key.
294
+ */
295
+ async delete(key) {
296
+ const response = await this._send(InternalOpCode.DELETE, key);
297
+ this._parseResponse(response);
298
+ }
299
+ /**
300
+ * Get a value by path.
301
+ * Wire format: path_count(2 LE) + [path_len(2 LE) + path_segment]...
302
+ */
303
+ async getPath(path) {
304
+ // Encode path as single segment for now (could split on '/' for multi-segment)
305
+ const pathBuf = Buffer.from(path, 'utf8');
306
+ const payload = Buffer.alloc(2 + 2 + pathBuf.length);
307
+ payload.writeUInt16LE(1, 0); // path_count = 1
308
+ payload.writeUInt16LE(pathBuf.length, 2); // path_len
309
+ pathBuf.copy(payload, 4); // path
310
+ const response = await this._send(InternalOpCode.GET_PATH, payload);
311
+ const { opcode, payload: responsePayload } = this._parseResponse(response);
312
+ if (opcode === InternalOpCode.VALUE) {
313
+ // If payload is empty, the key doesn't exist
314
+ if (responsePayload.length === 0) {
315
+ return null;
316
+ }
317
+ return responsePayload;
318
+ }
319
+ return null;
320
+ }
321
+ /**
322
+ * Put a value at a path.
323
+ * Wire format: path_count(2 LE) + [path_len(2 LE) + path_segment]... + value
324
+ */
325
+ async putPath(path, value) {
326
+ const pathBuf = Buffer.from(path, 'utf8');
327
+ const payload = Buffer.alloc(2 + 2 + pathBuf.length + value.length);
328
+ payload.writeUInt16LE(1, 0); // path_count = 1
329
+ payload.writeUInt16LE(pathBuf.length, 2); // path_len
330
+ pathBuf.copy(payload, 4); // path
331
+ value.copy(payload, 4 + pathBuf.length); // value
332
+ const response = await this._send(InternalOpCode.PUT_PATH, payload);
333
+ this._parseResponse(response);
334
+ }
335
+ /**
336
+ * Execute a query and return TOON-formatted results.
337
+ *
338
+ * Wire format: path_len(2) + path + limit(4) + offset(4) + cols_count(2) + [col_len(2) + col]...
339
+ */
340
+ async query(pathPrefix, options) {
341
+ const opts = options || {};
342
+ const pathBuf = Buffer.from(pathPrefix, 'utf8');
343
+ const columns = opts.columns || [];
344
+ // Calculate payload size
345
+ let size = 2 + pathBuf.length + 4 + 4 + 2;
346
+ for (const col of columns) {
347
+ size += 2 + Buffer.byteLength(col, 'utf8');
348
+ }
349
+ const payload = Buffer.alloc(size);
350
+ let offset = 0;
351
+ // Path: path_len(2 LE) + path
352
+ payload.writeUInt16LE(pathBuf.length, offset);
353
+ offset += 2;
354
+ pathBuf.copy(payload, offset);
355
+ offset += pathBuf.length;
356
+ // Limit (4 LE) - 0 means no limit
357
+ payload.writeUInt32LE(opts.limit || 0, offset);
358
+ offset += 4;
359
+ // Offset (4 LE)
360
+ payload.writeUInt32LE(opts.offset || 0, offset);
361
+ offset += 4;
362
+ // Columns: count(2 LE) + [col_len(2 LE) + col]...
363
+ payload.writeUInt16LE(columns.length, offset);
364
+ offset += 2;
365
+ for (const col of columns) {
366
+ const colBuf = Buffer.from(col, 'utf8');
367
+ payload.writeUInt16LE(colBuf.length, offset);
368
+ offset += 2;
369
+ colBuf.copy(payload, offset);
370
+ offset += colBuf.length;
371
+ }
372
+ const response = await this._send(InternalOpCode.QUERY, payload);
373
+ const { payload: resultPayload } = this._parseResponse(response);
374
+ return resultPayload.toString('utf8');
375
+ }
376
+ /**
377
+ * Scan for keys with a prefix, returning key-value pairs.
378
+ * This is the preferred method for simple prefix-based iteration.
379
+ *
380
+ * Wire format: prefix string
381
+ * Response format: count(4 LE) + [key_len(2 LE) + key + val_len(4 LE) + val]...
382
+ */
383
+ async scan(prefix) {
384
+ const prefixBuf = Buffer.from(prefix, 'utf8');
385
+ const response = await this._send(InternalOpCode.SCAN, prefixBuf);
386
+ const { opcode, payload } = this._parseResponse(response);
387
+ if (opcode !== InternalOpCode.VALUE && opcode !== InternalOpCode.OK) {
388
+ throw new errors_1.ProtocolError(`Unexpected scan response opcode: 0x${opcode.toString(16)}`);
389
+ }
390
+ if (payload.length < 4) {
391
+ return []; // Empty result
392
+ }
393
+ // Parse response: count(4 LE) + [key_len(2 LE) + key + val_len(4 LE) + val]...
394
+ const count = payload.readUInt32LE(0);
395
+ const results = [];
396
+ let offset = 4;
397
+ for (let i = 0; i < count; i++) {
398
+ if (offset + 2 > payload.length) {
399
+ throw new errors_1.ProtocolError('Truncated scan response (key_len)');
400
+ }
401
+ const keyLen = payload.readUInt16LE(offset);
402
+ offset += 2;
403
+ if (offset + keyLen + 4 > payload.length) {
404
+ throw new errors_1.ProtocolError('Truncated scan response (key+val_len)');
405
+ }
406
+ const key = payload.subarray(offset, offset + keyLen);
407
+ offset += keyLen;
408
+ const valLen = payload.readUInt32LE(offset);
409
+ offset += 4;
410
+ if (offset + valLen > payload.length) {
411
+ throw new errors_1.ProtocolError('Truncated scan response (value)');
412
+ }
413
+ const value = payload.subarray(offset, offset + valLen);
414
+ offset += valLen;
415
+ results.push({ key, value });
416
+ }
417
+ return results;
418
+ }
419
+ /**
420
+ * Create a query builder.
421
+ */
422
+ queryBuilder(pathPrefix) {
423
+ return new query_1.Query(this, pathPrefix);
424
+ }
425
+ /**
426
+ * Begin a new transaction.
427
+ */
428
+ async beginTransaction() {
429
+ const response = await this._send(InternalOpCode.BEGIN_TXN);
430
+ const { opcode, payload } = this._parseResponse(response);
431
+ if (opcode === InternalOpCode.TXN_ID) {
432
+ return payload.readBigUInt64LE(0);
433
+ }
434
+ throw new errors_1.TransactionError('Failed to begin transaction');
435
+ }
436
+ /**
437
+ * Commit a transaction.
438
+ */
439
+ async commitTransaction(txnId) {
440
+ const payload = Buffer.alloc(8);
441
+ payload.writeBigUInt64LE(txnId, 0);
442
+ const response = await this._send(InternalOpCode.COMMIT_TXN, payload);
443
+ this._parseResponse(response);
444
+ }
445
+ /**
446
+ * Abort a transaction.
447
+ */
448
+ async abortTransaction(txnId) {
449
+ const payload = Buffer.alloc(8);
450
+ payload.writeBigUInt64LE(txnId, 0);
451
+ const response = await this._send(InternalOpCode.ABORT_TXN, payload);
452
+ this._parseResponse(response);
453
+ }
454
+ /**
455
+ * Force a checkpoint.
456
+ */
457
+ async checkpoint() {
458
+ const response = await this._send(InternalOpCode.CHECKPOINT);
459
+ this._parseResponse(response);
460
+ }
461
+ /**
462
+ * Get storage statistics.
463
+ */
464
+ async stats() {
465
+ const response = await this._send(InternalOpCode.STATS);
466
+ const { payload } = this._parseResponse(response);
467
+ const json = JSON.parse(payload.toString('utf8'));
468
+ return {
469
+ memtableSizeBytes: json.memtable_size_bytes || 0,
470
+ walSizeBytes: json.wal_size_bytes || 0,
471
+ activeTransactions: json.active_transactions || 0,
472
+ };
473
+ }
474
+ /**
475
+ * Ping the server.
476
+ */
477
+ async ping() {
478
+ try {
479
+ const response = await this._send(InternalOpCode.PING);
480
+ const { opcode } = this._parseResponse(response);
481
+ return opcode === InternalOpCode.PONG;
482
+ }
483
+ catch {
484
+ return false;
485
+ }
486
+ }
487
+ /**
488
+ * Close the connection.
489
+ */
490
+ async close() {
491
+ if (this._closed)
492
+ return;
493
+ this._closed = true;
494
+ if (this._socket) {
495
+ return new Promise((resolve) => {
496
+ this._socket.end(() => {
497
+ this._socket = null;
498
+ resolve();
499
+ });
500
+ });
501
+ }
502
+ }
503
+ }
504
+ exports.IpcClient = IpcClient;
505
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBjLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pcGMtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILDBEQUEwRDtBQUMxRCxFQUFFO0FBQ0Ysa0VBQWtFO0FBQ2xFLG1FQUFtRTtBQUNuRSwwQ0FBMEM7QUFDMUMsRUFBRTtBQUNGLGlEQUFpRDtBQUVqRCx5Q0FBMkI7QUFDM0IscUNBQTRFO0FBQzVFLG1DQUFnQztBQUVoQzs7R0FFRztBQUNVLFFBQUEsTUFBTSxHQUFHO0lBQ3BCLGdFQUFnRTtJQUNoRSxHQUFHLEVBQUUsSUFBSTtJQUNULEdBQUcsRUFBRSxJQUFJO0lBQ1QsTUFBTSxFQUFFLElBQUk7SUFDWixRQUFRLEVBQUUsSUFBSTtJQUNkLFNBQVMsRUFBRSxJQUFJO0lBQ2YsUUFBUSxFQUFFLElBQUk7SUFDZCxLQUFLLEVBQUUsSUFBSTtJQUNYLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLE9BQU8sRUFBRSxJQUFJO0lBQ2IsT0FBTyxFQUFFLElBQUk7SUFDYixJQUFJLEVBQUUsSUFBSTtJQUNWLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLEtBQUssRUFBRSxJQUFJO0lBQ1gsSUFBSSxFQUFFLElBQUk7SUFFVixrQkFBa0I7SUFDbEIsRUFBRSxFQUFFLElBQUk7SUFDUixLQUFLLEVBQUUsSUFBSTtJQUNYLEtBQUssRUFBRSxJQUFJO0lBQ1gsS0FBSyxFQUFFLElBQUk7SUFDWCxHQUFHLEVBQUUsSUFBSTtJQUNULFNBQVMsRUFBRSxJQUFJO0lBQ2YsU0FBUyxFQUFFLElBQUk7SUFDZixJQUFJLEVBQUUsSUFBSTtDQUNGLENBQUM7QUFFWCxrREFBa0Q7QUFDbEQsTUFBTSxjQUFjLEdBQUc7SUFDckIsR0FBRyxFQUFFLGNBQU0sQ0FBQyxHQUFHO0lBQ2YsR0FBRyxFQUFFLGNBQU0sQ0FBQyxHQUFHO0lBQ2YsTUFB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QUFDO1NBQ2xELENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBSTtRQUNSLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakQsT0FBTyxNQUFNLEtBQUssY0FBYyxDQUFDLElBQUksQ0FBQztRQUN4QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEtBQUs7UUFDVCxJQUFJLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxPQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDckIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7b0JBQ3BCLE9BQU8sRUFBRSxDQUFDO2dCQUNaLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBaGNELDhCQWdjQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU29jaERCIElQQyBDbGllbnRcbiAqXG4gKiBDb25uZWN0cyB0byBhIFNvY2hEQiBJUEMgc2VydmVyIHZpYSBVbml4IGRvbWFpbiBzb2NrZXQuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cblxuLy8gQ29weXJpZ2h0IDIwMjUgU3VzaGFudGggKGh0dHBzOi8vZ2l0aHViLmNvbS9zdXNoYW50aHB5KVxuLy9cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4vLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4vLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbi8vXG4vLyAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cbmltcG9ydCAqIGFzIG5ldCBmcm9tICduZXQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbkVycm9yLCBQcm90b2NvbEVycm9yLCBUcmFuc2FjdGlvbkVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgUXVlcnkgfSBmcm9tICcuL3F1ZXJ5JztcblxuLyoqXG4gKiBXaXJlIHByb3RvY29sIG9wY29kZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBPcENvZGUgPSB7XG4gIC8vIENsaWVudCDihpIgU2VydmVyIChtdXN0IG1hdGNoIHNvY2hkYi1zdG9yYWdlL3NyYy9pcGNfc2VydmVyLnJzKVxuICBQdXQ6IDB4MDEsXG4gIEdldDogMHgwMixcbiAgRGVsZXRlOiAweDAzLFxuICBCZWdpblR4bjogMHgwNCxcbiAgQ29tbWl0VHhuOiAweDA1LFxuICBBYm9ydFR4bjogMHgwNixcbiAgUXVlcnk6IDB4MDcsXG4gIENyZWF0ZVRhYmxlOiAweDA4LFxuICBQdXRQYXRoOiAweDA5LFxuICBHZXRQYXRoOiAweDBBLFxuICBTY2FuOiAweDBCLFxuICBDaGVja3BvaW50OiAweDBDLFxuICBTdGF0czogMHgwRCxcbiAgUGluZzogMHgwRSxcblxuICAvLyBTZXJ2ZXIg4oaSIENsaWVudFxuICBPSzogMHg4MCxcbiAgRXJyb3I6IDB4ODEsXG4gIFZhbHVlOiAweDgyLFxuICBUeG5JZDogMHg4MyxcbiAgUm93OiAweDg0LFxuICBFbmRTdHJlYW06IDB4ODUsXG4gIFN0YXRzUmVzcDogMHg4NixcbiAgUG9uZzogMHg4Nyxcbn0gYXMgY29uc3Q7XG5cbi8vIEludGVybmFsIE9wQ29kZSBtYXAgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5jb25zdCBJbnRlcm5hbE9wQ29kZSA9IHtcbiAgUFVUOiBPcENvZGUuUHV0LFxuICBHRVQ6IE9wQ29kZS5HZXQsXG4gIERFTEVURTogT3BDb2RlLkRlbGV0ZSxcbiAgQkVHSU5fVFhOOiBPcENvZGUuQmVnaW5UeG4sXG4gIENPTU1JVF9UWE46IE9wQ29kZS5Db21taXRUeG4sXG4gIEFCT1JUX1RYTjogT3BDb2RlLkFib3J0VHhuLFxuICBRVUVSWTogT3BDb2RlLlF1ZXJ5LFxuICBQVVRfUEFUSDogT3BDb2RlLlB1dFBhdGgsXG4gIEdFVF9QQVRIOiBPcENvZGUuR2V0UGF0aCxcbiAgU0NBTjogT3BDb2RlLlNjYW4sXG4gIENIRUNLUE9JTlQ6IE9wQ29kZS5DaGVja3BvaW50LFxuICBTVEFUUzogT3BDb2RlLlN0YXRzLFxuICBQSU5HOiBPcENvZGUuUGluZyxcbiAgT0s6IE9wQ29kZS5PSyxcbiAgRVJST1I6IE9wQ29kZS5FcnJvcixcbiAgVkFMVUU6IE9wQ29kZS5WYWx1ZSxcbiAgVFhOX0lEOiBPcENvZGUuVHhuSWQsXG4gIFJPVzogT3BDb2RlLlJvdyxcbiAgRU5EX1NUUkVBTTogT3BDb2RlLkVuZFN0cmVhbSxcbiAgU1RBVFNfUkVTUDogT3BDb2RlLlN0YXRzUmVzcCxcbiAgUE9ORzogT3BDb2RlLlBvbmcsXG59IGFzIGNvbnN0O1xuXG5jb25zdCBNQVhfTUVTU0FHRV9TSVpFID0gMTYgKiAxMDI0ICogMTAyNDsgLy8gMTYgTUJcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIElwY0NsaWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJcGNDbGllbnRDb25maWcge1xuICAvKiogUGF0aCB0byBVbml4IGRvbWFpbiBzb2NrZXQgKi9cbiAgc29ja2V0UGF0aDogc3RyaW5nO1xuICAvKiogQ29ubmVjdGlvbiB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogNTAwMCkgKi9cbiAgY29ubmVjdFRpbWVvdXQ/OiBudW1iZXI7XG4gIC8qKiBSZWFkIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChkZWZhdWx0OiAzMDAwMCkgKi9cbiAgcmVhZFRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogSVBDIENsaWVudCBmb3IgU29jaERCLlxuICpcbiAqIENvbm5lY3RzIHRvIGEgU29jaERCIHNlcnZlciB2aWEgVW5peCBkb21haW4gc29ja2V0LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBJcGNDbGllbnQgfSBmcm9tICdAc3VzaGFudGgvc29jaGRiJztcbiAqXG4gKiBjb25zdCBjbGllbnQgPSBhd2FpdCBJcGNDbGllbnQuY29ubmVjdCgnL3RtcC9zb2NoZGIuc29jaycpO1xuICpcbiAqIGF3YWl0IGNsaWVudC5wdXQoQnVmZmVyLmZyb20oJ2tleScpLCBCdWZmZXIuZnJvbSgndmFsdWUnKSk7XG4gKiBjb25zdCB2YWx1ZSA9IGF3YWl0IGNsaWVudC5nZXQoQnVmZmVyLmZyb20oJ2tleScpKTtcbiAqXG4gKiBhd2FpdCBjbGllbnQuY2xvc2UoKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgSXBjQ2xpZW50IHtcbiAgcHJpdmF0ZSBfc29ja2V0OiBuZXQuU29ja2V0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2NvbmZpZzogUmVxdWlyZWQ8SXBjQ2xpZW50Q29uZmlnPjtcbiAgcHJpdmF0ZSBfcGVuZGluZ1JlYWRzOiBBcnJheTx7XG4gICAgcmVzb2x2ZTogKGJ1ZjogQnVmZmVyKSA9PiB2b2lkO1xuICAgIHJlamVjdDogKGVycjogRXJyb3IpID0+IHZvaWQ7XG4gIH0+ID0gW107XG4gIHByaXZhdGUgX3JlYWRCdWZmZXI6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygwKTtcbiAgcHJpdmF0ZSBfY2xvc2VkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihjb25maWc6IElwY0NsaWVudENvbmZpZykge1xuICAgIHRoaXMuX2NvbmZpZyA9IHtcbiAgICAgIGNvbm5lY3RUaW1lb3V0OiA1MDAwLFxuICAgICAgcmVhZFRpbWVvdXQ6IDMwMDAwLFxuICAgICAgLi4uY29uZmlnLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29ubmVjdCB0byBhIFNvY2hEQiBJUEMgc2VydmVyLlxuICAgKlxuICAgKiBAcGFyYW0gc29ja2V0UGF0aCAtIFBhdGggdG8gdGhlIFVuaXggZG9tYWluIHNvY2tldFxuICAgKiBAcmV0dXJucyBBIGNvbm5lY3RlZCBJcGNDbGllbnQgaW5zdGFuY2VcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBjbGllbnQgPSBhd2FpdCBJcGNDbGllbnQuY29ubmVjdCgnL3RtcC9zb2NoZGIuc29jaycpO1xuICAgKiBgYGBcbiAgICovXG4gIHN0YXRpYyBhc3luYyBjb25uZWN0KHNvY2tldFBhdGg6IHN0cmluZyk6IFByb21pc2U8SXBjQ2xpZW50PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IElwY0NsaWVudCh7IHNvY2tldFBhdGggfSk7XG4gICAgYXdhaXQgY2xpZW50Ll9jb25uZWN0KCk7XG4gICAgcmV0dXJuIGNsaWVudDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IG5ldC5jcmVhdGVDb25uZWN0aW9uKFxuICAgICAgICB7IHBhdGg6IHRoaXMuX2NvbmZpZy5zb2NrZXRQYXRoIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9zb2NrZXQgPSBzb2NrZXQ7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgICBzb2NrZXQuc2V0VGltZW91dCh0aGlzLl9jb25maWcuY29ubmVjdFRpbWVvdXQpO1xuXG4gICAgICBzb2NrZXQub24oJ3RpbWVvdXQnLCAoKSA9PiB7XG4gICAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKCdDb25uZWN0aW9uIHRpbWVvdXQnKSk7XG4gICAgICB9KTtcblxuICAgICAgc29ja2V0Lm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgICAgcmVqZWN0KG5ldyBDb25uZWN0aW9uRXJyb3IoYENvbm5lY3Rpb24gZmFpbGVkOiAke2Vyci5tZXNzYWdlfWApKTtcbiAgICAgIH0pO1xuXG4gICAgICBzb2NrZXQub24oJ2RhdGEnLCAoZGF0YSkgPT4ge1xuICAgICAgICB0aGlzLl9yZWFkQnVmZmVyID0gQnVmZmVyLmNvbmNhdChbdGhpcy5fcmVhZEJ1ZmZlciwgZGF0YV0pO1xuICAgICAgICB0aGlzLl9wcm9jZXNzQnVmZmVyKCk7XG4gICAgICB9KTtcblxuICAgICAgc29ja2V0Lm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5fY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBwZW5kaW5nIG9mIHRoaXMuX3BlbmRpbmdSZWFkcykge1xuICAgICAgICAgIHBlbmRpbmcucmVqZWN0KG5ldyBDb25uZWN0aW9uRXJyb3IoJ0Nvbm5lY3Rpb24gY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3BlbmRpbmdSZWFkcyA9IFtdO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9wcm9jZXNzQnVmZmVyKCk6IHZvaWQge1xuICAgIC8vIFByb2Nlc3MgY29tcGxldGUgbWVzc2FnZXMgZnJvbSB0aGUgYnVmZmVyXG4gICAgd2hpbGUgKHRoaXMuX3JlYWRCdWZmZXIubGVuZ3RoID49IDUgJiYgdGhpcy5fcGVuZGluZ1JlYWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHRoaXMuX3JlYWRCdWZmZXIucmVhZFVJbnQzMkxFKDEpO1xuICAgICAgY29uc3QgdG90YWxMZW5ndGggPSA1ICsgbGVuZ3RoO1xuXG4gICAgICBpZiAodGhpcy5fcmVhZEJ1ZmZlci5sZW5ndGggPj0gdG90YWxMZW5ndGgpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHRoaXMuX3JlYWRCdWZmZXIuc3ViYXJyYXkoMCwgdG90YWxMZW5ndGgpO1xuICAgICAgICB0aGlzLl9yZWFkQnVmZmVyID0gdGhpcy5fcmVhZEJ1ZmZlci5zdWJhcnJheSh0b3RhbExlbmd0aCk7XG5cbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHRoaXMuX3BlbmRpbmdSZWFkcy5zaGlmdCgpO1xuICAgICAgICBpZiAocGVuZGluZykge1xuICAgICAgICAgIHBlbmRpbmcucmVzb2x2ZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfc2VuZChvcGNvZGU6IG51bWJlciwgcGF5bG9hZDogQnVmZmVyID0gQnVmZmVyLmFsbG9jKDApKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBpZiAodGhpcy5fY2xvc2VkIHx8ICF0aGlzLl9zb2NrZXQpIHtcbiAgICAgIHRocm93IG5ldyBDb25uZWN0aW9uRXJyb3IoJ05vdCBjb25uZWN0ZWQnKTtcbiAgICB9XG5cbiAgICAvLyBFbmNvZGUgbWVzc2FnZTogb3Bjb2RlICgxKSArIGxlbmd0aCAoNCBMRSkgKyBwYXlsb2FkXG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5hbGxvYyg1ICsgcGF5bG9hZC5sZW5ndGgpO1xuICAgIG1lc3NhZ2Uud3JpdGVVSW50OChvcGNvZGUsIDApO1xuICAgIG1lc3NhZ2Uud3JpdGVVSW50MzJMRShwYXlsb2FkLmxlbmd0aCwgMSk7XG4gICAgcGF5bG9hZC5jb3B5KG1lc3NhZ2UsIDUpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX3BlbmRpbmdSZWFkcy5wdXNoKHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuXG4gICAgICB0aGlzLl9zb2NrZXQhLndyaXRlKG1lc3NhZ2UsIChlcnIpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHRoaXMuX3BlbmRpbmdSZWFkcy5wb3AoKTtcbiAgICAgICAgICByZWplY3QobmV3IENvbm5lY3Rpb25FcnJvcihgV3JpdGUgZmFpbGVkOiAke2Vyci5tZXNzYWdlfWApKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNldCB0aW1lb3V0IGZvciByZXNwb25zZVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkeCA9IHRoaXMuX3BlbmRpbmdSZWFkcy5maW5kSW5kZXgoKHApID0+IHAucmVzb2x2ZSA9PT0gcmVzb2x2ZSk7XG4gICAgICAgIGlmIChpZHggIT09IC0xKSB7XG4gICAgICAgICAgdGhpcy5fcGVuZGluZ1JlYWRzLnNwbGljZShpZHgsIDEpO1xuICAgICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKCdSZWFkIHRpbWVvdXQnKSk7XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMuX2NvbmZpZy5yZWFkVGltZW91dCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlOiBCdWZmZXIpOiB7IG9wY29kZTogbnVtYmVyOyBwYXlsb2FkOiBCdWZmZXIgfSB7XG4gICAgY29uc3Qgb3Bjb2RlID0gcmVzcG9uc2UucmVhZFVJbnQ4KDApO1xuICAgIGNvbnN0IGxlbmd0aCA9IHJlc3BvbnNlLnJlYWRVSW50MzJMRSgxKTtcbiAgICBjb25zdCBwYXlsb2FkID0gcmVzcG9uc2Uuc3ViYXJyYXkoNSwgNSArIGxlbmd0aCk7XG5cbiAgICBpZiAob3Bjb2RlID09PSBJbnRlcm5hbE9wQ29kZS5FUlJPUikge1xuICAgICAgdGhyb3cgbmV3IFByb3RvY29sRXJyb3IocGF5bG9hZC50b1N0cmluZygndXRmOCcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBvcGNvZGUsIHBheWxvYWQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGUgYSBrZXkgZm9yIHRoZSB3aXJlIHByb3RvY29sLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHN0YXRpYyBlbmNvZGVLZXkoa2V5OiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIC8vIEZvcm1hdDogW2xlbmd0aDo0XVtvcDoxXVtrZXlfbGVuOjRdW2tleTouLi5dXG4gICAgY29uc3QgbXNnTGVuID0gMSArIDQgKyBrZXkubGVuZ3RoO1xuICAgIGNvbnN0IG1zZyA9IEJ1ZmZlci5hbGxvYyg0ICsgbXNnTGVuKTtcbiAgICBtc2cud3JpdGVVSW50MzJCRShtc2dMZW4sIDApO1xuICAgIG1zZy53cml0ZVVJbnQ4KEludGVybmFsT3BDb2RlLkdFVCwgNCk7XG4gICAgbXNnLndyaXRlVUludDMyQkUoa2V5Lmxlbmd0aCwgNSk7XG4gICAga2V5LmNvcHkobXNnLCA5KTtcbiAgICByZXR1cm4gbXNnO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZSBhIGtleS12YWx1ZSBwYWlyIGZvciB0aGUgd2lyZSBwcm90b2NvbC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBzdGF0aWMgZW5jb2RlS2V5VmFsdWUoa2V5OiBCdWZmZXIsIHZhbHVlOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIC8vIEZvcm1hdDogW2xlbmd0aDo0XVtvcDoxXVtrZXlfbGVuOjRdW2tleTouLi5dW3ZhbHVlX2xlbjo0XVt2YWx1ZTouLi5dXG4gICAgY29uc3QgbXNnTGVuID0gMSArIDQgKyBrZXkubGVuZ3RoICsgNCArIHZhbHVlLmxlbmd0aDtcbiAgICBjb25zdCBtc2cgPSBCdWZmZXIuYWxsb2MoNCArIG1zZ0xlbik7XG4gICAgbXNnLndyaXRlVUludDMyQkUobXNnTGVuLCAwKTtcbiAgICBtc2cud3JpdGVVSW50OChJbnRlcm5hbE9wQ29kZS5QVVQsIDQpO1xuICAgIG1zZy53cml0ZVVJbnQzMkJFKGtleS5sZW5ndGgsIDUpO1xuICAgIGtleS5jb3B5KG1zZywgOSk7XG4gICAgbXNnLndyaXRlVUludDMyQkUodmFsdWUubGVuZ3RoLCA5ICsga2V5Lmxlbmd0aCk7XG4gICAgdmFsdWUuY29weShtc2csIDEzICsga2V5Lmxlbmd0aCk7XG4gICAgcmV0dXJuIG1zZztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSB2YWx1ZSBieSBrZXkuXG4gICAqL1xuICBhc3luYyBnZXQoa2V5OiBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlciB8IG51bGw+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuR0VULCBrZXkpO1xuICAgIGNvbnN0IHsgb3Bjb2RlLCBwYXlsb2FkIH0gPSB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuICAgIGlmIChvcGNvZGUgPT09IEludGVybmFsT3BDb2RlLlZBTFVFKSB7XG4gICAgICAvLyBJZiBwYXlsb2FkIGlzIGVtcHR5LCB0aGUga2V5IGRvZXNuJ3QgZXhpc3RcbiAgICAgIGlmIChwYXlsb2FkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYSBrZXktdmFsdWUgcGFpci5cbiAgICovXG4gIGFzeW5jIHB1dChrZXk6IEJ1ZmZlciwgdmFsdWU6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEVuY29kZToga2V5X2xlbiAoNCBMRSkgKyBrZXkgKyB2YWx1ZVxuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuYWxsb2MoNCArIGtleS5sZW5ndGggKyB2YWx1ZS5sZW5ndGgpO1xuICAgIHBheWxvYWQud3JpdGVVSW50MzJMRShrZXkubGVuZ3RoLCAwKTtcbiAgICBrZXkuY29weShwYXlsb2FkLCA0KTtcbiAgICB2YWx1ZS5jb3B5KHBheWxvYWQsIDQgKyBrZXkubGVuZ3RoKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5QVVQsIHBheWxvYWQpO1xuICAgIHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZSBhIGtleS5cbiAgICovXG4gIGFzeW5jIGRlbGV0ZShrZXk6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5ERUxFVEUsIGtleSk7XG4gICAgdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgdmFsdWUgYnkgcGF0aC5cbiAgICogV2lyZSBmb3JtYXQ6IHBhdGhfY291bnQoMiBMRSkgKyBbcGF0aF9sZW4oMiBMRSkgKyBwYXRoX3NlZ21lbnRdLi4uXG4gICAqL1xuICBhc3luYyBnZXRQYXRoKHBhdGg6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyIHwgbnVsbD4ge1xuICAgIC8vIEVuY29kZSBwYXRoIGFzIHNpbmdsZSBzZWdtZW50IGZvciBub3cgKGNvdWxkIHNwbGl0IG9uICcvJyBmb3IgbXVsdGktc2VnbWVudClcbiAgICBjb25zdCBwYXRoQnVmID0gQnVmZmVyLmZyb20ocGF0aCwgJ3V0ZjgnKTtcbiAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmFsbG9jKDIgKyAyICsgcGF0aEJ1Zi5sZW5ndGgpO1xuICAgIHBheWxvYWQud3JpdGVVSW50MTZMRSgxLCAwKTsgLy8gcGF0aF9jb3VudCA9IDFcbiAgICBwYXlsb2FkLndyaXRlVUludDE2TEUocGF0aEJ1Zi5sZW5ndGgsIDIpOyAvLyBwYXRoX2xlblxuICAgIHBhdGhCdWYuY29weShwYXlsb2FkLCA0KTsgLy8gcGF0aFxuICAgIFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5HRVRfUEFUSCwgcGF5bG9hZCk7XG4gICAgY29uc3QgeyBvcGNvZGUsIHBheWxvYWQ6IHJlc3BvbnNlUGF5bG9hZCB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgICBpZiAob3Bjb2RlID09PSBJbnRlcm5hbE9wQ29kZS5WQUxVRSkge1xuICAgICAgLy8gSWYgcGF5bG9hZCBpcyBlbXB0eSwgdGhlIGtleSBkb2Vzbid0IGV4aXN0XG4gICAgICBpZiAocmVzcG9uc2VQYXlsb2FkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNwb25zZVBheWxvYWQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1dCBhIHZhbHVlIGF0IGEgcGF0aC5cbiAgICogV2lyZSBmb3JtYXQ6IHBhdGhfY291bnQoMiBMRSkgKyBbcGF0aF9sZW4oMiBMRSkgKyBwYXRoX3NlZ21lbnRdLi4uICsgdmFsdWVcbiAgICovXG4gIGFzeW5jIHB1dFBhdGgocGF0aDogc3RyaW5nLCB2YWx1ZTogQnVmZmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGF0aEJ1ZiA9IEJ1ZmZlci5mcm9tKHBhdGgsICd1dGY4Jyk7XG4gICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5hbGxvYygyICsgMiArIHBhdGhCdWYubGVuZ3RoICsgdmFsdWUubGVuZ3RoKTtcbiAgICBwYXlsb2FkLndyaXRlVUludDE2TEUoMSwgMCk7IC8vIHBhdGhfY291bnQgPSAxXG4gICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKHBhdGhCdWYubGVuZ3RoLCAyKTsgLy8gcGF0aF9sZW5cbiAgICBwYXRoQnVmLmNvcHkocGF5bG9hZCwgNCk7IC8vIHBhdGhcbiAgICB2YWx1ZS5jb3B5KHBheWxvYWQsIDQgKyBwYXRoQnVmLmxlbmd0aCk7IC8vIHZhbHVlXG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuUFVUX1BBVEgsIHBheWxvYWQpO1xuICAgIHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYSBxdWVyeSBhbmQgcmV0dXJuIFRPT04tZm9ybWF0dGVkIHJlc3VsdHMuXG4gICAqIFxuICAgKiBXaXJlIGZvcm1hdDogcGF0aF9sZW4oMikgKyBwYXRoICsgbGltaXQoNCkgKyBvZmZzZXQoNCkgKyBjb2xzX2NvdW50KDIpICsgW2NvbF9sZW4oMikgKyBjb2xdLi4uXG4gICAqL1xuICBhc3luYyBxdWVyeShcbiAgICBwYXRoUHJlZml4OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IHsgbGltaXQ/OiBudW1iZXI7IG9mZnNldD86IG51bWJlcjsgY29sdW1ucz86IHN0cmluZ1tdIH1cbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBvcHRzID0gb3B0aW9ucyB8fCB7fTtcbiAgICBjb25zdCBwYXRoQnVmID0gQnVmZmVyLmZyb20ocGF0aFByZWZpeCwgJ3V0ZjgnKTtcbiAgICBjb25zdCBjb2x1bW5zID0gb3B0cy5jb2x1bW5zIHx8IFtdO1xuICAgIFxuICAgIC8vIENhbGN1bGF0ZSBwYXlsb2FkIHNpemVcbiAgICBsZXQgc2l6ZSA9IDIgKyBwYXRoQnVmLmxlbmd0aCArIDQgKyA0ICsgMjtcbiAgICBmb3IgKGNvbnN0IGNvbCBvZiBjb2x1bW5zKSB7XG4gICAgICBzaXplICs9IDIgKyBCdWZmZXIuYnl0ZUxlbmd0aChjb2wsICd1dGY4Jyk7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuYWxsb2Moc2l6ZSk7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgXG4gICAgLy8gUGF0aDogcGF0aF9sZW4oMiBMRSkgKyBwYXRoXG4gICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKHBhdGhCdWYubGVuZ3RoLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSAyO1xuICAgIHBhdGhCdWYuY29weShwYXlsb2FkLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSBwYXRoQnVmLmxlbmd0aDtcbiAgICBcbiAgICAvLyBMaW1pdCAoNCBMRSkgLSAwIG1lYW5zIG5vIGxpbWl0XG4gICAgcGF5bG9hZC53cml0ZVVJbnQzMkxFKG9wdHMubGltaXQgfHwgMCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gNDtcbiAgICBcbiAgICAvLyBPZmZzZXQgKDQgTEUpXG4gICAgcGF5bG9hZC53cml0ZVVJbnQzMkxFKG9wdHMub2Zmc2V0IHx8IDAsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IDQ7XG4gICAgXG4gICAgLy8gQ29sdW1uczogY291bnQoMiBMRSkgKyBbY29sX2xlbigyIExFKSArIGNvbF0uLi5cbiAgICBwYXlsb2FkLndyaXRlVUludDE2TEUoY29sdW1ucy5sZW5ndGgsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IDI7XG4gICAgZm9yIChjb25zdCBjb2wgb2YgY29sdW1ucykge1xuICAgICAgY29uc3QgY29sQnVmID0gQnVmZmVyLmZyb20oY29sLCAndXRmOCcpO1xuICAgICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKGNvbEJ1Zi5sZW5ndGgsIG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gMjtcbiAgICAgIGNvbEJ1Zi5jb3B5KHBheWxvYWQsIG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gY29sQnVmLmxlbmd0aDtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuUVVFUlksIHBheWxvYWQpO1xuICAgIGNvbnN0IHsgcGF5bG9hZDogcmVzdWx0UGF5bG9hZCB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgICByZXR1cm4gcmVzdWx0UGF5bG9hZC50b1N0cmluZygndXRmOCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjYW4gZm9yIGtleXMgd2l0aCBhIHByZWZpeCwgcmV0dXJuaW5nIGtleS12YWx1ZSBwYWlycy5cbiAgICogVGhpcyBpcyB0aGUgcHJlZmVycmVkIG1ldGhvZCBmb3Igc2ltcGxlIHByZWZpeC1iYXNlZCBpdGVyYXRpb24uXG4gICAqIFxuICAgKiBXaXJlIGZvcm1hdDogcHJlZml4IHN0cmluZ1xuICAgKiBSZXNwb25zZSBmb3JtYXQ6IGNvdW50KDQgTEUpICsgW2tleV9sZW4oMiBMRSkgKyBrZXkgKyB2YWxfbGVuKDQgTEUpICsgdmFsXS4uLlxuICAgKi9cbiAgYXN5bmMgc2NhbihwcmVmaXg6IHN0cmluZyk6IFByb21pc2U8QXJyYXk8eyBrZXk6IEJ1ZmZlcjsgdmFsdWU6IEJ1ZmZlciB9Pj4ge1xuICAgIGNvbnN0IHByZWZpeEJ1ZiA9IEJ1ZmZlci5mcm9tKHByZWZpeCwgJ3V0ZjgnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuU0NBTiwgcHJlZml4QnVmKTtcbiAgICBjb25zdCB7IG9wY29kZSwgcGF5bG9hZCB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgICBpZiAob3Bjb2RlICE9PSBJbnRlcm5hbE9wQ29kZS5WQUxVRSAmJiBvcGNvZGUgIT09IEludGVybmFsT3BDb2RlLk9LKSB7XG4gICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFcnJvcihgVW5leHBlY3RlZCBzY2FuIHJlc3BvbnNlIG9wY29kZTogMHgke29wY29kZS50b1N0cmluZygxNil9YCk7XG4gICAgfVxuXG4gICAgaWYgKHBheWxvYWQubGVuZ3RoIDwgNCkge1xuICAgICAgcmV0dXJuIFtdOyAvLyBFbXB0eSByZXN1bHRcbiAgICB9XG5cbiAgICAvLyBQYXJzZSByZXNwb25zZTogY291bnQoNCBMRSkgKyBba2V5X2xlbigyIExFKSArIGtleSArIHZhbF9sZW4oNCBMRSkgKyB2YWxdLi4uXG4gICAgY29uc3QgY291bnQgPSBwYXlsb2FkLnJlYWRVSW50MzJMRSgwKTtcbiAgICBjb25zdCByZXN1bHRzOiBBcnJheTx7IGtleTogQnVmZmVyOyB2YWx1ZTogQnVmZmVyIH0+ID0gW107XG4gICAgbGV0IG9mZnNldCA9IDQ7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgIGlmIChvZmZzZXQgKyAyID4gcGF5bG9hZC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFByb3RvY29sRXJyb3IoJ1RydW5jYXRlZCBzY2FuIHJlc3BvbnNlIChrZXlfbGVuKScpO1xuICAgICAgfVxuICAgICAgY29uc3Qga2V5TGVuID0gcGF5bG9hZC5yZWFkVUludDE2TEUob2Zmc2V0KTtcbiAgICAgIG9mZnNldCArPSAyO1xuXG4gICAgICBpZiAob2Zmc2V0ICsga2V5TGVuICsgNCA+IHBheWxvYWQubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBQcm90b2NvbEVycm9yKCdUcnVuY2F0ZWQgc2NhbiByZXNwb25zZSAoa2V5K3ZhbF9sZW4pJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBrZXkgPSBwYXlsb2FkLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsga2V5TGVuKTtcbiAgICAgIG9mZnNldCArPSBrZXlMZW47XG5cbiAgICAgIGNvbnN0IHZhbExlbiA9IHBheWxvYWQucmVhZFVJbnQzMkxFKG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gNDtcblxuICAgICAgaWYgKG9mZnNldCArIHZhbExlbiA+IHBheWxvYWQubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBQcm90b2NvbEVycm9yKCdUcnVuY2F0ZWQgc2NhbiByZXNwb25zZSAodmFsdWUpJyk7XG4gICAgICB9XG4gICAgICBjb25zdCB2YWx1ZSA9IHBheWxvYWQuc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyB2YWxMZW4pO1xuICAgICAgb2Zmc2V0ICs9IHZhbExlbjtcblxuICAgICAgcmVzdWx0cy5wdXNoKHsga2V5LCB2YWx1ZSB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBxdWVyeSBidWlsZGVyLlxuICAgKi9cbiAgcXVlcnlCdWlsZGVyKHBhdGhQcmVmaXg6IHN0cmluZyk6IFF1ZXJ5IHtcbiAgICByZXR1cm4gbmV3IFF1ZXJ5KHRoaXMsIHBhdGhQcmVmaXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJlZ2luIGEgbmV3IHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgYmVnaW5UcmFuc2FjdGlvbigpOiBQcm9taXNlPGJpZ2ludD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5CRUdJTl9UWE4pO1xuICAgIGNvbnN0IHsgb3Bjb2RlLCBwYXlsb2FkIH0gPSB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuICAgIGlmIChvcGNvZGUgPT09IEludGVybmFsT3BDb2RlLlRYTl9JRCkge1xuICAgICAgcmV0dXJuIHBheWxvYWQucmVhZEJpZ1VJbnQ2NExFKDApO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgVHJhbnNhY3Rpb25FcnJvcignRmFpbGVkIHRvIGJlZ2luIHRyYW5zYWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogQ29tbWl0IGEgdHJhbnNhY3Rpb24uXG4gICAqL1xuICBhc3luYyBjb21taXRUcmFuc2FjdGlvbih0eG5JZDogYmlnaW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5hbGxvYyg4KTtcbiAgICBwYXlsb2FkLndyaXRlQmlnVUludDY0TEUodHhuSWQsIDApO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5DT01NSVRfVFhOLCBwYXlsb2FkKTtcbiAgICB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBYm9ydCBhIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgYWJvcnRUcmFuc2FjdGlvbih0eG5JZDogYmlnaW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5hbGxvYyg4KTtcbiAgICBwYXlsb2FkLndyaXRlQmlnVUludDY0TEUodHhuSWQsIDApO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5BQk9SVF9UWE4sIHBheWxvYWQpO1xuICAgIHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmNlIGEgY2hlY2twb2ludC5cbiAgICovXG4gIGFzeW5jIGNoZWNrcG9pbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLkNIRUNLUE9JTlQpO1xuICAgIHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzdG9yYWdlIHN0YXRpc3RpY3MuXG4gICAqL1xuICBhc3luYyBzdGF0cygpOiBQcm9taXNlPHtcbiAgICBtZW10YWJsZVNpemVCeXRlczogbnVtYmVyO1xuICAgIHdhbFNpemVCeXRlczogbnVtYmVyO1xuICAgIGFjdGl2ZVRyYW5zYWN0aW9uczogbnVtYmVyO1xuICB9PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLlNUQVRTKTtcbiAgICBjb25zdCB7IHBheWxvYWQgfSA9IHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgIGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKHBheWxvYWQudG9TdHJpbmcoJ3V0ZjgnKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lbXRhYmxlU2l6ZUJ5dGVzOiBqc29uLm1lbXRhYmxlX3NpemVfYnl0ZXMgfHwgMCxcbiAgICAgIHdhbFNpemVCeXRlczoganNvbi53YWxfc2l6ZV9ieXRlcyB8fCAwLFxuICAgICAgYWN0aXZlVHJhbnNhY3Rpb25zOiBqc29uLmFjdGl2ZV90cmFuc2FjdGlvbnMgfHwgMCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBpbmcgdGhlIHNlcnZlci5cbiAgICovXG4gIGFzeW5jIHBpbmcoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5QSU5HKTtcbiAgICAgIGNvbnN0IHsgb3Bjb2RlIH0gPSB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICAgIHJldHVybiBvcGNvZGUgPT09IEludGVybmFsT3BDb2RlLlBPTkc7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgY2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuX2Nsb3NlZCkgcmV0dXJuO1xuICAgIHRoaXMuX2Nsb3NlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy5fc29ja2V0KSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgdGhpcy5fc29ja2V0IS5lbmQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX3NvY2tldCA9IG51bGw7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19