@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
176 lines • 24.8 kB
JavaScript
import { Injectable } from '@angular/core';
import { ApplicationAvailability, ApplicationService, ApplicationType } from '@c8y/client';
import { AppStateService, ZipService } from '@c8y/ngx-components';
import { uniq } from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/client";
import * as i2 from "@c8y/ngx-components";
export class TranslationStoreService {
constructor(appService, appState, zip) {
this.appService = appService;
this.appState = appState;
this.zip = zip;
this.translationAppName = 'User defined translations';
this.translationAppContextPath = 'user-defined-translations';
}
/**
* Retrieves a list of available translations for the given locales from all the hosted apps available on the tenant.
*/
async getAvailableTranslations(locales) {
const { data: hostedApps } = await this.appService.list({
tenant: this.appState.currentTenant.value.name,
type: 'HOSTED',
pageSize: 2000
});
const uniqueContextPaths = uniq(hostedApps
.filter(app => app.contextPath && app.manifest?.webSdkVersion)
.map(app => app.contextPath));
const translations = {};
for (const contextPath of uniqueContextPaths) {
for (const locale of locales) {
try {
const translationsForLanguageAndApp = await this.getFileFromPath(`/apps/${contextPath}/${locale}.json`);
for (const key of Object.keys(translationsForLanguageAndApp)) {
if (!translations[key]) {
translations[key] = {};
}
translations[key][locale] = translationsForLanguageAndApp[key];
}
}
catch (e) {
continue;
}
}
}
return translations;
}
/**
* Retrieves the translations for the given locale from the translation app.
*/
async getTranslationsForLocale(locale) {
try {
const translations = await this.getFileFromTranslationApp(`${locale}.json`);
if (translations[locale]) {
return translations[locale];
}
}
catch (e) {
// do nothing.
}
return {};
}
/**
* Retrieves the translations for the given locales from the translation app.
*/
async loadTranslationsForLocales(locales) {
const translations = {};
const loadAndAddLocale = async (locale) => {
translations[locale] = await this.getTranslationsForLocale(locale);
};
await Promise.all(locales.map(loadAndAddLocale));
return translations;
}
/**
* Retrieves a combined list of translations for all the provided locales.
* The locales are combined into a single object per key and an array of these objects is returned.
*/
async getCombinedListOfTranslationsForPerKey(locales) {
const translations = await this.loadTranslationsForLocales(locales);
const translationMap = {};
for (const locale of Object.keys(translations)) {
for (const key of Object.keys(translations[locale])) {
let translationsForKey = translationMap[key];
if (!translationsForKey) {
translationsForKey = {};
translationMap[key] = translationsForKey;
}
translationsForKey[locale] = translations[locale][key];
}
}
const keys = Object.keys(translationMap).sort((a, b) => a.localeCompare(b));
return keys.map(key => Object.assign({ key }, translationMap[key]));
}
/**
* Updates the files of the translation application with the provided translations.
*/
async updateTranslations(translations) {
const filesToUpload = new Array();
const translationsPerLocale = {};
for (const entry of translations) {
const key = entry.key;
for (const locale of Object.keys(entry)) {
if (locale === 'key') {
continue;
}
if (!translationsPerLocale[locale]) {
translationsPerLocale[locale] = {};
}
if (entry[locale]) {
translationsPerLocale[locale][key] = entry[locale];
}
}
}
const langs = this.appState.state.langs;
for (const locale of langs) {
const fileName = `${locale}.json`;
filesToUpload.push({
path: fileName,
contents: new File([JSON.stringify({ [locale]: translationsPerLocale[locale] || {} })], fileName)
});
}
const app = await this.getOrCreateTranslationApp();
await this.appService.binary(app).updateFiles(filesToUpload);
}
/**
* @returns The translation app for the current tenant. If it does not exist, it will be created.
*/
async getOrCreateTranslationApp() {
const { data: apps } = await this.appService.listByName(this.translationAppName);
const ownApp = apps.find(app => app.contextPath === this.translationAppContextPath &&
app.owner.tenant.id === this.appState.currentTenant.value.name);
if (ownApp) {
return ownApp;
}
const { data: app } = await this.appService.create({
name: this.translationAppName,
contextPath: this.translationAppContextPath,
key: `${this.translationAppContextPath}-app-key`,
type: ApplicationType.HOSTED,
availability: ApplicationAvailability.MARKET,
config: {
icon: {
class: 'language1'
}
},
noAppSwitcher: true,
description: 'Providing user defined translations'
});
const zip = await this.zip.createZip([]);
const { data: binary } = await this.appService.binary(app).upload(zip, 'translations.zip');
const { data: updatedApp } = await this.appService.update({
id: app.id,
activeVersionId: binary.id
});
return updatedApp;
}
async getFileFromTranslationApp(file) {
return this.getFileFromPath(`/apps/public/${this.translationAppContextPath}/${file}`);
}
async getFileFromPath(path) {
const finalPath = `${path}?nocache=${Date.now()}`;
const response = await fetch(finalPath);
if (response.status !== 200) {
throw new Error(`Failed to fetch file from ${path}`);
}
return response.json();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, deps: [{ token: i1.ApplicationService }, { token: i2.AppStateService }, { token: i2.ZipService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationStoreService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.ApplicationService }, { type: i2.AppStateService }, { type: i2.ZipService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24tc3RvcmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RyYW5zbGF0aW9uLWVkaXRvci9kYXRhL3RyYW5zbGF0aW9uLXN0b3JlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGtCQUFrQixFQUNsQixlQUFlLEVBRWhCLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQzs7OztBQVVqQyxNQUFNLE9BQU8sdUJBQXVCO0lBSWxDLFlBQ1UsVUFBOEIsRUFDOUIsUUFBeUIsRUFDekIsR0FBZTtRQUZmLGVBQVUsR0FBVixVQUFVLENBQW9CO1FBQzlCLGFBQVEsR0FBUixRQUFRLENBQWlCO1FBQ3pCLFFBQUcsR0FBSCxHQUFHLENBQVk7UUFOTix1QkFBa0IsR0FBRywyQkFBMkIsQ0FBQztRQUNqRCw4QkFBeUIsR0FBRywyQkFBMkIsQ0FBQztJQU14RSxDQUFDO0lBRUo7O09BRUc7SUFDSCxLQUFLLENBQUMsd0JBQXdCLENBQUMsT0FBaUI7UUFDOUMsTUFBTSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1lBQ3RELE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUM5QyxJQUFJLEVBQUUsUUFBUTtZQUNkLFFBQVEsRUFBRSxJQUFJO1NBQ2YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQzdCLFVBQVU7YUFDUCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFH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RU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFZO1FBQ3hDLE1BQU0sU0FBUyxHQUFHLEdBQUcsSUFBSSxZQUFZLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ2xELE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXhDLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDOytHQTFNVSx1QkFBdUI7bUhBQXZCLHVCQUF1QixjQUZ0QixNQUFNOzs0RkFFUCx1QkFBdUI7a0JBSG5DLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25BdmFpbGFiaWxpdHksXG4gIEFwcGxpY2F0aW9uU2VydmljZSxcbiAgQXBwbGljYXRpb25UeXBlLFxuICBJQXBwbGljYXRpb25cbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlLCBaaXBTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyB1bmlxIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvY2FsZSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGxvY2FsZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvblN0b3JlU2VydmljZSB7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcE5hbWUgPSAnVXNlciBkZWZpbmVkIHRyYW5zbGF0aW9ucyc7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoID0gJ3VzZXItZGVmaW5lZC10cmFuc2xhdGlvbnMnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwU2VydmljZTogQXBwbGljYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwU3RhdGU6IEFwcFN0YXRlU2VydmljZSxcbiAgICBwcml2YXRlIHppcDogWmlwU2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgYXZhaWxhYmxlIHRyYW5zbGF0aW9ucyBmb3IgdGhlIGdpdmVuIGxvY2FsZXMgZnJvbSBhbGwgdGhlIGhvc3RlZCBhcHBzIGF2YWlsYWJsZSBvbiB0aGUgdGVuYW50LlxuICAgKi9cbiAgYXN5bmMgZ2V0QXZhaWxhYmxlVHJhbnNsYXRpb25zKGxvY2FsZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgeyBkYXRhOiBob3N0ZWRBcHBzIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UubGlzdCh7XG4gICAgICB0ZW5hbnQ6IHRoaXMuYXBwU3RhdGUuY3VycmVudFRlbmFudC52YWx1ZS5uYW1lLFxuICAgICAgdHlwZTogJ0hPU1RFRCcsXG4gICAgICBwYWdlU2l6ZTogMjAwMFxuICAgIH0pO1xuXG4gICAgY29uc3QgdW5pcXVlQ29udGV4dFBhdGhzID0gdW5pcShcbiAgICAgIGhvc3RlZEFwcHNcbiAgICAgICAgLmZpbHRlcihhcHAgPT4gYXBwLmNvbnRleHRQYXRoICYmIGFwcC5tYW5pZmVzdD8ud2ViU2RrVmVyc2lvbilcbiAgICAgICAgLm1hcChhcHAgPT4gYXBwLmNvbnRleHRQYXRoKVxuICAgICk7XG5cbiAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHsgW2tleTogc3RyaW5nXTogeyBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgZm9yIChjb25zdCBjb250ZXh0UGF0aCBvZiB1bmlxdWVDb250ZXh0UGF0aHMpIHtcbiAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnNGb3JMYW5ndWFnZUFuZEFwcCA9IGF3YWl0IHRoaXMuZ2V0RmlsZUZyb21QYXRoKFxuICAgICAgICAgICAgYC9hcHBzLyR7Y29udGV4dFBhdGh9LyR7bG9jYWxlfS5qc29uYFxuICAgICAgICAgICk7XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModHJhbnNsYXRpb25zRm9yTGFuZ3VhZ2VBbmRBcHApKSB7XG4gICAgICAgICAgICBpZiAoIXRyYW5zbGF0aW9uc1trZXldKSB7XG4gICAgICAgICAgICAgIHRyYW5zbGF0aW9uc1trZXldID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cmFuc2xhdGlvbnNba2V5XVtsb2NhbGVdID0gdHJhbnNsYXRpb25zRm9yTGFuZ3VhZ2VBbmRBcHBba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cmFuc2xhdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB0cmFuc2xhdGlvbnMgZm9yIHRoZSBnaXZlbiBsb2NhbGUgZnJvbSB0aGUgdHJhbnNsYXRpb24gYXBwLlxuICAgKi9cbiAgYXN5bmMgZ2V0VHJhbnNsYXRpb25zRm9yTG9jYWxlPFQgZXh0ZW5kcyBzdHJpbmc+KGxvY2FsZTogVCk6IFByb21pc2U8eyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSBhd2FpdCB0aGlzLmdldEZpbGVGcm9tVHJhbnNsYXRpb25BcHAoYCR7bG9jYWxlfS5qc29uYCk7XG4gICAgICBpZiAodHJhbnNsYXRpb25zW2xvY2FsZV0pIHtcbiAgICAgICAgcmV0dXJuIHRyYW5zbGF0aW9uc1tsb2NhbGVdO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmcuXG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIHRyYW5zbGF0aW9ucyBmb3IgdGhlIGdpdmVuIGxvY2FsZXMgZnJvbSB0aGUgdHJhbnNsYXRpb24gYXBwLlxuICAgKi9cbiAgYXN5bmMgbG9hZFRyYW5zbGF0aW9uc0ZvckxvY2FsZXMobG9jYWxlczogc3RyaW5nW10pOiBQcm9taXNlPHtcbiAgICBba2V5OiBzdHJpbmddOiB7XG4gICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmc7XG4gICAgfTtcbiAgfT4ge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uczoge1xuICAgICAgW2tleTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgICB9ID0ge307XG5cbiAgICBjb25zdCBsb2FkQW5kQWRkTG9jYWxlID0gYXN5bmMgKGxvY2FsZTogc3RyaW5nKSA9PiB7XG4gICAgICB0cmFuc2xhdGlvbnNbbG9jYWxlXSA9IGF3YWl0IHRoaXMuZ2V0VHJhbnNsYXRpb25zRm9yTG9jYWxlKGxvY2FsZSk7XG4gICAgfTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKGxvY2FsZXMubWFwKGxvYWRBbmRBZGRMb2NhbGUpKTtcblxuICAgIHJldHVybiB0cmFuc2xhdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY29tYmluZWQgbGlzdCBvZiB0cmFuc2xhdGlvbnMgZm9yIGFsbCB0aGUgcHJvdmlkZWQgbG9jYWxlcy5cbiAgICogVGhlIGxvY2FsZXMgYXJlIGNvbWJpbmVkIGludG8gYSBzaW5nbGUgb2JqZWN0IHBlciBrZXkgYW5kIGFuIGFycmF5IG9mIHRoZXNlIG9iamVjdHMgaXMgcmV0dXJuZWQuXG4gICAqL1xuICBhc3luYyBnZXRDb21iaW5lZExpc3RPZlRyYW5zbGF0aW9uc0ZvclBlcktleShcbiAgICBsb2NhbGVzOiBzdHJpbmdbXVxuICApOiBQcm9taXNlPHsga2V5OiBzdHJpbmc7IFtsb2NhbGU6IHN0cmluZ106IHN0cmluZyB9W10+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnMgPSBhd2FpdCB0aGlzLmxvYWRUcmFuc2xhdGlvbnNGb3JMb2NhbGVzKGxvY2FsZXMpO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uTWFwOiB7IFtrZXk6IHN0cmluZ106IHsgW2xvY2FsZTogc3RyaW5nXTogc3RyaW5nIH0gfSA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgT2JqZWN0LmtleXModHJhbnNsYXRpb25zKSkge1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModHJhbnNsYXRpb25zW2xvY2FsZV0pKSB7XG4gICAgICAgIGxldCB0cmFuc2xhdGlvbnNGb3JLZXkgPSB0cmFuc2xhdGlvbk1hcFtrZXldO1xuICAgICAgICBpZiAoIXRyYW5zbGF0aW9uc0ZvcktleSkge1xuICAgICAgICAgIHRyYW5zbGF0aW9uc0ZvcktleSA9IHt9O1xuICAgICAgICAgIHRyYW5zbGF0aW9uTWFwW2tleV0gPSB0cmFuc2xhdGlvbnNGb3JLZXk7XG4gICAgICAgIH1cblxuICAgICAgICB0cmFuc2xhdGlvbnNGb3JLZXlbbG9jYWxlXSA9IHRyYW5zbGF0aW9uc1tsb2NhbGVdW2tleV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRyYW5zbGF0aW9uTWFwKS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpO1xuXG4gICAgcmV0dXJuIGtleXMubWFwKGtleSA9PiBPYmplY3QuYXNzaWduKHsga2V5IH0sIHRyYW5zbGF0aW9uTWFwW2tleV0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBmaWxlcyBvZiB0aGUgdHJhbnNsYXRpb24gYXBwbGljYXRpb24gd2l0aCB0aGUgcHJvdmlkZWQgdHJhbnNsYXRpb25zLlxuICAgKi9cbiAgYXN5bmMgdXBkYXRlVHJhbnNsYXRpb25zKFxuICAgIHRyYW5zbGF0aW9uczogeyBrZXk6IHN0cmluZzsgW2xvY2FsZTogc3RyaW5nXTogc3RyaW5nIH1bXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmaWxlc1RvVXBsb2FkID0gbmV3IEFycmF5PHsgcGF0aDogc3RyaW5nOyBjb250ZW50czogRmlsZSB9PigpO1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uc1BlckxvY2FsZTogeyBbbG9jYWxlOiBzdHJpbmddOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHRyYW5zbGF0aW9ucykge1xuICAgICAgY29uc3Qga2V5ID0gZW50cnkua2V5O1xuICAgICAgZm9yIChjb25zdCBsb2NhbGUgb2YgT2JqZWN0LmtleXMoZW50cnkpKSB7XG4gICAgICAgIGlmIChsb2NhbGUgPT09ICdrZXknKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXSkge1xuICAgICAgICAgIHRyYW5zbGF0aW9uc1BlckxvY2FsZVtsb2NhbGVdID0ge307XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnlbbG9jYWxlXSkge1xuICAgICAgICAgIHRyYW5zbGF0aW9uc1BlckxvY2FsZVtsb2NhbGVdW2tleV0gPSBlbnRyeVtsb2NhbGVdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbGFuZ3MgPSB0aGlzLmFwcFN0YXRlLnN0YXRlLmxhbmdzIGFzIHN0cmluZ1tdO1xuXG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbGFuZ3MpIHtcbiAgICAgIGNvbnN0IGZpbGVOYW1lID0gYCR7bG9jYWxlfS5qc29uYDtcbiAgICAgIGZpbGVzVG9VcGxvYWQucHVzaCh7XG4gICAgICAgIHBhdGg6IGZpbGVOYW1lLFxuICAgICAgICBjb250ZW50czogbmV3IEZpbGUoXG4gICAgICAgICAgW0pTT04uc3RyaW5naWZ5KHsgW2xvY2FsZV06IHRyYW5zbGF0aW9uc1BlckxvY2FsZVtsb2NhbGVdIHx8IHt9IH0pXSxcbiAgICAgICAgICBmaWxlTmFtZVxuICAgICAgICApXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgYXBwID0gYXdhaXQgdGhpcy5nZXRPckNyZWF0ZVRyYW5zbGF0aW9uQXBwKCk7XG4gICAgYXdhaXQgdGhpcy5hcHBTZXJ2aWNlLmJpbmFyeShhcHApLnVwZGF0ZUZpbGVzKGZpbGVzVG9VcGxvYWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFRoZSB0cmFuc2xhdGlvbiBhcHAgZm9yIHRoZSBjdXJyZW50IHRlbmFudC4gSWYgaXQgZG9lcyBub3QgZXhpc3QsIGl0IHdpbGwgYmUgY3JlYXRlZC5cbiAgICovXG4gIGFzeW5jIGdldE9yQ3JlYXRlVHJhbnNsYXRpb25BcHAoKTogUHJvbWlzZTxJQXBwbGljYXRpb24+IHtcbiAgICBjb25zdCB7IGRhdGE6IGFwcHMgfSA9IGF3YWl0IHRoaXMuYXBwU2VydmljZS5saXN0QnlOYW1lKHRoaXMudHJhbnNsYXRpb25BcHBOYW1lKTtcbiAgICBjb25zdCBvd25BcHAgPSBhcHBzLmZpbmQoXG4gICAgICBhcHAgPT5cbiAgICAgICAgYXBwLmNvbnRleHRQYXRoID09PSB0aGlzLnRyYW5zbGF0aW9uQXBwQ29udGV4dFBhdGggJiZcbiAgICAgICAgYXBwLm93bmVyLnRlbmFudC5pZCA9PT0gdGhpcy5hcHBTdGF0ZS5jdXJyZW50VGVuYW50LnZhbHVlLm5hbWVcbiAgICApO1xuICAgIGlmIChvd25BcHApIHtcbiAgICAgIHJldHVybiBvd25BcHA7XG4gICAgfVxuXG4gICAgY29uc3QgeyBkYXRhOiBhcHAgfSA9IGF3YWl0IHRoaXMuYXBwU2VydmljZS5jcmVhdGUoe1xuICAgICAgbmFtZTogdGhpcy50cmFuc2xhdGlvbkFwcE5hbWUsXG4gICAgICBjb250ZXh0UGF0aDogdGhpcy50cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoLFxuICAgICAga2V5OiBgJHt0aGlzLnRyYW5zbGF0aW9uQXBwQ29udGV4dFBhdGh9LWFwcC1rZXlgLFxuICAgICAgdHlwZTogQXBwbGljYXRpb25UeXBlLkhPU1RFRCxcbiAgICAgIGF2YWlsYWJpbGl0eTogQXBwbGljYXRpb25BdmFpbGFiaWxpdHkuTUFSS0VULFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIGljb246IHtcbiAgICAgICAgICBjbGFzczogJ2xhbmd1YWdlMSdcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIG5vQXBwU3dpdGNoZXI6IHRydWUsXG4gICAgICBkZXNjcmlwdGlvbjogJ1Byb3ZpZGluZyB1c2VyIGRlZmluZWQgdHJhbnNsYXRpb25zJ1xuICAgIH0pO1xuICAgIGNvbnN0IHppcCA9IGF3YWl0IHRoaXMuemlwLmNyZWF0ZVppcChbXSk7XG5cbiAgICBjb25zdCB7IGRhdGE6IGJpbmFyeSB9ID0gYXdhaXQgdGhpcy5hcHBTZXJ2aWNlLmJpbmFyeShhcHApLnVwbG9hZCh6aXAsICd0cmFuc2xhdGlvbnMuemlwJyk7XG4gICAgY29uc3QgeyBkYXRhOiB1cGRhdGVkQXBwIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UudXBkYXRlKHtcbiAgICAgIGlkOiBhcHAuaWQsXG4gICAgICBhY3RpdmVWZXJzaW9uSWQ6IGJpbmFyeS5pZCBhcyBzdHJpbmdcbiAgICB9KTtcbiAgICByZXR1cm4gdXBkYXRlZEFwcDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RmlsZUZyb21UcmFuc2xhdGlvbkFwcChmaWxlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRGaWxlRnJvbVBhdGgoYC9hcHBzL3B1YmxpYy8ke3RoaXMudHJhbnNsYXRpb25BcHBDb250ZXh0UGF0aH0vJHtmaWxlfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRGaWxlRnJvbVBhdGgocGF0aDogc3RyaW5nKSB7XG4gICAgY29uc3QgZmluYWxQYXRoID0gYCR7cGF0aH0/bm9jYWNoZT0ke0RhdGUubm93KCl9YDtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGZpbmFsUGF0aCk7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIGZpbGUgZnJvbSAke3BhdGh9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbiAgfVxufVxuIl19