@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,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SochDB Query Builder
|
|
4
|
+
*
|
|
5
|
+
* Fluent query interface for SochDB.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.Query = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Fluent query builder for SochDB.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const results = await db.query('users/')
|
|
17
|
+
* .limit(10)
|
|
18
|
+
* .select(['name', 'email'])
|
|
19
|
+
* .toList();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
class Query {
|
|
23
|
+
_client;
|
|
24
|
+
_pathPrefix;
|
|
25
|
+
_limit;
|
|
26
|
+
_offset;
|
|
27
|
+
_columns;
|
|
28
|
+
constructor(client, pathPrefix) {
|
|
29
|
+
this._client = client;
|
|
30
|
+
this._pathPrefix = pathPrefix;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Limit the number of results.
|
|
34
|
+
*
|
|
35
|
+
* @param n - Maximum number of results to return
|
|
36
|
+
* @returns This query builder for chaining
|
|
37
|
+
*/
|
|
38
|
+
limit(n) {
|
|
39
|
+
this._limit = n;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Skip the first n results.
|
|
44
|
+
*
|
|
45
|
+
* @param n - Number of results to skip
|
|
46
|
+
* @returns This query builder for chaining
|
|
47
|
+
*/
|
|
48
|
+
offset(n) {
|
|
49
|
+
this._offset = n;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Select specific columns to return.
|
|
54
|
+
*
|
|
55
|
+
* @param columns - Array of column names to select
|
|
56
|
+
* @returns This query builder for chaining
|
|
57
|
+
*/
|
|
58
|
+
select(columns) {
|
|
59
|
+
this._columns = columns;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Execute the query and return results as TOON string.
|
|
64
|
+
*
|
|
65
|
+
* @returns TOON formatted string (e.g., "result[N]{cols}: row1; row2")
|
|
66
|
+
*/
|
|
67
|
+
async execute() {
|
|
68
|
+
return this._client.query(this._pathPrefix, {
|
|
69
|
+
limit: this._limit,
|
|
70
|
+
offset: this._offset,
|
|
71
|
+
columns: this._columns,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Execute and parse results into a list of objects.
|
|
76
|
+
*
|
|
77
|
+
* @returns Array of result objects
|
|
78
|
+
*/
|
|
79
|
+
async toList() {
|
|
80
|
+
const toonStr = await this.execute();
|
|
81
|
+
return this._parseToon(toonStr);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Execute and return the first result, or null if none.
|
|
85
|
+
*
|
|
86
|
+
* @returns First result or null
|
|
87
|
+
*/
|
|
88
|
+
async first() {
|
|
89
|
+
const originalLimit = this._limit;
|
|
90
|
+
this._limit = 1;
|
|
91
|
+
const results = await this.toList();
|
|
92
|
+
this._limit = originalLimit;
|
|
93
|
+
return results.length > 0 ? results[0] : null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Execute and return the count of results.
|
|
97
|
+
*
|
|
98
|
+
* @returns Number of matching results
|
|
99
|
+
*/
|
|
100
|
+
async count() {
|
|
101
|
+
const results = await this.toList();
|
|
102
|
+
return results.length;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Simple TOON parser.
|
|
106
|
+
*
|
|
107
|
+
* Parses TOON format: "result[N]{col1,col2}: val1,val2; val3,val4"
|
|
108
|
+
*/
|
|
109
|
+
_parseToon(toonStr) {
|
|
110
|
+
if (!toonStr || toonStr === 'result[0]{}:') {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
// Parse header: result[N]{cols}:
|
|
114
|
+
const headerMatch = toonStr.match(/^result\[(\d+)\]\{([^}]*)\}:\s*/);
|
|
115
|
+
if (!headerMatch) {
|
|
116
|
+
// Try to parse as JSON if not TOON format
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(toonStr);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const count = parseInt(headerMatch[1], 10);
|
|
125
|
+
if (count === 0) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const columns = headerMatch[2].split(',').map((c) => c.trim());
|
|
129
|
+
const body = toonStr.substring(headerMatch[0].length);
|
|
130
|
+
// Split rows by semicolon
|
|
131
|
+
const rows = body.split(';').map((r) => r.trim()).filter((r) => r.length > 0);
|
|
132
|
+
return rows.map((row) => {
|
|
133
|
+
const values = row.split(',').map((v) => v.trim());
|
|
134
|
+
const result = {};
|
|
135
|
+
columns.forEach((col, idx) => {
|
|
136
|
+
if (col && idx < values.length) {
|
|
137
|
+
// Try to parse as JSON/number
|
|
138
|
+
let value = values[idx];
|
|
139
|
+
if (value === 'null') {
|
|
140
|
+
value = null;
|
|
141
|
+
}
|
|
142
|
+
else if (value === 'true') {
|
|
143
|
+
value = true;
|
|
144
|
+
}
|
|
145
|
+
else if (value === 'false') {
|
|
146
|
+
value = false;
|
|
147
|
+
}
|
|
148
|
+
else if (!isNaN(Number(value))) {
|
|
149
|
+
value = Number(value);
|
|
150
|
+
}
|
|
151
|
+
result[col] = value;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return result;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.Query = Query;
|
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcXVlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7O0FBbUJIOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFhLEtBQUs7SUFDUixPQUFPLENBQVk7SUFDbkIsV0FBVyxDQUFTO0lBQ3BCLE1BQU0sQ0FBVTtJQUNoQixPQUFPLENBQVU7SUFDakIsUUFBUSxDQUFZO0lBRTVCLFlBQVksTUFBaUIsRUFBRSxVQUFrQjtRQUMvQyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsQ0FBUztRQUNiLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLENBQVM7UUFDZCxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxPQUFpQjtRQUN0QixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDMUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNwQixPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVE7U0FDdkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsTUFBTTtRQUNWLE1B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LENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2pDLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRSxDQUFDO3dCQUNyQixLQUFLLEdBQUcsSUFBSSxDQUFDO29CQUNmLENBQUM7eUJBQU0sSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFLENBQUM7d0JBQzVCLEtBQUssR0FBRyxJQUFJLENBQUM7b0JBQ2YsQ0FBQzt5QkFBTSxJQUFJLEtBQUssS0FBSyxPQUFPLEVBQUUsQ0FBQzt3QkFDN0IsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDaEIsQ0FBQzt5QkFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ2pDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3hCLENBQUM7b0JBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBRUgsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFuSkQsc0JBbUpDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTb2NoREIgUXVlcnkgQnVpbGRlclxuICpcbiAqIEZsdWVudCBxdWVyeSBpbnRlcmZhY2UgZm9yIFNvY2hEQi5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuXG4vLyBDb3B5cmlnaHQgMjAyNSBTdXNoYW50aCAoaHR0cHM6Ly9naXRodWIuY29tL3N1c2hhbnRocHkpXG4vL1xuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbi8vIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbi8vIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuLy9cbi8vICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuaW1wb3J0IHsgSXBjQ2xpZW50IH0gZnJvbSAnLi9pcGMtY2xpZW50JztcblxuLyoqXG4gKiBRdWVyeSByZXN1bHQgcm93LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1ZXJ5UmVzdWx0IHtcbiAgW2tleTogc3RyaW5nXTogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBGbHVlbnQgcXVlcnkgYnVpbGRlciBmb3IgU29jaERCLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHRzID0gYXdhaXQgZGIucXVlcnkoJ3VzZXJzLycpXG4gKiAgIC5saW1pdCgxMClcbiAqICAgLnNlbGVjdChbJ25hbWUnLCAnZW1haWwnXSlcbiAqICAgLnRvTGlzdCgpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBRdWVyeSB7XG4gIHByaXZhdGUgX2NsaWVudDogSXBjQ2xpZW50O1xuICBwcml2YXRlIF9wYXRoUHJlZml4OiBzdHJpbmc7XG4gIHByaXZhdGUgX2xpbWl0PzogbnVtYmVyO1xuICBwcml2YXRlIF9vZmZzZXQ/OiBudW1iZXI7XG4gIHByaXZhdGUgX2NvbHVtbnM/OiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihjbGllbnQ6IElwY0NsaWVudCwgcGF0aFByZWZpeDogc3RyaW5nKSB7XG4gICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMuX3BhdGhQcmVmaXggPSBwYXRoUHJlZml4O1xuICB9XG5cbiAgLyoqXG4gICAqIExpbWl0IHRoZSBudW1iZXIgb2YgcmVzdWx0cy5cbiAgICpcbiAgICogQHBhcmFtIG4gLSBNYXhpbXVtIG51bWJlciBvZiByZXN1bHRzIHRvIHJldHVyblxuICAgKiBAcmV0dXJucyBUaGlzIHF1ZXJ5IGJ1aWxkZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBsaW1pdChuOiBudW1iZXIpOiBRdWVyeSB7XG4gICAgdGhpcy5fbGltaXQgPSBuO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNraXAgdGhlIGZpcnN0IG4gcmVzdWx0cy5cbiAgICpcbiAgICogQHBhcmFtIG4gLSBOdW1iZXIgb2YgcmVzdWx0cyB0byBza2lwXG4gICAqIEByZXR1cm5zIFRoaXMgcXVlcnkgYnVpbGRlciBmb3IgY2hhaW5pbmdcbiAgICovXG4gIG9mZnNldChuOiBudW1iZXIpOiBRdWVyeSB7XG4gICAgdGhpcy5fb2Zmc2V0ID0gbjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3Qgc3BlY2lmaWMgY29sdW1ucyB0byByZXR1cm4uXG4gICAqXG4gICAqIEBwYXJhbSBjb2x1bW5zIC0gQXJyYXkgb2YgY29sdW1uIG5hbWVzIHRvIHNlbGVjdFxuICAgKiBAcmV0dXJucyBUaGlzIHF1ZXJ5IGJ1aWxkZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBzZWxlY3QoY29sdW1uczogc3RyaW5nW10pOiBRdWVyeSB7XG4gICAgdGhpcy5fY29sdW1ucyA9IGNvbHVtbnM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSB0aGUgcXVlcnkgYW5kIHJldHVybiByZXN1bHRzIGFzIFRPT04gc3RyaW5nLlxuICAgKlxuICAgKiBAcmV0dXJucyBUT09OIGZvcm1hdHRlZCBzdHJpbmcgKGUuZy4sIFwicmVzdWx0W05de2NvbHN9OiByb3cxOyByb3cyXCIpXG4gICAqL1xuICBhc3luYyBleGVjdXRlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5xdWVyeSh0aGlzLl9wYXRoUHJlZml4LCB7XG4gICAgICBsaW1pdDogdGhpcy5fbGltaXQsXG4gICAgICBvZmZzZXQ6IHRoaXMuX29mZnNldCxcbiAgICAgIGNvbHVtbnM6IHRoaXMuX2NvbHVtbnMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhbmQgcGFyc2UgcmVzdWx0cyBpbnRvIGEgbGlzdCBvZiBvYmplY3RzLlxuICAgKlxuICAgKiBAcmV0dXJucyBBcnJheSBvZiByZXN1bHQgb2JqZWN0c1xuICAgKi9cbiAgYXN5bmMgdG9MaXN0KCk6IFByb21pc2U8UXVlcnlSZXN1bHRbXT4ge1xuICAgIGNvbnN0IHRvb25TdHIgPSBhd2FpdCB0aGlzLmV4ZWN1dGUoKTtcbiAgICByZXR1cm4gdGhpcy5fcGFyc2VUb29uKHRvb25TdHIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYW5kIHJldHVybiB0aGUgZmlyc3QgcmVzdWx0LCBvciBudWxsIGlmIG5vbmUuXG4gICAqXG4gICAqIEByZXR1cm5zIEZpcnN0IHJlc3VsdCBvciBudWxsXG4gICAqL1xuICBhc3luYyBmaXJzdCgpOiBQcm9taXNlPFF1ZXJ5UmVzdWx0IHwgbnVsbD4ge1xuICAgIGNvbnN0IG9yaWdpbmFsTGltaXQgPSB0aGlzLl9saW1pdDtcbiAgICB0aGlzLl9saW1pdCA9IDE7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMudG9MaXN0KCk7XG4gICAgdGhpcy5fbGltaXQgPSBvcmlnaW5hbExpbWl0O1xuICAgIHJldHVybiByZXN1bHRzLmxlbmd0aCA+IDAgPyByZXN1bHRzWzBdIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGFuZCByZXR1cm4gdGhlIGNvdW50IG9mIHJlc3VsdHMuXG4gICAqXG4gICAqIEByZXR1cm5zIE51bWJlciBvZiBtYXRjaGluZyByZXN1bHRzXG4gICAqL1xuICBhc3luYyBjb3VudCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLnRvTGlzdCgpO1xuICAgIHJldHVybiByZXN1bHRzLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaW1wbGUgVE9PTiBwYXJzZXIuXG4gICAqXG4gICAqIFBhcnNlcyBUT09OIGZvcm1hdDogXCJyZXN1bHRbTl17Y29sMSxjb2wyfTogdmFsMSx2YWwyOyB2YWwzLHZhbDRcIlxuICAgKi9cbiAgcHJpdmF0ZSBfcGFyc2VUb29uKHRvb25TdHI6IHN0cmluZyk6IFF1ZXJ5UmVzdWx0W10ge1xuICAgIGlmICghdG9vblN0ciB8fCB0b29uU3RyID09PSAncmVzdWx0WzBde306Jykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIGhlYWRlcjogcmVzdWx0W05de2NvbHN9OlxuICAgIGNvbnN0IGhlYWRlck1hdGNoID0gdG9vblN0ci5tYXRjaCgvXnJlc3VsdFxcWyhcXGQrKVxcXVxceyhbXn1dKilcXH06XFxzKi8pO1xuICAgIGlmICghaGVhZGVyTWF0Y2gpIHtcbiAgICAgIC8vIFRyeSB0byBwYXJzZSBhcyBKU09OIGlmIG5vdCBUT09OIGZvcm1hdFxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodG9vblN0cik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvdW50ID0gcGFyc2VJbnQoaGVhZGVyTWF0Y2hbMV0sIDEwKTtcbiAgICBpZiAoY291bnQgPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2x1bW5zID0gaGVhZGVyTWF0Y2hbMl0uc3BsaXQoJywnKS5tYXAoKGMpID0+IGMudHJpbSgpKTtcbiAgICBjb25zdCBib2R5ID0gdG9vblN0ci5zdWJzdHJpbmcoaGVhZGVyTWF0Y2hbMF0ubGVuZ3RoKTtcblxuICAgIC8vIFNwbGl0IHJvd3MgYnkgc2VtaWNvbG9uXG4gICAgY29uc3Qgcm93cyA9IGJvZHkuc3BsaXQoJzsnKS5tYXAoKHIpID0+IHIudHJpbSgpKS5maWx0ZXIoKHIpID0+IHIubGVuZ3RoID4gMCk7XG5cbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gcm93LnNwbGl0KCcsJykubWFwKCh2KSA9PiB2LnRyaW0oKSk7XG4gICAgICBjb25zdCByZXN1bHQ6IFF1ZXJ5UmVzdWx0ID0ge307XG5cbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sLCBpZHgpID0+IHtcbiAgICAgICAgaWYgKGNvbCAmJiBpZHggPCB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gVHJ5IHRvIHBhcnNlIGFzIEpTT04vbnVtYmVyXG4gICAgICAgICAgbGV0IHZhbHVlOiB1bmtub3duID0gdmFsdWVzW2lkeF07XG4gICAgICAgICAgaWYgKHZhbHVlID09PSAnbnVsbCcpIHtcbiAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAnZmFsc2UnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIWlzTmFOKE51bWJlcih2YWx1ZSkpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IE51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdFtjb2xdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SochDB Embedded Server Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages the lifecycle of the SochDB server process for embedded mode.
|
|
6
|
+
* Automatically starts the server when needed and stops it on cleanup.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
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.startEmbeddedServer = startEmbeddedServer;
|
|
45
|
+
exports.stopEmbeddedServer = stopEmbeddedServer;
|
|
46
|
+
exports.stopAllEmbeddedServers = stopAllEmbeddedServers;
|
|
47
|
+
exports.isServerRunning = isServerRunning;
|
|
48
|
+
// Copyright 2025 Sushanth (https://github.com/sushanthpy)
|
|
49
|
+
//
|
|
50
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
51
|
+
// you may not use this file except in compliance with the License.
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const net = __importStar(require("net"));
|
|
55
|
+
const child_process_1 = require("child_process");
|
|
56
|
+
const errors_1 = require("./errors");
|
|
57
|
+
/**
|
|
58
|
+
* Find the sochdb-server binary (provides IPC interface)
|
|
59
|
+
*
|
|
60
|
+
* Note: sochdb-server uses Unix domain sockets, not available on Windows.
|
|
61
|
+
* On Windows, use the gRPC client instead for cross-platform compatibility.
|
|
62
|
+
*/
|
|
63
|
+
function findServerBinary() {
|
|
64
|
+
const platform = process.platform;
|
|
65
|
+
const arch = process.arch;
|
|
66
|
+
// Windows doesn't support Unix sockets, sochdb-server is not available
|
|
67
|
+
if (platform === 'win32') {
|
|
68
|
+
throw new errors_1.DatabaseError('sochdb-server is not available on Windows (requires Unix domain sockets). ' +
|
|
69
|
+
'Use the gRPC client for cross-platform support: ' +
|
|
70
|
+
'const client = await GrpcClient.connect("localhost:50051")');
|
|
71
|
+
}
|
|
72
|
+
let target;
|
|
73
|
+
if (platform === 'darwin') {
|
|
74
|
+
target = arch === 'arm64' ? 'aarch64-apple-darwin' : 'x86_64-apple-darwin';
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
target = arch === 'arm64' ? 'aarch64-unknown-linux-gnu' : 'x86_64-unknown-linux-gnu';
|
|
78
|
+
}
|
|
79
|
+
const binaryName = 'sochdb-server';
|
|
80
|
+
// Search paths - prioritize bundled binaries
|
|
81
|
+
const searchPaths = [
|
|
82
|
+
// Bundled in package (installed via npm) - from dist/cjs or dist/esm
|
|
83
|
+
path.join(__dirname, '..', '_bin', target, binaryName),
|
|
84
|
+
path.join(__dirname, '..', '..', '_bin', target, binaryName),
|
|
85
|
+
path.join(__dirname, '..', '..', '..', '_bin', target, binaryName),
|
|
86
|
+
// When running from source (src/) during development/testing
|
|
87
|
+
path.resolve(__dirname, '..', '_bin', target, binaryName),
|
|
88
|
+
// Development paths - from project root
|
|
89
|
+
path.join(__dirname, '..', '..', 'target', 'release', binaryName),
|
|
90
|
+
path.join(__dirname, '..', '..', 'target', 'debug', binaryName),
|
|
91
|
+
path.join(__dirname, '..', '..', '..', 'target', 'release', binaryName),
|
|
92
|
+
path.join(__dirname, '..', '..', '..', 'target', 'debug', binaryName),
|
|
93
|
+
// Absolute paths for sochdb workspace
|
|
94
|
+
path.resolve(process.cwd(), '_bin', target, binaryName),
|
|
95
|
+
path.resolve(process.cwd(), 'target', 'release', binaryName),
|
|
96
|
+
path.resolve(process.cwd(), '..', 'target', 'release', binaryName),
|
|
97
|
+
];
|
|
98
|
+
for (const p of searchPaths) {
|
|
99
|
+
if (fs.existsSync(p)) {
|
|
100
|
+
return p;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Try PATH
|
|
104
|
+
const pathDirs = (process.env.PATH || '').split(path.delimiter);
|
|
105
|
+
for (const dir of pathDirs) {
|
|
106
|
+
const p = path.join(dir, binaryName);
|
|
107
|
+
if (fs.existsSync(p)) {
|
|
108
|
+
return p;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
throw new errors_1.DatabaseError(`Could not find ${binaryName}. ` +
|
|
112
|
+
`The pre-built binary may not be available for your platform (${platform}/${arch}). ` +
|
|
113
|
+
`Install via: cargo build --release -p sochdb-tools`);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Wait for a Unix socket to become available
|
|
117
|
+
*/
|
|
118
|
+
async function waitForSocket(socketPath, timeoutMs = 10000) {
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
const checkInterval = 100;
|
|
121
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
122
|
+
if (fs.existsSync(socketPath)) {
|
|
123
|
+
// Try to connect to verify it's actually listening
|
|
124
|
+
try {
|
|
125
|
+
await new Promise((resolve, reject) => {
|
|
126
|
+
const socket = net.createConnection({ path: socketPath }, () => {
|
|
127
|
+
socket.destroy();
|
|
128
|
+
resolve();
|
|
129
|
+
});
|
|
130
|
+
socket.on('error', reject);
|
|
131
|
+
socket.setTimeout(1000);
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Socket exists but not ready yet
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
await new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
140
|
+
}
|
|
141
|
+
throw new errors_1.ConnectionError(`Timeout waiting for server socket at ${socketPath} after ${timeoutMs}ms`);
|
|
142
|
+
}
|
|
143
|
+
// Track running server instances
|
|
144
|
+
const runningServers = new Map();
|
|
145
|
+
/**
|
|
146
|
+
* Start an embedded SochDB server for the given database path.
|
|
147
|
+
* If a server is already running for this path, return the existing instance.
|
|
148
|
+
*
|
|
149
|
+
* @param dbPath - Path to the database directory
|
|
150
|
+
* @returns The socket path for connecting
|
|
151
|
+
*/
|
|
152
|
+
async function startEmbeddedServer(dbPath) {
|
|
153
|
+
const absolutePath = path.resolve(dbPath);
|
|
154
|
+
const socketPath = path.join(absolutePath, 'sochdb.sock');
|
|
155
|
+
// Check if server already running for this path
|
|
156
|
+
const existing = runningServers.get(absolutePath);
|
|
157
|
+
if (existing && existing.process.exitCode === null) {
|
|
158
|
+
// Server still running
|
|
159
|
+
return socketPath;
|
|
160
|
+
}
|
|
161
|
+
// Check if another process already has a server running
|
|
162
|
+
if (fs.existsSync(socketPath)) {
|
|
163
|
+
try {
|
|
164
|
+
// Try to connect - if successful, server is running
|
|
165
|
+
await waitForSocket(socketPath, 1000);
|
|
166
|
+
return socketPath;
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Socket exists but dead - clean it up
|
|
170
|
+
try {
|
|
171
|
+
fs.unlinkSync(socketPath);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Ignore
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Ensure database directory exists
|
|
179
|
+
if (!fs.existsSync(absolutePath)) {
|
|
180
|
+
fs.mkdirSync(absolutePath, { recursive: true });
|
|
181
|
+
}
|
|
182
|
+
// Find and spawn server
|
|
183
|
+
const serverBinary = findServerBinary();
|
|
184
|
+
const serverProcess = (0, child_process_1.spawn)(serverBinary, ['--db', absolutePath, '--socket', socketPath], {
|
|
185
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
186
|
+
detached: false,
|
|
187
|
+
});
|
|
188
|
+
// Collect stderr for error reporting
|
|
189
|
+
let stderrOutput = '';
|
|
190
|
+
serverProcess.stderr?.on('data', (data) => {
|
|
191
|
+
stderrOutput += data.toString();
|
|
192
|
+
});
|
|
193
|
+
// Handle process exit
|
|
194
|
+
serverProcess.on('exit', (code, signal) => {
|
|
195
|
+
runningServers.delete(absolutePath);
|
|
196
|
+
if (code !== 0 && code !== null) {
|
|
197
|
+
console.error(`SochDB server exited with code ${code}: ${stderrOutput}`);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
serverProcess.on('error', (err) => {
|
|
201
|
+
runningServers.delete(absolutePath);
|
|
202
|
+
console.error(`Failed to start SochDB server: ${err.message}`);
|
|
203
|
+
});
|
|
204
|
+
// Store instance
|
|
205
|
+
runningServers.set(absolutePath, {
|
|
206
|
+
process: serverProcess,
|
|
207
|
+
socketPath,
|
|
208
|
+
dbPath: absolutePath,
|
|
209
|
+
});
|
|
210
|
+
// Wait for server to be ready
|
|
211
|
+
try {
|
|
212
|
+
await waitForSocket(socketPath, 10000);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
// Kill the process if it didn't start properly
|
|
216
|
+
serverProcess.kill();
|
|
217
|
+
runningServers.delete(absolutePath);
|
|
218
|
+
throw new errors_1.DatabaseError(`Failed to start embedded server: ${stderrOutput || err.message}`);
|
|
219
|
+
}
|
|
220
|
+
return socketPath;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Stop the embedded server for a specific database path
|
|
224
|
+
*/
|
|
225
|
+
async function stopEmbeddedServer(dbPath) {
|
|
226
|
+
const absolutePath = path.resolve(dbPath);
|
|
227
|
+
const instance = runningServers.get(absolutePath);
|
|
228
|
+
if (!instance) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Send SIGTERM and wait for graceful shutdown
|
|
232
|
+
instance.process.kill('SIGTERM');
|
|
233
|
+
// Wait for process to exit (max 5 seconds)
|
|
234
|
+
await new Promise((resolve) => {
|
|
235
|
+
const timeout = setTimeout(() => {
|
|
236
|
+
// Force kill if still running
|
|
237
|
+
if (instance.process.exitCode === null) {
|
|
238
|
+
instance.process.kill('SIGKILL');
|
|
239
|
+
}
|
|
240
|
+
resolve();
|
|
241
|
+
}, 5000);
|
|
242
|
+
instance.process.on('exit', () => {
|
|
243
|
+
clearTimeout(timeout);
|
|
244
|
+
resolve();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
runningServers.delete(absolutePath);
|
|
248
|
+
// Clean up socket file
|
|
249
|
+
try {
|
|
250
|
+
if (fs.existsSync(instance.socketPath)) {
|
|
251
|
+
fs.unlinkSync(instance.socketPath);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// Ignore cleanup errors
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Stop all running embedded servers
|
|
260
|
+
*/
|
|
261
|
+
async function stopAllEmbeddedServers() {
|
|
262
|
+
const stopPromises = [];
|
|
263
|
+
for (const [dbPath] of runningServers) {
|
|
264
|
+
stopPromises.push(stopEmbeddedServer(dbPath));
|
|
265
|
+
}
|
|
266
|
+
await Promise.all(stopPromises);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Check if an embedded server is running for a database path
|
|
270
|
+
*/
|
|
271
|
+
function isServerRunning(dbPath) {
|
|
272
|
+
const absolutePath = path.resolve(dbPath);
|
|
273
|
+
const instance = runningServers.get(absolutePath);
|
|
274
|
+
return instance !== undefined && instance.process.exitCode === null;
|
|
275
|
+
}
|
|
276
|
+
// Cleanup on process exit
|
|
277
|
+
process.on('exit', () => {
|
|
278
|
+
for (const instance of runningServers.values()) {
|
|
279
|
+
try {
|
|
280
|
+
instance.process.kill('SIGKILL');
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// Ignore
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
process.on('SIGINT', async () => {
|
|
288
|
+
await stopAllEmbeddedServers();
|
|
289
|
+
process.exit(0);
|
|
290
|
+
});
|
|
291
|
+
process.on('SIGTERM', async () => {
|
|
292
|
+
await stopAllEmbeddedServers();
|
|
293
|
+
process.exit(0);
|
|
294
|
+
});
|
|
295
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmVyLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7O0dBT0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUlILGtEQStFQztBQUtELGdEQXFDQztBQUtELHdEQU1DO0FBS0QsMENBSUM7QUFoUkQsMERBQTBEO0FBQzFELEVBQUU7QUFDRixrRUFBa0U7QUFDbEUsbUVBQW1FO0FBRW5FLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0IseUNBQTJCO0FBQzNCLGlEQUFvRDtBQUNwRCxxQ0FBMEQ7QUFFMUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLGdCQUFnQjtJQUN2QixNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQ2xDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFFMUIsdUVBQXVFO0lBQ3ZFLElBQUksUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxzQkFBYSxDQUNyQiw0RUFBNEU7WUFDNUUsa0RBQWtEO1lBQ2xELDREQUE0RCxDQUM3RCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksTUFBYyxDQUFDO0lBQ25CLElBQUksUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLE1BQU0sR0FBRyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUM7SUFDN0UsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLEdBQUcsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixDQUFDO0lBQ3ZGLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUM7SUFFbkMsNkNBQTZDO0lBQzdDLE1BQU0sV0FBVyxHQUFHO1FBQ2xCLHFFQUFxRTtRQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUM7UUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQztRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQztRQUNsRSw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxDQUFDO1FBQ3pELHdDQUF3QztRQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUM7UUFDL0QsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUM7UUFDdkUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUM7UUFDckUsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFD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QUFzQixFQUFFLENBQUM7SUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsQixDQUFDLENBQUMsQ0FBQztBQUVILE9BQU8sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQy9CLE1BQU0sc0JBQXNCLEVBQUUsQ0FBQztJQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTb2NoREIgRW1iZWRkZWQgU2VydmVyIE1hbmFnZXJcbiAqXG4gKiBNYW5hZ2VzIHRoZSBsaWZlY3ljbGUgb2YgdGhlIFNvY2hEQiBzZXJ2ZXIgcHJvY2VzcyBmb3IgZW1iZWRkZWQgbW9kZS5cbiAqIEF1dG9tYXRpY2FsbHkgc3RhcnRzIHRoZSBzZXJ2ZXIgd2hlbiBuZWVkZWQgYW5kIHN0b3BzIGl0IG9uIGNsZWFudXAuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cblxuLy8gQ29weXJpZ2h0IDIwMjUgU3VzaGFudGggKGh0dHBzOi8vZ2l0aHViLmNvbS9zdXNoYW50aHB5KVxuLy9cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4vLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IHNwYXduLCBDaGlsZFByb2Nlc3MgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IENvbm5lY3Rpb25FcnJvciwgRGF0YWJhc2VFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcblxuLyoqXG4gKiBGaW5kIHRoZSBzb2NoZGItc2VydmVyIGJpbmFyeSAocHJvdmlkZXMgSVBDIGludGVyZmFjZSlcbiAqIFxuICogTm90ZTogc29jaGRiLXNlcnZlciB1c2VzIFVuaXggZG9tYWluIHNvY2tldHMsIG5vdCBhdmFpbGFibGUgb24gV2luZG93cy5cbiAqIE9uIFdpbmRvd3MsIHVzZSB0aGUgZ1JQQyBjbGllbnQgaW5zdGVhZCBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGF0aWJpbGl0eS5cbiAqL1xuZnVuY3Rpb24gZmluZFNlcnZlckJpbmFyeSgpOiBzdHJpbmcge1xuICBjb25zdCBwbGF0Zm9ybSA9IHByb2Nlc3MucGxhdGZvcm07XG4gIGNvbnN0IGFyY2ggPSBwcm9jZXNzLmFyY2g7XG5cbiAgLy8gV2luZG93cyBkb2Vzbid0IHN1cHBvcnQgVW5peCBzb2NrZXRzLCBzb2NoZGItc2VydmVyIGlzIG5vdCBhdmFpbGFibGVcbiAgaWYgKHBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgdGhyb3cgbmV3IERhdGFiYXNlRXJyb3IoXG4gICAgICAnc29jaGRiLXNlcnZlciBpcyBub3QgYXZhaWxhYmxlIG9uIFdpbmRvd3MgKHJlcXVpcmVzIFVuaXggZG9tYWluIHNvY2tldHMpLiAnICtcbiAgICAgICdVc2UgdGhlIGdSUEMgY2xpZW50IGZvciBjcm9zcy1wbGF0Zm9ybSBzdXBwb3J0OiAnICtcbiAgICAgICdjb25zdCBjbGllbnQgPSBhd2FpdCBHcnBjQ2xpZW50LmNvbm5lY3QoXCJsb2NhbGhvc3Q6NTAwNTFcIiknXG4gICAgKTtcbiAgfVxuXG4gIGxldCB0YXJnZXQ6IHN0cmluZztcbiAgaWYgKHBsYXRmb3JtID09PSAnZGFyd2luJykge1xuICAgIHRhcmdldCA9IGFyY2ggPT09ICdhcm02NCcgPyAnYWFyY2g2NC1hcHBsZS1kYXJ3aW4nIDogJ3g4Nl82NC1hcHBsZS1kYXJ3aW4nO1xuICB9IGVsc2Uge1xuICAgIHRhcmdldCA9IGFyY2ggPT09ICdhcm02NCcgPyAnYWFyY2g2NC11bmtub3duLWxpbnV4LWdudScgOiAneDg2XzY0LXVua25vd24tbGludXgtZ251JztcbiAgfVxuXG4gIGNvbnN0IGJpbmFyeU5hbWUgPSAnc29jaGRiLXNlcnZlcic7XG5cbiAgLy8gU2VhcmNoIHBhdGhzIC0gcHJpb3JpdGl6ZSBidW5kbGVkIGJpbmFyaWVzXG4gIGNvbnN0IHNlYXJjaFBhdGhzID0gW1xuICAgIC8vIEJ1bmRsZWQgaW4gcGFja2FnZSAoaW5zdGFsbGVkIHZpYSBucG0pIC0gZnJvbSBkaXN0L2NqcyBvciBkaXN0L2VzbVxuICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdfYmluJywgdGFyZ2V0LCBiaW5hcnlOYW1lKSxcbiAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnX2JpbicsIHRhcmdldCwgYmluYXJ5TmFtZSksXG4gICAgcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJy4uJywgJ19iaW4nLCB0YXJnZXQsIGJpbmFyeU5hbWUpLFxuICAgIC8vIFdoZW4gcnVubmluZyBmcm9tIHNvdXJjZSAoc3JjLykgZHVyaW5nIGRldmVsb3BtZW50L3Rlc3RpbmdcbiAgICBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4nLCAnX2JpbicsIHRhcmdldCwgYmluYXJ5TmFtZSksXG4gICAgLy8gRGV2ZWxvcG1lbnQgcGF0aHMgLSBmcm9tIHByb2plY3Qgcm9vdFxuICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICcuLicsICd0YXJnZXQnLCAncmVsZWFzZScsIGJpbmFyeU5hbWUpLFxuICAgIHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICcuLicsICd0YXJnZXQnLCAnZGVidWcnLCBiaW5hcnlOYW1lKSxcbiAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnLi4nLCAndGFyZ2V0JywgJ3JlbGVhc2UnLCBiaW5hcnlOYW1lKSxcbiAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAnLi4nLCAndGFyZ2V0JywgJ2RlYnVnJywgYmluYXJ5TmFtZSksXG4gICAgLy8gQWJzb2x1dGUgcGF0aHMgZm9yIHNvY2hkYiB3b3Jrc3BhY2VcbiAgICBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ19iaW4nLCB0YXJnZXQsIGJpbmFyeU5hbWUpLFxuICAgIHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAndGFyZ2V0JywgJ3JlbGVhc2UnLCBiaW5hcnlOYW1lKSxcbiAgICBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJy4uJywgJ3RhcmdldCcsICdyZWxlYXNlJywgYmluYXJ5TmFtZSksXG4gIF07XG5cbiAgZm9yIChjb25zdCBwIG9mIHNlYXJjaFBhdGhzKSB7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMocCkpIHtcbiAgICAgIHJldHVybiBwO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRyeSBQQVRIXG4gIGNvbnN0IHBhdGhEaXJzID0gKHByb2Nlc3MuZW52LlBBVEggfHwgJycpLnNwbGl0KHBhdGguZGVsaW1pdGVyKTtcbiAgZm9yIChjb25zdCBkaXIgb2YgcGF0aERpcnMpIHtcbiAgICBjb25zdCBwID0gcGF0aC5qb2luKGRpciwgYmluYXJ5TmFtZSk7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMocCkpIHtcbiAgICAgIHJldHVybiBwO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBEYXRhYmFzZUVycm9yKFxuICAgIGBDb3VsZCBub3QgZmluZCAke2JpbmFyeU5hbWV9LiBgICtcbiAgICBgVGhlIHByZS1idWlsdCBiaW5hcnkgbWF5IG5vdCBiZSBhdmFpbGFibGUgZm9yIHlvdXIgcGxhdGZvcm0gKCR7cGxhdGZvcm19LyR7YXJjaH0pLiBgICtcbiAgICBgSW5zdGFsbCB2aWE6IGNhcmdvIGJ1aWxkIC0tcmVsZWFzZSAtcCBzb2NoZGItdG9vbHNgXG4gICk7XG59XG5cbi8qKlxuICogV2FpdCBmb3IgYSBVbml4IHNvY2tldCB0byBiZWNvbWUgYXZhaWxhYmxlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JTb2NrZXQoc29ja2V0UGF0aDogc3RyaW5nLCB0aW1lb3V0TXM6IG51bWJlciA9IDEwMDAwKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gIGNvbnN0IGNoZWNrSW50ZXJ2YWwgPSAxMDA7XG5cbiAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aW1lb3V0TXMpIHtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhzb2NrZXRQYXRoKSkge1xuICAgICAgLy8gVHJ5IHRvIGNvbm5lY3QgdG8gdmVyaWZ5IGl0J3MgYWN0dWFsbHkgbGlzdGVuaW5nXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgY29uc3Qgc29ja2V0ID0gbmV0LmNyZWF0ZUNvbm5lY3Rpb24oeyBwYXRoOiBzb2NrZXRQYXRoIH0sICgpID0+IHtcbiAgICAgICAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc29ja2V0Lm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICAgICAgc29ja2V0LnNldFRpbWVvdXQoMTAwMCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gU29ja2V0IGV4aXN0cyBidXQgbm90IHJlYWR5IHlldFxuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgY2hlY2tJbnRlcnZhbCkpO1xuICB9XG5cbiAgdGhyb3cgbmV3IENvbm5lY3Rpb25FcnJvcihcbiAgICBgVGltZW91dCB3YWl0aW5nIGZvciBzZXJ2ZXIgc29ja2V0IGF0ICR7c29ja2V0UGF0aH0gYWZ0ZXIgJHt0aW1lb3V0TXN9bXNgXG4gICk7XG59XG5cbi8qKlxuICogRW1iZWRkZWQgc2VydmVyIGluc3RhbmNlXG4gKi9cbmludGVyZmFjZSBTZXJ2ZXJJbnN0YW5jZSB7XG4gIHByb2Nlc3M6IENoaWxkUHJvY2VzcztcbiAgc29ja2V0UGF0aDogc3RyaW5nO1xuICBkYlBhdGg6IHN0cmluZztcbn1cblxuLy8gVHJhY2sgcnVubmluZyBzZXJ2ZXIgaW5zdGFuY2VzXG5jb25zdCBydW5uaW5nU2VydmVyczogTWFwPHN0cmluZywgU2VydmVySW5zdGFuY2U+ID0gbmV3IE1hcCgpO1xuXG4vKipcbiAqIFN0YXJ0IGFuIGVtYmVkZGVkIFNvY2hEQiBzZXJ2ZXIgZm9yIHRoZSBnaXZlbiBkYXRhYmFzZSBwYXRoLlxuICogSWYgYSBzZXJ2ZXIgaXMgYWxyZWFkeSBydW5uaW5nIGZvciB0aGlzIHBhdGgsIHJldHVybiB0aGUgZXhpc3RpbmcgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIGRiUGF0aCAtIFBhdGggdG8gdGhlIGRhdGFiYXNlIGRpcmVjdG9yeVxuICogQHJldHVybnMgVGhlIHNvY2tldCBwYXRoIGZvciBjb25uZWN0aW5nXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydEVtYmVkZGVkU2VydmVyKGRiUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlKGRiUGF0aCk7XG4gIGNvbnN0IHNvY2tldFBhdGggPSBwYXRoLmpvaW4oYWJzb2x1dGVQYXRoLCAnc29jaGRiLnNvY2snKTtcblxuICAvLyBDaGVjayBpZiBzZXJ2ZXIgYWxyZWFkeSBydW5uaW5nIGZvciB0aGlzIHBhdGhcbiAgY29uc3QgZXhpc3RpbmcgPSBydW5uaW5nU2VydmVycy5nZXQoYWJzb2x1dGVQYXRoKTtcbiAgaWYgKGV4aXN0aW5nICYmIGV4aXN0aW5nLnByb2Nlc3MuZXhpdENvZGUgPT09IG51bGwpIHtcbiAgICAvLyBTZXJ2ZXIgc3RpbGwgcnVubmluZ1xuICAgIHJldHVybiBzb2NrZXRQYXRoO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgYW5vdGhlciBwcm9jZXNzIGFscmVhZHkgaGFzIGEgc2VydmVyIHJ1bm5pbmdcbiAgaWYgKGZzLmV4aXN0c1N5bmMoc29ja2V0UGF0aCkpIHtcbiAgICB0cnkge1xuICAgICAgLy8gVHJ5IHRvIGNvbm5lY3QgLSBpZiBzdWNjZXNzZnVsLCBzZXJ2ZXIgaXMgcnVubmluZ1xuICAgICAgYXdhaXQgd2FpdEZvclNvY2tldChzb2NrZXRQYXRoLCAxMDAwKTtcbiAgICAgIHJldHVybiBzb2NrZXRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gU29ja2V0IGV4aXN0cyBidXQgZGVhZCAtIGNsZWFuIGl0IHVwXG4gICAgICB0cnkge1xuICAgICAgICBmcy51bmxpbmtTeW5jKHNvY2tldFBhdGgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElnbm9yZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEVuc3VyZSBkYXRhYmFzZSBkaXJlY3RvcnkgZXhpc3RzXG4gIGlmICghZnMuZXhpc3RzU3luYyhhYnNvbHV0ZVBhdGgpKSB7XG4gICAgZnMubWtkaXJTeW5jKGFic29sdXRlUGF0aCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuICAvLyBGaW5kIGFuZCBzcGF3biBzZXJ2ZXJcbiAgY29uc3Qgc2VydmVyQmluYXJ5ID0gZmluZFNlcnZlckJpbmFyeSgpO1xuICBcbiAgY29uc3Qgc2VydmVyUHJvY2VzcyA9IHNwYXduKHNlcnZlckJpbmFyeSwgWyctLWRiJywgYWJzb2x1dGVQYXRoLCAnLS1zb2NrZXQnLCBzb2NrZXRQYXRoXSwge1xuICAgIHN0ZGlvOiBbJ2lnbm9yZScsICdwaXBlJywgJ3BpcGUnXSxcbiAgICBkZXRhY2hlZDogZmFsc2UsXG4gIH0pO1xuXG4gIC8vIENvbGxlY3Qgc3RkZXJyIGZvciBlcnJvciByZXBvcnRpbmdcbiAgbGV0IHN0ZGVyck91dHB1dCA9ICcnO1xuICBzZXJ2ZXJQcm9jZXNzLnN0ZGVycj8ub24oJ2RhdGEnLCAoZGF0YSkgPT4ge1xuICAgIHN0ZGVyck91dHB1dCArPSBkYXRhLnRvU3RyaW5nKCk7XG4gIH0pO1xuXG4gIC8vIEhhbmRsZSBwcm9jZXNzIGV4aXRcbiAgc2VydmVyUHJvY2Vzcy5vbignZXhpdCcsIChjb2RlLCBzaWduYWwpID0+IHtcbiAgICBydW5uaW5nU2VydmVycy5kZWxldGUoYWJzb2x1dGVQYXRoKTtcbiAgICBpZiAoY29kZSAhPT0gMCAmJiBjb2RlICE9PSBudWxsKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBTb2NoREIgc2VydmVyIGV4aXRlZCB3aXRoIGNvZGUgJHtjb2RlfTogJHtzdGRlcnJPdXRwdXR9YCk7XG4gICAgfVxuICB9KTtcblxuICBzZXJ2ZXJQcm9jZXNzLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICBydW5uaW5nU2VydmVycy5kZWxldGUoYWJzb2x1dGVQYXRoKTtcbiAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gc3RhcnQgU29jaERCIHNlcnZlcjogJHtlcnIubWVzc2FnZX1gKTtcbiAgfSk7XG5cbiAgLy8gU3RvcmUgaW5zdGFuY2VcbiAgcnVubmluZ1NlcnZlcnMuc2V0KGFic29sdXRlUGF0aCwge1xuICAgIHByb2Nlc3M6IHNlcnZlclByb2Nlc3MsXG4gICAgc29ja2V0UGF0aCxcbiAgICBkYlBhdGg6IGFic29sdXRlUGF0aCxcbiAgfSk7XG5cbiAgLy8gV2FpdCBmb3Igc2VydmVyIHRvIGJlIHJlYWR5XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvclNvY2tldChzb2NrZXRQYXRoLCAxMDAwMCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIEtpbGwgdGhlIHByb2Nlc3MgaWYgaXQgZGlkbid0IHN0YXJ0IHByb3Blcmx5XG4gICAgc2VydmVyUHJvY2Vzcy5raWxsKCk7XG4gICAgcnVubmluZ1NlcnZlcnMuZGVsZXRlKGFic29sdXRlUGF0aCk7XG4gICAgdGhyb3cgbmV3IERhdGFiYXNlRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIHN0YXJ0IGVtYmVkZGVkIHNlcnZlcjogJHtzdGRlcnJPdXRwdXQgfHwgKGVyciBhcyBFcnJvcikubWVzc2FnZX1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBzb2NrZXRQYXRoO1xufVxuXG4vKipcbiAqIFN0b3AgdGhlIGVtYmVkZGVkIHNlcnZlciBmb3IgYSBzcGVjaWZpYyBkYXRhYmFzZSBwYXRoXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdG9wRW1iZWRkZWRTZXJ2ZXIoZGJQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlKGRiUGF0aCk7XG4gIGNvbnN0IGluc3RhbmNlID0gcnVubmluZ1NlcnZlcnMuZ2V0KGFic29sdXRlUGF0aCk7XG5cbiAgaWYgKCFpbnN0YW5jZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFNlbmQgU0lHVEVSTSBhbmQgd2FpdCBmb3IgZ3JhY2VmdWwgc2h1dGRvd25cbiAgaW5zdGFuY2UucHJvY2Vzcy5raWxsKCdTSUdURVJNJyk7XG5cbiAgLy8gV2FpdCBmb3IgcHJvY2VzcyB0byBleGl0IChtYXggNSBzZWNvbmRzKVxuICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIC8vIEZvcmNlIGtpbGwgaWYgc3RpbGwgcnVubmluZ1xuICAgICAgaWYgKGluc3RhbmNlLnByb2Nlc3MuZXhpdENvZGUgPT09IG51bGwpIHtcbiAgICAgICAgaW5zdGFuY2UucHJvY2Vzcy5raWxsKCdTSUdLSUxMJyk7XG4gICAgICB9XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSwgNTAwMCk7XG5cbiAgICBpbnN0YW5jZS5wcm9jZXNzLm9uKCdleGl0JywgKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBydW5uaW5nU2VydmVycy5kZWxldGUoYWJzb2x1dGVQYXRoKTtcblxuICAvLyBDbGVhbiB1cCBzb2NrZXQgZmlsZVxuICB0cnkge1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGluc3RhbmNlLnNvY2tldFBhdGgpKSB7XG4gICAgICBmcy51bmxpbmtTeW5jKGluc3RhbmNlLnNvY2tldFBhdGgpO1xuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gSWdub3JlIGNsZWFudXAgZXJyb3JzXG4gIH1cbn1cblxuLyoqXG4gKiBTdG9wIGFsbCBydW5uaW5nIGVtYmVkZGVkIHNlcnZlcnNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0b3BBbGxFbWJlZGRlZFNlcnZlcnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHN0b3BQcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gIGZvciAoY29uc3QgW2RiUGF0aF0gb2YgcnVubmluZ1NlcnZlcnMpIHtcbiAgICBzdG9wUHJvbWlzZXMucHVzaChzdG9wRW1iZWRkZWRTZXJ2ZXIoZGJQYXRoKSk7XG4gIH1cbiAgYXdhaXQgUHJvbWlzZS5hbGwoc3RvcFByb21pc2VzKTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbWJlZGRlZCBzZXJ2ZXIgaXMgcnVubmluZyBmb3IgYSBkYXRhYmFzZSBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZlclJ1bm5pbmcoZGJQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlKGRiUGF0aCk7XG4gIGNvbnN0IGluc3RhbmNlID0gcnVubmluZ1NlcnZlcnMuZ2V0KGFic29sdXRlUGF0aCk7XG4gIHJldHVybiBpbnN0YW5jZSAhPT0gdW5kZWZpbmVkICYmIGluc3RhbmNlLnByb2Nlc3MuZXhpdENvZGUgPT09IG51bGw7XG59XG5cbi8vIENsZWFudXAgb24gcHJvY2VzcyBleGl0XG5wcm9jZXNzLm9uKCdleGl0JywgKCkgPT4ge1xuICBmb3IgKGNvbnN0IGluc3RhbmNlIG9mIHJ1bm5pbmdTZXJ2ZXJzLnZhbHVlcygpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGluc3RhbmNlLnByb2Nlc3Mua2lsbCgnU0lHS0lMTCcpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSWdub3JlXG4gICAgfVxuICB9XG59KTtcblxucHJvY2Vzcy5vbignU0lHSU5UJywgYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBzdG9wQWxsRW1iZWRkZWRTZXJ2ZXJzKCk7XG4gIHByb2Nlc3MuZXhpdCgwKTtcbn0pO1xuXG5wcm9jZXNzLm9uKCdTSUdURVJNJywgYXN5bmMgKCkgPT4ge1xuICBhd2FpdCBzdG9wQWxsRW1iZWRkZWRTZXJ2ZXJzKCk7XG4gIHByb2Nlc3MuZXhpdCgwKTtcbn0pO1xuIl19
|