@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).
94 lines • 26.7 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
import { DsfrPositionConst, newUniqueId } from '../../shared';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../link/item-link.component";
export class DsfrSidemenuComponent {
constructor() {
/** Attribut aria-label du menu latéral. */
this.ariaLabel = 'Menu latéral';
/** Affiche le menu latéral en version fixe */
this.sticky = false;
/** Affiche le menu latéral en version fixe sur 100% de la hauteur de la page. */
this.stickyFullHeight = false;
/** Le menu latéral est affiché à gauche par défaut mais il est possible de l'afficher à droite. */
this.position = DsfrPositionConst.LEFT;
/** Activer l'item sélectionné */
this.autoActive = true;
/** Evénement émis suite à la sélection d'un item avec lien `a` ou `routerLink`. */
this.itemSelect = new EventEmitter();
}
ngOnChanges({ menu }) {
if (menu) {
this._prevItemSelected = this.findItemActive(this.menu.items);
// Ajout des controlIds
this.checkControlId(this.menu?.items);
}
}
ngAfterContentInit() {
if (!this.controlId)
this.controlId = newUniqueId();
this.checkControlId(this.menu?.items);
}
/** @internal */
onSelectItem(item) {
if (this.autoActive) {
this.selectItem(item);
}
this.itemSelect.emit(item);
}
findItemActive(items) {
if (!items)
return undefined;
for (let i = 0; i < items.length; i++) {
const item = items[i];
let active = item.active ? item : undefined;
if (!active && item.subItems)
active = this.findItemActive(item.subItems);
if (active)
return active;
}
return undefined;
}
selectItem(item) {
if (this._prevItemSelected) {
this._prevItemSelected.active = false;
}
item.active = true;
this._prevItemSelected = item;
}
checkControlId(menuItems) {
if (!menuItems)
return;
menuItems.forEach((menuItem) => {
if (menuItem.subItems) {
if (!menuItem.controlId)
menuItem.controlId = newUniqueId();
this.checkControlId(menuItem.subItems);
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DsfrSidemenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DsfrSidemenuComponent, selector: "dsfr-sidemenu", inputs: { ariaLabel: "ariaLabel", controlId: "controlId", menu: "menu", sticky: "sticky", stickyFullHeight: "stickyFullHeight", position: "position", autoActive: "autoActive" }, outputs: { itemSelect: "itemSelect" }, usesOnChanges: true, ngImport: i0, template: "<nav\n class=\"fr-sidemenu\"\n [ngClass]=\"{\n 'fr-sidemenu--sticky': sticky,\n 'fr-sidemenu--sticky-full-height': stickyFullHeight,\n 'fr-sidemenu--right': position === 'right'\n }\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel\">\n <div class=\"fr-sidemenu__inner\">\n <button type=\"button\" class=\"fr-sidemenu__btn\" [attr.aria-controls]=\"controlId\" aria-expanded=\"false\">\n Dans cette rubrique\n </button>\n <div class=\"fr-collapse\" [id]=\"controlId\">\n <!--Titre de rubrique optionnel-->\n <ng-container *ngIf=\"menu?.title\">\n <div class=\"fr-sidemenu__title\">{{ menu.title }}</div>\n </ng-container>\n <!--Niveau 1-->\n <ul class=\"fr-sidemenu__list\">\n <ng-container *ngFor=\"let item1 of menu.items\">\n <li *ngIf=\"!item1.subItems\" class=\"fr-sidemenu__item\">\n <edu-item-link\n [item]=\"item1\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item1)\"\n [attr.aria-current]=\"item1.active ? 'page' : null\"></edu-item-link>\n </li>\n <li *ngIf=\"item1.subItems\" class=\"fr-sidemenu__item\">\n <!--Niveau 2-->\n <button\n type=\"button\"\n class=\"fr-sidemenu__btn\"\n aria-expanded=\"false\"\n [attr.aria-controls]=\"item1.controlId\"\n [attr.aria-current]=\"item1.active ? true : null\">\n <i *ngIf=\"item1.icon\" class=\"edu-item-icon\" [class]=\"item1.icon\" aria-hidden=\"true\"></i>\n {{ item1.label }}\n </button>\n <div class=\"fr-collapse\" [id]=\"item1.controlId\">\n <!--Titre de rubrique optionnel-->\n <ng-container *ngIf=\"item1.title\">\n <div class=\"fr-sidemenu__title\">{{ item1.title }}</div>\n </ng-container>\n <ul class=\"fr-sidemenu__list\">\n <ng-container *ngFor=\"let item2 of item1.subItems\">\n <li *ngIf=\"!item2.subItems\" class=\"fr-sidemenu__item\">\n <edu-item-link\n [item]=\"item2\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item2)\"\n [attr.aria-current]=\"item2.active ? 'page' : null\"></edu-item-link>\n </li>\n <li *ngIf=\"item2.subItems\" class=\"fr-sidemenu__item\">\n <button\n type=\"button\"\n class=\"fr-sidemenu__btn\"\n aria-expanded=\"false\"\n [attr.aria-controls]=\"item2.controlId\"\n [attr.aria-current]=\"item1.active ? true : null\">\n <i *ngIf=\"item2.icon\" class=\"edu-item-icon\" [class]=\"item2.icon\" aria-hidden=\"true\"></i>\n {{ item2.label }}\n </button>\n <div class=\"fr-collapse\" [id]=\"item2.controlId\">\n <ng-container *ngIf=\"item2.title\">\n <div class=\"fr-sidemenu__title\">{{ item2.title }}</div>\n </ng-container>\n <!--Niveau 3-->\n <ul class=\"fr-sidemenu__list\">\n <li\n *ngFor=\"let item3 of item2.subItems\"\n class=\"fr-sidemenu__item\"\n [attr.aria-current]=\"item3.active ? 'page' : null\">\n <edu-item-link\n [item]=\"item3\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item3)\"\n [attr.aria-current]=\"item3.active ? 'page' : null\"></edu-item-link>\n </li>\n </ul>\n </div>\n </li>\n </ng-container>\n </ul>\n </div>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n</nav>\n", styles: ["dsfr-sidemenu .edu-item-icon:before{--icon-size: 1rem;margin-right:.25rem}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ItemLinkComponent, selector: "edu-item-link", inputs: ["defaultIconPosition", "item"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DsfrSidemenuComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfr-sidemenu', encapsulation: ViewEncapsulation.None, template: "<nav\n class=\"fr-sidemenu\"\n [ngClass]=\"{\n 'fr-sidemenu--sticky': sticky,\n 'fr-sidemenu--sticky-full-height': stickyFullHeight,\n 'fr-sidemenu--right': position === 'right'\n }\"\n role=\"navigation\"\n [attr.aria-label]=\"ariaLabel\">\n <div class=\"fr-sidemenu__inner\">\n <button type=\"button\" class=\"fr-sidemenu__btn\" [attr.aria-controls]=\"controlId\" aria-expanded=\"false\">\n Dans cette rubrique\n </button>\n <div class=\"fr-collapse\" [id]=\"controlId\">\n <!--Titre de rubrique optionnel-->\n <ng-container *ngIf=\"menu?.title\">\n <div class=\"fr-sidemenu__title\">{{ menu.title }}</div>\n </ng-container>\n <!--Niveau 1-->\n <ul class=\"fr-sidemenu__list\">\n <ng-container *ngFor=\"let item1 of menu.items\">\n <li *ngIf=\"!item1.subItems\" class=\"fr-sidemenu__item\">\n <edu-item-link\n [item]=\"item1\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item1)\"\n [attr.aria-current]=\"item1.active ? 'page' : null\"></edu-item-link>\n </li>\n <li *ngIf=\"item1.subItems\" class=\"fr-sidemenu__item\">\n <!--Niveau 2-->\n <button\n type=\"button\"\n class=\"fr-sidemenu__btn\"\n aria-expanded=\"false\"\n [attr.aria-controls]=\"item1.controlId\"\n [attr.aria-current]=\"item1.active ? true : null\">\n <i *ngIf=\"item1.icon\" class=\"edu-item-icon\" [class]=\"item1.icon\" aria-hidden=\"true\"></i>\n {{ item1.label }}\n </button>\n <div class=\"fr-collapse\" [id]=\"item1.controlId\">\n <!--Titre de rubrique optionnel-->\n <ng-container *ngIf=\"item1.title\">\n <div class=\"fr-sidemenu__title\">{{ item1.title }}</div>\n </ng-container>\n <ul class=\"fr-sidemenu__list\">\n <ng-container *ngFor=\"let item2 of item1.subItems\">\n <li *ngIf=\"!item2.subItems\" class=\"fr-sidemenu__item\">\n <edu-item-link\n [item]=\"item2\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item2)\"\n [attr.aria-current]=\"item2.active ? 'page' : null\"></edu-item-link>\n </li>\n <li *ngIf=\"item2.subItems\" class=\"fr-sidemenu__item\">\n <button\n type=\"button\"\n class=\"fr-sidemenu__btn\"\n aria-expanded=\"false\"\n [attr.aria-controls]=\"item2.controlId\"\n [attr.aria-current]=\"item1.active ? true : null\">\n <i *ngIf=\"item2.icon\" class=\"edu-item-icon\" [class]=\"item2.icon\" aria-hidden=\"true\"></i>\n {{ item2.label }}\n </button>\n <div class=\"fr-collapse\" [id]=\"item2.controlId\">\n <ng-container *ngIf=\"item2.title\">\n <div class=\"fr-sidemenu__title\">{{ item2.title }}</div>\n </ng-container>\n <!--Niveau 3-->\n <ul class=\"fr-sidemenu__list\">\n <li\n *ngFor=\"let item3 of item2.subItems\"\n class=\"fr-sidemenu__item\"\n [attr.aria-current]=\"item3.active ? 'page' : null\">\n <edu-item-link\n [item]=\"item3\"\n customClass=\"fr-sidemenu__link\"\n (linkSelect)=\"onSelectItem(item3)\"\n [attr.aria-current]=\"item3.active ? 'page' : null\"></edu-item-link>\n </li>\n </ul>\n </div>\n </li>\n </ng-container>\n </ul>\n </div>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n</nav>\n", styles: ["dsfr-sidemenu .edu-item-icon:before{--icon-size: 1rem;margin-right:.25rem}\n"] }]
}], propDecorators: { ariaLabel: [{
type: Input
}], controlId: [{
type: Input
}], menu: [{
type: Input
}], sticky: [{
type: Input
}], stickyFullHeight: [{
type: Input
}], position: [{
type: Input
}], autoActive: [{
type: Input
}], itemSelect: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZW1lbnUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvc2lkZW1lbnUvc2lkZW1lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvc2lkZW1lbnUvc2lkZW1lbnUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFFTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFnQixpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7QUFTNUUsTUFBTSxPQUFPLHFCQUFxQjtJQU5sQztRQU9FLDRDQUE0QztRQUNuQyxjQUFTLEdBQUcsY0FBYyxDQUFDO1FBVXBDLCtDQUErQztRQUN0QyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRXhCLGlGQUFpRjtRQUN4RSxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFFbEMsbUdBQW1HO1FBQzFGLGFBQVEsR0FBaUIsaUJBQWlCLENBQUMsSUFBSSxDQUFDO1FBRXpELGlDQUFpQztRQUN4QixlQUFVLEdBQUcsSUFBSSxDQUFDO1FBRTNCLG1GQUFtRjtRQUN6RSxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7S0E0RHpEO0lBcERDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBaUI7UUFDakMsSUFBSSxJQUFJLEVBQUU7WUFDUixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzlELHVCQUF1QjtZQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDdkM7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztZQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFDcEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsWUFBWSxDQUFDLElBQWtCO1FBQzdCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3ZCO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVPLGNBQWMsQ0FBQyxLQUFxQjtRQUMxQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8sU0FBUyxDQUFDO1FBRTdCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRO2dCQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRSxJQUFJLE1BQU07Z0JBQUUsT0FBTyxNQUFNLENBQUM7U0FDM0I7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRU8sVUFBVSxDQUFDLElBQWtCO1FBQ25DLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1NBQ3ZDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRU8sY0FBYyxDQUFDLFNBQXlCO1FBQzlDLElBQUksQ0FBQyxTQUFTO1lBQUUsT0FBTztRQUV2QixTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDN0IsSUFBSSxRQUFRLENBQUMsUUFBUSxFQUFFO2dCQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVM7b0JBQUUsUUFBUSxDQUFDLFNBQVMsR0FBRyxXQUFXLEVBQUUsQ0FBQztnQkFDNUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDeEM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7K0dBcEZVLHFCQUFxQjttR0FBckIscUJBQXFCLG1TQ25CbEMsdWxJQTJGQTs7NEZEeEVhLHFCQUFxQjtrQkFOakMsU0FBUzsrQkFDRSxlQUFlLGlCQUdWLGlCQUFpQixDQUFDLElBQUk7OEJBSTVCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFLRyxJQUFJO3NCQUFaLEtBQUs7Z0JBR0csTUFBTTtzQkFBZCxLQUFLO2dCQUdHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0ksVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERzZnJQb3NpdGlvbiwgRHNmclBvc2l0aW9uQ29uc3QsIG5ld1VuaXF1ZUlkIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IERzZnJNZW51LCBEc2ZyTWVudUl0ZW0gfSBmcm9tICcuL21lbnUubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkc2ZyLXNpZGVtZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NpZGVtZW51LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2lkZW1lbnUuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgRHNmclNpZGVtZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlckNvbnRlbnRJbml0IHtcbiAgLyoqIEF0dHJpYnV0IGFyaWEtbGFiZWwgZHUgbWVudSBsYXTDqXJhbC4gICovXG4gIEBJbnB1dCgpIGFyaWFMYWJlbCA9ICdNZW51IGxhdMOpcmFsJztcblxuICAvKiogSWQgZHUgbWVudSwgZ8OpbsOpcsOpIHBhciBkw6lmYXV0IHNpIG5vbiBhZmZlY3TDqS4gKi9cbiAgQElucHV0KCkgY29udHJvbElkOiBzdHJpbmc7XG5cbiAgLyoqIE1vZMOobGUgZGUgZG9ubsOpZSBkdSBtZW51LiAqL1xuICAvL0ZJWE1FOiBSUEEgbGVzIGl0ZW1zIGRlIG1lbnUgZm91cm5pcyBwYXIgbGUgY2xpZW50IHBldXZlbnQgbXV0ZXIgc3VyIGxhIHByb3AgYWN0aXZlLCBpbCBzZXJhaXQgcHLDqWbDqXJhYmxlIGRlXG4gIC8vIGRpc3NvY2llciBsZSBtb2TDqGxlIGR1IGNsaWVudCAoaW1tdXRhYmxlKSBkZXMgZG9ubsOpZXMgZGUgcHLDqXNlbnRhdGlvbi5cbiAgQElucHV0KCkgbWVudTogRHNmck1lbnU7XG5cbiAgLyoqIEFmZmljaGUgbGUgbWVudSBsYXTDqXJhbCBlbiB2ZXJzaW9uIGZpeGUgICovXG4gIEBJbnB1dCgpIHN0aWNreSA9IGZhbHNlO1xuXG4gIC8qKiBBZmZpY2hlIGxlIG1lbnUgbGF0w6lyYWwgZW4gdmVyc2lvbiBmaXhlIHN1ciAxMDAlIGRlIGxhIGhhdXRldXIgZGUgbGEgcGFnZS4gKi9cbiAgQElucHV0KCkgc3RpY2t5RnVsbEhlaWdodCA9IGZhbHNlO1xuXG4gIC8qKiBMZSBtZW51IGxhdMOpcmFsIGVzdCBhZmZpY2jDqSDDoCBnYXVjaGUgcGFyIGTDqWZhdXQgbWFpcyBpbCBlc3QgcG9zc2libGUgZGUgbCdhZmZpY2hlciDDoCBkcm9pdGUuICovXG4gIEBJbnB1dCgpIHBvc2l0aW9uOiBEc2ZyUG9zaXRpb24gPSBEc2ZyUG9zaXRpb25Db25zdC5MRUZUO1xuXG4gIC8qKiBBY3RpdmVyIGwnaXRlbSBzw6lsZWN0aW9ubsOpICovXG4gIEBJbnB1dCgpIGF1dG9BY3RpdmUgPSB0cnVlO1xuXG4gIC8qKiBFdsOpbmVtZW50IMOpbWlzIHN1aXRlIMOgIGxhIHPDqWxlY3Rpb24gZCd1biBpdGVtIGF2ZWMgbGllbiBgYWAgb3UgYHJvdXRlckxpbmtgLiAqL1xuICBAT3V0cHV0KCkgaXRlbVNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8RHNmck1lbnVJdGVtPigpO1xuXG4gIC8qKiBQb2ludGV1ciBzdXIgbGUgZGVybmllciBpdGVtIHPDqWxjdGlvbm7DqSAocGVybWV0IGRlIGxlIGTDqXPDqWxlY3Rpb25uZXIgbG9ycyBkJ3VuZSBub3V2ZWxsZSBzw6lsZWN0aW9uKS4gKi9cbiAgLy9GSVhNRTogUlBBIGNldHRlIGFwcHJvY2hlIG5lIGZvbmN0aW9ubmUgcGFzIDogaWwgcGV1dCB5IGF2b2lyIHBsdXNpZXVycyBpdGVtcyBzw6lsZWN0aW9ubsOpcyBkYW5zIGxlIG1lbnUgaGnDqXJhY2hpcXVlXG4gIC8vIGR1IGNvdXAgdW4gYWxnbyBxdWkgZMOpc2FjdGl2ZXJhaXQgdG91dCBwdWlzIGFjdGl2ZXJhaXQgbCdpdGVtIHPDqWxlY3Rpb25uw6kgYWluc2kgcXVlIHNlcyBhc2NlbmRhbnRzIHNlcmFpdCBwbHVzXG4gIC8vIHNpbXBsZSBldCBmb3VybmlyYWl0IGxlIGNvbXBvcmV0ZW1lbnQgYXR0ZW5kdSBhdmVjIGxhIGxhIHByb3ByacOpdMOpIGF1dG9BY3RpdmVcbiAgcHJpdmF0ZSBfcHJldkl0ZW1TZWxlY3RlZDogRHNmck1lbnVJdGVtIHwgdW5kZWZpbmVkO1xuXG4gIG5nT25DaGFuZ2VzKHsgbWVudSB9OiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKG1lbnUpIHtcbiAgICAgIHRoaXMuX3ByZXZJdGVtU2VsZWN0ZWQgPSB0aGlzLmZpbmRJdGVtQWN0aXZlKHRoaXMubWVudS5pdGVtcyk7XG4gICAgICAvLyBBam91dCBkZXMgY29udHJvbElkc1xuICAgICAgdGhpcy5jaGVja0NvbnRyb2xJZCh0aGlzLm1lbnU/Lml0ZW1zKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xJZCkgdGhpcy5jb250cm9sSWQgPSBuZXdVbmlxdWVJZCgpO1xuICAgIHRoaXMuY2hlY2tDb250cm9sSWQodGhpcy5tZW51Py5pdGVtcyk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIG9uU2VsZWN0SXRlbShpdGVtOiBEc2ZyTWVudUl0ZW0pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hdXRvQWN0aXZlKSB7XG4gICAgICB0aGlzLnNlbGVjdEl0ZW0oaXRlbSk7XG4gICAgfVxuXG4gICAgdGhpcy5pdGVtU2VsZWN0LmVtaXQoaXRlbSk7XG4gIH1cblxuICBwcml2YXRlIGZpbmRJdGVtQWN0aXZlKGl0ZW1zOiBEc2ZyTWVudUl0ZW1bXSk6IERzZnJNZW51SXRlbSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFpdGVtcykgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgIGxldCBhY3RpdmUgPSBpdGVtLmFjdGl2ZSA/IGl0ZW0gOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWFjdGl2ZSAmJiBpdGVtLnN1Ykl0ZW1zKSBhY3RpdmUgPSB0aGlzLmZpbmRJdGVtQWN0aXZlKGl0ZW0uc3ViSXRlbXMpO1xuICAgICAgaWYgKGFjdGl2ZSkgcmV0dXJuIGFjdGl2ZTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0SXRlbShpdGVtOiBEc2ZyTWVudUl0ZW0pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcHJldkl0ZW1TZWxlY3RlZCkge1xuICAgICAgdGhpcy5fcHJldkl0ZW1TZWxlY3RlZC5hY3RpdmUgPSBmYWxzZTtcbiAgICB9XG4gICAgaXRlbS5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMuX3ByZXZJdGVtU2VsZWN0ZWQgPSBpdGVtO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0NvbnRyb2xJZChtZW51SXRlbXM6IERzZnJNZW51SXRlbVtdKTogdm9pZCB7XG4gICAgaWYgKCFtZW51SXRlbXMpIHJldHVybjtcblxuICAgIG1lbnVJdGVtcy5mb3JFYWNoKChtZW51SXRlbSkgPT4ge1xuICAgICAgaWYgKG1lbnVJdGVtLnN1Ykl0ZW1zKSB7XG4gICAgICAgIGlmICghbWVudUl0ZW0uY29udHJvbElkKSBtZW51SXRlbS5jb250cm9sSWQgPSBuZXdVbmlxdWVJZCgpO1xuICAgICAgICB0aGlzLmNoZWNrQ29udHJvbElkKG1lbnVJdGVtLnN1Ykl0ZW1zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIiwiPG5hdlxuICBjbGFzcz1cImZyLXNpZGVtZW51XCJcbiAgW25nQ2xhc3NdPVwie1xuICAgICdmci1zaWRlbWVudS0tc3RpY2t5Jzogc3RpY2t5LFxuICAgICdmci1zaWRlbWVudS0tc3RpY2t5LWZ1bGwtaGVpZ2h0Jzogc3RpY2t5RnVsbEhlaWdodCxcbiAgICAnZnItc2lkZW1lbnUtLXJpZ2h0JzogcG9zaXRpb24gPT09ICdyaWdodCdcbiAgfVwiXG4gIHJvbGU9XCJuYXZpZ2F0aW9uXCJcbiAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWxcIj5cbiAgPGRpdiBjbGFzcz1cImZyLXNpZGVtZW51X19pbm5lclwiPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZnItc2lkZW1lbnVfX2J0blwiIFthdHRyLmFyaWEtY29udHJvbHNdPVwiY29udHJvbElkXCIgYXJpYS1leHBhbmRlZD1cImZhbHNlXCI+XG4gICAgICBEYW5zIGNldHRlIHJ1YnJpcXVlXG4gICAgPC9idXR0b24+XG4gICAgPGRpdiBjbGFzcz1cImZyLWNvbGxhcHNlXCIgW2lkXT1cImNvbnRyb2xJZFwiPlxuICAgICAgPCEtLVRpdHJlIGRlIHJ1YnJpcXVlIG9wdGlvbm5lbC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lbnU/LnRpdGxlXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmci1zaWRlbWVudV9fdGl0bGVcIj57eyBtZW51LnRpdGxlIH19PC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwhLS1OaXZlYXUgMS0tPlxuICAgICAgPHVsIGNsYXNzPVwiZnItc2lkZW1lbnVfX2xpc3RcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbTEgb2YgbWVudS5pdGVtc1wiPlxuICAgICAgICAgIDxsaSAqbmdJZj1cIiFpdGVtMS5zdWJJdGVtc1wiIGNsYXNzPVwiZnItc2lkZW1lbnVfX2l0ZW1cIj5cbiAgICAgICAgICAgIDxlZHUtaXRlbS1saW5rXG4gICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW0xXCJcbiAgICAgICAgICAgICAgY3VzdG9tQ2xhc3M9XCJmci1zaWRlbWVudV9fbGlua1wiXG4gICAgICAgICAgICAgIChsaW5rU2VsZWN0KT1cIm9uU2VsZWN0SXRlbShpdGVtMSlcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWN1cnJlbnRdPVwiaXRlbTEuYWN0aXZlID8gJ3BhZ2UnIDogbnVsbFwiPjwvZWR1LWl0ZW0tbGluaz5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDxsaSAqbmdJZj1cIml0ZW0xLnN1Ykl0ZW1zXCIgY2xhc3M9XCJmci1zaWRlbWVudV9faXRlbVwiPlxuICAgICAgICAgICAgPCEtLU5pdmVhdSAyLS0+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImZyLXNpZGVtZW51X19idG5cIlxuICAgICAgICAgICAgICBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cIml0ZW0xLmNvbnRyb2xJZFwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtY3VycmVudF09XCJpdGVtMS5hY3RpdmUgPyB0cnVlIDogbnVsbFwiPlxuICAgICAgICAgICAgICA8aSAqbmdJZj1cIml0ZW0xLmljb25cIiBjbGFzcz1cImVkdS1pdGVtLWljb25cIiBbY2xhc3NdPVwiaXRlbTEuaWNvblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAge3sgaXRlbTEubGFiZWwgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZyLWNvbGxhcHNlXCIgW2lkXT1cIml0ZW0xLmNvbnRyb2xJZFwiPlxuICAgICAgICAgICAgICA8IS0tVGl0cmUgZGUgcnVicmlxdWUgb3B0aW9ubmVsLS0+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtMS50aXRsZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmci1zaWRlbWVudV9fdGl0bGVcIj57eyBpdGVtMS50aXRsZSB9fTwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPHVsIGNsYXNzPVwiZnItc2lkZW1lbnVfX2xpc3RcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtMiBvZiBpdGVtMS5zdWJJdGVtc1wiPlxuICAgICAgICAgICAgICAgICAgPGxpICpuZ0lmPVwiIWl0ZW0yLnN1Ykl0ZW1zXCIgY2xhc3M9XCJmci1zaWRlbWVudV9faXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZWR1LWl0ZW0tbGlua1xuICAgICAgICAgICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW0yXCJcbiAgICAgICAgICAgICAgICAgICAgICBjdXN0b21DbGFzcz1cImZyLXNpZGVtZW51X19saW5rXCJcbiAgICAgICAgICAgICAgICAgICAgICAobGlua1NlbGVjdCk9XCJvblNlbGVjdEl0ZW0oaXRlbTIpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWN1cnJlbnRdPVwiaXRlbTIuYWN0aXZlID8gJ3BhZ2UnIDogbnVsbFwiPjwvZWR1LWl0ZW0tbGluaz5cbiAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICA8bGkgKm5nSWY9XCJpdGVtMi5zdWJJdGVtc1wiIGNsYXNzPVwiZnItc2lkZW1lbnVfX2l0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZnItc2lkZW1lbnVfX2J0blwiXG4gICAgICAgICAgICAgICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cIml0ZW0yLmNvbnRyb2xJZFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1jdXJyZW50XT1cIml0ZW0xLmFjdGl2ZSA/IHRydWUgOiBudWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGkgKm5nSWY9XCJpdGVtMi5pY29uXCIgY2xhc3M9XCJlZHUtaXRlbS1pY29uXCIgW2NsYXNzXT1cIml0ZW0yLmljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAge3sgaXRlbTIubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmci1jb2xsYXBzZVwiIFtpZF09XCJpdGVtMi5jb250cm9sSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbTIudGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmci1zaWRlbWVudV9fdGl0bGVcIj57eyBpdGVtMi50aXRsZSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS1OaXZlYXUgMy0tPlxuICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImZyLXNpZGVtZW51X19saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0zIG9mIGl0ZW0yLnN1Ykl0ZW1zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmci1zaWRlbWVudV9faXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtY3VycmVudF09XCJpdGVtMy5hY3RpdmUgPyAncGFnZScgOiBudWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxlZHUtaXRlbS1saW5rXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2l0ZW1dPVwiaXRlbTNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1c3RvbUNsYXNzPVwiZnItc2lkZW1lbnVfX2xpbmtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsaW5rU2VsZWN0KT1cIm9uU2VsZWN0SXRlbShpdGVtMylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtY3VycmVudF09XCJpdGVtMy5hY3RpdmUgPyAncGFnZScgOiBudWxsXCI+PC9lZHUtaXRlbS1saW5rPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uYXY+XG4iXX0=