@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,154 @@
|
|
|
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
|
+
constructor(client, pathPrefix) {
|
|
24
|
+
this._client = client;
|
|
25
|
+
this._pathPrefix = pathPrefix;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Limit the number of results.
|
|
29
|
+
*
|
|
30
|
+
* @param n - Maximum number of results to return
|
|
31
|
+
* @returns This query builder for chaining
|
|
32
|
+
*/
|
|
33
|
+
limit(n) {
|
|
34
|
+
this._limit = n;
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Skip the first n results.
|
|
39
|
+
*
|
|
40
|
+
* @param n - Number of results to skip
|
|
41
|
+
* @returns This query builder for chaining
|
|
42
|
+
*/
|
|
43
|
+
offset(n) {
|
|
44
|
+
this._offset = n;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Select specific columns to return.
|
|
49
|
+
*
|
|
50
|
+
* @param columns - Array of column names to select
|
|
51
|
+
* @returns This query builder for chaining
|
|
52
|
+
*/
|
|
53
|
+
select(columns) {
|
|
54
|
+
this._columns = columns;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Execute the query and return results as TOON string.
|
|
59
|
+
*
|
|
60
|
+
* @returns TOON formatted string (e.g., "result[N]{cols}: row1; row2")
|
|
61
|
+
*/
|
|
62
|
+
async execute() {
|
|
63
|
+
return this._client.query(this._pathPrefix, {
|
|
64
|
+
limit: this._limit,
|
|
65
|
+
offset: this._offset,
|
|
66
|
+
columns: this._columns,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Execute and parse results into a list of objects.
|
|
71
|
+
*
|
|
72
|
+
* @returns Array of result objects
|
|
73
|
+
*/
|
|
74
|
+
async toList() {
|
|
75
|
+
const toonStr = await this.execute();
|
|
76
|
+
return this._parseToon(toonStr);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Execute and return the first result, or null if none.
|
|
80
|
+
*
|
|
81
|
+
* @returns First result or null
|
|
82
|
+
*/
|
|
83
|
+
async first() {
|
|
84
|
+
const originalLimit = this._limit;
|
|
85
|
+
this._limit = 1;
|
|
86
|
+
const results = await this.toList();
|
|
87
|
+
this._limit = originalLimit;
|
|
88
|
+
return results.length > 0 ? results[0] : null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Execute and return the count of results.
|
|
92
|
+
*
|
|
93
|
+
* @returns Number of matching results
|
|
94
|
+
*/
|
|
95
|
+
async count() {
|
|
96
|
+
const results = await this.toList();
|
|
97
|
+
return results.length;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Simple TOON parser.
|
|
101
|
+
*
|
|
102
|
+
* Parses TOON format: "result[N]{col1,col2}: val1,val2; val3,val4"
|
|
103
|
+
*/
|
|
104
|
+
_parseToon(toonStr) {
|
|
105
|
+
if (!toonStr || toonStr === 'result[0]{}:') {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
// Parse header: result[N]{cols}:
|
|
109
|
+
const headerMatch = toonStr.match(/^result\[(\d+)\]\{([^}]*)\}:\s*/);
|
|
110
|
+
if (!headerMatch) {
|
|
111
|
+
// Try to parse as JSON if not TOON format
|
|
112
|
+
try {
|
|
113
|
+
return JSON.parse(toonStr);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const count = parseInt(headerMatch[1], 10);
|
|
120
|
+
if (count === 0) {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const columns = headerMatch[2].split(',').map((c) => c.trim());
|
|
124
|
+
const body = toonStr.substring(headerMatch[0].length);
|
|
125
|
+
// Split rows by semicolon
|
|
126
|
+
const rows = body.split(';').map((r) => r.trim()).filter((r) => r.length > 0);
|
|
127
|
+
return rows.map((row) => {
|
|
128
|
+
const values = row.split(',').map((v) => v.trim());
|
|
129
|
+
const result = {};
|
|
130
|
+
columns.forEach((col, idx) => {
|
|
131
|
+
if (col && idx < values.length) {
|
|
132
|
+
// Try to parse as JSON/number
|
|
133
|
+
let value = values[idx];
|
|
134
|
+
if (value === 'null') {
|
|
135
|
+
value = null;
|
|
136
|
+
}
|
|
137
|
+
else if (value === 'true') {
|
|
138
|
+
value = true;
|
|
139
|
+
}
|
|
140
|
+
else if (value === 'false') {
|
|
141
|
+
value = false;
|
|
142
|
+
}
|
|
143
|
+
else if (!isNaN(Number(value))) {
|
|
144
|
+
value = Number(value);
|
|
145
|
+
}
|
|
146
|
+
result[col] = value;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return result;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.Query = Query;
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcXVlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7O0FBbUJIOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFhLEtBQUs7SUFPaEIsWUFBWSxNQUFpQixFQUFFLFVBQWtCO1FBQy9DLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxDQUFTO1FBQ2IsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDaEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsQ0FBUztRQUNkLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLE9BQWlCO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsT0FBTztRQUNYLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUMxQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbEIsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3BCLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUTtTQUN2QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxNQUFNO1FBQ1YsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8s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LENBQUM7b0JBQ2YsQ0FBQzt5QkFBTSxJQUFJLEtBQUssS0FBSyxNQUFNLEVBQUUsQ0FBQzt3QkFDNUIsS0FBSyxHQUFHLElBQUksQ0FBQztvQkFDZixDQUFDO3lCQUFNLElBQUksS0FBSyxLQUFLLE9BQU8sRUFBRSxDQUFDO3dCQUM3QixLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUNoQixDQUFDO3lCQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDakMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDeEIsQ0FBQztvQkFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO2dCQUN0QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQW5KRCxzQkFtSkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNvY2hEQiBRdWVyeSBCdWlsZGVyXG4gKlxuICogRmx1ZW50IHF1ZXJ5IGludGVyZmFjZSBmb3IgU29jaERCLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbi8vIENvcHlyaWdodCAyMDI1IFN1c2hhbnRoIChodHRwczovL2dpdGh1Yi5jb20vc3VzaGFudGhweSlcbi8vXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4vL1xuLy8gICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5pbXBvcnQgeyBJcGNDbGllbnQgfSBmcm9tICcuL2lwYy1jbGllbnQnO1xuXG4vKipcbiAqIFF1ZXJ5IHJlc3VsdCByb3cuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVlcnlSZXN1bHQge1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG4vKipcbiAqIEZsdWVudCBxdWVyeSBidWlsZGVyIGZvciBTb2NoREIuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBkYi5xdWVyeSgndXNlcnMvJylcbiAqICAgLmxpbWl0KDEwKVxuICogICAuc2VsZWN0KFsnbmFtZScsICdlbWFpbCddKVxuICogICAudG9MaXN0KCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFF1ZXJ5IHtcbiAgcHJpdmF0ZSBfY2xpZW50OiBJcGNDbGllbnQ7XG4gIHByaXZhdGUgX3BhdGhQcmVmaXg6IHN0cmluZztcbiAgcHJpdmF0ZSBfbGltaXQ/OiBudW1iZXI7XG4gIHByaXZhdGUgX29mZnNldD86IG51bWJlcjtcbiAgcHJpdmF0ZSBfY29sdW1ucz86IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogSXBjQ2xpZW50LCBwYXRoUHJlZml4OiBzdHJpbmcpIHtcbiAgICB0aGlzLl9jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5fcGF0aFByZWZpeCA9IHBhdGhQcmVmaXg7XG4gIH1cblxuICAvKipcbiAgICogTGltaXQgdGhlIG51bWJlciBvZiByZXN1bHRzLlxuICAgKlxuICAgKiBAcGFyYW0gbiAtIE1heGltdW0gbnVtYmVyIG9mIHJlc3VsdHMgdG8gcmV0dXJuXG4gICAqIEByZXR1cm5zIFRoaXMgcXVlcnkgYnVpbGRlciBmb3IgY2hhaW5pbmdcbiAgICovXG4gIGxpbWl0KG46IG51bWJlcik6IFF1ZXJ5IHtcbiAgICB0aGlzLl9saW1pdCA9IG47XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2tpcCB0aGUgZmlyc3QgbiByZXN1bHRzLlxuICAgKlxuICAgKiBAcGFyYW0gbiAtIE51bWJlciBvZiByZXN1bHRzIHRvIHNraXBcbiAgICogQHJldHVybnMgVGhpcyBxdWVyeSBidWlsZGVyIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgb2Zmc2V0KG46IG51bWJlcik6IFF1ZXJ5IHtcbiAgICB0aGlzLl9vZmZzZXQgPSBuO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBzcGVjaWZpYyBjb2x1bW5zIHRvIHJldHVybi5cbiAgICpcbiAgICogQHBhcmFtIGNvbHVtbnMgLSBBcnJheSBvZiBjb2x1bW4gbmFtZXMgdG8gc2VsZWN0XG4gICAqIEByZXR1cm5zIFRoaXMgcXVlcnkgYnVpbGRlciBmb3IgY2hhaW5pbmdcbiAgICovXG4gIHNlbGVjdChjb2x1bW5zOiBzdHJpbmdbXSk6IFF1ZXJ5IHtcbiAgICB0aGlzLl9jb2x1bW5zID0gY29sdW1ucztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIHRoZSBxdWVyeSBhbmQgcmV0dXJuIHJlc3VsdHMgYXMgVE9PTiBzdHJpbmcuXG4gICAqXG4gICAqIEByZXR1cm5zIFRPT04gZm9ybWF0dGVkIHN0cmluZyAoZS5nLiwgXCJyZXN1bHRbTl17Y29sc306IHJvdzE7IHJvdzJcIilcbiAgICovXG4gIGFzeW5jIGV4ZWN1dGUoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LnF1ZXJ5KHRoaXMuX3BhdGhQcmVmaXgsIHtcbiAgICAgIGxpbWl0OiB0aGlzLl9saW1pdCxcbiAgICAgIG9mZnNldDogdGhpcy5fb2Zmc2V0LFxuICAgICAgY29sdW1uczogdGhpcy5fY29sdW1ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGFuZCBwYXJzZSByZXN1bHRzIGludG8gYSBsaXN0IG9mIG9iamVjdHMuXG4gICAqXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIHJlc3VsdCBvYmplY3RzXG4gICAqL1xuICBhc3luYyB0b0xpc3QoKTogUHJvbWlzZTxRdWVyeVJlc3VsdFtdPiB7XG4gICAgY29uc3QgdG9vblN0ciA9IGF3YWl0IHRoaXMuZXhlY3V0ZSgpO1xuICAgIHJldHVybiB0aGlzLl9wYXJzZVRvb24odG9vblN0cik7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhbmQgcmV0dXJuIHRoZSBmaXJzdCByZXN1bHQsIG9yIG51bGwgaWYgbm9uZS5cbiAgICpcbiAgICogQHJldHVybnMgRmlyc3QgcmVzdWx0IG9yIG51bGxcbiAgICovXG4gIGFzeW5jIGZpcnN0KCk6IFByb21pc2U8UXVlcnlSZXN1bHQgfCBudWxsPiB7XG4gICAgY29uc3Qgb3JpZ2luYWxMaW1pdCA9IHRoaXMuX2xpbWl0O1xuICAgIHRoaXMuX2xpbWl0ID0gMTtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy50b0xpc3QoKTtcbiAgICB0aGlzLl9saW1pdCA9IG9yaWdpbmFsTGltaXQ7XG4gICAgcmV0dXJuIHJlc3VsdHMubGVuZ3RoID4gMCA/IHJlc3VsdHNbMF0gOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYW5kIHJldHVybiB0aGUgY291bnQgb2YgcmVzdWx0cy5cbiAgICpcbiAgICogQHJldHVybnMgTnVtYmVyIG9mIG1hdGNoaW5nIHJlc3VsdHNcbiAgICovXG4gIGFzeW5jIGNvdW50KCk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMudG9MaXN0KCk7XG4gICAgcmV0dXJuIHJlc3VsdHMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpbXBsZSBUT09OIHBhcnNlci5cbiAgICpcbiAgICogUGFyc2VzIFRPT04gZm9ybWF0OiBcInJlc3VsdFtOXXtjb2wxLGNvbDJ9OiB2YWwxLHZhbDI7IHZhbDMsdmFsNFwiXG4gICAqL1xuICBwcml2YXRlIF9wYXJzZVRvb24odG9vblN0cjogc3RyaW5nKTogUXVlcnlSZXN1bHRbXSB7XG4gICAgaWYgKCF0b29uU3RyIHx8IHRvb25TdHIgPT09ICdyZXN1bHRbMF17fTonKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgaGVhZGVyOiByZXN1bHRbTl17Y29sc306XG4gICAgY29uc3QgaGVhZGVyTWF0Y2ggPSB0b29uU3RyLm1hdGNoKC9ecmVzdWx0XFxbKFxcZCspXFxdXFx7KFtefV0qKVxcfTpcXHMqLyk7XG4gICAgaWYgKCFoZWFkZXJNYXRjaCkge1xuICAgICAgLy8gVHJ5IHRvIHBhcnNlIGFzIEpTT04gaWYgbm90IFRPT04gZm9ybWF0XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh0b29uU3RyKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgY291bnQgPSBwYXJzZUludChoZWFkZXJNYXRjaFsxXSwgMTApO1xuICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbHVtbnMgPSBoZWFkZXJNYXRjaFsyXS5zcGxpdCgnLCcpLm1hcCgoYykgPT4gYy50cmltKCkpO1xuICAgIGNvbnN0IGJvZHkgPSB0b29uU3RyLnN1YnN0cmluZyhoZWFkZXJNYXRjaFswXS5sZW5ndGgpO1xuXG4gICAgLy8gU3BsaXQgcm93cyBieSBzZW1pY29sb25cbiAgICBjb25zdCByb3dzID0gYm9keS5zcGxpdCgnOycpLm1hcCgocikgPT4gci50cmltKCkpLmZpbHRlcigocikgPT4gci5sZW5ndGggPiAwKTtcblxuICAgIHJldHVybiByb3dzLm1hcCgocm93KSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSByb3cuc3BsaXQoJywnKS5tYXAoKHYpID0+IHYudHJpbSgpKTtcbiAgICAgIGNvbnN0IHJlc3VsdDogUXVlcnlSZXN1bHQgPSB7fTtcblxuICAgICAgY29sdW1ucy5mb3JFYWNoKChjb2wsIGlkeCkgPT4ge1xuICAgICAgICBpZiAoY29sICYmIGlkeCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICAvLyBUcnkgdG8gcGFyc2UgYXMgSlNPTi9udW1iZXJcbiAgICAgICAgICBsZXQgdmFsdWU6IHVua25vd24gPSB2YWx1ZXNbaWR4XTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09ICdudWxsJykge1xuICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICd0cnVlJykge1xuICAgICAgICAgICAgdmFsdWUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICAgICAgICAgIHZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIGlmICghaXNOYU4oTnVtYmVyKHZhbHVlKSkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0W2NvbF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -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
|