@sinequa/assistant 3.9.4 → 3.9.6-rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chat/chat-message/chat-message.component.d.ts +17 -25
- package/chat/chat-message/i18n/de.json +11 -0
- package/chat/chat-reference/chat-reference.component.d.ts +18 -8
- package/chat/chat-reference/i18n/de.json +4 -0
- package/chat/chat-settings-v3/i18n/de.json +14 -0
- package/chat/chat.component.d.ts +2 -1
- package/chat/debug-message/debug-message-details/debug-message-details.component.d.ts +2 -3
- package/chat/debug-message/i18n/de.json +3 -0
- package/chat/dialogs/i18n/de.json +19 -0
- package/chat/directives/copy-to-clipboard.directive.d.ts +8 -0
- package/chat/documents-upload/document-list/document-list.component.d.ts +4 -9
- package/chat/documents-upload/document-overview/document-overview.component.d.ts +3 -17
- package/chat/documents-upload/document-upload/document-upload.component.d.ts +3 -8
- package/chat/documents-upload/documents-upload.service.d.ts +7 -16
- package/chat/documents-upload/i18n/de.json +24 -0
- package/chat/i18n/de.json +42 -0
- package/chat/markdown-it-plugins/code-block.plugin.d.ts +2 -0
- package/chat/markdown-it-plugins/image-reference.plugin.d.ts +3 -0
- package/chat/markdown-it-plugins/link.plugin.d.ts +5 -0
- package/chat/markdown-it-plugins/page-reference.plugin.d.ts +3 -0
- package/chat/markdown-it-plugins/reference.plugin.d.ts +7 -0
- package/chat/public-api.d.ts +2 -1
- package/chat/references/i18n/de.json +6 -0
- package/chat/references/references.component.d.ts +43 -0
- package/chat/saved-chats/i18n/de.json +5 -0
- package/chat/services/app.service.d.ts +2 -1
- package/chat/services/custom-elements.service.d.ts +13 -0
- package/chat/smart-renderer/smart-renderer.d.ts +23 -0
- package/chat/token-progress-bar/i18n/de.json +4 -0
- package/chat/tooltip/tooltip.directive.d.ts +2 -2
- package/chat/types.d.ts +8 -42
- package/esm2022/chat/chat-message/chat-message.component.mjs +33 -135
- package/esm2022/chat/chat-reference/chat-reference.component.mjs +60 -26
- package/esm2022/chat/chat-settings-v3/chat-settings-v3.component.mjs +1 -1
- package/esm2022/chat/chat.component.mjs +50 -13
- package/esm2022/chat/chat.service.mjs +3 -2
- package/esm2022/chat/debug-message/debug-message-details/debug-message-details.component.mjs +2 -2
- package/esm2022/chat/debug-message/debug-message.service.mjs +4 -7
- package/esm2022/chat/directives/copy-to-clipboard.directive.mjs +68 -0
- package/esm2022/chat/documents-upload/document-list/document-list.component.mjs +21 -22
- package/esm2022/chat/documents-upload/document-overview/document-overview.component.mjs +8 -31
- package/esm2022/chat/documents-upload/document-upload/document-upload.component.mjs +12 -14
- package/esm2022/chat/documents-upload/documents-upload.service.mjs +25 -44
- package/esm2022/chat/markdown-it-plugins/code-block.plugin.mjs +14 -0
- package/esm2022/chat/markdown-it-plugins/image-reference.plugin.mjs +58 -0
- package/esm2022/chat/markdown-it-plugins/link.plugin.mjs +15 -0
- package/esm2022/chat/markdown-it-plugins/page-reference.plugin.mjs +60 -0
- package/esm2022/chat/markdown-it-plugins/reference.plugin.mjs +68 -0
- package/esm2022/chat/public-api.mjs +3 -2
- package/esm2022/chat/references/references.component.mjs +293 -0
- package/esm2022/chat/saved-chats/saved-chats.component.mjs +4 -3
- package/esm2022/chat/saved-chats/saved-chats.service.mjs +9 -12
- package/esm2022/chat/services/app.service.mjs +8 -2
- package/esm2022/chat/services/assistant-configuration.service.mjs +9 -18
- package/esm2022/chat/services/assistant-metadata.service.mjs +3 -3
- package/esm2022/chat/services/assistant-tokens-tracking.service.mjs +3 -6
- package/esm2022/chat/services/custom-elements.service.mjs +43 -0
- package/esm2022/chat/smart-renderer/smart-renderer.mjs +103 -0
- package/esm2022/chat/tooltip/tooltip.directive.mjs +9 -9
- package/esm2022/chat/types.mjs +2 -5
- package/fesm2022/sinequa-assistant-chat.mjs +913 -498
- package/fesm2022/sinequa-assistant-chat.mjs.map +1 -1
- package/package.json +4 -6
- package/chat/prompt.component.d.ts +0 -25
- package/chat/unified-plugins/embedded-image-reference.plugin.d.ts +0 -3
- package/chat/unified-plugins/embedded-page-reference.plugin.d.ts +0 -3
- package/esm2022/chat/prompt.component.mjs +0 -88
- package/esm2022/chat/unified-plugins/embedded-image-reference.plugin.mjs +0 -56
- package/esm2022/chat/unified-plugins/embedded-page-reference.plugin.mjs +0 -57
|
@@ -7,7 +7,6 @@ import { BehaviorSubject, Subscription, combineLatest, filter, fromEvent, merge,
|
|
|
7
7
|
import { guid, isAuthenticated, setGlobalConfig } from "@sinequa/atomic";
|
|
8
8
|
import { ChatMessageComponent } from "./chat-message/chat-message.component";
|
|
9
9
|
import { ChatService } from "./chat.service";
|
|
10
|
-
import { AssistantUtils } from "./utils/utils.service";
|
|
11
10
|
import { DebugMessageComponent } from "./debug-message/debug-message.component";
|
|
12
11
|
import { InstanceManagerService } from "./instance-manager.service";
|
|
13
12
|
import { NotificationsService } from "./services/notification.service";
|
|
@@ -15,6 +14,11 @@ import { PrincipalService } from "./services/principal.service";
|
|
|
15
14
|
import { SearchService } from "./services/search.service";
|
|
16
15
|
import { TokenProgressBarComponent } from "./token-progress-bar/token-progress-bar.component";
|
|
17
16
|
import { TooltipDirective } from "./tooltip/tooltip.directive";
|
|
17
|
+
import { AssistantUtils } from "./utils/utils.service";
|
|
18
|
+
import { AssistantConfigurationService } from "./services/assistant-configuration.service";
|
|
19
|
+
import { AssistantTokensTrackingService } from "./services/assistant-tokens-tracking.service";
|
|
20
|
+
import { SavedChatsService } from "./saved-chats/saved-chats.service";
|
|
21
|
+
import { DebugMessageService } from "./debug-message/debug-message.service";
|
|
18
22
|
import * as i0 from "@angular/core";
|
|
19
23
|
import * as i1 from "@angular/common";
|
|
20
24
|
import * as i2 from "@angular/forms";
|
|
@@ -107,6 +111,13 @@ export class ChatComponent {
|
|
|
107
111
|
throw error;
|
|
108
112
|
}
|
|
109
113
|
})).subscribe());
|
|
114
|
+
// Example of listening to custom events from the web element and handling them in the Angular component
|
|
115
|
+
addEventListener('onOpenPreview', (event) => {
|
|
116
|
+
this.openPreview.emit(event.detail.reference);
|
|
117
|
+
});
|
|
118
|
+
addEventListener('onOpenDocument', (event) => {
|
|
119
|
+
this.openDocument.emit(event.detail.reference.record);
|
|
120
|
+
});
|
|
110
121
|
}
|
|
111
122
|
ngOnChanges(changes) {
|
|
112
123
|
this.changes$.next(changes);
|
|
@@ -259,8 +270,10 @@ export class ChatComponent {
|
|
|
259
270
|
*/
|
|
260
271
|
_addScrollListener() {
|
|
261
272
|
this._sub.add(merge(this.loading$, this.messages$, this.chatService.streaming$, fromEvent(this.messageList.nativeElement, 'scroll')).subscribe(() => {
|
|
262
|
-
|
|
263
|
-
|
|
273
|
+
setTimeout(() => {
|
|
274
|
+
this.isAtBottom = this._toggleScrollButtonVisibility();
|
|
275
|
+
this.cdr.detectChanges();
|
|
276
|
+
});
|
|
264
277
|
}));
|
|
265
278
|
}
|
|
266
279
|
/**
|
|
@@ -283,11 +296,11 @@ export class ChatComponent {
|
|
|
283
296
|
}
|
|
284
297
|
if (this.question.trim() && this.messages$.value && this.chatService.chatHistory) {
|
|
285
298
|
// When the user submits a question, if the user is editing a previous message, remove all subsequent messages from the chat history
|
|
286
|
-
if (this.indexMessageToEdit !== undefined) {
|
|
299
|
+
if (this.indexMessageToEdit !== undefined && this.rankMessageToEdit !== undefined) {
|
|
287
300
|
// Update the messages in the UI
|
|
288
301
|
this.messages$.next(this.messages$.value.slice(0, this.indexMessageToEdit));
|
|
289
302
|
// Update the raw messages in the chat history which is the clean version used to make the next request
|
|
290
|
-
this.chatService.chatHistory = this.chatService.chatHistory.slice(0, this.rankMessageToEdit);
|
|
303
|
+
this.chatService.chatHistory = this.chatService.chatHistory.slice(0, this.rankMessageToEdit - 1);
|
|
291
304
|
this.indexMessageToEdit = undefined;
|
|
292
305
|
this.rankMessageToEdit = undefined;
|
|
293
306
|
}
|
|
@@ -526,11 +539,20 @@ export class ChatComponent {
|
|
|
526
539
|
* If the chat is meant to be initialized with event === "Query", the corresponding user query message will be added to the chat history
|
|
527
540
|
*/
|
|
528
541
|
loadDefaultChat() {
|
|
542
|
+
const date = (new Date()).toLocaleString('en-US', { weekday: 'long', month: 'long', day: '2-digit', year: 'numeric' });
|
|
529
543
|
// Define the default system prompt and user prompt messages
|
|
530
|
-
const systemMsg = {
|
|
544
|
+
const systemMsg = {
|
|
545
|
+
role: 'system',
|
|
546
|
+
content: AssistantUtils.formatPrompt(this.transloco.translate(this.config.defaultValues.systemPrompt), { principal: this.principalService.principal, date }),
|
|
547
|
+
additionalProperties: { display: false, messageId: guid() }
|
|
548
|
+
};
|
|
531
549
|
// backward compatibility with old configuration files
|
|
532
550
|
const userPrompt = this.config.defaultValues.userPrompt.replace(/\{\{(.*?)\}\}/g, '[[$1]]');
|
|
533
|
-
const userMsg = {
|
|
551
|
+
const userMsg = {
|
|
552
|
+
role: 'user',
|
|
553
|
+
content: AssistantUtils.formatPrompt(this.transloco.translate(userPrompt), { principal: this.principalService.principal, date }),
|
|
554
|
+
additionalProperties: { display: this.config.modeSettings.displayUserPrompt, messageId: guid() }
|
|
555
|
+
};
|
|
534
556
|
if (this.config.modeSettings.initialization.event === 'Query') {
|
|
535
557
|
this._handleQueryMode(systemMsg, userMsg);
|
|
536
558
|
}
|
|
@@ -742,9 +764,11 @@ export class ChatComponent {
|
|
|
742
764
|
if (i >= 0) {
|
|
743
765
|
this.messages$.next(this.messages$.value.slice(0, i + 1));
|
|
744
766
|
// Rank of this found first previous 'user' message in the chat history
|
|
767
|
+
const rankFirstPreviousUserMessage = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, this.messages$.value[i].additionalProperties.messageId);
|
|
768
|
+
// Rank of the assistant's message on which the user clicked to regenerate
|
|
745
769
|
const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
|
|
746
770
|
// Define and Update the chat history based on which the assistant will generate a new answer
|
|
747
|
-
this.chatService.chatHistory = this.chatService.chatHistory.slice(0,
|
|
771
|
+
this.chatService.chatHistory = this.chatService.chatHistory.slice(0, rankFirstPreviousUserMessage);
|
|
748
772
|
// Fetch the answer
|
|
749
773
|
this.fetch(this.chatService.chatHistory);
|
|
750
774
|
this.chatService.generateAuditEvent('ast-regenerate.click', { 'rank': rank, 'message-id': message.additionalProperties.messageId });
|
|
@@ -909,11 +933,16 @@ export class ChatComponent {
|
|
|
909
933
|
/**
|
|
910
934
|
* Handle the click on a suggested action.
|
|
911
935
|
* @param action Suggested action.
|
|
912
|
-
* @param index
|
|
936
|
+
* @param index index of the message containing the suggested action.
|
|
937
|
+
* @returns void
|
|
913
938
|
*/
|
|
914
939
|
suggestActionClick(action, index) {
|
|
915
940
|
this.suggestAction.emit(action);
|
|
916
|
-
|
|
941
|
+
const details = {
|
|
942
|
+
'text': action.content,
|
|
943
|
+
'suggestedAction-type': action.type
|
|
944
|
+
};
|
|
945
|
+
this.chatService.generateAuditEvent('ast-suggested-action.click', details);
|
|
917
946
|
}
|
|
918
947
|
/**
|
|
919
948
|
* It looks for the debug messages available in the current group of "assistant" messages.
|
|
@@ -991,15 +1020,23 @@ export class ChatComponent {
|
|
|
991
1020
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
992
1021
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", queryChangeShouldTriggerReload: "queryChangeShouldTriggerReload", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", focusAfterResponse: "focusAfterResponse", chat: "chat", assistantMessageIcon: "assistantMessageIcon", userMessageIcon: "userMessageIcon", connectionErrorMessageIcon: "connectionErrorMessageIcon", searchWarningMessageIcon: "searchWarningMessageIcon", additionalWorkflowProperties: "additionalWorkflowProperties", appConfig: "appConfig" }, outputs: { connection: "connection", loading$: "loading", _config: "config", data: "data", openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction" }, providers: [
|
|
993
1022
|
ChatService,
|
|
1023
|
+
AssistantConfigurationService,
|
|
1024
|
+
AssistantTokensTrackingService,
|
|
1025
|
+
SavedChatsService,
|
|
1026
|
+
DebugMessageService,
|
|
994
1027
|
provideTranslocoScope('chat')
|
|
995
|
-
], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }, { propertyName: "reportTpl", first: true, predicate: ["reportTpl"], descendants: true }, { propertyName: "tokenConsumptionTpl", first: true, predicate: ["tokenConsumptionTpl"], descendants: true }, { propertyName: "debugMessagesTpl", first: true, predicate: ["debugMessagesTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 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\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\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\">{{ 'chat.loading' | transloco }}</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\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) === false && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\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-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.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-uploaded-doc-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;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}: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>.issue-report>div,: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%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.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 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))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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", "suggestedActions", "assistantMessageIcon", "userMessageIcon", "connectionErrorMessageIcon", "searchWarningMessageIcon", "streaming", "canEdit", "canRegenerate", "canCopy", "canDebug", "canLike", "canDislike"], outputs: ["openDocument", "openPreview", "suggestAction", "edit", "copy", "regenerate", "like", "dislike", "debug"] }, { kind: "component", type: TokenProgressBarComponent, selector: "sq-token-progress-bar", inputs: ["instanceId"] }, { kind: "component", type: DebugMessageComponent, selector: "sq-debug-message", inputs: ["data"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1028
|
+
], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }, { propertyName: "reportTpl", first: true, predicate: ["reportTpl"], descendants: true }, { propertyName: "tokenConsumptionTpl", first: true, predicate: ["tokenConsumptionTpl"], descendants: true }, { propertyName: "debugMessagesTpl", first: true, predicate: ["debugMessagesTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 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\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [id]=\"message.additionalProperties.messageId\"\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n [collapseReferences]=\"!!config?.globalSettings.collapseReferences\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\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\">{{ 'chat.loading' | transloco }}</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\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) === false && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\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-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.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-uploaded-doc-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;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}: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>.issue-report>div,: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%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.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 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))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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: ["id", "message", "conversation", "suggestedActions", "assistantMessageIcon", "userMessageIcon", "connectionErrorMessageIcon", "searchWarningMessageIcon", "streaming", "canEdit", "canRegenerate", "canCopy", "canDebug", "canLike", "canDislike", "collapseReferences"], outputs: ["openDocument", "openPreview", "suggestAction", "edit", "copy", "regenerate", "like", "dislike", "debug"] }, { kind: "component", type: TokenProgressBarComponent, selector: "sq-token-progress-bar", inputs: ["instanceId"] }, { kind: "component", type: DebugMessageComponent, selector: "sq-debug-message", inputs: ["data"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
996
1029
|
}
|
|
997
1030
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatComponent, decorators: [{
|
|
998
1031
|
type: Component,
|
|
999
1032
|
args: [{ selector: 'sq-chat-v3', providers: [
|
|
1000
1033
|
ChatService,
|
|
1034
|
+
AssistantConfigurationService,
|
|
1035
|
+
AssistantTokensTrackingService,
|
|
1036
|
+
SavedChatsService,
|
|
1037
|
+
DebugMessageService,
|
|
1001
1038
|
provideTranslocoScope('chat')
|
|
1002
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent, TokenProgressBarComponent, DebugMessageComponent, TooltipDirective, TranslocoPipe], template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 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\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\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\">{{ 'chat.loading' | transloco }}</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\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) === false && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\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-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.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-uploaded-doc-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;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}: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>.issue-report>div,: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%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.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 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))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"] }]
|
|
1039
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent, TokenProgressBarComponent, DebugMessageComponent, TooltipDirective, TranslocoPipe], template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 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\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [id]=\"message.additionalProperties.messageId\"\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n [collapseReferences]=\"!!config?.globalSettings.collapseReferences\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\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\">{{ 'chat.loading' | transloco }}</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\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) === false && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\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-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.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-uploaded-doc-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;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}: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>.issue-report>div,: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%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.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 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))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"] }]
|
|
1003
1040
|
}], propDecorators: { instanceId: [{
|
|
1004
1041
|
type: Input
|
|
1005
1042
|
}], query: [{
|
|
@@ -1061,4 +1098,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
1061
1098
|
}], appConfig: [{
|
|
1062
1099
|
type: Input
|
|
1063
1100
|
}] } });
|
|
1064
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBOEIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxTixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVGLE9BQU8sRUFBaUIsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXhILE9BQU8sRUFBbUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUxRyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFD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dUJBQUMsa0JBQWtCO2dCQUV2QixTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbnRlbnRDaGlsZCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkLCBpbmplY3QgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcbmltcG9ydCB7IFRyYW5zbG9jb1BpcGUsIFRyYW5zbG9jb1NlcnZpY2UsIHByb3ZpZGVUcmFuc2xvY29TY29wZSB9IGZyb20gJ0Bqc3ZlcnNlL3RyYW5zbG9jbyc7XG5pbXBvcnQgeyBIdWJDb25uZWN0aW9uLCBIdWJDb25uZWN0aW9uU3RhdGUgfSBmcm9tIFwiQG1pY3Jvc29mdC9zaWduYWxyXCI7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIFN1YnNjcmlwdGlvbiwgY29tYmluZUxhdGVzdCwgZmlsdGVyLCBmcm9tRXZlbnQsIG1lcmdlLCBvZiwgc3dpdGNoTWFwLCB0YWtlLCB0YXAgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQgeyBBcHBHbG9iYWxDb25maWcsIEFydGljbGUsIFF1ZXJ5LCBndWlkLCBpc0F1dGhlbnRpY2F0ZWQsIHNldEdsb2JhbENvbmZpZyB9IGZyb20gXCJAc2luZXF1YS9hdG9taWNcIjtcblxuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VDb21wb25lbnQgfSBmcm9tIFwiLi9jaGF0LW1lc3NhZ2UvY2hhdC1tZXNzYWdlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgQ2hhdFNlcnZpY2UgfSBmcm9tIFwiLi9jaGF0LnNlcnZpY2VcIjtcbmltcG9ydCB7IEFzc2lzdGFudFV0aWxzIH0gZnJvbSBcIi4vdXRpbHMvdXRpbHMuc2VydmljZVwiO1xuaW1wb3J0IHsgRGVidWdNZXNzYWdlQ29tcG9uZW50IH0gZnJvbSBcIi4vZGVidWctbWVzc2FnZS9kZWJ1Zy1tZXNzYWdlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgSW5zdGFuY2VNYW5hZ2VyU2VydmljZSB9IGZyb20gXCIuL2luc3RhbmNlLW1hbmFnZXIuc2VydmljZVwiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uc1NlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL3ByaW5jaXBhbC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBTZWFyY2hTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvc2VhcmNoLnNlcnZpY2VcIjtcbmltcG9ydCB7IFRva2VuUHJvZ3Jlc3NCYXJDb21wb25lbnQgfSBmcm9tIFwiLi90b2tlbi1wcm9ncmVzcy1iYXIvdG9rZW4tcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgVG9vbHRpcERpcmVjdGl2ZSB9IGZyb20gXCIuL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmVcIjtcbmltcG9ydCB7IENoYXRDb25maWcsIENoYXRDb250ZXh0QXR0YWNobWVudCwgQ2hhdE1lc3NhZ2UsIERlYnVnTWVzc2FnZSwgR2xsbU1vZGVsRGVzY3JpcHRpb24sIEluaXRDaGF0LCBNZXNzYWdlSGFuZGxlciwgUmF3TWVzc2FnZSwgU3VnZ2VzdGVkQWN0aW9uIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFJhd01lc3NhZ2VDb250ZW50LCBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tIFwiLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXNcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3EtY2hhdC12MycsIC8vIG1hbmRhdG9yeSBzaW5jZSBAc2luZXF1YS9jb21wb25lbnRzIGFscmVhZHkgaGFzIHRoZSBzYW1lIHRhZy1uYW1lIFwic3EtY2hhdFwiXG4gIHRlbXBsYXRlVXJsOiAnLi9jaGF0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2hhdC5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICBDaGF0U2VydmljZSxcbiAgICBwcm92aWRlVHJhbnNsb2NvU2NvcGUoJ2NoYXQnKVxuICBdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIENoYXRNZXNzYWdlQ29tcG9uZW50LCBUb2tlblByb2dyZXNzQmFyQ29tcG9uZW50LCBEZWJ1Z01lc3NhZ2VDb21wb25lbnQsIFRvb2x0aXBEaXJlY3RpdmUsIFRyYW5zbG9jb1BpcGVdXG59KVxuZXhwb3J0IGNsYXNzIENoYXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblxuICBwdWJsaWMgY2hhdFNlcnZpY2UgPSBpbmplY3QoQ2hhdFNlcnZpY2UpO1xuICBwdWJsaWMgaW5zdGFuY2VNYW5hZ2VyU2VydmljZSA9IGluamVjdChJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlKTtcbiAgcHVibGljIHNlYXJjaFNlcnZpY2UgPSBpbmplY3QoU2VhcmNoU2VydmljZSk7XG4gIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlID0gaW5qZWN0KFByaW5jaXBhbFNlcnZpY2UpO1xuICBwdWJsaWMgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHVibGljIG5vdGlmaWNhdGlvbnNTZXJ2aWNlID0gaW5qZWN0KE5vdGlmaWNhdGlvbnNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xvY28gPSBpbmplY3QoVHJhbnNsb2NvU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXNzaXN0YW50VXRpbHMgPSBpbmplY3QoQXNzaXN0YW50VXRpbHMpO1xuXG4gIC8qKiBEZWZpbmUgdGhlIGtleSBiYXNlZCBvbiBpdCwgdGhlIGNoYXQgc2VydmljZSBpbnN0YW5jZSB3aWxsIGJlIHN0b3JlZCAqL1xuICBASW5wdXQoKSBpbnN0YW5jZUlkOiBzdHJpbmc7XG4gIC8qKiBEZWZpbmUgdGhlIHF1ZXJ5IHRvIHVzZSB0byBmZXRjaCBhbnN3ZXJzICovXG4gIEBJbnB1dCgpIHF1ZXJ5OiBRdWVyeSA9IHRoaXMuc2VhcmNoU2VydmljZS5xdWVyeTtcbiAgLyoqIEZ1bmN0aW9uIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlc1xuICAgKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBjaGF0IHdpbGwgYmUgcmVsb2FkZWQgYnkgZGVmYXVsdFxuICAgKiBAcGFyYW0gcHJldlF1ZXJ5IFRoZSBwcmV2aW91cyBxdWVyeVxuICAgKiBAcGFyYW0gbmV3UXVlcnkgVGhlIG5ldyBxdWVyeVxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBASW5wdXQoKSBxdWVyeUNoYW5nZVNob3VsZFRyaWdnZXJSZWxvYWQ6IChwcmV2UXVlcnk6IFF1ZXJ5LCBuZXdRdWVyeTogUXVlcnkpID0+IGJvb2xlYW47XG4gIC8qKiBNYXAgb2YgbGlzdGVuZXJzIG92ZXJyaWRpbmcgZGVmYXVsdCByZWdpc3RlcmVkIG9uZXMqL1xuICBASW5wdXQoKSBtZXNzYWdlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIE1lc3NhZ2VIYW5kbGVyPGFueT4+ID0gbmV3IE1hcCgpO1xuICAvKiogV2hlbiB0aGUgYXNzaXN0YW50IGFuc3dlciBhIHVzZXIgcXVlc3Rpb24sIGF1dG9tYXRpY2FsbHkgc2Nyb2xsIGRvd24gdG8gdGhlIGJvdHRvbSBvZiB0aGUgZGlzY3Vzc2lvbiAqL1xuICBASW5wdXQoKSBhdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSA9IGZhbHNlO1xuICAvKiogV2hlbiB0aGUgYXNzaXN0YW50IGFuc3dlciBhIHVzZXIgcXVlc3Rpb24sIGF1dG9tYXRpY2FsbHkgZm9jdXMgdG8gdGhlIGNoYXQgaW5wdXQgKi9cbiAgQElucHV0KCkgZm9jdXNBZnRlclJlc3BvbnNlID0gZmFsc2U7XG4gIC8qKiBBIGNoYXQgZGlzY3Vzc2lvbiB0aGF0IHRoZSBjb21wb25lbnQgc2hvdWxkIGdldCBpbml0aWFsaXplZCB3aXRoIGl0ICovXG4gIEBJbnB1dCgpIGNoYXQ/OiBJbml0Q2hhdDtcbiAgLyoqIEljb24gdG8gdXNlIGZvciB0aGUgYXNzaXN0YW50IG1lc3NhZ2VzICovXG4gIEBJbnB1dCgpIGFzc2lzdGFudE1lc3NhZ2VJY29uID0gJ3NxLXNpbmVxdWEnO1xuICAvKiogSWNvbiB0byB1c2UgZm9yIHRoZSB1c2VyIG1lc3NhZ2VzICovXG4gIEBJbnB1dCgpIHVzZXJNZXNzYWdlSWNvbjogc3RyaW5nO1xuICAvKiogSWNvbiB0byB1c2UgZm9yIHRoZSBjb25uZWN0aW9uIGVycm9yIG1lc3NhZ2VzICovXG4gIEBJbnB1dCgpIGNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIC8qKiBJY29uIHRvIHVzZSBmb3IgdGhlIHNlYXJjaCB3YXJuaW5nIG1lc3NhZ2VzICovXG4gIEBJbnB1dCgpIHNlYXJjaFdhcm5pbmdNZXNzYWdlSWNvbjogc3RyaW5nO1xuICAvLyBBZGQgY3VzdG9tIGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMgdG8gdGhlIHVzZXIgcXVlcnkgbWVzc2FnZVxuICBASW5wdXQoKSBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIC8qKiBFdmVudCBlbWl0dGVyIHRyaWdnZXJlZCBvbmNlIHRoZSBzaWduYWxSIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWQgICovXG4gIEBPdXRwdXQoKSBjb25uZWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxIdWJDb25uZWN0aW9uPigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgZWFjaCB0aW1lIHRoZSBhc3Npc3RhbnQgdXBkYXRlcyB0aGUgY3VycmVudCBjaGF0ICovXG4gIC8qKiBFdmVudCBlbWl0dGVyIHRyaWdnZXJlZCB3aGVuIHRoZSBjaGF0IGlzIGxvYWRpbmcgbmV3IGNvbnRlbnQgKi9cbiAgQE91dHB1dChcImxvYWRpbmdcIikgbG9hZGluZyQgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KGZhbHNlKTtcbiAgLyoqIEVtaXRzIHRoZSBhc3Npc3RhbnQgY29uZmlndXJhdGlvbiB1c2VkIHdoZW4gaW5zdGFudGlhdGluZyB0aGUgY29tcG9uZW50ICovXG4gIEBPdXRwdXQoXCJjb25maWdcIikgX2NvbmZpZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdENvbmZpZz4oKTtcbiAgQE91dHB1dCgpIGRhdGEgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlW10+KCk7XG4gIC8qKiBFdmVudCBlbWl0dGVyIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyB0byBvcGVuIHRoZSBvcmlnaW5hbCBkb2N1bWVudCByZXByZXNlbnRpbmcgdGhlIGNvbnRleHQgYXR0YWNobWVudCovXG4gIEBPdXRwdXQoKSBvcGVuRG9jdW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPEFydGljbGU+KCk7XG4gIC8qKiBFdmVudCBlbWl0dGVyIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyB0byBvcGVuIHRoZSBwcmV2aWV3IG9mIGEgZG9jdW1lbnQgcmVwcmVzZW50aW5nIHRoZSBjb250ZXh0IGF0dGFjaG1lbnQgKi9cbiAgQE91dHB1dCgpIG9wZW5QcmV2aWV3ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0Q29udGV4dEF0dGFjaG1lbnQ+KCk7XG4gIC8qKiBFdmVudCBlbWl0dGVyIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyBvbiBhIHN1Z2dlc3RlZCBhY3Rpb24gKi9cbiAgQE91dHB1dCgpIHN1Z2dlc3RBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPFN1Z2dlc3RlZEFjdGlvbj4oKTtcbiAgLyoqIFZpZXdDaGlsZCBkZWNvcmF0b3JzIHRvIGFjY2VzcyB0aGUgdGVtcGxhdGUgZWxlbWVudHMgKi9cbiAgQFZpZXdDaGlsZCgnbWVzc2FnZUxpc3QnKSBtZXNzYWdlTGlzdD86IEVsZW1lbnRSZWY8SFRNTFVMaXN0RWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3F1ZXN0aW9uSW5wdXQnKSBxdWVzdGlvbklucHV0PzogRWxlbWVudFJlZjxIVE1MVGV4dEFyZWFFbGVtZW50PjtcbiAgLyoqIENvbnRlbnRDaGlsZCBkZWNvcmF0b3JzIGFsbG93aW5nIHRoZSBvdmVycmlkZSBvZiB0aGUgZGVmYXVsdCB0ZW1wbGF0ZXMgZnJvbSB0aGUgcGFyZW50IGNvbXBvbmVudCAqL1xuICBAQ29udGVudENoaWxkKCdsb2FkaW5nVHBsJykgbG9hZGluZ1RwbD86IFRlbXBsYXRlUmVmPGFueT47XG4gIEBDb250ZW50Q2hpbGQoJ3JlcG9ydFRwbCcpIHJlcG9ydFRwbD86IFRlbXBsYXRlUmVmPGFueT47XG4gIEBDb250ZW50Q2hpbGQoJ3Rva2VuQ29uc3VtcHRpb25UcGwnKSB0b2tlbkNvbnN1bXB0aW9uVHBsPzogVGVtcGxhdGVSZWY8YW55PjtcbiAgQENvbnRlbnRDaGlsZCgnZGVidWdNZXNzYWdlc1RwbCcpIGRlYnVnTWVzc2FnZXNUcGw/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIEBJbnB1dCgpIGFwcENvbmZpZzogQXBwR2xvYmFsQ29uZmlnO1xuXG4gIGNvbmZpZzogQ2hhdENvbmZpZztcbiAgbWVzc2FnZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDaGF0TWVzc2FnZVtdIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBpc0FkbWluT3JEZWxldGVkQWRtaW4gPSBmYWxzZTtcbiAgcXVlc3Rpb24gPSAnJztcblxuICBwcml2YXRlIF9zdWIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgX2RhdGFTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZDtcblxuICAvKiogVmFyaWFibGVzIHRoYXQgZGVwZW5kIG9uIHRoZSB0eXBlIG9mIG1vZGVsIGluIHVzZSAqL1xuICBtb2RlbERlc2NyaXB0aW9uPzogR2xsbU1vZGVsRGVzY3JpcHRpb247XG5cbiAgaW5kZXhNZXNzYWdlVG9FZGl0PzogbnVtYmVyO1xuICByYW5rTWVzc2FnZVRvRWRpdD86IG51bWJlcjtcbiAgY2hhbmdlcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNpbXBsZUNoYW5nZXMgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIGN1cnJlbnRNZXNzYWdlSW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgZmlyc3RDaGFuZ2VzSGFuZGxlZCA9IGZhbHNlO1xuICBpc0F0Qm90dG9tID0gdHJ1ZTtcbiAgaW5pdGlhbGl6YXRpb25FcnJvciA9IGZhbHNlO1xuICBlbmFibGVkVXNlcklucHV0ID0gZmFsc2U7XG4gIGlzQ29ubmVjdGVkID0gdHJ1ZTsgLy8gQnkgZGVmYXVsdCwgdGhlIGNoYXQgaXMgY29uc2lkZXJlZCBjb25uZWN0ZWRcbiAgcmV0cmlhbEF0dGVtcHRzOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIC8vIEZsYWcgdG8gdHJhY2sgd2hldGhlciB0aGUgJ3JlY29ubmVjdGVkJyBsaXN0ZW5lciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWRcbiAgcHJpdmF0ZSBfaXNSZWNvbm5lY3RlZExpc3RlbmVyUmVnaXN0ZXJlZCA9IGZhbHNlO1xuXG4gIC8vIElzc3VlIHJlcG9ydGluZ1xuICBpc3N1ZVR5cGVzPzogc3RyaW5nW107XG4gIGRlZmF1bHRJc3N1ZVR5cGVzOiBzdHJpbmdbXSA9IFtcbiAgICAnY2hhdC51c2VySW50ZXJmYWNlQnVnJyxcbiAgICAnY2hhdC5pbmNvcnJlY3RSZXNwb25zZScsXG4gICAgJ2NoYXQuaW5jb21wbGV0ZVJlc3BvbnNlJyxcbiAgICAnY2hhdC50ZWNobmljYWxJc3N1ZScsXG4gICAgJ2NoYXQucHJpdmFjeURhdGFTZWN1cml0eUlzc3VlJyxcbiAgICAnY2hhdC5vdGhlcklzc3VlJ1xuICBdO1xuICBpc3N1ZVR5cGU6IHN0cmluZyA9ICcnO1xuICByZXBvcnRDb21tZW50Pzogc3RyaW5nO1xuICBtZXNzYWdlVG9SZXBvcnQ/OiBDaGF0TWVzc2FnZTtcbiAgcmVwb3J0UmFuaz86IG51bWJlcjtcbiAgcmVwb3J0VHlwZTogJ2xpa2UnIHwgJ2Rpc2xpa2UnID0gJ2Rpc2xpa2UnO1xuICBzaG93UmVwb3J0ID0gZmFsc2U7XG5cbiAgLy8gRGVidWcgbWVzc2FnZXNcbiAgZGVidWdNZXNzYWdlczogRGVidWdNZXNzYWdlW10gfCB1bmRlZmluZWQ7XG4gIHNob3dEZWJ1Z01lc3NhZ2VzID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBfcHJldmlvdXNRdWVyeTogUXVlcnk7XG4gIHByaXZhdGUgX3JlbG9hZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFwcENvbmZpZykge1xuICAgICAgc2V0R2xvYmFsQ29uZmlnKHRoaXMuYXBwQ29uZmlnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdWIuYWRkKFxuICAgICAgb2YoaXNBdXRoZW50aWNhdGVkKCkpLnBpcGUoXG4gICAgICAgIHRhcChfID0+IHRoaXMuaW5zdGFudGlhdGVDaGF0U2VydmljZSgpKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0KCkpLFxuICAgICAgICBzd2l0Y2hNYXAoXyA9PiB0aGlzLmNoYXRTZXJ2aWNlLmluaXRQcm9jZXNzJC5waXBlKGZpbHRlcihCb29sZWFuKSkpLFxuICAgICAgICB0YXAoXyA9PiB7XG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmVtaXQodGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uKTtcbiAgICAgICAgICB0aGlzLm9uTG9hZENoYXQoKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRhcChfID0+IHRoaXMuY2hhdFNlcnZpY2Uub3ZlcnJpZGVVc2VyKCkpLFxuICAgICAgICBzd2l0Y2hNYXAoXyA9PiB0aGlzLmNoYXRTZXJ2aWNlLnVzZXJPdmVycmlkZSQpLFxuICAgICAgICBzd2l0Y2hNYXAoXyA9PiB0aGlzLmNoYXRTZXJ2aWNlLmFzc2lzdGFudENvbmZpZyQpLFxuICAgICAgICB0YXAoY29uZmlnID0+IHtcbiAgICAgICAgICB0aGlzLmlzQWRtaW5PckRlbGV0ZWRBZG1pbiA9IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwhLmlzQWRtaW5pc3RyYXRvciB8fCB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsIS5pc0RlbGVnYXRlZEFkbWluIHx8IGZhbHNlO1xuICAgICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnITtcbiAgICAgICAgICB0aGlzLmVuYWJsZWRVc2VySW5wdXQgPSB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuZW5hYmxlZFVzZXJJbnB1dDtcbiAgICAgICAgICB0aGlzLmlzc3VlVHlwZXMgPSB0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzPy5pc3N1ZVR5cGVzPy5sZW5ndGggPyB0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzIS5pc3N1ZVR5cGVzIDogdW5kZWZpbmVkO1xuICAgICAgICAgIHRoaXMuX2NvbmZpZy5lbWl0KGNvbmZpZyk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTW9kZWxEZXNjcmlwdGlvbigpO1xuICAgICAgICAgICAgaWYoIXRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCkge1xuICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c1F1ZXJ5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSk7IC8vIEluaXRpYWxpemUgdGhlIHByZXZpb3VzIHF1ZXJ5XG4gICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUNoYW5nZXMoKTtcbiAgICAgICAgICAgICAgdGhpcy5fYWRkU2Nyb2xsTGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXphdGlvbkVycm9yID0gdHJ1ZVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKS5zdWJzY3JpYmUoKVxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgdGhpcy5jaGFuZ2VzJC5uZXh0KGNoYW5nZXMpO1xuICAgIGlmICh0aGlzLmNvbmZpZykge1xuICAgICAgdGhpcy5faGFuZGxlQ2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX3N1Yi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX2RhdGFTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RvcENvbm5lY3Rpb24oKTtcbiAgfVxuXG4gIGdldCBpc0FkbWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsPy5pc0FkbWluaXN0cmF0b3IgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBjaGF0IHNlcnZpY2UgaW5zdGFuY2UgaXMgc3RvcmVkIGluIHRoZSBpbnN0YW5jZU1hbmFnZXJTZXJ2aWNlIHdpdGggcHJvdmlkZWQgQGlucHV0IGluc3RhbmNlSWQgYXMgYSBrZXlcbiAgICovXG4gIGluc3RhbnRpYXRlQ2hhdFNlcnZpY2UoKTogdm9pZCB7XG4gICAgdGhpcy5jaGF0U2VydmljZS5zZXRDaGF0SW5zdGFuY2VJZCh0aGlzLmluc3RhbmNlSWQpO1xuICAgIHRoaXMuaW5zdGFuY2VNYW5hZ2VyU2VydmljZS5zdG9yZUluc3RhbmNlKHRoaXMuaW5zdGFuY2VJZCwgdGhpcy5jaGF0U2VydmljZSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUgY2hhbmdlcyBpbiB0aGUgY2hhdCBjb21wb25lbnQuXG4gICAqIElmIHRoZSBjaGF0IHNlcnZpY2UgaXMgYSBXZWJTb2NrZXRDaGF0U2VydmljZSwgaXQgaGFuZGxlcyB0aGUgb3ZlcnJpZGUgb2YgdGhlIG1lc3NhZ2UgaGFuZGxlcnMgaWYgdGhleSBleGlzdC5cbiAgICogSW5pdGlhbGl6ZXMgdGhlIGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgY2hhdCBtZXNzYWdlcyBpZiB0aGV5IGV4aXN0LCBvdGhlcndpc2UgbG9hZHMgdGhlIGRlZmF1bHQgY2hhdC5cbiAgICogSWYgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQsIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBpcyBcIlF1ZXJ5XCIsIHRoZSBxdWVyeSBjaGFuZ2VzLCBhbmQgdGhlIHF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZCBmdW5jdGlvbiBpcyBwcm92aWRlZCxcbiAgICogdGhlbiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgaWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZS4gT3RoZXJ3aXNlLCB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgYnkgZGVmYXVsdC5cbiAgICogSXQgdGFrZXMgaW50byBhY2NvdW50IHRoZSBvbmdvaW5nIHN0cmVhbWluZyBwcm9jZXNzIGFuZCB0aGUgb25nb2luZyBzdG9wcGluZyBwcm9jZXNzIHRvIHRyaWdnZXIgdGhhdCBjb25kaXRpb25hbGx5IGRlZmluZSB0aGUgbG9naWNcbiAgICogb2YgdGhlIHJlbG9hZCA6XG4gICAqIC0gSWYgdGhlIGNoYXQgaXMgc3RyZWFtaW5nLCB0aGVuIHN0b3AgdGhlIGdlbmVyYXRpb24gYW5kIHdhaXQgZm9yIHRoZSBmZXRjaCB0byBjb21wbGV0ZSBiZWZvcmUgcmVsb2FkaW5nIHRoZSBjaGF0LlxuICAgKiAtIElmIHRoZSBjaGF0IGlzIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGVuIHdhaXQgZm9yIHRoZSBmZXRjaCB0byBjb21wbGV0ZSBiZWZvcmUgcmVsb2FkaW5nIHRoZSBjaGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlQ2hhbmdlcygpIHtcbiAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5jaGFuZ2VzJC52YWx1ZTtcbiAgICAvLyBJZiB0aGUgY2hhdCBzZXJ2aWNlIGlzIGEgV2ViU29ja2V0Q2hhdFNlcnZpY2UsIGhhbmRsZSB0aGUgb3ZlcnJpZGUgb2YgdGhlIG1lc3NhZ2UgaGFuZGxlcnMgaWYgZXhpc3RzXG4gICAgaWYgKGNoYW5nZXM/Lm1lc3NhZ2VIYW5kbGVycyAmJiB0aGlzLm1lc3NhZ2VIYW5kbGVycykge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5vdmVycmlkZU1lc3NhZ2VIYW5kbGVycyh0aGlzLm1lc3NhZ2VIYW5kbGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhlIGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgY2hhdCBtZXNzYWdlcyBpZiBleGlzdHMsIG90aGVyd2lzZSBsb2FkIHRoZSBkZWZhdWx0IGNoYXRcbiAgICAgKiBPbmNlIHRoZSBjaGF0IGlzIGluaXRpYWxpemVkIChmaXJzdENoYW5nZXNIYW5kbGVkIGlzIHRydWUpLCBhbGxvdyBvcGVuaW5nIHRoZSBjaGF0IHdpdGggdGhlIG5ldyBwcm92aWRlZCBtZXNzYWdlcyAoaWYgZXhpc3RzKVxuICAgICAqL1xuICAgIGlmICghdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkIHx8IGNoYW5nZXM/LmNoYXQpIHtcbiAgICAgIGNvbnN0IG9wZW5DaGF0ID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlcyQudmFsdWUgJiYgdGhpcy5jb25maWcuc2F2ZWRDaGF0U2V0dGluZ3M/LmVuYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxpc3RTYXZlZENoYXQoKTsgLy8gUmVmcmVzaCB0aGUgbGlzdCBvZiBzYXZlZCBjaGF0c1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jaGF0IS5tZXNzYWdlcyk7XG4gICAgICB9O1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZCgpO1xuICAgICAgaWYgKHRoaXMuY2hhdCkge1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWNoYXQubmV3Jywgeydjb25maWd1cmF0aW9uJzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckLnZhbHVlKSwnY2hhdC1pbml0JzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0KX0pO1xuICAgICAgICBvcGVuQ2hhdCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jaGF0Lm5ldycsIHsnY29uZmlndXJhdGlvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSl9KTtcbiAgICAgICAgdGhpcy5sb2FkRGVmYXVsdENoYXQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQsIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBpcyBcIlF1ZXJ5XCIsIHRoZSBxdWVyeSBjaGFuZ2VzIGFuZCB0aGUgcXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkIGZ1bmN0aW9uIGlzIHByb3ZpZGVkLFxuICAgICAqIHRoZW4gdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkIGlmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWVcbiAgICAgKiBPdGhlcndpc2UsIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCBieSBkZWZhdWx0XG4gICAgICovXG4gICAgaWYgKHRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCAmJiBjaGFuZ2VzPy5xdWVyeSAmJiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZXZlbnQgPT09ICdRdWVyeScpIHtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZCA/IHRoaXMucXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkKHRoaXMuX3ByZXZpb3VzUXVlcnksIHRoaXMucXVlcnkpIDogdHJ1ZSkge1xuICAgICAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgc3Vic2NyaXB0aW9uIHRvIHdhaXQgZm9yIGJvdGggc3RyZWFtaW5nJCBhbmQgc3RvcHBpbmdHZW5lcmF0aW9uJCB0byBiZSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gY29tYmluZUxhdGVzdChbXG4gICAgICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCxcbiAgICAgICAgICAgICAgdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kXG4gICAgICAgICAgICBdKVxuICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaWx0ZXIoKFtzdHJlYW1pbmcsIHN0b3BwaW5nXSkgPT4gIXN0cmVhbWluZyAmJiAhc3RvcHBpbmcpLCAvLyBXYWl0IHVudGlsIGJvdGggYXJlIGZhbHNlXG4gICAgICAgICAgICAgICAgdGFrZSgxKSAvLyBDb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgbWF0Y2hcbiAgICAgICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGUgdGhlIHJlbG9hZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlclJlbG9hZEFmdGVyUXVlcnlDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgX3ByZXZpb3VzUXVlcnkgd2l0aCB0aGUgY3VycmVudCBxdWVyeVxuICAgICAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzUXVlcnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpKTtcbiAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBzdWJzY3JpcHRpb24gYW5kIHJlc2V0IGl0cyB2YWx1ZVxuICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2Uuc3RvcEdlbmVyYXRpb24oKVxuICAgICAgICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgICAgICBuZXh0OiAoKSA9PiB7fSxcbiAgICAgICAgICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAgc3Vic2NyaXB0aW9uIGFuZCByZXNldCBpdHMgdmFsdWVcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAvLyBXYWl0IGZvciB0aGUgb25nb2luZyBmZXRjaCB0byBjb21wbGV0ZSwgdGhlbiB0cmlnZ2VyIHRoZSByZWxvYWRcbiAgICAgICAgICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC5waXBlKFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoKHN0cmVhbWluZykgPT4gIXN0cmVhbWluZyksXG4gICAgICAgICAgICAgICAgICAgIHRha2UoMSlcbiAgICAgICAgICAgICAgICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRXhlY3V0ZSB0aGUgcmVsb2FkIGFmdGVyIHRoZSBxdWVyeSBjaGFuZ2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlclJlbG9hZEFmdGVyUXVlcnlDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIF9wcmV2aW91c1F1ZXJ5IHdpdGggdGhlIGN1cnJlbnQgcXVlcnlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNRdWVyeSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSkpO1xuICAgICAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBzdWJzY3JpcHRpb24gYW5kIHJlc2V0IGl0cyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24hLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEV4ZWN1dGUgdGhlIHJlbG9hZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlXG4gICAgICAgICAgdGhpcy5fdHJpZ2dlclJlbG9hZEFmdGVyUXVlcnlDaGFuZ2UoKTtcbiAgICAgICAgICAvLyBVcGRhdGUgX3ByZXZpb3VzUXVlcnkgd2l0aCB0aGUgY3VycmVudCBxdWVyeVxuICAgICAgICAgIHRoaXMuX3ByZXZpb3VzUXVlcnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVXBkYXRlIF9wcmV2aW91c1F1ZXJ5IHdpdGggdGhlIGN1cnJlbnQgcXVlcnlcbiAgICAgICAgdGhpcy5fcHJldmlvdXNRdWVyeSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VycyBhIHJlbG9hZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlLlxuICAgKiBUaGlzIG1ldGhvZCBwZXJmb3JtcyB0aGUgbmVjZXNzYXJ5IG9wZXJhdGlvbnMgdG8gcmVsb2FkIHRoZSBjaGF0IGFmdGVyIGEgcXVlcnkgY2hhbmdlLlxuICAgKiBJdCBzZXRzIHRoZSBzeXN0ZW0gYW5kIHVzZXIgbWVzc2FnZXMsIHJlc2V0cyB0aGUgc2F2ZWRDaGF0SWQsIGdlbmVyYXRlcyBhIG5ldyBjaGF0SWQsXG4gICAqIGdlbmVyYXRlcyBhIG5ldyBjaGF0IGF1ZGl0IGV2ZW50LCBhbmQgaGFuZGxlcyB0aGUgcXVlcnkgbW9kZS5cbiAgICovXG4gIHByaXZhdGUgX3RyaWdnZXJSZWxvYWRBZnRlclF1ZXJ5Q2hhbmdlKCkge1xuICAgIGNvbnN0IHN5c3RlbU1zZyA9IHsgcm9sZTogJ3N5c3RlbScsIGNvbnRlbnQ6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuc3lzdGVtUHJvbXB0LCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiBmYWxzZSwgbWVzc2FnZUlkOiBndWlkKCkgfSB9O1xuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBvbGQgY29uZmlndXJhdGlvbiBmaWxlc1xuICAgIGNvbnN0IHVzZXJQcm9tcHQgPSB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnVzZXJQcm9tcHQucmVwbGFjZSgvXFx7XFx7KC4qPylcXH1cXH0vZywgJ1tbJDFdXScpO1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7IHJvbGU6ICd1c2VyJywgY29udGVudDogQXNzaXN0YW50VXRpbHMuZm9ybWF0UHJvbXB0KHRoaXMudHJhbnNsb2NvLnRyYW5zbGF0ZSh1c2VyUHJvbXB0KSAsIHsgcHJpbmNpcGFsOiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsIH0pLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuZGlzcGxheVVzZXJQcm9tcHQsIG1lc3NhZ2VJZDogZ3VpZCgpIH0gfTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQ2hhdElkKCk7IC8vIEdlbmVyYXRlIGEgbmV3IGNoYXRJZFxuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtY2hhdC5uZXcnLCB7J2NvbmZpZ3VyYXRpb24nOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNoYXRTZXJ2aWNlLmFzc2lzdGFudENvbmZpZyQudmFsdWUpfSk7IC8vIEdlbmVyYXRlIGEgbmV3IGNoYXQgYXVkaXQgZXZlbnRcbiAgICB0aGlzLl9oYW5kbGVRdWVyeU1vZGUoc3lzdGVtTXNnLCB1c2VyTXNnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgc2Nyb2xsIGxpc3RlbmVyIHRvIHRoZSBtZXNzYWdlIGxpc3QgZWxlbWVudC5cbiAgICogVGhlIGxpc3RlbmVyIGlzIHRyaWdnZXJlZCB3aGVuIGFueSBvZiB0aGUgZm9sbG93aW5nIGV2ZW50cyBvY2N1cjpcbiAgICogLSBMb2FkaW5nIHN0YXRlIGNoYW5nZXNcbiAgICogLSBNZXNzYWdlcyBjaGFuZ2VcbiAgICogLSBTdHJlYW1pbmcgc3RhdGUgY2hhbmdlc1xuICAgKiAtIFNjcm9sbCBldmVudCBvY2N1cnMgb24gdGhlIG1lc3NhZ2UgbGlzdCBlbGVtZW50XG4gICAqXG4gICAqIFdoZW4gdGhlIGxpc3RlbmVyIGlzIHRyaWdnZXJlZCwgaXQgdXBkYXRlcyB0aGUgYGlzQXRCb3R0b21gIHByb3BlcnR5LlxuICAgKi9cbiAgcHJpdmF0ZSBfYWRkU2Nyb2xsTGlzdGVuZXIoKSB7XG4gICAgdGhpcy5fc3ViLmFkZChcbiAgICAgIG1lcmdlKHRoaXMubG9hZGluZyQsIHRoaXMubWVzc2FnZXMkLCB0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQsIGZyb21FdmVudCh0aGlzLm1lc3NhZ2VMaXN0IS5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJykpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNBdEJvdHRvbSA9IHRoaXMuX3RvZ2dsZVNjcm9sbEJ1dHRvblZpc2liaWxpdHkoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbW9kZWwgZGVzY3JpcHRpb24gYmFzZWQgb24gdGhlIGRlZmF1bHRWYWx1ZXMgc2VydmljZV9pZCBhbmQgbW9kZWxfaWRcbiAgICovXG4gIHVwZGF0ZU1vZGVsRGVzY3JpcHRpb24oKSB7XG4gICAgdGhpcy5tb2RlbERlc2NyaXB0aW9uID0gdGhpcy5jaGF0U2VydmljZS5nZXRNb2RlbCh0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnNlcnZpY2VfaWQsIHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMubW9kZWxfaWQpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJtaXRzIGEgcXVlc3Rpb24gZnJvbSB0aGUgdXNlci5cbiAgICogSWYgdGhlIHVzZXIgaXMgZWRpdGluZyBhIHByZXZpb3VzIG1lc3NhZ2UsIHJlbW92ZXMgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5LlxuICAgKiBUcmlnZ2VycyB0aGUgZmV0Y2ggb2YgdGhlIGFuc3dlciBmb3IgdGhlIHN1Ym1pdHRlZCBxdWVzdGlvbiBieSBjYWxsaW5nIF9mZXRjaEFuc3dlcigpLlxuICAgKiBDbGVhcnMgdGhlIGlucHV0IHZhbHVlIGluIHRoZSBVSS5cbiAgICog4pqg77iPIElmIHRoZSBjaGF0IGlzIHN0cmVhbWluZyBvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICovXG4gIHN1Ym1pdFF1ZXN0aW9uKCkge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdWVzdGlvbi50cmltKCkgJiYgdGhpcy5tZXNzYWdlcyQudmFsdWUgJiYgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSkge1xuICAgICAgLy8gV2hlbiB0aGUgdXNlciBzdWJtaXRzIGEgcXVlc3Rpb24sIGlmIHRoZSB1c2VyIGlzIGVkaXRpbmcgYSBwcmV2aW91cyBtZXNzYWdlLCByZW1vdmUgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5XG4gICAgICBpZiAodGhpcy5pbmRleE1lc3NhZ2VUb0VkaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSVxuICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlLnNsaWNlKDAsIHRoaXMuaW5kZXhNZXNzYWdlVG9FZGl0KSk7XG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgcmF3IG1lc3NhZ2VzIGluIHRoZSBjaGF0IGhpc3Rvcnkgd2hpY2ggaXMgdGhlIGNsZWFuIHZlcnNpb24gdXNlZCB0byBtYWtlIHRoZSBuZXh0IHJlcXVlc3RcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3Rvcnkuc2xpY2UoMCwgdGhpcy5yYW5rTWVzc2FnZVRvRWRpdCk7XG4gICAgICAgIHRoaXMuaW5kZXhNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnJhbmtNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgLy8gUmVtb3ZlIHRoZSBzZWFyY2ggd2FybmluZyBtZXNzYWdlIGlmIGV4aXN0c1xuICAgICAgaWYgKHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkuYXQoLTEpPy5yb2xlID09PSAnc2VhcmNoLXdhcm5pbmcnKSB7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkucG9wKCk7XG4gICAgICB9XG4gICAgICAvLyBGZXRjaCB0aGUgYW5zd2VyXG4gICAgICB0aGlzLl9mZXRjaEFuc3dlcih0aGlzLnF1ZXN0aW9uLnRyaW0oKSwgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSk7XG4gICAgICAvLyBDbGVhciB0aGUgaW5wdXQgdmFsdWUgaW4gdGhlIFVJXG4gICAgICB0aGlzLnF1ZXN0aW9uSW5wdXQhLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgYXV0b2A7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXJzIHRoZSBmZXRjaCBvZiB0aGUgYW5zd2VyIGZvciB0aGUgZ2l2ZW4gcXVlc3Rpb24gYW5kIHVwZGF0ZXMgdGhlIGNvbnZlcnNhdGlvbi5cbiAgICogR2VuZXJhdGVzIGFuIGF1ZGl0IGV2ZW50IGZvciB0aGUgdXNlciBpbnB1dC5cbiAgICpcbiAgICogQHBhcmFtIHF1ZXN0aW9uIC0gVGhlIHF1ZXN0aW9uIGFza2VkIGJ5IHRoZSB1c2VyLlxuICAgKiBAcGFyYW0gY29udmVyc2F0aW9uIC0gVGhlIGN1cnJlbnQgY29udmVyc2F0aW9uIG1lc3NhZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBfZmV0Y2hBbnN3ZXIocXVlc3Rpb246IHN0cmluZywgY29udmVyc2F0aW9uOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgLy8gbWVyZ2UgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyBmcm9tIHRoZSBjaGF0IGNvbXBvbmVudCBhbmQgdGhlIGN1c3RvbWl6YXRpb24gSlNPTlxuICAgIGNvbnN0IGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMgPSB7IC4uLnRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMsIC4uLnRoaXMuYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyB9O1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7IHJvbGU6ICd1c2VyJywgY29udGVudDogcXVlc3Rpb24sIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRydWUsIG1lc3NhZ2VJZDogZ3VpZCgpLCBpc1VzZXJJbnB1dDogdHJ1ZSwgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyB9IH07XG4gICAgY29uc3QgbWVzc2FnZXMgPSBbLi4uY29udmVyc2F0aW9uLCB1c2VyTXNnXTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzKTsgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUkgd2l0aCB0aGUgbmV3IHVzZXIgbWVzc2FnZVxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSBtZXNzYWdlczsgLy8gVXBkYXRlIHRoZSBjaGF0IGhpc3Rvcnkgd2l0aCB0aGUgbmV3IHVzZXIgbWVzc2FnZVxuICAgIHRoaXMuZmV0Y2gobWVzc2FnZXMpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgeyAuLi50aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHVzZXJNc2cpLCAncXVlcnknOiBKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSwgJ2lzLXVzZXItaW5wdXQnOiB0cnVlLCAnZW5hYmxlZC1mdW5jdGlvbnMnOiB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkKS5tYXAoZnVuYyA9PiBmdW5jLm5hbWUpLCAnYWRkaXRpb25hbC13b3JrZmxvdy1wcm9wZXJ0aWVzJzogSlNPTi5zdHJpbmdpZnkoYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcykgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVwZW5kaW5nIG9uIHRoZSBjb25uZWN0aW9uJ3Mgc3RhdGUgOlxuICAgKiAgLSBJZiBjb25uZWN0ZWQgPT4gZ2l2ZW4gYSBsaXN0IG9mIG1lc3NhZ2VzLCB0aGUgY2hhdCBlbmRwb2ludCBpcyBpbnZva2VkIGZvciBhIGNvbnRpbnVhdGlvbiBhbmQgdXBkYXRlcyB0aGUgbGlzdCBvZiBtZXNzYWdlcyBhY2NvcmRpbmdseS5cbiAgICogIC0gSWYgYW55IG90aGVyIHN0YXRlID0+IGEgY29ubmVjdGlvbiBlcnJvciBtZXNzYWdlIGlzIGRpc3BsYXllZCBpbiB0aGUgY2hhdC5cbiAgICog4pqg77iPIElmIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGxpc3Qgb2YgbWVzc2FnZXMgdG8gaW52b2tlIHRoZSBjaGF0IGVuZHBvaW50IHdpdGhcbiAgICovXG4gIHB1YmxpYyBmZXRjaChtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSkge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl91cGRhdGVDb25uZWN0aW9uU3RhdHVzKCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgaWYgKHRoaXMuaXNDb25uZWN0ZWQpIHtcbiAgICAgIHRoaXMubG9hZGluZyQubmV4dCh0cnVlKTtcbiAgICAgIHRoaXMuX2RhdGFTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLl9kYXRhU3Vic2NyaXB0aW9uID0gdGhpcy5jaGF0U2VydmljZS5mZXRjaChtZXNzYWdlcywgdGhpcy5xdWVyeSlcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogcmVzID0+IHRoaXMudXBkYXRlRGF0YShyZXMuaGlzdG9yeSksXG4gICAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0dXMoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgIHJvbGU6ICdjb25uZWN0aW9uLWVycm9yJyxcbiAgICAgICAgICAgICAgICBjb250ZW50OiAoeyB0eXBlOiBcInRleHRcIiwgdGV4dDogdGhpcy50cmFuc2xvY28udHJhbnNsYXRlKHRoaXMuY29uZmlnLmNvbm5lY3Rpb25TZXR0aW5ncy5jb25uZWN0aW9uRXJyb3JNZXNzYWdlKSB9IGFzIFRleHRNZXNzYWdlQ29udGVudCksXG4gICAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCkgfVxuICAgICAgICAgICAgICB9IGFzIGFueSBhcyBDaGF0TWVzc2FnZTtcbiAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dChbLi4ubWVzc2FnZXMsIG1lc3NhZ2VdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGxhc3QgbWVzc2FnZSBpZiBpdCdzIGFuIGVtcHR5IG1lc3NhZ2VcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgZHVlIHRvIHRoZSBtYW5uZXIgaW4gd2hpY2ggdGhlIGNoYXQgc2VydmljZSBoYW5kbGVzIGNvbnNlY3V0aXZlIG1lc3NhZ2VzXG4gICAgICAgICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IHRoaXMubWVzc2FnZXMkLnZhbHVlPy5hdCgtMSk7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0VtcHR5QXNzaXN0YW50TWVzc2FnZShsYXN0TWVzc2FnZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZT8uc2xpY2UoMCwgLTEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0geyByb2xlOiAnY29ubmVjdGlvbi1lcnJvcicsIGNvbnRlbnQ6IHRoaXMudHJhbnNsb2NvLnRyYW5zbGF0ZSh0aGlzLmNvbmZpZy5jb25uZWN0aW9uU2V0dGluZ3MuY29ubmVjdGlvbkVycm9yTWVzc2FnZSksIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRydWUsIG1lc3NhZ2VJZDogZ3VpZCgpIH0gfTtcbiAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQoWy4uLm1lc3NhZ2VzLCBtZXNzYWdlXSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXV0b21hdGljU2Nyb2xsVG9MYXN0UmVzcG9uc2UpIHtcbiAgICAgIHRoaXMuc2Nyb2xsRG93bigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyeSB0byBmZXRjaCB0aGUgbWVzc2FnZXMgaWYgdGhlIGNvbm5lY3Rpb24gaXNzdWVzLlxuICAgKiAgLSBJZiByZWNvbm5lY3RpbmcgPT4ga2VlcCBkaXNwbGF5IHRoZSBjb25uZWN0aW9uIGVycm9yIG1lc3NhZ2UgZXZlbiB3aGVuIGNsaWNraW5nIG9uIHRoZSBcInJldHJ5XCIgYnV0dG9uIGFuZCBpbmNyZWFzaW5nIHRoZSBudW1iZXIgb2YgcmV0cmlhbCBhdHRlbXB0cywgdW50aWwgdGhlIGNvbm5lY3Rpb24gaXMgcmUtZXN0YWJsaXNoZWRcbiAgICogIC0gSWYgZGlzY29ubmVjdGVkID0+IE9uIGNsaWNrIG9uIHRoZSBcInJldHJ5XCIgYnV0dG9uLCBzdGFydCB0aGUgY29ubmVjdGlvbiBwcm9jZXNzIHdoaWxlIGRpc3BsYXlpbmcgdGhlIGNvbm5lY3Rpb24gZXJyb3IgbWVzc2FnZSA6XG4gICAqICAgICAgKiBJZiBzdWNjZXNzZnVsID0+IGdpdmVuIGEgbGlzdCBvZiBtZXNzYWdlcywgdGhlIGNoYXQgZW5kcG9pbnQgaXMgaW52b2tlZCBmb3IgYSBjb250aW51YXRpb24gYW5kIHVwZGF0ZXMgdGhlIGxpc3Qgb2YgbWVzc2FnZXMgYWNjb3JkaW5nbHkuXG4gICAqICAgICAgKiBJZiBmYWlsZWQgPT4gaW5jcmVhc2UgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzXG4gICAqL1xuICByZXRyeUZldGNoKCkge1xuICAgIC8vIEEgb25lLXRpbWUgbGlzdGVuZXIgZm9yIHJlY29ubmVjdGVkIGV2ZW50XG4gICAgY29uc3Qgb25SZWNvbm5lY3RlZEhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAvLyBHZXQgdGhlIG1lc3NhZ2VzIHdpdGhvdXQgdGhlIGxhc3Qgb25lICh0aGUgY29ubmVjdGlvbiBlcnJvciBtZXNzYWdlKVxuICAgICAgY29uc3QgbWVzc2FnZXMgPSB0aGlzLm1lc3NhZ2VzJC52YWx1ZSEuc2xpY2UoMCwgLTEpO1xuICAgICAgLy8gRmluZCB0aGUgbGFzdCBcInVzZXJcIiBtZXNzYWdlIGluIHRoZSBtZXNzYWdlcyBsaXN0XG4gICAgICBsZXQgaW5kZXggPSBtZXNzYWdlcy5sZW5ndGggLSAxO1xuICAgICAgd2hpbGUgKGluZGV4ID49IDAgJiYgbWVzc2FnZXNbaW5kZXhdLnJvbGUgIT09ICd1c2VyJykge1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgLy8gSWYgYSB1c2VyIG1lc3NhZ2UgaXMgZm91bmQgKGFuZCBpdCBzaG91bGQgYWx3YXlzIGJlIHRoZSBjYXNlKSwgcmVtb3ZlIGFsbCBzdWJzZXF1ZW50IG1lc3NhZ2VzIGZyb20gdGhlIGNoYXQgaGlzdG9yeVxuICAgICAgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUlcbiAgICAgIC8vIGFuZCBmZXRjaCB0aGUgYW5zd2VyIGZyb20gdGhlIGFzc2lzdGFudFxuICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZSEuc2xpY2UoMCwgaW5kZXggKyAxKSk7XG4gICAgICAgIGNvbnN0IHJlbWFwcGVkSW5kZXggPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5LCBtZXNzYWdlc1tpbmRleF0uYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLnNsaWNlKDAsIHJlbWFwcGVkSW5kZXggKyAxKTtcbiAgICAgICAgdGhpcy5mZXRjaCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmV0cmlhbEF0dGVtcHRzID0gdW5kZWZpbmVkOyAvLyBSZXNldCB0aGUgbnVtYmVyIG9mIHJldHJpYWwgYXR0ZW1wdHNcbiAgICAgIC8qKlxuICAgICAgICogVG8gcmVtb3ZlIHRoZSBoYW5kbGVyIGZvciBvbnJlY29ubmVjdGVkKCkgYWZ0ZXIgaXQncyBiZWVuIHJlZ2lzdGVyZWQsY2Fubm90IGRpcmVjdGx5IHVzZSBvZmYoKSBsaWtlIHlvdSB3b3VsZCBmb3Igbm9ybWFsIGV2ZW50cyByZWdpc3RlcmVkIHdpdGggY29ubmVjdGlvbi5vbigpLlxuICAgICAgICogSW5zdGVhZCwgeW91IG5lZWQgdG8gZXhwbGljaXRseSByZW1vdmUgb3IgcmVzZXQgdGhlIGhhbmRsZXIgYnkgYXNzaWduaW5nIGl0IHRvIG51bGwgb3IgYW4gZW1wdHkgZnVuY3Rpb25cbiAgICAgICAqL1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uIS5vbnJlY29ubmVjdGVkKCgpID0+IHt9KTtcbiAgICAgIC8vIFJlc2V0IHRoZSBmbGFnIHRvIGVuc3VyZSB0aGUgaGFuZGxlciBpcyByZWdpc3RlcmVkIGFnYWluIHdoZW4gbmVlZGVkXG4gICAgICB0aGlzLl9pc1JlY29ubmVjdGVkTGlzdGVuZXJSZWdpc3RlcmVkID0gZmFsc2U7XG4gICAgfVxuICAgIC8vIERlcGVuZGluZyBvbiB0aGUgY29ubmVjdGlvbidzIHN0YXRlLCB0YWtlIHRoZSBhcHByb3ByaWF0ZSBhY3Rpb25cbiAgICBzd2l0Y2ggKHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbiEuc3RhdGUpIHtcbiAgICAgIGNhc2UgSHViQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDpcbiAgICAgICAgLy8gSWYgdGhlIGNvbm5lY3Rpb24gaXMgcmUtZXN0YWJsaXNoZWQgaW4gdGhlIG1lYW50aW1lLCBmZXRjaCB0aGUgbWVzc2FnZXNcbiAgICAgICAgb25SZWNvbm5lY3RlZEhhbmRsZXIoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEh1YkNvbm5lY3Rpb25TdGF0ZS5SZWNvbm5lY3Rpbmc6XG4gICAgICAgIC8vIEF0dGFjaCB0aGUgcmVjb25uZWN0ZWQgbGlzdGVuZXIgaWYgbm90IGFscmVhZHkgcmVnaXN0ZXJlZFxuICAgICAgICBpZiAoIXRoaXMuX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQpIHtcbiAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNvbm5lY3Rpb24hLm9ucmVjb25uZWN0ZWQob25SZWNvbm5lY3RlZEhhbmRsZXIpO1xuICAgICAgICAgIHRoaXMuX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIEluY3JlYXNlIHRoZSBudW1iZXIgb2YgcmV0cmlhbCBhdHRlbXB0c1xuICAgICAgICB0aGlzLnJldHJpYWxBdHRlbXB0cyA9IHRoaXMucmV0cmlhbEF0dGVtcHRzID8gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgKyAxIDogMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0ZWQ6XG4gICAgICAgIC8vIFN0YXJ0IHRoZSBuZXcgY29ubmVjdGlvblxuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLnN0YXJ0Q29ubmVjdGlvbigpXG4gICAgICAgICAgLnRoZW4oKCkgPT4gb25SZWNvbm5lY3RlZEhhbmRsZXIoKSlcbiAgICAgICAgICAuY2F0Y2goKCkgPT4geyAvLyBJZiB0aGUgY29ubmVjdGlvbiBmYWlscywgaW5jcmVhc2UgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzXG4gICAgICAgICAgICB0aGlzLnJldHJpYWxBdHRlbXB0cyA9IHRoaXMucmV0cmlhbEF0dGVtcHRzID8gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgKyAxIDogMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIHNpZ25hbFIgY29ubmVjdGlvbiBpcyBjb25uZWN0ZWQuXG4gICAqIEZvciB0aGUgUkVTVCBwcm90b2NvbCwgdGhlIGNvbm5lY3Rpb24gaXMgYWx3YXlzIGNvbnNpZGVyZWQgY29ubmVjdGVkIChmb3IgdGhlIG1vbWVudCkuXG4gICAqL1xuICBwcml2YXRlIF91cGRhdGVDb25uZWN0aW9uU3RhdHVzKCkge1xuICAgIHRoaXMuaXNDb25uZWN0ZWQgPSB0aGlzLmNoYXRTZXJ2aWNlLmNvbm5lY3Rpb24hLnN0YXRlID09PSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgVUkgd2l0aCB0aGUgbmV3IG1lc3NhZ2VzXG4gICAqIEBwYXJhbSBtZXNzYWdlc1xuICAgKi9cbiAgdXBkYXRlRGF0YShtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSkge1xuICAgIHRoaXMubWVzc2FnZXMkLm5leHQobWVzc2FnZXMpO1xuICAgIHRoaXMuZGF0YS5lbWl0KG1lc3NhZ2VzKTtcbiAgICB0aGlzLmxvYWRpbmckLm5leHQoZmFsc2UpO1xuICAgIHRoaXMucXVlc3Rpb24gPSAnJztcbiAgICBpZiAodGhpcy5hdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSkge1xuICAgICAgdGhpcy5zY3JvbGxEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGNoYXQgZGlzY3Vzc2lvbiBpcyBzY3JvbGxlZCBkb3duIHRvIHRoZSBib3R0b20sIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgcHJpdmF0ZSBfdG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuIE1hdGgucm91bmQodGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHQgLSB0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCAtIDEpIDw9IHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGwgZG93biB0byB0aGUgYm90dG9tIG9mIHRoZSBjaGF0IGRpc2N1c3Npb25cbiAgICovXG4gIHNjcm9sbERvd24oKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0gdGhpcy5tZXNzYWdlTGlzdC5uYXRpdmVFbGVtZW50LnNjcm9sbEhlaWdodDtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfVxuICAgIH0sIDEwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIG5ldyBjaGF0IHdpdGggdGhlIGRlZmF1bHRWYWx1ZXMgc2V0dGluZ3MuXG4gICAqIFRoZSBzYXZlZENoYXRJZCBpbiB0aGUgY2hhdCBzZXJ2aWNlIHdpbGwgYmUgcmVzZXQsIHNvIHRoYXQgdGhlIHVwY29taW5nIHNhdmVkIGNoYXQgb3BlcmF0aW9ucyB3aWxsIGJlIHBlcmZvcm1lZCBvbiB0aGUgZnJlc2ggbmV3IGNoYXQuXG4gICAqIElmIHRoZSBzYXZlZENoYXQgZmVhdHVyZSBpcyBlbmFibGVkLCB0aGUgbGlzdCBvZiBzYXZlZCBjaGF0cyB3aWxsIGJlIHJlZnJlc2hlZC5cbiAgICog4pqg77iPIElmIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKi9cbiAgbmV3Q2hhdCgpIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZCgpOyAvLyBHZW5lcmF0ZSBhIG5ldyBjaGF0SWRcbiAgICBpZiAodGhpcy5jb25maWcuc2F2ZWRDaGF0U2V0dGluZ3M/LmVuYWJsZWQpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UubGlzdFNhdmVkQ2hhdCgpOyAvLyBSZWZyZXNoIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzXG4gICAgfVxuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtY2hhdC5uZXcnLCB7J2NvbmZpZ3VyYXRpb24nOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNoYXRTZXJ2aWNlLmFzc2lzdGFudENvbmZpZyQudmFsdWUpfSk7IC8vIEdlbmVyYXRlIGEgbmV3IGNoYXQgYXVkaXQgZXZlbnRcbiAgICB0aGlzLmxvYWREZWZhdWx0Q2hhdCgpOyAvLyBTdGFydCBhIG5ldyBjaGF0XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhlIHNwZWNpZmllZCBkb2N1bWVudCBJRHMgdG8gdGhlIGFzc2lzdGFudC5cbiAgICogSWYgbm8gZG9jdW1lbnQgSURzIGFyZSBwcm92aWRlZCwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICogSWYgdGhlIGFjdGlvbiBmb3IgYXR0YWNoaW5nIGEgZG9jdW1lbnQgaXMgbm90IGRlZmluZWQgYXQgdGhlIGFwcGxpY2F0aW9uIGN1c3RvbWl6YXRpb24gbGV2ZWwsIGFuIGVycm9yIGlzIGxvZ2dlZC5cbiAgICog4pqg77iPIElmIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBAcGFyYW0gaWRzIC0gQW4gYXJyYXkgb2YgZG9jdW1lbnQgSURzIHRvIGF0dGFjaC5cbiAgICovXG4gIGF0dGFjaFRvQ2hhdChpZHM6IHN0cmluZ1tdKSB7XG4gICAgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlIHx8ICEhdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghaWRzIHx8IGlkcz8ubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhdHRhY2hEb2NBY3Rpb24gPSB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuYWN0aW9ucz8uW1wiYXR0YWNoRG9jQWN0aW9uXCJdO1xuICAgIGlmICghYXR0YWNoRG9jQWN0aW9uKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBObyBhY3Rpb24gaXMgZGVmaW5lZCBmb3IgYXR0YWNoaW5nIGEgZG9jdW1lbnQgdG8gdGhlIGFzc2lzdGFudCBcIiR7dGhpcy5pbnN0YW5jZUlkfVwiYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHVzZXJNc2cgPSB7IHJvbGU6ICd1c2VyJywgY29udGVudDogJycsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7ZGlzcGxheTogZmFsc2UsIG1lc3NhZ2VJZDogZ3VpZCgpLCBpc1VzZXJJbnB1dDogZmFsc2UsIHR5cGU6IFwiQWN0aW9uXCIsIGZvcmNlZFdvcmtmbG93OiBhdHRhY2hEb2NBY3Rpb24uZm9yY2VkV29ya2Zsb3csIGZvcmNlZFdvcmtmbG93UHJvcGVydGllczogey4uLihhdHRhY2hEb2NBY3Rpb24uZm9yY2VkV29ya2Zsb3dQcm9wZXJ0aWVzIHx8IHt9KSwgaWRzfSwgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllczogdGhpcy5jb25maWcuYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllc319O1xuICAgIC8vIFJlbW92ZSB0aGUgc2VhcmNoIHdhcm5pbmcgbWVzc2FnZSBpZiBleGlzdHNcbiAgICBpZiAodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEuYXQoLTEpPy5yb2xlID09PSAnc2VhcmNoLXdhcm5pbmcnKSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IS5wb3AoKTtcbiAgICB9XG4gICAgY29uc3QgbWVzc2FnZXMgPSBbLi4udGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIHVzZXJNc2ddO1xuICAgIHRoaXMubWVzc2FnZXMkLm5leHQobWVzc2FnZXMpO1xuICAgIHRoaXMuZmV0Y2gobWVzc2FnZXMpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtYWN0aW9uLnJlcXVlc3RlZCcsIHtcbiAgICAgICdkZXRhaWwnOiAnYXR0YWNoRG9jQWN0aW9uJyxcbiAgICAgICdmb3JjZWQtd29ya2Zsb3cnOiAnU2luZXF1YUFkZFNlbGVjdGVkRG9jdW1lbnRzV29ya2Zsb3cnLFxuICAgICAgJ2ZvcmNlZC13b3JrZmxvdy1wcm9wZXJ0aWVzJzogSlNPTi5zdHJpbmdpZnkoaWRzKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCB0aGUgZGVmYXVsdCBjaGF0IHdpdGggdGhlIGRlZmF1bHRWYWx1ZXMgc2V0dGluZ3NcbiAgICogSWYgdGhlIGNoYXQgaXMgbWVhbnQgdG8gYmUgaW5pdGlhbGl6ZWQgd2l0aCBldmVudCA9PT0gXCJRdWVyeVwiLCB0aGUgY29ycmVzcG9uZGluZyB1c2VyIHF1ZXJ5IG1lc3NhZ2Ugd2lsbCBiZSBhZGRlZCB0byB0aGUgY2hhdCBoaXN0b3J5XG4gICAqL1xuICBsb2FkRGVmYXVsdENoYXQoKSB7XG4gICAgLy8gRGVmaW5lIHRoZSBkZWZhdWx0IHN5c3RlbSBwcm9tcHQgYW5kIHVzZXIgcHJvbXB0IG1lc3NhZ2VzXG4gICAgY29uc3Qgc3lzdGVtTXNnID0geyByb2xlOiAnc3lzdGVtJywgY29udGVudDogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zeXN0ZW1Qcm9tcHQsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IGZhbHNlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIG9sZCBjb25maWd1cmF0aW9uIGZpbGVzXG4gICAgY29uc3QgdXNlclByb21wdCA9IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMudXNlclByb21wdC5yZXBsYWNlKC9cXHtcXHsoLio/KVxcfVxcfS9nLCAnW1skMV1dJyk7XG4gICAgY29uc3QgdXNlck1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiBBc3Npc3RhbnRVdGlscy5mb3JtYXRQcm9tcHQodGhpcy50cmFuc2xvY28udHJhbnNsYXRlKHVzZXJQcm9tcHQpICwgeyBwcmluY2lwYWw6IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwgfSksIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdCwgbWVzc2FnZUlkOiBndWlkKCkgfSB9O1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5ldmVudCA9PT0gJ1F1ZXJ5Jykge1xuICAgICAgdGhpcy5faGFuZGxlUXVlcnlNb2RlKHN5c3RlbU1zZywgdXNlck1zZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2hhbmRsZVByb21wdE1vZGUoc3lzdGVtTXNnLCB1c2VyTXNnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUgcHJvbXB0IG1vZGUgb2YgdGhlIGNoYXQgY29tcG9uZW50LlxuICAgKiBJZiBgc2VuZFVzZXJQcm9tcHRgIGlzIHRydWUsIGl0IG9wZW5zIHRoZSBjaGF0IHdpdGggYm90aCBzeXN0ZW0gYW5kIHVzZXIgbWVzc2FnZXMsXG4gICAqIGFuZCBnZW5lcmF0ZXMgYXVkaXQgZXZlbnRzIGZvciBib3RoIG1lc3NhZ2VzLlxuICAgKiBJZiBgc2VuZFVzZXJQcm9tcHRgIGlzIGZhbHNlLCBpdCBvcGVucyB0aGUgY2hhdCB3aXRoIG9ubHkgdGhlIHN5c3RlbSBtZXNzYWdlLFxuICAgKiBhbmQgZ2VuZXJhdGVzIGFuIGF1ZGl0IGV2ZW50IGZvciB0aGUgc3lzdGVtIG1lc3NhZ2UuXG4gICAqXG4gICAqIEBwYXJhbSBzeXN0ZW1Nc2cgLSBUaGUgc3lzdGVtIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBjaGF0LlxuICAgKiBAcGFyYW0gdXNlck1zZyAtIFRoZSB1c2VyIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBjaGF0IChvcHRpb25hbCkuXG4gICAqL1xuICBwcml2YXRlIF9oYW5kbGVQcm9tcHRNb2RlKHN5c3RlbU1zZzogQ2hhdE1lc3NhZ2UsIHVzZXJNc2c6IENoYXRNZXNzYWdlKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5zZW5kVXNlclByb21wdCkge1xuICAgICAgdGhpcy5vcGVuQ2hhdChbc3lzdGVtTXNnLCB1c2VyTXNnXSk7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMoc3lzdGVtTXNnKSk7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHModXNlck1zZykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2ddKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhzeXN0ZW1Nc2cpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUgcXVlcnkgbW9kZSBieSBkaXNwbGF5aW5nIHRoZSBzeXN0ZW0gbWVzc2FnZSwgdXNlciBtZXNzYWdlLCBhbmQgdXNlciBxdWVyeSBtZXNzYWdlLlxuICAgKiBJZiB0aGUgcHJvdmlkZWQgcXVlcnkgdGV4dCBpcyBub3QgZW1wdHksIHRoZW4gYWRkIHRoZSB1c2VyIHF1ZXJ5IG1lc3NhZ2UgdG8gdGhlIGNoYXQgaGlzdG9yeSBhbmQgaW52b2tlIHRoZSBhc3Npc3RhbnRcbiAgICogT3RoZXJ3aXNlLCBqdXN0IHN0YXJ0IGEgbmV3IGNoYXQgd2l0aCBhIHdhcm5pbmcgbWVzc2FnZSBpbnZpdGluZyB0aGUgdXNlciB0byBwZXJmb3JtIGEgZnVsbCB0ZXh0IHNlYXJjaCB0byByZXRyaWV2ZSBzb21lIHJlc3VsdHNcbiAgICogQHBhcmFtIHN5c3RlbU1zZyAtIFRoZSBzeXN0ZW0gbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQuXG4gICAqIEBwYXJhbSB1c2VyTXNnIC0gVGhlIHVzZXIgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQuXG4gICAqL1xuICBwcml2YXRlIF9oYW5kbGVRdWVyeU1vZGUoc3lzdGVtTXNnOiBDaGF0TWVzc2FnZSwgdXNlck1zZzogQ2hhdE1lc3NhZ2UpIHtcbiAgICBpZiAoISF0aGlzLnF1ZXJ5LnRleHQpIHtcbiAgICAgIGNvbnN0IHVzZXJRdWVyeU1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiB0aGlzLnF1ZXJ5LnRleHQsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5kaXNwbGF5VXNlclF1ZXJ5LCBtZXNzYWdlSWQ6IGd1aWQoKSwgcXVlcnk6IHRoaXMucXVlcnksIGZvcmNlZFdvcmtmbG93OiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csIGZvcmNlZEZ1bmN0aW9uOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkRnVuY3Rpb24sIGlzVXNlcklucHV0OiB0cnVlLCBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzOiB0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzIH0gfTtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3Muc2VuZFVzZXJQcm9tcHQpIHtcbiAgICAgICAgdGhpcy5vcGVuQ2hhdChbc3lzdGVtTXNnLCB1c2VyTXNnLCB1c2VyUXVlcnlNc2ddKTtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB0aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHN5c3RlbU1zZykpO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHModXNlck1zZykpO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHsgLi4udGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyUXVlcnlNc2cpLCAncXVlcnknOiBKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSwgJ2lzLXVzZXItaW5wdXQnOiB0cnVlLCAnZm9yY2VkLXdvcmtmbG93JzogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmZvcmNlZFdvcmtmbG93LCAnZm9yY2VkLWZ1bmN0aW9uJzogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmZvcmNlZEZ1bmN0aW9uLCAnZW5hYmxlZC1mdW5jdGlvbnMnOiB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLmZ1bmN0aW9ucz8uZmlsdGVyKGZ1bmMgPT4gZnVuYy5lbmFibGVkKS5tYXAoZnVuYyA9PiBmdW5jLm5hbWUpLCAnYWRkaXRpb25hbC13b3JrZmxvdy1wcm9wZXJ0aWVzJzogSlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWcuYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcykgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMoc3lzdGVtTXNnKSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgeyAuLi50aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHVzZXJRdWVyeU1zZyksICdxdWVyeSc6IEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpLCAnaXMtdXNlci1pbnB1dCc6IHRydWUsICdmb3JjZWQtd29ya2Zsb3cnOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csICdmb3JjZWQtZnVuY3Rpb24nOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkRnVuY3Rpb24sICdlbmFibGVkLWZ1bmN0aW9ucyc6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuZnVuY3Rpb25zPy5maWx0ZXIoZnVuYyA9PiBmdW5jLmVuYWJsZWQpLm1hcChmdW5jID0+IGZ1bmMubmFtZSksICdhZGRpdGlvbmFsLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzKSB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgd2FybmluZ01zZyA9IHsgcm9sZTogJ3NlYXJjaC13YXJuaW5nJywgY29udGVudDogdGhpcy50cmFuc2xvY28udHJhbnNsYXRlKHRoaXMuY29uZmlnLmdsb2JhbFNldHRpbmdzLnNlYXJjaFdhcm5pbmdNZXNzYWdlKSwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCkgfSB9O1xuICAgICAgdGhpcy5vcGVuQ2hhdChbc3lzdGVtTXNnLCB3YXJuaW5nTXNnXSk7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMod2FybmluZ01zZykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMobWVzc2FnZTogQ2hhdE1lc3NhZ2UpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICBjb25zdCBkZXRhaWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge1xuICAgICAgJ2R1cmF0aW9uJzogMCxcbiAgICAgICdyb2xlJzogbWVzc2FnZS5yb2xlLFxuICAgICAgJ3JhbmsnOiByYW5rLFxuICAgICAgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZFxuICAgIH07XG4gICAgaWYgKCEhdGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncz8ubG9nQ29udGVudCkge1xuICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGRldGFpbHMudGV4dCA9IG1lc3NhZ2UuY29udGVudDtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShtZXNzYWdlLmNvbnRlbnQpKSB7XG4gICAgICAgIGRldGFpbHMudGV4dCA9IChtZXNzYWdlLmNvbnRlbnQuZmluZCgobXNnKSA9PiBtc2cudHlwZSA9PT0gXCJ0ZXh0XCIpIGFzIFRleHRNZXNzYWdlQ29udGVudCkudGV4dFxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGV0YWlscztcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydC9vcGVuIGEgbmV3IGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgbWVzc2FnZXMgYW5kIGNoYXRJZFxuICAgKiBJZiB0aGUgbGFzdCBtZXNzYWdlIGlzIGZyb20gdGhlIHVzZXIsIGEgcmVxdWVzdCB0byB0aGUgYXNzaXN0YW50IGlzIG1hZGUgdG8gZ2V0IGFuIGFuc3dlclxuICAgKiBJZiB0aGUgbGFzdCBtZXNzYWdlIGlzIGZyb20gdGhlIGFzc2lzdGFudCwgdGhlIGNvbnZlcnNhdGlvbiBpcyBsb2FkZWQgcmlnaHQgYXdheVxuICAgKiBAcGFyYW0gbWVzc2FnZXMgVGhlIGxpc3Qgb2YgbWVzc2FnZXMgb2YgdGhlIGNoYXRcbiAgICogQHBhcmFtIGNoYXRJZCAgVGhlIGlkIG9mIHRoZSBkaXNjdXNzaW9uLiBJZiBwcm92aWRlZCAoaWUuIGFuIGV4aXN0aW5nIGRpc2N1c3Npb24gaW4gdGhlIHNhdmVkIGNoYXQgaW5kZXgpLCB1cGRhdGUgdGhlIGNoYXRJZCBpbiB0aGUgY2hhdCBzZXJ2aWNlIGZvciB0aGUgdXBjb21pbmcgc2F2ZWQgY2hhdCBvcGVyYXRpb25zXG4gICAqL1xuICBvcGVuQ2hhdChtZXNzYWdlczogUmF3TWVzc2FnZVtdLCBjaGF0SWQ/OiBzdHJpbmcpIHtcbiAgICBpZiAoIW1lc3NhZ2VzIHx8ICFBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSkge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb2NjdXJzIHdoaWxlIHRyeWluZyB0byBsb2FkIHRoZSBkaXNjdXNzaW9uLiBJbnZhbGlkIG1lc3NhZ2VzIHJlY2VpdmVkIDonLCBtZXNzYWdlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjaGF0SWQpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVDaGF0SWQoY2hhdElkKTtcbiAgICB9XG4gICAgLy8gRW5zdXJlIGVhY2ggbWVzc2FnZSBoYXMgYSB1bmlxdWUgbWVzc2FnZUlkXG4gICAgLy8gVGhpcyBpcyBuZWNlc3Nhcnkgc3BlY2lhbGx5IGluIGNhc2UgdGhlIGFzc2lzdGFudCBpcyBzdGFydGVkIHdpdGggYSBwcmVkZWZpbmVkIGhpc3RvcnkgT3IgYW4gb2xkIHNhdmVkIGNoYXRcbiAgICBjb25zdCBtZXNzYWdlc1dpdGhJZHM6IENoYXRNZXNzYWdlW10gPSBtZXNzYWdlcy5tYXAoKG1zZykgPT4ge1xuICAgICAgbXNnLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCA/Pz0gZ3VpZCgpO1xuICAgICAgcmV0dXJuIG1zZyBhcyBDaGF0TWVzc2FnZTtcbiAgICB9KTtcblxuICAgIHRoaXMucmVzZXRDaGF0KCk7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlc1dpdGhJZHMpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSBtZXNzYWdlc1dpdGhJZHM7XG4gICAgY29uc3QgbGFzdE1lc3NhZ2UgPSBtZXNzYWdlcy5hdCgtMSk7XG4gICAgaWYgKGxhc3RNZXNzYWdlICYmIGxhc3RNZXNzYWdlLnJvbGUgPT09ICd1c2VyJykge1xuICAgICAgdGhpcy5mZXRjaChtZXNzYWdlc1dpdGhJZHMpOyAvLyBJZiB0aGUgbGFzdCBtZXNzYWdlIGlmIGZyb20gYSB1c2VyLCBhbiBhbnN3ZXIgZnJvbSB0aGUgYXNzaXN0YW50IGlzIGV4cGVjdGVkXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVEYXRhKG1lc3NhZ2VzV2l0aElkcyk7IC8vIElmIHRoZSBsYXN0IG1lc3NhZ2UgaWYgZnJvbSB0aGUgYXNzaXN0YW50LCB3ZSBjYW4gbG9hZCB0aGUgY29udmVyc2F0aW9uIHJpZ2h0IGF3YXlcbiAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICB9XG4gICAgdGhpcy5fYWRkU2Nyb2xsTGlzdGVuZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCB0aGUgY2hhdCBieSBjbGVhcmluZyB0aGUgY2hhdCBoaXN0b3J5IGFuZCB0aGUgVUkgYWNjb3JkaW5nbHlcbiAgICogVGhlIHVzZXIgaW5wdXQgd2lsbCBiZSBjbGVhcmVkXG4gICAqIFRoZSBmZXRjaCBzdWJzY3JpcHRpb24gd2lsbCBiZSB0ZXJtaW5hdGVkXG4gICAqL1xuICByZXNldENoYXQoKSB7XG4gICAgaWYgKHRoaXMubWVzc2FnZXMkLnZhbHVlKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHVuZGVmaW5lZCk7IC8vIFJlc2V0IGNoYXRcbiAgICB9XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHVuZGVmaW5lZDsgLy8gUmVzZXQgY2hhdCBoaXN0b3J5XG4gICAgdGhpcy5xdWVzdGlvbiA9ICcnO1xuICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCBhbmQgTG9hZCB0aGUgc2F2ZWQgY2hhdCBmcm9tIHRoZSBzYXZlZCBjaGF0IGluZGV4LlxuICAgKiBJZiB0aGUgc2F2ZWQgY2hhdCBpcyBmb3VuZCwgdGhlIGNoYXQgZGlzY3Vzc2lvbiB3aWxsIGJlIGxvYWRlZCB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlcyBhbmQgY2hhdElkXG4gICAqL1xuICBvbkxvYWRDaGF0KCkge1xuICAgIHRoaXMubG9hZGluZyQubmV4dCh0cnVlKTtcbiAgICB0aGlzLl9zdWIuYWRkKFxuICAgICAgdGhpcy5jaGF0U2VydmljZS5sb2FkU2F2ZWRDaGF0JFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoc2F2ZWRDaGF0ID0+ICEhc2F2ZWRDaGF0KSxcbiAgICAgICAgICBzd2l0Y2hNYXAoc2F2ZWRDaGF0ID0+IHRoaXMuY2hhdFNlcnZpY2UuZ2V0U2F2ZWRDaGF0KHNhdmVkQ2hhdCEuaWQpKSxcbiAgICAgICAgICBmaWx0ZXIoc2F2ZWRDaGF0SGlzdG9yeSA9PiAhIXNhdmVkQ2hhdEhpc3RvcnkpLFxuICAgICAgICAgIHRhcChzYXZlZENoYXRIaXN0b3J5ID0+IHRoaXMub3BlbkNoYXQoc2F2ZWRDaGF0SGlzdG9yeSEuaGlzdG9yeSwgc2F2ZWRDaGF0SGlzdG9yeSEuaWQpKVxuICAgICAgICApLnN1YnNjcmliZSgpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBjdXJyZW50IGFzc2lzdGFudCdzIGFuc3dlci5cbiAgICogVGhlIGZldGNoIHN1YnNjcmlwdGlvbiB3aWxsIGJlIHRlcm1pbmF0ZWQuXG4gICAqL1xuICBzdG9wR2VuZXJhdGlvbigpIHtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLnN0b3BHZW5lcmF0aW9uKCkuc3Vic2NyaWJlKFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBSZW1vdmUgdGhlIGxhc3QgbWVzc2FnZSBpZiBpdCdzIGFuIGVtcHR5IG1lc3NhZ2VcbiAgICAgICAgLy8gVGhpcyBpcyBkdWUgdG8gdGhlIG1hbm5lciBpbiB3aGljaCB0aGUgY2hhdCBzZXJ2aWNlIGhhbmRsZXMgY29uc2VjdXRpdmUgbWVzc2FnZXNcbiAgICAgICAgY29uc3QgbGFzdE1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzJC52YWx1ZT8uYXQoLTEpO1xuICAgICAgICBpZiAodGhpcy5pc0VtcHR5QXNzaXN0YW50TWVzc2FnZShsYXN0TWVzc2FnZSkpIHtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlPy5zbGljZSgwLCAtMSkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGVybWluYXRlRmV0Y2goKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlcm1pbmF0ZSB0aGUgZmV0Y2ggcHJvY2VzcyBieSB1bnN1YnNjcmliaW5nIGZyb20gdGhlIGRhdGEgc3Vic2NyaXB0aW9uIGFuZCB1cGRhdGluZyB0aGUgbG9hZGluZyBzdGF0dXMgdG8gZmFsc2UuXG4gICAqIEFkZGl0aW9uYWxseSwgZm9jdXMgb24gdGhlIGNoYXQgaW5wdXQgaWYgdGhlIGZvY3VzQWZ0ZXJSZXNwb25zZSBmbGFnIGlzIHNldCB0byB0cnVlLlxuICAgKi9cbiAgdGVybWluYXRlRmV0Y2goKSB7XG4gICAgdGhpcy5fZGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9kYXRhU3Vic2NyaXB0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubG9hZGluZyQubmV4dChmYWxzZSk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgaWYgKHRoaXMuZm9jdXNBZnRlclJlc3BvbnNlKSB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5xdWVzdGlvbklucHV0Py5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29weSBhIHByZXZpb3VzIHVzZXIgbWVzc2FnZSBvZiB0aGUgY2hhdCBoaXN0b3J5IHRvIHRoZSBjaGF0IHVzZXIgaW5wdXQuXG4gICAqIFRodXMsIHRoZSB1c2VyIGNhbiBlZGl0IGFuZCByZXN1Ym1pdCB0aGUgbWVzc2FnZS5cbiAgICogT25jZSB0aGUgZWRpdGVkIG1lc3NhZ2UgaXMgc3VibWl0dGVkLCBhbGwgc3Vic2VxdWVudCBtZXNzYWdlcyBzdGFydGluZyBmcm9tIEBwYXJhbSBpbmRleCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgaGlzdG9yeSBhbmQgdGhlIFVJIHdpbGwgYmUgdXBkYXRlZCBhY2NvcmRpbmdseS5cbiAgICogVGhlIGFzc2lzdGFudCB3aWxsIHJlZ2VuZXJhdGUgYSBuZXcgYW5zd2VyIGJhc2VkIG9uIHRoZSB1cGRhdGVkIGNoYXQgaGlzdG9yeS5cbiAgICog4pqg77iPIElmIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgdXNlcidzIG1lc3NhZ2UgdG8gZWRpdFxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB1c2VyJ3MgbWVzc2FnZSB0byBlZGl0XG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIGVkaXRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlIHx8ICEhdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaW5kZXhNZXNzYWdlVG9FZGl0ID0gaW5kZXg7XG4gICAgdGhpcy5yYW5rTWVzc2FnZVRvRWRpdCA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG5cbiAgICAvLyBHZXQgdXNlciBtZXNzYWdlIGZyb20gYm90aCBsZWdhY3kgYW5kIHRleHQgbWVzc2FnZSB0eXBlXG4gICAgdGhpcy5xdWVzdGlvbiA9IHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQgPT09ICdzdHJpbmcnID8gbWVzc2FnZS5jb250ZW50IDogKG1lc3NhZ2UuY29udGVudFswXSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHQ7XG5cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWVkaXQuY2xpY2snLCB7J3JhbmsnOiB0aGlzLnJhbmtNZXNzYWdlVG9FZGl0LCAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkfSk7XG4gIH1cblxuICAvKipcbiAgICogQ29weSBhIHByZXZpb3VzIGFzc2lzdGFudCBtZXNzYWdlIG9mIHRoZSBjaGF0IGhpc3RvcnkgdG8gdGhlIGNsaXBib2FyZC5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gY29weVxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBtZXNzYWdlIHRvIGNvcHlcbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgY29weU1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICAvLyBSZW1hcCB0aGUgaW5kZXggaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtY29weS5jbGljaycsIHsgJ3JhbmsnOiByYW5rLCAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0aW5nIGZyb20gdGhlIHByb3ZpZGVkIGluZGV4LCByZW1vdmUgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5IGFuZCB0aGUgVUkgYWNjb3JkaW5nbHkuXG4gICAqIFRoZSBhc3Npc3RhbnQgd2lsbCByZWdlbmVyYXRlIGEgbmV3IGFuc3dlciBiYXNlZCBvbiB0aGUgdXBkYXRlZCBjaGF0IGhpc3RvcnkuXG4gICAqIOKaoO+4jyBJZiB0aGUgYXNzaXN0YW50IGlzIHN0cmVhbWluZyBvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGFzc2lzdGFudCdzIG1lc3NhZ2UgdG8gcmVnZW5lcmF0ZVxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhc3Npc3RhbnQncyBtZXNzYWdlIHRvIHJlZ2VuZXJhdGVcbiAgICovXG4gIHJlZ2VuZXJhdGVNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlIHx8ICEhdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFVwZGF0ZSB0aGUgbWVzc2FnZXMgaW4gdGhlIFVJIGJ5IHJlbW92aW5nIGFsbCBzdWJzZXF1ZW50ICdhc3Npc3RhbnQnIG1lc3NhZ2VzIHN0YXJ0aW5nIGZyb20gdGhlIHByb3ZpZGVkIGluZGV4IHVudGlsIHRoZSBmaXJzdCBwcmV2aW91cyAndXNlcicgbWVzc2FnZVxuICAgIGxldCBpID0gaW5kZXg7XG4gICAgd2hpbGUgKGkgPj0gMCAmJiAhKCh0aGlzLm1lc3NhZ2VzJC52YWx1ZSEpW2ldLnJvbGUgPT09ICd1c2VyJyAmJiAodGhpcy5tZXNzYWdlcyQudmFsdWUhKVtpXS5hZGRpdGlvbmFsUHJvcGVydGllcy5pc1VzZXJJbnB1dCA9PT0gdHJ1ZSkpIHtcbiAgICAgIGktLTtcbiAgICB9XG4gICAgLy8gSXQgc2hvdWxkIGFsd2F5cyBiZSB0aGUgY2FzZSB0aGF0IGkgPiAwXG4gICAgaWYgKGkgPj0gMCkge1xuICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZSEuc2xpY2UoMCwgaSArIDEpKTtcbiAgICAgIC8vIFJhbmsgb2YgdGhpcyBmb3VuZCBmaXJzdCBwcmV2aW91cyAndXNlcicgbWVzc2FnZSBpbiB0aGUgY2hhdCBoaXN0b3J5XG4gICAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICAgIC8vIERlZmluZSBhbmQgVXBkYXRlIHRoZSBjaGF0IGhpc3RvcnkgYmFzZWQgb24gd2hpY2ggdGhlIGFzc2lzdGFudCB3aWxsIGdlbmVyYXRlIGEgbmV3IGFuc3dlclxuICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLnNsaWNlKDAsIHJhbmspO1xuICAgICAgLy8gRmV0Y2ggdGhlIGFuc3dlclxuICAgICAgdGhpcy5mZXRjaCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtcmVnZW5lcmF0ZS5jbGljaycsIHsgJ3JhbmsnOiByYW5rLCAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBrZXkgdXAgZXZlbnQgZm9yICdCYWNrc3BhY2UnIGFuZCAnRW50ZXInIGtleXMuXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBrZXlib2FyZCBldmVudC5cbiAgICovXG4gIG9uS2V5VXAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQmFja3NwYWNlJzpcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVIZWlnaHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICAgIGlmICghZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMuc3VibWl0UXVlc3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbGN1bGF0ZUhlaWdodCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIGFuZCBhZGp1c3RzIHRoZSBoZWlnaHQgb2YgdGhlIHF1ZXN0aW9uIGlucHV0IGVsZW1lbnQgYmFzZWQgb24gaXRzIGNvbnRlbnQuXG4gICAqIElmIHRoZSBFbnRlciBrZXkgaXMgcHJlc3NlZCB3aXRob3V0IHRoZSBTaGlmdCBrZXksIGl0IHByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yLlxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIGtleWJvYXJkIGV2ZW50XG4gICAqL1xuICBjYWxjdWxhdGVIZWlnaHQoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50Py5rZXkgPT09ICdFbnRlcicgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gMTcwO1xuICAgIGNvbnN0IGVsID0gdGhpcy5xdWVzdGlvbklucHV0IS5uYXRpdmVFbGVtZW50O1xuICAgIGVsLnN0eWxlLm1heEhlaWdodCA9IGAke21heEhlaWdodH1weGA7XG4gICAgZWwuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9IGAke2VsLnNjcm9sbEhlaWdodH1weGA7XG4gICAgZWwuc3R5bGUub3ZlcmZsb3dZID0gZWwuc2Nyb2xsSGVpZ2h0ID49IG1heEhlaWdodCA/ICdzY3JvbGwnIDogJ2hpZGRlbic7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIFwibGlrZVwiIGV2ZW50IG9uIGNsaWNraW5nIG9uIHRoZSB0aHVtYi11cCBpY29uIG9mIGFuIGFzc2lzdGFudCdzIG1lc3NhZ2VcbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGFzc2lzdGFudCBtZXNzYWdlIHRvIGxpa2VcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZSB0byBsaWtlXG4gICAqL1xuICBvbkxpa2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBSZW1hcCB0aGUgaW5kZXggaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtdGh1bWItdXAuY2xpY2snLCB7ICdyYW5rJzogcmFuaywgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCB9KTtcbiAgICB0aGlzLnJlcG9ydFR5cGUgPSAnbGlrZSc7XG4gICAgdGhpcy5tZXNzYWdlVG9SZXBvcnQgPSBtZXNzYWdlO1xuICAgIHRoaXMucmVwb3J0Q29tbWVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlcG9ydFJhbmsgPSByYW5rO1xuICAgIHRoaXMuc2hvd1JlcG9ydCA9IHRydWVcblxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhW3JhbmstMV0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3VwZGF0ZUNoYXRIaXN0b3J5KCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIFwiZGlzbGlrZVwiIGV2ZW50IG9uIGNsaWNraW5nIG9uIHRoZSB0aHVtYi1kb3duIGljb24gb2YgYW4gYXNzaXN0YW50J3MgbWVzc2FnZS5cbiAgICogSXQgYWxzbyBvcGVucyB0aGUgaXNzdWUgcmVwb3J0aW5nIGRpYWxvZy5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGFzc2lzdGFudCBtZXNzYWdlIHRvIGRpc2xpa2VcbiAgICogQHBhcmFtIGluZGV4IFRoZSByYW5rIG9mIHRoZSBtZXNzYWdlIHRvIGRpc2xpa2VcbiAgICovXG4gIG9uRGlzbGlrZShtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIFJlbWFwIHRoZSBpbmRleCBpbiB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC10aHVtYi1kb3duLmNsaWNrJywgeyAncmFuayc6IHJhbmssICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQgfSk7XG4gICAgdGhpcy5yZXBvcnRUeXBlID0gJ2Rpc2xpa2UnO1xuICAgIHRoaXMubWVzc2FnZVRvUmVwb3J0ID0gbWVzc2FnZTtcbiAgICB0aGlzLmlzc3VlVHlwZSA9ICcnO1xuICAgIHRoaXMucmVwb3J0Q29tbWVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlcG9ydFJhbmsgPSByYW5rO1xuICAgIHRoaXMuc2hvd1JlcG9ydCA9IHRydWVcblxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhW3JhbmstMV0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3VwZGF0ZUNoYXRIaXN0b3J5KCk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVDaGF0SGlzdG9yeSgpOiB2b2lkIHtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkKSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLnVwZGF0ZVNhdmVkQ2hhdCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRJZCwgdW5kZWZpbmVkLCB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcG9ydCBhbiBpc3N1ZSByZWxhdGVkIHRvIHRoZSBhc3Npc3RhbnQncyBtZXNzYWdlLlxuICAgKi9cbiAgc2VuZFJlcG9ydCgpOiB2b2lkIHtcbiAgICBjb25zdCBkZXRhaWxzID0ge1xuICAgICAgJ2NvbW1lbnQnOiB0aGlzLnJlcG9ydENvbW1lbnQsXG4gICAgICAncmFuayc6IHRoaXMucmVwb3J0UmFua1xuICAgIH07XG5cbiAgICAvL2NoZWNrIGlmIHRoZSBtZXNzYWdlIHRvIHJlcG9ydCBpcyBkZWZpbmVkLiBJdCBzaG91bGQgYWx3YXlzIGJlIHRoZSBjYXNlXG4gICAgaWYgKHRoaXMubWVzc2FnZVRvUmVwb3J0KSB7XG4gICAgICBkZXRhaWxzWydtZXNzYWdlLWlkJ10gPSB0aGlzLm1lc3NhZ2VUb1JlcG9ydC5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQ7XG4gICAgfVxuXG4gICAgLy8gaGlkZSB0ZXh0IGluIGNhc2UgbG9nQ29udGVudCBpcyBub3QgZW5hYmxlZFxuICAgIGlmICh0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzLmxvZ0NvbnRlbnQpXG4gICAgICBkZXRhaWxzWyd0ZXh0J10gPSB0aGlzLm1lc3NhZ2VUb1JlcG9ydCEuY29udGVudDtcblxuICAgIGlmICh0aGlzLnJlcG9ydFR5cGUgPT09ICdkaXNsaWtlJykge1xuICAgICAgZGV0YWlsc1sncmVwb3J0LXR5cGUnXSA9IHRoaXMuaXNzdWVUeXBlO1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1uZWdhdGl2ZS1yZXBvcnQuc2VuZCcsIGRldGFpbHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LXBvc2l0aXZlLXJlcG9ydC5zZW5kJywgZGV0YWlscyk7XG4gICAgfVxuICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2Uuc3VjY2Vzcyh0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUoJ2NoYXQuc2VuZFJlcG9ydE5vdGlmaWNhdGlvbicpKTtcbiAgICB0aGlzLnNob3dSZXBvcnQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgcmVwb3J0aW5nIGRpYWxvZy5cbiAgICovXG4gIGlnbm9yZVJlcG9ydCgpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dSZXBvcnQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIGNsaWNrIG9uIGEgcmVmZXJlbmNlJ3MgJ29wZW4gcHJldmlldycuXG4gICAqIEBwYXJhbSBkYXRhXG4gICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHJlZmVyZW5jZVxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgcmVmZXJlbmNlXG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIG9wZW5BdHRhY2htZW50UHJldmlldyhkYXRhOiB7IHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIgfSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoZGF0YS5yZWZlcmVuY2UpO1xuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAnZG9jLWlkJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkSWQsXG4gICAgICAnc291cmNlJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLnRyZWVwYXRoLFxuICAgICAgJ2NvbGxlY3Rpb24nOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQuY29sbGVjdGlvbixcbiAgICAgICdpbmRleCc6IGRhdGEucmVmZXJlbmNlLnJlY29yZC5kYXRhYmFzZWFsaWFzLFxuICAgICAgJ3JhbmsnOiByYW5rLFxuICAgICAgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZFxuICAgIH07XG4gICAgaWYgKCEhZGF0YS5wYXJ0SWQpIGRldGFpbHNbJ3BhcnQtaWQnXSA9IGRhdGEucGFydElkO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtYXR0YWNobWVudC5wcmV2aWV3LmNsaWNrJywgZGV0YWlscyk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBjbGljayBvbiBhIHJlZmVyZW5jZSdzICdvcGVuIG9yaWdpbmFsIGRvY3VtZW50Jy5cbiAgICogQHBhcmFtIGRhdGFcbiAgICogQHBhcmFtIG1lc3NhZ2UgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgcmVmZXJlbmNlXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0aGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSByZWZlcmVuY2VcbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgb3Blbk9yaWdpbmFsQXR0YWNobWVudChkYXRhOiB7IHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIgfSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5Eb2N1bWVudC5lbWl0KGRhdGEucmVmZXJlbmNlLnJlY29yZCk7XG4gICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICdkb2MtaWQnOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmRJZCxcbiAgICAgICdzb3VyY2UnOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQudHJlZXBhdGgsXG4gICAgICAnY29sbGVjdGlvbic6IGRhdGEucmVmZXJlbmNlLnJlY29yZC5jb2xsZWN0aW9uLFxuICAgICAgJ2luZGV4JzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLmRhdGFiYXNlYWxpYXMsXG4gICAgICAncmFuayc6IHJhbmssXG4gICAgICAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkXG4gICAgfTtcbiAgICBpZiAoISFkYXRhLnBhcnRJZCkgZGV0YWlsc1sncGFydC1pZCddID0gZGF0YS5wYXJ0SWQ7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1hdHRhY2htZW50LmxpbmsuY2xpY2snLCBkZXRhaWxzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIGNsaWNrIG9uIGEgc3VnZ2VzdGVkIGFjdGlvbi5cbiAgICogQHBhcmFtIGFjdGlvbiBTdWdnZXN0ZWQgYWN0aW9uLlxuICAgKiBAcGFyYW0gaW5kZXggUmFuayBvZiB0aGUgbWVzc2FnZSBpbiB0aGUgY2hhdEhpc3RvcnkgcmVsYXRlZCB0byB0aGUgc3VnZ2VzdGVkIGFjdGlvbi5cbiAgICovXG4gIHN1Z2dlc3RBY3Rpb25DbGljayhhY3Rpb246IFN1Z2dlc3RlZEFjdGlvbiwgaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuc3VnZ2VzdEFjdGlvbi5lbWl0KGFjdGlvbik7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1zdWdnZXN0ZWQtYWN0aW9uLmNsaWNrJywgeyd0ZXh0JzogYWN0aW9uLmNvbnRlbnQsICdzdWdnZXN0ZWRBY3Rpb24tdHlwZSc6IGFjdGlvbi50eXBlfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBJdCBsb29rcyBmb3IgdGhlIGRlYnVnIG1lc3NhZ2VzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBncm91cCBvZiBcImFzc2lzdGFudFwiIG1lc3NhZ2VzLlxuICAgKiBCeSBkZXNpZ24sIHRoZSBkZWJ1ZyBtZXNzYWdlcyBhcmUgb25seSBhdmFpbGFibGUgaW4gdGhlIGZpcnN0IHZpc2libGUgbWVzc2FnZSBhbW9uZyB0aGUgZ3JvdXAgb2YgXCJhc3Npc3RhbnRcIiBtZXNzYWdlcy5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgZGVidWcgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZVxuICAgKiBAcmV0dXJucyBUaGUgZGVidWcgbWVzc2FnZXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGdyb3VwIG9mIFwiYXNzaXN0YW50XCIgbWVzc2FnZXNcbiAgICovXG4gIGdldERlYnVnTWVzc2FnZXMobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpOiBEZWJ1Z01lc3NhZ2VbXSB7XG4gICAgLy8gSWYgaXQgaXMgbm90IGFuIGFzc2lzdGFudCBtZXNzYWdlLCByZXR1cm4gYW4gZW1wdHkgYXJyYXlcbiAgICBpZiAobWVzc2FnZS5yb2xlICE9PSAnYXNzaXN0YW50Jykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvLyBHZXQgdGhlIGFycmF5IG9mIG1lc3NhZ2VzIHVwIHRvIHRoZSBpbmRpY2F0ZWQgaW5kZXhcbiAgICBjb25zdCBhcnJheSA9IHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCBpbmRleCArIDEpO1xuICAgIC8vIElmIGl0IGlzIGFuIGFzc2lzdGFudCBtZXNzYWdlLCBsb29rIGZvciB0aGUgZGVidWcgbWVzc2FnZXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGdyb3VwIG9mIFwiYXNzaXN0YW50XCIgbWVzc2FnZXNcbiAgICAvLyBCeSBkZXNpZ24sIHRoZSBkZWJ1ZyBtZXNzYWdlcyBhcmUgb25seSBhdmFpbGFibGUgaW4gdGhlIGZpcnN0IHZpc2libGUgbWVzc2FnZSBhbW9uZyB0aGUgZ3JvdXAgXCJhc3Npc3RhbnRcIiBtZXNzYWdlcy5cbiAgICBjb25zdCBpZHggPSB0aGlzLmFzc2lzdGFudFV0aWxzLmZpcnN0VmlzaWJsZUFzc2lzdGFudE1lc3NhZ2VJbmRleChhcnJheSk7XG4gICAgaWYgKGlkeCA+IC0xKSB7XG4gICAgICByZXR1cm4gKHRoaXMubWVzc2FnZXMkLnZhbHVlISlbaWR4XS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGVidWcgfHwgW107XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIGNsaWNrIG9uIHRoZSAnc2hvdyBsb2cgaW5mbycgYnV0dG9uIG9mIGEgbWVzc2FnZS5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgZGVidWcgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZVxuICAgKi9cbiAgc2hvd0RlYnVnKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kZWJ1Z01lc3NhZ2VzID0gdGhpcy5nZXREZWJ1Z01lc3NhZ2VzKG1lc3NhZ2UsIGluZGV4KTtcbiAgICB0aGlzLnNob3dEZWJ1Z01lc3NhZ2VzID0gdHJ1ZTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHdoZXRoZXIgdGhlIGN1cnJlbnQgbWVzc2FnZSBpcyBhbiBhc3Npc3RhbnQgbWVzc2FnZSBhbmQgdGhhdCBhbGwgZm9sbG93aW5nIG1lc3NhZ2VzIGFyZSBhc3Npc3RhbnQgb25lc1xuICAgKiBVc2VkIHRvIGtlZXAgdGhlIFwiVmlldyBwcm9ncmVzc1wiIG9wZW5lZCBldmVuIHRob3VnaCB0aGUgYXNzaXN0YW50IGlzIHNlbmRpbmcgYWRkaXRpb25hbCBtZXNzYWdlcyBhZnRlciB0aGUgY3VycmVudCBvbmVcbiAgICogQHBhcmFtIG1lc3NhZ2VzIHRoZSBsaXN0IG9mIGN1cnJlbnQgbWVzc2FnZXNcbiAgICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBtZXNzYWdlXG4gICAqIEByZXR1cm5zIGlmIHRoaXMgbWVzc2FnZXMgYW5kIHRoZSBmb2xsb3dpbmcgb25lcyAoaWYgYW55KSBhcmUgdGhlIGxhc3Qgb25lc1xuICAgKi9cbiAgaXNBc3Npc3RhbnRMYXN0TWVzc2FnZXMobWVzc2FnZXM6IENoYXRNZXNzYWdlW10sIGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPCBtZXNzYWdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1lc3NhZ2VzW2ldLnJvbGUgIT09ICdhc3Npc3RhbnQnKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbWVzc2FnZSBpcyBhbiBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZS5cbiAgICogQW4gZW1wdHkgYXNzaXN0YW50IG1lc3NhZ2UgaXMgZGVmaW5lZCBhcyBhIG1lc3NhZ2Ugd2l0aCB0aGUgcm9sZSAnYXNzaXN0YW50JyxcbiAgICogYW4gZW1wdHkgY29udGVudCwgYW5kIG5vIGFkZGl0aW9uYWwgcHJvcGVydGllcyBzdWNoIGFzIGF0dGFjaG1lbnRzLCBwcm9ncmVzcyxcbiAgICogZGVidWcgaW5mb3JtYXRpb24sIG9yIHN1Z2dlc3RlZCBhY3Rpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG1lc3NhZ2UgaXMgYW4gZW1wdHkgYXNzaXN0YW50IG1lc3NhZ2UsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNFbXB0eUFzc2lzdGFudE1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoXG4gICAgICBtZXNzYWdlPy5yb2xlID09PSAnYXNzaXN0YW50J1xuICAgICAgJiYgKFxuICAgICAgICAvLyBMZWdhY3kgbWVzc2FnZSB0eXBlXG4gICAgICAgICh0eXBlb2YgbWVzc2FnZT8uY29udGVudCA9PT0gJ3N0cmluZycgJiYgbWVzc2FnZT8uY29udGVudCA9PT0gXCJcIilcbiAgICAgICAgLy8gTmV3IG1lc3NhZ2UgdHlwZVxuICAgICAgICAvLyAtIFRleHRcbiAgICAgICAgfHwgKChtZXNzYWdlPy5jb250ZW50IGFzIFJhd01lc3NhZ2VDb250ZW50KT8uWzBdIGFzIFRleHRNZXNzYWdlQ29udGVudCk/LnRleHQgPT09IFwiXCJcbiAgICAgICAgLy8gVE9ETzogaW1hZ2UgYW5kIHZpZGVvIG1lc3NhZ2UgdHlwZXMgaHR0cHM6Ly9zaW5lcXVhLmF0bGFzc2lhbi5uZXQvYnJvd3NlL0VTLTI1OTQwXG4gICAgICApXG4gICAgICAmJiAhbWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXM/LiRhdHRhY2htZW50XG4gICAgICAmJiAhbWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXM/LiRwcm9ncmVzc1xuICAgICAgJiYgIW1lc3NhZ2U/LmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy4kZGVidWdcbiAgICAgICYmICFtZXNzYWdlPy5hZGRpdGlvbmFsUHJvcGVydGllcz8uJHN1Z2dlc3RlZEFjdGlvblxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpbml0aWFsaXphdGlvbkVycm9yXCI+XG4gIDxkaXYgKm5nSWY9XCJtZXNzYWdlcyQgfCBhc3luYyBhcyBtZXNzYWdlczsgZWxzZSBsb2FkaW5nVHBsIHx8IGxvYWRpbmdUcGxEZWZhdWx0XCIgY2xhc3M9XCJoLTEwMCBkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICA8IS0tIFRva2VuIGNvbnN1bXB0aW9uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtcy0xXCIgKm5nSWY9XCJjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNwbGF5VXNlclF1b3RhQ29uc3VtcHRpb24gfHwgY29uZmlnPy5nbG9iYWxTZXR0aW5ncz8uZGlzcGxheUNoYXRUb2tlbnNDb25zdW1wdGlvblwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRva2VuQ29uc3VtcHRpb25UcGwgfHwgZGVmYXVsdFRva2VuQ29uc3VtcHRpb25UcGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBpbnN0YW5jZUlkIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gQ2hhdCBNZXNzYWdlcyAtLT5cbiAgICA8dWwgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW4gbGlzdC11bnN0eWxlZCBnYXAtMyBvdmVyZmxvdy1hdXRvIGZsZXgtZ3Jvdy0xIHBlLTIgcGItMlwiICNtZXNzYWdlTGlzdD5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IG1lc3NhZ2Ugb2YgbWVzc2FnZXM7IGxldCBpbmRleCA9IGluZGV4OyBsZXQgbGFzdCA9IGxhc3RcIj5cbiAgICAgICAgPCEtLSBSZWd1bGFyIG1lc3NhZ2VzIC0tPlxuICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW1cIlxuICAgICAgICAgICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5kaXNwbGF5ICYmICFpc0VtcHR5QXNzaXN0YW50TWVzc2FnZShtZXNzYWdlKVwiXG4gICAgICAgICAgW3N0eWxlLi0tYnMtbGlzdC1ncm91cC1pdGVtLXBhZGRpbmcteS5yZW1dPVwiJzAuNidcIlxuICAgICAgICAgIFtjbGFzcy5vcGFjaXR5LTUwXT1cImluZGV4TWVzc2FnZVRvRWRpdCAmJiAoaW5kZXhNZXNzYWdlVG9FZGl0IDwgKGluZGV4ICsgMSkpXCI+XG4gICAgICAgICAgPHNxLWNoYXQtbWVzc2FnZVxuICAgICAgICAgICAgW2NsYXNzLnNxLXVzZXItbWVzc2FnZV09XCJtZXNzYWdlLnJvbGUgPT09ICd1c2VyJ1wiXG4gICAgICAgICAgICBbY2xhc3MubGFzdC1tZXNzYWdlXT1cImxhc3RcIlxuICAgICAgICAgICAgW21lc3NhZ2VdPVwibWVzc2FnZVwiXG4gICAgICAgICAgICBbY29udmVyc2F0aW9uXT1cIm1lc3NhZ2VzXCJcbiAgICAgICAgICAgIFtzdWdnZXN0ZWRBY3Rpb25zXT1cImxhc3QgPyBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRzdWdnZXN0ZWRBY3Rpb24gOiB1bmRlZmluZWRcIlxuICAgICAgICAgICAgW2Fzc2lzdGFudE1lc3NhZ2VJY29uXT1cImFzc2lzdGFudE1lc3NhZ2VJY29uXCJcbiAgICAgICAgICAgIFt1c2VyTWVzc2FnZUljb25dPVwidXNlck1lc3NhZ2VJY29uXCJcbiAgICAgICAgICAgIFtjb25uZWN0aW9uRXJyb3JNZXNzYWdlSWNvbl09XCJjb25uZWN0aW9uRXJyb3JNZXNzYWdlSWNvblwiXG4gICAgICAgICAgICBbc2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXT1cInNlYXJjaFdhcm5pbmdNZXNzYWdlSWNvblwiXG4gICAgICAgICAgICBbc3RyZWFtaW5nXT1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpICYmIChsYXN0IHx8IGlzQXNzaXN0YW50TGFzdE1lc3NhZ2VzKG1lc3NhZ2VzLCBpbmRleCkpXCJcbiAgICAgICAgICAgIFtjYW5FZGl0XT1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSAmJiBpbmRleE1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgPT09ICd1c2VyJ1wiXG4gICAgICAgICAgICBbY2FuQ29weV09XCIoKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlIHx8ICFsYXN0KSAmJiBpbmRleE1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLnJvbGUgIT09ICdjb25uZWN0aW9uLWVycm9yJyAmJiBtZXNzYWdlLnJvbGUgIT09ICdzZWFyY2gtd2FybmluZydcIlxuICAgICAgICAgICAgW2Nhbkxpa2VdPVwiKChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSB8fCAhbGFzdCkgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50J1wiXG4gICAgICAgICAgICBbY2FuRGlzbGlrZV09XCIoKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlIHx8ICFsYXN0KSAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFtjYW5EZWJ1Z109XCIoKChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSAmJiBsYXN0KSB8fCAoIWxhc3QgJiYgbWVzc2FnZXNbaW5kZXgrMV0ucm9sZSAhPT0gJ2Fzc2lzdGFudCcpKSAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIChnZXREZWJ1Z01lc3NhZ2VzKG1lc3NhZ2UsIGluZGV4KS5sZW5ndGggPiAwKSAmJiAoKGlzQWRtaW5PckRlbGV0ZWRBZG1pbiB8fCAoY2hhdFNlcnZpY2UudXNlck92ZXJyaWRlJCB8IGFzeW5jKSkgJiYgY29uZmlnPy5kZWZhdWx0VmFsdWVzLmRlYnVnKVwiXG4gICAgICAgICAgICBbY2FuUmVnZW5lcmF0ZV09XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgICYmIChsYXN0IHx8ICghbGFzdCAmJiBtZXNzYWdlc1tpbmRleCsxXS5yb2xlICE9PSAnYXNzaXN0YW50JykpICAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIGluZGV4TWVzc2FnZVRvRWRpdCA9PT0gdW5kZWZpbmVkXCJcbiAgICAgICAgICAgIChlZGl0KT1cImVkaXRNZXNzYWdlKG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAoY29weSk9XCJjb3B5TWVzc2FnZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKHJlZ2VuZXJhdGUpPVwicmVnZW5lcmF0ZU1lc3NhZ2UobWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsIG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAob3BlblByZXZpZXcpPVwib3BlbkF0dGFjaG1lbnRQcmV2aWV3KCRldmVudCwgbWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChzdWdnZXN0QWN0aW9uKT1cInN1Z2dlc3RBY3Rpb25DbGljaygkZXZlbnQsIGluZGV4KVwiXG4gICAgICAgICAgICAobGlrZSk9XCJvbkxpa2UobWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChkaXNsaWtlKT1cIm9uRGlzbGlrZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKGRlYnVnKT1cInNob3dEZWJ1ZyhtZXNzYWdlLCBpbmRleClcIj5cbiAgICAgICAgICA8L3NxLWNoYXQtbWVzc2FnZT5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPCEtLSBMb2FkaW5nIHNwaW5uZXIgLS0+XG4gICAgICA8bGkgKm5nSWY9XCIobG9hZGluZyQgfCBhc3luYykgPT09IHRydWVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvYWRpbmdUcGwgfHwgbG9hZGluZ1RwbERlZmF1bHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbGk+XG4gICAgPC91bD5cblxuICAgIDwhLS0gUmVwb3J0aW5nIGEgZmVlZGJhY2sgZm9ybSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiaXNzdWUtcmVwb3J0IHAtMyByb3VuZGVkLWxnXCIgKm5nSWY9XCJzaG93UmVwb3J0XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicmVwb3J0VHBsIHx8IHJlcG9ydFRwbERlZmF1bHQ7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBtZXNzYWdlVG9SZXBvcnQsIHJhbms6IHJlcG9ydFJhbmssIHR5cGU6IHJlcG9ydFR5cGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBVc2VyIHRleHQgaW5wdXQgLS0+XG4gICAgQGlmICghc2hvd1JlcG9ydCkge1xuICAgICAgPGRpdiBjbGFzcz1cInVzZXItaW5wdXQgbXQtYXV0b1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgIDxkaXYgW2hpZGRlbl09XCIhaXNDb25uZWN0ZWRcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlbmFibGVkVXNlcklucHV0XCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW5wdXRUcGxcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8IS0tIFJldHJ5IGJ1dHRvbiAtLT5cbiAgICAgICAgICA8IS0tIGhpZGRlbiBhdHRyaWJ1dGUgaXMgaW4gY29uZmxpY3Qgd2l0aCBhIGNzcyBydWxlIGRpc3BsYXk6IGZsZXggLS0+XG4gICAgICAgICAgQGlmKCFpc0Nvbm5lY3RlZCl7XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIG1iLTQgYXN0LWVycm9yIGFzdC1idG4gc3EtcmV0cnlcIiAoY2xpY2spPVwicmV0cnlGZXRjaCgpXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7ICdjaGF0LnRyeUFnYWluJyB8IHRyYW5zbG9jbyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJyZXRyaWFsQXR0ZW1wdHNcIiBjbGFzcz1cIm1zLTIgYXR0ZW1wdHNcIj57eyByZXRyaWFsQXR0ZW1wdHMgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtZW5kIHNtYWxsIHRleHQtbXV0ZWQgcHgtM1wiICpuZ0lmPVwiISFjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyXCI+XG4gICAgICAgICAgICB7eyBjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyIHwgdHJhbnNsb2NvIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSBGbG9hdGluZyBzY3JvbGwgYnV0dG9uIC0tPlxuICAgIDxkaXYgKm5nSWY9XCIhaXNBdEJvdHRvbSAmJiAhc2hvd1JlcG9ydFwiIGNsYXNzPVwic3EtZmxvYXRpbmctc2Nyb2xsXCIgW25nQ2xhc3NdPVwiZW5hYmxlZFVzZXJJbnB1dCA/ICdzcS1mbG9hdGluZy1zY3JvbGwtLXdoZW4tdXNlci1pbnB1dCcgOiAnc3EtZmxvYXRpbmctc2Nyb2xsLS13aXRob3V0LXVzZXItaW5wdXQnXCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNoYWRvd1wiIChjbGljayk9XCJzY3JvbGxEb3duKClcIiBhcmlhLWxhYmVsPVwiU2Nyb2xsIGRvd25cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtYW5nbGUtZG91YmxlLWRvd25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuPCEtLSBORyBURU1QTEFURVMtLT5cblxuPG5nLXRlbXBsYXRlICNsb2FkaW5nVHBsRGVmYXVsdD5cbiAgPGRpdiBjbGFzcz1cInNwaW5uZXItZ3JvdyB0ZXh0LXByaW1hcnkgZC1ibG9jayBteC1hdXRvIG15LTVcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eyAnY2hhdC5sb2FkaW5nJyB8IHRyYW5zbG9jbyB9fTwvc3Bhbj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2lucHV0VHBsPlxuICA8ZGl2IGNsYXNzPVwicHgtMyBweS0xXCI+XG4gICAgPGRpdiBjbGFzcz1cImFzdC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgIDxidXR0b24gZGlzYWJsZWQgY2xhc3M9XCJidG4gYnRuLWxpZ2h0XCIgYXJpYS1sYWJlbD1cInNlYXJjaFwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zZWFyY2hcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDx0ZXh0YXJlYSAjcXVlc3Rpb25JbnB1dCByb3dzPVwiMVwiXG4gICAgICAgIHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ2NoYXQuYXNrU29tZXRoaW5nJyB8IHRyYW5zbG9jb1wiIGF1dG9mb2N1c1xuICAgICAgICBbKG5nTW9kZWwpXT1cInF1ZXN0aW9uXCJcbiAgICAgICAgKGtleXVwKT1cIm9uS2V5VXAoJGV2ZW50KVwiXG4gICAgICAgIChrZXlkb3duKT1cImNhbGN1bGF0ZUhlaWdodCgkZXZlbnQpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIihsb2FkaW5nJCB8IGFzeW5jKSB8fCAoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSB8fCAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKVwiPlxuICAgICAgPC90ZXh0YXJlYT5cbiAgICAgIDxkaXYgaWQ9XCJjaGF0LWFjdGlvbnNcIiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGxvYWRpbmckIHwgYXN5bmMpID09PSBmYWxzZSAmJiAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKSA9PT0gZmFsc2VcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbmQgbWVzc2FnZVwiXG4gICAgICAgICAgW3NxVG9vbHRpcF09XCInY2hhdC5zZW5kTWVzc2FnZScgfCB0cmFuc2xvY29cIlxuICAgICAgICAgIChjbGljayk9XCJzdWJtaXRRdWVzdGlvbigpXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtcGFwZXItcGxhbmVcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCJpbmRleE1lc3NhZ2VUb0VkaXRcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJDYW5jZWwgZWRpdGlvblwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxpZ2h0XCJcbiAgICAgICAgICBbc3FUb29sdGlwXT1cIidjaGF0LmNhbmNlbEVkaXRpb24nIHwgdHJhbnNsb2NvXCJcbiAgICAgICAgICAoY2xpY2spPVwiaW5kZXhNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkOyBxdWVzdGlvbiA9ICcnXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtdW5kby1hbHRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpICYmIChjaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kIHwgYXN5bmMpID09PSBmYWxzZVwiIGNsYXNzPVwicHJvY2Vzc2luZ1wiPlxuICAgICAgICAgIHt7ICdjaGF0LmdlbmVyYXRpbmcnIHwgdHJhbnNsb2NvIH19PGkgY2xhc3M9XCJmYXMgZmEtc3Bpbm5lciBmYS1wdWxzZVwiPjwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIihjaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kIHwgYXN5bmMpXCIgY2xhc3M9XCJwcm9jZXNzaW5nXCI+XG4gICAgICAgICAge3sgJ2NoYXQuc3RvcHBpbmcnIHwgdHJhbnNsb2NvIH19PGkgY2xhc3M9XCJmYXMgZmEtc3Bpbm5lciBmYS1wdWxzZVwiPjwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSAmJiAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKSA9PT0gZmFsc2VcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlN0b3AgZ2VuZXJhdGluZ1wiXG4gICAgICAgICAgW3NxVG9vbHRpcF09XCInY2hhdC5zdG9wR2VuZXJhdGlvbicgfCB0cmFuc2xvY29cIlxuICAgICAgICAgIChjbGljayk9XCJzdG9wR2VuZXJhdGlvbigpXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3RvcFwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3JlcG9ydFRwbERlZmF1bHQgbGV0LW1lc3NhZ2UgbGV0LXJhbms9XCJyYW5rXCIgbGV0LXR5cGU9XCJ0eXBlXCI+XG4gIDxkaXYgY2xhc3M9XCJweC0zXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInR5cGUgPT09ICdkaXNsaWtlJ1wiPlxuICAgICAgPGg1Pnt7ICdjaGF0Lmlzc3VlVHlwZScgfCB0cmFuc2xvY28gfX08L2g1PlxuICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0IG1iLTRcIiBbKG5nTW9kZWwpXT1cImlzc3VlVHlwZVwiPlxuICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCInJ1wiPnt7ICdjaGF0LmNob29zZUlzc3VlVHlwZScgfCB0cmFuc2xvY28gfX08L29wdGlvbj5cbiAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgdHlwZSBvZiAoaXNzdWVUeXBlcyA/PyBkZWZhdWx0SXNzdWVUeXBlcylcIiBbdmFsdWVdPVwidHlwZVwiPnt7IHR5cGUgfCB0cmFuc2xvY28gfX08L29wdGlvbj5cbiAgICAgIDwvc2VsZWN0PlxuICAgICAgPGg1Pnt7ICdjaGF0LmFza1VubGlrZVJlYXNvbnMnIHwgdHJhbnNsb2NvIH19PC9oNT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidHlwZSA9PT0gJ2xpa2UnXCI+XG4gICAgICA8aDU+e3sgJ2NoYXQuYXNrTGlrZVJlYXNvbnMnIHwgdHJhbnNsb2NvIH19PC9oNT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYm9yZGVyIGJvcmRlci1uZXV0cmFsLTIwMFwiIFsobmdNb2RlbCldPVwicmVwb3J0Q29tbWVudFwiIFtwbGFjZWhvbGRlcl09XCInY2hhdC53cml0ZUNvbW1lbnQnIHwgdHJhbnNsb2NvXCI+PC90ZXh0YXJlYT5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93LXJldmVyc2UgZ2FwLTEgbXQtMlwiPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIFtkaXNhYmxlZF09XCJ0eXBlID09PSAnZGlzbGlrZScgJiYgIWlzc3VlVHlwZVwiIChjbGljayk9XCJzZW5kUmVwb3J0KClcIj57eyAnY2hhdC5zZW5kJyB8IHRyYW5zbG9jbyB9fTwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGlnaHRcIiAoY2xpY2spPVwiaWdub3JlUmVwb3J0KClcIj57eyAnY2hhdC5kb05vdFNlbmQnIHwgdHJhbnNsb2NvIH19PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNkZWZhdWx0VG9rZW5Db25zdW1wdGlvblRwbCBsZXQtaW5zdGFuY2VJZD5cbiAgPHNxLXRva2VuLXByb2dyZXNzLWJhclxuICAgIFtpbnN0YW5jZUlkXT1cImluc3RhbmNlSWRcIj5cbiAgPC9zcS10b2tlbi1wcm9ncmVzcy1iYXI+XG48L25nLXRlbXBsYXRlPlxuXG48ZGl2IGNsYXNzPVwiZGVidWctbWVzc2FnZXNcIiBbY2xhc3MuZGlzcGxheWVkXT1cInNob3dEZWJ1Z01lc3NhZ2VzXCI+XG4gIDxidXR0b24gKm5nSWY9XCJzaG93RGVidWdNZXNzYWdlc1wiIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBzaGFkb3cgYmFjay1idG5cIiAoY2xpY2spPVwic2hvd0RlYnVnTWVzc2FnZXM9ZmFsc2VcIiBhcmlhLWxhYmVsPVwiSGlkZSBkZWJ1ZyBtZXNzYWdlc1wiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZXZyb24tcmlnaHRcIj48L2k+XG4gIDwvYnV0dG9uPlxuICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVidWdNZXNzYWdlc1RwbCB8fCBkZWZhdWx0RGVidWdNZXNzYWdlc1RwbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGRlYnVnTWVzc2FnZXMgfVwiPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2RlZmF1bHREZWJ1Z01lc3NhZ2VzVHBsIGxldC1kZWJ1Z01lc3NhZ2VzPlxuICA8c3EtZGVidWctbWVzc2FnZSBbZGF0YV09XCJkZWJ1Z01lc3NhZ2VzXCI+PC9zcS1kZWJ1Zy1tZXNzYWdlPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|
|
1101
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQWdDLE1BQU0sRUFBOEIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxTixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVGLE9BQU8sRUFBaUIsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXhILE9BQU8sRUFBbUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUxRyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDaEYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNEJBQTRCLENB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UTtnQkFDTixJQUFJO3NCQUFiLE1BQU07Z0JBRUcsWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNO2dCQUVHLGFBQWE7c0JBQXRCLE1BQU07Z0JBRW1CLFdBQVc7c0JBQXBDLFNBQVM7dUJBQUMsYUFBYTtnQkFDSSxhQUFhO3NCQUF4QyxTQUFTO3VCQUFDLGVBQWU7Z0JBRUUsVUFBVTtzQkFBckMsWUFBWTt1QkFBQyxZQUFZO2dCQUNDLFNBQVM7c0JBQW5DLFlBQVk7dUJBQUMsV0FBVztnQkFDWSxtQkFBbUI7c0JBQXZELFlBQVk7dUJBQUMscUJBQXFCO2dCQUNELGdCQUFnQjtzQkFBakQsWUFBWTt1QkFBQyxrQkFBa0I7Z0JBRXZCLFNBQVM7c0JBQWpCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgQ29udGVudENoaWxkLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQsIGluamVjdCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgVHJhbnNsb2NvUGlwZSwgVHJhbnNsb2NvU2VydmljZSwgcHJvdmlkZVRyYW5zbG9jb1Njb3BlIH0gZnJvbSAnQGpzdmVyc2UvdHJhbnNsb2NvJztcbmltcG9ydCB7IEh1YkNvbm5lY3Rpb24sIEh1YkNvbm5lY3Rpb25TdGF0ZSB9IGZyb20gXCJAbWljcm9zb2Z0L3NpZ25hbHJcIjtcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBjb21iaW5lTGF0ZXN0LCBmaWx0ZXIsIGZyb21FdmVudCwgbWVyZ2UsIG9mLCBzd2l0Y2hNYXAsIHRha2UsIHRhcCB9IGZyb20gXCJyeGpzXCI7XG5cbmltcG9ydCB7IEFwcEdsb2JhbENvbmZpZywgQXJ0aWNsZSwgUXVlcnksIGd1aWQsIGlzQXV0aGVudGljYXRlZCwgc2V0R2xvYmFsQ29uZmlnIH0gZnJvbSBcIkBzaW5lcXVhL2F0b21pY1wiO1xuXG5pbXBvcnQgeyBDaGF0TWVzc2FnZUNvbXBvbmVudCB9IGZyb20gXCIuL2NoYXQtbWVzc2FnZS9jaGF0LW1lc3NhZ2UuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBDaGF0U2VydmljZSB9IGZyb20gXCIuL2NoYXQuc2VydmljZVwiO1xuaW1wb3J0IHsgRGVidWdNZXNzYWdlQ29tcG9uZW50IH0gZnJvbSBcIi4vZGVidWctbWVzc2FnZS9kZWJ1Zy1tZXNzYWdlLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgSW5zdGFuY2VNYW5hZ2VyU2VydmljZSB9IGZyb20gXCIuL2luc3RhbmNlLW1hbmFnZXIuc2VydmljZVwiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uc1NlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9ub3RpZmljYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL3ByaW5jaXBhbC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBTZWFyY2hTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvc2VhcmNoLnNlcnZpY2VcIjtcbmltcG9ydCB7IFRva2VuUHJvZ3Jlc3NCYXJDb21wb25lbnQgfSBmcm9tIFwiLi90b2tlbi1wcm9ncmVzcy1iYXIvdG9rZW4tcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgVG9vbHRpcERpcmVjdGl2ZSB9IGZyb20gXCIuL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmVcIjtcbmltcG9ydCB7IENoYXRDb25maWcsIENoYXRDb250ZXh0QXR0YWNobWVudCwgQ2hhdE1lc3NhZ2UsIERlYnVnTWVzc2FnZSwgR2xsbU1vZGVsRGVzY3JpcHRpb24sIEluaXRDaGF0LCBNZXNzYWdlSGFuZGxlciwgUmF3TWVzc2FnZSwgU3VnZ2VzdGVkQWN0aW9uIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFJhd01lc3NhZ2VDb250ZW50LCBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tIFwiLi90eXBlcy9tZXNzYWdlLWNvbnRlbnQudHlwZXNcIjtcbmltcG9ydCB7IEFzc2lzdGFudFV0aWxzIH0gZnJvbSBcIi4vdXRpbHMvdXRpbHMuc2VydmljZVwiO1xuaW1wb3J0IHsgQXNzaXN0YW50Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9hc3Npc3RhbnQtY29uZmlndXJhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBBc3Npc3RhbnRUb2tlbnNUcmFja2luZ1NlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9hc3Npc3RhbnQtdG9rZW5zLXRyYWNraW5nLnNlcnZpY2VcIjtcbmltcG9ydCB7IFNhdmVkQ2hhdHNTZXJ2aWNlIH0gZnJvbSBcIi4vc2F2ZWQtY2hhdHMvc2F2ZWQtY2hhdHMuc2VydmljZVwiO1xuaW1wb3J0IHsgRGVidWdNZXNzYWdlU2VydmljZSB9IGZyb20gXCIuL2RlYnVnLW1lc3NhZ2UvZGVidWctbWVzc2FnZS5zZXJ2aWNlXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NxLWNoYXQtdjMnLCAvLyBtYW5kYXRvcnkgc2luY2UgQHNpbmVxdWEvY29tcG9uZW50cyBhbHJlYWR5IGhhcyB0aGUgc2FtZSB0YWctbmFtZSBcInNxLWNoYXRcIlxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXQuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgQ2hhdFNlcnZpY2UsXG4gICAgQXNzaXN0YW50Q29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgQXNzaXN0YW50VG9rZW5zVHJhY2tpbmdTZXJ2aWNlLFxuICAgIFNhdmVkQ2hhdHNTZXJ2aWNlLFxuICAgIERlYnVnTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJvdmlkZVRyYW5zbG9jb1Njb3BlKCdjaGF0JylcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBDaGF0TWVzc2FnZUNvbXBvbmVudCwgVG9rZW5Qcm9ncmVzc0JhckNvbXBvbmVudCwgRGVidWdNZXNzYWdlQ29tcG9uZW50LCBUb29sdGlwRGlyZWN0aXZlLCBUcmFuc2xvY29QaXBlXVxufSlcbmV4cG9ydCBjbGFzcyBDaGF0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgcHVibGljIGNoYXRTZXJ2aWNlID0gaW5qZWN0KENoYXRTZXJ2aWNlKTtcbiAgcHVibGljIGluc3RhbmNlTWFuYWdlclNlcnZpY2UgPSBpbmplY3QoSW5zdGFuY2VNYW5hZ2VyU2VydmljZSk7XG4gIHB1YmxpYyBzZWFyY2hTZXJ2aWNlID0gaW5qZWN0KFNlYXJjaFNlcnZpY2UpO1xuICBwdWJsaWMgcHJpbmNpcGFsU2VydmljZSA9IGluamVjdChQcmluY2lwYWxTZXJ2aWNlKTtcbiAgcHVibGljIGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHB1YmxpYyBub3RpZmljYXRpb25zU2VydmljZSA9IGluamVjdChOb3RpZmljYXRpb25zU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNsb2NvID0gaW5qZWN0KFRyYW5zbG9jb1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGFzc2lzdGFudFV0aWxzID0gaW5qZWN0KEFzc2lzdGFudFV0aWxzKTtcblxuICAvKiogRGVmaW5lIHRoZSBrZXkgYmFzZWQgb24gaXQsIHRoZSBjaGF0IHNlcnZpY2UgaW5zdGFuY2Ugd2lsbCBiZSBzdG9yZWQgKi9cbiAgQElucHV0KCkgaW5zdGFuY2VJZDogc3RyaW5nO1xuICAvKiogRGVmaW5lIHRoZSBxdWVyeSB0byB1c2UgdG8gZmV0Y2ggYW5zd2VycyAqL1xuICBASW5wdXQoKSBxdWVyeTogUXVlcnkgPSB0aGlzLnNlYXJjaFNlcnZpY2UucXVlcnk7XG4gIC8qKiBGdW5jdGlvbiB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgYWZ0ZXIgdGhlIHF1ZXJ5IGNoYW5nZXNcbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgY2hhdCB3aWxsIGJlIHJlbG9hZGVkIGJ5IGRlZmF1bHRcbiAgICogQHBhcmFtIHByZXZRdWVyeSBUaGUgcHJldmlvdXMgcXVlcnlcbiAgICogQHBhcmFtIG5ld1F1ZXJ5IFRoZSBuZXcgcXVlcnlcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgQElucHV0KCkgcXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkOiAocHJldlF1ZXJ5OiBRdWVyeSwgbmV3UXVlcnk6IFF1ZXJ5KSA9PiBib29sZWFuO1xuICAvKiogTWFwIG9mIGxpc3RlbmVycyBvdmVycmlkaW5nIGRlZmF1bHQgcmVnaXN0ZXJlZCBvbmVzKi9cbiAgQElucHV0KCkgbWVzc2FnZUhhbmRsZXJzOiBNYXA8c3RyaW5nLCBNZXNzYWdlSGFuZGxlcjxhbnk+PiA9IG5ldyBNYXAoKTtcbiAgLyoqIFdoZW4gdGhlIGFzc2lzdGFudCBhbnN3ZXIgYSB1c2VyIHF1ZXN0aW9uLCBhdXRvbWF0aWNhbGx5IHNjcm9sbCBkb3duIHRvIHRoZSBib3R0b20gb2YgdGhlIGRpc2N1c3Npb24gKi9cbiAgQElucHV0KCkgYXV0b21hdGljU2Nyb2xsVG9MYXN0UmVzcG9uc2UgPSBmYWxzZTtcbiAgLyoqIFdoZW4gdGhlIGFzc2lzdGFudCBhbnN3ZXIgYSB1c2VyIHF1ZXN0aW9uLCBhdXRvbWF0aWNhbGx5IGZvY3VzIHRvIHRoZSBjaGF0IGlucHV0ICovXG4gIEBJbnB1dCgpIGZvY3VzQWZ0ZXJSZXNwb25zZSA9IGZhbHNlO1xuICAvKiogQSBjaGF0IGRpc2N1c3Npb24gdGhhdCB0aGUgY29tcG9uZW50IHNob3VsZCBnZXQgaW5pdGlhbGl6ZWQgd2l0aCBpdCAqL1xuICBASW5wdXQoKSBjaGF0PzogSW5pdENoYXQ7XG4gIC8qKiBJY29uIHRvIHVzZSBmb3IgdGhlIGFzc2lzdGFudCBtZXNzYWdlcyAqL1xuICBASW5wdXQoKSBhc3Npc3RhbnRNZXNzYWdlSWNvbiA9ICdzcS1zaW5lcXVhJztcbiAgLyoqIEljb24gdG8gdXNlIGZvciB0aGUgdXNlciBtZXNzYWdlcyAqL1xuICBASW5wdXQoKSB1c2VyTWVzc2FnZUljb246IHN0cmluZztcbiAgLyoqIEljb24gdG8gdXNlIGZvciB0aGUgY29ubmVjdGlvbiBlcnJvciBtZXNzYWdlcyAqL1xuICBASW5wdXQoKSBjb25uZWN0aW9uRXJyb3JNZXNzYWdlSWNvbjogc3RyaW5nO1xuICAvKiogSWNvbiB0byB1c2UgZm9yIHRoZSBzZWFyY2ggd2FybmluZyBtZXNzYWdlcyAqL1xuICBASW5wdXQoKSBzZWFyY2hXYXJuaW5nTWVzc2FnZUljb246IHN0cmluZztcbiAgLy8gQWRkIGN1c3RvbSBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzIHRvIHRoZSB1c2VyIHF1ZXJ5IG1lc3NhZ2VcbiAgQElucHV0KCkgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgb25jZSB0aGUgc2lnbmFsUiBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkICAqL1xuICBAT3V0cHV0KCkgY29ubmVjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8SHViQ29ubmVjdGlvbj4oKTtcbiAgLyoqIEV2ZW50IGVtaXR0ZXIgdHJpZ2dlcmVkIGVhY2ggdGltZSB0aGUgYXNzaXN0YW50IHVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hhdCAqL1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgY2hhdCBpcyBsb2FkaW5nIG5ldyBjb250ZW50ICovXG4gIEBPdXRwdXQoXCJsb2FkaW5nXCIpIGxvYWRpbmckID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPihmYWxzZSk7XG4gIC8qKiBFbWl0cyB0aGUgYXNzaXN0YW50IGNvbmZpZ3VyYXRpb24gdXNlZCB3aGVuIGluc3RhbnRpYXRpbmcgdGhlIGNvbXBvbmVudCAqL1xuICBAT3V0cHV0KFwiY29uZmlnXCIpIF9jb25maWcgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRDb25maWc+KCk7XG4gIEBPdXRwdXQoKSBkYXRhID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZVtdPigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgdG8gb3BlbiB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgcmVwcmVzZW50aW5nIHRoZSBjb250ZXh0IGF0dGFjaG1lbnQqL1xuICBAT3V0cHV0KCkgb3BlbkRvY3VtZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxBcnRpY2xlPigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgdG8gb3BlbiB0aGUgcHJldmlldyBvZiBhIGRvY3VtZW50IHJlcHJlc2VudGluZyB0aGUgY29udGV4dCBhdHRhY2htZW50ICovXG4gIEBPdXRwdXQoKSBvcGVuUHJldmlldyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdENvbnRleHRBdHRhY2htZW50PigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYSBzdWdnZXN0ZWQgYWN0aW9uICovXG4gIEBPdXRwdXQoKSBzdWdnZXN0QWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxTdWdnZXN0ZWRBY3Rpb24+KCk7XG4gIC8qKiBWaWV3Q2hpbGQgZGVjb3JhdG9ycyB0byBhY2Nlc3MgdGhlIHRlbXBsYXRlIGVsZW1lbnRzICovXG4gIEBWaWV3Q2hpbGQoJ21lc3NhZ2VMaXN0JykgbWVzc2FnZUxpc3Q/OiBFbGVtZW50UmVmPEhUTUxVTGlzdEVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCdxdWVzdGlvbklucHV0JykgcXVlc3Rpb25JbnB1dD86IEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD47XG4gIC8qKiBDb250ZW50Q2hpbGQgZGVjb3JhdG9ycyBhbGxvd2luZyB0aGUgb3ZlcnJpZGUgb2YgdGhlIGRlZmF1bHQgdGVtcGxhdGVzIGZyb20gdGhlIHBhcmVudCBjb21wb25lbnQgKi9cbiAgQENvbnRlbnRDaGlsZCgnbG9hZGluZ1RwbCcpIGxvYWRpbmdUcGw/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBAQ29udGVudENoaWxkKCdyZXBvcnRUcGwnKSByZXBvcnRUcGw/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBAQ29udGVudENoaWxkKCd0b2tlbkNvbnN1bXB0aW9uVHBsJykgdG9rZW5Db25zdW1wdGlvblRwbD86IFRlbXBsYXRlUmVmPGFueT47XG4gIEBDb250ZW50Q2hpbGQoJ2RlYnVnTWVzc2FnZXNUcGwnKSBkZWJ1Z01lc3NhZ2VzVHBsPzogVGVtcGxhdGVSZWY8YW55PjtcblxuICBASW5wdXQoKSBhcHBDb25maWc6IEFwcEdsb2JhbENvbmZpZztcblxuICBjb25maWc6IENoYXRDb25maWc7XG4gIG1lc3NhZ2VzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Q2hhdE1lc3NhZ2VbXSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgaXNBZG1pbk9yRGVsZXRlZEFkbWluID0gZmFsc2U7XG4gIHF1ZXN0aW9uID0gJyc7XG5cbiAgcHJpdmF0ZSBfc3ViID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIF9kYXRhU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCB1bmRlZmluZWQ7XG5cbiAgLyoqIFZhcmlhYmxlcyB0aGF0IGRlcGVuZCBvbiB0aGUgdHlwZSBvZiBtb2RlbCBpbiB1c2UgKi9cbiAgbW9kZWxEZXNjcmlwdGlvbj86IEdsbG1Nb2RlbERlc2NyaXB0aW9uO1xuXG4gIGluZGV4TWVzc2FnZVRvRWRpdD86IG51bWJlcjtcbiAgcmFua01lc3NhZ2VUb0VkaXQ/OiBudW1iZXI7XG4gIGNoYW5nZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTaW1wbGVDaGFuZ2VzIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBjdXJyZW50TWVzc2FnZUluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGZpcnN0Q2hhbmdlc0hhbmRsZWQgPSBmYWxzZTtcbiAgaXNBdEJvdHRvbSA9IHRydWU7XG4gIGluaXRpYWxpemF0aW9uRXJyb3IgPSBmYWxzZTtcbiAgZW5hYmxlZFVzZXJJbnB1dCA9IGZhbHNlO1xuICBpc0Nvbm5lY3RlZCA9IHRydWU7IC8vIEJ5IGRlZmF1bHQsIHRoZSBjaGF0IGlzIGNvbnNpZGVyZWQgY29ubmVjdGVkXG4gIHJldHJpYWxBdHRlbXB0czogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAvLyBGbGFnIHRvIHRyYWNrIHdoZXRoZXIgdGhlICdyZWNvbm5lY3RlZCcgbGlzdGVuZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkXG4gIHByaXZhdGUgX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuICAvLyBJc3N1ZSByZXBvcnRpbmdcbiAgaXNzdWVUeXBlcz86IHN0cmluZ1tdO1xuICBkZWZhdWx0SXNzdWVUeXBlczogc3RyaW5nW10gPSBbXG4gICAgJ2NoYXQudXNlckludGVyZmFjZUJ1ZycsXG4gICAgJ2NoYXQuaW5jb3JyZWN0UmVzcG9uc2UnLFxuICAgICdjaGF0LmluY29tcGxldGVSZXNwb25zZScsXG4gICAgJ2NoYXQudGVjaG5pY2FsSXNzdWUnLFxuICAgICdjaGF0LnByaXZhY3lEYXRhU2VjdXJpdHlJc3N1ZScsXG4gICAgJ2NoYXQub3RoZXJJc3N1ZSdcbiAgXTtcbiAgaXNzdWVUeXBlOiBzdHJpbmcgPSAnJztcbiAgcmVwb3J0Q29tbWVudD86IHN0cmluZztcbiAgbWVzc2FnZVRvUmVwb3J0PzogQ2hhdE1lc3NhZ2U7XG4gIHJlcG9ydFJhbms/OiBudW1iZXI7XG4gIHJlcG9ydFR5cGU6ICdsaWtlJyB8ICdkaXNsaWtlJyA9ICdkaXNsaWtlJztcbiAgc2hvd1JlcG9ydCA9IGZhbHNlO1xuXG4gIC8vIERlYnVnIG1lc3NhZ2VzXG4gIGRlYnVnTWVzc2FnZXM6IERlYnVnTWVzc2FnZVtdIHwgdW5kZWZpbmVkO1xuICBzaG93RGVidWdNZXNzYWdlcyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgX3ByZXZpb3VzUXVlcnk6IFF1ZXJ5O1xuICBwcml2YXRlIF9yZWxvYWRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hcHBDb25maWcpIHtcbiAgICAgIHNldEdsb2JhbENvbmZpZyh0aGlzLmFwcENvbmZpZyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3ViLmFkZChcbiAgICAgIG9mKGlzQXV0aGVudGljYXRlZCgpKS5waXBlKFxuICAgICAgICB0YXAoXyA9PiB0aGlzLmluc3RhbnRpYXRlQ2hhdFNlcnZpY2UoKSksXG4gICAgICAgIHN3aXRjaE1hcChfID0+IHRoaXMuY2hhdFNlcnZpY2UuaW5pdCgpKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0UHJvY2VzcyQucGlwZShmaWx0ZXIoQm9vbGVhbikpKSxcbiAgICAgICAgdGFwKF8gPT4ge1xuICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5lbWl0KHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbik7XG4gICAgICAgICAgdGhpcy5vbkxvYWRDaGF0KCk7XG4gICAgICAgIH0pLFxuICAgICAgICB0YXAoXyA9PiB0aGlzLmNoYXRTZXJ2aWNlLm92ZXJyaWRlVXNlcigpKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS51c2VyT3ZlcnJpZGUkKSxcbiAgICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckKSxcbiAgICAgICAgdGFwKGNvbmZpZyA9PiB7XG4gICAgICAgICAgdGhpcy5pc0FkbWluT3JEZWxldGVkQWRtaW4gPSB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsIS5pc0FkbWluaXN0cmF0b3IgfHwgdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbCEuaXNEZWxlZ2F0ZWRBZG1pbiB8fCBmYWxzZTtcbiAgICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyE7XG4gICAgICAgICAgdGhpcy5lbmFibGVkVXNlcklucHV0ID0gdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmVuYWJsZWRVc2VySW5wdXQ7XG4gICAgICAgICAgdGhpcy5pc3N1ZVR5cGVzID0gdGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncz8uaXNzdWVUeXBlcz8ubGVuZ3RoID8gdGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncyEuaXNzdWVUeXBlcyA6IHVuZGVmaW5lZDtcbiAgICAgICAgICB0aGlzLl9jb25maWcuZW1pdChjb25maWcpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZU1vZGVsRGVzY3JpcHRpb24oKTtcbiAgICAgICAgICAgIGlmKCF0aGlzLmZpcnN0Q2hhbmdlc0hhbmRsZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNRdWVyeSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSkpOyAvLyBJbml0aWFsaXplIHRoZSBwcmV2aW91cyBxdWVyeVxuICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVDaGFuZ2VzKCk7XG4gICAgICAgICAgICAgIHRoaXMuX2FkZFNjcm9sbExpc3RlbmVyKCk7XG4gICAgICAgICAgICAgIHRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6YXRpb25FcnJvciA9IHRydWVcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICkuc3Vic2NyaWJlKClcbiAgICApO1xuXG4gICAgLy8gRXhhbXBsZSBvZiBsaXN0ZW5pbmcgdG8gY3VzdG9tIGV2ZW50cyBmcm9tIHRoZSB3ZWIgZWxlbWVudCBhbmQgaGFuZGxpbmcgdGhlbSBpbiB0aGUgQW5ndWxhciBjb21wb25lbnRcbiAgICBhZGRFdmVudExpc3RlbmVyKCdvbk9wZW5QcmV2aWV3JywgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIHRoaXMub3BlblByZXZpZXcuZW1pdChldmVudC5kZXRhaWwucmVmZXJlbmNlKTtcbiAgICB9KTtcbiAgICBhZGRFdmVudExpc3RlbmVyKCdvbk9wZW5Eb2N1bWVudCcsIChldmVudDogYW55KSA9PiB7XG4gICAgICB0aGlzLm9wZW5Eb2N1bWVudC5lbWl0KGV2ZW50LmRldGFpbC5yZWZlcmVuY2UucmVjb3JkKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICB0aGlzLmNoYW5nZXMkLm5leHQoY2hhbmdlcyk7XG4gICAgaWYgKHRoaXMuY29uZmlnKSB7XG4gICAgICB0aGlzLl9oYW5kbGVDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fZGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5zdG9wQ29ubmVjdGlvbigpO1xuICB9XG5cbiAgZ2V0IGlzQWRtaW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWw/LmlzQWRtaW5pc3RyYXRvciB8fCBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGNoYXQgc2VydmljZSBpbnN0YW5jZSBpcyBzdG9yZWQgaW4gdGhlIGluc3RhbmNlTWFuYWdlclNlcnZpY2Ugd2l0aCBwcm92aWRlZCBAaW5wdXQgaW5zdGFuY2VJZCBhcyBhIGtleVxuICAgKi9cbiAgaW5zdGFudGlhdGVDaGF0U2VydmljZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLnNldENoYXRJbnN0YW5jZUlkKHRoaXMuaW5zdGFuY2VJZCk7XG4gICAgdGhpcy5pbnN0YW5jZU1hbmFnZXJTZXJ2aWNlLnN0b3JlSW5zdGFuY2UodGhpcy5pbnN0YW5jZUlkLCB0aGlzLmNoYXRTZXJ2aWNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBjaGFuZ2VzIGluIHRoZSBjaGF0IGNvbXBvbmVudC5cbiAgICogSWYgdGhlIGNoYXQgc2VydmljZSBpcyBhIFdlYlNvY2tldENoYXRTZXJ2aWNlLCBpdCBoYW5kbGVzIHRoZSBvdmVycmlkZSBvZiB0aGUgbWVzc2FnZSBoYW5kbGVycyBpZiB0aGV5IGV4aXN0LlxuICAgKiBJbml0aWFsaXplcyB0aGUgY2hhdCB3aXRoIHRoZSBwcm92aWRlZCBjaGF0IG1lc3NhZ2VzIGlmIHRoZXkgZXhpc3QsIG90aGVyd2lzZSBsb2FkcyB0aGUgZGVmYXVsdCBjaGF0LlxuICAgKiBJZiB0aGUgY2hhdCBpcyBpbml0aWFsaXplZCwgdGhlIGluaXRpYWxpemF0aW9uIGV2ZW50IGlzIFwiUXVlcnlcIiwgdGhlIHF1ZXJ5IGNoYW5nZXMsIGFuZCB0aGUgcXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkIGZ1bmN0aW9uIGlzIHByb3ZpZGVkLFxuICAgKiB0aGVuIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCBpZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlLiBPdGhlcndpc2UsIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCBieSBkZWZhdWx0LlxuICAgKiBJdCB0YWtlcyBpbnRvIGFjY291bnQgdGhlIG9uZ29pbmcgc3RyZWFtaW5nIHByb2Nlc3MgYW5kIHRoZSBvbmdvaW5nIHN0b3BwaW5nIHByb2Nlc3MgdG8gdHJpZ2dlciB0aGF0IGNvbmRpdGlvbmFsbHkgZGVmaW5lIHRoZSBsb2dpY1xuICAgKiBvZiB0aGUgcmVsb2FkIDpcbiAgICogLSBJZiB0aGUgY2hhdCBpcyBzdHJlYW1pbmcsIHRoZW4gc3RvcCB0aGUgZ2VuZXJhdGlvbiBhbmQgd2FpdCBmb3IgdGhlIGZldGNoIHRvIGNvbXBsZXRlIGJlZm9yZSByZWxvYWRpbmcgdGhlIGNoYXQuXG4gICAqIC0gSWYgdGhlIGNoYXQgaXMgc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZW4gd2FpdCBmb3IgdGhlIGZldGNoIHRvIGNvbXBsZXRlIGJlZm9yZSByZWxvYWRpbmcgdGhlIGNoYXQuXG4gICAqL1xuICBwcml2YXRlIF9oYW5kbGVDaGFuZ2VzKCkge1xuICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLmNoYW5nZXMkLnZhbHVlO1xuICAgIC8vIElmIHRoZSBjaGF0IHNlcnZpY2UgaXMgYSBXZWJTb2NrZXRDaGF0U2VydmljZSwgaGFuZGxlIHRoZSBvdmVycmlkZSBvZiB0aGUgbWVzc2FnZSBoYW5kbGVycyBpZiBleGlzdHNcbiAgICBpZiAoY2hhbmdlcz8ubWVzc2FnZUhhbmRsZXJzICYmIHRoaXMubWVzc2FnZUhhbmRsZXJzKSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLm92ZXJyaWRlTWVzc2FnZUhhbmRsZXJzKHRoaXMubWVzc2FnZUhhbmRsZXJzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGUgY2hhdCB3aXRoIHRoZSBwcm92aWRlZCBjaGF0IG1lc3NhZ2VzIGlmIGV4aXN0cywgb3RoZXJ3aXNlIGxvYWQgdGhlIGRlZmF1bHQgY2hhdFxuICAgICAqIE9uY2UgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQgKGZpcnN0Q2hhbmdlc0hhbmRsZWQgaXMgdHJ1ZSksIGFsbG93IG9wZW5pbmcgdGhlIGNoYXQgd2l0aCB0aGUgbmV3IHByb3ZpZGVkIG1lc3NhZ2VzIChpZiBleGlzdHMpXG4gICAgICovXG4gICAgaWYgKCF0aGlzLmZpcnN0Q2hhbmdlc0hhbmRsZWQgfHwgY2hhbmdlcz8uY2hhdCkge1xuICAgICAgY29uc3Qgb3BlbkNoYXQgPSAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VzJC52YWx1ZSAmJiB0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncz8uZW5hYmxlZCkge1xuICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2UubGlzdFNhdmVkQ2hhdCgpOyAvLyBSZWZyZXNoIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcGVuQ2hhdCh0aGlzLmNoYXQhLm1lc3NhZ2VzKTtcbiAgICAgIH07XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQ2hhdElkKCk7XG4gICAgICBpZiAodGhpcy5jaGF0KSB7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtY2hhdC5uZXcnLCB7J2NvbmZpZ3VyYXRpb24nOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNoYXRTZXJ2aWNlLmFzc2lzdGFudENvbmZpZyQudmFsdWUpLCdjaGF0LWluaXQnOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNoYXQpfSk7XG4gICAgICAgIG9wZW5DaGF0KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWNoYXQubmV3Jywgeydjb25maWd1cmF0aW9uJzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckLnZhbHVlKX0pO1xuICAgICAgICB0aGlzLmxvYWREZWZhdWx0Q2hhdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY2hhdCBpcyBpbml0aWFsaXplZCwgdGhlIGluaXRpYWxpemF0aW9uIGV2ZW50IGlzIFwiUXVlcnlcIiwgdGhlIHF1ZXJ5IGNoYW5nZXMgYW5kIHRoZSBxdWVyeUNoYW5nZVNob3VsZFRyaWdnZXJSZWxvYWQgZnVuY3Rpb24gaXMgcHJvdmlkZWQsXG4gICAgICogdGhlbiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgaWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZVxuICAgICAqIE90aGVyd2lzZSwgdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBpZiAodGhpcy5maXJzdENoYW5nZXNIYW5kbGVkICYmIGNoYW5nZXM/LnF1ZXJ5ICYmIHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5ldmVudCA9PT0gJ1F1ZXJ5Jykge1xuICAgICAgaWYgKHRoaXMucXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkID8gdGhpcy5xdWVyeUNoYW5nZVNob3VsZFRyaWdnZXJSZWxvYWQodGhpcy5fcHJldmlvdXNRdWVyeSwgdGhpcy5xdWVyeSkgOiB0cnVlKSB7XG4gICAgICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgICAgIGlmICghdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBzdWJzY3JpcHRpb24gdG8gd2FpdCBmb3IgYm90aCBzdHJlYW1pbmckIGFuZCBzdG9wcGluZ0dlbmVyYXRpb24kIHRvIGJlIGZhbHNlXG4gICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICAgICAgICAgICAgdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLFxuICAgICAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiRcbiAgICAgICAgICAgIF0pXG4gICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGZpbHRlcigoW3N0cmVhbWluZywgc3RvcHBpbmddKSA9PiAhc3RyZWFtaW5nICYmICFzdG9wcGluZyksIC8vIFdhaXQgdW50aWwgYm90aCBhcmUgZmFsc2VcbiAgICAgICAgICAgICAgICB0YWtlKDEpIC8vIENvbXBsZXRlIGFmdGVyIHRoZSBmaXJzdCBtYXRjaFxuICAgICAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gRXhlY3V0ZSB0aGUgcmVsb2FkIGFmdGVyIHRoZSBxdWVyeSBjaGFuZ2VcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVsb2FkQWZ0ZXJRdWVyeUNoYW5nZSgpO1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBfcHJldmlvdXNRdWVyeSB3aXRoIHRoZSBjdXJyZW50IHF1ZXJ5XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJldmlvdXNRdWVyeSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSkpO1xuICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIHN1YnNjcmlwdGlvbiBhbmQgcmVzZXQgaXRzIHZhbHVlXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gdGhpcy5jaGF0U2VydmljZS5zdG9wR2VuZXJhdGlvbigpXG4gICAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgICAgIG5leHQ6ICgpID0+IHt9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBzdWJzY3JpcHRpb24gYW5kIHJlc2V0IGl0cyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIHRoZSBvbmdvaW5nIGZldGNoIHRvIGNvbXBsZXRlLCB0aGVuIHRyaWdnZXIgdGhlIHJlbG9hZFxuICAgICAgICAgICAgICAgICAgdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcigoc3RyZWFtaW5nKSA9PiAhc3RyZWFtaW5nKSxcbiAgICAgICAgICAgICAgICAgICAgdGFrZSgxKVxuICAgICAgICAgICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBFeGVjdXRlIHRoZSByZWxvYWQgYWZ0ZXIgdGhlIHF1ZXJ5IGNoYW5nZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVsb2FkQWZ0ZXJRdWVyeUNoYW5nZSgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgX3ByZXZpb3VzUXVlcnkgd2l0aCB0aGUgY3VycmVudCBxdWVyeVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcmV2aW91c1F1ZXJ5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIHN1YnNjcmlwdGlvbiBhbmQgcmVzZXQgaXRzIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiEudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRXhlY3V0ZSB0aGUgcmVsb2FkIGFmdGVyIHRoZSBxdWVyeSBjaGFuZ2VcbiAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVsb2FkQWZ0ZXJRdWVyeUNoYW5nZSgpO1xuICAgICAgICAgIC8vIFVwZGF0ZSBfcHJldmlvdXNRdWVyeSB3aXRoIHRoZSBjdXJyZW50IHF1ZXJ5XG4gICAgICAgICAgdGhpcy5fcHJldmlvdXNRdWVyeSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVcGRhdGUgX3ByZXZpb3VzUXVlcnkgd2l0aCB0aGUgY3VycmVudCBxdWVyeVxuICAgICAgICB0aGlzLl9wcmV2aW91c1F1ZXJ5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXJzIGEgcmVsb2FkIGFmdGVyIHRoZSBxdWVyeSBjaGFuZ2UuXG4gICAqIFRoaXMgbWV0aG9kIHBlcmZvcm1zIHRoZSBuZWNlc3Nhcnkgb3BlcmF0aW9ucyB0byByZWxvYWQgdGhlIGNoYXQgYWZ0ZXIgYSBxdWVyeSBjaGFuZ2UuXG4gICAqIEl0IHNldHMgdGhlIHN5c3RlbSBhbmQgdXNlciBtZXNzYWdlcywgcmVzZXRzIHRoZSBzYXZlZENoYXRJZCwgZ2VuZXJhdGVzIGEgbmV3IGNoYXRJZCxcbiAgICogZ2VuZXJhdGVzIGEgbmV3IGNoYXQgYXVkaXQgZXZlbnQsIGFuZCBoYW5kbGVzIHRoZSBxdWVyeSBtb2RlLlxuICAgKi9cbiAgcHJpdmF0ZSBfdHJpZ2dlclJlbG9hZEFmdGVyUXVlcnlDaGFuZ2UoKSB7XG4gICAgY29uc3Qgc3lzdGVtTXNnID0geyByb2xlOiAnc3lzdGVtJywgY29udGVudDogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zeXN0ZW1Qcm9tcHQsIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IGZhbHNlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIG9sZCBjb25maWd1cmF0aW9uIGZpbGVzXG4gICAgY29uc3QgdXNlclByb21wdCA9IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMudXNlclByb21wdC5yZXBsYWNlKC9cXHtcXHsoLio/KVxcfVxcfS9nLCAnW1skMV1dJyk7XG4gICAgY29uc3QgdXNlck1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiBBc3Npc3RhbnRVdGlscy5mb3JtYXRQcm9tcHQodGhpcy50cmFuc2xvY28udHJhbnNsYXRlKHVzZXJQcm9tcHQpICwgeyBwcmluY2lwYWw6IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwgfSksIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdCwgbWVzc2FnZUlkOiBndWlkKCkgfSB9O1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVDaGF0SWQoKTsgLy8gR2VuZXJhdGUgYSBuZXcgY2hhdElkXG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jaGF0Lm5ldycsIHsnY29uZmlndXJhdGlvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSl9KTsgLy8gR2VuZXJhdGUgYSBuZXcgY2hhdCBhdWRpdCBldmVudFxuICAgIHRoaXMuX2hhbmRsZVF1ZXJ5TW9kZShzeXN0ZW1Nc2csIHVzZXJNc2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBzY3JvbGwgbGlzdGVuZXIgdG8gdGhlIG1lc3NhZ2UgbGlzdCBlbGVtZW50LlxuICAgKiBUaGUgbGlzdGVuZXIgaXMgdHJpZ2dlcmVkIHdoZW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgZXZlbnRzIG9jY3VyOlxuICAgKiAtIExvYWRpbmcgc3RhdGUgY2hhbmdlc1xuICAgKiAtIE1lc3NhZ2VzIGNoYW5nZVxuICAgKiAtIFN0cmVhbWluZyBzdGF0ZSBjaGFuZ2VzXG4gICAqIC0gU2Nyb2xsIGV2ZW50IG9jY3VycyBvbiB0aGUgbWVzc2FnZSBsaXN0IGVsZW1lbnRcbiAgICpcbiAgICogV2hlbiB0aGUgbGlzdGVuZXIgaXMgdHJpZ2dlcmVkLCBpdCB1cGRhdGVzIHRoZSBgaXNBdEJvdHRvbWAgcHJvcGVydHkuXG4gICAqL1xuICBwcml2YXRlIF9hZGRTY3JvbGxMaXN0ZW5lcigpIHtcbiAgICB0aGlzLl9zdWIuYWRkKFxuICAgICAgbWVyZ2UodGhpcy5sb2FkaW5nJCwgdGhpcy5tZXNzYWdlcyQsIHRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCwgZnJvbUV2ZW50KHRoaXMubWVzc2FnZUxpc3QhLm5hdGl2ZUVsZW1lbnQsICdzY3JvbGwnKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5pc0F0Qm90dG9tID0gdGhpcy5fdG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpO1xuICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBtb2RlbCBkZXNjcmlwdGlvbiBiYXNlZCBvbiB0aGUgZGVmYXVsdFZhbHVlcyBzZXJ2aWNlX2lkIGFuZCBtb2RlbF9pZFxuICAgKi9cbiAgdXBkYXRlTW9kZWxEZXNjcmlwdGlvbigpIHtcbiAgICB0aGlzLm1vZGVsRGVzY3JpcHRpb24gPSB0aGlzLmNoYXRTZXJ2aWNlLmdldE1vZGVsKHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuc2VydmljZV9pZCwgdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5tb2RlbF9pZCk7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Ym1pdHMgYSBxdWVzdGlvbiBmcm9tIHRoZSB1c2VyLlxuICAgKiBJZiB0aGUgdXNlciBpcyBlZGl0aW5nIGEgcHJldmlvdXMgbWVzc2FnZSwgcmVtb3ZlcyBhbGwgc3Vic2VxdWVudCBtZXNzYWdlcyBmcm9tIHRoZSBjaGF0IGhpc3RvcnkuXG4gICAqIFRyaWdnZXJzIHRoZSBmZXRjaCBvZiB0aGUgYW5zd2VyIGZvciB0aGUgc3VibWl0dGVkIHF1ZXN0aW9uIGJ5IGNhbGxpbmcgX2ZldGNoQW5zd2VyKCkuXG4gICAqIENsZWFycyB0aGUgaW5wdXQgdmFsdWUgaW4gdGhlIFVJLlxuICAgKiDimqDvuI8gSWYgdGhlIGNoYXQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKi9cbiAgc3VibWl0UXVlc3Rpb24oKSB7XG4gICAgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlIHx8ICEhdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnF1ZXN0aW9uLnRyaW0oKSAmJiB0aGlzLm1lc3NhZ2VzJC52YWx1ZSAmJiB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KSB7XG4gICAgICAvLyBXaGVuIHRoZSB1c2VyIHN1Ym1pdHMgYSBxdWVzdGlvbiwgaWYgdGhlIHVzZXIgaXMgZWRpdGluZyBhIHByZXZpb3VzIG1lc3NhZ2UsIHJlbW92ZSBhbGwgc3Vic2VxdWVudCBtZXNzYWdlcyBmcm9tIHRoZSBjaGF0IGhpc3RvcnlcbiAgICAgIGlmICh0aGlzLmluZGV4TWVzc2FnZVRvRWRpdCAhPT0gdW5kZWZpbmVkICYmIHRoaXMucmFua01lc3NhZ2VUb0VkaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSVxuICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlLnNsaWNlKDAsIHRoaXMuaW5kZXhNZXNzYWdlVG9FZGl0KSk7XG4gICAgICAgIC8vIFVwZGF0ZSB0aGUgcmF3IG1lc3NhZ2VzIGluIHRoZSBjaGF0IGhpc3Rvcnkgd2hpY2ggaXMgdGhlIGNsZWFuIHZlcnNpb24gdXNlZCB0byBtYWtlIHRoZSBuZXh0IHJlcXVlc3RcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3Rvcnkuc2xpY2UoMCwgdGhpcy5yYW5rTWVzc2FnZVRvRWRpdC0xKTtcbiAgICAgICAgdGhpcy5pbmRleE1lc3NhZ2VUb0VkaXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucmFua01lc3NhZ2VUb0VkaXQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvLyBSZW1vdmUgdGhlIHNlYXJjaCB3YXJuaW5nIG1lc3NhZ2UgaWYgZXhpc3RzXG4gICAgICBpZiAodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5hdCgtMSk/LnJvbGUgPT09ICdzZWFyY2gtd2FybmluZycpIHtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeS5wb3AoKTtcbiAgICAgIH1cbiAgICAgIC8vIEZldGNoIHRoZSBhbnN3ZXJcbiAgICAgIHRoaXMuX2ZldGNoQW5zd2VyKHRoaXMucXVlc3Rpb24udHJpbSgpLCB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICAgIC8vIENsZWFyIHRoZSBpbnB1dCB2YWx1ZSBpbiB0aGUgVUlcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgICAgdGhpcy5xdWVzdGlvbklucHV0IS5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IGBhdXRvYDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlcnMgdGhlIGZldGNoIG9mIHRoZSBhbnN3ZXIgZm9yIHRoZSBnaXZlbiBxdWVzdGlvbiBhbmQgdXBkYXRlcyB0aGUgY29udmVyc2F0aW9uLlxuICAgKiBHZW5lcmF0ZXMgYW4gYXVkaXQgZXZlbnQgZm9yIHRoZSB1c2VyIGlucHV0LlxuICAgKlxuICAgKiBAcGFyYW0gcXVlc3Rpb24gLSBUaGUgcXVlc3Rpb24gYXNrZWQgYnkgdGhlIHVzZXIuXG4gICAqIEBwYXJhbSBjb252ZXJzYXRpb24gLSBUaGUgY3VycmVudCBjb252ZXJzYXRpb24gbWVzc2FnZXMuXG4gICAqL1xuICBwcml2YXRlIF9mZXRjaEFuc3dlcihxdWVzdGlvbjogc3RyaW5nLCBjb252ZXJzYXRpb246IENoYXRNZXNzYWdlW10pIHtcbiAgICAvLyBtZXJnZSBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzIGZyb20gdGhlIGNoYXQgY29tcG9uZW50IGFuZCB0aGUgY3VzdG9taXphdGlvbiBKU09OXG4gICAgY29uc3QgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyA9IHsgLi4udGhpcy5jb25maWcuYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcywgLi4udGhpcy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzIH07XG4gICAgY29uc3QgdXNlck1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiBxdWVzdGlvbiwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCksIGlzVXNlcklucHV0OiB0cnVlLCBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzIH0gfTtcbiAgICBjb25zdCBtZXNzYWdlcyA9IFsuLi5jb252ZXJzYXRpb24sIHVzZXJNc2ddO1xuICAgIHRoaXMubWVzc2FnZXMkLm5leHQobWVzc2FnZXMpOyAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSSB3aXRoIHRoZSBuZXcgdXNlciBtZXNzYWdlXG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IG1lc3NhZ2VzOyAvLyBVcGRhdGUgdGhlIGNoYXQgaGlzdG9yeSB3aXRoIHRoZSBuZXcgdXNlciBtZXNzYWdlXG4gICAgdGhpcy5mZXRjaChtZXNzYWdlcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB7IC4uLnRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHModXNlck1zZyksICdxdWVyeSc6IEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpLCAnaXMtdXNlci1pbnB1dCc6IHRydWUsICdlbmFibGVkLWZ1bmN0aW9ucyc6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuZnVuY3Rpb25zPy5maWx0ZXIoZnVuYyA9PiBmdW5jLmVuYWJsZWQpLm1hcChmdW5jID0+IGZ1bmMubmFtZSksICdhZGRpdGlvbmFsLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeShhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzKSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXBlbmRpbmcgb24gdGhlIGNvbm5lY3Rpb24ncyBzdGF0ZSA6XG4gICAqICAtIElmIGNvbm5lY3RlZCA9PiBnaXZlbiBhIGxpc3Qgb2YgbWVzc2FnZXMsIHRoZSBjaGF0IGVuZHBvaW50IGlzIGludm9rZWQgZm9yIGEgY29udGludWF0aW9uIGFuZCB1cGRhdGVzIHRoZSBsaXN0IG9mIG1lc3NhZ2VzIGFjY29yZGluZ2x5LlxuICAgKiAgLSBJZiBhbnkgb3RoZXIgc3RhdGUgPT4gYSBjb25uZWN0aW9uIGVycm9yIG1lc3NhZ2UgaXMgZGlzcGxheWVkIGluIHRoZSBjaGF0LlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqIEBwYXJhbSBtZXNzYWdlcyBUaGUgbGlzdCBvZiBtZXNzYWdlcyB0byBpbnZva2UgdGhlIGNoYXQgZW5kcG9pbnQgd2l0aFxuICAgKi9cbiAgcHVibGljIGZldGNoKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgaWYgKCEhdGhpcy5jaGF0U2VydmljZS5zdHJlYW1pbmckLnZhbHVlIHx8ICEhdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kLnZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX3VwZGF0ZUNvbm5lY3Rpb25TdGF0dXMoKTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG5cbiAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCkge1xuICAgICAgdGhpcy5sb2FkaW5nJC5uZXh0KHRydWUpO1xuICAgICAgdGhpcy5fZGF0YVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX2RhdGFTdWJzY3JpcHRpb24gPSB0aGlzLmNoYXRTZXJ2aWNlLmZldGNoKG1lc3NhZ2VzLCB0aGlzLnF1ZXJ5KVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiByZXMgPT4gdGhpcy51cGRhdGVEYXRhKHJlcy5oaXN0b3J5KSxcbiAgICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlQ29ubmVjdGlvblN0YXR1cygpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgICAgcm9sZTogJ2Nvbm5lY3Rpb24tZXJyb3InLFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6ICh7IHR5cGU6IFwidGV4dFwiLCB0ZXh0OiB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuY29ubmVjdGlvblNldHRpbmdzLmNvbm5lY3Rpb25FcnJvck1lc3NhZ2UpIH0gYXMgVGV4dE1lc3NhZ2VDb250ZW50KSxcbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9XG4gICAgICAgICAgICAgIH0gYXMgYW55IGFzIENoYXRNZXNzYWdlO1xuICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KFsuLi5tZXNzYWdlcywgbWVzc2FnZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgbGFzdCBtZXNzYWdlIGlmIGl0J3MgYW4gZW1wdHkgbWVzc2FnZVxuICAgICAgICAgICAgLy8gVGhpcyBpcyBkdWUgdG8gdGhlIG1hbm5lciBpbiB3aGljaCB0aGUgY2hhdCBzZXJ2aWNlIGhhbmRsZXMgY29uc2VjdXRpdmUgbWVzc2FnZXNcbiAgICAgICAgICAgIGNvbnN0IGxhc3RNZXNzYWdlID0gdGhpcy5tZXNzYWdlcyQudmFsdWU/LmF0KC0xKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRW1wdHlBc3Npc3RhbnRNZXNzYWdlKGxhc3RNZXNzYWdlKSkge1xuICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlPy5zbGljZSgwLCAtMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7IHJvbGU6ICdjb25uZWN0aW9uLWVycm9yJywgY29udGVudDogdGhpcy50cmFuc2xvY28udHJhbnNsYXRlKHRoaXMuY29uZmlnLmNvbm5lY3Rpb25TZXR0aW5ncy5jb25uZWN0aW9uRXJyb3JNZXNzYWdlKSwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdHJ1ZSwgbWVzc2FnZUlkOiBndWlkKCkgfSB9O1xuICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dChbLi4ubWVzc2FnZXMsIG1lc3NhZ2VdKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdXRvbWF0aWNTY3JvbGxUb0xhc3RSZXNwb25zZSkge1xuICAgICAgdGhpcy5zY3JvbGxEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHJ5IHRvIGZldGNoIHRoZSBtZXNzYWdlcyBpZiB0aGUgY29ubmVjdGlvbiBpc3N1ZXMuXG4gICAqICAtIElmIHJlY29ubmVjdGluZyA9PiBrZWVwIGRpc3BsYXkgdGhlIGNvbm5lY3Rpb24gZXJyb3IgbWVzc2FnZSBldmVuIHdoZW4gY2xpY2tpbmcgb24gdGhlIFwicmV0cnlcIiBidXR0b24gYW5kIGluY3JlYXNpbmcgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzLCB1bnRpbCB0aGUgY29ubmVjdGlvbiBpcyByZS1lc3RhYmxpc2hlZFxuICAgKiAgLSBJZiBkaXNjb25uZWN0ZWQgPT4gT24gY2xpY2sgb24gdGhlIFwicmV0cnlcIiBidXR0b24sIHN0YXJ0IHRoZSBjb25uZWN0aW9uIHByb2Nlc3Mgd2hpbGUgZGlzcGxheWluZyB0aGUgY29ubmVjdGlvbiBlcnJvciBtZXNzYWdlIDpcbiAgICogICAgICAqIElmIHN1Y2Nlc3NmdWwgPT4gZ2l2ZW4gYSBsaXN0IG9mIG1lc3NhZ2VzLCB0aGUgY2hhdCBlbmRwb2ludCBpcyBpbnZva2VkIGZvciBhIGNvbnRpbnVhdGlvbiBhbmQgdXBkYXRlcyB0aGUgbGlzdCBvZiBtZXNzYWdlcyBhY2NvcmRpbmdseS5cbiAgICogICAgICAqIElmIGZhaWxlZCA9PiBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHJldHJpYWwgYXR0ZW1wdHNcbiAgICovXG4gIHJldHJ5RmV0Y2goKSB7XG4gICAgLy8gQSBvbmUtdGltZSBsaXN0ZW5lciBmb3IgcmVjb25uZWN0ZWQgZXZlbnRcbiAgICBjb25zdCBvblJlY29ubmVjdGVkSGFuZGxlciA9ICgpID0+IHtcbiAgICAgIC8vIEdldCB0aGUgbWVzc2FnZXMgd2l0aG91dCB0aGUgbGFzdCBvbmUgKHRoZSBjb25uZWN0aW9uIGVycm9yIG1lc3NhZ2UpXG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCAtMSk7XG4gICAgICAvLyBGaW5kIHRoZSBsYXN0IFwidXNlclwiIG1lc3NhZ2UgaW4gdGhlIG1lc3NhZ2VzIGxpc3RcbiAgICAgIGxldCBpbmRleCA9IG1lc3NhZ2VzLmxlbmd0aCAtIDE7XG4gICAgICB3aGlsZSAoaW5kZXggPj0gMCAmJiBtZXNzYWdlc1tpbmRleF0ucm9sZSAhPT0gJ3VzZXInKSB7XG4gICAgICAgIGluZGV4LS07XG4gICAgICB9XG4gICAgICAvLyBJZiBhIHVzZXIgbWVzc2FnZSBpcyBmb3VuZCAoYW5kIGl0IHNob3VsZCBhbHdheXMgYmUgdGhlIGNhc2UpLCByZW1vdmUgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5XG4gICAgICAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSVxuICAgICAgLy8gYW5kIGZldGNoIHRoZSBhbnN3ZXIgZnJvbSB0aGUgYXNzaXN0YW50XG4gICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCBpbmRleCArIDEpKTtcbiAgICAgICAgY29uc3QgcmVtYXBwZWRJbmRleCA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnksIG1lc3NhZ2VzW2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEuc2xpY2UoMCwgcmVtYXBwZWRJbmRleCArIDEpO1xuICAgICAgICB0aGlzLmZldGNoKHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPSB1bmRlZmluZWQ7IC8vIFJlc2V0IHRoZSBudW1iZXIgb2YgcmV0cmlhbCBhdHRlbXB0c1xuICAgICAgLyoqXG4gICAgICAgKiBUbyByZW1vdmUgdGhlIGhhbmRsZXIgZm9yIG9ucmVjb25uZWN0ZWQoKSBhZnRlciBpdCdzIGJlZW4gcmVnaXN0ZXJlZCxjYW5ub3QgZGlyZWN0bHkgdXNlIG9mZigpIGxpa2UgeW91IHdvdWxkIGZvciBub3JtYWwgZXZlbnRzIHJlZ2lzdGVyZWQgd2l0aCBjb25uZWN0aW9uLm9uKCkuXG4gICAgICAgKiBJbnN0ZWFkLCB5b3UgbmVlZCB0byBleHBsaWNpdGx5IHJlbW92ZSBvciByZXNldCB0aGUgaGFuZGxlciBieSBhc3NpZ25pbmcgaXQgdG8gbnVsbCBvciBhbiBlbXB0eSBmdW5jdGlvblxuICAgICAgICovXG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNvbm5lY3Rpb24hLm9ucmVjb25uZWN0ZWQoKCkgPT4ge30pO1xuICAgICAgLy8gUmVzZXQgdGhlIGZsYWcgdG8gZW5zdXJlIHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgYWdhaW4gd2hlbiBuZWVkZWRcbiAgICAgIHRoaXMuX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgLy8gRGVwZW5kaW5nIG9uIHRoZSBjb25uZWN0aW9uJ3Mgc3RhdGUsIHRha2UgdGhlIGFwcHJvcHJpYXRlIGFjdGlvblxuICAgIHN3aXRjaCAodGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uIS5zdGF0ZSkge1xuICAgICAgY2FzZSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkOlxuICAgICAgICAvLyBJZiB0aGUgY29ubmVjdGlvbiBpcyByZS1lc3RhYmxpc2hlZCBpbiB0aGUgbWVhbnRpbWUsIGZldGNoIHRoZSBtZXNzYWdlc1xuICAgICAgICBvblJlY29ubmVjdGVkSGFuZGxlcigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgSHViQ29ubmVjdGlvblN0YXRlLlJlY29ubmVjdGluZzpcbiAgICAgICAgLy8gQXR0YWNoIHRoZSByZWNvbm5lY3RlZCBsaXN0ZW5lciBpZiBub3QgYWxyZWFkeSByZWdpc3RlcmVkXG4gICAgICAgIGlmICghdGhpcy5faXNSZWNvbm5lY3RlZExpc3RlbmVyUmVnaXN0ZXJlZCkge1xuICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbiEub25yZWNvbm5lY3RlZChvblJlY29ubmVjdGVkSGFuZGxlcik7XG4gICAgICAgICAgdGhpcy5faXNSZWNvbm5lY3RlZExpc3RlbmVyUmVnaXN0ZXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSW5jcmVhc2UgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzXG4gICAgICAgIHRoaXMucmV0cmlhbEF0dGVtcHRzID0gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPyB0aGlzLnJldHJpYWxBdHRlbXB0cyArIDEgOiAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgSHViQ29ubmVjdGlvblN0YXRlLkRpc2Nvbm5lY3RlZDpcbiAgICAgICAgLy8gU3RhcnQgdGhlIG5ldyBjb25uZWN0aW9uXG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RhcnRDb25uZWN0aW9uKClcbiAgICAgICAgICAudGhlbigoKSA9PiBvblJlY29ubmVjdGVkSGFuZGxlcigpKVxuICAgICAgICAgIC5jYXRjaCgoKSA9PiB7IC8vIElmIHRoZSBjb25uZWN0aW9uIGZhaWxzLCBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHJldHJpYWwgYXR0ZW1wdHNcbiAgICAgICAgICAgIHRoaXMucmV0cmlhbEF0dGVtcHRzID0gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPyB0aGlzLnJldHJpYWxBdHRlbXB0cyArIDEgOiAxO1xuICAgICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgc2lnbmFsUiBjb25uZWN0aW9uIGlzIGNvbm5lY3RlZC5cbiAgICogRm9yIHRoZSBSRVNUIHByb3RvY29sLCB0aGUgY29ubmVjdGlvbiBpcyBhbHdheXMgY29uc2lkZXJlZCBjb25uZWN0ZWQgKGZvciB0aGUgbW9tZW50KS5cbiAgICovXG4gIHByaXZhdGUgX3VwZGF0ZUNvbm5lY3Rpb25TdGF0dXMoKSB7XG4gICAgdGhpcy5pc0Nvbm5lY3RlZCA9IHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbiEuc3RhdGUgPT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBVSSB3aXRoIHRoZSBuZXcgbWVzc2FnZXNcbiAgICogQHBhcmFtIG1lc3NhZ2VzXG4gICAqL1xuICB1cGRhdGVEYXRhKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5kYXRhLmVtaXQobWVzc2FnZXMpO1xuICAgIHRoaXMubG9hZGluZyQubmV4dChmYWxzZSk7XG4gICAgdGhpcy5xdWVzdGlvbiA9ICcnO1xuICAgIGlmICh0aGlzLmF1dG9tYXRpY1Njcm9sbFRvTGFzdFJlc3BvbnNlKSB7XG4gICAgICB0aGlzLnNjcm9sbERvd24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhdCBkaXNjdXNzaW9uIGlzIHNjcm9sbGVkIGRvd24gdG8gdGhlIGJvdHRvbSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBwcml2YXRlIF90b2dnbGVTY3JvbGxCdXR0b25WaXNpYmlsaXR5KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50LnNjcm9sbEhlaWdodCAtIHRoaXMubWVzc2FnZUxpc3Q/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wIC0gMSkgPD0gdGhpcy5tZXNzYWdlTGlzdD8ubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjcm9sbCBkb3duIHRvIHRoZSBib3R0b20gb2YgdGhlIGNoYXQgZGlzY3Vzc2lvblxuICAgKi9cbiAgc2Nyb2xsRG93bigpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLm1lc3NhZ2VMaXN0Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgIHRoaXMubWVzc2FnZUxpc3QubmF0aXZlRWxlbWVudC5zY3JvbGxUb3AgPSB0aGlzLm1lc3NhZ2VMaXN0Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSwgMTApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgbmV3IGNoYXQgd2l0aCB0aGUgZGVmYXVsdFZhbHVlcyBzZXR0aW5ncy5cbiAgICogVGhlIHNhdmVkQ2hhdElkIGluIHRoZSBjaGF0IHNlcnZpY2Ugd2lsbCBiZSByZXNldCwgc28gdGhhdCB0aGUgdXBjb21pbmcgc2F2ZWQgY2hhdCBvcGVyYXRpb25zIHdpbGwgYmUgcGVyZm9ybWVkIG9uIHRoZSBmcmVzaCBuZXcgY2hhdC5cbiAgICogSWYgdGhlIHNhdmVkQ2hhdCBmZWF0dXJlIGlzIGVuYWJsZWQsIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzIHdpbGwgYmUgcmVmcmVzaGVkLlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqL1xuICBuZXdDaGF0KCkge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQ2hhdElkKCk7IC8vIEdlbmVyYXRlIGEgbmV3IGNoYXRJZFxuICAgIGlmICh0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncz8uZW5hYmxlZCkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5saXN0U2F2ZWRDaGF0KCk7IC8vIFJlZnJlc2ggdGhlIGxpc3Qgb2Ygc2F2ZWQgY2hhdHNcbiAgICB9XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jaGF0Lm5ldycsIHsnY29uZmlndXJhdGlvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSl9KTsgLy8gR2VuZXJhdGUgYSBuZXcgY2hhdCBhdWRpdCBldmVudFxuICAgIHRoaXMubG9hZERlZmF1bHRDaGF0KCk7IC8vIFN0YXJ0IGEgbmV3IGNoYXRcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2hlcyB0aGUgc3BlY2lmaWVkIGRvY3VtZW50IElEcyB0byB0aGUgYXNzaXN0YW50LlxuICAgKiBJZiBubyBkb2N1bWVudCBJRHMgYXJlIHByb3ZpZGVkLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBJZiB0aGUgYWN0aW9uIGZvciBhdHRhY2hpbmcgYSBkb2N1bWVudCBpcyBub3QgZGVmaW5lZCBhdCB0aGUgYXBwbGljYXRpb24gY3VzdG9taXphdGlvbiBsZXZlbCwgYW4gZXJyb3IgaXMgbG9nZ2VkLlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqIEBwYXJhbSBpZHMgLSBBbiBhcnJheSBvZiBkb2N1bWVudCBJRHMgdG8gYXR0YWNoLlxuICAgKi9cbiAgYXR0YWNoVG9DaGF0KGlkczogc3RyaW5nW10pIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFpZHMgfHwgaWRzPy5sZW5ndGggPCAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0dGFjaERvY0FjdGlvbiA9IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5hY3Rpb25zPy5bXCJhdHRhY2hEb2NBY3Rpb25cIl07XG4gICAgaWYgKCFhdHRhY2hEb2NBY3Rpb24pIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYE5vIGFjdGlvbiBpcyBkZWZpbmVkIGZvciBhdHRhY2hpbmcgYSBkb2N1bWVudCB0byB0aGUgYXNzaXN0YW50IFwiJHt0aGlzLmluc3RhbmNlSWR9XCJgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdXNlck1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiAnJywgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiBmYWxzZSwgbWVzc2FnZUlkOiBndWlkKCksIGlzVXNlcklucHV0OiBmYWxzZSwgdHlwZTogXCJBY3Rpb25cIiwgZm9yY2VkV29ya2Zsb3c6IGF0dGFjaERvY0FjdGlvbi5mb3JjZWRXb3JrZmxvdywgZm9yY2VkV29ya2Zsb3dQcm9wZXJ0aWVzOiB7Li4uKGF0dGFjaERvY0FjdGlvbi5mb3JjZWRXb3JrZmxvd1Byb3BlcnRpZXMgfHwge30pLCBpZHN9LCBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzOiB0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzfX07XG4gICAgLy8gUmVtb3ZlIHRoZSBzZWFyY2ggd2FybmluZyBtZXNzYWdlIGlmIGV4aXN0c1xuICAgIGlmICh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IS5hdCgtMSk/LnJvbGUgPT09ICdzZWFyY2gtd2FybmluZycpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLnBvcCgpO1xuICAgIH1cbiAgICBjb25zdCBtZXNzYWdlcyA9IFsuLi50aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgdXNlck1zZ107XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5mZXRjaChtZXNzYWdlcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1hY3Rpb24ucmVxdWVzdGVkJywge1xuICAgICAgJ2RldGFpbCc6ICdhdHRhY2hEb2NBY3Rpb24nLFxuICAgICAgJ2ZvcmNlZC13b3JrZmxvdyc6ICdTaW5lcXVhQWRkU2VsZWN0ZWREb2N1bWVudHNXb3JrZmxvdycsXG4gICAgICAnZm9yY2VkLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeShpZHMpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBkZWZhdWx0IGNoYXQgd2l0aCB0aGUgZGVmYXVsdFZhbHVlcyBzZXR0aW5nc1xuICAgKiBJZiB0aGUgY2hhdCBpcyBtZWFudCB0byBiZSBpbml0aWFsaXplZCB3aXRoIGV2ZW50ID09PSBcIlF1ZXJ5XCIsIHRoZSBjb3JyZXNwb25kaW5nIHVzZXIgcXVlcnkgbWVzc2FnZSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjaGF0IGhpc3RvcnlcbiAgICovXG4gIGxvYWREZWZhdWx0Q2hhdCgpIHtcbiAgICBjb25zdCBkYXRlID0gKG5ldyBEYXRlKCkpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgd2Vla2RheTogJ2xvbmcnLCBtb250aDogJ2xvbmcnLCBkYXk6ICcyLWRpZ2l0JywgeWVhcjogJ251bWVyaWMnIH0pO1xuICAgIC8vIERlZmluZSB0aGUgZGVmYXVsdCBzeXN0ZW0gcHJvbXB0IGFuZCB1c2VyIHByb21wdCBtZXNzYWdlc1xuICAgIGNvbnN0IHN5c3RlbU1zZyA9IHtcbiAgICAgIHJvbGU6ICdzeXN0ZW0nLFxuICAgICAgY29udGVudDogQXNzaXN0YW50VXRpbHMuZm9ybWF0UHJvbXB0KFxuICAgICAgICB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zeXN0ZW1Qcm9tcHQpLFxuICAgICAgICB7IHByaW5jaXBhbDogdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbCwgZGF0ZSB9XG4gICAgICApLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogZmFsc2UsIG1lc3NhZ2VJZDogZ3VpZCgpIH1cbiAgICB9O1xuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBvbGQgY29uZmlndXJhdGlvbiBmaWxlc1xuICAgIGNvbnN0IHVzZXJQcm9tcHQgPSB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnVzZXJQcm9tcHQucmVwbGFjZSgvXFx7XFx7KC4qPylcXH1cXH0vZywgJ1tbJDFdXScpO1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7XG4gICAgICByb2xlOiAndXNlcicsXG4gICAgICBjb250ZW50OiBBc3Npc3RhbnRVdGlscy5mb3JtYXRQcm9tcHQoXG4gICAgICAgIHRoaXMudHJhbnNsb2NvLnRyYW5zbGF0ZSh1c2VyUHJvbXB0KSxcbiAgICAgICAgeyBwcmluY2lwYWw6IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwsIGRhdGUgfVxuICAgICAgKSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdCwgbWVzc2FnZUlkOiBndWlkKCkgfVxuICAgIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmV2ZW50ID09PSAnUXVlcnknKSB7XG4gICAgICB0aGlzLl9oYW5kbGVRdWVyeU1vZGUoc3lzdGVtTXNnLCB1c2VyTXNnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faGFuZGxlUHJvbXB0TW9kZShzeXN0ZW1Nc2csIHVzZXJNc2cpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBwcm9tcHQgbW9kZSBvZiB0aGUgY2hhdCBjb21wb25lbnQuXG4gICAqIElmIGBzZW5kVXNlclByb21wdGAgaXMgdHJ1ZSwgaXQgb3BlbnMgdGhlIGNoYXQgd2l0aCBib3RoIHN5c3RlbSBhbmQgdXNlciBtZXNzYWdlcyxcbiAgICogYW5kIGdlbmVyYXRlcyBhdWRpdCBldmVudHMgZm9yIGJvdGggbWVzc2FnZXMuXG4gICAqIElmIGBzZW5kVXNlclByb21wdGAgaXMgZmFsc2UsIGl0IG9wZW5zIHRoZSBjaGF0IHdpdGggb25seSB0aGUgc3lzdGVtIG1lc3NhZ2UsXG4gICAqIGFuZCBnZW5lcmF0ZXMgYW4gYXVkaXQgZXZlbnQgZm9yIHRoZSBzeXN0ZW0gbWVzc2FnZS5cbiAgICpcbiAgICogQHBhcmFtIHN5c3RlbU1zZyAtIFRoZSBzeXN0ZW0gbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSB1c2VyTXNnIC0gVGhlIHVzZXIgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIGNoYXQgKG9wdGlvbmFsKS5cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZVByb21wdE1vZGUoc3lzdGVtTXNnOiBDaGF0TWVzc2FnZSwgdXNlck1zZzogQ2hhdE1lc3NhZ2UpIHtcbiAgICBpZiAodGhpcy5jb25maWcubW9kZVNldHRpbmdzLnNlbmRVc2VyUHJvbXB0KSB7XG4gICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHVzZXJNc2ddKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhzeXN0ZW1Nc2cpKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyTXNnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3BlbkNoYXQoW3N5c3RlbU1zZ10pO1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB0aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHN5c3RlbU1zZykpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBxdWVyeSBtb2RlIGJ5IGRpc3BsYXlpbmcgdGhlIHN5c3RlbSBtZXNzYWdlLCB1c2VyIG1lc3NhZ2UsIGFuZCB1c2VyIHF1ZXJ5IG1lc3NhZ2UuXG4gICAqIElmIHRoZSBwcm92aWRlZCBxdWVyeSB0ZXh0IGlzIG5vdCBlbXB0eSwgdGhlbiBhZGQgdGhlIHVzZXIgcXVlcnkgbWVzc2FnZSB0byB0aGUgY2hhdCBoaXN0b3J5IGFuZCBpbnZva2UgdGhlIGFzc2lzdGFudFxuICAgKiBPdGhlcndpc2UsIGp1c3Qgc3RhcnQgYSBuZXcgY2hhdCB3aXRoIGEgd2FybmluZyBtZXNzYWdlIGludml0aW5nIHRoZSB1c2VyIHRvIHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1xuICAgKiBAcGFyYW0gc3lzdGVtTXNnIC0gVGhlIHN5c3RlbSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICogQHBhcmFtIHVzZXJNc2cgLSBUaGUgdXNlciBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZVF1ZXJ5TW9kZShzeXN0ZW1Nc2c6IENoYXRNZXNzYWdlLCB1c2VyTXNnOiBDaGF0TWVzc2FnZSkge1xuICAgIGlmICghIXRoaXMucXVlcnkudGV4dCkge1xuICAgICAgY29uc3QgdXNlclF1ZXJ5TXNnID0geyByb2xlOiAndXNlcicsIGNvbnRlbnQ6IHRoaXMucXVlcnkudGV4dCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmRpc3BsYXlVc2VyUXVlcnksIG1lc3NhZ2VJZDogZ3VpZCgpLCBxdWVyeTogdGhpcy5xdWVyeSwgZm9yY2VkV29ya2Zsb3c6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRXb3JrZmxvdywgZm9yY2VkRnVuY3Rpb246IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRGdW5jdGlvbiwgaXNVc2VySW5wdXQ6IHRydWUsIGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXM6IHRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMgfSB9O1xuICAgICAgaWYgKHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5zZW5kVXNlclByb21wdCkge1xuICAgICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHVzZXJNc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMoc3lzdGVtTXNnKSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyTXNnKSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgeyAuLi50aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHVzZXJRdWVyeU1zZyksICdxdWVyeSc6IEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpLCAnaXMtdXNlci1pbnB1dCc6IHRydWUsICdmb3JjZWQtd29ya2Zsb3cnOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csICdmb3JjZWQtZnVuY3Rpb24nOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkRnVuY3Rpb24sICdlbmFibGVkLWZ1bmN0aW9ucyc6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuZnVuY3Rpb25zPy5maWx0ZXIoZnVuYyA9PiBmdW5jLmVuYWJsZWQpLm1hcChmdW5jID0+IGZ1bmMubmFtZSksICdhZGRpdGlvbmFsLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzKSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub3BlbkNoYXQoW3N5c3RlbU1zZywgdXNlclF1ZXJ5TXNnXSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhzeXN0ZW1Nc2cpKTtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB7IC4uLnRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHModXNlclF1ZXJ5TXNnKSwgJ3F1ZXJ5JzogSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSksICdpcy11c2VyLWlucHV0JzogdHJ1ZSwgJ2ZvcmNlZC13b3JrZmxvdyc6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRXb3JrZmxvdywgJ2ZvcmNlZC1mdW5jdGlvbic6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRGdW5jdGlvbiwgJ2VuYWJsZWQtZnVuY3Rpb25zJzogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5mdW5jdGlvbnM/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCkubWFwKGZ1bmMgPT4gZnVuYy5uYW1lKSwgJ2FkZGl0aW9uYWwtd29ya2Zsb3ctcHJvcGVydGllcyc6IEpTT04uc3RyaW5naWZ5KHRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMpIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB3YXJuaW5nTXNnID0geyByb2xlOiAnc2VhcmNoLXdhcm5pbmcnLCBjb250ZW50OiB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuZ2xvYmFsU2V0dGluZ3Muc2VhcmNoV2FybmluZ01lc3NhZ2UpLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHdhcm5pbmdNc2ddKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh3YXJuaW5nTXNnKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhtZXNzYWdlOiBDaGF0TWVzc2FnZSk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIGNvbnN0IGRldGFpbHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7XG4gICAgICAnZHVyYXRpb24nOiAwLFxuICAgICAgJ3JvbGUnOiBtZXNzYWdlLnJvbGUsXG4gICAgICAncmFuayc6IHJhbmssXG4gICAgICAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkXG4gICAgfTtcbiAgICBpZiAoISF0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzPy5sb2dDb250ZW50KSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGV0YWlscy50ZXh0ID0gbWVzc2FnZS5jb250ZW50O1xuICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2UuY29udGVudCkpIHtcbiAgICAgICAgZGV0YWlscy50ZXh0ID0gKG1lc3NhZ2UuY29udGVudC5maW5kKChtc2cpID0+IG1zZy50eXBlID09PSBcInRleHRcIikgYXMgVGV4dE1lc3NhZ2VDb250ZW50KS50ZXh0XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXRhaWxzO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0L29wZW4gYSBuZXcgY2hhdCB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlcyBhbmQgY2hhdElkXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgdXNlciwgYSByZXF1ZXN0IHRvIHRoZSBhc3Npc3RhbnQgaXMgbWFkZSB0byBnZXQgYW4gYW5zd2VyXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgYXNzaXN0YW50LCB0aGUgY29udmVyc2F0aW9uIGlzIGxvYWRlZCByaWdodCBhd2F5XG4gICAqIEBwYXJhbSBtZXNzYWdlcyBUaGUgbGlzdCBvZiBtZXNzYWdlcyBvZiB0aGUgY2hhdFxuICAgKiBAcGFyYW0gY2hhdElkICBUaGUgaWQgb2YgdGhlIGRpc2N1c3Npb24uIElmIHByb3ZpZGVkIChpZS4gYW4gZXhpc3RpbmcgZGlzY3Vzc2lvbiBpbiB0aGUgc2F2ZWQgY2hhdCBpbmRleCksIHVwZGF0ZSB0aGUgY2hhdElkIGluIHRoZSBjaGF0IHNlcnZpY2UgZm9yIHRoZSB1cGNvbWluZyBzYXZlZCBjaGF0IG9wZXJhdGlvbnNcbiAgICovXG4gIG9wZW5DaGF0KG1lc3NhZ2VzOiBSYXdNZXNzYWdlW10sIGNoYXRJZD86IHN0cmluZykge1xuICAgIGlmICghbWVzc2FnZXMgfHwgIUFycmF5LmlzQXJyYXkobWVzc2FnZXMpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cnMgd2hpbGUgdHJ5aW5nIHRvIGxvYWQgdGhlIGRpc2N1c3Npb24uIEludmFsaWQgbWVzc2FnZXMgcmVjZWl2ZWQgOicsIG1lc3NhZ2VzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNoYXRJZCkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZChjaGF0SWQpO1xuICAgIH1cbiAgICAvLyBFbnN1cmUgZWFjaCBtZXNzYWdlIGhhcyBhIHVuaXF1ZSBtZXNzYWdlSWRcbiAgICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBzcGVjaWFsbHkgaW4gY2FzZSB0aGUgYXNzaXN0YW50IGlzIHN0YXJ0ZWQgd2l0aCBhIHByZWRlZmluZWQgaGlzdG9yeSBPciBhbiBvbGQgc2F2ZWQgY2hhdFxuICAgIGNvbnN0IG1lc3NhZ2VzV2l0aElkczogQ2hhdE1lc3NhZ2VbXSA9IG1lc3NhZ2VzLm1hcCgobXNnKSA9PiB7XG4gICAgICBtc2cuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkID8/PSBndWlkKCk7XG4gICAgICByZXR1cm4gbXNnIGFzIENoYXRNZXNzYWdlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZXNldENoYXQoKTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzV2l0aElkcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IG1lc3NhZ2VzV2l0aElkcztcbiAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG1lc3NhZ2VzLmF0KC0xKTtcbiAgICBpZiAobGFzdE1lc3NhZ2UgJiYgbGFzdE1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInKSB7XG4gICAgICB0aGlzLmZldGNoKG1lc3NhZ2VzV2l0aElkcyk7IC8vIElmIHRoZSBsYXN0IG1lc3NhZ2UgaWYgZnJvbSBhIHVzZXIsIGFuIGFuc3dlciBmcm9tIHRoZSBhc3Npc3RhbnQgaXMgZXhwZWN0ZWRcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGEobWVzc2FnZXNXaXRoSWRzKTsgLy8gSWYgdGhlIGxhc3QgbWVzc2FnZSBpZiBmcm9tIHRoZSBhc3Npc3RhbnQsIHdlIGNhbiBsb2FkIHRoZSBjb252ZXJzYXRpb24gcmlnaHQgYXdheVxuICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgIH1cbiAgICB0aGlzLl9hZGRTY3JvbGxMaXN0ZW5lcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBjaGF0IGJ5IGNsZWFyaW5nIHRoZSBjaGF0IGhpc3RvcnkgYW5kIHRoZSBVSSBhY2NvcmRpbmdseVxuICAgKiBUaGUgdXNlciBpbnB1dCB3aWxsIGJlIGNsZWFyZWRcbiAgICogVGhlIGZldGNoIHN1YnNjcmlwdGlvbiB3aWxsIGJlIHRlcm1pbmF0ZWRcbiAgICovXG4gIHJlc2V0Q2hhdCgpIHtcbiAgICBpZiAodGhpcy5tZXNzYWdlcyQudmFsdWUpIHtcbiAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodW5kZWZpbmVkKTsgLy8gUmVzZXQgY2hhdFxuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdW5kZWZpbmVkOyAvLyBSZXNldCBjaGF0IGhpc3RvcnlcbiAgICB0aGlzLnF1ZXN0aW9uID0gJyc7XG4gICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGFuZCBMb2FkIHRoZSBzYXZlZCBjaGF0IGZyb20gdGhlIHNhdmVkIGNoYXQgaW5kZXguXG4gICAqIElmIHRoZSBzYXZlZCBjaGF0IGlzIGZvdW5kLCB0aGUgY2hhdCBkaXNjdXNzaW9uIHdpbGwgYmUgbG9hZGVkIHdpdGggdGhlIHByb3ZpZGVkIG1lc3NhZ2VzIGFuZCBjaGF0SWRcbiAgICovXG4gIG9uTG9hZENoYXQoKSB7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KHRydWUpO1xuICAgIHRoaXMuX3N1Yi5hZGQoXG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxvYWRTYXZlZENoYXQkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIGZpbHRlcihzYXZlZENoYXQgPT4gISFzYXZlZENoYXQpLFxuICAgICAgICAgIHN3aXRjaE1hcChzYXZlZENoYXQgPT4gdGhpcy5jaGF0U2VydmljZS5nZXRTYXZlZENoYXQoc2F2ZWRDaGF0IS5pZCkpLFxuICAgICAgICAgIGZpbHRlcihzYXZlZENoYXRIaXN0b3J5ID0+ICEhc2F2ZWRDaGF0SGlzdG9yeSksXG4gICAgICAgICAgdGFwKHNhdmVkQ2hhdEhpc3RvcnkgPT4gdGhpcy5vcGVuQ2hhdChzYXZlZENoYXRIaXN0b3J5IS5oaXN0b3J5LCBzYXZlZENoYXRIaXN0b3J5IS5pZCkpXG4gICAgICAgICkuc3Vic2NyaWJlKClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3AgdGhlIGdlbmVyYXRpb24gb2YgdGhlIGN1cnJlbnQgYXNzaXN0YW50J3MgYW5zd2VyLlxuICAgKiBUaGUgZmV0Y2ggc3Vic2NyaXB0aW9uIHdpbGwgYmUgdGVybWluYXRlZC5cbiAgICovXG4gIHN0b3BHZW5lcmF0aW9uKCkge1xuICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RvcEdlbmVyYXRpb24oKS5zdWJzY3JpYmUoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSB0aGUgbGFzdCBtZXNzYWdlIGlmIGl0J3MgYW4gZW1wdHkgbWVzc2FnZVxuICAgICAgICAvLyBUaGlzIGlzIGR1ZSB0byB0aGUgbWFubmVyIGluIHdoaWNoIHRoZSBjaGF0IHNlcnZpY2UgaGFuZGxlcyBjb25zZWN1dGl2ZSBtZXNzYWdlc1xuICAgICAgICBjb25zdCBsYXN0TWVzc2FnZSA9IHRoaXMubWVzc2FnZXMkLnZhbHVlPy5hdCgtMSk7XG4gICAgICAgIGlmICh0aGlzLmlzRW1wdHlBc3Npc3RhbnRNZXNzYWdlKGxhc3RNZXNzYWdlKSkge1xuICAgICAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodGhpcy5tZXNzYWdlcyQudmFsdWU/LnNsaWNlKDAsIC0xKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGVybWluYXRlIHRoZSBmZXRjaCBwcm9jZXNzIGJ5IHVuc3Vic2NyaWJpbmcgZnJvbSB0aGUgZGF0YSBzdWJzY3JpcHRpb24gYW5kIHVwZGF0aW5nIHRoZSBsb2FkaW5nIHN0YXR1cyB0byBmYWxzZS5cbiAgICogQWRkaXRpb25hbGx5LCBmb2N1cyBvbiB0aGUgY2hhdCBpbnB1dCBpZiB0aGUgZm9jdXNBZnRlclJlc3BvbnNlIGZsYWcgaXMgc2V0IHRvIHRydWUuXG4gICAqL1xuICB0ZXJtaW5hdGVGZXRjaCgpIHtcbiAgICB0aGlzLl9kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX2RhdGFTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KGZhbHNlKTtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG5cbiAgICBpZiAodGhpcy5mb2N1c0FmdGVyUmVzcG9uc2UpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnF1ZXN0aW9uSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb3B5IGEgcHJldmlvdXMgdXNlciBtZXNzYWdlIG9mIHRoZSBjaGF0IGhpc3RvcnkgdG8gdGhlIGNoYXQgdXNlciBpbnB1dC5cbiAgICogVGh1cywgdGhlIHVzZXIgY2FuIGVkaXQgYW5kIHJlc3VibWl0IHRoZSBtZXNzYWdlLlxuICAgKiBPbmNlIHRoZSBlZGl0ZWQgbWVzc2FnZSBpcyBzdWJtaXR0ZWQsIGFsbCBzdWJzZXF1ZW50IG1lc3NhZ2VzIHN0YXJ0aW5nIGZyb20gQHBhcmFtIGluZGV4IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBoaXN0b3J5IGFuZCB0aGUgVUkgd2lsbCBiZSB1cGRhdGVkIGFjY29yZGluZ2x5LlxuICAgKiBUaGUgYXNzaXN0YW50IHdpbGwgcmVnZW5lcmF0ZSBhIG5ldyBhbnN3ZXIgYmFzZWQgb24gdGhlIHVwZGF0ZWQgY2hhdCBoaXN0b3J5LlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSB1c2VyJ3MgbWVzc2FnZSB0byBlZGl0XG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHVzZXIncyBtZXNzYWdlIHRvIGVkaXRcbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgZWRpdE1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pbmRleE1lc3NhZ2VUb0VkaXQgPSBpbmRleDtcbiAgICB0aGlzLnJhbmtNZXNzYWdlVG9FZGl0ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcblxuICAgIC8vIEdldCB1c2VyIG1lc3NhZ2UgZnJvbSBib3RoIGxlZ2FjeSBhbmQgdGV4dCBtZXNzYWdlIHR5cGVcbiAgICB0aGlzLnF1ZXN0aW9uID0gdHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZycgPyBtZXNzYWdlLmNvbnRlbnQgOiAobWVzc2FnZS5jb250ZW50WzBdIGFzIFRleHRNZXNzYWdlQ29udGVudCkudGV4dDtcblxuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtZWRpdC5jbGljaycsIHsncmFuayc6IHRoaXMucmFua01lc3NhZ2VUb0VkaXQsICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWR9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3B5IGEgcHJldmlvdXMgYXNzaXN0YW50IG1lc3NhZ2Ugb2YgdGhlIGNoYXQgaGlzdG9yeSB0byB0aGUgY2xpcGJvYXJkLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBjb3B5XG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG1lc3NhZ2UgdG8gY29weVxuICAgKiBAcmV0dXJucyB2b2lkXG4gICAqL1xuICBjb3B5TWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcikge1xuICAgIC8vIFJlbWFwIHRoZSBpbmRleCBpbiB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jb3B5LmNsaWNrJywgeyAncmFuayc6IHJhbmssICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRpbmcgZnJvbSB0aGUgcHJvdmlkZWQgaW5kZXgsIHJlbW92ZSBhbGwgc3Vic2VxdWVudCBtZXNzYWdlcyBmcm9tIHRoZSBjaGF0IGhpc3RvcnkgYW5kIHRoZSBVSSBhY2NvcmRpbmdseS5cbiAgICogVGhlIGFzc2lzdGFudCB3aWxsIHJlZ2VuZXJhdGUgYSBuZXcgYW5zd2VyIGJhc2VkIG9uIHRoZSB1cGRhdGVkIGNoYXQgaGlzdG9yeS5cbiAgICog4pqg77iPIElmIHRoZSBhc3Npc3RhbnQgaXMgc3RyZWFtaW5nIG9yIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgYXNzaXN0YW50J3MgbWVzc2FnZSB0byByZWdlbmVyYXRlXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGFzc2lzdGFudCdzIG1lc3NhZ2UgdG8gcmVnZW5lcmF0ZVxuICAgKi9cbiAgcmVnZW5lcmF0ZU1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUkgYnkgcmVtb3ZpbmcgYWxsIHN1YnNlcXVlbnQgJ2Fzc2lzdGFudCcgbWVzc2FnZXMgc3RhcnRpbmcgZnJvbSB0aGUgcHJvdmlkZWQgaW5kZXggdW50aWwgdGhlIGZpcnN0IHByZXZpb3VzICd1c2VyJyBtZXNzYWdlXG4gICAgbGV0IGkgPSBpbmRleDtcbiAgICB3aGlsZSAoaSA+PSAwICYmICEoKHRoaXMubWVzc2FnZXMkLnZhbHVlISlbaV0ucm9sZSA9PT0gJ3VzZXInICYmICh0aGlzLm1lc3NhZ2VzJC52YWx1ZSEpW2ldLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLmlzVXNlcklucHV0ID09PSB0cnVlKSkge1xuICAgICAgaS0tO1xuICAgIH1cbiAgICAvLyBJdCBzaG91bGQgYWx3YXlzIGJlIHRoZSBjYXNlIHRoYXQgaSA+IDBcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCBpICsgMSkpO1xuICAgICAgLy8gUmFuayBvZiB0aGlzIGZvdW5kIGZpcnN0IHByZXZpb3VzICd1c2VyJyBtZXNzYWdlIGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICAgIGNvbnN0IHJhbmtGaXJzdFByZXZpb3VzVXNlck1lc3NhZ2UgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgdGhpcy5tZXNzYWdlcyQudmFsdWUhW2ldLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgICAvLyBSYW5rIG9mIHRoZSBhc3Npc3RhbnQncyBtZXNzYWdlIG9uIHdoaWNoIHRoZSB1c2VyIGNsaWNrZWQgdG8gcmVnZW5lcmF0ZVxuICAgICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgICAvLyBEZWZpbmUgYW5kIFVwZGF0ZSB0aGUgY2hhdCBoaXN0b3J5IGJhc2VkIG9uIHdoaWNoIHRoZSBhc3Npc3RhbnQgd2lsbCBnZW5lcmF0ZSBhIG5ldyBhbnN3ZXJcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IS5zbGljZSgwLCByYW5rRmlyc3RQcmV2aW91c1VzZXJNZXNzYWdlKTtcbiAgICAgIC8vIEZldGNoIHRoZSBhbnN3ZXJcbiAgICAgIHRoaXMuZmV0Y2godGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSk7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LXJlZ2VuZXJhdGUuY2xpY2snLCB7ICdyYW5rJzogcmFuaywgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUga2V5IHVwIGV2ZW50IGZvciAnQmFja3NwYWNlJyBhbmQgJ0VudGVyJyBrZXlzLlxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUga2V5Ym9hcmQgZXZlbnQuXG4gICAqL1xuICBvbktleVVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0JhY2tzcGFjZSc6XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlSGVpZ2h0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgICBpZiAoIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLnN1Ym1pdFF1ZXN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jYWxjdWxhdGVIZWlnaHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyBhbmQgYWRqdXN0cyB0aGUgaGVpZ2h0IG9mIHRoZSBxdWVzdGlvbiBpbnB1dCBlbGVtZW50IGJhc2VkIG9uIGl0cyBjb250ZW50LlxuICAgKiBJZiB0aGUgRW50ZXIga2V5IGlzIHByZXNzZWQgd2l0aG91dCB0aGUgU2hpZnQga2V5LCBpdCBwcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvci5cbiAgICogQHBhcmFtIGV2ZW50IFRoZSBrZXlib2FyZCBldmVudFxuICAgKi9cbiAgY2FsY3VsYXRlSGVpZ2h0KGV2ZW50PzogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudD8ua2V5ID09PSAnRW50ZXInICYmICFldmVudC5zaGlmdEtleSkge1xuICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGNvbnN0IG1heEhlaWdodCA9IDE3MDtcbiAgICBjb25zdCBlbCA9IHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudDtcbiAgICBlbC5zdHlsZS5tYXhIZWlnaHQgPSBgJHttYXhIZWlnaHR9cHhgO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9ICdhdXRvJztcbiAgICBlbC5zdHlsZS5oZWlnaHQgPSBgJHtlbC5zY3JvbGxIZWlnaHR9cHhgO1xuICAgIGVsLnN0eWxlLm92ZXJmbG93WSA9IGVsLnNjcm9sbEhlaWdodCA+PSBtYXhIZWlnaHQgPyAnc2Nyb2xsJyA6ICdoaWRkZW4nO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSBcImxpa2VcIiBldmVudCBvbiBjbGlja2luZyBvbiB0aGUgdGh1bWItdXAgaWNvbiBvZiBhbiBhc3Npc3RhbnQncyBtZXNzYWdlXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBhc3Npc3RhbnQgbWVzc2FnZSB0byBsaWtlXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG1lc3NhZ2UgdG8gbGlrZVxuICAgKi9cbiAgb25MaWtlKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgLy8gUmVtYXAgdGhlIGluZGV4IGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LXRodW1iLXVwLmNsaWNrJywgeyAncmFuayc6IHJhbmssICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQgfSk7XG4gICAgdGhpcy5yZXBvcnRUeXBlID0gJ2xpa2UnO1xuICAgIHRoaXMubWVzc2FnZVRvUmVwb3J0ID0gbWVzc2FnZTtcbiAgICB0aGlzLnJlcG9ydENvbW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yZXBvcnRSYW5rID0gcmFuaztcbiAgICB0aGlzLnNob3dSZXBvcnQgPSB0cnVlXG5cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZCA9IHRydWU7XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSFbcmFuay0xXS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGlzbGlrZWQgPSBmYWxzZTtcbiAgICB0aGlzLl91cGRhdGVDaGF0SGlzdG9yeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSBcImRpc2xpa2VcIiBldmVudCBvbiBjbGlja2luZyBvbiB0aGUgdGh1bWItZG93biBpY29uIG9mIGFuIGFzc2lzdGFudCdzIG1lc3NhZ2UuXG4gICAqIEl0IGFsc28gb3BlbnMgdGhlIGlzc3VlIHJlcG9ydGluZyBkaWFsb2cuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBhc3Npc3RhbnQgbWVzc2FnZSB0byBkaXNsaWtlXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgcmFuayBvZiB0aGUgbWVzc2FnZSB0byBkaXNsaWtlXG4gICAqL1xuICBvbkRpc2xpa2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBSZW1hcCB0aGUgaW5kZXggaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtdGh1bWItZG93bi5jbGljaycsIHsgJ3JhbmsnOiByYW5rLCAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkIH0pO1xuICAgIHRoaXMucmVwb3J0VHlwZSA9ICdkaXNsaWtlJztcbiAgICB0aGlzLm1lc3NhZ2VUb1JlcG9ydCA9IG1lc3NhZ2U7XG4gICAgdGhpcy5pc3N1ZVR5cGUgPSAnJztcbiAgICB0aGlzLnJlcG9ydENvbW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yZXBvcnRSYW5rID0gcmFuaztcbiAgICB0aGlzLnNob3dSZXBvcnQgPSB0cnVlXG5cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZCA9IHRydWU7XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSFbcmFuay0xXS5hZGRpdGlvbmFsUHJvcGVydGllcy4kbGlrZWQgPSBmYWxzZTtcbiAgICB0aGlzLl91cGRhdGVDaGF0SGlzdG9yeSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlQ2hhdEhpc3RvcnkoKTogdm9pZCB7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICBpZiAodGhpcy5jb25maWcuc2F2ZWRDaGF0U2V0dGluZ3MuZW5hYmxlZCkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS51cGRhdGVTYXZlZENoYXQodGhpcy5jaGF0U2VydmljZS5jaGF0SWQsIHVuZGVmaW5lZCwgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSkuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBvcnQgYW4gaXNzdWUgcmVsYXRlZCB0byB0aGUgYXNzaXN0YW50J3MgbWVzc2FnZS5cbiAgICovXG4gIHNlbmRSZXBvcnQoKTogdm9pZCB7XG4gICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICdjb21tZW50JzogdGhpcy5yZXBvcnRDb21tZW50LFxuICAgICAgJ3JhbmsnOiB0aGlzLnJlcG9ydFJhbmtcbiAgICB9O1xuXG4gICAgLy9jaGVjayBpZiB0aGUgbWVzc2FnZSB0byByZXBvcnQgaXMgZGVmaW5lZC4gSXQgc2hvdWxkIGFsd2F5cyBiZSB0aGUgY2FzZVxuICAgIGlmICh0aGlzLm1lc3NhZ2VUb1JlcG9ydCkge1xuICAgICAgZGV0YWlsc1snbWVzc2FnZS1pZCddID0gdGhpcy5tZXNzYWdlVG9SZXBvcnQuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkO1xuICAgIH1cblxuICAgIC8vIGhpZGUgdGV4dCBpbiBjYXNlIGxvZ0NvbnRlbnQgaXMgbm90IGVuYWJsZWRcbiAgICBpZiAodGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncy5sb2dDb250ZW50KVxuICAgICAgZGV0YWlsc1sndGV4dCddID0gdGhpcy5tZXNzYWdlVG9SZXBvcnQhLmNvbnRlbnQ7XG5cbiAgICBpZiAodGhpcy5yZXBvcnRUeXBlID09PSAnZGlzbGlrZScpIHtcbiAgICAgIGRldGFpbHNbJ3JlcG9ydC10eXBlJ10gPSB0aGlzLmlzc3VlVHlwZTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbmVnYXRpdmUtcmVwb3J0LnNlbmQnLCBkZXRhaWxzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1wb3NpdGl2ZS1yZXBvcnQuc2VuZCcsIGRldGFpbHMpO1xuICAgIH1cbiAgICB0aGlzLm5vdGlmaWNhdGlvbnNTZXJ2aWNlLnN1Y2Nlc3ModGhpcy50cmFuc2xvY28udHJhbnNsYXRlKCdjaGF0LnNlbmRSZXBvcnROb3RpZmljYXRpb24nKSk7XG4gICAgdGhpcy5zaG93UmVwb3J0ID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgdGhlIHJlcG9ydGluZyBkaWFsb2cuXG4gICAqL1xuICBpZ25vcmVSZXBvcnQoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93UmVwb3J0ID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBjbGljayBvbiBhIHJlZmVyZW5jZSdzICdvcGVuIHByZXZpZXcnLlxuICAgKiBAcGFyYW0gZGF0YVxuICAgKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSByZWZlcmVuY2VcbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHJlZmVyZW5jZVxuICAgKiBAcmV0dXJucyB2b2lkXG4gICAqL1xuICBvcGVuQXR0YWNobWVudFByZXZpZXcoZGF0YTogeyByZWZlcmVuY2U6IENoYXRDb250ZXh0QXR0YWNobWVudCwgcGFydElkPzogbnVtYmVyIH0sIG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5vcGVuUHJldmlldy5lbWl0KGRhdGEucmVmZXJlbmNlKTtcbiAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICBjb25zdCBkZXRhaWxzID0ge1xuICAgICAgJ2RvYy1pZCc6IGRhdGEucmVmZXJlbmNlLnJlY29yZElkLFxuICAgICAgJ3NvdXJjZSc6IGRhdGEucmVmZXJlbmNlLnJlY29yZC50cmVlcGF0aCxcbiAgICAgICdjb2xsZWN0aW9uJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLmNvbGxlY3Rpb24sXG4gICAgICAnaW5kZXgnOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQuZGF0YWJhc2VhbGlhcyxcbiAgICAgICdyYW5rJzogcmFuayxcbiAgICAgICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWRcbiAgICB9O1xuICAgIGlmICghIWRhdGEucGFydElkKSBkZXRhaWxzWydwYXJ0LWlkJ10gPSBkYXRhLnBhcnRJZDtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWF0dGFjaG1lbnQucHJldmlldy5jbGljaycsIGRldGFpbHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB0aGUgY2xpY2sgb24gYSByZWZlcmVuY2UncyAnb3BlbiBvcmlnaW5hbCBkb2N1bWVudCcuXG4gICAqIEBwYXJhbSBkYXRhXG4gICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHJlZmVyZW5jZVxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgcmVmZXJlbmNlXG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIG9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoZGF0YTogeyByZWZlcmVuY2U6IENoYXRDb250ZXh0QXR0YWNobWVudCwgcGFydElkPzogbnVtYmVyIH0sIG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5vcGVuRG9jdW1lbnQuZW1pdChkYXRhLnJlZmVyZW5jZS5yZWNvcmQpO1xuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAnZG9jLWlkJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkSWQsXG4gICAgICAnc291cmNlJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLnRyZWVwYXRoLFxuICAgICAgJ2NvbGxlY3Rpb24nOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQuY29sbGVjdGlvbixcbiAgICAgICdpbmRleCc6IGRhdGEucmVmZXJlbmNlLnJlY29yZC5kYXRhYmFzZWFsaWFzLFxuICAgICAgJ3JhbmsnOiByYW5rLFxuICAgICAgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZFxuICAgIH07XG4gICAgaWYgKCEhZGF0YS5wYXJ0SWQpIGRldGFpbHNbJ3BhcnQtaWQnXSA9IGRhdGEucGFydElkO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtYXR0YWNobWVudC5saW5rLmNsaWNrJywgZGV0YWlscyk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBjbGljayBvbiBhIHN1Z2dlc3RlZCBhY3Rpb24uXG4gICAqIEBwYXJhbSBhY3Rpb24gU3VnZ2VzdGVkIGFjdGlvbi5cbiAgICogQHBhcmFtIGluZGV4IGluZGV4IG9mIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHN1Z2dlc3RlZCBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIHN1Z2dlc3RBY3Rpb25DbGljayhhY3Rpb246IFN1Z2dlc3RlZEFjdGlvbiwgaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuc3VnZ2VzdEFjdGlvbi5lbWl0KGFjdGlvbik7XG4gICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICd0ZXh0JzogYWN0aW9uLmNvbnRlbnQsXG4gICAgICAnc3VnZ2VzdGVkQWN0aW9uLXR5cGUnOiBhY3Rpb24udHlwZVxuICAgIH07XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1zdWdnZXN0ZWQtYWN0aW9uLmNsaWNrJywgZGV0YWlscyk7XG4gIH1cblxuICAvKipcbiAgICogSXQgbG9va3MgZm9yIHRoZSBkZWJ1ZyBtZXNzYWdlcyBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgZ3JvdXAgb2YgXCJhc3Npc3RhbnRcIiBtZXNzYWdlcy5cbiAgICogQnkgZGVzaWduLCB0aGUgZGVidWcgbWVzc2FnZXMgYXJlIG9ubHkgYXZhaWxhYmxlIGluIHRoZSBmaXJzdCB2aXNpYmxlIG1lc3NhZ2UgYW1vbmcgdGhlIGdyb3VwIG9mIFwiYXNzaXN0YW50XCIgbWVzc2FnZXMuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIGRlYnVnIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG1lc3NhZ2VcbiAgICogQHJldHVybnMgVGhlIGRlYnVnIG1lc3NhZ2VzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBncm91cCBvZiBcImFzc2lzdGFudFwiIG1lc3NhZ2VzXG4gICAqL1xuICBnZXREZWJ1Z01lc3NhZ2VzKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKTogRGVidWdNZXNzYWdlW10ge1xuICAgIC8vIElmIGl0IGlzIG5vdCBhbiBhc3Npc3RhbnQgbWVzc2FnZSwgcmV0dXJuIGFuIGVtcHR5IGFycmF5XG4gICAgaWYgKG1lc3NhZ2Uucm9sZSAhPT0gJ2Fzc2lzdGFudCcpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLy8gR2V0IHRoZSBhcnJheSBvZiBtZXNzYWdlcyB1cCB0byB0aGUgaW5kaWNhdGVkIGluZGV4XG4gICAgY29uc3QgYXJyYXkgPSB0aGlzLm1lc3NhZ2VzJC52YWx1ZSEuc2xpY2UoMCwgaW5kZXggKyAxKTtcbiAgICAvLyBJZiBpdCBpcyBhbiBhc3Npc3RhbnQgbWVzc2FnZSwgbG9vayBmb3IgdGhlIGRlYnVnIG1lc3NhZ2VzIGF2YWlsYWJsZSBpbiB0aGUgY3VycmVudCBncm91cCBvZiBcImFzc2lzdGFudFwiIG1lc3NhZ2VzXG4gICAgLy8gQnkgZGVzaWduLCB0aGUgZGVidWcgbWVzc2FnZXMgYXJlIG9ubHkgYXZhaWxhYmxlIGluIHRoZSBmaXJzdCB2aXNpYmxlIG1lc3NhZ2UgYW1vbmcgdGhlIGdyb3VwIFwiYXNzaXN0YW50XCIgbWVzc2FnZXMuXG4gICAgY29uc3QgaWR4ID0gdGhpcy5hc3Npc3RhbnRVdGlscy5maXJzdFZpc2libGVBc3Npc3RhbnRNZXNzYWdlSW5kZXgoYXJyYXkpO1xuICAgIGlmIChpZHggPiAtMSkge1xuICAgICAgcmV0dXJuICh0aGlzLm1lc3NhZ2VzJC52YWx1ZSEpW2lkeF0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGRlYnVnIHx8IFtdO1xuICAgIH1cbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBjbGljayBvbiB0aGUgJ3Nob3cgbG9nIGluZm8nIGJ1dHRvbiBvZiBhIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIGRlYnVnIGluZm9ybWF0aW9uXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG1lc3NhZ2VcbiAgICovXG4gIHNob3dEZWJ1ZyhtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZGVidWdNZXNzYWdlcyA9IHRoaXMuZ2V0RGVidWdNZXNzYWdlcyhtZXNzYWdlLCBpbmRleCk7XG4gICAgdGhpcy5zaG93RGVidWdNZXNzYWdlcyA9IHRydWU7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSB3aGV0aGVyIHRoZSBjdXJyZW50IG1lc3NhZ2UgaXMgYW4gYXNzaXN0YW50IG1lc3NhZ2UgYW5kIHRoYXQgYWxsIGZvbGxvd2luZyBtZXNzYWdlcyBhcmUgYXNzaXN0YW50IG9uZXNcbiAgICogVXNlZCB0byBrZWVwIHRoZSBcIlZpZXcgcHJvZ3Jlc3NcIiBvcGVuZWQgZXZlbiB0aG91Z2ggdGhlIGFzc2lzdGFudCBpcyBzZW5kaW5nIGFkZGl0aW9uYWwgbWVzc2FnZXMgYWZ0ZXIgdGhlIGN1cnJlbnQgb25lXG4gICAqIEBwYXJhbSBtZXNzYWdlcyB0aGUgbGlzdCBvZiBjdXJyZW50IG1lc3NhZ2VzXG4gICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgbWVzc2FnZVxuICAgKiBAcmV0dXJucyBpZiB0aGlzIG1lc3NhZ2VzIGFuZCB0aGUgZm9sbG93aW5nIG9uZXMgKGlmIGFueSkgYXJlIHRoZSBsYXN0IG9uZXNcbiAgICovXG4gIGlzQXNzaXN0YW50TGFzdE1lc3NhZ2VzKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdLCBpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgZm9yIChsZXQgaSA9IGluZGV4OyBpIDwgbWVzc2FnZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChtZXNzYWdlc1tpXS5yb2xlICE9PSAnYXNzaXN0YW50JykgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGdpdmVuIG1lc3NhZ2UgaXMgYW4gZW1wdHkgYXNzaXN0YW50IG1lc3NhZ2UuXG4gICAqIEFuIGVtcHR5IGFzc2lzdGFudCBtZXNzYWdlIGlzIGRlZmluZWQgYXMgYSBtZXNzYWdlIHdpdGggdGhlIHJvbGUgJ2Fzc2lzdGFudCcsXG4gICAqIGFuIGVtcHR5IGNvbnRlbnQsIGFuZCBubyBhZGRpdGlvbmFsIHByb3BlcnRpZXMgc3VjaCBhcyBhdHRhY2htZW50cywgcHJvZ3Jlc3MsXG4gICAqIGRlYnVnIGluZm9ybWF0aW9uLCBvciBzdWdnZXN0ZWQgYWN0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBjaGVjay5cbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBtZXNzYWdlIGlzIGFuIGVtcHR5IGFzc2lzdGFudCBtZXNzYWdlLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICovXG4gIGlzRW1wdHlBc3Npc3RhbnRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgaWYgKFxuICAgICAgbWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCdcbiAgICAgICYmIChcbiAgICAgICAgLy8gTGVnYWN5IG1lc3NhZ2UgdHlwZVxuICAgICAgICAodHlwZW9mIG1lc3NhZ2U/LmNvbnRlbnQgPT09ICdzdHJpbmcnICYmIG1lc3NhZ2U/LmNvbnRlbnQgPT09IFwiXCIpXG4gICAgICAgIC8vIE5ldyBtZXNzYWdlIHR5cGVcbiAgICAgICAgLy8gLSBUZXh0XG4gICAgICAgIHx8ICgobWVzc2FnZT8uY29udGVudCBhcyBSYXdNZXNzYWdlQ29udGVudCk/LlswXSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpPy50ZXh0ID09PSBcIlwiXG4gICAgICAgIC8vIFRPRE86IGltYWdlIGFuZCB2aWRlbyBtZXNzYWdlIHR5cGVzIGh0dHBzOi8vc2luZXF1YS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9FUy0yNTk0MFxuICAgICAgKVxuICAgICAgJiYgIW1lc3NhZ2U/LmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy4kYXR0YWNobWVudFxuICAgICAgJiYgIW1lc3NhZ2U/LmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy4kcHJvZ3Jlc3NcbiAgICAgICYmICFtZXNzYWdlPy5hZGRpdGlvbmFsUHJvcGVydGllcz8uJGRlYnVnXG4gICAgICAmJiAhbWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXM/LiRzdWdnZXN0ZWRBY3Rpb25cbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhaW5pdGlhbGl6YXRpb25FcnJvclwiPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZXMkIHwgYXN5bmMgYXMgbWVzc2FnZXM7IGVsc2UgbG9hZGluZ1RwbCB8fCBsb2FkaW5nVHBsRGVmYXVsdFwiIGNsYXNzPVwiaC0xMDAgZC1mbGV4IGZsZXgtY29sdW1uXCI+XG4gICAgPCEtLSBUb2tlbiBjb25zdW1wdGlvbiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwibXMtMVwiICpuZ0lmPVwiY29uZmlnPy5nbG9iYWxTZXR0aW5ncz8uZGlzcGxheVVzZXJRdW90YUNvbnN1bXB0aW9uIHx8IGNvbmZpZz8uZ2xvYmFsU2V0dGluZ3M/LmRpc3BsYXlDaGF0VG9rZW5zQ29uc3VtcHRpb25cIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0b2tlbkNvbnN1bXB0aW9uVHBsIHx8IGRlZmF1bHRUb2tlbkNvbnN1bXB0aW9uVHBsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogaW5zdGFuY2VJZCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIENoYXQgTWVzc2FnZXMgLS0+XG4gICAgPHVsIGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGxpc3QtdW5zdHlsZWQgZ2FwLTMgb3ZlcmZsb3ctYXV0byBmbGV4LWdyb3ctMSBwZS0yIHBiLTJcIiAjbWVzc2FnZUxpc3Q+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBtZXNzYWdlIG9mIG1lc3NhZ2VzOyBsZXQgaW5kZXggPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgIDwhLS0gUmVndWxhciBtZXNzYWdlcyAtLT5cbiAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtXCJcbiAgICAgICAgICAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuZGlzcGxheSAmJiAhaXNFbXB0eUFzc2lzdGFudE1lc3NhZ2UobWVzc2FnZSlcIlxuICAgICAgICAgIFtzdHlsZS4tLWJzLWxpc3QtZ3JvdXAtaXRlbS1wYWRkaW5nLXkucmVtXT1cIicwLjYnXCJcbiAgICAgICAgICBbY2xhc3Mub3BhY2l0eS01MF09XCJpbmRleE1lc3NhZ2VUb0VkaXQgJiYgKGluZGV4TWVzc2FnZVRvRWRpdCA8IChpbmRleCArIDEpKVwiPlxuICAgICAgICAgIDxzcS1jaGF0LW1lc3NhZ2VcbiAgICAgICAgICAgIFtpZF09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZFwiXG4gICAgICAgICAgICBbY2xhc3Muc3EtdXNlci1tZXNzYWdlXT1cIm1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInXCJcbiAgICAgICAgICAgIFtjbGFzcy5sYXN0LW1lc3NhZ2VdPVwibGFzdFwiXG4gICAgICAgICAgICBbbWVzc2FnZV09XCJtZXNzYWdlXCJcbiAgICAgICAgICAgIFtjb252ZXJzYXRpb25dPVwibWVzc2FnZXNcIlxuICAgICAgICAgICAgW3N1Z2dlc3RlZEFjdGlvbnNdPVwibGFzdCA/IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJHN1Z2dlc3RlZEFjdGlvbiA6IHVuZGVmaW5lZFwiXG4gICAgICAgICAgICBbYXNzaXN0YW50TWVzc2FnZUljb25dPVwiYXNzaXN0YW50TWVzc2FnZUljb25cIlxuICAgICAgICAgICAgW3VzZXJNZXNzYWdlSWNvbl09XCJ1c2VyTWVzc2FnZUljb25cIlxuICAgICAgICAgICAgW2Nvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXT1cImNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXCJcbiAgICAgICAgICAgIFtzZWFyY2hXYXJuaW5nTWVzc2FnZUljb25dPVwic2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXCJcbiAgICAgICAgICAgIFtzdHJlYW1pbmddPVwiKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgJiYgKGxhc3QgfHwgaXNBc3Npc3RhbnRMYXN0TWVzc2FnZXMobWVzc2FnZXMsIGluZGV4KSlcIlxuICAgICAgICAgICAgW2NhbkVkaXRdPVwiKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIGluZGV4TWVzc2FnZVRvRWRpdCA9PT0gdW5kZWZpbmVkICYmIG1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInXCJcbiAgICAgICAgICAgIFtjYW5Db3B5XT1cIigoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgfHwgIWxhc3QpICYmIGluZGV4TWVzc2FnZVRvRWRpdCA9PT0gdW5kZWZpbmVkICYmIG1lc3NhZ2Uucm9sZSAhPT0gJ2Nvbm5lY3Rpb24tZXJyb3InICYmIG1lc3NhZ2Uucm9sZSAhPT0gJ3NlYXJjaC13YXJuaW5nJ1wiXG4gICAgICAgICAgICBbY2FuTGlrZV09XCIoKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlIHx8ICFsYXN0KSAmJiBtZXNzYWdlLnJvbGUgPT09ICdhc3Npc3RhbnQnXCJcbiAgICAgICAgICAgIFtjYW5EaXNsaWtlXT1cIigoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgfHwgIWxhc3QpICYmIG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCdcIlxuICAgICAgICAgICAgW2NhbkRlYnVnXT1cIigoKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICYmIGxhc3QpIHx8ICghbGFzdCAmJiBtZXNzYWdlc1tpbmRleCsxXS5yb2xlICE9PSAnYXNzaXN0YW50JykpICYmIG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgKGdldERlYnVnTWVzc2FnZXMobWVzc2FnZSwgaW5kZXgpLmxlbmd0aCA+IDApICYmICgoaXNBZG1pbk9yRGVsZXRlZEFkbWluIHx8IChjaGF0U2VydmljZS51c2VyT3ZlcnJpZGUkIHwgYXN5bmMpKSAmJiBjb25maWc/LmRlZmF1bHRWYWx1ZXMuZGVidWcpXCJcbiAgICAgICAgICAgIFtjYW5SZWdlbmVyYXRlXT1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSAgJiYgKGxhc3QgfHwgKCFsYXN0ICYmIG1lc3NhZ2VzW2luZGV4KzFdLnJvbGUgIT09ICdhc3Npc3RhbnQnKSkgICYmIG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgaW5kZXhNZXNzYWdlVG9FZGl0ID09PSB1bmRlZmluZWRcIlxuICAgICAgICAgICAgW2NvbGxhcHNlUmVmZXJlbmNlc109XCIhIWNvbmZpZz8uZ2xvYmFsU2V0dGluZ3MuY29sbGFwc2VSZWZlcmVuY2VzXCJcbiAgICAgICAgICAgIChlZGl0KT1cImVkaXRNZXNzYWdlKG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAoY29weSk9XCJjb3B5TWVzc2FnZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKHJlZ2VuZXJhdGUpPVwicmVnZW5lcmF0ZU1lc3NhZ2UobWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsIG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAob3BlblByZXZpZXcpPVwib3BlbkF0dGFjaG1lbnRQcmV2aWV3KCRldmVudCwgbWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChzdWdnZXN0QWN0aW9uKT1cInN1Z2dlc3RBY3Rpb25DbGljaygkZXZlbnQsIGluZGV4KVwiXG4gICAgICAgICAgICAobGlrZSk9XCJvbkxpa2UobWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChkaXNsaWtlKT1cIm9uRGlzbGlrZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKGRlYnVnKT1cInNob3dEZWJ1ZyhtZXNzYWdlLCBpbmRleClcIj5cbiAgICAgICAgICA8L3NxLWNoYXQtbWVzc2FnZT5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPCEtLSBMb2FkaW5nIHNwaW5uZXIgLS0+XG4gICAgICA8bGkgKm5nSWY9XCIobG9hZGluZyQgfCBhc3luYykgPT09IHRydWVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvYWRpbmdUcGwgfHwgbG9hZGluZ1RwbERlZmF1bHRcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbGk+XG4gICAgPC91bD5cblxuICAgIDwhLS0gUmVwb3J0aW5nIGEgZmVlZGJhY2sgZm9ybSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiaXNzdWUtcmVwb3J0IHAtMyByb3VuZGVkLWxnXCIgKm5nSWY9XCJzaG93UmVwb3J0XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicmVwb3J0VHBsIHx8IHJlcG9ydFRwbERlZmF1bHQ7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBtZXNzYWdlVG9SZXBvcnQsIHJhbms6IHJlcG9ydFJhbmssIHR5cGU6IHJlcG9ydFR5cGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBVc2VyIHRleHQgaW5wdXQgLS0+XG4gICAgQGlmICghc2hvd1JlcG9ydCkge1xuICAgICAgPGRpdiBjbGFzcz1cInVzZXItaW5wdXQgbXQtYXV0b1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgIDxkaXYgW2hpZGRlbl09XCIhaXNDb25uZWN0ZWRcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlbmFibGVkVXNlcklucHV0XCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW5wdXRUcGxcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8IS0tIFJldHJ5IGJ1dHRvbiAtLT5cbiAgICAgICAgICA8IS0tIGhpZGRlbiBhdHRyaWJ1dGUgaXMgaW4gY29uZmxpY3Qgd2l0aCBhIGNzcyBydWxlIGRpc3BsYXk6IGZsZXggLS0+XG4gICAgICAgICAgQGlmKCFpc0Nvbm5lY3RlZCl7XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIG1iLTQgYXN0LWVycm9yIGFzdC1idG4gc3EtcmV0cnlcIiAoY2xpY2spPVwicmV0cnlGZXRjaCgpXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7ICdjaGF0LnRyeUFnYWluJyB8IHRyYW5zbG9jbyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJyZXRyaWFsQXR0ZW1wdHNcIiBjbGFzcz1cIm1zLTIgYXR0ZW1wdHNcIj57eyByZXRyaWFsQXR0ZW1wdHMgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtZW5kIHNtYWxsIHRleHQtbXV0ZWQgcHgtM1wiICpuZ0lmPVwiISFjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyXCI+XG4gICAgICAgICAgICB7eyBjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNjbGFpbWVyIHwgdHJhbnNsb2NvIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSBGbG9hdGluZyBzY3JvbGwgYnV0dG9uIC0tPlxuICAgIDxkaXYgKm5nSWY9XCIhaXNBdEJvdHRvbSAmJiAhc2hvd1JlcG9ydFwiIGNsYXNzPVwic3EtZmxvYXRpbmctc2Nyb2xsXCIgW25nQ2xhc3NdPVwiZW5hYmxlZFVzZXJJbnB1dCA/ICdzcS1mbG9hdGluZy1zY3JvbGwtLXdoZW4tdXNlci1pbnB1dCcgOiAnc3EtZmxvYXRpbmctc2Nyb2xsLS13aXRob3V0LXVzZXItaW5wdXQnXCI+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNoYWRvd1wiIChjbGljayk9XCJzY3JvbGxEb3duKClcIiBhcmlhLWxhYmVsPVwiU2Nyb2xsIGRvd25cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtYW5nbGUtZG91YmxlLWRvd25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuPCEtLSBORyBURU1QTEFURVMtLT5cblxuPG5nLXRlbXBsYXRlICNsb2FkaW5nVHBsRGVmYXVsdD5cbiAgPGRpdiBjbGFzcz1cInNwaW5uZXItZ3JvdyB0ZXh0LXByaW1hcnkgZC1ibG9jayBteC1hdXRvIG15LTVcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eyAnY2hhdC5sb2FkaW5nJyB8IHRyYW5zbG9jbyB9fTwvc3Bhbj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2lucHV0VHBsPlxuICA8ZGl2IGNsYXNzPVwicHgtMyBweS0xXCI+XG4gICAgPGRpdiBjbGFzcz1cImFzdC1pbnB1dC1jb250YWluZXJcIj5cbiAgICAgIDxidXR0b24gZGlzYWJsZWQgY2xhc3M9XCJidG4gYnRuLWxpZ2h0XCIgYXJpYS1sYWJlbD1cInNlYXJjaFwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zZWFyY2hcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDx0ZXh0YXJlYSAjcXVlc3Rpb25JbnB1dCByb3dzPVwiMVwiXG4gICAgICAgIHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ2NoYXQuYXNrU29tZXRoaW5nJyB8IHRyYW5zbG9jb1wiIGF1dG9mb2N1c1xuICAgICAgICBbKG5nTW9kZWwpXT1cInF1ZXN0aW9uXCJcbiAgICAgICAgKGtleXVwKT1cIm9uS2V5VXAoJGV2ZW50KVwiXG4gICAgICAgIChrZXlkb3duKT1cImNhbGN1bGF0ZUhlaWdodCgkZXZlbnQpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIihsb2FkaW5nJCB8IGFzeW5jKSB8fCAoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSB8fCAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKVwiPlxuICAgICAgPC90ZXh0YXJlYT5cbiAgICAgIDxkaXYgaWQ9XCJjaGF0LWFjdGlvbnNcIiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgKGxvYWRpbmckIHwgYXN5bmMpID09PSBmYWxzZSAmJiAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKSA9PT0gZmFsc2VcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbmQgbWVzc2FnZVwiXG4gICAgICAgICAgW3NxVG9vbHRpcF09XCInY2hhdC5zZW5kTWVzc2FnZScgfCB0cmFuc2xvY29cIlxuICAgICAgICAgIChjbGljayk9XCJzdWJtaXRRdWVzdGlvbigpXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtcGFwZXItcGxhbmVcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCJpbmRleE1lc3NhZ2VUb0VkaXRcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJDYW5jZWwgZWRpdGlvblwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxpZ2h0XCJcbiAgICAgICAgICBbc3FUb29sdGlwXT1cIidjaGF0LmNhbmNlbEVkaXRpb24nIHwgdHJhbnNsb2NvXCJcbiAgICAgICAgICAoY2xpY2spPVwiaW5kZXhNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkOyBxdWVzdGlvbiA9ICcnXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtdW5kby1hbHRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpICYmIChjaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kIHwgYXN5bmMpID09PSBmYWxzZVwiIGNsYXNzPVwicHJvY2Vzc2luZ1wiPlxuICAgICAgICAgIHt7ICdjaGF0LmdlbmVyYXRpbmcnIHwgdHJhbnNsb2NvIH19PGkgY2xhc3M9XCJmYXMgZmEtc3Bpbm5lciBmYS1wdWxzZVwiPjwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cIihjaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kIHwgYXN5bmMpXCIgY2xhc3M9XCJwcm9jZXNzaW5nXCI+XG4gICAgICAgICAge3sgJ2NoYXQuc3RvcHBpbmcnIHwgdHJhbnNsb2NvIH19PGkgY2xhc3M9XCJmYXMgZmEtc3Bpbm5lciBmYS1wdWxzZVwiPjwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSAmJiAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKSA9PT0gZmFsc2VcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlN0b3AgZ2VuZXJhdGluZ1wiXG4gICAgICAgICAgW3NxVG9vbHRpcF09XCInY2hhdC5zdG9wR2VuZXJhdGlvbicgfCB0cmFuc2xvY29cIlxuICAgICAgICAgIChjbGljayk9XCJzdG9wR2VuZXJhdGlvbigpXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3RvcFwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI3JlcG9ydFRwbERlZmF1bHQgbGV0LW1lc3NhZ2UgbGV0LXJhbms9XCJyYW5rXCIgbGV0LXR5cGU9XCJ0eXBlXCI+XG4gIDxkaXYgY2xhc3M9XCJweC0zXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInR5cGUgPT09ICdkaXNsaWtlJ1wiPlxuICAgICAgPGg1Pnt7ICdjaGF0Lmlzc3VlVHlwZScgfCB0cmFuc2xvY28gfX08L2g1PlxuICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0IG1iLTRcIiBbKG5nTW9kZWwpXT1cImlzc3VlVHlwZVwiPlxuICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCInJ1wiPnt7ICdjaGF0LmNob29zZUlzc3VlVHlwZScgfCB0cmFuc2xvY28gfX08L29wdGlvbj5cbiAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgdHlwZSBvZiAoaXNzdWVUeXBlcyA/PyBkZWZhdWx0SXNzdWVUeXBlcylcIiBbdmFsdWVdPVwidHlwZVwiPnt7IHR5cGUgfCB0cmFuc2xvY28gfX08L29wdGlvbj5cbiAgICAgIDwvc2VsZWN0PlxuICAgICAgPGg1Pnt7ICdjaGF0LmFza1VubGlrZVJlYXNvbnMnIHwgdHJhbnNsb2NvIH19PC9oNT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidHlwZSA9PT0gJ2xpa2UnXCI+XG4gICAgICA8aDU+e3sgJ2NoYXQuYXNrTGlrZVJlYXNvbnMnIHwgdHJhbnNsb2NvIH19PC9oNT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYm9yZGVyIGJvcmRlci1uZXV0cmFsLTIwMFwiIFsobmdNb2RlbCldPVwicmVwb3J0Q29tbWVudFwiIFtwbGFjZWhvbGRlcl09XCInY2hhdC53cml0ZUNvbW1lbnQnIHwgdHJhbnNsb2NvXCI+PC90ZXh0YXJlYT5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93LXJldmVyc2UgZ2FwLTEgbXQtMlwiPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIFtkaXNhYmxlZF09XCJ0eXBlID09PSAnZGlzbGlrZScgJiYgIWlzc3VlVHlwZVwiIChjbGljayk9XCJzZW5kUmVwb3J0KClcIj57eyAnY2hhdC5zZW5kJyB8IHRyYW5zbG9jbyB9fTwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGlnaHRcIiAoY2xpY2spPVwiaWdub3JlUmVwb3J0KClcIj57eyAnY2hhdC5kb05vdFNlbmQnIHwgdHJhbnNsb2NvIH19PC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNkZWZhdWx0VG9rZW5Db25zdW1wdGlvblRwbCBsZXQtaW5zdGFuY2VJZD5cbiAgPHNxLXRva2VuLXByb2dyZXNzLWJhclxuICAgIFtpbnN0YW5jZUlkXT1cImluc3RhbmNlSWRcIj5cbiAgPC9zcS10b2tlbi1wcm9ncmVzcy1iYXI+XG48L25nLXRlbXBsYXRlPlxuXG48ZGl2IGNsYXNzPVwiZGVidWctbWVzc2FnZXNcIiBbY2xhc3MuZGlzcGxheWVkXT1cInNob3dEZWJ1Z01lc3NhZ2VzXCI+XG4gIDxidXR0b24gKm5nSWY9XCJzaG93RGVidWdNZXNzYWdlc1wiIGNsYXNzPVwiYnRuIGJ0bi1saWdodCBzaGFkb3cgYmFjay1idG5cIiAoY2xpY2spPVwic2hvd0RlYnVnTWVzc2FnZXM9ZmFsc2VcIiBhcmlhLWxhYmVsPVwiSGlkZSBkZWJ1ZyBtZXNzYWdlc1wiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZXZyb24tcmlnaHRcIj48L2k+XG4gIDwvYnV0dG9uPlxuICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGVidWdNZXNzYWdlc1RwbCB8fCBkZWZhdWx0RGVidWdNZXNzYWdlc1RwbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGRlYnVnTWVzc2FnZXMgfVwiPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2RlZmF1bHREZWJ1Z01lc3NhZ2VzVHBsIGxldC1kZWJ1Z01lc3NhZ2VzPlxuICA8c3EtZGVidWctbWVzc2FnZSBbZGF0YV09XCJkZWJ1Z01lc3NhZ2VzXCI+PC9zcS1kZWJ1Zy1tZXNzYWdlPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|