UNPKG

@singleton-i18n/angular-client

Version:

Singleton client code for Angular 10.

305 lines 32.2 kB
/* * Copyright 2019-2021 VMware, Inc. * SPDX-License-Identifier: EPL-2.0 */ import { NgModule, Pipe, Injectable } from '@angular/core'; import { Directive, ElementRef, Input } from '@angular/core'; import { Subject, BehaviorSubject, of } from 'rxjs'; import { DateFormatter } from './src/formatters/date.formatter'; import { L10nService } from './src/services/l10n.service'; import { I18nService } from './src/services/i18n.service'; import { VIPService } from './src/services/vip.service'; import { PatternCategories, getNameSpace } from './src/config'; import { VIPServiceConstants } from './src/constants'; import { isDefined } from './src/util'; export class MockL10nPipe { transform(key, value) { const args = []; for (let i = 2; i < arguments.length; i++) { args[i - 2] = arguments[i]; } return L10nFormat(value, args); } } MockL10nPipe.decorators = [ { type: Pipe, args: [{ name: 'translate' },] } ]; export class MockL10nPipePlus { constructor(l10nService) { this.l10nService = l10nService; } transform(key, ...args) { if (typeof key !== 'string') { return undefined; } if (!isDefined(key)) { return null; } const source = this.l10nService.getSourceString(key); // If source is undefined return key. Avoid error due to source parsing in L10nFormat. if (!source) { return key; } return L10nFormat(source, args); } } MockL10nPipePlus.decorators = [ { type: Pipe, args: [{ name: 'vtranslate' },] } ]; MockL10nPipePlus.ctorParameters = () => [ { type: L10nService } ]; export class MockCurrencyPipe { transform(value, currency) { return { 'USD': '$', }[currency] + value; } } MockCurrencyPipe.decorators = [ { type: Pipe, args: [{ name: 'currencyFormat' },] } ]; export class MockDatePipe { transform(value, format) { const date = new Date(value); return { 'medium': `${date.getUTCMonth()}/${date.getUTCDate()}/${date.getUTCFullYear()}`, 'short': `${date.getUTCMonth()}/${date.getUTCDate()}/${date.getUTCFullYear()}`, }[format] || value; } } MockDatePipe.decorators = [ { type: Pipe, args: [{ name: 'dateFormat' },] } ]; export class MockNumberFormatPipe { transform(value, locale) { return value + ''; } } MockNumberFormatPipe.decorators = [ { type: Pipe, args: [{ name: 'numberFormat' },] } ]; export class MockL10nDirective { constructor(el, l10nService) { this.el = el; this.l10nService = l10nService; } ngAfterViewInit() { if (!isDefined(this.l10n)) { throw Error('key error'); } const source = isDefined(this.source) ? this.source : this.l10nService.getSourceString(this.l10n); // If source is undefined return key. Avoid error due to source parsing in L10nFormat. this.el.nativeElement.textContent = source ? L10nFormat(source, this.params) : this.l10n; } } MockL10nDirective.decorators = [ { type: Directive, args: [{ selector: '[l10n]' },] } ]; MockL10nDirective.ctorParameters = () => [ { type: ElementRef }, { type: L10nService } ]; MockL10nDirective.propDecorators = { l10n: [{ type: Input, args: ['l10n',] }], source: [{ type: Input }], comment: [{ type: Input }], params: [{ type: Input }] }; export class TranslationLoader { getTranslationByComponent(url) { return Promise.resolve('mock'); } } export class VIPServiceMock { constructor(translationLoader) { this.mainConfig = {}; this.translationLoader = translationLoader; } initData(initData) { this.mainConfig = initData; // there's really no need to ever call this return Promise.resolve('mock'); } registerComponent(config, isMain = false) { return; } getLocale() { return 'en_US'; } localeData() { return {}; } getI18nScope() { return [ PatternCategories.CURRENCIES, PatternCategories.DATE, PatternCategories.NUMBER, PatternCategories.PLURAL, ]; } } VIPServiceMock.decorators = [ { type: Injectable } ]; VIPServiceMock.ctorParameters = () => [ { type: TranslationLoader } ]; export class BaseDataServiceMock { constructor() { this.coreService = { onTranslationChange: new Subject(), }; this.currentLocale = 'en-US'; this.current = new BehaviorSubject(this.currentLocale); this.stream = new BehaviorSubject(this.currentLocale); this.onLocaleChange = new BehaviorSubject(this.currentLocale); } } export class L10nServiceMock extends BaseDataServiceMock { constructor() { super(); } getLongKey(config, key) { const nameSpace = config ? getNameSpace(config) : undefined; return nameSpace ? nameSpace .concat(VIPServiceConstants.NAME_SPACE_SEPARATOR) .concat(key) : key; } translate(key, value, args, comment) { return L10nFormat(value, args); } getTranslation(key, source, args, comment) { return of(this.translate(key, source, args)); } getMessage(key, args) { if (typeof key !== 'string') { return undefined; } if (!isDefined(key)) { return null; } const source = this.getSourceString(key); // If source is undefined return key. Avoid error due to source parsing in L10nFormat. if (!source) { return key; } const translation = this.translate(key, source, args); return translation; } // Todo: add method to register sourceBundle under certain namespace. getSourceString(key) { return undefined; } registerSourceBundles(...args) { } } export class I18nServiceMock extends BaseDataServiceMock { constructor() { super(); } formatCurrency(value, currencyCode) { return { 'USD': '$', }[currencyCode] + value; } formatDate(value, pattern, timezone) { return value; } formatNumber(value, locale) { return value + ''; } formatPercent(value, locale) { return value; } getLocalizedPattern(pattern, locale) { return { 'shortTime': 'h:mm a', 'mediumTime': 'h:mm:ss a', 'longTime': 'h:mm:ss z', 'fullTime': 'h:mm:ss zzzz', 'shortDate': 'M/d/yy', 'mediumDate': 'MMM d, y', 'longDate': 'MMMM d, y', 'fullDate': 'EEEE, MMMM d, y', 'short': 'M/d/yy, h:mm a', 'medium': 'MMM d, y, h:mm:ss a', 'long': 'MMMM d, y, h:mm:ss a z', 'full': 'EEEE, MMMM d, y, h:mm:ss a zzzz', }[pattern]; } } export class VIPModuleMock { /** * Use this method in your root module to provide the mocked VIP Service * @static * @returns {ModuleWithProviders} * @memberof VIPModule */ static forRoot() { return { ngModule: VIPModuleMock, providers: [ TranslationLoader, DateFormatter, { provide: VIPService, useClass: VIPServiceMock }, { provide: L10nService, useClass: L10nServiceMock }, { provide: I18nService, useClass: I18nServiceMock }, ] }; } } VIPModuleMock.decorators = [ { type: NgModule, args: [{ imports: [], declarations: [ MockL10nPipe, MockL10nPipePlus, MockL10nDirective, MockCurrencyPipe, MockDatePipe, MockNumberFormatPipe, ], exports: [ MockL10nPipe, MockL10nPipePlus, MockL10nDirective, MockCurrencyPipe, MockDatePipe, MockNumberFormatPipe, ] },] } ]; export function L10nFormat(message, args) { if (message.indexOf('=0') > -1 || message.indexOf('=1') > -1) { let substr, wordNumber; switch (args[0]) { case 0: substr = '=0'; wordNumber = ""; break; case 1: substr = '=1'; wordNumber = "one"; break; default: substr = 'other'; wordNumber = args[0].toString(); break; } const startSubstr = message.indexOf(substr) + substr.length + 1; return message.substring(startSubstr, message.indexOf('}', startSubstr)).replace('#', wordNumber); } const templateMatcher = /{\s?([\d]*)\s?}/g; if (args && args.length) { const strings = [].concat(...args); // args could be an array of arrays, or just an array so flatten for (let i = 0; i < strings.length; i++) { message = message.replace(templateMatcher, function (substring, b) { return (b.trim() === i.toString() && strings[i] != null) ? strings[i] : substring; }); } } return message.trim(); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlwLm1vZHVsZS5tb2NrLmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3JsaWdlbmcvUHJvamVjdHMvRGV2b3BzL0NsaWVudF9Bbmd1bGFyX0dpdEh1Yl9OcG1qcy92aXAvY2kvcHViMm9yZy9DbGllbnRfQW5ndWxhcl9HaXRIdWJfTnBtanMvc2luZ2xldG9uL3Byb2plY3RzL2FuZ3VsYXItY2xpZW50LyIsInNvdXJjZXMiOlsidmlwLm1vZHVsZS5tb2NrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUNILE9BQU8sRUFBdUIsUUFBUSxFQUFFLElBQUksRUFBaUIsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDNUUsT0FBTyxFQUFjLE9BQU8sRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWhFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzFELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQWEsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFHdkMsTUFBTSxPQUFPLFlBQVk7SUFDckIsU0FBUyxDQUFDLEdBQVcsRUFBRSxLQUFhO1FBQ2hDLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0s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QyxPQUFPLENBQUMsZUFBZSxFQUFFLFVBQVUsU0FBaUIsRUFBRSxDQUFTO2dCQUM3RSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3RGLENBQUMsQ0FBQyxDQUFDO1NBQ047S0FDSjtJQUNELE9BQU8sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQzFCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTktMjAyMSBWTXdhcmUsIEluYy5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wXG4gKi9cbmltcG9ydCB7IE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlLCBQaXBlLCBQaXBlVHJhbnNmb3JtLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBBZnRlclZpZXdJbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBCZWhhdmlvclN1YmplY3QsIG9mIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IERhdGVGb3JtYXR0ZXIgfSBmcm9tICcuL3NyYy9mb3JtYXR0ZXJzL2RhdGUuZm9ybWF0dGVyJztcbmltcG9ydCB7IEwxMG5TZXJ2aWNlIH0gZnJvbSAnLi9zcmMvc2VydmljZXMvbDEwbi5zZXJ2aWNlJztcbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnLi9zcmMvc2VydmljZXMvaTE4bi5zZXJ2aWNlJztcbmltcG9ydCB7IFZJUFNlcnZpY2UgfSBmcm9tICcuL3NyYy9zZXJ2aWNlcy92aXAuc2VydmljZSc7XG5pbXBvcnQgeyBQYXR0ZXJuQ2F0ZWdvcmllcywgVklQQ29uZmlnLCBnZXROYW1lU3BhY2UgfSBmcm9tICcuL3NyYy9jb25maWcnO1xuaW1wb3J0IHsgVklQU2VydmljZUNvbnN0YW50cyB9IGZyb20gJy4vc3JjL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tICcuL3NyYy91dGlsJztcblxuQFBpcGUoeyBuYW1lOiAndHJhbnNsYXRlJyB9KVxuZXhwb3J0IGNsYXNzIE1vY2tMMTBuUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIHRyYW5zZm9ybShrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDI7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDJdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBMMTBuRm9ybWF0KHZhbHVlLCBhcmdzKTtcbiAgICB9XG59XG5cbkBQaXBlKHsgbmFtZTogJ3Z0cmFuc2xhdGUnIH0pXG5leHBvcnQgY2xhc3MgTW9ja0wxMG5QaXBlUGx1cyBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbDEwblNlcnZpY2U6IEwxMG5TZXJ2aWNlKSB7IH1cbiAgICB0cmFuc2Zvcm0oa2V5OiBzdHJpbmcsIC4uLmFyZ3M6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICAgICAgaWYgKCFpc0RlZmluZWQoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5sMTBuU2VydmljZS5nZXRTb3VyY2VTdHJpbmcoa2V5KTtcbiAgICAgICAgLy8gSWYgc291cmNlIGlzIHVuZGVmaW5lZCByZXR1cm4ga2V5LiBBdm9pZCBlcnJvciBkdWUgdG8gc291cmNlIHBhcnNpbmcgaW4gTDEwbkZvcm1hdC5cbiAgICAgICAgaWYgKCFzb3VyY2UpIHsgcmV0dXJuIGtleTsgfVxuICAgICAgICByZXR1cm4gTDEwbkZvcm1hdChzb3VyY2UsIGFyZ3MpO1xuICAgIH1cbn1cblxuQFBpcGUoeyBuYW1lOiAnY3VycmVuY3lGb3JtYXQnIH0pXG5leHBvcnQgY2xhc3MgTW9ja0N1cnJlbmN5UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIHRyYW5zZm9ybSh2YWx1ZTogc3RyaW5nLCBjdXJyZW5jeTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICdVU0QnOiAnJCcsXG4gICAgICAgIH1bY3VycmVuY3ldICsgdmFsdWU7XG4gICAgfVxufVxuXG5AUGlwZSh7IG5hbWU6ICdkYXRlRm9ybWF0JyB9KVxuZXhwb3J0IGNsYXNzIE1vY2tEYXRlUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIHRyYW5zZm9ybSh2YWx1ZTogc3RyaW5nLCBmb3JtYXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAnbWVkaXVtJzogYCR7ZGF0ZS5nZXRVVENNb250aCgpfS8ke2RhdGUuZ2V0VVRDRGF0ZSgpfS8ke2RhdGUuZ2V0VVRDRnVsbFllYXIoKX1gLFxuICAgICAgICAgICAgJ3Nob3J0JzogYCR7ZGF0ZS5nZXRVVENNb250aCgpfS8ke2RhdGUuZ2V0VVRDRGF0ZSgpfS8ke2RhdGUuZ2V0VVRDRnVsbFllYXIoKX1gLFxuICAgICAgICB9W2Zvcm1hdF0gfHwgdmFsdWU7XG4gICAgfVxufVxuXG5AUGlwZSh7IG5hbWU6ICdudW1iZXJGb3JtYXQnIH0pXG5leHBvcnQgY2xhc3MgTW9ja051bWJlckZvcm1hdFBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcbiAgICB0cmFuc2Zvcm0odmFsdWU6IGFueSwgbG9jYWxlPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgJyc7XG4gICAgfVxufVxuXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1tsMTBuXSdcbn0pXG5leHBvcnQgY2xhc3MgTW9ja0wxMG5EaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcblxuICAgIEBJbnB1dCgnbDEwbicpIGwxMG46IHN0cmluZztcbiAgICBASW5wdXQoKSBzb3VyY2U6IHN0cmluZztcbiAgICBASW5wdXQoKSBjb21tZW50OiBzdHJpbmc7XG4gICAgQElucHV0KCkgcGFyYW1zOiBzdHJpbmdbXTtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBwcml2YXRlIGwxMG5TZXJ2aWNlOiBMMTBuU2VydmljZSkgeyB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIGlmICghaXNEZWZpbmVkKHRoaXMubDEwbikpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdrZXkgZXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBpc0RlZmluZWQodGhpcy5zb3VyY2UpID8gdGhpcy5zb3VyY2UgOiB0aGlzLmwxMG5TZXJ2aWNlLmdldFNvdXJjZVN0cmluZyh0aGlzLmwxMG4pO1xuICAgICAgICAvLyBJZiBzb3VyY2UgaXMgdW5kZWZpbmVkIHJldHVybiBrZXkuIEF2b2lkIGVycm9yIGR1ZSB0byBzb3VyY2UgcGFyc2luZyBpbiBMMTBuRm9ybWF0LlxuICAgICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQudGV4dENvbnRlbnQgPSBzb3VyY2UgPyBMMTBuRm9ybWF0KHNvdXJjZSwgdGhpcy5wYXJhbXMpIDogdGhpcy5sMTBuO1xuICAgIH1cblxufVxuXG5cbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvbkxvYWRlciB7XG4gICAgZ2V0VHJhbnNsYXRpb25CeUNvbXBvbmVudCh1cmw6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoJ21vY2snKTtcbiAgICB9XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBWSVBTZXJ2aWNlTW9jayB7XG4gICAgcHJpdmF0ZSB0cmFuc2xhdGlvbkxvYWRlcjogVHJhbnNsYXRpb25Mb2FkZXI7XG4gICAgcHVibGljIG1haW5Db25maWc6IGFueSA9IHt9O1xuXG4gICAgY29uc3RydWN0b3IodHJhbnNsYXRpb25Mb2FkZXI6IFRyYW5zbGF0aW9uTG9hZGVyKSB7XG4gICAgICAgIHRoaXMudHJhbnNsYXRpb25Mb2FkZXIgPSB0cmFuc2xhdGlvbkxvYWRlcjtcbiAgICB9XG5cbiAgICBpbml0RGF0YShpbml0RGF0YTogVklQQ29uZmlnKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgdGhpcy5tYWluQ29uZmlnID0gaW5pdERhdGE7XG4gICAgICAgIC8vIHRoZXJlJ3MgcmVhbGx5IG5vIG5lZWQgdG8gZXZlciBjYWxsIHRoaXNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgnbW9jaycpO1xuICAgIH1cblxuICAgIHJlZ2lzdGVyQ29tcG9uZW50KGNvbmZpZzogVklQQ29uZmlnLCBpc01haW46IGJvb2xlYW4gPSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZ2V0TG9jYWxlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiAnZW5fVVMnO1xuICAgIH1cblxuICAgIGxvY2FsZURhdGEoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBnZXRJMThuU2NvcGUoKTogUGF0dGVybkNhdGVnb3JpZXNbXSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBQYXR0ZXJuQ2F0ZWdvcmllcy5DVVJSRU5DSUVTLFxuICAgICAgICAgICAgUGF0dGVybkNhdGVnb3JpZXMuREFURSxcbiAgICAgICAgICAgIFBhdHRlcm5DYXRlZ29yaWVzLk5VTUJFUixcbiAgICAgICAgICAgIFBhdHRlcm5DYXRlZ29yaWVzLlBMVVJBTCxcbiAgICAgICAgXTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCYXNlRGF0YVNlcnZpY2VNb2NrIHtcbiAgICBjb3JlU2VydmljZSA9IHtcbiAgICAgICAgb25UcmFuc2xhdGlvbkNoYW5nZTogbmV3IFN1YmplY3QoKSxcbiAgICB9O1xuICAgIGN1cnJlbnRMb2NhbGUgPSAnZW4tVVMnO1xuXG4gICAgY3VycmVudCA9IG5ldyBCZWhhdmlvclN1YmplY3QodGhpcy5jdXJyZW50TG9jYWxlKTtcbiAgICBzdHJlYW0gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHRoaXMuY3VycmVudExvY2FsZSk7XG4gICAgb25Mb2NhbGVDaGFuZ2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KHRoaXMuY3VycmVudExvY2FsZSk7XG59XG5cbnR5cGUgc291cmNlQnVuZGxlT2JqZWN0ID0geyBba2V5OiBzdHJpbmddOiBhbnkgfTtcblxuZXhwb3J0IGNsYXNzIEwxMG5TZXJ2aWNlTW9jayBleHRlbmRzIEJhc2VEYXRhU2VydmljZU1vY2sge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIGdldExvbmdLZXkoY29uZmlnOiBWSVBDb25maWcsIGtleTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG5hbWVTcGFjZSA9IGNvbmZpZyA/IGdldE5hbWVTcGFjZShjb25maWcpIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gbmFtZVNwYWNlID8gbmFtZVNwYWNlXG4gICAgICAgICAgICAuY29uY2F0KFZJUFNlcnZpY2VDb25zdGFudHMuTkFNRV9TUEFDRV9TRVBBUkFUT1IpXG4gICAgICAgICAgICAuY29uY2F0KGtleSkgOiBrZXk7XG4gICAgfVxuXG4gICAgdHJhbnNsYXRlKGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBhcmdzPzogYW55W10sIGNvbW1lbnQ/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gTDEwbkZvcm1hdCh2YWx1ZSwgYXJncyk7XG4gICAgfVxuXG4gICAgZ2V0VHJhbnNsYXRpb24oa2V5OiBzdHJpbmcsIHNvdXJjZTogc3RyaW5nLCBhcmdzPzogYW55W10sIGNvbW1lbnQ/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgICAgICByZXR1cm4gb2YodGhpcy50cmFuc2xhdGUoa2V5LCBzb3VyY2UsIGFyZ3MpKTtcbiAgICB9XG5cbiAgICBnZXRNZXNzYWdlKGtleTogc3RyaW5nLCBhcmdzPzogYW55W10pOiBzdHJpbmcge1xuICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICBpZiAoIWlzRGVmaW5lZChrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLmdldFNvdXJjZVN0cmluZyhrZXkpO1xuICAgICAgICAvLyBJZiBzb3VyY2UgaXMgdW5kZWZpbmVkIHJldHVybiBrZXkuIEF2b2lkIGVycm9yIGR1ZSB0byBzb3VyY2UgcGFyc2luZyBpbiBMMTBuRm9ybWF0LlxuICAgICAgICBpZiAoIXNvdXJjZSkgeyByZXR1cm4ga2V5OyB9XG4gICAgICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gdGhpcy50cmFuc2xhdGUoa2V5LCBzb3VyY2UsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gdHJhbnNsYXRpb247XG4gICAgfVxuXG4gICAgLy8gVG9kbzogYWRkIG1ldGhvZCB0byByZWdpc3RlciBzb3VyY2VCdW5kbGUgdW5kZXIgY2VydGFpbiBuYW1lc3BhY2UuXG4gICAgZ2V0U291cmNlU3RyaW5nKGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZWdpc3RlclNvdXJjZUJ1bmRsZXMoLi4uYXJnczogc291cmNlQnVuZGxlT2JqZWN0W10pOiB2b2lkIHsgfVxufVxuXG5leHBvcnQgY2xhc3MgSTE4blNlcnZpY2VNb2NrIGV4dGVuZHMgQmFzZURhdGFTZXJ2aWNlTW9jayB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGZvcm1hdEN1cnJlbmN5KHZhbHVlOiBhbnksIGN1cnJlbmN5Q29kZTogc3RyaW5nKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICdVU0QnOiAnJCcsXG4gICAgICAgIH1bY3VycmVuY3lDb2RlXSArIHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBmb3JtYXREYXRlKHZhbHVlOiBhbnksIHBhdHRlcm46IHN0cmluZywgdGltZXpvbmU/OiBzdHJpbmcpOiBhbnkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGZvcm1hdE51bWJlcih2YWx1ZTogYW55LCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdmFsdWUgKyAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgZm9ybWF0UGVyY2VudCh2YWx1ZTogYW55LCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldExvY2FsaXplZFBhdHRlcm4ocGF0dGVybjogc3RyaW5nLCBsb2NhbGU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ3Nob3J0VGltZSc6ICdoOm1tIGEnLFxuICAgICAgICAgICAgJ21lZGl1bVRpbWUnOiAnaDptbTpzcyBhJyxcbiAgICAgICAgICAgICdsb25nVGltZSc6ICdoOm1tOnNzIHonLFxuICAgICAgICAgICAgJ2Z1bGxUaW1lJzogJ2g6bW06c3Mgenp6eicsXG4gICAgICAgICAgICAnc2hvcnREYXRlJzogJ00vZC95eScsXG4gICAgICAgICAgICAnbWVkaXVtRGF0ZSc6ICdNTU0gZCwgeScsXG4gICAgICAgICAgICAnbG9uZ0RhdGUnOiAnTU1NTSBkLCB5JyxcbiAgICAgICAgICAgICdmdWxsRGF0ZSc6ICdFRUVFLCBNTU1NIGQsIHknLFxuICAgICAgICAgICAgJ3Nob3J0JzogJ00vZC95eSwgaDptbSBhJyxcbiAgICAgICAgICAgICdtZWRpdW0nOiAnTU1NIGQsIHksIGg6bW06c3MgYScsXG4gICAgICAgICAgICAnbG9uZyc6ICdNTU1NIGQsIHksIGg6bW06c3MgYSB6JyxcbiAgICAgICAgICAgICdmdWxsJzogJ0VFRUUsIE1NTU0gZCwgeSwgaDptbTpzcyBhIHp6enonLFxuICAgICAgICB9W3BhdHRlcm5dO1xuICAgIH1cbn1cblxuQE5nTW9kdWxlKHtcbiAgICBpbXBvcnRzOiBbXSxcbiAgICBkZWNsYXJhdGlvbnM6IFtcbiAgICAgICAgTW9ja0wxMG5QaXBlLFxuICAgICAgICBNb2NrTDEwblBpcGVQbHVzLFxuICAgICAgICBNb2NrTDEwbkRpcmVjdGl2ZSxcbiAgICAgICAgTW9ja0N1cnJlbmN5UGlwZSxcbiAgICAgICAgTW9ja0RhdGVQaXBlLFxuICAgICAgICBNb2NrTnVtYmVyRm9ybWF0UGlwZSxcbiAgICBdLFxuICAgIGV4cG9ydHM6IFtcbiAgICAgICAgTW9ja0wxMG5QaXBlLFxuICAgICAgICBNb2NrTDEwblBpcGVQbHVzLFxuICAgICAgICBNb2NrTDEwbkRpcmVjdGl2ZSxcbiAgICAgICAgTW9ja0N1cnJlbmN5UGlwZSxcbiAgICAgICAgTW9ja0RhdGVQaXBlLFxuICAgICAgICBNb2NrTnVtYmVyRm9ybWF0UGlwZSxcbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIFZJUE1vZHVsZU1vY2sge1xuICAgIC8qKlxuICAgICAqIFVzZSB0aGlzIG1ldGhvZCBpbiB5b3VyIHJvb3QgbW9kdWxlIHRvIHByb3ZpZGUgdGhlIG1vY2tlZCBWSVAgU2VydmljZVxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAcmV0dXJucyB7TW9kdWxlV2l0aFByb3ZpZGVyc31cbiAgICAgKiBAbWVtYmVyb2YgVklQTW9kdWxlXG4gICAgICovXG4gICAgc3RhdGljIGZvclJvb3QoKTogTW9kdWxlV2l0aFByb3ZpZGVyczxWSVBNb2R1bGVNb2NrPiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZ01vZHVsZTogVklQTW9kdWxlTW9jayxcbiAgICAgICAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uTG9hZGVyLFxuICAgICAgICAgICAgICAgIERhdGVGb3JtYXR0ZXIsXG4gICAgICAgICAgICAgICAgeyBwcm92aWRlOiBWSVBTZXJ2aWNlLCB1c2VDbGFzczogVklQU2VydmljZU1vY2sgfSxcbiAgICAgICAgICAgICAgICB7IHByb3ZpZGU6IEwxMG5TZXJ2aWNlLCB1c2VDbGFzczogTDEwblNlcnZpY2VNb2NrIH0sXG4gICAgICAgICAgICAgICAgeyBwcm92aWRlOiBJMThuU2VydmljZSwgdXNlQ2xhc3M6IEkxOG5TZXJ2aWNlTW9jayB9LFxuICAgICAgICAgICAgXVxuICAgICAgICB9O1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEwxMG5Gb3JtYXQobWVzc2FnZTogc3RyaW5nLCBhcmdzOiBhbnlbXSkge1xuICAgIGlmIChtZXNzYWdlLmluZGV4T2YoJz0wJyk+LTEgfHwgbWVzc2FnZS5pbmRleE9mKCc9MScpPi0xKSB7XG4gICAgICAgIGxldCBzdWJzdHIsIHdvcmROdW1iZXI6IHN0cmluZztcbiAgICAgICAgc3dpdGNoIChhcmdzWzBdKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgc3Vic3RyID0gJz0wJztcbiAgICAgICAgICAgICAgICB3b3JkTnVtYmVyID0gXCJcIjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICBzdWJzdHIgPSAnPTEnO1xuICAgICAgICAgICAgICAgIHdvcmROdW1iZXIgPSBcIm9uZVwiO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBzdWJzdHIgPSAnb3RoZXInO1xuICAgICAgICAgICAgICAgIHdvcmROdW1iZXIgPSBhcmdzWzBdLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFydFN1YnN0ciA9IG1lc3NhZ2UuaW5kZXhPZihzdWJzdHIpICsgc3Vic3RyLmxlbmd0aCArIDE7XG4gICAgICAgIHJldHVybiBtZXNzYWdlLnN1YnN0cmluZyhzdGFydFN1YnN0ciwgbWVzc2FnZS5pbmRleE9mKCd9Jywgc3RhcnRTdWJzdHIpKS5yZXBsYWNlKCcjJywgd29yZE51bWJlcik7XG4gICAgfVxuXG4gICAgY29uc3QgdGVtcGxhdGVNYXRjaGVyID0gL3tcXHM/KFtcXGRdKilcXHM/fS9nO1xuXG4gICAgaWYgKGFyZ3MgJiYgYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3Qgc3RyaW5ncyA9IFtdLmNvbmNhdCguLi5hcmdzKTsgICAvLyBhcmdzIGNvdWxkIGJlIGFuIGFycmF5IG9mIGFycmF5cywgb3IganVzdCBhbiBhcnJheSBzbyBmbGF0dGVuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaW5ncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZSh0ZW1wbGF0ZU1hdGNoZXIsIGZ1bmN0aW9uIChzdWJzdHJpbmc6IHN0cmluZywgYjogc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChiLnRyaW0oKSA9PT0gaS50b1N0cmluZygpICYmIHN0cmluZ3NbaV0gIT0gbnVsbCkgPyBzdHJpbmdzW2ldIDogc3Vic3RyaW5nO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2UudHJpbSgpO1xufVxuIl19