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 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 both request Accept header and response Content-Type
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
- // If write is called, treat as streaming
180
- if (chunk && isSSE) {
181
- const chunkStr = chunk.toString();
182
- const parsed = this.parseSSEChunk(chunkStr, textDeltas);
183
- if (parsed) {
184
- chunks.push(parsed);
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 = chunk.toString();
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mohen",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Unified request/response logger for Express and tRPC with SSE support (墨痕 - ink trace)",
5
5
  "main": "dist/logger.js",
6
6
  "types": "dist/logger.d.ts",
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 both request Accept header and response Content-Type
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
- // If write is called, treat as streaming
216
- if (chunk && isSSE) {
217
- const chunkStr = chunk.toString();
218
- const parsed = this.parseSSEChunk(chunkStr, textDeltas);
219
- if (parsed) {
220
- chunks.push(parsed);
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 = chunk.toString();
340
+ const chunkStr = this.decodeChunk(chunk);
234
341
  const parsed = this.parseSSEChunk(chunkStr, textDeltas);
235
342
  if (parsed) {
236
343
  chunks.push(parsed);
@@ -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) => {