Repository URL to install this package:
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Injectable } from '@angular/core';
import { DomainsService, ApplicationsService, } from '@wa-motif-open-api/platform-service';
import { ServicesService, OperationsService } from '@wa-motif-open-api/catalog-service';
import { ApplicationsService as AppService } from '@wa-motif-open-api/catalog-service';
import { Observable } from 'rxjs';
import { NGXLogger } from 'web-console-core';
/** @type {?} */
const LOG_TAG = '[ServiceCatalogService]';
export class ServiceCatalogService {
/**
* @param {?} domainService
* @param {?} applicationService
* @param {?} appService
* @param {?} servicesService
* @param {?} operationsService
* @param {?} logger
*/
constructor(domainService, applicationService, appService, servicesService, operationsService, logger) {
this.domainService = domainService;
this.applicationService = applicationService;
this.appService = appService;
this.servicesService = servicesService;
this.operationsService = operationsService;
this.logger = logger;
}
/**
* Returns a JSON with the Service Catalog Structure
* @return {?}
*/
getServiceCatalog() {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'getServiceCatalog called');
/** @type {?} */
const serviceCatalog = [];
this.domainService.getDomains().subscribe((/**
* @param {?} domains
* @return {?}
*/
(domains) => {
/** @type {?} */
const domainsCount = domains.length;
/** @type {?} */
let processedDomains = 0;
for (const domain of domains) {
/** @type {?} */
const domainInfo = domain;
domainInfo.applications = [];
serviceCatalog.push(domainInfo);
this.applicationService.getApplications(domain.name).subscribe((/**
* @param {?} applications
* @return {?}
*/
(applications) => {
/** @type {?} */
const appCount = applications.length;
/** @type {?} */
let processedApps = 0;
if (appCount === 0) {
processedDomains++;
if (processedDomains === domainsCount) {
observer.next(serviceCatalog);
observer.complete();
this.logger.debug(LOG_TAG, 'getServiceCatalog completed');
}
}
for (const application of applications) {
/** @type {?} */
const applicationInfo = application;
this.appService.getServiceList(domain.name, application.name).subscribe((/**
* @param {?} services
* @return {?}
*/
(services) => {
applicationInfo.services = services;
// tslint:disable-next-line:max-line-length
this.logger.debug(LOG_TAG, 'getServiceCatalog services[' + application.name + '@' + domain.name + ']:', services);
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'getServiceCatalog error:', error);
observer.error(error);
}), (/**
* @return {?}
*/
() => {
processedApps++;
if (processedApps === appCount) {
processedDomains++;
}
if (processedDomains === domainsCount) {
observer.next(serviceCatalog);
observer.complete();
this.logger.debug(LOG_TAG, 'getServiceCatalog completed');
}
}));
domainInfo.applications.push(applicationInfo);
}
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'getServiceCatalog error:', error);
observer.error(error);
}));
if (processedDomains === domainsCount) {
observer.next(serviceCatalog);
observer.complete();
this.logger.debug(LOG_TAG, 'getServiceCatalog completed');
}
}
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'getServiceCatalog error:', error);
observer.error(error);
}));
}));
}
/**
* @return {?}
*/
getServices() {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'getServices called');
/** @type {?} */
const services = [];
this.getServiceCatalog().subscribe((/**
* @param {?} serviceCatalog
* @return {?}
*/
(serviceCatalog) => {
this.logger.debug(LOG_TAG, 'getServices rawData:', serviceCatalog);
serviceCatalog.forEach((/**
* @param {?} domain
* @return {?}
*/
domain => {
if (domain.applications) {
for (let i = 0; i < domain.applications.length; i++) {
/** @type {?} */
const application = domain.applications[i];
if (application.services) {
for (let y = 0; y < application.services.length; y++) {
/** @type {?} */
const service = application.services[y];
if (service.serviceOperationList) {
for (let z = 0; z < service.serviceOperationList.length; z++) {
/** @type {?} */
const operation = service.serviceOperationList[z];
/** @type {?} */
const serviceEntry = {
domain: domain.name,
application: application.name,
service: service.name,
serviceEnabled: service.enabled,
channel: service.channel,
name: operation.name,
description: operation.description,
type: 'Operation'
};
services.push(serviceEntry);
}
}
}
}
}
}
}));
observer.next(services);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
this.logger.error(LOG_TAG, 'getServices error:', error);
observer.error(error);
}));
}));
}
/**
* @param {?} domainName
* @return {?}
*/
createNewDomain(domainName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'createNewDomain called for ', domainName);
/** @type {?} */
const domainCreate = { name: domainName, description: 'Description of ' + domainName };
this.domainService.createDomain(domainCreate).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} domain
* @param {?} applicationName
* @return {?}
*/
createNewApplication(domain, applicationName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'createNewApplication called for ', domain, applicationName);
/** @type {?} */
const appCreate = { name: applicationName, description: 'Description of ' + applicationName };
this.applicationService.createApplication(domain, appCreate).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} domain
* @param {?} application
* @param {?} serviceName
* @param {?} channel
* @return {?}
*/
createNewService(domain, application, serviceName, channel) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'createNewService called for ', domain, application, serviceName, channel);
/** @type {?} */
const serviceCreate = {
name: serviceName
};
this.servicesService.createService(channel, domain, application, serviceCreate).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} channel
* @param {?} domain
* @param {?} application
* @param {?} service
* @param {?} operationName
* @param {?} description
* @param {?} pluginName
* @param {?} encrypted
* @param {?} secure
* @param {?} counted
* @param {?} sessionless
* @param {?} inputParams
* @param {?} outputParams
* @return {?}
*/
createNewOperation(channel, domain, application, service, operationName, description, pluginName, encrypted, secure, counted, sessionless, inputParams, outputParams) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'createNewOperation called for ', domain, application, service, operationName);
/** @type {?} */
const serviceOperation = {
counted: counted,
encryptActive: encrypted,
inputParams: inputParams,
outputParams: outputParams,
pluginName: pluginName,
secure: secure,
sessionless: sessionless,
name: operationName,
description: description
};
this.operationsService.createServiceOperation(channel, domain, application, service, serviceOperation).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} domainName
* @return {?}
*/
deleteDomain(domainName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'deleteDomain called for ', domainName);
this.domainService.deleteDomain(domainName).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} domainName
* @param {?} applicationName
* @return {?}
*/
deleteApplication(domainName, applicationName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'deleteApplication called for ', domainName, applicationName);
this.applicationService.deleteApplication(domainName, applicationName).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} channel
* @param {?} domainName
* @param {?} applicationName
* @param {?} serviceName
* @return {?}
*/
deleteService(channel, domainName, applicationName, serviceName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'deleteService called for ', domainName, applicationName, serviceName);
this.servicesService.deleteService(channel, domainName, applicationName, serviceName).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
/**
* @param {?} channel
* @param {?} domainName
* @param {?} applicationName
* @param {?} serviceName
* @param {?} operationName
* @return {?}
*/
deleteOperation(channel, domainName, applicationName, serviceName, operationName) {
return new Observable((/**
* @param {?} observer
* @return {?}
*/
(observer) => {
this.logger.debug(LOG_TAG, 'deleteOperation called for ', domainName, applicationName, serviceName, operationName);
this.operationsService.deleteServiceOperation(channel, domainName, applicationName, serviceName, operationName).subscribe((/**
* @param {?} data
* @return {?}
*/
(data) => {
observer.next(data);
observer.complete();
}), (/**
* @param {?} error
* @return {?}
*/
(error) => {
observer.error(error);
}));
}));
}
}
ServiceCatalogService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
ServiceCatalogService.ctorParameters = () => [
{ type: DomainsService },
{ type: ApplicationsService },
{ type: AppService },
{ type: ServicesService },
{ type: OperationsService },
{ type: NGXLogger }
];
if (false) {
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.domainsList;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.domainService;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.applicationService;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.appService;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.servicesService;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.operationsService;
/**
* @type {?}
* @private
*/
ServiceCatalogService.prototype.logger;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VydmljZUNhdGFsb2dTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbW90aWYtd2ViLWFkbWluLWNvcmUvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvU2VydmljZUNhdGFsb2dTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxjQUFjLEVBRWQsbUJBQW1CLEdBR2pCLE1BQU0scUNBQXFDLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFHcEIsaUJBQWlCLEVBQ0MsTUFBTSxvQ0FBb0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsbUJBQW1CLElBQUksVUFBVSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFdkYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7O01BRXZDLE9BQU8sR0FBRyx5QkFBeUI7QUFHekMsTUFBTSxPQUFPLHFCQUFxQjs7Ozs7Ozs7O0lBSTlCLFlBQW9CLGFBQTZCLEVBQ3JDLGtCQUF1QyxFQUN2QyxVQUFzQixFQUN0QixlQUFnQyxFQUNoQyxpQkFBb0MsRUFDcEMsTUFBaUI7UUFMVCxrQkFBYSxHQUFiLGFBQWEsQ0FBZ0I7UUFDckMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFxQjtRQUN2QyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLFdBQU0sR0FBTixNQUFNLENBQVc7SUFDN0IsQ0FBQzs7Ozs7SUFLTSxpQkFBaUI7UUFDcEIsT0FBTyxJQUFJLFVBQVU7Ozs7UUFBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBRS9CLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSwwQkFBMEIsQ0FBRSxD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LENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUIsQ0FBQyxFQUFDLENBQUM7UUFDUCxDQUFDLEVBQUMsQ0FBQztJQUNQLENBQUM7OztZQS9SSixVQUFVOzs7O1lBbEJGLGNBQWM7WUFFZCxtQkFBbUI7WUFTSSxVQUFVO1lBTGpDLGVBQWU7WUFHcEIsaUJBQWlCO1lBS1osU0FBUzs7Ozs7OztJQU9kLDRDQUFtQzs7Ozs7SUFFdkIsOENBQXFDOzs7OztJQUM3QyxtREFBK0M7Ozs7O0lBQy9DLDJDQUE4Qjs7Ozs7SUFDOUIsZ0RBQXdDOzs7OztJQUN4QyxrREFBNEM7Ozs7O0lBQzVDLHVDQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbWFpbnNTZXJ2aWNlLFxuICAgICAgICAgRG9tYWluLCBEb21haW5DcmVhdGUsXG4gICAgICAgICBBcHBsaWNhdGlvbnNTZXJ2aWNlLFxuICAgICAgICAgQXBwbGljYXRpb24sXG4gICAgICAgICBBcHBsaWNhdGlvbkNyZWF0ZSxcbiAgICAgICAgICB9IGZyb20gJ0B3YS1tb3RpZi1vcGVuLWFwaS9wbGF0Zm9ybS1zZXJ2aWNlJztcbmltcG9ydCB7IFNlcnZpY2VzU2VydmljZSxcbiAgICBTZXJ2aWNlLFxuICAgIFNlcnZpY2VDcmVhdGUsXG4gICAgT3BlcmF0aW9uc1NlcnZpY2UsXG4gICAgU2VydmljZU9wZXJhdGlvbiB9IGZyb20gJ0B3YS1tb3RpZi1vcGVuLWFwaS9jYXRhbG9nLXNlcnZpY2UnO1xuaW1wb3J0IHsgQXBwbGljYXRpb25zU2VydmljZSBhcyBBcHBTZXJ2aWNlIH0gZnJvbSAnQHdhLW1vdGlmLW9wZW4tYXBpL2NhdGFsb2ctc2VydmljZSc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IE5HWExvZ2dlciB9IGZyb20gJ3dlYi1jb25zb2xlLWNvcmUnO1xuXG5jb25zdCBMT0dfVEFHID0gJ1tTZXJ2aWNlQ2F0YWxvZ1NlcnZpY2VdJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNlcnZpY2VDYXRhbG9nU2VydmljZSB7XG5cbiAgICBwcml2YXRlIGRvbWFpbnNMaXN0OiBBcnJheTxEb21haW4+O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkb21haW5TZXJ2aWNlOiBEb21haW5zU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBhcHBsaWNhdGlvblNlcnZpY2U6IEFwcGxpY2F0aW9uc1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgYXBwU2VydmljZTogQXBwU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzZXJ2aWNlc1NlcnZpY2U6IFNlcnZpY2VzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBvcGVyYXRpb25zU2VydmljZTogT3BlcmF0aW9uc1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbG9nZ2VyOiBOR1hMb2dnZXIpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgSlNPTiB3aXRoIHRoZSBTZXJ2aWNlIENhdGFsb2cgU3RydWN0dXJlXG4gICAgICovXG4gICAgcHVibGljIGdldFNlcnZpY2VDYXRhbG9nKCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHtcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2dldFNlcnZpY2VDYXRhbG9nIGNhbGxlZCcgKTtcblxuICAgICAgICAgICAgY29uc3Qgc2VydmljZUNhdGFsb2cgPSBbXTtcblxuICAgICAgICAgICAgdGhpcy5kb21haW5TZXJ2aWNlLmdldERvbWFpbnMoKS5zdWJzY3JpYmUoKCBkb21haW5zOiBBcnJheTxEb21haW4+ICkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRvbWFpbnNDb3VudCA9IGRvbWFpbnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGxldCBwcm9jZXNzZWREb21haW5zID0gMDtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZG9tYWluIG9mIGRvbWFpbnMpIHtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkb21haW5JbmZvOiBhbnkgPSBkb21haW47XG4gICAgICAgICAgICAgICAgICAgIGRvbWFpbkluZm8uYXBwbGljYXRpb25zID0gW107XG4gICAgICAgICAgICAgICAgICAgIHNlcnZpY2VDYXRhbG9nLnB1c2goZG9tYWluSW5mbyk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBsaWNhdGlvblNlcnZpY2UuZ2V0QXBwbGljYXRpb25zKGRvbWFpbi5uYW1lKS5zdWJzY3JpYmUoKCBhcHBsaWNhdGlvbnM6IEFycmF5PEFwcGxpY2F0aW9uPiApID0+IHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXBwQ291bnQgPSBhcHBsaWNhdGlvbnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHByb2Nlc3NlZEFwcHMgPSAwO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXBwQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWREb21haW5zKys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwcm9jZXNzZWREb21haW5zID09PSBkb21haW5zQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCggc2VydmljZUNhdGFsb2cgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2dldFNlcnZpY2VDYXRhbG9nIGNvbXBsZXRlZCcgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYXBwbGljYXRpb24gb2YgYXBwbGljYXRpb25zICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFwcGxpY2F0aW9uSW5mbzogYW55ID0gYXBwbGljYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBTZXJ2aWNlLmdldFNlcnZpY2VMaXN0KGRvbWFpbi5uYW1lLCBhcHBsaWNhdGlvbi5uYW1lKS5zdWJzY3JpYmUoICggc2VydmljZXM6IEFycmF5PFNlcnZpY2U+ICkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBsaWNhdGlvbkluZm8uc2VydmljZXMgPSBzZXJ2aWNlcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZ2V0U2VydmljZUNhdGFsb2cgc2VydmljZXNbJyArIGFwcGxpY2F0aW9uLm5hbWUgKyAnQCcgKyBkb21haW4ubmFtZSArICddOicsIHNlcnZpY2VzICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ2dldFNlcnZpY2VDYXRhbG9nIGVycm9yOicgLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NlZEFwcHMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZEFwcHMgPT09IGFwcENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWREb21haW5zKys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwcm9jZXNzZWREb21haW5zID09PSBkb21haW5zQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoIHNlcnZpY2VDYXRhbG9nICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2dldFNlcnZpY2VDYXRhbG9nIGNvbXBsZXRlZCcgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkluZm8uYXBwbGljYXRpb25zLnB1c2goYXBwbGljYXRpb25JbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ2dldFNlcnZpY2VDYXRhbG9nIGVycm9yOicgLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICggcHJvY2Vzc2VkRG9tYWlucyA9PT0gZG9tYWluc0NvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KCBzZXJ2aWNlQ2F0YWxvZyApO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdnZXRTZXJ2aWNlQ2F0YWxvZyBjb21wbGV0ZWQnICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdnZXRTZXJ2aWNlQ2F0YWxvZyBlcnJvcjonICwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2VydmljZXMoKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZ2V0U2VydmljZXMgY2FsbGVkJyApO1xuXG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlczogYW55ID0gW107XG5cbiAgICAgICAgICAgIHRoaXMuZ2V0U2VydmljZUNhdGFsb2coKS5zdWJzY3JpYmUoKHNlcnZpY2VDYXRhbG9nKSA9PiB7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZ2V0U2VydmljZXMgcmF3RGF0YTonLCBzZXJ2aWNlQ2F0YWxvZyApO1xuXG4gICAgICAgICAgICAgICAgc2VydmljZUNhdGFsb2cuZm9yRWFjaChkb21haW4gPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChkb21haW4uYXBwbGljYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCA7IGkgPCBkb21haW4uYXBwbGljYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXBwbGljYXRpb24gPSBkb21haW4uYXBwbGljYXRpb25zW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcGxpY2F0aW9uLnNlcnZpY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgYXBwbGljYXRpb24uc2VydmljZXMubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlcnZpY2UgPSBhcHBsaWNhdGlvbi5zZXJ2aWNlc1t5XTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZpY2Uuc2VydmljZU9wZXJhdGlvbkxpc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCB6ID0gMDsgeiA8IHNlcnZpY2Uuc2VydmljZU9wZXJhdGlvbkxpc3QubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3BlcmF0aW9uID0gc2VydmljZS5zZXJ2aWNlT3BlcmF0aW9uTGlzdFt6XTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXJ2aWNlRW50cnk6IGFueSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbjogZG9tYWluLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBsaWNhdGlvbjogYXBwbGljYXRpb24ubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2U6IHNlcnZpY2UubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcnZpY2VFbmFibGVkIDogc2VydmljZS5lbmFibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbDogc2VydmljZS5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogb3BlcmF0aW9uLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogb3BlcmF0aW9uLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ09wZXJhdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VydmljZXMucHVzaChzZXJ2aWNlRW50cnkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KCBzZXJ2aWNlcyApO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG5cbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdnZXRTZXJ2aWNlcyBlcnJvcjonICwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVOZXdEb21haW4oZG9tYWluTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxEb21haW4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnY3JlYXRlTmV3RG9tYWluIGNhbGxlZCBmb3IgJywgZG9tYWluTmFtZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGRvbWFpbkNyZWF0ZTogRG9tYWluQ3JlYXRlID0geyBuYW1lOiBkb21haW5OYW1lLCBkZXNjcmlwdGlvbjogJ0Rlc2NyaXB0aW9uIG9mICcgKyBkb21haW5OYW1lIH07XG5cbiAgICAgICAgICAgIHRoaXMuZG9tYWluU2VydmljZS5jcmVhdGVEb21haW4oZG9tYWluQ3JlYXRlKS5zdWJzY3JpYmUoKGRhdGE6IERvbWFpbikgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoZGF0YSk7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlTmV3QXBwbGljYXRpb24oZG9tYWluOiBzdHJpbmcsIGFwcGxpY2F0aW9uTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxBcHBsaWNhdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdjcmVhdGVOZXdBcHBsaWNhdGlvbiBjYWxsZWQgZm9yICcsIGRvbWFpbiwgYXBwbGljYXRpb25OYW1lKTtcblxuICAgICAgICAgICAgY29uc3QgYXBwQ3JlYXRlOiBBcHBsaWNhdGlvbkNyZWF0ZSA9IHsgbmFtZTogYXBwbGljYXRpb25OYW1lLCBkZXNjcmlwdGlvbjogJ0Rlc2NyaXB0aW9uIG9mICcgKyBhcHBsaWNhdGlvbk5hbWUgfTtcblxuICAgICAgICAgICAgdGhpcy5hcHBsaWNhdGlvblNlcnZpY2UuY3JlYXRlQXBwbGljYXRpb24oZG9tYWluLCBhcHBDcmVhdGUpLnN1YnNjcmliZSgoZGF0YTogQXBwbGljYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGRhdGEpO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZU5ld1NlcnZpY2UoZG9tYWluOiBzdHJpbmcsIGFwcGxpY2F0aW9uOiBzdHJpbmcsIHNlcnZpY2VOYW1lOiBzdHJpbmcsIGNoYW5uZWw6IHN0cmluZyk6IE9ic2VydmFibGU8U2VydmljZT4ge1xuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdjcmVhdGVOZXdTZXJ2aWNlIGNhbGxlZCBmb3IgJywgZG9tYWluLCBhcHBsaWNhdGlvbiwgc2VydmljZU5hbWUsIGNoYW5uZWwpO1xuXG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlQ3JlYXRlOiBTZXJ2aWNlQ3JlYXRlID0ge1xuICAgICAgICAgICAgICAgIG5hbWU6IHNlcnZpY2VOYW1lXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzU2VydmljZS5jcmVhdGVTZXJ2aWNlKGNoYW5uZWwsIGRvbWFpbiwgYXBwbGljYXRpb24sIHNlcnZpY2VDcmVhdGUpLnN1YnNjcmliZSgoZGF0YTogU2VydmljZSkgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoZGF0YSk7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlTmV3T3BlcmF0aW9uKGNoYW5uZWw6IHN0cmluZyxcbiAgICAgICAgZG9tYWluOiBzdHJpbmcsXG4gICAgICAgIGFwcGxpY2F0aW9uOiBzdHJpbmcsXG4gICAgICAgIHNlcnZpY2U6IHN0cmluZyxcbiAgICAgICAgb3BlcmF0aW9uTmFtZTogc3RyaW5nLFxuICAgICAgICBkZXNjcmlwdGlvbjogc3RyaW5nLFxuICAgICAgICBwbHVnaW5OYW1lOiBzdHJpbmcsXG4gICAgICAgIGVuY3J5cHRlZDogYm9vbGVhbixcbiAgICAgICAgc2VjdXJlOiBib29sZWFuLFxuICAgICAgICBjb3VudGVkOiBib29sZWFuLFxuICAgICAgICBzZXNzaW9ubGVzczogYm9vbGVhbixcbiAgICAgICAgaW5wdXRQYXJhbXM6IHN0cmluZyxcbiAgICAgICAgb3V0cHV0UGFyYW1zOiBzdHJpbmdcbiAgICAgICAgKTogT2JzZXJ2YWJsZTxTZXJ2aWNlT3BlcmF0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHtcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2NyZWF0ZU5ld09wZXJhdGlvbiBjYWxsZWQgZm9yICcsIGRvbWFpbiwgYXBwbGljYXRpb24sIHNlcnZpY2UsIG9wZXJhdGlvbk5hbWUpO1xuICAgICAgICAgICAgY29uc3Qgc2VydmljZU9wZXJhdGlvbjogU2VydmljZU9wZXJhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBjb3VudGVkOiBjb3VudGVkLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRBY3RpdmU6IGVuY3J5cHRlZCxcbiAgICAgICAgICAgICAgICBpbnB1dFBhcmFtczogaW5wdXRQYXJhbXMsXG4gICAgICAgICAgICAgICAgb3V0cHV0UGFyYW1zOiBvdXRwdXRQYXJhbXMsXG4gICAgICAgICAgICAgICAgcGx1Z2luTmFtZTogcGx1Z2luTmFtZSxcbiAgICAgICAgICAgICAgICBzZWN1cmU6IHNlY3VyZSxcbiAgICAgICAgICAgICAgICBzZXNzaW9ubGVzczogc2Vzc2lvbmxlc3MsXG4gICAgICAgICAgICAgICAgbmFtZTogb3BlcmF0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb25cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uc1NlcnZpY2UuY3JlYXRlU2VydmljZU9wZXJhdGlvbihjaGFubmVsLFxuICAgICAgICAgICAgICAgIGRvbWFpbiwgYXBwbGljYXRpb24sIHNlcnZpY2UsIHNlcnZpY2VPcGVyYXRpb24pLiBzdWJzY3JpYmUoKGRhdGE6IFNlcnZpY2VPcGVyYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pO1xuICAgIH1cblxuXG4gICAgcHVibGljIGRlbGV0ZURvbWFpbihkb21haW5OYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnZGVsZXRlRG9tYWluIGNhbGxlZCBmb3IgJywgZG9tYWluTmFtZSk7XG4gICAgICAgICAgICB0aGlzLmRvbWFpblNlcnZpY2UuZGVsZXRlRG9tYWluKGRvbWFpbk5hbWUpLnN1YnNjcmliZSgoZGF0YTogRG9tYWluKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChkYXRhKTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGVBcHBsaWNhdGlvbihkb21haW5OYW1lOiBzdHJpbmcsIGFwcGxpY2F0aW9uTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2RlbGV0ZUFwcGxpY2F0aW9uIGNhbGxlZCBmb3IgJywgZG9tYWluTmFtZSwgYXBwbGljYXRpb25OYW1lKTtcbiAgICAgICAgICAgIHRoaXMuYXBwbGljYXRpb25TZXJ2aWNlLmRlbGV0ZUFwcGxpY2F0aW9uKGRvbWFpbk5hbWUsIGFwcGxpY2F0aW9uTmFtZSkuc3Vic2NyaWJlKChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChkYXRhKTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGVTZXJ2aWNlKGNoYW5uZWw6IHN0cmluZywgZG9tYWluTmFtZTogc3RyaW5nLCBhcHBsaWNhdGlvbk5hbWU6IHN0cmluZywgc2VydmljZU5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdkZWxldGVTZXJ2aWNlIGNhbGxlZCBmb3IgJywgZG9tYWluTmFtZSwgYXBwbGljYXRpb25OYW1lLCBzZXJ2aWNlTmFtZSk7XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzU2VydmljZS5kZWxldGVTZXJ2aWNlKGNoYW5uZWwsIGRvbWFpbk5hbWUsIGFwcGxpY2F0aW9uTmFtZSwgc2VydmljZU5hbWUpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoZGF0YSk7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVsZXRlT3BlcmF0aW9uKGNoYW5uZWw6IHN0cmluZyxcbiAgICAgICAgZG9tYWluTmFtZTogc3RyaW5nLFxuICAgICAgICBhcHBsaWNhdGlvbk5hbWU6IHN0cmluZyxcbiAgICAgICAgc2VydmljZU5hbWU6IHN0cmluZyxcbiAgICAgICAgb3BlcmF0aW9uTmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2RlbGV0ZU9wZXJhdGlvbiBjYWxsZWQgZm9yICcsIGRvbWFpbk5hbWUsIGFwcGxpY2F0aW9uTmFtZSwgc2VydmljZU5hbWUsIG9wZXJhdGlvbk5hbWUpO1xuICAgICAgICAgICAgdGhpcy5vcGVyYXRpb25zU2VydmljZS5kZWxldGVTZXJ2aWNlT3BlcmF0aW9uKGNoYW5uZWwsXG4gICAgICAgICAgICAgICAgZG9tYWluTmFtZSwgYXBwbGljYXRpb25OYW1lLCBzZXJ2aWNlTmFtZSwgb3BlcmF0aW9uTmFtZSkuIHN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuXG5cblxuIl19