Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

vipera-npm-registry / motif-web-admin-core   js

Repository URL to install this package:

Version: 0.3.1 

/ esm2015 / lib / sections / RESTManager / components / rest-manager-section-component.js

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import * as tslib_1 from "tslib";
import { Component, ViewChild, Input } from '@angular/core';
import { PluginView } from 'web-console-core';
import { NGXLogger } from 'web-console-core';
import { RESTCatalogComponent, GridCommandType } from './rest-catalog-component/rest-catalog-component';
import { RESTCatalogEditorComponent } from './rest-catalog-editor/rest-catalog-editor-component';
import { RESTContextDialogComponent, DialogMode } from './dialogs/new-context-dialog/rest-context-dialog-component';
import { WCSubscriptionHandler } from '../../../components/Commons/wc-subscription-handler';
import { WCNotificationCenter, NotificationType } from 'web-console-ui-kit';
import { RESTContextCatalogService } from '../../../services/RESTContextCatalogService';
/** @type {?} */
const LOG_TAG = '[RESTManagerSectionComponent]';
let RESTManagerSectionComponent = class RESTManagerSectionComponent {
    /**
     * @param {?} logger
     * @param {?} restCatalogService
     * @param {?} notificationCenter
     */
    constructor(logger, restCatalogService, notificationCenter) {
        this.logger = logger;
        this.restCatalogService = restCatalogService;
        this.notificationCenter = notificationCenter;
        // combo box selection
        this._subHandler = new WCSubscriptionHandler();
        this.statsModel = { items: [] };
        this.logger.debug(LOG_TAG, 'Opening...');
    }
    /**
     * Angular ngOnInit
     * @return {?}
     */
    ngOnInit() {
        this.logger.debug(LOG_TAG, 'Initializing...');
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this.logger.debug(LOG_TAG, 'ngOnDestroy ');
        this.freeMem();
    }
    /**
     * @return {?}
     */
    freeMem() {
        this.selectedDomain = null;
        this._selectedApplication = null;
    }
    /**
     * @return {?}
     */
    onRefreshClicked() {
        this.refreshCatalog();
    }
    /**
     * @private
     * @return {?}
     */
    clearStatsInfo() {
        this.statsModel = { items: [] };
    }
    /**
     * @private
     * @return {?}
     */
    refreshCatalog() {
        /** @type {?} */
        let domain = (this.selectedDomain ? this.selectedDomain.name : null);
        /** @type {?} */
        let application = (this._selectedApplication ? this._selectedApplication.name : null);
        this.restCatalogSelector.reloadData(domain, application);
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onDomainSelectionClear(event) {
        this.selectedDomain = null;
        //this.selectedApplication = null;
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onApplicationSelectionClear(event) {
        this.selectedApplication = null;
    }
    /**
     * Set the selcted application
     * @param {?} application
     * @return {?}
     */
    set selectedApplication(application) {
        this._selectedApplication = application;
        this.refreshCatalog();
    }
    /**
     * @return {?}
     */
    get selectedApplication() {
        return this._selectedApplication;
    }
    /**
     * @private
     * @return {?}
     */
    rebuildStatsInfo() {
        /** @type {?} */
        const totalContexts = this.restCatalogSelector.tableModel.getContextsCount();
        /** @type {?} */
        const enabledContexts = this.restCatalogSelector.tableModel.getEnabledContextsCount();
        /** @type {?} */
        const disabledContexts = this.restCatalogSelector.tableModel.getDisabledContextsCount();
        this.statsModel = {
            items: [
                { label: "active", value: "" + totalContexts, cssClass: "stats-info-primary" },
                { label: "enabled", value: "" + enabledContexts, cssClass: "stats-info-ok" },
                { label: "disabled", value: "" + disabledContexts, cssClass: "stats-info-ko" }
            ]
        };
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onCatalogDataReload(event) {
        this.restCatalogEditor.clear();
        this.rebuildStatsInfo();
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onCatalogDataReloadError(event) {
        this.logger.error(LOG_TAG, 'onCatalogDataReloadError error:', event);
        this.clearStatsInfo();
        this.notificationCenter.post({
            name: 'LoadRESTContextError',
            title: 'REST Context Load',
            message: 'Error loading REST contexts:',
            type: NotificationType.Error,
            error: event.error,
            closable: true
        });
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onChangesSaved(event) {
        this.logger.debug(LOG_TAG, 'onChangesSaved: ', event);
        //TODO!!
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onFilterChange(event) {
        this.logger.debug(LOG_TAG, 'onFilterChange called');
        this.restCatalogSelector.setFilter(event.srcElement['value']);
    }
    /**
     * @param {?} nodeEvent
     * @return {?}
     */
    nodeSelect(nodeEvent) {
        this.logger.debug(LOG_TAG, 'nodeSelect ', nodeEvent);
        this.restCatalogEditor.startEdit(nodeEvent.node);
        /*
        this.updateCommands(nodeType);
        */
    }
    /**
     * @return {?}
     */
    onAddRESTContextPressed() {
        if (this.canAddNewContext) {
            this.contextEditDialog.showForNew(this.selectedDomain.name, this.selectedApplication.name);
        }
    }
    /**
     * @return {?}
     */
    get canAddNewContext() {
        return (this.selectedDomain != null && this.selectedApplication != null);
    }
    /**
     * @param {?} event
     * @return {?}
     */
    doCreateRESTContext(event) {
        this._subHandler.add(this.restCatalogService.createRESTContext(event.domain, event.application, event.name, event.url).subscribe((/**
         * @param {?} results
         * @return {?}
         */
        (results) => {
            this.logger.info(LOG_TAG, 'REST context created:', results);
            this.notificationCenter.post({
                name: 'CreateRESTContext',
                title: 'REST Context Create',
                message: 'REST Context created successfully.',
                type: NotificationType.Success
            });
            this.refreshCatalog();
        }), (/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.logger.error(LOG_TAG, 'Creating REST Context error:', error);
            this.notificationCenter.post({
                name: 'CreateRESTContextError',
                title: 'REST Context Create',
                message: 'Error creating REST context:',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    }
    /**
     * @param {?} event
     * @return {?}
     */
    doUpdateRESTContext(event) {
        this._subHandler.add(this.restCatalogService.updateRESTContext(event.domain, event.application, event.name, event.url).subscribe((/**
         * @param {?} results
         * @return {?}
         */
        (results) => {
            this.logger.info(LOG_TAG, 'REST context updated:', results);
            this.notificationCenter.post({
                name: 'UpdateRESTContext',
                title: 'REST Context Update',
                message: 'REST Context updated successfully.',
                type: NotificationType.Success
            });
            this.refreshCatalog();
        }), (/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.logger.error(LOG_TAG, 'Update REST Context error:', error);
            this.notificationCenter.post({
                name: 'UpdateRESTContextError',
                title: 'REST Context Update',
                message: 'Error updating REST context:',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    }
    /**
     * @param {?} domain
     * @param {?} application
     * @param {?} contextName
     * @param {?} url
     * @param {?} enabled
     * @return {?}
     */
    doToggleContextStatus(domain, application, contextName, url, enabled) {
        this.logger.debug(LOG_TAG, 'doToggleContextStatus : ', domain, application, contextName, url, enabled);
        this._subHandler.add(this.restCatalogService.enableRESTContext(domain, application, contextName, enabled).subscribe((/**
         * @param {?} result
         * @return {?}
         */
        (result) => {
            this.logger.info(LOG_TAG, 'REST context status change:', result);
            this.notificationCenter.post({
                name: 'ChangeStatusRESTContext',
                title: 'Change REST Context Status',
                message: 'REST Context status changed successfully.',
                type: NotificationType.Success
            });
            this.refreshCatalog();
        }), (/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.logger.error(LOG_TAG, 'Changin REST Context status error:', error);
            this.notificationCenter.post({
                name: 'ChangeStatusRESTContextError',
                title: 'Change REST Context Status',
                message: 'Error changing REST context status: ',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    }
    /**
     * @param {?} domain
     * @param {?} application
     * @param {?} contextName
     * @return {?}
     */
    doDeleteContext(domain, application, contextName) {
        this.logger.debug(LOG_TAG, 'deleteContext : ', domain, application, contextName);
        this._subHandler.add(this.restCatalogService.deleteRESTContext(domain, application, contextName).subscribe((/**
         * @param {?} result
         * @return {?}
         */
        (result) => {
            this.logger.info(LOG_TAG, 'REST context deleted:', result);
            this.notificationCenter.post({
                name: 'DeleteRESTContext',
                title: 'Delete REST Context',
                message: 'REST Context deleted successfully.',
                type: NotificationType.Success
            });
            this.refreshCatalog();
        }), (/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.logger.error(LOG_TAG, 'Deleting REST Context error:', error);
            this.notificationCenter.post({
                name: 'DeleteRESTContextError',
                title: 'Delete REST Context',
                message: 'Error deleting REST context:',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    }
    /**
     * @param {?} event
     * @return {?}
     */
    onDialogConfirmation(event) {
        if (event.dialogMode === DialogMode.New) {
            this.doCreateRESTContext(event);
        }
        else if (event.dialogMode === DialogMode.Edit) {
            this.doUpdateRESTContext(event);
        }
    }
    /**
     * @param {?} command
     * @return {?}
     */
    onNodeCommand(command) {
        this.logger.error(LOG_TAG, 'onNodeCommand:', command);
        if (command.command === GridCommandType.Delete) {
            this.doDeleteContext(command.node.domain, command.node.application, command.node.name);
        }
        else if (command.command === GridCommandType.Edit) {
            this.contextEditDialog.showForEdit(command.node.domain, command.node.application, command.node.name, command.node.url, command.node["enabled"]);
        }
        else if (command.command === GridCommandType.PublishToggle) {
            this.doToggleContextStatus(command.node.domain, command.node.application, command.node.name, command.node.url, !command.node["enabled"]);
        }
    }
};
RESTManagerSectionComponent.decorators = [
    { type: Component, args: [{
                selector: 'wa-rest-manager-section',
                template: "<wc-dashboard-header [title]=\"'REST Channel Manager'\"></wc-dashboard-header>\n<wc-stats-info-component [model]=\"statsModel\"></wc-stats-info-component>\n\n<wa-rest-context-dialog #contextEditDialog (confirm)=\"onDialogConfirmation($event)\"></wa-rest-context-dialog>\n\n\n<div class=\"row spread\" #target>\n  <div class=\"flex-toolbar\" style=\"display:flex;align-items: center;\">\n\n    <div style=\"margin-right:10px;width:60%;max-width: 400px;min-width: 250px;\">\n      <label>Domain</label>\n      <wc-domain-selector-combobox #domainSelector [(ngModel)]=\"selectedDomain\" (selectionCancelled)=\"onDomainSelectionClear($event)\"></wc-domain-selector-combobox>\n    </div>\n\n    <div style=\"margin-left: 40px;margin-right:10px;width:60%;max-width: 400px;min-width: 250px;\">\n      <label>Application</label>\n      <wc-application-selector-combobox #applicationSelector [domain]=\"(selectedDomain ? selectedDomain.name : null)\" [(ngModel)]=\"selectedApplication\" (selectionCancelled)=\"onApplicationSelectionClear($event)\"></wc-application-selector-combobox>\n    </div>\n\n    <kendo-textbox-container floatingLabel=\"Filter\">\n      <input\n        #filterInput\n        kendoTextBox\n        (afterValueChanged)=\"onFilterChange($event)\"\n      />\n    </kendo-textbox-container>\n\n\n    <div>\n      <label>&nbsp;</label>\n      <kendo-buttongroup look=\"flat\">\n        <button\n          motif-acl=\"com.vipera.osgi.foundation.restcontent.api.rest.RestContentApi:CREATE:createContext\" \n          kendoButton\n          [toggleable]=\"false\"\n          [icon]=\"'globe-outline'\"\n          (click)=\"onAddRESTContextPressed()\"\n          [disabled]=\"!canAddNewContext\"\n        >\n          Create New Context\n        </button>\n      </kendo-buttongroup>\n    </div>\n\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\n</div>\n\n<div class=\"row fill\">\n  <kendo-splitter>\n    <kendo-splitter-pane style=\"overflow: hidden;\">\n      <div style=\"height: 100%;\">\n        <wa-rest-catalog-component (nodeCommand)=\"onNodeCommand($event)\"\n          (nodeSelection)=\"nodeSelect($event)\"\n          (dataReload)=\"onCatalogDataReload($event)\"\n          (dataReloadError)=\"onCatalogDataReloadError($event)\"\n          #restCatalogSelector\n        ></wa-rest-catalog-component>\n      </div>\n    </kendo-splitter-pane>\n\n    <kendo-splitter-pane [collapsible]=\"true\" size=\"30%\">\n      <wa-rest-catalog-editor-component\n        #restCatalogEditor\n        (changesSaved)=\"onChangesSaved($event)\"\n      ></wa-rest-catalog-editor-component>\n    </kendo-splitter-pane>\n  </kendo-splitter>\n</div>\n",
                styles: [":host{display:flex;flex:1;flex-direction:column}"]
            }] }
];
/** @nocollapse */
RESTManagerSectionComponent.ctorParameters = () => [
    { type: NGXLogger },
    { type: RESTContextCatalogService },
    { type: WCNotificationCenter }
];
RESTManagerSectionComponent.propDecorators = {
    restCatalogSelector: [{ type: ViewChild, args: ['restCatalogSelector',] }],
    restCatalogEditor: [{ type: ViewChild, args: ['restCatalogEditor',] }],
    contextEditDialog: [{ type: ViewChild, args: ['contextEditDialog',] }],
    selectedDomain: [{ type: Input }],
    selectedApplication: [{ type: Input }]
};
RESTManagerSectionComponent = tslib_1.__decorate([
    PluginView('REST Channel', {
        iconName: 'wa-ico-services',
        userData: {
            acl: {
                permissions: ["com.vipera.osgi.core.platform.api.rest.PlatformApi:READ:getDomains",
                    "com.vipera.osgi.core.platform.api.rest.PlatformApi:READ:getApplications",
                    "com.vipera.osgi.foundation.restcontent.api.rest.RestContentApi:READ:getContexts",
                    "com.vipera.osgi.foundation.restcontent.api.rest.RestContentApi:READ:getSupportedAttributes",
                    "com.vipera.osgi.foundation.restcontent.api.rest.RestContentApi:READ:getContext"]
            }
        }
    }),
    tslib_1.__metadata("design:paramtypes", [NGXLogger,
        RESTContextCatalogService,
        WCNotificationCenter])
], RESTManagerSectionComponent);
export { RESTManagerSectionComponent };
if (false) {
    /** @type {?} */
    RESTManagerSectionComponent.prototype.restCatalogSelector;
    /** @type {?} */
    RESTManagerSectionComponent.prototype.restCatalogEditor;
    /** @type {?} */
    RESTManagerSectionComponent.prototype.contextEditDialog;
    /** @type {?} */
    RESTManagerSectionComponent.prototype.selectedDomain;
    /** @type {?} */
    RESTManagerSectionComponent.prototype._selectedApplication;
    /**
     * @type {?}
     * @private
     */
    RESTManagerSectionComponent.prototype._subHandler;
    /** @type {?} */
    RESTManagerSectionComponent.prototype.statsModel;
    /**
     * @type {?}
     * @private
     */
    RESTManagerSectionComponent.prototype.logger;
    /**
     * @type {?}
     * @private
     */
    RESTManagerSectionComponent.prototype.restCatalogService;
    /**
     * @type {?}
     * @private
     */
    RESTManagerSectionComponent.prototype.notificationCenter;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1tYW5hZ2VyLXNlY3Rpb24tY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbW90aWYtd2ViLWFkbWluLWNvcmUvIiwic291cmNlcyI6WyJsaWIvc2VjdGlvbnMvUkVTVE1hbmFnZXIvY29tcG9uZW50cy9yZXN0LW1hbmFnZXItc2VjdGlvbi1jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBMkMsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0MsT0FBTyxFQUFFLG9CQUFvQixFQUFpQyxlQUFlLEVBQTBELE1BQU0saURBQWlELENBQUM7QUFDL0wsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDakcsT0FBTyxFQUFFLDBCQUEwQixFQUEyQixVQUFVLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUM3SSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUM1RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1RSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7TUFFbEYsT0FBTyxHQUFHLCtCQUErQjtJQW1CbEMsMkJBQTJCLFNBQTNCLDJCQUEyQjs7Ozs7O0lBYXBDLFlBQW9CLE1BQWlCLEVBQ3pCLGtCQUE2QyxFQUM3QyxrQkFBd0M7UUFGaEMsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUN6Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQTJCO1FBQzdDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBc0I7O1FBTjVDLGdCQUFXLEdBQXlCLElBQUkscUJBQXFCLEVBQUUsQ0FBQztRQUV4RSxl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IHsgRG9tYWluLCBBcHBsaWNhdGlvbiB9IGZyb20gJ0B3YS1tb3RpZi1vcGVuLWFwaS9wbGF0Zm9ybS1zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQsIENoYW5nZURldGVjdG9yUmVmLCBSZW5kZXJlcjIsIE9uRGVzdHJveSwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFBsdWdpblZpZXcgfSBmcm9tICd3ZWItY29uc29sZS1jb3JlJztcbmltcG9ydCB7IE5HWExvZ2dlciB9IGZyb20gJ3dlYi1jb25zb2xlLWNvcmUnO1xuaW1wb3J0IHsgUkVTVENhdGFsb2dDb21wb25lbnQsIFJFU1RDYXRhbG9nTm9kZVNlbGVjdGlvbkV2ZW50LCBHcmlkQ29tbWFuZFR5cGUsIFJFU1RDYXRhbG9nTm9kZUNvbW1hbmRFdmVudCwgUkVTVENhdGFsb2dEYXRhRXJyb3JFdmVudCB9IGZyb20gJy4vcmVzdC1jYXRhbG9nLWNvbXBvbmVudC9yZXN0LWNhdGFsb2ctY29tcG9uZW50JztcbmltcG9ydCB7IFJFU1RDYXRhbG9nRWRpdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9yZXN0LWNhdGFsb2ctZWRpdG9yL3Jlc3QtY2F0YWxvZy1lZGl0b3ItY29tcG9uZW50JztcbmltcG9ydCB7IFJFU1RDb250ZXh0RGlhbG9nQ29tcG9uZW50LCBSRVNUQ29udGV4dERpYWxvZ1Jlc3VsdCwgRGlhbG9nTW9kZSB9IGZyb20gJy4vZGlhbG9ncy9uZXctY29udGV4dC1kaWFsb2cvcmVzdC1jb250ZXh0LWRpYWxvZy1jb21wb25lbnQnO1xuaW1wb3J0IHsgV0NTdWJzY3JpcHRpb25IYW5kbGVyIH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9Db21tb25zL3djLXN1YnNjcmlwdGlvbi1oYW5kbGVyJztcbmltcG9ydCB7IFdDTm90aWZpY2F0aW9uQ2VudGVyLCBOb3RpZmljYXRpb25UeXBlIH0gZnJvbSAnd2ViLWNvbnNvbGUtdWkta2l0JztcbmltcG9ydCB7IFdDU3RhdHNJbmZvTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL1N0YXRzL3N0YXRzLWluZm8tY29tcG9uZW50JztcbmltcG9ydCB7IFJFU1RDb250ZXh0Q2F0YWxvZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9SRVNUQ29udGV4dENhdGFsb2dTZXJ2aWNlJztcblxuY29uc3QgTE9HX1RBRyA9ICdbUkVTVE1hbmFnZXJTZWN0aW9uQ29tcG9uZW50XSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnd2EtcmVzdC1tYW5hZ2VyLXNlY3Rpb24nLFxuICAgIHN0eWxlVXJsczogWycuL3Jlc3QtbWFuYWdlci1zZWN0aW9uLWNvbXBvbmVudC5zY3NzJ10sXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Jlc3QtbWFuYWdlci1zZWN0aW9uLWNvbXBvbmVudC5odG1sJ1xufSlcbkBQbHVnaW5WaWV3KCdSRVNUIENoYW5uZWwnLCB7XG4gICAgaWNvbk5hbWU6ICd3YS1pY28tc2VydmljZXMnLFxuICAgIHVzZXJEYXRhOiB7XG4gICAgICAgIGFjbDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFtcImNvbS52aXBlcmEub3NnaS5jb3JlLnBsYXRmb3JtLmFwaS5yZXN0LlBsYXRmb3JtQXBpOlJFQUQ6Z2V0RG9tYWluc1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29tLnZpcGVyYS5vc2dpLmNvcmUucGxhdGZvcm0uYXBpLnJlc3QuUGxhdGZvcm1BcGk6UkVBRDpnZXRBcHBsaWNhdGlvbnNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbS52aXBlcmEub3NnaS5mb3VuZGF0aW9uLnJlc3Rjb250ZW50LmFwaS5yZXN0LlJlc3RDb250ZW50QXBpOlJFQUQ6Z2V0Q29udGV4dHNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbS52aXBlcmEub3NnaS5mb3VuZGF0aW9uLnJlc3Rjb250ZW50LmFwaS5yZXN0LlJlc3RDb250ZW50QXBpOlJFQUQ6Z2V0U3VwcG9ydGVkQXR0cmlidXRlc1wiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29tLnZpcGVyYS5vc2dpLmZvdW5kYXRpb24ucmVzdGNvbnRlbnQuYXBpLnJlc3QuUmVzdENvbnRlbnRBcGk6UkVBRDpnZXRDb250ZXh0XCJdXG4gICAgICAgIH1cbiAgICB9XG59KVxuZXhwb3J0IGNsYXNzIFJFU1RNYW5hZ2VyU2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIEBWaWV3Q2hpbGQoJ3Jlc3RDYXRhbG9nU2VsZWN0b3InKSByZXN0Q2F0YWxvZ1NlbGVjdG9yOiBSRVNUQ2F0YWxvZ0NvbXBvbmVudDtcbiAgICBAVmlld0NoaWxkKCdyZXN0Q2F0YWxvZ0VkaXRvcicpIHJlc3RDYXRhbG9nRWRpdG9yOiBSRVNUQ2F0YWxvZ0VkaXRvckNvbXBvbmVudDtcbiAgICBAVmlld0NoaWxkKCdjb250ZXh0RWRpdERpYWxvZycpIGNvbnRleHRFZGl0RGlhbG9nOiBSRVNUQ29udGV4dERpYWxvZ0NvbXBvbmVudDtcblxuICAgIEBJbnB1dCgpIHB1YmxpYyBzZWxlY3RlZERvbWFpbjogRG9tYWluO1xuICAgIHB1YmxpYyBfc2VsZWN0ZWRBcHBsaWNhdGlvbjogQXBwbGljYXRpb247IC8vIGNvbWJvIGJveCBzZWxlY3Rpb25cblxuICAgIHByaXZhdGUgX3N1YkhhbmRsZXI6IFdDU3Vic2NyaXB0aW9uSGFuZGxlcj0gbmV3IFdDU3Vic2NyaXB0aW9uSGFuZGxlcigpO1xuXG4gICAgc3RhdHNNb2RlbDogV0NTdGF0c0luZm9Nb2RlbCA9IHsgaXRlbXM6IFtdIH07XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogTkdYTG9nZ2VyLFxuICAgICAgICBwcml2YXRlIHJlc3RDYXRhbG9nU2VydmljZTogUkVTVENvbnRleHRDYXRhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBub3RpZmljYXRpb25DZW50ZXI6IFdDTm90aWZpY2F0aW9uQ2VudGVyXG4gICAgICAgICkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnT3BlbmluZy4uLicpO1xuXG4gICAgfSBcblxuICAgIC8qKlxuICAgICAqIEFuZ3VsYXIgbmdPbkluaXRcbiAgICAgKi9cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ0luaXRpYWxpemluZy4uLicpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ25nT25EZXN0cm95ICcpO1xuICAgICAgICB0aGlzLmZyZWVNZW0oKTtcbiAgICB9XG5cbiAgICBmcmVlTWVtKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRG9tYWluID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRBcHBsaWNhdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgb25SZWZyZXNoQ2xpY2tlZCgpe1xuICAgICAgICB0aGlzLnJlZnJlc2hDYXRhbG9nKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclN0YXRzSW5mbygpe1xuICAgICAgICB0aGlzLnN0YXRzTW9kZWwgPSB7IGl0ZW1zOiBbXSB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVmcmVzaENhdGFsb2coKXtcbiAgICAgICAgbGV0IGRvbWFpbiA9ICh0aGlzLnNlbGVjdGVkRG9tYWluP3RoaXMuc2VsZWN0ZWREb21haW4ubmFtZTpudWxsKTtcbiAgICAgICAgbGV0IGFwcGxpY2F0aW9uID0gKHRoaXMuX3NlbGVjdGVkQXBwbGljYXRpb24/dGhpcy5fc2VsZWN0ZWRBcHBsaWNhdGlvbi5uYW1lOm51bGwpO1xuICAgICAgICB0aGlzLnJlc3RDYXRhbG9nU2VsZWN0b3IucmVsb2FkRGF0YShkb21haW4sIGFwcGxpY2F0aW9uKTtcbiAgICB9XG4gICAgXG4gICAgb25Eb21haW5TZWxlY3Rpb25DbGVhcihldmVudCl7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWREb21haW4gPSBudWxsO1xuICAgICAgICAvL3RoaXMuc2VsZWN0ZWRBcHBsaWNhdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgb25BcHBsaWNhdGlvblNlbGVjdGlvbkNsZWFyKGV2ZW50KXtcbiAgICAgICAgdGhpcy5zZWxlY3RlZEFwcGxpY2F0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgIC8qKlxuICAgICogU2V0IHRoZSBzZWxjdGVkIGFwcGxpY2F0aW9uXG4gICAgKi9cbiAgIEBJbnB1dCgpXG4gICBwdWJsaWMgc2V0IHNlbGVjdGVkQXBwbGljYXRpb24oYXBwbGljYXRpb246IEFwcGxpY2F0aW9uKSB7XG4gICAgICAgdGhpcy5fc2VsZWN0ZWRBcHBsaWNhdGlvbiA9IGFwcGxpY2F0aW9uO1xuICAgICAgIHRoaXMucmVmcmVzaENhdGFsb2coKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGVkQXBwbGljYXRpb24oKTpBcHBsaWNhdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZEFwcGxpY2F0aW9uO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVidWlsZFN0YXRzSW5mbygpe1xuICAgICAgICBjb25zdCB0b3RhbENvbnRleHRzID0gdGhpcy5yZXN0Q2F0YWxvZ1NlbGVjdG9yLnRhYmxlTW9kZWwuZ2V0Q29udGV4dHNDb3VudCgpO1xuICAgICAgICBjb25zdCBlbmFibGVkQ29udGV4dHMgPSB0aGlzLnJlc3RDYXRhbG9nU2VsZWN0b3IudGFibGVNb2RlbC5nZXRFbmFibGVkQ29udGV4dHNDb3VudCgpO1xuICAgICAgICBjb25zdCBkaXNhYmxlZENvbnRleHRzID0gdGhpcy5yZXN0Q2F0YWxvZ1NlbGVjdG9yLnRhYmxlTW9kZWwuZ2V0RGlzYWJsZWRDb250ZXh0c0NvdW50KCk7XG4gICAgICAgIHRoaXMuc3RhdHNNb2RlbCA9IHsgXG4gICAgICAgICAgICBpdGVtczogW1xuICAgICAgICAgICAgICAgIHsgbGFiZWw6IFwiYWN0aXZlXCIsIHZhbHVlOiBcIlwiK3RvdGFsQ29udGV4dHMsIGNzc0NsYXNzOlwic3RhdHMtaW5mby1wcmltYXJ5XCIgfSxcbiAgICAgICAgICAgICAgICB7IGxhYmVsOiBcImVuYWJsZWRcIiwgdmFsdWU6IFwiXCIrZW5hYmxlZENvbnRleHRzLCBjc3NDbGFzczpcInN0YXRzLWluZm8tb2tcIiB9LFxuICAgICAgICAgICAgICAgIHsgbGFiZWw6IFwiZGlzYWJsZWRcIiwgdmFsdWU6IFwiXCIrZGlzYWJsZWRDb250ZXh0cywgY3NzQ2xhc3M6XCJzdGF0cy1pbmZvLWtvXCIgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9IFxuICAgIH1cblxuICAgIG9uQ2F0YWxvZ0RhdGFSZWxvYWQoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5yZXN0Q2F0YWxvZ0VkaXRvci5jbGVhcigpO1xuICAgICAgICB0aGlzLnJlYnVpbGRTdGF0c0luZm8oKTtcbiAgICB9XG5cbiAgICBvbkNhdGFsb2dEYXRhUmVsb2FkRXJyb3IoZXZlbnQ6IFJFU1RDYXRhbG9nRGF0YUVycm9yRXZlbnQpe1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHLCAnb25DYXRhbG9nRGF0YVJlbG9hZEVycm9yIGVycm9yOicsIGV2ZW50KTtcbiAgICAgICAgdGhpcy5jbGVhclN0YXRzSW5mbygpO1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgIG5hbWU6ICdMb2FkUkVTVENvbnRleHRFcnJvcicsXG4gICAgICAgICAgICB0aXRsZTogJ1JFU1QgQ29udGV4dCBMb2FkJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBsb2FkaW5nIFJFU1QgY29udGV4dHM6JyxcbiAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICBlcnJvcjogZXZlbnQuZXJyb3IsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25DaGFuZ2VzU2F2ZWQoZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnb25DaGFuZ2VzU2F2ZWQ6ICcsIGV2ZW50KTtcbiAgICAgICAgLy9UT0RPISFcbiAgICB9XG5cbiAgICBwdWJsaWMgb25GaWx0ZXJDaGFuZ2UoZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdvbkZpbHRlckNoYW5nZSBjYWxsZWQnKTtcbiAgICAgICAgdGhpcy5yZXN0Q2F0YWxvZ1NlbGVjdG9yLnNldEZpbHRlcihldmVudC5zcmNFbGVtZW50Wyd2YWx1ZSddKTtcbiAgICB9XG5cblxuICAgIG5vZGVTZWxlY3Qobm9kZUV2ZW50OiBSRVNUQ2F0YWxvZ05vZGVTZWxlY3Rpb25FdmVudCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnbm9kZVNlbGVjdCAnLCBub2RlRXZlbnQpO1xuICAgICAgICB0aGlzLnJlc3RDYXRhbG9nRWRpdG9yLnN0YXJ0RWRpdChub2RlRXZlbnQubm9kZSk7XG4gICAgICAgIC8qXG4gICAgICAgIHRoaXMudXBkYXRlQ29tbWFuZHMobm9kZVR5cGUpO1xuICAgICAgICAqL1xuICAgIH1cblxuICAgIG9uQWRkUkVTVENvbnRleHRQcmVzc2VkKCl7XG4gICAgICAgIGlmICh0aGlzLmNhbkFkZE5ld0NvbnRleHQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0RWRpdERpYWxvZy5zaG93Rm9yTmV3KHRoaXMuc2VsZWN0ZWREb21haW4ubmFtZSwgdGhpcy5zZWxlY3RlZEFwcGxpY2F0aW9uLm5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjYW5BZGROZXdDb250ZXh0KCk6Ym9vbGVhbntcbiAgICAgICAgcmV0dXJuICh0aGlzLnNlbGVjdGVkRG9tYWluIT1udWxsICYmIHRoaXMuc2VsZWN0ZWRBcHBsaWNhdGlvbiE9bnVsbCk7XG4gICAgfVxuXG4gICAgZG9DcmVhdGVSRVNUQ29udGV4dChldmVudDpSRVNUQ29udGV4dERpYWxvZ1Jlc3VsdCl7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKFxuICAgICAgICAgICAgdGhpcy5yZXN0Q2F0YWxvZ1NlcnZpY2UuY3JlYXRlUkVTVENvbnRleHQoZXZlbnQuZG9tYWluLCBldmVudC5hcHBsaWNhdGlvbiwgZXZlbnQubmFtZSwgZXZlbnQudXJsKS5zdWJzY3JpYmUoIChyZXN1bHRzKT0+IHtcblxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oTE9HX1RBRyAsICdSRVNUIGNvbnRleHQgY3JlYXRlZDonLCByZXN1bHRzKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ0NyZWF0ZVJFU1RDb250ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdSRVNUIENvbnRleHQgQ3JlYXRlJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1JFU1QgQ29udGV4dCBjcmVhdGVkIHN1Y2Nlc3NmdWxseS4nLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hDYXRhbG9nKCk7XG5cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ0NyZWF0aW5nIFJFU1QgQ29udGV4dCBlcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdDcmVhdGVSRVNUQ29udGV4dEVycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdSRVNUIENvbnRleHQgQ3JlYXRlJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ0Vycm9yIGNyZWF0aW5nIFJFU1QgY29udGV4dDonLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkVycm9yLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgZG9VcGRhdGVSRVNUQ29udGV4dChldmVudDpSRVNUQ29udGV4dERpYWxvZ1Jlc3VsdCl7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKFxuICAgICAgICAgICAgdGhpcy5yZXN0Q2F0YWxvZ1NlcnZpY2UudXBkYXRlUkVTVENvbnRleHQoZXZlbnQuZG9tYWluLCBldmVudC5hcHBsaWNhdGlvbiwgZXZlbnQubmFtZSwgZXZlbnQudXJsKS5zdWJzY3JpYmUoIChyZXN1bHRzKT0+IHtcblxuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oTE9HX1RBRyAsICdSRVNUIGNvbnRleHQgdXBkYXRlZDonLCByZXN1bHRzKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ1VwZGF0ZVJFU1RDb250ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdSRVNUIENvbnRleHQgVXBkYXRlJyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1JFU1QgQ29udGV4dCB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4nLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hDYXRhbG9nKCk7XG5cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ1VwZGF0ZSBSRVNUIENvbnRleHQgZXJyb3I6JywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiAnVXBkYXRlUkVTVENvbnRleHRFcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnUkVTVCBDb250ZXh0IFVwZGF0ZScsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciB1cGRhdGluZyBSRVNUIGNvbnRleHQ6JyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIGRvVG9nZ2xlQ29udGV4dFN0YXR1cyhkb21haW46c3RyaW5nLCBhcHBsaWNhdGlvbjogc3RyaW5nLCBjb250ZXh0TmFtZTpzdHJpbmcsIHVybDpzdHJpbmcsIGVuYWJsZWQ6Ym9vbGVhbil7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdkb1RvZ2dsZUNvbnRleHRTdGF0dXMgOiAnLCBkb21haW4sIGFwcGxpY2F0aW9uLCBjb250ZXh0TmFtZSwgdXJsLCBlbmFibGVkKTtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQoXG4gICAgICAgICAgICB0aGlzLnJlc3RDYXRhbG9nU2VydmljZS5lbmFibGVSRVNUQ29udGV4dChkb21haW4sIGFwcGxpY2F0aW9uLCBjb250ZXh0TmFtZSwgZW5hYmxlZCkuc3Vic2NyaWJlKChyZXN1bHQpPT57XG5cbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKExPR19UQUcgLCAnUkVTVCBjb250ZXh0IHN0YXR1cyBjaGFuZ2U6JywgcmVzdWx0KTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ0NoYW5nZVN0YXR1c1JFU1RDb250ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdDaGFuZ2UgUkVTVCBDb250ZXh0IFN0YXR1cycsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdSRVNUIENvbnRleHQgc3RhdHVzIGNoYW5nZWQgc3VjY2Vzc2Z1bGx5LicsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuU3VjY2Vzc1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaENhdGFsb2coKTtcblxuXG4gICAgICAgICAgICB9LCAoZXJyb3IpPT57XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ0NoYW5naW4gUkVTVCBDb250ZXh0IHN0YXR1cyBlcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdDaGFuZ2VTdGF0dXNSRVNUQ29udGV4dEVycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdDaGFuZ2UgUkVTVCBDb250ZXh0IFN0YXR1cycsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBjaGFuZ2luZyBSRVNUIGNvbnRleHQgc3RhdHVzOiAnLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkVycm9yLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApOyAgICBcbiAgICB9XG5cbiAgICBkb0RlbGV0ZUNvbnRleHQoZG9tYWluOnN0cmluZywgYXBwbGljYXRpb246IHN0cmluZywgY29udGV4dE5hbWU6c3RyaW5nKXtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2RlbGV0ZUNvbnRleHQgOiAnLCBkb21haW4sIGFwcGxpY2F0aW9uLCBjb250ZXh0TmFtZSk7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKFxuICAgICAgICAgICAgdGhpcy5yZXN0Q2F0YWxvZ1NlcnZpY2UuZGVsZXRlUkVTVENvbnRleHQoZG9tYWluLCBhcHBsaWNhdGlvbiwgY29udGV4dE5hbWUpLnN1YnNjcmliZSgocmVzdWx0KT0+e1xuXG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuaW5mbyhMT0dfVEFHICwgJ1JFU1QgY29udGV4dCBkZWxldGVkOicsIHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdEZWxldGVSRVNUQ29udGV4dCcsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnRGVsZXRlIFJFU1QgQ29udGV4dCcsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdSRVNUIENvbnRleHQgZGVsZXRlZCBzdWNjZXNzZnVsbHkuJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZyZXNoQ2F0YWxvZygpO1xuXG5cbiAgICAgICAgICAgIH0sIChlcnJvcik9PntcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHLCAnRGVsZXRpbmcgUkVTVCBDb250ZXh0IGVycm9yOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ0RlbGV0ZVJFU1RDb250ZXh0RXJyb3InLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0RlbGV0ZSBSRVNUIENvbnRleHQnLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgZGVsZXRpbmcgUkVTVCBjb250ZXh0OicsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgb25EaWFsb2dDb25maXJtYXRpb24oZXZlbnQ6UkVTVENvbnRleHREaWFsb2dSZXN1bHQpe1xuICAgICAgICBpZiAoZXZlbnQuZGlhbG9nTW9kZT09PURpYWxvZ01vZGUuTmV3KXtcbiAgICAgICAgICAgIHRoaXMuZG9DcmVhdGVSRVNUQ29udGV4dChldmVudCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuZGlhbG9nTW9kZT09PURpYWxvZ01vZGUuRWRpdCkge1xuICAgICAgICAgICAgdGhpcy5kb1VwZGF0ZVJFU1RDb250ZXh0KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uTm9kZUNvbW1hbmQoY29tbWFuZDpSRVNUQ2F0YWxvZ05vZGVDb21tYW5kRXZlbnQpe1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHLCAnb25Ob2RlQ29tbWFuZDonLCBjb21tYW5kKTtcbiAgICAgICAgaWYgKGNvbW1hbmQuY29tbWFuZD09PUdyaWRDb21tYW5kVHlwZS5EZWxldGUpe1xuICAgICAgICAgICAgdGhpcy5kb0RlbGV0ZUNvbnRleHQoY29tbWFuZC5ub2RlLmRvbWFpbiwgY29tbWFuZC5ub2RlLmFwcGxpY2F0aW9uLCBjb21tYW5kLm5vZGUubmFtZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZC5jb21tYW5kPT09R3JpZENvbW1hbmRUeXBlLkVkaXQpe1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0RWRpdERpYWxvZy5zaG93Rm9yRWRpdChjb21tYW5kLm5vZGUuZG9tYWluLCBcbiAgICAgICAgICAgICAgICBjb21tYW5kLm5vZGUuYXBwbGljYXRpb24sIFxuICAgICAgICAgICAgICAgIGNvbW1hbmQubm9kZS5uYW1lLCBjb21tYW5kLm5vZGUudXJsLCBjb21tYW5kLm5vZGVbXCJlbmFibGVkXCJdKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb21tYW5kLmNvbW1hbmQ9PT1HcmlkQ29tbWFuZFR5cGUuUHVibGlzaFRvZ2dsZSl7XG4gICAgICAgICAgICB0aGlzLmRvVG9nZ2xlQ29udGV4dFN0YXR1cyhjb21tYW5kLm5vZGUuZG9tYWluLCBjb21tYW5kLm5vZGUuYXBwbGljYXRpb24sIGNvbW1hbmQubm9kZS5uYW1lLCBjb21tYW5kLm5vZGUudXJsLCAhY29tbWFuZC5ub2RlW1wiZW5hYmxlZFwiXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbn0gICBcbiJdfQ==