@sinequa/assistant 3.6.2 → 3.7.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/chat/chat-message/chat-message.component.d.ts +4 -2
- package/chat/chat.component.d.ts +56 -17
- package/chat/chat.service.d.ts +23 -1
- package/chat/rest-chat.service.d.ts +1 -0
- package/chat/saved-chats/saved-chats.component.d.ts +2 -2
- package/chat/styles/assistant.scss +5 -0
- package/chat/types.d.ts +128 -3
- package/chat/websocket-chat.service.d.ts +6 -6
- package/esm2020/chat/chat-message/chat-message.component.mjs +9 -4
- package/esm2020/chat/chat-reference/chat-reference.component.mjs +3 -3
- package/esm2020/chat/chat.component.mjs +262 -60
- package/esm2020/chat/chat.service.mjs +49 -3
- package/esm2020/chat/debug-message/debug-message.component.mjs +3 -3
- package/esm2020/chat/rest-chat.service.mjs +8 -3
- package/esm2020/chat/saved-chats/saved-chats.component.mjs +16 -5
- package/esm2020/chat/token-progress-bar/token-progress-bar.component.mjs +3 -3
- package/esm2020/chat/types.mjs +11 -3
- package/esm2020/chat/websocket-chat.service.mjs +191 -99
- package/fesm2015/sinequa-assistant-chat.mjs +552 -178
- package/fesm2015/sinequa-assistant-chat.mjs.map +1 -1
- package/fesm2020/sinequa-assistant-chat.mjs +542 -175
- package/fesm2020/sinequa-assistant-chat.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { AuthenticationService } from "@sinequa/core/login";
|
|
|
3
3
|
import { SignalRWebService } from "@sinequa/core/web-services";
|
|
4
4
|
import { HttpTransportType, LogLevel } from "@microsoft/signalr";
|
|
5
5
|
import { ChatService } from "./chat.service";
|
|
6
|
-
import { merge, fromEvent, Observable, Subject, catchError, filter, forkJoin, map, shareReplay, switchMap, tap, throwError, takeUntil, take } from "rxjs";
|
|
6
|
+
import { merge, fromEvent, Observable, Subject, catchError, filter, forkJoin, map, shareReplay, switchMap, tap, throwError, takeUntil, take, mergeMap, of } from "rxjs";
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
export class WebSocketChatService extends ChatService {
|
|
9
9
|
constructor() {
|
|
@@ -11,10 +11,8 @@ export class WebSocketChatService extends ChatService {
|
|
|
11
11
|
this._messageHandlers = new Map();
|
|
12
12
|
this._actionMap = new Map();
|
|
13
13
|
this._progress = undefined;
|
|
14
|
-
this._content = "";
|
|
15
14
|
this._attachments = [];
|
|
16
|
-
this.
|
|
17
|
-
this._debugMessages = undefined;
|
|
15
|
+
this._debugMessages = [];
|
|
18
16
|
this.signalRService = inject(SignalRWebService);
|
|
19
17
|
this.authenticationService = inject(AuthenticationService);
|
|
20
18
|
}
|
|
@@ -64,36 +62,36 @@ export class WebSocketChatService extends ChatService {
|
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
listModels() {
|
|
67
|
-
const modelsSubject = new Subject();
|
|
65
|
+
const modelsSubject$ = new Subject();
|
|
68
66
|
this.connection.on('ListModels', (res) => {
|
|
69
67
|
this.models = res.models?.filter(model => !!model.enable);
|
|
70
|
-
modelsSubject
|
|
71
|
-
modelsSubject
|
|
68
|
+
modelsSubject$.next(this.models);
|
|
69
|
+
modelsSubject$.complete();
|
|
72
70
|
});
|
|
73
71
|
// Send the request to get the list of models
|
|
74
72
|
this.connection.invoke('ListModels', { debug: this.chatConfig$.value.defaultValues.debug })
|
|
75
73
|
.catch(error => {
|
|
76
74
|
console.error('Error invoking ListModels:', error);
|
|
77
|
-
modelsSubject
|
|
78
|
-
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection
|
|
75
|
+
modelsSubject$.error(new Error(error));
|
|
76
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
79
77
|
});
|
|
80
|
-
return modelsSubject
|
|
78
|
+
return modelsSubject$.asObservable();
|
|
81
79
|
}
|
|
82
80
|
listFunctions() {
|
|
83
|
-
const functionsSubject = new Subject();
|
|
81
|
+
const functionsSubject$ = new Subject();
|
|
84
82
|
this.connection.on('ListFunctions', (res) => {
|
|
85
83
|
this.functions = res.functions?.filter(func => func.enabled);
|
|
86
|
-
functionsSubject
|
|
87
|
-
functionsSubject
|
|
84
|
+
functionsSubject$.next(this.functions);
|
|
85
|
+
functionsSubject$.complete();
|
|
88
86
|
});
|
|
89
87
|
// Send the request to get the list of functions
|
|
90
88
|
this.connection.invoke('ListFunctions', { debug: this.chatConfig$.value.defaultValues.debug })
|
|
91
89
|
.catch(error => {
|
|
92
90
|
console.error('Error invoking ListFunctions:', error);
|
|
93
|
-
functionsSubject
|
|
94
|
-
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection
|
|
91
|
+
functionsSubject$.error(new Error(error));
|
|
92
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
95
93
|
});
|
|
96
|
-
return functionsSubject
|
|
94
|
+
return functionsSubject$.asObservable();
|
|
97
95
|
}
|
|
98
96
|
fetch(messages, query) {
|
|
99
97
|
// Start streaming by invoking the Chat method
|
|
@@ -121,7 +119,8 @@ export class WebSocketChatService extends ChatService {
|
|
|
121
119
|
data.instanceId = this.chatInstanceId;
|
|
122
120
|
data.savedChatId = this.savedChatId;
|
|
123
121
|
}
|
|
124
|
-
|
|
122
|
+
// Initialize the response with an empty assistant message
|
|
123
|
+
this._response = [{ role: "assistant", content: "", additionalProperties: { display: true } }]; // here display: true is needed in order to be able to show the progress
|
|
125
124
|
// Create a Subject to signal completion
|
|
126
125
|
const completion$ = new Subject();
|
|
127
126
|
// Create observables for each non-global handler in the _messageHandlers map (default and eventual custom ones) once it is triggered by the hub connection
|
|
@@ -129,8 +128,19 @@ export class WebSocketChatService extends ChatService {
|
|
|
129
128
|
.from(this._messageHandlers.entries())
|
|
130
129
|
.filter(([eventName, eventHandler]) => !eventHandler.isGlobalHandler)
|
|
131
130
|
.map(([eventName, eventHandler]) => {
|
|
132
|
-
return fromEvent(this.connection, eventName).pipe(
|
|
133
|
-
|
|
131
|
+
return fromEvent(this.connection, eventName).pipe(mergeMap((event) => {
|
|
132
|
+
// Wrap the handler in a try-catch block to prevent the entire stream from failing if an error occurs in a single handler
|
|
133
|
+
try {
|
|
134
|
+
// Execute the handler and emit the result
|
|
135
|
+
// NB: here we could use [eventHandler.handler(event)] which behind the scenes mergeMap interprets this array as an observable sequence with one item, which it then emits
|
|
136
|
+
return of(eventHandler.handler(event));
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
console.error(`Error in event handler for ${eventName}:`, error);
|
|
140
|
+
// Use throwError to propagate the error downstream
|
|
141
|
+
return throwError(() => new Error(`Error in event handler for ${eventName}: ${error}`));
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
134
144
|
});
|
|
135
145
|
// Then merge them into a single observable in order to simulate the streaming behavior
|
|
136
146
|
const combined$ = merge(...observables).pipe(map(() => {
|
|
@@ -144,37 +154,74 @@ export class WebSocketChatService extends ChatService {
|
|
|
144
154
|
time: a.executionTime,
|
|
145
155
|
}))
|
|
146
156
|
: undefined;
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
|
|
157
|
+
// Always update ONLY the first assistant message of the _response with the new $progress, $attachment and $debug
|
|
158
|
+
// Assuming that the first assistant message is always visible since the hub does not send hidden messages by design
|
|
159
|
+
// So even if the first assistant message is hidden (display: false), the _response[0] will and should contain :
|
|
160
|
+
// - $progress, $attachment and $debug
|
|
161
|
+
// - the content of the first visible assistant message in the workflow
|
|
162
|
+
// This is mandatory in order to match the behavior of consecutive messages and maintain consistency with the chatHistory
|
|
163
|
+
if (!!this._progress || this._attachments.length > 0 || this._debugMessages.length > 0) {
|
|
164
|
+
this._response[0].additionalProperties.$progress = this._progress;
|
|
165
|
+
this._response[0].additionalProperties.$attachment = this._attachments;
|
|
166
|
+
this._response[0].additionalProperties.$debug = this._debugMessages;
|
|
150
167
|
}
|
|
151
168
|
// Return the result
|
|
152
|
-
return { history: [...messages,
|
|
169
|
+
return { history: [...messages, ...this._response], executionTime: this._executionTime };
|
|
153
170
|
}), takeUntil(completion$));
|
|
154
171
|
// return a new Observable that emits the result of the combined stream and handles the eventual errors of the invocation of the Chat method
|
|
155
172
|
return new Observable(observer => {
|
|
156
173
|
// Subscribe to combined stream
|
|
157
174
|
combined$.subscribe({
|
|
158
175
|
next: (value) => observer.next(value),
|
|
159
|
-
error: (err) => observer.error(err)
|
|
160
|
-
complete: () => observer.complete(),
|
|
176
|
+
error: (err) => observer.error(err)
|
|
161
177
|
});
|
|
162
178
|
// Invoke the Chat method and handle errors
|
|
163
179
|
this.connection.invoke('Chat', data)
|
|
180
|
+
.then(() => {
|
|
181
|
+
// If a valid assistant message with (display: true) was found, update it
|
|
182
|
+
// and it should always the case
|
|
183
|
+
const index = this.firstVisibleAssistantMessageIndex(this.chatHistory);
|
|
184
|
+
if (index !== -1) {
|
|
185
|
+
this.chatHistory[index].additionalProperties.$progress = this._progress;
|
|
186
|
+
this.chatHistory[index].additionalProperties.$attachment = this._attachments;
|
|
187
|
+
this.chatHistory[index].additionalProperties.$debug = this._debugMessages;
|
|
188
|
+
}
|
|
189
|
+
// Save/update the chat if savedChat enabled
|
|
190
|
+
if (this.chatConfig$.value.savedChatSettings.enabled && this.chatHistory.some((msg) => msg.additionalProperties?.isUserInput === true)) {
|
|
191
|
+
const action = !this.savedChatId ? this.addSavedChat(this.chatHistory).pipe(tap(() => this.listSavedChat())) : this.updateSavedChat(this.savedChatId, undefined, this.chatHistory);
|
|
192
|
+
action.pipe(take(1)).subscribe({
|
|
193
|
+
next: () => { },
|
|
194
|
+
error: (error) => {
|
|
195
|
+
this.streaming$.next(false);
|
|
196
|
+
observer.error(error);
|
|
197
|
+
},
|
|
198
|
+
complete: () => {
|
|
199
|
+
this.streaming$.next(false);
|
|
200
|
+
observer.complete();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this.streaming$.next(false);
|
|
206
|
+
observer.complete();
|
|
207
|
+
}
|
|
208
|
+
})
|
|
164
209
|
.catch(error => {
|
|
165
210
|
console.error('Error invoking Chat:', error);
|
|
211
|
+
this.streaming$.next(false);
|
|
166
212
|
// Emit the error to the newly created observable
|
|
167
213
|
observer.error(error);
|
|
168
214
|
// Return a resolved promise to handle the error and prevent unhandled promise rejection
|
|
169
215
|
return Promise.resolve();
|
|
170
216
|
})
|
|
171
217
|
.finally(() => {
|
|
172
|
-
|
|
218
|
+
// This block concerns ONLY the completion of the "Chat" method invocation.
|
|
219
|
+
// This means the completion of the combined$ stream.
|
|
220
|
+
// It does not take into account the completion of the entire fetch method (the observable returned by fetch) and which depends on the completion of the save chat action if enabled
|
|
221
|
+
this._response = []; // Clear the _response
|
|
173
222
|
this._actionMap.clear(); // Clear the _actionMap
|
|
174
|
-
this._content = ""; // Clear the _content
|
|
175
223
|
this._progress = undefined; // Clear the _progress
|
|
176
224
|
this._attachments = []; // Clear the _attachments
|
|
177
|
-
this._suggestedActions = []; // Clear the _suggestedActions
|
|
178
225
|
this._debugMessages = []; // Clear the _debugMessages
|
|
179
226
|
this._executionTime = ""; // Clear the _executionTime
|
|
180
227
|
completion$.next(); // Emit a signal to complete the observables
|
|
@@ -182,6 +229,33 @@ export class WebSocketChatService extends ChatService {
|
|
|
182
229
|
});
|
|
183
230
|
});
|
|
184
231
|
}
|
|
232
|
+
stopGeneration() {
|
|
233
|
+
// Start stopping generation by invoking the CancelTasks method
|
|
234
|
+
this.stoppingGeneration$.next(true);
|
|
235
|
+
// Create a Subject to hold the result of the CancelTasks method
|
|
236
|
+
const stopGenerationSubject$ = new Subject();
|
|
237
|
+
this.connection.on('CancelTasks', (res) => {
|
|
238
|
+
// When the generation is stopped before streaming any VISIBLE assistant message, this means that $progress, $attachment and $debug properties will be lost.
|
|
239
|
+
// However, the "ContextMessage" frames will be persisted in the chatHistory and the assistant may reference them in the next generation.
|
|
240
|
+
// This leads to the problem of referencing undisplayed attachments in the next generation.
|
|
241
|
+
// To solve this problem, we need to persist $progress, $attachment and $debug properties by adding a new assistant message with empty content and these properties.
|
|
242
|
+
if (this._response.length === 1 && this._response[0].content === "") {
|
|
243
|
+
this.chatHistory?.push({ role: "assistant", content: "", additionalProperties: { display: true, $progress: this._progress, $attachment: this._attachments, $debug: this._debugMessages } });
|
|
244
|
+
}
|
|
245
|
+
stopGenerationSubject$.next(!!res); // Emit the result of the CancelTasks method
|
|
246
|
+
stopGenerationSubject$.complete(); // Complete the subject
|
|
247
|
+
this.stoppingGeneration$.next(false); // Complete stopping generation
|
|
248
|
+
});
|
|
249
|
+
// Invoke the CancelTasks method and handle errors
|
|
250
|
+
this.connection.invoke('CancelTasks')
|
|
251
|
+
.catch(error => {
|
|
252
|
+
console.error('Error invoking CancelTasks:', error);
|
|
253
|
+
stopGenerationSubject$.error(new Error(error));
|
|
254
|
+
this.stoppingGeneration$.next(false); // Complete stopping generation
|
|
255
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
256
|
+
});
|
|
257
|
+
return stopGenerationSubject$.asObservable();
|
|
258
|
+
}
|
|
185
259
|
listSavedChat() {
|
|
186
260
|
if (!this.chatConfig$.value.savedChatSettings.enabled) {
|
|
187
261
|
return;
|
|
@@ -201,27 +275,27 @@ export class WebSocketChatService extends ChatService {
|
|
|
201
275
|
});
|
|
202
276
|
}
|
|
203
277
|
getSavedChat(id) {
|
|
204
|
-
const savedChatSubject = new Subject();
|
|
278
|
+
const savedChatSubject$ = new Subject();
|
|
205
279
|
const data = {
|
|
206
280
|
instanceId: this.chatInstanceId,
|
|
207
281
|
savedChatId: id,
|
|
208
282
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
209
283
|
};
|
|
210
284
|
this.connection.on('SavedChatGet', (res) => {
|
|
211
|
-
savedChatSubject
|
|
212
|
-
savedChatSubject
|
|
285
|
+
savedChatSubject$.next(res.savedChat);
|
|
286
|
+
savedChatSubject$.complete();
|
|
213
287
|
});
|
|
214
288
|
// Invoke the method SavedChatGet
|
|
215
289
|
this.connection.invoke('SavedChatGet', data)
|
|
216
290
|
.catch(error => {
|
|
217
291
|
console.error('Error invoking SavedChatGet:', error);
|
|
218
|
-
savedChatSubject
|
|
219
|
-
return Promise.resolve();
|
|
292
|
+
savedChatSubject$.error(new Error(error));
|
|
293
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
220
294
|
});
|
|
221
|
-
return savedChatSubject
|
|
295
|
+
return savedChatSubject$.asObservable();
|
|
222
296
|
}
|
|
223
297
|
addSavedChat(messages) {
|
|
224
|
-
const addSavedChatSubject = new Subject();
|
|
298
|
+
const addSavedChatSubject$ = new Subject();
|
|
225
299
|
const data = {
|
|
226
300
|
instanceId: this.chatInstanceId,
|
|
227
301
|
savedChatId: this.chatId,
|
|
@@ -231,20 +305,20 @@ export class WebSocketChatService extends ChatService {
|
|
|
231
305
|
this.connection.on('SavedChatAdd', (res) => {
|
|
232
306
|
this.setSavedChatId(res.savedChat.id); // Persist the savedChatId
|
|
233
307
|
this.generateAuditEvent('saved-chat.add', {}, res.savedChat.id); // Generate audit event
|
|
234
|
-
addSavedChatSubject
|
|
235
|
-
addSavedChatSubject
|
|
308
|
+
addSavedChatSubject$.next(res.savedChat);
|
|
309
|
+
addSavedChatSubject$.complete();
|
|
236
310
|
});
|
|
237
311
|
// Invoke the method SavedChatAdd
|
|
238
312
|
this.connection.invoke('SavedChatAdd', data)
|
|
239
313
|
.catch(error => {
|
|
240
314
|
console.error('Error invoking SavedChatAdd:', error);
|
|
241
|
-
addSavedChatSubject
|
|
242
|
-
return Promise.resolve();
|
|
315
|
+
addSavedChatSubject$.error(new Error(error));
|
|
316
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
243
317
|
});
|
|
244
|
-
return addSavedChatSubject
|
|
318
|
+
return addSavedChatSubject$.asObservable();
|
|
245
319
|
}
|
|
246
320
|
updateSavedChat(id, name, messages) {
|
|
247
|
-
const updateSavedChatSubject = new Subject();
|
|
321
|
+
const updateSavedChatSubject$ = new Subject();
|
|
248
322
|
const data = {
|
|
249
323
|
instanceId: this.chatInstanceId,
|
|
250
324
|
savedChatId: id,
|
|
@@ -255,45 +329,64 @@ export class WebSocketChatService extends ChatService {
|
|
|
255
329
|
if (messages)
|
|
256
330
|
data["history"] = messages;
|
|
257
331
|
this.connection.on('SavedChatUpdate', (res) => {
|
|
258
|
-
updateSavedChatSubject
|
|
259
|
-
updateSavedChatSubject
|
|
332
|
+
updateSavedChatSubject$.next(res.savedChat);
|
|
333
|
+
updateSavedChatSubject$.complete();
|
|
260
334
|
});
|
|
261
335
|
// Invoke the method SavedChatUpdate
|
|
262
336
|
this.connection.invoke('SavedChatUpdate', data)
|
|
263
337
|
.catch(error => {
|
|
264
338
|
console.error('Error invoking SavedChatUpdate:', error);
|
|
265
|
-
updateSavedChatSubject
|
|
266
|
-
return Promise.resolve();
|
|
339
|
+
updateSavedChatSubject$.error(new Error(error));
|
|
340
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
267
341
|
});
|
|
268
|
-
return updateSavedChatSubject
|
|
342
|
+
return updateSavedChatSubject$.asObservable();
|
|
269
343
|
}
|
|
270
344
|
deleteSavedChat(ids) {
|
|
271
|
-
const deleteSavedChatSubject = new Subject();
|
|
345
|
+
const deleteSavedChatSubject$ = new Subject();
|
|
272
346
|
const data = {
|
|
273
347
|
instanceId: this.chatInstanceId,
|
|
274
348
|
SavedChatIds: ids,
|
|
275
349
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
276
350
|
};
|
|
277
351
|
this.connection.on('SavedChatDelete', (res) => {
|
|
278
|
-
deleteSavedChatSubject
|
|
279
|
-
deleteSavedChatSubject
|
|
352
|
+
deleteSavedChatSubject$.next(res.deleteCount);
|
|
353
|
+
deleteSavedChatSubject$.complete();
|
|
280
354
|
});
|
|
281
355
|
// Invoke the method SavedChatDelete
|
|
282
356
|
this.connection.invoke('SavedChatDelete', data)
|
|
283
357
|
.catch(error => {
|
|
284
358
|
console.error('Error invoking SavedChatDelete:', error);
|
|
285
|
-
deleteSavedChatSubject
|
|
286
|
-
return Promise.resolve();
|
|
359
|
+
deleteSavedChatSubject$.error(new Error(error));
|
|
360
|
+
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection when no further error handling exists downstream
|
|
287
361
|
});
|
|
288
|
-
return deleteSavedChatSubject
|
|
362
|
+
return deleteSavedChatSubject$.asObservable();
|
|
289
363
|
}
|
|
290
364
|
/**
|
|
291
365
|
* Initialize out-of-the-box handlers
|
|
292
|
-
* It is a placeholder for non-streaming scenarios, where you invoke a specific hub method, and the server responds with
|
|
366
|
+
* It is a placeholder for non-streaming scenarios, where you invoke a specific hub method, and the server responds with frame message(s)
|
|
293
367
|
*/
|
|
294
368
|
initMessageHandlers() {
|
|
295
|
-
this.addMessageHandler("
|
|
296
|
-
|
|
369
|
+
this.addMessageHandler("Error", {
|
|
370
|
+
handler: (error) => {
|
|
371
|
+
console.error(error);
|
|
372
|
+
this.notificationsService.error(error);
|
|
373
|
+
},
|
|
374
|
+
isGlobalHandler: true
|
|
375
|
+
});
|
|
376
|
+
this.addMessageHandler("Quota", {
|
|
377
|
+
handler: (message) => {
|
|
378
|
+
try {
|
|
379
|
+
this.updateQuota(message.quota);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
console.error(error);
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
isGlobalHandler: true
|
|
386
|
+
});
|
|
387
|
+
this.addMessageHandler("Debug", { handler: () => { },
|
|
388
|
+
isGlobalHandler: true
|
|
389
|
+
});
|
|
297
390
|
this.addMessageHandler("ActionStart", { handler: (action) => this._actionMap.set(action.guid, action),
|
|
298
391
|
isGlobalHandler: false });
|
|
299
392
|
this.addMessageHandler("ActionResult", {
|
|
@@ -309,35 +402,48 @@ export class WebSocketChatService extends ChatService {
|
|
|
309
402
|
isGlobalHandler: false
|
|
310
403
|
});
|
|
311
404
|
this.addMessageHandler("Message", {
|
|
312
|
-
handler: (message) => this.
|
|
405
|
+
handler: (message) => this._response.at(-1).content += message ?? "",
|
|
313
406
|
isGlobalHandler: false
|
|
314
407
|
});
|
|
315
408
|
this.addMessageHandler("History", {
|
|
316
409
|
handler: (history) => {
|
|
317
|
-
|
|
318
|
-
//
|
|
319
|
-
this.chatHistory
|
|
320
|
-
|
|
321
|
-
this.chatHistory.at(-1).additionalProperties.$suggestedAction = this._suggestedActions;
|
|
322
|
-
this.chatHistory.at(-1).additionalProperties.$debug = this._debugMessages;
|
|
323
|
-
// Emit the updated chat usage metrics once the generation of the assistant response is completed
|
|
410
|
+
// The ChatHistory is updated: it is the current copy concatenated with the new items ONLY (it can have multiple messages: the context messages + the response message)
|
|
411
|
+
// This is mandatory to not lose the previous updates of the chatHistory when the assistant is streaming multiple message steps
|
|
412
|
+
this.chatHistory = [...this.chatHistory, ...(history.history.slice(this.chatHistory.length))];
|
|
413
|
+
// Emit the updated chat usage metrics
|
|
324
414
|
if (!!this.chatHistory.at(-1)?.additionalProperties.usageMetrics) {
|
|
325
415
|
this.updateChatUsageMetrics(this.chatHistory.at(-1).additionalProperties.usageMetrics);
|
|
326
416
|
}
|
|
327
|
-
// Save/update the chat if savedChat enabled
|
|
328
|
-
if (this.chatConfig$.value.savedChatSettings.enabled && this.chatHistory.some((msg) => msg.additionalProperties?.isUserInput === true)) {
|
|
329
|
-
const action = !this.savedChatId ? this.addSavedChat(this.chatHistory) : this.updateSavedChat(this.savedChatId, undefined, this.chatHistory);
|
|
330
|
-
action.pipe(take(1)).subscribe();
|
|
331
|
-
}
|
|
332
417
|
this._executionTime = history.executionTime;
|
|
418
|
+
},
|
|
419
|
+
isGlobalHandler: false
|
|
420
|
+
});
|
|
421
|
+
this.addMessageHandler("SuggestedActions", {
|
|
422
|
+
handler: (message) => {
|
|
423
|
+
// Since after the "History" and "MessageBreak" that this event is caught,
|
|
424
|
+
// $suggestedAction needs to be updated directly to the last visible "assistant" message in the _response and the chatHistory
|
|
425
|
+
this._response.at(-1).additionalProperties.$suggestedAction = (this._response.at(-1).additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
|
|
426
|
+
const index = this.lastVisibleAssistantMessageIndex(this.chatHistory);
|
|
427
|
+
if (index !== -1) {
|
|
428
|
+
this.chatHistory[index].additionalProperties.$suggestedAction = (this.chatHistory[index].additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
|
|
429
|
+
}
|
|
430
|
+
},
|
|
431
|
+
isGlobalHandler: false
|
|
432
|
+
});
|
|
433
|
+
this.addMessageHandler("DebugDisplay", {
|
|
434
|
+
handler: (message) => this._debugMessages = this._debugMessages.concat(message),
|
|
435
|
+
isGlobalHandler: false
|
|
436
|
+
});
|
|
437
|
+
this.addMessageHandler("MessageBreak", {
|
|
438
|
+
handler: () => {
|
|
333
439
|
// Generate audit event
|
|
334
440
|
const details = {
|
|
335
441
|
'duration': this._executionTime,
|
|
336
442
|
'text': this.chatHistory.at(-1).content,
|
|
337
443
|
'role': this.chatHistory.at(-1).role,
|
|
338
444
|
'rank': this.chatHistory.length - 1,
|
|
339
|
-
'generation-tokencount': this.chatHistory.at(-1).additionalProperties.usageMetrics
|
|
340
|
-
'prompt-tokencount': this.chatHistory.at(-1).additionalProperties.usageMetrics
|
|
445
|
+
'generation-tokencount': this.chatHistory.at(-1).additionalProperties.usageMetrics?.completionTokenCount,
|
|
446
|
+
'prompt-tokencount': this.chatHistory.at(-1).additionalProperties.usageMetrics?.promptTokenCount,
|
|
341
447
|
'attachments': JSON.stringify(this._attachments.map(({ recordId, contextId, parts, type }) => ({
|
|
342
448
|
recordId,
|
|
343
449
|
contextId,
|
|
@@ -346,31 +452,13 @@ export class WebSocketChatService extends ChatService {
|
|
|
346
452
|
})))
|
|
347
453
|
};
|
|
348
454
|
this.generateAuditEvent('message', details);
|
|
455
|
+
// Push a new assistant message to the _response array ONLY if the content of the last message is not empty
|
|
456
|
+
if (this._response.at(-1).content !== "") {
|
|
457
|
+
this._response.push({ role: "assistant", content: "", additionalProperties: { display: true } });
|
|
458
|
+
}
|
|
349
459
|
},
|
|
350
460
|
isGlobalHandler: false
|
|
351
461
|
});
|
|
352
|
-
this.addMessageHandler("Error", {
|
|
353
|
-
handler: (error) => {
|
|
354
|
-
console.error(error);
|
|
355
|
-
this.notificationsService.error(error);
|
|
356
|
-
},
|
|
357
|
-
isGlobalHandler: true
|
|
358
|
-
});
|
|
359
|
-
this.addMessageHandler("Quota", {
|
|
360
|
-
handler: (message) => this.updateQuota(message.quota),
|
|
361
|
-
isGlobalHandler: true
|
|
362
|
-
});
|
|
363
|
-
this.addMessageHandler("SuggestedActions", {
|
|
364
|
-
handler: (message) => {
|
|
365
|
-
// Suggested actions are concatenated to the existing ones in case of multiple events "SuggestedActions"
|
|
366
|
-
this._suggestedActions = this._suggestedActions.concat(message.suggestedActions);
|
|
367
|
-
},
|
|
368
|
-
isGlobalHandler: false
|
|
369
|
-
});
|
|
370
|
-
this.addMessageHandler("DebugDisplay", {
|
|
371
|
-
handler: (message) => this._debugMessages = this._debugMessages ? this._debugMessages.concat(message) : [message],
|
|
372
|
-
isGlobalHandler: false
|
|
373
|
-
});
|
|
374
462
|
}
|
|
375
463
|
/**
|
|
376
464
|
* Override and register the entire _messageHandlers map by merging the provided map with the default one
|
|
@@ -385,7 +473,7 @@ export class WebSocketChatService extends ChatService {
|
|
|
385
473
|
});
|
|
386
474
|
// Merge the new event handlers with the existing ones
|
|
387
475
|
this._messageHandlers = new Map([...this._messageHandlers, ..._messageHandlers]);
|
|
388
|
-
// Register the global
|
|
476
|
+
// Register the global handlers among the merged map
|
|
389
477
|
this._messageHandlers.forEach((eventHandler, eventName) => {
|
|
390
478
|
if (eventHandler.isGlobalHandler) {
|
|
391
479
|
this.registerMessageHandler(eventName, eventHandler);
|
|
@@ -395,7 +483,7 @@ export class WebSocketChatService extends ChatService {
|
|
|
395
483
|
/**
|
|
396
484
|
* Add a listener for a specific event.
|
|
397
485
|
* If a listener for this same event already exists, it will be overridden.
|
|
398
|
-
* If the listener has "
|
|
486
|
+
* If the listener has "isGlobalHandler" set to true, it will be registered to the hub connection.
|
|
399
487
|
* @param eventName Name of the event to register a listener for
|
|
400
488
|
* @param eventHandler The handler to be called when the event is received
|
|
401
489
|
*/
|
|
@@ -449,8 +537,12 @@ export class WebSocketChatService extends ChatService {
|
|
|
449
537
|
reject(new Error("No endpoint provided to connect the websocket to"));
|
|
450
538
|
return;
|
|
451
539
|
}
|
|
452
|
-
const logLevel = this.
|
|
540
|
+
const logLevel = this._getLogLevel();
|
|
453
541
|
this.connection = this.signalRService.buildConnection(this.REQUEST_URL, { ...this.defaultOptions, ...options }, logLevel, true);
|
|
542
|
+
const signalRServerTimeoutInMilliseconds = this.chatConfig$.value?.connectionSettings.signalRServerTimeoutInMilliseconds;
|
|
543
|
+
if (signalRServerTimeoutInMilliseconds) {
|
|
544
|
+
this.connection.serverTimeoutInMilliseconds = signalRServerTimeoutInMilliseconds;
|
|
545
|
+
}
|
|
454
546
|
resolve();
|
|
455
547
|
});
|
|
456
548
|
}
|
|
@@ -468,7 +560,7 @@ export class WebSocketChatService extends ChatService {
|
|
|
468
560
|
stopConnection() {
|
|
469
561
|
return this.signalRService.stopConnection(this.connection);
|
|
470
562
|
}
|
|
471
|
-
|
|
563
|
+
_getTransports() {
|
|
472
564
|
switch (this.chatConfig$.value?.connectionSettings.signalRTransport) {
|
|
473
565
|
case "WebSockets":
|
|
474
566
|
return HttpTransportType.WebSockets;
|
|
@@ -480,7 +572,7 @@ export class WebSocketChatService extends ChatService {
|
|
|
480
572
|
return HttpTransportType.None;
|
|
481
573
|
}
|
|
482
574
|
}
|
|
483
|
-
|
|
575
|
+
_getLogLevel() {
|
|
484
576
|
switch (this.chatConfig$.value?.connectionSettings.signalRLogLevel) {
|
|
485
577
|
case "Critical":
|
|
486
578
|
return LogLevel.Critical; // Log level for diagnostic messages that indicate a failure that will terminate the entire application.
|
|
@@ -514,7 +606,7 @@ export class WebSocketChatService extends ChatService {
|
|
|
514
606
|
// as far as we know, signalR only lets us tweak the request with this access token factory
|
|
515
607
|
// so we pass along the Sinequa CSRF token to pass the CSRF check..
|
|
516
608
|
return {
|
|
517
|
-
transport: this.
|
|
609
|
+
transport: this._getTransports(),
|
|
518
610
|
withCredentials: true,
|
|
519
611
|
headers,
|
|
520
612
|
accessTokenFactory: () => this.authenticationService.processedCredentials?.data?.csrfToken || ""
|
|
@@ -526,4 +618,4 @@ WebSocketChatService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0",
|
|
|
526
618
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: WebSocketChatService, decorators: [{
|
|
527
619
|
type: Injectable
|
|
528
620
|
}], ctorParameters: function () { return []; } });
|
|
529
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWNoYXQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L3dlYnNvY2tldC1jaGF0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxFQUFxQixpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWxGLE9BQU8sRUFBRSxpQkFBaUIsRUFBaUIsUUFBUSxFQUFrQixNQUFNLG9CQUFvQixDQUFDO0FBRWhHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUFHMUosTUFBTSxPQUFPLG9CQUFxQixTQUFRLFdBQVc7SUFnQm5EO1FBQ0UsS0FBSyxFQUFFLENBQUM7UUFiRixxQkFBZ0IsR0FBcUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMvRCxlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7UUFDOUMsY0FBUyxHQUErQixTQUFTLENBQUM7UUFDbEQsYUFBUSxHQUFHLEVBQUUsQ0FBQztRQUVkLGlCQUFZLEdBQTRCLEVBQUUsQ0FBQztRQUMzQyxzQkFBaUIsR0FBc0IsRUFBRSxDQUFDO1FBQzFDLG1CQUFjLEdBQStCLFNBQVMsQ0FBQztRQUV4RCxtQkFBYyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzNDLDBC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WUFDbEMsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUk7WUFDakQsYUFBYSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUk7U0FDbkQsQ0FBQztRQUNGLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLG9CQUFvQixFQUFFO1lBQ25ELE9BQU8sR0FBRyxFQUFDLEdBQUcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLENBQUM7U0FDOUc7UUFBQSxDQUFDO1FBQ0YsMkVBQTJFO1FBQzNFLDJGQUEyRjtRQUMzRixtRUFBbUU7UUFDbkUsT0FBTztZQUNMLFNBQVMsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQy9CLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLE9BQU87WUFDUCxrQkFBa0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLFNBQVMsSUFBSSxFQUFFO1NBQ2pHLENBQUE7SUFDSCxDQUFDOztpSEEzbUJVLG9CQUFvQjtxSEFBcEIsb0JBQW9COzJGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQXV0aGVudGljYXRpb25TZXJ2aWNlIH0gZnJvbSBcIkBzaW5lcXVhL2NvcmUvbG9naW5cIjtcbmltcG9ydCB7IENvbm5lY3Rpb25PcHRpb25zLCBTaWduYWxSV2ViU2VydmljZSB9IGZyb20gXCJAc2luZXF1YS9jb3JlL3dlYi1zZXJ2aWNlc1wiO1xuaW1wb3J0IHsgUXVlcnkgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS9hcHAtdXRpbHNcIjtcbmltcG9ydCB7IEh0dHBUcmFuc3BvcnRUeXBlLCBIdWJDb25uZWN0aW9uLCBMb2dMZXZlbCwgTWVzc2FnZUhlYWRlcnMgfSBmcm9tIFwiQG1pY3Jvc29mdC9zaWduYWxyXCI7XG5pbXBvcnQgeyBBY3Rpb25NZXNzYWdlLCBBY3Rpb25SZXN1bHRFdmVudCwgQWN0aW9uU3RhcnRFdmVudCwgQWN0aW9uU3RvcEV2ZW50LCBNZXNzYWdlRXZlbnQsIENoYXRNZXNzYWdlLCBDaGF0UGF5bG9hZCwgQ2hhdFJlc3BvbnNlLCBHbGxtRnVuY3Rpb24sIEdsbG1Nb2RlbERlc2NyaXB0aW9uLCBNZXNzYWdlSGFuZGxlciwgSGlzdG9yeUV2ZW50LCBFcnJvckV2ZW50LCBRdW90YUV2ZW50LCBDaGF0Q29udGV4dEF0dGFjaG1lbnQsIENvbnRleHRNZXNzYWdlRXZlbnQsIFNhdmVkQ2hhdEhpc3RvcnksIFNhdmVkQ2hhdCwgQ2hhdFByb2dyZXNzLCBTdWdnZXN0ZWRBY3Rpb25zRXZlbnQsIFN1Z2dlc3RlZEFjdGlvbiwgRGVidWdNZXNzYWdlRXZlbnQsIERlYnVnTWVzc2FnZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBDaGF0U2VydmljZSB9IGZyb20gXCIuL2NoYXQuc2VydmljZVwiO1xuaW1wb3J0IHsgbWVyZ2UsIGZyb21FdmVudCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgY2F0Y2hFcnJvciwgZmlsdGVyLCBmb3JrSm9pbiwgbWFwLCBzaGFyZVJlcGxheSwgc3dpdGNoTWFwLCB0YXAsIHRocm93RXJyb3IsIHRha2VVbnRpbCwgdGFrZSB9IGZyb20gXCJyeGpzXCI7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBXZWJTb2NrZXRDaGF0U2VydmljZSBleHRlbmRzIENoYXRTZXJ2aWNlIHtcblxuICBwdWJsaWMgY29ubmVjdGlvbjogSHViQ29ubmVjdGlvbiB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIF9tZXNzYWdlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIE1lc3NhZ2VIYW5kbGVyPGFueT4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIF9hY3Rpb25NYXAgPSBuZXcgTWFwPHN0cmluZywgQWN0aW9uTWVzc2FnZT4oKTtcbiAgcHJpdmF0ZSBfcHJvZ3Jlc3M6IENoYXRQcm9ncmVzc1tdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBwcml2YXRlIF9jb250ZW50ID0gXCJcIjtcbiAgcHJpdmF0ZSBfZXhlY3V0aW9uVGltZTogc3RyaW5nO1xuICBwcml2YXRlIF9hdHRhY2htZW50czogQ2hhdENvbnRleHRBdHRhY2htZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBfc3VnZ2VzdGVkQWN0aW9uczogU3VnZ2VzdGVkQWN0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBfZGVidWdNZXNzYWdlczogRGVidWdNZXNzYWdlW10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgcHVibGljIHNpZ25hbFJTZXJ2aWNlID0gaW5qZWN0KFNpZ25hbFJXZWJTZXJ2aWNlKTtcbiAgcHVibGljIGF1dGhlbnRpY2F0aW9uU2VydmljZSA9IGluamVjdChBdXRoZW50aWNhdGlvblNlcnZpY2UpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgY2hhdCBwcm9jZXNzIGFmdGVyIHRoZSBsb2dpbiBpcyBjb21wbGV0ZS5cbiAgICogSXQgaW5jbHVkZXMgYnVpbGRpbmcgYW5kIHN0YXJ0aW5nIGEgY29ubmVjdGlvbiwgZXhlY3V0aW5nIHBhcmFsbGVsIHJlcXVlc3RzIGZvciBtb2RlbHMgYW5kIGZ1bmN0aW9ucywgYW5kIGhhbmRsaW5nIGVycm9ycyBkdXJpbmcgdGhlIHByb2Nlc3MuXG4gICAqXG4gICAqIEByZXR1cm5zIEFuIE9ic2VydmFibGU8Ym9vbGVhbj4gaW5kaWNhdGluZyB0aGUgc3VjY2VzcyBvZiB0aGUgaW5pdGlhbGl6YXRpb24gcHJvY2Vzcy5cbiAgICovXG4gIGluaXQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMubG9naW5TZXJ2aWNlLmV2ZW50cy5waXBlKFxuICAgICAgZmlsdGVyKChlKSA9PiBlLnR5cGUgPT09ICdsb2dpbi1jb21wbGV0ZScpLFxuICAgICAgdGFwKCgpID0+IHRoaXMuZ2V0UmVxdWVzdHNVcmwoKSksXG4gICAgICAvLyBCdWlsZCB0aGUgY29ubmVjdGlvblxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuYnVpbGRDb25uZWN0aW9uKCkpLFxuICAgICAgdGFwKCgpID0+IHRoaXMuaW5pdE1lc3NhZ2VIYW5kbGVycygpKSxcbiAgICAgIC8vIFN0YXJ0IHRoZSBjb25uZWN0aW9uXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5zdGFydENvbm5lY3Rpb24oKSksXG4gICAgICAvLyBFeGVjdXRlIHBhcmFsbGVsIHJlcXVlc3RzIGZvciBtb2RlbHMgYW5kIGZ1bmN0aW9uc1xuICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKFtcbiAgICAgICAgICB0aGlzLmxpc3RNb2RlbHMoKSxcbiAgICAgICAgICB0aGlzLmxpc3RGdW5jdGlvbnMoKVxuICAgICAgICBdKVxuICAgICAgfSksXG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgb2YgcGFyYWxsZWwgcmVxdWVzdHMgdG8gYSBib29sZWFuIGluZGljYXRpbmcgc3VjY2Vzc1xuICAgICAgbWFwKChbbW9kZWxzLCBmdW5jdGlvbnNdKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9ICEhbW9kZWxzICYmICEhZnVuY3Rpb25zO1xuICAgICAgICB0aGlzLmluaXRQcm9jZXNzJC5uZXh0KHJlc3VsdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KSxcbiAgICAgIC8vIEFueSBlcnJvcnMgZHVyaW5nIHRoZSBwcm9jZXNzIGFyZSBjYXVnaHQsIGxvZ2dlZCwgYW5kIHJlLXRocm93biB0byBwcm9wYWdhdGUgdGhlIGVycm9yIGZ1cnRoZXJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkOicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgfSksXG4gICAgICAvLyBDYWNoZSBhbmQgcmVwbGF5IHRoZSBlbWl0dGVkIHZhbHVlIGZvciBzdWJzZXF1ZW50IHN1YnNjcmliZXJzXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lIHRoZSBhc3Npc3RhbnQgZW5kcG9pbnQgdG8gdXNlIGZvciB0aGUgd2Vic29ja2V0IHJlcXVlc3RzXG4gICAqIEl0IGNhbiBiZSBvdmVycmlkZGVuIGJ5IHRoZSBhcHAgY29uZmlnXG4gICAqL1xuICBnZXRSZXF1ZXN0c1VybCgpIHtcbiAgICBpZiAodGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLndlYnNvY2tldEVuZHBvaW50KSB7XG4gICAgICB0aGlzLlJFUVVFU1RfVVJMID0gdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLndlYnNvY2tldEVuZHBvaW50O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBwcm9wZXJ0eSAnd2Vic29ja2V0RW5kcG9pbnQnIG11c3QgYmUgcHJvdmlkZWQgd2hlbiBhdHRlbXB0aW5nIHRvIHVzZSAnV2ViU29ja2V0JyBpbiBhc3Npc3RhbnQgaW5zdGFuY2VgKTtcbiAgICB9XG4gIH1cblxuICBsaXN0TW9kZWxzKCk6IE9ic2VydmFibGU8R2xsbU1vZGVsRGVzY3JpcHRpb25bXSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IG1vZGVsc1N1YmplY3QgPSBuZXcgU3ViamVjdDxHbGxtTW9kZWxEZXNjcmlwdGlvbltdIHwgdW5kZWZpbmVkPigpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignTGlzdE1vZGVscycsIChyZXMpID0+IHtcbiAgICAgIHRoaXMubW9kZWxzID0gKHJlcy5tb2RlbHMgYXMgR2xsbU1vZGVsRGVzY3JpcHRpb25bXSB8IHVuZGVmaW5lZCk/LmZpbHRlcihtb2RlbCA9PiAhIW1vZGVsLmVuYWJsZSk7XG4gICAgICBtb2RlbHNTdWJqZWN0Lm5leHQodGhpcy5tb2RlbHMpO1xuICAgICAgbW9kZWxzU3ViamVjdC5jb21wbGV0ZSgpXG4gICAgfSk7XG5cbiAgICAvLyBTZW5kIHRoZSByZXF1ZXN0IHRvIGdldCB0aGUgbGlzdCBvZiBtb2RlbHNcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnTGlzdE1vZGVscycsIHsgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWcgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIExpc3RNb2RlbHM6JywgZXJyb3IpO1xuICAgICAgICBtb2RlbHNTdWJqZWN0LmNvbXBsZXRlKClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpOyAvLyBSZXR1cm4gYSByZXNvbHZlZCBwcm9taXNlIHRvIGhhbmRsZSB0aGUgZXJyb3IgYW5kIHByZXZlbnQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uXG4gICAgICB9KVxuXG4gICAgcmV0dXJuIG1vZGVsc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBsaXN0RnVuY3Rpb25zKCk6IE9ic2VydmFibGU8R2xsbUZ1bmN0aW9uW10gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmdW5jdGlvbnNTdWJqZWN0ID0gbmV3IFN1YmplY3Q8R2xsbUZ1bmN0aW9uW10gfCB1bmRlZmluZWQ+KCk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24hLm9uKCdMaXN0RnVuY3Rpb25zJywgKHJlcykgPT4ge1xuICAgICAgdGhpcy5mdW5jdGlvbnMgPSAocmVzLmZ1bmN0aW9ucyBhcyBHbGxtRnVuY3Rpb25bXSB8IHVuZGVmaW5lZCk/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCk7XG4gICAgICBmdW5jdGlvbnNTdWJqZWN0Lm5leHQodGhpcy5mdW5jdGlvbnMpO1xuICAgICAgZnVuY3Rpb25zU3ViamVjdC5jb21wbGV0ZSgpXG4gICAgfSk7XG5cbiAgICAvLyBTZW5kIHRoZSByZXF1ZXN0IHRvIGdldCB0aGUgbGlzdCBvZiBmdW5jdGlvbnNcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnTGlzdEZ1bmN0aW9ucycsIHsgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWcgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIExpc3RGdW5jdGlvbnM6JywgZXJyb3IpO1xuICAgICAgICBmdW5jdGlvbnNTdWJqZWN0LmNvbXBsZXRlKClcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpOyAvLyBSZXR1cm4gYSByZXNvbHZlZCBwcm9taXNlIHRvIGhhbmRsZSB0aGUgZXJyb3IgYW5kIHByZXZlbnQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uXG4gICAgICB9KVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSwgcXVlcnk6IFF1ZXJ5KTogT2JzZXJ2YWJsZTxDaGF0UmVzcG9uc2U+IHtcbiAgICAvLyBTdGFydCBzdHJlYW1pbmcgYnkgaW52b2tpbmcgdGhlIENoYXQgbWV0aG9kXG4gICAgdGhpcy5zdHJlYW1pbmckLm5leHQodHJ1ZSk7XG5cbiAgICAvLyBQcmVwYXJlIHRoZSBwYXlsb2FkIHRvIHNlbmQgdG8gdGhlIENoYXQgbWV0aG9kXG4gICAgY29uc3QgZGF0YTogQ2hhdFBheWxvYWQgPSB7XG4gICAgICBoaXN0b3J5OiBtZXNzYWdlcyxcbiAgICAgIGZ1bmN0aW9uczogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5mdW5jdGlvbnM/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCkubWFwKGZ1bmMgPT4gZnVuYy5uYW1lKSxcbiAgICAgIGRlYnVnOiB0aGlzLmNoYXRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmRlYnVnLFxuICAgICAgc2VydmljZVNldHRpbmdzOiB7XG4gICAgICAgIHNlcnZpY2VfaWQ6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuc2VydmljZV9pZCxcbiAgICAgICAgbW9kZWxfaWQ6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMubW9kZWxfaWQsXG4gICAgICAgIHRvcF9wOiB0aGlzLmNoYXRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLnRvcF9wLFxuICAgICAgICB0ZW1wZXJhdHVyZTogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy50ZW1wZXJhdHVyZSxcbiAgICAgICAgbWF4X3Rva2VuczogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5tYXhfdG9rZW5zLFxuICAgICAgICAuLi50aGlzLmNoYXRDb25maWckLnZhbHVlIS5hZGRpdGlvbmFsU2VydmljZVNldHRpbmdzXG4gICAgICB9LFxuICAgICAgYXBwUXVlcnk6IHtcbiAgICAgICAgYXBwOiB0aGlzLmFwcFNlcnZpY2UuYXBwTmFtZSxcbiAgICAgICAgcXVlcnlcbiAgICAgIH0sXG4gICAgICBnZW5lcmljQ2hhdEVycm9yTWVzc2FnZTogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZ2xvYmFsU2V0dGluZ3MuZ2VuZXJpY0NoYXRFcnJvck1lc3NhZ2VcbiAgICB9XG4gICAgaWYgKHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLnNhdmVkQ2hhdFNldHRpbmdzLmVuYWJsZWQpIHtcbiAgICAgIGRhdGEuaW5zdGFuY2VJZCA9IHRoaXMuY2hhdEluc3RhbmNlSWQ7XG4gICAgICBkYXRhLnNhdmVkQ2hhdElkID0gdGhpcy5zYXZlZENoYXRJZDtcbiAgICB9XG5cbiAgICBsZXQgcmVzcG9uc2U6IENoYXRNZXNzYWdlID0ge3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZX19OyAvLyBoZXJlIGRpc3BsYXk6IHRydWUgaXMgbmVlZGVkIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gc2hvdyB0aGUgcHJvZ3Jlc3NcblxuICAgIC8vIENyZWF0ZSBhIFN1YmplY3QgdG8gc2lnbmFsIGNvbXBsZXRpb25cbiAgICBjb25zdCBjb21wbGV0aW9uJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICAvLyBDcmVhdGUgb2JzZXJ2YWJsZXMgZm9yIGVhY2ggbm9uLWdsb2JhbCBoYW5kbGVyIGluIHRoZSBfbWVzc2FnZUhhbmRsZXJzIG1hcCAoZGVmYXVsdCBhbmQgZXZlbnR1YWwgY3VzdG9tIG9uZXMpIG9uY2UgaXQgaXMgdHJpZ2dlcmVkIGJ5IHRoZSBodWIgY29ubmVjdGlvblxuICAgIGNvbnN0IG9ic2VydmFibGVzID0gQXJyYXlcbiAgICAgIC5mcm9tKHRoaXMuX21lc3NhZ2VIYW5kbGVycy5lbnRyaWVzKCkpXG4gICAgICAuZmlsdGVyKChbZXZlbnROYW1lLCBldmVudEhhbmRsZXJdKSA9PiAhZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcilcbiAgICAgIC5tYXAoKFtldmVudE5hbWUsIGV2ZW50SGFuZGxlcl0pID0+IHtcbiAgICAgICAgcmV0dXJuIGZyb21FdmVudDxhbnk+KHRoaXMuY29ubmVjdGlvbiEsIGV2ZW50TmFtZSkucGlwZShcbiAgICAgICAgICBtYXAoKGV2ZW50KSA9PiBldmVudEhhbmRsZXIuaGFuZGxlcihldmVudCkpIC8vIEV4ZWN1dGUgdGhlIGNvcnJlc3BvbmRpbmcgaGFuZGxlclxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAvLyBUaGVuIG1lcmdlIHRoZW0gaW50byBhIHNpbmdsZSBvYnNlcnZhYmxlIGluIG9yZGVyIHRvIHNpbXVsYXRlIHRoZSBzdHJlYW1pbmcgYmVoYXZpb3JcbiAgICBjb25zdCBjb21iaW5lZCQgPSBtZXJnZSguLi5vYnNlcnZhYmxlcykucGlwZShcbiAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgIC8vIERlZmluZSAkcHJvZ3Jlc3MgZnJvbSB0aGUgX2FjdGlvbk1hcFxuICAgICAgICBjb25zdCBhY3Rpb25zID0gQXJyYXkuZnJvbSh0aGlzLl9hY3Rpb25NYXAudmFsdWVzKCkpO1xuICAgICAgICB0aGlzLl9wcm9ncmVzcyA9IGFjdGlvbnMubGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFjdGlvbnMubWFwKChhKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogYS5kaXNwbGF5TmFtZSA/PyBcIlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBhLmRpc3BsYXlWYWx1ZSA/PyBcIlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lOiBhLmV4ZWN1dGlvblRpbWUgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZTogYS5leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIEFzIHNvb24gYXMgdGhlIGZpcnN0IF9jb250ZW50LCAkcHJvZ3Jlc3MsIF9hdHRhY2htZW50cyBvciBfX3N1Z2dlc3RlZEFjdGlvbnMgaXMgZGVmaW5lZCBhbmQgbm90IGVtcHR5LCB0aGUgYXNzaXN0YW50IGlzIGNvbnNpZGVyZWQgYXMgc3RyZWFtaW5nXG4gICAgICAgIGlmKCEhdGhpcy5fY29udGVudCB8fCB0aGlzLl9wcm9ncmVzcyB8fCB0aGlzLl9hdHRhY2htZW50cy5sZW5ndGggPiAwIHx8IHRoaXMuX3N1Z2dlc3RlZEFjdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJlc3BvbnNlID0gey4uLnJlc3BvbnNlLCBjb250ZW50OiB0aGlzLl9jb250ZW50LCBhZGRpdGlvbmFsUHJvcGVydGllczogey4uLnJlc3BvbnNlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLCAkcHJvZ3Jlc3M6IHRoaXMuX3Byb2dyZXNzLCAkYXR0YWNobWVudDogdGhpcy5fYXR0YWNobWVudHMsICRzdWdnZXN0ZWRBY3Rpb246IHRoaXMuX3N1Z2dlc3RlZEFjdGlvbnMsICRkZWJ1ZzogdGhpcy5fZGVidWdNZXNzYWdlc319O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmV0dXJuIHRoZSByZXN1bHRcbiAgICAgICAgcmV0dXJuIHsgaGlzdG9yeTogWy4uLm1lc3NhZ2VzLCByZXNwb25zZV0sIGV4ZWN1dGlvblRpbWU6IHRoaXMuX2V4ZWN1dGlvblRpbWUgfTtcbiAgICAgIH0pLFxuICAgICAgdGFrZVVudGlsKGNvbXBsZXRpb24kKSwgLy8gQ29tcGxldGUgdGhlIG9ic2VydmFibGUgd2hlbiBjb21wbGV0aW9uJCBlbWl0c1xuICAgICk7XG5cbiAgICAvLyByZXR1cm4gYSBuZXcgT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSByZXN1bHQgb2YgdGhlIGNvbWJpbmVkIHN0cmVhbSBhbmQgaGFuZGxlcyB0aGUgZXZlbnR1YWwgZXJyb3JzIG9mIHRoZSBpbnZvY2F0aW9uIG9mIHRoZSBDaGF0IG1ldGhvZFxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgICAvLyBTdWJzY3JpYmUgdG8gY29tYmluZWQgc3RyZWFtXG4gICAgICBjb21iaW5lZCQuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHZhbHVlKSA9PiBvYnNlcnZlci5uZXh0KHZhbHVlKSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IG9ic2VydmVyLmVycm9yKGVyciksXG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiBvYnNlcnZlci5jb21wbGV0ZSgpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIEludm9rZSB0aGUgQ2hhdCBtZXRob2QgYW5kIGhhbmRsZSBlcnJvcnNcbiAgICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdDaGF0JywgZGF0YSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbnZva2luZyBDaGF0OicsIGVycm9yKTtcbiAgICAgICAgICAvLyBFbWl0IHRoZSBlcnJvciB0byB0aGUgbmV3bHkgY3JlYXRlZCBvYnNlcnZhYmxlXG4gICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIC8vIFJldHVybiBhIHJlc29sdmVkIHByb21pc2UgdG8gaGFuZGxlIHRoZSBlcnJvciBhbmQgcHJldmVudCB1bmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb25cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICB0aGlzLnN0cmVhbWluZyQubmV4dChmYWxzZSk7IC8vIENvbXBsZXRlIHN0cmVhbWluZyByZWdhcmRsZXNzIG9mIHN1Y2Nlc3Mgb3IgZXJyb3JcbiAgICAgICAgICB0aGlzLl9hY3Rpb25NYXAuY2xlYXIoKTsgLy8gQ2xlYXIgdGhlIF9hY3Rpb25NYXBcbiAgICAgICAgICB0aGlzLl9jb250ZW50ID0gXCJcIjsgLy8gQ2xlYXIgdGhlIF9jb250ZW50XG4gICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSB1bmRlZmluZWQ7IC8vIENsZWFyIHRoZSBfcHJvZ3Jlc3NcbiAgICAgICAgICB0aGlzLl9hdHRhY2htZW50cyA9IFtdOyAvLyBDbGVhciB0aGUgX2F0dGFjaG1lbnRzXG4gICAgICAgICAgdGhpcy5fc3VnZ2VzdGVkQWN0aW9ucyA9IFtdOyAvLyBDbGVhciB0aGUgX3N1Z2dlc3RlZEFjdGlvbnNcbiAgICAgICAgICB0aGlzLl9kZWJ1Z01lc3NhZ2VzID0gW107IC8vIENsZWFyIHRoZSBfZGVidWdNZXNzYWdlc1xuICAgICAgICAgIHRoaXMuX2V4ZWN1dGlvblRpbWUgPSBcIlwiOyAvLyBDbGVhciB0aGUgX2V4ZWN1dGlvblRpbWVcbiAgICAgICAgICBjb21wbGV0aW9uJC5uZXh0KCk7IC8vIEVtaXQgYSBzaWduYWwgdG8gY29tcGxldGUgdGhlIG9ic2VydmFibGVzXG4gICAgICAgICAgY29tcGxldGlvbiQuY29tcGxldGUoKTsgLy8gQ29tcGxldGUgdGhlIHN1YmplY3RcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBsaXN0U2F2ZWRDaGF0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0TGlzdCcsIChyZXMpID0+IHtcbiAgICAgIHRoaXMuc2F2ZWRDaGF0cyQubmV4dChyZXMuc2F2ZWRDaGF0cyk7IC8vIGVtaXRzIHRoZSByZXN1bHQgdG8gdGhlIHNhdmVkQ2hhdHMkIHN1YmplY3RcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdExpc3RcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnU2F2ZWRDaGF0TGlzdCcsIGRhdGEpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbnZva2luZyBTYXZlZENoYXRMaXN0OicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRTYXZlZENoYXQoaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8U2F2ZWRDaGF0SGlzdG9yeSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHNhdmVkQ2hhdFN1YmplY3QgPSBuZXcgU3ViamVjdDxTYXZlZENoYXRIaXN0b3J5IHwgdW5kZWZpbmVkPigpO1xuXG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogaWQsXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24hLm9uKCdTYXZlZENoYXRHZXQnLCAocmVzKSA9PiB7XG4gICAgICBzYXZlZENoYXRTdWJqZWN0Lm5leHQocmVzLnNhdmVkQ2hhdCk7XG4gICAgICBzYXZlZENoYXRTdWJqZWN0LmNvbXBsZXRlKClcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdEdldFxuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdTYXZlZENoYXRHZXQnLCBkYXRhKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgU2F2ZWRDaGF0R2V0OicsIGVycm9yKTtcbiAgICAgICAgc2F2ZWRDaGF0U3ViamVjdC5jb21wbGV0ZSgpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pXG5cbiAgICByZXR1cm4gc2F2ZWRDaGF0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIGFkZFNhdmVkQ2hhdChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSk6IE9ic2VydmFibGU8U2F2ZWRDaGF0PiB7XG4gICAgY29uc3QgYWRkU2F2ZWRDaGF0U3ViamVjdCA9IG5ldyBTdWJqZWN0PFNhdmVkQ2hhdD4oKTtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgc2F2ZWRDaGF0SWQ6IHRoaXMuY2hhdElkLFxuICAgICAgaGlzdG9yeTogbWVzc2FnZXMsXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24hLm9uKCdTYXZlZENoYXRBZGQnLCAocmVzKSA9PiB7XG4gICAgICB0aGlzLnNldFNhdmVkQ2hhdElkKHJlcy5zYXZlZENoYXQuaWQpOyAvLyBQZXJzaXN0IHRoZSBzYXZlZENoYXRJZFxuICAgICAgdGhpcy5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ3NhdmVkLWNoYXQuYWRkJywge30sIHJlcy5zYXZlZENoYXQuaWQpOyAvLyBHZW5lcmF0ZSBhdWRpdCBldmVudFxuICAgICAgYWRkU2F2ZWRDaGF0U3ViamVjdC5uZXh0KHJlcy5zYXZlZENoYXQpO1xuICAgICAgYWRkU2F2ZWRDaGF0U3ViamVjdC5jb21wbGV0ZSgpXG4gICAgfSk7XG5cbiAgICAvLyBJbnZva2UgdGhlIG1ldGhvZCBTYXZlZENoYXRBZGRcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnU2F2ZWRDaGF0QWRkJywgZGF0YSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIFNhdmVkQ2hhdEFkZDonLCBlcnJvcik7XG4gICAgICAgIGFkZFNhdmVkQ2hhdFN1YmplY3QuY29tcGxldGUoKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KVxuXG4gICAgcmV0dXJuIGFkZFNhdmVkQ2hhdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICB1cGRhdGVTYXZlZENoYXQoaWQ6IHN0cmluZywgbmFtZT86IHN0cmluZywgbWVzc2FnZXM/OiBDaGF0TWVzc2FnZVtdKTogT2JzZXJ2YWJsZTxTYXZlZENoYXQ+IHtcbiAgICBjb25zdCB1cGRhdGVTYXZlZENoYXRTdWJqZWN0ID0gbmV3IFN1YmplY3Q8U2F2ZWRDaGF0PigpO1xuXG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogaWQsXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICBpZihuYW1lKSBkYXRhW1widGl0bGVcIl0gPSBuYW1lO1xuICAgIGlmKG1lc3NhZ2VzKSBkYXRhW1wiaGlzdG9yeVwiXSA9IG1lc3NhZ2VzO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0VXBkYXRlJywgKHJlcykgPT4ge1xuICAgICAgdXBkYXRlU2F2ZWRDaGF0U3ViamVjdC5uZXh0KHJlcy5zYXZlZENoYXQpO1xuICAgICAgdXBkYXRlU2F2ZWRDaGF0U3ViamVjdC5jb21wbGV0ZSgpXG4gICAgfSk7XG5cbiAgICAvLyBJbnZva2UgdGhlIG1ldGhvZCBTYXZlZENoYXRVcGRhdGVcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnU2F2ZWRDaGF0VXBkYXRlJywgZGF0YSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIFNhdmVkQ2hhdFVwZGF0ZTonLCBlcnJvcik7XG4gICAgICAgIHVwZGF0ZVNhdmVkQ2hhdFN1YmplY3QuY29tcGxldGUoKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KVxuXG4gICAgcmV0dXJuIHVwZGF0ZVNhdmVkQ2hhdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBkZWxldGVTYXZlZENoYXQoaWRzOiBzdHJpbmdbXSk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgY29uc3QgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgU2F2ZWRDaGF0SWRzOiBpZHMsXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24hLm9uKCdTYXZlZENoYXREZWxldGUnLCAocmVzKSA9PiB7XG4gICAgICBkZWxldGVTYXZlZENoYXRTdWJqZWN0Lm5leHQocmVzLmRlbGV0ZUNvdW50KTtcbiAgICAgIGRlbGV0ZVNhdmVkQ2hhdFN1YmplY3QuY29tcGxldGUoKTtcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdERlbGV0ZVxuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdTYXZlZENoYXREZWxldGUnLCBkYXRhKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgU2F2ZWRDaGF0RGVsZXRlOicsIGVycm9yKTtcbiAgICAgICAgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdC5jb21wbGV0ZSgpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KVxuXG4gICAgcmV0dXJuIGRlbGV0ZVNhdmVkQ2hhdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBvdXQtb2YtdGhlLWJveCBoYW5kbGVyc1xuICAgKiBJdCBpcyBhIHBsYWNlaG9sZGVyIGZvciBub24tc3RyZWFtaW5nIHNjZW5hcmlvcywgd2hlcmUgeW91IGludm9rZSBhIHNwZWNpZmljIGh1YiBtZXRob2QsIGFuZCB0aGUgc2VydmVyIHJlc3BvbmRzIHdpdGggYSBzaW5nbGUgbWVzc2FnZSBvciBhIHJlc3VsdFxuICAgKi9cbiAgaW5pdE1lc3NhZ2VIYW5kbGVycygpIHtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJEZWJ1Z1wiLFxuICAgICAgeyBoYW5kbGVyOiAoZGVidWc6IGFueSkgPT4gY29uc29sZS5sb2coZGVidWcpLFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IHRydWVcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIkFjdGlvblN0YXJ0XCIsXG4gICAgICB7IGhhbmRsZXI6IChhY3Rpb246IEFjdGlvblN0YXJ0RXZlbnQpID0+IHRoaXMuX2FjdGlvbk1hcC5zZXQoYWN0aW9uLmd1aWQsIGFjdGlvbiksXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIkFjdGlvblJlc3VsdFwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAoYWN0aW9uOiBBY3Rpb25SZXN1bHRFdmVudCkgPT4gdGhpcy5fYWN0aW9uTWFwLnNldChhY3Rpb24uZ3VpZCwgeyAuLi50aGlzLl9hY3Rpb25NYXAuZ2V0KGFjdGlvbi5ndWlkKSwgLi4uYWN0aW9uIH0pLFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJBY3Rpb25TdG9wXCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6IChhY3Rpb246IEFjdGlvblN0b3BFdmVudCkgPT4gdGhpcy5fYWN0aW9uTWFwLnNldChhY3Rpb24uZ3VpZCwgeyAuLi50aGlzLl9hY3Rpb25NYXAuZ2V0KGFjdGlvbi5ndWlkKSwgLi4uYWN0aW9uIH0pLFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJDb250ZXh0TWVzc2FnZVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogQ29udGV4dE1lc3NhZ2VFdmVudCkgPT4gdGhpcy5fYXR0YWNobWVudHMucHVzaChtZXNzYWdlLm1ldGFkYXRhKSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiTWVzc2FnZVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogTWVzc2FnZUV2ZW50KSA9PiB0aGlzLl9jb250ZW50ICs9IG1lc3NhZ2UgPz8gXCJcIixcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiSGlzdG9yeVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAoaGlzdG9yeTogSGlzdG9yeUV2ZW50KSA9PiB7XG4gICAgICAgICAgdGhpcy5jaGF0SGlzdG9yeSA9IGhpc3RvcnkuaGlzdG9yeTtcbiAgICAgICAgICAvLyBSZS1hdHRhY2ggdGhlIHskcHJvZ3Jlc3MsICRhdHRhY2htZW50LCAkc3VnZ2VzdGVkQWN0aW9uIGFuZCAkZGVidWd9IG9mIHRoZSBsYXN0IHJlc3BvbnNlIHRvIHRoZSBsYXN0IGFzc2lzdGFudCdzIHJlc3BvbnNlIGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICAgICAgICB0aGlzLmNoYXRIaXN0b3J5LmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzID0gdGhpcy5fcHJvZ3Jlc3M7XG4gICAgICAgICAgdGhpcy5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50ID0gdGhpcy5fYXR0YWNobWVudHM7XG4gICAgICAgICAgdGhpcy5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gPSB0aGlzLl9zdWdnZXN0ZWRBY3Rpb25zO1xuICAgICAgICAgIHRoaXMuY2hhdEhpc3RvcnkuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGVidWcgPSB0aGlzLl9kZWJ1Z01lc3NhZ2VzO1xuICAgICAgICAgIC8vIEVtaXQgdGhlIHVwZGF0ZWQgY2hhdCB1c2FnZSBtZXRyaWNzIG9uY2UgdGhlIGdlbmVyYXRpb24gb2YgdGhlIGFzc2lzdGFudCByZXNwb25zZSBpcyBjb21wbGV0ZWRcbiAgICAgICAgICBpZiAoISF0aGlzLmNoYXRIaXN0b3J5LmF0KC0xKT8uYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoYXRVc2FnZU1ldHJpY3ModGhpcy5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcyEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTYXZlL3VwZGF0ZSB0aGUgY2hhdCBpZiBzYXZlZENoYXQgZW5hYmxlZFxuICAgICAgICAgIGlmICh0aGlzLmNoYXRDb25maWckLnZhbHVlIS5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkICYmIHRoaXMuY2hhdEhpc3Rvcnkuc29tZSgobXNnKSA9PiBtc2cuYWRkaXRpb25hbFByb3BlcnRpZXM/LmlzVXNlcklucHV0ID09PSB0cnVlKSkge1xuICAgICAgICAgICAgY29uc3QgYWN0aW9uID0gIXRoaXMuc2F2ZWRDaGF0SWQgPyB0aGlzLmFkZFNhdmVkQ2hhdCh0aGlzLmNoYXRIaXN0b3J5KSA6IHRoaXMudXBkYXRlU2F2ZWRDaGF0KHRoaXMuc2F2ZWRDaGF0SWQsIHVuZGVmaW5lZCwgdGhpcy5jaGF0SGlzdG9yeSk7XG4gICAgICAgICAgICBhY3Rpb24ucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fZXhlY3V0aW9uVGltZSA9IGhpc3RvcnkuZXhlY3V0aW9uVGltZTtcbiAgICAgICAgICAvLyBHZW5lcmF0ZSBhdWRpdCBldmVudFxuICAgICAgICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAgICAgICAnZHVyYXRpb24nOiB0aGlzLl9leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgJ3RleHQnOiB0aGlzLmNoYXRIaXN0b3J5LmF0KC0xKSEuY29udGVudCxcbiAgICAgICAgICAgICdyb2xlJzogdGhpcy5jaGF0SGlzdG9yeS5hdCgtMSkhLnJvbGUsIC8vICdhc3Npc3RhbnQnXG4gICAgICAgICAgICAncmFuayc6IHRoaXMuY2hhdEhpc3RvcnkubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgICdnZW5lcmF0aW9uLXRva2VuY291bnQnOiB0aGlzLmNoYXRIaXN0b3J5LmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzIS5jb21wbGV0aW9uVG9rZW5Db3VudCxcbiAgICAgICAgICAgICdwcm9tcHQtdG9rZW5jb3VudCc6IHRoaXMuY2hhdEhpc3RvcnkuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy51c2FnZU1ldHJpY3MhLnByb21wdFRva2VuQ291bnQsXG4gICAgICAgICAgICAnYXR0YWNobWVudHMnOiBKU09OLnN0cmluZ2lmeSh0aGlzLl9hdHRhY2htZW50cy5tYXAoKHsgcmVjb3JkSWQsIGNvbnRleHRJZCwgcGFydHMsIHR5cGUgfSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNvcmRJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFydHM6IHBhcnRzLm1hcCgoeyBwYXJ0SWQsIHRleHQgfSkgPT4gKHsgcGFydElkLCB0ZXh0IH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pKSlcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRoaXMuZ2VuZXJhdGVBdWRpdEV2ZW50KCdtZXNzYWdlJywgZGV0YWlscyk7XG4gICAgICAgIH0sXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIkVycm9yXCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6IChlcnJvcjogRXJyb3JFdmVudCkgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2UuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IHRydWVcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIlF1b3RhXCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBRdW90YUV2ZW50KSA9PiB0aGlzLnVwZGF0ZVF1b3RhKG1lc3NhZ2UucXVvdGEpLFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IHRydWVcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIlN1Z2dlc3RlZEFjdGlvbnNcIixcbiAgICAgIHtcbiAgICAgICAgaGFuZGxlcjogKG1lc3NhZ2U6IFN1Z2dlc3RlZEFjdGlvbnNFdmVudCkgPT4ge1xuICAgICAgICAgIC8vIFN1Z2dlc3RlZCBhY3Rpb25zIGFyZSBjb25jYXRlbmF0ZWQgdG8gdGhlIGV4aXN0aW5nIG9uZXMgaW4gY2FzZSBvZiBtdWx0aXBsZSBldmVudHMgXCJTdWdnZXN0ZWRBY3Rpb25zXCJcbiAgICAgICAgICB0aGlzLl9zdWdnZXN0ZWRBY3Rpb25zID0gdGhpcy5fc3VnZ2VzdGVkQWN0aW9ucy5jb25jYXQobWVzc2FnZS5zdWdnZXN0ZWRBY3Rpb25zKTtcbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiRGVidWdEaXNwbGF5XCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBEZWJ1Z01lc3NhZ2VFdmVudCkgPT4gdGhpcy5fZGVidWdNZXNzYWdlcyA9IHRoaXMuX2RlYnVnTWVzc2FnZXMgPyB0aGlzLl9kZWJ1Z01lc3NhZ2VzLmNvbmNhdChtZXNzYWdlKSA6IFttZXNzYWdlXSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgYW5kIHJlZ2lzdGVyIHRoZSBlbnRpcmUgX21lc3NhZ2VIYW5kbGVycyBtYXAgYnkgbWVyZ2luZyB0aGUgcHJvdmlkZWQgbWFwIHdpdGggdGhlIGRlZmF1bHQgb25lXG4gICAqIEBwYXJhbSBfbWVzc2FnZUhhbmRsZXJzXG4gICAqL1xuICBvdmVycmlkZU1lc3NhZ2VIYW5kbGVyczxUPihfbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxUPj4pIHtcbiAgICAvLyBDbGVhciB0aGUgYWxyZWFkeSByZWdpc3RlcmVkIGdsb2JhbCBjaGF0IGhhbmRsZXJzIGJlZm9yZSBtZXJnaW5nIHRoZSBuZXcgb25lc1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5mb3JFYWNoKChldmVudEhhbmRsZXIsIGV2ZW50TmFtZSkgPT4ge1xuICAgICAgaWYoZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcikge1xuICAgICAgICB0aGlzLnVuc3Vic2NyaWJlTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIE1lcmdlIHRoZSBuZXcgZXZlbnQgaGFuZGxlcnMgd2l0aCB0aGUgZXhpc3Rpbmcgb25lc1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycyA9IG5ldyBNYXAoWy4uLnRoaXMuX21lc3NhZ2VIYW5kbGVycywgLi4uX21lc3NhZ2VIYW5kbGVyc10pO1xuXG4gICAgLy8gUmVnaXN0ZXIgdGhlIGdsb2JhbCBjaGF0IGhhbmRsZXJzIGFtb25nIHRoZSBtZXJnZWQgbWFwXG4gICAgdGhpcy5fbWVzc2FnZUhhbmRsZXJzLmZvckVhY2goKGV2ZW50SGFuZGxlciwgZXZlbnROYW1lKSA9PiB7XG4gICAgICBpZihldmVudEhhbmRsZXIuaXNHbG9iYWxIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAqIElmIGEgbGlzdGVuZXIgZm9yIHRoaXMgc2FtZSBldmVudCBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSBvdmVycmlkZGVuLlxuICAgKiBJZiB0aGUgbGlzdGVuZXIgaGFzIFwiaXNDaGF0R2xvYmFsSGFuZGxlclwiIHNldCB0byB0cnVlLCBpdCB3aWxsIGJlIHJlZ2lzdGVyZWQgdG8gdGhlIGh1YiBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0gZXZlbnROYW1lIE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yXG4gICAqIEBwYXJhbSBldmVudEhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIHJlY2VpdmVkXG4gICAqL1xuICBhZGRNZXNzYWdlSGFuZGxlcjxUPihldmVudE5hbWU6IHN0cmluZywgZXZlbnRIYW5kbGVyOiBNZXNzYWdlSGFuZGxlcjxUPikge1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIER5bmFtaWNhbGx5IHJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAqIElmIGEgbGlzdGVuZXIgZm9yIHRoaXMgZXZlbnQgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcnJpZGRlbi5cbiAgICogQHBhcmFtIGV2ZW50TmFtZSBOYW1lIG9mIHRoZSBldmVudCB0byByZWdpc3RlciBhIGxpc3RlbmVyIGZvclxuICAgKiBAcGFyYW0gZXZlbnRIYW5kbGVyIFRoZSBoYW5kbGVyIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyByZWNlaXZlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI8VD4oZXZlbnROYW1lOiBzdHJpbmcsIGV2ZW50SGFuZGxlcjogTWVzc2FnZUhhbmRsZXI8VD4pIHtcbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbikge1xuICAgICAgY29uc29sZS5sb2coXCJObyBjb25uZWN0aW9uIGZvdW5kIHRvIHJlZ2lzdGVyIHRoZSBsaXN0ZW5lclwiICsgZXZlbnROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24ub24oZXZlbnROYW1lLCAoZGF0YTogVCkgPT4ge1xuICAgICAgZXZlbnRIYW5kbGVyLmhhbmRsZXIoZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgZXZlbnQgZnJvbSB0aGUgX21lc3NhZ2VIYW5kbGVycyBtYXAgYW5kIHVuc3Vic2NyaWJlIGZyb20gcmVjZWl2aW5nIG1lc3NhZ2VzIGZvciB0aGlzIGV2ZW50IGZyb20gdGhlIFNpZ25hbFIgaHViLlxuICAgKiBAcGFyYW0gZXZlbnROYW1lIE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIgZm9yXG4gICAqL1xuICByZW1vdmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZykge1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBmcm9tIHJlY2VpdmluZyBtZXNzYWdlcyBmb3IgYSBzcGVjaWZpYyBldmVudCBmcm9tIHRoZSBTaWduYWxSIGh1Yi5cbiAgICogQUxMIGl0cyByZWxhdGVkIGxpc3RlbmVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSBodWIgY29ubmVjdGlvblxuICAgKiBUaGlzIGlzIG5lZWRlZCB0byBwcmV2ZW50IGFjY3VtdWxhdGluZyBvbGQgbGlzdGVuZXJzIHdoZW4gb3ZlcnJpZGluZyB0aGUgZW50aXJlIF9tZXNzYWdlSGFuZGxlcnMgbWFwXG4gICAqIEBwYXJhbSBldmVudE5hbWUgTmFtZSBvZiB0aGUgZXZlbnRcbiAgICovXG4gIHByb3RlY3RlZCB1bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uIS5vZmYoZXZlbnROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbm5lY3Rpb24gdG8gdGhlIHNpZ25hbFIgd2Vic29ja2V0IGFuZCByZWdpc3RlciBkZWZhdWx0IGxpc3RlbmVycyB0byB0aGUgbWV0aG9kcyBkZWZpbmVkIGluIHRoZSBzZXJ2ZXIgaHViIGNsYXNzXG4gICAqIEBwYXJhbSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciB0aGUgY29ubmVjdGlvbi4gSXQgb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IG9wdGlvbnNcbiAgICogQHBhcmFtIGxvZ0xldmVsIERlZmluZSB0aGUgbG9nIGxldmVsIGRpc3BsYXllZCBpbiB0aGUgY29uc29sZVxuICAgKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBidWlsdFxuICAgKi9cbiAgYnVpbGRDb25uZWN0aW9uKG9wdGlvbnM/OiBDb25uZWN0aW9uT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXRoaXMuUkVRVUVTVF9VUkwpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiTm8gZW5kcG9pbnQgcHJvdmlkZWQgdG8gY29ubmVjdCB0aGUgd2Vic29ja2V0IHRvXCIpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBsb2dMZXZlbCA9IHRoaXMuZ2V0TG9nTGV2ZWwoKTtcbiAgICAgIHRoaXMuY29ubmVjdGlvbiA9IHRoaXMuc2lnbmFsUlNlcnZpY2UuYnVpbGRDb25uZWN0aW9uKHRoaXMuUkVRVUVTVF9VUkwsIHsuLi50aGlzLmRlZmF1bHRPcHRpb25zLCAuLi5vcHRpb25zfSwgbG9nTGV2ZWwsIHRydWUpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBjb25uZWN0aW9uXG4gICAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIHN0YXJ0ZWRcbiAgICovXG4gIHN0YXJ0Q29ubmVjdGlvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5zaWduYWxSU2VydmljZS5zdGFydENvbm5lY3Rpb24odGhpcy5jb25uZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIHRoZSBjb25uZWN0aW9uXG4gICAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIHN0b3BwZWRcbiAgICovXG4gIHN0b3BDb25uZWN0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLnNpZ25hbFJTZXJ2aWNlLnN0b3BDb25uZWN0aW9uKHRoaXMuY29ubmVjdGlvbik7XG4gIH1cblxuICBwcml2YXRlIGdldFRyYW5zcG9ydHMoKTogSHR0cFRyYW5zcG9ydFR5cGUge1xuICAgIHN3aXRjaCAodGhpcy5jaGF0Q29uZmlnJC52YWx1ZT8uY29ubmVjdGlvblNldHRpbmdzLnNpZ25hbFJUcmFuc3BvcnQpIHtcbiAgICAgIGNhc2UgXCJXZWJTb2NrZXRzXCI6XG4gICAgICAgIHJldHVybiBIdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzO1xuICAgICAgY2FzZSBcIlNlcnZlclNlbnRFdmVudHNcIjpcbiAgICAgICAgcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLlNlcnZlclNlbnRFdmVudHM7XG4gICAgICBjYXNlIFwiTG9uZ1BvbGxpbmdcIjpcbiAgICAgICAgcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLkxvbmdQb2xsaW5nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLk5vbmU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRMb2dMZXZlbCgpOiBMb2dMZXZlbCB7XG4gICAgc3dpdGNoICh0aGlzLmNoYXRDb25maWckLnZhbHVlPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUkxvZ0xldmVsKSB7XG4gICAgICBjYXNlIFwiQ3JpdGljYWxcIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLkNyaXRpY2FsOyAvLyBMb2cgbGV2ZWwgZm9yIGRpYWdub3N0aWMgbWVzc2FnZXMgdGhhdCBpbmRpY2F0ZSBhIGZhaWx1cmUgdGhhdCB3aWxsIHRlcm1pbmF0ZSB0aGUgZW50aXJlIGFwcGxpY2F0aW9uLlxuICAgICAgY2FzZSBcIkRlYnVnXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5EZWJ1ZzsgLy8gTG9nIGxldmVsIGZvciBsb3cgc2V2ZXJpdHkgZGlhZ25vc3RpYyBtZXNzYWdlcy5cbiAgICAgIGNhc2UgXCJFcnJvclwiOlxuICAgICAgICByZXR1cm4gTG9nTGV2ZWwuRXJyb3I7IC8vIExvZyBsZXZlbCBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcyB0aGF0IGluZGljYXRlIGEgZmFpbHVyZSBpbiB0aGUgY3VycmVudCBvcGVyYXRpb24uXG4gICAgICBjYXNlIFwiSW5mb3JtYXRpb25cIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLkluZm9ybWF0aW9uOyAvLyBMb2cgbGV2ZWwgZm9yIGluZm9ybWF0aW9uYWwgZGlhZ25vc3RpYyBtZXNzYWdlcy5cbiAgICAgIGNhc2UgXCJOb25lXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5Ob25lOyAvLyBUaGUgaGlnaGVzdCBwb3NzaWJsZSBsb2cgbGV2ZWwuIFVzZWQgd2hlbiBjb25maWd1cmluZyBsb2dnaW5nIHRvIGluZGljYXRlIHRoYXQgbm8gbG9nIG1lc3NhZ2VzIHNob3VsZCBiZSBlbWl0dGVkLlxuICAgICAgY2FzZSBcIlRyYWNlXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5UcmFjZTsgLy8gTG9nIGxldmVsIGZvciB2ZXJ5IGxvdyBzZXZlcml0eSBkaWFnbm9zdGljIG1lc3NhZ2VzLlxuICAgICAgY2FzZSBcIldhcm5pbmdcIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLldhcm5pbmc7IC8vIExvZyBsZXZlbCBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcyB0aGF0IGluZGljYXRlIGEgbm9uLWZhdGFsIHByb2JsZW0uXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gTG9nTGV2ZWwuTm9uZTsgLy8gVGhlIGhpZ2hlc3QgcG9zc2libGUgbG9nIGxldmVsLiBVc2VkIHdoZW4gY29uZmlndXJpbmcgbG9nZ2luZyB0byBpbmRpY2F0ZSB0aGF0IG5vIGxvZyBtZXNzYWdlcyBzaG91bGQgYmUgZW1pdHRlZC5cbiAgICB9XG4gIH1cblxuICBnZXQgZGVmYXVsdE9wdGlvbnMoKTogQ29ubmVjdGlvbk9wdGlvbnMge1xuICAgIGxldCBoZWFkZXJzOiBNZXNzYWdlSGVhZGVycyA9IHtcbiAgICAgIFwic2luZXF1YS1mb3JjZS1jYW1lbC1jYXNlXCI6IFwidHJ1ZVwiLFxuICAgICAgXCJ4LWxhbmd1YWdlXCI6IHRoaXMuaW50bFNlcnZpY2UuY3VycmVudExvY2FsZS5uYW1lLFxuICAgICAgXCJ1aS1sYW5ndWFnZVwiOiB0aGlzLmludGxTZXJ2aWNlLmN1cnJlbnRMb2NhbGUubmFtZSxcbiAgICB9O1xuICAgIGlmICh0aGlzLmF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZXNzZWRDcmVkZW50aWFscykge1xuICAgICAgaGVhZGVycyA9IHsuLi5oZWFkZXJzLCBcInNpbmVxdWEtY3NyZi10b2tlblwiOiB0aGlzLmF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZXNzZWRDcmVkZW50aWFscy5kYXRhLmNzcmZUb2tlbn07XG4gICAgfTtcbiAgICAvLyBGb3IgdGhlIGZpcnN0IEdFVCByZXF1ZXN0IHNlbnQgYnkgc2lnbmFsUiB0byBzdGFydCBhIFdlYlNvY2tldCBwcm90b2NvbCxcbiAgICAvLyBhcyBmYXIgYXMgd2Uga25vdywgc2lnbmFsUiBvbmx5IGxldHMgdXMgdHdlYWsgdGhlIHJlcXVlc3Qgd2l0aCB0aGlzIGFjY2VzcyB0b2tlbiBmYWN0b3J5XG4gICAgLy8gc28gd2UgcGFzcyBhbG9uZyB0aGUgU2luZXF1YSBDU1JGIHRva2VuIHRvIHBhc3MgdGhlIENTUkYgY2hlY2suLlxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc3BvcnQ6IHRoaXMuZ2V0VHJhbnNwb3J0cygpLFxuICAgICAgd2l0aENyZWRlbnRpYWxzOiB0cnVlLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdGhpcy5hdXRoZW50aWNhdGlvblNlcnZpY2UucHJvY2Vzc2VkQ3JlZGVudGlhbHM/LmRhdGE/LmNzcmZUb2tlbiB8fCBcIlwiXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
621
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWNoYXQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L3dlYnNvY2tldC1jaGF0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxFQUFxQixpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWxGLE9BQU8sRUFBRSxpQkFBaUIsRUFBaUIsUUFBUSxFQUFrQixNQUFNLG9CQUFvQixDQUFDO0FBRWhHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQUd4SyxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsV0FBVztJQWVuRDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBWkYscUJBQWdCLEdBQXFDLElBQUksR0FBRyxFQUFFLENBQUM7UUFFL0QsZUFBVSxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO1FBQzlDLGNBQVMsR0FBK0IsU0FBUyxDQUFDO1FBRWxELGlCQUFZLEdBQTRCLEVBQUUsQ0FBQztRQUMzQyxtQkFBYyxHQUFtQixFQUFFLENBQUM7UUFFckMsbUJBQWMsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUMzQywwQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FB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QUUsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNoQyxlQUFlLEVBQUUsSUFBSTtZQUNyQixPQUFPO1lBQ1Asa0JBQWtCLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLG9CQUFvQixFQUFFLElBQUksRUFBRSxTQUFTLElBQUksRUFBRTtTQUNqRyxDQUFBO0lBQ0gsQ0FBQzs7aUhBOXNCVSxvQkFBb0I7cUhBQXBCLG9CQUFvQjsyRkFBcEIsb0JBQW9CO2tCQURoQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEF1dGhlbnRpY2F0aW9uU2VydmljZSB9IGZyb20gXCJAc2luZXF1YS9jb3JlL2xvZ2luXCI7XG5pbXBvcnQgeyBDb25uZWN0aW9uT3B0aW9ucywgU2lnbmFsUldlYlNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS93ZWItc2VydmljZXNcIjtcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSBcIkBzaW5lcXVhL2NvcmUvYXBwLXV0aWxzXCI7XG5pbXBvcnQgeyBIdHRwVHJhbnNwb3J0VHlwZSwgSHViQ29ubmVjdGlvbiwgTG9nTGV2ZWwsIE1lc3NhZ2VIZWFkZXJzIH0gZnJvbSBcIkBtaWNyb3NvZnQvc2lnbmFsclwiO1xuaW1wb3J0IHsgQWN0aW9uTWVzc2FnZSwgQWN0aW9uUmVzdWx0RXZlbnQsIEFjdGlvblN0YXJ0RXZlbnQsIEFjdGlvblN0b3BFdmVudCwgTWVzc2FnZUV2ZW50LCBDaGF0TWVzc2FnZSwgQ2hhdFBheWxvYWQsIENoYXRSZXNwb25zZSwgR2xsbUZ1bmN0aW9uLCBHbGxtTW9kZWxEZXNjcmlwdGlvbiwgTWVzc2FnZUhhbmRsZXIsIEhpc3RvcnlFdmVudCwgRXJyb3JFdmVudCwgUXVvdGFFdmVudCwgQ2hhdENvbnRleHRBdHRhY2htZW50LCBDb250ZXh0TWVzc2FnZUV2ZW50LCBTYXZlZENoYXRIaXN0b3J5LCBTYXZlZENoYXQsIENoYXRQcm9ncmVzcywgU3VnZ2VzdGVkQWN0aW9uc0V2ZW50LCBEZWJ1Z01lc3NhZ2VFdmVudCwgRGVidWdNZXNzYWdlIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IENoYXRTZXJ2aWNlIH0gZnJvbSBcIi4vY2hhdC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBtZXJnZSwgZnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBjYXRjaEVycm9yLCBmaWx0ZXIsIGZvcmtKb2luLCBtYXAsIHNoYXJlUmVwbGF5LCBzd2l0Y2hNYXAsIHRhcCwgdGhyb3dFcnJvciwgdGFrZVVudGlsLCB0YWtlLCBtZXJnZU1hcCwgb2YgfSBmcm9tIFwicnhqc1wiO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0Q2hhdFNlcnZpY2UgZXh0ZW5kcyBDaGF0U2VydmljZSB7XG5cbiAgcHVibGljIGNvbm5lY3Rpb246IEh1YkNvbm5lY3Rpb24gfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBfbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxhbnk+PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBfcmVzcG9uc2U6IENoYXRNZXNzYWdlW107XG4gIHByaXZhdGUgX2FjdGlvbk1hcCA9IG5ldyBNYXA8c3RyaW5nLCBBY3Rpb25NZXNzYWdlPigpO1xuICBwcml2YXRlIF9wcm9ncmVzczogQ2hhdFByb2dyZXNzW10gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIHByaXZhdGUgX2V4ZWN1dGlvblRpbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBfYXR0YWNobWVudHM6IENoYXRDb250ZXh0QXR0YWNobWVudFtdID0gW107XG4gIHByaXZhdGUgX2RlYnVnTWVzc2FnZXM6IERlYnVnTWVzc2FnZVtdID0gW107XG5cbiAgcHVibGljIHNpZ25hbFJTZXJ2aWNlID0gaW5qZWN0KFNpZ25hbFJXZWJTZXJ2aWNlKTtcbiAgcHVibGljIGF1dGhlbnRpY2F0aW9uU2VydmljZSA9IGluamVjdChBdXRoZW50aWNhdGlvblNlcnZpY2UpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgY2hhdCBwcm9jZXNzIGFmdGVyIHRoZSBsb2dpbiBpcyBjb21wbGV0ZS5cbiAgICogSXQgaW5jbHVkZXMgYnVpbGRpbmcgYW5kIHN0YXJ0aW5nIGEgY29ubmVjdGlvbiwgZXhlY3V0aW5nIHBhcmFsbGVsIHJlcXVlc3RzIGZvciBtb2RlbHMgYW5kIGZ1bmN0aW9ucywgYW5kIGhhbmRsaW5nIGVycm9ycyBkdXJpbmcgdGhlIHByb2Nlc3MuXG4gICAqXG4gICAqIEByZXR1cm5zIEFuIE9ic2VydmFibGU8Ym9vbGVhbj4gaW5kaWNhdGluZyB0aGUgc3VjY2VzcyBvZiB0aGUgaW5pdGlhbGl6YXRpb24gcHJvY2Vzcy5cbiAgICovXG4gIGluaXQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMubG9naW5TZXJ2aWNlLmV2ZW50cy5waXBlKFxuICAgICAgZmlsdGVyKChlKSA9PiBlLnR5cGUgPT09ICdsb2dpbi1jb21wbGV0ZScpLFxuICAgICAgdGFwKCgpID0+IHRoaXMuZ2V0UmVxdWVzdHNVcmwoKSksXG4gICAgICAvLyBCdWlsZCB0aGUgY29ubmVjdGlvblxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuYnVpbGRDb25uZWN0aW9uKCkpLFxuICAgICAgdGFwKCgpID0+IHRoaXMuaW5pdE1lc3NhZ2VIYW5kbGVycygpKSxcbiAgICAgIC8vIFN0YXJ0IHRoZSBjb25uZWN0aW9uXG4gICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5zdGFydENvbm5lY3Rpb24oKSksXG4gICAgICAvLyBFeGVjdXRlIHBhcmFsbGVsIHJlcXVlc3RzIGZvciBtb2RlbHMgYW5kIGZ1bmN0aW9uc1xuICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKFtcbiAgICAgICAgICB0aGlzLmxpc3RNb2RlbHMoKSxcbiAgICAgICAgICB0aGlzLmxpc3RGdW5jdGlvbnMoKVxuICAgICAgICBdKVxuICAgICAgfSksXG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgb2YgcGFyYWxsZWwgcmVxdWVzdHMgdG8gYSBib29sZWFuIGluZGljYXRpbmcgc3VjY2Vzc1xuICAgICAgbWFwKChbbW9kZWxzLCBmdW5jdGlvbnNdKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9ICEhbW9kZWxzICYmICEhZnVuY3Rpb25zO1xuICAgICAgICB0aGlzLmluaXRQcm9jZXNzJC5uZXh0KHJlc3VsdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KSxcbiAgICAgIC8vIEFueSBlcnJvcnMgZHVyaW5nIHRoZSBwcm9jZXNzIGFyZSBjYXVnaHQsIGxvZ2dlZCwgYW5kIHJlLXRocm93biB0byBwcm9wYWdhdGUgdGhlIGVycm9yIGZ1cnRoZXJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycmVkOicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgfSksXG4gICAgICAvLyBDYWNoZSBhbmQgcmVwbGF5IHRoZSBlbWl0dGVkIHZhbHVlIGZvciBzdWJzZXF1ZW50IHN1YnNjcmliZXJzXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lIHRoZSBhc3Npc3RhbnQgZW5kcG9pbnQgdG8gdXNlIGZvciB0aGUgd2Vic29ja2V0IHJlcXVlc3RzXG4gICAqIEl0IGNhbiBiZSBvdmVycmlkZGVuIGJ5IHRoZSBhcHAgY29uZmlnXG4gICAqL1xuICBnZXRSZXF1ZXN0c1VybCgpIHtcbiAgICBpZiAodGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLndlYnNvY2tldEVuZHBvaW50KSB7XG4gICAgICB0aGlzLlJFUVVFU1RfVVJMID0gdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuY29ubmVjdGlvblNldHRpbmdzLndlYnNvY2tldEVuZHBvaW50O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBwcm9wZXJ0eSAnd2Vic29ja2V0RW5kcG9pbnQnIG11c3QgYmUgcHJvdmlkZWQgd2hlbiBhdHRlbXB0aW5nIHRvIHVzZSAnV2ViU29ja2V0JyBpbiBhc3Npc3RhbnQgaW5zdGFuY2VgKTtcbiAgICB9XG4gIH1cblxuICBsaXN0TW9kZWxzKCk6IE9ic2VydmFibGU8R2xsbU1vZGVsRGVzY3JpcHRpb25bXSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IG1vZGVsc1N1YmplY3QkID0gbmV3IFN1YmplY3Q8R2xsbU1vZGVsRGVzY3JpcHRpb25bXSB8IHVuZGVmaW5lZD4oKTtcblxuICAgIHRoaXMuY29ubmVjdGlvbiEub24oJ0xpc3RNb2RlbHMnLCAocmVzKSA9PiB7XG4gICAgICB0aGlzLm1vZGVscyA9IChyZXMubW9kZWxzIGFzIEdsbG1Nb2RlbERlc2NyaXB0aW9uW10gfCB1bmRlZmluZWQpPy5maWx0ZXIobW9kZWwgPT4gISFtb2RlbC5lbmFibGUpO1xuICAgICAgbW9kZWxzU3ViamVjdCQubmV4dCh0aGlzLm1vZGVscyk7XG4gICAgICBtb2RlbHNTdWJqZWN0JC5jb21wbGV0ZSgpXG4gICAgfSk7XG5cbiAgICAvLyBTZW5kIHRoZSByZXF1ZXN0IHRvIGdldCB0aGUgbGlzdCBvZiBtb2RlbHNcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnTGlzdE1vZGVscycsIHsgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWcgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIExpc3RNb2RlbHM6JywgZXJyb3IpO1xuICAgICAgICBtb2RlbHNTdWJqZWN0JC5lcnJvcihuZXcgRXJyb3IoZXJyb3IpKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpOyAvLyBSZXR1cm4gYSByZXNvbHZlZCBwcm9taXNlIHRvIGhhbmRsZSB0aGUgZXJyb3IgYW5kIHByZXZlbnQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uIHdoZW4gbm8gZnVydGhlciBlcnJvciBoYW5kbGluZyBleGlzdHMgZG93bnN0cmVhbVxuICAgICAgfSlcblxuICAgIHJldHVybiBtb2RlbHNTdWJqZWN0JC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIGxpc3RGdW5jdGlvbnMoKTogT2JzZXJ2YWJsZTxHbGxtRnVuY3Rpb25bXSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGZ1bmN0aW9uc1N1YmplY3QkID0gbmV3IFN1YmplY3Q8R2xsbUZ1bmN0aW9uW10gfCB1bmRlZmluZWQ+KCk7XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24hLm9uKCdMaXN0RnVuY3Rpb25zJywgKHJlcykgPT4ge1xuICAgICAgdGhpcy5mdW5jdGlvbnMgPSAocmVzLmZ1bmN0aW9ucyBhcyBHbGxtRnVuY3Rpb25bXSB8IHVuZGVmaW5lZCk/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCk7XG4gICAgICBmdW5jdGlvbnNTdWJqZWN0JC5uZXh0KHRoaXMuZnVuY3Rpb25zKTtcbiAgICAgIGZ1bmN0aW9uc1N1YmplY3QkLmNvbXBsZXRlKClcbiAgICB9KTtcblxuICAgIC8vIFNlbmQgdGhlIHJlcXVlc3QgdG8gZ2V0IHRoZSBsaXN0IG9mIGZ1bmN0aW9uc1xuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdMaXN0RnVuY3Rpb25zJywgeyBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1ZyB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgTGlzdEZ1bmN0aW9uczonLCBlcnJvcik7XG4gICAgICAgIGZ1bmN0aW9uc1N1YmplY3QkLmVycm9yKG5ldyBFcnJvcihlcnJvcikpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7IC8vIFJldHVybiBhIHJlc29sdmVkIHByb21pc2UgdG8gaGFuZGxlIHRoZSBlcnJvciBhbmQgcHJldmVudCB1bmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb24gd2hlbiBubyBmdXJ0aGVyIGVycm9yIGhhbmRsaW5nIGV4aXN0cyBkb3duc3RyZWFtXG4gICAgICB9KVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uc1N1YmplY3QkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgZmV0Y2gobWVzc2FnZXM6IENoYXRNZXNzYWdlW10sIHF1ZXJ5OiBRdWVyeSk6IE9ic2VydmFibGU8Q2hhdFJlc3BvbnNlPiB7XG4gICAgLy8gU3RhcnQgc3RyZWFtaW5nIGJ5IGludm9raW5nIHRoZSBDaGF0IG1ldGhvZFxuICAgIHRoaXMuc3RyZWFtaW5nJC5uZXh0KHRydWUpO1xuXG4gICAgLy8gUHJlcGFyZSB0aGUgcGF5bG9hZCB0byBzZW5kIHRvIHRoZSBDaGF0IG1ldGhvZFxuICAgIGNvbnN0IGRhdGE6IENoYXRQYXlsb2FkID0ge1xuICAgICAgaGlzdG9yeTogbWVzc2FnZXMsXG4gICAgICBmdW5jdGlvbnM6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZnVuY3Rpb25zPy5maWx0ZXIoZnVuYyA9PiBmdW5jLmVuYWJsZWQpLm1hcChmdW5jID0+IGZ1bmMubmFtZSksXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1ZyxcbiAgICAgIHNlcnZpY2VTZXR0aW5nczoge1xuICAgICAgICBzZXJ2aWNlX2lkOiB0aGlzLmNoYXRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLnNlcnZpY2VfaWQsXG4gICAgICAgIG1vZGVsX2lkOiB0aGlzLmNoYXRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLm1vZGVsX2lkLFxuICAgICAgICB0b3BfcDogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy50b3BfcCxcbiAgICAgICAgdGVtcGVyYXR1cmU6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMudGVtcGVyYXR1cmUsXG4gICAgICAgIG1heF90b2tlbnM6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMubWF4X3Rva2VucyxcbiAgICAgICAgLi4udGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuYWRkaXRpb25hbFNlcnZpY2VTZXR0aW5nc1xuICAgICAgfSxcbiAgICAgIGFwcFF1ZXJ5OiB7XG4gICAgICAgIGFwcDogdGhpcy5hcHBTZXJ2aWNlLmFwcE5hbWUsXG4gICAgICAgIHF1ZXJ5XG4gICAgICB9LFxuICAgICAgZ2VuZXJpY0NoYXRFcnJvck1lc3NhZ2U6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmdsb2JhbFNldHRpbmdzLmdlbmVyaWNDaGF0RXJyb3JNZXNzYWdlXG4gICAgfVxuICAgIGlmICh0aGlzLmNoYXRDb25maWckLnZhbHVlIS5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkKSB7XG4gICAgICBkYXRhLmluc3RhbmNlSWQgPSB0aGlzLmNoYXRJbnN0YW5jZUlkO1xuICAgICAgZGF0YS5zYXZlZENoYXRJZCA9IHRoaXMuc2F2ZWRDaGF0SWQ7XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgcmVzcG9uc2Ugd2l0aCBhbiBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZVxuICAgIHRoaXMuX3Jlc3BvbnNlID0gW3tyb2xlOiBcImFzc2lzdGFudFwiLCBjb250ZW50OiBcIlwiLCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRydWV9fV0gLy8gaGVyZSBkaXNwbGF5OiB0cnVlIGlzIG5lZWRlZCBpbiBvcmRlciB0byBiZSBhYmxlIHRvIHNob3cgdGhlIHByb2dyZXNzXG5cbiAgICAvLyBDcmVhdGUgYSBTdWJqZWN0IHRvIHNpZ25hbCBjb21wbGV0aW9uXG4gICAgY29uc3QgY29tcGxldGlvbiQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgLy8gQ3JlYXRlIG9ic2VydmFibGVzIGZvciBlYWNoIG5vbi1nbG9iYWwgaGFuZGxlciBpbiB0aGUgX21lc3NhZ2VIYW5kbGVycyBtYXAgKGRlZmF1bHQgYW5kIGV2ZW50dWFsIGN1c3RvbSBvbmVzKSBvbmNlIGl0IGlzIHRyaWdnZXJlZCBieSB0aGUgaHViIGNvbm5lY3Rpb25cbiAgICBjb25zdCBvYnNlcnZhYmxlcyA9IEFycmF5XG4gICAgICAuZnJvbSh0aGlzLl9tZXNzYWdlSGFuZGxlcnMuZW50cmllcygpKVxuICAgICAgLmZpbHRlcigoW2V2ZW50TmFtZSwgZXZlbnRIYW5kbGVyXSkgPT4gIWV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpXG4gICAgICAubWFwKChbZXZlbnROYW1lLCBldmVudEhhbmRsZXJdKSA9PiB7XG4gICAgICAgIHJldHVybiBmcm9tRXZlbnQ8YW55Pih0aGlzLmNvbm5lY3Rpb24hLCBldmVudE5hbWUpLnBpcGUoXG4gICAgICAgICAgbWVyZ2VNYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBXcmFwIHRoZSBoYW5kbGVyIGluIGEgdHJ5LWNhdGNoIGJsb2NrIHRvIHByZXZlbnQgdGhlIGVudGlyZSBzdHJlYW0gZnJvbSBmYWlsaW5nIGlmIGFuIGVycm9yIG9jY3VycyBpbiBhIHNpbmdsZSBoYW5kbGVyXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyBFeGVjdXRlIHRoZSBoYW5kbGVyIGFuZCBlbWl0IHRoZSByZXN1bHRcbiAgICAgICAgICAgICAgLy8gTkI6IGhlcmUgd2UgY291bGQgdXNlIFtldmVudEhhbmRsZXIuaGFuZGxlcihldmVudCldIHdoaWNoIGJlaGluZCB0aGUgc2NlbmVzIG1lcmdlTWFwIGludGVycHJldHMgdGhpcyBhcnJheSBhcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggb25lIGl0ZW0sIHdoaWNoIGl0IHRoZW4gZW1pdHNcbiAgICAgICAgICAgICAgcmV0dXJuIG9mKGV2ZW50SGFuZGxlci5oYW5kbGVyKGV2ZW50KSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06YCwgZXJyb3IpO1xuICAgICAgICAgICAgICAvLyBVc2UgdGhyb3dFcnJvciB0byBwcm9wYWdhdGUgdGhlIGVycm9yIGRvd25zdHJlYW1cbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06ICR7ZXJyb3J9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgIC8vIFRoZW4gbWVyZ2UgdGhlbSBpbnRvIGEgc2luZ2xlIG9ic2VydmFibGUgaW4gb3JkZXIgdG8gc2ltdWxhdGUgdGhlIHN0cmVhbWluZyBiZWhhdmlvclxuICAgIGNvbnN0IGNvbWJpbmVkJCA9IG1lcmdlKC4uLm9ic2VydmFibGVzKS5waXBlKFxuICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgLy8gRGVmaW5lICRwcm9ncmVzcyBmcm9tIHRoZSBfYWN0aW9uTWFwXG4gICAgICAgIGNvbnN0IGFjdGlvbnMgPSBBcnJheS5mcm9tKHRoaXMuX2FjdGlvbk1hcC52YWx1ZXMoKSk7XG4gICAgICAgIHRoaXMuX3Byb2dyZXNzID0gYWN0aW9ucy5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gYWN0aW9ucy5tYXAoKGEpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBhLmRpc3BsYXlOYW1lID8/IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGEuZGlzcGxheVZhbHVlID8/IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmU6IGEuZXhlY3V0aW9uVGltZSAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lOiBhLmV4ZWN1dGlvblRpbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gQWx3YXlzIHVwZGF0ZSBPTkxZIHRoZSBmaXJzdCBhc3Npc3RhbnQgbWVzc2FnZSBvZiB0aGUgX3Jlc3BvbnNlIHdpdGggdGhlIG5ldyAkcHJvZ3Jlc3MsICRhdHRhY2htZW50IGFuZCAkZGVidWdcbiAgICAgICAgLy8gQXNzdW1pbmcgdGhhdCB0aGUgZmlyc3QgYXNzaXN0YW50IG1lc3NhZ2UgaXMgYWx3YXlzIHZpc2libGUgc2luY2UgdGhlIGh1YiBkb2VzIG5vdCBzZW5kIGhpZGRlbiBtZXNzYWdlcyBieSBkZXNpZ25cbiAgICAgICAgLy8gU28gZXZlbiBpZiB0aGUgZmlyc3QgYXNzaXN0YW50IG1lc3NhZ2UgaXMgaGlkZGVuIChkaXNwbGF5OiBmYWxzZSksIHRoZSBfcmVzcG9uc2VbMF0gd2lsbCBhbmQgc2hvdWxkIGNvbnRhaW4gOlxuICAgICAgICAvLyAgLSAkcHJvZ3Jlc3MsICRhdHRhY2htZW50IGFuZCAkZGVidWdcbiAgICAgICAgLy8gIC0gdGhlIGNvbnRlbnQgb2YgdGhlIGZpcnN0IHZpc2libGUgYXNzaXN0YW50IG1lc3NhZ2UgaW4gdGhlIHdvcmtmbG93XG4gICAgICAgIC8vIFRoaXMgaXMgbWFuZGF0b3J5IGluIG9yZGVyIHRvIG1hdGNoIHRoZSBiZWhhdmlvciBvZiBjb25zZWN1dGl2ZSBtZXNzYWdlcyBhbmQgbWFpbnRhaW4gY29uc2lzdGVuY3kgd2l0aCB0aGUgY2hhdEhpc3RvcnlcbiAgICAgICAgaWYoISF0aGlzLl9wcm9ncmVzcyB8fCB0aGlzLl9hdHRhY2htZW50cy5sZW5ndGggPiAwIHx8IHRoaXMuX2RlYnVnTWVzc2FnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlWzBdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRwcm9ncmVzcyA9IHRoaXMuX3Byb2dyZXNzO1xuICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlWzBdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50ID0gdGhpcy5fYXR0YWNobWVudHM7XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VbMF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGRlYnVnID0gdGhpcy5fZGVidWdNZXNzYWdlcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJldHVybiB0aGUgcmVzdWx0XG4gICAgICAgIHJldHVybiB7IGhpc3Rvcnk6IFsuLi5tZXNzYWdlcywgLi4udGhpcy5fcmVzcG9uc2VdLCBleGVjdXRpb25UaW1lOiB0aGlzLl9leGVjdXRpb25UaW1lIH07XG4gICAgICB9KSxcbiAgICAgIHRha2VVbnRpbChjb21wbGV0aW9uJCksIC8vIENvbXBsZXRlIHRoZSBvYnNlcnZhYmxlIHdoZW4gY29tcGxldGlvbiQgZW1pdHNcbiAgICApO1xuXG4gICAgLy8gcmV0dXJuIGEgbmV3IE9ic2VydmFibGUgdGhhdCBlbWl0cyB0aGUgcmVzdWx0IG9mIHRoZSBjb21iaW5lZCBzdHJlYW0gYW5kIGhhbmRsZXMgdGhlIGV2ZW50dWFsIGVycm9ycyBvZiB0aGUgaW52b2NhdGlvbiBvZiB0aGUgQ2hhdCBtZXRob2RcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGUob2JzZXJ2ZXIgPT4ge1xuICAgICAgLy8gU3Vic2NyaWJlIHRvIGNvbWJpbmVkIHN0cmVhbVxuICAgICAgY29tYmluZWQkLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICh2YWx1ZSkgPT4gb2JzZXJ2ZXIubmV4dCh2YWx1ZSksXG4gICAgICAgIGVycm9yOiAoZXJyKSA9PiBvYnNlcnZlci5lcnJvcihlcnIpXG4gICAgICB9KTtcblxuICAgICAgLy8gSW52b2tlIHRoZSBDaGF0IG1ldGhvZCBhbmQgaGFuZGxlIGVycm9yc1xuICAgICAgdGhpcy5jb25uZWN0aW9uIS5pbnZva2UoJ0NoYXQnLCBkYXRhKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gSWYgYSB2YWxpZCBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIChkaXNwbGF5OiB0cnVlKSB3YXMgZm91bmQsIHVwZGF0ZSBpdFxuICAgICAgICAgIC8vIGFuZCBpdCBzaG91bGQgYWx3YXlzIHRoZSBjYXNlXG4gICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmZpcnN0VmlzaWJsZUFzc2lzdGFudE1lc3NhZ2VJbmRleCh0aGlzLmNoYXRIaXN0b3J5KTtcbiAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNoYXRIaXN0b3J5IVtpbmRleF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzID0gdGhpcy5fcHJvZ3Jlc3M7XG4gICAgICAgICAgICB0aGlzLmNoYXRIaXN0b3J5IVtpbmRleF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgPSB0aGlzLl9hdHRhY2htZW50cztcbiAgICAgICAgICAgIHRoaXMuY2hhdEhpc3RvcnkhW2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGVidWcgPSB0aGlzLl9kZWJ1Z01lc3NhZ2VzO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTYXZlL3VwZGF0ZSB0aGUgY2hhdCBpZiBzYXZlZENoYXQgZW5hYmxlZFxuICAgICAgICAgIGlmICh0aGlzLmNoYXRDb25maWckLnZhbHVlIS5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkICYmIHRoaXMuY2hhdEhpc3RvcnkhLnNvbWUoKG1zZykgPT4gbXNnLmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy5pc1VzZXJJbnB1dCA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9ICF0aGlzLnNhdmVkQ2hhdElkID8gdGhpcy5hZGRTYXZlZENoYXQodGhpcy5jaGF0SGlzdG9yeSEpLnBpcGUodGFwKCgpID0+IHRoaXMubGlzdFNhdmVkQ2hhdCgpKSkgOiB0aGlzLnVwZGF0ZVNhdmVkQ2hhdCh0aGlzLnNhdmVkQ2hhdElkLCB1bmRlZmluZWQsIHRoaXMuY2hhdEhpc3RvcnkpO1xuICAgICAgICAgICAgYWN0aW9uLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgbmV4dDogKCkgPT4ge30sXG4gICAgICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbWluZyQubmV4dChmYWxzZSk7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtaW5nJC5uZXh0KGZhbHNlKTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW1pbmckLm5leHQoZmFsc2UpO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgQ2hhdDonLCBlcnJvcik7XG4gICAgICAgICAgdGhpcy5zdHJlYW1pbmckLm5leHQoZmFsc2UpO1xuICAgICAgICAgIC8vIEVtaXQgdGhlIGVycm9yIHRvIHRoZSBuZXdseSBjcmVhdGVkIG9ic2VydmFibGVcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgIC8vIFRoaXMgYmxvY2sgY29uY2VybnMgT05MWSB0aGUgY29tcGxldGlvbiBvZiB0aGUgXCJDaGF0XCIgbWV0aG9kIGludm9jYXRpb24uXG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGUgY29tcGxldGlvbiBvZiB0aGUgY29tYmluZWQkIHN0cmVhbS5cbiAgICAgICAgICAvLyBJdCBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCB0aGUgY29tcGxldGlvbiBvZiB0aGUgZW50aXJlIGZldGNoIG1ldGhvZCAodGhlIG9ic2VydmFibGUgcmV0dXJuZWQgYnkgZmV0Y2gpIGFuZCB3aGljaCBkZXBlbmRzIG9uIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBzYXZlIGNoYXQgYWN0aW9uIGlmIGVuYWJsZWRcbiAgICAgICAgICB0aGlzLl9yZXNwb25zZSA9IFtdOyAvLyBDbGVhciB0aGUgX3Jlc3BvbnNlXG4gICAgICAgICAgdGhpcy5fYWN0aW9uTWFwLmNsZWFyKCk7IC8vIENsZWFyIHRoZSBfYWN0aW9uTWFwXG4gICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSB1bmRlZmluZWQ7IC8vIENsZWFyIHRoZSBfcHJvZ3Jlc3NcbiAgICAgICAgICB0aGlzLl9hdHRhY2htZW50cyA9IFtdOyAvLyBDbGVhciB0aGUgX2F0dGFjaG1lbnRzXG4gICAgICAgICAgdGhpcy5fZGVidWdNZXNzYWdlcyA9IFtdOyAvLyBDbGVhciB0aGUgX2RlYnVnTWVzc2FnZXNcbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lID0gXCJcIjsgLy8gQ2xlYXIgdGhlIF9leGVjdXRpb25UaW1lXG4gICAgICAgICAgY29tcGxldGlvbiQubmV4dCgpOyAvLyBFbWl0IGEgc2lnbmFsIHRvIGNvbXBsZXRlIHRoZSBvYnNlcnZhYmxlc1xuICAgICAgICAgIGNvbXBsZXRpb24kLmNvbXBsZXRlKCk7IC8vIENvbXBsZXRlIHRoZSBzdWJqZWN0XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc3RvcEdlbmVyYXRpb24oKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgLy8gU3RhcnQgc3RvcHBpbmcgZ2VuZXJhdGlvbiBieSBpbnZva2luZyB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgdGhpcy5zdG9wcGluZ0dlbmVyYXRpb24kLm5leHQodHJ1ZSk7XG4gICAgLy8gQ3JlYXRlIGEgU3ViamVjdCB0byBob2xkIHRoZSByZXN1bHQgb2YgdGhlIENhbmNlbFRhc2tzIG1ldGhvZFxuICAgIGNvbnN0IHN0b3BHZW5lcmF0aW9uU3ViamVjdCQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignQ2FuY2VsVGFza3MnLCAocmVzKSA9PiB7XG4gICAgICAvLyBXaGVuIHRoZSBnZW5lcmF0aW9uIGlzIHN0b3BwZWQgYmVmb3JlIHN0cmVhbWluZyBhbnkgVklTSUJMRSBhc3Npc3RhbnQgbWVzc2FnZSwgdGhpcyBtZWFucyB0aGF0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIHdpbGwgYmUgbG9zdC5cbiAgICAgIC8vIEhvd2V2ZXIsIHRoZSBcIkNvbnRleHRNZXNzYWdlXCIgZnJhbWVzIHdpbGwgYmUgcGVyc2lzdGVkIGluIHRoZSBjaGF0SGlzdG9yeSBhbmQgdGhlIGFzc2lzdGFudCBtYXkgcmVmZXJlbmNlIHRoZW0gaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRoaXMgbGVhZHMgdG8gdGhlIHByb2JsZW0gb2YgcmVmZXJlbmNpbmcgdW5kaXNwbGF5ZWQgYXR0YWNobWVudHMgaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRvIHNvbHZlIHRoaXMgcHJvYmxlbSwgd2UgbmVlZCB0byBwZXJzaXN0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIGJ5IGFkZGluZyBhIG5ldyBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIGVtcHR5IGNvbnRlbnQgYW5kIHRoZXNlIHByb3BlcnRpZXMuXG4gICAgICBpZiAodGhpcy5fcmVzcG9uc2UubGVuZ3RoID09PSAxICYmIHRoaXMuX3Jlc3BvbnNlWzBdLmNvbnRlbnQgPT09IFwiXCIpIHtcbiAgICAgICAgdGhpcy5jaGF0SGlzdG9yeT8ucHVzaCh7cm9sZTogXCJhc3Npc3RhbnRcIiwgY29udGVudDogXCJcIiwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0cnVlLCAkcHJvZ3Jlc3M6IHRoaXMuX3Byb2dyZXNzLCAkYXR0YWNobWVudDogdGhpcy5fYXR0YWNobWVudHMsICRkZWJ1ZzogdGhpcy5fZGVidWdNZXNzYWdlc319KTtcbiAgICAgIH1cbiAgICAgIHN0b3BHZW5lcmF0aW9uU3ViamVjdCQubmV4dCghIXJlcyk7IC8vIEVtaXQgdGhlIHJlc3VsdCBvZiB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgICBzdG9wR2VuZXJhdGlvblN1YmplY3QkLmNvbXBsZXRlKCk7IC8vIENvbXBsZXRlIHRoZSBzdWJqZWN0XG4gICAgICB0aGlzLnN0b3BwaW5nR2VuZXJhdGlvbiQubmV4dChmYWxzZSk7IC8vIENvbXBsZXRlIHN0b3BwaW5nIGdlbmVyYXRpb25cbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kIGFuZCBoYW5kbGUgZXJyb3JzXG4gICAgdGhpcy5jb25uZWN0aW9uIS5pbnZva2UoJ0NhbmNlbFRhc2tzJylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIENhbmNlbFRhc2tzOicsIGVycm9yKTtcbiAgICAgICAgc3RvcEdlbmVyYXRpb25TdWJqZWN0JC5lcnJvcihuZXcgRXJyb3IoZXJyb3IpKTtcbiAgICAgICAgdGhpcy5zdG9wcGluZ0dlbmVyYXRpb24kLm5leHQoZmFsc2UpOyAvLyBDb21wbGV0ZSBzdG9wcGluZyBnZW5lcmF0aW9uXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTsgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiB3aGVuIG5vIGZ1cnRoZXIgZXJyb3IgaGFuZGxpbmcgZXhpc3RzIGRvd25zdHJlYW1cbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHN0b3BHZW5lcmF0aW9uU3ViamVjdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBsaXN0U2F2ZWRDaGF0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0TGlzdCcsIChyZXMpID0+IHtcbiAgICAgIHRoaXMuc2F2ZWRDaGF0cyQubmV4dChyZXMuc2F2ZWRDaGF0cyk7IC8vIGVtaXRzIHRoZSByZXN1bHQgdG8gdGhlIHNhdmVkQ2hhdHMkIHN1YmplY3RcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdExpc3RcbiAgICB0aGlzLmNvbm5lY3Rpb24hLmludm9rZSgnU2F2ZWRDaGF0TGlzdCcsIGRhdGEpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbnZva2luZyBTYXZlZENoYXRMaXN0OicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRTYXZlZENoYXQoaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8U2F2ZWRDaGF0SGlzdG9yeSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHNhdmVkQ2hhdFN1YmplY3QkID0gbmV3IFN1YmplY3Q8U2F2ZWRDaGF0SGlzdG9yeSB8IHVuZGVmaW5lZD4oKTtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpbnN0YW5jZUlkOiB0aGlzLmNoYXRJbnN0YW5jZUlkLFxuICAgICAgc2F2ZWRDaGF0SWQ6IGlkLFxuICAgICAgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0R2V0JywgKHJlcykgPT4ge1xuICAgICAgc2F2ZWRDaGF0U3ViamVjdCQubmV4dChyZXMuc2F2ZWRDaGF0KTtcbiAgICAgIHNhdmVkQ2hhdFN1YmplY3QkLmNvbXBsZXRlKClcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdEdldFxuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdTYXZlZENoYXRHZXQnLCBkYXRhKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgU2F2ZWRDaGF0R2V0OicsIGVycm9yKTtcbiAgICAgICAgc2F2ZWRDaGF0U3ViamVjdCQuZXJyb3IobmV3IEVycm9yKGVycm9yKSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTsgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiB3aGVuIG5vIGZ1cnRoZXIgZXJyb3IgaGFuZGxpbmcgZXhpc3RzIGRvd25zdHJlYW1cbiAgICAgIH0pXG5cbiAgICByZXR1cm4gc2F2ZWRDaGF0U3ViamVjdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBhZGRTYXZlZENoYXQobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pOiBPYnNlcnZhYmxlPFNhdmVkQ2hhdD4ge1xuICAgIGNvbnN0IGFkZFNhdmVkQ2hhdFN1YmplY3QkID0gbmV3IFN1YmplY3Q8U2F2ZWRDaGF0PigpO1xuXG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogdGhpcy5jaGF0SWQsXG4gICAgICBoaXN0b3J5OiBtZXNzYWdlcyxcbiAgICAgIGRlYnVnOiB0aGlzLmNoYXRDb25maWckLnZhbHVlIS5kZWZhdWx0VmFsdWVzLmRlYnVnXG4gICAgfTtcblxuICAgIHRoaXMuY29ubmVjdGlvbiEub24oJ1NhdmVkQ2hhdEFkZCcsIChyZXMpID0+IHtcbiAgICAgIHRoaXMuc2V0U2F2ZWRDaGF0SWQocmVzLnNhdmVkQ2hhdC5pZCk7IC8vIFBlcnNpc3QgdGhlIHNhdmVkQ2hhdElkXG4gICAgICB0aGlzLmdlbmVyYXRlQXVkaXRFdmVudCgnc2F2ZWQtY2hhdC5hZGQnLCB7fSwgcmVzLnNhdmVkQ2hhdC5pZCk7IC8vIEdlbmVyYXRlIGF1ZGl0IGV2ZW50XG4gICAgICBhZGRTYXZlZENoYXRTdWJqZWN0JC5uZXh0KHJlcy5zYXZlZENoYXQpO1xuICAgICAgYWRkU2F2ZWRDaGF0U3ViamVjdCQuY29tcGxldGUoKVxuICAgIH0pO1xuXG4gICAgLy8gSW52b2tlIHRoZSBtZXRob2QgU2F2ZWRDaGF0QWRkXG4gICAgdGhpcy5jb25uZWN0aW9uIS5pbnZva2UoJ1NhdmVkQ2hhdEFkZCcsIGRhdGEpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbnZva2luZyBTYXZlZENoYXRBZGQ6JywgZXJyb3IpO1xuICAgICAgICBhZGRTYXZlZENoYXRTdWJqZWN0JC5lcnJvcihuZXcgRXJyb3IoZXJyb3IpKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpOyAvLyBSZXR1cm4gYSByZXNvbHZlZCBwcm9taXNlIHRvIGhhbmRsZSB0aGUgZXJyb3IgYW5kIHByZXZlbnQgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uIHdoZW4gbm8gZnVydGhlciBlcnJvciBoYW5kbGluZyBleGlzdHMgZG93bnN0cmVhbVxuICAgICAgfSlcblxuICAgIHJldHVybiBhZGRTYXZlZENoYXRTdWJqZWN0JC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHVwZGF0ZVNhdmVkQ2hhdChpZDogc3RyaW5nLCBuYW1lPzogc3RyaW5nLCBtZXNzYWdlcz86IENoYXRNZXNzYWdlW10pOiBPYnNlcnZhYmxlPFNhdmVkQ2hhdD4ge1xuICAgIGNvbnN0IHVwZGF0ZVNhdmVkQ2hhdFN1YmplY3QkID0gbmV3IFN1YmplY3Q8U2F2ZWRDaGF0PigpO1xuXG4gICAgY29uc3QgZGF0YSA9IHtcbiAgICAgIGluc3RhbmNlSWQ6IHRoaXMuY2hhdEluc3RhbmNlSWQsXG4gICAgICBzYXZlZENoYXRJZDogaWQsXG4gICAgICBkZWJ1ZzogdGhpcy5jaGF0Q29uZmlnJC52YWx1ZSEuZGVmYXVsdFZhbHVlcy5kZWJ1Z1xuICAgIH07XG5cbiAgICBpZihuYW1lKSBkYXRhW1widGl0bGVcIl0gPSBuYW1lO1xuICAgIGlmKG1lc3NhZ2VzKSBkYXRhW1wiaGlzdG9yeVwiXSA9IG1lc3NhZ2VzO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0VXBkYXRlJywgKHJlcykgPT4ge1xuICAgICAgdXBkYXRlU2F2ZWRDaGF0U3ViamVjdCQubmV4dChyZXMuc2F2ZWRDaGF0KTtcbiAgICAgIHVwZGF0ZVNhdmVkQ2hhdFN1YmplY3QkLmNvbXBsZXRlKClcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdFVwZGF0ZVxuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdTYXZlZENoYXRVcGRhdGUnLCBkYXRhKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgU2F2ZWRDaGF0VXBkYXRlOicsIGVycm9yKTtcbiAgICAgICAgdXBkYXRlU2F2ZWRDaGF0U3ViamVjdCQuZXJyb3IobmV3IEVycm9yKGVycm9yKSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTsgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiB3aGVuIG5vIGZ1cnRoZXIgZXJyb3IgaGFuZGxpbmcgZXhpc3RzIGRvd25zdHJlYW1cbiAgICAgIH0pXG5cbiAgICByZXR1cm4gdXBkYXRlU2F2ZWRDaGF0U3ViamVjdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBkZWxldGVTYXZlZENoYXQoaWRzOiBzdHJpbmdbXSk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgY29uc3QgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCQgPSBuZXcgU3ViamVjdDxudW1iZXI+KCk7XG5cbiAgICBjb25zdCBkYXRhID0ge1xuICAgICAgaW5zdGFuY2VJZDogdGhpcy5jaGF0SW5zdGFuY2VJZCxcbiAgICAgIFNhdmVkQ2hhdElkczogaWRzLFxuICAgICAgZGVidWc6IHRoaXMuY2hhdENvbmZpZyQudmFsdWUhLmRlZmF1bHRWYWx1ZXMuZGVidWdcbiAgICB9O1xuXG4gICAgdGhpcy5jb25uZWN0aW9uIS5vbignU2F2ZWRDaGF0RGVsZXRlJywgKHJlcykgPT4ge1xuICAgICAgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCQubmV4dChyZXMuZGVsZXRlQ291bnQpO1xuICAgICAgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCQuY29tcGxldGUoKTtcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgbWV0aG9kIFNhdmVkQ2hhdERlbGV0ZVxuICAgIHRoaXMuY29ubmVjdGlvbiEuaW52b2tlKCdTYXZlZENoYXREZWxldGUnLCBkYXRhKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgU2F2ZWRDaGF0RGVsZXRlOicsIGVycm9yKTtcbiAgICAgICAgZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCQuZXJyb3IobmV3IEVycm9yKGVycm9yKSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTsgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiB3aGVuIG5vIGZ1cnRoZXIgZXJyb3IgaGFuZGxpbmcgZXhpc3RzIGRvd25zdHJlYW1cbiAgICAgIH0pXG5cbiAgICByZXR1cm4gZGVsZXRlU2F2ZWRDaGF0U3ViamVjdCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBvdXQtb2YtdGhlLWJveCBoYW5kbGVyc1xuICAgKiBJdCBpcyBhIHBsYWNlaG9sZGVyIGZvciBub24tc3RyZWFtaW5nIHNjZW5hcmlvcywgd2hlcmUgeW91IGludm9rZSBhIHNwZWNpZmljIGh1YiBtZXRob2QsIGFuZCB0aGUgc2VydmVyIHJlc3BvbmRzIHdpdGggZnJhbWUgbWVzc2FnZShzKVxuICAgKi9cbiAgaW5pdE1lc3NhZ2VIYW5kbGVycygpIHtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJFcnJvclwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAoZXJyb3I6IEVycm9yRXZlbnQpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiB0cnVlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJRdW90YVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogUXVvdGFFdmVudCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVF1b3RhKG1lc3NhZ2UucXVvdGEpXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiB0cnVlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJEZWJ1Z1wiLFxuICAgICAgeyBoYW5kbGVyOiAoKSA9PiB7fSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiB0cnVlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJBY3Rpb25TdGFydFwiLFxuICAgICAgeyBoYW5kbGVyOiAoYWN0aW9uOiBBY3Rpb25TdGFydEV2ZW50KSA9PiB0aGlzLl9hY3Rpb25NYXAuc2V0KGFjdGlvbi5ndWlkLCBhY3Rpb24pLFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJBY3Rpb25SZXN1bHRcIixcbiAgICAgIHtcbiAgICAgICAgaGFuZGxlcjogKGFjdGlvbjogQWN0aW9uUmVzdWx0RXZlbnQpID0+IHRoaXMuX2FjdGlvbk1hcC5zZXQoYWN0aW9uLmd1aWQsIHsgLi4udGhpcy5fYWN0aW9uTWFwLmdldChhY3Rpb24uZ3VpZCksIC4uLmFjdGlvbiB9KSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiQWN0aW9uU3RvcFwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAoYWN0aW9uOiBBY3Rpb25TdG9wRXZlbnQpID0+IHRoaXMuX2FjdGlvbk1hcC5zZXQoYWN0aW9uLmd1aWQsIHsgLi4udGhpcy5fYWN0aW9uTWFwLmdldChhY3Rpb24uZ3VpZCksIC4uLmFjdGlvbiB9KSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiQ29udGV4dE1lc3NhZ2VcIixcbiAgICAgIHtcbiAgICAgICAgaGFuZGxlcjogKG1lc3NhZ2U6IENvbnRleHRNZXNzYWdlRXZlbnQpID0+IHRoaXMuX2F0dGFjaG1lbnRzLnB1c2gobWVzc2FnZS5tZXRhZGF0YSksXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIk1lc3NhZ2VcIixcbiAgICAgIHtcbiAgICAgICAgaGFuZGxlcjogKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkgPT4gdGhpcy5fcmVzcG9uc2UuYXQoLTEpIS5jb250ZW50ICs9IG1lc3NhZ2UgPz8gXCJcIixcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiSGlzdG9yeVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAoaGlzdG9yeTogSGlzdG9yeUV2ZW50KSA9PiB7XG4gICAgICAgICAgLy8gVGhlIENoYXRIaXN0b3J5IGlzIHVwZGF0ZWQ6IGl0IGlzIHRoZSBjdXJyZW50IGNvcHkgY29uY2F0ZW5hdGVkIHdpdGggdGhlIG5ldyBpdGVtcyBPTkxZIChpdCBjYW4gaGF2ZSBtdWx0aXBsZSBtZXNzYWdlczogdGhlIGNvbnRleHQgbWVzc2FnZXMgKyB0aGUgcmVzcG9uc2UgbWVzc2FnZSlcbiAgICAgICAgICAvLyBUaGlzIGlzIG1hbmRhdG9yeSB0byBub3QgbG9zZSB0aGUgcHJldmlvdXMgdXBkYXRlcyBvZiB0aGUgY2hhdEhpc3Rvcnkgd2hlbiB0aGUgYXNzaXN0YW50IGlzIHN0cmVhbWluZyBtdWx0aXBsZSBtZXNzYWdlIHN0ZXBzXG4gICAgICAgICAgdGhpcy5jaGF0SGlzdG9yeSA9IFsuLi50aGlzLmNoYXRIaXN0b3J5ISwgLi4uKGhpc3RvcnkuaGlzdG9yeS5zbGljZSh0aGlzLmNoYXRIaXN0b3J5IS5sZW5ndGgpKV07XG4gICAgICAgICAgLy8gRW1pdCB0aGUgdXBkYXRlZCBjaGF0IHVzYWdlIG1ldHJpY3NcbiAgICAgICAgICBpZiAoISF0aGlzLmNoYXRIaXN0b3J5LmF0KC0xKT8uYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoYXRVc2FnZU1ldHJpY3ModGhpcy5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcyEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lID0gaGlzdG9yeS5leGVjdXRpb25UaW1lO1xuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFxuICAgICAgXCJTdWdnZXN0ZWRBY3Rpb25zXCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBTdWdnZXN0ZWRBY3Rpb25zRXZlbnQpID0+IHtcbiAgICAgICAgICAvLyBTaW5jZSBhZnRlciB0aGUgXCJIaXN0b3J5XCIgYW5kIFwiTWVzc2FnZUJyZWFrXCIgdGhhdCB0aGlzIGV2ZW50IGlzIGNhdWdodCxcbiAgICAgICAgICAvLyAkc3VnZ2VzdGVkQWN0aW9uIG5lZWRzIHRvIGJlIHVwZGF0ZWQgZGlyZWN0bHkgdG8gdGhlIGxhc3QgdmlzaWJsZSBcImFzc2lzdGFudFwiIG1lc3NhZ2UgaW4gdGhlIF9yZXNwb25zZSBhbmQgdGhlIGNoYXRIaXN0b3J5XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2UuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uID0gKHRoaXMuX3Jlc3BvbnNlLmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMuJHN1Z2dlc3RlZEFjdGlvbiB8fCBbXSkuY29uY2F0KG1lc3NhZ2Uuc3VnZ2VzdGVkQWN0aW9ucyk7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmxhc3RWaXNpYmxlQXNzaXN0YW50TWVzc2FnZUluZGV4KHRoaXMuY2hhdEhpc3RvcnkpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuY2hhdEhpc3RvcnkhW2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uID0gKHRoaXMuY2hhdEhpc3RvcnkhW2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uIHx8IFtdKS5jb25jYXQobWVzc2FnZS5zdWdnZXN0ZWRBY3Rpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICAgIH1cbiAgICApO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXG4gICAgICBcIkRlYnVnRGlzcGxheVwiLFxuICAgICAge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogRGVidWdNZXNzYWdlRXZlbnQpID0+IHRoaXMuX2RlYnVnTWVzc2FnZXMgPSB0aGlzLl9kZWJ1Z01lc3NhZ2VzLmNvbmNhdChtZXNzYWdlKSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcbiAgICAgIFwiTWVzc2FnZUJyZWFrXCIsXG4gICAgICB7XG4gICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAvLyBHZW5lcmF0ZSBhdWRpdCBldmVudFxuICAgICAgICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAgICAgICAnZHVyYXRpb24nOiB0aGlzLl9leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgJ3RleHQnOiB0aGlzLmNoYXRIaXN0b3J5IS5hdCgtMSkhLmNvbnRlbnQsXG4gICAgICAgICAgICAncm9sZSc6IHRoaXMuY2hhdEhpc3RvcnkhLmF0KC0xKSEucm9sZSwgLy8gJ2Fzc2lzdGFudCdcbiAgICAgICAgICAgICdyYW5rJzogdGhpcy5jaGF0SGlzdG9yeSEubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgICdnZW5lcmF0aW9uLXRva2VuY291bnQnOiB0aGlzLmNoYXRIaXN0b3J5IS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcz8uY29tcGxldGlvblRva2VuQ291bnQsXG4gICAgICAgICAgICAncHJvbXB0LXRva2VuY291bnQnOiB0aGlzLmNoYXRIaXN0b3J5IS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcz8ucHJvbXB0VG9rZW5Db3VudCxcbiAgICAgICAgICAgICdhdHRhY2htZW50cyc6IEpTT04uc3RyaW5naWZ5KHRoaXMuX2F0dGFjaG1lbnRzLm1hcCgoeyByZWNvcmRJZCwgY29udGV4dElkLCBwYXJ0cywgdHlwZSB9KSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0czogcGFydHMubWFwKCh7IHBhcnRJZCwgdGV4dCB9KSA9PiAoeyBwYXJ0SWQsIHRleHQgfSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpKVxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ21lc3NhZ2UnLCBkZXRhaWxzKTtcbiAgICAgICAgICAvLyBQdXNoIGEgbmV3IGFzc2lzdGFudCBtZXNzYWdlIHRvIHRoZSBfcmVzcG9uc2UgYXJyYXkgT05MWSBpZiB0aGUgY29udGVudCBvZiB0aGUgbGFzdCBtZXNzYWdlIGlzIG5vdCBlbXB0eVxuICAgICAgICAgIGlmICh0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmNvbnRlbnQgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlLnB1c2goe3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZX19KVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgYW5kIHJlZ2lzdGVyIHRoZSBlbnRpcmUgX21lc3NhZ2VIYW5kbGVycyBtYXAgYnkgbWVyZ2luZyB0aGUgcHJvdmlkZWQgbWFwIHdpdGggdGhlIGRlZmF1bHQgb25lXG4gICAqIEBwYXJhbSBfbWVzc2FnZUhhbmRsZXJzXG4gICAqL1xuICBvdmVycmlkZU1lc3NhZ2VIYW5kbGVyczxUPihfbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxUPj4pIHtcbiAgICAvLyBDbGVhciB0aGUgYWxyZWFkeSByZWdpc3RlcmVkIGdsb2JhbCBjaGF0IGhhbmRsZXJzIGJlZm9yZSBtZXJnaW5nIHRoZSBuZXcgb25lc1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5mb3JFYWNoKChldmVudEhhbmRsZXIsIGV2ZW50TmFtZSkgPT4ge1xuICAgICAgaWYoZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcikge1xuICAgICAgICB0aGlzLnVuc3Vic2NyaWJlTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIE1lcmdlIHRoZSBuZXcgZXZlbnQgaGFuZGxlcnMgd2l0aCB0aGUgZXhpc3Rpbmcgb25lc1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycyA9IG5ldyBNYXAoWy4uLnRoaXMuX21lc3NhZ2VIYW5kbGVycywgLi4uX21lc3NhZ2VIYW5kbGVyc10pO1xuXG4gICAgLy8gUmVnaXN0ZXIgdGhlIGdsb2JhbCBoYW5kbGVycyBhbW9uZyB0aGUgbWVyZ2VkIG1hcFxuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5mb3JFYWNoKChldmVudEhhbmRsZXIsIGV2ZW50TmFtZSkgPT4ge1xuICAgICAgaWYoZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcikge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIGxpc3RlbmVyIGZvciBhIHNwZWNpZmljIGV2ZW50LlxuICAgKiBJZiBhIGxpc3RlbmVyIGZvciB0aGlzIHNhbWUgZXZlbnQgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcnJpZGRlbi5cbiAgICogSWYgdGhlIGxpc3RlbmVyIGhhcyBcImlzR2xvYmFsSGFuZGxlclwiIHNldCB0byB0cnVlLCBpdCB3aWxsIGJlIHJlZ2lzdGVyZWQgdG8gdGhlIGh1YiBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0gZXZlbnROYW1lIE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yXG4gICAqIEBwYXJhbSBldmVudEhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIHJlY2VpdmVkXG4gICAqL1xuICBhZGRNZXNzYWdlSGFuZGxlcjxUPihldmVudE5hbWU6IHN0cmluZywgZXZlbnRIYW5kbGVyOiBNZXNzYWdlSGFuZGxlcjxUPikge1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIER5bmFtaWNhbGx5IHJlZ2lzdGVyIGEgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAqIElmIGEgbGlzdGVuZXIgZm9yIHRoaXMgZXZlbnQgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcnJpZGRlbi5cbiAgICogQHBhcmFtIGV2ZW50TmFtZSBOYW1lIG9mIHRoZSBldmVudCB0byByZWdpc3RlciBhIGxpc3RlbmVyIGZvclxuICAgKiBAcGFyYW0gZXZlbnRIYW5kbGVyIFRoZSBoYW5kbGVyIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyByZWNlaXZlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI8VD4oZXZlbnROYW1lOiBzdHJpbmcsIGV2ZW50SGFuZGxlcjogTWVzc2FnZUhhbmRsZXI8VD4pIHtcbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbikge1xuICAgICAgY29uc29sZS5sb2coXCJObyBjb25uZWN0aW9uIGZvdW5kIHRvIHJlZ2lzdGVyIHRoZSBsaXN0ZW5lclwiICsgZXZlbnROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNvbm5lY3Rpb24ub24oZXZlbnROYW1lLCAoZGF0YTogVCkgPT4ge1xuICAgICAgZXZlbnRIYW5kbGVyLmhhbmRsZXIoZGF0YSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgbGlzdGVuZXIgZm9yIGEgc3BlY2lmaWMgZXZlbnQgZnJvbSB0aGUgX21lc3NhZ2VIYW5kbGVycyBtYXAgYW5kIHVuc3Vic2NyaWJlIGZyb20gcmVjZWl2aW5nIG1lc3NhZ2VzIGZvciB0aGlzIGV2ZW50IGZyb20gdGhlIFNpZ25hbFIgaHViLlxuICAgKiBAcGFyYW0gZXZlbnROYW1lIE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIgZm9yXG4gICAqL1xuICByZW1vdmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZykge1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICB0aGlzLnVuc3Vic2NyaWJlTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBmcm9tIHJlY2VpdmluZyBtZXNzYWdlcyBmb3IgYSBzcGVjaWZpYyBldmVudCBmcm9tIHRoZSBTaWduYWxSIGh1Yi5cbiAgICogQUxMIGl0cyByZWxhdGVkIGxpc3RlbmVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSBodWIgY29ubmVjdGlvblxuICAgKiBUaGlzIGlzIG5lZWRlZCB0byBwcmV2ZW50IGFjY3VtdWxhdGluZyBvbGQgbGlzdGVuZXJzIHdoZW4gb3ZlcnJpZGluZyB0aGUgZW50aXJlIF9tZXNzYWdlSGFuZGxlcnMgbWFwXG4gICAqIEBwYXJhbSBldmVudE5hbWUgTmFtZSBvZiB0aGUgZXZlbnRcbiAgICovXG4gIHByb3RlY3RlZCB1bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uIS5vZmYoZXZlbnROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbm5lY3Rpb24gdG8gdGhlIHNpZ25hbFIgd2Vic29ja2V0IGFuZCByZWdpc3RlciBkZWZhdWx0IGxpc3RlbmVycyB0byB0aGUgbWV0aG9kcyBkZWZpbmVkIGluIHRoZSBzZXJ2ZXIgaHViIGNsYXNzXG4gICAqIEBwYXJhbSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciB0aGUgY29ubmVjdGlvbi4gSXQgb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IG9wdGlvbnNcbiAgICogQHBhcmFtIGxvZ0xldmVsIERlZmluZSB0aGUgbG9nIGxldmVsIGRpc3BsYXllZCBpbiB0aGUgY29uc29sZVxuICAgKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBidWlsdFxuICAgKi9cbiAgYnVpbGRDb25uZWN0aW9uKG9wdGlvbnM/OiBDb25uZWN0aW9uT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXRoaXMuUkVRVUVTVF9VUkwpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiTm8gZW5kcG9pbnQgcHJvdmlkZWQgdG8gY29ubmVjdCB0aGUgd2Vic29ja2V0IHRvXCIpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBsb2dMZXZlbCA9IHRoaXMuX2dldExvZ0xldmVsKCk7XG4gICAgICB0aGlzLmNvbm5lY3Rpb24gPSB0aGlzLnNpZ25hbFJTZXJ2aWNlLmJ1aWxkQ29ubmVjdGlvbih0aGlzLlJFUVVFU1RfVVJMLCB7Li4udGhpcy5kZWZhdWx0T3B0aW9ucywgLi4ub3B0aW9uc30sIGxvZ0xldmVsLCB0cnVlKTtcblxuICAgICAgY29uc3Qgc2lnbmFsUlNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHRoaXMuY2hhdENvbmZpZyQudmFsdWU/LmNvbm5lY3Rpb25TZXR0aW5ncy5zaWduYWxSU2VydmVyVGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgICAgaWYgKHNpZ25hbFJTZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHMpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uLnNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHNpZ25hbFJTZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCB0aGUgY29ubmVjdGlvblxuICAgKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBzdGFydGVkXG4gICAqL1xuICBzdGFydENvbm5lY3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuc2lnbmFsUlNlcnZpY2Uuc3RhcnRDb25uZWN0aW9uKHRoaXMuY29ubmVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgY29ubmVjdGlvblxuICAgKiBAcmV0dXJucyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBzdG9wcGVkXG4gICAqL1xuICBzdG9wQ29ubmVjdGlvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5zaWduYWxSU2VydmljZS5zdG9wQ29ubmVjdGlvbih0aGlzLmNvbm5lY3Rpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VHJhbnNwb3J0cygpOiBIdHRwVHJhbnNwb3J0VHlwZSB7XG4gICAgc3dpdGNoICh0aGlzLmNoYXRDb25maWckLnZhbHVlPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUlRyYW5zcG9ydCkge1xuICAgICAgY2FzZSBcIldlYlNvY2tldHNcIjpcbiAgICAgICAgcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLldlYlNvY2tldHM7XG4gICAgICBjYXNlIFwiU2VydmVyU2VudEV2ZW50c1wiOlxuICAgICAgICByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuU2VydmVyU2VudEV2ZW50cztcbiAgICAgIGNhc2UgXCJMb25nUG9sbGluZ1wiOlxuICAgICAgICByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuTG9uZ1BvbGxpbmc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gSHR0cFRyYW5zcG9ydFR5cGUuTm9uZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXRMb2dMZXZlbCgpOiBMb2dMZXZlbCB7XG4gICAgc3dpdGNoICh0aGlzLmNoYXRDb25maWckLnZhbHVlPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUkxvZ0xldmVsKSB7XG4gICAgICBjYXNlIFwiQ3JpdGljYWxcIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLkNyaXRpY2FsOyAvLyBMb2cgbGV2ZWwgZm9yIGRpYWdub3N0aWMgbWVzc2FnZXMgdGhhdCBpbmRpY2F0ZSBhIGZhaWx1cmUgdGhhdCB3aWxsIHRlcm1pbmF0ZSB0aGUgZW50aXJlIGFwcGxpY2F0aW9uLlxuICAgICAgY2FzZSBcIkRlYnVnXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5EZWJ1ZzsgLy8gTG9nIGxldmVsIGZvciBsb3cgc2V2ZXJpdHkgZGlhZ25vc3RpYyBtZXNzYWdlcy5cbiAgICAgIGNhc2UgXCJFcnJvclwiOlxuICAgICAgICByZXR1cm4gTG9nTGV2ZWwuRXJyb3I7IC8vIExvZyBsZXZlbCBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcyB0aGF0IGluZGljYXRlIGEgZmFpbHVyZSBpbiB0aGUgY3VycmVudCBvcGVyYXRpb24uXG4gICAgICBjYXNlIFwiSW5mb3JtYXRpb25cIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLkluZm9ybWF0aW9uOyAvLyBMb2cgbGV2ZWwgZm9yIGluZm9ybWF0aW9uYWwgZGlhZ25vc3RpYyBtZXNzYWdlcy5cbiAgICAgIGNhc2UgXCJOb25lXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5Ob25lOyAvLyBUaGUgaGlnaGVzdCBwb3NzaWJsZSBsb2cgbGV2ZWwuIFVzZWQgd2hlbiBjb25maWd1cmluZyBsb2dnaW5nIHRvIGluZGljYXRlIHRoYXQgbm8gbG9nIG1lc3NhZ2VzIHNob3VsZCBiZSBlbWl0dGVkLlxuICAgICAgY2FzZSBcIlRyYWNlXCI6XG4gICAgICAgIHJldHVybiBMb2dMZXZlbC5UcmFjZTsgLy8gTG9nIGxldmVsIGZvciB2ZXJ5IGxvdyBzZXZlcml0eSBkaWFnbm9zdGljIG1lc3NhZ2VzLlxuICAgICAgY2FzZSBcIldhcm5pbmdcIjpcbiAgICAgICAgcmV0dXJuIExvZ0xldmVsLldhcm5pbmc7IC8vIExvZyBsZXZlbCBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcyB0aGF0IGluZGljYXRlIGEgbm9uLWZhdGFsIHByb2JsZW0uXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gTG9nTGV2ZWwuTm9uZTsgLy8gVGhlIGhpZ2hlc3QgcG9zc2libGUgbG9nIGxldmVsLiBVc2VkIHdoZW4gY29uZmlndXJpbmcgbG9nZ2luZyB0byBpbmRpY2F0ZSB0aGF0IG5vIGxvZyBtZXNzYWdlcyBzaG91bGQgYmUgZW1pdHRlZC5cbiAgICB9XG4gIH1cblxuICBnZXQgZGVmYXVsdE9wdGlvbnMoKTogQ29ubmVjdGlvbk9wdGlvbnMge1xuICAgIGxldCBoZWFkZXJzOiBNZXNzYWdlSGVhZGVycyA9IHtcbiAgICAgIFwic2luZXF1YS1mb3JjZS1jYW1lbC1jYXNlXCI6IFwidHJ1ZVwiLFxuICAgICAgXCJ4LWxhbmd1YWdlXCI6IHRoaXMuaW50bFNlcnZpY2UuY3VycmVudExvY2FsZS5uYW1lLFxuICAgICAgXCJ1aS1sYW5ndWFnZVwiOiB0aGlzLmludGxTZXJ2aWNlLmN1cnJlbnRMb2NhbGUubmFtZSxcbiAgICB9O1xuICAgIGlmICh0aGlzLmF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZXNzZWRDcmVkZW50aWFscykge1xuICAgICAgaGVhZGVycyA9IHsuLi5oZWFkZXJzLCBcInNpbmVxdWEtY3NyZi10b2tlblwiOiB0aGlzLmF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZXNzZWRDcmVkZW50aWFscy5kYXRhLmNzcmZUb2tlbn07XG4gICAgfTtcbiAgICAvLyBGb3IgdGhlIGZpcnN0IEdFVCByZXF1ZXN0IHNlbnQgYnkgc2lnbmFsUiB0byBzdGFydCBhIFdlYlNvY2tldCBwcm90b2NvbCxcbiAgICAvLyBhcyBmYXIgYXMgd2Uga25vdywgc2lnbmFsUiBvbmx5IGxldHMgdXMgdHdlYWsgdGhlIHJlcXVlc3Qgd2l0aCB0aGlzIGFjY2VzcyB0b2tlbiBmYWN0b3J5XG4gICAgLy8gc28gd2UgcGFzcyBhbG9uZyB0aGUgU2luZXF1YSBDU1JGIHRva2VuIHRvIHBhc3MgdGhlIENTUkYgY2hlY2suLlxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc3BvcnQ6IHRoaXMuX2dldFRyYW5zcG9ydHMoKSxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogdHJ1ZSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBhY2Nlc3NUb2tlbkZhY3Rvcnk6ICgpID0+IHRoaXMuYXV0aGVudGljYXRpb25TZXJ2aWNlLnByb2Nlc3NlZENyZWRlbnRpYWxzPy5kYXRhPy5jc3JmVG9rZW4gfHwgXCJcIlxuICAgIH1cbiAgfVxufVxuIl19
|