UNPKG

@cometchat/chat-uikit-angular

Version:

Ready-to-use Chat UI Components for Angular (JavaScript/Web)

198 lines 39.6 kB
import { Component, Input, ChangeDetectionStrategy, } from "@angular/core"; import { CometChat } from "@cometchat/chat-sdk-javascript"; import { fontHelper, localize, CometChatUIKitConstants, } from "@cometchat/uikit-resources"; import "@cometchat/uikit-elements"; import { CallLogDetailsConfiguration, CallLogsConfiguration, WithDetailsStyle, } from "@cometchat/uikit-shared"; import * as i0 from "@angular/core"; import * as i1 from "../../../CometChatTheme.service"; import * as i2 from "../../CometChatCallLogs/cometchat-call-logs/cometchat-call-logs.component"; import * as i3 from "../../CometChatCallLogDetails/cometchat-call-log-details/cometchat-call-log-details.component"; import * as i4 from "@angular/common"; export class CometChatCallLogsWithDetailsComponent { constructor(elementRef, ref, themeService) { this.elementRef = elementRef; this.ref = ref; this.themeService = themeService; this.isMobileView = false; this.messageText = localize("NO_CALLS_SELECTED"); this.withDetailsStyle = {}; this.showMoreInfo = true; this.backdropStyle = {}; this.callLogDetailsConfiguration = new CallLogDetailsConfiguration({}); this.callLogConfiguration = new CallLogsConfiguration({}); this.onError = (error) => { console.log(error); }; this.computedCallLogDetailsConfig = new CallLogDetailsConfiguration({}); this.labelStyle = { background: "transparent", textFont: "700 22px Inter", textColor: "rgba(20, 20, 20, 0.33)", }; this.onBackClick = () => { this.user = null; this.group = null; this.activeCall = null; }; this.onInfoClick = (call) => { this.call = call; this.setActiveCallLog(); }; this.emptyMessageStyle = () => { return { background: this.withDetailsStyle.background || this.themeService.theme.palette.getBackground(), height: this.withDetailsStyle.height, width: `calc(${this.withDetailsStyle.width} - 280px)`, border: this.withDetailsStyle.border, borderRadius: this.withDetailsStyle.borderRadius, }; }; this.chatsWrapperStyles = () => { return { height: this.withDetailsStyle.height, width: this.withDetailsStyle.width, border: this.withDetailsStyle.border, borderRadius: this.withDetailsStyle.borderRadius, background: this.withDetailsStyle.background || this.themeService.theme.palette.getBackground(), }; }; } ngOnChanges(changes) { if (changes["user"] || changes["group"]) { this.setActiveCallLog(); } if (changes["isMobileView"]) { if (this.isMobileView) { this.backdropStyle.height = "100%"; this.backdropStyle.width = "100%"; this.computedCallLogDetailsConfig = this.computedCallLogDetailsConfiguration(); } else if (!this.isMobileView) { this.backdropStyle.height = "100%"; this.backdropStyle.width = "100%"; this.computedCallLogDetailsConfig = this.computedCallLogDetailsConfiguration(); } setTimeout(() => { this.updateBackdropHeight(); }, 100); } } updateBackdropHeight() { let divHeight = this.elementRef.nativeElement.offsetHeight; let divWidth = this.elementRef.nativeElement.offsetWidth; if (divHeight === 0 || divWidth === 0) { const rect = this.elementRef.nativeElement.getBoundingClientRect(); divHeight = rect.height; divWidth = rect.width; } this.backdropStyle = { height: divHeight + "px", width: divWidth + "px", background: "rgba(0, 0, 0, 0.5)", position: "fixed", }; if (this.isMobileView) { this.backdropStyle.height = divHeight + "px"; this.backdropStyle.width = divWidth + "px"; } else { this.backdropStyle.height = divHeight + "px"; this.backdropStyle.width = divWidth + "px"; } this.backdropStyle.height = divHeight + "px"; this.backdropStyle.width = divWidth + "px"; } setWithDetailsStyle() { let defaultStyle = new WithDetailsStyle({ width: "100%", height: "100%", background: this.themeService.theme.palette.getBackground(), borderRadius: "none", border: "none", messageTextColor: this.themeService.theme.palette.getAccent600(), messageTextFont: fontHelper(this.themeService.theme.typography.title1), }); this.withDetailsStyle = { ...defaultStyle, ...this.withDetailsStyle, }; this.labelStyle.textFont = this.withDetailsStyle.messageTextFont; this.labelStyle.textColor = this.withDetailsStyle.messageTextColor; } setActiveCallLog() { this.activeCall = this.call; if (this.call.getInitiator().getUid() == this.loggedInUser?.getUid()) { if (this.call.getReceiverType() == CometChatUIKitConstants.MessageReceiverType.user) { this.user = this.call.getReceiver(); this.group = null; } else { this.user = null; this.group = this.call.getReceiver(); } } else { this.user = this.call.getInitiator(); } } ngOnInit() { this.computedCallLogDetailsConfig = this.computedCallLogDetailsConfiguration(); this.updateBackdropHeight(); this.setWithDetailsStyle(); CometChat.getLoggedinUser() .then((user) => { this.loggedInUser = user; }) .catch((error) => { if (this.onError) { this.onError(error); } }); } computedCallLogDetailsConfiguration() { const config = new CallLogDetailsConfiguration({}); Object.assign(config, this.callLogDetailsConfiguration); config.callLogDetailsStyle = { ...config.callLogDetailsStyle, border: `1px solid ${this.themeService.theme.palette?.getAccent100()}`, }; if (this.isMobileView) config.onBackClick = () => { this.activeCall = null; this.user = null; this.group = null; }; return config; } } CometChatCallLogsWithDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CometChatCallLogsWithDetailsComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.CometChatThemeService }], target: i0.ɵɵFactoryTarget.Component }); CometChatCallLogsWithDetailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: CometChatCallLogsWithDetailsComponent, selector: "cometchat-call-logs-with-details", inputs: { isMobileView: "isMobileView", messageText: "messageText", withDetailsStyle: "withDetailsStyle", showMoreInfo: "showMoreInfo", backdropStyle: "backdropStyle", call: "call", callLogDetailsConfiguration: "callLogDetailsConfiguration", callLogConfiguration: "callLogConfiguration", onError: "onError" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"cc-with-details__wrapper\" [ngStyle]=\"chatsWrapperStyles()\">\n <div class=\"cc-with-details__sidebar\" [ngClass]=\"{mobile : isMobileView}\">\n <cometchat-call-logs [activeCall]=\"activeCall\" [showMoreInfo]=\"showMoreInfo\" [backdropStyle]=\"backdropStyle\"\n [activeCall]=\"activeCall\" [titleAlignment]=\"callLogConfiguration?.titleAlignment!\"\n [emptyStateView]=\"callLogConfiguration.emptyStateView\" \n [errorStateView]=\"callLogConfiguration.errorStateView\"\n [subtitleView]=\"callLogConfiguration.subtitleView\" \n [listItemView]=\"callLogConfiguration.listItemView\" \n [tailView]=\"callLogConfiguration.tailView\" \n [loadingIconURL]=\"callLogConfiguration.loadingIconURL\" [loadingStateView]=\"callLogConfiguration.loadingStateView\"\n [callLogRequestBuilder]=\"callLogConfiguration.callLogRequestBuilder\"\n [onItemClick]=\"callLogConfiguration.onItemClick!\" [onInfoClick]=\"callLogConfiguration.onInfoClick || onInfoClick! \"\n [onError]=\"callLogConfiguration.onError!\" [listItemStyle]=\"callLogConfiguration.listItemStyle\"\n [infoIconUrl]=\"callLogConfiguration.infoIconUrl\" [datePattern]=\"callLogConfiguration.datePattern\"\n [dateSeparatorPattern]=\"callLogConfiguration.dateSeparatorPattern\"\n [incomingAudioCallIconUrl]=\"callLogConfiguration.incomingAudioCallIconUrl\"\n [incomingVideoCallIconUrl]=\"callLogConfiguration.incomingVideoCallIconUrl\"\n [outgoingAudioCallIconUrl]=\"callLogConfiguration.outgoingAudioCallIconUrl\"\n [outgoingVideoCallIconUrl]=\"callLogConfiguration.outgoingVideoCallIconUrl\"\n [missedAudioCallIconUrl]=\"callLogConfiguration.missedAudioCallIconUrl\"\n [missedVideoCallIconUrl]=\"callLogConfiguration.missedVideoCallIconUrl\"\n [callLogsStyle]=\"callLogConfiguration.callLogsStyle\" [avatarStyle]=\"callLogConfiguration.avatarStyle\"\n [hideSeparator]=\"callLogConfiguration.hideSeparator\"\n [outgoingCallConfiguration]=\"callLogConfiguration.outgoingCallConfiguration\"></cometchat-call-logs>\n </div>\n <div class=\"cc-with-details__main\" [ngClass]=\"{mobile : isMobileView}\" *ngIf=\"activeCall && (user || group)\">\n <!--call details Screen-->\n <cometchat-call-log-details [user]=\"user!\" [group]=\"group!\" [call]=\"call\"\n [backIconUrl]=\"computedCallLogDetailsConfig.backIconUrl\" [avatarStyle]=\"computedCallLogDetailsConfig.avatarStyle\"\n [onBackClick]=\"computedCallLogDetailsConfig.onBackClick || onBackClick\"\n [callLogHistoryConfiguration]=\"computedCallLogDetailsConfig.callLogHistoryConfiguration\"\n [callLogParticipantsConfiguration]=\"computedCallLogDetailsConfig.callLogParticipantsConfiguration\"\n [callLogRecordingsConfiguration]=\"computedCallLogDetailsConfig.callLogRecordingsConfiguration\"\n [callLogDetailStyle]=\"computedCallLogDetailsConfig.callLogDetailsStyle\">\n </cometchat-call-log-details>\n </div>\n\n <div class=\"cc-decorator__message--empty\" *ngIf=\"!user && !group\" [ngStyle]=\"emptyMessageStyle()\">\n <cometchat-label [text]=\"messageText\" [labelStyle]=\"labelStyle\"></cometchat-label>\n </div>", styles: [".cc-with-details__wrapper{display:flex;height:100%;width:100%;box-sizing:border-box}.cc-with-details__sidebar{width:280px;height:100%;position:relative}.cc-with-details__main{width:calc(100% - 280px);height:100%}.mobile{width:100%!important;height:100%;position:absolute}.cc-decorator__message--empty{display:flex;justify-content:center;align-items:center}\n"], components: [{ type: i2.CometchatCallLogsComponent, selector: "cometchat-call-logs", inputs: ["title", "titleAlignment", "listItemView", "subtitleView", "tailView", "menu", "emptyStateView", "errorStateView", "emptyStateText", "errorStateText", "loadingStateView", "loadingIconURL", "infoIconUrl", "missedAudioCallIconUrl", "missedVideoCallIconUrl", "outgoingAudioCallIconUrl", "outgoingVideoCallIconUrl", "incomingAudioCallIconUrl", "incomingVideoCallIconUrl", "callLogRequestBuilder", "cometchatCallObject", "onItemClick", "onInfoClick", "onError", "activeCall", "datePattern", "DateSeparatorPattern", "callLogsStyle", "avatarStyle", "hideSeparator", "dateSeparatorStyle", "outgoingCallConfiguration", "hideError", "showSectionHeader", "showMoreInfo", "sectionHeaderField", "backdropStyle", "dateStyle", "listItemStyle", "ongoingCallConfiguration"] }, { type: i3.CometChatCallLogDetailsComponent, selector: "cometchat-call-log-details", inputs: ["call", "group", "user", "title", "onBackClick", "hideProfile", "subtitleView", "customProfileView", "backIconUrl", "greaterThanIconURL", "callButtonsConfiguration", "callLogParticipantsConfiguration", "callLogHistoryConfiguration", "callLogRecordingsConfiguration", "onError", "datePattern", "datePattern2", "data", "avatarStyle", "labelStyle", "callDetailsStyle", "listItemStyle", "dateStyle", "callButtonsStyle"] }], directives: [{ type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: CometChatCallLogsWithDetailsComponent, decorators: [{ type: Component, args: [{ selector: "cometchat-call-logs-with-details", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cc-with-details__wrapper\" [ngStyle]=\"chatsWrapperStyles()\">\n <div class=\"cc-with-details__sidebar\" [ngClass]=\"{mobile : isMobileView}\">\n <cometchat-call-logs [activeCall]=\"activeCall\" [showMoreInfo]=\"showMoreInfo\" [backdropStyle]=\"backdropStyle\"\n [activeCall]=\"activeCall\" [titleAlignment]=\"callLogConfiguration?.titleAlignment!\"\n [emptyStateView]=\"callLogConfiguration.emptyStateView\" \n [errorStateView]=\"callLogConfiguration.errorStateView\"\n [subtitleView]=\"callLogConfiguration.subtitleView\" \n [listItemView]=\"callLogConfiguration.listItemView\" \n [tailView]=\"callLogConfiguration.tailView\" \n [loadingIconURL]=\"callLogConfiguration.loadingIconURL\" [loadingStateView]=\"callLogConfiguration.loadingStateView\"\n [callLogRequestBuilder]=\"callLogConfiguration.callLogRequestBuilder\"\n [onItemClick]=\"callLogConfiguration.onItemClick!\" [onInfoClick]=\"callLogConfiguration.onInfoClick || onInfoClick! \"\n [onError]=\"callLogConfiguration.onError!\" [listItemStyle]=\"callLogConfiguration.listItemStyle\"\n [infoIconUrl]=\"callLogConfiguration.infoIconUrl\" [datePattern]=\"callLogConfiguration.datePattern\"\n [dateSeparatorPattern]=\"callLogConfiguration.dateSeparatorPattern\"\n [incomingAudioCallIconUrl]=\"callLogConfiguration.incomingAudioCallIconUrl\"\n [incomingVideoCallIconUrl]=\"callLogConfiguration.incomingVideoCallIconUrl\"\n [outgoingAudioCallIconUrl]=\"callLogConfiguration.outgoingAudioCallIconUrl\"\n [outgoingVideoCallIconUrl]=\"callLogConfiguration.outgoingVideoCallIconUrl\"\n [missedAudioCallIconUrl]=\"callLogConfiguration.missedAudioCallIconUrl\"\n [missedVideoCallIconUrl]=\"callLogConfiguration.missedVideoCallIconUrl\"\n [callLogsStyle]=\"callLogConfiguration.callLogsStyle\" [avatarStyle]=\"callLogConfiguration.avatarStyle\"\n [hideSeparator]=\"callLogConfiguration.hideSeparator\"\n [outgoingCallConfiguration]=\"callLogConfiguration.outgoingCallConfiguration\"></cometchat-call-logs>\n </div>\n <div class=\"cc-with-details__main\" [ngClass]=\"{mobile : isMobileView}\" *ngIf=\"activeCall && (user || group)\">\n <!--call details Screen-->\n <cometchat-call-log-details [user]=\"user!\" [group]=\"group!\" [call]=\"call\"\n [backIconUrl]=\"computedCallLogDetailsConfig.backIconUrl\" [avatarStyle]=\"computedCallLogDetailsConfig.avatarStyle\"\n [onBackClick]=\"computedCallLogDetailsConfig.onBackClick || onBackClick\"\n [callLogHistoryConfiguration]=\"computedCallLogDetailsConfig.callLogHistoryConfiguration\"\n [callLogParticipantsConfiguration]=\"computedCallLogDetailsConfig.callLogParticipantsConfiguration\"\n [callLogRecordingsConfiguration]=\"computedCallLogDetailsConfig.callLogRecordingsConfiguration\"\n [callLogDetailStyle]=\"computedCallLogDetailsConfig.callLogDetailsStyle\">\n </cometchat-call-log-details>\n </div>\n\n <div class=\"cc-decorator__message--empty\" *ngIf=\"!user && !group\" [ngStyle]=\"emptyMessageStyle()\">\n <cometchat-label [text]=\"messageText\" [labelStyle]=\"labelStyle\"></cometchat-label>\n </div>", styles: [".cc-with-details__wrapper{display:flex;height:100%;width:100%;box-sizing:border-box}.cc-with-details__sidebar{width:280px;height:100%;position:relative}.cc-with-details__main{width:calc(100% - 280px);height:100%}.mobile{width:100%!important;height:100%;position:absolute}.cc-decorator__message--empty{display:flex;justify-content:center;align-items:center}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.CometChatThemeService }]; }, propDecorators: { isMobileView: [{ type: Input }], messageText: [{ type: Input }], withDetailsStyle: [{ type: Input }], showMoreInfo: [{ type: Input }], backdropStyle: [{ type: Input }], call: [{ type: Input }], callLogDetailsConfiguration: [{ type: Input }], callLogConfiguration: [{ type: Input }], onError: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tZXRjaGF0LWNhbGwtbG9ncy13aXRoLWRldGFpbHMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2hhdC11aWtpdC1hbmd1bGFyL3NyYy9DYWxscy9Db21ldENoYXRDYWxsTG9nc1dpdGhEZXRhaWxzL2NvbWV0Y2hhdC1jYWxsLWxvZ3Mtd2l0aC1kZXRhaWxzL2NvbWV0Y2hhdC1jYWxsLWxvZ3Mtd2l0aC1kZXRhaWxzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NoYXQtdWlraXQtYW5ndWxhci9zcmMvQ2FsbHMvQ29tZXRDaGF0Q2FsbExvZ3NXaXRoRGV0YWlscy9jb21ldGNoYXQtY2FsbC1sb2dzLXdpdGgtZGV0YWlscy9jb21ldGNoYXQtY2FsbC1sb2dzLXdpdGgtZGV0YWlscy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFDTCx1QkFBdUIsR0FLeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRTNELE9BQU8sRUFDTCxVQUFVLEVBQ1YsUUFBUSxFQUNSLHVCQUF1QixHQUN4QixNQUFNLDRCQUE0QixDQUFDO0FBRXBDLE9BQU8sMkJBQTJCLENBQUM7QUFHbkMsT0FBTyxFQUNMLDJCQUEyQixFQUMzQixxQkFBcUIsRUFDckIsZ0JBQWdCLEdBQ2pCLE1BQU0seUJBQXlCLENBQUM7Ozs7OztBQVFqQyxNQUFNLE9BQU8scUNBQXFDO0lBc0NoRCxZQUNVLFVBQXNCLEVBQ3RCLEdBQXNCLEVBQ3RCLFlBQW1DO1FBRm5DLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDdEIsaUJBQVksR0FBWixZQUFZLENBQXVCO1FBdENwQyxpQkFBWSxHQUFZLEtBQUssQ0FBQztR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QUcsSUFBSSwyQkFBMkIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUV4RCxNQUFNLENBQUMsbUJBQW1CLEdBQUc7WUFDM0IsR0FBRyxNQUFNLENBQUMsbUJBQW1CO1lBQzdCLE1BQU0sRUFBRSxhQUFhLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsRUFBRTtTQUN2RSxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsWUFBWTtZQUNuQixNQUFNLENBQUMsV0FBVyxHQUFHLEdBQUcsRUFBRTtnQkFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztZQUNwQixDQUFDLENBQUM7UUFFSixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOzttSUF6S1UscUNBQXFDO3VIQUFyQyxxQ0FBcUMsbVpDakNsRCwybUdBdUNROzRGRE5LLHFDQUFxQztrQkFOakQsU0FBUzsrQkFDRSxrQ0FBa0MsbUJBRzNCLHVCQUF1QixDQUFDLE1BQU07cUtBS3RDLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFFRywyQkFBMkI7c0JBQW5DLEtBQUs7Z0JBR0csb0JBQW9CO3NCQUE1QixLQUFLO2dCQUdHLE9BQU87c0JBQWYsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgT25Jbml0LFxuICBJbnB1dCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIEVsZW1lbnRSZWYsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb21ldENoYXQgfSBmcm9tIFwiQGNvbWV0Y2hhdC9jaGF0LXNkay1qYXZhc2NyaXB0XCI7XG5cbmltcG9ydCB7XG4gIGZvbnRIZWxwZXIsXG4gIGxvY2FsaXplLFxuICBDb21ldENoYXRVSUtpdENvbnN0YW50cyxcbn0gZnJvbSBcIkBjb21ldGNoYXQvdWlraXQtcmVzb3VyY2VzXCI7XG5cbmltcG9ydCBcIkBjb21ldGNoYXQvdWlraXQtZWxlbWVudHNcIjtcbmltcG9ydCB7IENvbWV0Q2hhdFRoZW1lU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9Db21ldENoYXRUaGVtZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBCYWNrZHJvcFN0eWxlIH0gZnJvbSBcIkBjb21ldGNoYXQvdWlraXQtZWxlbWVudHNcIjtcbmltcG9ydCB7XG4gIENhbGxMb2dEZXRhaWxzQ29uZmlndXJhdGlvbixcbiAgQ2FsbExvZ3NDb25maWd1cmF0aW9uLFxuICBXaXRoRGV0YWlsc1N0eWxlLFxufSBmcm9tIFwiQGNvbWV0Y2hhdC91aWtpdC1zaGFyZWRcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImNvbWV0Y2hhdC1jYWxsLWxvZ3Mtd2l0aC1kZXRhaWxzXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vY29tZXRjaGF0LWNhbGwtbG9ncy13aXRoLWRldGFpbHMuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2NvbWV0Y2hhdC1jYWxsLWxvZ3Mtd2l0aC1kZXRhaWxzLmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQ29tZXRDaGF0Q2FsbExvZ3NXaXRoRGV0YWlsc0NvbXBvbmVudFxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzXG57XG4gIEBJbnB1dCgpIGlzTW9iaWxlVmlldzogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtZXNzYWdlVGV4dDogc3RyaW5nID0gbG9jYWxpemUoXCJOT19DQUxMU19TRUxFQ1RFRFwiKTtcbiAgQElucHV0KCkgd2l0aERldGFpbHNTdHlsZTogV2l0aERldGFpbHNTdHlsZSA9IHt9O1xuICBASW5wdXQoKSBzaG93TW9yZUluZm86IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBiYWNrZHJvcFN0eWxlOiBCYWNrZHJvcFN0eWxlID0ge307XG4gIEBJbnB1dCgpIGNhbGwhOiBhbnk7XG5cbiAgQElucHV0KCkgY2FsbExvZ0RldGFpbHNDb25maWd1cmF0aW9uOiBDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24gPVxuICAgIG5ldyBDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24oe30pO1xuXG4gIEBJbnB1dCgpIGNhbGxMb2dDb25maWd1cmF0aW9uOiBDYWxsTG9nc0NvbmZpZ3VyYXRpb24gPVxuICAgIG5ldyBDYWxsTG9nc0NvbmZpZ3VyYXRpb24oe30pO1xuXG4gIEBJbnB1dCgpIG9uRXJyb3I6ICgoZXJyb3I6IENvbWV0Q2hhdC5Db21ldENoYXRFeGNlcHRpb24pID0+IHZvaWQpIHwgbnVsbCA9IChcbiAgICBlcnJvcjogQ29tZXRDaGF0LkNvbWV0Q2hhdEV4Y2VwdGlvblxuICApID0+IHtcbiAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gIH07XG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIGZvciBpbnRlcm5hbCB1c2VcbiAgICovXG4gIHB1YmxpYyBsb2dnZWRJblVzZXIhOiBDb21ldENoYXQuVXNlciB8IG51bGw7XG4gIHB1YmxpYyBhY3RpdmVDYWxsITphbnk7XG4gIHVzZXIhOiBhbnkgfCBudWxsO1xuICBncm91cCE6IENvbWV0Q2hhdC5Hcm91cCB8IG51bGw7XG5cbiAgY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZzogQ2FsbExvZ0RldGFpbHNDb25maWd1cmF0aW9uID1cbiAgICBuZXcgQ2FsbExvZ0RldGFpbHNDb25maWd1cmF0aW9uKHt9KTtcblxuICBsYWJlbFN0eWxlOiBhbnkgPSB7XG4gICAgYmFja2dyb3VuZDogXCJ0cmFuc3BhcmVudFwiLFxuICAgIHRleHRGb250OiBcIjcwMCAyMnB4IEludGVyXCIsXG4gICAgdGV4dENvbG9yOiBcInJnYmEoMjAsIDIwLCAyMCwgMC4zMylcIixcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSByZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgdGhlbWVTZXJ2aWNlOiBDb21ldENoYXRUaGVtZVNlcnZpY2VcbiAgKSB7fVxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbXCJ1c2VyXCJdIHx8IGNoYW5nZXNbXCJncm91cFwiXSkge1xuICAgICAgdGhpcy5zZXRBY3RpdmVDYWxsTG9nKCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbXCJpc01vYmlsZVZpZXdcIl0pIHtcbiAgICAgIGlmICh0aGlzLmlzTW9iaWxlVmlldykge1xuICAgICAgICB0aGlzLmJhY2tkcm9wU3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG4gICAgICAgIHRoaXMuYmFja2Ryb3BTdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuICAgICAgICB0aGlzLmNvbXB1dGVkQ2FsbExvZ0RldGFpbHNDb25maWcgPVxuICAgICAgICAgIHRoaXMuY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24oKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNNb2JpbGVWaWV3KSB7XG4gICAgICAgIHRoaXMuYmFja2Ryb3BTdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbiAgICAgICAgdGhpcy5iYWNrZHJvcFN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG4gICAgICAgIHRoaXMuY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZyA9XG4gICAgICAgICAgdGhpcy5jb21wdXRlZENhbGxMb2dEZXRhaWxzQ29uZmlndXJhdGlvbigpO1xuICAgICAgfVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlQmFja2Ryb3BIZWlnaHQoKTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQmFja2Ryb3BIZWlnaHQoKSB7XG4gICAgbGV0IGRpdkhlaWdodCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICBsZXQgZGl2V2lkdGggPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICBpZiAoZGl2SGVpZ2h0ID09PSAwIHx8IGRpdldpZHRoID09PSAwKSB7XG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBkaXZIZWlnaHQgPSByZWN0LmhlaWdodDtcbiAgICAgIGRpdldpZHRoID0gcmVjdC53aWR0aDtcbiAgICB9XG4gICAgdGhpcy5iYWNrZHJvcFN0eWxlID0ge1xuICAgICAgaGVpZ2h0OiBkaXZIZWlnaHQgKyBcInB4XCIsXG4gICAgICB3aWR0aDogZGl2V2lkdGggKyBcInB4XCIsXG4gICAgICBiYWNrZ3JvdW5kOiBcInJnYmEoMCwgMCwgMCwgMC41KVwiLFxuICAgICAgcG9zaXRpb246IFwiZml4ZWRcIixcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuaXNNb2JpbGVWaWV3KSB7XG4gICAgICB0aGlzLmJhY2tkcm9wU3R5bGUuaGVpZ2h0ID0gZGl2SGVpZ2h0ICsgXCJweFwiO1xuICAgICAgdGhpcy5iYWNrZHJvcFN0eWxlLndpZHRoID0gZGl2V2lkdGggKyBcInB4XCI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYmFja2Ryb3BTdHlsZS5oZWlnaHQgPSBkaXZIZWlnaHQgKyBcInB4XCI7XG4gICAgICB0aGlzLmJhY2tkcm9wU3R5bGUud2lkdGggPSBkaXZXaWR0aCArIFwicHhcIjtcbiAgICB9XG5cbiAgICB0aGlzLmJhY2tkcm9wU3R5bGUuaGVpZ2h0ID0gZGl2SGVpZ2h0ICsgXCJweFwiO1xuICAgIHRoaXMuYmFja2Ryb3BTdHlsZS53aWR0aCA9IGRpdldpZHRoICsgXCJweFwiO1xuICB9XG5cbiAgb25CYWNrQ2xpY2sgPSAoKSA9PiB7XG4gICAgdGhpcy51c2VyID0gbnVsbDtcbiAgICB0aGlzLmdyb3VwID0gbnVsbDtcbiAgICB0aGlzLmFjdGl2ZUNhbGwgPSBudWxsO1xuICB9O1xuICBzZXRXaXRoRGV0YWlsc1N0eWxlKCkge1xuICAgIGxldCBkZWZhdWx0U3R5bGU6IFdpdGhEZXRhaWxzU3R5bGUgPSBuZXcgV2l0aERldGFpbHNTdHlsZSh7XG4gICAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgICAgYmFja2dyb3VuZDogdGhpcy50aGVtZVNlcnZpY2UudGhlbWUucGFsZXR0ZS5nZXRCYWNrZ3JvdW5kKCksXG4gICAgICBib3JkZXJSYWRpdXM6IFwibm9uZVwiLFxuICAgICAgYm9yZGVyOiBcIm5vbmVcIixcbiAgICAgIG1lc3NhZ2VUZXh0Q29sb3I6IHRoaXMudGhlbWVTZXJ2aWNlLnRoZW1lLnBhbGV0dGUuZ2V0QWNjZW50NjAwKCksXG4gICAgICBtZXNzYWdlVGV4dEZvbnQ6IGZvbnRIZWxwZXIodGhpcy50aGVtZVNlcnZpY2UudGhlbWUudHlwb2dyYXBoeS50aXRsZTEpLFxuICAgIH0pO1xuICAgIHRoaXMud2l0aERldGFpbHNTdHlsZSA9IHtcbiAgICAgIC4uLmRlZmF1bHRTdHlsZSxcbiAgICAgIC4uLnRoaXMud2l0aERldGFpbHNTdHlsZSxcbiAgICB9O1xuICAgIHRoaXMubGFiZWxTdHlsZS50ZXh0Rm9udCA9IHRoaXMud2l0aERldGFpbHNTdHlsZS5tZXNzYWdlVGV4dEZvbnQ7XG4gICAgdGhpcy5sYWJlbFN0eWxlLnRleHRDb2xvciA9IHRoaXMud2l0aERldGFpbHNTdHlsZS5tZXNzYWdlVGV4dENvbG9yO1xuICB9XG5cbiAgcHVibGljIG9uSW5mb0NsaWNrOiAoY2FsbDogYW55KSA9PiB2b2lkID0gKGNhbGw6IGFueSkgPT4ge1xuICAgIHRoaXMuY2FsbCA9IGNhbGw7XG4gICAgdGhpcy5zZXRBY3RpdmVDYWxsTG9nKCk7XG4gIH07XG4gIHNldEFjdGl2ZUNhbGxMb2coKSB7XG4gICAgdGhpcy5hY3RpdmVDYWxsID0gdGhpcy5jYWxsO1xuICAgIGlmICh0aGlzLmNhbGwhLmdldEluaXRpYXRvcigpLmdldFVpZCgpID09IHRoaXMubG9nZ2VkSW5Vc2VyPy5nZXRVaWQoKSkge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLmNhbGwhLmdldFJlY2VpdmVyVHlwZSgpID09XG4gICAgICAgIENvbWV0Q2hhdFVJS2l0Q29uc3RhbnRzLk1lc3NhZ2VSZWNlaXZlclR5cGUudXNlclxuICAgICAgKSB7XG4gICAgICAgIHRoaXMudXNlciA9IHRoaXMuY2FsbCEuZ2V0UmVjZWl2ZXIoKSBhcyB1bmtub3duIGFzIENvbWV0Q2hhdC5Vc2VyO1xuICAgICAgICB0aGlzLmdyb3VwID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudXNlciA9IG51bGw7XG4gICAgICAgIHRoaXMuZ3JvdXAgPSB0aGlzLmNhbGwhLmdldFJlY2VpdmVyKCkgYXMgdW5rbm93biBhcyBDb21ldENoYXQuR3JvdXA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudXNlciA9IHRoaXMuY2FsbCEuZ2V0SW5pdGlhdG9yKCkgYXMgdW5rbm93biBhcyBDb21ldENoYXQuVXNlcjtcbiAgICB9XG4gIH1cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jb21wdXRlZENhbGxMb2dEZXRhaWxzQ29uZmlnID1cbiAgICAgIHRoaXMuY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24oKTtcbiAgICB0aGlzLnVwZGF0ZUJhY2tkcm9wSGVpZ2h0KCk7XG4gICAgdGhpcy5zZXRXaXRoRGV0YWlsc1N0eWxlKCk7XG4gICAgQ29tZXRDaGF0LmdldExvZ2dlZGluVXNlcigpXG4gICAgICAudGhlbigodXNlcjogQ29tZXRDaGF0LlVzZXIgfCBudWxsKSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VkSW5Vc2VyID0gdXNlcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yOiBDb21ldENoYXQuQ29tZXRDaGF0RXhjZXB0aW9uKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLm9uRXJyb3IpIHtcbiAgICAgICAgICB0aGlzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuICBjb21wdXRlZENhbGxMb2dEZXRhaWxzQ29uZmlndXJhdGlvbigpOiBDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24ge1xuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDYWxsTG9nRGV0YWlsc0NvbmZpZ3VyYXRpb24oe30pO1xuICAgIE9iamVjdC5hc3NpZ24oY29uZmlnLCB0aGlzLmNhbGxMb2dEZXRhaWxzQ29uZmlndXJhdGlvbik7XG5cbiAgICBjb25maWcuY2FsbExvZ0RldGFpbHNTdHlsZSA9IHtcbiAgICAgIC4uLmNvbmZpZy5jYWxsTG9nRGV0YWlsc1N0eWxlLFxuICAgICAgYm9yZGVyOiBgMXB4IHNvbGlkICR7dGhpcy50aGVtZVNlcnZpY2UudGhlbWUucGFsZXR0ZT8uZ2V0QWNjZW50MTAwKCl9YCxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuaXNNb2JpbGVWaWV3KVxuICAgICAgY29uZmlnLm9uQmFja0NsaWNrID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmFjdGl2ZUNhbGwgPSBudWxsO1xuICAgICAgICB0aGlzLnVzZXIgPSBudWxsO1xuICAgICAgICB0aGlzLmdyb3VwID0gbnVsbDtcbiAgICAgIH07XG5cbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG4gIGVtcHR5TWVzc2FnZVN0eWxlID0gKCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBiYWNrZ3JvdW5kOlxuICAgICAgICB0aGlzLndpdGhEZXRhaWxzU3R5bGUuYmFja2dyb3VuZCB8fFxuICAgICAgICB0aGlzLnRoZW1lU2VydmljZS50aGVtZS5wYWxldHRlLmdldEJhY2tncm91bmQoKSxcbiAgICAgIGhlaWdodDogdGhpcy53aXRoRGV0YWlsc1N0eWxlLmhlaWdodCxcbiAgICAgIHdpZHRoOiBgY2FsYygke3RoaXMud2l0aERldGFpbHNTdHlsZS53aWR0aH0gLSAyODBweClgLFxuICAgICAgYm9yZGVyOiB0aGlzLndpdGhEZXRhaWxzU3R5bGUuYm9yZGVyLFxuICAgICAgYm9yZGVyUmFkaXVzOiB0aGlzLndpdGhEZXRhaWxzU3R5bGUuYm9yZGVyUmFkaXVzLFxuICAgIH07XG4gIH07XG4gIGNoYXRzV3JhcHBlclN0eWxlcyA9ICgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaGVpZ2h0OiB0aGlzLndpdGhEZXRhaWxzU3R5bGUuaGVpZ2h0LFxuICAgICAgd2lkdGg6IHRoaXMud2l0aERldGFpbHNTdHlsZS53aWR0aCxcbiAgICAgIGJvcmRlcjogdGhpcy53aXRoRGV0YWlsc1N0eWxlLmJvcmRlcixcbiAgICAgIGJvcmRlclJhZGl1czogdGhpcy53aXRoRGV0YWlsc1N0eWxlLmJvcmRlclJhZGl1cyxcbiAgICAgIGJhY2tncm91bmQ6XG4gICAgICAgIHRoaXMud2l0aERldGFpbHNTdHlsZS5iYWNrZ3JvdW5kIHx8XG4gICAgICAgIHRoaXMudGhlbWVTZXJ2aWNlLnRoZW1lLnBhbGV0dGUuZ2V0QmFja2dyb3VuZCgpLFxuICAgIH07XG4gIH07XG59XG4iLCI8ZGl2IGNsYXNzPVwiY2Mtd2l0aC1kZXRhaWxzX193cmFwcGVyXCIgW25nU3R5bGVdPVwiY2hhdHNXcmFwcGVyU3R5bGVzKClcIj5cbiAgPGRpdiBjbGFzcz1cImNjLXdpdGgtZGV0YWlsc19fc2lkZWJhclwiIFtuZ0NsYXNzXT1cInttb2JpbGUgOiBpc01vYmlsZVZpZXd9XCI+XG4gICAgPGNvbWV0Y2hhdC1jYWxsLWxvZ3MgW2FjdGl2ZUNhbGxdPVwiYWN0aXZlQ2FsbFwiIFtzaG93TW9yZUluZm9dPVwic2hvd01vcmVJbmZvXCIgW2JhY2tkcm9wU3R5bGVdPVwiYmFja2Ryb3BTdHlsZVwiXG4gICAgICBbYWN0aXZlQ2FsbF09XCJhY3RpdmVDYWxsXCIgW3RpdGxlQWxpZ25tZW50XT1cImNhbGxMb2dDb25maWd1cmF0aW9uPy50aXRsZUFsaWdubWVudCFcIlxuICAgICAgW2VtcHR5U3RhdGVWaWV3XT1cImNhbGxMb2dDb25maWd1cmF0aW9uLmVtcHR5U3RhdGVWaWV3XCIgXG4gICAgICBbZXJyb3JTdGF0ZVZpZXddPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24uZXJyb3JTdGF0ZVZpZXdcIlxuICAgICAgW3N1YnRpdGxlVmlld109XCJjYWxsTG9nQ29uZmlndXJhdGlvbi5zdWJ0aXRsZVZpZXdcIiBcbiAgICAgIFtsaXN0SXRlbVZpZXddPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ubGlzdEl0ZW1WaWV3XCIgXG4gICAgICBbdGFpbFZpZXddPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24udGFpbFZpZXdcIiBcbiAgICAgIFtsb2FkaW5nSWNvblVSTF09XCJjYWxsTG9nQ29uZmlndXJhdGlvbi5sb2FkaW5nSWNvblVSTFwiIFtsb2FkaW5nU3RhdGVWaWV3XT1cImNhbGxMb2dDb25maWd1cmF0aW9uLmxvYWRpbmdTdGF0ZVZpZXdcIlxuICAgICAgW2NhbGxMb2dSZXF1ZXN0QnVpbGRlcl09XCJjYWxsTG9nQ29uZmlndXJhdGlvbi5jYWxsTG9nUmVxdWVzdEJ1aWxkZXJcIlxuICAgICAgW29uSXRlbUNsaWNrXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLm9uSXRlbUNsaWNrIVwiIFtvbkluZm9DbGlja109XCJjYWxsTG9nQ29uZmlndXJhdGlvbi5vbkluZm9DbGljayB8fCBvbkluZm9DbGljayEgXCJcbiAgICAgIFtvbkVycm9yXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLm9uRXJyb3IhXCIgW2xpc3RJdGVtU3R5bGVdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ubGlzdEl0ZW1TdHlsZVwiXG4gICAgICBbaW5mb0ljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24uaW5mb0ljb25VcmxcIiBbZGF0ZVBhdHRlcm5dPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24uZGF0ZVBhdHRlcm5cIlxuICAgICAgW2RhdGVTZXBhcmF0b3JQYXR0ZXJuXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLmRhdGVTZXBhcmF0b3JQYXR0ZXJuXCJcbiAgICAgIFtpbmNvbWluZ0F1ZGlvQ2FsbEljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24uaW5jb21pbmdBdWRpb0NhbGxJY29uVXJsXCJcbiAgICAgIFtpbmNvbWluZ1ZpZGVvQ2FsbEljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24uaW5jb21pbmdWaWRlb0NhbGxJY29uVXJsXCJcbiAgICAgIFtvdXRnb2luZ0F1ZGlvQ2FsbEljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ub3V0Z29pbmdBdWRpb0NhbGxJY29uVXJsXCJcbiAgICAgIFtvdXRnb2luZ1ZpZGVvQ2FsbEljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ub3V0Z29pbmdWaWRlb0NhbGxJY29uVXJsXCJcbiAgICAgIFttaXNzZWRBdWRpb0NhbGxJY29uVXJsXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLm1pc3NlZEF1ZGlvQ2FsbEljb25VcmxcIlxuICAgICAgW21pc3NlZFZpZGVvQ2FsbEljb25VcmxdPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ubWlzc2VkVmlkZW9DYWxsSWNvblVybFwiXG4gICAgICBbY2FsbExvZ3NTdHlsZV09XCJjYWxsTG9nQ29uZmlndXJhdGlvbi5jYWxsTG9nc1N0eWxlXCIgW2F2YXRhclN0eWxlXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLmF2YXRhclN0eWxlXCJcbiAgICAgIFtoaWRlU2VwYXJhdG9yXT1cImNhbGxMb2dDb25maWd1cmF0aW9uLmhpZGVTZXBhcmF0b3JcIlxuICAgICAgW291dGdvaW5nQ2FsbENvbmZpZ3VyYXRpb25dPVwiY2FsbExvZ0NvbmZpZ3VyYXRpb24ub3V0Z29pbmdDYWxsQ29uZmlndXJhdGlvblwiPjwvY29tZXRjaGF0LWNhbGwtbG9ncz5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYy13aXRoLWRldGFpbHNfX21haW5cIiBbbmdDbGFzc109XCJ7bW9iaWxlIDogaXNNb2JpbGVWaWV3fVwiICpuZ0lmPVwiYWN0aXZlQ2FsbCAmJiAodXNlciB8fCBncm91cClcIj5cbiAgICA8IS0tY2FsbCBkZXRhaWxzIFNjcmVlbi0tPlxuICAgIDxjb21ldGNoYXQtY2FsbC1sb2ctZGV0YWlscyBbdXNlcl09XCJ1c2VyIVwiIFtncm91cF09XCJncm91cCFcIiBbY2FsbF09XCJjYWxsXCJcbiAgICAgIFtiYWNrSWNvblVybF09XCJjb21wdXRlZENhbGxMb2dEZXRhaWxzQ29uZmlnLmJhY2tJY29uVXJsXCIgW2F2YXRhclN0eWxlXT1cImNvbXB1dGVkQ2FsbExvZ0RldGFpbHNDb25maWcuYXZhdGFyU3R5bGVcIlxuICAgICAgW29uQmFja0NsaWNrXT1cImNvbXB1dGVkQ2FsbExvZ0RldGFpbHNDb25maWcub25CYWNrQ2xpY2sgfHwgb25CYWNrQ2xpY2tcIlxuICAgICAgW2NhbGxMb2dIaXN0b3J5Q29uZmlndXJhdGlvbl09XCJjb21wdXRlZENhbGxMb2dEZXRhaWxzQ29uZmlnLmNhbGxMb2dIaXN0b3J5Q29uZmlndXJhdGlvblwiXG4gICAgICBbY2FsbExvZ1BhcnRpY2lwYW50c0NvbmZpZ3VyYXRpb25dPVwiY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZy5jYWxsTG9nUGFydGljaXBhbnRzQ29uZmlndXJhdGlvblwiXG4gICAgICBbY2FsbExvZ1JlY29yZGluZ3NDb25maWd1cmF0aW9uXT1cImNvbXB1dGVkQ2FsbExvZ0RldGFpbHNDb25maWcuY2FsbExvZ1JlY29yZGluZ3NDb25maWd1cmF0aW9uXCJcbiAgICAgIFtjYWxsTG9nRGV0YWlsU3R5bGVdPVwiY29tcHV0ZWRDYWxsTG9nRGV0YWlsc0NvbmZpZy5jYWxsTG9nRGV0YWlsc1N0eWxlXCI+XG4gICAgPC9jb21ldGNoYXQtY2FsbC1sb2ctZGV0YWlscz5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNjLWRlY29yYXRvcl9fbWVzc2FnZS0tZW1wdHlcIiAqbmdJZj1cIiF1c2VyICYmICFncm91cFwiIFtuZ1N0eWxlXT1cImVtcHR5TWVzc2FnZVN0eWxlKClcIj5cbiAgICA8Y29tZXRjaGF0LWxhYmVsIFt0ZXh0XT1cIm1lc3NhZ2VUZXh0XCIgW2xhYmVsU3R5bGVdPVwibGFiZWxTdHlsZVwiPjwvY29tZXRjaGF0LWxhYmVsPlxuICA8L2Rpdj4iXX0=