@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
338 lines • 47 kB
JavaScript
import { Location } from '@angular/common';
import { PRIMARY_OUTLET } from '@angular/router';
import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging';
import { EnvironmentModule } from '@microsoft/windows-admin-center-sdk/core/manifest/environment-modules';
import { forkJoin, Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
/**
* Static function name for the navigation title function in a component class
*/
export const navigationTitleFunctionName = 'navigationTitle';
/**
* Navigation class to provide set of static helper functions.
*/
export class Navigation {
/**
* Turn off browser history push.
* - instead sending all path change to the Shell to create history.
*/
static turnOffHistory() {
if (window.history.pushState !== MsftSme.noop) {
Navigation.pushStateBackup = window.history.pushState;
Object.defineProperty(window.history, 'pushState', {
value: MsftSme.noop
});
}
}
/**
* Turn on browser history push.
*/
static turnOnHistory() {
if (Navigation.pushStateBackup && window.history.pushState === MsftSme.noop) {
Object.defineProperty(window.history, 'pushState', {
value: Navigation.pushStateBackup
});
}
}
/**
* Compare two urls by removing leading and trailing slashes.
*
* @param url1 the url to compare.
* @param url2 the url to compare.
* @return boolean true if matches. null url returns false.
*/
static areEqualUrl(url1, url2) {
if (url1 == null || url2 == null) {
return false;
}
return Navigation.trimSlash(url1) === Navigation.trimSlash(url2);
}
/**
* Compare two urls for number of segments.
*
* @param url1 the url to compare.
* @param url2 the url to compare.
* @param count the number of segments to compare.
* @return boolean true if matches for number of segments.
*/
static areEqualSegments(url1, url2, count) {
if (url1 == null || url2 == null) {
return false;
}
const segments1 = Navigation.trimSlash(url1).split('/');
const segments2 = Navigation.trimSlash(url2).split('/');
if (segments1.length < count || segments2.length < count) {
return false;
}
for (let i = 0; i < count; i++) {
if (segments1[i] !== segments2[i]) {
return false;
}
}
return true;
}
/**
* Trim leading and trailing slashes.
*
* @param url the url to trim leading and trailing slashes.
* @returns the updated url.
*/
static trimSlash(url) {
if (url == null) {
return url;
}
if (url.length > 0 && url[0] === '/') {
url = url.substring(1);
}
if (url.length > 0 && url[url.length - 1] === '/') {
url = url.substring(0, url.length - 1);
}
return url;
}
/**
* Get url segments combined module name and path of entry point.
*
* @param moduleName the module name.
* @param entryPointName the name of entry point.
* @return the url segments.
*/
static getModuleEntryPointUrlSegment(moduleName, entryPointName) {
return `${moduleName}!${entryPointName}`;
}
/**
* Builds selectable paths from the given route.
*
* @param appContextService The application context service object.
* @param route The route to extract the breadcrumb for
* @param pathPrefix The prefix to prepend to the route path
* @return SelectablePath[] the selectable paths.
*/
static buildSelectablePathsForRoute(appContextService, route, pathPrefix) {
const asyncArray = [];
const childrenQueue = route.children.slice(0);
pathPrefix = pathPrefix ? pathPrefix : '';
while (childrenQueue.length > 0) {
// we are only interested in primary routes that have a displayName at this time
const child = childrenQueue.shift();
if (child.outlet === PRIMARY_OUTLET) {
// append the routes URL segment
const segmentPath = child.url
.filter(seg1 => seg1 && seg1.path && seg1.path.length > 0)
.map(seg2 => seg2.path)
.join('/');
if (segmentPath) {
// only add a segment if there's any valuable information to it.
pathPrefix = Location.joinWithSlash(pathPrefix, segmentPath);
}
let result = null;
if (child.component && child.component[navigationTitleFunctionName]) {
// the label can be null to indicate if it's home page access.
result = child.component[navigationTitleFunctionName](appContextService, child);
if (result) {
if (result instanceof Observable) {
// observable query.
asyncArray.push(result);
}
else if (typeof result === 'object') {
// returned as array.
const paths = result;
asyncArray.push(of(paths));
}
else if (typeof result === 'string') {
// returned as string.
const selectablePath = {
label: result,
path: pathPrefix
};
asyncArray.push(of([selectablePath]));
}
else {
const message = MsftSme.getStrings()
.MsftSmeShell.Angular.Navigation.NavigationTitleReturnTypeError.message;
throw new Error(message);
}
}
}
}
// continue building recursively
child.children.forEach(grandChild => {
if (grandChild.outlet === PRIMARY_OUTLET) {
childrenQueue.push(grandChild);
}
});
}
return forkJoin(asyncArray).pipe(map(resultArray => {
const result = [];
resultArray.forEach((items, index, array) => {
items.forEach(item => {
result.push(item);
});
});
return result;
}));
}
/**
* Navigate to the connection.
*
* @param router the router.
* @param connection the connection object.
*/
static navigateConnection(router, connection) {
const typeInfo = EnvironmentModule.getConnectionTypeInfo(connection.type);
const moduleEntrySegment = Navigation.getModuleEntryPointUrlSegment(typeInfo.solution.parentModule.name, typeInfo.solution.name);
const rootEntrySegment = Navigation.getModuleEntryPointUrlSegment(typeInfo.solution.parentModule.name, typeInfo.solution.tools.defaultTool);
const pathSegments = ['solutions', moduleEntrySegment, 'tools', rootEntrySegment];
return router.navigate(pathSegments);
}
/**
* Get navigation URL by solution/name, module/name, connection/name and connection/type.
*
* (ex.
* - /
* - /msft.sme.server-manager!servers
* - /msft.sme.server-manager!servers/tools/msft.sme.server-manager!overview
* - /msft.sme.server-manager!servers +
* /connections/msft.sme.connection-type.server/sme-full1.redmond.corp.microsoft.com +
* /tools/msft.sme.server-manager!overview)
* @param data the RPC shell navigate data.
* @return string the url to navigate to the tool.
*/
static getNavigationUrlForToolEntryPoint(data) {
if (data.navigateNext) {
return data.navigateNext;
}
if (data.settings) {
let settingsUrl = `/settings`;
if (data.settings.name) {
settingsUrl += `/${data.settings.name}`;
}
if (data.settings.nestedUrlAndOptions) {
settingsUrl += data.settings.nestedUrlAndOptions;
}
return settingsUrl;
}
else if (!data.solution || !data.solution.moduleName) {
// no solution goes to root (homepage)
return '/';
}
else if (!data.solution.entryPointName) {
// it requires entryPointName.
Logging.logError('navigation', 'Argument error: entryPointName of the solution is required.');
return null;
}
let url = `/${data.solution.moduleName}!${data.solution.entryPointName}`;
if (data.connection) {
if (!data.connection.name || !data.connection.type) {
// connection list for empty connection like 'data.connection === {}'
url += '/connections';
return url;
}
url += `/connections/${data.connection.type}/${data.connection.name}`;
}
// allow to navigate inside of solution just by tool name, so data.connection == null is expected.
if (data.tool) {
if (data.tool.moduleName && !data.tool.entryPointName) {
// it requires entryPointName.
Logging.logError('navigation', 'Argument error: entryPointName of the tool is required.');
return null;
}
url += `/tools/${data.tool.moduleName}!${data.tool.entryPointName}`;
}
else if (data.connectionSettings) {
url += '/tools/settings';
if (data.connectionSettings.tabUrlName) {
url += `/${data.connectionSettings.tabUrlName}`;
}
}
if (data.toolNestedUrlAndOptions) {
url += data.toolNestedUrlAndOptions;
}
return url;
}
/**
* Get navigation extra data from current activated route on shell.
*
* @param route the activated route.
*/
static getUrlNavigationDataExtras(route) {
const snapshot = route.snapshot;
const fragment = snapshot.queryParamMap.get('fragment');
let queryParams = null;
try {
const query = snapshot.queryParamMap.get('queryParams');
if (query) {
queryParams = JSON.parse(query);
}
}
catch {
}
return { fragment, queryParams };
}
/**
* Get the navigation data from the path on module.
*
* @param router the Router object.
* @param path The path URI with module.
*/
static getUrlNavigationData(router, path) {
const urlTree = router.parseUrl(path);
const options = {
fragment: urlTree.fragment,
queryParams: urlTree.queryParams
};
urlTree.fragment = null;
urlTree.queryParams = {};
const rootPath = urlTree.toString();
const rootPathTrimmed = Navigation.trimSlash(rootPath);
const commands = rootPathTrimmed === '' ? [''] : rootPathTrimmed.split('/');
for (let index = 0; index < commands.length; index++) {
// decodeURI to passing parameters to module path.
commands[index] = decodeURI(commands[index]);
}
return { commands, options };
}
/**
* Get the navigation queryParams on shell/module.
*
* @param dataExtras The navigation data extras object.
* @returns the params data for router navigation call.
*/
static getUrlQueryParams(dataExtras) {
const params = {};
if (dataExtras.fragment) {
params.fragment = dataExtras.fragment;
}
if (dataExtras.queryParams && Object.keys(dataExtras.queryParams).length > 0) {
params.queryParams = JSON.stringify(dataExtras.queryParams);
}
return params;
}
/**
* Get serialized the data extras object into url string.
*
* @param options the navigation data extras object.
* @returns the URL string.
*/
static getUrlSerializedDataExtras(options) {
let extra = '';
if (options.queryParams) {
let keys = Object.keys(options.queryParams);
keys = keys.sort();
keys.forEach((key, index) => extra += `${index === 0 ? '?' : '&'}${key}=${options.queryParams[key]}`);
}
if (options.fragment) {
extra += `#${options.fragment}`;
}
return extra;
}
}
/**
* The url options for gateway and connection.
*/
Navigation.gatewayUrl = 'gatewayUrl';
/**
* The url options for version of static content.
*/
Navigation.staticVersion = 'staticVersion';
Navigation.pushStateBackup = null;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL3NlcnZpY2UvbmF2aWdhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFrRCxjQUFjLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sOERBQThELENBQUM7QUFDdkYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUVBQXVFLENBQUM7QUFJMUcsT0FBTyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQWtDckM7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxpQkFBaUIsQ0FBQztBQWM3RDs7R0FFRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBYW5COzs7T0FHRztJQUNJLE1BQU0sQ0FBQyxjQUFjO1FBQ3hCLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssT0FBTyxDQUFDLElBQUksRUFBRTtZQUMzQyxVQUFVLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUU7Z0JBQy9DLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSTthQUN0QixDQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxhQUFhO1FBQ3ZCLElBQUksVUFBVSxDQUFDLGVBQWUsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsSUFBSSxFQUFFO1lBQ3pFLE1B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SSxNQUFNLENBQUMsMEJBQTBCLENBQUMsT0FBNkI7UUFDbEUsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxPQUFPLENBQUMsV0FBVyxFQUFFO1lBQ3JCLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzVDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssSUFBSSxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUN6RztRQUVELElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtZQUNsQixLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDbkM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDOztBQXpXRDs7R0FFRztBQUNXLHFCQUFVLEdBQUcsWUFBWSxDQUFDO0FBRXhDOztHQUVHO0FBQ1csd0JBQWEsR0FBRyxlQUFlLENBQUM7QUFFL0IsMEJBQWUsR0FBUSxJQUFJLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBQYXJhbXMsIFBSSU1BUllfT1VUTEVULCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBMb2dnaW5nIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9kaWFnbm9zdGljcy9sb2dnaW5nJztcclxuaW1wb3J0IHsgRW52aXJvbm1lbnRNb2R1bGUgfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL21hbmlmZXN0L2Vudmlyb25tZW50LW1vZHVsZXMnO1xyXG5pbXBvcnQgeyBTZWxlY3RhYmxlUGF0aCB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvcnBjL3JlcG9ydC9ycGMtcmVwb3J0LW1vZGVsJztcclxuaW1wb3J0IHsgUnBjU2hlbGxOYXZpZ2F0ZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvcnBjL3NoZWxsLW5hdmlnYXRlL3JwYy1zaGVsbC1uYXZpZ2F0ZS1tb2RlbCc7XHJcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL3NlY3VyaXR5L2Nvbm5lY3Rpb24nO1xyXG5pbXBvcnQgeyBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBTdHJpbmdzIH0gZnJvbSAnLi4vZ2VuZXJhdGVkL3N0cmluZ3MnO1xyXG5pbXBvcnQgeyBBcHBDb250ZXh0U2VydmljZSB9IGZyb20gJy4vYXBwLWNvbnRleHQuc2VydmljZSc7XHJcblxyXG4vKipcclxuICogVGhlIG5hdmlnYXRpb24gZGF0YSBleHRyYSBmb3IgaG9sZGluZyBmcmFnZW1lbnQgcGFyYW1ldGVyIGFuZCBxdWVyeVBhcmFtcyBmb3IgbW9kdWxlIHVybC5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvbkRhdGFFeHRyYXMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZnJhZ21lbnQgc3RyaW5nIGZvciBtb2R1bGUgaWYgYW55LlxyXG4gICAgICovXHJcbiAgICBmcmFnbWVudD86IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBxdWVyeSBwYXJhbWV0ZXJzIGZvciBtb2R1bGUgaWYgYW55LlxyXG4gICAgICovXHJcbiAgICBxdWVyeVBhcmFtcz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGUgbmF2aWdhdGlvbiBkYXRhIHRvIG5hdmlnYXRlIGluc2lkZSBvZiBtb2R1bGUuXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIE5hdmlnYXRpb25EYXRhIHtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIG5hdmlnYXRpb24gY29tbWFuZHMgKHBhdGggc2VnbWVudHMpLlxyXG4gICAgICovXHJcbiAgICBjb21tYW5kczogc3RyaW5nW107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbmF2aWdhdGlvbiBkYXRhIGV4dHJhcyBmb3IgbW9kdWxlLlxyXG4gICAgICovXHJcbiAgICBvcHRpb25zOiBOYXZpZ2F0aW9uRGF0YUV4dHJhcztcclxufVxyXG5cclxuLyoqXHJcbiAqIFN0YXRpYyBmdW5jdGlvbiBuYW1lIGZvciB0aGUgbmF2aWdhdGlvbiB0aXRsZSBmdW5jdGlvbiBpbiBhIGNvbXBvbmVudCBjbGFzc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IG5hdmlnYXRpb25UaXRsZUZ1bmN0aW9uTmFtZSA9ICduYXZpZ2F0aW9uVGl0bGUnO1xyXG5cclxuLyoqXHJcbiAqIE5hdmlnYXRpb24gVGl0bGUgRnVuY3Rpb24gUmV0dXJuIHR5cGVcclxuICovXHJcbmV4cG9ydCB0eXBlIE5hdmlnYXRpb25UaXRsZSA9IHN0cmluZyB8IFNlbGVjdGFibGVQYXRoW10gfCBPYnNlcnZhYmxlPFNlbGVjdGFibGVQYXRoW10+O1xyXG5cclxuLyoqXHJcbiAqIENhbGxiYWNrIGZvciBkYXRhLnRpdGxlIHByb3BlcnR5IGluIHJvdXRlciBjb25maWd1cmF0aW9uLlxyXG4gKi9cclxuaW50ZXJmYWNlIE5hdmlnYXRpb25UaXRsZURhdGEge1xyXG4gICAgdGl0bGU6IHN0cmluZyB8ICgoYXBwQ29udGV4dFNlcnZpY2U6IEFwcENvbnRleHRTZXJ2aWNlLCBjaGlsZFJvdXRlcjogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCkgPT4gc3RyaW5nIHwgU2VsZWN0YWJsZVBhdGhbXSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBOYXZpZ2F0aW9uIGNsYXNzIHRvIHByb3ZpZGUgc2V0IG9mIHN0YXRpYyBoZWxwZXIgZnVuY3Rpb25zLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIE5hdmlnYXRpb24ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdXJsIG9wdGlvbnMgZm9yIGdhdGV3YXkgYW5kIGNvbm5lY3Rpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgZ2F0ZXdheVVybCA9ICdnYXRld2F5VXJsJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSB1cmwgb3B0aW9ucyBmb3IgdmVyc2lvbiBvZiBzdGF0aWMgY29udGVudC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBzdGF0aWNWZXJzaW9uID0gJ3N0YXRpY1ZlcnNpb24nO1xyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIHB1c2hTdGF0ZUJhY2t1cDogYW55ID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFR1cm4gb2ZmIGJyb3dzZXIgaGlzdG9yeSBwdXNoLlxyXG4gICAgICogLSBpbnN0ZWFkIHNlbmRpbmcgYWxsIHBhdGggY2hhbmdlIHRvIHRoZSBTaGVsbCB0byBjcmVhdGUgaGlzdG9yeS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyB0dXJuT2ZmSGlzdG9yeSgpOiB2b2lkIHtcclxuICAgICAgICBpZiAod2luZG93Lmhpc3RvcnkucHVzaFN0YXRlICE9PSBNc2Z0U21lLm5vb3ApIHtcclxuICAgICAgICAgICAgTmF2aWdhdGlvbi5wdXNoU3RhdGVCYWNrdXAgPSB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGU7XHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuaGlzdG9yeSwgJ3B1c2hTdGF0ZScsIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlOiBNc2Z0U21lLm5vb3BcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVHVybiBvbiBicm93c2VyIGhpc3RvcnkgcHVzaC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyB0dXJuT25IaXN0b3J5KCk6IHZvaWQge1xyXG4gICAgICAgIGlmIChOYXZpZ2F0aW9uLnB1c2hTdGF0ZUJhY2t1cCAmJiB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUgPT09IE1zZnRTbWUubm9vcCkge1xyXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93Lmhpc3RvcnksICdwdXNoU3RhdGUnLCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogTmF2aWdhdGlvbi5wdXNoU3RhdGVCYWNrdXBcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFyZSB0d28gdXJscyBieSByZW1vdmluZyBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB1cmwxIHRoZSB1cmwgdG8gY29tcGFyZS5cclxuICAgICAqIEBwYXJhbSB1cmwyIHRoZSB1cmwgdG8gY29tcGFyZS5cclxuICAgICAqIEByZXR1cm4gYm9vbGVhbiB0cnVlIGlmIG1hdGNoZXMuIG51bGwgdXJsIHJldHVybnMgZmFsc2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgYXJlRXF1YWxVcmwodXJsMTogc3RyaW5nLCB1cmwyOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodXJsMSA9PSBudWxsIHx8IHVybDIgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gTmF2aWdhdGlvbi50cmltU2xhc2godXJsMSkgPT09IE5hdmlnYXRpb24udHJpbVNsYXNoKHVybDIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFyZSB0d28gdXJscyBmb3IgbnVtYmVyIG9mIHNlZ21lbnRzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB1cmwxIHRoZSB1cmwgdG8gY29tcGFyZS5cclxuICAgICAqIEBwYXJhbSB1cmwyIHRoZSB1cmwgdG8gY29tcGFyZS5cclxuICAgICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHNlZ21lbnRzIHRvIGNvbXBhcmUuXHJcbiAgICAgKiBAcmV0dXJuIGJvb2xlYW4gdHJ1ZSBpZiBtYXRjaGVzIGZvciBudW1iZXIgb2Ygc2VnbWVudHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgYXJlRXF1YWxTZWdtZW50cyh1cmwxOiBzdHJpbmcsIHVybDI6IHN0cmluZywgY291bnQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh1cmwxID09IG51bGwgfHwgdXJsMiA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHNlZ21lbnRzMSA9IE5hdmlnYXRpb24udHJpbVNsYXNoKHVybDEpLnNwbGl0KCcvJyk7XHJcbiAgICAgICAgY29uc3Qgc2VnbWVudHMyID0gTmF2aWdhdGlvbi50cmltU2xhc2godXJsMikuc3BsaXQoJy8nKTtcclxuXHJcbiAgICAgICAgaWYgKHNlZ21lbnRzMS5sZW5ndGggPCBjb3VudCB8fCBzZWdtZW50czIubGVuZ3RoIDwgY291bnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWdtZW50czFbaV0gIT09IHNlZ21lbnRzMltpXSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRyaW0gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gdXJsIHRoZSB1cmwgdG8gdHJpbSBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzLlxyXG4gICAgICogQHJldHVybnMgdGhlIHVwZGF0ZWQgdXJsLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHN0YXRpYyB0cmltU2xhc2godXJsOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICh1cmwgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdXJsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHVybC5sZW5ndGggPiAwICYmIHVybFswXSA9PT0gJy8nKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybC5zdWJzdHJpbmcoMSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodXJsLmxlbmd0aCA+IDAgJiYgdXJsW3VybC5sZW5ndGggLSAxXSA9PT0gJy8nKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybC5zdWJzdHJpbmcoMCwgdXJsLmxlbmd0aCAtIDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHVybDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB1cmwgc2VnbWVudHMgY29tYmluZWQgbW9kdWxlIG5hbWUgYW5kIHBhdGggb2YgZW50cnkgcG9pbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIG1vZHVsZU5hbWUgdGhlIG1vZHVsZSBuYW1lLlxyXG4gICAgICogQHBhcmFtIGVudHJ5UG9pbnROYW1lIHRoZSBuYW1lIG9mIGVudHJ5IHBvaW50LlxyXG4gICAgICogQHJldHVybiB0aGUgdXJsIHNlZ21lbnRzLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGdldE1vZHVsZUVudHJ5UG9pbnRVcmxTZWdtZW50KG1vZHVsZU5hbWU6IHN0cmluZywgZW50cnlQb2ludE5hbWU/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiBgJHttb2R1bGVOYW1lfSEke2VudHJ5UG9pbnROYW1lfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCdWlsZHMgc2VsZWN0YWJsZSBwYXRocyBmcm9tIHRoZSBnaXZlbiByb3V0ZS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gYXBwQ29udGV4dFNlcnZpY2UgVGhlIGFwcGxpY2F0aW9uIGNvbnRleHQgc2VydmljZSBvYmplY3QuXHJcbiAgICAgKiBAcGFyYW0gcm91dGUgVGhlIHJvdXRlIHRvIGV4dHJhY3QgdGhlIGJyZWFkY3J1bWIgZm9yXHJcbiAgICAgKiBAcGFyYW0gcGF0aFByZWZpeCBUaGUgcHJlZml4IHRvIHByZXBlbmQgdG8gdGhlIHJvdXRlIHBhdGhcclxuICAgICAqIEByZXR1cm4gU2VsZWN0YWJsZVBhdGhbXSB0aGUgc2VsZWN0YWJsZSBwYXRocy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBidWlsZFNlbGVjdGFibGVQYXRoc0ZvclJvdXRlKFxyXG4gICAgICAgIGFwcENvbnRleHRTZXJ2aWNlOiBBcHBDb250ZXh0U2VydmljZSxcclxuICAgICAgICByb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcclxuICAgICAgICBwYXRoUHJlZml4Pzogc3RyaW5nKTogT2JzZXJ2YWJsZTxTZWxlY3RhYmxlUGF0aFtdPiB7XHJcbiAgICAgICAgY29uc3QgYXN5bmNBcnJheTogT2JzZXJ2YWJsZTxTZWxlY3RhYmxlUGF0aFtdPltdID0gW107XHJcbiAgICAgICAgY29uc3QgY2hpbGRyZW5RdWV1ZSA9IHJvdXRlLmNoaWxkcmVuLnNsaWNlKDApO1xyXG4gICAgICAgIHBhdGhQcmVmaXggPSBwYXRoUHJlZml4ID8gcGF0aFByZWZpeCA6ICcnO1xyXG5cclxuICAgICAgICB3aGlsZSAoY2hpbGRyZW5RdWV1ZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIC8vIHdlIGFyZSBvbmx5IGludGVyZXN0ZWQgaW4gcHJpbWFyeSByb3V0ZXMgdGhhdCBoYXZlIGEgZGlzcGxheU5hbWUgYXQgdGhpcyB0aW1lXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW5RdWV1ZS5zaGlmdCgpO1xyXG4gICAgICAgICAgICBpZiAoY2hpbGQub3V0bGV0ID09PSBQUklNQVJZX09VVExFVCkge1xyXG4gICAgICAgICAgICAgICAgLy8gYXBwZW5kIHRoZSByb3V0ZXMgVVJMIHNlZ21lbnRcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNlZ21lbnRQYXRoID0gY2hpbGQudXJsXHJcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihzZWcxID0+IHNlZzEgJiYgc2VnMS5wYXRoICYmIHNlZzEucGF0aC5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoc2VnMiA9PiBzZWcyLnBhdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgLmpvaW4oJy8nKTtcclxuICAgICAgICAgICAgICAgIGlmIChzZWdtZW50UGF0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgYWRkIGEgc2VnbWVudCBpZiB0aGVyZSdzIGFueSB2YWx1YWJsZSBpbmZvcm1hdGlvbiB0byBpdC5cclxuICAgICAgICAgICAgICAgICAgICBwYXRoUHJlZml4ID0gTG9jYXRpb24uam9pbldpdGhTbGFzaChwYXRoUHJlZml4LCBzZWdtZW50UGF0aCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdDogTmF2aWdhdGlvblRpdGxlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5jb21wb25lbnQgJiYgY2hpbGQuY29tcG9uZW50W25hdmlnYXRpb25UaXRsZUZ1bmN0aW9uTmFtZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgbGFiZWwgY2FuIGJlIG51bGwgdG8gaW5kaWNhdGUgaWYgaXQncyBob21lIHBhZ2UgYWNjZXNzLlxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNoaWxkLmNvbXBvbmVudFtuYXZpZ2F0aW9uVGl0bGVGdW5jdGlvbk5hbWVdKGFwcENvbnRleHRTZXJ2aWNlLCBjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgT2JzZXJ2YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2JzZXJ2YWJsZSBxdWVyeS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzeW5jQXJyYXkucHVzaChyZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm5lZCBhcyBhcnJheS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGhzOiBTZWxlY3RhYmxlUGF0aFtdID0gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmNBcnJheS5wdXNoKG9mKHBhdGhzKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldHVybmVkIGFzIHN0cmluZy5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGFibGVQYXRoOiBTZWxlY3RhYmxlUGF0aCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGhQcmVmaXhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3luY0FycmF5LnB1c2gob2YoW3NlbGVjdGFibGVQYXRoXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IE1zZnRTbWUuZ2V0U3RyaW5nczxTdHJpbmdzPigpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLk1zZnRTbWVTaGVsbC5Bbmd1bGFyLk5hdmlnYXRpb24uTmF2aWdhdGlvblRpdGxlUmV0dXJuVHlwZUVycm9yLm1lc3NhZ2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGNvbnRpbnVlIGJ1aWxkaW5nIHJlY3Vyc2l2ZWx5XHJcbiAgICAgICAgICAgIGNoaWxkLmNoaWxkcmVuLmZvckVhY2goZ3JhbmRDaGlsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZ3JhbmRDaGlsZC5vdXRsZXQgPT09IFBSSU1BUllfT1VUTEVUKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5RdWV1ZS5wdXNoKGdyYW5kQ2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmb3JrSm9pbihhc3luY0FycmF5KS5waXBlKG1hcChyZXN1bHRBcnJheSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdDogU2VsZWN0YWJsZVBhdGhbXSA9IFtdO1xyXG4gICAgICAgICAgICByZXN1bHRBcnJheS5mb3JFYWNoKChpdGVtcywgaW5kZXgsIGFycmF5KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE5hdmlnYXRlIHRvIHRoZSBjb25uZWN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSByb3V0ZXIgdGhlIHJvdXRlci5cclxuICAgICAqIEBwYXJhbSBjb25uZWN0aW9uIHRoZSBjb25uZWN0aW9uIG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBuYXZpZ2F0ZUNvbm5lY3Rpb24ocm91dGVyOiBSb3V0ZXIsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICBjb25zdCB0eXBlSW5mbyA9IEVudmlyb25tZW50TW9kdWxlLmdldENvbm5lY3Rpb25UeXBlSW5mbyhjb25uZWN0aW9uLnR5cGUpO1xyXG4gICAgICAgIGNvbnN0IG1vZHVsZUVudHJ5U2VnbWVudCA9IE5hdmlnYXRpb24uZ2V0TW9kdWxlRW50cnlQb2ludFVybFNlZ21lbnQodHlwZUluZm8uc29sdXRpb24ucGFyZW50TW9kdWxlLm5hbWUsIHR5cGVJbmZvLnNvbHV0aW9uLm5hbWUpO1xyXG4gICAgICAgIGNvbnN0IHJvb3RFbnRyeVNlZ21lbnQgPSBOYXZpZ2F0aW9uLmdldE1vZHVsZUVudHJ5UG9pbnRVcmxTZWdtZW50KFxyXG4gICAgICAgICAgICB0eXBlSW5mby5zb2x1dGlvbi5wYXJlbnRNb2R1bGUubmFtZSwgdHlwZUluZm8uc29sdXRpb24udG9vbHMuZGVmYXVsdFRvb2wpO1xyXG4gICAgICAgIGNvbnN0IHBhdGhTZWdtZW50czogc3RyaW5nW10gPSBbJ3NvbHV0aW9ucycsIG1vZHVsZUVudHJ5U2VnbWVudCwgJ3Rvb2xzJywgcm9vdEVudHJ5U2VnbWVudF07XHJcbiAgICAgICAgcmV0dXJuIHJvdXRlci5uYXZpZ2F0ZShwYXRoU2VnbWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IG5hdmlnYXRpb24gVVJMIGJ5IHNvbHV0aW9uL25hbWUsIG1vZHVsZS9uYW1lLCBjb25uZWN0aW9uL25hbWUgYW5kIGNvbm5lY3Rpb24vdHlwZS5cclxuICAgICAqXHJcbiAgICAgKiAoZXguXHJcbiAgICAgKiAgICAtIC9cclxuICAgICAqICAgIC0gL21zZnQuc21lLnNlcnZlci1tYW5hZ2VyIXNlcnZlcnNcclxuICAgICAqICAgIC0gL21zZnQuc21lLnNlcnZlci1tYW5hZ2VyIXNlcnZlcnMvdG9vbHMvbXNmdC5zbWUuc2VydmVyLW1hbmFnZXIhb3ZlcnZpZXdcclxuICAgICAqICAgIC0gL21zZnQuc21lLnNlcnZlci1tYW5hZ2VyIXNlcnZlcnMgK1xyXG4gICAgICogICAgICAgICAgL2Nvbm5lY3Rpb25zL21zZnQuc21lLmNvbm5lY3Rpb24tdHlwZS5zZXJ2ZXIvc21lLWZ1bGwxLnJlZG1vbmQuY29ycC5taWNyb3NvZnQuY29tICtcclxuICAgICAqICAgICAgICAgIC90b29scy9tc2Z0LnNtZS5zZXJ2ZXItbWFuYWdlciFvdmVydmlldylcclxuICAgICAqIEBwYXJhbSBkYXRhIHRoZSBSUEMgc2hlbGwgbmF2aWdhdGUgZGF0YS5cclxuICAgICAqIEByZXR1cm4gc3RyaW5nIHRoZSB1cmwgdG8gbmF2aWdhdGUgdG8gdGhlIHRvb2wuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0TmF2aWdhdGlvblVybEZvclRvb2xFbnRyeVBvaW50KGRhdGE6IFJwY1NoZWxsTmF2aWdhdGUpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmIChkYXRhLm5hdmlnYXRlTmV4dCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZGF0YS5uYXZpZ2F0ZU5leHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZGF0YS5zZXR0aW5ncykge1xyXG4gICAgICAgICAgICBsZXQgc2V0dGluZ3NVcmwgPSBgL3NldHRpbmdzYDtcclxuICAgICAgICAgICAgaWYgKGRhdGEuc2V0dGluZ3MubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3NVcmwgKz0gYC8ke2RhdGEuc2V0dGluZ3MubmFtZX1gO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZGF0YS5zZXR0aW5ncy5uZXN0ZWRVcmxBbmRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5nc1VybCArPSBkYXRhLnNldHRpbmdzLm5lc3RlZFVybEFuZE9wdGlvbnM7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzZXR0aW5nc1VybDtcclxuICAgICAgICB9IGVsc2UgaWYgKCFkYXRhLnNvbHV0aW9uIHx8ICFkYXRhLnNvbHV0aW9uLm1vZHVsZU5hbWUpIHtcclxuICAgICAgICAgICAgLy8gbm8gc29sdXRpb24gZ29lcyB0byByb290IChob21lcGFnZSlcclxuICAgICAgICAgICAgcmV0dXJuICcvJztcclxuICAgICAgICB9IGVsc2UgaWYgKCFkYXRhLnNvbHV0aW9uLmVudHJ5UG9pbnROYW1lKSB7XHJcbiAgICAgICAgICAgIC8vIGl0IHJlcXVpcmVzIGVudHJ5UG9pbnROYW1lLlxyXG4gICAgICAgICAgICBMb2dnaW5nLmxvZ0Vycm9yKCduYXZpZ2F0aW9uJywgJ0FyZ3VtZW50IGVycm9yOiBlbnRyeVBvaW50TmFtZSBvZiB0aGUgc29sdXRpb24gaXMgcmVxdWlyZWQuJyk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHVybCA9IGAvJHtkYXRhLnNvbHV0aW9uLm1vZHVsZU5hbWV9ISR7ZGF0YS5zb2x1dGlvbi5lbnRyeVBvaW50TmFtZX1gO1xyXG4gICAgICAgIGlmIChkYXRhLmNvbm5lY3Rpb24pIHtcclxuICAgICAgICAgICAgaWYgKCFkYXRhLmNvbm5lY3Rpb24ubmFtZSB8fCAhZGF0YS5jb25uZWN0aW9uLnR5cGUpIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbm5lY3Rpb24gbGlzdCBmb3IgZW1wdHkgY29ubmVjdGlvbiBsaWtlICdkYXRhLmNvbm5lY3Rpb24gPT09IHt9J1xyXG4gICAgICAgICAgICAgICAgdXJsICs9ICcvY29ubmVjdGlvbnMnO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVybDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdXJsICs9IGAvY29ubmVjdGlvbnMvJHtkYXRhLmNvbm5lY3Rpb24udHlwZX0vJHtkYXRhLmNvbm5lY3Rpb24ubmFtZX1gO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYWxsb3cgdG8gbmF2aWdhdGUgaW5zaWRlIG9mIHNvbHV0aW9uIGp1c3QgYnkgdG9vbCBuYW1lLCBzbyBkYXRhLmNvbm5lY3Rpb24gPT0gbnVsbCBpcyBleHBlY3RlZC5cclxuICAgICAgICBpZiAoZGF0YS50b29sKSB7XHJcbiAgICAgICAgICAgIGlmIChkYXRhLnRvb2wubW9kdWxlTmFtZSAmJiAhZGF0YS50b29sLmVudHJ5UG9pbnROYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpdCByZXF1aXJlcyBlbnRyeVBvaW50TmFtZS5cclxuICAgICAgICAgICAgICAgIExvZ2dpbmcubG9nRXJyb3IoJ25hdmlnYXRpb24nLCAnQXJndW1lbnQgZXJyb3I6IGVudHJ5UG9pbnROYW1lIG9mIHRoZSB0b29sIGlzIHJlcXVpcmVkLicpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHVybCArPSBgL3Rvb2xzLyR7ZGF0YS50b29sLm1vZHVsZU5hbWV9ISR7ZGF0YS50b29sLmVudHJ5UG9pbnROYW1lfWA7XHJcbiAgICAgICAgfSBlbHNlIGlmIChkYXRhLmNvbm5lY3Rpb25TZXR0aW5ncykge1xyXG4gICAgICAgICAgICB1cmwgKz0gJy90b29scy9zZXR0aW5ncyc7XHJcbiAgICAgICAgICAgIGlmIChkYXRhLmNvbm5lY3Rpb25TZXR0aW5ncy50YWJVcmxOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICB1cmwgKz0gYC8ke2RhdGEuY29ubmVjdGlvblNldHRpbmdzLnRhYlVybE5hbWV9YDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGRhdGEudG9vbE5lc3RlZFVybEFuZE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdXJsICs9IGRhdGEudG9vbE5lc3RlZFVybEFuZE9wdGlvbnM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IG5hdmlnYXRpb24gZXh0cmEgZGF0YSBmcm9tIGN1cnJlbnQgYWN0aXZhdGVkIHJvdXRlIG9uIHNoZWxsLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSByb3V0ZSB0aGUgYWN0aXZhdGVkIHJvdXRlLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGdldFVybE5hdmlnYXRpb25EYXRhRXh0cmFzKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSk6IE5hdmlnYXRpb25EYXRhRXh0cmFzIHtcclxuICAgICAgICBjb25zdCBzbmFwc2hvdCA9IHJvdXRlLnNuYXBzaG90O1xyXG4gICAgICAgIGNvbnN0IGZyYWdtZW50ID0gc25hcHNob3QucXVlcnlQYXJhbU1hcC5nZXQoJ2ZyYWdtZW50Jyk7XHJcbiAgICAgICAgbGV0IHF1ZXJ5UGFyYW1zID0gbnVsbDtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCBxdWVyeSA9IHNuYXBzaG90LnF1ZXJ5UGFyYW1NYXAuZ2V0KCdxdWVyeVBhcmFtcycpO1xyXG4gICAgICAgICAgICBpZiAocXVlcnkpIHtcclxuICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW1zID0gSlNPTi5wYXJzZShxdWVyeSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4geyBmcmFnbWVudCwgcXVlcnlQYXJhbXMgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgbmF2aWdhdGlvbiBkYXRhIGZyb20gdGhlIHBhdGggb24gbW9kdWxlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSByb3V0ZXIgdGhlIFJvdXRlciBvYmplY3QuXHJcbiAgICAgKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCBVUkkgd2l0aCBtb2R1bGUuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0VXJsTmF2aWdhdGlvbkRhdGEocm91dGVyOiBSb3V0ZXIsIHBhdGg6IHN0cmluZyk6IE5hdmlnYXRpb25EYXRhIHtcclxuICAgICAgICBjb25zdCB1cmxUcmVlID0gcm91dGVyLnBhcnNlVXJsKHBhdGgpO1xyXG4gICAgICAgIGNvbnN0IG9wdGlvbnM6IE5hdmlnYXRpb25EYXRhRXh0cmFzID0ge1xyXG4gICAgICAgICAgICBmcmFnbWVudDogdXJsVHJlZS5mcmFnbWVudCxcclxuICAgICAgICAgICAgcXVlcnlQYXJhbXM6IHVybFRyZWUucXVlcnlQYXJhbXNcclxuICAgICAgICB9O1xyXG4gICAgICAgIHVybFRyZWUuZnJhZ21lbnQgPSBudWxsO1xyXG4gICAgICAgIHVybFRyZWUucXVlcnlQYXJhbXMgPSB7fTtcclxuICAgICAgICBjb25zdCByb290UGF0aCA9IHVybFRyZWUudG9TdHJpbmcoKTtcclxuICAgICAgICBjb25zdCByb290UGF0aFRyaW1tZWQgPSBOYXZpZ2F0aW9uLnRyaW1TbGFzaChyb290UGF0aCk7XHJcbiAgICAgICAgY29uc3QgY29tbWFuZHM6IHN0cmluZ1tdID0gcm9vdFBhdGhUcmltbWVkID09PSAnJyA/IFsnJ10gOiByb290UGF0aFRyaW1tZWQuc3BsaXQoJy8nKTtcclxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY29tbWFuZHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgIC8vIGRlY29kZVVSSSB0byBwYXNzaW5nIHBhcmFtZXRlcnMgdG8gbW9kdWxlIHBhdGguXHJcbiAgICAgICAgICAgIGNvbW1hbmRzW2luZGV4XSA9IGRlY29kZVVSSShjb21tYW5kc1tpbmRleF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHsgY29tbWFuZHMsIG9wdGlvbnMgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgbmF2aWdhdGlvbiBxdWVyeVBhcmFtcyBvbiBzaGVsbC9tb2R1bGUuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGRhdGFFeHRyYXMgVGhlIG5hdmlnYXRpb24gZGF0YSBleHRyYXMgb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMgdGhlIHBhcmFtcyBkYXRhIGZvciByb3V0ZXIgbmF2aWdhdGlvbiBjYWxsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGdldFVybFF1ZXJ5UGFyYW1zKGRhdGFFeHRyYXM6IE5hdmlnYXRpb25EYXRhRXh0cmFzKTogUGFyYW1zIHtcclxuICAgICAgICBjb25zdCBwYXJhbXM6IFBhcmFtcyA9IHt9O1xyXG4gICAgICAgIGlmIChkYXRhRXh0cmFzLmZyYWdtZW50KSB7XHJcbiAgICAgICAgICAgIHBhcmFtcy5mcmFnbWVudCA9IGRhdGFFeHRyYXMuZnJhZ21lbnQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZGF0YUV4dHJhcy5xdWVyeVBhcmFtcyAmJiBPYmplY3Qua2V5cyhkYXRhRXh0cmFzLnF1ZXJ5UGFyYW1zKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHBhcmFtcy5xdWVyeVBhcmFtcyA9IEpTT04uc3RyaW5naWZ5KGRhdGFFeHRyYXMucXVlcnlQYXJhbXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHBhcmFtcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCBzZXJpYWxpemVkIHRoZSBkYXRhIGV4dHJhcyBvYmplY3QgaW50byB1cmwgc3RyaW5nLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBuYXZpZ2F0aW9uIGRhdGEgZXh0cmFzIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHRoZSBVUkwgc3RyaW5nLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGdldFVybFNlcmlhbGl6ZWREYXRhRXh0cmFzKG9wdGlvbnM6IE5hdmlnYXRpb25EYXRhRXh0cmFzKTogc3RyaW5nIHtcclxuICAgICAgICBsZXQgZXh0cmEgPSAnJztcclxuICAgICAgICBpZiAob3B0aW9ucy5xdWVyeVBhcmFtcykge1xyXG4gICAgICAgICAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKG9wdGlvbnMucXVlcnlQYXJhbXMpO1xyXG4gICAgICAgICAgICBrZXlzID0ga2V5cy5zb3J0KCk7XHJcbiAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5LCBpbmRleCkgPT4gZXh0cmEgKz0gYCR7aW5kZXggPT09IDAgPyAnPycgOiAnJid9JHtrZXl9PSR7b3B0aW9ucy5xdWVyeVBhcmFtc1trZXldfWApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuZnJhZ21lbnQpIHtcclxuICAgICAgICAgICAgZXh0cmEgKz0gYCMke29wdGlvbnMuZnJhZ21lbnR9YDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBleHRyYTtcclxuICAgIH1cclxufVxyXG4iXX0=