@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).
95 lines • 34.4 kB
JavaScript
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { DsfrSizeConst, LinkDownloadComponent, SvgIconComponent } from '../../shared';
import { DsfrBadgesGroupComponent } from '../badges-group';
import { DsfrLinkComponent } from '../link';
import { DsfrTagsGroupComponent } from '../tags-group';
import { BasePanelComponent } from './base-panel.component';
import { DsfrPanelBackgroundConst, DsfrPanelBorderConst } from './base-panel.model';
import * as i0 from "@angular/core";
import * as i1 from "../../shared";
import * as i2 from "@angular/common";
export class DsfrCardComponent extends BasePanelComponent {
/**@internal */
constructor(i18n) {
super();
this.i18n = i18n;
/**
* Zone d'actions, composée de bouton ou de liens, optionnelle (mais incompatible avec la
* deuxième zone de détail). Si activée elle affiche le slot avec sélecteur `footer`
*/
this.hasFooter = false;
/** Texte alternatif d'une image à utiliser uniquement si l'image à une information à passer. */
this.imageAlt = '';
/**
* Supprime l'icône du lien.
*
* @since 1.12
*/
this.noIcon = false;
/**
* Type d'illustration
* - `img` : pour l'utilisation d'une balise '<img>'.
* - `svg` : pour l'utilisation de '<edu-svg-icon>'.
* Si c'est le cas, `@ImagePath` devient le path du fichier `sprite.svg` et la concaténation de l'id du svg à afficher.
*/
this.imageType = 'img';
/** Remplace le lien du bouton de download par un markup de bouton */
this.isDownloadButton = false;
/** Signale quand la carte est sélectionnée. */
this.cardSelect = new EventEmitter();
/** @internal */
this.DsfrBorder = DsfrPanelBorderConst;
/** @internal */
this.DsfrBackground = DsfrPanelBackgroundConst;
/** @internal */
this.DsfrSize = DsfrSizeConst;
}
/** @internal */
onLinkSelect() {
// on propage l'output, pas besoin de gérer ici le preventDefault, c'est géré en amont
if (this.route) {
this.cardSelect.emit(this.route);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrCardComponent, deps: [{ token: i1.DsfrI18nService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DsfrCardComponent, isStandalone: true, selector: "dsfr-card", inputs: { badgesOnMedia: "badgesOnMedia", detail: "detail", detailIcon: "detailIcon", detailBottomIcon: "detailBottomIcon", hasFooter: "hasFooter", imageAlt: "imageAlt", imageFit: "imageFit", imagePath: "imagePath", imageRatio: "imageRatio", noIcon: "noIcon", imageType: "imageType", isDownloadButton: "isDownloadButton" }, outputs: { cardSelect: "cardSelect" }, usesInheritance: true, ngImport: i0, template: "<div\n [ngClass]=\"{\n 'fr-card': true,\n 'fr-card--horizontal': horizontal,\n 'fr-card--download': download,\n 'fr-enlarge-link': enlargeLink && hasLink() && !hasFooter,\n 'fr-card--no-arrow': hasFooter,\n 'fr-card--no-border': customBorder === DsfrBorder.NO_BORDER,\n 'fr-card--shadow': customBorder === DsfrBorder.SHADOW,\n 'fr-card--grey': customBackground === DsfrBackground.GREY,\n 'fr-card--no-background': customBackground === DsfrBackground.TRANSPARENT,\n 'fr-card--sm': panelSize === DsfrSize.SM,\n 'fr-card--lg': panelSize === DsfrSize.LG,\n 'fr-card--no-icon': noIcon,\n 'fr-enlarge-button': enlargeButton || isDownloadButton\n }\">\n <!-- Card body -->\n <div class=\"fr-card__body\">\n <div class=\"fr-card__content\">\n <!-- Titre du contenu -->\n <ng-container *ngTemplateOutlet=\"cardHeadingTemplate\"></ng-container>\n\n <!-- D\u00E9tail du haut -->\n @if (detail || (tags && tags.length) || (badges && badges.length && !badgesOnMedia)) {\n <div class=\"fr-card__start\">\n @if (tags && tags.length) {\n <dsfr-tags-group [tags]=\"tags\"></dsfr-tags-group>\n }\n @if (badges && badges.length && !badgesOnMedia) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n @if (detail || detailIcon) {\n <p class=\"fr-card__detail\" [ngClass]=\"detailIcon\">\n {{ detail }}\n </p>\n }\n </div>\n }\n\n <!-- Description -->\n @if (description) {\n <p class=\"fr-card__desc\" [innerHTML]=\"description\"></p>\n }\n\n <!-- D\u00E9tail du bas -->\n @if (detailBottom || detailBottomIcon || (downloadAssessFile && download)) {\n <div class=\"fr-card__end\">\n <p class=\"fr-card__detail\" [ngClass]=\"detailBottomIcon\">\n {{ detailBottom }}\n </p>\n </div>\n }\n </div>\n\n <!-- Card footer -->\n @if (hasFooter) {\n <div class=\"fr-card__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n }\n </div>\n\n <!-- Card header -->\n @if (imagePath) {\n <div class=\"fr-card__header\">\n <div class=\"fr-card__img\">\n @if (imageType === 'img') {\n <img\n [src]=\"imagePath\"\n class=\"fr-responsive-img\"\n [ngClass]=\"{\n 'fr-ratio-32x9': imageRatio === '16:9/2',\n 'fr-ratio-16x9': imageRatio === '16:9',\n 'fr-ratio-3x2': imageRatio === '3:2',\n 'fr-ratio-4x3': imageRatio === '4:3',\n 'fr-ratio-1x1': imageRatio === '1:1',\n 'fr-ratio-3x4': imageRatio === '3:4',\n 'fr-ratio-2x3': imageRatio === '2:3'\n }\"\n [ngStyle]=\"{ 'object-fit': imageFit }\"\n [attr.alt]=\"imageAlt\" />\n }\n <!-- L\u2019alternative de l\u2019image (attribut alt) doit toujours \u00EAtre pr\u00E9sente, sa valeur peut-\u00EAtre vide (image n\u2019apportant pas de sens suppl\u00E9mentaire au contexte) ou non (porteuse de texte ou apportant du sens) selon votre contexte -->\n @if (imageType === 'svg') {\n <edu-svg-icon [iconPath]=\"imagePath\"></edu-svg-icon>\n }\n </div>\n @if (badges && badgesOnMedia) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n </div>\n }\n</div>\n\n<!-- Templates ----------------------------------------------------------------------------------------------------- -->\n\n<ng-template #cardHeadingTemplate>\n @switch (headingLevel) {\n @case ('H2') {\n <h2 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h2>\n }\n @case ('H4') {\n <h4 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h6>\n }\n @default {\n <h3 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h3>\n }\n }\n</ng-template>\n\n<ng-template #headingTemplate>\n <!-- Definition des templates directement ici pour une projection du slot correcte (pas de else)-->\n\n <!-- Titre simple -------------------------------------------------------->\n @if (!hasLink()) {\n @if (heading) {\n <!-- FIXME V2 supprimer le innerHtml-et le span associ\u00E9 -->\n <span [innerHTML]=\"heading\"></span>\n } @else {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n }\n\n <!-- Lien --------------------------------------------------------------->\n @if (hasLink()) {\n <!-- Lien sans t\u00E9l\u00E9chargement -->\n @if (!download) {\n <dsfr-link\n [customClass]=\"'edu-link'\"\n [ariaLabel]=\"ariaLabel ?? ''\"\n [disabled]=\"disabled\"\n [link]=\"link\"\n [linkTarget]=\"linkTarget\"\n [label]=\"heading\"\n [route]=\"route\"\n [routePath]=\"routePath\"\n [routerLinkActive]=\"routerLinkActive ?? ''\"\n [routerLinkExtras]=\"routerLinkExtras\"\n [mode]=\"enlargeButton ? 'button' : 'link'\"\n (linkSelect)=\"onLinkSelect()\">\n @if (!heading) {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n </dsfr-link>\n } @else {\n <!-- Lien de t\u00E9l\u00E9chargement -->\n <edu-link-download\n [item]=\"itemLink\"\n [downloadDirect]=\"downloadDirect\"\n [downloadAssessFile]=\"downloadAssessFile\"\n [linkTarget]=\"linkTarget\"\n [langCode]=\"downloadLangCode\"\n [isButton]=\"isDownloadButton\"\n (linkSelect)=\"onLinkSelect()\"></edu-link-download>\n }\n }\n</ng-template>\n\n<!-- Template s\u00E9par\u00E9 pour avoir une seule d\u00E9finition du select heading (DO NOT DELETE) -->\n<ng-template #headingTemplateSlot>\n <ng-content select=\"[heading]\"></ng-content>\n</ng-template>\n", styles: [".fr-card{height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: DsfrBadgesGroupComponent, selector: "dsfr-badges-group", inputs: ["badges", "small"] }, { kind: "component", type: DsfrTagsGroupComponent, selector: "dsfr-tags-group", inputs: ["tags", "mode"], outputs: ["tagSelect"] }, { kind: "component", type: SvgIconComponent, selector: "edu-svg-icon", inputs: ["iconPath", "role", "ariaHidden", "alt"] }, { kind: "component", type: DsfrLinkComponent, selector: "dsfr-link", inputs: ["ariaCurrent", "ariaLabel", "ariaControls", "customClass", "disabled", "icon", "iconPosition", "linkId", "label", "link", "linkTarget", "route", "routePath", "routerLinkActive", "routerLinkActiveOptions", "routerLinkExtras", "linkSize", "tooltipMessage", "mode", "ariaCurrentWhenActive", "size", "targetLink", "routerLink"], outputs: ["linkSelect"] }, { kind: "component", type: LinkDownloadComponent, selector: "edu-link-download", inputs: ["customClass", "downloadDirect", "downloadAssessFile", "langCode", "linkTarget", "isButton", "item"], outputs: ["linkSelect"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DsfrCardComponent, decorators: [{
type: Component,
args: [{ selector: 'dsfr-card', encapsulation: ViewEncapsulation.None, standalone: true, imports: [
CommonModule,
DsfrBadgesGroupComponent,
DsfrTagsGroupComponent,
SvgIconComponent,
DsfrLinkComponent,
LinkDownloadComponent,
], template: "<div\n [ngClass]=\"{\n 'fr-card': true,\n 'fr-card--horizontal': horizontal,\n 'fr-card--download': download,\n 'fr-enlarge-link': enlargeLink && hasLink() && !hasFooter,\n 'fr-card--no-arrow': hasFooter,\n 'fr-card--no-border': customBorder === DsfrBorder.NO_BORDER,\n 'fr-card--shadow': customBorder === DsfrBorder.SHADOW,\n 'fr-card--grey': customBackground === DsfrBackground.GREY,\n 'fr-card--no-background': customBackground === DsfrBackground.TRANSPARENT,\n 'fr-card--sm': panelSize === DsfrSize.SM,\n 'fr-card--lg': panelSize === DsfrSize.LG,\n 'fr-card--no-icon': noIcon,\n 'fr-enlarge-button': enlargeButton || isDownloadButton\n }\">\n <!-- Card body -->\n <div class=\"fr-card__body\">\n <div class=\"fr-card__content\">\n <!-- Titre du contenu -->\n <ng-container *ngTemplateOutlet=\"cardHeadingTemplate\"></ng-container>\n\n <!-- D\u00E9tail du haut -->\n @if (detail || (tags && tags.length) || (badges && badges.length && !badgesOnMedia)) {\n <div class=\"fr-card__start\">\n @if (tags && tags.length) {\n <dsfr-tags-group [tags]=\"tags\"></dsfr-tags-group>\n }\n @if (badges && badges.length && !badgesOnMedia) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n @if (detail || detailIcon) {\n <p class=\"fr-card__detail\" [ngClass]=\"detailIcon\">\n {{ detail }}\n </p>\n }\n </div>\n }\n\n <!-- Description -->\n @if (description) {\n <p class=\"fr-card__desc\" [innerHTML]=\"description\"></p>\n }\n\n <!-- D\u00E9tail du bas -->\n @if (detailBottom || detailBottomIcon || (downloadAssessFile && download)) {\n <div class=\"fr-card__end\">\n <p class=\"fr-card__detail\" [ngClass]=\"detailBottomIcon\">\n {{ detailBottom }}\n </p>\n </div>\n }\n </div>\n\n <!-- Card footer -->\n @if (hasFooter) {\n <div class=\"fr-card__footer\">\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n }\n </div>\n\n <!-- Card header -->\n @if (imagePath) {\n <div class=\"fr-card__header\">\n <div class=\"fr-card__img\">\n @if (imageType === 'img') {\n <img\n [src]=\"imagePath\"\n class=\"fr-responsive-img\"\n [ngClass]=\"{\n 'fr-ratio-32x9': imageRatio === '16:9/2',\n 'fr-ratio-16x9': imageRatio === '16:9',\n 'fr-ratio-3x2': imageRatio === '3:2',\n 'fr-ratio-4x3': imageRatio === '4:3',\n 'fr-ratio-1x1': imageRatio === '1:1',\n 'fr-ratio-3x4': imageRatio === '3:4',\n 'fr-ratio-2x3': imageRatio === '2:3'\n }\"\n [ngStyle]=\"{ 'object-fit': imageFit }\"\n [attr.alt]=\"imageAlt\" />\n }\n <!-- L\u2019alternative de l\u2019image (attribut alt) doit toujours \u00EAtre pr\u00E9sente, sa valeur peut-\u00EAtre vide (image n\u2019apportant pas de sens suppl\u00E9mentaire au contexte) ou non (porteuse de texte ou apportant du sens) selon votre contexte -->\n @if (imageType === 'svg') {\n <edu-svg-icon [iconPath]=\"imagePath\"></edu-svg-icon>\n }\n </div>\n @if (badges && badgesOnMedia) {\n <dsfr-badges-group [badges]=\"badges\"></dsfr-badges-group>\n }\n </div>\n }\n</div>\n\n<!-- Templates ----------------------------------------------------------------------------------------------------- -->\n\n<ng-template #cardHeadingTemplate>\n @switch (headingLevel) {\n @case ('H2') {\n <h2 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h2>\n }\n @case ('H4') {\n <h4 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h4>\n }\n @case ('H5') {\n <h5 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h5>\n }\n @case ('H6') {\n <h6 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h6>\n }\n @default {\n <h3 class=\"fr-card__title\">\n <ng-container *ngTemplateOutlet=\"headingTemplate\"></ng-container>\n </h3>\n }\n }\n</ng-template>\n\n<ng-template #headingTemplate>\n <!-- Definition des templates directement ici pour une projection du slot correcte (pas de else)-->\n\n <!-- Titre simple -------------------------------------------------------->\n @if (!hasLink()) {\n @if (heading) {\n <!-- FIXME V2 supprimer le innerHtml-et le span associ\u00E9 -->\n <span [innerHTML]=\"heading\"></span>\n } @else {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n }\n\n <!-- Lien --------------------------------------------------------------->\n @if (hasLink()) {\n <!-- Lien sans t\u00E9l\u00E9chargement -->\n @if (!download) {\n <dsfr-link\n [customClass]=\"'edu-link'\"\n [ariaLabel]=\"ariaLabel ?? ''\"\n [disabled]=\"disabled\"\n [link]=\"link\"\n [linkTarget]=\"linkTarget\"\n [label]=\"heading\"\n [route]=\"route\"\n [routePath]=\"routePath\"\n [routerLinkActive]=\"routerLinkActive ?? ''\"\n [routerLinkExtras]=\"routerLinkExtras\"\n [mode]=\"enlargeButton ? 'button' : 'link'\"\n (linkSelect)=\"onLinkSelect()\">\n @if (!heading) {\n <ng-container *ngTemplateOutlet=\"headingTemplateSlot\"></ng-container>\n }\n </dsfr-link>\n } @else {\n <!-- Lien de t\u00E9l\u00E9chargement -->\n <edu-link-download\n [item]=\"itemLink\"\n [downloadDirect]=\"downloadDirect\"\n [downloadAssessFile]=\"downloadAssessFile\"\n [linkTarget]=\"linkTarget\"\n [langCode]=\"downloadLangCode\"\n [isButton]=\"isDownloadButton\"\n (linkSelect)=\"onLinkSelect()\"></edu-link-download>\n }\n }\n</ng-template>\n\n<!-- Template s\u00E9par\u00E9 pour avoir une seule d\u00E9finition du select heading (DO NOT DELETE) -->\n<ng-template #headingTemplateSlot>\n <ng-content select=\"[heading]\"></ng-content>\n</ng-template>\n", styles: [".fr-card{height:100%}\n"] }]
}], ctorParameters: () => [{ type: i1.DsfrI18nService }], propDecorators: { badgesOnMedia: [{
type: Input
}], detail: [{
type: Input
}], detailIcon: [{
type: Input
}], detailBottomIcon: [{
type: Input
}], hasFooter: [{
type: Input
}], imageAlt: [{
type: Input
}], imageFit: [{
type: Input
}], imagePath: [{
type: Input
}], imageRatio: [{
type: Input
}], noIcon: [{
type: Input
}], imageType: [{
type: Input
}], isDownloadButton: [{
type: Input
}], cardSelect: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHNmci1jb21wb25lbnRzL3NyYy9saWIvY29tcG9uZW50cy9jYXJkL2NhcmQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvY2FyZC9jYXJkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFGLE9BQU8sRUFBbUIsYUFBYSxFQUFFLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7QUFrQnBGLE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxrQkFBa0I7SUFnRXZELGVBQWU7SUFDZixZQUFtQixJQUFxQjtRQUN0QyxLQUFLLEVBQUUsQ0FBQztRQURTLFNBQUksR0FBSixJQUFJLENBQWlCO1FBbER4Qzs7O1dBR0c7UUFDTSxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRTNCLGdHQUFnRztRQUN2RixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBYy9COzs7O1dBSUc7UUFDTSxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRXhCOzs7OztXQUtHO1FBQ00sY0FBUyxHQUFrQixLQUFLLENBQUM7UUFFMUMscUVBQXFFO1FBQzVELHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUVsQywrQ0FBK0M7UUFDNUIsZUFBVSxHQUF5QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBRXpFLGdCQUFnQjtRQUNHLGVBQVUsR0FBRyxvQkFBb0IsQ0FBQztRQUNyRCxnQkFBZ0I7UUFDRyxtQkFBYyxHQUFHLHdCQUF3QixDQUFDO1FBQzdELGdCQUFnQjtRQUNHLGFBQVEsR0FBRyxhQUFhLENBQUM7SUFLNUMsQ0FBQztJQUVELGdCQUFnQjtJQUNoQixZQUFZO1FBQ1Ysc0ZBQXNGO1FBQ3RGLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDOytHQTNFVSxpQkFBaUI7bUdBQWpCLGlCQUFpQix1Y0N6QjlCLHl0TUFrTEEsZ0ZEaktJLFlBQVkseVhBQ1osd0JBQXdCLDJGQUN4QixzQkFBc0IsOEdBQ3RCLGdCQUFnQiw0R0FDaEIsaUJBQWlCLDZaQUNqQixxQkFBcUI7OzRGQUdaLGlCQUFpQjtrQkFmN0IsU0FBUzsrQkFDRSxXQUFXLGlCQUdOLGlCQUFpQixDQUFDLElBQUksY0FDekIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osd0JBQXdCO3dCQUN4QixzQkFBc0I7d0JBQ3RCLGdCQUFnQjt3QkFDaEIsaUJBQWlCO3dCQUNqQixxQkFBcUI7cUJBQ3RCO29GQUlRLGFBQWE7c0JBQXJCLEtBQUs7Z0JBS0csTUFBTTtzQkFBZCxLQUFLO2dCQUdHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQU1HLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csUUFBUTtzQkFBaEIsS0FBSztnQkFNRyxRQUFRO3NCQUFoQixLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csVUFBVTtzQkFBbEIsS0FBSztnQkFPRyxNQUFNO3NCQUFkLEtBQUs7Z0JBUUcsU0FBUztzQkFBakIsS0FBSztnQkFHRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBR2EsVUFBVTtzQkFBNUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERzZnJJMThuU2VydmljZSwgRHNmclNpemVDb25zdCwgTGlua0Rvd25sb2FkQ29tcG9uZW50LCBTdmdJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IERzZnJCYWRnZXNHcm91cENvbXBvbmVudCB9IGZyb20gJy4uL2JhZGdlcy1ncm91cCc7XG5pbXBvcnQgeyBEc2ZyTGlua0NvbXBvbmVudCB9IGZyb20gJy4uL2xpbmsnO1xuaW1wb3J0IHsgRHNmclRhZ3NHcm91cENvbXBvbmVudCB9IGZyb20gJy4uL3RhZ3MtZ3JvdXAnO1xuaW1wb3J0IHsgQmFzZVBhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9iYXNlLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEc2ZyUGFuZWxCYWNrZ3JvdW5kQ29uc3QsIERzZnJQYW5lbEJvcmRlckNvbnN0IH0gZnJvbSAnLi9iYXNlLXBhbmVsLm1vZGVsJztcbmltcG9ydCB7IERzZnJJbWFnZUZpdCwgRHNmckltYWdlUmF0aW8sIERzZnJJbWFnZVR5cGUgfSBmcm9tICcuL2NhcmQubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkc2ZyLWNhcmQnLFxuICB0ZW1wbGF0ZVVybDogJy4vY2FyZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhcmQuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBEc2ZyQmFkZ2VzR3JvdXBDb21wb25lbnQsXG4gICAgRHNmclRhZ3NHcm91cENvbXBvbmVudCxcbiAgICBTdmdJY29uQ29tcG9uZW50LFxuICAgIERzZnJMaW5rQ29tcG9uZW50LFxuICAgIExpbmtEb3dubG9hZENvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRHNmckNhcmRDb21wb25lbnQgZXh0ZW5kcyBCYXNlUGFuZWxDb21wb25lbnQge1xuICAvKiogU2kgdHJ1ZSwgbGVzIGJhZGdlcyBzZXJvbnQgYWZmaWNow6lzIHN1ciBsYSB6b25lIG1lZGlhLiAqL1xuICBASW5wdXQoKSBiYWRnZXNPbk1lZGlhOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBMZSBkw6l0YWlsLCBvcHRpb25uZWwuXG4gICAqL1xuICBASW5wdXQoKSBkZXRhaWw6IHN0cmluZztcblxuICAvKiogSWPDtG5lIGRlIGxhIHpvbmUgZGUgZMOpdGFpbCwgb3B0aW9ubmVsLiAqL1xuICBASW5wdXQoKSBkZXRhaWxJY29uOiBzdHJpbmc7XG5cbiAgLyoqIEljw7RuZSBkZXZhbnQgbGUgZMOpdGFpbCBzaXR1w6kgYXUgYmFzIGRlIGxhIGNhcnRlLCBvcHRpb25uZWwuICovXG4gIEBJbnB1dCgpIGRldGFpbEJvdHRvbUljb246IHN0cmluZztcblxuICAvKipcbiAgICogWm9uZSBkJ2FjdGlvbnMsIGNvbXBvc8OpZSBkZSBib3V0b24gb3UgZGUgbGllbnMsIG9wdGlvbm5lbGxlIChtYWlzIGluY29tcGF0aWJsZSBhdmVjIGxhXG4gICAqIGRldXhpw6htZSB6b25lIGRlIGTDqXRhaWwpLiBTaSBhY3RpdsOpZSBlbGxlIGFmZmljaGUgbGUgc2xvdCBhdmVjIHPDqWxlY3RldXIgYGZvb3RlcmBcbiAgICovXG4gIEBJbnB1dCgpIGhhc0Zvb3RlciA9IGZhbHNlO1xuXG4gIC8qKiBUZXh0ZSBhbHRlcm5hdGlmIGQndW5lIGltYWdlIMOgIHV0aWxpc2VyIHVuaXF1ZW1lbnQgc2kgbCdpbWFnZSDDoCB1bmUgaW5mb3JtYXRpb24gw6AgcGFzc2VyLiAqL1xuICBASW5wdXQoKSBpbWFnZUFsdDogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIFNlbG9uIGxhIHZhbGV1ciB1dGlsaXPDqWUgcG91ciAnaW1hZ2VGaXQnLCBsJ8OpbMOpbWVudCBwZXV0IMOqdHJlIHJvZ27DqSwgbWlzIMOgIGwnw6ljaGVsbGUgb3Ugw6l0aXLDqSwgYWZpbiBkZSByZW1wbGlyXG4gICAqIGxhIGJvw650ZSBxdWkgbGUgY29udGllbnQuXG4gICAqL1xuICBASW5wdXQoKSBpbWFnZUZpdDogRHNmckltYWdlRml0O1xuXG4gIC8qKiBVcmwgZGUgbCdpbWFnZSBkZSBsJ2VudMOqdGUsIG9wdGlvbm5lbC4gKi9cbiAgQElucHV0KCkgaW1hZ2VQYXRoOiBzdHJpbmc7XG5cbiAgLyoqIFJhdGlvIGRlIGwnaW1hZ2UuICovXG4gIEBJbnB1dCgpIGltYWdlUmF0aW86IERzZnJJbWFnZVJhdGlvO1xuXG4gIC8qKlxuICAgKiBTdXBwcmltZSBsJ2ljw7RuZSBkdSBsaWVuLlxuICAgKlxuICAgKiBAc2luY2UgMS4xMlxuICAgKi9cbiAgQElucHV0KCkgbm9JY29uID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFR5cGUgZCdpbGx1c3RyYXRpb25cbiAgICogLSBgaW1nYCA6IHBvdXIgbCd1dGlsaXNhdGlvbiBkJ3VuZSBiYWxpc2UgJzxpbWc+Jy5cbiAgICogLSBgc3ZnYCA6IHBvdXIgbCd1dGlsaXNhdGlvbiBkZSAnPGVkdS1zdmctaWNvbj4nLlxuICAgKiBTaSBjJ2VzdCBsZSBjYXMsIGBASW1hZ2VQYXRoYCBkZXZpZW50IGxlIHBhdGggZHUgZmljaGllciBgc3ByaXRlLnN2Z2AgZXQgbGEgY29uY2F0w6luYXRpb24gZGUgbCdpZCBkdSBzdmcgw6AgYWZmaWNoZXIuXG4gICAqL1xuICBASW5wdXQoKSBpbWFnZVR5cGU6IERzZnJJbWFnZVR5cGUgPSAnaW1nJztcblxuICAvKiogUmVtcGxhY2UgbGUgbGllbiBkdSBib3V0b24gZGUgZG93bmxvYWQgcGFyIHVuIG1hcmt1cCBkZSBib3V0b24gKi9cbiAgQElucHV0KCkgaXNEb3dubG9hZEJ1dHRvbiA9IGZhbHNlO1xuXG4gIC8qKiBTaWduYWxlIHF1YW5kIGxhIGNhcnRlIGVzdCBzw6lsZWN0aW9ubsOpZS4gKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IGNhcmRTZWxlY3Q6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IERzZnJCb3JkZXIgPSBEc2ZyUGFuZWxCb3JkZXJDb25zdDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgRHNmckJhY2tncm91bmQgPSBEc2ZyUGFuZWxCYWNrZ3JvdW5kQ29uc3Q7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IERzZnJTaXplID0gRHNmclNpemVDb25zdDtcblxuICAvKipAaW50ZXJuYWwgKi9cbiAgY29uc3RydWN0b3IocHVibGljIGkxOG46IERzZnJJMThuU2VydmljZSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIG9uTGlua1NlbGVjdCgpOiB2b2lkIHtcbiAgICAvLyBvbiBwcm9wYWdlIGwnb3V0cHV0LCBwYXMgYmVzb2luIGRlIGfDqXJlciBpY2kgbGUgcHJldmVudERlZmF1bHQsIGMnZXN0IGfDqXLDqSBlbiBhbW9udFxuICAgIGlmICh0aGlzLnJvdXRlKSB7XG4gICAgICB0aGlzLmNhcmRTZWxlY3QuZW1pdCh0aGlzLnJvdXRlKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXZcbiAgW25nQ2xhc3NdPVwie1xuICAgICdmci1jYXJkJzogdHJ1ZSxcbiAgICAnZnItY2FyZC0taG9yaXpvbnRhbCc6IGhvcml6b250YWwsXG4gICAgJ2ZyLWNhcmQtLWRvd25sb2FkJzogZG93bmxvYWQsXG4gICAgJ2ZyLWVubGFyZ2UtbGluayc6IGVubGFyZ2VMaW5rICYmIGhhc0xpbmsoKSAmJiAhaGFzRm9vdGVyLFxuICAgICdmci1jYXJkLS1uby1hcnJvdyc6IGhhc0Zvb3RlcixcbiAgICAnZnItY2FyZC0tbm8tYm9yZGVyJzogY3VzdG9tQm9yZGVyID09PSBEc2ZyQm9yZGVyLk5PX0JPUkRFUixcbiAgICAnZnItY2FyZC0tc2hhZG93JzogY3VzdG9tQm9yZGVyID09PSBEc2ZyQm9yZGVyLlNIQURPVyxcbiAgICAnZnItY2FyZC0tZ3JleSc6IGN1c3RvbUJhY2tncm91bmQgPT09IERzZnJCYWNrZ3JvdW5kLkdSRVksXG4gICAgJ2ZyLWNhcmQtLW5vLWJhY2tncm91bmQnOiBjdXN0b21CYWNrZ3JvdW5kID09PSBEc2ZyQmFja2dyb3VuZC5UUkFOU1BBUkVOVCxcbiAgICAnZnItY2FyZC0tc20nOiBwYW5lbFNpemUgPT09IERzZnJTaXplLlNNLFxuICAgICdmci1jYXJkLS1sZyc6IHBhbmVsU2l6ZSA9PT0gRHNmclNpemUuTEcsXG4gICAgJ2ZyLWNhcmQtLW5vLWljb24nOiBub0ljb24sXG4gICAgJ2ZyLWVubGFyZ2UtYnV0dG9uJzogZW5sYXJnZUJ1dHRvbiB8fCBpc0Rvd25sb2FkQnV0dG9uXG4gIH1cIj5cbiAgPCEtLSBDYXJkIGJvZHkgLS0+XG4gIDxkaXYgY2xhc3M9XCJmci1jYXJkX19ib2R5XCI+XG4gICAgPGRpdiBjbGFzcz1cImZyLWNhcmRfX2NvbnRlbnRcIj5cbiAgICAgIDwhLS0gVGl0cmUgZHUgY29udGVudSAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjYXJkSGVhZGluZ1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gRMOpdGFpbCBkdSBoYXV0IC0tPlxuICAgICAgQGlmIChkZXRhaWwgfHwgKHRhZ3MgJiYgdGFncy5sZW5ndGgpIHx8IChiYWRnZXMgJiYgYmFkZ2VzLmxlbmd0aCAmJiAhYmFkZ2VzT25NZWRpYSkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cImZyLWNhcmRfX3N0YXJ0XCI+XG4gICAgICAgICAgQGlmICh0YWdzICYmIHRhZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgICA8ZHNmci10YWdzLWdyb3VwIFt0YWdzXT1cInRhZ3NcIj48L2RzZnItdGFncy1ncm91cD5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChiYWRnZXMgJiYgYmFkZ2VzLmxlbmd0aCAmJiAhYmFkZ2VzT25NZWRpYSkge1xuICAgICAgICAgICAgPGRzZnItYmFkZ2VzLWdyb3VwIFtiYWRnZXNdPVwiYmFkZ2VzXCI+PC9kc2ZyLWJhZGdlcy1ncm91cD5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChkZXRhaWwgfHwgZGV0YWlsSWNvbikge1xuICAgICAgICAgICAgPHAgY2xhc3M9XCJmci1jYXJkX19kZXRhaWxcIiBbbmdDbGFzc109XCJkZXRhaWxJY29uXCI+XG4gICAgICAgICAgICAgIHt7IGRldGFpbCB9fVxuICAgICAgICAgICAgPC9wPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gRGVzY3JpcHRpb24gLS0+XG4gICAgICBAaWYgKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgIDxwIGNsYXNzPVwiZnItY2FyZF9fZGVzY1wiIFtpbm5lckhUTUxdPVwiZGVzY3JpcHRpb25cIj48L3A+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gRMOpdGFpbCBkdSBiYXMgLS0+XG4gICAgICBAaWYgKGRldGFpbEJvdHRvbSB8fCBkZXRhaWxCb3R0b21JY29uIHx8IChkb3dubG9hZEFzc2Vzc0ZpbGUgJiYgZG93bmxvYWQpKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmci1jYXJkX19lbmRcIj5cbiAgICAgICAgICA8cCBjbGFzcz1cImZyLWNhcmRfX2RldGFpbFwiIFtuZ0NsYXNzXT1cImRldGFpbEJvdHRvbUljb25cIj5cbiAgICAgICAgICAgIHt7IGRldGFpbEJvdHRvbSB9fVxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIENhcmQgZm9vdGVyIC0tPlxuICAgIEBpZiAoaGFzRm9vdGVyKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiZnItY2FyZF9fZm9vdGVyXCI+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltmb290ZXJdXCI+PC9uZy1jb250ZW50PlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICA8IS0tIENhcmQgaGVhZGVyIC0tPlxuICBAaWYgKGltYWdlUGF0aCkge1xuICAgIDxkaXYgY2xhc3M9XCJmci1jYXJkX19oZWFkZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmci1jYXJkX19pbWdcIj5cbiAgICAgICAgQGlmIChpbWFnZVR5cGUgPT09ICdpbWcnKSB7XG4gICAgICAgICAgPGltZ1xuICAgICAgICAgICAgW3NyY109XCJpbWFnZVBhdGhcIlxuICAgICAgICAgICAgY2xhc3M9XCJmci1yZXNwb25zaXZlLWltZ1wiXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICdmci1yYXRpby0zMng5JzogaW1hZ2VSYXRpbyA9PT0gJzE2OjkvMicsXG4gICAgICAgICAgICAgICdmci1yYXRpby0xNng5JzogaW1hZ2VSYXRpbyA9PT0gJzE2OjknLFxuICAgICAgICAgICAgICAnZnItcmF0aW8tM3gyJzogaW1hZ2VSYXRpbyA9PT0gJzM6MicsXG4gICAgICAgICAgICAgICdmci1yYXRpby00eDMnOiBpbWFnZVJhdGlvID09PSAnNDozJyxcbiAgICAgICAgICAgICAgJ2ZyLXJhdGlvLTF4MSc6IGltYWdlUmF0aW8gPT09ICcxOjEnLFxuICAgICAgICAgICAgICAnZnItcmF0aW8tM3g0JzogaW1hZ2VSYXRpbyA9PT0gJzM6NCcsXG4gICAgICAgICAgICAgICdmci1yYXRpby0yeDMnOiBpbWFnZVJhdGlvID09PSAnMjozJ1xuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJ7ICdvYmplY3QtZml0JzogaW1hZ2VGaXQgfVwiXG4gICAgICAgICAgICBbYXR0ci5hbHRdPVwiaW1hZ2VBbHRcIiAvPlxuICAgICAgICB9XG4gICAgICAgIDwhLS0gTOKAmWFsdGVybmF0aXZlIGRlIGzigJlpbWFnZSAoYXR0cmlidXQgYWx0KSBkb2l0IHRvdWpvdXJzIMOqdHJlIHByw6lzZW50ZSwgc2EgdmFsZXVyIHBldXQtw6p0cmUgdmlkZSAoaW1hZ2UgbuKAmWFwcG9ydGFudCBwYXMgZGUgc2VucyBzdXBwbMOpbWVudGFpcmUgYXUgY29udGV4dGUpIG91IG5vbiAocG9ydGV1c2UgZGUgdGV4dGUgb3UgYXBwb3J0YW50IGR1IHNlbnMpIHNlbG9uIHZvdHJlIGNvbnRleHRlIC0tPlxuICAgICAgICBAaWYgKGltYWdlVHlwZSA9PT0gJ3N2ZycpIHtcbiAgICAgICAgICA8ZWR1LXN2Zy1pY29uIFtpY29uUGF0aF09XCJpbWFnZVBhdGhcIj48L2VkdS1zdmctaWNvbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgICBAaWYgKGJhZGdlcyAmJiBiYWRnZXNPbk1lZGlhKSB7XG4gICAgICAgIDxkc2ZyLWJhZGdlcy1ncm91cCBbYmFkZ2VzXT1cImJhZGdlc1wiPjwvZHNmci1iYWRnZXMtZ3JvdXA+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIH1cbjwvZGl2PlxuXG48IS0tIFRlbXBsYXRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAtLT5cblxuPG5nLXRlbXBsYXRlICNjYXJkSGVhZGluZ1RlbXBsYXRlPlxuICBAc3dpdGNoIChoZWFkaW5nTGV2ZWwpIHtcbiAgICBAY2FzZSAoJ0gyJykge1xuICAgICAgPGgyIGNsYXNzPVwiZnItY2FyZF9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oMj5cbiAgICB9XG4gICAgQGNhc2UgKCdINCcpIHtcbiAgICAgIDxoNCBjbGFzcz1cImZyLWNhcmRfX3RpdGxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJoZWFkaW5nVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvaDQ+XG4gICAgfVxuICAgIEBjYXNlICgnSDUnKSB7XG4gICAgICA8aDUgY2xhc3M9XCJmci1jYXJkX190aXRsZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaGVhZGluZ1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8L2g1PlxuICAgIH1cbiAgICBAY2FzZSAoJ0g2Jykge1xuICAgICAgPGg2IGNsYXNzPVwiZnItY2FyZF9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oNj5cbiAgICB9XG4gICAgQGRlZmF1bHQge1xuICAgICAgPGgzIGNsYXNzPVwiZnItY2FyZF9fdGl0bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9oMz5cbiAgICB9XG4gIH1cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjaGVhZGluZ1RlbXBsYXRlPlxuICA8IS0tIERlZmluaXRpb24gZGVzIHRlbXBsYXRlcyBkaXJlY3RlbWVudCBpY2kgcG91ciB1bmUgcHJvamVjdGlvbiBkdSBzbG90IGNvcnJlY3RlIChwYXMgZGUgZWxzZSktLT5cblxuICA8IS0tIFRpdHJlIHNpbXBsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgQGlmICghaGFzTGluaygpKSB7XG4gICAgQGlmIChoZWFkaW5nKSB7XG4gICAgICA8IS0tIEZJWE1FIFYyIHN1cHByaW1lciBsZSBpbm5lckh0bWwtZXQgbGUgc3BhbiBhc3NvY2nDqSAtLT5cbiAgICAgIDxzcGFuIFtpbm5lckhUTUxdPVwiaGVhZGluZ1wiPjwvc3Bhbj5cbiAgICB9IEBlbHNlIHtcbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJoZWFkaW5nVGVtcGxhdGVTbG90XCI+PC9uZy1jb250YWluZXI+XG4gICAgfVxuICB9XG5cbiAgPCEtLSBMaWVuICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gIEBpZiAoaGFzTGluaygpKSB7XG4gICAgPCEtLSBMaWVuIHNhbnMgdMOpbMOpY2hhcmdlbWVudCAtLT5cbiAgICBAaWYgKCFkb3dubG9hZCkge1xuICAgICAgPGRzZnItbGlua1xuICAgICAgICBbY3VzdG9tQ2xhc3NdPVwiJ2VkdS1saW5rJ1wiXG4gICAgICAgIFthcmlhTGFiZWxdPVwiYXJpYUxhYmVsID8/ICcnXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW2xpbmtdPVwibGlua1wiXG4gICAgICAgIFtsaW5rVGFyZ2V0XT1cImxpbmtUYXJnZXRcIlxuICAgICAgICBbbGFiZWxdPVwiaGVhZGluZ1wiXG4gICAgICAgIFtyb3V0ZV09XCJyb3V0ZVwiXG4gICAgICAgIFtyb3V0ZVBhdGhdPVwicm91dGVQYXRoXCJcbiAgICAgICAgW3JvdXRlckxpbmtBY3RpdmVdPVwicm91dGVyTGlua0FjdGl2ZSA/PyAnJ1wiXG4gICAgICAgIFtyb3V0ZXJMaW5rRXh0cmFzXT1cInJvdXRlckxpbmtFeHRyYXNcIlxuICAgICAgICBbbW9kZV09XCJlbmxhcmdlQnV0dG9uID8gJ2J1dHRvbicgOiAnbGluaydcIlxuICAgICAgICAobGlua1NlbGVjdCk9XCJvbkxpbmtTZWxlY3QoKVwiPlxuICAgICAgICBAaWYgKCFoZWFkaW5nKSB7XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRpbmdUZW1wbGF0ZVNsb3RcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgfVxuICAgICAgPC9kc2ZyLWxpbms+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8IS0tIExpZW4gZGUgdMOpbMOpY2hhcmdlbWVudCAtLT5cbiAgICAgIDxlZHUtbGluay1kb3dubG9hZFxuICAgICAgICBbaXRlbV09XCJpdGVtTGlua1wiXG4gICAgICAgIFtkb3dubG9hZERpcmVjdF09XCJkb3dubG9hZERpcmVjdFwiXG4gICAgICAgIFtkb3dubG9hZEFzc2Vzc0ZpbGVdPVwiZG93bmxvYWRBc3Nlc3NGaWxlXCJcbiAgICAgICAgW2xpbmtUYXJnZXRdPVwibGlua1RhcmdldFwiXG4gICAgICAgIFtsYW5nQ29kZV09XCJkb3dubG9hZExhbmdDb2RlXCJcbiAgICAgICAgW2lzQnV0dG9uXT1cImlzRG93bmxvYWRCdXR0b25cIlxuICAgICAgICAobGlua1NlbGVjdCk9XCJvbkxpbmtTZWxlY3QoKVwiPjwvZWR1LWxpbmstZG93bmxvYWQ+XG4gICAgfVxuICB9XG48L25nLXRlbXBsYXRlPlxuXG48IS0tIFRlbXBsYXRlIHPDqXBhcsOpIHBvdXIgYXZvaXIgdW5lIHNldWxlIGTDqWZpbml0aW9uIGR1IHNlbGVjdCBoZWFkaW5nIChETyBOT1QgREVMRVRFKSAtLT5cbjxuZy10ZW1wbGF0ZSAjaGVhZGluZ1RlbXBsYXRlU2xvdD5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2hlYWRpbmddXCI+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==