From 767d7d7b0358e757185bf750d53dde8159a46304 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Sat, 7 Dec 2019 20:45:50 +0530 Subject: [PATCH] implemented message post in ts + some optimizations --- .../javascript/ts/src/dto/ChatMessageDTO.ts | 2 +- chatto/src/main/javascript/ts/src/main.ts | 8 +- .../main/javascript/ts/src/model/ChatModel.ts | 12 +- .../ts/src/model/ChatModelHelper.ts | 7 +- .../ts/src/service/EncryptionService.ts | 6 +- .../ts/src/service/SJCLEncryptionService.ts | 11 +- .../javascript/ts/src/singleton/JsonAPI.ts | 4 +- .../main/javascript/ts/src/view/ChatView.ts | 118 +++++++++++- .../javascript/ts/src/view/FetchHandler.ts | 33 ++++ chatto/src/main/resources/static/js/bundle.js | 182 +++++++++++++++--- chatto/src/main/resources/templates/chat.html | 4 +- 11 files changed, 330 insertions(+), 57 deletions(-) create mode 100644 chatto/src/main/javascript/ts/src/view/FetchHandler.ts diff --git a/chatto/src/main/javascript/ts/src/dto/ChatMessageDTO.ts b/chatto/src/main/javascript/ts/src/dto/ChatMessageDTO.ts index 90b1041..01e39ff 100644 --- a/chatto/src/main/javascript/ts/src/dto/ChatMessageDTO.ts +++ b/chatto/src/main/javascript/ts/src/dto/ChatMessageDTO.ts @@ -4,5 +4,5 @@ export class ChatMessageDTO { public toUser: string | undefined; public fromUser: string | undefined; public messageCipher!: MessageCipherDTO; - public messageTime!: Date; + public messageTime: Date | undefined | null; } \ No newline at end of file diff --git a/chatto/src/main/javascript/ts/src/main.ts b/chatto/src/main/javascript/ts/src/main.ts index 8f27533..efe0fcd 100644 --- a/chatto/src/main/javascript/ts/src/main.ts +++ b/chatto/src/main/javascript/ts/src/main.ts @@ -8,7 +8,6 @@ import { ModelFactory } from "./model/ModelFactory"; import { ActiveUserViewModel } from "./viewmodel/ActiveUserViewModel"; import { ChatMessageViewModel } from "./viewmodel/ChatMessageViewModel"; import * as Handlebars from "handlebars"; -import markdownit = require('markdown-it'); import { ChatModel } from "./model/ChatModel"; import { ChatView } from "./view/ChatView"; import { ChatController } from "./controller/ChatController"; @@ -18,8 +17,9 @@ import * as log from 'loglevel'; // import log from 'loglevel'; import { EncryptionService } from "./service/EncryptionService"; import { SJCLEncryptionService } from "./service/SJCLEncryptionService"; +import { MessageCipherDTO } from "./dto/MessageCipherDTO"; // var markdownit = require('markdown-it'); -var md = new markdownit(); +// var md = new markdownit(); const userBox = document.getElementById('contacts-box'); @@ -72,8 +72,8 @@ var msgContainerTemplate = Handlebars.compile(source); JsonAPI.ACTIVE_USERS_GET + 'aef'; const encryptionService: EncryptionService = new SJCLEncryptionService(); -let ct = encryptionService.encrypt("password","data"); -console.log(encryptionService.decrypt("password", JSON.parse(ct as string))); +let messageCipherDTO: MessageCipherDTO = encryptionService.encrypt("password","data"); +console.log(encryptionService.decrypt("password", messageCipherDTO)); Handlebars.registerHelper('avatar', function() { return '
'; diff --git a/chatto/src/main/javascript/ts/src/model/ChatModel.ts b/chatto/src/main/javascript/ts/src/model/ChatModel.ts index 6b44c68..611f4df 100644 --- a/chatto/src/main/javascript/ts/src/model/ChatModel.ts +++ b/chatto/src/main/javascript/ts/src/model/ChatModel.ts @@ -39,7 +39,7 @@ export class ChatModel implements Subject { console.log('Subject: Detached an observer.'); } - public setUserMessages(username: string, messages: ChatMessageViewModel[]) { + private setUserMessages(username: string, messages: ChatMessageViewModel[]) { this._messagesMap.set(username, messages); } @@ -61,13 +61,15 @@ export class ChatModel implements Subject { this.notify("some user"); } - public async getmessages(userName: string, passphrase: string, lastMessageTime: string | null): Promise { - const cVMs = await ChatModelHelper.getMessages(userName, passphrase, lastMessageTime, this); + public async getmessages(contactName: string, passphrase: string, lastMessageTime: string | null): Promise { + const cVMs = await ChatModelHelper.getMessages(contactName, passphrase, lastMessageTime, this); if (cVMs != null) { log.info('Subject: My state has just changed') log.debug(cVMs); - this._messagesMap.set(userName, cVMs); - this.notify(userName); + // this._messagesMap.set(userName, cVMs); + this.setUserMessages(contactName, cVMs); + JsonAPI.contactName = contactName; + this.notify(contactName); } else { log.error('Messages were null'); diff --git a/chatto/src/main/javascript/ts/src/model/ChatModelHelper.ts b/chatto/src/main/javascript/ts/src/model/ChatModelHelper.ts index a71a2f8..4c2cf53 100644 --- a/chatto/src/main/javascript/ts/src/model/ChatModelHelper.ts +++ b/chatto/src/main/javascript/ts/src/model/ChatModelHelper.ts @@ -12,7 +12,7 @@ import { EncryptionService } from "../service/EncryptionService"; import { SJCLEncryptionService } from "../service/SJCLEncryptionService"; import { ChatModel } from "./ChatModel" export class ChatModelHelper { - private static readonly encryptionService = new SJCLEncryptionService(); + private static readonly _encryptionService: EncryptionService = new SJCLEncryptionService(); public static async getMessages(userName: string, passphrase: string, lastMessageTime: string | null, chatModel: ChatModel): Promise { switch (lastMessageTime) { @@ -54,8 +54,9 @@ export class ChatModelHelper { const vm = new ChatMessageViewModel(); vm.fromUser = chatMessageDTO.fromUser; vm.toUser = chatMessageDTO.toUser; - vm.messageTime = chatMessageDTO.messageTime; - vm.message = this.encryptionService.decrypt(passphrase, chatMessageDTO.messageCipher) as string; + // vm.messageTime = chatMessageDTO.messageTime; + chatMessageDTO.messageTime == null ? log.error("Message time somehow null") : vm.messageTime = chatMessageDTO.messageTime; + vm.message = this._encryptionService.decrypt(passphrase, chatMessageDTO.messageCipher) as string; return vm; } diff --git a/chatto/src/main/javascript/ts/src/service/EncryptionService.ts b/chatto/src/main/javascript/ts/src/service/EncryptionService.ts index 8a6bec0..3867b68 100644 --- a/chatto/src/main/javascript/ts/src/service/EncryptionService.ts +++ b/chatto/src/main/javascript/ts/src/service/EncryptionService.ts @@ -1,4 +1,6 @@ +import { MessageCipherDTO } from "../dto/MessageCipherDTO"; + export interface EncryptionService { - encrypt(passphrase: string, plainText: string): Object, - decrypt(passphrase: string, cipher: Object): Object + encrypt(passphrase: string, plainText: string): any, + decrypt(passphrase: string, cipher: MessageCipherDTO): string } \ No newline at end of file diff --git a/chatto/src/main/javascript/ts/src/service/SJCLEncryptionService.ts b/chatto/src/main/javascript/ts/src/service/SJCLEncryptionService.ts index 82c22ad..913bea2 100644 --- a/chatto/src/main/javascript/ts/src/service/SJCLEncryptionService.ts +++ b/chatto/src/main/javascript/ts/src/service/SJCLEncryptionService.ts @@ -1,14 +1,15 @@ import { EncryptionService } from "./EncryptionService"; import * as sjcl from "sjcl"; +import { MessageCipherDTO } from "../dto/MessageCipherDTO"; export class SJCLEncryptionService implements EncryptionService { - private readonly params: any = { mode: "gcm", ts: 128, adata: "", iter: 10000} - public encrypt(passphrase: string, plainText: string): Object { - return sjcl.encrypt(passphrase, plainText, this.params); + private readonly params = { mode: "gcm", ts: 128, adata: "", iter: 10000} + public encrypt(passphrase: string, plainText: string): MessageCipherDTO { + // @ts-ignore + return JSON.parse(sjcl.encrypt(passphrase, plainText, this.params) as string) as MessageCipherDTO; } - public decrypt(passphrase: string, cipher: Object): Object { - // return sjcl.decrypt(passphrase, cipher as sjcl.SjclCipherEncrypted, undefined, undefined); + public decrypt(passphrase: string, cipher: MessageCipherDTO): string { return sjcl.decrypt(passphrase, JSON.stringify(cipher), undefined, undefined); } } \ No newline at end of file diff --git a/chatto/src/main/javascript/ts/src/singleton/JsonAPI.ts b/chatto/src/main/javascript/ts/src/singleton/JsonAPI.ts index 4f0e120..4884f47 100644 --- a/chatto/src/main/javascript/ts/src/singleton/JsonAPI.ts +++ b/chatto/src/main/javascript/ts/src/singleton/JsonAPI.ts @@ -1,8 +1,10 @@ export namespace JsonAPI { // @ts-ignore: Cannot find name 'hostAddress'. - export let userName: string | null = localStorage.getItem('userName'); + export let principleName: string | null = localStorage.getItem('username'); + export let contactName: string | null; export let authToken: string | null = localStorage.getItem('authToken'); export const ACTIVE_USERS_GET = `/api/chat/get/active-users`; export const CHAT_MESSAGES_GET = `/api/chat/get/messages`; + export const MESSAGE_POST = '/api/chat/post/message'; } \ No newline at end of file diff --git a/chatto/src/main/javascript/ts/src/view/ChatView.ts b/chatto/src/main/javascript/ts/src/view/ChatView.ts index d5479aa..0ee83d4 100644 --- a/chatto/src/main/javascript/ts/src/view/ChatView.ts +++ b/chatto/src/main/javascript/ts/src/view/ChatView.ts @@ -7,35 +7,51 @@ import * as DOMPurify from 'dompurify'; import { MarkDownService } from "../service/MarkDownService"; import { MarkDownItMarkDownService } from "../service/MarkDownItMarkDownService"; import { JsonAPI } from "../singleton/JsonAPI"; +import { MessageCipherDTO } from "../dto/MessageCipherDTO"; +import { SJCLEncryptionService } from "../service/SJCLEncryptionService"; +import { EncryptionService } from "../service/EncryptionService"; +import { ChatMessageDTO } from "../dto/ChatMessageDTO"; +import { fetchHandler } from "./FetchHandler"; // var md = new markdownit(); export class ChatView implements Observer { - private readonly _element: HTMLElement; + private readonly _chatModel: ChatModel; + private readonly _messageContainer: HTMLElement; + // private readonly _messageSendButton: HTMLElement; private readonly _messageSendTemplate = TemplateFactory.getTemplate('msg_container_send_template'); private readonly _messageReceiveTemplate = TemplateFactory.getTemplate('msg_container_template'); private readonly _markdownService: MarkDownService = new MarkDownItMarkDownService(); + private readonly _encryptionService: EncryptionService = new SJCLEncryptionService(); - constructor(model: ChatModel, element: HTMLElement) { - this._element = element; + constructor(chatModel: ChatModel, messageContainer: HTMLElement) { + this._messageContainer = messageContainer; + this._chatModel = chatModel; + // this._messageSendButton = messageSendButton; + this.addEventListeners(); } update(data: ChatMessageViewModel[]): void { log.info('ChatView: updating view'); // let html: string = ""; + this._messageContainer.innerHTML = ""; data.forEach((vm: ChatMessageViewModel) => { const vmTemp = vm; vmTemp.message = this._markdownService.render(vm.message); /** Very Important!!! * Sanitizing HTML before displaying on webpage to prevent XSS attacks!! */ - if (vmTemp.fromUser == JsonAPI.userName) { - $(this._element).append(DOMPurify.sanitize(this._messageSendTemplate(vmTemp))); + let rendered; + if (vmTemp.fromUser == JsonAPI.principleName) { + rendered = DOMPurify.sanitize(this._messageSendTemplate(vmTemp)); + } else { - $(this._element).append(DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp))); + rendered = DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp)); } + $(this._messageContainer).append(rendered); + log.debug() // html += this._messageSendTemplate(vm); }); @@ -43,4 +59,94 @@ export class ChatView implements Observer { // this._element.innerHTML = html; // log.debug(this._element.innerHTML); } + + private addEventListeners(): void { + this.addChatFormEL(); + } + + private addChatFormEL() { + const chatForm = document.getElementById('chatMessageForm') as HTMLSelectElement; + + if (chatForm == null) { + log.error("Chat form is null"); + } + else { + chatForm.addEventListener('submit', (e) => this.createChatMessageDTO(e, chatForm)) + + } + + } + + private createChatMessageDTO(e: Event, chatForm: HTMLSelectElement): void { + e.preventDefault(); + + let contactName = JsonAPI.contactName; + + if(contactName == null) + { + log.error("Contact name is null"); + return; + } + + if (!chatForm.checkValidity()) { + console.log("error"); + chatForm.classList.add('was-validated'); + return; + } + chatForm.classList.add('was-validated'); + + + const chatInput = document.getElementById('chatInput') as HTMLInputElement; + const passphraseInput = document.getElementById('passphrase') as HTMLInputElement; + + if (chatInput.value == '' || chatInput.value == null) { + log.error("Chat input is null."); + return; + } + + if (passphraseInput.value == '' || passphraseInput.value == null) { + log.error("Chat input is null."); + return; + } + + // @ts-ignore + const messageContent = chatInput.value; + const context = { fromUser: JsonAPI.principleName, message: this._markdownService.render(messageContent), messageTime: new Date().toLocaleString() }; + const msgContainer: string = this._messageSendTemplate(context); + $(this._messageContainer).append(DOMPurify.sanitize(msgContainer)); + // scrollChatAreaAnimated(2400); + // let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent, { mode: "gcm", ts: 128, adata: "", iter: iterations }); + let messageCipher: MessageCipherDTO = this._encryptionService.encrypt(passphraseInput.value, messageContent) + // let messageCipherJson = JSON.parse(messageCipher); + let chatMessageDTO = { + "fromUser": JsonAPI.principleName, + "toUser": contactName, + "messageCipher": messageCipher, + // "messageTime": null + } + // @ts-ignore + this.sendMessageAJAX(chatMessageDTO); + } + + private sendMessageAJAX(chatMessageDTO: ChatMessageDTO): void { + let headers = new Headers(); + // console.log("Token = " + btoa("hmm" + ":" + "hmm")) + + // headers.append('Accept','application/json') + headers.append('Content-Type', 'application/json'); + // headers.append('Authorization', basicAuthToken); + // @ts-ignore + headers.append('X-AUTH-TOKEN', JsonAPI.authToken); + fetch(JsonAPI.MESSAGE_POST, { + method: 'POST', + headers: headers, + body: JSON.stringify(chatMessageDTO) + }) + .then(response => { + log.debug(response); + return response.clone(); + }) + .then(response => fetchHandler(response)); + + } } \ No newline at end of file diff --git a/chatto/src/main/javascript/ts/src/view/FetchHandler.ts b/chatto/src/main/javascript/ts/src/view/FetchHandler.ts new file mode 100644 index 0000000..0f1c42a --- /dev/null +++ b/chatto/src/main/javascript/ts/src/view/FetchHandler.ts @@ -0,0 +1,33 @@ +import { sprintf } from "sprintf-js"; + +export function fetchHandler(response: any) { + if (response.ok) { + return response.json().then((json: any) => { + // the status was ok and there is a json body + // return Promise.resolve({ json: json, response: response }); + // alertify.success('Message sent succesfully' + sprintf(" (http code %d)", response.status)); + }).catch((err: any) => { + // the status was ok but there is no json body + // return Promise.resolve({ response: response }); + // alertify.success('Message sent succesfully' + sprintf(" (http code %d)", response.status)); + }); + + } else { + return response.json().catch((err: any) => { + // the status was not ok and there is no json body + // throw new Error(response.statusText); + // alertify.error('Some error occured. Please try again.'); + }).then((json: any) => { + // the status was not ok but there is a json body + // throw new Error(json.error.message); // example error message returned by a REST + // let delay = alertify.get('notifier', 'delay'); + // alertify.set('notifier', 'delay', 30); + let errorMessage = ""; + json.errors.forEach(function(data: any) { + errorMessage += sprintf("Field Name: %s \n Rejected value: %s \n Reason: %s \n", data.field_name, data.rejected_value, data.error_message); + }); + // alertify.error(sprintf('There were errors in your message - %s', errorMessage)); + // alertify.set('notifier', 'delay', delay); + }); + } +} diff --git a/chatto/src/main/resources/static/js/bundle.js b/chatto/src/main/resources/static/js/bundle.js index 55c5ef7..1ca501a 100644 --- a/chatto/src/main/resources/static/js/bundle.js +++ b/chatto/src/main/resources/static/js/bundle.js @@ -29,7 +29,7 @@ class ChatController { } exports.ChatController = ChatController; -},{"../model/AbstractModel":4,"../model/UserModel":8,"../view/AbstractView":13,"../view/UserView":15,"../viewmodel/ChatMessageViewModel":17}],2:[function(require,module,exports){ +},{"../model/AbstractModel":4,"../model/UserModel":8,"../view/AbstractView":13,"../view/UserView":16,"../viewmodel/ChatMessageViewModel":18}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("../model/AbstractModel"); @@ -68,7 +68,7 @@ class UserController { } exports.UserController = UserController; -},{"../model/AbstractModel":4,"../model/UserModel":8,"../view/AbstractView":13,"../view/UserView":15,"../viewmodel/ActiveUserViewModel":16}],3:[function(require,module,exports){ +},{"../model/AbstractModel":4,"../model/UserModel":8,"../view/AbstractView":13,"../view/UserView":16,"../viewmodel/ActiveUserViewModel":17}],3:[function(require,module,exports){ (function (global){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); @@ -76,7 +76,6 @@ const UserModel_1 = require("./model/UserModel"); const UserView_1 = require("./view/UserView"); const UserController_1 = require("./controller/UserController"); const Handlebars = (typeof window !== "undefined" ? window['Handlebars'] : typeof global !== "undefined" ? global['Handlebars'] : null); -const markdownit = (typeof window !== "undefined" ? window['markdownit'] : typeof global !== "undefined" ? global['markdownit'] : null); const ChatModel_1 = require("./model/ChatModel"); const ChatView_1 = require("./view/ChatView"); const ChatController_1 = require("./controller/ChatController"); @@ -85,7 +84,7 @@ const JsonAPI_1 = require("./singleton/JsonAPI"); const log = (typeof window !== "undefined" ? window['log'] : typeof global !== "undefined" ? global['log'] : null); const SJCLEncryptionService_1 = require("./service/SJCLEncryptionService"); // var markdownit = require('markdown-it'); -var md = new markdownit(); +// var md = new markdownit(); const userBox = document.getElementById('contacts-box'); log.setLevel("TRACE"); const chatModel = new ChatModel_1.ChatModel(); @@ -117,15 +116,15 @@ var source = document.getElementById("msg_container_template").innerHTML; var msgContainerTemplate = Handlebars.compile(source); JsonAPI_1.JsonAPI.ACTIVE_USERS_GET + 'aef'; const encryptionService = new SJCLEncryptionService_1.SJCLEncryptionService(); -let ct = encryptionService.encrypt("password", "data"); -console.log(encryptionService.decrypt("password", JSON.parse(ct))); +let messageCipherDTO = encryptionService.encrypt("password", "data"); +console.log(encryptionService.decrypt("password", messageCipherDTO)); Handlebars.registerHelper('avatar', function () { return '
'; }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./controller/ChatController":1,"./controller/UserController":2,"./model/ChatModel":5,"./model/UserModel":8,"./service/SJCLEncryptionService":10,"./singleton/JsonAPI":11,"./view/ChatView":14,"./view/UserView":15}],4:[function(require,module,exports){ +},{"./controller/ChatController":1,"./controller/UserController":2,"./model/ChatModel":5,"./model/UserModel":8,"./service/SJCLEncryptionService":10,"./singleton/JsonAPI":11,"./view/ChatView":14,"./view/UserView":16}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); @@ -133,6 +132,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); (function (global){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const JsonAPI_1 = require("../singleton/JsonAPI"); const log = (typeof window !== "undefined" ? window['log'] : typeof global !== "undefined" ? global['log'] : null); const ChatModelHelper_1 = require("./ChatModelHelper"); class ChatModel { @@ -177,13 +177,15 @@ class ChatModel { console.log(chatMessageList); this.notify("some user"); } - async getmessages(userName, passphrase, lastMessageTime) { - const cVMs = await ChatModelHelper_1.ChatModelHelper.getMessages(userName, passphrase, lastMessageTime, this); + async getmessages(contactName, passphrase, lastMessageTime) { + const cVMs = await ChatModelHelper_1.ChatModelHelper.getMessages(contactName, passphrase, lastMessageTime, this); if (cVMs != null) { log.info('Subject: My state has just changed'); log.debug(cVMs); - this._messagesMap.set(userName, cVMs); - this.notify(userName); + // this._messagesMap.set(userName, cVMs); + this.setUserMessages(contactName, cVMs); + JsonAPI_1.JsonAPI.contactName = contactName; + this.notify(contactName); } else { log.error('Messages were null'); @@ -198,7 +200,7 @@ exports.ChatModel = ChatModel; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./ChatModelHelper":6}],6:[function(require,module,exports){ +},{"../singleton/JsonAPI":11,"./ChatModelHelper":6}],6:[function(require,module,exports){ (function (global){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); @@ -244,8 +246,9 @@ class ChatModelHelper { const vm = new ChatMessageViewModel_1.ChatMessageViewModel(); vm.fromUser = chatMessageDTO.fromUser; vm.toUser = chatMessageDTO.toUser; - vm.messageTime = chatMessageDTO.messageTime; - vm.message = this.encryptionService.decrypt(passphrase, chatMessageDTO.messageCipher); + // vm.messageTime = chatMessageDTO.messageTime; + chatMessageDTO.messageTime == null ? log.error("Message time somehow null") : vm.messageTime = chatMessageDTO.messageTime; + vm.message = this._encryptionService.decrypt(passphrase, chatMessageDTO.messageCipher); return vm; } static async getAllMessagesAjax(toUser) { @@ -288,11 +291,11 @@ class ChatModelHelper { } } exports.ChatModelHelper = ChatModelHelper; -ChatModelHelper.encryptionService = new SJCLEncryptionService_1.SJCLEncryptionService(); +ChatModelHelper._encryptionService = new SJCLEncryptionService_1.SJCLEncryptionService(); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../service/SJCLEncryptionService":10,"../singleton/JsonAPI":11,"../viewmodel/ChatMessageViewModel":17,"./FetchErrorHandler":7}],7:[function(require,module,exports){ +},{"../service/SJCLEncryptionService":10,"../singleton/JsonAPI":11,"../viewmodel/ChatMessageViewModel":18,"./FetchErrorHandler":7}],7:[function(require,module,exports){ (function (global){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); @@ -443,10 +446,10 @@ class SJCLEncryptionService { this.params = { mode: "gcm", ts: 128, adata: "", iter: 10000 }; } encrypt(passphrase, plainText) { - return sjcl.encrypt(passphrase, plainText, this.params); + // @ts-ignore + return JSON.parse(sjcl.encrypt(passphrase, plainText, this.params)); } decrypt(passphrase, cipher) { - // return sjcl.decrypt(passphrase, cipher as sjcl.SjclCipherEncrypted, undefined, undefined); return sjcl.decrypt(passphrase, JSON.stringify(cipher), undefined, undefined); } } @@ -460,10 +463,11 @@ Object.defineProperty(exports, "__esModule", { value: true }); var JsonAPI; (function (JsonAPI) { // @ts-ignore: Cannot find name 'hostAddress'. - JsonAPI.userName = localStorage.getItem('userName'); + JsonAPI.principleName = localStorage.getItem('username'); JsonAPI.authToken = localStorage.getItem('authToken'); JsonAPI.ACTIVE_USERS_GET = `/api/chat/get/active-users`; JsonAPI.CHAT_MESSAGES_GET = `/api/chat/get/messages`; + JsonAPI.MESSAGE_POST = '/api/chat/post/message'; })(JsonAPI = exports.JsonAPI || (exports.JsonAPI = {})); },{}],12:[function(require,module,exports){ @@ -516,41 +520,163 @@ const log = (typeof window !== "undefined" ? window['log'] : typeof global !== " const DOMPurify = (typeof window !== "undefined" ? window['DOMPurify'] : typeof global !== "undefined" ? global['DOMPurify'] : null); const MarkDownItMarkDownService_1 = require("../service/MarkDownItMarkDownService"); const JsonAPI_1 = require("../singleton/JsonAPI"); +const SJCLEncryptionService_1 = require("../service/SJCLEncryptionService"); +const FetchHandler_1 = require("./FetchHandler"); // var md = new markdownit(); class ChatView { - constructor(model, element) { + constructor(chatModel, messageContainer) { + // private readonly _messageSendButton: HTMLElement; this._messageSendTemplate = TemplateFactory_1.TemplateFactory.getTemplate('msg_container_send_template'); this._messageReceiveTemplate = TemplateFactory_1.TemplateFactory.getTemplate('msg_container_template'); this._markdownService = new MarkDownItMarkDownService_1.MarkDownItMarkDownService(); - this._element = element; + this._encryptionService = new SJCLEncryptionService_1.SJCLEncryptionService(); + this._messageContainer = messageContainer; + this._chatModel = chatModel; + // this._messageSendButton = messageSendButton; + this.addEventListeners(); } update(data) { log.info('ChatView: updating view'); // let html: string = ""; + this._messageContainer.innerHTML = ""; data.forEach((vm) => { const vmTemp = vm; vmTemp.message = this._markdownService.render(vm.message); /** Very Important!!! * Sanitizing HTML before displaying on webpage to prevent XSS attacks!! */ - if (vmTemp.fromUser == JsonAPI_1.JsonAPI.userName) { - $(this._element).append(DOMPurify.sanitize(this._messageSendTemplate(vmTemp))); + let rendered; + if (vmTemp.fromUser == JsonAPI_1.JsonAPI.principleName) { + rendered = DOMPurify.sanitize(this._messageSendTemplate(vmTemp)); } else { - $(this._element).append(DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp))); + rendered = DOMPurify.sanitize(this._messageReceiveTemplate(vmTemp)); } + $(this._messageContainer).append(rendered); + log.debug(); // html += this._messageSendTemplate(vm); }); // html = DOMPurify.sanitize(md.render(html)); // this._element.innerHTML = html; // log.debug(this._element.innerHTML); } + addEventListeners() { + this.addChatFormEL(); + } + addChatFormEL() { + const chatForm = document.getElementById('chatMessageForm'); + if (chatForm == null) { + log.error("Chat form is null"); + } + else { + chatForm.addEventListener('submit', (e) => this.createChatMessageDTO(e, chatForm)); + } + } + createChatMessageDTO(e, chatForm) { + e.preventDefault(); + let contactName = JsonAPI_1.JsonAPI.contactName; + if (contactName == null) { + log.error("Contact name is null"); + return; + } + if (!chatForm.checkValidity()) { + console.log("error"); + chatForm.classList.add('was-validated'); + return; + } + chatForm.classList.add('was-validated'); + const chatInput = document.getElementById('chatInput'); + const passphraseInput = document.getElementById('passphrase'); + if (chatInput.value == '' || chatInput.value == null) { + log.error("Chat input is null."); + return; + } + if (passphraseInput.value == '' || passphraseInput.value == null) { + log.error("Chat input is null."); + return; + } + // @ts-ignore + const messageContent = chatInput.value; + const context = { fromUser: JsonAPI_1.JsonAPI.principleName, message: this._markdownService.render(messageContent), messageTime: new Date().toLocaleString() }; + const msgContainer = this._messageSendTemplate(context); + $(this._messageContainer).append(DOMPurify.sanitize(msgContainer)); + // scrollChatAreaAnimated(2400); + // let messageCipher = sjcl.encrypt(passphraseInput.value, messageContent, { mode: "gcm", ts: 128, adata: "", iter: iterations }); + let messageCipher = this._encryptionService.encrypt(passphraseInput.value, messageContent); + // let messageCipherJson = JSON.parse(messageCipher); + let chatMessageDTO = { + "fromUser": JsonAPI_1.JsonAPI.principleName, + "toUser": contactName, + "messageCipher": messageCipher, + }; + // @ts-ignore + this.sendMessageAJAX(chatMessageDTO); + } + sendMessageAJAX(chatMessageDTO) { + let headers = new Headers(); + // console.log("Token = " + btoa("hmm" + ":" + "hmm")) + // headers.append('Accept','application/json') + headers.append('Content-Type', 'application/json'); + // headers.append('Authorization', basicAuthToken); + // @ts-ignore + headers.append('X-AUTH-TOKEN', JsonAPI_1.JsonAPI.authToken); + fetch(JsonAPI_1.JsonAPI.MESSAGE_POST, { + method: 'POST', + headers: headers, + body: JSON.stringify(chatMessageDTO) + }) + .then(response => { + log.debug(response); + return response.clone(); + }) + .then(response => FetchHandler_1.fetchHandler(response)); + } } exports.ChatView = ChatView; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../service/MarkDownItMarkDownService":9,"../singleton/JsonAPI":11,"../template/TemplateFactory":12}],15:[function(require,module,exports){ +},{"../service/MarkDownItMarkDownService":9,"../service/SJCLEncryptionService":10,"../singleton/JsonAPI":11,"../template/TemplateFactory":12,"./FetchHandler":15}],15:[function(require,module,exports){ +(function (global){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const sprintf_js_1 = (typeof window !== "undefined" ? window['sprintf'] : typeof global !== "undefined" ? global['sprintf'] : null); +function fetchHandler(response) { + if (response.ok) { + return response.json().then((json) => { + // the status was ok and there is a json body + // return Promise.resolve({ json: json, response: response }); + // alertify.success('Message sent succesfully' + sprintf(" (http code %d)", response.status)); + }).catch((err) => { + // the status was ok but there is no json body + // return Promise.resolve({ response: response }); + // alertify.success('Message sent succesfully' + sprintf(" (http code %d)", response.status)); + }); + } + else { + return response.json().catch((err) => { + // the status was not ok and there is no json body + // throw new Error(response.statusText); + // alertify.error('Some error occured. Please try again.'); + }).then((json) => { + // the status was not ok but there is a json body + // throw new Error(json.error.message); // example error message returned by a REST + // let delay = alertify.get('notifier', 'delay'); + // alertify.set('notifier', 'delay', 30); + let errorMessage = ""; + json.errors.forEach(function (data) { + errorMessage += sprintf_js_1.sprintf("Field Name: %s \n Rejected value: %s \n Reason: %s \n", data.field_name, data.rejected_value, data.error_message); + }); + // alertify.error(sprintf('There were errors in your message - %s', errorMessage)); + // alertify.set('notifier', 'delay', delay); + }); + } +} +exports.fetchHandler = fetchHandler; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],16:[function(require,module,exports){ (function (global){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); @@ -638,14 +764,14 @@ exports.UserView = UserView; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../template/TemplateFactory":12}],16:[function(require,module,exports){ +},{"../template/TemplateFactory":12}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class ActiveUserViewModel { } exports.ActiveUserViewModel = ActiveUserViewModel; -},{}],17:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class ChatMessageViewModel { @@ -653,4 +779,4 @@ class ChatMessageViewModel { exports.ChatMessageViewModel = ChatMessageViewModel; },{}]},{},[3]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJ0cy9zcmMvY29udHJvbGxlci9DaGF0Q29udHJvbGxlci50cyIsInRzL3NyYy9jb250cm9sbGVyL1VzZXJDb250cm9sbGVyLnRzIiwidHMvc3JjL21haW4udHMiLCJ0cy9zcmMvbW9kZWwvQ2hhdE1vZGVsLnRzIiwidHMvc3JjL21vZGVsL0NoYXRNb2RlbEhlbHBlci50cyIsInRzL3NyYy9tb2RlbC9GZXRjaEVycm9ySGFuZGxlci50cyIsInRzL3NyYy9tb2RlbC9Vc2VyTW9kZWwudHMiLCJ0cy9zcmMvc2VydmljZS9NYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlLnRzIiwidHMvc3JjL3NlcnZpY2UvU0pDTEVuY3J5cHRpb25TZXJ2aWNlLnRzIiwidHMvc3JjL3NpbmdsZXRvbi9Kc29uQVBJLnRzIiwidHMvc3JjL3RlbXBsYXRlL1RlbXBsYXRlRmFjdG9yeS50cyIsInRzL3NyYy92aWV3L0NoYXRWaWV3LnRzIiwidHMvc3JjL3ZpZXcvVXNlclZpZXcudHMiLCJ0cy9zcmMvdmlld21vZGVsL0FjdGl2ZVVzZXJWaWV3TW9kZWwudHMiLCJ0cy9zcmMvdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7QUNDQSxrQ0FBK0I7QUFDL0IsOEJBQTJCO0FBQzNCLGdDQUE2QjtBQUM3Qiw0QkFBeUI7QUFHekIsNEVBQXlFO0FBSXpFLE1BQWEsY0FBYztJQUt2QixZQUFZLEtBQWdCLEVBQUUsSUFBYztRQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUN0QixDQUFDO0lBR0Q7O09BRUc7SUFDSSxZQUFZLENBQUMsRUFBMEI7UUFDMUMsSUFBSSxDQUFD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QUFPLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELEVBQUUsQ0FBQyxTQUFTLElBQUksU0FBUyxDQUFDO0lBQzlCLENBQUM7Q0FFSjtBQS9GRCw0QkErRkM7Ozs7Ozs7QUMxR0QsTUFBYSxtQkFBbUI7Q0FJL0I7QUFKRCxrREFJQzs7Ozs7QUNKRCxNQUFhLG9CQUFvQjtDQU9oQztBQVBELG9EQU9DIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gXCIuL0Fic3RyYWN0Q29udHJvbGxlclwiO1xuaW1wb3J0IFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiXG5pbXBvcnQgXCIuLi9tb2RlbC9Vc2VyTW9kZWxcIlxuaW1wb3J0IFwiLi4vdmlldy9BYnN0cmFjdFZpZXdcIlxuaW1wb3J0IFwiLi4vdmlldy9Vc2VyVmlld1wiXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4uL3ZpZXcvQWJzdHJhY3RWaWV3XCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCB7IENoYXRNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9DaGF0TW9kZWxcIjtcbmltcG9ydCB7IENoYXRWaWV3IH0gZnJvbSBcIi4uL3ZpZXcvQ2hhdFZpZXdcIjtcblxuZXhwb3J0IGNsYXNzIENoYXRDb250cm9sbGVyIHtcbiAgICBwcml2YXRlIF9tb2RlbDogQ2hhdE1vZGVsO1xuICAgIHByaXZhdGUgX3ZpZXc6IENoYXRWaWV3O1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihtb2RlbDogQ2hhdE1vZGVsLCB2aWV3OiBDaGF0Vmlldykge1xuICAgICAgICB0aGlzLl9tb2RlbCA9IG1vZGVsO1xuICAgICAgICB0aGlzLl92aWV3ID0gdmlldztcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIGV2ZW50SGFuZGxlclxuICAgICAqL1xuICAgIHB1YmxpYyBldmVudEhhbmRsZXIodm06IENoYXRNZXNzYWdlVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbW9kZWwuc29tZUJ1c2luZXNzTWV0aG9kKHZtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdGVzdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY2hhdE1lc3NhZ2VWaWV3TW9kZWxzOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdID0gW107XG4gICAgICAgIGxldCBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2sgPSBuZXcgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwoKTtcbiAgICAgICAgY2hhdE1lc3NhZ2VWaWV3TW9kZWxNb2NrLmZyb21Vc2VyID0gXCJ1c2VyMVwiO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2sudG9Vc2VyID0gXCJ1c2VyMlwiO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2subWVzc2FnZSA9IFwiXCI7XG4gICAgICAgIGNoYXRNZXNzYWdlVmlld01vZGVsTW9jay5tZXNzYWdlVGltZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGNoYXRNZXNzYWdlVmlld01vZGVscy5wdXNoKGNoYXRNZXNzYWdlVmlld01vZGVsTW9jayk7XG4gICAgfVxuXG4gICAgXG59IiwiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gXCIuL0Fic3RyYWN0Q29udHJvbGxlclwiO1xuaW1wb3J0IFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiXG5pbXBvcnQgXCIuLi9tb2RlbC9Vc2VyTW9kZWxcIlxuaW1wb3J0IFwiLi4vdmlldy9BYnN0cmFjdFZpZXdcIlxuaW1wb3J0IFwiLi4vdmlldy9Vc2VyVmlld1wiXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4uL3ZpZXcvQWJzdHJhY3RWaWV3XCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBVc2VyVmlldyB9IGZyb20gXCIuLi92aWV3L1VzZXJWaWV3XCI7XG5pbXBvcnQgeyBVc2VyTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvVXNlck1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ29udHJvbGxlciB7XG4gICAgcHJpdmF0ZSBfbW9kZWw6IFVzZXJNb2RlbDtcbiAgICBwcml2YXRlIF92aWV3OiBVc2VyVmlldztcblxuXG4gICAgY29uc3RydWN0b3IobW9kZWw6IFVzZXJNb2RlbCwgdmlldzogVXNlclZpZXcpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy5fdmlldyA9IHZpZXc7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBldmVudEhhbmRsZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgZXZlbnRIYW5kbGVyKHZtOiBBY3RpdmVVc2VyVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbW9kZWwuc29tZUJ1c2luZXNzTWV0aG9kKHZtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdGVzdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYWN0aXZlVXNlcnNNb2NrOiBBY3RpdmVVc2VyVmlld01vZGVsW10gPSBbXTtcbiAgICAgICAgbGV0IGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrID0gbmV3IEFjdGl2ZVVzZXJWaWV3TW9kZWwoKTtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sudXNlck5hbWUgPSBcInNvbWUgdXNlclwiO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jay5sYXN0QWN0aXZlID0gXCIzIGhycyBhZ29cIjtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sub25saW5lID0gdHJ1ZTtcbiAgICAgICAgYWN0aXZlVXNlcnNNb2NrLnB1c2goYWN0aXZlVXNlclZpZXdNb2RlbE1vY2spO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jayA9IG5ldyBBY3RpdmVVc2VyVmlld01vZGVsKCk7XG4gICAgICAgIGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrLmxhc3RBY3RpdmUgPSBcIjMgaHJzIGFnb1wiO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jay5vbmxpbmUgPSB0cnVlO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jay51c2VyTmFtZSA9IFwic29tZSB1c2VyIDJcIjtcbiAgICAgICAgYWN0aXZlVXNlcnNNb2NrLnB1c2goYWN0aXZlVXNlclZpZXdNb2RlbE1vY2spO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcihhY3RpdmVVc2Vyc01vY2spO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBY3RpdmVVc2VycygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbW9kZWwuZ2V0QWN0aXZlVXNlcnMoKTtcbiAgICB9XG5cbiAgICBcbn0iLCJpbXBvcnQgeyBDb250cm9sbGVyIH0gZnJvbSBcIi4vY29udHJvbGxlci9BYnN0cmFjdENvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFVzZXJNb2RlbCB9IGZyb20gXCIuL21vZGVsL1VzZXJNb2RlbFwiXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL21vZGVsL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IFZpZXcgfSBmcm9tIFwiLi92aWV3L0Fic3RyYWN0Vmlld1wiO1xuaW1wb3J0IHsgVXNlclZpZXcgfSBmcm9tIFwiLi92aWV3L1VzZXJWaWV3XCI7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXIvVXNlckNvbnRyb2xsZXJcIjtcbmltcG9ydCB7IE1vZGVsRmFjdG9yeSB9IGZyb20gXCIuL21vZGVsL01vZGVsRmFjdG9yeVwiO1xuaW1wb3J0IHsgQWN0aXZlVXNlclZpZXdNb2RlbCB9IGZyb20gXCIuL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuL3ZpZXdtb2RlbC9DaGF0TWVzc2FnZVZpZXdNb2RlbFwiO1xuaW1wb3J0ICogYXMgSGFuZGxlYmFycyBmcm9tIFwiaGFuZGxlYmFyc1wiO1xuaW1wb3J0IG1hcmtkb3duaXQgPSByZXF1aXJlKCdtYXJrZG93bi1pdCcpO1xuaW1wb3J0IHsgQ2hhdE1vZGVsIH0gZnJvbSBcIi4vbW9kZWwvQ2hhdE1vZGVsXCI7XG5pbXBvcnQgeyBDaGF0VmlldyB9IGZyb20gXCIuL3ZpZXcvQ2hhdFZpZXdcIjtcbmltcG9ydCB7IENoYXRDb250cm9sbGVyIH0gZnJvbSBcIi4vY29udHJvbGxlci9DaGF0Q29udHJvbGxlclwiO1xuaW1wb3J0IHsgSnNvbkFQSSB9IGZyb20gXCIuL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG4vLyBpbXBvcnQgbG9nID0gcmVxdWlyZSgnbG9nbGV2ZWwnKVxuaW1wb3J0ICogYXMgbG9nIGZyb20gJ2xvZ2xldmVsJztcbi8vIGltcG9ydCBsb2cgZnJvbSAnbG9nbGV2ZWwnO1xuaW1wb3J0IHsgRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlL0VuY3J5cHRpb25TZXJ2aWNlXCI7XG5pbXBvcnQgeyBTSkNMRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlL1NKQ0xFbmNyeXB0aW9uU2VydmljZVwiO1xuLy8gdmFyIG1hcmtkb3duaXQgPSByZXF1aXJlKCdtYXJrZG93bi1pdCcpO1xudmFyIG1kID0gbmV3IG1hcmtkb3duaXQoKTtcblxuXG5jb25zdCB1c2VyQm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhY3RzLWJveCcpO1xuXG5sb2cuc2V0TGV2ZWwoXCJUUkFDRVwiKVxuXG5jb25zdCBjaGF0TW9kZWwgPSBuZXcgQ2hhdE1vZGVsKCk7XG5cbmNvbnN0IHVzZXJNb2RlbCA9IG5ldyBVc2VyTW9kZWwoKTtcbi8vIGNvbnN0IHVzZXJNb2RlbCA9IE1vZGVsRmFjdG9yeS5jcmVhdGVNb2RlbChcIlVTRVJcIik7XG4vLyBAdHMtaWdub3JlOiBBcmd1bWVudCBvZiB0eXBlICdIVE1MRWxlbWVudCB8IG51bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHBhcmFtZXRlciBvZiB0eXBlICdIVE1MRWxlbWVudCcuIFR5cGUgJ251bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHR5cGUgJ0hUTUxFbGVtZW50Jy5cbmNvbnN0IHVzZXJWaWV3ID0gbmV3IFVzZXJWaWV3KHVzZXJNb2RlbCwgY2hhdE1vZGVsLCB1c2VyQm94KTtcblxuLy8gY29uc29sZS5sb2codXNlckJveCk7XG5cbnVzZXJNb2RlbC5hdHRhY2godXNlclZpZXcpO1xuLy8gdXNlclZpZXcubW9kZWxcblxuXG5jb25zdCB1c2VyQ29udHJvbGxlciA9IG5ldyBVc2VyQ29udHJvbGxlcih1c2VyTW9kZWwsIHVzZXJWaWV3KTtcbi8vIHVzZXJDb250cm9sbGVyLnRlc3QoKTtcblxuXG5cbi8vIHVzZXJNb2RlbC5zb21lQnVzaW5lc3NNZXRob2QoYWN0aXZlVXNlcnNNb2NrKTtcbmxvZy5pbmZvKFwiaGVsbG9cIik7XG5cbmNvbnN0IGNoYXRBcmVhID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoYXQtYXJlYS1uZXcnKTtcbi8vIEB0cy1pZ25vcmU6IEFyZ3VtZW50IG9mIHR5cGUgJ0hUTUxFbGVtZW50IHwgbnVsbCcgaXMgbm90IGFzc2lnbmFibGUgdG8gcGFyYW1ldGVyIG9mIHR5cGUgJ0hUTUxFbGVtZW50Jy4gVHlwZSAnbnVsbCcgaXMgbm90IGFzc2lnbmFibGUgdG8gdHlwZSAnSFRNTEVsZW1lbnQnLlxuY29uc3QgY2hhdFZpZXcgPSBuZXcgQ2hhdFZpZXcoY2hhdE1vZGVsLCBjaGF0QXJlYSk7XG5jaGF0TW9kZWwuYXR0YWNoKGNoYXRWaWV3KTtcbmNvbnN0IGNoYXRDb250cm9sbGVyID0gbmV3IENoYXRDb250cm9sbGVyKGNoYXRNb2RlbCwgY2hhdFZpZXcpO1xuXG5cbmZ1bmN0aW9uIHNvbWVGdW5jKHZtOiBBY3RpdmVVc2VyVmlld01vZGVsKTogdm9pZCB7XG4gICAgLy8gbG9nLmluZm8odm0pO1xuICAgIC8vIGxvZ2dlci5pbmZvKHZtKVxufVxuXG51c2VyQ29udHJvbGxlci5nZXRBY3RpdmVVc2VycygpO1xuXG5sb2cuaW5mbyhcInRlc3RcIik7XG4vLyBzb21lRnVuYyhhY3RpdmVVc2VyVmlld01vZGVsTW9jayk7XG5cbi8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG52YXIgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtc2dfY29udGFpbmVyX3RlbXBsYXRlXCIpLmlubmVySFRNTDtcblxudmFyIG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG5cbkpzb25BUEkuQUNUSVZFX1VTRVJTX0dFVCArICdhZWYnO1xuXG5jb25zdCBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UgPSBuZXcgU0pDTEVuY3J5cHRpb25TZXJ2aWNlKCk7XG5sZXQgY3QgPSBlbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFwicGFzc3dvcmRcIixcImRhdGFcIik7XG5jb25zb2xlLmxvZyhlbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFwicGFzc3dvcmRcIiwgSlNPTi5wYXJzZShjdCBhcyBzdHJpbmcpKSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2F2YXRhcicsIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAnPGRpdiBjbGFzcz1cImltZ19jb250X21zZ1wiPiA8aW1nIHNyYz1cImh0dHBzOi8vc3RhdGljLnR1cmJvc3F1aWQuY29tL1ByZXZpZXcvMDAxMjkyLzQ4MS9XVi9fRC5qcGdcIiBjbGFzcz1cInJvdW5kZWQtY2lyY2xlIHVzZXJfaW1nX21zZ1wiPiA8L2Rpdj4nO1xufSk7IiwiaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmFibGVcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vQWJzdHJhY3RNb2RlbFwiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZlclwiO1xuaW1wb3J0IHsgZmV0Y2hFcnJvckhhbmRsZXIgfSBmcm9tIFwiLi9GZXRjaEVycm9ySGFuZGxlclwiO1xuaW1wb3J0IHsgQWN0aXZlVXNlclZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsXCI7XG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5pbXBvcnQgbG9nID0gcmVxdWlyZSgnbG9nbGV2ZWwnKTtcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2UvRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IFNKQ0xFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL1NKQ0xFbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VEVE8gfSBmcm9tIFwiLi4vZHRvL0NoYXRNZXNzYWdlRFRPXCI7XG5pbXBvcnQgeyBDaGF0TW9kZWxIZWxwZXIgfSBmcm9tIFwiLi9DaGF0TW9kZWxIZWxwZXJcIjtcblxuZXhwb3J0IGNsYXNzIENoYXRNb2RlbCBpbXBsZW1lbnRzIFN1YmplY3Qge1xuICAgIC8qKlxuICAqIEB0eXBlIHtPYnNlcnZlcltdfSBMaXN0IG9mIHN1YnNjcmliZXJzLiBJbiByZWFsIGxpZmUsIHRoZSBsaXN0IG9mXG4gICogc3Vic2NyaWJlcnMgY2FuIGJlIHN0b3JlZCBtb3JlIGNvbXByZWhlbnNpdmVseSAoY2F0ZWdvcml6ZWQgYnkgZXZlbnRcbiAgKiB0eXBlLCBldGMuKS5cbiAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcbiAgICBwcml2YXRlIHN0YXRlOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdIHwgbnVsbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlc01hcDogTWFwPHN0cmluZywgQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXT47XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX21lc3NhZ2VzTWFwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3Vic2NyaXB0aW9uIG1hbmFnZW1lbnQgbWV0aG9kcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgYXR0YWNoKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgICAgICBjb25zb2xlLmxvZygnU3ViamVjdDogQXR0YWNoZWQgYW4gb2JzZXJ2ZXIuJyk7XG4gICAgICAgIHRoaXMuX29ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGV0YWNoKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBvYnNlcnZlckluZGV4ID0gdGhpcy5fb2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLl9vYnNlcnZlcnMuc3BsaWNlKG9ic2VydmVySW5kZXgsIDEpO1xuICAgICAgICBjb25zb2xlLmxvZygnU3ViamVjdDogRGV0YWNoZWQgYW4gb2JzZXJ2ZXIuJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFVzZXJNZXNzYWdlcyh1c2VybmFtZTogc3RyaW5nLCBtZXNzYWdlczogQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXSkge1xuICAgICAgICB0aGlzLl9tZXNzYWdlc01hcC5zZXQodXNlcm5hbWUsIG1lc3NhZ2VzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIHVwZGF0ZSBpbiBlYWNoIHN1YnNjcmliZXIuXG4gICAgICovXG4gICAgcHVibGljIG5vdGlmeSh1c2VyTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBOb3RpZnlpbmcgb2JzZXJ2ZXJzLi4uJyk7XG4gICAgICAgIGZvciAoY29uc3Qgb2JzZXJ2ZXIgb2YgdGhpcy5fb2JzZXJ2ZXJzKSB7XG4gICAgICAgICAgICBvYnNlcnZlci51cGRhdGUodGhpcy5fbWVzc2FnZXNNYXAuZ2V0KHVzZXJOYW1lKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc29tZUJ1c2luZXNzTWV0aG9kKGNoYXRNZXNzYWdlTGlzdDogQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0YXRlID0gY2hhdE1lc3NhZ2VMaXN0O1xuICAgICAgICB0aGlzLmhlbHBlck1ldGhvZCgpO1xuICAgICAgICBjb25zb2xlLmxvZyhgU3ViamVjdDogTXkgc3RhdGUgaGFzIGp1c3QgY2hhbmdlZGApO1xuICAgICAgICBjb25zb2xlLmxvZyhjaGF0TWVzc2FnZUxpc3QpO1xuICAgICAgICB0aGlzLm5vdGlmeShcInNvbWUgdXNlclwiKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0bWVzc2FnZXModXNlck5hbWU6IHN0cmluZywgcGFzc3BocmFzZTogc3RyaW5nLCBsYXN0TWVzc2FnZVRpbWU6IHN0cmluZyB8IG51bGwpOiBQcm9taXNlPENoYXRNZXNzYWdlVmlld01vZGVsW10+IHtcbiAgICAgICAgY29uc3QgY1ZNcyA9IGF3YWl0IENoYXRNb2RlbEhlbHBlci5nZXRNZXNzYWdlcyh1c2VyTmFtZSwgcGFzc3BocmFzZSwgbGFzdE1lc3NhZ2VUaW1lLCB0aGlzKTtcbiAgICAgICAgaWYgKGNWTXMgIT0gbnVsbCkge1xuICAgICAgICAgICAgbG9nLmluZm8oJ1N1YmplY3Q6IE15IHN0YXRlIGhhcyBqdXN0IGNoYW5nZWQnKVxuICAgICAgICAgICAgbG9nLmRlYnVnKGNWTXMpO1xuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZXNNYXAuc2V0KHVzZXJOYW1lLCBjVk1zKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5KHVzZXJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcignTWVzc2FnZXMgd2VyZSBudWxsJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY1ZNcztcbiAgICB9XG5cblxuXG4gICAgcHJpdmF0ZSBoZWxwZXJNZXRob2QoKSB7IH1cblxuICAgIHB1YmxpYyBwb3B1bGF0ZU1lc3NhZ2VzKCk6IHZvaWQge1xuXG4gICAgfVxuXG5cblxufSIsImltcG9ydCB7IENoYXRNZXNzYWdlRFRPIH0gZnJvbSBcIi4uL2R0by9DaGF0TWVzc2FnZURUT1wiO1xuXG5pbXBvcnQgKiBhcyBsb2cgZnJvbSBcImxvZ2xldmVsXCI7XG5cbmltcG9ydCB7IENoYXRNZXNzYWdlVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9DaGF0TWVzc2FnZVZpZXdNb2RlbFwiO1xuXG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5cbmltcG9ydCB7IGZldGNoRXJyb3JIYW5kbGVyIH0gZnJvbSBcIi4vRmV0Y2hFcnJvckhhbmRsZXJcIjtcblxuaW1wb3J0IHsgRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZS9FbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgU0pDTEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2UvU0pDTEVuY3J5cHRpb25TZXJ2aWNlXCI7XG5pbXBvcnQgeyBDaGF0TW9kZWwgfSBmcm9tIFwiLi9DaGF0TW9kZWxcIlxuZXhwb3J0IGNsYXNzIENoYXRNb2RlbEhlbHBlciB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgZW5jcnlwdGlvblNlcnZpY2UgPSBuZXcgU0pDTEVuY3J5cHRpb25TZXJ2aWNlKCk7XG5cbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGdldE1lc3NhZ2VzKHVzZXJOYW1lOiBzdHJpbmcsIHBhc3NwaHJhc2U6IHN0cmluZywgbGFzdE1lc3NhZ2VUaW1lOiBzdHJpbmcgfCBudWxsLCBjaGF0TW9kZWw6IENoYXRNb2RlbCk6IFByb21pc2U8Q2hhdE1lc3NhZ2VWaWV3TW9kZWxbXT4ge1xuICAgICAgICBzd2l0Y2ggKGxhc3RNZXNzYWdlVGltZSkge1xuICAgICAgICAgICAgY2FzZSBudWxsOiB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcy5nZXRBbGxNZXNzYWdlc0FqYXgodXNlck5hbWUpXG4gICAgICAgICAgICAgICAgLy8gICAgIC50aGVuKChkYXRhOiBDaGF0TWVzc2FnZURUT1tdKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICBsb2cuZGVidWcoYFN1YmplY3Q6IHJlY2VpdmVkIGFsbCBtZXNzYWdlc2ApO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gbGV0IHVzZXJOYW1lcyA9IGRhdGEubWFwKENoYXRNZXNzYWdlVmlld01vZGVsID0+IENoYXRNZXNzYWdlVmlld01vZGVsLmZyb21Vc2VyKVxuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gbGV0IHN1bXQgPSBkYXRhLm1hcChjaGF0TWVzc2FnZVZpZXdNb2RlbCA9PiB7IHJldHVybiB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQocGFzc3BocmFzZSwgY2hhdE1lc3NhZ2VWaWV3TW9kZWwubWVzc2FnZUNpcGhlcikgfSk7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICByZXR1cm4gZGF0YS5tYXAodm0gPT4gdGhpcy50b0NoYXRNZXNzYWdlVk0odm0sIHBhc3NwaHJhc2UpKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIC8vIGNoYXRNb2RlbC5zZXRVc2VyTWVzc2FnZXModXNlck5hbWUsIGNoYXRNZXNzYWdlVk1zKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIC8vIGNoYXRNb2RlbC5ub3RpZnkoKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgfSlcbiAgICAgICAgICAgICAgICAvLyBicmVhaztcblxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGE6IENoYXRNZXNzYWdlRFRPW10gPSBhd2FpdCB0aGlzLmdldEFsbE1lc3NhZ2VzQWpheCh1c2VyTmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEubWFwKHZtID0+IHRoaXMudG9DaGF0TWVzc2FnZVZNKHZtLCBwYXNzcGhyYXNlKSk7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmdldE5ld01lc3NhZ2VzQWpheCh1c2VyTmFtZSwgbGFzdE1lc3NhZ2VUaW1lKVxuICAgICAgICAgICAgICAgIC8vICAgICAudGhlbigoZGF0YTogQ2hhdE1lc3NhZ2VEVE9bXSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgbG9nLmRlYnVnKGBTdWJqZWN0OiByZWNlaXZlZCBuZXcgbWVzc2FnZXNgKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIHJldHVybiBkYXRhLm1hcCh2bSA9PiB0aGlzLnRvQ2hhdE1lc3NhZ2VWTSh2bSwgcGFzc3BocmFzZSkpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gY2hhdE1vZGVsLnNldFVzZXJNZXNzYWdlcyh1c2VyTmFtZSwgY2hhdE1lc3NhZ2VWTXMpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gdGhpcy5zdGF0ZSA9IGRhdGE7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICAvLyBjaGF0TW9kZWwubm90aWZ5KCk7XG4gICAgICAgICAgICAgICAgLy8gICAgIH0pXG4gICAgICAgICAgICAgICAgLy8gYnJlYWs7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YTogQ2hhdE1lc3NhZ2VEVE9bXSA9IGF3YWl0IHRoaXMuZ2V0TmV3TWVzc2FnZXNBamF4KHVzZXJOYW1lLCBsYXN0TWVzc2FnZVRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLm1hcCh2bSA9PiB0aGlzLnRvQ2hhdE1lc3NhZ2VWTSh2bSwgcGFzc3BocmFzZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgdG9DaGF0TWVzc2FnZVZNKGNoYXRNZXNzYWdlRFRPOiBDaGF0TWVzc2FnZURUTywgcGFzc3BocmFzZTogc3RyaW5nKTogQ2hhdE1lc3NhZ2VWaWV3TW9kZWwge1xuICAgICAgICBjb25zdCB2bSA9IG5ldyBDaGF0TWVzc2FnZVZpZXdNb2RlbCgpO1xuICAgICAgICB2bS5mcm9tVXNlciA9IGNoYXRNZXNzYWdlRFRPLmZyb21Vc2VyO1xuICAgICAgICB2bS50b1VzZXIgPSBjaGF0TWVzc2FnZURUTy50b1VzZXI7XG4gICAgICAgIHZtLm1lc3NhZ2VUaW1lID0gY2hhdE1lc3NhZ2VEVE8ubWVzc2FnZVRpbWU7XG4gICAgICAgIHZtLm1lc3NhZ2UgPSB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQocGFzc3BocmFzZSwgY2hhdE1lc3NhZ2VEVE8ubWVzc2FnZUNpcGhlcikgYXMgc3RyaW5nO1xuICAgICAgICByZXR1cm4gdm07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZ2V0QWxsTWVzc2FnZXNBamF4KHRvVXNlcjogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGlmIChKc29uQVBJLmF1dGhUb2tlbiA9PSBudWxsKSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoXCJhdXRoVG9rZW4gbnVsbFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIEpzb25BUEkuYXV0aFRva2VuKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtKc29uQVBJLkNIQVRfTUVTU0FHRVNfR0VUfS8ke3RvVXNlcn1gLCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgIGlmIChmZXRjaEVycm9ySGFuZGxlcihyZXNwb25zZS5jbG9uZSgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YTogUHJvbWlzZTxhbnk+ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhc3luYyBnZXROZXdNZXNzYWdlc0FqYXgodG9Vc2VyOiBzdHJpbmcsIGxhc3RNZXNzYWdlVGltZVN0YW1wOiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaWYgKEpzb25BUEkuYXV0aFRva2VuID09IG51bGwpIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcihcImF1dGhUb2tlbiBudWxsXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9O1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnWC1BVVRILVRPS0VOJywgSnNvbkFQSS5hdXRoVG9rZW4pO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke0pzb25BUEkuQ0hBVF9NRVNTQUdFU19HRVR9LyR7dG9Vc2VyfS8ke2xhc3RNZXNzYWdlVGltZVN0YW1wfWAsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZS5jbG9uZSgpKTtcbiAgICAgICAgaWYgKGZldGNoRXJyb3JIYW5kbGVyKHJlc3BvbnNlLmNsb25lKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhOiBQcm9taXNlPGFueT4gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbn0iLCJpbXBvcnQgbG9nID0gcmVxdWlyZShcImxvZ2xldmVsXCIpO1xuaW1wb3J0IHsgc3ByaW50ZiB9IGZyb20gXCJzcHJpbnRmLWpzXCI7XG4vLyBpbXBvcnQgc3ByaW50ZiA9IHJlcXVpcmUoJ3NwcmludGYtanMnKS5zcHJpbnRmO1xuXG5leHBvcnQgZnVuY3Rpb24gZmV0Y2hFcnJvckhhbmRsZXIocmVzcG9uc2U6IFJlc3BvbnNlKSB7XG4gICAgLy8gYWxlcnRpZnkuc3VjY2VzcygnQ3VycmVudCBwb3NpdGlvbiA6ICcgKyBhbGVydGlmeS5nZXQoJ25vdGlmaWVyJywgJ3Bvc2l0aW9uJykpO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgbm90IG9rIGFuZCB0aGVyZSBpcyBubyBqc29uIGJvZHlcbiAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICAgICAgICAgIC8vIHdpbmRvdy5hbGVydChzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignU29tZSBlcnJvciBvY2N1cmVkLiBIdHRwIGNvZGUgaXMgJXMnLCByZXNwb25zZS5zdGF0dXMpKTtcbiAgICAgICAgICAgIGxvZy5lcnJvcihzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgbG9nLmVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSkudGhlbihqc29uID0+IHtcbiAgICAgICAgICAgIC8vIHRoZSBzdGF0dXMgd2FzIG5vdCBvayBidXQgdGhlcmUgaXMgYSBqc29uIGJvZHlcbiAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihqc29uLmVycm9yLm1lc3NhZ2UpOyAvLyBleGFtcGxlIGVycm9yIG1lc3NhZ2UgcmV0dXJuZWQgYnkgYSBSRVNUIEFQSVxuICAgICAgICAgICAgLy8gd2luZG93LmFsZXJ0KHNwcmludGYoJ0Vycm9yOiAlcyAoSHR0cCBjb2RlICVzKScsIGpzb24sIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignU29tZSBlcnJvciBvY2N1cmVkLiBIdHRwIGNvZGUgaXMgJXMnLCByZXNwb25zZS5zdGF0dXMpKTtcbiAgICAgICAgICAgIGxvZy5lcnJvcihzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgbG9nLmVycm9yKGpzb24pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmVyXCI7XG5pbXBvcnQgeyBmZXRjaEVycm9ySGFuZGxlciB9IGZyb20gXCIuL0ZldGNoRXJyb3JIYW5kbGVyXCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCAqIGFzIGxvZyBmcm9tIFwibG9nbGV2ZWxcIjtcblxuZXhwb3J0IGNsYXNzIFVzZXJNb2RlbCBpbXBsZW1lbnRzIFN1YmplY3Qge1xuICAgIC8qKlxuICAqIEB0eXBlIHtPYnNlcnZlcltdfSBMaXN0IG9mIHN1YnNjcmliZXJzLiBJbiByZWFsIGxpZmUsIHRoZSBsaXN0IG9mXG4gICogc3Vic2NyaWJlcnMgY2FuIGJlIHN0b3JlZCBtb3JlIGNvbXByZWhlbnNpdmVseSAoY2F0ZWdvcml6ZWQgYnkgZXZlbnRcbiAgKiB0eXBlLCBldGMuKS5cbiAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IG9ic2VydmVyczogT2JzZXJ2ZXJbXSA9IFtdO1xuICAgIHByaXZhdGUgc3RhdGU6IEFjdGl2ZVVzZXJWaWV3TW9kZWxbXSB8IHVuZGVmaW5lZDtcbiAgICAvLyBAdHMtaWdub3JlOiBDYW5ub3QgZmluZCBuYW1lICdob3N0QWRkcmVzcycuXG5cbiAgICBjb25zdHJ1Y3RvcigpIHsgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdWJzY3JpcHRpb24gbWFuYWdlbWVudCBtZXRob2RzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2gob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBBdHRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgcHVibGljIGRldGFjaChvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXJJbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2Uob2JzZXJ2ZXJJbmRleCwgMSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBEZXRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIHVwZGF0ZSBpbiBlYWNoIHN1YnNjcmliZXIuXG4gICAgICovXG4gICAgcHVibGljIG5vdGlmeSgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1N1YmplY3Q6IE5vdGlmeWluZyBvYnNlcnZlcnMuLi4nKTtcbiAgICAgICAgZm9yIChjb25zdCBvYnNlcnZlciBvZiB0aGlzLm9ic2VydmVycykge1xuICAgICAgICAgICAgb2JzZXJ2ZXIudXBkYXRlKHRoaXMuc3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNvbWVCdXNpbmVzc01ldGhvZChhY3RpdmV1c2VyTGlzdDogQWN0aXZlVXNlclZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBhY3RpdmV1c2VyTGlzdDtcbiAgICAgICAgdGhpcy5oZWxwZXJNZXRob2QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYFN1YmplY3Q6IE15IHN0YXRlIGhhcyBqdXN0IGNoYW5nZWRgKTtcbiAgICAgICAgY29uc29sZS5sb2coYWN0aXZldXNlckxpc3QpO1xuICAgICAgICB0aGlzLm5vdGlmeSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldEFjdGl2ZVVzZXJzXG4gICAgICovXG4gICAgcHVibGljIGdldEFjdGl2ZVVzZXJzKCk6IHZvaWQge1xuICAgICAgICBpZihKc29uQVBJLmF1dGhUb2tlbiE9IG51bGwpe1xuICAgICAgICB0aGlzLmdldEFjdGl2ZVVzZXJzQWpheChKc29uQVBJLmF1dGhUb2tlbiwgSnNvbkFQSS5BQ1RJVkVfVVNFUlNfR0VUKVxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gLy8gYWN0aXZlVXNlcnMgPSBkYXRhO1xuICAgICAgICAgICAgICAgIC8vIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2FjdGl2ZVVzZXJzJywgSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ2FjdGl2ZVVzZXJzJykpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWJqZWN0OiByZWNlaXZlZCBhamF4IGFjdGl2ZSB1c2Vyc2ApO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBkYXRhO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5KCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbG9nLmVycm9yKCdBdXRoIHRva2VuIGlzIG51bGwnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldEFjdGl2ZVVzZXJzQWpheChhdXRoVG9rZW4yOiBzdHJpbmcsIFVSTDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgbGV0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICAvLyBoZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsIGJhc2ljQXV0aFRva2VuKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIGF1dGhUb2tlbjIpO1xuICAgICAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChKc29uQVBJLkFDVElWRV9VU0VSU19HRVQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZS5jbG9uZSgpKTtcbiAgICAgICAgaWYgKGZldGNoRXJyb3JIYW5kbGVyKHJlc3BvbnNlLmNsb25lKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgLy8gcmV0dXJuIGRhdGE7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoZGF0YSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIHJlc29sdmUoZGF0YSlcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICByZWplY3QoJ1Jlc3BvbnNlIGRhdGEgbnVsbCcpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoZWxwZXJNZXRob2QoKSB7IH1cblxufSIsImltcG9ydCBtYXJrZG93bml0ID0gcmVxdWlyZSgnbWFya2Rvd24taXQnKTtcbmltcG9ydCB7IE1hcmtEb3duU2VydmljZSB9IGZyb20gJy4vTWFya0Rvd25TZXJ2aWNlJztcbmV4cG9ydCBjbGFzcyBNYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlIGltcGxlbWVudHMgTWFya0Rvd25TZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZCA9IG5ldyBtYXJrZG93bml0KCk7XG5cbiAgICByZW5kZXIoaW5wdXRTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZC5yZW5kZXIoaW5wdXRTdHJpbmcpO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gXCIuL0VuY3J5cHRpb25TZXJ2aWNlXCI7XG5pbXBvcnQgKiBhcyBzamNsIGZyb20gXCJzamNsXCI7XG5cbmV4cG9ydCBjbGFzcyBTSkNMRW5jcnlwdGlvblNlcnZpY2UgaW1wbGVtZW50cyBFbmNyeXB0aW9uU2VydmljZSB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXJhbXM6IGFueSA9IHsgbW9kZTogXCJnY21cIiwgdHM6IDEyOCwgYWRhdGE6IFwiXCIsIGl0ZXI6IDEwMDAwfVxuICAgIHB1YmxpYyBlbmNyeXB0KHBhc3NwaHJhc2U6IHN0cmluZywgcGxhaW5UZXh0OiBzdHJpbmcpOiBPYmplY3Qge1xuICAgICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhc3NwaHJhc2UsIHBsYWluVGV4dCwgdGhpcy5wYXJhbXMpO1xuICAgIH0gXG4gICAgXG4gICAgcHVibGljIGRlY3J5cHQocGFzc3BocmFzZTogc3RyaW5nLCBjaXBoZXI6IE9iamVjdCk6IE9iamVjdCB7XG4gICAgICAgIC8vIHJldHVybiBzamNsLmRlY3J5cHQocGFzc3BocmFzZSwgY2lwaGVyIGFzIHNqY2wuU2pjbENpcGhlckVuY3J5cHRlZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuICAgICAgICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhc3NwaHJhc2UsIEpTT04uc3RyaW5naWZ5KGNpcGhlciksIHVuZGVmaW5lZCwgdW5kZWZpbmVkKTtcbiAgICB9XG59IiwiZXhwb3J0IG5hbWVzcGFjZSBKc29uQVBJIHtcbiAgICAvLyBAdHMtaWdub3JlOiBDYW5ub3QgZmluZCBuYW1lICdob3N0QWRkcmVzcycuXG4gICAgZXhwb3J0IGxldCB1c2VyTmFtZTogc3RyaW5nIHwgbnVsbCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd1c2VyTmFtZScpO1xuICAgIGV4cG9ydCBsZXQgYXV0aFRva2VuOiBzdHJpbmcgfCBudWxsID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2F1dGhUb2tlbicpO1xuICAgIGV4cG9ydCBjb25zdCBBQ1RJVkVfVVNFUlNfR0VUID0gYC9hcGkvY2hhdC9nZXQvYWN0aXZlLXVzZXJzYDtcbiAgICBleHBvcnQgY29uc3QgQ0hBVF9NRVNTQUdFU19HRVQgPSBgL2FwaS9jaGF0L2dldC9tZXNzYWdlc2A7XG4gICAgXG59IiwiZXhwb3J0IGNsYXNzIFRlbXBsYXRlRmFjdG9yeSB7XG4gICAgLy8gc3RhdGljIGdldFRlbXBsYXRlKHRlbXBsYXRlTmFtZTogc3RyaW5nKTogSGFuZGxlYmFycy5UZW1wbGF0ZURlbGVnYXRlPGFueT4ge1xuXG4gICAgLy8gICAgIHN3aXRjaCAodGVtcGxhdGVOYW1lKSB7XG4gICAgLy8gICAgICAgICBjYXNlIFwidXNlci1jb250YWN0LW9ubGluZS10ZW1wbGF0ZVwiOiB7XG4gICAgLy8gICAgICAgICAgICAgLy8gbGV0IHNvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidXNlci1jb250YWN0LW9ubGluZS10ZW1wbGF0ZVwiKS5pbm5lckhUTUw7XG4gICAgLy8gICAgICAgICAgICAgLy8gbGV0IG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG4gICAgLy8gICAgICAgICAgICAgLy8gcmV0dXJuIG1zZ0NvbnRhaW5lclRlbXBsYXRlO1xuICAgIC8vICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRlbXBsYXRlKHRlbXBsYXRlTmFtZSk7XG4gICAgLy8gICAgICAgICB9XG4gICAgLy8gICAgICAgICBjYXNlIFwibXNnX2NvbnRhaW5lcl9zZW5kX3RlbXBsYXRlXCI6IHtcbiAgICAvLyAgICAgICAgICAgICAvLyBsZXQgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtc2dfY29udGFpbmVyX3NlbmRfdGVtcGxhdGVcIikuaW5uZXJIVE1MO1xuICAgIC8vICAgICAgICAgICAgIC8vIGxldCBtc2dDb250YWluZXJUZW1wbGF0ZSA9IEhhbmRsZWJhcnMuY29tcGlsZShzb3VyY2UpO1xuICAgIC8vICAgICAgICAgICAgIC8vIHJldHVybiBtc2dDb250YWluZXJUZW1wbGF0ZTtcbiAgICAvLyAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVUZW1wbGF0ZSh0ZW1wbGF0ZU5hbWUpO1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICAgICAgY2FzZSBcIm1zZ19jb250YWluZXJfdGVtcGxhdGVcIjoge1xuICAgIC8vICAgICAgICAgICAgIC8vIGxldCBzb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1zZ19jb250YWluZXJfc2VuZF90ZW1wbGF0ZVwiKS5pbm5lckhUTUw7XG4gICAgLy8gICAgICAgICAgICAgLy8gbGV0IG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG4gICAgLy8gICAgICAgICAgICAgLy8gcmV0dXJuIG1zZ0NvbnRhaW5lclRlbXBsYXRlO1xuICAgIC8vICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRlbXBsYXRlKHRlbXBsYXRlTmFtZSk7XG4gICAgLy8gICAgICAgICB9XG4gICAgLy8gICAgICAgICBkZWZhdWx0OlxuICAgIC8vICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB0ZW1wbGF0ZSBuYW1lJyk7XG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG5cbiAgICBzdGF0aWMgZ2V0VGVtcGxhdGUodGVtcGxhdGVOYW1lOiBzdHJpbmcpOiBIYW5kbGViYXJzLlRlbXBsYXRlRGVsZWdhdGU8YW55PiB7XG4gICAgICAgIC8vQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgbGV0IHNvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRlbXBsYXRlTmFtZSkuaW5uZXJIVE1MO1xuICAgICAgICBsZXQgbXNnQ29udGFpbmVyVGVtcGxhdGUgPSBIYW5kbGViYXJzLmNvbXBpbGUoc291cmNlKTtcbiAgICAgICAgcmV0dXJuIG1zZ0NvbnRhaW5lclRlbXBsYXRlO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmVyXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUZhY3RvcnkgfSBmcm9tIFwiLi4vdGVtcGxhdGUvVGVtcGxhdGVGYWN0b3J5XCI7XG5pbXBvcnQgeyBDaGF0TW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQ2hhdE1vZGVsXCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCAqIGFzIGxvZyBmcm9tICdsb2dsZXZlbCc7XG5pbXBvcnQgKiBhcyBET01QdXJpZnkgZnJvbSAnZG9tcHVyaWZ5JztcbmltcG9ydCB7IE1hcmtEb3duU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL01hcmtEb3duU2VydmljZVwiO1xuaW1wb3J0IHsgTWFya0Rvd25JdE1hcmtEb3duU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL01hcmtEb3duSXRNYXJrRG93blNlcnZpY2VcIjtcbmltcG9ydCB7IEpzb25BUEkgfSBmcm9tIFwiLi4vc2luZ2xldG9uL0pzb25BUElcIjtcbi8vIHZhciBtZCA9IG5ldyBtYXJrZG93bml0KCk7XG5cbmV4cG9ydCBjbGFzcyBDaGF0VmlldyBpbXBsZW1lbnRzIE9ic2VydmVyIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlU2VuZFRlbXBsYXRlID0gVGVtcGxhdGVGYWN0b3J5LmdldFRlbXBsYXRlKCdtc2dfY29udGFpbmVyX3NlbmRfdGVtcGxhdGUnKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlUmVjZWl2ZVRlbXBsYXRlID0gVGVtcGxhdGVGYWN0b3J5LmdldFRlbXBsYXRlKCdtc2dfY29udGFpbmVyX3RlbXBsYXRlJyk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfbWFya2Rvd25TZXJ2aWNlOiBNYXJrRG93blNlcnZpY2UgPSBuZXcgTWFya0Rvd25JdE1hcmtEb3duU2VydmljZSgpO1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihtb2RlbDogQ2hhdE1vZGVsLCBlbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cblxuICAgIHVwZGF0ZShkYXRhOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIGxvZy5pbmZvKCdDaGF0VmlldzogdXBkYXRpbmcgdmlldycpO1xuICAgICAgICAvLyBsZXQgaHRtbDogc3RyaW5nID0gXCJcIjtcbiAgICAgICAgZGF0YS5mb3JFYWNoKCh2bTogQ2hhdE1lc3NhZ2VWaWV3TW9kZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZtVGVtcCA9IHZtO1xuICAgICAgICAgICAgdm1UZW1wLm1lc3NhZ2UgPSB0aGlzLl9tYXJrZG93blNlcnZpY2UucmVuZGVyKHZtLm1lc3NhZ2UpO1xuICAgICAgICAgICAgLyoqIFZlcnkgSW1wb3J0YW50ISEhXG4gICAgICAgICAgICAqIFNhbml0aXppbmcgSFRNTCBiZWZvcmUgZGlzcGxheWluZyBvbiB3ZWJwYWdlIHRvIHByZXZlbnQgWFNTIGF0dGFja3MhIVxuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh2bVRlbXAuZnJvbVVzZXIgPT0gSnNvbkFQSS51c2VyTmFtZSkge1xuICAgICAgICAgICAgICAgICQodGhpcy5fZWxlbWVudCkuYXBwZW5kKERPTVB1cmlmeS5zYW5pdGl6ZSh0aGlzLl9tZXNzYWdlU2VuZFRlbXBsYXRlKHZtVGVtcCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICQodGhpcy5fZWxlbWVudCkuYXBwZW5kKERPTVB1cmlmeS5zYW5pdGl6ZSh0aGlzLl9tZXNzYWdlUmVjZWl2ZVRlbXBsYXRlKHZtVGVtcCkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGh0bWwgKz0gdGhpcy5fbWVzc2FnZVNlbmRUZW1wbGF0ZSh2bSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGh0bWwgPSBET01QdXJpZnkuc2FuaXRpemUobWQucmVuZGVyKGh0bWwpKTtcbiAgICAgICAgLy8gdGhpcy5fZWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICAvLyBsb2cuZGVidWcodGhpcy5fZWxlbWVudC5pbm5lckhUTUwpO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmVyXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgVmlldyB9IGZyb20gXCIuL0Fic3RyYWN0Vmlld1wiO1xuaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gXCIuLi9jb250cm9sbGVyL0Fic3RyYWN0Q29udHJvbGxlclwiO1xuaW1wb3J0IHsgVGVtcGxhdGVGYWN0b3J5IH0gZnJvbSBcIi4uL3RlbXBsYXRlL1RlbXBsYXRlRmFjdG9yeVwiO1xuaW1wb3J0IHsgQWN0aXZlVXNlclZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL0NoYXRNb2RlbFwiO1xuaW1wb3J0IGxvZyA9IHJlcXVpcmUoXCJsb2dsZXZlbFwiKTtcbmltcG9ydCAqIGFzIERPTVB1cmlmeSBmcm9tIFwiZG9tcHVyaWZ5XCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyVmlldyBpbXBsZW1lbnRzIE9ic2VydmVyIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tb2RlbDogTW9kZWw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfY2hhdE1vZGVsOiBDaGF0TW9kZWw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLy8gcHJpdmF0ZSB1c2VyQm94ZXM6IGFueVtdID0gIFtdO1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihtb2RlbDogTW9kZWwsIGNoYXRNb2RlbDogQ2hhdE1vZGVsLCBlbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgICB0aGlzLl9tb2RlbCA9IG1vZGVsO1xuICAgICAgICB0aGlzLl9jaGF0TW9kZWwgPSBjaGF0TW9kZWw7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQgPSBlbGVtZW50O1xuICAgIH1cblxuXG5cblxuICAgIHVwZGF0ZShkYXRhOiBBY3RpdmVVc2VyVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgbGV0IHRlbXBsYXRlID0gVGVtcGxhdGVGYWN0b3J5LmdldFRlbXBsYXRlKCd1c2VyLWNvbnRhY3Qtb25saW5lLXRlbXBsYXRlJyk7XG4gICAgICAgIGxldCBodG1sOiBzdHJpbmcgPSBcIlwiO1xuICAgICAgICBkYXRhLmZvckVhY2goKGVsZW1lbnQ6IEFjdGl2ZVVzZXJWaWV3TW9kZWwpID0+IHtcbiAgICAgICAgICAgIGh0bWwgKz0gdGVtcGxhdGUoZWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyB0aGlzLl9lbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgICQodGhpcy5fZWxlbWVudCkuaHRtbChET01QdXJpZnkuc2FuaXRpemUoaHRtbCkpO1xuICAgICAgICB0aGlzLmFkZFVzZXJDYWxsQmFja3MoKTtcbiAgICAgICAgY29uc29sZS5sb2codGhpcy5fZWxlbWVudC5pbm5lckhUTUwpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGVscGVyKCk6IHZvaWQge1xuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRVc2VyQ2FsbEJhY2tzKCk6IHZvaWQge1xuICAgICAgICBsZXQgdXNlckJveGVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndXNlci1ib3gnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1c2VyQm94ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB1c2VyQm94ID0gdXNlckJveGVzW2ldO1xuICAgICAgICAgICAgdXNlckJveGVzW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy51c2VyQ2FsbEJhY2suYmluZCh0aGlzLCB1c2VyQm94KSk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHByaXZhdGUgdXNlckNhbGxCYWNrKGVsOiBFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndXNlci1ib3ggYWN0aXZlJyk7XG5cbiAgICAgICAgbGV0IHBhc3NwaHJhc2U6IHN0cmluZyA9ICcnO1xuICAgICAgICBpZiAoY3VycmVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBsZXQgcGFzc3BocmFzZUlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3NwaHJhc2UnKSBhcyBhbnk7XG5cbiAgICAgICAgICAgIGlmIChwYXNzcGhyYXNlSW5wdXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcigncGFzc3BocmFzZUlucHV0IGVsZW1lbnQgcmVmZXJlbmNlIGlzIG51bGwnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXNzcGhyYXNlID0gcGFzc3BocmFzZUlucHV0LnZhbHVlXG4gICAgICAgICAgICBpZiAocGFzc3BocmFzZSA9PSAnJyB8fCBwYXNzcGhyYXNlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBhbGVydCgnUGxlYXNlIGlucHV0IHBhc3NwaHJhc2UnKVxuICAgICAgICAgICAgICAgIC8vIGFsZXJ0aWZ5LmVycm9yKCdQbGVhc2UgZW50ZXIgYSBwYXNzcGhyYXNlJyk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKCdwYXNzcGhyYXNlIGlzIGVtcHR5IG9yIG51bGwnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50WzBdLmNsYXNzTmFtZSA9IGN1cnJlbnRbMF0uY2xhc3NOYW1lLnJlcGxhY2UoXCIgYWN0aXZlXCIsIFwiXCIpO1xuXG4gICAgICAgIH1cbiAgICAgICAgLy8gQWRkIHRoZSBhY3RpdmUgY2xhc3MgdG8gdGhlIGN1cnJlbnQvY2xpY2tlZCBidXR0b25cbiAgICAgICAgZWxzZSBpZiAoY3VycmVudC5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgbGV0IGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFzc3BocmFzZS1pbml0aWFsJykgYXMgYW55O1xuICAgICAgICAgICAgaWYoZWxlbSA9PSBudWxsKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcigncGFzc3BocmFzZUlucHV0IGVsZW1lbnQgcmVmZXJlbmNlIGlzIG51bGwnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXNzcGhyYXNlID0gZWxlbS52YWx1ZTtcbiAgICAgICAgICAgIGlmIChwYXNzcGhyYXNlID09ICcnIHx8IHBhc3NwaHJhc2UgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vICAgICAvLyBhbGVydCgnUGxlYXNlIGlucHV0IHBhc3NwaHJhc2UnKVxuICAgICAgICAgICAgICAgIC8vICAgICAvLyBhbGVydGlmeS5lcnJvcignUGxlYXNlIGVudGVyIGEgcGFzc3BocmFzZScpO1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcigncGFzc3BocmFzZSBpcyBlbXB0eSBvciBudWxsJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduby11c2VyLXNlbGVjdGVkJykuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hhdC1jYXJkJykuaGlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICAgICAgZWxlbS5oaWRkZW4gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndG8tdXNlci1zcGFuJykpO1xuICAgICAgICBsZXQgZWxlbSA9IGVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3RvLXVzZXItc3BhbicpWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBsZXQgdXNlck5hbWUgPSBlbGVtLmlubmVyVGV4dDtcbiAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VzZXItbmFtZS1zcGFuJykuaW5uZXJUZXh0ID0gdXNlck5hbWU7XG4gICAgICAgIHRoaXMuX2NoYXRNb2RlbC5nZXRtZXNzYWdlcyh1c2VyTmFtZSwgcGFzc3BocmFzZSwgbnVsbCk7XG4gICAgICAgIC8vIHBvcHVsYXRlTWVzc2FnZXModXNlck5hbWUsIHBhc3NwaHJhc2UpO1xuICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdzZWxlY3RlZFVzZXInLCB1c2VyTmFtZSk7XG4gICAgICAgIGVsLmNsYXNzTmFtZSArPSBcIiBhY3RpdmVcIjtcbiAgICB9XG5cbn0iLCJleHBvcnQgY2xhc3MgQWN0aXZlVXNlclZpZXdNb2RlbCB7XG4gICAgdXNlck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBvbmxpbmU6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgbGFzdEFjdGl2ZTogc3RyaW5nfCB1bmRlZmluZWQ7XG59IiwiZXhwb3J0IGNsYXNzIENoYXRNZXNzYWdlVmlld01vZGVsIHtcbiAgICBwdWJsaWMgdG9Vc2VyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgcHVibGljIGZyb21Vc2VyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgcHVibGljIG1lc3NhZ2UhOiBzdHJpbmc7XG4gICAgcHVibGljIG1lc3NhZ2VUaW1lITogRGF0ZTtcblxuICAgIFxufSJdfQ== +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMTAuMC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJ0cy9zcmMvY29udHJvbGxlci9DaGF0Q29udHJvbGxlci50cyIsInRzL3NyYy9jb250cm9sbGVyL1VzZXJDb250cm9sbGVyLnRzIiwidHMvc3JjL21haW4udHMiLCJ0cy9zcmMvbW9kZWwvQ2hhdE1vZGVsLnRzIiwidHMvc3JjL21vZGVsL0NoYXRNb2RlbEhlbHBlci50cyIsInRzL3NyYy9tb2RlbC9GZXRjaEVycm9ySGFuZGxlci50cyIsInRzL3NyYy9tb2RlbC9Vc2VyTW9kZWwudHMiLCJ0cy9zcmMvc2VydmljZS9NYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlLnRzIiwidHMvc3JjL3NlcnZpY2UvU0pDTEVuY3J5cHRpb25TZXJ2aWNlLnRzIiwidHMvc3JjL3NpbmdsZXRvbi9Kc29uQVBJLnRzIiwidHMvc3JjL3RlbXBsYXRlL1RlbXBsYXRlRmFjdG9yeS50cyIsInRzL3NyYy92aWV3L0NoYXRWaWV3LnRzIiwidHMvc3JjL3ZpZXcvRmV0Y2hIYW5kbGVyLnRzIiwidHMvc3JjL3ZpZXcvVXNlclZpZXcudHMiLCJ0cy9zcmMvdmlld21vZGVsL0FjdGl2ZVVzZXJWaWV3TW9kZWwudHMiLCJ0cy9zcmMvdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7QUNDQSxrQ0FBK0I7QUFDL0IsOEJBQTJCO0FBQzNCLGdDQUE2QjtBQUM3Qiw0QkFBeUI7QUFHekIsNEVBQXlFO0FBSXpFLE1BQWEsY0FBYztJQUt2QixZQUFZLEtBQWdCLEVBQUUsSUFBYztRQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUN0QixDQUFDO0lB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LENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQztJQUM5QixDQUFDO0NBRUo7QUEvRkQsNEJBK0ZDOzs7Ozs7O0FDMUdELE1BQWEsbUJBQW1CO0NBSS9CO0FBSkQsa0RBSUM7Ozs7O0FDSkQsTUFBYSxvQkFBb0I7Q0FPaEM7QUFQRCxvREFPQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsImltcG9ydCB7IENvbnRyb2xsZXIgfSBmcm9tIFwiLi9BYnN0cmFjdENvbnRyb2xsZXJcIjtcbmltcG9ydCBcIi4uL21vZGVsL0Fic3RyYWN0TW9kZWxcIlxuaW1wb3J0IFwiLi4vbW9kZWwvVXNlck1vZGVsXCJcbmltcG9ydCBcIi4uL3ZpZXcvQWJzdHJhY3RWaWV3XCJcbmltcG9ydCBcIi4uL3ZpZXcvVXNlclZpZXdcIlxuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiO1xuaW1wb3J0IHsgVmlldyB9IGZyb20gXCIuLi92aWV3L0Fic3RyYWN0Vmlld1wiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsXCI7XG5pbXBvcnQgeyBDaGF0TW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQ2hhdE1vZGVsXCI7XG5pbXBvcnQgeyBDaGF0VmlldyB9IGZyb20gXCIuLi92aWV3L0NoYXRWaWV3XCI7XG5cbmV4cG9ydCBjbGFzcyBDaGF0Q29udHJvbGxlciB7XG4gICAgcHJpdmF0ZSBfbW9kZWw6IENoYXRNb2RlbDtcbiAgICBwcml2YXRlIF92aWV3OiBDaGF0VmlldztcblxuXG4gICAgY29uc3RydWN0b3IobW9kZWw6IENoYXRNb2RlbCwgdmlldzogQ2hhdFZpZXcpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy5fdmlldyA9IHZpZXc7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBldmVudEhhbmRsZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgZXZlbnRIYW5kbGVyKHZtOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX21vZGVsLnNvbWVCdXNpbmVzc01ldGhvZCh2bSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlc3QoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNoYXRNZXNzYWdlVmlld01vZGVsczogQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXSA9IFtdO1xuICAgICAgICBsZXQgY2hhdE1lc3NhZ2VWaWV3TW9kZWxNb2NrID0gbmV3IENoYXRNZXNzYWdlVmlld01vZGVsKCk7XG4gICAgICAgIGNoYXRNZXNzYWdlVmlld01vZGVsTW9jay5mcm9tVXNlciA9IFwidXNlcjFcIjtcbiAgICAgICAgY2hhdE1lc3NhZ2VWaWV3TW9kZWxNb2NrLnRvVXNlciA9IFwidXNlcjJcIjtcbiAgICAgICAgY2hhdE1lc3NhZ2VWaWV3TW9kZWxNb2NrLm1lc3NhZ2UgPSBcIlwiO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2subWVzc2FnZVRpbWUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbHMucHVzaChjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2spO1xuICAgIH1cblxuICAgIFxufSIsImltcG9ydCB7IENvbnRyb2xsZXIgfSBmcm9tIFwiLi9BYnN0cmFjdENvbnRyb2xsZXJcIjtcbmltcG9ydCBcIi4uL21vZGVsL0Fic3RyYWN0TW9kZWxcIlxuaW1wb3J0IFwiLi4vbW9kZWwvVXNlck1vZGVsXCJcbmltcG9ydCBcIi4uL3ZpZXcvQWJzdHJhY3RWaWV3XCJcbmltcG9ydCBcIi4uL3ZpZXcvVXNlclZpZXdcIlxuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiO1xuaW1wb3J0IHsgVmlldyB9IGZyb20gXCIuLi92aWV3L0Fic3RyYWN0Vmlld1wiO1xuaW1wb3J0IHsgQWN0aXZlVXNlclZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgVXNlclZpZXcgfSBmcm9tIFwiLi4vdmlldy9Vc2VyVmlld1wiO1xuaW1wb3J0IHsgVXNlck1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL1VzZXJNb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgVXNlckNvbnRyb2xsZXIge1xuICAgIHByaXZhdGUgX21vZGVsOiBVc2VyTW9kZWw7XG4gICAgcHJpdmF0ZSBfdmlldzogVXNlclZpZXc7XG5cblxuICAgIGNvbnN0cnVjdG9yKG1vZGVsOiBVc2VyTW9kZWwsIHZpZXc6IFVzZXJWaWV3KSB7XG4gICAgICAgIHRoaXMuX21vZGVsID0gbW9kZWw7XG4gICAgICAgIHRoaXMuX3ZpZXcgPSB2aWV3O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogZXZlbnRIYW5kbGVyXG4gICAgICovXG4gICAgcHVibGljIGV2ZW50SGFuZGxlcih2bTogQWN0aXZlVXNlclZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX21vZGVsLnNvbWVCdXNpbmVzc01ldGhvZCh2bSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlc3QoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZVVzZXJzTW9jazogQWN0aXZlVXNlclZpZXdNb2RlbFtdID0gW107XG4gICAgICAgIGxldCBhY3RpdmVVc2VyVmlld01vZGVsTW9jayA9IG5ldyBBY3RpdmVVc2VyVmlld01vZGVsKCk7XG4gICAgICAgIGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrLnVzZXJOYW1lID0gXCJzb21lIHVzZXJcIjtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2subGFzdEFjdGl2ZSA9IFwiMyBocnMgYWdvXCI7XG4gICAgICAgIGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrLm9ubGluZSA9IHRydWU7XG4gICAgICAgIGFjdGl2ZVVzZXJzTW9jay5wdXNoKGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrKTtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sgPSBuZXcgQWN0aXZlVXNlclZpZXdNb2RlbCgpO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jay5sYXN0QWN0aXZlID0gXCIzIGhycyBhZ29cIjtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sub25saW5lID0gdHJ1ZTtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sudXNlck5hbWUgPSBcInNvbWUgdXNlciAyXCI7XG4gICAgICAgIGFjdGl2ZVVzZXJzTW9jay5wdXNoKGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrKTtcbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIoYWN0aXZlVXNlcnNNb2NrKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0QWN0aXZlVXNlcnMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX21vZGVsLmdldEFjdGl2ZVVzZXJzKCk7XG4gICAgfVxuXG4gICAgXG59IiwiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXIvQWJzdHJhY3RDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBVc2VyTW9kZWwgfSBmcm9tIFwiLi9tb2RlbC9Vc2VyTW9kZWxcIlxuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4vdmlldy9BYnN0cmFjdFZpZXdcIjtcbmltcG9ydCB7IFVzZXJWaWV3IH0gZnJvbSBcIi4vdmlldy9Vc2VyVmlld1wiO1xuaW1wb3J0IHsgVXNlckNvbnRyb2xsZXIgfSBmcm9tIFwiLi9jb250cm9sbGVyL1VzZXJDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBNb2RlbEZhY3RvcnkgfSBmcm9tIFwiLi9tb2RlbC9Nb2RlbEZhY3RvcnlcIjtcbmltcG9ydCB7IEFjdGl2ZVVzZXJWaWV3TW9kZWwgfSBmcm9tIFwiLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCAqIGFzIEhhbmRsZWJhcnMgZnJvbSBcImhhbmRsZWJhcnNcIjtcbmltcG9ydCB7IENoYXRNb2RlbCB9IGZyb20gXCIuL21vZGVsL0NoYXRNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdFZpZXcgfSBmcm9tIFwiLi92aWV3L0NoYXRWaWV3XCI7XG5pbXBvcnQgeyBDaGF0Q29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXIvQ2hhdENvbnRyb2xsZXJcIjtcbmltcG9ydCB7IEpzb25BUEkgfSBmcm9tIFwiLi9zaW5nbGV0b24vSnNvbkFQSVwiO1xuLy8gaW1wb3J0IGxvZyA9IHJlcXVpcmUoJ2xvZ2xldmVsJylcbmltcG9ydCAqIGFzIGxvZyBmcm9tICdsb2dsZXZlbCc7XG4vLyBpbXBvcnQgbG9nIGZyb20gJ2xvZ2xldmVsJztcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZS9FbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgU0pDTEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZS9TSkNMRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IE1lc3NhZ2VDaXBoZXJEVE8gfSBmcm9tIFwiLi9kdG8vTWVzc2FnZUNpcGhlckRUT1wiO1xuLy8gdmFyIG1hcmtkb3duaXQgPSByZXF1aXJlKCdtYXJrZG93bi1pdCcpO1xuLy8gdmFyIG1kID0gbmV3IG1hcmtkb3duaXQoKTtcblxuXG5jb25zdCB1c2VyQm94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvbnRhY3RzLWJveCcpO1xuXG5sb2cuc2V0TGV2ZWwoXCJUUkFDRVwiKVxuXG5jb25zdCBjaGF0TW9kZWwgPSBuZXcgQ2hhdE1vZGVsKCk7XG5cbmNvbnN0IHVzZXJNb2RlbCA9IG5ldyBVc2VyTW9kZWwoKTtcbi8vIGNvbnN0IHVzZXJNb2RlbCA9IE1vZGVsRmFjdG9yeS5jcmVhdGVNb2RlbChcIlVTRVJcIik7XG4vLyBAdHMtaWdub3JlOiBBcmd1bWVudCBvZiB0eXBlICdIVE1MRWxlbWVudCB8IG51bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHBhcmFtZXRlciBvZiB0eXBlICdIVE1MRWxlbWVudCcuIFR5cGUgJ251bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHR5cGUgJ0hUTUxFbGVtZW50Jy5cbmNvbnN0IHVzZXJWaWV3ID0gbmV3IFVzZXJWaWV3KHVzZXJNb2RlbCwgY2hhdE1vZGVsLCB1c2VyQm94KTtcblxuLy8gY29uc29sZS5sb2codXNlckJveCk7XG5cbnVzZXJNb2RlbC5hdHRhY2godXNlclZpZXcpO1xuLy8gdXNlclZpZXcubW9kZWxcblxuXG5jb25zdCB1c2VyQ29udHJvbGxlciA9IG5ldyBVc2VyQ29udHJvbGxlcih1c2VyTW9kZWwsIHVzZXJWaWV3KTtcbi8vIHVzZXJDb250cm9sbGVyLnRlc3QoKTtcblxuXG5cbi8vIHVzZXJNb2RlbC5zb21lQnVzaW5lc3NNZXRob2QoYWN0aXZlVXNlcnNNb2NrKTtcbmxvZy5pbmZvKFwiaGVsbG9cIik7XG5cbmNvbnN0IGNoYXRBcmVhID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoYXQtYXJlYS1uZXcnKTtcbi8vIEB0cy1pZ25vcmU6IEFyZ3VtZW50IG9mIHR5cGUgJ0hUTUxFbGVtZW50IHwgbnVsbCcgaXMgbm90IGFzc2lnbmFibGUgdG8gcGFyYW1ldGVyIG9mIHR5cGUgJ0hUTUxFbGVtZW50Jy4gVHlwZSAnbnVsbCcgaXMgbm90IGFzc2lnbmFibGUgdG8gdHlwZSAnSFRNTEVsZW1lbnQnLlxuY29uc3QgY2hhdFZpZXcgPSBuZXcgQ2hhdFZpZXcoY2hhdE1vZGVsLCBjaGF0QXJlYSk7XG5jaGF0TW9kZWwuYXR0YWNoKGNoYXRWaWV3KTtcbmNvbnN0IGNoYXRDb250cm9sbGVyID0gbmV3IENoYXRDb250cm9sbGVyKGNoYXRNb2RlbCwgY2hhdFZpZXcpO1xuXG5cbmZ1bmN0aW9uIHNvbWVGdW5jKHZtOiBBY3RpdmVVc2VyVmlld01vZGVsKTogdm9pZCB7XG4gICAgLy8gbG9nLmluZm8odm0pO1xuICAgIC8vIGxvZ2dlci5pbmZvKHZtKVxufVxuXG51c2VyQ29udHJvbGxlci5nZXRBY3RpdmVVc2VycygpO1xuXG5sb2cuaW5mbyhcInRlc3RcIik7XG4vLyBzb21lRnVuYyhhY3RpdmVVc2VyVmlld01vZGVsTW9jayk7XG5cbi8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG52YXIgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtc2dfY29udGFpbmVyX3RlbXBsYXRlXCIpLmlubmVySFRNTDtcblxudmFyIG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG5cbkpzb25BUEkuQUNUSVZFX1VTRVJTX0dFVCArICdhZWYnO1xuXG5jb25zdCBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UgPSBuZXcgU0pDTEVuY3J5cHRpb25TZXJ2aWNlKCk7XG5sZXQgbWVzc2FnZUNpcGhlckRUTzogTWVzc2FnZUNpcGhlckRUTyA9IGVuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQoXCJwYXNzd29yZFwiLFwiZGF0YVwiKTtcbmNvbnNvbGUubG9nKGVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQoXCJwYXNzd29yZFwiLCBtZXNzYWdlQ2lwaGVyRFRPKSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2F2YXRhcicsIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAnPGRpdiBjbGFzcz1cImltZ19jb250X21zZ1wiPiA8aW1nIHNyYz1cImh0dHBzOi8vc3RhdGljLnR1cmJvc3F1aWQuY29tL1ByZXZpZXcvMDAxMjkyLzQ4MS9XVi9fRC5qcGdcIiBjbGFzcz1cInJvdW5kZWQtY2lyY2xlIHVzZXJfaW1nX21zZ1wiPiA8L2Rpdj4nO1xufSk7IiwiaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmFibGVcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vQWJzdHJhY3RNb2RlbFwiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZlclwiO1xuaW1wb3J0IHsgZmV0Y2hFcnJvckhhbmRsZXIgfSBmcm9tIFwiLi9GZXRjaEVycm9ySGFuZGxlclwiO1xuaW1wb3J0IHsgQWN0aXZlVXNlclZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsXCI7XG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5pbXBvcnQgbG9nID0gcmVxdWlyZSgnbG9nbGV2ZWwnKTtcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2UvRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IFNKQ0xFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL1NKQ0xFbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VEVE8gfSBmcm9tIFwiLi4vZHRvL0NoYXRNZXNzYWdlRFRPXCI7XG5pbXBvcnQgeyBDaGF0TW9kZWxIZWxwZXIgfSBmcm9tIFwiLi9DaGF0TW9kZWxIZWxwZXJcIjtcblxuZXhwb3J0IGNsYXNzIENoYXRNb2RlbCBpbXBsZW1lbnRzIFN1YmplY3Qge1xuICAgIC8qKlxuICAqIEB0eXBlIHtPYnNlcnZlcltdfSBMaXN0IG9mIHN1YnNjcmliZXJzLiBJbiByZWFsIGxpZmUsIHRoZSBsaXN0IG9mXG4gICogc3Vic2NyaWJlcnMgY2FuIGJlIHN0b3JlZCBtb3JlIGNvbXByZWhlbnNpdmVseSAoY2F0ZWdvcml6ZWQgYnkgZXZlbnRcbiAgKiB0eXBlLCBldGMuKS5cbiAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcbiAgICBwcml2YXRlIHN0YXRlOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdIHwgbnVsbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlc01hcDogTWFwPHN0cmluZywgQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXT47XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMuX21lc3NhZ2VzTWFwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3Vic2NyaXB0aW9uIG1hbmFnZW1lbnQgbWV0aG9kcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgYXR0YWNoKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgICAgICBjb25zb2xlLmxvZygnU3ViamVjdDogQXR0YWNoZWQgYW4gb2JzZXJ2ZXIuJyk7XG4gICAgICAgIHRoaXMuX29ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGV0YWNoKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBvYnNlcnZlckluZGV4ID0gdGhpcy5fb2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLl9vYnNlcnZlcnMuc3BsaWNlKG9ic2VydmVySW5kZXgsIDEpO1xuICAgICAgICBjb25zb2xlLmxvZygnU3ViamVjdDogRGV0YWNoZWQgYW4gb2JzZXJ2ZXIuJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRVc2VyTWVzc2FnZXModXNlcm5hbWU6IHN0cmluZywgbWVzc2FnZXM6IENoYXRNZXNzYWdlVmlld01vZGVsW10pIHtcbiAgICAgICAgdGhpcy5fbWVzc2FnZXNNYXAuc2V0KHVzZXJuYW1lLCBtZXNzYWdlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlciBhbiB1cGRhdGUgaW4gZWFjaCBzdWJzY3JpYmVyLlxuICAgICAqL1xuICAgIHB1YmxpYyBub3RpZnkodXNlck5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zb2xlLmxvZygnU3ViamVjdDogTm90aWZ5aW5nIG9ic2VydmVycy4uLicpO1xuICAgICAgICBmb3IgKGNvbnN0IG9ic2VydmVyIG9mIHRoaXMuX29ic2VydmVycykge1xuICAgICAgICAgICAgb2JzZXJ2ZXIudXBkYXRlKHRoaXMuX21lc3NhZ2VzTWFwLmdldCh1c2VyTmFtZSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNvbWVCdXNpbmVzc01ldGhvZChjaGF0TWVzc2FnZUxpc3Q6IENoYXRNZXNzYWdlVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IGNoYXRNZXNzYWdlTGlzdDtcbiAgICAgICAgdGhpcy5oZWxwZXJNZXRob2QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYFN1YmplY3Q6IE15IHN0YXRlIGhhcyBqdXN0IGNoYW5nZWRgKTtcbiAgICAgICAgY29uc29sZS5sb2coY2hhdE1lc3NhZ2VMaXN0KTtcbiAgICAgICAgdGhpcy5ub3RpZnkoXCJzb21lIHVzZXJcIik7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldG1lc3NhZ2VzKGNvbnRhY3ROYW1lOiBzdHJpbmcsIHBhc3NwaHJhc2U6IHN0cmluZywgbGFzdE1lc3NhZ2VUaW1lOiBzdHJpbmcgfCBudWxsKTogUHJvbWlzZTxDaGF0TWVzc2FnZVZpZXdNb2RlbFtdPiB7XG4gICAgICAgIGNvbnN0IGNWTXMgPSBhd2FpdCBDaGF0TW9kZWxIZWxwZXIuZ2V0TWVzc2FnZXMoY29udGFjdE5hbWUsIHBhc3NwaHJhc2UsIGxhc3RNZXNzYWdlVGltZSwgdGhpcyk7XG4gICAgICAgIGlmIChjVk1zICE9IG51bGwpIHtcbiAgICAgICAgICAgIGxvZy5pbmZvKCdTdWJqZWN0OiBNeSBzdGF0ZSBoYXMganVzdCBjaGFuZ2VkJylcbiAgICAgICAgICAgIGxvZy5kZWJ1ZyhjVk1zKTtcbiAgICAgICAgICAgIC8vIHRoaXMuX21lc3NhZ2VzTWFwLnNldCh1c2VyTmFtZSwgY1ZNcyk7XG4gICAgICAgICAgICB0aGlzLnNldFVzZXJNZXNzYWdlcyhjb250YWN0TmFtZSwgY1ZNcyk7XG4gICAgICAgICAgICBKc29uQVBJLmNvbnRhY3ROYW1lID0gY29udGFjdE5hbWU7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeShjb250YWN0TmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoJ01lc3NhZ2VzIHdlcmUgbnVsbCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNWTXM7XG4gICAgfVxuXG5cblxuICAgIHByaXZhdGUgaGVscGVyTWV0aG9kKCkgeyB9XG5cbiAgICBwdWJsaWMgcG9wdWxhdGVNZXNzYWdlcygpOiB2b2lkIHtcblxuICAgIH1cblxuXG5cbn0iLCJpbXBvcnQgeyBDaGF0TWVzc2FnZURUTyB9IGZyb20gXCIuLi9kdG8vQ2hhdE1lc3NhZ2VEVE9cIjtcblxuaW1wb3J0ICogYXMgbG9nIGZyb20gXCJsb2dsZXZlbFwiO1xuXG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcblxuaW1wb3J0IHsgSnNvbkFQSSB9IGZyb20gXCIuLi9zaW5nbGV0b24vSnNvbkFQSVwiO1xuXG5pbXBvcnQgeyBmZXRjaEVycm9ySGFuZGxlciB9IGZyb20gXCIuL0ZldGNoRXJyb3JIYW5kbGVyXCI7XG5cbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2UvRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IFNKQ0xFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL1NKQ0xFbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgQ2hhdE1vZGVsIH0gZnJvbSBcIi4vQ2hhdE1vZGVsXCJcbmV4cG9ydCBjbGFzcyBDaGF0TW9kZWxIZWxwZXIge1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9lbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UgPSBuZXcgU0pDTEVuY3J5cHRpb25TZXJ2aWNlKCk7XG5cbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGdldE1lc3NhZ2VzKHVzZXJOYW1lOiBzdHJpbmcsIHBhc3NwaHJhc2U6IHN0cmluZywgbGFzdE1lc3NhZ2VUaW1lOiBzdHJpbmcgfCBudWxsLCBjaGF0TW9kZWw6IENoYXRNb2RlbCk6IFByb21pc2U8Q2hhdE1lc3NhZ2VWaWV3TW9kZWxbXT4ge1xuICAgICAgICBzd2l0Y2ggKGxhc3RNZXNzYWdlVGltZSkge1xuICAgICAgICAgICAgY2FzZSBudWxsOiB7XG4gICAgICAgICAgICAgICAgLy8gdGhpcy5nZXRBbGxNZXNzYWdlc0FqYXgodXNlck5hbWUpXG4gICAgICAgICAgICAgICAgLy8gICAgIC50aGVuKChkYXRhOiBDaGF0TWVzc2FnZURUT1tdKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICBsb2cuZGVidWcoYFN1YmplY3Q6IHJlY2VpdmVkIGFsbCBtZXNzYWdlc2ApO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gbGV0IHVzZXJOYW1lcyA9IGRhdGEubWFwKENoYXRNZXNzYWdlVmlld01vZGVsID0+IENoYXRNZXNzYWdlVmlld01vZGVsLmZyb21Vc2VyKVxuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gbGV0IHN1bXQgPSBkYXRhLm1hcChjaGF0TWVzc2FnZVZpZXdNb2RlbCA9PiB7IHJldHVybiB0aGlzLmVuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQocGFzc3BocmFzZSwgY2hhdE1lc3NhZ2VWaWV3TW9kZWwubWVzc2FnZUNpcGhlcikgfSk7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICByZXR1cm4gZGF0YS5tYXAodm0gPT4gdGhpcy50b0NoYXRNZXNzYWdlVk0odm0sIHBhc3NwaHJhc2UpKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIC8vIGNoYXRNb2RlbC5zZXRVc2VyTWVzc2FnZXModXNlck5hbWUsIGNoYXRNZXNzYWdlVk1zKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIC8vIGNoYXRNb2RlbC5ub3RpZnkoKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgfSlcbiAgICAgICAgICAgICAgICAvLyBicmVhaztcblxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGE6IENoYXRNZXNzYWdlRFRPW10gPSBhd2FpdCB0aGlzLmdldEFsbE1lc3NhZ2VzQWpheCh1c2VyTmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEubWFwKHZtID0+IHRoaXMudG9DaGF0TWVzc2FnZVZNKHZtLCBwYXNzcGhyYXNlKSk7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmdldE5ld01lc3NhZ2VzQWpheCh1c2VyTmFtZSwgbGFzdE1lc3NhZ2VUaW1lKVxuICAgICAgICAgICAgICAgIC8vICAgICAudGhlbigoZGF0YTogQ2hhdE1lc3NhZ2VEVE9bXSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgbG9nLmRlYnVnKGBTdWJqZWN0OiByZWNlaXZlZCBuZXcgbWVzc2FnZXNgKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgICAgIHJldHVybiBkYXRhLm1hcCh2bSA9PiB0aGlzLnRvQ2hhdE1lc3NhZ2VWTSh2bSwgcGFzc3BocmFzZSkpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gY2hhdE1vZGVsLnNldFVzZXJNZXNzYWdlcyh1c2VyTmFtZSwgY2hhdE1lc3NhZ2VWTXMpO1xuICAgICAgICAgICAgICAgIC8vICAgICAgICAgLy8gdGhpcy5zdGF0ZSA9IGRhdGE7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgICAvLyBjaGF0TW9kZWwubm90aWZ5KCk7XG4gICAgICAgICAgICAgICAgLy8gICAgIH0pXG4gICAgICAgICAgICAgICAgLy8gYnJlYWs7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YTogQ2hhdE1lc3NhZ2VEVE9bXSA9IGF3YWl0IHRoaXMuZ2V0TmV3TWVzc2FnZXNBamF4KHVzZXJOYW1lLCBsYXN0TWVzc2FnZVRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLm1hcCh2bSA9PiB0aGlzLnRvQ2hhdE1lc3NhZ2VWTSh2bSwgcGFzc3BocmFzZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgdG9DaGF0TWVzc2FnZVZNKGNoYXRNZXNzYWdlRFRPOiBDaGF0TWVzc2FnZURUTywgcGFzc3BocmFzZTogc3RyaW5nKTogQ2hhdE1lc3NhZ2VWaWV3TW9kZWwge1xuICAgICAgICBjb25zdCB2bSA9IG5ldyBDaGF0TWVzc2FnZVZpZXdNb2RlbCgpO1xuICAgICAgICB2bS5mcm9tVXNlciA9IGNoYXRNZXNzYWdlRFRPLmZyb21Vc2VyO1xuICAgICAgICB2bS50b1VzZXIgPSBjaGF0TWVzc2FnZURUTy50b1VzZXI7XG4gICAgICAgIC8vIHZtLm1lc3NhZ2VUaW1lID0gY2hhdE1lc3NhZ2VEVE8ubWVzc2FnZVRpbWU7XG4gICAgICAgIGNoYXRNZXNzYWdlRFRPLm1lc3NhZ2VUaW1lID09IG51bGwgPyBsb2cuZXJyb3IoXCJNZXNzYWdlIHRpbWUgc29tZWhvdyBudWxsXCIpIDogdm0ubWVzc2FnZVRpbWUgPSBjaGF0TWVzc2FnZURUTy5tZXNzYWdlVGltZTtcbiAgICAgICAgdm0ubWVzc2FnZSA9IHRoaXMuX2VuY3J5cHRpb25TZXJ2aWNlLmRlY3J5cHQocGFzc3BocmFzZSwgY2hhdE1lc3NhZ2VEVE8ubWVzc2FnZUNpcGhlcikgYXMgc3RyaW5nO1xuICAgICAgICByZXR1cm4gdm07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZ2V0QWxsTWVzc2FnZXNBamF4KHRvVXNlcjogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIGlmIChKc29uQVBJLmF1dGhUb2tlbiA9PSBudWxsKSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoXCJhdXRoVG9rZW4gbnVsbFwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIEpzb25BUEkuYXV0aFRva2VuKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtKc29uQVBJLkNIQVRfTUVTU0FHRVNfR0VUfS8ke3RvVXNlcn1gLCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgIGlmIChmZXRjaEVycm9ySGFuZGxlcihyZXNwb25zZS5jbG9uZSgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YTogUHJvbWlzZTxhbnk+ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhc3luYyBnZXROZXdNZXNzYWdlc0FqYXgodG9Vc2VyOiBzdHJpbmcsIGxhc3RNZXNzYWdlVGltZVN0YW1wOiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgaWYgKEpzb25BUEkuYXV0aFRva2VuID09IG51bGwpIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcihcImF1dGhUb2tlbiBudWxsXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9O1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnWC1BVVRILVRPS0VOJywgSnNvbkFQSS5hdXRoVG9rZW4pO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke0pzb25BUEkuQ0hBVF9NRVNTQUdFU19HRVR9LyR7dG9Vc2VyfS8ke2xhc3RNZXNzYWdlVGltZVN0YW1wfWAsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZS5jbG9uZSgpKTtcbiAgICAgICAgaWYgKGZldGNoRXJyb3JIYW5kbGVyKHJlc3BvbnNlLmNsb25lKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhOiBQcm9taXNlPGFueT4gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbn0iLCJpbXBvcnQgbG9nID0gcmVxdWlyZShcImxvZ2xldmVsXCIpO1xuaW1wb3J0IHsgc3ByaW50ZiB9IGZyb20gXCJzcHJpbnRmLWpzXCI7XG4vLyBpbXBvcnQgc3ByaW50ZiA9IHJlcXVpcmUoJ3NwcmludGYtanMnKS5zcHJpbnRmO1xuXG5leHBvcnQgZnVuY3Rpb24gZmV0Y2hFcnJvckhhbmRsZXIocmVzcG9uc2U6IFJlc3BvbnNlKSB7XG4gICAgLy8gYWxlcnRpZnkuc3VjY2VzcygnQ3VycmVudCBwb3NpdGlvbiA6ICcgKyBhbGVydGlmeS5nZXQoJ25vdGlmaWVyJywgJ3Bvc2l0aW9uJykpO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgbm90IG9rIGFuZCB0aGVyZSBpcyBubyBqc29uIGJvZHlcbiAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICAgICAgICAgIC8vIHdpbmRvdy5hbGVydChzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignU29tZSBlcnJvciBvY2N1cmVkLiBIdHRwIGNvZGUgaXMgJXMnLCByZXNwb25zZS5zdGF0dXMpKTtcbiAgICAgICAgICAgIGxvZy5lcnJvcihzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgbG9nLmVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSkudGhlbihqc29uID0+IHtcbiAgICAgICAgICAgIC8vIHRoZSBzdGF0dXMgd2FzIG5vdCBvayBidXQgdGhlcmUgaXMgYSBqc29uIGJvZHlcbiAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihqc29uLmVycm9yLm1lc3NhZ2UpOyAvLyBleGFtcGxlIGVycm9yIG1lc3NhZ2UgcmV0dXJuZWQgYnkgYSBSRVNUIEFQSVxuICAgICAgICAgICAgLy8gd2luZG93LmFsZXJ0KHNwcmludGYoJ0Vycm9yOiAlcyAoSHR0cCBjb2RlICVzKScsIGpzb24sIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignU29tZSBlcnJvciBvY2N1cmVkLiBIdHRwIGNvZGUgaXMgJXMnLCByZXNwb25zZS5zdGF0dXMpKTtcbiAgICAgICAgICAgIGxvZy5lcnJvcihzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgbG9nLmVycm9yKGpzb24pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmVyXCI7XG5pbXBvcnQgeyBmZXRjaEVycm9ySGFuZGxlciB9IGZyb20gXCIuL0ZldGNoRXJyb3JIYW5kbGVyXCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCAqIGFzIGxvZyBmcm9tIFwibG9nbGV2ZWxcIjtcblxuZXhwb3J0IGNsYXNzIFVzZXJNb2RlbCBpbXBsZW1lbnRzIFN1YmplY3Qge1xuICAgIC8qKlxuICAqIEB0eXBlIHtPYnNlcnZlcltdfSBMaXN0IG9mIHN1YnNjcmliZXJzLiBJbiByZWFsIGxpZmUsIHRoZSBsaXN0IG9mXG4gICogc3Vic2NyaWJlcnMgY2FuIGJlIHN0b3JlZCBtb3JlIGNvbXByZWhlbnNpdmVseSAoY2F0ZWdvcml6ZWQgYnkgZXZlbnRcbiAgKiB0eXBlLCBldGMuKS5cbiAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IG9ic2VydmVyczogT2JzZXJ2ZXJbXSA9IFtdO1xuICAgIHByaXZhdGUgc3RhdGU6IEFjdGl2ZVVzZXJWaWV3TW9kZWxbXSB8IHVuZGVmaW5lZDtcbiAgICAvLyBAdHMtaWdub3JlOiBDYW5ub3QgZmluZCBuYW1lICdob3N0QWRkcmVzcycuXG5cbiAgICBjb25zdHJ1Y3RvcigpIHsgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdWJzY3JpcHRpb24gbWFuYWdlbWVudCBtZXRob2RzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2gob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBBdHRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgcHVibGljIGRldGFjaChvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXJJbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2Uob2JzZXJ2ZXJJbmRleCwgMSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBEZXRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIHVwZGF0ZSBpbiBlYWNoIHN1YnNjcmliZXIuXG4gICAgICovXG4gICAgcHVibGljIG5vdGlmeSgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1N1YmplY3Q6IE5vdGlmeWluZyBvYnNlcnZlcnMuLi4nKTtcbiAgICAgICAgZm9yIChjb25zdCBvYnNlcnZlciBvZiB0aGlzLm9ic2VydmVycykge1xuICAgICAgICAgICAgb2JzZXJ2ZXIudXBkYXRlKHRoaXMuc3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNvbWVCdXNpbmVzc01ldGhvZChhY3RpdmV1c2VyTGlzdDogQWN0aXZlVXNlclZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBhY3RpdmV1c2VyTGlzdDtcbiAgICAgICAgdGhpcy5oZWxwZXJNZXRob2QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYFN1YmplY3Q6IE15IHN0YXRlIGhhcyBqdXN0IGNoYW5nZWRgKTtcbiAgICAgICAgY29uc29sZS5sb2coYWN0aXZldXNlckxpc3QpO1xuICAgICAgICB0aGlzLm5vdGlmeSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldEFjdGl2ZVVzZXJzXG4gICAgICovXG4gICAgcHVibGljIGdldEFjdGl2ZVVzZXJzKCk6IHZvaWQge1xuICAgICAgICBpZihKc29uQVBJLmF1dGhUb2tlbiE9IG51bGwpe1xuICAgICAgICB0aGlzLmdldEFjdGl2ZVVzZXJzQWpheChKc29uQVBJLmF1dGhUb2tlbiwgSnNvbkFQSS5BQ1RJVkVfVVNFUlNfR0VUKVxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gLy8gYWN0aXZlVXNlcnMgPSBkYXRhO1xuICAgICAgICAgICAgICAgIC8vIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2FjdGl2ZVVzZXJzJywgSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ2FjdGl2ZVVzZXJzJykpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWJqZWN0OiByZWNlaXZlZCBhamF4IGFjdGl2ZSB1c2Vyc2ApO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBkYXRhO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZ5KCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbG9nLmVycm9yKCdBdXRoIHRva2VuIGlzIG51bGwnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldEFjdGl2ZVVzZXJzQWpheChhdXRoVG9rZW4yOiBzdHJpbmcsIFVSTDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgbGV0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICAvLyBoZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsIGJhc2ljQXV0aFRva2VuKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIGF1dGhUb2tlbjIpO1xuICAgICAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChKc29uQVBJLkFDVElWRV9VU0VSU19HRVQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZS5jbG9uZSgpKTtcbiAgICAgICAgaWYgKGZldGNoRXJyb3JIYW5kbGVyKHJlc3BvbnNlLmNsb25lKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgLy8gcmV0dXJuIGRhdGE7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoZGF0YSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIHJlc29sdmUoZGF0YSlcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICByZWplY3QoJ1Jlc3BvbnNlIGRhdGEgbnVsbCcpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoZWxwZXJNZXRob2QoKSB7IH1cblxufSIsImltcG9ydCBtYXJrZG93bml0ID0gcmVxdWlyZSgnbWFya2Rvd24taXQnKTtcbmltcG9ydCB7IE1hcmtEb3duU2VydmljZSB9IGZyb20gJy4vTWFya0Rvd25TZXJ2aWNlJztcbmV4cG9ydCBjbGFzcyBNYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlIGltcGxlbWVudHMgTWFya0Rvd25TZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tZCA9IG5ldyBtYXJrZG93bml0KCk7XG5cbiAgICByZW5kZXIoaW5wdXRTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZC5yZW5kZXIoaW5wdXRTdHJpbmcpO1xuICAgIH1cbn0iLCJpbXBvcnQgeyBFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gXCIuL0VuY3J5cHRpb25TZXJ2aWNlXCI7XG5pbXBvcnQgKiBhcyBzamNsIGZyb20gXCJzamNsXCI7XG5pbXBvcnQgeyBNZXNzYWdlQ2lwaGVyRFRPIH0gZnJvbSBcIi4uL2R0by9NZXNzYWdlQ2lwaGVyRFRPXCI7XG5cbmV4cG9ydCBjbGFzcyBTSkNMRW5jcnlwdGlvblNlcnZpY2UgaW1wbGVtZW50cyBFbmNyeXB0aW9uU2VydmljZSB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXJhbXMgPSB7IG1vZGU6IFwiZ2NtXCIsIHRzOiAxMjgsIGFkYXRhOiBcIlwiLCBpdGVyOiAxMDAwMH1cbiAgICBwdWJsaWMgZW5jcnlwdChwYXNzcGhyYXNlOiBzdHJpbmcsIHBsYWluVGV4dDogc3RyaW5nKTogTWVzc2FnZUNpcGhlckRUTyB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2Uoc2pjbC5lbmNyeXB0KHBhc3NwaHJhc2UsIHBsYWluVGV4dCwgdGhpcy5wYXJhbXMpIGFzIHN0cmluZykgYXMgTWVzc2FnZUNpcGhlckRUTztcbiAgICB9IFxuICAgIFxuICAgIHB1YmxpYyBkZWNyeXB0KHBhc3NwaHJhc2U6IHN0cmluZywgY2lwaGVyOiBNZXNzYWdlQ2lwaGVyRFRPKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXNzcGhyYXNlLCBKU09OLnN0cmluZ2lmeShjaXBoZXIpLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG4gICAgfVxufSIsImV4cG9ydCBuYW1lc3BhY2UgSnNvbkFQSSB7XG4gICAgLy8gQHRzLWlnbm9yZTogQ2Fubm90IGZpbmQgbmFtZSAnaG9zdEFkZHJlc3MnLlxuICAgIGV4cG9ydCBsZXQgcHJpbmNpcGxlTmFtZTogc3RyaW5nIHwgbnVsbCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd1c2VybmFtZScpO1xuICAgIGV4cG9ydCBsZXQgY29udGFjdE5hbWU6IHN0cmluZyB8IG51bGw7XG4gICAgZXhwb3J0IGxldCBhdXRoVG9rZW46IHN0cmluZyB8IG51bGwgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYXV0aFRva2VuJyk7XG4gICAgZXhwb3J0IGNvbnN0IEFDVElWRV9VU0VSU19HRVQgPSBgL2FwaS9jaGF0L2dldC9hY3RpdmUtdXNlcnNgO1xuICAgIGV4cG9ydCBjb25zdCBDSEFUX01FU1NBR0VTX0dFVCA9IGAvYXBpL2NoYXQvZ2V0L21lc3NhZ2VzYDtcbiAgICBleHBvcnQgY29uc3QgTUVTU0FHRV9QT1NUID0gJy9hcGkvY2hhdC9wb3N0L21lc3NhZ2UnO1xuICAgIFxufSIsImV4cG9ydCBjbGFzcyBUZW1wbGF0ZUZhY3Rvcnkge1xuICAgIC8vIHN0YXRpYyBnZXRUZW1wbGF0ZSh0ZW1wbGF0ZU5hbWU6IHN0cmluZyk6IEhhbmRsZWJhcnMuVGVtcGxhdGVEZWxlZ2F0ZTxhbnk+IHtcblxuICAgIC8vICAgICBzd2l0Y2ggKHRlbXBsYXRlTmFtZSkge1xuICAgIC8vICAgICAgICAgY2FzZSBcInVzZXItY29udGFjdC1vbmxpbmUtdGVtcGxhdGVcIjoge1xuICAgIC8vICAgICAgICAgICAgIC8vIGxldCBzb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInVzZXItY29udGFjdC1vbmxpbmUtdGVtcGxhdGVcIikuaW5uZXJIVE1MO1xuICAgIC8vICAgICAgICAgICAgIC8vIGxldCBtc2dDb250YWluZXJUZW1wbGF0ZSA9IEhhbmRsZWJhcnMuY29tcGlsZShzb3VyY2UpO1xuICAgIC8vICAgICAgICAgICAgIC8vIHJldHVybiBtc2dDb250YWluZXJUZW1wbGF0ZTtcbiAgICAvLyAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVUZW1wbGF0ZSh0ZW1wbGF0ZU5hbWUpO1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICAgICAgY2FzZSBcIm1zZ19jb250YWluZXJfc2VuZF90ZW1wbGF0ZVwiOiB7XG4gICAgLy8gICAgICAgICAgICAgLy8gbGV0IHNvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibXNnX2NvbnRhaW5lcl9zZW5kX3RlbXBsYXRlXCIpLmlubmVySFRNTDtcbiAgICAvLyAgICAgICAgICAgICAvLyBsZXQgbXNnQ29udGFpbmVyVGVtcGxhdGUgPSBIYW5kbGViYXJzLmNvbXBpbGUoc291cmNlKTtcbiAgICAvLyAgICAgICAgICAgICAvLyByZXR1cm4gbXNnQ29udGFpbmVyVGVtcGxhdGU7XG4gICAgLy8gICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGVtcGxhdGUodGVtcGxhdGVOYW1lKTtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgICAgIGNhc2UgXCJtc2dfY29udGFpbmVyX3RlbXBsYXRlXCI6IHtcbiAgICAvLyAgICAgICAgICAgICAvLyBsZXQgc291cmNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtc2dfY29udGFpbmVyX3NlbmRfdGVtcGxhdGVcIikuaW5uZXJIVE1MO1xuICAgIC8vICAgICAgICAgICAgIC8vIGxldCBtc2dDb250YWluZXJUZW1wbGF0ZSA9IEhhbmRsZWJhcnMuY29tcGlsZShzb3VyY2UpO1xuICAgIC8vICAgICAgICAgICAgIC8vIHJldHVybiBtc2dDb250YWluZXJUZW1wbGF0ZTtcbiAgICAvLyAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVUZW1wbGF0ZSh0ZW1wbGF0ZU5hbWUpO1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICAgICAgZGVmYXVsdDpcbiAgICAvLyAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdGVtcGxhdGUgbmFtZScpO1xuICAgIC8vICAgICB9XG4gICAgLy8gfVxuXG4gICAgc3RhdGljIGdldFRlbXBsYXRlKHRlbXBsYXRlTmFtZTogc3RyaW5nKTogSGFuZGxlYmFycy5UZW1wbGF0ZURlbGVnYXRlPGFueT4ge1xuICAgICAgICAvL0B0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgIGxldCBzb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0ZW1wbGF0ZU5hbWUpLmlubmVySFRNTDtcbiAgICAgICAgbGV0IG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG4gICAgICAgIHJldHVybiBtc2dDb250YWluZXJUZW1wbGF0ZTtcbiAgICB9XG59IiwiaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZlclwiO1xuaW1wb3J0IHsgVGVtcGxhdGVGYWN0b3J5IH0gZnJvbSBcIi4uL3RlbXBsYXRlL1RlbXBsYXRlRmFjdG9yeVwiO1xuaW1wb3J0IHsgQ2hhdE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL0NoYXRNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0NoYXRNZXNzYWdlVmlld01vZGVsXCI7XG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnbG9nbGV2ZWwnO1xuaW1wb3J0ICogYXMgRE9NUHVyaWZ5IGZyb20gJ2RvbXB1cmlmeSc7XG5pbXBvcnQgeyBNYXJrRG93blNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZS9NYXJrRG93blNlcnZpY2VcIjtcbmltcG9ydCB7IE1hcmtEb3duSXRNYXJrRG93blNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZS9NYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlXCI7XG5pbXBvcnQgeyBKc29uQVBJIH0gZnJvbSBcIi4uL3NpbmdsZXRvbi9Kc29uQVBJXCI7XG5pbXBvcnQgeyBNZXNzYWdlQ2lwaGVyRFRPIH0gZnJvbSBcIi4uL2R0by9NZXNzYWdlQ2lwaGVyRFRPXCI7XG5pbXBvcnQgeyBTSkNMRW5jcnlwdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZS9TSkNMRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2UvRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IENoYXRNZXNzYWdlRFRPIH0gZnJvbSBcIi4uL2R0by9DaGF0TWVzc2FnZURUT1wiO1xuaW1wb3J0IHsgZmV0Y2hIYW5kbGVyIH0gZnJvbSBcIi4vRmV0Y2hIYW5kbGVyXCI7XG4vLyB2YXIgbWQgPSBuZXcgbWFya2Rvd25pdCgpO1xuXG5leHBvcnQgY2xhc3MgQ2hhdFZpZXcgaW1wbGVtZW50cyBPYnNlcnZlciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfY2hhdE1vZGVsOiBDaGF0TW9kZWw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZUNvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XG4gICAgLy8gcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZVNlbmRCdXR0b246IEhUTUxFbGVtZW50O1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2VTZW5kVGVtcGxhdGUgPSBUZW1wbGF0ZUZhY3RvcnkuZ2V0VGVtcGxhdGUoJ21zZ19jb250YWluZXJfc2VuZF90ZW1wbGF0ZScpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21lc3NhZ2VSZWNlaXZlVGVtcGxhdGUgPSBUZW1wbGF0ZUZhY3RvcnkuZ2V0VGVtcGxhdGUoJ21zZ19jb250YWluZXJfdGVtcGxhdGUnKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tYXJrZG93blNlcnZpY2U6IE1hcmtEb3duU2VydmljZSA9IG5ldyBNYXJrRG93bkl0TWFya0Rvd25TZXJ2aWNlKCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfZW5jcnlwdGlvblNlcnZpY2U6IEVuY3J5cHRpb25TZXJ2aWNlID0gbmV3IFNKQ0xFbmNyeXB0aW9uU2VydmljZSgpO1xuXG5cbiAgICBjb25zdHJ1Y3RvcihjaGF0TW9kZWw6IENoYXRNb2RlbCwgbWVzc2FnZUNvbnRhaW5lcjogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5fbWVzc2FnZUNvbnRhaW5lciA9IG1lc3NhZ2VDb250YWluZXI7XG4gICAgICAgIHRoaXMuX2NoYXRNb2RlbCA9IGNoYXRNb2RlbDtcbiAgICAgICAgLy8gdGhpcy5fbWVzc2FnZVNlbmRCdXR0b24gPSBtZXNzYWdlU2VuZEJ1dHRvbjtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgIH1cblxuXG4gICAgdXBkYXRlKGRhdGE6IENoYXRNZXNzYWdlVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgbG9nLmluZm8oJ0NoYXRWaWV3OiB1cGRhdGluZyB2aWV3Jyk7XG4gICAgICAgIC8vIGxldCBodG1sOiBzdHJpbmcgPSBcIlwiO1xuICAgICAgICB0aGlzLl9tZXNzYWdlQ29udGFpbmVyLmlubmVySFRNTCA9IFwiXCI7XG4gICAgICAgIGRhdGEuZm9yRWFjaCgodm06IENoYXRNZXNzYWdlVmlld01vZGVsKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2bVRlbXAgPSB2bTtcbiAgICAgICAgICAgIHZtVGVtcC5tZXNzYWdlID0gdGhpcy5fbWFya2Rvd25TZXJ2aWNlLnJlbmRlcih2bS5tZXNzYWdlKTtcbiAgICAgICAgICAgIC8qKiBWZXJ5IEltcG9ydGFudCEhIVxuICAgICAgICAgICAgKiBTYW5pdGl6aW5nIEhUTUwgYmVmb3JlIGRpc3BsYXlpbmcgb24gd2VicGFnZSB0byBwcmV2ZW50IFhTUyBhdHRhY2tzISFcbiAgICAgICAgICAgICovXG4gICAgICAgICAgICBsZXQgcmVuZGVyZWQ7XG4gICAgICAgICAgICBpZiAodm1UZW1wLmZyb21Vc2VyID09IEpzb25BUEkucHJpbmNpcGxlTmFtZSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkID0gRE9NUHVyaWZ5LnNhbml0aXplKHRoaXMuX21lc3NhZ2VTZW5kVGVtcGxhdGUodm1UZW1wKSk7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkID0gRE9NUHVyaWZ5LnNhbml0aXplKHRoaXMuX21lc3NhZ2VSZWNlaXZlVGVtcGxhdGUodm1UZW1wKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkKHRoaXMuX21lc3NhZ2VDb250YWluZXIpLmFwcGVuZChyZW5kZXJlZCk7XG4gICAgICAgICAgICBsb2cuZGVidWcoKVxuICAgICAgICAgICAgLy8gaHRtbCArPSB0aGlzLl9tZXNzYWdlU2VuZFRlbXBsYXRlKHZtKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gaHRtbCA9IERPTVB1cmlmeS5zYW5pdGl6ZShtZC5yZW5kZXIoaHRtbCkpO1xuICAgICAgICAvLyB0aGlzLl9lbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIC8vIGxvZy5kZWJ1Zyh0aGlzLl9lbGVtZW50LmlubmVySFRNTCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRFdmVudExpc3RlbmVycygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hZGRDaGF0Rm9ybUVMKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRDaGF0Rm9ybUVMKCkge1xuICAgICAgICBjb25zdCBjaGF0Rm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGF0TWVzc2FnZUZvcm0nKSBhcyBIVE1MU2VsZWN0RWxlbWVudDtcblxuICAgICAgICBpZiAoY2hhdEZvcm0gPT0gbnVsbCkge1xuICAgICAgICAgICAgbG9nLmVycm9yKFwiQ2hhdCBmb3JtIGlzIG51bGxcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjaGF0Rm9ybS5hZGRFdmVudExpc3RlbmVyKCdzdWJtaXQnLCAoZSkgPT4gdGhpcy5jcmVhdGVDaGF0TWVzc2FnZURUTyhlLCBjaGF0Rm9ybSkpXG5cbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVDaGF0TWVzc2FnZURUTyhlOiBFdmVudCwgY2hhdEZvcm06IEhUTUxTZWxlY3RFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBsZXQgY29udGFjdE5hbWUgPSBKc29uQVBJLmNvbnRhY3ROYW1lO1xuXG4gICAgICAgIGlmKGNvbnRhY3ROYW1lID09IG51bGwpXG4gICAgICAgIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcihcIkNvbnRhY3QgbmFtZSBpcyBudWxsXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjaGF0Rm9ybS5jaGVja1ZhbGlkaXR5KCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiZXJyb3JcIik7XG4gICAgICAgICAgICBjaGF0Rm9ybS5jbGFzc0xpc3QuYWRkKCd3YXMtdmFsaWRhdGVkJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY2hhdEZvcm0uY2xhc3NMaXN0LmFkZCgnd2FzLXZhbGlkYXRlZCcpO1xuXG5cbiAgICAgICAgY29uc3QgY2hhdElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoYXRJbnB1dCcpIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHBhc3NwaHJhc2VJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzcGhyYXNlJykgYXMgSFRNTElucHV0RWxlbWVudDtcblxuICAgICAgICBpZiAoY2hhdElucHV0LnZhbHVlID09ICcnIHx8IGNoYXRJbnB1dC52YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoXCJDaGF0IGlucHV0IGlzIG51bGwuXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhc3NwaHJhc2VJbnB1dC52YWx1ZSA9PSAnJyB8fCBwYXNzcGhyYXNlSW5wdXQudmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgbG9nLmVycm9yKFwiQ2hhdCBpbnB1dCBpcyBudWxsLlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgY29uc3QgbWVzc2FnZUNvbnRlbnQgPSBjaGF0SW5wdXQudmFsdWU7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB7IGZyb21Vc2VyOiBKc29uQVBJLnByaW5jaXBsZU5hbWUsIG1lc3NhZ2U6IHRoaXMuX21hcmtkb3duU2VydmljZS5yZW5kZXIobWVzc2FnZUNvbnRlbnQpLCBtZXNzYWdlVGltZTogbmV3IERhdGUoKS50b0xvY2FsZVN0cmluZygpIH07XG4gICAgICAgIGNvbnN0IG1zZ0NvbnRhaW5lcjogc3RyaW5nID0gdGhpcy5fbWVzc2FnZVNlbmRUZW1wbGF0ZShjb250ZXh0KTtcbiAgICAgICAgJCh0aGlzLl9tZXNzYWdlQ29udGFpbmVyKS5hcHBlbmQoRE9NUHVyaWZ5LnNhbml0aXplKG1zZ0NvbnRhaW5lcikpO1xuICAgICAgICAvLyBzY3JvbGxDaGF0QXJlYUFuaW1hdGVkKDI0MDApO1xuICAgICAgICAvLyBsZXQgbWVzc2FnZUNpcGhlciA9IHNqY2wuZW5jcnlwdChwYXNzcGhyYXNlSW5wdXQudmFsdWUsIG1lc3NhZ2VDb250ZW50LCB7IG1vZGU6IFwiZ2NtXCIsIHRzOiAxMjgsIGFkYXRhOiBcIlwiLCBpdGVyOiBpdGVyYXRpb25zIH0pO1xuICAgICAgICBsZXQgbWVzc2FnZUNpcGhlcjogTWVzc2FnZUNpcGhlckRUTyA9IHRoaXMuX2VuY3J5cHRpb25TZXJ2aWNlLmVuY3J5cHQocGFzc3BocmFzZUlucHV0LnZhbHVlLCBtZXNzYWdlQ29udGVudClcbiAgICAgICAgLy8gbGV0IG1lc3NhZ2VDaXBoZXJKc29uID0gSlNPTi5wYXJzZShtZXNzYWdlQ2lwaGVyKTtcbiAgICAgICAgbGV0IGNoYXRNZXNzYWdlRFRPID0ge1xuICAgICAgICAgICAgXCJmcm9tVXNlclwiOiBKc29uQVBJLnByaW5jaXBsZU5hbWUsXG4gICAgICAgICAgICBcInRvVXNlclwiOiBjb250YWN0TmFtZSxcbiAgICAgICAgICAgIFwibWVzc2FnZUNpcGhlclwiOiBtZXNzYWdlQ2lwaGVyLFxuICAgICAgICAgICAgLy8gXCJtZXNzYWdlVGltZVwiOiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnNlbmRNZXNzYWdlQUpBWChjaGF0TWVzc2FnZURUTyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZW5kTWVzc2FnZUFKQVgoY2hhdE1lc3NhZ2VEVE86IENoYXRNZXNzYWdlRFRPKTogdm9pZCB7XG4gICAgICAgIGxldCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgICAgLy9cdGNvbnNvbGUubG9nKFwiVG9rZW4gPSBcIiArIGJ0b2EoXCJobW1cIiArIFwiOlwiICsgXCJobW1cIikpXG5cbiAgICAgICAgLy8gaGVhZGVycy5hcHBlbmQoJ0FjY2VwdCcsJ2FwcGxpY2F0aW9uL2pzb24nKVxuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgLy8gaGVhZGVycy5hcHBlbmQoJ0F1dGhvcml6YXRpb24nLCBiYXNpY0F1dGhUb2tlbik7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIEpzb25BUEkuYXV0aFRva2VuKTtcbiAgICAgICAgZmV0Y2goSnNvbkFQSS5NRVNTQUdFX1BPU1QsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGNoYXRNZXNzYWdlRFRPKVxuICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIGxvZy5kZWJ1ZyhyZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmNsb25lKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4gZmV0Y2hIYW5kbGVyKHJlc3BvbnNlKSk7XG5cbiAgICB9XG59IiwiaW1wb3J0IHsgc3ByaW50ZiB9IGZyb20gXCJzcHJpbnRmLWpzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBmZXRjaEhhbmRsZXIocmVzcG9uc2U6IGFueSkge1xuICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpLnRoZW4oKGpzb246IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgb2sgYW5kIHRoZXJlIGlzIGEganNvbiBib2R5XG4gICAgICAgICAgICAvLyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsganNvbjoganNvbiwgcmVzcG9uc2U6IHJlc3BvbnNlIH0pO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuc3VjY2VzcygnTWVzc2FnZSBzZW50IHN1Y2Nlc2Z1bGx5JyArIHNwcmludGYoXCIgKGh0dHAgY29kZSAlZClcIiwgcmVzcG9uc2Uuc3RhdHVzKSk7XG4gICAgICAgIH0pLmNhdGNoKChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgb2sgYnV0IHRoZXJlIGlzIG5vIGpzb24gYm9keVxuICAgICAgICAgICAgLy8gcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiByZXNwb25zZSB9KTtcbiAgICAgICAgICAgIC8vIGFsZXJ0aWZ5LnN1Y2Nlc3MoJ01lc3NhZ2Ugc2VudCBzdWNjZXNmdWxseScgKyBzcHJpbnRmKFwiIChodHRwIGNvZGUgJWQpXCIsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICB9KTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCkuY2F0Y2goKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyB0aGUgc3RhdHVzIHdhcyBub3Qgb2sgYW5kIHRoZXJlIGlzIG5vIGpzb24gYm9keVxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3IoJ1NvbWUgZXJyb3Igb2NjdXJlZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTtcbiAgICAgICAgfSkudGhlbigoanNvbjogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyB0aGUgc3RhdHVzIHdhcyBub3Qgb2sgYnV0IHRoZXJlIGlzIGEganNvbiBib2R5XG4gICAgICAgICAgICAvLyB0aHJvdyBuZXcgRXJyb3IoanNvbi5lcnJvci5tZXNzYWdlKTsgLy8gZXhhbXBsZSBlcnJvciBtZXNzYWdlIHJldHVybmVkIGJ5IGEgUkVTVFxuICAgICAgICAgICAgLy8gbGV0IGRlbGF5ID0gYWxlcnRpZnkuZ2V0KCdub3RpZmllcicsICdkZWxheScpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuc2V0KCdub3RpZmllcicsICdkZWxheScsIDMwKTtcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBcIlwiO1xuICAgICAgICAgICAganNvbi5lcnJvcnMuZm9yRWFjaChmdW5jdGlvbihkYXRhOiBhbnkpIHtcbiAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgKz0gc3ByaW50ZihcIkZpZWxkIE5hbWU6ICVzIFxcbiBSZWplY3RlZCB2YWx1ZTogJXMgXFxuIFJlYXNvbjogJXMgXFxuXCIsIGRhdGEuZmllbGRfbmFtZSwgZGF0YS5yZWplY3RlZF92YWx1ZSwgZGF0YS5lcnJvcl9tZXNzYWdlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignVGhlcmUgd2VyZSBlcnJvcnMgaW4geW91ciBtZXNzYWdlIC0gJXMnLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIC8vIGFsZXJ0aWZ5LnNldCgnbm90aWZpZXInLCAnZGVsYXknLCBkZWxheSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2ZXJcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4vQWJzdHJhY3RWaWV3XCI7XG5pbXBvcnQgeyBDb250cm9sbGVyIH0gZnJvbSBcIi4uL2NvbnRyb2xsZXIvQWJzdHJhY3RDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUZhY3RvcnkgfSBmcm9tIFwiLi4vdGVtcGxhdGUvVGVtcGxhdGVGYWN0b3J5XCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBDaGF0TW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQ2hhdE1vZGVsXCI7XG5pbXBvcnQgbG9nID0gcmVxdWlyZShcImxvZ2xldmVsXCIpO1xuaW1wb3J0ICogYXMgRE9NUHVyaWZ5IGZyb20gXCJkb21wdXJpZnlcIjtcblxuZXhwb3J0IGNsYXNzIFVzZXJWaWV3IGltcGxlbWVudHMgT2JzZXJ2ZXIge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21vZGVsOiBNb2RlbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jaGF0TW9kZWw6IENoYXRNb2RlbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvLyBwcml2YXRlIHVzZXJCb3hlczogYW55W10gPSAgW107XG5cblxuICAgIGNvbnN0cnVjdG9yKG1vZGVsOiBNb2RlbCwgY2hhdE1vZGVsOiBDaGF0TW9kZWwsIGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuX21vZGVsID0gbW9kZWw7XG4gICAgICAgIHRoaXMuX2NoYXRNb2RlbCA9IGNoYXRNb2RlbDtcbiAgICAgICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG5cblxuXG4gICAgdXBkYXRlKGRhdGE6IEFjdGl2ZVVzZXJWaWV3TW9kZWxbXSk6IHZvaWQge1xuICAgICAgICBsZXQgdGVtcGxhdGUgPSBUZW1wbGF0ZUZhY3RvcnkuZ2V0VGVtcGxhdGUoJ3VzZXItY29udGFjdC1vbmxpbmUtdGVtcGxhdGUnKTtcbiAgICAgICAgbGV0IGh0bWw6IHN0cmluZyA9IFwiXCI7XG4gICAgICAgIGRhdGEuZm9yRWFjaCgoZWxlbWVudDogQWN0aXZlVXNlclZpZXdNb2RlbCkgPT4ge1xuICAgICAgICAgICAgaHRtbCArPSB0ZW1wbGF0ZShlbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHRoaXMuX2VsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgJCh0aGlzLl9lbGVtZW50KS5odG1sKERPTVB1cmlmeS5zYW5pdGl6ZShodG1sKSk7XG4gICAgICAgIHRoaXMuYWRkVXNlckNhbGxCYWNrcygpO1xuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLl9lbGVtZW50LmlubmVySFRNTCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoZWxwZXIoKTogdm9pZCB7XG5cbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZFVzZXJDYWxsQmFja3MoKTogdm9pZCB7XG4gICAgICAgIGxldCB1c2VyQm94ZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd1c2VyLWJveCcpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVzZXJCb3hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHVzZXJCb3ggPSB1c2VyQm94ZXNbaV07XG4gICAgICAgICAgICB1c2VyQm94ZXNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnVzZXJDYWxsQmFjay5iaW5kKHRoaXMsIHVzZXJCb3gpKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgcHJpdmF0ZSB1c2VyQ2FsbEJhY2soZWw6IEVsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgbGV0IGN1cnJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd1c2VyLWJveCBhY3RpdmUnKTtcblxuICAgICAgICBsZXQgcGFzc3BocmFzZTogc3RyaW5nID0gJyc7XG4gICAgICAgIGlmIChjdXJyZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxldCBwYXNzcGhyYXNlSW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFzc3BocmFzZScpIGFzIGFueTtcblxuICAgICAgICAgICAgaWYgKHBhc3NwaHJhc2VJbnB1dCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKCdwYXNzcGhyYXNlSW5wdXQgZWxlbWVudCByZWZlcmVuY2UgaXMgbnVsbCcpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhc3NwaHJhc2UgPSBwYXNzcGhyYXNlSW5wdXQudmFsdWVcbiAgICAgICAgICAgIGlmIChwYXNzcGhyYXNlID09ICcnIHx8IHBhc3NwaHJhc2UgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGFsZXJ0KCdQbGVhc2UgaW5wdXQgcGFzc3BocmFzZScpXG4gICAgICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3IoJ1BsZWFzZSBlbnRlciBhIHBhc3NwaHJhc2UnKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoJ3Bhc3NwaHJhc2UgaXMgZW1wdHkgb3IgbnVsbCcpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnJlbnRbMF0uY2xhc3NOYW1lID0gY3VycmVudFswXS5jbGFzc05hbWUucmVwbGFjZShcIiBhY3RpdmVcIiwgXCJcIik7XG5cbiAgICAgICAgfVxuICAgICAgICAvLyBBZGQgdGhlIGFjdGl2ZSBjbGFzcyB0byB0aGUgY3VycmVudC9jbGlja2VkIGJ1dHRvblxuICAgICAgICBlbHNlIGlmIChjdXJyZW50Lmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICBsZXQgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzcGhyYXNlLWluaXRpYWwnKSBhcyBhbnk7XG4gICAgICAgICAgICBpZihlbGVtID09IG51bGwpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKCdwYXNzcGhyYXNlSW5wdXQgZWxlbWVudCByZWZlcmVuY2UgaXMgbnVsbCcpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhc3NwaHJhc2UgPSBlbGVtLnZhbHVlO1xuICAgICAgICAgICAgaWYgKHBhc3NwaHJhc2UgPT0gJycgfHwgcGFzc3BocmFzZSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIGFsZXJ0KCdQbGVhc2UgaW5wdXQgcGFzc3BocmFzZScpXG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIGFsZXJ0aWZ5LmVycm9yKCdQbGVhc2UgZW50ZXIgYSBwYXNzcGhyYXNlJyk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKCdwYXNzcGhyYXNlIGlzIGVtcHR5IG9yIG51bGwnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vLXVzZXItc2VsZWN0ZWQnKS5oaWRkZW4gPSB0cnVlO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGF0LWNhcmQnKS5oaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgICAgICBlbGVtLmhpZGRlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd0by11c2VyLXNwYW4nKSk7XG4gICAgICAgIGxldCBlbGVtID0gZWwuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndG8tdXNlci1zcGFuJylbMF0gYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGxldCB1c2VyTmFtZSA9IGVsZW0uaW5uZXJUZXh0O1xuICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1uYW1lLXNwYW4nKS5pbm5lclRleHQgPSB1c2VyTmFtZTtcbiAgICAgICAgdGhpcy5fY2hhdE1vZGVsLmdldG1lc3NhZ2VzKHVzZXJOYW1lLCBwYXNzcGhyYXNlLCBudWxsKTtcbiAgICAgICAgLy8gcG9wdWxhdGVNZXNzYWdlcyh1c2VyTmFtZSwgcGFzc3BocmFzZSk7XG4gICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NlbGVjdGVkVXNlcicsIHVzZXJOYW1lKTtcbiAgICAgICAgZWwuY2xhc3NOYW1lICs9IFwiIGFjdGl2ZVwiO1xuICAgIH1cblxufSIsImV4cG9ydCBjbGFzcyBBY3RpdmVVc2VyVmlld01vZGVsIHtcbiAgICB1c2VyTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIG9ubGluZTogYm9vbGVhbiB8IHVuZGVmaW5lZDtcbiAgICBsYXN0QWN0aXZlOiBzdHJpbmd8IHVuZGVmaW5lZDtcbn0iLCJleHBvcnQgY2xhc3MgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwge1xuICAgIHB1YmxpYyB0b1VzZXI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBwdWJsaWMgZnJvbVVzZXI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBwdWJsaWMgbWVzc2FnZSE6IHN0cmluZztcbiAgICBwdWJsaWMgbWVzc2FnZVRpbWUhOiBEYXRlO1xuXG4gICAgXG59Il19 diff --git a/chatto/src/main/resources/templates/chat.html b/chatto/src/main/resources/templates/chat.html index 89ff581..3c5c0ba 100644 --- a/chatto/src/main/resources/templates/chat.html +++ b/chatto/src/main/resources/templates/chat.html @@ -234,7 +234,7 @@
{{{message}}} - {{time}} + {{messageTime}}
@@ -243,7 +243,7 @@
{{{message}}} - {{time}} + {{messageTime}}