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

124 lines 26.3 kB
import { Component, EventEmitter, Inject, Input, Output, ViewEncapsulation } from '@angular/core'; import { LocalStorage, StorageEnum, isOnBrowser } from '../../shared'; import { DSFR_CONFIG_TOKEN } from '../../shared/config/config-token'; import * as i0 from "@angular/core"; import * as i1 from "../../shared"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; export const DISPLAY_MODAL_ID = 'theme-modal-id'; export class DsfrDisplayComponent { /** @internal */ constructor(config, i18n, elementRef) { this.config = config; this.i18n = i18n; this.elementRef = elementRef; /** * l'identifiant de la modale portant les paramètres d'affichage. */ this.displayId = DISPLAY_MODAL_ID; /** * Événement émis lorsque le thème change avec la valeur du nouveau thème : `light`, `dark` ou `system`. */ this.displayChange = new EventEmitter(); /** @internal */ this.themes = { light: { id: 'theme-light', value: 'light', label: this.i18n.t('display.light.label'), img: 'sun.svg', link: '/pictograms/environment/sun.svg', deprecatedLink: '/sun.svg', }, dark: { id: 'theme-dark', value: 'dark', label: this.i18n.t('display.dark.label'), img: 'moon.svg', link: '/pictograms/environment/moon.svg', deprecatedLink: '/moon.svg', }, system: { id: 'theme-system', value: 'system', label: this.i18n.t('display.system.label'), hint: this.i18n.t('display.system.hint'), img: 'system.svg', link: '/pictograms/system/system.svg', deprecatedLink: '/system.svg', }, }; /** @internal */ this.closeI18n = this.i18n.t('commons.close'); /** @internal */ this.name = 'radios-theme'; /** @internal */ this.themeValues = Object.values(this.themes); this._useDeprecatedLink = false; } get pictoPath() { return this.artworkDirPath; } /** * Chemin des pictogrammes (du composant display) renseigné par le développeur. * * Note: ce chemin doit permettre de récupérer directement les fichiers SVG suivants : moon.svg, sun.svg, system.svg * * @deprecated Use `artworkDirPath` instead. */ set pictoPath(path) { this.artworkDirPath = path; this._useDeprecatedLink = true; } ngOnInit() { this.initDisplayTheme(); if (this.artworkDirPath === undefined) { this.artworkDirPath = this.config.artworkDirPath; } } /** @internal */ onChange() { this.setHtmlSchemeAttribute(this.currentTheme); this.displayChange.emit(this.currentTheme); } /** @internal */ buildSvgPath(theme, sprite) { return this.artworkDirPath + (this._useDeprecatedLink ? theme.deprecatedLink : theme.link) + sprite; } initDisplayTheme() { if (!isOnBrowser()) return; // Si l’utilisateur effectue une modification, son choix est conservé (dans le local storage) pour les visites ultérieures. let savedTheme = LocalStorage.get(StorageEnum.SCHEME); if (savedTheme) { this.setHtmlSchemeAttribute(savedTheme); } // Sinon on prend le theme de la balise HTML else { const nativeElt = this.elementRef?.nativeElement; const html = nativeElt?.ownerDocument?.documentElement; savedTheme = html?.getAttribute('data-fr-scheme'); } this.currentTheme = savedTheme || 'system'; } setHtmlSchemeAttribute(value) { const nativeElt = this.elementRef?.nativeElement; const html = nativeElt?.ownerDocument?.documentElement; html?.setAttribute('data-fr-scheme', value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DsfrDisplayComponent, deps: [{ token: DSFR_CONFIG_TOKEN }, { token: i1.I18nService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DsfrDisplayComponent, selector: "dsfr-display", inputs: { displayId: "displayId", artworkDirPath: "artworkDirPath", pictoPath: "pictoPath" }, outputs: { displayChange: "displayChange" }, ngImport: i0, template: "<dialog [id]=\"displayId\" class=\"fr-modal\" role=\"dialog\" [attr.aria-labelledby]=\"displayId + '-title'\">\n <div class=\"fr-container fr-container--fluid fr-container-md\">\n <div class=\"fr-grid-row fr-grid-row--center\">\n <div class=\"fr-col-12 fr-col-md-6 fr-col-lg-4\">\n <div class=\"fr-modal__body\">\n <div class=\"fr-modal__header\">\n <button type=\"button\" class=\"fr-btn--close fr-btn\" [attr.aria-controls]=\"displayId\" [title]=\"closeI18n\">\n {{ closeI18n }}\n </button>\n </div>\n <div class=\"fr-modal__content\">\n <h1 [id]=\"displayId + '-title'\" class=\"fr-modal__title\">{{ i18n.t('display.heading') }}</h1>\n <!-- BUG: classe fr-display inexistante c\u00F4t\u00E9 DSFR 1.11 mais utilis\u00E9 dans leur template -->\n <div [id]=\"displayId + '-fr-display'\" class=\"fr-display\">\n <fieldset class=\"fr-fieldset\" [id]=\"displayId + '-display-fieldset'\">\n <legend\n class=\"fr-fieldset__legend--regular fr-fieldset__legend\"\n [id]=\"displayId + '-display-fieldset-legend'\">\n {{ i18n.t('display.hint') }}\n </legend>\n <!-- Groupe radios ------------------------------------------------------------------------------------>\n <!-- TODO A mutualiser avec les radios rich quand on pourra -->\n <div *ngFor=\"let radio of themeValues\" class=\"fr-fieldset__element\">\n <div class=\"fr-radio-group fr-radio-rich\">\n <input\n type=\"radio\"\n [id]=\"radio.id\"\n [name]=\"name\"\n [value]=\"radio.value\"\n [(ngModel)]=\"currentTheme\"\n (ngModelChange)=\"onChange()\" />\n <label class=\"fr-label\" [for]=\"radio.id\">{{ radio.label }}</label>\n <div class=\"fr-radio-rich__img\">\n <svg aria-hidden=\"true\" class=\"fr-artwork\" viewBox=\"0 0 80 80\" width=\"80px\" height=\"80px\">\n <use\n class=\"fr-artwork-decorative\"\n [attr.href]=\"buildSvgPath(radio, '#artwork-decorative')\"></use>\n <use class=\"fr-artwork-minor\" [attr.href]=\"buildSvgPath(radio, '#artwork-minor')\"></use>\n <use class=\"fr-artwork-major\" [attr.href]=\"buildSvgPath(radio, '#artwork-major')\"></use>\n </svg>\n </div>\n </div>\n </div>\n <!----------------------------------------------------------------------------------------------------->\n </fieldset>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</dialog>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DsfrDisplayComponent, decorators: [{ type: Component, args: [{ selector: 'dsfr-display', encapsulation: ViewEncapsulation.None, template: "<dialog [id]=\"displayId\" class=\"fr-modal\" role=\"dialog\" [attr.aria-labelledby]=\"displayId + '-title'\">\n <div class=\"fr-container fr-container--fluid fr-container-md\">\n <div class=\"fr-grid-row fr-grid-row--center\">\n <div class=\"fr-col-12 fr-col-md-6 fr-col-lg-4\">\n <div class=\"fr-modal__body\">\n <div class=\"fr-modal__header\">\n <button type=\"button\" class=\"fr-btn--close fr-btn\" [attr.aria-controls]=\"displayId\" [title]=\"closeI18n\">\n {{ closeI18n }}\n </button>\n </div>\n <div class=\"fr-modal__content\">\n <h1 [id]=\"displayId + '-title'\" class=\"fr-modal__title\">{{ i18n.t('display.heading') }}</h1>\n <!-- BUG: classe fr-display inexistante c\u00F4t\u00E9 DSFR 1.11 mais utilis\u00E9 dans leur template -->\n <div [id]=\"displayId + '-fr-display'\" class=\"fr-display\">\n <fieldset class=\"fr-fieldset\" [id]=\"displayId + '-display-fieldset'\">\n <legend\n class=\"fr-fieldset__legend--regular fr-fieldset__legend\"\n [id]=\"displayId + '-display-fieldset-legend'\">\n {{ i18n.t('display.hint') }}\n </legend>\n <!-- Groupe radios ------------------------------------------------------------------------------------>\n <!-- TODO A mutualiser avec les radios rich quand on pourra -->\n <div *ngFor=\"let radio of themeValues\" class=\"fr-fieldset__element\">\n <div class=\"fr-radio-group fr-radio-rich\">\n <input\n type=\"radio\"\n [id]=\"radio.id\"\n [name]=\"name\"\n [value]=\"radio.value\"\n [(ngModel)]=\"currentTheme\"\n (ngModelChange)=\"onChange()\" />\n <label class=\"fr-label\" [for]=\"radio.id\">{{ radio.label }}</label>\n <div class=\"fr-radio-rich__img\">\n <svg aria-hidden=\"true\" class=\"fr-artwork\" viewBox=\"0 0 80 80\" width=\"80px\" height=\"80px\">\n <use\n class=\"fr-artwork-decorative\"\n [attr.href]=\"buildSvgPath(radio, '#artwork-decorative')\"></use>\n <use class=\"fr-artwork-minor\" [attr.href]=\"buildSvgPath(radio, '#artwork-minor')\"></use>\n <use class=\"fr-artwork-major\" [attr.href]=\"buildSvgPath(radio, '#artwork-major')\"></use>\n </svg>\n </div>\n </div>\n </div>\n <!----------------------------------------------------------------------------------------------------->\n </fieldset>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</dialog>\n" }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [DSFR_CONFIG_TOKEN] }] }, { type: i1.I18nService }, { type: i0.ElementRef }]; }, propDecorators: { displayId: [{ type: Input }], artworkDirPath: [{ type: Input }], displayChange: [{ type: Output }], pictoPath: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHNmci1jb21wb25lbnRzL3NyYy9saWIvY29tcG9uZW50cy9kaXNwbGF5L2Rpc3BsYXkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWRzZnItY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvZGlzcGxheS9kaXNwbGF5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RILE9BQU8sRUFBZSxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7QUFHckUsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7QUFTakQsTUFBTSxPQUFPLG9CQUFvQjtJQTJEL0IsZ0JBQWdCO0lBQ2hCLFlBQ3FDLE1BQWtCLEVBQzlDLElBQWlCLEVBQ2hCLFVBQXNCO1FBRkssV0FBTSxHQUFOLE1BQU0sQ0FBWTtRQUM5QyxTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ2hCLGVBQVUsR0FBVixVQUFVLENBQVk7UUE5RGhDOztXQUVHO1FBQ00sY0FBUyxHQUFHLGdCQUFnQixDQUFDO1FBT3RDOztXQUVHO1FBQ08sa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBU3JELGdCQUFnQjtRQUNQLFdBQU0sR0FBRztZQUNoQixLQUFLLEVBQUU7Z0JBQ0wsRUFBRSxFQUFFLGFBQWE7Z0JBQ2pCLEtBQUssRUFBRSxPQUFPO2dCQUNkLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxD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QUFDLENBQUM7U0FDbkQ7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsSUFBSSxRQUFRLENBQUM7SUFDN0MsQ0FBQztJQUVPLHNCQUFzQixDQUFDLEtBQW1CO1FBQ2hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDO1FBQ2pELE1BQU0sSUFBSSxHQUFHLFNBQVMsRUFBRSxhQUFhLEVBQUUsZUFBZSxDQUFDO1FBQ3ZELElBQUksRUFBRSxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDOUMsQ0FBQzsrR0EzSFUsb0JBQW9CLGtCQTZEckIsaUJBQWlCO21HQTdEaEIsb0JBQW9CLCtMQ2RqQyxxNUZBb0RBOzs0RkR0Q2Esb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGNBQWMsaUJBRVQsaUJBQWlCLENBQUMsSUFBSTs7MEJBK0RsQyxNQUFNOzJCQUFDLGlCQUFpQjsrRkF6RGxCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBS0csY0FBYztzQkFBdEIsS0FBSztnQkFLSSxhQUFhO3NCQUF0QixNQUFNO2dCQStETSxTQUFTO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSTE4blNlcnZpY2UsIExvY2FsU3RvcmFnZSwgU3RvcmFnZUVudW0sIGlzT25Ccm93c2VyIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IERTRlJfQ09ORklHX1RPS0VOIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbmZpZy9jb25maWctdG9rZW4nO1xuaW1wb3J0IHsgRHNmckNvbmZpZyB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb25maWcvY29uZmlnLm1vZGVsJztcblxuZXhwb3J0IGNvbnN0IERJU1BMQVlfTU9EQUxfSUQgPSAndGhlbWUtbW9kYWwtaWQnO1xuXG50eXBlIERpc3BsYXlUaGVtZSA9ICdsaWdodCcgfCAnZGFyaycgfCAnc3lzdGVtJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHNmci1kaXNwbGF5JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Rpc3BsYXkuY29tcG9uZW50Lmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBEc2ZyRGlzcGxheUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKlxuICAgKiBsJ2lkZW50aWZpYW50IGRlIGxhIG1vZGFsZSBwb3J0YW50IGxlcyBwYXJhbcOodHJlcyBkJ2FmZmljaGFnZS5cbiAgICovXG4gIEBJbnB1dCgpIGRpc3BsYXlJZCA9IERJU1BMQVlfTU9EQUxfSUQ7XG5cbiAgLyoqXG4gICAqIENoZW1pbiB2ZXJzIGxlIHLDqXBlcnRvaXJlIGV4cG9zYW50IGxlcyBwaWN0b2dyYW1tZXMgaWxsdXN0cmF0aWZzIERTRlIuXG4gICAqL1xuICBASW5wdXQoKSBhcnR3b3JrRGlyUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiDDiXbDqW5lbWVudCDDqW1pcyBsb3JzcXVlIGxlIHRow6htZSBjaGFuZ2UgYXZlYyBsYSB2YWxldXIgZHUgbm91dmVhdSB0aMOobWUgOiBgbGlnaHRgLCBgZGFya2Agb3UgYHN5c3RlbWAuXG4gICAqL1xuICBAT3V0cHV0KCkgZGlzcGxheUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKlxuICAgKiBUaMOobWUgY291cmFudCBkdSBjb21wb3NhbnQuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgY3VycmVudFRoZW1lOiBEaXNwbGF5VGhlbWU7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICByZWFkb25seSB0aGVtZXMgPSB7XG4gICAgbGlnaHQ6IHtcbiAgICAgIGlkOiAndGhlbWUtbGlnaHQnLFxuICAgICAgdmFsdWU6ICdsaWdodCcsXG4gICAgICBsYWJlbDogdGhpcy5pMThuLnQoJ2Rpc3BsYXkubGlnaHQubGFiZWwnKSxcbiAgICAgIGltZzogJ3N1bi5zdmcnLFxuICAgICAgbGluazogJy9waWN0b2dyYW1zL2Vudmlyb25tZW50L3N1bi5zdmcnLFxuICAgICAgZGVwcmVjYXRlZExpbms6ICcvc3VuLnN2ZycsXG4gICAgfSxcbiAgICBkYXJrOiB7XG4gICAgICBpZDogJ3RoZW1lLWRhcmsnLFxuICAgICAgdmFsdWU6ICdkYXJrJyxcbiAgICAgIGxhYmVsOiB0aGlzLmkxOG4udCgnZGlzcGxheS5kYXJrLmxhYmVsJyksXG4gICAgICBpbWc6ICdtb29uLnN2ZycsXG4gICAgICBsaW5rOiAnL3BpY3RvZ3JhbXMvZW52aXJvbm1lbnQvbW9vbi5zdmcnLFxuICAgICAgZGVwcmVjYXRlZExpbms6ICcvbW9vbi5zdmcnLFxuICAgIH0sXG4gICAgc3lzdGVtOiB7XG4gICAgICBpZDogJ3RoZW1lLXN5c3RlbScsXG4gICAgICB2YWx1ZTogJ3N5c3RlbScsXG4gICAgICBsYWJlbDogdGhpcy5pMThuLnQoJ2Rpc3BsYXkuc3lzdGVtLmxhYmVsJyksXG4gICAgICBoaW50OiB0aGlzLmkxOG4udCgnZGlzcGxheS5zeXN0ZW0uaGludCcpLFxuICAgICAgaW1nOiAnc3lzdGVtLnN2ZycsXG4gICAgICBsaW5rOiAnL3BpY3RvZ3JhbXMvc3lzdGVtL3N5c3RlbS5zdmcnLFxuICAgICAgZGVwcmVjYXRlZExpbms6ICcvc3lzdGVtLnN2ZycsXG4gICAgfSxcbiAgfTtcblxuICAvKiogQGludGVybmFsICovIHJlYWRvbmx5IGNsb3NlSTE4biA9IHRoaXMuaTE4bi50KCdjb21tb25zLmNsb3NlJyk7XG4gIC8qKiBAaW50ZXJuYWwgKi8gbmFtZSA9ICdyYWRpb3MtdGhlbWUnO1xuICAvKiogQGludGVybmFsICovIHRoZW1lVmFsdWVzID0gT2JqZWN0LnZhbHVlcyh0aGlzLnRoZW1lcyk7XG4gIC8qKiBAaW50ZXJuYWwgKi8gX3N2Z1Jvb3RQYXRoOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBfdXNlRGVwcmVjYXRlZExpbmsgPSBmYWxzZTtcblxuICAvKiogQGludGVybmFsICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRFNGUl9DT05GSUdfVE9LRU4pIHByaXZhdGUgY29uZmlnOiBEc2ZyQ29uZmlnLFxuICAgIHB1YmxpYyBpMThuOiBJMThuU2VydmljZSxcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICkge31cblxuICBnZXQgcGljdG9QYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXJ0d29ya0RpclBhdGg7XG4gIH1cblxuICAvKipcbiAgICogQ2hlbWluIGRlcyBwaWN0b2dyYW1tZXMgKGR1IGNvbXBvc2FudCBkaXNwbGF5KSByZW5zZWlnbsOpIHBhciBsZSBkw6l2ZWxvcHBldXIuXG4gICAqXG4gICAqIE5vdGU6IGNlIGNoZW1pbiBkb2l0IHBlcm1ldHRyZSBkZSByw6ljdXDDqXJlciBkaXJlY3RlbWVudCBsZXMgZmljaGllcnMgU1ZHIHN1aXZhbnRzIDogbW9vbi5zdmcsIHN1bi5zdmcsIHN5c3RlbS5zdmdcbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBhcnR3b3JrRGlyUGF0aGAgaW5zdGVhZC5cbiAgICovXG4gIEBJbnB1dCgpIHNldCBwaWN0b1BhdGgocGF0aDogc3RyaW5nKSB7XG4gICAgdGhpcy5hcnR3b3JrRGlyUGF0aCA9IHBhdGg7XG4gICAgdGhpcy5fdXNlRGVwcmVjYXRlZExpbmsgPSB0cnVlO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0RGlzcGxheVRoZW1lKCk7XG4gICAgaWYgKHRoaXMuYXJ0d29ya0RpclBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5hcnR3b3JrRGlyUGF0aCA9IHRoaXMuY29uZmlnLmFydHdvcmtEaXJQYXRoO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgb25DaGFuZ2UoKSB7XG4gICAgdGhpcy5zZXRIdG1sU2NoZW1lQXR0cmlidXRlKHRoaXMuY3VycmVudFRoZW1lKTtcbiAgICB0aGlzLmRpc3BsYXlDaGFuZ2UuZW1pdCh0aGlzLmN1cnJlbnRUaGVtZSk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIGJ1aWxkU3ZnUGF0aCh0aGVtZTogYW55LCBzcHJpdGU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFydHdvcmtEaXJQYXRoICsgKHRoaXMuX3VzZURlcHJlY2F0ZWRMaW5rID8gdGhlbWUuZGVwcmVjYXRlZExpbmsgOiB0aGVtZS5saW5rKSArIHNwcml0ZTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdERpc3BsYXlUaGVtZSgpOiB2b2lkIHtcbiAgICBpZiAoIWlzT25Ccm93c2VyKCkpIHJldHVybjtcblxuICAgIC8vIFNpIGzigJl1dGlsaXNhdGV1ciBlZmZlY3R1ZSB1bmUgbW9kaWZpY2F0aW9uLCBzb24gY2hvaXggZXN0IGNvbnNlcnbDqSAoZGFucyBsZSBsb2NhbCBzdG9yYWdlKSBwb3VyIGxlcyB2aXNpdGVzIHVsdMOpcmlldXJlcy5cbiAgICBsZXQgc2F2ZWRUaGVtZSA9IDxEaXNwbGF5VGhlbWU+TG9jYWxTdG9yYWdlLmdldChTdG9yYWdlRW51bS5TQ0hFTUUpO1xuICAgIGlmIChzYXZlZFRoZW1lKSB7XG4gICAgICB0aGlzLnNldEh0bWxTY2hlbWVBdHRyaWJ1dGUoc2F2ZWRUaGVtZSk7XG4gICAgfVxuXG4gICAgLy8gU2lub24gb24gcHJlbmQgbGUgdGhlbWUgZGUgbGEgYmFsaXNlIEhUTUxcbiAgICBlbHNlIHtcbiAgICAgIGNvbnN0IG5hdGl2ZUVsdCA9IHRoaXMuZWxlbWVudFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IGh0bWwgPSBuYXRpdmVFbHQ/Lm93bmVyRG9jdW1lbnQ/LmRvY3VtZW50RWxlbWVudDtcbiAgICAgIHNhdmVkVGhlbWUgPSBodG1sPy5nZXRBdHRyaWJ1dGUoJ2RhdGEtZnItc2NoZW1lJyk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50VGhlbWUgPSBzYXZlZFRoZW1lIHx8ICdzeXN0ZW0nO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRIdG1sU2NoZW1lQXR0cmlidXRlKHZhbHVlOiBEaXNwbGF5VGhlbWUpIHtcbiAgICBjb25zdCBuYXRpdmVFbHQgPSB0aGlzLmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgaHRtbCA9IG5hdGl2ZUVsdD8ub3duZXJEb2N1bWVudD8uZG9jdW1lbnRFbGVtZW50O1xuICAgIGh0bWw/LnNldEF0dHJpYnV0ZSgnZGF0YS1mci1zY2hlbWUnLCB2YWx1ZSk7XG4gIH1cbn1cbiIsIjxkaWFsb2cgW2lkXT1cImRpc3BsYXlJZFwiIGNsYXNzPVwiZnItbW9kYWxcIiByb2xlPVwiZGlhbG9nXCIgW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cImRpc3BsYXlJZCArICctdGl0bGUnXCI+XG4gIDxkaXYgY2xhc3M9XCJmci1jb250YWluZXIgZnItY29udGFpbmVyLS1mbHVpZCBmci1jb250YWluZXItbWRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZnItZ3JpZC1yb3cgZnItZ3JpZC1yb3ctLWNlbnRlclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZyLWNvbC0xMiBmci1jb2wtbWQtNiBmci1jb2wtbGctNFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZnItbW9kYWxfX2JvZHlcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnItbW9kYWxfX2hlYWRlclwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJmci1idG4tLWNsb3NlIGZyLWJ0blwiIFthdHRyLmFyaWEtY29udHJvbHNdPVwiZGlzcGxheUlkXCIgW3RpdGxlXT1cImNsb3NlSTE4blwiPlxuICAgICAgICAgICAgICB7eyBjbG9zZUkxOG4gfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmci1tb2RhbF9fY29udGVudFwiPlxuICAgICAgICAgICAgPGgxIFtpZF09XCJkaXNwbGF5SWQgKyAnLXRpdGxlJ1wiIGNsYXNzPVwiZnItbW9kYWxfX3RpdGxlXCI+e3sgaTE4bi50KCdkaXNwbGF5LmhlYWRpbmcnKSB9fTwvaDE+XG4gICAgICAgICAgICA8IS0tIEJVRzogY2xhc3NlIGZyLWRpc3BsYXkgaW5leGlzdGFudGUgY8O0dMOpIERTRlIgMS4xMSBtYWlzIHV0aWxpc8OpIGRhbnMgbGV1ciB0ZW1wbGF0ZSAtLT5cbiAgICAgICAgICAgIDxkaXYgW2lkXT1cImRpc3BsYXlJZCArICctZnItZGlzcGxheSdcIiBjbGFzcz1cImZyLWRpc3BsYXlcIj5cbiAgICAgICAgICAgICAgPGZpZWxkc2V0IGNsYXNzPVwiZnItZmllbGRzZXRcIiBbaWRdPVwiZGlzcGxheUlkICsgJy1kaXNwbGF5LWZpZWxkc2V0J1wiPlxuICAgICAgICAgICAgICAgIDxsZWdlbmRcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZnItZmllbGRzZXRfX2xlZ2VuZC0tcmVndWxhciBmci1maWVsZHNldF9fbGVnZW5kXCJcbiAgICAgICAgICAgICAgICAgIFtpZF09XCJkaXNwbGF5SWQgKyAnLWRpc3BsYXktZmllbGRzZXQtbGVnZW5kJ1wiPlxuICAgICAgICAgICAgICAgICAge3sgaTE4bi50KCdkaXNwbGF5LmhpbnQnKSB9fVxuICAgICAgICAgICAgICAgIDwvbGVnZW5kPlxuICAgICAgICAgICAgICAgIDwhLS0gR3JvdXBlIHJhZGlvcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgICAgICAgICAgICAgPCEtLSBUT0RPIEEgbXV0dWFsaXNlciBhdmVjIGxlcyByYWRpb3MgcmljaCBxdWFuZCBvbiBwb3VycmEgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcmFkaW8gb2YgdGhlbWVWYWx1ZXNcIiBjbGFzcz1cImZyLWZpZWxkc2V0X19lbGVtZW50XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnItcmFkaW8tZ3JvdXAgZnItcmFkaW8tcmljaFwiPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFkaW9cIlxuICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCJyYWRpby5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInJhZGlvLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImN1cnJlbnRUaGVtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25DaGFuZ2UoKVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZyLWxhYmVsXCIgW2Zvcl09XCJyYWRpby5pZFwiPnt7IHJhZGlvLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZyLXJhZGlvLXJpY2hfX2ltZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzdmcgYXJpYS1oaWRkZW49XCJ0cnVlXCIgY2xhc3M9XCJmci1hcnR3b3JrXCIgdmlld0JveD1cIjAgMCA4MCA4MFwiIHdpZHRoPVwiODBweFwiIGhlaWdodD1cIjgwcHhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx1c2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmci1hcnR3b3JrLWRlY29yYXRpdmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5ocmVmXT1cImJ1aWxkU3ZnUGF0aChyYWRpbywgJyNhcnR3b3JrLWRlY29yYXRpdmUnKVwiPjwvdXNlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHVzZSBjbGFzcz1cImZyLWFydHdvcmstbWlub3JcIiBbYXR0ci5ocmVmXT1cImJ1aWxkU3ZnUGF0aChyYWRpbywgJyNhcnR3b3JrLW1pbm9yJylcIj48L3VzZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx1c2UgY2xhc3M9XCJmci1hcnR3b3JrLW1ham9yXCIgW2F0dHIuaHJlZl09XCJidWlsZFN2Z1BhdGgocmFkaW8sICcjYXJ0d29yay1tYWpvcicpXCI+PC91c2U+XG4gICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICAgICAgICAgICAgPC9maWVsZHNldD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGlhbG9nPlxuIl19