UNPKG

@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).

85 lines 15.4 kB
import { CommonModule, DOCUMENT } from '@angular/common'; import { Component, EventEmitter, Inject, Input, Output, ViewEncapsulation } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { DsfrI18nPipe, newUniqueId } from '../../shared'; import * as i0 from "@angular/core"; import * as i1 from "../../shared"; import * as i2 from "@angular/common"; /** Composant de sélection de la langue. */ export class DsfrTranslateComponent { /** @internal */ constructor(langService, elementRef, document) { this.langService = langService; this.elementRef = elementRef; this.document = document; /** Liste des langues proposées à l'utilisateur. */ this.languages = []; /** Sans bordure si 'false' */ this.outline = true; /** Événement émit uniquement si la langue sélectionnée ne contient pas de href. Il contient le code de la langue. */ this.langChange = new EventEmitter(); } get currentLangCode() { return this.langService.lang; } get currentLabel() { let label = ''; const language = this.getCurrentLang(); if (language && language.label) { label = language.label; } return label; } /** Force la langue courante. */ set currentLangCode(value) { this.langService.lang = value; // Informe le service this.setDocLang(value); // Positionne la langue dans le document html } /** @internal */ ngOnInit() { this.collapseId = newUniqueId(); } /** @internal */ onClick(event, lang) { this.currentLangCode = lang.value; if (!lang.link) { event.preventDefault(); // Si on ne déclenche pas le href, on est obligé de fermer manuellement le composant this.collapse(); this.langChange.emit(lang.value); } } getCurrentLang() { return this.languages.find((l) => l.value === this.currentLangCode); } collapse() { const nativeElt = this.elementRef.nativeElement; const buttonElt = nativeElt.querySelector('button'); if (buttonElt) { buttonElt.setAttribute('aria-expanded', 'false'); buttonElt.setAttribute('data-fr-js-collapse-button', true); } } /** Positionne l'attribut lang dans la balise html, ex : lang="fr" */ setDocLang(codeLang) { this.document?.documentElement.setAttribute('lang', codeLang); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrTranslateComponent, deps: [{ token: i1.LangService }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrTranslateComponent, isStandalone: true, selector: "dsfr-translate", inputs: { languages: "languages", outline: "outline", currentLangCode: "currentLangCode" }, outputs: { langChange: "langChange" }, ngImport: i0, template: "<nav role=\"navigation\" class=\"fr-translate fr-nav\">\n <div class=\"fr-nav__item\">\n <button\n type=\"button\"\n [ngClass]=\"{\n 'fr-translate__btn': true,\n 'fr-btn fr-btn--tertiary': outline,\n 'fr-btn--tertiary-no-outline': !outline\n }\"\n [attr.aria-controls]=\"collapseId\"\n aria-expanded=\"false\"\n title=\"{{ 'translate.tooltip' | dsfrI18n }}\">\n {{ currentLangCode.toUpperCase() }}<span class=\"fr-hidden-lg\">&nbsp;- {{ currentLabel }}</span>\n </button>\n <div class=\"fr-collapse fr-translate__menu fr-menu\" [id]=\"collapseId\">\n <ul class=\"fr-menu__list\">\n @for (lang of languages; track lang) {\n <li>\n <a\n class=\"fr-translate__language fr-nav__link\"\n hreflang=\"{{ lang.value }}\"\n lang=\"{{ lang.value }}\"\n [href]=\"lang.link ? lang.link : lang.value\"\n [attr.aria-current]=\"lang.value === currentLangCode ? true : null\"\n (click)=\"onClick($event, lang)\">\n {{ lang.value.toUpperCase() }}&nbsp;- {{ lang.label }}\n </a>\n </li>\n }\n </ul>\n </div>\n </div>\n</nav>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: DsfrI18nPipe, name: "dsfrI18n" }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrTranslateComponent, decorators: [{ type: Component, args: [{ selector: 'dsfr-translate', encapsulation: ViewEncapsulation.None, standalone: true, imports: [CommonModule, FormsModule, DsfrI18nPipe], template: "<nav role=\"navigation\" class=\"fr-translate fr-nav\">\n <div class=\"fr-nav__item\">\n <button\n type=\"button\"\n [ngClass]=\"{\n 'fr-translate__btn': true,\n 'fr-btn fr-btn--tertiary': outline,\n 'fr-btn--tertiary-no-outline': !outline\n }\"\n [attr.aria-controls]=\"collapseId\"\n aria-expanded=\"false\"\n title=\"{{ 'translate.tooltip' | dsfrI18n }}\">\n {{ currentLangCode.toUpperCase() }}<span class=\"fr-hidden-lg\">&nbsp;- {{ currentLabel }}</span>\n </button>\n <div class=\"fr-collapse fr-translate__menu fr-menu\" [id]=\"collapseId\">\n <ul class=\"fr-menu__list\">\n @for (lang of languages; track lang) {\n <li>\n <a\n class=\"fr-translate__language fr-nav__link\"\n hreflang=\"{{ lang.value }}\"\n lang=\"{{ lang.value }}\"\n [href]=\"lang.link ? lang.link : lang.value\"\n [attr.aria-current]=\"lang.value === currentLangCode ? true : null\"\n (click)=\"onClick($event, lang)\">\n {{ lang.value.toUpperCase() }}&nbsp;- {{ lang.label }}\n </a>\n </li>\n }\n </ul>\n </div>\n </div>\n</nav>\n" }] }], ctorParameters: () => [{ type: i1.LangService }, { type: i0.ElementRef }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }], propDecorators: { languages: [{ type: Input }], outline: [{ type: Input }], langChange: [{ type: Output }], currentLangCode: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1kc2ZyLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL3RyYW5zbGF0ZS90cmFuc2xhdGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvdHJhbnNsYXRlL3RyYW5zbGF0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFlLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7OztBQVV0RSwyQ0FBMkM7QUFDM0MsTUFBTSxPQUFPLHNCQUFzQjtJQWFqQyxnQkFBZ0I7SUFDaEIsWUFDVSxXQUF3QixFQUN4QixVQUFzQixFQUNLLFFBQWtCO1FBRjdDLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDSyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBaEJ2RCxtREFBbUQ7UUFDMUMsY0FBUyxHQUFlLEVBQUUsQ0FBQztRQUVwQyw4QkFBOEI7UUFDckIsWUFBTyxHQUFHLElBQUksQ0FBQztRQUV4QixxSEFBcUg7UUFDM0csZUFBVSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFVL0MsQ0FBQztJQUVKLElBQUksZUFBZTtRQUNqQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDZixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFdkMsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQy9CLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQ3pCLENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxnQ0FBZ0M7SUFDaEMsSUFBYSxlQUFlLENBQUMsS0FBYTtRQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxxQkFBcUI7UUFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLDZDQUE2QztJQUN2RSxDQUFDO0lBRUQsZ0JBQWdCO0lBQ2hCLFFBQVE7UUFDTixJQUFJLENBQUMsVUFBVSxHQUFHLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsT0FBTyxDQUFDLEtBQVksRUFBRSxJQUFjO1FBQ2xDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUVsQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3ZCLG9GQUFvRjtZQUNwRixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBRU8sY0FBYztRQUNwQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRU8sUUFBUTtRQUNkLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBQ2hELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLFNBQVMsQ0FBQyxZQUFZLENBQUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2pELFNBQVMsQ0FBQyxZQUFZLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0QsQ0FBQztJQUNILENBQUM7SUFFRCxxRUFBcUU7SUFDN0QsVUFBVSxDQUFDLFFBQWdCO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEVBQUUsZUFBZSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEUsQ0FBQzsrR0ExRVUsc0JBQXNCLHVFQWlCdkIsUUFBUTttR0FqQlAsc0JBQXNCLDZNQ2RuQyxtdENBaUNBLDJDRHRCWSxZQUFZLDRIQUFFLFdBQVcsMEJBQUUsWUFBWTs7NEZBR3RDLHNCQUFzQjtrQkFSbEMsU0FBUzsrQkFDRSxnQkFBZ0IsaUJBRVgsaUJBQWlCLENBQUMsSUFBSSxjQUN6QixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksQ0FBQzs7MEJBb0IvQyxNQUFNOzJCQUFDLFFBQVE7eUNBZlQsU0FBUztzQkFBakIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUs7Z0JBR0ksVUFBVTtzQkFBbkIsTUFBTTtnQkE0Qk0sZUFBZTtzQkFBM0IsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSwgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEc2ZySTE4blBpcGUsIExhbmdTZXJ2aWNlLCBuZXdVbmlxdWVJZCB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBEc2ZyTGFuZyB9IGZyb20gJy4vbGFuZy5tb2RlbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RzZnItdHJhbnNsYXRlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RyYW5zbGF0ZS5jb21wb25lbnQuaHRtbCcsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlLCBEc2ZySTE4blBpcGVdLFxufSlcbi8qKiBDb21wb3NhbnQgZGUgc8OpbGVjdGlvbiBkZSBsYSBsYW5ndWUuICovXG5leHBvcnQgY2xhc3MgRHNmclRyYW5zbGF0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKiBMaXN0ZSBkZXMgbGFuZ3VlcyBwcm9wb3PDqWVzIMOgIGwndXRpbGlzYXRldXIuICovXG4gIEBJbnB1dCgpIGxhbmd1YWdlczogRHNmckxhbmdbXSA9IFtdO1xuXG4gIC8qKiBTYW5zIGJvcmR1cmUgc2kgJ2ZhbHNlJyAqL1xuICBASW5wdXQoKSBvdXRsaW5lID0gdHJ1ZTtcblxuICAvKiogw4l2w6luZW1lbnQgw6ltaXQgdW5pcXVlbWVudCBzaSBsYSBsYW5ndWUgc8OpbGVjdGlvbm7DqWUgbmUgY29udGllbnQgcGFzIGRlIGhyZWYuIElsIGNvbnRpZW50IGxlIGNvZGUgZGUgbGEgbGFuZ3VlLiAqL1xuICBAT3V0cHV0KCkgbGFuZ0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgY29sbGFwc2VJZDogc3RyaW5nO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBsYW5nU2VydmljZTogTGFuZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQ6IERvY3VtZW50LFxuICApIHt9XG5cbiAgZ2V0IGN1cnJlbnRMYW5nQ29kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxhbmdTZXJ2aWNlLmxhbmc7XG4gIH1cblxuICBnZXQgY3VycmVudExhYmVsKCk6IHN0cmluZyB7XG4gICAgbGV0IGxhYmVsID0gJyc7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSB0aGlzLmdldEN1cnJlbnRMYW5nKCk7XG5cbiAgICBpZiAobGFuZ3VhZ2UgJiYgbGFuZ3VhZ2UubGFiZWwpIHtcbiAgICAgIGxhYmVsID0gbGFuZ3VhZ2UubGFiZWw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxhYmVsO1xuICB9XG5cbiAgLyoqIEZvcmNlIGxhIGxhbmd1ZSBjb3VyYW50ZS4gKi9cbiAgQElucHV0KCkgc2V0IGN1cnJlbnRMYW5nQ29kZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5sYW5nU2VydmljZS5sYW5nID0gdmFsdWU7IC8vIEluZm9ybWUgbGUgc2VydmljZVxuICAgIHRoaXMuc2V0RG9jTGFuZyh2YWx1ZSk7IC8vIFBvc2l0aW9ubmUgbGEgbGFuZ3VlIGRhbnMgbGUgZG9jdW1lbnQgaHRtbFxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbGxhcHNlSWQgPSBuZXdVbmlxdWVJZCgpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBvbkNsaWNrKGV2ZW50OiBFdmVudCwgbGFuZzogRHNmckxhbmcpIHtcbiAgICB0aGlzLmN1cnJlbnRMYW5nQ29kZSA9IGxhbmcudmFsdWU7XG5cbiAgICBpZiAoIWxhbmcubGluaykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIC8vIFNpIG9uIG5lIGTDqWNsZW5jaGUgcGFzIGxlIGhyZWYsIG9uIGVzdCBvYmxpZ8OpIGRlIGZlcm1lciBtYW51ZWxsZW1lbnQgbGUgY29tcG9zYW50XG4gICAgICB0aGlzLmNvbGxhcHNlKCk7XG4gICAgICB0aGlzLmxhbmdDaGFuZ2UuZW1pdChsYW5nLnZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEN1cnJlbnRMYW5nKCk6IERzZnJMYW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5sYW5ndWFnZXMuZmluZCgobCkgPT4gbC52YWx1ZSA9PT0gdGhpcy5jdXJyZW50TGFuZ0NvZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb2xsYXBzZSgpIHtcbiAgICBjb25zdCBuYXRpdmVFbHQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBidXR0b25FbHQgPSBuYXRpdmVFbHQucXVlcnlTZWxlY3RvcignYnV0dG9uJyk7XG4gICAgaWYgKGJ1dHRvbkVsdCkge1xuICAgICAgYnV0dG9uRWx0LnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xuICAgICAgYnV0dG9uRWx0LnNldEF0dHJpYnV0ZSgnZGF0YS1mci1qcy1jb2xsYXBzZS1idXR0b24nLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvKiogUG9zaXRpb25uZSBsJ2F0dHJpYnV0IGxhbmcgZGFucyBsYSBiYWxpc2UgaHRtbCwgZXggOiBsYW5nPVwiZnJcIiAqL1xuICBwcml2YXRlIHNldERvY0xhbmcoY29kZUxhbmc6IHN0cmluZykge1xuICAgIHRoaXMuZG9jdW1lbnQ/LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2xhbmcnLCBjb2RlTGFuZyk7XG4gIH1cbn1cbiIsIjxuYXYgcm9sZT1cIm5hdmlnYXRpb25cIiBjbGFzcz1cImZyLXRyYW5zbGF0ZSBmci1uYXZcIj5cbiAgPGRpdiBjbGFzcz1cImZyLW5hdl9faXRlbVwiPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAnZnItdHJhbnNsYXRlX19idG4nOiB0cnVlLFxuICAgICAgICAnZnItYnRuIGZyLWJ0bi0tdGVydGlhcnknOiBvdXRsaW5lLFxuICAgICAgICAnZnItYnRuLS10ZXJ0aWFyeS1uby1vdXRsaW5lJzogIW91dGxpbmVcbiAgICAgIH1cIlxuICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCJjb2xsYXBzZUlkXCJcbiAgICAgIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiXG4gICAgICB0aXRsZT1cInt7ICd0cmFuc2xhdGUudG9vbHRpcCcgfCBkc2ZySTE4biB9fVwiPlxuICAgICAge3sgY3VycmVudExhbmdDb2RlLnRvVXBwZXJDYXNlKCkgfX08c3BhbiBjbGFzcz1cImZyLWhpZGRlbi1sZ1wiPiZuYnNwOy0ge3sgY3VycmVudExhYmVsIH19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxkaXYgY2xhc3M9XCJmci1jb2xsYXBzZSBmci10cmFuc2xhdGVfX21lbnUgZnItbWVudVwiIFtpZF09XCJjb2xsYXBzZUlkXCI+XG4gICAgICA8dWwgY2xhc3M9XCJmci1tZW51X19saXN0XCI+XG4gICAgICAgIEBmb3IgKGxhbmcgb2YgbGFuZ3VhZ2VzOyB0cmFjayBsYW5nKSB7XG4gICAgICAgICAgPGxpPlxuICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgY2xhc3M9XCJmci10cmFuc2xhdGVfX2xhbmd1YWdlIGZyLW5hdl9fbGlua1wiXG4gICAgICAgICAgICAgIGhyZWZsYW5nPVwie3sgbGFuZy52YWx1ZSB9fVwiXG4gICAgICAgICAgICAgIGxhbmc9XCJ7eyBsYW5nLnZhbHVlIH19XCJcbiAgICAgICAgICAgICAgW2hyZWZdPVwibGFuZy5saW5rID8gbGFuZy5saW5rIDogbGFuZy52YWx1ZVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtY3VycmVudF09XCJsYW5nLnZhbHVlID09PSBjdXJyZW50TGFuZ0NvZGUgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvbkNsaWNrKCRldmVudCwgbGFuZylcIj5cbiAgICAgICAgICAgICAge3sgbGFuZy52YWx1ZS50b1VwcGVyQ2FzZSgpIH19Jm5ic3A7LSB7eyBsYW5nLmxhYmVsIH19XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgfVxuICAgICAgPC91bD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25hdj5cbiJdfQ==