@singleton-i18n/angular-client
Version:
Singleton client code for Angular 10.
213 lines • 28 kB
JavaScript
/*
* Copyright 2019-2021 VMware, Inc.
* SPDX-License-Identifier: EPL-2.0
*/
import { Injectable } from '@angular/core';
import { getNameSpace } from '../config';
import { LocaleService } from './locale.service';
import { isDefined } from '../util';
import { filterArgs } from '../extensions/stringable';
import { MessageFormat } from '../formatters/message.formatter';
import { BaseService } from './base.service';
import { VIPService } from './vip.service';
import { VIPServiceConstants } from '../constants';
import { I18nContext } from './i18n.context';
const pseudoTag = '@@';
export class L10nService extends BaseService {
constructor(vipService, localeService, messageFormat, i18nContext) {
super(vipService, localeService);
this.vipService = vipService;
this.localeService = localeService;
this.messageFormat = messageFormat;
this.i18nContext = i18nContext;
}
/**
* Generate long key with namespace.
* @param config
* @param key raw key
*/
getLongKey(config, key) {
const nameSpace = config ? getNameSpace(config) : undefined;
return nameSpace ? nameSpace
.concat(VIPServiceConstants.NAME_SPACE_SEPARATOR)
.concat(key) : key;
}
/**
* In the mutiple component situation, the namespace is necessary.
* Default workspace the main component in root scope and each lazy scope.
* @param key raw key with namespace
*/
parseKey(key) {
let nameSpace;
let rawKey = key;
if (key && key.indexOf(VIPServiceConstants.NAME_SPACE_SEPARATOR) > -1) {
const parts = key.split(VIPServiceConstants.NAME_SPACE_SEPARATOR);
nameSpace = parts[0];
rawKey = parts[1];
}
nameSpace = nameSpace ? nameSpace : getNameSpace(this.vipService.mainConfig);
return { rawKey: rawKey, nameSpace: nameSpace };
}
/**
* If translation is certainly be loaded before application bootstrap, the locale can be
* skipped, otherwise make sure getting available locale from the return of stream API.
* @param nameSpace
* @param locale
*/
resolveLocaleData(nameSpace, locale) {
let localeData;
let translations;
const currentLocale = locale ? locale : this.currentLocale;
localeData = this.vipService.localeData[currentLocale];
translations = localeData && localeData.messages &&
localeData.messages[nameSpace] ? localeData.messages[nameSpace] : undefined;
return translations;
}
/**
* Register source bundles to the main configuration on demand.
* For the isolated module (separated lib), the namespace is required.
* Considering using the last item of the array for the configuration or new API instead.
* @param args Source bundle objects from Angular component.
*/
registerSourceBundles(...args) {
if (args) {
this.vipService.registerSourceBundles(args, this.vipService.mainConfig);
}
}
/**
* Get source string via key with namespace
* @param key raw key with namespace
*/
getSourceString(key) {
if (typeof key !== 'string') {
return undefined;
}
const l10nKey = this.parseKey(key);
const sourceBundle = this.resolveLocaleData(l10nKey.nameSpace, this.localeService.defaultLocale.languageCode);
if (sourceBundle && sourceBundle[l10nKey.rawKey]) {
// If the corresponding value of key is an array containing source and comment
if (Array.isArray(sourceBundle[l10nKey.rawKey])) {
// prevent empty array
if (sourceBundle[l10nKey.rawKey][0]) {
return sourceBundle[l10nKey.rawKey][0];
}
}
else {
return sourceBundle[l10nKey.rawKey];
}
console.error('No English found for key: %s in sourceBundle', key);
}
return key;
}
/**
* Determine whether the key already exists in the sourceBundles or translation.
* if the locale is source locale, check whether the key exists in sourceBundles.
* if the locale is not source locale, check whether the key exists in translation.
* @param key raw key with namespace
* @param locale
*/
isExistKey(key, locale) {
const l10nKey = this.parseKey(key);
if (this.localeService.isSourceLanguage) {
locale = this.localeService.defaultLocale.languageCode;
}
else {
locale = locale ? locale : this.currentLocale;
}
// sourceBundle or translations
const resourceBundle = this.resolveLocaleData(l10nKey.nameSpace, locale);
const isExist = resourceBundle && resourceBundle[l10nKey.rawKey] ? true : false;
return isExist;
}
formatMessage(isFallback, locale, message, args) {
if (isFallback) {
locale = this.localeService.defaultLocale.languageCode;
}
return this.messageFormat.format(locale, message, args);
}
/**
* @param key raw key with namespace
* @param source source string for translation
* @param args variables for placeholders
* @param locale work with steam API
*/
translate(key, source, args, locale) {
let translation;
let isFallback;
const l10nKey = this.parseKey(key);
if (this.localeService.isSourceLanguage) {
translation = source;
}
else {
locale = locale ? locale : this.currentLocale;
const translations = this.resolveLocaleData(l10nKey.nameSpace, locale);
translation = translations ? translations[l10nKey.rawKey] : undefined;
if (!translation || translation === '') {
translation = source;
const pseudoInConfig = this.vipService.mainConfig && this.vipService.mainConfig.isPseudo;
const i18nEnabled = this.i18nContext.i18nEnabled !== false;
if (pseudoInConfig && i18nEnabled) {
translation = `${pseudoTag}${source}${pseudoTag}`;
}
isFallback = true;
}
}
if (translation && translation.trim() !== '') {
translation = this.formatMessage(isFallback, locale, translation, args);
}
return translation;
}
/**
* @param key raw key with namespace
* @param args variables and comment
* @param locale optinal parameter for live update through 'stream' API
*/
getMessage(key, args, locale) {
if (typeof key !== 'string') {
return undefined;
}
if (!isDefined(key)) {
return null;
}
// Detect whether existing Object in args Array, if exist, convert them into strings
args = filterArgs(args);
const source = this.getSourceString(key);
const translation = this.translate(key, source, args, locale);
return translation;
}
/**
* This API is designed to generate scoped translate method for the isolated module.
* The key with namespace which is generated by the configuration.
* @param config The VIP configuration with product name, component name and version.
*/
getScopedTranslate(config) {
return (key, args, locale) => {
const longKey = this.getLongKey(config, key);
return this.getMessage(longKey, args, locale);
};
}
/**
* getSplitedMessage
* get message array splited by the seperator
* @param key raw key with namespace
* @param args variables
* @param locale optinal parameter for live update through 'stream' API
* @param seperator is a regular expressions, default value is /##\d+/
*/
getSplitedMessage(key, args, locale, seperator) {
const message = this.getMessage(key, args, locale);
const defaultSeperator = /##\d+/;
seperator = isDefined(seperator) ? seperator : defaultSeperator;
return message.split(seperator);
}
}
L10nService.decorators = [
{ type: Injectable }
];
L10nService.ctorParameters = () => [
{ type: VIPService },
{ type: LocaleService },
{ type: MessageFormat },
{ type: I18nContext }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDEwbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3JsaWdlbmcvUHJvamVjdHMvRGV2b3BzL0NsaWVudF9Bbmd1bGFyX0dpdEh1Yl9OcG1qcy92aXAvY2kvcHViMm9yZy9DbGllbnRfQW5ndWxhcl9HaXRIdWJfTnBtanMvc2luZ2xldG9uL3Byb2plY3RzL2FuZ3VsYXItY2xpZW50LyIsInNvdXJjZXMiOlsic3JjL3NlcnZpY2VzL2wxMG4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQWEsTUFBTSxXQUFXLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBYyxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQztBQVV2QixNQUFNLE9BQU8sV0FBWSxTQUFRLFdBQVc7SUFDeEMsWUFDYyxVQUFzQixFQUN0QixhQUE0QixFQUM5QixhQUE0QixFQUM1QixXQUF3QjtRQUVoQyxLQUFLLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBTHZCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDOUIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7SUFHcEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxVQUFVLENBQUMsTUFBaUIsRUFBRSxHQUFXO1FBQzVDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDNUQsT0FBTyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDdkIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDO2FBQ2hELE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssUUFBUSxDQUFDLEdBQVc7UUFDeEIsSUFBSSxTQUFpQixDQUFDO1FBQ3RCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNqQixJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDbkUsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2xFLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNyQjtRQUNELFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0UsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLGlCQUFpQixDQUFDLFNBQWlCLEVBQUUsTUFBZTtRQUN2RCxJQUFJLFVBQXNCLENBQUM7UUFDM0IsSUFBSSxZQUFpQixDQUFDO1FBQ3RCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQzNELFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN2RCxZQUFZLEdBQUcsVUFBVSxJQUFJLFVBQVUsQ0FBQyxRQUFRO1lBQzVDLFVBQVUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNoRixPQUFPLFlBQVksQ0FBQztJQUN4QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxxQkFBcUIsQ0FBQyxHQUFHLElBQTBCO1FBQ3RELElBQUksSUFBSSxFQUFFO1lBQ04sSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUMzRTtJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSSxlQUFlLENBQUMsR0FBVztRQUM5QixJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUFFLE9BQU8sU0FBUyxDQUFDO1NBQUU7UUFDbEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFDekQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDbkQsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM5Qyw4RUFBOEU7WUFDOUUsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtnQkFDN0Msc0JBQXNCO2dCQUN0QixJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2pDLE9BQU8sWUFBWSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDMUM7YUFDSjtpQkFBTTtnQkFDSCxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDdkM7WUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3RFO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksVUFBVSxDQUFDLEdBQVcsRUFBRSxNQUFlO1FBQzFDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFO1lBQ3JDLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUM7U0FDMUQ7YUFBTTtZQUNILE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztTQUNqRDtRQUNELCtCQUErQjtRQUMvQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN6RSxNQUFNLE9BQU8sR0FBRyxjQUFjLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDaEYsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxVQUFtQixFQUFFLE1BQWMsRUFBRSxPQUFlLEVBQUUsSUFBb0I7UUFDNUYsSUFBSSxVQUFVLEVBQUU7WUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDO1NBQUU7UUFDM0UsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFNBQVMsQ0FBQyxHQUFXLEVBQUUsTUFBYyxFQUFFLElBQWlCLEVBQUUsTUFBZTtRQUM1RSxJQUFJLFdBQW1CLENBQUM7UUFDeEIsSUFBSSxVQUFtQixDQUFDO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFO1lBQ3JDLFdBQVcsR0FBRyxNQUFNLENBQUM7U0FDeEI7YUFBTTtZQUNILE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztZQUM5QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RSxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDdEUsSUFBSSxDQUFDLFdBQVcsSUFBSSxXQUFXLEtBQUssRUFBRSxFQUFFO2dCQUNwQyxXQUFXLEdBQUcsTUFBTSxDQUFDO2dCQUNyQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7Z0JBQ3pGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxLQUFLLEtBQUssQ0FBQztnQkFDM0QsSUFBSSxjQUFjLElBQUksV0FBVyxFQUFFO29CQUMvQixXQUFXLEdBQUcsR0FBRyxTQUFTLEdBQUcsTUFBTSxHQUFHLFNBQVMsRUFBRSxDQUFDO2lCQUNyRDtnQkFDRCxVQUFVLEdBQUcsSUFBSSxDQUFDO2FBQ3JCO1NBQ0o7UUFDRCxJQUFJLFdBQVcsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQzFDLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzNFO1FBQ0QsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxVQUFVLENBQUMsR0FBVyxFQUFFLElBQWlCLEVBQUUsTUFBZTtRQUM3RCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUFFLE9BQU8sU0FBUyxDQUFDO1NBQUU7UUFDbEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNqQixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsb0ZBQW9GO1FBQ3BGLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFeEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzlELE9BQU8sV0FBVyxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksa0JBQWtCLENBQUMsTUFBaUI7UUFDdkMsT0FBTyxDQUFDLEdBQVcsRUFBRSxJQUFpQixFQUFFLE1BQWUsRUFBRSxFQUFFO1lBQ3ZELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzdDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksaUJBQWlCLENBQUMsR0FBVyxFQUFFLElBQVksRUFBRSxNQUFlLEVBQUUsU0FBa0I7UUFDbkYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDO1FBQ2pDLFNBQVMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUM7UUFDaEUsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7OztZQWpNSixVQUFVOzs7WUFiRixVQUFVO1lBTFYsYUFBYTtZQUdiLGFBQWE7WUFJYixXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDE5LTIwMjEgVk13YXJlLCBJbmMuXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBnZXROYW1lU3BhY2UsIFZJUENvbmZpZyB9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBMb2NhbGVTZXJ2aWNlIH0gZnJvbSAnLi9sb2NhbGUuc2VydmljZSc7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7IGZpbHRlckFyZ3MgfSBmcm9tICcuLi9leHRlbnNpb25zL3N0cmluZ2FibGUnO1xuaW1wb3J0IHsgTWVzc2FnZUZvcm1hdCB9IGZyb20gJy4uL2Zvcm1hdHRlcnMvbWVzc2FnZS5mb3JtYXR0ZXInO1xuaW1wb3J0IHsgQmFzZVNlcnZpY2UgfSBmcm9tICcuL2Jhc2Uuc2VydmljZSc7XG5pbXBvcnQgeyBWSVBTZXJ2aWNlLCBMb2NhbGVEYXRhIH0gZnJvbSAnLi92aXAuc2VydmljZSc7XG5pbXBvcnQgeyBWSVBTZXJ2aWNlQ29uc3RhbnRzIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEkxOG5Db250ZXh0IH0gZnJvbSAnLi9pMThuLmNvbnRleHQnO1xuXG5jb25zdCBwc2V1ZG9UYWcgPSAnQEAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEwxME5LZXkge1xuICAgIHJhd0tleTogc3RyaW5nO1xuICAgIG5hbWVTcGFjZTogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBzb3VyY2VCdW5kbGVPYmplY3QgPSB7IFtrZXk6IHN0cmluZ106IGFueSB9O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTDEwblNlcnZpY2UgZXh0ZW5kcyBCYXNlU2VydmljZSB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByb3RlY3RlZCB2aXBTZXJ2aWNlOiBWSVBTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgbG9jYWxlU2VydmljZTogTG9jYWxlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBtZXNzYWdlRm9ybWF0OiBNZXNzYWdlRm9ybWF0LFxuICAgICAgICBwcml2YXRlIGkxOG5Db250ZXh0OiBJMThuQ29udGV4dFxuICAgICkge1xuICAgICAgICBzdXBlcih2aXBTZXJ2aWNlLCBsb2NhbGVTZXJ2aWNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBsb25nIGtleSB3aXRoIG5hbWVzcGFjZS5cbiAgICAgKiBAcGFyYW0gY29uZmlnXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5XG4gICAgICovXG4gICAgcHVibGljIGdldExvbmdLZXkoY29uZmlnOiBWSVBDb25maWcsIGtleTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG5hbWVTcGFjZSA9IGNvbmZpZyA/IGdldE5hbWVTcGFjZShjb25maWcpIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbmFtZVNwYWNlID8gbmFtZVNwYWNlXG4gICAgICAgICAgICAuY29uY2F0KFZJUFNlcnZpY2VDb25zdGFudHMuTkFNRV9TUEFDRV9TRVBBUkFUT1IpXG4gICAgICAgICAgICAuY29uY2F0KGtleSkgOiBrZXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW4gdGhlIG11dGlwbGUgY29tcG9uZW50IHNpdHVhdGlvbiwgdGhlIG5hbWVzcGFjZSBpcyBuZWNlc3NhcnkuXG4gICAgICogRGVmYXVsdCB3b3Jrc3BhY2UgdGhlIG1haW4gY29tcG9uZW50IGluIHJvb3Qgc2NvcGUgYW5kIGVhY2ggbGF6eSBzY29wZS5cbiAgICAgKiBAcGFyYW0ga2V5IHJhdyBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKi9cbiAgICBwcml2YXRlIHBhcnNlS2V5KGtleTogc3RyaW5nKTogTDEwTktleSB7XG4gICAgICAgIGxldCBuYW1lU3BhY2U6IHN0cmluZztcbiAgICAgICAgbGV0IHJhd0tleSA9IGtleTtcbiAgICAgICAgaWYgKGtleSAmJiBrZXkuaW5kZXhPZihWSVBTZXJ2aWNlQ29uc3RhbnRzLk5BTUVfU1BBQ0VfU0VQQVJBVE9SKSA+IC0xKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGtleS5zcGxpdChWSVBTZXJ2aWNlQ29uc3RhbnRzLk5BTUVfU1BBQ0VfU0VQQVJBVE9SKTtcbiAgICAgICAgICAgIG5hbWVTcGFjZSA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgcmF3S2V5ID0gcGFydHNbMV07XG4gICAgICAgIH1cbiAgICAgICAgbmFtZVNwYWNlID0gbmFtZVNwYWNlID8gbmFtZVNwYWNlIDogZ2V0TmFtZVNwYWNlKHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnKTtcbiAgICAgICAgcmV0dXJuIHsgcmF3S2V5OiByYXdLZXksIG5hbWVTcGFjZTogbmFtZVNwYWNlIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdHJhbnNsYXRpb24gaXMgY2VydGFpbmx5IGJlIGxvYWRlZCBiZWZvcmUgYXBwbGljYXRpb24gYm9vdHN0cmFwLCB0aGUgbG9jYWxlIGNhbiBiZVxuICAgICAqIHNraXBwZWQsIG90aGVyd2lzZSBtYWtlIHN1cmUgZ2V0dGluZyBhdmFpbGFibGUgbG9jYWxlIGZyb20gdGhlIHJldHVybiBvZiBzdHJlYW0gQVBJLlxuICAgICAqIEBwYXJhbSBuYW1lU3BhY2VcbiAgICAgKiBAcGFyYW0gbG9jYWxlXG4gICAgICovXG4gICAgcHVibGljIHJlc29sdmVMb2NhbGVEYXRhKG5hbWVTcGFjZTogc3RyaW5nLCBsb2NhbGU/OiBzdHJpbmcpIHtcbiAgICAgICAgbGV0IGxvY2FsZURhdGE6IExvY2FsZURhdGE7XG4gICAgICAgIGxldCB0cmFuc2xhdGlvbnM6IGFueTtcbiAgICAgICAgY29uc3QgY3VycmVudExvY2FsZSA9IGxvY2FsZSA/IGxvY2FsZSA6IHRoaXMuY3VycmVudExvY2FsZTtcbiAgICAgICAgbG9jYWxlRGF0YSA9IHRoaXMudmlwU2VydmljZS5sb2NhbGVEYXRhW2N1cnJlbnRMb2NhbGVdO1xuICAgICAgICB0cmFuc2xhdGlvbnMgPSBsb2NhbGVEYXRhICYmIGxvY2FsZURhdGEubWVzc2FnZXMgJiZcbiAgICAgICAgICAgIGxvY2FsZURhdGEubWVzc2FnZXNbbmFtZVNwYWNlXSA/IGxvY2FsZURhdGEubWVzc2FnZXNbbmFtZVNwYWNlXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRyYW5zbGF0aW9ucztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBzb3VyY2UgYnVuZGxlcyB0byB0aGUgbWFpbiBjb25maWd1cmF0aW9uIG9uIGRlbWFuZC5cbiAgICAgKiBGb3IgdGhlIGlzb2xhdGVkIG1vZHVsZSAoc2VwYXJhdGVkIGxpYiksIHRoZSBuYW1lc3BhY2UgaXMgcmVxdWlyZWQuXG4gICAgICogQ29uc2lkZXJpbmcgdXNpbmcgdGhlIGxhc3QgaXRlbSBvZiB0aGUgYXJyYXkgZm9yIHRoZSBjb25maWd1cmF0aW9uIG9yIG5ldyBBUEkgaW5zdGVhZC5cbiAgICAgKiBAcGFyYW0gYXJncyBTb3VyY2UgYnVuZGxlIG9iamVjdHMgZnJvbSBBbmd1bGFyIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVnaXN0ZXJTb3VyY2VCdW5kbGVzKC4uLmFyZ3M6IHNvdXJjZUJ1bmRsZU9iamVjdFtdKSB7XG4gICAgICAgIGlmIChhcmdzKSB7XG4gICAgICAgICAgICB0aGlzLnZpcFNlcnZpY2UucmVnaXN0ZXJTb3VyY2VCdW5kbGVzKGFyZ3MsIHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBzb3VyY2Ugc3RyaW5nIHZpYSBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKiBAcGFyYW0ga2V5IHJhdyBrZXkgd2l0aCBuYW1lc3BhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0U291cmNlU3RyaW5nKGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICAgICAgY29uc3QgbDEwbktleSA9IHRoaXMucGFyc2VLZXkoa2V5KTtcbiAgICAgICAgY29uc3Qgc291cmNlQnVuZGxlID0gdGhpcy5yZXNvbHZlTG9jYWxlRGF0YShsMTBuS2V5Lm5hbWVTcGFjZSxcbiAgICAgICAgICAgIHRoaXMubG9jYWxlU2VydmljZS5kZWZhdWx0TG9jYWxlLmxhbmd1YWdlQ29kZSk7XG4gICAgICAgIGlmIChzb3VyY2VCdW5kbGUgJiYgc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XSkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2Yga2V5IGlzIGFuIGFycmF5IGNvbnRhaW5pbmcgc291cmNlIGFuZCBjb21tZW50XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldKSkge1xuICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgZW1wdHkgYXJyYXlcbiAgICAgICAgICAgICAgICBpZiAoc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XVswXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlQnVuZGxlW2wxMG5LZXkucmF3S2V5XVswXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignTm8gRW5nbGlzaCBmb3VuZCBmb3Iga2V5OiAlcyBpbiBzb3VyY2VCdW5kbGUnLCBrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGtleSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgc291cmNlQnVuZGxlcyBvciB0cmFuc2xhdGlvbi5cbiAgICAgKiBpZiB0aGUgbG9jYWxlIGlzIHNvdXJjZSBsb2NhbGUsIGNoZWNrIHdoZXRoZXIgdGhlIGtleSBleGlzdHMgaW4gc291cmNlQnVuZGxlcy5cbiAgICAgKiBpZiB0aGUgbG9jYWxlIGlzIG5vdCBzb3VyY2UgbG9jYWxlLCBjaGVjayB3aGV0aGVyIHRoZSBrZXkgZXhpc3RzIGluIHRyYW5zbGF0aW9uLlxuICAgICAqIEBwYXJhbSBrZXkgcmF3IGtleSB3aXRoIG5hbWVzcGFjZVxuICAgICAqIEBwYXJhbSBsb2NhbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFeGlzdEtleShrZXk6IHN0cmluZywgbG9jYWxlPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGwxMG5LZXkgPSB0aGlzLnBhcnNlS2V5KGtleSk7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZVNlcnZpY2UuaXNTb3VyY2VMYW5ndWFnZSkge1xuICAgICAgICAgICAgbG9jYWxlID0gdGhpcy5sb2NhbGVTZXJ2aWNlLmRlZmF1bHRMb2NhbGUubGFuZ3VhZ2VDb2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlID8gbG9jYWxlIDogdGhpcy5jdXJyZW50TG9jYWxlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNvdXJjZUJ1bmRsZSBvciB0cmFuc2xhdGlvbnNcbiAgICAgICAgY29uc3QgcmVzb3VyY2VCdW5kbGUgPSB0aGlzLnJlc29sdmVMb2NhbGVEYXRhKGwxMG5LZXkubmFtZVNwYWNlLCBsb2NhbGUpO1xuICAgICAgICBjb25zdCBpc0V4aXN0ID0gcmVzb3VyY2VCdW5kbGUgJiYgcmVzb3VyY2VCdW5kbGVbbDEwbktleS5yYXdLZXldID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICByZXR1cm4gaXNFeGlzdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvcm1hdE1lc3NhZ2UoaXNGYWxsYmFjazogYm9vbGVhbiwgbG9jYWxlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgYXJncz86IHN0cmluZ1tdIHwge30pIHtcbiAgICAgICAgaWYgKGlzRmFsbGJhY2spIHsgbG9jYWxlID0gdGhpcy5sb2NhbGVTZXJ2aWNlLmRlZmF1bHRMb2NhbGUubGFuZ3VhZ2VDb2RlOyB9XG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2VGb3JtYXQuZm9ybWF0KGxvY2FsZSwgbWVzc2FnZSwgYXJncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHNvdXJjZSBzb3VyY2Ugc3RyaW5nIGZvciB0cmFuc2xhdGlvblxuICAgICAqIEBwYXJhbSBhcmdzIHZhcmlhYmxlcyBmb3IgcGxhY2Vob2xkZXJzXG4gICAgICogQHBhcmFtIGxvY2FsZSB3b3JrIHdpdGggc3RlYW0gQVBJXG4gICAgICovXG4gICAgcHVibGljIHRyYW5zbGF0ZShrZXk6IHN0cmluZywgc291cmNlOiBzdHJpbmcsIGFyZ3M/OiBhbnlbXSB8IHt9LCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBsZXQgdHJhbnNsYXRpb246IHN0cmluZztcbiAgICAgICAgbGV0IGlzRmFsbGJhY2s6IGJvb2xlYW47XG4gICAgICAgIGNvbnN0IGwxMG5LZXkgPSB0aGlzLnBhcnNlS2V5KGtleSk7XG4gICAgICAgIGlmICh0aGlzLmxvY2FsZVNlcnZpY2UuaXNTb3VyY2VMYW5ndWFnZSkge1xuICAgICAgICAgICAgdHJhbnNsYXRpb24gPSBzb3VyY2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUgPyBsb2NhbGUgOiB0aGlzLmN1cnJlbnRMb2NhbGU7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSB0aGlzLnJlc29sdmVMb2NhbGVEYXRhKGwxMG5LZXkubmFtZVNwYWNlLCBsb2NhbGUpO1xuICAgICAgICAgICAgdHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvbnMgPyB0cmFuc2xhdGlvbnNbbDEwbktleS5yYXdLZXldIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKCF0cmFuc2xhdGlvbiB8fCB0cmFuc2xhdGlvbiA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGlvbiA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBwc2V1ZG9JbkNvbmZpZyA9IHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnICYmIHRoaXMudmlwU2VydmljZS5tYWluQ29uZmlnLmlzUHNldWRvO1xuICAgICAgICAgICAgICAgIGNvbnN0IGkxOG5FbmFibGVkID0gdGhpcy5pMThuQ29udGV4dC5pMThuRW5hYmxlZCAhPT0gZmFsc2U7XG4gICAgICAgICAgICAgICAgaWYgKHBzZXVkb0luQ29uZmlnICYmIGkxOG5FbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uID0gYCR7cHNldWRvVGFnfSR7c291cmNlfSR7cHNldWRvVGFnfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzRmFsbGJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2xhdGlvbiAmJiB0cmFuc2xhdGlvbi50cmltKCkgIT09ICcnKSB7XG4gICAgICAgICAgICB0cmFuc2xhdGlvbiA9IHRoaXMuZm9ybWF0TWVzc2FnZShpc0ZhbGxiYWNrLCBsb2NhbGUsIHRyYW5zbGF0aW9uLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIGFyZ3MgdmFyaWFibGVzIGFuZCBjb21tZW50XG4gICAgICogQHBhcmFtIGxvY2FsZSBvcHRpbmFsIHBhcmFtZXRlciBmb3IgbGl2ZSB1cGRhdGUgdGhyb3VnaCAnc3RyZWFtJyBBUElcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0TWVzc2FnZShrZXk6IHN0cmluZywgYXJncz86IGFueVtdIHwge30sIGxvY2FsZT86IHN0cmluZykge1xuICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICBpZiAoIWlzRGVmaW5lZChrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERldGVjdCB3aGV0aGVyIGV4aXN0aW5nIE9iamVjdCBpbiBhcmdzIEFycmF5LCBpZiBleGlzdCwgY29udmVydCB0aGVtIGludG8gc3RyaW5nc1xuICAgICAgICBhcmdzID0gZmlsdGVyQXJncyhhcmdzKTtcblxuICAgICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmdldFNvdXJjZVN0cmluZyhrZXkpO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHRoaXMudHJhbnNsYXRlKGtleSwgc291cmNlLCBhcmdzLCBsb2NhbGUpO1xuICAgICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBBUEkgaXMgZGVzaWduZWQgdG8gZ2VuZXJhdGUgc2NvcGVkIHRyYW5zbGF0ZSBtZXRob2QgZm9yIHRoZSBpc29sYXRlZCBtb2R1bGUuXG4gICAgICogVGhlIGtleSB3aXRoIG5hbWVzcGFjZSB3aGljaCBpcyBnZW5lcmF0ZWQgYnkgdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAgICogQHBhcmFtIGNvbmZpZyBUaGUgVklQIGNvbmZpZ3VyYXRpb24gd2l0aCBwcm9kdWN0IG5hbWUsIGNvbXBvbmVudCBuYW1lIGFuZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTY29wZWRUcmFuc2xhdGUoY29uZmlnOiBWSVBDb25maWcpOiBGdW5jdGlvbiB7XG4gICAgICAgIHJldHVybiAoa2V5OiBzdHJpbmcsIGFyZ3M/OiBhbnlbXSB8IHt9LCBsb2NhbGU/OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxvbmdLZXkgPSB0aGlzLmdldExvbmdLZXkoY29uZmlnLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShsb25nS2V5LCBhcmdzLCBsb2NhbGUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldFNwbGl0ZWRNZXNzYWdlXG4gICAgICogZ2V0IG1lc3NhZ2UgYXJyYXkgc3BsaXRlZCBieSB0aGUgc2VwZXJhdG9yXG4gICAgICogQHBhcmFtIGtleSByYXcga2V5IHdpdGggbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIGFyZ3MgdmFyaWFibGVzXG4gICAgICogQHBhcmFtIGxvY2FsZSBvcHRpbmFsIHBhcmFtZXRlciBmb3IgbGl2ZSB1cGRhdGUgdGhyb3VnaCAnc3RyZWFtJyBBUElcbiAgICAgKiBAcGFyYW0gc2VwZXJhdG9yIGlzIGEgcmVndWxhciBleHByZXNzaW9ucywgZGVmYXVsdCB2YWx1ZSBpcyAvIyNcXGQrL1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTcGxpdGVkTWVzc2FnZShrZXk6IHN0cmluZywgYXJncz86IGFueVtdLCBsb2NhbGU/OiBzdHJpbmcsIHNlcGVyYXRvcj86IFJlZ0V4cCkge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5nZXRNZXNzYWdlKGtleSwgYXJncywgbG9jYWxlKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdFNlcGVyYXRvciA9IC8jI1xcZCsvO1xuICAgICAgICBzZXBlcmF0b3IgPSBpc0RlZmluZWQoc2VwZXJhdG9yKSA/IHNlcGVyYXRvciA6IGRlZmF1bHRTZXBlcmF0b3I7XG4gICAgICAgIHJldHVybiBtZXNzYWdlLnNwbGl0KHNlcGVyYXRvcik7XG4gICAgfVxufVxuIl19