@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
179 lines • 25.6 kB
JavaScript
import { Injectable } from '@angular/core';
import { ApplicationAvailability, ApplicationService, ApplicationType, FetchClient } 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, fetchClient) {
this.appService = appService;
this.appState = appState;
this.zip = zip;
this.fetchClient = fetchClient;
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`);
const translationsForLang = translationsForLanguageAndApp[locale];
for (const key of Object.keys(translationsForLang)) {
if (!translations[key]) {
translations[key] = {};
}
translations[key][locale] = translationsForLang[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()}`;
// using fetch client instead of fetch directly here to ensure loading indicator is shown during these requests
const response = await this.fetchClient.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 }, { token: i1.FetchClient }], 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 }, { type: i1.FetchClient }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRpb24tc3RvcmUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RyYW5zbGF0aW9uLWVkaXRvci9kYXRhL3RyYW5zbGF0aW9uLXN0b3JlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGtCQUFrQixFQUNsQixlQUFlLEVBQ2YsV0FBVyxFQUVaLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQzs7OztBQVVqQyxNQUFNLE9BQU8sdUJBQXVCO0lBSWxDLFlBQ1UsVUFBOEIsRUFDOUIsUUFBeUIsRUFDekIsR0FBZSxFQUNmLFdBQXdCO1FBSHhCLGVBQVUsR0FBVixVQUFVLENBQW9CO1FBQzlCLGFBQVEsR0FBUixRQUFRLENBQWlCO1FBQ3pCLFFBQUcsR0FBSCxHQUFHLENBQVk7UUFDZixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQVBmLHVCQUFrQixHQUFHLDJCQUEyQixDQUFDO1FBQ2pELDhCQUF5QixHQUFHLDJCQUEyQixDQUFDO0lBT3hFLENBQUM7SUFFSjs7T0FFRztJQUNILEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxPQUFpQjtRQUM5QyxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7WUFDdEQsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQzlDLElBQUksRUFBRSxRQUFRO1lBQ2QsUUFBUSxFQUFFLElBQUk7U0FDZixDQUFDLENBQUM7UUFFSCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FD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SUFBWTtRQUNsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFTyxLQUFLLENBQUMsZUFBZSxDQUFDLElBQVk7UUFDeEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxJQUFJLFlBQVksSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFFbEQsK0dBQStHO1FBQy9HLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFekQsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7K0dBOU1VLHVCQUF1QjttSEFBdkIsdUJBQXVCLGNBRnRCLE1BQU07OzRGQUVQLHVCQUF1QjtrQkFIbkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkF2YWlsYWJpbGl0eSxcbiAgQXBwbGljYXRpb25TZXJ2aWNlLFxuICBBcHBsaWNhdGlvblR5cGUsXG4gIEZldGNoQ2xpZW50LFxuICBJQXBwbGljYXRpb25cbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQXBwU3RhdGVTZXJ2aWNlLCBaaXBTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyB1bmlxIH0gZnJvbSAnbG9kYXNoLWVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvY2FsZSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGxvY2FsZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFuc2xhdGlvblN0b3JlU2VydmljZSB7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcE5hbWUgPSAnVXNlciBkZWZpbmVkIHRyYW5zbGF0aW9ucyc7XG4gIHByb3RlY3RlZCByZWFkb25seSB0cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoID0gJ3VzZXItZGVmaW5lZC10cmFuc2xhdGlvbnMnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwU2VydmljZTogQXBwbGljYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwU3RhdGU6IEFwcFN0YXRlU2VydmljZSxcbiAgICBwcml2YXRlIHppcDogWmlwU2VydmljZSxcbiAgICBwcml2YXRlIGZldGNoQ2xpZW50OiBGZXRjaENsaWVudFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgYXZhaWxhYmxlIHRyYW5zbGF0aW9ucyBmb3IgdGhlIGdpdmVuIGxvY2FsZXMgZnJvbSBhbGwgdGhlIGhvc3RlZCBhcHBzIGF2YWlsYWJsZSBvbiB0aGUgdGVuYW50LlxuICAgKi9cbiAgYXN5bmMgZ2V0QXZhaWxhYmxlVHJhbnNsYXRpb25zKGxvY2FsZXM6IHN0cmluZ1tdKSB7XG4gICAgY29uc3QgeyBkYXRhOiBob3N0ZWRBcHBzIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UubGlzdCh7XG4gICAgICB0ZW5hbnQ6IHRoaXMuYXBwU3RhdGUuY3VycmVudFRlbmFudC52YWx1ZS5uYW1lLFxuICAgICAgdHlwZTogJ0hPU1RFRCcsXG4gICAgICBwYWdlU2l6ZTogMjAwMFxuICAgIH0pO1xuXG4gICAgY29uc3QgdW5pcXVlQ29udGV4dFBhdGhzID0gdW5pcShcbiAgICAgIGhvc3RlZEFwcHNcbiAgICAgICAgLmZpbHRlcihhcHAgPT4gYXBwLmNvbnRleHRQYXRoICYmIGFwcC5tYW5pZmVzdD8ud2ViU2RrVmVyc2lvbilcbiAgICAgICAgLm1hcChhcHAgPT4gYXBwLmNvbnRleHRQYXRoKVxuICAgICk7XG5cbiAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHsgW2tleTogc3RyaW5nXTogeyBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgZm9yIChjb25zdCBjb250ZXh0UGF0aCBvZiB1bmlxdWVDb250ZXh0UGF0aHMpIHtcbiAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnNGb3JMYW5ndWFnZUFuZEFwcCA9IGF3YWl0IHRoaXMuZ2V0RmlsZUZyb21QYXRoKFxuICAgICAgICAgICAgYC9hcHBzLyR7Y29udGV4dFBhdGh9LyR7bG9jYWxlfS5qc29uYFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgdHJhbnNsYXRpb25zRm9yTGFuZyA9IHRyYW5zbGF0aW9uc0Zvckxhbmd1YWdlQW5kQXBwW2xvY2FsZV07XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModHJhbnNsYXRpb25zRm9yTGFuZykpIHtcbiAgICAgICAgICAgIGlmICghdHJhbnNsYXRpb25zW2tleV0pIHtcbiAgICAgICAgICAgICAgdHJhbnNsYXRpb25zW2tleV0gPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyYW5zbGF0aW9uc1trZXldW2xvY2FsZV0gPSB0cmFuc2xhdGlvbnNGb3JMYW5nW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNsYXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgdHJhbnNsYXRpb25zIGZvciB0aGUgZ2l2ZW4gbG9jYWxlIGZyb20gdGhlIHRyYW5zbGF0aW9uIGFwcC5cbiAgICovXG4gIGFzeW5jIGdldFRyYW5zbGF0aW9uc0ZvckxvY2FsZTxUIGV4dGVuZHMgc3RyaW5nPihsb2NhbGU6IFQpOiBQcm9taXNlPHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5nZXRGaWxlRnJvbVRyYW5zbGF0aW9uQXBwKGAke2xvY2FsZX0uanNvbmApO1xuICAgICAgaWYgKHRyYW5zbGF0aW9uc1tsb2NhbGVdKSB7XG4gICAgICAgIHJldHVybiB0cmFuc2xhdGlvbnNbbG9jYWxlXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBkbyBub3RoaW5nLlxuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB0cmFuc2xhdGlvbnMgZm9yIHRoZSBnaXZlbiBsb2NhbGVzIGZyb20gdGhlIHRyYW5zbGF0aW9uIGFwcC5cbiAgICovXG4gIGFzeW5jIGxvYWRUcmFuc2xhdGlvbnNGb3JMb2NhbGVzKGxvY2FsZXM6IHN0cmluZ1tdKTogUHJvbWlzZTx7XG4gICAgW2tleTogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHtcbiAgICAgIFtrZXk6IHN0cmluZ106IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG4gICAgfSA9IHt9O1xuXG4gICAgY29uc3QgbG9hZEFuZEFkZExvY2FsZSA9IGFzeW5jIChsb2NhbGU6IHN0cmluZykgPT4ge1xuICAgICAgdHJhbnNsYXRpb25zW2xvY2FsZV0gPSBhd2FpdCB0aGlzLmdldFRyYW5zbGF0aW9uc0ZvckxvY2FsZShsb2NhbGUpO1xuICAgIH07XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChsb2NhbGVzLm1hcChsb2FkQW5kQWRkTG9jYWxlKSk7XG5cbiAgICByZXR1cm4gdHJhbnNsYXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGNvbWJpbmVkIGxpc3Qgb2YgdHJhbnNsYXRpb25zIGZvciBhbGwgdGhlIHByb3ZpZGVkIGxvY2FsZXMuXG4gICAqIFRoZSBsb2NhbGVzIGFyZSBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIG9iamVjdCBwZXIga2V5IGFuZCBhbiBhcnJheSBvZiB0aGVzZSBvYmplY3RzIGlzIHJldHVybmVkLlxuICAgKi9cbiAgYXN5bmMgZ2V0Q29tYmluZWRMaXN0T2ZUcmFuc2xhdGlvbnNGb3JQZXJLZXkoXG4gICAgbG9jYWxlczogc3RyaW5nW11cbiAgKTogUHJvbWlzZTx7IGtleTogc3RyaW5nOyBbbG9jYWxlOiBzdHJpbmddOiBzdHJpbmcgfVtdPiB7XG4gICAgY29uc3QgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5sb2FkVHJhbnNsYXRpb25zRm9yTG9jYWxlcyhsb2NhbGVzKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbk1hcDogeyBba2V5OiBzdHJpbmddOiB7IFtsb2NhbGU6IHN0cmluZ106IHN0cmluZyB9IH0gPSB7fTtcblxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIE9iamVjdC5rZXlzKHRyYW5zbGF0aW9ucykpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRyYW5zbGF0aW9uc1tsb2NhbGVdKSkge1xuICAgICAgICBsZXQgdHJhbnNsYXRpb25zRm9yS2V5ID0gdHJhbnNsYXRpb25NYXBba2V5XTtcbiAgICAgICAgaWYgKCF0cmFuc2xhdGlvbnNGb3JLZXkpIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNGb3JLZXkgPSB7fTtcbiAgICAgICAgICB0cmFuc2xhdGlvbk1hcFtrZXldID0gdHJhbnNsYXRpb25zRm9yS2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNsYXRpb25zRm9yS2V5W2xvY2FsZV0gPSB0cmFuc2xhdGlvbnNbbG9jYWxlXVtrZXldO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh0cmFuc2xhdGlvbk1hcCkuc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKTtcblxuICAgIHJldHVybiBrZXlzLm1hcChrZXkgPT4gT2JqZWN0LmFzc2lnbih7IGtleSB9LCB0cmFuc2xhdGlvbk1hcFtrZXldKSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgZmlsZXMgb2YgdGhlIHRyYW5zbGF0aW9uIGFwcGxpY2F0aW9uIHdpdGggdGhlIHByb3ZpZGVkIHRyYW5zbGF0aW9ucy5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZVRyYW5zbGF0aW9ucyhcbiAgICB0cmFuc2xhdGlvbnM6IHsga2V5OiBzdHJpbmc7IFtsb2NhbGU6IHN0cmluZ106IHN0cmluZyB9W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmlsZXNUb1VwbG9hZCA9IG5ldyBBcnJheTx7IHBhdGg6IHN0cmluZzsgY29udGVudHM6IEZpbGUgfT4oKTtcbiAgICBjb25zdCB0cmFuc2xhdGlvbnNQZXJMb2NhbGU6IHsgW2xvY2FsZTogc3RyaW5nXTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB9ID0ge307XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiB0cmFuc2xhdGlvbnMpIHtcbiAgICAgIGNvbnN0IGtleSA9IGVudHJ5LmtleTtcbiAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIE9iamVjdC5rZXlzKGVudHJ5KSkge1xuICAgICAgICBpZiAobG9jYWxlID09PSAna2V5Jykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdHJhbnNsYXRpb25zUGVyTG9jYWxlW2xvY2FsZV0pIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXSA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5W2xvY2FsZV0pIHtcbiAgICAgICAgICB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXVtrZXldID0gZW50cnlbbG9jYWxlXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxhbmdzID0gdGhpcy5hcHBTdGF0ZS5zdGF0ZS5sYW5ncyBhcyBzdHJpbmdbXTtcblxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxhbmdzKSB7XG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGAke2xvY2FsZX0uanNvbmA7XG4gICAgICBmaWxlc1RvVXBsb2FkLnB1c2goe1xuICAgICAgICBwYXRoOiBmaWxlTmFtZSxcbiAgICAgICAgY29udGVudHM6IG5ldyBGaWxlKFxuICAgICAgICAgIFtKU09OLnN0cmluZ2lmeSh7IFtsb2NhbGVdOiB0cmFuc2xhdGlvbnNQZXJMb2NhbGVbbG9jYWxlXSB8fCB7fSB9KV0sXG4gICAgICAgICAgZmlsZU5hbWVcbiAgICAgICAgKVxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IGFwcCA9IGF3YWl0IHRoaXMuZ2V0T3JDcmVhdGVUcmFuc2xhdGlvbkFwcCgpO1xuICAgIGF3YWl0IHRoaXMuYXBwU2VydmljZS5iaW5hcnkoYXBwKS51cGRhdGVGaWxlcyhmaWxlc1RvVXBsb2FkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBUaGUgdHJhbnNsYXRpb24gYXBwIGZvciB0aGUgY3VycmVudCB0ZW5hbnQuIElmIGl0IGRvZXMgbm90IGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqL1xuICBhc3luYyBnZXRPckNyZWF0ZVRyYW5zbGF0aW9uQXBwKCk6IFByb21pc2U8SUFwcGxpY2F0aW9uPiB7XG4gICAgY29uc3QgeyBkYXRhOiBhcHBzIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UubGlzdEJ5TmFtZSh0aGlzLnRyYW5zbGF0aW9uQXBwTmFtZSk7XG4gICAgY29uc3Qgb3duQXBwID0gYXBwcy5maW5kKFxuICAgICAgYXBwID0+XG4gICAgICAgIGFwcC5jb250ZXh0UGF0aCA9PT0gdGhpcy50cmFuc2xhdGlvbkFwcENvbnRleHRQYXRoICYmXG4gICAgICAgIGFwcC5vd25lci50ZW5hbnQuaWQgPT09IHRoaXMuYXBwU3RhdGUuY3VycmVudFRlbmFudC52YWx1ZS5uYW1lXG4gICAgKTtcbiAgICBpZiAob3duQXBwKSB7XG4gICAgICByZXR1cm4gb3duQXBwO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGF0YTogYXBwIH0gPSBhd2FpdCB0aGlzLmFwcFNlcnZpY2UuY3JlYXRlKHtcbiAgICAgIG5hbWU6IHRoaXMudHJhbnNsYXRpb25BcHBOYW1lLFxuICAgICAgY29udGV4dFBhdGg6IHRoaXMudHJhbnNsYXRpb25BcHBDb250ZXh0UGF0aCxcbiAgICAgIGtleTogYCR7dGhpcy50cmFuc2xhdGlvbkFwcENvbnRleHRQYXRofS1hcHAta2V5YCxcbiAgICAgIHR5cGU6IEFwcGxpY2F0aW9uVHlwZS5IT1NURUQsXG4gICAgICBhdmFpbGFiaWxpdHk6IEFwcGxpY2F0aW9uQXZhaWxhYmlsaXR5Lk1BUktFVCxcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBpY29uOiB7XG4gICAgICAgICAgY2xhc3M6ICdsYW5ndWFnZTEnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBub0FwcFN3aXRjaGVyOiB0cnVlLFxuICAgICAgZGVzY3JpcHRpb246ICdQcm92aWRpbmcgdXNlciBkZWZpbmVkIHRyYW5zbGF0aW9ucydcbiAgICB9KTtcbiAgICBjb25zdCB6aXAgPSBhd2FpdCB0aGlzLnppcC5jcmVhdGVaaXAoW10pO1xuXG4gICAgY29uc3QgeyBkYXRhOiBiaW5hcnkgfSA9IGF3YWl0IHRoaXMuYXBwU2VydmljZS5iaW5hcnkoYXBwKS51cGxvYWQoemlwLCAndHJhbnNsYXRpb25zLnppcCcpO1xuICAgIGNvbnN0IHsgZGF0YTogdXBkYXRlZEFwcCB9ID0gYXdhaXQgdGhpcy5hcHBTZXJ2aWNlLnVwZGF0ZSh7XG4gICAgICBpZDogYXBwLmlkLFxuICAgICAgYWN0aXZlVmVyc2lvbklkOiBiaW5hcnkuaWQgYXMgc3RyaW5nXG4gICAgfSk7XG4gICAgcmV0dXJuIHVwZGF0ZWRBcHA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldEZpbGVGcm9tVHJhbnNsYXRpb25BcHAoZmlsZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RmlsZUZyb21QYXRoKGAvYXBwcy9wdWJsaWMvJHt0aGlzLnRyYW5zbGF0aW9uQXBwQ29udGV4dFBhdGh9LyR7ZmlsZX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RmlsZUZyb21QYXRoKHBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IGZpbmFsUGF0aCA9IGAke3BhdGh9P25vY2FjaGU9JHtEYXRlLm5vdygpfWA7XG5cbiAgICAvLyB1c2luZyBmZXRjaCBjbGllbnQgaW5zdGVhZCBvZiBmZXRjaCBkaXJlY3RseSBoZXJlIHRvIGVuc3VyZSBsb2FkaW5nIGluZGljYXRvciBpcyBzaG93biBkdXJpbmcgdGhlc2UgcmVxdWVzdHNcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZmV0Y2hDbGllbnQuZmV0Y2goZmluYWxQYXRoKTtcblxuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggZmlsZSBmcm9tICR7cGF0aH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xuICB9XG59XG4iXX0=