@edugouvfr/ngx-dsfr
Version:
NgxDsfr est un portage Angular des éléments d'interface du Système de Design de l'État Français (DSFR).
154 lines • 21.9 kB
JavaScript
import { Inject, Injectable } from '@angular/core';
import { BehaviorSubject, merge, Observable } from 'rxjs';
import { fromFetch } from 'rxjs/internal/observable/dom/fetch';
import { DSFR_CONFIG_TOKEN } from '../config/config-token';
import { Language } from '../services';
import { jsonPath2Value } from '../utils';
import { LABELS_BUNDLE_EN } from './i18n-labels-bundle-en';
import { LABELS_BUNDLE_FR } from './i18n-labels-bundle-fr';
import * as i0 from "@angular/core";
import * as i1 from "../services";
/**
* Maintient le code langue de l'application et signale le changement de langue.
*/
export class DsfrI18nService {
constructor(config, logger, langService) {
this.logger = logger;
this.langService = langService;
/**
* L'ensemble des bundles de libellés gérés par le service I18N.
*/
this.bundles = new Map();
this.completeLangChange = new BehaviorSubject(this.langService.lang);
this.completeLangChange$ = this.completeLangChange.asObservable();
this.bundles.set(Language.FR, LABELS_BUNDLE_FR);
this.bundles.set(Language.EN, LABELS_BUNDLE_EN);
this.onLangChange(this.langService.lang); // défaut
this.readMessagesFiles(config?.i18n).subscribe({
complete: () => this.startSubscribe(),
});
}
/**
* Retourne la valeur de traduction dans `messages` partir d'un path json.
* @param jsonPath le chemin dans le fichier de messages json de la langue courante
* @return le message et si non trouvé le path json
*/
t(jsonPath) {
return jsonPath2Value(this.currentBundle, jsonPath) ?? this.messageNotFound(this.langService.lang, jsonPath);
}
/**
* Permet d'étendre les ressources d'internationalisation sur un périmètre de langue défini.
*
* @param lang Le code langue sur deux caractères en minuscules.
* @param extension Le bundle contenant l'ensemble des libellés traduits dans la langue indiquée.
*/
extendsLabelsBundle(lang, extension) {
const locale = lang.toLowerCase();
if (locale.length !== 2) {
this.logger.warn("Le code langue n'est pas indiqué sur deux caractères, l'extension est ignorée");
return;
}
const existing = this.bundles.get(lang);
if (existing) {
//RPA: un jour viendra peut-être où la ligne ci-dessous ne compilera plus et ce serait une bonne chose
// on aimerait en effet qu'une erreur soit levée par le compilateur TS car le type I18nBundle est actuellement
// défini strictement (c'est juste un alias sur le type I18nBaseBundle)
// ce jour là ajuster la définition du type I18nBundle
const extendedBundle = { ...existing, ...extension };
this.bundles.set(lang, extendedBundle);
// si on modifie le bundle de la langue courante, il faut mettre à jour le bundle courant
if (this.langService.lang === lang) {
this.currentBundle = extendedBundle;
}
}
else {
this.logger.warn(`Aucun bundle à étendre pour le code langue <${lang}>`);
}
}
/**
* Démarre l'abonnement au changement de langue.
*/
startSubscribe() {
this.langService.langChange$.subscribe((code) => this.onLangChange(code));
}
/**
* Charge le bon fichier de messages selon le code langue, messages en anglais si non trouvé.
*/
onLangChange(code) {
this.currentBundle = this.bundles?.get(code) ?? this.bundles?.get(Language.EN) ?? LABELS_BUNDLE_EN;
this.completeLangChange.next(code); // indique la fin du chargement des bundles corrects
}
/**
* Si message non trouvé, retourne le message en anglais pour les langues autres que les langues par défaut.
*/
messageNotFound(codeLang, jsonPath) {
this.logger.warn(`Aucune traduction '${codeLang}' pour '${jsonPath}'`);
// try fallback to english
const englishFallback = codeLang !== Language.EN ? jsonPath2Value(this.bundles.get(Language.EN), jsonPath) : null;
return englishFallback ?? jsonPath;
}
/**
* Lit tous les fichiers de la configuration
* @param i18nconfig Configuration i18n
* @return événement complet sur l'observable quand tous les fichiers ont été lus, erreur ou non
*/
readMessagesFiles(i18nConfig) {
const all = [];
i18nConfig?.messagesFiles?.forEach((mf) => {
const observable = fetchFile(mf.filePath);
observable.subscribe({
next: (data) => {
console.info(`Lecture du fichier ${mf.filePath}`);
this.bundles.set(mf.code, data);
},
error: (err) => {
console.error(`Erreur ${err} dans la lecture du fichier ${mf.filePath}`);
},
});
all.push(observable);
});
return new Observable((subscriber) => {
merge(...all).subscribe({
complete: () => subscriber.complete(),
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, deps: [{ token: DSFR_CONFIG_TOKEN }, { token: i1.LoggerService }, { token: i1.LangService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrI18nService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [DSFR_CONFIG_TOKEN]
}] }, { type: i1.LoggerService }, { type: i1.LangService }] });
/**
* Lecture d'un fichier sur le serveur
* @param filePath Chemin partiel du fichier
* @param contentType text par défaut
* @return Observable
*/
function fetchFile(filePath, contentType = 'text/plain') {
const myHeaders = new Headers();
myHeaders.append('Content-Type', contentType);
const myConfig = { headers: myHeaders };
return new Observable((subscriber) => {
const fetchObs = fromFetch(filePath, myConfig).subscribe({
next: (response) => {
if (response.ok) {
response.json().then((data) => {
subscriber.next(data);
subscriber.complete();
});
}
else {
subscriber.error(response.status);
subscriber.complete();
}
},
error: (err) => subscriber.error(err),
});
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL3NoYXJlZC9pMThuL2kxOG4uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBRS9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzNELE9BQU8sRUFBZSxRQUFRLEVBQWlCLE1BQU0sYUFBYSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDMUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUJBQXlCLENBQUM7OztBQUczRDs7R0FFRztBQUVILE1BQU0sT0FBTyxlQUFlO0lBZ0IxQixZQUM2QixNQUFrQixFQUM1QixNQUFxQixFQUNyQixXQUF3QjtRQUR4QixXQUFNLEdBQU4sTUFBTSxDQUFlO1FBQ3JCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBYjNDOztXQUVHO1FBQ0ssWUFBTyxHQUFHLElBQUksR0FBRyxFQUEwQixDQUFDO1FBWWxELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLGVBQWUsQ0FBUyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ25ELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzdDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFO1NBQ3RDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsQ0FBQyxDQUFDLFFBQWdCO1FBQ2hCLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMvRyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxtQkFBbUIsQ0FBQyxJQUFZLEVBQUUsU0FBa0M7UUFDbEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2xDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO1lBRWxHLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQStCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BFLElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixzR0FBc0c7WUFDdEcsOEdBQThHO1lBQzlHLHVFQUF1RTtZQUN2RSxzREFBc0Q7WUFDdEQsTUFBTSxjQUFjLEdBQW1CLEVBQUUsR0FBRyxRQUFRLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQztZQUNyRSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFDdkMseUZBQXlGO1lBQ3pGLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxhQUFhLEdBQUcsY0FBYyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLCtDQUErQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQzNFLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDTyxjQUFjO1FBQ3RCLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRDs7T0FFRztJQUNPLFlBQVksQ0FBQyxJQUFZO1FBQ2pDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLGdCQUFnQixDQUFDO1FBQ25HLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxvREFBb0Q7SUFDMUYsQ0FBQztJQUVEOztPQUVHO0lBQ08sZUFBZSxDQUFDLFFBQWdCLEVBQUUsUUFBZ0I7UUFDMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLFFBQVEsV0FBVyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZFLDBCQUEwQjtRQUMxQixNQUFNLGVBQWUsR0FBRyxRQUFRLEtBQUssUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBRWxILE9BQU8sZUFBZSxJQUFJLFFBQVEsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGlCQUFpQixDQUFDLFVBQXNDO1FBQzlELE1BQU0sR0FBRyxHQUF5QixFQUFFLENBQUM7UUFDckMsVUFBVSxFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUN4QyxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7Z0JBQ25CLElBQUksRUFBRSxDQUFDLElBQVMsRUFBRSxFQUFFO29CQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztvQkFDbEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbEMsQ0FBQztnQkFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtvQkFDYixPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRywrQkFBK0IsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQzNFLENBQUM7YUFDRixDQUFDLENBQUM7WUFDSCxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLFVBQVUsQ0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQ3pDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDdEIsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7YUFDdEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOytHQTVIVSxlQUFlLGtCQWlCaEIsaUJBQWlCO21IQWpCaEIsZUFBZSxjQURGLE1BQU07OzRGQUNuQixlQUFlO2tCQUQzQixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7MEJBa0I3QixNQUFNOzJCQUFDLGlCQUFpQjs7QUE4RzdCOzs7OztHQUtHO0FBQ0gsU0FBUyxTQUFTLENBQUMsUUFBZ0IsRUFBRSxXQUFXLEdBQUcsWUFBWTtJQUM3RCxNQUFNLFNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQ2hDLFNBQVMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sUUFBUSxHQUFHLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBRXhDLE9BQU8sSUFBSSxVQUFVLENBQU0sQ0FBQyxVQUFVLEVBQUUsRUFBRTtRQUN4QyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUN2RCxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDakIsSUFBSSxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7b0JBQ2hCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTt3QkFDNUIsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFDdEIsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN4QixDQUFDLENBQUMsQ0FBQztnQkFDTCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sVUFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2xDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDeEIsQ0FBQztZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ3RDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBtZXJnZSwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZnJvbUZldGNoIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vYnNlcnZhYmxlL2RvbS9mZXRjaCc7XG5cbmltcG9ydCB7IERTRlJfQ09ORklHX1RPS0VOIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZy10b2tlbic7XG5pbXBvcnQgeyBEc2ZyQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnL2NvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBEc2ZySTE4bkNvbmZpZyB9IGZyb20gJy4uL2NvbmZpZy9pMThuLWNvbmZpZyc7XG5pbXBvcnQgeyBMYW5nU2VydmljZSwgTGFuZ3VhZ2UsIExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBqc29uUGF0aDJWYWx1ZSB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7IExBQkVMU19CVU5ETEVfRU4gfSBmcm9tICcuL2kxOG4tbGFiZWxzLWJ1bmRsZS1lbic7XG5pbXBvcnQgeyBMQUJFTFNfQlVORExFX0ZSIH0gZnJvbSAnLi9pMThuLWxhYmVscy1idW5kbGUtZnInO1xuaW1wb3J0IHsgRHNmckkxOG5CdW5kbGUsIERzZnJJMThuRXh0ZW5zaW9uQnVuZGxlIH0gZnJvbSAnLi9pMThuLXR5cGVzJztcblxuLyoqXG4gKiBNYWludGllbnQgbGUgY29kZSBsYW5ndWUgZGUgbCdhcHBsaWNhdGlvbiBldCBzaWduYWxlIGxlIGNoYW5nZW1lbnQgZGUgbGFuZ3VlLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIERzZnJJMThuU2VydmljZSB7XG4gIC8qKiBPYnNlcnZhYmxlIGF1IGNoYW5nZW1lbnQgZGUgbGEgbGFuZ3VlIChmaW4gZHUgY2hhcmdlbWVudCBkZXMgbm91dmVhdXggYnVuZGxlcykgKi9cbiAgY29tcGxldGVMYW5nQ2hhbmdlJDogT2JzZXJ2YWJsZTxzdHJpbmc+O1xuXG4gIHByaXZhdGUgY29tcGxldGVMYW5nQ2hhbmdlOiBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPjtcblxuICAvKipcbiAgICogTCdlbnNlbWJsZSBkZXMgYnVuZGxlcyBkZSBsaWJlbGzDqXMgZ8OpcsOpcyBwYXIgbGUgc2VydmljZSBJMThOLlxuICAgKi9cbiAgcHJpdmF0ZSBidW5kbGVzID0gbmV3IE1hcDxzdHJpbmcsIERzZnJJMThuQnVuZGxlPigpO1xuXG4gIC8qKlxuICAgKiBNZXNzYWdlcyAoSlNPTikgZGUgbGEgbGFuZ3VlIGNvdXJhbnRlLlxuICAgKi9cbiAgcHJpdmF0ZSBjdXJyZW50QnVuZGxlOiBEc2ZySTE4bkJ1bmRsZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERTRlJfQ09ORklHX1RPS0VOKSBjb25maWc6IERzZnJDb25maWcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBsYW5nU2VydmljZTogTGFuZ1NlcnZpY2UsXG4gICkge1xuICAgIHRoaXMuY29tcGxldGVMYW5nQ2hhbmdlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHRoaXMubGFuZ1NlcnZpY2UubGFuZyk7XG4gICAgdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UkID0gdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UuYXNPYnNlcnZhYmxlKCk7XG5cbiAgICB0aGlzLmJ1bmRsZXMuc2V0KExhbmd1YWdlLkZSLCBMQUJFTFNfQlVORExFX0ZSKTtcbiAgICB0aGlzLmJ1bmRsZXMuc2V0KExhbmd1YWdlLkVOLCBMQUJFTFNfQlVORExFX0VOKTtcbiAgICB0aGlzLm9uTGFuZ0NoYW5nZSh0aGlzLmxhbmdTZXJ2aWNlLmxhbmcpOyAvLyBkw6lmYXV0XG4gICAgdGhpcy5yZWFkTWVzc2FnZXNGaWxlcyhjb25maWc/LmkxOG4pLnN1YnNjcmliZSh7XG4gICAgICBjb21wbGV0ZTogKCkgPT4gdGhpcy5zdGFydFN1YnNjcmliZSgpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldG91cm5lIGxhIHZhbGV1ciBkZSB0cmFkdWN0aW9uIGRhbnMgYG1lc3NhZ2VzYCBwYXJ0aXIgZCd1biBwYXRoIGpzb24uXG4gICAqIEBwYXJhbSBqc29uUGF0aCBsZSBjaGVtaW4gZGFucyBsZSBmaWNoaWVyIGRlIG1lc3NhZ2VzIGpzb24gZGUgbGEgbGFuZ3VlIGNvdXJhbnRlXG4gICAqIEByZXR1cm4gbGUgbWVzc2FnZSBldCBzaSBub24gdHJvdXbDqSBsZSBwYXRoIGpzb25cbiAgICovXG4gIHQoanNvblBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGpzb25QYXRoMlZhbHVlKHRoaXMuY3VycmVudEJ1bmRsZSwganNvblBhdGgpID8/IHRoaXMubWVzc2FnZU5vdEZvdW5kKHRoaXMubGFuZ1NlcnZpY2UubGFuZywganNvblBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcm1ldCBkJ8OpdGVuZHJlIGxlcyByZXNzb3VyY2VzIGQnaW50ZXJuYXRpb25hbGlzYXRpb24gc3VyIHVuIHDDqXJpbcOodHJlIGRlIGxhbmd1ZSBkw6lmaW5pLlxuICAgKlxuICAgKiBAcGFyYW0gbGFuZyBMZSBjb2RlIGxhbmd1ZSBzdXIgZGV1eCBjYXJhY3TDqHJlcyBlbiBtaW51c2N1bGVzLlxuICAgKiBAcGFyYW0gZXh0ZW5zaW9uIExlIGJ1bmRsZSBjb250ZW5hbnQgbCdlbnNlbWJsZSBkZXMgbGliZWxsw6lzIHRyYWR1aXRzIGRhbnMgbGEgbGFuZ3VlIGluZGlxdcOpZS5cbiAgICovXG4gIGV4dGVuZHNMYWJlbHNCdW5kbGUobGFuZzogc3RyaW5nLCBleHRlbnNpb246IERzZnJJMThuRXh0ZW5zaW9uQnVuZGxlKTogdm9pZCB7XG4gICAgY29uc3QgbG9jYWxlID0gbGFuZy50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChsb2NhbGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiTGUgY29kZSBsYW5ndWUgbidlc3QgcGFzIGluZGlxdcOpIHN1ciBkZXV4IGNhcmFjdMOocmVzLCBsJ2V4dGVuc2lvbiBlc3QgaWdub3LDqWVcIik7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZzogRHNmckkxOG5CdW5kbGUgfCB1bmRlZmluZWQgPSB0aGlzLmJ1bmRsZXMuZ2V0KGxhbmcpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgLy9SUEE6IHVuIGpvdXIgdmllbmRyYSBwZXV0LcOqdHJlIG/DuSBsYSBsaWduZSBjaS1kZXNzb3VzIG5lIGNvbXBpbGVyYSBwbHVzIGV0IGNlIHNlcmFpdCB1bmUgYm9ubmUgY2hvc2VcbiAgICAgIC8vIG9uIGFpbWVyYWl0IGVuIGVmZmV0IHF1J3VuZSBlcnJldXIgc29pdCBsZXbDqWUgcGFyIGxlIGNvbXBpbGF0ZXVyIFRTIGNhciBsZSB0eXBlIEkxOG5CdW5kbGUgZXN0IGFjdHVlbGxlbWVudFxuICAgICAgLy8gZMOpZmluaSBzdHJpY3RlbWVudCAoYydlc3QganVzdGUgdW4gYWxpYXMgc3VyIGxlIHR5cGUgSTE4bkJhc2VCdW5kbGUpXG4gICAgICAvLyBjZSBqb3VyIGzDoCBhanVzdGVyIGxhIGTDqWZpbml0aW9uIGR1IHR5cGUgSTE4bkJ1bmRsZVxuICAgICAgY29uc3QgZXh0ZW5kZWRCdW5kbGU6IERzZnJJMThuQnVuZGxlID0geyAuLi5leGlzdGluZywgLi4uZXh0ZW5zaW9uIH07XG4gICAgICB0aGlzLmJ1bmRsZXMuc2V0KGxhbmcsIGV4dGVuZGVkQnVuZGxlKTtcbiAgICAgIC8vIHNpIG9uIG1vZGlmaWUgbGUgYnVuZGxlIGRlIGxhIGxhbmd1ZSBjb3VyYW50ZSwgaWwgZmF1dCBtZXR0cmUgw6Agam91ciBsZSBidW5kbGUgY291cmFudFxuICAgICAgaWYgKHRoaXMubGFuZ1NlcnZpY2UubGFuZyA9PT0gbGFuZykge1xuICAgICAgICB0aGlzLmN1cnJlbnRCdW5kbGUgPSBleHRlbmRlZEJ1bmRsZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2dnZXIud2FybihgQXVjdW4gYnVuZGxlIMOgIMOpdGVuZHJlIHBvdXIgbGUgY29kZSBsYW5ndWUgPCR7bGFuZ30+YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIETDqW1hcnJlIGwnYWJvbm5lbWVudCBhdSBjaGFuZ2VtZW50IGRlIGxhbmd1ZS5cbiAgICovXG4gIHByb3RlY3RlZCBzdGFydFN1YnNjcmliZSgpIHtcbiAgICB0aGlzLmxhbmdTZXJ2aWNlLmxhbmdDaGFuZ2UkLnN1YnNjcmliZSgoY29kZSkgPT4gdGhpcy5vbkxhbmdDaGFuZ2UoY29kZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYXJnZSBsZSBib24gZmljaGllciBkZSBtZXNzYWdlcyBzZWxvbiBsZSBjb2RlIGxhbmd1ZSwgbWVzc2FnZXMgZW4gYW5nbGFpcyBzaSBub24gdHJvdXbDqS5cbiAgICovXG4gIHByb3RlY3RlZCBvbkxhbmdDaGFuZ2UoY29kZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50QnVuZGxlID0gdGhpcy5idW5kbGVzPy5nZXQoY29kZSkgPz8gdGhpcy5idW5kbGVzPy5nZXQoTGFuZ3VhZ2UuRU4pID8/IExBQkVMU19CVU5ETEVfRU47XG4gICAgdGhpcy5jb21wbGV0ZUxhbmdDaGFuZ2UubmV4dChjb2RlKTsgLy8gaW5kaXF1ZSBsYSBmaW4gZHUgY2hhcmdlbWVudCBkZXMgYnVuZGxlcyBjb3JyZWN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFNpIG1lc3NhZ2Ugbm9uIHRyb3V2w6ksIHJldG91cm5lIGxlIG1lc3NhZ2UgZW4gYW5nbGFpcyBwb3VyIGxlcyBsYW5ndWVzIGF1dHJlcyBxdWUgbGVzIGxhbmd1ZXMgcGFyIGTDqWZhdXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgbWVzc2FnZU5vdEZvdW5kKGNvZGVMYW5nOiBzdHJpbmcsIGpzb25QYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHRoaXMubG9nZ2VyLndhcm4oYEF1Y3VuZSB0cmFkdWN0aW9uICcke2NvZGVMYW5nfScgcG91ciAnJHtqc29uUGF0aH0nYCk7XG4gICAgLy8gdHJ5IGZhbGxiYWNrIHRvIGVuZ2xpc2hcbiAgICBjb25zdCBlbmdsaXNoRmFsbGJhY2sgPSBjb2RlTGFuZyAhPT0gTGFuZ3VhZ2UuRU4gPyBqc29uUGF0aDJWYWx1ZSh0aGlzLmJ1bmRsZXMuZ2V0KExhbmd1YWdlLkVOKSwganNvblBhdGgpIDogbnVsbDtcblxuICAgIHJldHVybiBlbmdsaXNoRmFsbGJhY2sgPz8ganNvblBhdGg7XG4gIH1cblxuICAvKipcbiAgICogTGl0IHRvdXMgbGVzIGZpY2hpZXJzIGRlIGxhIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIGkxOG5jb25maWcgQ29uZmlndXJhdGlvbiBpMThuXG4gICAqIEByZXR1cm4gw6l2w6luZW1lbnQgY29tcGxldCBzdXIgbCdvYnNlcnZhYmxlIHF1YW5kIHRvdXMgbGVzIGZpY2hpZXJzIG9udCDDqXTDqSBsdXMsIGVycmV1ciBvdSBub25cbiAgICovXG4gIHByaXZhdGUgcmVhZE1lc3NhZ2VzRmlsZXMoaTE4bkNvbmZpZzogRHNmckkxOG5Db25maWcgfCB1bmRlZmluZWQpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCBhbGw6IE9ic2VydmFibGU8c3RyaW5nPltdID0gW107XG4gICAgaTE4bkNvbmZpZz8ubWVzc2FnZXNGaWxlcz8uZm9yRWFjaCgobWYpID0+IHtcbiAgICAgIGNvbnN0IG9ic2VydmFibGUgPSBmZXRjaEZpbGUobWYuZmlsZVBhdGgpO1xuICAgICAgb2JzZXJ2YWJsZS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgICAgY29uc29sZS5pbmZvKGBMZWN0dXJlIGR1IGZpY2hpZXIgJHttZi5maWxlUGF0aH1gKTtcbiAgICAgICAgICB0aGlzLmJ1bmRsZXMuc2V0KG1mLmNvZGUsIGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycmV1ciAke2Vycn0gZGFucyBsYSBsZWN0dXJlIGR1IGZpY2hpZXIgJHttZi5maWxlUGF0aH1gKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYWxsLnB1c2gob2JzZXJ2YWJsZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8dm9pZD4oKHN1YnNjcmliZXIpID0+IHtcbiAgICAgIG1lcmdlKC4uLmFsbCkuc3Vic2NyaWJlKHtcbiAgICAgICAgY29tcGxldGU6ICgpID0+IHN1YnNjcmliZXIuY29tcGxldGUoKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogTGVjdHVyZSBkJ3VuIGZpY2hpZXIgc3VyIGxlIHNlcnZldXJcbiAqIEBwYXJhbSBmaWxlUGF0aCBDaGVtaW4gcGFydGllbCBkdSBmaWNoaWVyXG4gKiBAcGFyYW0gY29udGVudFR5cGUgdGV4dCBwYXIgZMOpZmF1dFxuICogQHJldHVybiBPYnNlcnZhYmxlXG4gKi9cbmZ1bmN0aW9uIGZldGNoRmlsZShmaWxlUGF0aDogc3RyaW5nLCBjb250ZW50VHlwZSA9ICd0ZXh0L3BsYWluJyk6IE9ic2VydmFibGU8YW55PiB7XG4gIGNvbnN0IG15SGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gIG15SGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcbiAgY29uc3QgbXlDb25maWcgPSB7IGhlYWRlcnM6IG15SGVhZGVycyB9O1xuXG4gIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxhbnk+KChzdWJzY3JpYmVyKSA9PiB7XG4gICAgY29uc3QgZmV0Y2hPYnMgPSBmcm9tRmV0Y2goZmlsZVBhdGgsIG15Q29uZmlnKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoZGF0YSk7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3Vic2NyaWJlci5lcnJvcihyZXNwb25zZS5zdGF0dXMpO1xuICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiBzdWJzY3JpYmVyLmVycm9yKGVyciksXG4gICAgfSk7XG4gIH0pO1xufVxuIl19