Repository URL to install this package:
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, ElementRef, ViewChild } from '@angular/core';
import { PluginView } from 'web-console-core';
import { NGXLogger } from 'web-console-core';
import { WCNotificationCenter, NotificationType } from 'web-console-ui-kit';
import { BundlesService } from '@wa-motif-open-api/web-content-service';
import { WCSubscriptionHandler } from '../../../components/Commons/wc-subscription-handler';
import * as _ from 'lodash';
import { faUpload } from '@fortawesome/free-solid-svg-icons';
import { WebContentUpdateDialogComponent } from './dialog/webcontent-update-dialog';
import { UpdatePoller, UpdatePollerEventStatus } from './update-poller/UpdatePoller';
import { BundleUtils, PublishingStatus } from './BundleUtils';
/** @type {?} */
const LOG_TAG = '[WebContentSectionComponent]';
/** @enum {string} */
const CommandType = {
Edit: 'cmdEdit',
Download: 'cmdDowload',
Delete: 'cmdDelete',
Publish: 'cmdPublish',
};
let WebContentSectionComponent = class WebContentSectionComponent {
/**
* @param {?} logger
* @param {?} notificationCenter
* @param {?} elem
* @param {?} webContentService
*/
constructor(logger, notificationCenter, elem, webContentService) {
this.logger = logger;
this.notificationCenter = notificationCenter;
this.elem = elem;
this.webContentService = webContentService;
this.statsModel = { items: [] };
this.faUpload = faUpload;
this._subHandler = new WCSubscriptionHandler();
this._pollers = [];
// Data binding
this.loading = false;
this.publishConfirmationTitleProvider = {
/**
* @param {?} rowData
* @return {?}
*/
getTitle(rowData) {
if (rowData.info.syntheticStatus === PublishingStatus.Published) {
return "Unpublish ?";
}
else if (rowData.info.syntheticStatus === PublishingStatus.Error) {
return "Unpublish ?";
}
else {
return "Publish ?";
}
}
};
this.commands = [
{
commandIcon: 'wa-ico-edit',
commandId: CommandType.Edit,
title: 'Edit'
},
{
commandIcon: 'wa-ico-download',
commandId: CommandType.Download,
title: 'Download'
},
{
commandIcon: 'wa-ico-no',
commandId: CommandType.Delete,
title: 'Delete',
hasConfirmation: true,
confirmationTitle: 'Delete ?'
}
];
this.logger.debug(LOG_TAG, 'Opening...');
}
/**
* Angular ngOnInit
* @return {?}
*/
ngOnInit() {
this.logger.debug(LOG_TAG, 'Initializing...');
this.refreshData();
}
/**
* @return {?}
*/
ngOnDestroy() {
this.logger.debug(LOG_TAG, 'ngOnDestroy ');
this.freeMem();
}
/**
* @return {?}
*/
freeMem() {
this.gridData = null;
this._subHandler.unsubscribe();
}
/**
* @return {?}
*/
onRefreshClicked() {
this.refreshData();
}
/**
* @param {?} bundleStatus
* @return {?}
*/
updateModelWith(bundleStatus) {
/** @type {?} */
let index = _.findIndex(this.gridData, (/**
* @param {?} item
* @return {?}
*/
(item) => {
return (item == bundleStatus);
}));
if (index >= 0) {
this.gridData[index] = bundleStatus;
}
}
/**
* @return {?}
*/
refreshData() {
this.logger.debug(LOG_TAG, 'refreshData called.');
this.loading = true;
this._subHandler.add(this.webContentService.getBundlesList().subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.logger.debug(LOG_TAG, 'Get bundle statuses results:', data);
this.gridData = _.forEach(data, (/**
* @param {?} element
* @return {?}
*/
(element) => {
element.info["syntheticStatus"] = BundleUtils.buildSyntheticStatus(element);
element.info["url"] = BundleUtils.buildUrl(element);
}));
this.logger.debug(LOG_TAG, '*** Get bundle statuses results gridData:', this.gridData);
this.gridData = data;
this.logger.debug(LOG_TAG, '*** Get bundle statuses results gridData:', this.gridData);
this.rebuildStatsInfo();
this.loading = false;
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Get bundle statuses failed: ', error);
this.loading = false;
this.clearStatsInfo();
this.notificationCenter.post({
name: 'GetBundleStatusesError',
title: 'Get Bundle Statuses',
message: 'Error getting bundle statuses:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @private
* @return {?}
*/
clearStatsInfo() {
this.statsModel = { items: [] };
}
/**
* @private
* @return {?}
*/
rebuildStatsInfo() {
/** @type {?} */
const statuses = _.map(this.gridData, 'info.syntheticStatus');
/** @type {?} */
const total = statuses.length;
/** @type {?} */
const published = _.countBy(statuses, (/**
* @param {?} status
* @return {?}
*/
(status) => (status === "PUBLISHED")));
if (!published) {
published.true = 0;
published.false = 0;
}
if (!published.true) {
published.true = 0;
}
if (!published.false) {
published.false = 0;
}
this.statsModel = {
items: [
{ label: "bundles", value: "" + total, cssClass: "stats-info-primary" },
{ label: "published", value: "" + published.true, cssClass: "stats-info-ok" },
{ label: "unpublished", value: "" + published.false, cssClass: "stats-info-ko" }
]
};
}
/**
* @param {?} item
* @return {?}
*/
doTogglePublishBundle(item) {
this.logger.debug(LOG_TAG, 'doTogglePublishBundle: ', item);
if (item.info["syntheticStatus"] === PublishingStatus.Unpublished) {
this.doPublishBundle(item);
}
else if (item.info["syntheticStatus"] === PublishingStatus.Published) {
this.doUnpublishBundle(item);
}
else if (item.info["syntheticStatus"] === PublishingStatus.Error) {
this.doUnpublishBundle(item);
}
}
/**
* @param {?} item
* @return {?}
*/
doPublishBundle(item) {
this.logger.debug(LOG_TAG, 'doPublishBundle: ', item);
this._subHandler.add(this.webContentService.publishBundle(item.info.name, item.info.version).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.logger.debug(LOG_TAG, 'Bundle published successfully: ', data);
this.refreshData();
this.notificationCenter.post({
name: 'PublishBundleSuccess',
title: 'Publishing Bundle',
message: 'Bundle publish request sent successfully.',
type: NotificationType.Info
});
// Create arefresh poller
/** @type {?} */
let newPoller = new UpdatePoller(item.info.name, item.info.version, this.webContentService, this.logger);
this._pollers.push(newPoller);
newPoller.start(3, 3000, item).subscribe((/**
* @param {?} results
* @return {?}
*/
(results) => {
if (results.status === UpdatePollerEventStatus.Complete) {
this.updateModelWith(results.bundleStatus);
}
/** @type {?} */
let test = _.remove(this._pollers, (/**
* @param {?} poller
* @return {?}
*/
function (poller) {
return (results.source === poller);
}));
}));
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Download Bundle failed: ', error);
this.loading = false;
this.notificationCenter.post({
name: 'PublishBundleError',
title: 'Publish Bundle',
message: 'Error publishing bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @param {?} item
* @return {?}
*/
doUnpublishBundle(item) {
this.logger.debug(LOG_TAG, 'doUnpublishBundle: ', item);
this._subHandler.add(this.webContentService.unpublishBundle(item.info.name, item.info.version).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.logger.debug(LOG_TAG, 'Bundle unpublished successfully: ', data);
this.refreshData();
this.notificationCenter.post({
name: 'UnpublishBundleSuccess',
title: 'Unpublish Bundle',
message: 'Bundle unpublished successfully.',
type: NotificationType.Info
});
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Unpublish Bundle failed: ', error);
this.loading = false;
this.notificationCenter.post({
name: 'UnpublishBundleError',
title: 'Unpublish Bundle',
message: 'Error unpublishing bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @param {?} item
* @return {?}
*/
doDownloadBundle(item) {
this.notificationCenter.post({
name: 'DownloadBundleProgress',
title: 'Download Bundle',
message: 'Downloading bundle...',
type: NotificationType.Info
});
this.logger.debug(LOG_TAG, 'doDownloadBundle: ', item);
this._subHandler.add(this.webContentService.downloadBundle(item.info.name, item.info.version).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.logger.debug(LOG_TAG, 'Bundle downloaded successfully: ', data);
/** @type {?} */
const blob = new Blob([data], { type: 'application/zip' });
/** @type {?} */
const fileName = item.info.name + '_' + item.info.version + '.zip';
saveAs(blob, fileName);
// FileSaver.saveAs(blob, fileName);
this.logger.debug(LOG_TAG, 'Bundle saved: ', fileName);
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Download Bundle failed: ', error);
this.loading = false;
this.notificationCenter.post({
name: 'DownloadBundleError',
title: 'Download Bundle',
message: 'Error downloading bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @param {?} item
* @return {?}
*/
doDeleteBundle(item) {
this.logger.debug(LOG_TAG, 'doDeleteBundle: ', item);
/** @type {?} */
let bundleName = item.info.name;
/** @type {?} */
let bundleVersion = item.info.version;
this.logger.debug(LOG_TAG, "doDeleteBundle bundleName='" + bundleName + "' bundleVersion='" + bundleVersion + "'");
this._subHandler.add(this.webContentService.deleteBundle(bundleName, bundleVersion).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.logger.debug(LOG_TAG, 'Delete Bundle success: ', data);
this.notificationCenter.post({
name: 'DeleteBundleSuccess',
title: 'Delete Bundle',
message: 'Bundle deleted successfully.',
type: NotificationType.Info
});
this.refreshData();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Delete Bundle failed: ', error);
this.notificationCenter.post({
name: 'DeleteBundleError',
title: 'Delete Bundle',
message: 'Error deleting bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @param {?} event
* @return {?}
*/
onCommandConfirm(event) {
this.logger.debug(LOG_TAG, 'onCommandConfirm event: ', event);
if (event.id === CommandType.Publish) {
this.doTogglePublishBundle(event.rowData.dataItem);
}
else if (event.id === CommandType.Delete) {
this.doDeleteBundle(event.rowData.dataItem);
}
}
/**
* @param {?} event
* @return {?}
*/
onCommandClick(event) {
this.logger.debug(LOG_TAG, 'onCommandClick event: ', event);
if (event.id === CommandType.Download) {
this.doDownloadBundle(event.rowData.dataItem);
}
else if (event.id === CommandType.Delete) {
this.doDeleteBundle(event.rowData.dataItem);
}
else if (event.id === CommandType.Edit) {
this.doEditBundle(event);
}
}
/**
* @param {?} event
* @return {?}
*/
doEditBundle(event) {
this.logger.debug(LOG_TAG, 'doEditBundle : ', event);
this._updateDialog.show(event.rowData.dataItem.info.name, event.rowData.dataItem.info.version, event.rowData.dataItem.info.domain, event.rowData.dataItem.info.application, event.rowData.dataItem.info.context);
}
/**
* @param {?} error
* @return {?}
*/
onUploadError(error) {
this.notificationCenter.post({
name: 'UploadBundleError',
title: 'Upload Bundle',
message: 'Error uploading bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
}
/**
* @param {?} event
* @return {?}
*/
uploadAssetBundle(event) {
this.logger.debug(LOG_TAG, 'uploadAssetBundle : ', event);
this.notificationCenter.post({
name: 'UploadAssetBundleProgress',
title: 'Upload Asset Bundle',
message: 'Uploading the asset bundle...',
type: NotificationType.Info
});
this._subHandler.add(this.webContentService.uploadBundle(event.file).subscribe((/**
* @param {?} event
* @return {?}
*/
(event) => {
this.refreshData();
this.logger.debug(LOG_TAG, 'Bundle uploaded successfully: ', event);
this.notificationCenter.post({
name: 'UploadBundleSuccess',
title: 'Upload Bundle',
message: 'The bundle has been successfully uploaded.',
type: NotificationType.Success
});
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Error uploading bundle: ', error);
this.notificationCenter.post({
name: 'UploadBundleError',
title: 'Upload Bundle',
message: 'Error uploading bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
/**
* @param {?} event
* @return {?}
*/
onUpdateConfirm(event) {
this.logger.debug(LOG_TAG, 'onUpdateConfirm: ', event);
/** @type {?} */
const bundleName = event.bundleName;
/** @type {?} */
const bundleVersion = event.bundleVersion;
/** @type {?} */
const bundleUpdate = {
application: event.application,
context: event.context,
domain: event.domain
};
this.logger.debug(LOG_TAG, 'onUpdateConfirm: ', bundleName, bundleVersion, bundleUpdate);
this._subHandler.add(this.webContentService.updateBundle(bundleName, bundleVersion, bundleUpdate).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
this.refreshData();
this.logger.debug(LOG_TAG, 'Bundle updated successfully: ', event);
this.notificationCenter.post({
name: 'UpdateBundleSuccess',
title: 'Update Bundle',
message: 'The bundle has been successfully updated.',
type: NotificationType.Success
});
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'Error updating bundle: ', error);
this.notificationCenter.post({
name: 'UpdateBundleError',
title: 'Update Bundle',
message: 'Error updating bundle:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
};
WebContentSectionComponent.decorators = [
{ type: Component, args: [{
selector: 'wa-web-content-section',
template: "<wc-loading-overlay [visible]=\"loading\"></wc-loading-overlay>\n<wa-webcontent-update-dialog #updateDialog (confirm)=\"onUpdateConfirm($event)\"></wa-webcontent-update-dialog>\n\n<wc-stats-info-component [model]=\"statsModel\"></wc-stats-info-component>\n\n<wc-dashboard-header [title]=\"'Web Content'\"></wc-dashboard-header>\n\n<div class=\"row spread\">\n <div class=\"flex-toolbar\" style=\"display:flex;align-items: center;\">\n <div>\n <label> </label>\n <kendo-buttongroup look=\"flat\">\n <button\n kendoButton\n motif-acl=\"com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:UPDATE:uploadBundle\"\n [toggleable]=\"false\"\n (click)=\"uploadSlideDownPanelEx.toggle()\"\n >\n <fa-icon [icon]=\"faUpload\"></fa-icon>Add Bundle\n </button>\n </kendo-buttongroup>\n </div>\n </div>\n\n <div class=\"flex-cmd\">\n <kendo-buttongroup look=\"flat\">\n <button\n kendoButton\n [toggleable]=\"false\"\n [icon]=\"'refresh'\"\n (click)=\"onRefreshClicked()\"\n >\n Refresh\n </button>\n </kendo-buttongroup>\n </div>\n</div>\n\n<div class=\"row fill\">\n\n <div>\n\n <wc-upload-panel #uploadSlideDownPanelEx (upload)=\"uploadAssetBundle($event)\" (uploadError)=\"onUploadError($event)\"></wc-upload-panel>\n\n <kendo-grid #datagrid [data]=\"gridData\">\n <kendo-grid-column field=\"info.name\" title=\"Name\"> </kendo-grid-column>\n\n <kendo-grid-column field=\"info.version\" title=\"Version\">\n </kendo-grid-column>\n\n <!--\n <kendo-grid-column field=\"info.context\" title=\"Context\">\n </kendo-grid-column>\n -->\n\n <kendo-grid-column field=\"info.context\" title=\"Context\">\n <ng-template\n kendoGridCellTemplate\n let-dataItem\n let-columnIndex=\"columnIndex\"\n let-rowIndex=\"rowIndex\"\n let-column=\"column\"\n >\n <a *ngIf=\"dataItem.info.syntheticStatus === 'PUBLISHED'; else notPublished\" class=\"wc-web-content-url\" \n href=\"{{dataItem.info.url}}\" target=\"_blank\">{{dataItem.info.context}}</a> \n <ng-template #notPublished>\n {{dataItem.info.context}}\n </ng-template>\n\n </ng-template>\n </kendo-grid-column>\n \n <kendo-grid-column field=\"info.domain\" title=\"Domain\">\n </kendo-grid-column>\n\n <kendo-grid-column field=\"info.application\" title=\"Application\">\n </kendo-grid-column>\n\n <kendo-grid-column field=\"info.syntheticStatus\" title=\"Status\">\n <ng-template\n kendoGridCellTemplate\n let-dataItem\n let-columnIndex=\"columnIndex\"\n let-rowIndex=\"rowIndex\"\n let-column=\"column\"\n >\n <wc-grid-editor-command\n [motif-acl]=\"['com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:CREATE:publishBundle',\n 'com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:CREATE:unpublishBundle']\"\n [alignMode]=\"'left'\"\n [rowIndex]=\"rowIndex\"\n [hasConfirmation]=\"true\"\n [confirmationTitleProvider]=\"publishConfirmationTitleProvider\"\n [columnIndex]=\"columnIndex\"\n [column]=\"column\"\n [value]=\"dataItem[column.field]\"\n [dataItem]=\"dataItem\"\n (commandConfirm)=\"doTogglePublishBundle(dataItem)\"\n >\n <span\n *ngIf=\"dataItem.info.syntheticStatus === 'PUBLISHED'\"\n class=\"badge badge-status badge-enabled\"\n >\n PUBLISHED\n </span>\n <span\n *ngIf=\"dataItem.info.syntheticStatus === 'UNPUBLISHED'\"\n class=\"badge badge-status badge-disabled\"\n >\n UNPUBLISHED\n </span>\n <span\n *ngIf=\"dataItem.info.syntheticStatus === 'PUBLISHING'\"\n class=\"badge badge-status badge-disabled\"\n >\n PUBLISHING\n </span>\n <span\n *ngIf=\"dataItem.info.syntheticStatus === 'UNPUBLISHING'\"\n class=\"badge badge-status badge-disabled\"\n >\n UNPUBLISHING\n </span>\n <span\n *ngIf=\"dataItem.info.syntheticStatus === 'ERROR'\"\n class=\"badge badge-status badge-error\"\n >\n IN ERROR\n </span>\n </wc-grid-editor-command>\n </ng-template>\n </kendo-grid-column>\n\n <kendo-grid-column title=\"\">\n <ng-template\n kendoGridCellTemplate\n let-dataItem\n let-columnIndex=\"columnIndex\"\n let-rowIndex=\"rowIndex\"\n let-column=\"column\"\n >\n <wc-grid-editor-commands-group\n [motif-acl]=\"['com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:UPDATE:updateBundle',\n 'com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:READ:downloadBundle',\n 'com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:DELETE:deleteBundle']\"\n motif-acl-hidden=\"true\"\n [commands]=\"commands\"\n [alignMode]=\"'end'\"\n [rowIndex]=\"rowIndex\"\n [columnIndex]=\"columnIndex\"\n [column]=\"column\"\n [value]=\"dataItem[column.field]\"\n [dataItem]=\"dataItem\"\n (commandConfirm)=\"onCommandConfirm($event)\"\n (commandClick)=\"onCommandClick($event)\"\n ></wc-grid-editor-commands-group>\n </ng-template>\n </kendo-grid-column>\n\n <div *kendoGridDetailTemplate=\"let dataItem\">\n <kendo-grid #datagridDetails [data]=\"dataItem.status\">\n <kendo-grid-column field=\"instance\" title=\"Node\"> </kendo-grid-column>\n <kendo-grid-column field=\"status\" title=\"Status\">\n <ng-template\n kendoGridCellTemplate\n let-dataItem\n let-columnIndex=\"columnIndex\"\n let-rowIndex=\"rowIndex\"\n let-column=\"column\"\n >\n <span\n *ngIf=\"dataItem.status === 'PUBLISHED'\"\n class=\"badge badge-status badge-enabled\"\n >\n PUBLISHED\n </span>\n <span\n *ngIf=\"dataItem.status === 'UNPUBLISHED'\"\n class=\"badge badge-status badge-disabled\"\n >\n UNPUBLISHED\n </span>\n </ng-template>\n </kendo-grid-column>\n </kendo-grid>\n </div>\n </kendo-grid>\n\n </div>\n\n</div>\n",
styles: [":host{display:flex;flex:1;flex-direction:column}:host ::ng-deep .grid-btn-editor.wc-table-delete-command{justify-content:center}.wc-web-content-url:hover{text-decoration:underline}:host ::ng-deep tr.k-grid-norecords.ng-star-inserted{text-align:left;display:contents}"]
}] }
];
/** @nocollapse */
WebContentSectionComponent.ctorParameters = () => [
{ type: NGXLogger },
{ type: WCNotificationCenter },
{ type: ElementRef },
{ type: BundlesService }
];
WebContentSectionComponent.propDecorators = {
_updateDialog: [{ type: ViewChild, args: ['updateDialog',] }]
};
WebContentSectionComponent = tslib_1.__decorate([
PluginView('WebContent', {
iconName: 'wa-ico-web',
userData: {
acl: {
permissions: ["com.vipera.osgi.foundation.webcontent.api.rest.WebContentApi:READ:getBundlesList"]
}
}
}),
tslib_1.__metadata("design:paramtypes", [NGXLogger,
WCNotificationCenter,
ElementRef,
BundlesService])
], WebContentSectionComponent);
export { WebContentSectionComponent };
if (false) {
/** @type {?} */
WebContentSectionComponent.prototype.statsModel;
/** @type {?} */
WebContentSectionComponent.prototype.faUpload;
/** @type {?} */
WebContentSectionComponent.prototype.gridData;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype._subHandler;
/** @type {?} */
WebContentSectionComponent.prototype._updateDialog;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype._pollers;
/** @type {?} */
WebContentSectionComponent.prototype.loading;
/** @type {?} */
WebContentSectionComponent.prototype.publishConfirmationTitleProvider;
/** @type {?} */
WebContentSectionComponent.prototype.commands;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype.logger;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype.notificationCenter;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype.elem;
/**
* @type {?}
* @private
*/
WebContentSectionComponent.prototype.webContentService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViY29udGVudC1zZWN0aW9uLWNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL21vdGlmLXdlYi1hZG1pbi1jb3JlLyIsInNvdXJjZXMiOlsibGliL3NlY3Rpb25zL1dlYkNvbnRlbnQvY29tcG9uZW50cy93ZWJjb250ZW50LXNlY3Rpb24tY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBcUIsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxjQUFjLEVBQTJELE1BQU0sd0NBQXdDLENBQUM7QUFDakksT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDNUYsT0FBTyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzdELE9BQU8sRUFBRSwrQkFBK0IsRUFBc0IsTUFBTSxtQ0FBbUMsQ0FBQztBQUd4RyxPQUFPLEVBQUUsWUFBWSxFQUFxQix1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7O01BRXhELE9BQU8sR0FBRyw4QkFBOEI7OztJQUcxQyxNQUFPLFNBQVM7SUFDaEIsVUFBVyxZQUFZO0lBQ3ZCLFFBQVMsV0FBVztJQUNwQixTQUFVLFlBQVk7O0lBZWIsMEJBQTBCLFNBQTFCLDBCQUEwQjs7Ozs7OztJQWlEbkMsWUFBb0IsTUFBaUIsRUFDekIsa0JBQXdDLEVBQ3hDLElBQWdCLEVB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O1NBQ0o7S0FDSixDQUFDOzZDQWtEOEIsU0FBUztRQUNMLG9CQUFvQjtRQUNsQyxVQUFVO1FBQ0csY0FBYztHQXBEcEMsMEJBQTBCLENBK2F0QztTQS9hWSwwQkFBMEI7OztJQUVuQyxnREFBNkM7O0lBRTdDLDhDQUFvQjs7SUFDcEIsOENBQXlCOzs7OztJQUV6QixpREFBeUU7O0lBQ3pFLG1EQUEwRTs7Ozs7SUFFMUUsOENBQTRDOztJQUc1Qyw2Q0FBdUI7O0lBRXZCLHNFQVVDOztJQUdELDhDQWtCRTs7Ozs7SUFHVSw0Q0FBeUI7Ozs7O0lBQ2pDLHdEQUFnRDs7Ozs7SUFDaEQsMENBQXdCOzs7OztJQUN4Qix1REFBeUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBXQ0dyaWRFZGl0b3JDb21tYW5kc0NvbmZpZywgV0NDb25maXJtYXRpb25UaXRsZVByb3ZpZGVyLCBXQ0dyaWRFZGl0b3JDb21tYW5kQ29tcG9uZW50RXZlbnQgfSBmcm9tICd3ZWItY29uc29sZS11aS1raXQnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIE9uRGVzdHJveSwgRWxlbWVudFJlZiwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQbHVnaW5WaWV3IH0gZnJvbSAnd2ViLWNvbnNvbGUtY29yZSc7XG5pbXBvcnQgeyBOR1hMb2dnZXJ9IGZyb20gJ3dlYi1jb25zb2xlLWNvcmUnO1xuaW1wb3J0IHsgV0NOb3RpZmljYXRpb25DZW50ZXIsIE5vdGlmaWNhdGlvblR5cGUgfSBmcm9tICd3ZWItY29uc29sZS11aS1raXQnO1xuaW1wb3J0IHsgQnVuZGxlc1NlcnZpY2UsIEJ1bmRsZVN0YXR1cywgQ2x1c3RlckJ1bmRsZVN0YXR1cywgQnVuZGxlLCBCdW5kbGVVcGRhdGUgfSBmcm9tICdAd2EtbW90aWYtb3Blbi1hcGkvd2ViLWNvbnRlbnQtc2VydmljZSc7XG5pbXBvcnQgeyBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL0NvbW1vbnMvd2Mtc3Vic2NyaXB0aW9uLWhhbmRsZXInO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZmFVcGxvYWQgfSBmcm9tICdAZm9ydGF3ZXNvbWUvZnJlZS1zb2xpZC1zdmctaWNvbnMnO1xuaW1wb3J0IHsgV2ViQ29udGVudFVwZGF0ZURpYWxvZ0NvbXBvbmVudCwgVXBkYXRlRGlhbG9nUmVzdWx0IH0gZnJvbSAnLi9kaWFsb2cvd2ViY29udGVudC11cGRhdGUtZGlhbG9nJztcbmltcG9ydCB7IFdDVXBsb2FkUGFuZWxFdmVudCB9IGZyb20gJy4uLy4uLy4uL2NvbXBvbmVudHMvVUkvd2MtdXBsb2FkLXBhbmVsLWNvbXBvbmVudC93Yy11cGxvYWQtcGFuZWwtY29tcG9uZW50JztcbmltcG9ydCB7IFdDU3RhdHNJbmZvTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL1N0YXRzL3N0YXRzLWluZm8tY29tcG9uZW50JztcbmltcG9ydCB7IFVwZGF0ZVBvbGxlciwgVXBkYXRlUG9sbGVyRXZlbnQsIFVwZGF0ZVBvbGxlckV2ZW50U3RhdHVzIH0gZnJvbSAnLi91cGRhdGUtcG9sbGVyL1VwZGF0ZVBvbGxlcic7XG5pbXBvcnQgeyBCdW5kbGVVdGlscywgUHVibGlzaGluZ1N0YXR1cyB9IGZyb20gJy4vQnVuZGxlVXRpbHMnO1xuXG5jb25zdCBMT0dfVEFHID0gJ1tXZWJDb250ZW50U2VjdGlvbkNvbXBvbmVudF0nO1xuXG5lbnVtIENvbW1hbmRUeXBlIHtcbiAgICBFZGl0ID0gJ2NtZEVkaXQnLFxuICAgIERvd25sb2FkID0gJ2NtZERvd2xvYWQnLFxuICAgIERlbGV0ZSA9ICdjbWREZWxldGUnLFxuICAgIFB1Ymxpc2ggPSAnY21kUHVibGlzaCdcbn1cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnd2Etd2ViLWNvbnRlbnQtc2VjdGlvbicsXG4gICAgc3R5bGVVcmxzOiBbICcuL3dlYmNvbnRlbnQtc2VjdGlvbi1jb21wb25lbnQuc2NzcycgXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vd2ViY29udGVudC1zZWN0aW9uLWNvbXBvbmVudC5odG1sJ1xuICB9KVxuQFBsdWdpblZpZXcoJ1dlYkNvbnRlbnQnLCB7XG4gICAgaWNvbk5hbWU6ICd3YS1pY28td2ViJyxcbiAgICB1c2VyRGF0YToge1xuICAgICAgICBhY2w6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbXCJjb20udmlwZXJhLm9zZ2kuZm91bmRhdGlvbi53ZWJjb250ZW50LmFwaS5yZXN0LldlYkNvbnRlbnRBcGk6UkVBRDpnZXRCdW5kbGVzTGlzdFwiXVxuICAgICAgICB9XG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBXZWJDb250ZW50U2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIHN0YXRzTW9kZWw6IFdDU3RhdHNJbmZvTW9kZWwgPSB7IGl0ZW1zOiBbXSB9O1xuXG4gICAgZmFVcGxvYWQgPSBmYVVwbG9hZDtcbiAgICBncmlkRGF0YTogQnVuZGxlU3RhdHVzW107XG5cbiAgICBwcml2YXRlIF9zdWJIYW5kbGVyOiBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIgPSBuZXcgV0NTdWJzY3JpcHRpb25IYW5kbGVyKCk7XG4gICAgQFZpZXdDaGlsZCgndXBkYXRlRGlhbG9nJykgX3VwZGF0ZURpYWxvZzogV2ViQ29udGVudFVwZGF0ZURpYWxvZ0NvbXBvbmVudDtcblxuICAgIHByaXZhdGUgX3BvbGxlcnMgOiBBcnJheTxVcGRhdGVQb2xsZXI+ID0gW107XG5cbiAgICAvLyBEYXRhIGJpbmRpbmdcbiAgICBwdWJsaWMgbG9hZGluZyA9IGZhbHNlO1xuXG4gICAgcHVibGlzaENvbmZpcm1hdGlvblRpdGxlUHJvdmlkZXI6IFdDQ29uZmlybWF0aW9uVGl0bGVQcm92aWRlciA9IHtcbiAgICAgICAgZ2V0VGl0bGUocm93RGF0YSk6IHN0cmluZyB7XG4gICAgICAgICAgICBpZiAocm93RGF0YS5pbmZvLnN5bnRoZXRpY1N0YXR1cyA9PT0gUHVibGlzaGluZ1N0YXR1cy5QdWJsaXNoZWQpe1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlVucHVibGlzaCA/XCI7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJvd0RhdGEuaW5mby5zeW50aGV0aWNTdGF0dXMgPT09IFB1Ymxpc2hpbmdTdGF0dXMuRXJyb3Ipe1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlVucHVibGlzaCA/XCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlB1Ymxpc2ggP1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBjb21tYW5kczogV0NHcmlkRWRpdG9yQ29tbWFuZHNDb25maWcgPSBbXG4gICAgICAgIHsgXG4gICAgICAgICAgICBjb21tYW5kSWNvbjogJ3dhLWljby1lZGl0JyxcbiAgICAgICAgICAgIGNvbW1hbmRJZDogQ29tbWFuZFR5cGUuRWRpdCxcbiAgICAgICAgICAgIHRpdGxlOiAnRWRpdCdcbiAgICAgICAgfSxcbiAgICAgICAgeyBcbiAgICAgICAgICAgIGNvbW1hbmRJY29uOiAnd2EtaWNvLWRvd25sb2FkJyxcbiAgICAgICAgICAgIGNvbW1hbmRJZDogQ29tbWFuZFR5cGUuRG93bmxvYWQsXG4gICAgICAgICAgICB0aXRsZTogJ0Rvd25sb2FkJ1xuICAgICAgICB9LFxuICAgICAgICB7IFxuICAgICAgICAgICAgY29tbWFuZEljb246ICd3YS1pY28tbm8nLFxuICAgICAgICAgICAgY29tbWFuZElkOiBDb21tYW5kVHlwZS5EZWxldGUsXG4gICAgICAgICAgICB0aXRsZTogJ0RlbGV0ZScsXG4gICAgICAgICAgICBoYXNDb25maXJtYXRpb246IHRydWUsXG4gICAgICAgICAgICBjb25maXJtYXRpb25UaXRsZTogJ0RlbGV0ZSA/JyBcbiAgICAgICAgfVxuICAgIF07XG5cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbG9nZ2VyOiBOR1hMb2dnZXIsXG4gICAgICAgIHByaXZhdGUgbm90aWZpY2F0aW9uQ2VudGVyOiBXQ05vdGlmaWNhdGlvbkNlbnRlcixcbiAgICAgICAgcHJpdmF0ZSBlbGVtOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHdlYkNvbnRlbnRTZXJ2aWNlOiBCdW5kbGVzU2VydmljZSkge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdPcGVuaW5nLi4uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW5ndWxhciBuZ09uSW5pdFxuICAgICAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ0luaXRpYWxpemluZy4uLicpO1xuICAgICAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcgLCAnbmdPbkRlc3Ryb3kgJyk7XG4gICAgICAgIHRoaXMuZnJlZU1lbSgpO1xuICAgIH1cblxuICAgIGZyZWVNZW0oKSB7XG4gICAgICAgIHRoaXMuZ3JpZERhdGEgPSBudWxsO1xuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgb25SZWZyZXNoQ2xpY2tlZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoRGF0YSgpO1xuICAgIH1cblxuICAgIHVwZGF0ZU1vZGVsV2l0aChidW5kbGVTdGF0dXM6QnVuZGxlU3RhdHVzKXtcbiAgICAgICAgbGV0IGluZGV4ID0gXy5maW5kSW5kZXgodGhpcy5ncmlkRGF0YSwgKGl0ZW06QnVuZGxlU3RhdHVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIChpdGVtPT1idW5kbGVTdGF0dXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGluZGV4Pj0wKXtcbiAgICAgICAgICAgIHRoaXMuZ3JpZERhdGFbaW5kZXhdID0gYnVuZGxlU3RhdHVzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVmcmVzaERhdGEoKXtcblxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAncmVmcmVzaERhdGEgY2FsbGVkLicpO1xuXG4gICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKHRoaXMud2ViQ29udGVudFNlcnZpY2UuZ2V0QnVuZGxlc0xpc3QoKS5zdWJzY3JpYmUoIChkYXRhOiBBcnJheTxCdW5kbGVTdGF0dXM+KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnR2V0IGJ1bmRsZSBzdGF0dXNlcyByZXN1bHRzOicsIGRhdGEpO1xuXG4gICAgICAgICAgICB0aGlzLmdyaWREYXRhID0gXy5mb3JFYWNoKGRhdGEsIChlbGVtZW50OiBCdW5kbGVTdGF0dXMpID0+IHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmluZm9bXCJzeW50aGV0aWNTdGF0dXNcIl0gPSBCdW5kbGVVdGlscy5idWlsZFN5bnRoZXRpY1N0YXR1cyhlbGVtZW50KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmluZm9bXCJ1cmxcIl0gPSBCdW5kbGVVdGlscy5idWlsZFVybChlbGVtZW50KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnKioqIEdldCBidW5kbGUgc3RhdHVzZXMgcmVzdWx0cyBncmlkRGF0YTonLCB0aGlzLmdyaWREYXRhKTtcblxuICAgICAgICAgICAgdGhpcy5ncmlkRGF0YSA9IGRhdGE7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICcqKiogR2V0IGJ1bmRsZSBzdGF0dXNlcyByZXN1bHRzIGdyaWREYXRhOicsIHRoaXMuZ3JpZERhdGEpO1xuXG4gICAgICAgICAgICB0aGlzLnJlYnVpbGRTdGF0c0luZm8oKTtcbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgXG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ0dldCBidW5kbGUgc3RhdHVzZXMgZmFpbGVkOiAnLCBlcnJvcik7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJTdGF0c0luZm8oKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdHZXRCdW5kbGVTdGF0dXNlc0Vycm9yJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0dldCBCdW5kbGUgU3RhdHVzZXMnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBnZXR0aW5nIGJ1bmRsZSBzdGF0dXNlczonLFxuICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkpO1xuICAgICAgICBcbiAgICB9XG5cbiAgICBwcml2YXRlIGNsZWFyU3RhdHNJbmZvKCl7XG4gICAgICAgIHRoaXMuc3RhdHNNb2RlbCA9IHsgaXRlbXM6IFtdIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWJ1aWxkU3RhdHNJbmZvKCl7XG5cbiAgICAgICAgY29uc3Qgc3RhdHVzZXMgPSBfLm1hcCh0aGlzLmdyaWREYXRhLCAnaW5mby5zeW50aGV0aWNTdGF0dXMnKTtcblxuICAgICAgICBjb25zdCB0b3RhbCA9IHN0YXR1c2VzLmxlbmd0aDtcblxuICAgICAgICBjb25zdCBwdWJsaXNoZWQgPSBfLmNvdW50QnkoXG4gICAgICAgICAgICBzdGF0dXNlcyxcbiAgICAgICAgICAgIChzdGF0dXMpID0+IChzdGF0dXMgPT09IFwiUFVCTElTSEVEXCIpXG4gICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICBpZiAoIXB1Ymxpc2hlZCl7XG4gICAgICAgICAgICBwdWJsaXNoZWQudHJ1ZSA9IDA7XG4gICAgICAgICAgICBwdWJsaXNoZWQuZmFsc2UgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFwdWJsaXNoZWQudHJ1ZSl7XG4gICAgICAgICAgICBwdWJsaXNoZWQudHJ1ZSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXB1Ymxpc2hlZC5mYWxzZSl7XG4gICAgICAgICAgICBwdWJsaXNoZWQuZmFsc2UgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdGF0c01vZGVsID0geyBcbiAgICAgICAgICAgIGl0ZW1zOiBbXG4gICAgICAgICAgICAgICAgeyBsYWJlbDogXCJidW5kbGVzXCIsIHZhbHVlOiBcIlwiK3RvdGFsLCBjc3NDbGFzczogXCJzdGF0cy1pbmZvLXByaW1hcnlcIiB9LFxuICAgICAgICAgICAgICAgIHsgbGFiZWw6IFwicHVibGlzaGVkXCIsIHZhbHVlOiBcIlwiK3B1Ymxpc2hlZC50cnVlLCBjc3NDbGFzczpcInN0YXRzLWluZm8tb2tcIiB9LFxuICAgICAgICAgICAgICAgIHsgbGFiZWw6IFwidW5wdWJsaXNoZWRcIiwgdmFsdWU6IFwiXCIrcHVibGlzaGVkLmZhbHNlLCBjc3NDbGFzczpcInN0YXRzLWluZm8ta29cIiB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0gXG4gICAgfVxuICAgIFxuXG4gICAgZG9Ub2dnbGVQdWJsaXNoQnVuZGxlKGl0ZW06IEJ1bmRsZVN0YXR1cyk6dm9pZCB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdkb1RvZ2dsZVB1Ymxpc2hCdW5kbGU6ICcsIGl0ZW0pO1xuICAgICAgICBpZiAoaXRlbS5pbmZvW1wic3ludGhldGljU3RhdHVzXCJdID09PSBQdWJsaXNoaW5nU3RhdHVzLlVucHVibGlzaGVkKXtcbiAgICAgICAgICAgIHRoaXMuZG9QdWJsaXNoQnVuZGxlKGl0ZW0pO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uaW5mb1tcInN5bnRoZXRpY1N0YXR1c1wiXSA9PT0gUHVibGlzaGluZ1N0YXR1cy5QdWJsaXNoZWQpe1xuICAgICAgICAgICAgdGhpcy5kb1VucHVibGlzaEJ1bmRsZShpdGVtKTtcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtLmluZm9bXCJzeW50aGV0aWNTdGF0dXNcIl0gPT09IFB1Ymxpc2hpbmdTdGF0dXMuRXJyb3Ipe1xuICAgICAgICAgICAgdGhpcy5kb1VucHVibGlzaEJ1bmRsZShpdGVtKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRvUHVibGlzaEJ1bmRsZShpdGVtOiBCdW5kbGVTdGF0dXMpOnZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZG9QdWJsaXNoQnVuZGxlOiAnLCBpdGVtKTtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy53ZWJDb250ZW50U2VydmljZS5wdWJsaXNoQnVuZGxlKGl0ZW0uaW5mby5uYW1lLCBpdGVtLmluZm8udmVyc2lvbikuc3Vic2NyaWJlKCAoZGF0YSk9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdCdW5kbGUgcHVibGlzaGVkIHN1Y2Nlc3NmdWxseTogJywgZGF0YSk7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnUHVibGlzaEJ1bmRsZVN1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnUHVibGlzaGluZyBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdCdW5kbGUgcHVibGlzaCByZXF1ZXN0IHNlbnQgc3VjY2Vzc2Z1bGx5LicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5JbmZvXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gQ3JlYXRlIGFyZWZyZXNoIHBvbGxlclxuICAgICAgICAgICAgbGV0IG5ld1BvbGxlciA9IG5ldyBVcGRhdGVQb2xsZXIoaXRlbS5pbmZvLm5hbWUsIGl0ZW0uaW5mby52ZXJzaW9uLCB0aGlzLndlYkNvbnRlbnRTZXJ2aWNlLCB0aGlzLmxvZ2dlcik7XG4gICAgICAgICAgICB0aGlzLl9wb2xsZXJzLnB1c2gobmV3UG9sbGVyKTtcbiAgICAgICAgICAgIG5ld1BvbGxlci5zdGFydCgzLCAzMDAwLCBpdGVtKS5zdWJzY3JpYmUoIChyZXN1bHRzOlVwZGF0ZVBvbGxlckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMuc3RhdHVzID09PSBVcGRhdGVQb2xsZXJFdmVudFN0YXR1cy5Db21wbGV0ZSl7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTW9kZWxXaXRoKHJlc3VsdHMuYnVuZGxlU3RhdHVzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IHRlc3QgPSBfLnJlbW92ZSh0aGlzLl9wb2xsZXJzLCBmdW5jdGlvbihwb2xsZXI6IFVwZGF0ZVBvbGxlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHJlc3VsdHMuc291cmNlPT09cG9sbGVyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG5cbiAgICAgICAgfSwgKGVycm9yKT0+e1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHLCAnRG93bmxvYWQgQnVuZGxlIGZhaWxlZDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdQdWJsaXNoQnVuZGxlRXJyb3InLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnUHVibGlzaCBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBwdWJsaXNoaW5nIGJ1bmRsZTonLFxuICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkpO1xuICAgIH1cblxuICAgIGRvVW5wdWJsaXNoQnVuZGxlKGl0ZW06IEJ1bmRsZVN0YXR1cyk6dm9pZCB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdkb1VucHVibGlzaEJ1bmRsZTogJywgaXRlbSk7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKHRoaXMud2ViQ29udGVudFNlcnZpY2UudW5wdWJsaXNoQnVuZGxlKGl0ZW0uaW5mby5uYW1lLCBpdGVtLmluZm8udmVyc2lvbikuc3Vic2NyaWJlKCAoZGF0YSk9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdCdW5kbGUgdW5wdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5OiAnLCBkYXRhKTtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaERhdGEoKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdVbnB1Ymxpc2hCdW5kbGVTdWNjZXNzJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1VucHVibGlzaCBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdCdW5kbGUgdW5wdWJsaXNoZWQgc3VjY2Vzc2Z1bGx5LicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5JbmZvXG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgIH0sIChlcnJvcik9PntcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ1VucHVibGlzaCBCdW5kbGUgZmFpbGVkOiAnLCBlcnJvcik7XG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ1VucHVibGlzaEJ1bmRsZUVycm9yJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1VucHVibGlzaCBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciB1bnB1Ymxpc2hpbmcgYnVuZGxlOicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KSk7XG4gICAgfVxuXG5cbiAgICBkb0Rvd25sb2FkQnVuZGxlKGl0ZW06IEJ1bmRsZVN0YXR1cyk6dm9pZCB7XG5cbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICBuYW1lOiAnRG93bmxvYWRCdW5kbGVQcm9ncmVzcycsXG4gICAgICAgICAgICB0aXRsZTogJ0Rvd25sb2FkIEJ1bmRsZScsXG4gICAgICAgICAgICBtZXNzYWdlOiAnRG93bmxvYWRpbmcgYnVuZGxlLi4uJyxcbiAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuSW5mb1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZG9Eb3dubG9hZEJ1bmRsZTogJywgaXRlbSk7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKHRoaXMud2ViQ29udGVudFNlcnZpY2UuZG93bmxvYWRCdW5kbGUoaXRlbS5pbmZvLm5hbWUsIGl0ZW0uaW5mby52ZXJzaW9uKS5zdWJzY3JpYmUoIChkYXRhIDpCbG9iKT0+IHtcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ0J1bmRsZSBkb3dubG9hZGVkIHN1Y2Nlc3NmdWxseTogJywgZGF0YSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbZGF0YV0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL3ppcCcgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gaXRlbS5pbmZvLm5hbWUgKyAnXycgKyBpdGVtLmluZm8udmVyc2lvbiArICcuemlwJztcbiAgICAgICAgICAgIHNhdmVBcyhibG9iLCBmaWxlTmFtZSk7XG4gICAgICAgICAgICAvLyBGaWxlU2F2ZXIuc2F2ZUFzKGJsb2IsIGZpbGVOYW1lKTtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdCdW5kbGUgc2F2ZWQ6ICcsIGZpbGVOYW1lKTtcblxuXG4gICAgICAgIH0sIChlcnJvcik9PntcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ0Rvd25sb2FkIEJ1bmRsZSBmYWlsZWQ6ICcsIGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnRG93bmxvYWRCdW5kbGVFcnJvcicsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdEb3dubG9hZCBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBkb3dubG9hZGluZyBidW5kbGU6JyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkVycm9yLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBkb0RlbGV0ZUJ1bmRsZShpdGVtOiBCdW5kbGVTdGF0dXMpOnZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZG9EZWxldGVCdW5kbGU6ICcsIGl0ZW0pO1xuICAgICAgICBsZXQgYnVuZGxlTmFtZSA9IGl0ZW0uaW5mby5uYW1lO1xuICAgICAgICBsZXQgYnVuZGxlVmVyc2lvbiA9IGl0ZW0uaW5mby52ZXJzaW9uO1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCBcImRvRGVsZXRlQnVuZGxlIGJ1bmRsZU5hbWU9J1wiK2J1bmRsZU5hbWUrXCInIGJ1bmRsZVZlcnNpb249J1wiICsgYnVuZGxlVmVyc2lvbiArIFwiJ1wiKTtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy53ZWJDb250ZW50U2VydmljZS5kZWxldGVCdW5kbGUoYnVuZGxlTmFtZSwgYnVuZGxlVmVyc2lvbikuc3Vic2NyaWJlKCAoZGF0YSkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnRGVsZXRlIEJ1bmRsZSBzdWNjZXNzOiAnLCBkYXRhKTtcbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdEZWxldGVCdW5kbGVTdWNjZXNzJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0RlbGV0ZSBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdCdW5kbGUgZGVsZXRlZCBzdWNjZXNzZnVsbHkuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkluZm9cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG5cbiAgICAgICAgfSwgKGVycm9yKSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdEZWxldGUgQnVuZGxlIGZhaWxlZDogJywgZXJyb3IpO1xuXG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnRGVsZXRlQnVuZGxlRXJyb3InLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnRGVsZXRlIEJ1bmRsZScsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0Vycm9yIGRlbGV0aW5nIGJ1bmRsZTonLFxuICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KSkgOyAgICAgIFxuICAgIH1cblxuICAgIG9uQ29tbWFuZENvbmZpcm0oZXZlbnQ6IFdDR3JpZEVkaXRvckNvbW1hbmRDb21wb25lbnRFdmVudCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnb25Db21tYW5kQ29uZmlybSBldmVudDogJywgZXZlbnQpO1xuICAgICAgICBpZiAoZXZlbnQuaWQ9PT1Db21tYW5kVHlwZS5QdWJsaXNoKXtcbiAgICAgICAgICAgIHRoaXMuZG9Ub2dnbGVQdWJsaXNoQnVuZGxlKGV2ZW50LnJvd0RhdGEuZGF0YUl0ZW0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LmlkPT09Q29tbWFuZFR5cGUuRGVsZXRlKXtcbiAgICAgICAgICAgIHRoaXMuZG9EZWxldGVCdW5kbGUoZXZlbnQucm93RGF0YS5kYXRhSXRlbSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkNvbW1hbmRDbGljayhldmVudDogV0NHcmlkRWRpdG9yQ29tbWFuZENvbXBvbmVudEV2ZW50KXtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ29uQ29tbWFuZENsaWNrIGV2ZW50OiAnLCBldmVudCk7XG4gICAgICAgIGlmIChldmVudC5pZD09PUNvbW1hbmRUeXBlLkRvd25sb2FkKXtcbiAgICAgICAgICAgIHRoaXMuZG9Eb3dubG9hZEJ1bmRsZShldmVudC5yb3dEYXRhLmRhdGFJdGVtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5pZD09PUNvbW1hbmRUeXBlLkRlbGV0ZSl7XG4gICAgICAgICAgICB0aGlzLmRvRGVsZXRlQnVuZGxlKGV2ZW50LnJvd0RhdGEuZGF0YUl0ZW0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmlkPT09Q29tbWFuZFR5cGUuRWRpdCl7XG4gICAgICAgICAgICB0aGlzLmRvRWRpdEJ1bmRsZShldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkb0VkaXRCdW5kbGUoZXZlbnQ6IFdDR3JpZEVkaXRvckNvbW1hbmRDb21wb25lbnRFdmVudCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZG9FZGl0QnVuZGxlIDogJywgZXZlbnQpO1xuICAgICAgICB0aGlzLl91cGRhdGVEaWFsb2cuc2hvdyhldmVudC5yb3dEYXRhLmRhdGFJdGVtLmluZm8ubmFtZSwgZXZlbnQucm93RGF0YS5kYXRhSXRlbS5pbmZvLnZlcnNpb24sIGV2ZW50LnJvd0RhdGEuZGF0YUl0ZW0uaW5mby5kb21haW4sIGV2ZW50LnJvd0RhdGEuZGF0YUl0ZW0uaW5mby5hcHBsaWNhdGlvbiwgZXZlbnQucm93RGF0YS5kYXRhSXRlbS5pbmZvLmNvbnRleHQpO1xuICAgIH1cblxuICAgIG9uVXBsb2FkRXJyb3IoZXJyb3Ipe1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgIG5hbWU6ICdVcGxvYWRCdW5kbGVFcnJvcicsXG4gICAgICAgICAgICB0aXRsZTogJ1VwbG9hZCBCdW5kbGUnLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0Vycm9yIHVwbG9hZGluZyBidW5kbGU6JyxcbiAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9XG5cblxuICAgIHVwbG9hZEFzc2V0QnVuZGxlKGV2ZW50OiBXQ1VwbG9hZFBhbmVsRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ3VwbG9hZEFzc2V0QnVuZGxlIDogJywgZXZlbnQpO1xuXG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgbmFtZTogJ1VwbG9hZEFzc2V0QnVuZGxlUHJvZ3Jlc3MnLFxuICAgICAgICAgICAgdGl0bGU6ICdVcGxvYWQgQXNzZXQgQnVuZGxlJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdVcGxvYWRpbmcgdGhlIGFzc2V0IGJ1bmRsZS4uLicsXG4gICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkluZm9cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy53ZWJDb250ZW50U2VydmljZS51cGxvYWRCdW5kbGUoZXZlbnQuZmlsZSkuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoRGF0YSgpO1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ0J1bmRsZSB1cGxvYWRlZCBzdWNjZXNzZnVsbHk6ICcsIGV2ZW50KTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ1VwbG9hZEJ1bmRsZVN1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnVXBsb2FkIEJ1bmRsZScsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBidW5kbGUgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVwbG9hZGVkLicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdFcnJvciB1cGxvYWRpbmcgYnVuZGxlOiAnLCBlcnJvcik7XG5cbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdVcGxvYWRCdW5kbGVFcnJvcicsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdVcGxvYWQgQnVuZGxlJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgdXBsb2FkaW5nIGJ1bmRsZTonLFxuICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkpO1xuICAgIH1cblxuICAgIG9uVXBkYXRlQ29uZmlybShldmVudDpVcGRhdGVEaWFsb2dSZXN1bHQpe1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnb25VcGRhdGVDb25maXJtOiAnLCBldmVudCk7XG4gICAgICAgIGNvbnN0IGJ1bmRsZU5hbWUgPSBldmVudC5idW5kbGVOYW1lO1xuICAgICAgICBjb25zdCBidW5kbGVWZXJzaW9uID0gZXZlbnQuYnVuZGxlVmVyc2lvbjtcbiAgICAgICAgY29uc3QgYnVuZGxlVXBkYXRlOiBCdW5kbGVVcGRhdGUgPSB7XG4gICAgICAgICAgICBhcHBsaWNhdGlvbjogZXZlbnQuYXBwbGljYXRpb24sXG4gICAgICAgICAgICBjb250ZXh0OiBldmVudC5jb250ZXh0LFxuICAgICAgICAgICAgZG9tYWluOiBldmVudC5kb21haW5cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ29uVXBkYXRlQ29uZmlybTogJywgYnVuZGxlTmFtZSwgYnVuZGxlVmVyc2lvbiwgYnVuZGxlVXBkYXRlKTtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy53ZWJDb250ZW50U2VydmljZS51cGRhdGVCdW5kbGUoYnVuZGxlTmFtZSwgYnVuZGxlVmVyc2lvbiwgYnVuZGxlVXBkYXRlKS5zdWJzY3JpYmUoIChkYXRhKSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMucmVmcmVzaERhdGEoKTtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdCdW5kbGUgdXBkYXRlZCBzdWNjZXNzZnVsbHk6ICcsIGV2ZW50KTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ1VwZGF0ZUJ1bmRsZVN1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnVXBkYXRlIEJ1bmRsZScsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBidW5kbGUgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcbiAgICAgICAgICAgIH0pO1xuXG5cbiAgICAgICAgfSwgKGVycm9yKSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdFcnJvciB1cGRhdGluZyBidW5kbGU6ICcsIGVycm9yKTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ1VwZGF0ZUJ1bmRsZUVycm9yJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1VwZGF0ZSBCdW5kbGUnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciB1cGRhdGluZyBidW5kbGU6JyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkVycm9yLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSkpO1xuICAgIH1cblxufVxuIl19