mohen 1.1.0 → 1.2.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/dist/logger.js +100 -9
- package/package.json +1 -1
- package/src/logger.ts +115 -8
- package/test/logger.test.ts +112 -0
package/dist/logger.js
CHANGED
|
@@ -132,6 +132,48 @@ class UnifiedLogger {
|
|
|
132
132
|
console.error('Logger write error:', err);
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Decode chunk to string, handling Uint8Array/Buffer from TextEncoderStream
|
|
137
|
+
*/
|
|
138
|
+
decodeChunk(chunk) {
|
|
139
|
+
if (chunk === null || chunk === undefined) {
|
|
140
|
+
return '';
|
|
141
|
+
}
|
|
142
|
+
// Handle Uint8Array (from TextEncoderStream in AI SDK)
|
|
143
|
+
if (chunk instanceof Uint8Array) {
|
|
144
|
+
return Buffer.from(chunk).toString('utf-8');
|
|
145
|
+
}
|
|
146
|
+
// Handle Buffer
|
|
147
|
+
if (Buffer.isBuffer(chunk)) {
|
|
148
|
+
return chunk.toString('utf-8');
|
|
149
|
+
}
|
|
150
|
+
// Handle string
|
|
151
|
+
if (typeof chunk === 'string') {
|
|
152
|
+
return chunk;
|
|
153
|
+
}
|
|
154
|
+
// Fallback: try toString but check if it looks like byte array
|
|
155
|
+
const str = chunk.toString();
|
|
156
|
+
// Detect if toString produced a comma-separated byte list like "100,97,116,97"
|
|
157
|
+
// This happens when Uint8Array.toString() is called without proper decoding
|
|
158
|
+
if (/^\d+(,\d+)*$/.test(str) && str.includes(',')) {
|
|
159
|
+
try {
|
|
160
|
+
const bytes = new Uint8Array(str.split(',').map(Number));
|
|
161
|
+
return Buffer.from(bytes).toString('utf-8');
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return str;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return str;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if content looks like SSE data
|
|
171
|
+
*/
|
|
172
|
+
looksLikeSSE(content) {
|
|
173
|
+
return content.trimStart().startsWith('data:') ||
|
|
174
|
+
content.includes('\ndata:') ||
|
|
175
|
+
content.trimStart().startsWith('event:');
|
|
176
|
+
}
|
|
135
177
|
// ===========================================================================
|
|
136
178
|
// Express Middleware
|
|
137
179
|
// ===========================================================================
|
|
@@ -146,10 +188,39 @@ class UnifiedLogger {
|
|
|
146
188
|
const requestId = this.generateRequestId();
|
|
147
189
|
// Initialize metadata object on request
|
|
148
190
|
req.logMetadata = {};
|
|
149
|
-
// Detect SSE - check
|
|
191
|
+
// Detect SSE - check request Accept header initially
|
|
150
192
|
let isSSE = req.headers.accept === 'text/event-stream';
|
|
151
193
|
const chunks = [];
|
|
152
194
|
const textDeltas = []; // Collect text-delta content
|
|
195
|
+
// Helper to check Content-Type header for SSE
|
|
196
|
+
const checkContentTypeForSSE = (headers) => {
|
|
197
|
+
if (!headers)
|
|
198
|
+
return;
|
|
199
|
+
// headers can be an object or array of [key, value] pairs
|
|
200
|
+
if (Array.isArray(headers)) {
|
|
201
|
+
for (let i = 0; i < headers.length; i += 2) {
|
|
202
|
+
const key = headers[i];
|
|
203
|
+
const value = headers[i + 1];
|
|
204
|
+
if (typeof key === 'string' &&
|
|
205
|
+
key.toLowerCase() === 'content-type' &&
|
|
206
|
+
typeof value === 'string' &&
|
|
207
|
+
value.includes('text/event-stream')) {
|
|
208
|
+
isSSE = true;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (typeof headers === 'object') {
|
|
214
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
215
|
+
if (key.toLowerCase() === 'content-type' &&
|
|
216
|
+
typeof value === 'string' &&
|
|
217
|
+
value.includes('text/event-stream')) {
|
|
218
|
+
isSSE = true;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
153
224
|
// Intercept setHeader to detect SSE by Content-Type
|
|
154
225
|
const originalSetHeader = res.setHeader.bind(res);
|
|
155
226
|
res.setHeader = ((name, value) => {
|
|
@@ -160,6 +231,20 @@ class UnifiedLogger {
|
|
|
160
231
|
}
|
|
161
232
|
return originalSetHeader(name, value);
|
|
162
233
|
});
|
|
234
|
+
// Intercept writeHead to detect SSE (used by AI SDK's pipeUIMessageStreamToResponse)
|
|
235
|
+
const originalWriteHead = res.writeHead.bind(res);
|
|
236
|
+
res.writeHead = ((statusCode, statusMessageOrHeaders, maybeHeaders) => {
|
|
237
|
+
// writeHead can be called as:
|
|
238
|
+
// writeHead(statusCode)
|
|
239
|
+
// writeHead(statusCode, headers)
|
|
240
|
+
// writeHead(statusCode, statusMessage, headers)
|
|
241
|
+
let headers = maybeHeaders;
|
|
242
|
+
if (!headers && typeof statusMessageOrHeaders === 'object') {
|
|
243
|
+
headers = statusMessageOrHeaders;
|
|
244
|
+
}
|
|
245
|
+
checkContentTypeForSSE(headers);
|
|
246
|
+
return originalWriteHead(statusCode, statusMessageOrHeaders, maybeHeaders);
|
|
247
|
+
});
|
|
163
248
|
// Capture request info
|
|
164
249
|
const requestInfo = {
|
|
165
250
|
body: req.body,
|
|
@@ -176,12 +261,18 @@ class UnifiedLogger {
|
|
|
176
261
|
let responseBody;
|
|
177
262
|
let logged = false;
|
|
178
263
|
res.write = ((chunk, encodingOrCallback, callback) => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const chunkStr =
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
264
|
+
if (chunk) {
|
|
265
|
+
// Properly decode the chunk (handles Uint8Array from TextEncoderStream)
|
|
266
|
+
const chunkStr = this.decodeChunk(chunk);
|
|
267
|
+
// Auto-detect SSE from content if not already detected
|
|
268
|
+
if (!isSSE && this.looksLikeSSE(chunkStr)) {
|
|
269
|
+
isSSE = true;
|
|
270
|
+
}
|
|
271
|
+
if (isSSE) {
|
|
272
|
+
const parsed = this.parseSSEChunk(chunkStr, textDeltas);
|
|
273
|
+
if (parsed) {
|
|
274
|
+
chunks.push(parsed);
|
|
275
|
+
}
|
|
185
276
|
}
|
|
186
277
|
}
|
|
187
278
|
return originalWrite(chunk, encodingOrCallback, callback);
|
|
@@ -193,7 +284,7 @@ class UnifiedLogger {
|
|
|
193
284
|
if (isSSE) {
|
|
194
285
|
// SSE streaming path
|
|
195
286
|
if (chunk) {
|
|
196
|
-
const chunkStr =
|
|
287
|
+
const chunkStr = this.decodeChunk(chunk);
|
|
197
288
|
const parsed = this.parseSSEChunk(chunkStr, textDeltas);
|
|
198
289
|
if (parsed) {
|
|
199
290
|
chunks.push(parsed);
|
|
@@ -438,4 +529,4 @@ function attachTrpcMetadata(ctx, metadata) {
|
|
|
438
529
|
}
|
|
439
530
|
// Default export for simpler imports
|
|
440
531
|
exports.default = createLogger;
|
|
441
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXNkQSxvQ0FzQkM7QUFTRCx3Q0FLQztBQUtELGdEQVFDO0FBdmdCRCx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBa0Q3QiwrRUFBK0U7QUFDL0Usb0JBQW9CO0FBQ3BCLCtFQUErRTtBQUUvRSxNQUFNLGFBQWE7SUFRakIsWUFBWSxRQUFnQixFQUFFLFVBQXlCLEVBQUU7UUFDdkQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLGVBQWU7UUFDN0UsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQztRQUN0RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7UUFDN0MsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUUvQywwQkFBMEI7UUFDMUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLFNBQVMs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LENBQUM7UUFDckIsR0FBRyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBYSxFQUNiLFFBQWlDO0lBRWpDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsR0FBRyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQscUNBQXFDO0FBQ3JDLGtCQUFlLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW50ZXJmYWNlIExvZ0VudHJ5IHtcbiAgdGltZXN0YW1wOiBzdHJpbmc7XG4gIHJlcXVlc3RJZDogc3RyaW5nO1xuICB0eXBlOiAnaHR0cCcgfCAndHJwYyc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGR1cmF0aW9uOiBudW1iZXI7XG4gIHJlcXVlc3Q/OiB7XG4gICAgYm9keT86IHVua25vd247XG4gICAgcXVlcnk/OiB1bmtub3duO1xuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9O1xuICByZXNwb25zZT86IHtcbiAgICBib2R5PzogdW5rbm93bjtcbiAgICBzdHJlYW1pbmc/OiBib29sZWFuO1xuICAgIGNodW5rcz86IHVua25vd25bXTtcbiAgICB0ZXh0Pzogc3RyaW5nOyAvLyBBZ2dyZWdhdGVkIHRleHQgZnJvbSB0ZXh0LWRlbHRhIGNodW5rc1xuICB9O1xuICBlcnJvcj86IHtcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgc3RhY2s/OiBzdHJpbmc7XG4gIH07XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmludGVyZmFjZSBMb2dnZXJPcHRpb25zIHtcbiAgbWF4U2l6ZUJ5dGVzPzogbnVtYmVyOyAgICAgIC8vIERlZmF1bHQ6IDEwTUJcbiAgaW5jbHVkZUhlYWRlcnM/OiBib29sZWFuOyAgIC8vIERlZmF1bHQ6IGZhbHNlXG4gIHJlZGFjdD86IHN0cmluZ1tdOyAgICAgICAgICAvLyBGaWVsZHMgdG8gcmVkYWN0IGZyb20gbG9nc1xuICBpZ25vcmVQYXRocz86IHN0cmluZ1tdOyAgICAgLy8gUGF0aHMgdG8gaWdub3JlIChzdXBwb3J0cyB3aWxkY2FyZHMgbGlrZSAvaGVhbHRoLyopXG4gIGluY2x1ZGVQYXRocz86IHN0cmluZ1tdOyAgICAvLyBPbmx5IGxvZyB0aGVzZSBwYXRocyAoc3VwcG9ydHMgd2lsZGNhcmRzKVxufVxuXG4vLyBFeHRlbmQgRXhwcmVzcyBSZXF1ZXN0IHRvIGluY2x1ZGUgbWV0YWRhdGFcbmRlY2xhcmUgZ2xvYmFsIHtcbiAgbmFtZXNwYWNlIEV4cHJlc3Mge1xuICAgIGludGVyZmFjZSBSZXF1ZXN0IHtcbiAgICAgIGxvZ01ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgfVxuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENvcmUgTG9nZ2VyIENsYXNzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNsYXNzIFVuaWZpZWRMb2dnZXIge1xuICBwcml2YXRlIGZpbGVQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgbWF4U2l6ZUJ5dGVzOiBudW1iZXI7XG4gIHByaXZhdGUgaW5jbHVkZUhlYWRlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVkYWN0RmllbGRzOiBTZXQ8c3RyaW5nPjtcbiAgcHJpdmF0ZSBpZ25vcmVQYXRoczogc3RyaW5nW107XG4gIHByaXZhdGUgaW5jbHVkZVBhdGhzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihmaWxlUGF0aDogc3RyaW5nLCBvcHRpb25zOiBMb2dnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLmZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKGZpbGVQYXRoKTtcbiAgICB0aGlzLm1heFNpemVCeXRlcyA9IG9wdGlvbnMubWF4U2l6ZUJ5dGVzID8/IDEwICogMTAyNCAqIDEwMjQ7IC8vIDEwTUIgZGVmYXVsdFxuICAgIHRoaXMuaW5jbHVkZUhlYWRlcnMgPSBvcHRpb25zLmluY2x1ZGVIZWFkZXJzID8/IGZhbHNlO1xuICAgIHRoaXMucmVkYWN0RmllbGRzID0gbmV3IFNldChvcHRpb25zLnJlZGFjdCA/PyBbJ3Bhc3N3b3JkJywgJ3Rva2VuJywgJ2F1dGhvcml6YXRpb24nLCAnY29va2llJ10pO1xuICAgIHRoaXMuaWdub3JlUGF0aHMgPSBvcHRpb25zLmlnbm9yZVBhdGhzID8/IFtdO1xuICAgIHRoaXMuaW5jbHVkZVBhdGhzID0gb3B0aW9ucy5pbmNsdWRlUGF0aHMgPz8gW107XG5cbiAgICAvLyBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGNvbnN0IGRpciA9IHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZVJlcXVlc3RJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtEYXRlLm5vdygpLnRvU3RyaW5nKDM2KX0tJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA5KX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXRjaFBhdGgocGF0dGVybjogc3RyaW5nLCByZXF1ZXN0UGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gQ29udmVydCB3aWxkY2FyZCBwYXR0ZXJuIHRvIHJlZ2V4XG4gICAgLy8gL2FwaS8qIG1hdGNoZXMgL2FwaS9hbnl0aGluZ1xuICAgIC8vIC9oZWFsdGggbWF0Y2hlcyBleGFjdGx5IC9oZWFsdGhcbiAgICBjb25zdCByZWdleFBhdHRlcm4gPSBwYXR0ZXJuXG4gICAgICAucmVwbGFjZSgvWy4rP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpIC8vIEVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJzIGV4Y2VwdCAqXG4gICAgICAucmVwbGFjZSgvXFwqL2csICcuKicpOyAvLyBDb252ZXJ0ICogdG8gLipcbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoYF4ke3JlZ2V4UGF0dGVybn0kYCk7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QocmVxdWVzdFBhdGgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG91bGRMb2cocmVxdWVzdFBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIEV4dHJhY3QgcGF0aCB3aXRob3V0IHF1ZXJ5IHN0cmluZ1xuICAgIGNvbnN0IHBhdGhPbmx5ID0gcmVxdWVzdFBhdGguc3BsaXQoJz8nKVswXTtcblxuICAgIC8vIElmIGluY2x1ZGVQYXRocyBpcyBzZXQsIG9ubHkgbG9nIG1hdGNoaW5nIHBhdGhzXG4gICAgaWYgKHRoaXMuaW5jbHVkZVBhdGhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmluY2x1ZGVQYXRocy5zb21lKChwYXR0ZXJuKSA9PiB0aGlzLm1hdGNoUGF0aChwYXR0ZXJuLCBwYXRoT25seSkpO1xuICAgIH1cblxuICAgIC8vIElmIGlnbm9yZVBhdGhzIGlzIHNldCwgc2tpcCBtYXRjaGluZyBwYXRoc1xuICAgIGlmICh0aGlzLmlnbm9yZVBhdGhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiAhdGhpcy5pZ25vcmVQYXRocy5zb21lKChwYXR0ZXJuKSA9PiB0aGlzLm1hdGNoUGF0aChwYXR0ZXJuLCBwYXRoT25seSkpO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSByZWRhY3Qob2JqOiB1bmtub3duKTogdW5rbm93biB7XG4gICAgaWYgKG9iaiA9PT0gbnVsbCB8fCBvYmogPT09IHVuZGVmaW5lZCkgcmV0dXJuIG9iajtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHJldHVybiBvYmo7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICByZXR1cm4gb2JqLm1hcCgoaXRlbSkgPT4gdGhpcy5yZWRhY3QoaXRlbSkpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvYmogYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKSB7XG4gICAgICBpZiAodGhpcy5yZWRhY3RGaWVsZHMuaGFzKGtleS50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICByZXN1bHRba2V5XSA9ICdbUkVEQUNURURdJztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXN1bHRba2V5XSA9IHRoaXMucmVkYWN0KHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kUm90YXRlKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5maWxlUGF0aCkpIHJldHVybjtcblxuICAgICAgY29uc3Qgc3RhdHMgPSBmcy5zdGF0U3luYyh0aGlzLmZpbGVQYXRoKTtcbiAgICAgIGlmIChzdGF0cy5zaXplID4gdGhpcy5tYXhTaXplQnl0ZXMpIHtcbiAgICAgICAgLy8gUmVhZCBmaWxlLCBrZWVwIGxhc3QgMjUlIG9mIGxpbmVzXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5maWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIGNvbnN0IGxpbmVzID0gY29udGVudC50cmltKCkuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCBrZWVwQ291bnQgPSBNYXRoLmZsb29yKGxpbmVzLmxlbmd0aCAqIDAuMjUpO1xuICAgICAgICBjb25zdCBuZXdDb250ZW50ID0gbGluZXMuc2xpY2UoLWtlZXBDb3VudCkuam9pbignXFxuJykgKyAnXFxuJztcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmZpbGVQYXRoLCBuZXdDb250ZW50KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0xvZ2dlciByb3RhdGlvbiBlcnJvcjonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlKGVudHJ5OiBMb2dFbnRyeSk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmNoZWNrQW5kUm90YXRlKCk7XG4gICAgICBjb25zdCByZWRhY3RlZEVudHJ5ID0gdGhpcy5yZWRhY3QoZW50cnkpIGFzIExvZ0VudHJ5O1xuICAgICAgY29uc3QgbGluZSA9IEpTT04uc3RyaW5naWZ5KHJlZGFjdGVkRW50cnkpICsgJ1xcbic7XG4gICAgICBmcy5hcHBlbmRGaWxlU3luYyh0aGlzLmZpbGVQYXRoLCBsaW5lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0xvZ2dlciB3cml0ZSBlcnJvcjonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBFeHByZXNzIE1pZGRsZXdhcmVcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZXhwcmVzc01pZGRsZXdhcmUoKSB7XG4gICAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdFBhdGggPSByZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybDtcblxuICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIGxvZyB0aGlzIHBhdGhcbiAgICAgIGlmICghdGhpcy5zaG91bGRMb2cocmVxdWVzdFBhdGgpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHRoaXMuZ2VuZXJhdGVSZXF1ZXN0SWQoKTtcblxuICAgICAgLy8gSW5pdGlhbGl6ZSBtZXRhZGF0YSBvYmplY3Qgb24gcmVxdWVzdFxuICAgICAgcmVxLmxvZ01ldGFkYXRhID0ge307XG5cbiAgICAgIC8vIERldGVjdCBTU0UgLSBjaGVjayBib3RoIHJlcXVlc3QgQWNjZXB0IGhlYWRlciBhbmQgcmVzcG9uc2UgQ29udGVudC1UeXBlXG4gICAgICBsZXQgaXNTU0UgPSByZXEuaGVhZGVycy5hY2NlcHQgPT09ICd0ZXh0L2V2ZW50LXN0cmVhbSc7XG4gICAgICBjb25zdCBjaHVua3M6IHVua25vd25bXSA9IFtdO1xuICAgICAgY29uc3QgdGV4dERlbHRhczogc3RyaW5nW10gPSBbXTsgLy8gQ29sbGVjdCB0ZXh0LWRlbHRhIGNvbnRlbnRcbiAgICAgIFxuICAgICAgLy8gSW50ZXJjZXB0IHNldEhlYWRlciB0byBkZXRlY3QgU1NFIGJ5IENvbnRlbnQtVHlwZVxuICAgICAgY29uc3Qgb3JpZ2luYWxTZXRIZWFkZXIgPSByZXMuc2V0SGVhZGVyLmJpbmQocmVzKTtcbiAgICAgIHJlcy5zZXRIZWFkZXIgPSAoKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IHJlYWRvbmx5IHN0cmluZ1tdKTogUmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSAnY29udGVudC10eXBlJyAmJiBcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgXG4gICAgICAgICAgICB2YWx1ZS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkge1xuICAgICAgICAgIGlzU1NFID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3JpZ2luYWxTZXRIZWFkZXIobmFtZSwgdmFsdWUpO1xuICAgICAgfSkgYXMgdHlwZW9mIHJlcy5zZXRIZWFkZXI7XG5cbiAgICAgIC8vIENhcHR1cmUgcmVxdWVzdCBpbmZvXG4gICAgICBjb25zdCByZXF1ZXN0SW5mbzogTG9nRW50cnlbJ3JlcXVlc3QnXSA9IHtcbiAgICAgICAgYm9keTogcmVxLmJvZHksXG4gICAgICAgIHF1ZXJ5OiByZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5pbmNsdWRlSGVhZGVycykge1xuICAgICAgICByZXF1ZXN0SW5mby5oZWFkZXJzID0gcmVxLmhlYWRlcnMgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJjZXB0IHdyaXRlL2VuZCBmb3Igc3RyZWFtaW5nIGRldGVjdGlvblxuICAgICAgY29uc3Qgb3JpZ2luYWxXcml0ZSA9IHJlcy53cml0ZS5iaW5kKHJlcyk7XG4gICAgICBjb25zdCBvcmlnaW5hbEVuZCA9IHJlcy5lbmQuYmluZChyZXMpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxKc29uID0gcmVzLmpzb24uYmluZChyZXMpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxTZW5kID0gcmVzLnNlbmQuYmluZChyZXMpO1xuICAgICAgbGV0IHJlc3BvbnNlQm9keTogdW5rbm93bjtcbiAgICAgIGxldCBsb2dnZWQgPSBmYWxzZTtcblxuICAgICAgcmVzLndyaXRlID0gKChjaHVuazogYW55LCBlbmNvZGluZ09yQ2FsbGJhY2s/OiBhbnksIGNhbGxiYWNrPzogYW55KTogYm9vbGVhbiA9PiB7XG4gICAgICAgIC8vIElmIHdyaXRlIGlzIGNhbGxlZCwgdHJlYXQgYXMgc3RyZWFtaW5nXG4gICAgICAgIGlmIChjaHVuayAmJiBpc1NTRSkge1xuICAgICAgICAgIGNvbnN0IGNodW5rU3RyID0gY2h1bmsudG9TdHJpbmcoKTtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLnBhcnNlU1NFQ2h1bmsoY2h1bmtTdHIsIHRleHREZWx0YXMpO1xuICAgICAgICAgIGlmIChwYXJzZWQpIHtcbiAgICAgICAgICAgIGNodW5rcy5wdXNoKHBhcnNlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcmlnaW5hbFdyaXRlKGNodW5rLCBlbmNvZGluZ09yQ2FsbGJhY2ssIGNhbGxiYWNrKTtcbiAgICAgIH0pIGFzIHR5cGVvZiByZXMud3JpdGU7XG5cbiAgICAgIHJlcy5lbmQgPSAoKGNodW5rPzogYW55LCBlbmNvZGluZ09yQ2FsbGJhY2s/OiBhbnksIGNhbGxiYWNrPzogYW55KTogUmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAobG9nZ2VkKSByZXR1cm4gb3JpZ2luYWxFbmQoY2h1bmssIGVuY29kaW5nT3JDYWxsYmFjaywgY2FsbGJhY2spO1xuICAgICAgICBsb2dnZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmIChpc1NTRSkge1xuICAgICAgICAgIC8vIFNTRSBzdHJlYW1pbmcgcGF0aFxuICAgICAgICAgIGlmIChjaHVuaykge1xuICAgICAgICAgICAgY29uc3QgY2h1bmtTdHIgPSBjaHVuay50b1N0cmluZygpO1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5wYXJzZVNTRUNodW5rKGNodW5rU3RyLCB0ZXh0RGVsdGFzKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWQpIHtcbiAgICAgICAgICAgICAgY2h1bmtzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICBzdHJlYW1pbmc6IHRydWUsXG4gICAgICAgICAgICAgIGNodW5rcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8vIEFkZCBhZ2dyZWdhdGVkIHRleHQgaWYgd2UgY29sbGVjdGVkIHRleHQtZGVsdGFzXG4gICAgICAgICAgaWYgKHRleHREZWx0YXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZW50cnkucmVzcG9uc2UhLnRleHQgPSB0ZXh0RGVsdGFzLmpvaW4oJycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXEubG9nTWV0YWRhdGEgJiYgT2JqZWN0LmtleXMocmVxLmxvZ01ldGFkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBlbnRyeS5tZXRhZGF0YSA9IHJlcS5sb2dNZXRhZGF0YTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLndyaXRlKGVudHJ5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBSZWd1bGFyIHJlc3BvbnNlIHBhdGhcbiAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICBib2R5OiByZXNwb25zZUJvZHksXG4gICAgICAgICAgICAgIHN0cmVhbWluZzogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAocmVxLmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKHJlcS5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZW50cnkubWV0YWRhdGEgPSByZXEubG9nTWV0YWRhdGE7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy53cml0ZShlbnRyeSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3JpZ2luYWxFbmQoY2h1bmssIGVuY29kaW5nT3JDYWxsYmFjaywgY2FsbGJhY2spO1xuICAgICAgfSkgYXMgdHlwZW9mIHJlcy5lbmQ7XG5cbiAgICAgIGNvbnN0IGxvZ1Jlc3BvbnNlID0gKCkgPT4ge1xuICAgICAgICBpZiAobG9nZ2VkKSByZXR1cm47XG4gICAgICAgIGxvZ2dlZCA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZW50cnk6IExvZ0VudHJ5ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICB0eXBlOiAnaHR0cCcsXG4gICAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlLFxuICAgICAgICAgIGR1cmF0aW9uOiBEYXRlLm5vdygpIC0gc3RhcnQsXG4gICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIGJvZHk6IHJlc3BvbnNlQm9keSxcbiAgICAgICAgICAgIHN0cmVhbWluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocmVxLmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKHJlcS5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGVudHJ5Lm1ldGFkYXRhID0gcmVxLmxvZ01ldGFkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy53cml0ZShlbnRyeSk7XG4gICAgICB9O1xuXG4gICAgICByZXMuanNvbiA9IChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgcmVzcG9uc2VCb2R5ID0gYm9keTtcbiAgICAgICAgbG9nUmVzcG9uc2UoKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsSnNvbihib2R5KTtcbiAgICAgIH07XG5cbiAgICAgIHJlcy5zZW5kID0gKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICBpZiAoIWxvZ2dlZCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZUJvZHkgPSB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycgPyBKU09OLnBhcnNlKGJvZHkpIDogYm9keTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJlc3BvbnNlQm9keSA9IGJvZHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ1Jlc3BvbnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsU2VuZChib2R5KTtcbiAgICAgIH07XG5cbiAgICAgIG5leHQoKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVNTRUNodW5rKHJhdzogc3RyaW5nLCB0ZXh0RGVsdGFzOiBzdHJpbmdbXSk6IHVua25vd24ge1xuICAgIGNvbnN0IGxpbmVzID0gcmF3LnNwbGl0KCdcXG4nKTtcbiAgICBjb25zdCByZXN1bHRzOiB1bmtub3duW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnZGF0YTogJykpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGxpbmUuc2xpY2UoNikudHJpbSgpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gJ1tET05FXScpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goeyB0eXBlOiAnZG9uZScgfSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIEhhbmRsZSB0ZXh0LWRlbHRhIHR5cGUgLSBjb2xsZWN0IHRoZSBkZWx0YSB0ZXh0XG4gICAgICAgICAgaWYgKHBhcnNlZC50eXBlID09PSAndGV4dC1kZWx0YScgJiYgdHlwZW9mIHBhcnNlZC5kZWx0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRleHREZWx0YXMucHVzaChwYXJzZWQuZGVsdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICByZXN1bHRzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHsgcmF3OiBkYXRhIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHNpbmdsZSByZXN1bHQgb3IgYXJyYXlcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHJlc3VsdHNbMF07XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gdFJQQyBNaWRkbGV3YXJlXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHRycGNNaWRkbGV3YXJlPFRDb250ZXh0IGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKSB7XG4gICAgY29uc3QgbG9nZ2VyID0gdGhpcztcblxuICAgIHJldHVybiBhc3luYyBmdW5jdGlvbiBsb2dnZXJNaWRkbGV3YXJlKG9wdHM6IHtcbiAgICAgIHBhdGg6IHN0cmluZztcbiAgICAgIHR5cGU6ICdxdWVyeScgfCAnbXV0YXRpb24nIHwgJ3N1YnNjcmlwdGlvbic7XG4gICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgIGN0eDogVENvbnRleHQgJiB7IGxvZ01ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfTtcbiAgICAgIG5leHQ6ICgpID0+IFByb21pc2U8eyBvazogYm9vbGVhbjsgZGF0YT86IHVua25vd247IGVycm9yPzogRXJyb3IgfT47XG4gICAgfSkge1xuICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIGxvZyB0aGlzIHBhdGhcbiAgICAgIGlmICghbG9nZ2VyLnNob3VsZExvZyhvcHRzLnBhdGgpKSB7XG4gICAgICAgIHJldHVybiBvcHRzLm5leHQoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgcmVxdWVzdElkID0gbG9nZ2VyLmdlbmVyYXRlUmVxdWVzdElkKCk7XG5cbiAgICAgIC8vIEluaXRpYWxpemUgbWV0YWRhdGEgb24gY29udGV4dCBpZiBub3QgcHJlc2VudFxuICAgICAgaWYgKCFvcHRzLmN0eC5sb2dNZXRhZGF0YSkge1xuICAgICAgICBvcHRzLmN0eC5sb2dNZXRhZGF0YSA9IHt9O1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvcHRzLm5leHQoKTtcblxuICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgIHR5cGU6ICd0cnBjJyxcbiAgICAgICAgICBtZXRob2Q6IG9wdHMudHlwZS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICAgIHBhdGg6IG9wdHMucGF0aCxcbiAgICAgICAgICBzdGF0dXNDb2RlOiByZXN1bHQub2sgPyAyMDAgOiA1MDAsXG4gICAgICAgICAgZHVyYXRpb246IERhdGUubm93KCkgLSBzdGFydCxcbiAgICAgICAgICByZXF1ZXN0OiB7XG4gICAgICAgICAgICBib2R5OiBvcHRzLmlucHV0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIGJvZHk6IHJlc3VsdC5kYXRhLFxuICAgICAgICAgICAgc3RyZWFtaW5nOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEF0dGFjaCBtZXRhZGF0YSBpZiBwcmVzZW50XG4gICAgICAgIGlmIChvcHRzLmN0eC5sb2dNZXRhZGF0YSAmJiBPYmplY3Qua2V5cyhvcHRzLmN0eC5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGVudHJ5Lm1ldGFkYXRhID0gb3B0cy5jdHgubG9nTWV0YWRhdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgZW50cnkuZXJyb3IgPSB7XG4gICAgICAgICAgICBtZXNzYWdlOiByZXN1bHQuZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICAgIHN0YWNrOiByZXN1bHQuZXJyb3Iuc3RhY2ssXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci53cml0ZShlbnRyeSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IGVyciA9IGVycm9yIGFzIEVycm9yO1xuXG4gICAgICAgIGNvbnN0IGVudHJ5OiBMb2dFbnRyeSA9IHtcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgdHlwZTogJ3RycGMnLFxuICAgICAgICAgIG1ldGhvZDogb3B0cy50eXBlLnRvVXBwZXJDYXNlKCksXG4gICAgICAgICAgcGF0aDogb3B0cy5wYXRoLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDUwMCxcbiAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgICAgIGJvZHk6IG9wdHMuaW5wdXQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICBzdGFjazogZXJyLnN0YWNrLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gQXR0YWNoIG1ldGFkYXRhIGlmIHByZXNlbnRcbiAgICAgICAgaWYgKG9wdHMuY3R4LmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKG9wdHMuY3R4LmxvZ01ldGFkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZW50cnkubWV0YWRhdGEgPSBvcHRzLmN0eC5sb2dNZXRhZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci53cml0ZShlbnRyeSk7XG5cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGYWN0b3J5IEZ1bmN0aW9uIChNYWluIEV4cG9ydClcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihmaWxlUGF0aDogc3RyaW5nLCBvcHRpb25zPzogTG9nZ2VyT3B0aW9ucykge1xuICBjb25zdCBsb2dnZXIgPSBuZXcgVW5pZmllZExvZ2dlcihmaWxlUGF0aCwgb3B0aW9ucyk7XG5cbiAgcmV0dXJuIHtcbiAgICAvKiogRXhwcmVzcyBtaWRkbGV3YXJlIC0gdXNlIHdpdGggYXBwLnVzZSgpICovXG4gICAgZXhwcmVzczogKCkgPT4gbG9nZ2VyLmV4cHJlc3NNaWRkbGV3YXJlKCksXG5cbiAgICAvKiogdFJQQyBtaWRkbGV3YXJlIC0gdXNlIHdpdGggdC5wcm9jZWR1cmUudXNlKCkgKi9cbiAgICB0cnBjOiA8VENvbnRleHQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpID0+IFxuICAgICAgbG9nZ2VyLnRycGNNaWRkbGV3YXJlPFRDb250ZXh0PigpLFxuXG4gICAgLyoqIERpcmVjdCB3cml0ZSBhY2Nlc3MgZm9yIGN1c3RvbSBsb2dnaW5nICovXG4gICAgd3JpdGU6IChlbnRyeTogUGFydGlhbDxMb2dFbnRyeT4pID0+IGxvZ2dlci53cml0ZSh7XG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHJlcXVlc3RJZDogYCR7RGF0ZS5ub3coKS50b1N0cmluZygzNil9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOSl9YCxcbiAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgIG1ldGhvZDogJ0NVU1RPTScsXG4gICAgICBwYXRoOiAnLycsXG4gICAgICBkdXJhdGlvbjogMCxcbiAgICAgIC4uLmVudHJ5LFxuICAgIH0gYXMgTG9nRW50cnkpLFxuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBIZWxwZXIgdG8gYXR0YWNoIG1ldGFkYXRhIChmb3IgY2xlYW5lciBBUEkpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQXR0YWNoIG1ldGFkYXRhIHRvIHRoZSBjdXJyZW50IHJlcXVlc3QgbG9nIGVudHJ5IChFeHByZXNzKVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXR0YWNoTWV0YWRhdGEocmVxOiBSZXF1ZXN0LCBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkIHtcbiAgaWYgKCFyZXEubG9nTWV0YWRhdGEpIHtcbiAgICByZXEubG9nTWV0YWRhdGEgPSB7fTtcbiAgfVxuICBPYmplY3QuYXNzaWduKHJlcS5sb2dNZXRhZGF0YSwgbWV0YWRhdGEpO1xufVxuXG4vKipcbiAqIEF0dGFjaCBtZXRhZGF0YSB0byB0aGUgY3VycmVudCByZXF1ZXN0IGxvZyBlbnRyeSAodFJQQylcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaFRycGNNZXRhZGF0YTxUQ29udGV4dCBleHRlbmRzIHsgbG9nTWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PihcbiAgY3R4OiBUQ29udGV4dCxcbiAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiB2b2lkIHtcbiAgaWYgKCFjdHgubG9nTWV0YWRhdGEpIHtcbiAgICBjdHgubG9nTWV0YWRhdGEgPSB7fTtcbiAgfVxuICBPYmplY3QuYXNzaWduKGN0eC5sb2dNZXRhZGF0YSwgbWV0YWRhdGEpO1xufVxuXG4vLyBEZWZhdWx0IGV4cG9ydCBmb3Igc2ltcGxlciBpbXBvcnRzXG5leHBvcnQgZGVmYXVsdCBjcmVhdGVMb2dnZXI7XG4iXX0=
|
|
532
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlrQkEsb0NBc0JDO0FBU0Qsd0NBS0M7QUFLRCxnREFRQztBQWxuQkQsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQWtEN0IsK0VBQStFO0FBQy9FLG9CQUFvQjtBQUNwQiwrRUFBK0U7QUFFL0UsTUFBTSxhQUFhO0lBUWpCLFlBQVksUUFBZ0IsRUFBRSxVQUF5QixFQUFFO1FBQ3ZELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxZQUFZLElBQUksRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxlQUFlO1FBQzdFLElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLGNBQWMsSUFBSSxLQUFLLENBQUM7UUFDdEQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNoRyxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUM7UUFFL0MsMEJBQTBCO1FBQzFCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFT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R0FBRyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBYSxFQUNiLFFBQWlDO0lBRWpDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDckIsR0FBRyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQscUNBQXFDO0FBQ3JDLGtCQUFlLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW50ZXJmYWNlIExvZ0VudHJ5IHtcbiAgdGltZXN0YW1wOiBzdHJpbmc7XG4gIHJlcXVlc3RJZDogc3RyaW5nO1xuICB0eXBlOiAnaHR0cCcgfCAndHJwYyc7XG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGR1cmF0aW9uOiBudW1iZXI7XG4gIHJlcXVlc3Q/OiB7XG4gICAgYm9keT86IHVua25vd247XG4gICAgcXVlcnk/OiB1bmtub3duO1xuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9O1xuICByZXNwb25zZT86IHtcbiAgICBib2R5PzogdW5rbm93bjtcbiAgICBzdHJlYW1pbmc/OiBib29sZWFuO1xuICAgIGNodW5rcz86IHVua25vd25bXTtcbiAgICB0ZXh0Pzogc3RyaW5nOyAvLyBBZ2dyZWdhdGVkIHRleHQgZnJvbSB0ZXh0LWRlbHRhIGNodW5rc1xuICB9O1xuICBlcnJvcj86IHtcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gICAgc3RhY2s/OiBzdHJpbmc7XG4gIH07XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmludGVyZmFjZSBMb2dnZXJPcHRpb25zIHtcbiAgbWF4U2l6ZUJ5dGVzPzogbnVtYmVyOyAgICAgIC8vIERlZmF1bHQ6IDEwTUJcbiAgaW5jbHVkZUhlYWRlcnM/OiBib29sZWFuOyAgIC8vIERlZmF1bHQ6IGZhbHNlXG4gIHJlZGFjdD86IHN0cmluZ1tdOyAgICAgICAgICAvLyBGaWVsZHMgdG8gcmVkYWN0IGZyb20gbG9nc1xuICBpZ25vcmVQYXRocz86IHN0cmluZ1tdOyAgICAgLy8gUGF0aHMgdG8gaWdub3JlIChzdXBwb3J0cyB3aWxkY2FyZHMgbGlrZSAvaGVhbHRoLyopXG4gIGluY2x1ZGVQYXRocz86IHN0cmluZ1tdOyAgICAvLyBPbmx5IGxvZyB0aGVzZSBwYXRocyAoc3VwcG9ydHMgd2lsZGNhcmRzKVxufVxuXG4vLyBFeHRlbmQgRXhwcmVzcyBSZXF1ZXN0IHRvIGluY2x1ZGUgbWV0YWRhdGFcbmRlY2xhcmUgZ2xvYmFsIHtcbiAgbmFtZXNwYWNlIEV4cHJlc3Mge1xuICAgIGludGVyZmFjZSBSZXF1ZXN0IHtcbiAgICAgIGxvZ01ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgfVxuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENvcmUgTG9nZ2VyIENsYXNzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmNsYXNzIFVuaWZpZWRMb2dnZXIge1xuICBwcml2YXRlIGZpbGVQYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgbWF4U2l6ZUJ5dGVzOiBudW1iZXI7XG4gIHByaXZhdGUgaW5jbHVkZUhlYWRlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVkYWN0RmllbGRzOiBTZXQ8c3RyaW5nPjtcbiAgcHJpdmF0ZSBpZ25vcmVQYXRoczogc3RyaW5nW107XG4gIHByaXZhdGUgaW5jbHVkZVBhdGhzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihmaWxlUGF0aDogc3RyaW5nLCBvcHRpb25zOiBMb2dnZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLmZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKGZpbGVQYXRoKTtcbiAgICB0aGlzLm1heFNpemVCeXRlcyA9IG9wdGlvbnMubWF4U2l6ZUJ5dGVzID8/IDEwICogMTAyNCAqIDEwMjQ7IC8vIDEwTUIgZGVmYXVsdFxuICAgIHRoaXMuaW5jbHVkZUhlYWRlcnMgPSBvcHRpb25zLmluY2x1ZGVIZWFkZXJzID8/IGZhbHNlO1xuICAgIHRoaXMucmVkYWN0RmllbGRzID0gbmV3IFNldChvcHRpb25zLnJlZGFjdCA/PyBbJ3Bhc3N3b3JkJywgJ3Rva2VuJywgJ2F1dGhvcml6YXRpb24nLCAnY29va2llJ10pO1xuICAgIHRoaXMuaWdub3JlUGF0aHMgPSBvcHRpb25zLmlnbm9yZVBhdGhzID8/IFtdO1xuICAgIHRoaXMuaW5jbHVkZVBhdGhzID0gb3B0aW9ucy5pbmNsdWRlUGF0aHMgPz8gW107XG5cbiAgICAvLyBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGNvbnN0IGRpciA9IHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZVJlcXVlc3RJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtEYXRlLm5vdygpLnRvU3RyaW5nKDM2KX0tJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA5KX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXRjaFBhdGgocGF0dGVybjogc3RyaW5nLCByZXF1ZXN0UGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gQ29udmVydCB3aWxkY2FyZCBwYXR0ZXJuIHRvIHJlZ2V4XG4gICAgLy8gL2FwaS8qIG1hdGNoZXMgL2FwaS9hbnl0aGluZ1xuICAgIC8vIC9oZWFsdGggbWF0Y2hlcyBleGFjdGx5IC9oZWFsdGhcbiAgICBjb25zdCByZWdleFBhdHRlcm4gPSBwYXR0ZXJuXG4gICAgICAucmVwbGFjZSgvWy4rP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpIC8vIEVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJzIGV4Y2VwdCAqXG4gICAgICAucmVwbGFjZSgvXFwqL2csICcuKicpOyAvLyBDb252ZXJ0ICogdG8gLipcbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoYF4ke3JlZ2V4UGF0dGVybn0kYCk7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QocmVxdWVzdFBhdGgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG91bGRMb2cocmVxdWVzdFBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIEV4dHJhY3QgcGF0aCB3aXRob3V0IHF1ZXJ5IHN0cmluZ1xuICAgIGNvbnN0IHBhdGhPbmx5ID0gcmVxdWVzdFBhdGguc3BsaXQoJz8nKVswXTtcblxuICAgIC8vIElmIGluY2x1ZGVQYXRocyBpcyBzZXQsIG9ubHkgbG9nIG1hdGNoaW5nIHBhdGhzXG4gICAgaWYgKHRoaXMuaW5jbHVkZVBhdGhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmluY2x1ZGVQYXRocy5zb21lKChwYXR0ZXJuKSA9PiB0aGlzLm1hdGNoUGF0aChwYXR0ZXJuLCBwYXRoT25seSkpO1xuICAgIH1cblxuICAgIC8vIElmIGlnbm9yZVBhdGhzIGlzIHNldCwgc2tpcCBtYXRjaGluZyBwYXRoc1xuICAgIGlmICh0aGlzLmlnbm9yZVBhdGhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiAhdGhpcy5pZ25vcmVQYXRocy5zb21lKChwYXR0ZXJuKSA9PiB0aGlzLm1hdGNoUGF0aChwYXR0ZXJuLCBwYXRoT25seSkpO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSByZWRhY3Qob2JqOiB1bmtub3duKTogdW5rbm93biB7XG4gICAgaWYgKG9iaiA9PT0gbnVsbCB8fCBvYmogPT09IHVuZGVmaW5lZCkgcmV0dXJuIG9iajtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHJldHVybiBvYmo7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICByZXR1cm4gb2JqLm1hcCgoaXRlbSkgPT4gdGhpcy5yZWRhY3QoaXRlbSkpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvYmogYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKSB7XG4gICAgICBpZiAodGhpcy5yZWRhY3RGaWVsZHMuaGFzKGtleS50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICByZXN1bHRba2V5XSA9ICdbUkVEQUNURURdJztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXN1bHRba2V5XSA9IHRoaXMucmVkYWN0KHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kUm90YXRlKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5maWxlUGF0aCkpIHJldHVybjtcblxuICAgICAgY29uc3Qgc3RhdHMgPSBmcy5zdGF0U3luYyh0aGlzLmZpbGVQYXRoKTtcbiAgICAgIGlmIChzdGF0cy5zaXplID4gdGhpcy5tYXhTaXplQnl0ZXMpIHtcbiAgICAgICAgLy8gUmVhZCBmaWxlLCBrZWVwIGxhc3QgMjUlIG9mIGxpbmVzXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5maWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIGNvbnN0IGxpbmVzID0gY29udGVudC50cmltKCkuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCBrZWVwQ291bnQgPSBNYXRoLmZsb29yKGxpbmVzLmxlbmd0aCAqIDAuMjUpO1xuICAgICAgICBjb25zdCBuZXdDb250ZW50ID0gbGluZXMuc2xpY2UoLWtlZXBDb3VudCkuam9pbignXFxuJykgKyAnXFxuJztcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLmZpbGVQYXRoLCBuZXdDb250ZW50KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0xvZ2dlciByb3RhdGlvbiBlcnJvcjonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlKGVudHJ5OiBMb2dFbnRyeSk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmNoZWNrQW5kUm90YXRlKCk7XG4gICAgICBjb25zdCByZWRhY3RlZEVudHJ5ID0gdGhpcy5yZWRhY3QoZW50cnkpIGFzIExvZ0VudHJ5O1xuICAgICAgY29uc3QgbGluZSA9IEpTT04uc3RyaW5naWZ5KHJlZGFjdGVkRW50cnkpICsgJ1xcbic7XG4gICAgICBmcy5hcHBlbmRGaWxlU3luYyh0aGlzLmZpbGVQYXRoLCBsaW5lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0xvZ2dlciB3cml0ZSBlcnJvcjonLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGUgY2h1bmsgdG8gc3RyaW5nLCBoYW5kbGluZyBVaW50OEFycmF5L0J1ZmZlciBmcm9tIFRleHRFbmNvZGVyU3RyZWFtXG4gICAqL1xuICBwcml2YXRlIGRlY29kZUNodW5rKGNodW5rOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmIChjaHVuayA9PT0gbnVsbCB8fCBjaHVuayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIFxuICAgIC8vIEhhbmRsZSBVaW50OEFycmF5IChmcm9tIFRleHRFbmNvZGVyU3RyZWFtIGluIEFJIFNESylcbiAgICBpZiAoY2h1bmsgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspLnRvU3RyaW5nKCd1dGYtOCcpO1xuICAgIH1cbiAgICBcbiAgICAvLyBIYW5kbGUgQnVmZmVyXG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpIHtcbiAgICAgIHJldHVybiBjaHVuay50b1N0cmluZygndXRmLTgnKTtcbiAgICB9XG4gICAgXG4gICAgLy8gSGFuZGxlIHN0cmluZ1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gY2h1bms7XG4gICAgfVxuICAgIFxuICAgIC8vIEZhbGxiYWNrOiB0cnkgdG9TdHJpbmcgYnV0IGNoZWNrIGlmIGl0IGxvb2tzIGxpa2UgYnl0ZSBhcnJheVxuICAgIGNvbnN0IHN0ciA9IGNodW5rLnRvU3RyaW5nKCk7XG4gICAgXG4gICAgLy8gRGV0ZWN0IGlmIHRvU3RyaW5nIHByb2R1Y2VkIGEgY29tbWEtc2VwYXJhdGVkIGJ5dGUgbGlzdCBsaWtlIFwiMTAwLDk3LDExNiw5N1wiXG4gICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gVWludDhBcnJheS50b1N0cmluZygpIGlzIGNhbGxlZCB3aXRob3V0IHByb3BlciBkZWNvZGluZ1xuICAgIGlmICgvXlxcZCsoLFxcZCspKiQvLnRlc3Qoc3RyKSAmJiBzdHIuaW5jbHVkZXMoJywnKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShzdHIuc3BsaXQoJywnKS5tYXAoTnVtYmVyKSk7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShieXRlcykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjb250ZW50IGxvb2tzIGxpa2UgU1NFIGRhdGFcbiAgICovXG4gIHByaXZhdGUgbG9va3NMaWtlU1NFKGNvbnRlbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb250ZW50LnRyaW1TdGFydCgpLnN0YXJ0c1dpdGgoJ2RhdGE6JykgfHwgXG4gICAgICAgICAgIGNvbnRlbnQuaW5jbHVkZXMoJ1xcbmRhdGE6JykgfHxcbiAgICAgICAgICAgY29udGVudC50cmltU3RhcnQoKS5zdGFydHNXaXRoKCdldmVudDonKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBFeHByZXNzIE1pZGRsZXdhcmVcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZXhwcmVzc01pZGRsZXdhcmUoKSB7XG4gICAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdFBhdGggPSByZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybDtcblxuICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIGxvZyB0aGlzIHBhdGhcbiAgICAgIGlmICghdGhpcy5zaG91bGRMb2cocmVxdWVzdFBhdGgpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHRoaXMuZ2VuZXJhdGVSZXF1ZXN0SWQoKTtcblxuICAgICAgLy8gSW5pdGlhbGl6ZSBtZXRhZGF0YSBvYmplY3Qgb24gcmVxdWVzdFxuICAgICAgcmVxLmxvZ01ldGFkYXRhID0ge307XG5cbiAgICAgIC8vIERldGVjdCBTU0UgLSBjaGVjayByZXF1ZXN0IEFjY2VwdCBoZWFkZXIgaW5pdGlhbGx5XG4gICAgICBsZXQgaXNTU0UgPSByZXEuaGVhZGVycy5hY2NlcHQgPT09ICd0ZXh0L2V2ZW50LXN0cmVhbSc7XG4gICAgICBjb25zdCBjaHVua3M6IHVua25vd25bXSA9IFtdO1xuICAgICAgY29uc3QgdGV4dERlbHRhczogc3RyaW5nW10gPSBbXTsgLy8gQ29sbGVjdCB0ZXh0LWRlbHRhIGNvbnRlbnRcblxuICAgICAgLy8gSGVscGVyIHRvIGNoZWNrIENvbnRlbnQtVHlwZSBoZWFkZXIgZm9yIFNTRVxuICAgICAgY29uc3QgY2hlY2tDb250ZW50VHlwZUZvclNTRSA9IChoZWFkZXJzOiBhbnkpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKCFoZWFkZXJzKSByZXR1cm47XG4gICAgICAgIFxuICAgICAgICAvLyBoZWFkZXJzIGNhbiBiZSBhbiBvYmplY3Qgb3IgYXJyYXkgb2YgW2tleSwgdmFsdWVdIHBhaXJzXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGhlYWRlcnMpKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBoZWFkZXJzW2ldO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBoZWFkZXJzW2kgKyAxXTtcbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJyAmJiBcbiAgICAgICAgICAgICAgICBrZXkudG9Mb3dlckNhc2UoKSA9PT0gJ2NvbnRlbnQtdHlwZScgJiYgXG4gICAgICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiBcbiAgICAgICAgICAgICAgICB2YWx1ZS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkge1xuICAgICAgICAgICAgICBpc1NTRSA9IHRydWU7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGhlYWRlcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgIGlmIChrZXkudG9Mb3dlckNhc2UoKSA9PT0gJ2NvbnRlbnQtdHlwZScgJiYgXG4gICAgICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiBcbiAgICAgICAgICAgICAgICB2YWx1ZS5pbmNsdWRlcygndGV4dC9ldmVudC1zdHJlYW0nKSkge1xuICAgICAgICAgICAgICBpc1NTRSA9IHRydWU7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIEludGVyY2VwdCBzZXRIZWFkZXIgdG8gZGV0ZWN0IFNTRSBieSBDb250ZW50LVR5cGVcbiAgICAgIGNvbnN0IG9yaWdpbmFsU2V0SGVhZGVyID0gcmVzLnNldEhlYWRlci5iaW5kKHJlcyk7XG4gICAgICByZXMuc2V0SGVhZGVyID0gKChuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCByZWFkb25seSBzdHJpbmdbXSk6IFJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2NvbnRlbnQtdHlwZScgJiYgXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIFxuICAgICAgICAgICAgdmFsdWUuaW5jbHVkZXMoJ3RleHQvZXZlbnQtc3RyZWFtJykpIHtcbiAgICAgICAgICBpc1NTRSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsU2V0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICAgIH0pIGFzIHR5cGVvZiByZXMuc2V0SGVhZGVyO1xuXG4gICAgICAvLyBJbnRlcmNlcHQgd3JpdGVIZWFkIHRvIGRldGVjdCBTU0UgKHVzZWQgYnkgQUkgU0RLJ3MgcGlwZVVJTWVzc2FnZVN0cmVhbVRvUmVzcG9uc2UpXG4gICAgICBjb25zdCBvcmlnaW5hbFdyaXRlSGVhZCA9IHJlcy53cml0ZUhlYWQuYmluZChyZXMpO1xuICAgICAgcmVzLndyaXRlSGVhZCA9ICgoXG4gICAgICAgIHN0YXR1c0NvZGU6IG51bWJlcixcbiAgICAgICAgc3RhdHVzTWVzc2FnZU9ySGVhZGVycz86IHN0cmluZyB8IGFueSxcbiAgICAgICAgbWF5YmVIZWFkZXJzPzogYW55XG4gICAgICApOiBSZXNwb25zZSA9PiB7XG4gICAgICAgIC8vIHdyaXRlSGVhZCBjYW4gYmUgY2FsbGVkIGFzOlxuICAgICAgICAvLyB3cml0ZUhlYWQoc3RhdHVzQ29kZSlcbiAgICAgICAgLy8gd3JpdGVIZWFkKHN0YXR1c0NvZGUsIGhlYWRlcnMpXG4gICAgICAgIC8vIHdyaXRlSGVhZChzdGF0dXNDb2RlLCBzdGF0dXNNZXNzYWdlLCBoZWFkZXJzKVxuICAgICAgICBsZXQgaGVhZGVycyA9IG1heWJlSGVhZGVycztcbiAgICAgICAgaWYgKCFoZWFkZXJzICYmIHR5cGVvZiBzdGF0dXNNZXNzYWdlT3JIZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGhlYWRlcnMgPSBzdGF0dXNNZXNzYWdlT3JIZWFkZXJzO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjaGVja0NvbnRlbnRUeXBlRm9yU1NFKGhlYWRlcnMpO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsV3JpdGVIZWFkKHN0YXR1c0NvZGUsIHN0YXR1c01lc3NhZ2VPckhlYWRlcnMgYXMgYW55LCBtYXliZUhlYWRlcnMpO1xuICAgICAgfSkgYXMgdHlwZW9mIHJlcy53cml0ZUhlYWQ7XG5cbiAgICAgIC8vIENhcHR1cmUgcmVxdWVzdCBpbmZvXG4gICAgICBjb25zdCByZXF1ZXN0SW5mbzogTG9nRW50cnlbJ3JlcXVlc3QnXSA9IHtcbiAgICAgICAgYm9keTogcmVxLmJvZHksXG4gICAgICAgIHF1ZXJ5OiByZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5pbmNsdWRlSGVhZGVycykge1xuICAgICAgICByZXF1ZXN0SW5mby5oZWFkZXJzID0gcmVxLmhlYWRlcnMgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJjZXB0IHdyaXRlL2VuZCBmb3Igc3RyZWFtaW5nIGRldGVjdGlvblxuICAgICAgY29uc3Qgb3JpZ2luYWxXcml0ZSA9IHJlcy53cml0ZS5iaW5kKHJlcyk7XG4gICAgICBjb25zdCBvcmlnaW5hbEVuZCA9IHJlcy5lbmQuYmluZChyZXMpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxKc29uID0gcmVzLmpzb24uYmluZChyZXMpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxTZW5kID0gcmVzLnNlbmQuYmluZChyZXMpO1xuICAgICAgbGV0IHJlc3BvbnNlQm9keTogdW5rbm93bjtcbiAgICAgIGxldCBsb2dnZWQgPSBmYWxzZTtcblxuICAgICAgcmVzLndyaXRlID0gKChjaHVuazogYW55LCBlbmNvZGluZ09yQ2FsbGJhY2s/OiBhbnksIGNhbGxiYWNrPzogYW55KTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGlmIChjaHVuaykge1xuICAgICAgICAgIC8vIFByb3Blcmx5IGRlY29kZSB0aGUgY2h1bmsgKGhhbmRsZXMgVWludDhBcnJheSBmcm9tIFRleHRFbmNvZGVyU3RyZWFtKVxuICAgICAgICAgIGNvbnN0IGNodW5rU3RyID0gdGhpcy5kZWNvZGVDaHVuayhjaHVuayk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQXV0by1kZXRlY3QgU1NFIGZyb20gY29udGVudCBpZiBub3QgYWxyZWFkeSBkZXRlY3RlZFxuICAgICAgICAgIGlmICghaXNTU0UgJiYgdGhpcy5sb29rc0xpa2VTU0UoY2h1bmtTdHIpKSB7XG4gICAgICAgICAgICBpc1NTRSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgIGlmIChpc1NTRSkge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5wYXJzZVNTRUNodW5rKGNodW5rU3RyLCB0ZXh0RGVsdGFzKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWQpIHtcbiAgICAgICAgICAgICAgY2h1bmtzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsV3JpdGUoY2h1bmssIGVuY29kaW5nT3JDYWxsYmFjaywgY2FsbGJhY2spO1xuICAgICAgfSkgYXMgdHlwZW9mIHJlcy53cml0ZTtcblxuICAgICAgcmVzLmVuZCA9ICgoY2h1bms/OiBhbnksIGVuY29kaW5nT3JDYWxsYmFjaz86IGFueSwgY2FsbGJhY2s/OiBhbnkpOiBSZXNwb25zZSA9PiB7XG4gICAgICAgIGlmIChsb2dnZWQpIHJldHVybiBvcmlnaW5hbEVuZChjaHVuaywgZW5jb2RpbmdPckNhbGxiYWNrLCBjYWxsYmFjayk7XG4gICAgICAgIGxvZ2dlZCA9IHRydWU7XG5cbiAgICAgICAgaWYgKGlzU1NFKSB7XG4gICAgICAgICAgLy8gU1NFIHN0cmVhbWluZyBwYXRoXG4gICAgICAgICAgaWYgKGNodW5rKSB7XG4gICAgICAgICAgICBjb25zdCBjaHVua1N0ciA9IHRoaXMuZGVjb2RlQ2h1bmsoY2h1bmspO1xuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5wYXJzZVNTRUNodW5rKGNodW5rU3RyLCB0ZXh0RGVsdGFzKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWQpIHtcbiAgICAgICAgICAgICAgY2h1bmtzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICBzdHJlYW1pbmc6IHRydWUsXG4gICAgICAgICAgICAgIGNodW5rcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8vIEFkZCBhZ2dyZWdhdGVkIHRleHQgaWYgd2UgY29sbGVjdGVkIHRleHQtZGVsdGFzXG4gICAgICAgICAgaWYgKHRleHREZWx0YXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZW50cnkucmVzcG9uc2UhLnRleHQgPSB0ZXh0RGVsdGFzLmpvaW4oJycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXEubG9nTWV0YWRhdGEgJiYgT2JqZWN0LmtleXMocmVxLmxvZ01ldGFkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBlbnRyeS5tZXRhZGF0YSA9IHJlcS5sb2dNZXRhZGF0YTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLndyaXRlKGVudHJ5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBSZWd1bGFyIHJlc3BvbnNlIHBhdGhcbiAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgICAgICAgIG1ldGhvZDogcmVxLm1ldGhvZCxcbiAgICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgICBib2R5OiByZXNwb25zZUJvZHksXG4gICAgICAgICAgICAgIHN0cmVhbWluZzogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAocmVxLmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKHJlcS5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZW50cnkubWV0YWRhdGEgPSByZXEubG9nTWV0YWRhdGE7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy53cml0ZShlbnRyeSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3JpZ2luYWxFbmQoY2h1bmssIGVuY29kaW5nT3JDYWxsYmFjaywgY2FsbGJhY2spO1xuICAgICAgfSkgYXMgdHlwZW9mIHJlcy5lbmQ7XG5cbiAgICAgIGNvbnN0IGxvZ1Jlc3BvbnNlID0gKCkgPT4ge1xuICAgICAgICBpZiAobG9nZ2VkKSByZXR1cm47XG4gICAgICAgIGxvZ2dlZCA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZW50cnk6IExvZ0VudHJ5ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICB0eXBlOiAnaHR0cCcsXG4gICAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICAgIHBhdGg6IHJlcXVlc3RQYXRoLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlLFxuICAgICAgICAgIGR1cmF0aW9uOiBEYXRlLm5vdygpIC0gc3RhcnQsXG4gICAgICAgICAgcmVxdWVzdDogcmVxdWVzdEluZm8sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIGJvZHk6IHJlc3BvbnNlQm9keSxcbiAgICAgICAgICAgIHN0cmVhbWluZzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocmVxLmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKHJlcS5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGVudHJ5Lm1ldGFkYXRhID0gcmVxLmxvZ01ldGFkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy53cml0ZShlbnRyeSk7XG4gICAgICB9O1xuXG4gICAgICByZXMuanNvbiA9IChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgcmVzcG9uc2VCb2R5ID0gYm9keTtcbiAgICAgICAgbG9nUmVzcG9uc2UoKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsSnNvbihib2R5KTtcbiAgICAgIH07XG5cbiAgICAgIHJlcy5zZW5kID0gKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICBpZiAoIWxvZ2dlZCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXNwb25zZUJvZHkgPSB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycgPyBKU09OLnBhcnNlKGJvZHkpIDogYm9keTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJlc3BvbnNlQm9keSA9IGJvZHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxvZ1Jlc3BvbnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsU2VuZChib2R5KTtcbiAgICAgIH07XG5cbiAgICAgIG5leHQoKTtcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVNTRUNodW5rKHJhdzogc3RyaW5nLCB0ZXh0RGVsdGFzOiBzdHJpbmdbXSk6IHVua25vd24ge1xuICAgIGNvbnN0IGxpbmVzID0gcmF3LnNwbGl0KCdcXG4nKTtcbiAgICBjb25zdCByZXN1bHRzOiB1bmtub3duW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnZGF0YTogJykpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGxpbmUuc2xpY2UoNikudHJpbSgpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gJ1tET05FXScpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goeyB0eXBlOiAnZG9uZScgfSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIEhhbmRsZSB0ZXh0LWRlbHRhIHR5cGUgLSBjb2xsZWN0IHRoZSBkZWx0YSB0ZXh0XG4gICAgICAgICAgaWYgKHBhcnNlZC50eXBlID09PSAndGV4dC1kZWx0YScgJiYgdHlwZW9mIHBhcnNlZC5kZWx0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRleHREZWx0YXMucHVzaChwYXJzZWQuZGVsdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICByZXN1bHRzLnB1c2gocGFyc2VkKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHsgcmF3OiBkYXRhIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHNpbmdsZSByZXN1bHQgb3IgYXJyYXlcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHJlc3VsdHNbMF07XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gdFJQQyBNaWRkbGV3YXJlXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIHRycGNNaWRkbGV3YXJlPFRDb250ZXh0IGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKSB7XG4gICAgY29uc3QgbG9nZ2VyID0gdGhpcztcblxuICAgIHJldHVybiBhc3luYyBmdW5jdGlvbiBsb2dnZXJNaWRkbGV3YXJlKG9wdHM6IHtcbiAgICAgIHBhdGg6IHN0cmluZztcbiAgICAgIHR5cGU6ICdxdWVyeScgfCAnbXV0YXRpb24nIHwgJ3N1YnNjcmlwdGlvbic7XG4gICAgICBpbnB1dDogdW5rbm93bjtcbiAgICAgIGN0eDogVENvbnRleHQgJiB7IGxvZ01ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfTtcbiAgICAgIG5leHQ6ICgpID0+IFByb21pc2U8eyBvazogYm9vbGVhbjsgZGF0YT86IHVua25vd247IGVycm9yPzogRXJyb3IgfT47XG4gICAgfSkge1xuICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIGxvZyB0aGlzIHBhdGhcbiAgICAgIGlmICghbG9nZ2VyLnNob3VsZExvZyhvcHRzLnBhdGgpKSB7XG4gICAgICAgIHJldHVybiBvcHRzLm5leHQoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgcmVxdWVzdElkID0gbG9nZ2VyLmdlbmVyYXRlUmVxdWVzdElkKCk7XG5cbiAgICAgIC8vIEluaXRpYWxpemUgbWV0YWRhdGEgb24gY29udGV4dCBpZiBub3QgcHJlc2VudFxuICAgICAgaWYgKCFvcHRzLmN0eC5sb2dNZXRhZGF0YSkge1xuICAgICAgICBvcHRzLmN0eC5sb2dNZXRhZGF0YSA9IHt9O1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvcHRzLm5leHQoKTtcblxuICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPSB7XG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgIHR5cGU6ICd0cnBjJyxcbiAgICAgICAgICBtZXRob2Q6IG9wdHMudHlwZS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICAgIHBhdGg6IG9wdHMucGF0aCxcbiAgICAgICAgICBzdGF0dXNDb2RlOiByZXN1bHQub2sgPyAyMDAgOiA1MDAsXG4gICAgICAgICAgZHVyYXRpb246IERhdGUubm93KCkgLSBzdGFydCxcbiAgICAgICAgICByZXF1ZXN0OiB7XG4gICAgICAgICAgICBib2R5OiBvcHRzLmlucHV0LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIGJvZHk6IHJlc3VsdC5kYXRhLFxuICAgICAgICAgICAgc3RyZWFtaW5nOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEF0dGFjaCBtZXRhZGF0YSBpZiBwcmVzZW50XG4gICAgICAgIGlmIChvcHRzLmN0eC5sb2dNZXRhZGF0YSAmJiBPYmplY3Qua2V5cyhvcHRzLmN0eC5sb2dNZXRhZGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGVudHJ5Lm1ldGFkYXRhID0gb3B0cy5jdHgubG9nTWV0YWRhdGE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgZW50cnkuZXJyb3IgPSB7XG4gICAgICAgICAgICBtZXNzYWdlOiByZXN1bHQuZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICAgIHN0YWNrOiByZXN1bHQuZXJyb3Iuc3RhY2ssXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci53cml0ZShlbnRyeSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IGVyciA9IGVycm9yIGFzIEVycm9yO1xuXG4gICAgICAgIGNvbnN0IGVudHJ5OiBMb2dFbnRyeSA9IHtcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgdHlwZTogJ3RycGMnLFxuICAgICAgICAgIG1ldGhvZDogb3B0cy50eXBlLnRvVXBwZXJDYXNlKCksXG4gICAgICAgICAgcGF0aDogb3B0cy5wYXRoLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDUwMCxcbiAgICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0LFxuICAgICAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgICAgIGJvZHk6IG9wdHMuaW5wdXQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICBzdGFjazogZXJyLnN0YWNrLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gQXR0YWNoIG1ldGFkYXRhIGlmIHByZXNlbnRcbiAgICAgICAgaWYgKG9wdHMuY3R4LmxvZ01ldGFkYXRhICYmIE9iamVjdC5rZXlzKG9wdHMuY3R4LmxvZ01ldGFkYXRhKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZW50cnkubWV0YWRhdGEgPSBvcHRzLmN0eC5sb2dNZXRhZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci53cml0ZShlbnRyeSk7XG5cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGYWN0b3J5IEZ1bmN0aW9uIChNYWluIEV4cG9ydClcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihmaWxlUGF0aDogc3RyaW5nLCBvcHRpb25zPzogTG9nZ2VyT3B0aW9ucykge1xuICBjb25zdCBsb2dnZXIgPSBuZXcgVW5pZmllZExvZ2dlcihmaWxlUGF0aCwgb3B0aW9ucyk7XG5cbiAgcmV0dXJuIHtcbiAgICAvKiogRXhwcmVzcyBtaWRkbGV3YXJlIC0gdXNlIHdpdGggYXBwLnVzZSgpICovXG4gICAgZXhwcmVzczogKCkgPT4gbG9nZ2VyLmV4cHJlc3NNaWRkbGV3YXJlKCksXG5cbiAgICAvKiogdFJQQyBtaWRkbGV3YXJlIC0gdXNlIHdpdGggdC5wcm9jZWR1cmUudXNlKCkgKi9cbiAgICB0cnBjOiA8VENvbnRleHQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpID0+IFxuICAgICAgbG9nZ2VyLnRycGNNaWRkbGV3YXJlPFRDb250ZXh0PigpLFxuXG4gICAgLyoqIERpcmVjdCB3cml0ZSBhY2Nlc3MgZm9yIGN1c3RvbSBsb2dnaW5nICovXG4gICAgd3JpdGU6IChlbnRyeTogUGFydGlhbDxMb2dFbnRyeT4pID0+IGxvZ2dlci53cml0ZSh7XG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHJlcXVlc3RJZDogYCR7RGF0ZS5ub3coKS50b1N0cmluZygzNil9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOSl9YCxcbiAgICAgIHR5cGU6ICdodHRwJyxcbiAgICAgIG1ldGhvZDogJ0NVU1RPTScsXG4gICAgICBwYXRoOiAnLycsXG4gICAgICBkdXJhdGlvbjogMCxcbiAgICAgIC4uLmVudHJ5LFxuICAgIH0gYXMgTG9nRW50cnkpLFxuICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBIZWxwZXIgdG8gYXR0YWNoIG1ldGFkYXRhIChmb3IgY2xlYW5lciBBUEkpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQXR0YWNoIG1ldGFkYXRhIHRvIHRoZSBjdXJyZW50IHJlcXVlc3QgbG9nIGVudHJ5IChFeHByZXNzKVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXR0YWNoTWV0YWRhdGEocmVxOiBSZXF1ZXN0LCBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiB2b2lkIHtcbiAgaWYgKCFyZXEubG9nTWV0YWRhdGEpIHtcbiAgICByZXEubG9nTWV0YWRhdGEgPSB7fTtcbiAgfVxuICBPYmplY3QuYXNzaWduKHJlcS5sb2dNZXRhZGF0YSwgbWV0YWRhdGEpO1xufVxuXG4vKipcbiAqIEF0dGFjaCBtZXRhZGF0YSB0byB0aGUgY3VycmVudCByZXF1ZXN0IGxvZyBlbnRyeSAodFJQQylcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaFRycGNNZXRhZGF0YTxUQ29udGV4dCBleHRlbmRzIHsgbG9nTWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PihcbiAgY3R4OiBUQ29udGV4dCxcbiAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiB2b2lkIHtcbiAgaWYgKCFjdHgubG9nTWV0YWRhdGEpIHtcbiAgICBjdHgubG9nTWV0YWRhdGEgPSB7fTtcbiAgfVxuICBPYmplY3QuYXNzaWduKGN0eC5sb2dNZXRhZGF0YSwgbWV0YWRhdGEpO1xufVxuXG4vLyBEZWZhdWx0IGV4cG9ydCBmb3Igc2ltcGxlciBpbXBvcnRzXG5leHBvcnQgZGVmYXVsdCBjcmVhdGVMb2dnZXI7XG4iXX0=
|
package/package.json
CHANGED
package/src/logger.ts
CHANGED
|
@@ -158,6 +158,55 @@ class UnifiedLogger {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Decode chunk to string, handling Uint8Array/Buffer from TextEncoderStream
|
|
163
|
+
*/
|
|
164
|
+
private decodeChunk(chunk: any): string {
|
|
165
|
+
if (chunk === null || chunk === undefined) {
|
|
166
|
+
return '';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Handle Uint8Array (from TextEncoderStream in AI SDK)
|
|
170
|
+
if (chunk instanceof Uint8Array) {
|
|
171
|
+
return Buffer.from(chunk).toString('utf-8');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Handle Buffer
|
|
175
|
+
if (Buffer.isBuffer(chunk)) {
|
|
176
|
+
return chunk.toString('utf-8');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Handle string
|
|
180
|
+
if (typeof chunk === 'string') {
|
|
181
|
+
return chunk;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Fallback: try toString but check if it looks like byte array
|
|
185
|
+
const str = chunk.toString();
|
|
186
|
+
|
|
187
|
+
// Detect if toString produced a comma-separated byte list like "100,97,116,97"
|
|
188
|
+
// This happens when Uint8Array.toString() is called without proper decoding
|
|
189
|
+
if (/^\d+(,\d+)*$/.test(str) && str.includes(',')) {
|
|
190
|
+
try {
|
|
191
|
+
const bytes = new Uint8Array(str.split(',').map(Number));
|
|
192
|
+
return Buffer.from(bytes).toString('utf-8');
|
|
193
|
+
} catch {
|
|
194
|
+
return str;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return str;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Check if content looks like SSE data
|
|
203
|
+
*/
|
|
204
|
+
private looksLikeSSE(content: string): boolean {
|
|
205
|
+
return content.trimStart().startsWith('data:') ||
|
|
206
|
+
content.includes('\ndata:') ||
|
|
207
|
+
content.trimStart().startsWith('event:');
|
|
208
|
+
}
|
|
209
|
+
|
|
161
210
|
// ===========================================================================
|
|
162
211
|
// Express Middleware
|
|
163
212
|
// ===========================================================================
|
|
@@ -177,10 +226,39 @@ class UnifiedLogger {
|
|
|
177
226
|
// Initialize metadata object on request
|
|
178
227
|
req.logMetadata = {};
|
|
179
228
|
|
|
180
|
-
// Detect SSE - check
|
|
229
|
+
// Detect SSE - check request Accept header initially
|
|
181
230
|
let isSSE = req.headers.accept === 'text/event-stream';
|
|
182
231
|
const chunks: unknown[] = [];
|
|
183
232
|
const textDeltas: string[] = []; // Collect text-delta content
|
|
233
|
+
|
|
234
|
+
// Helper to check Content-Type header for SSE
|
|
235
|
+
const checkContentTypeForSSE = (headers: any): void => {
|
|
236
|
+
if (!headers) return;
|
|
237
|
+
|
|
238
|
+
// headers can be an object or array of [key, value] pairs
|
|
239
|
+
if (Array.isArray(headers)) {
|
|
240
|
+
for (let i = 0; i < headers.length; i += 2) {
|
|
241
|
+
const key = headers[i];
|
|
242
|
+
const value = headers[i + 1];
|
|
243
|
+
if (typeof key === 'string' &&
|
|
244
|
+
key.toLowerCase() === 'content-type' &&
|
|
245
|
+
typeof value === 'string' &&
|
|
246
|
+
value.includes('text/event-stream')) {
|
|
247
|
+
isSSE = true;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} else if (typeof headers === 'object') {
|
|
252
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
253
|
+
if (key.toLowerCase() === 'content-type' &&
|
|
254
|
+
typeof value === 'string' &&
|
|
255
|
+
value.includes('text/event-stream')) {
|
|
256
|
+
isSSE = true;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
184
262
|
|
|
185
263
|
// Intercept setHeader to detect SSE by Content-Type
|
|
186
264
|
const originalSetHeader = res.setHeader.bind(res);
|
|
@@ -193,6 +271,27 @@ class UnifiedLogger {
|
|
|
193
271
|
return originalSetHeader(name, value);
|
|
194
272
|
}) as typeof res.setHeader;
|
|
195
273
|
|
|
274
|
+
// Intercept writeHead to detect SSE (used by AI SDK's pipeUIMessageStreamToResponse)
|
|
275
|
+
const originalWriteHead = res.writeHead.bind(res);
|
|
276
|
+
res.writeHead = ((
|
|
277
|
+
statusCode: number,
|
|
278
|
+
statusMessageOrHeaders?: string | any,
|
|
279
|
+
maybeHeaders?: any
|
|
280
|
+
): Response => {
|
|
281
|
+
// writeHead can be called as:
|
|
282
|
+
// writeHead(statusCode)
|
|
283
|
+
// writeHead(statusCode, headers)
|
|
284
|
+
// writeHead(statusCode, statusMessage, headers)
|
|
285
|
+
let headers = maybeHeaders;
|
|
286
|
+
if (!headers && typeof statusMessageOrHeaders === 'object') {
|
|
287
|
+
headers = statusMessageOrHeaders;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
checkContentTypeForSSE(headers);
|
|
291
|
+
|
|
292
|
+
return originalWriteHead(statusCode, statusMessageOrHeaders as any, maybeHeaders);
|
|
293
|
+
}) as typeof res.writeHead;
|
|
294
|
+
|
|
196
295
|
// Capture request info
|
|
197
296
|
const requestInfo: LogEntry['request'] = {
|
|
198
297
|
body: req.body,
|
|
@@ -212,12 +311,20 @@ class UnifiedLogger {
|
|
|
212
311
|
let logged = false;
|
|
213
312
|
|
|
214
313
|
res.write = ((chunk: any, encodingOrCallback?: any, callback?: any): boolean => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const chunkStr =
|
|
218
|
-
|
|
219
|
-
if
|
|
220
|
-
|
|
314
|
+
if (chunk) {
|
|
315
|
+
// Properly decode the chunk (handles Uint8Array from TextEncoderStream)
|
|
316
|
+
const chunkStr = this.decodeChunk(chunk);
|
|
317
|
+
|
|
318
|
+
// Auto-detect SSE from content if not already detected
|
|
319
|
+
if (!isSSE && this.looksLikeSSE(chunkStr)) {
|
|
320
|
+
isSSE = true;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (isSSE) {
|
|
324
|
+
const parsed = this.parseSSEChunk(chunkStr, textDeltas);
|
|
325
|
+
if (parsed) {
|
|
326
|
+
chunks.push(parsed);
|
|
327
|
+
}
|
|
221
328
|
}
|
|
222
329
|
}
|
|
223
330
|
return originalWrite(chunk, encodingOrCallback, callback);
|
|
@@ -230,7 +337,7 @@ class UnifiedLogger {
|
|
|
230
337
|
if (isSSE) {
|
|
231
338
|
// SSE streaming path
|
|
232
339
|
if (chunk) {
|
|
233
|
-
const chunkStr =
|
|
340
|
+
const chunkStr = this.decodeChunk(chunk);
|
|
234
341
|
const parsed = this.parseSSEChunk(chunkStr, textDeltas);
|
|
235
342
|
if (parsed) {
|
|
236
343
|
chunks.push(parsed);
|
package/test/logger.test.ts
CHANGED
|
@@ -521,6 +521,118 @@ describe('mohen logger', () => {
|
|
|
521
521
|
});
|
|
522
522
|
});
|
|
523
523
|
|
|
524
|
+
describe('AI SDK Style Streaming', () => {
|
|
525
|
+
it('should detect SSE via writeHead (AI SDK pipeUIMessageStreamToResponse)', async () => {
|
|
526
|
+
app.get('/api/ai-stream', (req, res) => {
|
|
527
|
+
// AI SDK uses writeHead instead of setHeader
|
|
528
|
+
res.writeHead(200, {
|
|
529
|
+
'Content-Type': 'text/event-stream',
|
|
530
|
+
'Cache-Control': 'no-cache',
|
|
531
|
+
'Connection': 'keep-alive',
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
res.write('data: {"type":"start"}\n\n');
|
|
535
|
+
res.write('data: {"type":"text-delta","delta":"Hello"}\n\n');
|
|
536
|
+
res.write('data: {"type":"finish"}\n\n');
|
|
537
|
+
res.end();
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
await request(app)
|
|
541
|
+
.get('/api/ai-stream')
|
|
542
|
+
.expect(200);
|
|
543
|
+
|
|
544
|
+
const entries = readLogEntries();
|
|
545
|
+
expect(entries).toHaveLength(1);
|
|
546
|
+
expect(entries[0]).toMatchObject({
|
|
547
|
+
type: 'http',
|
|
548
|
+
method: 'GET',
|
|
549
|
+
path: '/api/ai-stream',
|
|
550
|
+
response: {
|
|
551
|
+
streaming: true,
|
|
552
|
+
text: 'Hello',
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
expect(entries[0].response.chunks).toContainEqual({ type: 'start' });
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
it('should handle Uint8Array chunks from TextEncoderStream', async () => {
|
|
559
|
+
app.get('/api/binary-stream', (req, res) => {
|
|
560
|
+
res.writeHead(200, {
|
|
561
|
+
'Content-Type': 'text/event-stream',
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Simulate TextEncoderStream output (Uint8Array)
|
|
565
|
+
const encoder = new TextEncoder();
|
|
566
|
+
res.write(encoder.encode('data: {"type":"start"}\n\n'));
|
|
567
|
+
res.write(encoder.encode('data: {"type":"text-delta","delta":"Binary"}\n\n'));
|
|
568
|
+
res.write(encoder.encode('data: {"type":"text-delta","delta":" works"}\n\n'));
|
|
569
|
+
res.write(encoder.encode('data: [DONE]\n\n'));
|
|
570
|
+
res.end();
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
await request(app)
|
|
574
|
+
.get('/api/binary-stream')
|
|
575
|
+
.expect(200);
|
|
576
|
+
|
|
577
|
+
const entries = readLogEntries();
|
|
578
|
+
expect(entries).toHaveLength(1);
|
|
579
|
+
expect(entries[0]).toMatchObject({
|
|
580
|
+
type: 'http',
|
|
581
|
+
path: '/api/binary-stream',
|
|
582
|
+
response: {
|
|
583
|
+
streaming: true,
|
|
584
|
+
text: 'Binary works',
|
|
585
|
+
},
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
it('should auto-detect SSE from content when headers not set', async () => {
|
|
590
|
+
app.get('/api/auto-detect', (req, res) => {
|
|
591
|
+
// No SSE headers set, but content is SSE format
|
|
592
|
+
res.write('data: {"type":"start"}\n\n');
|
|
593
|
+
res.write('data: {"type":"text-delta","delta":"Auto"}\n\n');
|
|
594
|
+
res.write('data: {"type":"text-delta","delta":" detected"}\n\n');
|
|
595
|
+
res.end();
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
await request(app)
|
|
599
|
+
.get('/api/auto-detect')
|
|
600
|
+
.expect(200);
|
|
601
|
+
|
|
602
|
+
const entries = readLogEntries();
|
|
603
|
+
expect(entries).toHaveLength(1);
|
|
604
|
+
expect(entries[0]).toMatchObject({
|
|
605
|
+
type: 'http',
|
|
606
|
+
path: '/api/auto-detect',
|
|
607
|
+
response: {
|
|
608
|
+
streaming: true,
|
|
609
|
+
text: 'Auto detected',
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
it('should handle writeHead with statusMessage parameter', async () => {
|
|
615
|
+
app.get('/api/writehead-msg', (req, res) => {
|
|
616
|
+
// writeHead(statusCode, statusMessage, headers)
|
|
617
|
+
res.writeHead(200, 'OK', {
|
|
618
|
+
'Content-Type': 'text/event-stream',
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
res.write('data: {"type":"text-delta","delta":"Test"}\n\n');
|
|
622
|
+
res.end();
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
await request(app)
|
|
626
|
+
.get('/api/writehead-msg')
|
|
627
|
+
.expect(200);
|
|
628
|
+
|
|
629
|
+
const entries = readLogEntries();
|
|
630
|
+
expect(entries).toHaveLength(1);
|
|
631
|
+
expect(entries[0].response.streaming).toBe(true);
|
|
632
|
+
expect(entries[0].response.text).toBe('Test');
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
|
|
524
636
|
describe('SSE Text Delta Parsing', () => {
|
|
525
637
|
it('should aggregate text-delta chunks into text field', async () => {
|
|
526
638
|
app.get('/api/stream', (req, res) => {
|