@sinequa/assistant 3.9.2 → 3.9.4

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.
Files changed (43) hide show
  1. package/chat/chat.component.d.ts +35 -38
  2. package/chat/chat.service.d.ts +190 -84
  3. package/chat/debug-message/debug-message-details/debug-message-details.component.d.ts +19 -0
  4. package/chat/debug-message/debug-message.component.d.ts +9 -12
  5. package/chat/debug-message/debug-message.service.d.ts +15 -0
  6. package/chat/documents-upload/document-list/document-list.component.d.ts +1 -0
  7. package/chat/public-api.d.ts +0 -2
  8. package/chat/saved-chats/i18n/en.json +1 -1
  9. package/chat/saved-chats/i18n/fr.json +1 -1
  10. package/chat/saved-chats/saved-chats.component.d.ts +1 -0
  11. package/chat/saved-chats/saved-chats.service.d.ts +27 -0
  12. package/chat/services/assistant-configuration.service.d.ts +34 -0
  13. package/chat/services/assistant-metadata.service.d.ts +18 -0
  14. package/chat/services/assistant-tokens-tracking.service.d.ts +23 -0
  15. package/chat/services/assistant-ws-frames.service.d.ts +50 -0
  16. package/chat/services/signalR-connection.service.d.ts +25 -0
  17. package/chat/types.d.ts +12 -3
  18. package/chat/utils/utils.service.d.ts +67 -0
  19. package/esm2022/chat/chat.component.mjs +198 -227
  20. package/esm2022/chat/chat.service.mjs +450 -267
  21. package/esm2022/chat/debug-message/debug-message-details/debug-message-details.component.mjs +43 -0
  22. package/esm2022/chat/debug-message/debug-message.component.mjs +27 -30
  23. package/esm2022/chat/debug-message/debug-message.service.mjs +52 -0
  24. package/esm2022/chat/dialogs/rename-saved-chat.component.mjs +6 -5
  25. package/esm2022/chat/documents-upload/document-list/document-list.component.mjs +4 -2
  26. package/esm2022/chat/public-api.mjs +1 -3
  27. package/esm2022/chat/saved-chats/saved-chats.component.mjs +11 -10
  28. package/esm2022/chat/saved-chats/saved-chats.service.mjs +161 -0
  29. package/esm2022/chat/services/assistant-configuration.service.mjs +167 -0
  30. package/esm2022/chat/services/assistant-metadata.service.mjs +63 -0
  31. package/esm2022/chat/services/assistant-tokens-tracking.service.mjs +53 -0
  32. package/esm2022/chat/services/assistant-ws-frames.service.mjs +388 -0
  33. package/esm2022/chat/services/signalR-connection.service.mjs +105 -0
  34. package/esm2022/chat/types.mjs +1 -1
  35. package/esm2022/chat/unified-plugins/embedded-image-reference.plugin.mjs +2 -3
  36. package/esm2022/chat/utils/utils.service.mjs +170 -0
  37. package/fesm2022/sinequa-assistant-chat.mjs +2000 -1652
  38. package/fesm2022/sinequa-assistant-chat.mjs.map +1 -1
  39. package/package.json +1 -1
  40. package/chat/rest-chat.service.d.ts +0 -31
  41. package/chat/websocket-chat.service.d.ts +0 -102
  42. package/esm2022/chat/rest-chat.service.mjs +0 -300
  43. package/esm2022/chat/websocket-chat.service.mjs +0 -659
@@ -0,0 +1,388 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { TranslocoService } from '@jsverse/transloco';
3
+ import { Observable, Subject, fromEvent, merge, of, throwError } from 'rxjs';
4
+ import { map, mergeMap, takeUntil, tap, take, switchMap, finalize } from 'rxjs/operators';
5
+ import { guid } from "@sinequa/atomic";
6
+ import { AppService } from './app.service';
7
+ import { AssistantUtils } from '../utils/utils.service';
8
+ import { NotificationsService } from './notification.service';
9
+ import * as i0 from "@angular/core";
10
+ export class AssistantWsFramesService {
11
+ constructor() {
12
+ this.appService = inject(AppService);
13
+ this.transloco = inject(TranslocoService);
14
+ this.assistantUtils = inject(AssistantUtils);
15
+ this.notificationsService = inject(NotificationsService);
16
+ this._messageHandlers = new Map();
17
+ this._actionMap = new Map();
18
+ this._progress = undefined;
19
+ this._attachments = [];
20
+ this._debugMessages = [];
21
+ }
22
+ init(context) {
23
+ this.context = context;
24
+ }
25
+ ensureInitialized() {
26
+ if (!this.context) {
27
+ throw new Error('AssistantWsFramesService not initialized. Call init() first.');
28
+ }
29
+ }
30
+ fetch(messages, query) {
31
+ this.ensureInitialized();
32
+ const context = this.context;
33
+ const assistantConfig = context.getAssistantConfig();
34
+ // Start streaming by invoking the Chat method
35
+ context.setStreamingStatus(true);
36
+ // Prepare the payload to send to the Chat method
37
+ const data = {
38
+ history: messages,
39
+ functions: assistantConfig.defaultValues.functions?.filter(func => func.enabled).map(func => func.name),
40
+ debug: assistantConfig.defaultValues.debug,
41
+ serviceSettings: {
42
+ service_id: assistantConfig.defaultValues.service_id,
43
+ model_id: assistantConfig.defaultValues.model_id,
44
+ top_p: assistantConfig.defaultValues.top_p,
45
+ temperature: assistantConfig.defaultValues.temperature,
46
+ max_tokens: assistantConfig.defaultValues.max_tokens,
47
+ ...assistantConfig.additionalServiceSettings
48
+ },
49
+ appQuery: {
50
+ app: this.appService.appName,
51
+ query
52
+ },
53
+ instanceId: context.getChatInstanceId(),
54
+ chatId: context.getChatId(),
55
+ genericChatErrorMessage: assistantConfig.globalSettings.genericChatErrorMessage ? this.transloco.translate(assistantConfig.globalSettings.genericChatErrorMessage) : ""
56
+ };
57
+ // Initialize the response with an empty assistant message
58
+ // here display: true is needed in order to be able to show the progress
59
+ // here messageId is needed but it is temporary and will be replaced by the correct messageId generated by the assistant when the message starts streaming
60
+ this._response = [{ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid() } }];
61
+ // Create a Subject to signal completion
62
+ const completion$ = new Subject();
63
+ // Create observables for each non-global handler in the _messageHandlers map (default and eventual custom ones) once it is triggered by the hub connection
64
+ const observables = Array
65
+ .from(this._messageHandlers.entries())
66
+ .filter(([eventName, eventHandler]) => !eventHandler.isGlobalHandler)
67
+ .map(([eventName, eventHandler]) => fromEvent(context.getHubConnection(), eventName).pipe(mergeMap((event) => {
68
+ // Wrap the handler in a try-catch block to prevent the entire stream from failing if an error occurs in a single handler
69
+ try {
70
+ // Execute the handler and emit the result
71
+ // 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
72
+ return of(eventHandler.handler(event));
73
+ }
74
+ catch (error) {
75
+ console.error(`Error in event handler for ${eventName}:`, error);
76
+ // Use throwError to propagate the error downstream
77
+ return throwError(() => new Error(`Error in event handler for ${eventName}: ${error}`));
78
+ }
79
+ })));
80
+ // Then merge them into a single observable in order to simulate the streaming behavior
81
+ const combined$ = merge(...observables).pipe(map(() => {
82
+ // Define $progress from the _actionMap
83
+ const actions = Array.from(this._actionMap.values());
84
+ this._progress = actions.length > 0
85
+ ? actions.map((a) => ({
86
+ title: a.displayName ?? "",
87
+ content: a.displayValue ?? "",
88
+ done: a.executionTime !== undefined,
89
+ time: a.executionTime,
90
+ }))
91
+ : undefined;
92
+ // Always update ONLY the first assistant message of the _response with the new $progress, $attachment and $debug
93
+ // Assuming that the first assistant message is always visible since the hub does not send hidden messages by design
94
+ // So even if the first assistant message is hidden (display: false), the _response[0] will and should contain :
95
+ // - $progress, $attachment and $debug
96
+ // - the content of the first visible assistant message in the workflow
97
+ // This is mandatory in order to match the behavior of consecutive messages and maintain consistency with the chatHistory
98
+ if (!!this._progress || this._attachments.length > 0 || this._debugMessages.length > 0) {
99
+ this._response[0].additionalProperties.$progress = this._progress;
100
+ this._response[0].additionalProperties.$attachment = this._attachments;
101
+ this._response[0].additionalProperties.$debug = this._debugMessages;
102
+ }
103
+ // Return the result
104
+ return { history: [...messages, ...this._response], executionTime: this._executionTime, executionTimeMilliseconds: this._executionTimeMilliseconds };
105
+ }),
106
+ // Complete the observable when completion$ emits
107
+ takeUntil(completion$));
108
+ // return a new Observable that emits the result of the combined stream and handles the eventual errors of the invocation of the Chat method
109
+ return new Observable(observer => {
110
+ // Subscribe to combined stream
111
+ combined$.subscribe({
112
+ next: (value) => observer.next(value),
113
+ error: (err) => observer.error(err)
114
+ });
115
+ // Invoke the Chat method and handle errors
116
+ context.getHubConnection().invoke('Chat', data)
117
+ .then(() => {
118
+ const chatHistory = context.getChatHistory();
119
+ // If a valid assistant message with (display: true) was found, update it
120
+ // and it should always the case
121
+ const index = this.assistantUtils.firstVisibleAssistantMessageIndex(chatHistory);
122
+ if (index !== -1) {
123
+ chatHistory[index].additionalProperties.$progress = this._progress;
124
+ chatHistory[index].additionalProperties.$attachment = this._attachments;
125
+ chatHistory[index].additionalProperties.$debug = this._debugMessages;
126
+ context.setChatHistory(chatHistory);
127
+ }
128
+ // Save/update the chat if savedChat enabled
129
+ if (assistantConfig.savedChatSettings.enabled && context.getChatHistory().some((msg) => msg.additionalProperties?.isUserInput === true)) {
130
+ context.isExistingSavedChat(context.getChatId()).pipe(take(1), switchMap((exists) => exists
131
+ ? context.updateSavedChat(context.getChatId(), undefined, context.getChatHistory())
132
+ : context.addSavedChat(context.getChatId(), context.getChatHistory()).pipe(tap(() => context.listSavedChat()))), finalize(() => context.setStreamingStatus(false))).subscribe({
133
+ next: () => { },
134
+ error: (error) => observer.error(error),
135
+ complete: () => observer.complete()
136
+ });
137
+ }
138
+ else {
139
+ context.setStreamingStatus(false);
140
+ observer.complete();
141
+ }
142
+ })
143
+ .catch(error => {
144
+ console.error('Error invoking Chat:', error);
145
+ context.setStreamingStatus(false);
146
+ // Emit the error to the newly created observable
147
+ observer.error(error);
148
+ // Return a resolved promise to handle the error and prevent unhandled promise rejection
149
+ return Promise.resolve();
150
+ })
151
+ .finally(() => {
152
+ // This block concerns ONLY the completion of the "Chat" method invocation.
153
+ // This means the completion of the combined$ stream.
154
+ // 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
155
+ this._response = []; // Clear the _response
156
+ this._actionMap.clear(); // Clear the _actionMap
157
+ this._progress = undefined; // Clear the _progress
158
+ this._attachments = []; // Clear the _attachments
159
+ this._debugMessages = []; // Clear the _debugMessages
160
+ this._executionTime = ""; // Clear the _executionTime
161
+ this._executionTimeMilliseconds = undefined; // Clear the _executionTimeMilliseconds
162
+ completion$.next(); // Emit a signal to complete the observables
163
+ completion$.complete(); // Complete the subject
164
+ });
165
+ });
166
+ }
167
+ initMessageHandlers() {
168
+ this.ensureInitialized();
169
+ const context = this.context;
170
+ this.addMessageHandler("Error", {
171
+ handler: (error) => {
172
+ if (error.indexOf('SavedChatList') !== -1) {
173
+ context.setSavedChatsErrorStatus(true);
174
+ }
175
+ console.error(error);
176
+ this.notificationsService.error(error);
177
+ },
178
+ isGlobalHandler: true
179
+ });
180
+ this.addMessageHandler("Quota", {
181
+ handler: (message) => {
182
+ try {
183
+ context.updateQuota(message.quota);
184
+ }
185
+ catch (error) {
186
+ console.error(error);
187
+ }
188
+ },
189
+ isGlobalHandler: true
190
+ });
191
+ this.addMessageHandler("Debug", { handler: () => { }, isGlobalHandler: true });
192
+ this.addMessageHandler("ActionStart", {
193
+ handler: (action) => this._actionMap.set(action.guid, action),
194
+ isGlobalHandler: false
195
+ });
196
+ this.addMessageHandler("ActionResult", {
197
+ handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
198
+ isGlobalHandler: false
199
+ });
200
+ this.addMessageHandler("ActionStop", {
201
+ handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
202
+ isGlobalHandler: false
203
+ });
204
+ this.addMessageHandler("ContextMessage", {
205
+ handler: (message) => { this._attachments.push(message.additionalProperties); },
206
+ isGlobalHandler: false
207
+ });
208
+ this.addMessageHandler("Message", {
209
+ handler: (message) => {
210
+ this._response.at(-1).content += message.delta ?? "";
211
+ this._response.at(-1).additionalProperties.messageId = message.messageId;
212
+ },
213
+ isGlobalHandler: false
214
+ });
215
+ this.addMessageHandler("History", {
216
+ handler: (history) => {
217
+ // 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)
218
+ // This is mandatory to not lose the previous updates of the chatHistory when the assistant is streaming multiple message steps
219
+ const currentChatHistory = (context.getChatHistory() || []);
220
+ const newHistory = [...currentChatHistory, ...(history.history.slice(currentChatHistory.length))];
221
+ context.setChatHistory(newHistory);
222
+ // Emit the updated chat usage metrics
223
+ const lastMessage = newHistory.at(-1);
224
+ if (lastMessage?.additionalProperties.usageMetrics) {
225
+ context.updateChatUsageMetrics(lastMessage.additionalProperties.usageMetrics);
226
+ }
227
+ this._executionTime = history.executionTime;
228
+ this._executionTimeMilliseconds = history.executionTimeMilliseconds;
229
+ },
230
+ isGlobalHandler: false
231
+ });
232
+ this.addMessageHandler("SuggestedActions", {
233
+ handler: (message) => {
234
+ // Since after the "History" and "MessageBreak" that this event is caught,
235
+ // $suggestedAction needs to be updated directly to the last visible "assistant" message in the _response and the chatHistory
236
+ this._response.at(-1).additionalProperties.$suggestedAction = (this._response.at(-1).additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
237
+ const chatHistory = context.getChatHistory();
238
+ const index = this.assistantUtils.lastVisibleAssistantMessageIndex(chatHistory);
239
+ if (index !== -1) {
240
+ chatHistory[index].additionalProperties.$suggestedAction = (chatHistory[index].additionalProperties.$suggestedAction || []).concat(message.suggestedActions);
241
+ context.setChatHistory(chatHistory);
242
+ }
243
+ },
244
+ isGlobalHandler: false
245
+ });
246
+ this.addMessageHandler("DebugDisplay", {
247
+ handler: (message) => this._debugMessages = this._debugMessages.concat(message),
248
+ isGlobalHandler: false
249
+ });
250
+ this.addMessageHandler("MessageBreak", {
251
+ handler: () => {
252
+ // Systematically happens right after the "History" event
253
+ // This is the moment when the assistant message is fully streamed
254
+ const assistantConfig = context.getAssistantConfig();
255
+ const chatHistory = context.getChatHistory();
256
+ if (!assistantConfig || !chatHistory || !chatHistory.length)
257
+ return;
258
+ const lastChatMessage = chatHistory.at(-1);
259
+ const details = {
260
+ 'duration': this._executionTimeMilliseconds !== undefined ? this._executionTimeMilliseconds : this._executionTime,
261
+ 'role': lastChatMessage.role,
262
+ 'rank': chatHistory.length,
263
+ 'message-id': lastChatMessage.additionalProperties.messageId,
264
+ 'generation-tokencount': lastChatMessage.additionalProperties.usageMetrics?.completionTokenCount,
265
+ 'prompt-tokencount': lastChatMessage.additionalProperties.usageMetrics?.promptTokenCount,
266
+ 'attachments': JSON.stringify(this._attachments.map(({ recordId, contextId, parts, type }) => ({
267
+ recordId,
268
+ contextId,
269
+ parts: parts.map(({ partId, text }) => {
270
+ if (!!assistantConfig.auditSettings?.logContent)
271
+ return { partId, text };
272
+ return { partId };
273
+ }),
274
+ type
275
+ })))
276
+ };
277
+ if (!!assistantConfig.auditSettings?.logContent) {
278
+ if (typeof lastChatMessage.content === 'string') {
279
+ details['text'] = lastChatMessage.content;
280
+ }
281
+ else if (Array.isArray(lastChatMessage.content)) {
282
+ details['text'] = lastChatMessage.content.find((msg) => msg.type === "text").text;
283
+ }
284
+ }
285
+ context.generateAuditEvent('ast-message.message', details);
286
+ // Push a new assistant message to the _response array ONLY if the content of the last message is not empty
287
+ if (this._response.at(-1).content !== "") {
288
+ this._response.push({ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid() } });
289
+ }
290
+ },
291
+ isGlobalHandler: false
292
+ });
293
+ }
294
+ overrideMessageHandlers(_messageHandlers) {
295
+ this.ensureInitialized();
296
+ // Clear the already registered global chat handlers before merging the new ones
297
+ this._messageHandlers.forEach((eventHandler, eventName) => {
298
+ if (eventHandler.isGlobalHandler) {
299
+ this.unsubscribeMessageHandler(eventName);
300
+ }
301
+ });
302
+ // Merge the new event handlers with the existing ones
303
+ this._messageHandlers = new Map([...this._messageHandlers, ..._messageHandlers]);
304
+ // Register the global handlers among the merged map
305
+ this._messageHandlers.forEach((eventHandler, eventName) => {
306
+ if (eventHandler.isGlobalHandler) {
307
+ this.registerMessageHandler(eventName, eventHandler);
308
+ }
309
+ });
310
+ }
311
+ addMessageHandler(eventName, eventHandler) {
312
+ this.ensureInitialized();
313
+ this._messageHandlers.set(eventName, eventHandler);
314
+ if (eventHandler.isGlobalHandler) {
315
+ this.registerMessageHandler(eventName, eventHandler);
316
+ }
317
+ }
318
+ registerMessageHandler(eventName, eventHandler) {
319
+ this.ensureInitialized();
320
+ const connection = this.context.getHubConnection();
321
+ if (!connection) {
322
+ console.log("No connection found to register the listener" + eventName);
323
+ return;
324
+ }
325
+ connection.on(eventName, (data) => {
326
+ eventHandler.handler(data);
327
+ });
328
+ }
329
+ removeMessageHandler(eventName) {
330
+ this.ensureInitialized();
331
+ this._messageHandlers.delete(eventName);
332
+ this.unsubscribeMessageHandler(eventName);
333
+ }
334
+ unsubscribeMessageHandler(eventName) {
335
+ this.ensureInitialized();
336
+ const connection = this.context.getHubConnection();
337
+ connection?.off(eventName);
338
+ }
339
+ stopGeneration() {
340
+ this.ensureInitialized();
341
+ const context = this.context;
342
+ const connection = context.getHubConnection();
343
+ // Start stopping generation by invoking the CancelTasks method
344
+ context.setStoppingGenerationStatus(true);
345
+ // Create a Subject to hold the result of the CancelTasks method
346
+ const stopGenerationSubject$ = new Subject();
347
+ connection.on('CancelTasks', (res) => {
348
+ // When the generation is stopped before streaming any VISIBLE assistant message, this means that $progress, $attachment and $debug properties will be lost.
349
+ // However, the "ContextMessage" frames will be persisted in the chatHistory and the assistant may reference them in the next generation.
350
+ // This leads to the problem of referencing undisplayed attachments in the next generation.
351
+ // 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.
352
+ // In the other hand, this leads to the problem of having many empty assistant messages in the chat history, if a stop generation happens multiple times in a row with no content generated yet.
353
+ // To solve this problem mentioned in the ticket ES-27024, we need to allow such operation ONLY if the last assistant message's content in the chat history is not empty.
354
+ const chatHistory = context.getChatHistory();
355
+ const isLastChatHistoryMessageAssistantContentEmpty = chatHistory?.length
356
+ && chatHistory.at(-1)?.role === "assistant"
357
+ && (chatHistory.at(-1)?.content === ""
358
+ ||
359
+ chatHistory.at(-1)?.content?.find((msg) => msg.type === "text")?.text === "");
360
+ if (this._response && this._response.length === 1 && this._response[0].content === "" && !isLastChatHistoryMessageAssistantContentEmpty) {
361
+ const newChatHistory = chatHistory ? [...chatHistory] : [];
362
+ newChatHistory.push({ role: "assistant", content: "", additionalProperties: { display: true, messageId: guid(), $progress: this._progress, $attachment: this._attachments, $debug: this._debugMessages } });
363
+ context.setChatHistory(newChatHistory);
364
+ }
365
+ // Emit the result of the CancelTasks method
366
+ stopGenerationSubject$.next(!!res);
367
+ // Complete the subject
368
+ stopGenerationSubject$.complete();
369
+ // Complete stopping generation
370
+ context.setStoppingGenerationStatus(false);
371
+ });
372
+ // Invoke the CancelTasks method and handle errors
373
+ connection.invoke('CancelTasks')
374
+ .catch(error => {
375
+ console.error('Error invoking CancelTasks:', error);
376
+ stopGenerationSubject$.error(new Error(error));
377
+ context.setStoppingGenerationStatus(false);
378
+ return Promise.resolve();
379
+ });
380
+ return stopGenerationSubject$.asObservable();
381
+ }
382
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
383
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService }); }
384
+ }
385
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssistantWsFramesService, decorators: [{
386
+ type: Injectable
387
+ }] });
388
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzaXN0YW50LXdzLWZyYW1lcy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvc2VydmljZXMvYXNzaXN0YW50LXdzLWZyYW1lcy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM3RSxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFMUYsT0FBTyxFQUFFLElBQUksRUFBUyxNQUFNLGlCQUFpQixDQUFDO0FBMkI5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUF5QjlELE1BQU0sT0FBTyx3QkFBd0I7SUFEckM7UUFJVSxlQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2hDLGNBQVMsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNyQyxtQkFBYyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN4Qyx5QkFBb0IsR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUVwRCxxQkFBZ0IsR0FBcUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUUvRCxlQUFVLEdB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Q0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILGtEQUFrRDtRQUNsRCxVQUFVLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQzthQUM3QixLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLDZCQUE2QixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELHNCQUFzQixDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ3pELE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztRQUVMLE9BQU8sc0JBQXNCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDL0MsQ0FBQzsrR0EvWlUsd0JBQXdCO21IQUF4Qix3QkFBd0I7OzRGQUF4Qix3QkFBd0I7a0JBRHBDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh1YkNvbm5lY3Rpb24gfSBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xuaW1wb3J0IHsgVHJhbnNsb2NvU2VydmljZSB9IGZyb20gJ0Bqc3ZlcnNlL3RyYW5zbG9jbyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBmcm9tRXZlbnQsIG1lcmdlLCBvZiwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBtZXJnZU1hcCwgdGFrZVVudGlsLCB0YXAsIHRha2UsIHN3aXRjaE1hcCwgZmluYWxpemUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGd1aWQsIFF1ZXJ5IH0gZnJvbSBcIkBzaW5lcXVhL2F0b21pY1wiO1xuXG5pbXBvcnQge1xuICBBY3Rpb25NZXNzYWdlLFxuICBBY3Rpb25SZXN1bHRFdmVudCxcbiAgQWN0aW9uU3RhcnRFdmVudCxcbiAgQWN0aW9uU3RvcEV2ZW50LFxuICBDaGF0Q29uZmlnLFxuICBDaGF0Q29udGV4dEF0dGFjaG1lbnQsXG4gIENoYXRNZXNzYWdlLFxuICBDaGF0UGF5bG9hZCxcbiAgQ2hhdFByb2dyZXNzLFxuICBDaGF0UmVzcG9uc2UsXG4gIENoYXRVc2FnZU1ldHJpY3MsXG4gIENvbnRleHRNZXNzYWdlRXZlbnQsXG4gIERlYnVnTWVzc2FnZSxcbiAgRGVidWdNZXNzYWdlRXZlbnQsXG4gIEVycm9yRXZlbnQsXG4gIEhpc3RvcnlFdmVudCxcbiAgTWVzc2FnZUhhbmRsZXIsXG4gIE1lc3NhZ2VFdmVudCxcbiAgUXVvdGEsXG4gIFF1b3RhRXZlbnQsXG4gIFNhdmVkQ2hhdFJlc3BvbnNlLFxuICBTdWdnZXN0ZWRBY3Rpb25zRXZlbnRcbn0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQgeyBBcHBTZXJ2aWNlIH0gZnJvbSAnLi9hcHAuc2VydmljZSc7XG5pbXBvcnQgeyBBc3Npc3RhbnRVdGlscyB9IGZyb20gJy4uL3V0aWxzL3V0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uc1NlcnZpY2UgfSBmcm9tICcuL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IE1lc3NhZ2VDb250ZW50LCBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tICcuLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2lzdGFudFdzRnJhbWVzQ29udGV4dCB7XG4gIGdldEFzc2lzdGFudENvbmZpZzogKCkgPT4gQ2hhdENvbmZpZyB8IHVuZGVmaW5lZDtcbiAgZ2V0Q2hhdEluc3RhbmNlSWQ6ICgpID0+IHN0cmluZztcbiAgZ2V0Q2hhdElkOiAoKSA9PiBzdHJpbmc7XG4gIGdldEh1YkNvbm5lY3Rpb246ICgpID0+IEh1YkNvbm5lY3Rpb24gfCB1bmRlZmluZWQ7XG4gIGdldENoYXRIaXN0b3J5OiAoKSA9PiBDaGF0TWVzc2FnZVtdIHwgdW5kZWZpbmVkO1xuXG4gIHNldFN0cmVhbWluZ1N0YXR1czogKGlzU3RyZWFtaW5nOiBib29sZWFuKSA9PiB2b2lkO1xuICBzZXRDaGF0SGlzdG9yeTogKGhpc3Rvcnk6IENoYXRNZXNzYWdlW10gfCB1bmRlZmluZWQpID0+IHZvaWQ7XG4gIHNldFN0b3BwaW5nR2VuZXJhdGlvblN0YXR1czogKGlzU3RvcHBpbmc6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHNldFNhdmVkQ2hhdHNFcnJvclN0YXR1czogKGhhc0Vycm9yOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIHVwZGF0ZVF1b3RhOiAocXVvdGE6IFF1b3RhLCBwcm9wYWdhdGVFcnJvcj86IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUNoYXRVc2FnZU1ldHJpY3M6IChtZXRyaWNzOiBDaGF0VXNhZ2VNZXRyaWNzKSA9PiB2b2lkO1xuICBnZW5lcmF0ZUF1ZGl0RXZlbnQ6ICh0eXBlOiBzdHJpbmcsIGRldGFpbHM6IFJlY29yZDxzdHJpbmcsIGFueT4sIGlkPzogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBhZGRTYXZlZENoYXQ6IChpZDogc3RyaW5nLCBtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSkgPT4gT2JzZXJ2YWJsZTxTYXZlZENoYXRSZXNwb25zZT47XG4gIHVwZGF0ZVNhdmVkQ2hhdDogKGlkOiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIG1lc3NhZ2VzPzogQ2hhdE1lc3NhZ2VbXSkgPT4gT2JzZXJ2YWJsZTxTYXZlZENoYXRSZXNwb25zZT47XG4gIGxpc3RTYXZlZENoYXQ6ICgpID0+IHZvaWQ7XG4gIGlzRXhpc3RpbmdTYXZlZENoYXQ6IChpZDogc3RyaW5nKSA9PiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQXNzaXN0YW50V3NGcmFtZXNTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBjb250ZXh0OiBBc3Npc3RhbnRXc0ZyYW1lc0NvbnRleHQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBhcHBTZXJ2aWNlID0gaW5qZWN0KEFwcFNlcnZpY2UpO1xuICBwcml2YXRlIHRyYW5zbG9jbyA9IGluamVjdChUcmFuc2xvY29TZXJ2aWNlKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRVdGlscyA9IGluamVjdChBc3Npc3RhbnRVdGlscyk7XG4gIHByaXZhdGUgbm90aWZpY2F0aW9uc1NlcnZpY2UgPSBpbmplY3QoTm90aWZpY2F0aW9uc1NlcnZpY2UpO1xuXG4gIHByaXZhdGUgX21lc3NhZ2VIYW5kbGVyczogTWFwPHN0cmluZywgTWVzc2FnZUhhbmRsZXI8YW55Pj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgX3Jlc3BvbnNlOiBDaGF0TWVzc2FnZVtdO1xuICBwcml2YXRlIF9hY3Rpb25NYXAgPSBuZXcgTWFwPHN0cmluZywgQWN0aW9uTWVzc2FnZT4oKTtcbiAgcHJpdmF0ZSBfcHJvZ3Jlc3M6IENoYXRQcm9ncmVzc1tdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBwcml2YXRlIF9leGVjdXRpb25UaW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHM/OiBudW1iZXI7XG4gIHByaXZhdGUgX2F0dGFjaG1lbnRzOiBDaGF0Q29udGV4dEF0dGFjaG1lbnRbXSA9IFtdO1xuICBwcml2YXRlIF9kZWJ1Z01lc3NhZ2VzOiBEZWJ1Z01lc3NhZ2VbXSA9IFtdO1xuXG4gIHB1YmxpYyBpbml0KGNvbnRleHQ6IEFzc2lzdGFudFdzRnJhbWVzQ29udGV4dCk6IHZvaWQge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUluaXRpYWxpemVkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Fzc2lzdGFudFdzRnJhbWVzU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LicpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSwgcXVlcnk6IFF1ZXJ5KTogT2JzZXJ2YWJsZTxDaGF0UmVzcG9uc2U+IHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuY29udGV4dCE7XG4gICAgY29uc3QgYXNzaXN0YW50Q29uZmlnID0gY29udGV4dC5nZXRBc3Npc3RhbnRDb25maWcoKSE7XG5cbiAgICAgLy8gU3RhcnQgc3RyZWFtaW5nIGJ5IGludm9raW5nIHRoZSBDaGF0IG1ldGhvZFxuICAgIGNvbnRleHQuc2V0U3RyZWFtaW5nU3RhdHVzKHRydWUpO1xuXG4gICAgLy8gUHJlcGFyZSB0aGUgcGF5bG9hZCB0byBzZW5kIHRvIHRoZSBDaGF0IG1ldGhvZFxuICAgIGNvbnN0IGRhdGE6IENoYXRQYXlsb2FkID0ge1xuICAgICAgaGlzdG9yeTogbWVzc2FnZXMsXG4gICAgICBmdW5jdGlvbnM6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkKS5tYXAoZnVuYyA9PiBmdW5jLm5hbWUpLFxuICAgICAgZGVidWc6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLmRlYnVnLFxuICAgICAgc2VydmljZVNldHRpbmdzOiB7XG4gICAgICAgIHNlcnZpY2VfaWQ6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLnNlcnZpY2VfaWQsXG4gICAgICAgIG1vZGVsX2lkOiBhc3Npc3RhbnRDb25maWcuZGVmYXVsdFZhbHVlcy5tb2RlbF9pZCxcbiAgICAgICAgdG9wX3A6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLnRvcF9wLFxuICAgICAgICB0ZW1wZXJhdHVyZTogYXNzaXN0YW50Q29uZmlnLmRlZmF1bHRWYWx1ZXMudGVtcGVyYXR1cmUsXG4gICAgICAgIG1heF90b2tlbnM6IGFzc2lzdGFudENvbmZpZy5kZWZhdWx0VmFsdWVzLm1heF90b2tlbnMsXG4gICAgICAgIC4uLmFzc2lzdGFudENvbmZpZy5hZGRpdGlvbmFsU2VydmljZVNldHRpbmdzXG4gICAgICB9LFxuICAgICAgYXBwUXVlcnk6IHtcbiAgICAgICAgYXBwOiB0aGlzLmFwcFNlcnZpY2UuYXBwTmFtZSxcbiAgICAgICAgcXVlcnlcbiAgICAgIH0sXG4gICAgICBpbnN0YW5jZUlkOiBjb250ZXh0LmdldENoYXRJbnN0YW5jZUlkKCksXG4gICAgICBjaGF0SWQ6IGNvbnRleHQuZ2V0Q2hhdElkKCksXG4gICAgICBnZW5lcmljQ2hhdEVycm9yTWVzc2FnZTogYXNzaXN0YW50Q29uZmlnLmdsb2JhbFNldHRpbmdzLmdlbmVyaWNDaGF0RXJyb3JNZXNzYWdlID8gdGhpcy50cmFuc2xvY28udHJhbnNsYXRlKGFzc2lzdGFudENvbmZpZy5nbG9iYWxTZXR0aW5ncy5nZW5lcmljQ2hhdEVycm9yTWVzc2FnZSkgOiBcIlwiXG4gICAgfTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIHJlc3BvbnNlIHdpdGggYW4gZW1wdHkgYXNzaXN0YW50IG1lc3NhZ2VcbiAgICAvLyBoZXJlIGRpc3BsYXk6IHRydWUgaXMgbmVlZGVkIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gc2hvdyB0aGUgcHJvZ3Jlc3NcbiAgICAvLyBoZXJlIG1lc3NhZ2VJZCBpcyBuZWVkZWQgYnV0IGl0IGlzIHRlbXBvcmFyeSBhbmQgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgY29ycmVjdCBtZXNzYWdlSWQgZ2VuZXJhdGVkIGJ5IHRoZSBhc3Npc3RhbnQgd2hlbiB0aGUgbWVzc2FnZSBzdGFydHMgc3RyZWFtaW5nXG4gICAgdGhpcy5fcmVzcG9uc2UgPSBbeyByb2xlOiBcImFzc2lzdGFudFwiLCBjb250ZW50OiBcIlwiLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH1dO1xuXG4gICAgLy8gQ3JlYXRlIGEgU3ViamVjdCB0byBzaWduYWwgY29tcGxldGlvblxuICAgIGNvbnN0IGNvbXBsZXRpb24kID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8vIENyZWF0ZSBvYnNlcnZhYmxlcyBmb3IgZWFjaCBub24tZ2xvYmFsIGhhbmRsZXIgaW4gdGhlIF9tZXNzYWdlSGFuZGxlcnMgbWFwIChkZWZhdWx0IGFuZCBldmVudHVhbCBjdXN0b20gb25lcykgb25jZSBpdCBpcyB0cmlnZ2VyZWQgYnkgdGhlIGh1YiBjb25uZWN0aW9uXG4gICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSBBcnJheVxuICAgICAgLmZyb20odGhpcy5fbWVzc2FnZUhhbmRsZXJzLmVudHJpZXMoKSlcbiAgICAgIC5maWx0ZXIoKFtldmVudE5hbWUsIGV2ZW50SGFuZGxlcl0pID0+ICFldmVudEhhbmRsZXIuaXNHbG9iYWxIYW5kbGVyKVxuICAgICAgLm1hcCgoW2V2ZW50TmFtZSwgZXZlbnRIYW5kbGVyXSkgPT4gZnJvbUV2ZW50PGFueT4oY29udGV4dC5nZXRIdWJDb25uZWN0aW9uKCkhLCBldmVudE5hbWUpLnBpcGUoXG4gICAgICAgICAgbWVyZ2VNYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBXcmFwIHRoZSBoYW5kbGVyIGluIGEgdHJ5LWNhdGNoIGJsb2NrIHRvIHByZXZlbnQgdGhlIGVudGlyZSBzdHJlYW0gZnJvbSBmYWlsaW5nIGlmIGFuIGVycm9yIG9jY3VycyBpbiBhIHNpbmdsZSBoYW5kbGVyXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyBFeGVjdXRlIHRoZSBoYW5kbGVyIGFuZCBlbWl0IHRoZSByZXN1bHRcbiAgICAgICAgICAgICAgLy8gTkI6IGhlcmUgd2UgY291bGQgdXNlIFtldmVudEhhbmRsZXIuaGFuZGxlcihldmVudCldIHdoaWNoIGJlaGluZCB0aGUgc2NlbmVzIG1lcmdlTWFwIGludGVycHJldHMgdGhpcyBhcnJheSBhcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggb25lIGl0ZW0sIHdoaWNoIGl0IHRoZW4gZW1pdHNcbiAgICAgICAgICAgICAgcmV0dXJuIG9mKGV2ZW50SGFuZGxlci5oYW5kbGVyKGV2ZW50KSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06YCwgZXJyb3IpO1xuICAgICAgICAgICAgICAvLyBVc2UgdGhyb3dFcnJvciB0byBwcm9wYWdhdGUgdGhlIGVycm9yIGRvd25zdHJlYW1cbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKGBFcnJvciBpbiBldmVudCBoYW5kbGVyIGZvciAke2V2ZW50TmFtZX06ICR7ZXJyb3J9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICkpO1xuXG4gICAgLy8gVGhlbiBtZXJnZSB0aGVtIGludG8gYSBzaW5nbGUgb2JzZXJ2YWJsZSBpbiBvcmRlciB0byBzaW11bGF0ZSB0aGUgc3RyZWFtaW5nIGJlaGF2aW9yXG4gICAgY29uc3QgY29tYmluZWQkID0gbWVyZ2UoLi4ub2JzZXJ2YWJsZXMpLnBpcGUoXG4gICAgICBtYXAoKCkgPT4ge1xuICAgICAgICAvLyBEZWZpbmUgJHByb2dyZXNzIGZyb20gdGhlIF9hY3Rpb25NYXBcbiAgICAgICAgY29uc3QgYWN0aW9ucyA9IEFycmF5LmZyb20odGhpcy5fYWN0aW9uTWFwLnZhbHVlcygpKTtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSBhY3Rpb25zLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhY3Rpb25zLm1hcCgoYSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGEuZGlzcGxheU5hbWUgPz8gXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogYS5kaXNwbGF5VmFsdWUgPz8gXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZTogYS5leGVjdXRpb25UaW1lICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWU6IGEuZXhlY3V0aW9uVGltZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBBbHdheXMgdXBkYXRlIE9OTFkgdGhlIGZpcnN0IGFzc2lzdGFudCBtZXNzYWdlIG9mIHRoZSBfcmVzcG9uc2Ugd2l0aCB0aGUgbmV3ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1Z1xuICAgICAgICAvLyBBc3N1bWluZyB0aGF0IHRoZSBmaXJzdCBhc3Npc3RhbnQgbWVzc2FnZSBpcyBhbHdheXMgdmlzaWJsZSBzaW5jZSB0aGUgaHViIGRvZXMgbm90IHNlbmQgaGlkZGVuIG1lc3NhZ2VzIGJ5IGRlc2lnblxuICAgICAgICAvLyBTbyBldmVuIGlmIHRoZSBmaXJzdCBhc3Npc3RhbnQgbWVzc2FnZSBpcyBoaWRkZW4gKGRpc3BsYXk6IGZhbHNlKSwgdGhlIF9yZXNwb25zZVswXSB3aWxsIGFuZCBzaG91bGQgY29udGFpbiA6XG4gICAgICAgIC8vICAtICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1Z1xuICAgICAgICAvLyAgLSB0aGUgY29udGVudCBvZiB0aGUgZmlyc3QgdmlzaWJsZSBhc3Npc3RhbnQgbWVzc2FnZSBpbiB0aGUgd29ya2Zsb3dcbiAgICAgICAgLy8gVGhpcyBpcyBtYW5kYXRvcnkgaW4gb3JkZXIgdG8gbWF0Y2ggdGhlIGJlaGF2aW9yIG9mIGNvbnNlY3V0aXZlIG1lc3NhZ2VzIGFuZCBtYWludGFpbiBjb25zaXN0ZW5jeSB3aXRoIHRoZSBjaGF0SGlzdG9yeVxuICAgICAgICBpZighIXRoaXMuX3Byb2dyZXNzIHx8IHRoaXMuX2F0dGFjaG1lbnRzLmxlbmd0aCA+IDAgfHwgdGhpcy5fZGVidWdNZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VbMF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzID0gdGhpcy5fcHJvZ3Jlc3M7XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2VbMF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgPSB0aGlzLl9hdHRhY2htZW50cztcbiAgICAgICAgICB0aGlzLl9yZXNwb25zZVswXS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGVidWcgPSB0aGlzLl9kZWJ1Z01lc3NhZ2VzO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiB0aGUgcmVzdWx0XG4gICAgICAgIHJldHVybiB7IGhpc3Rvcnk6IFsuLi5tZXNzYWdlcywgLi4udGhpcy5fcmVzcG9uc2VdLCBleGVjdXRpb25UaW1lOiB0aGlzLl9leGVjdXRpb25UaW1lLCBleGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzOiB0aGlzLl9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzIH07XG4gICAgICB9KSxcbiAgICAgIC8vIENvbXBsZXRlIHRoZSBvYnNlcnZhYmxlIHdoZW4gY29tcGxldGlvbiQgZW1pdHNcbiAgICAgIHRha2VVbnRpbChjb21wbGV0aW9uJCksXG4gICAgKTtcblxuICAgIC8vIHJldHVybiBhIG5ldyBPYnNlcnZhYmxlIHRoYXQgZW1pdHMgdGhlIHJlc3VsdCBvZiB0aGUgY29tYmluZWQgc3RyZWFtIGFuZCBoYW5kbGVzIHRoZSBldmVudHVhbCBlcnJvcnMgb2YgdGhlIGludm9jYXRpb24gb2YgdGhlIENoYXQgbWV0aG9kXG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgIC8vIFN1YnNjcmliZSB0byBjb21iaW5lZCBzdHJlYW1cbiAgICAgIGNvbWJpbmVkJC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAodmFsdWUpID0+IG9ic2VydmVyLm5leHQodmFsdWUpLFxuICAgICAgICBlcnJvcjogKGVycikgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEludm9rZSB0aGUgQ2hhdCBtZXRob2QgYW5kIGhhbmRsZSBlcnJvcnNcbiAgICAgIGNvbnRleHQuZ2V0SHViQ29ubmVjdGlvbigpIS5pbnZva2UoJ0NoYXQnLCBkYXRhKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hhdEhpc3RvcnkgPSBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhO1xuICAgICAgICAgIC8vIElmIGEgdmFsaWQgYXNzaXN0YW50IG1lc3NhZ2Ugd2l0aCAoZGlzcGxheTogdHJ1ZSkgd2FzIGZvdW5kLCB1cGRhdGUgaXRcbiAgICAgICAgICAvLyBhbmQgaXQgc2hvdWxkIGFsd2F5cyB0aGUgY2FzZVxuICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5maXJzdFZpc2libGVBc3Npc3RhbnRNZXNzYWdlSW5kZXgoY2hhdEhpc3RvcnkpO1xuICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNoYXRIaXN0b3J5W2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgPSB0aGlzLl9wcm9ncmVzcztcbiAgICAgICAgICAgIGNoYXRIaXN0b3J5W2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kYXR0YWNobWVudCA9IHRoaXMuX2F0dGFjaG1lbnRzO1xuICAgICAgICAgICAgY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkZWJ1ZyA9IHRoaXMuX2RlYnVnTWVzc2FnZXM7XG4gICAgICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KGNoYXRIaXN0b3J5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTYXZlL3VwZGF0ZSB0aGUgY2hhdCBpZiBzYXZlZENoYXQgZW5hYmxlZFxuICAgICAgICAgIGlmIChhc3Npc3RhbnRDb25maWcuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCAmJiBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhLnNvbWUoKG1zZykgPT4gbXNnLmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy5pc1VzZXJJbnB1dCA9PT0gdHJ1ZSkpIHtcbiAgICAgICAgICAgIGNvbnRleHQuaXNFeGlzdGluZ1NhdmVkQ2hhdChjb250ZXh0LmdldENoYXRJZCgpKS5waXBlKFxuICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICBzd2l0Y2hNYXAoKGV4aXN0cykgPT5cbiAgICAgICAgICAgICAgICBleGlzdHNcbiAgICAgICAgICAgICAgICAgID8gY29udGV4dC51cGRhdGVTYXZlZENoYXQoY29udGV4dC5nZXRDaGF0SWQoKSwgdW5kZWZpbmVkLCBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhKVxuICAgICAgICAgICAgICAgICAgOiBjb250ZXh0LmFkZFNhdmVkQ2hhdChjb250ZXh0LmdldENoYXRJZCgpLCBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIHRhcCgoKSA9PiBjb250ZXh0Lmxpc3RTYXZlZENoYXQoKSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiBjb250ZXh0LnNldFN0cmVhbWluZ1N0YXR1cyhmYWxzZSkpXG4gICAgICAgICAgICApLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgIG5leHQ6ICgpID0+IHt9LFxuICAgICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiBvYnNlcnZlci5lcnJvcihlcnJvciksXG4gICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5zZXRTdHJlYW1pbmdTdGF0dXMoZmFsc2UpO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW52b2tpbmcgQ2hhdDonLCBlcnJvcik7XG4gICAgICAgICAgY29udGV4dC5zZXRTdHJlYW1pbmdTdGF0dXMoZmFsc2UpO1xuICAgICAgICAgIC8vIEVtaXQgdGhlIGVycm9yIHRvIHRoZSBuZXdseSBjcmVhdGVkIG9ic2VydmFibGVcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgLy8gUmV0dXJuIGEgcmVzb2x2ZWQgcHJvbWlzZSB0byBoYW5kbGUgdGhlIGVycm9yIGFuZCBwcmV2ZW50IHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgIC8vIFRoaXMgYmxvY2sgY29uY2VybnMgT05MWSB0aGUgY29tcGxldGlvbiBvZiB0aGUgXCJDaGF0XCIgbWV0aG9kIGludm9jYXRpb24uXG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGUgY29tcGxldGlvbiBvZiB0aGUgY29tYmluZWQkIHN0cmVhbS5cbiAgICAgICAgICAvLyBJdCBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCB0aGUgY29tcGxldGlvbiBvZiB0aGUgZW50aXJlIGZldGNoIG1ldGhvZCAodGhlIG9ic2VydmFibGUgcmV0dXJuZWQgYnkgZmV0Y2gpIGFuZCB3aGljaCBkZXBlbmRzIG9uIHRoZSBjb21wbGV0aW9uIG9mIHRoZSBzYXZlIGNoYXQgYWN0aW9uIGlmIGVuYWJsZWRcbiAgICAgICAgICB0aGlzLl9yZXNwb25zZSA9IFtdOyAvLyBDbGVhciB0aGUgX3Jlc3BvbnNlXG4gICAgICAgICAgdGhpcy5fYWN0aW9uTWFwLmNsZWFyKCk7IC8vIENsZWFyIHRoZSBfYWN0aW9uTWFwXG4gICAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSB1bmRlZmluZWQ7IC8vIENsZWFyIHRoZSBfcHJvZ3Jlc3NcbiAgICAgICAgICB0aGlzLl9hdHRhY2htZW50cyA9IFtdOyAvLyBDbGVhciB0aGUgX2F0dGFjaG1lbnRzXG4gICAgICAgICAgdGhpcy5fZGVidWdNZXNzYWdlcyA9IFtdOyAvLyBDbGVhciB0aGUgX2RlYnVnTWVzc2FnZXNcbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lID0gXCJcIjsgLy8gQ2xlYXIgdGhlIF9leGVjdXRpb25UaW1lXG4gICAgICAgICAgdGhpcy5fZXhlY3V0aW9uVGltZU1pbGxpc2Vjb25kcyA9IHVuZGVmaW5lZDsgLy8gQ2xlYXIgdGhlIF9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzXG4gICAgICAgICAgY29tcGxldGlvbiQubmV4dCgpOyAvLyBFbWl0IGEgc2lnbmFsIHRvIGNvbXBsZXRlIHRoZSBvYnNlcnZhYmxlc1xuICAgICAgICAgIGNvbXBsZXRpb24kLmNvbXBsZXRlKCk7IC8vIENvbXBsZXRlIHRoZSBzdWJqZWN0XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGluaXRNZXNzYWdlSGFuZGxlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQhO1xuXG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkVycm9yXCIsIHtcbiAgICAgICAgaGFuZGxlcjogKGVycm9yOiBFcnJvckV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yLmluZGV4T2YoJ1NhdmVkQ2hhdExpc3QnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc2V0U2F2ZWRDaGF0c0Vycm9yU3RhdHVzKHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLmVycm9yKGVycm9yKTtcbiAgICAgICAgfSxcbiAgICAgICAgaXNHbG9iYWxIYW5kbGVyOiB0cnVlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiUXVvdGFcIiwge1xuICAgICAgICBoYW5kbGVyOiAobWVzc2FnZTogUXVvdGFFdmVudCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb250ZXh0LnVwZGF0ZVF1b3RhKG1lc3NhZ2UucXVvdGEpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGlzR2xvYmFsSGFuZGxlcjogdHJ1ZVxuICAgICAgfVxuICAgICk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkRlYnVnXCIsIHsgaGFuZGxlcjogKCkgPT4ge30sIGlzR2xvYmFsSGFuZGxlcjogdHJ1ZSB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiQWN0aW9uU3RhcnRcIiwge1xuICAgICAgaGFuZGxlcjogKGFjdGlvbjogQWN0aW9uU3RhcnRFdmVudCkgPT4gdGhpcy5fYWN0aW9uTWFwLnNldChhY3Rpb24uZ3VpZCwgYWN0aW9uKSxcbiAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiQWN0aW9uUmVzdWx0XCIsIHtcbiAgICAgIGhhbmRsZXI6IChhY3Rpb246IEFjdGlvblJlc3VsdEV2ZW50KSA9PiB0aGlzLl9hY3Rpb25NYXAuc2V0KGFjdGlvbi5ndWlkLCB7IC4uLnRoaXMuX2FjdGlvbk1hcC5nZXQoYWN0aW9uLmd1aWQpLCAuLi5hY3Rpb24gfSksXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkFjdGlvblN0b3BcIiwge1xuICAgICAgaGFuZGxlcjogKGFjdGlvbjogQWN0aW9uU3RvcEV2ZW50KSA9PiB0aGlzLl9hY3Rpb25NYXAuc2V0KGFjdGlvbi5ndWlkLCB7IC4uLnRoaXMuX2FjdGlvbk1hcC5nZXQoYWN0aW9uLmd1aWQpLCAuLi5hY3Rpb24gfSksXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIkNvbnRleHRNZXNzYWdlXCIsIHtcbiAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBDb250ZXh0TWVzc2FnZUV2ZW50KSA9PiB7IHRoaXMuX2F0dGFjaG1lbnRzLnB1c2gobWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcyk7IH0sXG4gICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgfSk7XG4gICAgdGhpcy5hZGRNZXNzYWdlSGFuZGxlcihcIk1lc3NhZ2VcIiwge1xuICAgICAgaGFuZGxlcjogKG1lc3NhZ2U6IE1lc3NhZ2VFdmVudCkgPT4ge1xuICAgICAgICB0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmNvbnRlbnQgKz0gbWVzc2FnZS5kZWx0YSA/PyBcIlwiO1xuICAgICAgICB0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCA9IG1lc3NhZ2UubWVzc2FnZUlkO1xuICAgICAgfSxcbiAgICAgIGlzR2xvYmFsSGFuZGxlcjogZmFsc2VcbiAgICB9KTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiSGlzdG9yeVwiLCB7XG4gICAgICAgIGhhbmRsZXI6IChoaXN0b3J5OiBIaXN0b3J5RXZlbnQpID0+IHtcbiAgICAgICAgICAvLyBUaGUgQ2hhdEhpc3RvcnkgaXMgdXBkYXRlZDogaXQgaXMgdGhlIGN1cnJlbnQgY29weSBjb25jYXRlbmF0ZWQgd2l0aCB0aGUgbmV3IGl0ZW1zIE9OTFkgKGl0IGNhbiBoYXZlIG11bHRpcGxlIG1lc3NhZ2VzOiB0aGUgY29udGV4dCBtZXNzYWdlcyArIHRoZSByZXNwb25zZSBtZXNzYWdlKVxuICAgICAgICAgIC8vIFRoaXMgaXMgbWFuZGF0b3J5IHRvIG5vdCBsb3NlIHRoZSBwcmV2aW91cyB1cGRhdGVzIG9mIHRoZSBjaGF0SGlzdG9yeSB3aGVuIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG11bHRpcGxlIG1lc3NhZ2Ugc3RlcHNcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q2hhdEhpc3RvcnkgPSAoY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpIHx8IFtdKSBhcyBDaGF0TWVzc2FnZVtdO1xuICAgICAgICAgIGNvbnN0IG5ld0hpc3RvcnkgPSBbLi4uY3VycmVudENoYXRIaXN0b3J5LCAuLi4oaGlzdG9yeS5oaXN0b3J5LnNsaWNlKGN1cnJlbnRDaGF0SGlzdG9yeS5sZW5ndGgpKV0gYXMgQ2hhdE1lc3NhZ2VbXTtcbiAgICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KG5ld0hpc3RvcnkpO1xuXG4gICAgICAgICAgLy8gRW1pdCB0aGUgdXBkYXRlZCBjaGF0IHVzYWdlIG1ldHJpY3NcbiAgICAgICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG5ld0hpc3RvcnkuYXQoLTEpO1xuICAgICAgICAgIGlmIChsYXN0TWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKSB7XG4gICAgICAgICAgICBjb250ZXh0LnVwZGF0ZUNoYXRVc2FnZU1ldHJpY3MobGFzdE1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMudXNhZ2VNZXRyaWNzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fZXhlY3V0aW9uVGltZSA9IGhpc3RvcnkuZXhlY3V0aW9uVGltZTtcbiAgICAgICAgICB0aGlzLl9leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzID0gaGlzdG9yeS5leGVjdXRpb25UaW1lTWlsbGlzZWNvbmRzO1xuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiU3VnZ2VzdGVkQWN0aW9uc1wiLCB7XG4gICAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBTdWdnZXN0ZWRBY3Rpb25zRXZlbnQpID0+IHtcbiAgICAgICAgICAvLyBTaW5jZSBhZnRlciB0aGUgXCJIaXN0b3J5XCIgYW5kIFwiTWVzc2FnZUJyZWFrXCIgdGhhdCB0aGlzIGV2ZW50IGlzIGNhdWdodCxcbiAgICAgICAgICAvLyAkc3VnZ2VzdGVkQWN0aW9uIG5lZWRzIHRvIGJlIHVwZGF0ZWQgZGlyZWN0bHkgdG8gdGhlIGxhc3QgdmlzaWJsZSBcImFzc2lzdGFudFwiIG1lc3NhZ2UgaW4gdGhlIF9yZXNwb25zZSBhbmQgdGhlIGNoYXRIaXN0b3J5XG4gICAgICAgICAgdGhpcy5fcmVzcG9uc2UuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uID0gKHRoaXMuX3Jlc3BvbnNlLmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMuJHN1Z2dlc3RlZEFjdGlvbiB8fCBbXSkuY29uY2F0KG1lc3NhZ2Uuc3VnZ2VzdGVkQWN0aW9ucyk7XG4gICAgICAgICAgY29uc3QgY2hhdEhpc3RvcnkgPSBjb250ZXh0LmdldENoYXRIaXN0b3J5KCkhO1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5sYXN0VmlzaWJsZUFzc2lzdGFudE1lc3NhZ2VJbmRleChjaGF0SGlzdG9yeSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gPSAoY2hhdEhpc3RvcnlbaW5kZXhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gfHwgW10pLmNvbmNhdChtZXNzYWdlLnN1Z2dlc3RlZEFjdGlvbnMpO1xuICAgICAgICAgICAgY29udGV4dC5zZXRDaGF0SGlzdG9yeShjaGF0SGlzdG9yeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLmFkZE1lc3NhZ2VIYW5kbGVyKFwiRGVidWdEaXNwbGF5XCIsIHtcbiAgICAgIGhhbmRsZXI6IChtZXNzYWdlOiBEZWJ1Z01lc3NhZ2VFdmVudCkgPT4gdGhpcy5fZGVidWdNZXNzYWdlcyA9IHRoaXMuX2RlYnVnTWVzc2FnZXMuY29uY2F0KG1lc3NhZ2UpLFxuICAgICAgaXNHbG9iYWxIYW5kbGVyOiBmYWxzZVxuICAgIH0pO1xuICAgIHRoaXMuYWRkTWVzc2FnZUhhbmRsZXIoXCJNZXNzYWdlQnJlYWtcIiwge1xuICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgLy8gU3lzdGVtYXRpY2FsbHkgaGFwcGVucyByaWdodCBhZnRlciB0aGUgXCJIaXN0b3J5XCIgZXZlbnRcbiAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBtb21lbnQgd2hlbiB0aGUgYXNzaXN0YW50IG1lc3NhZ2UgaXMgZnVsbHkgc3RyZWFtZWRcbiAgICAgICAgICBjb25zdCBhc3Npc3RhbnRDb25maWcgPSBjb250ZXh0LmdldEFzc2lzdGFudENvbmZpZygpO1xuICAgICAgICAgIGNvbnN0IGNoYXRIaXN0b3J5ID0gY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpO1xuICAgICAgICAgIGlmICghYXNzaXN0YW50Q29uZmlnIHx8ICFjaGF0SGlzdG9yeSB8fCAhY2hhdEhpc3RvcnkubGVuZ3RoKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBsYXN0Q2hhdE1lc3NhZ2UgPSBjaGF0SGlzdG9yeS5hdCgtMSkhO1xuXG4gICAgICAgICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICAgICAgICdkdXJhdGlvbic6IHRoaXMuX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCA/IHRoaXMuX2V4ZWN1dGlvblRpbWVNaWxsaXNlY29uZHMgOiB0aGlzLl9leGVjdXRpb25UaW1lLFxuICAgICAgICAgICAgJ3JvbGUnOiBsYXN0Q2hhdE1lc3NhZ2Uucm9sZSxcbiAgICAgICAgICAgICdyYW5rJzogY2hhdEhpc3RvcnkubGVuZ3RoLFxuICAgICAgICAgICAgJ21lc3NhZ2UtaWQnOiBsYXN0Q2hhdE1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkLFxuICAgICAgICAgICAgJ2dlbmVyYXRpb24tdG9rZW5jb3VudCc6IGxhc3RDaGF0TWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy51c2FnZU1ldHJpY3M/LmNvbXBsZXRpb25Ub2tlbkNvdW50LFxuICAgICAgICAgICAgJ3Byb21wdC10b2tlbmNvdW50JzogbGFzdENoYXRNZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLnVzYWdlTWV0cmljcz8ucHJvbXB0VG9rZW5Db3VudCxcbiAgICAgICAgICAgICdhdHRhY2htZW50cyc6IEpTT04uc3RyaW5naWZ5KHRoaXMuX2F0dGFjaG1lbnRzLm1hcCgoeyByZWNvcmRJZCwgY29udGV4dElkLCBwYXJ0cywgdHlwZSB9KSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29yZElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHRJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJ0czogcGFydHMubWFwKCh7IHBhcnRJZCwgdGV4dCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFhc3Npc3RhbnRDb25maWcuYXVkaXRTZXR0aW5ncz8ubG9nQ29udGVudCkgcmV0dXJuIHsgcGFydElkLCB0ZXh0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBwYXJ0SWQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pKSlcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmICghIWFzc2lzdGFudENvbmZpZy5hdWRpdFNldHRpbmdzPy5sb2dDb250ZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxhc3RDaGF0TWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAoZGV0YWlscyBhcyBhbnkpWyd0ZXh0J10gPSBsYXN0Q2hhdE1lc3NhZ2UuY29udGVudDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShsYXN0Q2hhdE1lc3NhZ2UuY29udGVudCkpIHtcbiAgICAgICAgICAgICAgKGRldGFpbHMgYXMgYW55KVsndGV4dCddID0gKGxhc3RDaGF0TWVzc2FnZS5jb250ZW50LmZpbmQoKG1zZykgPT4gbXNnLnR5cGUgPT09IFwidGV4dFwiKSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGV4dC5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCBkZXRhaWxzKTtcbiAgICAgICAgICAvLyBQdXNoIGEgbmV3IGFzc2lzdGFudCBtZXNzYWdlIHRvIHRoZSBfcmVzcG9uc2UgYXJyYXkgT05MWSBpZiB0aGUgY29udGVudCBvZiB0aGUgbGFzdCBtZXNzYWdlIGlzIG5vdCBlbXB0eVxuICAgICAgICAgIGlmICh0aGlzLl9yZXNwb25zZS5hdCgtMSkhLmNvbnRlbnQgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc3BvbnNlLnB1c2goe3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCl9fSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBpc0dsb2JhbEhhbmRsZXI6IGZhbHNlXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZU1lc3NhZ2VIYW5kbGVyczxUPihfbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxUPj4pOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgLy8gQ2xlYXIgdGhlIGFscmVhZHkgcmVnaXN0ZXJlZCBnbG9iYWwgY2hhdCBoYW5kbGVycyBiZWZvcmUgbWVyZ2luZyB0aGUgbmV3IG9uZXNcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlcnMuZm9yRWFjaCgoZXZlbnRIYW5kbGVyLCBldmVudE5hbWUpID0+IHtcbiAgICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gTWVyZ2UgdGhlIG5ldyBldmVudCBoYW5kbGVycyB3aXRoIHRoZSBleGlzdGluZyBvbmVzXG4gICAgdGhpcy5fbWVzc2FnZUhhbmRsZXJzID0gbmV3IE1hcChbLi4udGhpcy5fbWVzc2FnZUhhbmRsZXJzLCAuLi5fbWVzc2FnZUhhbmRsZXJzXSk7XG4gICAgLy8gUmVnaXN0ZXIgdGhlIGdsb2JhbCBoYW5kbGVycyBhbW9uZyB0aGUgbWVyZ2VkIG1hcFxuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5mb3JFYWNoKChldmVudEhhbmRsZXIsIGV2ZW50TmFtZSkgPT4ge1xuICAgICAgaWYoZXZlbnRIYW5kbGVyLmlzR2xvYmFsSGFuZGxlcikge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFkZE1lc3NhZ2VIYW5kbGVyPFQ+KGV2ZW50TmFtZTogc3RyaW5nLCBldmVudEhhbmRsZXI6IE1lc3NhZ2VIYW5kbGVyPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIHRoaXMuX21lc3NhZ2VIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBldmVudEhhbmRsZXIpO1xuICAgIGlmKGV2ZW50SGFuZGxlci5pc0dsb2JhbEhhbmRsZXIpIHtcbiAgICAgIHRoaXMucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcihldmVudE5hbWUsIGV2ZW50SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI8VD4oZXZlbnROYW1lOiBzdHJpbmcsIGV2ZW50SGFuZGxlcjogTWVzc2FnZUhhbmRsZXI8VD4pOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuY29udGV4dCEuZ2V0SHViQ29ubmVjdGlvbigpO1xuICAgIGlmICghY29ubmVjdGlvbikge1xuICAgICAgY29uc29sZS5sb2coXCJObyBjb25uZWN0aW9uIGZvdW5kIHRvIHJlZ2lzdGVyIHRoZSBsaXN0ZW5lclwiICsgZXZlbnROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29ubmVjdGlvbi5vbihldmVudE5hbWUsIChkYXRhOiBUKSA9PiB7XG4gICAgICBldmVudEhhbmRsZXIuaGFuZGxlcihkYXRhKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICB0aGlzLl9tZXNzYWdlSGFuZGxlcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgdGhpcy51bnN1YnNjcmliZU1lc3NhZ2VIYW5kbGVyKGV2ZW50TmFtZSk7XG4gIH1cblxuICBwdWJsaWMgdW5zdWJzY3JpYmVNZXNzYWdlSGFuZGxlcihldmVudE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb250ZXh0IS5nZXRIdWJDb25uZWN0aW9uKCk7XG4gICAgY29ubmVjdGlvbj8ub2ZmKGV2ZW50TmFtZSk7XG4gIH1cblxuICBwdWJsaWMgc3RvcEdlbmVyYXRpb24oKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNvbnRleHQhO1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb250ZXh0LmdldEh1YkNvbm5lY3Rpb24oKSE7XG5cbiAgICAgLy8gU3RhcnQgc3RvcHBpbmcgZ2VuZXJhdGlvbiBieSBpbnZva2luZyB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgY29udGV4dC5zZXRTdG9wcGluZ0dlbmVyYXRpb25TdGF0dXModHJ1ZSk7XG4gICAgLy8gQ3JlYXRlIGEgU3ViamVjdCB0byBob2xkIHRoZSByZXN1bHQgb2YgdGhlIENhbmNlbFRhc2tzIG1ldGhvZFxuICAgIGNvbnN0IHN0b3BHZW5lcmF0aW9uU3ViamVjdCQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgY29ubmVjdGlvbi5vbignQ2FuY2VsVGFza3MnLCAocmVzKSA9PiB7XG4gICAgICAvLyBXaGVuIHRoZSBnZW5lcmF0aW9uIGlzIHN0b3BwZWQgYmVmb3JlIHN0cmVhbWluZyBhbnkgVklTSUJMRSBhc3Npc3RhbnQgbWVzc2FnZSwgdGhpcyBtZWFucyB0aGF0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIHdpbGwgYmUgbG9zdC5cbiAgICAgIC8vIEhvd2V2ZXIsIHRoZSBcIkNvbnRleHRNZXNzYWdlXCIgZnJhbWVzIHdpbGwgYmUgcGVyc2lzdGVkIGluIHRoZSBjaGF0SGlzdG9yeSBhbmQgdGhlIGFzc2lzdGFudCBtYXkgcmVmZXJlbmNlIHRoZW0gaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRoaXMgbGVhZHMgdG8gdGhlIHByb2JsZW0gb2YgcmVmZXJlbmNpbmcgdW5kaXNwbGF5ZWQgYXR0YWNobWVudHMgaW4gdGhlIG5leHQgZ2VuZXJhdGlvbi5cbiAgICAgIC8vIFRvIHNvbHZlIHRoaXMgcHJvYmxlbSwgd2UgbmVlZCB0byBwZXJzaXN0ICRwcm9ncmVzcywgJGF0dGFjaG1lbnQgYW5kICRkZWJ1ZyBwcm9wZXJ0aWVzIGJ5IGFkZGluZyBhIG5ldyBhc3Npc3RhbnQgbWVzc2FnZSB3aXRoIGVtcHR5IGNvbnRlbnQgYW5kIHRoZXNlIHByb3BlcnRpZXMuXG4gICAgICAvLyBJbiB0aGUgb3RoZXIgaGFuZCwgdGhpcyBsZWFkcyB0byB0aGUgcHJvYmxlbSBvZiBoYXZpbmcgbWFueSBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZXMgaW4gdGhlIGNoYXQgaGlzdG9yeSwgaWYgYSBzdG9wIGdlbmVyYXRpb24gaGFwcGVucyBtdWx0aXBsZSB0aW1lcyBpbiBhIHJvdyB3aXRoIG5vIGNvbnRlbnQgZ2VuZXJhdGVkIHlldC5cbiAgICAgIC8vIFRvIHNvbHZlIHRoaXMgcHJvYmxlbSBtZW50aW9uZWQgaW4gdGhlIHRpY2tldCBFUy0yNzAyNCwgd2UgbmVlZCB0byBhbGxvdyBzdWNoIG9wZXJhdGlvbiBPTkxZIGlmIHRoZSBsYXN0IGFzc2lzdGFudCBtZXNzYWdlJ3MgY29udGVudCBpbiB0aGUgY2hhdCBoaXN0b3J5IGlzIG5vdCBlbXB0eS5cbiAgICAgIGNvbnN0IGNoYXRIaXN0b3J5ID0gY29udGV4dC5nZXRDaGF0SGlzdG9yeSgpO1xuICAgICAgY29uc3QgaXNMYXN0Q2hhdEhpc3RvcnlNZXNzYWdlQXNzaXN0YW50Q29udGVudEVtcHR5ID0gY2hhdEhpc3Rvcnk/Lmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICBjaGF0SGlzdG9yeS5hdCgtMSk/LnJvbGUgPT09IFwiYXNzaXN0YW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoY2hhdEhpc3RvcnkuYXQoLTEpPy5jb250ZW50ID09PSBcIlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoY2hhdEhpc3RvcnkuYXQoLTEpPy5jb250ZW50IGFzIE1lc3NhZ2VDb250ZW50W10pPy5maW5kKChtc2cpID0+IG1zZy50eXBlID09PSBcInRleHRcIikgYXMgVGV4dE1lc3NhZ2VDb250ZW50KT8udGV4dCA9PT0gXCJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgIGlmICh0aGlzLl9yZXNwb25zZSAmJiB0aGlzLl9yZXNwb25zZS5sZW5ndGggPT09IDEgJiYgdGhpcy5fcmVzcG9uc2VbMF0uY29udGVudCA9PT0gXCJcIiAmJiAhaXNMYXN0Q2hhdEhpc3RvcnlNZXNzYWdlQXNzaXN0YW50Q29udGVudEVtcHR5KSB7XG4gICAgICAgIGNvbnN0IG5ld0NoYXRIaXN0b3J5ID0gY2hhdEhpc3RvcnkgPyBbLi4uY2hhdEhpc3RvcnldIDogW107XG4gICAgICAgIG5ld0NoYXRIaXN0b3J5LnB1c2goe3JvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQ6IFwiXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCksICRwcm9ncmVzczogdGhpcy5fcHJvZ3Jlc3MsICRhdHRhY2htZW50OiB0aGlzLl9hdHRhY2htZW50cywgJGRlYnVnOiB0aGlzLl9kZWJ1Z01lc3NhZ2VzfX0pO1xuICAgICAgICBjb250ZXh0LnNldENoYXRIaXN0b3J5KG5ld0NoYXRIaXN0b3J5KTtcbiAgICAgIH1cbiAgICAgIC8vIEVtaXQgdGhlIHJlc3VsdCBvZiB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kXG4gICAgICBzdG9wR2VuZXJhdGlvblN1YmplY3QkLm5leHQoISFyZXMpO1xuICAgICAgLy8gQ29tcGxldGUgdGhlIHN1YmplY3RcbiAgICAgIHN0b3BHZW5lcmF0aW9uU3ViamVjdCQuY29tcGxldGUoKTtcbiAgICAgIC8vIENvbXBsZXRlIHN0b3BwaW5nIGdlbmVyYXRpb25cbiAgICAgIGNvbnRleHQuc2V0U3RvcHBpbmdHZW5lcmF0aW9uU3RhdHVzKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIC8vIEludm9rZSB0aGUgQ2FuY2VsVGFza3MgbWV0aG9kIGFuZCBoYW5kbGUgZXJyb3JzXG4gICAgY29ubmVjdGlvbi5pbnZva2UoJ0NhbmNlbFRhc2tzJylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGludm9raW5nIENhbmNlbFRhc2tzOicsIGVycm9yKTtcbiAgICAgICAgc3RvcEdlbmVyYXRpb25TdWJqZWN0JC5lcnJvcihuZXcgRXJyb3IoZXJyb3IgYXMgc3RyaW5nKSk7XG4gICAgICAgIGNvbnRleHQuc2V0U3RvcHBpbmdHZW5lcmF0aW9uU3RhdHVzKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gc3RvcEdlbmVyYXRpb25TdWJqZWN0JC5hc09ic2VydmFibGUoKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,105 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { HttpTransportType, LogLevel } from '@microsoft/signalr';
3
+ import { getToken } from '@sinequa/atomic';
4
+ import { AssistantUtils } from '../utils/utils.service';
5
+ import { SignalRWebService } from './signalR.web.service';
6
+ import * as i0 from "@angular/core";
7
+ export class SignalRConnectionService {
8
+ constructor() {
9
+ this.signalRWebService = inject(SignalRWebService);
10
+ this.assistantUtils = inject(AssistantUtils);
11
+ }
12
+ init(config) {
13
+ this.operationConfig = config;
14
+ }
15
+ ensureInitialized() {
16
+ if (!this.operationConfig) {
17
+ throw new Error('SignalRConnectionService not initialized. Call init() first.');
18
+ }
19
+ }
20
+ _getLogLevel() {
21
+ this.ensureInitialized();
22
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
23
+ switch (assistantConfig?.connectionSettings.signalRLogLevel) {
24
+ case "Critical": return LogLevel.Critical;
25
+ case "Debug": return LogLevel.Debug;
26
+ case "Error": return LogLevel.Error;
27
+ case "Information": return LogLevel.Information;
28
+ case "None": return LogLevel.None;
29
+ case "Trace": return LogLevel.Trace;
30
+ case "Warning": return LogLevel.Warning;
31
+ default: return LogLevel.None;
32
+ }
33
+ }
34
+ _getTransports() {
35
+ this.ensureInitialized();
36
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
37
+ switch (assistantConfig?.connectionSettings.signalRTransport) {
38
+ case "WebSockets": return HttpTransportType.WebSockets;
39
+ case "ServerSentEvents": return HttpTransportType.ServerSentEvents;
40
+ case "LongPolling": return HttpTransportType.LongPolling;
41
+ default: return HttpTransportType.None;
42
+ }
43
+ }
44
+ getDefaultOptions() {
45
+ this.ensureInitialized();
46
+ let headers = {
47
+ "sinequa-force-camel-case": "true",
48
+ "x-language": this.assistantUtils.getCurrentLocaleName(),
49
+ "ui-language": this.assistantUtils.getCurrentLocaleName(),
50
+ };
51
+ const token = getToken();
52
+ if (token) {
53
+ headers = { ...headers, "sinequa-csrf-token": token };
54
+ }
55
+ return {
56
+ transport: this._getTransports(),
57
+ withCredentials: true,
58
+ headers,
59
+ skipNegotiation: false,
60
+ accessTokenFactory: () => token || ""
61
+ };
62
+ }
63
+ buildConnection(options) {
64
+ this.ensureInitialized();
65
+ return new Promise((resolve, reject) => {
66
+ const wsRequestUrl = this.operationConfig.getWsRequestUrl();
67
+ if (!wsRequestUrl) {
68
+ reject(new Error("No endpoint provided to connect the websocket to"));
69
+ return;
70
+ }
71
+ const assistantConfig = this.operationConfig.getAssistantConfigValue();
72
+ const logLevel = this._getLogLevel();
73
+ const defaultOpts = this.getDefaultOptions();
74
+ if (assistantConfig?.connectionSettings.signalRSkipNegotiation === true) {
75
+ options = { ...options, skipNegotiation: true };
76
+ }
77
+ const connection = this.signalRWebService.buildConnection(wsRequestUrl, { ...defaultOpts, ...options }, logLevel, true);
78
+ const signalRServerTimeoutInMilliseconds = assistantConfig?.connectionSettings.signalRServerTimeoutInMilliseconds;
79
+ if (signalRServerTimeoutInMilliseconds && connection) {
80
+ connection.serverTimeoutInMilliseconds = signalRServerTimeoutInMilliseconds;
81
+ }
82
+ this.operationConfig.setHubConnection(connection);
83
+ resolve();
84
+ });
85
+ }
86
+ startConnection() {
87
+ this.ensureInitialized();
88
+ const connection = this.operationConfig.getHubConnection();
89
+ return this.signalRWebService.startConnection(connection);
90
+ }
91
+ stopConnection() {
92
+ this.ensureInitialized();
93
+ const connection = this.operationConfig.getHubConnection();
94
+ return this.signalRWebService.stopConnection(connection);
95
+ }
96
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
97
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, providedIn: 'root' }); }
98
+ }
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SignalRConnectionService, decorators: [{
100
+ type: Injectable,
101
+ args: [{
102
+ providedIn: 'root'
103
+ }]
104
+ }] });
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFsUi1jb25uZWN0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9zZXJ2aWNlcy9zaWduYWxSLWNvbm5lY3Rpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQWlCLGlCQUFpQixFQUFFLFFBQVEsRUFBa0IsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxpQkFBaUIsRUFBcUIsTUFBTSx1QkFBdUIsQ0FBQzs7QUFhN0UsTUFBTSxPQUFPLHdCQUF3QjtJQUhyQztRQUtVLHNCQUFpQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzlDLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0tBK0ZqRDtJQTdGUSxJQUFJLENBQUMsTUFBd0M7UUFDbEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUM7SUFDaEMsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztRQUNsRixDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWdCLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUN4RSxRQUFRLGVBQWUsRUFBRSxrQkFBa0IsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUM1RCxLQUFLLFVBQVUsQ0FB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YmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh1YkNvbm5lY3Rpb24sIEh0dHBUcmFuc3BvcnRUeXBlLCBMb2dMZXZlbCwgTWVzc2FnZUhlYWRlcnMgfSBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xuaW1wb3J0IHsgZ2V0VG9rZW4gfSBmcm9tICdAc2luZXF1YS9hdG9taWMnO1xuaW1wb3J0IHsgQXNzaXN0YW50VXRpbHMgfSBmcm9tICcuLi91dGlscy91dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hbFJXZWJTZXJ2aWNlLCBDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4vc2lnbmFsUi53ZWIuc2VydmljZSc7XG5pbXBvcnQgeyBDaGF0Q29uZmlnIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25hbFJDb25uZWN0aW9uT3BlcmF0aW9uQ29uZmlnIHtcbiAgZ2V0V3NSZXF1ZXN0VXJsOiAoKSA9PiBzdHJpbmc7XG4gIGdldEFzc2lzdGFudENvbmZpZ1ZhbHVlOiAoKSA9PiBDaGF0Q29uZmlnIHwgdW5kZWZpbmVkO1xuICBnZXRIdWJDb25uZWN0aW9uOiAoKSA9PiBIdWJDb25uZWN0aW9uIHwgdW5kZWZpbmVkO1xuICBzZXRIdWJDb25uZWN0aW9uOiAoY29ubmVjdGlvbjogSHViQ29ubmVjdGlvbiB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU2lnbmFsUkNvbm5lY3Rpb25TZXJ2aWNlIHtcbiAgcHJpdmF0ZSBvcGVyYXRpb25Db25maWc6IFNpZ25hbFJDb25uZWN0aW9uT3BlcmF0aW9uQ29uZmlnIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHNpZ25hbFJXZWJTZXJ2aWNlID0gaW5qZWN0KFNpZ25hbFJXZWJTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBhc3Npc3RhbnRVdGlscyA9IGluamVjdChBc3Npc3RhbnRVdGlscyk7XG5cbiAgcHVibGljIGluaXQoY29uZmlnOiBTaWduYWxSQ29ubmVjdGlvbk9wZXJhdGlvbkNvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMub3BlcmF0aW9uQ29uZmlnID0gY29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBlbnN1cmVJbml0aWFsaXplZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMub3BlcmF0aW9uQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NpZ25hbFJDb25uZWN0aW9uU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldExvZ0xldmVsKCk6IExvZ0xldmVsIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgYXNzaXN0YW50Q29uZmlnID0gdGhpcy5vcGVyYXRpb25Db25maWchLmdldEFzc2lzdGFudENvbmZpZ1ZhbHVlKCk7XG4gICAgc3dpdGNoIChhc3Npc3RhbnRDb25maWc/LmNvbm5lY3Rpb25TZXR0aW5ncy5zaWduYWxSTG9nTGV2ZWwpIHtcbiAgICAgIGNhc2UgXCJDcml0aWNhbFwiOiByZXR1cm4gTG9nTGV2ZWwuQ3JpdGljYWw7XG4gICAgICBjYXNlIFwiRGVidWdcIjogcmV0dXJuIExvZ0xldmVsLkRlYnVnO1xuICAgICAgY2FzZSBcIkVycm9yXCI6IHJldHVybiBMb2dMZXZlbC5FcnJvcjtcbiAgICAgIGNhc2UgXCJJbmZvcm1hdGlvblwiOiByZXR1cm4gTG9nTGV2ZWwuSW5mb3JtYXRpb247XG4gICAgICBjYXNlIFwiTm9uZVwiOiByZXR1cm4gTG9nTGV2ZWwuTm9uZTtcbiAgICAgIGNhc2UgXCJUcmFjZVwiOiByZXR1cm4gTG9nTGV2ZWwuVHJhY2U7XG4gICAgICBjYXNlIFwiV2FybmluZ1wiOiByZXR1cm4gTG9nTGV2ZWwuV2FybmluZztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBMb2dMZXZlbC5Ob25lO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldFRyYW5zcG9ydHMoKTogSHR0cFRyYW5zcG9ydFR5cGUge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBhc3Npc3RhbnRDb25maWcgPSB0aGlzLm9wZXJhdGlvbkNvbmZpZyEuZ2V0QXNzaXN0YW50Q29uZmlnVmFsdWUoKTtcbiAgICBzd2l0Y2ggKGFzc2lzdGFudENvbmZpZz8uY29ubmVjdGlvblNldHRpbmdzLnNpZ25hbFJUcmFuc3BvcnQpIHtcbiAgICAgIGNhc2UgXCJXZWJTb2NrZXRzXCI6IHJldHVybiBIdHRwVHJhbnNwb3J0VHlwZS5XZWJTb2NrZXRzO1xuICAgICAgY2FzZSBcIlNlcnZlclNlbnRFdmVudHNcIjogcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLlNlcnZlclNlbnRFdmVudHM7XG4gICAgICBjYXNlIFwiTG9uZ1BvbGxpbmdcIjogcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLkxvbmdQb2xsaW5nO1xuICAgICAgZGVmYXVsdDogcmV0dXJuIEh0dHBUcmFuc3BvcnRUeXBlLk5vbmU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWZhdWx0T3B0aW9ucygpOiBDb25uZWN0aW9uT3B0aW9ucyB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIGxldCBoZWFkZXJzOiBNZXNzYWdlSGVhZGVycyA9IHtcbiAgICAgIFwic2luZXF1YS1mb3JjZS1jYW1lbC1jYXNlXCI6IFwidHJ1ZVwiLFxuICAgICAgXCJ4LWxhbmd1YWdlXCI6IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0Q3VycmVudExvY2FsZU5hbWUoKSxcbiAgICAgIFwidWktbGFuZ3VhZ2VcIjogdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRDdXJyZW50TG9jYWxlTmFtZSgpLFxuICAgIH07XG4gICAgY29uc3QgdG9rZW4gPSBnZXRUb2tlbigpO1xuICAgIGlmICh0b2tlbikge1xuICAgICAgaGVhZGVycyA9IHsgLi4uaGVhZGVycywgXCJzaW5lcXVhLWNzcmYtdG9rZW5cIjogdG9rZW4gfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNwb3J0OiB0aGlzLl9nZXRUcmFuc3BvcnRzKCksXG4gICAgICB3aXRoQ3JlZGVudGlhbHM6IHRydWUsXG4gICAgICBoZWFkZXJzLFxuICAgICAgc2tpcE5lZ290aWF0aW9uOiBmYWxzZSxcbiAgICAgIGFjY2Vzc1Rva2VuRmFjdG9yeTogKCkgPT4gdG9rZW4gfHwgXCJcIlxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgYnVpbGRDb25uZWN0aW9uKG9wdGlvbnM/OiBDb25uZWN0aW9uT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgd3NSZXF1ZXN0VXJsID0gdGhpcy5vcGVyYXRpb25Db25maWchLmdldFdzUmVxdWVzdFVybCgpO1xuICAgICAgaWYgKCF3c1JlcXVlc3RVcmwpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIk5vIGVuZHBvaW50IHByb3ZpZGVkIHRvIGNvbm5lY3QgdGhlIHdlYnNvY2tldCB0b1wiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFzc2lzdGFudENvbmZpZyA9IHRoaXMub3BlcmF0aW9uQ29uZmlnIS5nZXRBc3Npc3RhbnRDb25maWdWYWx1ZSgpO1xuICAgICAgY29uc3QgbG9nTGV2ZWwgPSB0aGlzLl9nZXRMb2dMZXZlbCgpO1xuICAgICAgY29uc3QgZGVmYXVsdE9wdHMgPSB0aGlzLmdldERlZmF1bHRPcHRpb25zKCk7XG4gICAgICBpZiAoYXNzaXN0YW50Q29uZmlnPy5jb25uZWN0aW9uU2V0dGluZ3Muc2lnbmFsUlNraXBOZWdvdGlhdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBvcHRpb25zID0gey4uLm9wdGlvbnMsIHNraXBOZWdvdGlhdGlvbjogdHJ1ZX07XG4gICAgICB9XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5zaWduYWxSV2ViU2VydmljZS5idWlsZENvbm5lY3Rpb24od3NSZXF1ZXN0VXJsLCB7IC4uLmRlZmF1bHRPcHRzLCAuLi5vcHRpb25zIH0sIGxvZ0xldmVsLCB0cnVlKTtcblxuICAgICAgY29uc3Qgc2lnbmFsUlNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGFzc2lzdGFudENvbmZpZz8uY29ubmVjdGlvblNldHRpbmdzLnNpZ25hbFJTZXJ2ZXJUaW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gICAgICBpZiAoc2lnbmFsUlNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcyAmJiBjb25uZWN0aW9uKSB7XG4gICAgICAgIGNvbm5lY3Rpb24uc2VydmVyVGltZW91dEluTWlsbGlzZWNvbmRzID0gc2lnbmFsUlNlcnZlclRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICAgIH1cbiAgICAgIHRoaXMub3BlcmF0aW9uQ29uZmlnIS5zZXRIdWJDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0Q29ubmVjdGlvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMub3BlcmF0aW9uQ29uZmlnIS5nZXRIdWJDb25uZWN0aW9uKCk7XG4gICAgcmV0dXJuIHRoaXMuc2lnbmFsUldlYlNlcnZpY2Uuc3RhcnRDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuICB9XG5cbiAgcHVibGljIHN0b3BDb25uZWN0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5vcGVyYXRpb25Db25maWchLmdldEh1YkNvbm5lY3Rpb24oKTtcbiAgICByZXR1cm4gdGhpcy5zaWduYWxSV2ViU2VydmljZS5zdG9wQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgfVxufVxuIl19