@sinequa/assistant 3.2.0 → 3.2.1

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.
@@ -105,8 +105,10 @@ export class ChatComponent extends AbstractFacet {
105
105
  if (changes?.messageHandlers && this.messageHandlers && this.chatService instanceof WebSocketChatService) {
106
106
  this.chatService.overrideMessageHandlers(this.messageHandlers);
107
107
  }
108
- // Initialize the chat with the provided chat messages if exists, otherwise load the default chat
109
- // Once the chat is initialized (firstChangesHandled is true), allow opening the chat with the new provided messages (if exists)
108
+ /**
109
+ * Initialize the chat with the provided chat messages if exists, otherwise load the default chat
110
+ * Once the chat is initialized (firstChangesHandled is true), allow opening the chat with the new provided messages (if exists)
111
+ */
110
112
  if (!this.firstChangesHandled || changes?.chat) {
111
113
  const openChat = () => {
112
114
  if (this.messages$.value && this.config.savedChatSettings.enabled) {
@@ -116,22 +118,35 @@ export class ChatComponent extends AbstractFacet {
116
118
  };
117
119
  this.chat ? openChat() : this.loadDefaultChat();
118
120
  }
119
- // If the chat is initialized and the initialization event is "Query", then a fresh new chat should be started with the provided query
121
+ /**
122
+ * If the chat is initialized, the initialization event is "Query", the query changes and the queryChangeShouldTriggerReload function is provided,
123
+ * then the chat should be reloaded if the function returns true
124
+ * Otherwise, the chat should be reloaded by default
125
+ */
120
126
  if (this.firstChangesHandled && changes?.query && this.config.modeSettings.initialization.event === 'Query') {
121
- const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false } };
122
- const userMsg = { role: 'user', content: ChatService.formatPrompt(this.config.defaultValues.userPrompt, { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt } };
123
- // If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
124
- // Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
125
- if (!!this.query.text) {
126
- const userQueryMsg = { role: 'user', content: this.query.text, additionalProperties: { display: this.config.modeSettings.initialization.displayUserQuery, query: this.query, forcedWorkflow: this.config.modeSettings.initialization.forcedWorkflow, isUserInput: true } };
127
- this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
128
- }
129
- else {
130
- const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
131
- this.openChat([warningMsg]);
127
+ const previousQuery = changes.query.previousValue;
128
+ const currentQuery = changes.query.currentValue;
129
+ if (this.queryChangeShouldTriggerReload ? this.queryChangeShouldTriggerReload(previousQuery, currentQuery) : true) {
130
+ this.triggerReloadAfterQueryChange(currentQuery);
132
131
  }
133
132
  }
134
133
  }
134
+ triggerReloadAfterQueryChange(query) {
135
+ const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false } };
136
+ const userMsg = { role: 'user', content: ChatService.formatPrompt(this.config.defaultValues.userPrompt, { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt } };
137
+ /**
138
+ * If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
139
+ * Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
140
+ */
141
+ if (!!this.query.text) {
142
+ const userQueryMsg = { role: 'user', content: this.query.text, additionalProperties: { display: this.config.modeSettings.initialization.displayUserQuery, query: this.query, forcedWorkflow: this.config.modeSettings.initialization.forcedWorkflow, isUserInput: true } };
143
+ this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
144
+ }
145
+ else {
146
+ const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
147
+ this.openChat([warningMsg]);
148
+ }
149
+ }
135
150
  addScrollListener() {
136
151
  this.sub.add(merge(this.loading$, this.messages$, this.chatService.streaming$, fromEvent(this.messageList.nativeElement, 'scroll')).subscribe(() => {
137
152
  this.isAtBottom = this.toggleScrollButtonVisibility();
@@ -166,13 +181,11 @@ export class ChatComponent extends AbstractFacet {
166
181
  this.chatService.chatHistory = this.chatService.chatHistory.slice(0, this.messageToEdit);
167
182
  this.messageToEdit = undefined;
168
183
  }
169
- // Re-attach the $progress and $attachment of the last response to the last assistant's response in the chat history
170
- this.chatService.chatHistory.at(-1).additionalProperties.$progress = this.messages$.value.at(-1).additionalProperties.$progress;
171
- this.chatService.chatHistory.at(-1).additionalProperties.$attachment = this.messages$.value.at(-1).additionalProperties.$attachment;
172
184
  // Fetch the answer
173
185
  this.fetchAnswer(this.question.trim(), this.chatService.chatHistory);
174
186
  // Clear the input value in the UI
175
187
  this.questionInput.nativeElement.value = '';
188
+ this.questionInput.nativeElement.style.height = `auto`;
176
189
  }
177
190
  }
178
191
  fetchAnswer(question, conversation) {
@@ -235,9 +248,11 @@ export class ChatComponent extends AbstractFacet {
235
248
  }
236
249
  /**
237
250
  * Start a new chat with the defaultValues settings
251
+ * The savedChatId in the chat service will be reset, so that the upcoming saved chat operations will be performed on the fresh new chat
238
252
  * If the savedChat feature is enabled, the list of saved chats will be refreshed
239
253
  */
240
254
  newChat() {
255
+ this.chatService.setSavedChatId(undefined); // Reset the savedChatId
241
256
  if (this.config.savedChatSettings.enabled) {
242
257
  this.chatService.listSavedChat(); // Refresh the list of saved chats
243
258
  }
@@ -271,14 +286,16 @@ export class ChatComponent extends AbstractFacet {
271
286
  * If the last message is from the user, a request to the assistant is made to get an answer
272
287
  * If the last message is from the assistant, the conversation is loaded right away
273
288
  * @param messages The list of messages of the chat
274
- * @param chatId The id of the chat. If not provided, a new id will be generated
289
+ * @param chatId The id of the chat. If provided (ie. an existing discussion in the saved chat index), update the savedChatId in the chat service for the upcoming saved chat operations
275
290
  */
276
291
  openChat(messages, chatId) {
277
292
  if (!messages || !Array.isArray(messages)) {
278
293
  console.error('Error occurs while trying to load the chat discussion. Invalid messages received :', messages);
279
294
  return;
280
295
  }
281
- this.chatService.setSavedChatId(chatId || ChatService.generateGUID());
296
+ if (chatId) {
297
+ this.chatService.setSavedChatId(chatId);
298
+ }
282
299
  this.resetChat();
283
300
  this.messages$.next(messages);
284
301
  this.chatService.chatHistory = messages;
@@ -333,60 +350,44 @@ export class ChatComponent extends AbstractFacet {
333
350
  }
334
351
  onKeyUp(event) {
335
352
  switch (event.key) {
336
- case 'ArrowUp':
337
- this.navigateMessage(-1);
338
- break;
339
- case 'ArrowDown':
340
- this.navigateMessage(1);
353
+ case 'Backspace':
354
+ this.calculateHeight();
341
355
  break;
342
356
  case 'Enter':
343
- this.submitQuestion();
357
+ if (!event.shiftKey)
358
+ this.submitQuestion();
359
+ this.calculateHeight();
344
360
  break;
345
361
  default:
346
362
  break;
347
363
  }
348
- // Handle Shift + Enter
349
- if (event.shiftKey && event.key === 'Enter') {
350
- this.submitQuestion();
351
- }
352
364
  }
353
- navigateMessage(direction) {
354
- if (!this.chatService.chatHistory || this.chatService.chatHistory.length < 1) {
355
- return;
356
- }
357
- const userMessages = this.chatService.chatHistory.filter(m => m.role === 'user');
358
- if (userMessages.length < 1) {
359
- return;
360
- }
361
- this.currentMessageIndex = (this.currentMessageIndex ?? userMessages.length) + direction;
362
- if (this.currentMessageIndex < 0) {
363
- // If the user presses up arrow on the first message, stay at the first message
364
- this.currentMessageIndex = 0;
365
- }
366
- else if (this.currentMessageIndex >= userMessages.length) {
367
- // If the user presses down arrow on the last previous message, clear the input
368
- this.currentMessageIndex = undefined;
369
- this.question = '';
370
- return;
371
- }
372
- this.question = userMessages[this.currentMessageIndex].content;
365
+ calculateHeight() {
366
+ const maxHeight = 170;
367
+ const el = this.questionInput.nativeElement;
368
+ el.style.maxHeight = `${maxHeight}px`;
369
+ el.style.height = 'auto';
370
+ el.style.height = `${el.scrollHeight}px`;
371
+ el.style.overflowY = el.scrollHeight >= maxHeight ? 'scroll' : 'hidden';
373
372
  }
374
373
  }
375
374
  ChatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
376
- ChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", protocol: "protocol", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", chat: "chat", customAssistantIcon: "customAssistantIcon" }, outputs: { data: "data", referenceClicked: "referenceClicked", openPreview: "openPreview", loading$: "loading", error: "error", _config: "config" }, providers: [
375
+ ChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", queryChangeShouldTriggerReload: "queryChangeShouldTriggerReload", protocol: "protocol", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", chat: "chat", customAssistantIcon: "customAssistantIcon" }, outputs: { data: "data", referenceClicked: "referenceClicked", openPreview: "openPreview", loading$: "loading", error: "error", _config: "config" }, providers: [
377
376
  RestChatService,
378
377
  WebSocketChatService
379
- ], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <i class=\"fas fa-search\"></i>\n <input #questionInput\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:center;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container input{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem)}.ast-input-container input,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChatMessageComponent, selector: "sq-chat-message", inputs: ["message", "conversation", "assistantIcon", "streaming", "canEdit", "canRegenerate", "canCopy"], outputs: ["referenceClicked", "edit", "regenerate", "openPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
378
+ ], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2 pb-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight()\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n </textarea>\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:end;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChatMessageComponent, selector: "sq-chat-message", inputs: ["message", "conversation", "assistantIcon", "streaming", "canEdit", "canRegenerate", "canCopy"], outputs: ["referenceClicked", "edit", "regenerate", "openPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
380
379
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, decorators: [{
381
380
  type: Component,
382
381
  args: [{ selector: 'sq-chat-v3', providers: [
383
382
  RestChatService,
384
383
  WebSocketChatService
385
- ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent], template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <i class=\"fas fa-search\"></i>\n <input #questionInput\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:center;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container input{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem)}.ast-input-container input,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"] }]
384
+ ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent], template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2 pb-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight()\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n </textarea>\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:end;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"] }]
386
385
  }], ctorParameters: function () { return []; }, propDecorators: { instanceId: [{
387
386
  type: Input
388
387
  }], query: [{
389
388
  type: Input
389
+ }], queryChangeShouldTriggerReload: [{
390
+ type: Input
390
391
  }], protocol: [{
391
392
  type: Input
392
393
  }], messageHandlers: [{
@@ -421,4 +422,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
421
422
  type: ContentChild,
422
423
  args: ['loadingTpl']
423
424
  }] } });
424
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBOEIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFOLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNELE9BQU8sRUFBRSxtQkFBbUIsRUFBVSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZ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ZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgQ29udGVudENoaWxkLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIkBzaW5lcXVhL2NvbXBvbmVudHMvYWN0aW9uXCI7XG5pbXBvcnQgeyBBYnN0cmFjdEZhY2V0IH0gZnJvbSBcIkBzaW5lcXVhL2NvbXBvbmVudHMvZmFjZXRcIjtcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29tcG9uZW50cy9zZWFyY2hcIjtcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSBcIkBzaW5lcXVhL2NvcmUvYXBwLXV0aWxzXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxXZWJTZXJ2aWNlLCBSZWNvcmQgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS93ZWItc2VydmljZXNcIjtcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBmaWx0ZXIsIGZyb21FdmVudCwgbWFwLCBtZXJnZSwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgQ2hhdFNlcnZpY2UgfSBmcm9tIFwiLi9jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXRDb250ZXh0QXR0YWNobWVudCwgQ2hhdENvbmZpZywgQ2hhdE1lc3NhZ2UsIEdsbG1Nb2RlbERlc2NyaXB0aW9uLCBNZXNzYWdlSGFuZGxlciwgUmF3TWVzc2FnZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlIH0gZnJvbSBcIi4vaW5zdGFuY2UtbWFuYWdlci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBXZWJTb2NrZXRDaGF0U2VydmljZSB9IGZyb20gXCIuL3dlYnNvY2tldC1jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXRNZXNzYWdlQ29tcG9uZW50IH0gZnJvbSBcIi4vY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnRcIjtcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBMb2dpblNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS9sb2dpblwiO1xuaW1wb3J0IHsgUmVzdENoYXRTZXJ2aWNlIH0gZnJvbSBcIi4vcmVzdC1jaGF0LnNlcnZpY2VcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJbml0Q2hhdCB7XG4gIG1lc3NhZ2VzOiBSYXdNZXNzYWdlW107XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NxLWNoYXQtdjMnLCAvLyBtYW5kYXRvcnkgc2luY2UgQHNpbmVxdWEvY29tcG9uZW50cyBhbHJlYWR5IGhhcyB0aGUgc2FtZSB0YWctbmFtZSBcInNxLWNoYXRcIlxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXQuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgUmVzdENoYXRTZXJ2aWNlLFxuICAgIFdlYlNvY2tldENoYXRTZXJ2aWNlXG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgQ2hhdE1lc3NhZ2VDb21wb25lbnRdXG59KVxuZXhwb3J0IGNsYXNzIENoYXRDb21wb25lbnQgZXh0ZW5kcyBBYnN0cmFjdEZhY2V0IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgcHVibGljIGxvZ2luU2VydmljZSA9IGluamVjdChMb2dpblNlcnZpY2UpO1xuICBwdWJsaWMgd2Vic29ja2V0U2VydmljZSA9IGluamVjdChXZWJTb2NrZXRDaGF0U2VydmljZSk7XG4gIHB1YmxpYyByZXN0U2VydmljZSA9IGluamVjdChSZXN0Q2hhdFNlcnZpY2UpO1xuICBwdWJsaWMgaW5zdGFuY2VNYW5hZ2VyU2VydmljZSA9IGluamVjdChJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlKTtcbiAgcHVibGljIHNlYXJjaFNlcnZpY2UgPSBpbmplY3QoU2VhcmNoU2VydmljZSk7XG4gIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlID0gaW5qZWN0KFByaW5jaXBhbFdlYlNlcnZpY2UpO1xuICBwdWJsaWMgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAvKiogRGVmaW5lIHRoZSBrZXkgYmFzZWQgb24gaXQsIHRoZSBjaGF0IHNlcnZpY2UgaW5zdGFuY2Ugd2lsbCBiZSBzdG9yZWQgKi9cbiAgQElucHV0KCkgaW5zdGFuY2VJZDogc3RyaW5nO1xuICAvKiogRGVmaW5lIHRoZSBxdWVyeSB0byB1c2UgdG8gZmV0Y2ggYW5zd2VycyAqL1xuICBASW5wdXQoKSBxdWVyeTogUXVlcnkgPSB0aGlzLnNlYXJjaFNlcnZpY2UucXVlcnk7XG4gIC8qKiBEZWZpbmUgdGhlIHByb3RvY29sIHRvIGJlIHVzZWQgZm9yIHRoaXMgY2hhdCBpbnN0YW5jZSovXG4gIEBJbnB1dCgpIHByb3RvY29sOiAnUkVTVCcgfCAnV0VCU09DS0VUJyA9IFwiV0VCU09DS0VUXCI7XG4gIC8qKiBNYXAgb2YgbGlzdGVuZXJzIG92ZXJyaWRpbmcgZGVmYXVsdCByZWdpc3RlcmVkIG9uZXMqL1xuICBASW5wdXQoKSBtZXNzYWdlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIE1lc3NhZ2VIYW5kbGVyPGFueT4+ID0gbmV3IE1hcCgpO1xuICAvKiogV2hlbiB0aGUgYXNzaXN0YW50IGFuc3dlciBhIHVzZXIgcXVlc3Rpb24sIGF1dG9tYXRpY2FsbHkgc2Nyb2xsIGRvd24gdG8gdGhlIGJvdHRvbSBvZiB0aGUgZGlzY3Vzc2lvbiAqL1xuICBASW5wdXQoKSBhdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSA9IGZhbHNlO1xuICBASW5wdXQoKSBjaGF0PzogSW5pdENoYXQ7XG4gIEBJbnB1dCgpIGN1c3RvbUFzc2lzdGFudEljb24gPSAnJztcbiAgQE91dHB1dCgpIGRhdGEgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlW10+KCk7XG4gIEBPdXRwdXQoKSByZWZlcmVuY2VDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxSZWNvcmQ+KCk7XG4gIEBPdXRwdXQoKSBvcGVuUHJldmlldyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdENvbnRleHRBdHRhY2htZW50PigpO1xuICBAT3V0cHV0KFwibG9hZGluZ1wiKSBsb2FkaW5nJCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oZmFsc2UpO1xuICBAT3V0cHV0KCkgZXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dChcImNvbmZpZ1wiKSBfY29uZmlnID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0Q29uZmlnPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ21lc3NhZ2VMaXN0JykgbWVzc2FnZUxpc3Q/OiBFbGVtZW50UmVmPEhUTUxVTGlzdEVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCdxdWVzdGlvbklucHV0JykgcXVlc3Rpb25JbnB1dD86IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XG5cbiAgQENvbnRlbnRDaGlsZCgnbG9hZGluZ1RwbCcpIGxvYWRpbmdUcGw/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIGNoYXRTZXJ2aWNlOiBDaGF0U2VydmljZTtcbiAgY29uZmlnOiBDaGF0Q29uZmlnO1xuICBtZXNzYWdlcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENoYXRNZXNzYWdlW10gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbiAgcXVlc3Rpb24gPSAnJztcblxuICBfYWN0aW9uczogQWN0aW9uW10gPSBbXTtcblxuICBzdWIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIGRhdGFTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZDtcblxuICAvKiogVmFyaWFibGVzIHRoYXQgZGVwZW5kIG9uIHRoZSB0eXBlIG9mIG1vZGVsIGluIHVzZSAqL1xuICBtb2RlbERlc2NyaXB0aW9uPzogR2xsbU1vZGVsRGVzY3JpcHRpb247XG4gIGFzc2lzdGFudEljb246IHN0cmluZztcbiAgcHJpdmFjeVVybDogc3RyaW5nO1xuXG4gIG1lc3NhZ2VUb0VkaXQ/OiBudW1iZXI7XG4gIGNoYW5nZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTaW1wbGVDaGFuZ2VzIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBjdXJyZW50TWVzc2FnZUluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGZpcnN0Q2hhbmdlc0hhbmRsZWQgPSBmYWxzZTtcbiAgaXNBdEJvdHRvbSA9IHRydWU7XG4gIGluaXRpYWxpemF0aW9uRXJyb3IgPSBmYWxzZTtcbiAgZW5hYmxlZFVzZXJJbnB1dCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9hY3Rpb25zLnB1c2gobmV3IEFjdGlvbih7XG4gICAgICBpY29uOiAnZmFzIGZhLXN5bmMnLFxuICAgICAgdGl0bGU6ICdSZXNldCBjaGF0JyxcbiAgICAgIGFjdGlvbjogKCkgPT4gdGhpcy5sb2FkRGVmYXVsdENoYXQoKVxuICAgIH0pKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc3ViLmFkZChcbiAgICAgIHRoaXMubG9naW5TZXJ2aWNlLmV2ZW50cy5waXBlKFxuICAgICAgICBmaWx0ZXIoZSA9PiBlLnR5cGUgPT09ICdsb2dpbi1jb21wbGV0ZScpLFxuICAgICAgICB0YXAoXyA9PiB0aGlzLmluc3RhbnRpYXRlQ2hhdFNlcnZpY2UoKSksXG4gICAgICAgIG1hcChfID0+IHRoaXMuY2hhdFNlcnZpY2UuaW5pdENoYXRDb25maWcoKSksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmNoYXRTZXJ2aWNlLmluaXRDb25maWckKSxcbiAgICAgICAgZmlsdGVyKGluaXRDb25maWcgPT4gISFpbml0Q29uZmlnKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0KCkpLFxuICAgICAgICBmaWx0ZXIoc3VjY2VzcyA9PiAhIXN1Y2Nlc3MpLFxuICAgICAgICB0YXAoXyA9PiB0aGlzLm9uTG9hZENoYXQoKSksXG4gICAgICAgIHN3aXRjaE1hcChfID0+IHRoaXMuY2hhdFNlcnZpY2UuY2hhdENvbmZpZyQpLFxuICAgICAgICB0YXAoY29uZmlnID0+IHtcbiAgICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyE7XG4gICAgICAgICAgdGhpcy5lbmFibGVkVXNlcklucHV0ID0gdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmVuYWJsZWRVc2VySW5wdXQ7XG4gICAgICAgICAgdGhpcy5fY29uZmlnLmVtaXQoY29uZmlnKTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVNb2RlbERlc2NyaXB0aW9uKCk7XG4gICAgICAgICAgICBpZighdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkKSB7XG4gICAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2hhbmdlcygpO1xuICAgICAgICAgICAgICB0aGlzLmFkZFNjcm9sbExpc3RlbmVyKCk7XG4gICAgICAgICAgICAgIHRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6YXRpb25FcnJvciA9IHRydWVcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICkuc3Vic2NyaWJlKClcbiAgICApO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIHRoaXMuY2hhbmdlcyQubmV4dChjaGFuZ2VzKTtcbiAgICBpZiAodGhpcy5jb25maWcpIHtcbiAgICAgIHRoaXMuaGFuZGxlQ2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgaW5zdGFudGlhdGVDaGF0U2VydmljZSgpOiB2b2lkIHtcbiAgICBzd2l0Y2ggKHRoaXMucHJvdG9jb2wpIHtcbiAgICAgIGNhc2UgJ1JFU1QnOlxuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlID0gdGhpcy5yZXN0U2VydmljZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdXRUJTT0NLRVQnOlxuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlID0gdGhpcy53ZWJzb2NrZXRTZXJ2aWNlO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGZvdW5kIGEgQ2hhdFNlcnZpY2UgaW1wbGVtZW50YXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgcHJvdmlkZWQgcHJvdG9jb2w6ICcke3RoaXMucHJvdG9jb2x9J2ApO1xuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLnNldENoYXRJbnN0YW5jZUlkKHRoaXMuaW5zdGFuY2VJZCk7XG4gICAgdGhpcy5pbnN0YW5jZU1hbmFnZXJTZXJ2aWNlLnN0b3JlSW5zdGFuY2UodGhpcy5pbnN0YW5jZUlkLCB0aGlzLmNoYXRTZXJ2aWNlKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldCBhY3Rpb25zKCkgeyByZXR1cm4gdGhpcy5fYWN0aW9uczsgfVxuXG4gIHByaXZhdGUgaGFuZGxlQ2hhbmdlcygpIHtcbiAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5jaGFuZ2VzJC52YWx1ZTtcbiAgICAvLyBJZiB0aGUgY2hhdCBzZXJ2aWNlIGlzIGEgV2ViU29ja2V0Q2hhdFNlcnZpY2UsIGhhbmRsZSB0aGUgb3ZlcnJpZGUgb2YgdGhlIG1lc3NhZ2UgaGFuZGxlcnMgaWYgZXhpc3RzXG4gICAgaWYgKGNoYW5nZXM/Lm1lc3NhZ2VIYW5kbGVycyAmJiB0aGlzLm1lc3NhZ2VIYW5kbGVycyAmJiB0aGlzLmNoYXRTZXJ2aWNlIGluc3RhbmNlb2YgV2ViU29ja2V0Q2hhdFNlcnZpY2UpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2Uub3ZlcnJpZGVNZXNzYWdlSGFuZGxlcnModGhpcy5tZXNzYWdlSGFuZGxlcnMpO1xuICAgIH1cbiAgICAvLyBJbml0aWFsaXplIHRoZSBjaGF0IHdpdGggdGhlIHByb3ZpZGVkIGNoYXQgbWVzc2FnZXMgaWYgZXhpc3RzLCBvdGhlcndpc2UgbG9hZCB0aGUgZGVmYXVsdCBjaGF0XG4gICAgLy8gT25jZSB0aGUgY2hhdCBpcyBpbml0aWFsaXplZCAoZmlyc3RDaGFuZ2VzSGFuZGxlZCBpcyB0cnVlKSwgYWxsb3cgb3BlbmluZyB0aGUgY2hhdCB3aXRoIHRoZSBuZXcgcHJvdmlkZWQgbWVzc2FnZXMgKGlmIGV4aXN0cylcbiAgICBpZiAoIXRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCB8fCBjaGFuZ2VzPy5jaGF0KSB7XG4gICAgICBjb25zdCBvcGVuQ2hhdCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZXMkLnZhbHVlICYmIHRoaXMuY29uZmlnLnNhdmVkQ2hhdFNldHRpbmdzLmVuYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxpc3RTYXZlZENoYXQoKTsgLy8gUmVmcmVzaCB0aGUgbGlzdCBvZiBzYXZlZCBjaGF0c1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jaGF0IS5tZXNzYWdlcylcbiAgICAgIH07XG4gICAgICB0aGlzLmNoYXQgPyBvcGVuQ2hhdCgpIDogdGhpcy5sb2FkRGVmYXVsdENoYXQoKTtcbiAgICB9XG4gICAgLy8gSWYgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQgYW5kIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBpcyBcIlF1ZXJ5XCIsIHRoZW4gYSBmcmVzaCBuZXcgY2hhdCBzaG91bGQgYmUgc3RhcnRlZCB3aXRoIHRoZSBwcm92aWRlZCBxdWVyeVxuICAgIGlmICh0aGlzLmZpcnN0Q2hhbmdlc0hhbmRsZWQgJiYgY2hhbmdlcz8ucXVlcnkgJiYgdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmV2ZW50ID09PSAnUXVlcnknKSB7XG4gICAgICBjb25zdCBzeXN0ZW1Nc2cgPSB7cm9sZTogJ3N5c3RlbScsIGNvbnRlbnQ6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuc3lzdGVtUHJvbXB0LCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IGZhbHNlfX07XG4gICAgICBjb25zdCB1c2VyTXNnID0ge3JvbGU6ICd1c2VyJywgY29udGVudDogQ2hhdFNlcnZpY2UuZm9ybWF0UHJvbXB0KHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMudXNlclByb21wdCwge3ByaW5jaXBhbDogdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbH0pLCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdH19O1xuICAgICAgLy8gSWYgdGhlIHByb3ZpZGVkIHF1ZXJ5IHRleHQgaXMgbm90IGVtcHR5LCB0aGVuIGFkZCB0aGUgdXNlciBxdWVyeSBtZXNzYWdlIHRvIHRoZSBjaGF0IGhpc3RvcnkgYW5kIGludm9rZSB0aGUgYXNzaXN0YW50XG4gICAgICAvLyBPdGhlcndpc2UsIGp1c3Qgc3RhcnQgYSBuZXcgY2hhdCB3aXRoIGEgd2FybmluZyBtZXNzYWdlIGludml0aW5nIHRoZSB1c2VyIHRvIHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1xuICAgICAgaWYgKCEhdGhpcy5xdWVyeS50ZXh0KSB7XG4gICAgICAgIGNvbnN0IHVzZXJRdWVyeU1zZyA9IHtyb2xlOiAndXNlcicsIGNvbnRlbnQ6IHRoaXMucXVlcnkudGV4dCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZGlzcGxheVVzZXJRdWVyeSwgcXVlcnk6IHRoaXMucXVlcnksIGZvcmNlZFdvcmtmbG93OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csIGlzVXNlcklucHV0OiB0cnVlfX07XG4gICAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jb25maWcubW9kZVNldHRpbmdzLnNlbmRVc2VyUHJvbXB0ID8gW3N5c3RlbU1zZywgdXNlck1zZywgdXNlclF1ZXJ5TXNnXSA6IFtzeXN0ZW1Nc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2FybmluZ01zZyA9IHtyb2xlOiAnYXNzaXN0YW50JywgY29udGVudDogXCJZb3UgbXVzdCBwZXJmb3JtIGEgZnVsbCB0ZXh0IHNlYXJjaCB0byByZXRyaWV2ZSBzb21lIHJlc3VsdHNcIiwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0cnVlfX07XG4gICAgICAgIHRoaXMub3BlbkNoYXQoW3dhcm5pbmdNc2ddKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZFNjcm9sbExpc3RlbmVyKCkge1xuICAgIHRoaXMuc3ViLmFkZChcbiAgICAgIG1lcmdlKHRoaXMubG9hZGluZyQsIHRoaXMubWVzc2FnZXMkLCB0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQsIGZyb21FdmVudCh0aGlzLm1lc3NhZ2VMaXN0IS5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJykpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNBdEJvdHRvbSA9IHRoaXMudG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICB1cGRhdGVNb2RlbERlc2NyaXB0aW9uKCkge1xuICAgIHRoaXMubW9kZWxEZXNjcmlwdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2UuZ2V0TW9kZWwodGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zZXJ2aWNlX2lkLCB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLm1vZGVsX2lkKTtcbiAgICB0aGlzLmFzc2lzdGFudEljb24gPSAhIXRoaXMuY3VzdG9tQXNzaXN0YW50SWNvbiA/IHRoaXMuY3VzdG9tQXNzaXN0YW50SWNvbiA6ICdzcS1zaW5lcXVhJztcbiAgICBzd2l0Y2godGhpcy5tb2RlbERlc2NyaXB0aW9uPy5wcm92aWRlcikge1xuICAgICAgY2FzZSAnR29vZ2xlJzpcbiAgICAgICAgdGhpcy5wcml2YWN5VXJsID0gJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQXp1cmVPcGVuQUknOlxuICAgICAgICB0aGlzLnByaXZhY3lVcmwgPSAnaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2xlZ2FsL2NvZ25pdGl2ZS1zZXJ2aWNlcy9vcGVuYWkvZGF0YS1wcml2YWN5JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdPcGVuQUknOlxuICAgICAgICB0aGlzLnByaXZhY3lVcmwgPSAnaHR0cHM6Ly9vcGVuYWkuY29tL2VudGVycHJpc2UtcHJpdmFjeSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQ29oZXJlJzpcbiAgICAgICAgdGhpcy5wcml2YWN5VXJsID0gJ2h0dHBzOi8vY29oZXJlLmNvbS9zZWN1cml0eSc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBzdWJtaXRRdWVzdGlvbigpIHtcbiAgICBpZih0aGlzLnF1ZXN0aW9uLnRyaW0oKSAmJiB0aGlzLm1lc3NhZ2VzJC52YWx1ZSAmJiB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KSB7XG4gICAgICBpZiAodGhpcy5tZXNzYWdlVG9FZGl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUlcbiAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZS5zbGljZSgwLCB0aGlzLm1lc3NhZ2VUb0VkaXQpKTtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSByYXcgbWVzc2FnZXMgaW4gdGhlIGNoYXQgaGlzdG9yeSB3aGljaCBpcyB0aGUgY2xlYW4gdmVyc2lvbiB1c2VkIHRvIG1ha2UgdGhlIG5leHQgcmVxdWVzdFxuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5zbGljZSgwLCB0aGlzLm1lc3NhZ2VUb0VkaXQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VUb0VkaXQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvLyBSZS1hdHRhY2ggdGhlICRwcm9ncmVzcyBhbmQgJGF0dGFjaG1lbnQgb2YgdGhlIGxhc3QgcmVzcG9uc2UgdG8gdGhlIGxhc3QgYXNzaXN0YW50J3MgcmVzcG9uc2UgaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRwcm9ncmVzcyA9IHRoaXMubWVzc2FnZXMkLnZhbHVlLmF0KC0xKSEuYWRkaXRpb25hbFByb3BlcnRpZXMuJHByb2dyZXNzO1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5hdCgtMSkhLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50ID0gdGhpcy5tZXNzYWdlcyQudmFsdWUuYXQoLTEpIS5hZGRpdGlvbmFsUHJvcGVydGllcy4kYXR0YWNobWVudDtcbiAgICAgIC8vIEZldGNoIHRoZSBhbnN3ZXJcbiAgICAgIHRoaXMuZmV0Y2hBbnN3ZXIodGhpcy5xdWVzdGlvbi50cmltKCksIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhKTtcbiAgICAgIC8vIENsZWFyIHRoZSBpbnB1dCB2YWx1ZSBpbiB0aGUgVUlcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hBbnN3ZXIocXVlc3Rpb246IHN0cmluZywgY29udmVyc2F0aW9uOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgY29uc3QgdXNlck1zZyA9IHtyb2xlOiAndXNlcicsIGNvbnRlbnQ6IHF1ZXN0aW9uLCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRydWUsIGlzVXNlcklucHV0OiB0cnVlfX07XG4gICAgY29uc3QgbWVzc2FnZXMgPSBbLi4uY29udmVyc2F0aW9uLCB1c2VyTXNnXTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzKTtcbiAgICB0aGlzLmZldGNoKG1lc3NhZ2VzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIGxpc3Qgb2YgbWVzc2FnZXMsIGZldGNoIHRoZSBzZXJ2ZXIgZm9yIGEgY29udGludWF0aW9uIGFuZCB1cGRhdGVzXG4gICAqIHRoZSBsaXN0IG9mIG1lc3NhZ2VzIGFjY29yZGluZ2x5LlxuICAgKiBAcGFyYW0gbWVzc2FnZXNcbiAgICovXG4gIHB1YmxpYyBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSkge1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLmxvYWRpbmckLm5leHQodHJ1ZSk7XG4gICAgdGhpcy5kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZGF0YVN1YnNjcmlwdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2UuZmV0Y2gobWVzc2FnZXMsIHRoaXMucXVlcnkpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogcmVzID0+IHRoaXMudXBkYXRlRGF0YShyZXMuaGlzdG9yeSksXG4gICAgICAgIGVycm9yOiBlcnIgPT4ge1xuICAgICAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgdGhpcy5lcnJvci5lbWl0KGVycik7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIGlmKHRoaXMuYXV0b21hdGljU2Nyb2xsVG9MYXN0UmVzcG9uc2UpIHtcbiAgICAgIHRoaXMuc2Nyb2xsRG93bigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIFVJIHdpdGggdGhlIG5ldyBtZXNzYWdlc1xuICAgKiBAcGFyYW0gbWVzc2FnZXNcbiAgICovXG4gIHVwZGF0ZURhdGEobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pIHtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzKTtcbiAgICB0aGlzLmRhdGEuZW1pdChtZXNzYWdlcyk7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLnF1ZXN0aW9uID0gJyc7XG4gICAgaWYodGhpcy5hdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSkge1xuICAgICAgdGhpcy5zY3JvbGxEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0b2dnbGVTY3JvbGxCdXR0b25WaXNpYmlsaXR5KCk6IGJvb2xlYW4ge1xuICAgIGlmKHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSGVpZ2h0IC0gdGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudC5zY3JvbGxUb3AgLSAxKSA8PSB0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzY3JvbGxEb3duKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYodGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0gdGhpcy5tZXNzYWdlTGlzdC5uYXRpdmVFbGVtZW50LnNjcm9sbEhlaWdodDtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfVxuICAgIH0sIDEwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIG5ldyBjaGF0IHdpdGggdGhlIGRlZmF1bHRWYWx1ZXMgc2V0dGluZ3NcbiAgICogSWYgdGhlIHNhdmVkQ2hhdCBmZWF0dXJlIGlzIGVuYWJsZWQsIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzIHdpbGwgYmUgcmVmcmVzaGVkXG4gICAqL1xuICBuZXdDaGF0KCkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkKSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxpc3RTYXZlZENoYXQoKTsgLy8gUmVmcmVzaCB0aGUgbGlzdCBvZiBzYXZlZCBjaGF0c1xuICAgIH1cbiAgICB0aGlzLmxvYWREZWZhdWx0Q2hhdCgpOyAvLyBTdGFydCBhIG5ldyBjaGF0XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgdGhlIGRlZmF1bHQgY2hhdCB3aXRoIHRoZSBkZWZhdWx0VmFsdWVzIHNldHRpbmdzXG4gICAqIElmIHRoZSBjaGF0IGlzIG1lYW50IHRvIGJlIGluaXRpYWxpemVkIHdpdGggZXZlbnQgPT09IFwiUXVlcnlcIiwgdGhlIGNvcnJlc3BvbmRpbmcgdXNlciBxdWVyeSBtZXNzYWdlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGNoYXQgaGlzdG9yeVxuICAgKi9cbiAgbG9hZERlZmF1bHRDaGF0KCkge1xuICAgIGNvbnN0IHN5c3RlbU1zZyA9IHtyb2xlOiAnc3lzdGVtJywgY29udGVudDogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zeXN0ZW1Qcm9tcHQsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogZmFsc2V9fTtcbiAgICBjb25zdCB1c2VyTXNnID0ge3JvbGU6ICd1c2VyJywgY29udGVudDogQ2hhdFNlcnZpY2UuZm9ybWF0UHJvbXB0KHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMudXNlclByb21wdCwge3ByaW5jaXBhbDogdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbH0pLCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdH19O1xuICAgIGlmICh0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZXZlbnQgPT09ICdRdWVyeScpIHtcbiAgICAgIC8vIElmIHRoZSBwcm92aWRlZCBxdWVyeSB0ZXh0IGlzIG5vdCBlbXB0eSwgdGhlbiBhZGQgdGhlIHVzZXIgcXVlcnkgbWVzc2FnZSB0byB0aGUgY2hhdCBoaXN0b3J5IGFuZCBpbnZva2UgdGhlIGFzc2lzdGFudFxuICAgICAgLy8gT3RoZXJ3aXNlLCBqdXN0IHN0YXJ0IGEgbmV3IGNoYXQgd2l0aCBhIHdhcm5pbmcgbWVzc2FnZSBpbnZpdGluZyB0aGUgdXNlciB0byBwZXJmb3JtIGEgZnVsbCB0ZXh0IHNlYXJjaCB0byByZXRyaWV2ZSBzb21lIHJlc3VsdHNcbiAgICAgIGlmICghIXRoaXMucXVlcnkudGV4dCkge1xuICAgICAgICBjb25zdCB1c2VyUXVlcnlNc2cgPSB7cm9sZTogJ3VzZXInLCBjb250ZW50OiB0aGlzLnF1ZXJ5LnRleHQsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmRpc3BsYXlVc2VyUXVlcnksIHF1ZXJ5OiB0aGlzLnF1ZXJ5LCBmb3JjZWRXb3JrZmxvdzogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmZvcmNlZFdvcmtmbG93LCBpc1VzZXJJbnB1dDogdHJ1ZX19O1xuICAgICAgICB0aGlzLm9wZW5DaGF0KHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5zZW5kVXNlclByb21wdCA/IFtzeXN0ZW1Nc2csIHVzZXJNc2csIHVzZXJRdWVyeU1zZ10gOiBbc3lzdGVtTXNnLCB1c2VyUXVlcnlNc2ddKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHdhcm5pbmdNc2cgPSB7cm9sZTogJ2Fzc2lzdGFudCcsIGNvbnRlbnQ6IFwiWW91IG11c3QgcGVyZm9ybSBhIGZ1bGwgdGV4dCBzZWFyY2ggdG8gcmV0cmlldmUgc29tZSByZXN1bHRzXCIsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdHJ1ZX19O1xuICAgICAgICB0aGlzLm9wZW5DaGF0KFt3YXJuaW5nTXNnXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3BlbkNoYXQoW3N5c3RlbU1zZywgdXNlck1zZ10pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydC9vcGVuIGEgbmV3IGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgbWVzc2FnZXMgYW5kIGNoYXRJZFxuICAgKiBJZiB0aGUgbGFzdCBtZXNzYWdlIGlzIGZyb20gdGhlIHVzZXIsIGEgcmVxdWVzdCB0byB0aGUgYXNzaXN0YW50IGlzIG1hZGUgdG8gZ2V0IGFuIGFuc3dlclxuICAgKiBJZiB0aGUgbGFzdCBtZXNzYWdlIGlzIGZyb20gdGhlIGFzc2lzdGFudCwgdGhlIGNvbnZlcnNhdGlvbiBpcyBsb2FkZWQgcmlnaHQgYXdheVxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGxpc3Qgb2YgbWVzc2FnZXMgb2YgdGhlIGNoYXRcbiAgICogQHBhcmFtIGNoYXRJZCAgVGhlIGlkIG9mIHRoZSBjaGF0LiBJZiBub3QgcHJvdmlkZWQsIGEgbmV3IGlkIHdpbGwgYmUgZ2VuZXJhdGVkXG4gICAqL1xuICBvcGVuQ2hhdChtZXNzYWdlczogUmF3TWVzc2FnZVtdLCBjaGF0SWQ/OiBzdHJpbmcpIHtcbiAgICBpZiAoIW1lc3NhZ2VzIHx8ICFBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSkge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb2NjdXJzIHdoaWxlIHRyeWluZyB0byBsb2FkIHRoZSBjaGF0IGRpc2N1c3Npb24uIEludmFsaWQgbWVzc2FnZXMgcmVjZWl2ZWQgOicsIG1lc3NhZ2VzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jaGF0U2VydmljZS5zZXRTYXZlZENoYXRJZChjaGF0SWQgfHwgQ2hhdFNlcnZpY2UuZ2VuZXJhdGVHVUlEKCkpO1xuICAgIHRoaXMucmVzZXRDaGF0KCk7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IG1lc3NhZ2VzO1xuICAgIGNvbnN0IGxhc3RNZXNzYWdlID0gbWVzc2FnZXMuYXQoLTEpO1xuICAgIGlmKGxhc3RNZXNzYWdlICYmIGxhc3RNZXNzYWdlLnJvbGUgPT09ICd1c2VyJykge1xuICAgICAgdGhpcy5mZXRjaChtZXNzYWdlcyk7IC8vIElmIHRoZSBsYXN0IG1lc3NhZ2UgaWYgZnJvbSBhIHVzZXIsIGFuIGFuc3dlciBmcm9tIHRoZSBhc3Npc3RhbnQgaXMgZXhwZWN0ZWRcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGEobWVzc2FnZXMpOyAvLyBJZiB0aGUgbGFzdCBtZXNzYWdlIGlmIGZyb20gdGhlIGFzc2lzdGFudCwgd2UgY2FuIGxvYWQgdGhlIGNvbnZlcnNhdGlvbiByaWdodCBhd2F5XG4gICAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBjaGF0IGJ5IGNsZWFyaW5nIHRoZSBtZXNzYWdlcyBhbmQgdGhlIGNoYXQgaGlzdG9yeVxuICAgKiBUaGUgcXVlc3Rpb24gaW5wdXQgd2lsbCBiZSBmb2N1c2VkIGFmdGVyIHRoZSBjaGF0IGlzIHJlc2V0XG4gICAqIFRoZSBmZXRjaCBzdWJzY3JpcHRpb24gd2lsbCBiZSB0ZXJtaW5hdGVkXG4gICAqL1xuICByZXNldENoYXQoKSB7XG4gICAgaWYodGhpcy5tZXNzYWdlcyQudmFsdWUpIHtcbiAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodW5kZWZpbmVkKTsgLy8gUmVzZXQgY2hhdFxuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdW5kZWZpbmVkOyAvLyBSZXNldCBjaGF0IGhpc3RvcnlcbiAgICB0aGlzLnF1ZXN0aW9uID0gJyc7XG4gICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICB9XG5cbiAgb25Mb2FkQ2hhdCgpIHtcbiAgICB0aGlzLmxvYWRpbmckLm5leHQodHJ1ZSk7XG4gICAgdGhpcy5zdWIuYWRkKFxuICAgICAgdGhpcy5jaGF0U2VydmljZS5sb2FkU2F2ZWRDaGF0JFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoc2F2ZWRDaGF0ID0+ICEhc2F2ZWRDaGF0KSxcbiAgICAgICAgICBzd2l0Y2hNYXAoc2F2ZWRDaGF0ID0+IHRoaXMuY2hhdFNlcnZpY2UuZ2V0U2F2ZWRDaGF0KHNhdmVkQ2hhdCEuaWQpKSxcbiAgICAgICAgICBmaWx0ZXIoc2F2ZWRDaGF0SGlzdG9yeSA9PiAhIXNhdmVkQ2hhdEhpc3RvcnkpLFxuICAgICAgICAgIHRhcChzYXZlZENoYXRIaXN0b3J5ID0+IHRoaXMub3BlbkNoYXQoc2F2ZWRDaGF0SGlzdG9yeSEuaGlzdG9yeSwgc2F2ZWRDaGF0SGlzdG9yeSEuaWQpKVxuICAgICAgICApLnN1YnNjcmliZSgpXG4gICAgKTtcbiAgfVxuXG4gIHRlcm1pbmF0ZUZldGNoKCkge1xuICAgIHRoaXMuZGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRhdGFTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KGZhbHNlKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH0pXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgZWRpdE1lc3NhZ2UoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMubWVzc2FnZVRvRWRpdCA9IGluZGV4O1xuICAgIHRoaXMucXVlc3Rpb24gPSB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtpbmRleF0uY29udGVudDtcbiAgICB0aGlzLnF1ZXN0aW9uSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIHJlZ2VuZXJhdGVNZXNzYWdlKGluZGV4OiBudW1iZXIpIHtcbiAgICAgLy8gRGVmaW5lIHRoZSBjaGF0IGhpc3RvcnkgYmFzZWQgb24gd2hpY2ggdGhlIGFzc2lzdGFudCB3aWxsIGdlbmVyYXRlIGEgbmV3IGFuc3dlclxuICAgIGNvbnN0IHNsaWNlZE1lc3NhZ2VzID0gdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEuc2xpY2UoMCwgaW5kZXgpO1xuICAgIC8vIEFjY29yZGluZ2x5IHVwZGF0ZSB0aGUgbWVzc2FnZXMgaW4gdGhlIFVJXG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChzbGljZWRNZXNzYWdlcyk7XG4gICAgLy8gRmV0Y2ggdGhlIGFuc3dlclxuICAgIHRoaXMuZmV0Y2goc2xpY2VkTWVzc2FnZXMpO1xuICB9XG5cbiAgb25LZXlVcChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgdGhpcy5uYXZpZ2F0ZU1lc3NhZ2UoLTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIHRoaXMubmF2aWdhdGVNZXNzYWdlKDEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgdGhpcy5zdWJtaXRRdWVzdGlvbigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBTaGlmdCArIEVudGVyXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5ICYmIGV2ZW50LmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgdGhpcy5zdWJtaXRRdWVzdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbmF2aWdhdGVNZXNzYWdlKGRpcmVjdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IHx8IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB1c2VyTWVzc2FnZXMgPSB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5LmZpbHRlcihtID0+IG0ucm9sZSA9PT0gJ3VzZXInKTtcblxuICAgIGlmICh1c2VyTWVzc2FnZXMubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY3VycmVudE1lc3NhZ2VJbmRleCA9ICh0aGlzLmN1cnJlbnRNZXNzYWdlSW5kZXggPz8gdXNlck1lc3NhZ2VzLmxlbmd0aCkgKyBkaXJlY3Rpb247XG5cbiAgICBpZiAodGhpcy5jdXJyZW50TWVzc2FnZUluZGV4IDwgMCkge1xuICAgICAgLy8gSWYgdGhlIHVzZXIgcHJlc3NlcyB1cCBhcnJvdyBvbiB0aGUgZmlyc3QgbWVzc2FnZSwgc3RheSBhdCB0aGUgZmlyc3QgbWVzc2FnZVxuICAgICAgdGhpcy5jdXJyZW50TWVzc2FnZUluZGV4ID0gMDtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudE1lc3NhZ2VJbmRleCA+PSB1c2VyTWVzc2FnZXMubGVuZ3RoKSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciBwcmVzc2VzIGRvd24gYXJyb3cgb24gdGhlIGxhc3QgcHJldmlvdXMgbWVzc2FnZSwgY2xlYXIgdGhlIGlucHV0XG4gICAgICB0aGlzLmN1cnJlbnRNZXNzYWdlSW5kZXggPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnF1ZXN0aW9uID0gJyc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5xdWVzdGlvbiA9IHVzZXJNZXNzYWdlc1t0aGlzLmN1cnJlbnRNZXNzYWdlSW5kZXhdLmNvbnRlbnQ7XG4gIH1cbn1cbiIsIlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpbml0aWFsaXphdGlvbkVycm9yXCI+XG4gIDxkaXYgKm5nSWY9XCJtZXNzYWdlcyQgfCBhc3luYyBhcyBtZXNzYWdlczsgZWxzZSBsb2FkaW5nVHBsIHx8IGxvYWRpbmdUcGxEZWZhdWx0XCIgY2xhc3M9XCJoLTEwMCBkLWZsZXggZmxleC1jb2x1bW5cIj5cblxuICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgbGlzdC1ncm91cC1mbHVzaCBvdmVyZmxvdy1hdXRvIHBlLTJcIiAjbWVzc2FnZUxpc3Q+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBtZXNzYWdlIG9mIG1lc3NhZ2VzOyBsZXQgaW5kZXggPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgIDwhLS0gUmVndWxhciBtZXNzYWdlcyAtLT5cbiAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtXCIgKm5nSWY9XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLmRpc3BsYXlcIlxuICAgICAgICAgICAgW2NsYXNzLm9wYWNpdHktNTBdPVwibWVzc2FnZVRvRWRpdCAmJiBtZXNzYWdlVG9FZGl0IDwgaW5kZXggKyAxXCI+XG4gICAgICAgICAgPHNxLWNoYXQtbWVzc2FnZVxuICAgICAgICAgICAgW2NsYXNzLnNxLXVzZXItbWVzc2FnZV09XCJtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFttZXNzYWdlXT1cIm1lc3NhZ2VcIlxuICAgICAgICAgICAgW2NvbnZlcnNhdGlvbl09XCJtZXNzYWdlc1wiXG4gICAgICAgICAgICBbYXNzaXN0YW50SWNvbl09XCJjdXN0b21Bc3Npc3RhbnRJY29uIHx8IGFzc2lzdGFudEljb25cIlxuICAgICAgICAgICAgW3N0cmVhbWluZ109XCJsYXN0ICYmIChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpXCJcbiAgICAgICAgICAgIFtjYW5FZGl0XT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIG1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFtjYW5SZWdlbmVyYXRlXT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIG1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIGxhc3RcIlxuICAgICAgICAgICAgW2NhbkNvcHldPVwiIShsYXN0ICYmIChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpKSAmJiBtZXNzYWdlVG9FZGl0ID09PSB1bmRlZmluZWQgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50J1wiXG4gICAgICAgICAgICAoZWRpdCk9XCJlZGl0TWVzc2FnZShpbmRleClcIiAocmVnZW5lcmF0ZSk9XCJyZWdlbmVyYXRlTWVzc2FnZShpbmRleClcIlxuICAgICAgICAgICAgKHJlZmVyZW5jZUNsaWNrZWQpPVwicmVmZXJlbmNlQ2xpY2tlZC5lbWl0KCRldmVudClcIlxuICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5QcmV2aWV3LmVtaXQoJGV2ZW50KVwiPlxuICAgICAgICAgIDwvc3EtY2hhdC1tZXNzYWdlPlxuICAgICAgICA8L2xpPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbVwiICpuZ0lmPVwiKGxvYWRpbmckIHwgYXN5bmMpID09PSB0cnVlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2FkaW5nVHBsIHx8IGxvYWRpbmdUcGxEZWZhdWx0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L2xpPlxuICAgIDwvdWw+XG5cbiAgICA8ZGl2IGNsYXNzPVwidXNlci1pbnB1dCBtdC1hdXRvXCIgKm5nSWY9XCJlbmFibGVkVXNlcklucHV0XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaW5wdXRUcGxcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtZW5kIHNtYWxsIHRleHQtbXV0ZWQgcHgtM1wiICpuZ0lmPVwiISFjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyXCI+XG4gICAgICAgICAge3sgY29uZmlnPy5nbG9iYWxTZXR0aW5ncz8uZGlzY2xhaW1lciB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48IS0tIE5HIFRFTVBMQVRFUy0tPlxuXG48bmctdGVtcGxhdGUgI2xvYWRpbmdUcGxEZWZhdWx0PlxuICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ncm93IHRleHQtcHJpbWFyeSBkLWJsb2NrIG14LWF1dG8gbXktNVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPkxvYWRpbmcuLi48L3NwYW4+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNpbnB1dFRwbD5cbiAgPGRpdiBjbGFzcz1cInB4LTMgcHktMVwiPlxuICAgIDxkaXYgY2xhc3M9XCJhc3QtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1zZWFyY2hcIj48L2k+XG4gICAgICA8aW5wdXQgI3F1ZXN0aW9uSW5wdXRcbiAgICAgICAgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiQXNrIHNvbWV0aGluZ1wiIGF1dG9mb2N1c1xuICAgICAgICBbKG5nTW9kZWwpXT1cInF1ZXN0aW9uXCJcbiAgICAgICAgKGtleXVwKT1cIm9uS2V5VXAoJGV2ZW50KVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIobG9hZGluZyQgfCBhc3luYykgfHwgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYylcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCIhKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgJiYgIShsb2FkaW5nJCB8IGFzeW5jKVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImJ0biBidG4tbGlnaHQgbXMtMlwiXG4gICAgICAgIHRpdGxlPVwiU2VuZCBtZXNzYWdlXCJcbiAgICAgICAgKGNsaWNrKT1cInN1Ym1pdFF1ZXN0aW9uKClcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtcGFwZXItcGxhbmVcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS08YnV0dG9uXG4gICAgICAgICpuZ0lmPVwiKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYylcIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxpZ2h0IG1zLTJcIlxuICAgICAgICB0aXRsZT1cIlN0b3AgZ2VuZXJhdGluZ1wiXG4gICAgICAgIChjbGljayk9XCJ0ZXJtaW5hdGVGZXRjaCgpXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXN0b3BcIj48L2k+XG4gICAgICA8L2J1dHRvbj4tLT5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCJtZXNzYWdlVG9FZGl0XCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBtcy0yXCJcbiAgICAgICAgdGl0bGU9XCJDYW5jZWwgZWRpdGlvblwiXG4gICAgICAgIChjbGljayk9XCJtZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkOyBxdWVzdGlvbiA9ICcnXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXVuZG8tYWx0XCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwic3EtZmxvYXRpbmctc2Nyb2xsXCIgKm5nSWY9XCIhaXNBdEJvdHRvbVwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNoYWRvd1wiIChjbGljayk9XCJzY3JvbGxEb3duKClcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1kb3VibGUtZG93blwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
425
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBOEIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFOLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNELE9BQU8sRUFBRSxtQkFBbUIsRUFBVSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZ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LEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQU9HLDhCQUE4QjtzQkFBdEMsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRUcsNkJBQTZCO3NCQUFyQyxLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBRUksSUFBSTtzQkFBYixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNZLFFBQVE7c0JBQTFCLE1BQU07dUJBQUMsU0FBUztnQkFDUCxLQUFLO3NCQUFkLE1BQU07Z0JBQ1csT0FBTztzQkFBeEIsTUFBTTt1QkFBQyxRQUFRO2dCQUVVLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYTtnQkFDSSxhQUFhO3NCQUF4QyxTQUFTO3VCQUFDLGVBQWU7Z0JBRUUsVUFBVTtzQkFBckMsWUFBWTt1QkFBQyxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgQ29udGVudENoaWxkLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIkBzaW5lcXVhL2NvbXBvbmVudHMvYWN0aW9uXCI7XG5pbXBvcnQgeyBBYnN0cmFjdEZhY2V0IH0gZnJvbSBcIkBzaW5lcXVhL2NvbXBvbmVudHMvZmFjZXRcIjtcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29tcG9uZW50cy9zZWFyY2hcIjtcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSBcIkBzaW5lcXVhL2NvcmUvYXBwLXV0aWxzXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxXZWJTZXJ2aWNlLCBSZWNvcmQgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS93ZWItc2VydmljZXNcIjtcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBmaWx0ZXIsIGZyb21FdmVudCwgbWFwLCBtZXJnZSwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgQ2hhdFNlcnZpY2UgfSBmcm9tIFwiLi9jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXRDb250ZXh0QXR0YWNobWVudCwgQ2hhdENvbmZpZywgQ2hhdE1lc3NhZ2UsIEdsbG1Nb2RlbERlc2NyaXB0aW9uLCBNZXNzYWdlSGFuZGxlciwgUmF3TWVzc2FnZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlIH0gZnJvbSBcIi4vaW5zdGFuY2UtbWFuYWdlci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBXZWJTb2NrZXRDaGF0U2VydmljZSB9IGZyb20gXCIuL3dlYnNvY2tldC1jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXRNZXNzYWdlQ29tcG9uZW50IH0gZnJvbSBcIi4vY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnRcIjtcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBMb2dpblNlcnZpY2UgfSBmcm9tIFwiQHNpbmVxdWEvY29yZS9sb2dpblwiO1xuaW1wb3J0IHsgUmVzdENoYXRTZXJ2aWNlIH0gZnJvbSBcIi4vcmVzdC1jaGF0LnNlcnZpY2VcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJbml0Q2hhdCB7XG4gIG1lc3NhZ2VzOiBSYXdNZXNzYWdlW107XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NxLWNoYXQtdjMnLCAvLyBtYW5kYXRvcnkgc2luY2UgQHNpbmVxdWEvY29tcG9uZW50cyBhbHJlYWR5IGhhcyB0aGUgc2FtZSB0YWctbmFtZSBcInNxLWNoYXRcIlxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXQuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgUmVzdENoYXRTZXJ2aWNlLFxuICAgIFdlYlNvY2tldENoYXRTZXJ2aWNlXG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgQ2hhdE1lc3NhZ2VDb21wb25lbnRdXG59KVxuZXhwb3J0IGNsYXNzIENoYXRDb21wb25lbnQgZXh0ZW5kcyBBYnN0cmFjdEZhY2V0IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgcHVibGljIGxvZ2luU2VydmljZSA9IGluamVjdChMb2dpblNlcnZpY2UpO1xuICBwdWJsaWMgd2Vic29ja2V0U2VydmljZSA9IGluamVjdChXZWJTb2NrZXRDaGF0U2VydmljZSk7XG4gIHB1YmxpYyByZXN0U2VydmljZSA9IGluamVjdChSZXN0Q2hhdFNlcnZpY2UpO1xuICBwdWJsaWMgaW5zdGFuY2VNYW5hZ2VyU2VydmljZSA9IGluamVjdChJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlKTtcbiAgcHVibGljIHNlYXJjaFNlcnZpY2UgPSBpbmplY3QoU2VhcmNoU2VydmljZSk7XG4gIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlID0gaW5qZWN0KFByaW5jaXBhbFdlYlNlcnZpY2UpO1xuICBwdWJsaWMgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAvKiogRGVmaW5lIHRoZSBrZXkgYmFzZWQgb24gaXQsIHRoZSBjaGF0IHNlcnZpY2UgaW5zdGFuY2Ugd2lsbCBiZSBzdG9yZWQgKi9cbiAgQElucHV0KCkgaW5zdGFuY2VJZDogc3RyaW5nO1xuICAvKiogRGVmaW5lIHRoZSBxdWVyeSB0byB1c2UgdG8gZmV0Y2ggYW5zd2VycyAqL1xuICBASW5wdXQoKSBxdWVyeTogUXVlcnkgPSB0aGlzLnNlYXJjaFNlcnZpY2UucXVlcnk7XG4gIC8qKiBGdW5jdGlvbiB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgYWZ0ZXIgdGhlIHF1ZXJ5IGNoYW5nZXNcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgY2hhdCB3aWxsIGJlIHJlbG9hZGVkIGJ5IGRlZmF1bHRcbiAgICogQHBhcmFtIHByZXZRdWVyeSBUaGUgcHJldmlvdXMgcXVlcnlcbiAgICogQHBhcmFtIG5ld1F1ZXJ5IFRoZSBuZXcgcXVlcnlcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgQElucHV0KCkgcXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkOiAocHJldlF1ZXJ5OiBhbnksIG5ld1F1ZXJ5OiBhbnkpID0+IGJvb2xlYW47XG4gIC8qKiBEZWZpbmUgdGhlIHByb3RvY29sIHRvIGJlIHVzZWQgZm9yIHRoaXMgY2hhdCBpbnN0YW5jZSovXG4gIEBJbnB1dCgpIHByb3RvY29sOiAnUkVTVCcgfCAnV0VCU09DS0VUJyA9IFwiV0VCU09DS0VUXCI7XG4gIC8qKiBNYXAgb2YgbGlzdGVuZXJzIG92ZXJyaWRpbmcgZGVmYXVsdCByZWdpc3RlcmVkIG9uZXMqL1xuICBASW5wdXQoKSBtZXNzYWdlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIE1lc3NhZ2VIYW5kbGVyPGFueT4+ID0gbmV3IE1hcCgpO1xuICAvKiogV2hlbiB0aGUgYXNzaXN0YW50IGFuc3dlciBhIHVzZXIgcXVlc3Rpb24sIGF1dG9tYXRpY2FsbHkgc2Nyb2xsIGRvd24gdG8gdGhlIGJvdHRvbSBvZiB0aGUgZGlzY3Vzc2lvbiAqL1xuICBASW5wdXQoKSBhdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSA9IGZhbHNlO1xuICBASW5wdXQoKSBjaGF0PzogSW5pdENoYXQ7XG4gIEBJbnB1dCgpIGN1c3RvbUFzc2lzdGFudEljb24gPSAnJztcblxuICBAT3V0cHV0KCkgZGF0YSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2VbXT4oKTtcbiAgQE91dHB1dCgpIHJlZmVyZW5jZUNsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFJlY29yZD4oKTtcbiAgQE91dHB1dCgpIG9wZW5QcmV2aWV3ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0Q29udGV4dEF0dGFjaG1lbnQ+KCk7XG4gIEBPdXRwdXQoXCJsb2FkaW5nXCIpIGxvYWRpbmckID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPihmYWxzZSk7XG4gIEBPdXRwdXQoKSBlcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KFwiY29uZmlnXCIpIF9jb25maWcgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRDb25maWc+KCk7XG5cbiAgQFZpZXdDaGlsZCgnbWVzc2FnZUxpc3QnKSBtZXNzYWdlTGlzdD86IEVsZW1lbnRSZWY8SFRNTFVMaXN0RWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3F1ZXN0aW9uSW5wdXQnKSBxdWVzdGlvbklucHV0PzogRWxlbWVudFJlZjxIVE1MVGV4dEFyZWFFbGVtZW50PjtcblxuICBAQ29udGVudENoaWxkKCdsb2FkaW5nVHBsJykgbG9hZGluZ1RwbD86IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgY2hhdFNlcnZpY2U6IENoYXRTZXJ2aWNlO1xuICBjb25maWc6IENoYXRDb25maWc7XG4gIG1lc3NhZ2VzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q2hhdE1lc3NhZ2VbXSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBxdWVzdGlvbiA9ICcnO1xuXG4gIF9hY3Rpb25zOiBBY3Rpb25bXSA9IFtdO1xuXG4gIHN1YiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgZGF0YVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkO1xuXG4gIC8qKiBWYXJpYWJsZXMgdGhhdCBkZXBlbmQgb24gdGhlIHR5cGUgb2YgbW9kZWwgaW4gdXNlICovXG4gIG1vZGVsRGVzY3JpcHRpb24/OiBHbGxtTW9kZWxEZXNjcmlwdGlvbjtcbiAgYXNzaXN0YW50SWNvbjogc3RyaW5nO1xuICBwcml2YWN5VXJsOiBzdHJpbmc7XG5cbiAgbWVzc2FnZVRvRWRpdD86IG51bWJlcjtcbiAgY2hhbmdlcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNpbXBsZUNoYW5nZXMgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIGN1cnJlbnRNZXNzYWdlSW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgZmlyc3RDaGFuZ2VzSGFuZGxlZCA9IGZhbHNlO1xuICBpc0F0Qm90dG9tID0gdHJ1ZTtcbiAgaW5pdGlhbGl6YXRpb25FcnJvciA9IGZhbHNlO1xuICBlbmFibGVkVXNlcklucHV0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2FjdGlvbnMucHVzaChuZXcgQWN0aW9uKHtcbiAgICAgIGljb246ICdmYXMgZmEtc3luYycsXG4gICAgICB0aXRsZTogJ1Jlc2V0IGNoYXQnLFxuICAgICAgYWN0aW9uOiAoKSA9PiB0aGlzLmxvYWREZWZhdWx0Q2hhdCgpXG4gICAgfSkpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWIuYWRkKFxuICAgICAgdGhpcy5sb2dpblNlcnZpY2UuZXZlbnRzLnBpcGUoXG4gICAgICAgIGZpbHRlcihlID0+IGUudHlwZSA9PT0gJ2xvZ2luLWNvbXBsZXRlJyksXG4gICAgICAgIHRhcChfID0+IHRoaXMuaW5zdGFudGlhdGVDaGF0U2VydmljZSgpKSxcbiAgICAgICAgbWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0Q2hhdENvbmZpZygpKSxcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuY2hhdFNlcnZpY2UuaW5pdENvbmZpZyQpLFxuICAgICAgICBmaWx0ZXIoaW5pdENvbmZpZyA9PiAhIWluaXRDb25maWcpLFxuICAgICAgICBzd2l0Y2hNYXAoXyA9PiB0aGlzLmNoYXRTZXJ2aWNlLmluaXQoKSksXG4gICAgICAgIGZpbHRlcihzdWNjZXNzID0+ICEhc3VjY2VzcyksXG4gICAgICAgIHRhcChfID0+IHRoaXMub25Mb2FkQ2hhdCgpKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5jaGF0Q29uZmlnJCksXG4gICAgICAgIHRhcChjb25maWcgPT4ge1xuICAgICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnITtcbiAgICAgICAgICB0aGlzLmVuYWJsZWRVc2VySW5wdXQgPSB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuZW5hYmxlZFVzZXJJbnB1dDtcbiAgICAgICAgICB0aGlzLl9jb25maWcuZW1pdChjb25maWcpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1vZGVsRGVzY3JpcHRpb24oKTtcbiAgICAgICAgICAgIGlmKCF0aGlzLmZpcnN0Q2hhbmdlc0hhbmRsZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGFuZ2VzKCk7XG4gICAgICAgICAgICAgIHRoaXMuYWRkU2Nyb2xsTGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXphdGlvbkVycm9yID0gdHJ1ZVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgdGhpcy5jaGFuZ2VzJC5uZXh0KGNoYW5nZXMpO1xuICAgIGlmICh0aGlzLmNvbmZpZykge1xuICAgICAgdGhpcy5oYW5kbGVDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRhdGFTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBpbnN0YW50aWF0ZUNoYXRTZXJ2aWNlKCk6IHZvaWQge1xuICAgIHN3aXRjaCAodGhpcy5wcm90b2NvbCkge1xuICAgICAgY2FzZSAnUkVTVCc6XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UgPSB0aGlzLnJlc3RTZXJ2aWNlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1dFQlNPQ0tFVCc6XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UgPSB0aGlzLndlYnNvY2tldFNlcnZpY2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZm91bmQgYSBDaGF0U2VydmljZSBpbXBsZW1lbnRhdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm92aWRlZCBwcm90b2NvbDogJyR7dGhpcy5wcm90b2NvbH0nYCk7XG4gICAgfVxuICAgIHRoaXMuY2hhdFNlcnZpY2Uuc2V0Q2hhdEluc3RhbmNlSWQodGhpcy5pbnN0YW5jZUlkKTtcbiAgICB0aGlzLmluc3RhbmNlTWFuYWdlclNlcnZpY2Uuc3RvcmVJbnN0YW5jZSh0aGlzLmluc3RhbmNlSWQsIHRoaXMuY2hhdFNlcnZpY2UpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZ2V0IGFjdGlvbnMoKSB7IHJldHVybiB0aGlzLl9hY3Rpb25zOyB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDaGFuZ2VzKCkge1xuICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLmNoYW5nZXMkLnZhbHVlO1xuICAgIC8vIElmIHRoZSBjaGF0IHNlcnZpY2UgaXMgYSBXZWJTb2NrZXRDaGF0U2VydmljZSwgaGFuZGxlIHRoZSBvdmVycmlkZSBvZiB0aGUgbWVzc2FnZSBoYW5kbGVycyBpZiBleGlzdHNcbiAgICBpZiAoY2hhbmdlcz8ubWVzc2FnZUhhbmRsZXJzICYmIHRoaXMubWVzc2FnZUhhbmRsZXJzICYmIHRoaXMuY2hhdFNlcnZpY2UgaW5zdGFuY2VvZiBXZWJTb2NrZXRDaGF0U2VydmljZSkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5vdmVycmlkZU1lc3NhZ2VIYW5kbGVycyh0aGlzLm1lc3NhZ2VIYW5kbGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhlIGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgY2hhdCBtZXNzYWdlcyBpZiBleGlzdHMsIG90aGVyd2lzZSBsb2FkIHRoZSBkZWZhdWx0IGNoYXRcbiAgICAgKiBPbmNlIHRoZSBjaGF0IGlzIGluaXRpYWxpemVkIChmaXJzdENoYW5nZXNIYW5kbGVkIGlzIHRydWUpLCBhbGxvdyBvcGVuaW5nIHRoZSBjaGF0IHdpdGggdGhlIG5ldyBwcm92aWRlZCBtZXNzYWdlcyAoaWYgZXhpc3RzKVxuICAgICAqL1xuICAgIGlmICghdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkIHx8IGNoYW5nZXM/LmNoYXQpIHtcbiAgICAgIGNvbnN0IG9wZW5DaGF0ID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlcyQudmFsdWUgJiYgdGhpcy5jb25maWcuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2UubGlzdFNhdmVkQ2hhdCgpOyAvLyBSZWZyZXNoIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcGVuQ2hhdCh0aGlzLmNoYXQhLm1lc3NhZ2VzKVxuICAgICAgfTtcbiAgICAgIHRoaXMuY2hhdCA/IG9wZW5DaGF0KCkgOiB0aGlzLmxvYWREZWZhdWx0Q2hhdCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY2hhdCBpcyBpbml0aWFsaXplZCwgdGhlIGluaXRpYWxpemF0aW9uIGV2ZW50IGlzIFwiUXVlcnlcIiwgdGhlIHF1ZXJ5IGNoYW5nZXMgYW5kIHRoZSBxdWVyeUNoYW5nZVNob3VsZFRyaWdnZXJSZWxvYWQgZnVuY3Rpb24gaXMgcHJvdmlkZWQsXG4gICAgICogdGhlbiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgaWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgICAqIE90aGVyd2lzZSwgdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBpZiAodGhpcy5maXJzdENoYW5nZXNIYW5kbGVkICYmIGNoYW5nZXM/LnF1ZXJ5ICYmIHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5ldmVudCA9PT0gJ1F1ZXJ5Jykge1xuICAgICAgY29uc3QgcHJldmlvdXNRdWVyeSA9IGNoYW5nZXMucXVlcnkucHJldmlvdXNWYWx1ZTtcbiAgICAgIGNvbnN0IGN1cnJlbnRRdWVyeSA9IGNoYW5nZXMucXVlcnkuY3VycmVudFZhbHVlO1xuXG4gICAgICBpZiAodGhpcy5xdWVyeUNoYW5nZVNob3VsZFRyaWdnZXJSZWxvYWQgPyB0aGlzLnF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZChwcmV2aW91c1F1ZXJ5LCBjdXJyZW50UXVlcnkpIDogdHJ1ZSkge1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxvYWRBZnRlclF1ZXJ5Q2hhbmdlKGN1cnJlbnRRdWVyeSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0cmlnZ2VyUmVsb2FkQWZ0ZXJRdWVyeUNoYW5nZShxdWVyeTogUXVlcnkpIHtcbiAgICBjb25zdCBzeXN0ZW1Nc2cgPSB7cm9sZTogJ3N5c3RlbScsIGNvbnRlbnQ6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuc3lzdGVtUHJvbXB0LCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IGZhbHNlfX07XG4gICAgY29uc3QgdXNlck1zZyA9IHtyb2xlOiAndXNlcicsIGNvbnRlbnQ6IENoYXRTZXJ2aWNlLmZvcm1hdFByb21wdCh0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnVzZXJQcm9tcHQsIHtwcmluY2lwYWw6IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWx9KSwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuZGlzcGxheVVzZXJQcm9tcHR9fTtcbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcHJvdmlkZWQgcXVlcnkgdGV4dCBpcyBub3QgZW1wdHksIHRoZW4gYWRkIHRoZSB1c2VyIHF1ZXJ5IG1lc3NhZ2UgdG8gdGhlIGNoYXQgaGlzdG9yeSBhbmQgaW52b2tlIHRoZSBhc3Npc3RhbnRcbiAgICAgKiBPdGhlcndpc2UsIGp1c3Qgc3RhcnQgYSBuZXcgY2hhdCB3aXRoIGEgd2FybmluZyBtZXNzYWdlIGludml0aW5nIHRoZSB1c2VyIHRvIHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1xuICAgICAqL1xuICAgIGlmICghIXRoaXMucXVlcnkudGV4dCkge1xuICAgICAgY29uc3QgdXNlclF1ZXJ5TXNnID0ge3JvbGU6ICd1c2VyJywgY29udGVudDogdGhpcy5xdWVyeS50ZXh0LCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5kaXNwbGF5VXNlclF1ZXJ5LCBxdWVyeTogdGhpcy5xdWVyeSwgZm9yY2VkV29ya2Zsb3c6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRXb3JrZmxvdywgaXNVc2VySW5wdXQ6IHRydWV9fTtcbiAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jb25maWcubW9kZVNldHRpbmdzLnNlbmRVc2VyUHJvbXB0ID8gW3N5c3RlbU1zZywgdXNlck1zZywgdXNlclF1ZXJ5TXNnXSA6IFtzeXN0ZW1Nc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB3YXJuaW5nTXNnID0ge3JvbGU6ICdhc3Npc3RhbnQnLCBjb250ZW50OiBcIllvdSBtdXN0IHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1wiLCBhZGRpdGlvbmFsUHJvcGVydGllczoge2Rpc3BsYXk6IHRydWV9fTtcbiAgICAgIHRoaXMub3BlbkNoYXQoW3dhcm5pbmdNc2ddKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZFNjcm9sbExpc3RlbmVyKCkge1xuICAgIHRoaXMuc3ViLmFkZChcbiAgICAgIG1lcmdlKHRoaXMubG9hZGluZyQsIHRoaXMubWVzc2FnZXMkLCB0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQsIGZyb21FdmVudCh0aGlzLm1lc3NhZ2VMaXN0IS5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJykpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNBdEJvdHRvbSA9IHRoaXMudG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICB1cGRhdGVNb2RlbERlc2NyaXB0aW9uKCkge1xuICAgIHRoaXMubW9kZWxEZXNjcmlwdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2UuZ2V0TW9kZWwodGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zZXJ2aWNlX2lkLCB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLm1vZGVsX2lkKTtcbiAgICB0aGlzLmFzc2lzdGFudEljb24gPSAhIXRoaXMuY3VzdG9tQXNzaXN0YW50SWNvbiA/IHRoaXMuY3VzdG9tQXNzaXN0YW50SWNvbiA6ICdzcS1zaW5lcXVhJztcbiAgICBzd2l0Y2godGhpcy5tb2RlbERlc2NyaXB0aW9uPy5wcm92aWRlcikge1xuICAgICAgY2FzZSAnR29vZ2xlJzpcbiAgICAgICAgdGhpcy5wcml2YWN5VXJsID0gJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQXp1cmVPcGVuQUknOlxuICAgICAgICB0aGlzLnByaXZhY3lVcmwgPSAnaHR0cHM6Ly9sZWFybi5taWNyb3NvZnQuY29tL2VuLXVzL2xlZ2FsL2NvZ25pdGl2ZS1zZXJ2aWNlcy9vcGVuYWkvZGF0YS1wcml2YWN5JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdPcGVuQUknOlxuICAgICAgICB0aGlzLnByaXZhY3lVcmwgPSAnaHR0cHM6Ly9vcGVuYWkuY29tL2VudGVycHJpc2UtcHJpdmFjeSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQ29oZXJlJzpcbiAgICAgICAgdGhpcy5wcml2YWN5VXJsID0gJ2h0dHBzOi8vY29oZXJlLmNvbS9zZWN1cml0eSc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBzdWJtaXRRdWVzdGlvbigpIHtcbiAgICBpZih0aGlzLnF1ZXN0aW9uLnRyaW0oKSAmJiB0aGlzLm1lc3NhZ2VzJC52YWx1ZSAmJiB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KSB7XG4gICAgICBpZiAodGhpcy5tZXNzYWdlVG9FZGl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUlcbiAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZS5zbGljZSgwLCB0aGlzLm1lc3NhZ2VUb0VkaXQpKTtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSByYXcgbWVzc2FnZXMgaW4gdGhlIGNoYXQgaGlzdG9yeSB3aGljaCBpcyB0aGUgY2xlYW4gdmVyc2lvbiB1c2VkIHRvIG1ha2UgdGhlIG5leHQgcmVxdWVzdFxuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5zbGljZSgwLCB0aGlzLm1lc3NhZ2VUb0VkaXQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VUb0VkaXQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvLyBGZXRjaCB0aGUgYW5zd2VyXG4gICAgICB0aGlzLmZldGNoQW5zd2VyKHRoaXMucXVlc3Rpb24udHJpbSgpLCB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICAgIC8vIENsZWFyIHRoZSBpbnB1dCB2YWx1ZSBpbiB0aGUgVUlcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgICAgdGhpcy5xdWVzdGlvbklucHV0IS5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGBhdXRvYDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZldGNoQW5zd2VyKHF1ZXN0aW9uOiBzdHJpbmcsIGNvbnZlcnNhdGlvbjogQ2hhdE1lc3NhZ2VbXSkge1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7cm9sZTogJ3VzZXInLCBjb250ZW50OiBxdWVzdGlvbiwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0cnVlLCBpc1VzZXJJbnB1dDogdHJ1ZX19O1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gWy4uLmNvbnZlcnNhdGlvbiwgdXNlck1zZ107XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5mZXRjaChtZXNzYWdlcyk7XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gYSBsaXN0IG9mIG1lc3NhZ2VzLCBmZXRjaCB0aGUgc2VydmVyIGZvciBhIGNvbnRpbnVhdGlvbiBhbmQgdXBkYXRlc1xuICAgKiB0aGUgbGlzdCBvZiBtZXNzYWdlcyBhY2NvcmRpbmdseS5cbiAgICogQHBhcmFtIG1lc3NhZ2VzXG4gICAqL1xuICBwdWJsaWMgZmV0Y2gobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pIHtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KHRydWUpO1xuICAgIHRoaXMuZGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRhdGFTdWJzY3JpcHRpb24gPSB0aGlzLmNoYXRTZXJ2aWNlLmZldGNoKG1lc3NhZ2VzLCB0aGlzLnF1ZXJ5KVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IHJlcyA9PiB0aGlzLnVwZGF0ZURhdGEocmVzLmhpc3RvcnkpLFxuICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgIHRoaXMuZXJyb3IuZW1pdChlcnIpO1xuICAgICAgICB9LFxuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZih0aGlzLmF1dG9tYXRpY1Njcm9sbFRvTGFzdFJlc3BvbnNlKSB7XG4gICAgICB0aGlzLnNjcm9sbERvd24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBVSSB3aXRoIHRoZSBuZXcgbWVzc2FnZXNcbiAgICogQHBhcmFtIG1lc3NhZ2VzXG4gICAqL1xuICB1cGRhdGVEYXRhKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5kYXRhLmVtaXQobWVzc2FnZXMpO1xuICAgIHRoaXMubG9hZGluZyQubmV4dChmYWxzZSk7XG4gICAgdGhpcy5xdWVzdGlvbiA9ICcnO1xuICAgIGlmKHRoaXMuYXV0b21hdGljU2Nyb2xsVG9MYXN0UmVzcG9uc2UpIHtcbiAgICAgIHRoaXMuc2Nyb2xsRG93bigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpOiBib29sZWFuIHtcbiAgICBpZih0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50LnNjcm9sbEhlaWdodCAtIHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wIC0gMSkgPD0gdGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc2Nyb2xsRG93bigpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmKHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlTGlzdC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCA9IHRoaXMubWVzc2FnZUxpc3QubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9LCAxMCk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgYSBuZXcgY2hhdCB3aXRoIHRoZSBkZWZhdWx0VmFsdWVzIHNldHRpbmdzXG4gICAqIFRoZSBzYXZlZENoYXRJZCBpbiB0aGUgY2hhdCBzZXJ2aWNlIHdpbGwgYmUgcmVzZXQsIHNvIHRoYXQgdGhlIHVwY29taW5nIHNhdmVkIGNoYXQgb3BlcmF0aW9ucyB3aWxsIGJlIHBlcmZvcm1lZCBvbiB0aGUgZnJlc2ggbmV3IGNoYXRcbiAgICogSWYgdGhlIHNhdmVkQ2hhdCBmZWF0dXJlIGlzIGVuYWJsZWQsIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzIHdpbGwgYmUgcmVmcmVzaGVkXG4gICAqL1xuICBuZXdDaGF0KCkge1xuICAgIHRoaXMuY2hhdFNlcnZpY2Uuc2V0U2F2ZWRDaGF0SWQodW5kZWZpbmVkKTsgLy8gUmVzZXQgdGhlIHNhdmVkQ2hhdElkXG4gICAgaWYgKHRoaXMuY29uZmlnLnNhdmVkQ2hhdFNldHRpbmdzLmVuYWJsZWQpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UubGlzdFNhdmVkQ2hhdCgpOyAvLyBSZWZyZXNoIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzXG4gICAgfVxuICAgIHRoaXMubG9hZERlZmF1bHRDaGF0KCk7IC8vIFN0YXJ0IGEgbmV3IGNoYXRcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCB0aGUgZGVmYXVsdCBjaGF0IHdpdGggdGhlIGRlZmF1bHRWYWx1ZXMgc2V0dGluZ3NcbiAgICogSWYgdGhlIGNoYXQgaXMgbWVhbnQgdG8gYmUgaW5pdGlhbGl6ZWQgd2l0aCBldmVudCA9PT0gXCJRdWVyeVwiLCB0aGUgY29ycmVzcG9uZGluZyB1c2VyIHF1ZXJ5IG1lc3NhZ2Ugd2lsbCBiZSBhZGRlZCB0byB0aGUgY2hhdCBoaXN0b3J5XG4gICAqL1xuICBsb2FkRGVmYXVsdENoYXQoKSB7XG4gICAgY29uc3Qgc3lzdGVtTXNnID0ge3JvbGU6ICdzeXN0ZW0nLCBjb250ZW50OiB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnN5c3RlbVByb21wdCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiBmYWxzZX19O1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7cm9sZTogJ3VzZXInLCBjb250ZW50OiBDaGF0U2VydmljZS5mb3JtYXRQcm9tcHQodGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy51c2VyUHJvbXB0LCB7cHJpbmNpcGFsOiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsfSksIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmRpc3BsYXlVc2VyUHJvbXB0fX07XG4gICAgaWYgKHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5ldmVudCA9PT0gJ1F1ZXJ5Jykge1xuICAgICAgLy8gSWYgdGhlIHByb3ZpZGVkIHF1ZXJ5IHRleHQgaXMgbm90IGVtcHR5LCB0aGVuIGFkZCB0aGUgdXNlciBxdWVyeSBtZXNzYWdlIHRvIHRoZSBjaGF0IGhpc3RvcnkgYW5kIGludm9rZSB0aGUgYXNzaXN0YW50XG4gICAgICAvLyBPdGhlcndpc2UsIGp1c3Qgc3RhcnQgYSBuZXcgY2hhdCB3aXRoIGEgd2FybmluZyBtZXNzYWdlIGludml0aW5nIHRoZSB1c2VyIHRvIHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1xuICAgICAgaWYgKCEhdGhpcy5xdWVyeS50ZXh0KSB7XG4gICAgICAgIGNvbnN0IHVzZXJRdWVyeU1zZyA9IHtyb2xlOiAndXNlcicsIGNvbnRlbnQ6IHRoaXMucXVlcnkudGV4dCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZGlzcGxheVVzZXJRdWVyeSwgcXVlcnk6IHRoaXMucXVlcnksIGZvcmNlZFdvcmtmbG93OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csIGlzVXNlcklucHV0OiB0cnVlfX07XG4gICAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jb25maWcubW9kZVNldHRpbmdzLnNlbmRVc2VyUHJvbXB0ID8gW3N5c3RlbU1zZywgdXNlck1zZywgdXNlclF1ZXJ5TXNnXSA6IFtzeXN0ZW1Nc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgd2FybmluZ01zZyA9IHtyb2xlOiAnYXNzaXN0YW50JywgY29udGVudDogXCJZb3UgbXVzdCBwZXJmb3JtIGEgZnVsbCB0ZXh0IHNlYXJjaCB0byByZXRyaWV2ZSBzb21lIHJlc3VsdHNcIiwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiB0cnVlfX07XG4gICAgICAgIHRoaXMub3BlbkNoYXQoW3dhcm5pbmdNc2ddKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcGVuQ2hhdChbc3lzdGVtTXNnLCB1c2VyTXNnXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0L29wZW4gYSBuZXcgY2hhdCB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlcyBhbmQgY2hhdElkXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgdXNlciwgYSByZXF1ZXN0IHRvIHRoZSBhc3Npc3RhbnQgaXMgbWFkZSB0byBnZXQgYW4gYW5zd2VyXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgYXNzaXN0YW50LCB0aGUgY29udmVyc2F0aW9uIGlzIGxvYWRlZCByaWdodCBhd2F5XG4gICAqIEBwYXJhbSBtZXNzYWdlcyBUaGUgbGlzdCBvZiBtZXNzYWdlcyBvZiB0aGUgY2hhdFxuICAgKiBAcGFyYW0gY2hhdElkICBUaGUgaWQgb2YgdGhlIGNoYXQuIElmIHByb3ZpZGVkIChpZS4gYW4gZXhpc3RpbmcgZGlzY3Vzc2lvbiBpbiB0aGUgc2F2ZWQgY2hhdCBpbmRleCksIHVwZGF0ZSB0aGUgc2F2ZWRDaGF0SWQgaW4gdGhlIGNoYXQgc2VydmljZSBmb3IgdGhlIHVwY29taW5nIHNhdmVkIGNoYXQgb3BlcmF0aW9uc1xuICAgKi9cbiAgb3BlbkNoYXQobWVzc2FnZXM6IFJhd01lc3NhZ2VbXSwgY2hhdElkPzogc3RyaW5nKSB7XG4gICAgaWYgKCFtZXNzYWdlcyB8fCAhQXJyYXkuaXNBcnJheShtZXNzYWdlcykpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VycyB3aGlsZSB0cnlpbmcgdG8gbG9hZCB0aGUgY2hhdCBkaXNjdXNzaW9uLiBJbnZhbGlkIG1lc3NhZ2VzIHJlY2VpdmVkIDonLCBtZXNzYWdlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjaGF0SWQpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc2V0U2F2ZWRDaGF0SWQoY2hhdElkKTtcbiAgICB9XG4gICAgdGhpcy5yZXNldENoYXQoKTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzKTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gbWVzc2FnZXM7XG4gICAgY29uc3QgbGFzdE1lc3NhZ2UgPSBtZXNzYWdlcy5hdCgtMSk7XG4gICAgaWYobGFzdE1lc3NhZ2UgJiYgbGFzdE1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInKSB7XG4gICAgICB0aGlzLmZldGNoKG1lc3NhZ2VzKTsgLy8gSWYgdGhlIGxhc3QgbWVzc2FnZSBpZiBmcm9tIGEgdXNlciwgYW4gYW5zd2VyIGZyb20gdGhlIGFzc2lzdGFudCBpcyBleHBlY3RlZFxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMudXBkYXRlRGF0YShtZXNzYWdlcyk7IC8vIElmIHRoZSBsYXN0IG1lc3NhZ2UgaWYgZnJvbSB0aGUgYXNzaXN0YW50LCB3ZSBjYW4gbG9hZCB0aGUgY29udmVyc2F0aW9uIHJpZ2h0IGF3YXlcbiAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdGhlIGNoYXQgYnkgY2xlYXJpbmcgdGhlIG1lc3NhZ2VzIGFuZCB0aGUgY2hhdCBoaXN0b3J5XG4gICAqIFRoZSBxdWVzdGlvbiBpbnB1dCB3aWxsIGJlIGZvY3VzZWQgYWZ0ZXIgdGhlIGNoYXQgaXMgcmVzZXRcbiAgICogVGhlIGZldGNoIHN1YnNjcmlwdGlvbiB3aWxsIGJlIHRlcm1pbmF0ZWRcbiAgICovXG4gIHJlc2V0Q2hhdCgpIHtcbiAgICBpZih0aGlzLm1lc3NhZ2VzJC52YWx1ZSkge1xuICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh1bmRlZmluZWQpOyAvLyBSZXNldCBjaGF0XG4gICAgfVxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSB1bmRlZmluZWQ7IC8vIFJlc2V0IGNoYXQgaGlzdG9yeVxuICAgIHRoaXMucXVlc3Rpb24gPSAnJztcbiAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gIH1cblxuICBvbkxvYWRDaGF0KCkge1xuICAgIHRoaXMubG9hZGluZyQubmV4dCh0cnVlKTtcbiAgICB0aGlzLnN1Yi5hZGQoXG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxvYWRTYXZlZENoYXQkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGZpbHRlcihzYXZlZENoYXQgPT4gISFzYXZlZENoYXQpLFxuICAgICAgICAgIHN3aXRjaE1hcChzYXZlZENoYXQgPT4gdGhpcy5jaGF0U2VydmljZS5nZXRTYXZlZENoYXQoc2F2ZWRDaGF0IS5pZCkpLFxuICAgICAgICAgIGZpbHRlcihzYXZlZENoYXRIaXN0b3J5ID0+ICEhc2F2ZWRDaGF0SGlzdG9yeSksXG4gICAgICAgICAgdGFwKHNhdmVkQ2hhdEhpc3RvcnkgPT4gdGhpcy5vcGVuQ2hhdChzYXZlZENoYXRIaXN0b3J5IS5oaXN0b3J5LCBzYXZlZENoYXRIaXN0b3J5IS5pZCkpXG4gICAgICAgICkuc3Vic2NyaWJlKClcbiAgICApO1xuICB9XG5cbiAgdGVybWluYXRlRmV0Y2goKSB7XG4gICAgdGhpcy5kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZGF0YVN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRpbmckLm5leHQoZmFsc2UpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5xdWVzdGlvbklucHV0Py5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfSlcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBlZGl0TWVzc2FnZShpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5tZXNzYWdlVG9FZGl0ID0gaW5kZXg7XG4gICAgdGhpcy5xdWVzdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhW2luZGV4XS5jb250ZW50O1xuICAgIHRoaXMucXVlc3Rpb25JbnB1dD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgcmVnZW5lcmF0ZU1lc3NhZ2UoaW5kZXg6IG51bWJlcikge1xuICAgICAvLyBEZWZpbmUgdGhlIGNoYXQgaGlzdG9yeSBiYXNlZCBvbiB3aGljaCB0aGUgYXNzaXN0YW50IHdpbGwgZ2VuZXJhdGUgYSBuZXcgYW5zd2VyXG4gICAgY29uc3Qgc2xpY2VkTWVzc2FnZXMgPSB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IS5zbGljZSgwLCBpbmRleCk7XG4gICAgLy8gQWNjb3JkaW5nbHkgdXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUlcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHNsaWNlZE1lc3NhZ2VzKTtcbiAgICAvLyBGZXRjaCB0aGUgYW5zd2VyXG4gICAgdGhpcy5mZXRjaChzbGljZWRNZXNzYWdlcyk7XG4gIH1cblxuICBvbktleVVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0JhY2tzcGFjZSc6XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlSGVpZ2h0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICBpZiAoIWV2ZW50LnNoaWZ0S2V5KSB0aGlzLnN1Ym1pdFF1ZXN0aW9uKCk7XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlSGVpZ2h0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgY2FsY3VsYXRlSGVpZ2h0KCk6IHZvaWQge1xuICAgIGNvbnN0IG1heEhlaWdodCA9IDE3MDtcbiAgICBjb25zdCBlbCA9IHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudDtcbiAgICBlbC5zdHlsZS5tYXhIZWlnaHQgPSBgJHttYXhIZWlnaHR9cHhgO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcbiAgICBlbC5zdHlsZS5oZWlnaHQgPSBgJHtlbC5zY3JvbGxIZWlnaHR9cHhgO1xuICAgIGVsLnN0eWxlLm92ZXJmbG93WSA9IGVsLnNjcm9sbEhlaWdodCA+PSBtYXhIZWlnaHQgPyAnc2Nyb2xsJyA6ICdoaWRkZW4nO1xuICB9XG59XG4iLCJcbjxuZy1jb250YWluZXIgKm5nSWY9XCIhaW5pdGlhbGl6YXRpb25FcnJvclwiPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZXMkIHwgYXN5bmMgYXMgbWVzc2FnZXM7IGVsc2UgbG9hZGluZ1RwbCB8fCBsb2FkaW5nVHBsRGVmYXVsdFwiIGNsYXNzPVwiaC0xMDAgZC1mbGV4IGZsZXgtY29sdW1uXCI+XG5cbiAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2ggb3ZlcmZsb3ctYXV0byBwZS0yIHBiLTJcIiAjbWVzc2FnZUxpc3Q+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBtZXNzYWdlIG9mIG1lc3NhZ2VzOyBsZXQgaW5kZXggPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgIDwhLS0gUmVndWxhciBtZXNzYWdlcyAtLT5cbiAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtXCIgKm5nSWY9XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLmRpc3BsYXlcIlxuICAgICAgICAgICAgW2NsYXNzLm9wYWNpdHktNTBdPVwibWVzc2FnZVRvRWRpdCAmJiBtZXNzYWdlVG9FZGl0IDwgaW5kZXggKyAxXCI+XG4gICAgICAgICAgPHNxLWNoYXQtbWVzc2FnZVxuICAgICAgICAgICAgW2NsYXNzLnNxLXVzZXItbWVzc2FnZV09XCJtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFttZXNzYWdlXT1cIm1lc3NhZ2VcIlxuICAgICAgICAgICAgW2NvbnZlcnNhdGlvbl09XCJtZXNzYWdlc1wiXG4gICAgICAgICAgICBbYXNzaXN0YW50SWNvbl09XCJjdXN0b21Bc3Npc3RhbnRJY29uIHx8IGFzc2lzdGFudEljb25cIlxuICAgICAgICAgICAgW3N0cmVhbWluZ109XCJsYXN0ICYmIChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpXCJcbiAgICAgICAgICAgIFtjYW5FZGl0XT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIG1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFtjYW5SZWdlbmVyYXRlXT1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIG1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIGxhc3RcIlxuICAgICAgICAgICAgW2NhbkNvcHldPVwiIShsYXN0ICYmIChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpKSAmJiBtZXNzYWdlVG9FZGl0ID09PSB1bmRlZmluZWQgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50J1wiXG4gICAgICAgICAgICAoZWRpdCk9XCJlZGl0TWVzc2FnZShpbmRleClcIiAocmVnZW5lcmF0ZSk9XCJyZWdlbmVyYXRlTWVzc2FnZShpbmRleClcIlxuICAgICAgICAgICAgKHJlZmVyZW5jZUNsaWNrZWQpPVwicmVmZXJlbmNlQ2xpY2tlZC5lbWl0KCRldmVudClcIlxuICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5QcmV2aWV3LmVtaXQoJGV2ZW50KVwiPlxuICAgICAgICAgIDwvc3EtY2hhdC1tZXNzYWdlPlxuICAgICAgICA8L2xpPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbVwiICpuZ0lmPVwiKGxvYWRpbmckIHwgYXN5bmMpID09PSB0cnVlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2FkaW5nVHBsIHx8IGxvYWRpbmdUcGxEZWZhdWx0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L2xpPlxuICAgIDwvdWw+XG5cbiAgICA8ZGl2IGNsYXNzPVwidXNlci1pbnB1dCBtdC1hdXRvXCIgKm5nSWY9XCJlbmFibGVkVXNlcklucHV0XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaW5wdXRUcGxcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtZW5kIHNtYWxsIHRleHQtbXV0ZWQgcHgtM1wiICpuZ0lmPVwiISFjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyXCI+XG4gICAgICAgICAge3sgY29uZmlnPy5nbG9iYWxTZXR0aW5ncz8uZGlzY2xhaW1lciB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48IS0tIE5HIFRFTVBMQVRFUy0tPlxuXG48bmctdGVtcGxhdGUgI2xvYWRpbmdUcGxEZWZhdWx0PlxuICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ncm93IHRleHQtcHJpbWFyeSBkLWJsb2NrIG14LWF1dG8gbXktNVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPkxvYWRpbmcuLi48L3NwYW4+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNpbnB1dFRwbD5cbiAgPGRpdiBjbGFzcz1cInB4LTMgcHktMVwiPlxuICAgIDxkaXYgY2xhc3M9XCJhc3QtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICA8YnV0dG9uIGRpc2FibGVkIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zZWFyY2hcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDx0ZXh0YXJlYSAjcXVlc3Rpb25JbnB1dCByb3dzPVwiMVwiXG4gICAgICAgIHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICBwbGFjZWhvbGRlcj1cIkFzayBzb21ldGhpbmdcIiBhdXRvZm9jdXNcbiAgICAgICAgWyhuZ01vZGVsKV09XCJxdWVzdGlvblwiXG4gICAgICAgIChrZXl1cCk9XCJvbktleVVwKCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJjYWxjdWxhdGVIZWlnaHQoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIobG9hZGluZyQgfCBhc3luYykgfHwgKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYylcIj5cbiAgICAgIDwvdGV4dGFyZWE+XG4gICAgICA8YnV0dG9uXG4gICAgICAgICpuZ0lmPVwiIShjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpICYmICEobG9hZGluZyQgfCBhc3luYylcIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxpZ2h0IG1zLTJcIlxuICAgICAgICB0aXRsZT1cIlNlbmQgbWVzc2FnZVwiXG4gICAgICAgIChjbGljayk9XCJzdWJtaXRRdWVzdGlvbigpXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXBhcGVyLXBsYW5lXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8IS0tPGJ1dHRvblxuICAgICAgICAqbmdJZj1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBtcy0yXCJcbiAgICAgICAgdGl0bGU9XCJTdG9wIGdlbmVyYXRpbmdcIlxuICAgICAgICAoY2xpY2spPVwidGVybWluYXRlRmV0Y2goKVwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zdG9wXCI+PC9pPlxuICAgICAgPC9idXR0b24+LS0+XG4gICAgICA8YnV0dG9uXG4gICAgICAgICpuZ0lmPVwibWVzc2FnZVRvRWRpdFwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImJ0biBidG4tbGlnaHQgbXMtMlwiXG4gICAgICAgIHRpdGxlPVwiQ2FuY2VsIGVkaXRpb25cIlxuICAgICAgICAoY2xpY2spPVwibWVzc2FnZVRvRWRpdCA9IHVuZGVmaW5lZDsgcXVlc3Rpb24gPSAnJ1wiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS11bmRvLWFsdFwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGRpdiBjbGFzcz1cInNxLWZsb2F0aW5nLXNjcm9sbFwiICpuZ0lmPVwiIWlzQXRCb3R0b21cIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzaGFkb3dcIiAoY2xpY2spPVwic2Nyb2xsRG93bigpXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtYW5nbGUtZG91YmxlLWRvd25cIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==