UNPKG

@linid-dm/directory-manager-client-core

Version:

Core package by providing a set of angular components for the Directory Manager app.

173 lines 40.3 kB
import { __decorate } from "tslib"; /** * Copyright (C) 2020-2024 Linagora * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version, provided you comply with the Additional Terms applicable for * LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU * Affero General Public License, subsections (b), (c), and (e), pursuant to * which these Appropriate Legal Notices must notably (i) retain the display of * the "LinID™" trademark/logo at the top of the interface window, the display * of the “You are using the Open Source and free version of LinID™, powered by * Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise * offer!” infobox and in the e-mails sent with the Program, notice appended to * any type of outbound messages (e.g. e-mail and meeting requests) as well as * in the LinID Directory Manager user interface, (ii) retain all hypertext * links between LinID Directory Manager and https://linid.org/, as well as * between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA * intellectual property rights over its trademarks and commercial brands. Other * Additional Terms apply, see <http://www.linagora.com/licenses/> for more * details. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License and * its applicable Additional Terms for LinID Directory Manager along with this * program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero * General Public License version 3 and <http://www.linagora.com/licenses/> for * the Additional Terms applicable to the LinID Directory Manager software. */ import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core'; import { Select } from '@ngxs/store'; import { Subject, debounceTime, takeUntil, tap } from 'rxjs'; import { Data, UiState, } from '../../shared'; import * as i0 from "@angular/core"; import * as i1 from "@ngxs/store"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "@angular/flex-layout/flex"; import * as i5 from "@angular/flex-layout/extended"; import * as i6 from "@angular/material/button"; import * as i7 from "@angular/material/form-field"; import * as i8 from "@angular/material/icon"; import * as i9 from "@angular/material/input"; import * as i10 from "@angular/material/tooltip"; export class GenericDataHeaderComponent { set advancedSearchMatHint(advancedSearchMatHint) { if (!!advancedSearchMatHint) { this._advancedSearchMatHint = advancedSearchMatHint; this.lineHeight = Math.round(Number(getComputedStyle(this._advancedSearchMatHint.nativeElement) .getPropertyValue('line-height') .replace('px', ''))); } } get advancedSearchMatHint() { return this._advancedSearchMatHint; } set selectedResourceRootTypeId(selectedResourceRootTypeId) { this._largeHeaderWidth = null; this.largeBtnAdditionnalClasses = { 'hide-btn': false }; this.smallBtnAdditionnalClasses = { 'hide-btn': false }; this._selectedResourceRootTypeId = selectedResourceRootTypeId; this.search = this.dataJsTable.byId[this.selectedResourceRootTypeId]?.filterValue; } get selectedResourceRootTypeId() { return this._selectedResourceRootTypeId; } set offsetWidth(offsetWidth) { if (!!offsetWidth) { this._offsetWidth = offsetWidth; this._updateButtonDisplay(); } } get offsetWidth() { return this._offsetWidth; } constructor(_store$) { this._store$ = _store$; this._COMPONENT_MIN_WIDTH = 290; this.largeBtnAdditionnalClasses = { 'hide-btn': false, }; this.smallBtnAdditionnalClasses = { 'hide-btn': false, }; this.clickOnAddResourceBtn = new EventEmitter(); this._onDestroy$ = new Subject(); this.search = ''; this.modelChanged = new Subject(); } ngOnInit() { this.modelChanged .pipe(debounceTime(300), takeUntil(this._onDestroy$), tap((currentSearch) => { this._store$.dispatch(new Data.SetFilterValue({ filterValue: currentSearch, dataTypeId: this.selectedResourceRootTypeId, })); })) .subscribe(); } ngAfterViewInit() { let largeBtnWidth = 0; let smallBtnWidth = 0; if (this.canCreate) { largeBtnWidth = this.createLargeBtn._elementRef.nativeElement.offsetWidth; smallBtnWidth = this.createMiniFabBtn._elementRef.nativeElement.offsetWidth; } let filterMinWidth = this._COMPONENT_MIN_WIDTH - smallBtnWidth; this._largeHeaderWidth = filterMinWidth + largeBtnWidth; this._updateButtonDisplay(); } clearInputFilter() { this.search = ''; this.modelChanged.next(''); } updateSearch(search) { this.modelChanged.next(search); } addNewResource() { this.clickOnAddResourceBtn.emit(); } ngOnDestroy() { this._onDestroy$.next(); this._onDestroy$.complete(); } _updateButtonDisplay() { if (this._largeHeaderWidth != null) { const displayLargeBtn = this._largeHeaderWidth <= this.offsetWidth; this.largeBtnAdditionnalClasses = { 'hide-btn': !displayLargeBtn }; this.smallBtnAdditionnalClasses = { 'hide-btn': displayLargeBtn }; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GenericDataHeaderComponent, deps: [{ token: i1.Store }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: GenericDataHeaderComponent, selector: "dm-generic-data-header", inputs: { advancedSearchMatHint: "advancedSearchMatHint", canCreate: "canCreate", addBtnLabel: "addBtnLabel", dataJsTable: "dataJsTable", selectedResourceRootTypeId: "selectedResourceRootTypeId", offsetWidth: "offsetWidth", isLargeScreen: "isLargeScreen", isAdvancedSearchActivated: "isAdvancedSearchActivated" }, outputs: { clickOnAddResourceBtn: "clickOnAddResourceBtn" }, viewQueries: [{ propertyName: "createLargeBtn", first: true, predicate: ["createLargeBtn"], descendants: true }, { propertyName: "createMiniFabBtn", first: true, predicate: ["createMiniFabBtn"], descendants: true }], ngImport: i0, template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<div fxLayout=\"row\" class=\"div-gnc-filter\">\n <mat-form-field\n *ngIf=\"filterAccessibility$ | async as filterAccessibility\"\n fxFlex\n color=\"accent\"\n [ngClass]=\"{\n 'gnc-filter-activated':\n advancedSearchMatHint?.nativeElement.offsetHeight <= lineHeight\n }\"\n class=\"gnc-filter\"\n >\n <mat-label>\n <mat-icon aria-hidden=\"true\">filter_list_alt</mat-icon>\n {{ filterAccessibility.label }}\n </mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"search\"\n (ngModelChange)=\"updateSearch($event)\"\n class=\"filter\"\n />\n <button\n *ngIf=\"search\"\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"filterAccessibility.clearSearch\"\n (click)=\"clearInputFilter()\"\n class=\"reset-input-btn\"\n [matTooltip]=\"filterAccessibility.clearSearch\"\n >\n <mat-icon aria-hidden=\"true\"> clear </mat-icon>\n </button>\n </mat-form-field>\n <div\n *ngIf=\"canCreate\"\n class=\"div-add-button\"\n [ngClass]=\"{\n 'div-add-button-with-advanced-search':\n advancedSearchMatHint?.nativeElement.offsetHeight <= lineHeight\n }\"\n >\n <button\n #createLargeBtn\n mat-raised-button\n color=\"accent\"\n (click)=\"addNewResource()\"\n class=\"lg-add-btn\"\n [ngClass]=\"largeBtnAdditionnalClasses\"\n >\n {{ addBtnLabel }}\n </button>\n <button\n #createMiniFabBtn\n mat-mini-fab\n color=\"accent\"\n matTooltipPosition=\"right\"\n [matTooltip]=\"addBtnLabel\"\n (click)=\"addNewResource()\"\n class=\"sm-add-btn\"\n [ngClass]=\"smallBtnAdditionnalClasses\"\n >\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n </button>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.gnc-filter{padding:20px 20px 0}.gnc-filter-activated{padding-top:10px}.div-add-button{margin-top:25px;padding-right:5px}.div-add-button-with-advanced-search{margin-top:15px}.lg-add-btn{width:max-content}button.mdc-fab--mini.sm-add-btn:active:not([class*=mat-elevation-z]){box-shadow:none}.hide-btn{display:none}mat-label{display:flex}.reset-input-btn{height:1.5em;width:1.5em;padding:0;display:flex;align-items:center;justify-content:center}.reset-input-btn mat-icon{font-size:inherit;height:auto;width:auto}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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.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"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i6.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] }); } } __decorate([ Select(UiState.getFilterAccessibility) ], GenericDataHeaderComponent.prototype, "filterAccessibility$", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: GenericDataHeaderComponent, decorators: [{ type: Component, args: [{ selector: 'dm-generic-data-header', template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<div fxLayout=\"row\" class=\"div-gnc-filter\">\n <mat-form-field\n *ngIf=\"filterAccessibility$ | async as filterAccessibility\"\n fxFlex\n color=\"accent\"\n [ngClass]=\"{\n 'gnc-filter-activated':\n advancedSearchMatHint?.nativeElement.offsetHeight <= lineHeight\n }\"\n class=\"gnc-filter\"\n >\n <mat-label>\n <mat-icon aria-hidden=\"true\">filter_list_alt</mat-icon>\n {{ filterAccessibility.label }}\n </mat-label>\n <input\n type=\"text\"\n matInput\n [(ngModel)]=\"search\"\n (ngModelChange)=\"updateSearch($event)\"\n class=\"filter\"\n />\n <button\n *ngIf=\"search\"\n matSuffix\n mat-icon-button\n [attr.aria-label]=\"filterAccessibility.clearSearch\"\n (click)=\"clearInputFilter()\"\n class=\"reset-input-btn\"\n [matTooltip]=\"filterAccessibility.clearSearch\"\n >\n <mat-icon aria-hidden=\"true\"> clear </mat-icon>\n </button>\n </mat-form-field>\n <div\n *ngIf=\"canCreate\"\n class=\"div-add-button\"\n [ngClass]=\"{\n 'div-add-button-with-advanced-search':\n advancedSearchMatHint?.nativeElement.offsetHeight <= lineHeight\n }\"\n >\n <button\n #createLargeBtn\n mat-raised-button\n color=\"accent\"\n (click)=\"addNewResource()\"\n class=\"lg-add-btn\"\n [ngClass]=\"largeBtnAdditionnalClasses\"\n >\n {{ addBtnLabel }}\n </button>\n <button\n #createMiniFabBtn\n mat-mini-fab\n color=\"accent\"\n matTooltipPosition=\"right\"\n [matTooltip]=\"addBtnLabel\"\n (click)=\"addNewResource()\"\n class=\"sm-add-btn\"\n [ngClass]=\"smallBtnAdditionnalClasses\"\n >\n <mat-icon aria-hidden=\"true\">add</mat-icon>\n </button>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.gnc-filter{padding:20px 20px 0}.gnc-filter-activated{padding-top:10px}.div-add-button{margin-top:25px;padding-right:5px}.div-add-button-with-advanced-search{margin-top:15px}.lg-add-btn{width:max-content}button.mdc-fab--mini.sm-add-btn:active:not([class*=mat-elevation-z]){box-shadow:none}.hide-btn{display:none}mat-label{display:flex}.reset-input-btn{height:1.5em;width:1.5em;padding:0;display:flex;align-items:center;justify-content:center}.reset-input-btn mat-icon{font-size:inherit;height:auto;width:auto}\n"] }] }], ctorParameters: () => [{ type: i1.Store }], propDecorators: { filterAccessibility$: [], createLargeBtn: [{ type: ViewChild, args: ['createLargeBtn'] }], createMiniFabBtn: [{ type: ViewChild, args: ['createMiniFabBtn'] }], advancedSearchMatHint: [{ type: Input }], canCreate: [{ type: Input }], addBtnLabel: [{ type: Input }], dataJsTable: [{ type: Input }], selectedResourceRootTypeId: [{ type: Input }], offsetWidth: [{ type: Input }], isLargeScreen: [{ type: Input }], isAdvancedSearchActivated: [{ type: Input }], clickOnAddResourceBtn: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1kYXRhLWhlYWRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9saWJzL2NsaWVudC1jb3JlL3NyYy9saWIvZmVhdHVyZS9nZW5lcmljLWRhdGEtaGVhZGVyL2dlbmVyaWMtZGF0YS1oZWFkZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGlicy9jbGllbnQtY29yZS9zcmMvbGliL2ZlYXR1cmUvZ2VuZXJpYy1kYXRhLWhlYWRlci9nZW5lcmljLWRhdGEtaGVhZGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFFSCxPQUFPLEVBRUwsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsTUFBTSxFQUFTLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBYyxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekUsT0FBTyxFQUNMLElBQUksRUFJSixPQUFPLEdBQ1IsTUFBTSxjQUFjLENBQUM7Ozs7Ozs7Ozs7OztBQU90QixNQUFNLE9BQU8sMEJBQTBCO0lBa0JyQyxJQUFhLHFCQUFxQixDQUFDLHFCQUFpQztRQUNsRSxJQUFJLENBQUMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxxQkFBcUIsQ0FBQztZQUVwRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQzFCLE1BQU0sQ0FDSixnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDO2lCQUN4RCxnQkFBZ0IsQ0FBQyxh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QkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVPLDBCQUEwQjtzQkFBdEMsS0FBSztnQkFhTyxXQUFXO3NCQUF2QixLQUFLO2dCQVdHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUcseUJBQXlCO3NCQUFqQyxLQUFLO2dCQUVJLHFCQUFxQjtzQkFBOUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDIwLTIwMjQgTGluYWdvcmFcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdCB1bmRlclxuICogdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueVxuICogbGF0ZXIgdmVyc2lvbiwgcHJvdmlkZWQgeW91IGNvbXBseSB3aXRoIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgZm9yXG4gKiBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBzb2Z0d2FyZSBieSBMSU5BR09SQSBwdXJzdWFudCB0byBTZWN0aW9uIDcgb2YgdGhlIEdOVVxuICogQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIHN1YnNlY3Rpb25zIChiKSwgKGMpLCBhbmQgKGUpLCBwdXJzdWFudCB0b1xuICogd2hpY2ggdGhlc2UgQXBwcm9wcmlhdGUgTGVnYWwgTm90aWNlcyBtdXN0IG5vdGFibHkgKGkpIHJldGFpbiB0aGUgZGlzcGxheSBvZlxuICogdGhlIFwiTGluSUTihKJcIiB0cmFkZW1hcmsvbG9nbyBhdCB0aGUgdG9wIG9mIHRoZSBpbnRlcmZhY2Ugd2luZG93LCB0aGUgZGlzcGxheVxuICogb2YgdGhlIOKAnFlvdSBhcmUgdXNpbmcgdGhlIE9wZW4gU291cmNlIGFuZCBmcmVlIHZlcnNpb24gb2YgTGluSUTihKIsIHBvd2VyZWQgYnlcbiAqIExpbmFnb3JhIMKpIDIwMDnigJMyMDEzLiBDb250cmlidXRlIHRvIExpbklEIFImRCBieSBzdWJzY3JpYmluZyB0byBhbiBFbnRlcnByaXNlXG4gKiBvZmZlciHigJ0gaW5mb2JveCBhbmQgaW4gdGhlIGUtbWFpbHMgc2VudCB3aXRoIHRoZSBQcm9ncmFtLCBub3RpY2UgYXBwZW5kZWQgdG9cbiAqIGFueSB0eXBlIG9mIG91dGJvdW5kIG1lc3NhZ2VzIChlLmcuIGUtbWFpbCBhbmQgbWVldGluZyByZXF1ZXN0cykgYXMgd2VsbCBhc1xuICogaW4gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHVzZXIgaW50ZXJmYWNlLCAoaWkpIHJldGFpbiBhbGwgaHlwZXJ0ZXh0XG4gKiBsaW5rcyBiZXR3ZWVuIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIGFuZCBodHRwczovL2xpbmlkLm9yZy8sIGFzIHdlbGwgYXNcbiAqIGJldHdlZW4gTElOQUdPUkEgYW5kIExJTkFHT1JBLmNvbSwgYW5kIChpaWkpIHJlZnJhaW4gZnJvbSBpbmZyaW5naW5nIExJTkFHT1JBXG4gKiBpbnRlbGxlY3R1YWwgcHJvcGVydHkgcmlnaHRzIG92ZXIgaXRzIHRyYWRlbWFya3MgYW5kIGNvbW1lcmNpYWwgYnJhbmRzLiBPdGhlclxuICogQWRkaXRpb25hbCBUZXJtcyBhcHBseSwgc2VlIDxodHRwOi8vd3d3LmxpbmFnb3JhLmNvbS9saWNlbnNlcy8+IGZvciBtb3JlXG4gKiBkZXRhaWxzLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVFxuICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1NcbiAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmVcbiAqIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFuZFxuICogaXRzIGFwcGxpY2FibGUgQWRkaXRpb25hbCBUZXJtcyBmb3IgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYWxvbmcgd2l0aCB0aGlzXG4gKiBwcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4gZm9yIHRoZSBHTlUgQWZmZXJvXG4gKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMyBhbmQgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yXG4gKiB0aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIHRvIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBzb2Z0d2FyZS5cbiAqL1xuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgU2VsZWN0LCBTdG9yZSB9IGZyb20gJ0BuZ3hzL3N0b3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIGRlYm91bmNlVGltZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIERhdGEsXG4gIElGaWx0ZXJBY2Nlc3NpYmlsaXR5LFxuICBJUGVyc2lzdGVudFVpRGF0YSxcbiAgSnNUYWJsZSxcbiAgVWlTdGF0ZSxcbn0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZG0tZ2VuZXJpYy1kYXRhLWhlYWRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9nZW5lcmljLWRhdGEtaGVhZGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZ2VuZXJpYy1kYXRhLWhlYWRlci5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBHZW5lcmljRGF0YUhlYWRlckNvbXBvbmVudFxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0XG57XG4gIEBTZWxlY3QoVWlTdGF0ZS5nZXRGaWx0ZXJBY2Nlc3NpYmlsaXR5KVxuICBmaWx0ZXJBY2Nlc3NpYmlsaXR5JDogT2JzZXJ2YWJsZTxJRmlsdGVyQWNjZXNzaWJpbGl0eT47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfQ09NUE9ORU5UX01JTl9XSURUSCA9IDI5MDtcbiAgcHJpdmF0ZSBfbGFyZ2VIZWFkZXJXaWR0aDogbnVtYmVyO1xuICBwdWJsaWMgbGFyZ2VCdG5BZGRpdGlvbm5hbENsYXNzZXM6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge1xuICAgICdoaWRlLWJ0bic6IGZhbHNlLFxuICB9O1xuICBwdWJsaWMgc21hbGxCdG5BZGRpdGlvbm5hbENsYXNzZXM6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge1xuICAgICdoaWRlLWJ0bic6IGZhbHNlLFxuICB9O1xuXG4gIEBWaWV3Q2hpbGQoJ2NyZWF0ZUxhcmdlQnRuJykgY3JlYXRlTGFyZ2VCdG46IE1hdEJ1dHRvbjtcbiAgQFZpZXdDaGlsZCgnY3JlYXRlTWluaUZhYkJ0bicpIGNyZWF0ZU1pbmlGYWJCdG46IE1hdEJ1dHRvbjtcblxuICBASW5wdXQoKSBzZXQgYWR2YW5jZWRTZWFyY2hNYXRIaW50KGFkdmFuY2VkU2VhcmNoTWF0SGludDogRWxlbWVudFJlZikge1xuICAgIGlmICghIWFkdmFuY2VkU2VhcmNoTWF0SGludCkge1xuICAgICAgdGhpcy5fYWR2YW5jZWRTZWFyY2hNYXRIaW50ID0gYWR2YW5jZWRTZWFyY2hNYXRIaW50O1xuXG4gICAgICB0aGlzLmxpbmVIZWlnaHQgPSBNYXRoLnJvdW5kKFxuICAgICAgICBOdW1iZXIoXG4gICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9hZHZhbmNlZFNlYXJjaE1hdEhpbnQubmF0aXZlRWxlbWVudClcbiAgICAgICAgICAgIC5nZXRQcm9wZXJ0eVZhbHVlKCdsaW5lLWhlaWdodCcpXG4gICAgICAgICAgICAucmVwbGFjZSgncHgnLCAnJylcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBnZXQgYWR2YW5jZWRTZWFyY2hNYXRIaW50KCk6IEVsZW1lbnRSZWYge1xuICAgIHJldHVybiB0aGlzLl9hZHZhbmNlZFNlYXJjaE1hdEhpbnQ7XG4gIH1cblxuICBASW5wdXQoKSBjYW5DcmVhdGU6IGJvb2xlYW47XG5cbiAgQElucHV0KCkgYWRkQnRuTGFiZWw6IHN0cmluZztcblxuICBASW5wdXQoKSBkYXRhSnNUYWJsZTogSnNUYWJsZTxJUGVyc2lzdGVudFVpRGF0YT47XG5cbiAgQElucHV0KCkgc2V0IHNlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkKHNlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sYXJnZUhlYWRlcldpZHRoID0gbnVsbDtcbiAgICB0aGlzLmxhcmdlQnRuQWRkaXRpb25uYWxDbGFzc2VzID0geyAnaGlkZS1idG4nOiBmYWxzZSB9O1xuICAgIHRoaXMuc21hbGxCdG5BZGRpdGlvbm5hbENsYXNzZXMgPSB7ICdoaWRlLWJ0bic6IGZhbHNlIH07XG4gICAgdGhpcy5fc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQgPSBzZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZDtcbiAgICB0aGlzLnNlYXJjaCA9XG4gICAgICB0aGlzLmRhdGFKc1RhYmxlLmJ5SWRbdGhpcy5zZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZF0/LmZpbHRlclZhbHVlO1xuICB9XG5cbiAgZ2V0IHNlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkO1xuICB9XG5cbiAgQElucHV0KCkgc2V0IG9mZnNldFdpZHRoKG9mZnNldFdpZHRoOiBudW1iZXIpIHtcbiAgICBpZiAoISFvZmZzZXRXaWR0aCkge1xuICAgICAgdGhpcy5fb2Zmc2V0V2lkdGggPSBvZmZzZXRXaWR0aDtcbiAgICAgIHRoaXMuX3VwZGF0ZUJ1dHRvbkRpc3BsYXkoKTtcbiAgICB9XG4gIH1cblxuICBnZXQgb2Zmc2V0V2lkdGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fb2Zmc2V0V2lkdGg7XG4gIH1cblxuICBASW5wdXQoKSBpc0xhcmdlU2NyZWVuOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIGlzQWR2YW5jZWRTZWFyY2hBY3RpdmF0ZWQ6IGJvb2xlYW47XG5cbiAgQE91dHB1dCgpIGNsaWNrT25BZGRSZXNvdXJjZUJ0biA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcml2YXRlIF9vbkRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIF9hZHZhbmNlZFNlYXJjaE1hdEhpbnQ6IEVsZW1lbnRSZWY7XG5cbiAgcHJpdmF0ZSBfb2Zmc2V0V2lkdGg6IG51bWJlcjtcblxuICBwcml2YXRlIF9zZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZDogc3RyaW5nO1xuXG4gIHB1YmxpYyBkaXZBZGRCdXR0b25NYXhXaWR0aDogbnVtYmVyO1xuXG4gIHB1YmxpYyBzZWFyY2ggPSAnJztcblxuICBwdWJsaWMgbW9kZWxDaGFuZ2VkID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuXG4gIHB1YmxpYyBsaW5lSGVpZ2h0OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfc3RvcmUkOiBTdG9yZSkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm1vZGVsQ2hhbmdlZFxuICAgICAgLnBpcGUoXG4gICAgICAgIGRlYm91bmNlVGltZSgzMDApLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95JCksXG4gICAgICAgIHRhcCgoY3VycmVudFNlYXJjaCkgPT4ge1xuICAgICAgICAgIHRoaXMuX3N0b3JlJC5kaXNwYXRjaChcbiAgICAgICAgICAgIG5ldyBEYXRhLlNldEZpbHRlclZhbHVlKHtcbiAgICAgICAgICAgICAgZmlsdGVyVmFsdWU6IGN1cnJlbnRTZWFyY2gsXG4gICAgICAgICAgICAgIGRhdGFUeXBlSWQ6IHRoaXMuc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgbGV0IGxhcmdlQnRuV2lkdGggPSAwO1xuICAgIGxldCBzbWFsbEJ0bldpZHRoID0gMDtcbiAgICBpZiAodGhpcy5jYW5DcmVhdGUpIHtcbiAgICAgIGxhcmdlQnRuV2lkdGggPSB0aGlzLmNyZWF0ZUxhcmdlQnRuLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgICBzbWFsbEJ0bldpZHRoID1cbiAgICAgICAgdGhpcy5jcmVhdGVNaW5pRmFiQnRuLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgfVxuICAgIGxldCBmaWx0ZXJNaW5XaWR0aCA9IHRoaXMuX0NPTVBPTkVOVF9NSU5fV0lEVEggLSBzbWFsbEJ0bldpZHRoO1xuICAgIHRoaXMuX2xhcmdlSGVhZGVyV2lkdGggPSBmaWx0ZXJNaW5XaWR0aCArIGxhcmdlQnRuV2lkdGg7XG4gICAgdGhpcy5fdXBkYXRlQnV0dG9uRGlzcGxheSgpO1xuICB9XG5cbiAgY2xlYXJJbnB1dEZpbHRlcigpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMubW9kZWxDaGFuZ2VkLm5leHQoJycpO1xuICB9XG5cbiAgdXBkYXRlU2VhcmNoKHNlYXJjaDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlbENoYW5nZWQubmV4dChzZWFyY2gpO1xuICB9XG5cbiAgYWRkTmV3UmVzb3VyY2UoKTogdm9pZCB7XG4gICAgdGhpcy5jbGlja09uQWRkUmVzb3VyY2VCdG4uZW1pdCgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fb25EZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5fb25EZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlQnV0dG9uRGlzcGxheSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fbGFyZ2VIZWFkZXJXaWR0aCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBkaXNwbGF5TGFyZ2VCdG4gPSB0aGlzLl9sYXJnZUhlYWRlcldpZHRoIDw9IHRoaXMub2Zmc2V0V2lkdGg7XG4gICAgICB0aGlzLmxhcmdlQnRuQWRkaXRpb25uYWxDbGFzc2VzID0geyAnaGlkZS1idG4nOiAhZGlzcGxheUxhcmdlQnRuIH07XG4gICAgICB0aGlzLnNtYWxsQnRuQWRkaXRpb25uYWxDbGFzc2VzID0geyAnaGlkZS1idG4nOiBkaXNwbGF5TGFyZ2VCdG4gfTtcbiAgICB9XG4gIH1cbn1cbiIsIjwhLS0gQ29weXJpZ2h0IChDKSAyMDIwLTIwMjQgTGluYWdvcmFcblxuVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXJcbnRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZVxuU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnlcbmxhdGVyIHZlcnNpb24sIHByb3ZpZGVkIHlvdSBjb21wbHkgd2l0aCB0aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIGZvclxuTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgc29mdHdhcmUgYnkgTElOQUdPUkEgcHVyc3VhbnQgdG8gU2VjdGlvbiA3IG9mIHRoZSBHTlVcbkFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBzdWJzZWN0aW9ucyAoYiksIChjKSwgYW5kIChlKSwgcHVyc3VhbnQgdG9cbndoaWNoIHRoZXNlIEFwcHJvcHJpYXRlIExlZ2FsIE5vdGljZXMgbXVzdCBub3RhYmx5IChpKSByZXRhaW4gdGhlIGRpc3BsYXkgb2ZcbnRoZSBcIkxpbklE4oSiXCIgdHJhZGVtYXJrL2xvZ28gYXQgdGhlIHRvcCBvZiB0aGUgaW50ZXJmYWNlIHdpbmRvdywgdGhlIGRpc3BsYXlcbm9mIHRoZSDigJxZb3UgYXJlIHVzaW5nIHRoZSBPcGVuIFNvdXJjZSBhbmQgZnJlZSB2ZXJzaW9uIG9mIExpbklE4oSiLCBwb3dlcmVkIGJ5XG5MaW5hZ29yYSDCqSAyMDA54oCTMjAxMy4gQ29udHJpYnV0ZSB0byBMaW5JRCBSJkQgYnkgc3Vic2NyaWJpbmcgdG8gYW4gRW50ZXJwcmlzZVxub2ZmZXIh4oCdIGluZm9ib3ggYW5kIGluIHRoZSBlLW1haWxzIHNlbnQgd2l0aCB0aGUgUHJvZ3JhbSwgbm90aWNlIGFwcGVuZGVkIHRvXG5hbnkgdHlwZSBvZiBvdXRib3VuZCBtZXNzYWdlcyAoZS5nLiBlLW1haWwgYW5kIG1lZXRpbmcgcmVxdWVzdHMpIGFzIHdlbGwgYXNcbmluIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciB1c2VyIGludGVyZmFjZSwgKGlpKSByZXRhaW4gYWxsIGh5cGVydGV4dFxubGlua3MgYmV0d2VlbiBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbmQgaHR0cHM6Ly9saW5pZC5vcmcvLCBhcyB3ZWxsIGFzXG5iZXR3ZWVuIExJTkFHT1JBIGFuZCBMSU5BR09SQS5jb20sIGFuZCAoaWlpKSByZWZyYWluIGZyb20gaW5mcmluZ2luZyBMSU5BR09SQVxuaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvdmVyIGl0cyB0cmFkZW1hcmtzIGFuZCBjb21tZXJjaWFsIGJyYW5kcy4gT3RoZXJcbkFkZGl0aW9uYWwgVGVybXMgYXBwbHksIHNlZSA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3IgbW9yZVxuZGV0YWlscy5cblxuVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG5BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuZGV0YWlscy5cblxuWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFuZFxuaXRzIGFwcGxpY2FibGUgQWRkaXRpb25hbCBUZXJtcyBmb3IgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYWxvbmcgd2l0aCB0aGlzXG5wcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4gZm9yIHRoZSBHTlUgQWZmZXJvXG5HZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMyBhbmQgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yXG50aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIHRvIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBzb2Z0d2FyZS4gLS0+XG5cbjxkaXYgZnhMYXlvdXQ9XCJyb3dcIiBjbGFzcz1cImRpdi1nbmMtZmlsdGVyXCI+XG4gIDxtYXQtZm9ybS1maWVsZFxuICAgICpuZ0lmPVwiZmlsdGVyQWNjZXNzaWJpbGl0eSQgfCBhc3luYyBhcyBmaWx0ZXJBY2Nlc3NpYmlsaXR5XCJcbiAgICBmeEZsZXhcbiAgICBjb2xvcj1cImFjY2VudFwiXG4gICAgW25nQ2xhc3NdPVwie1xuICAgICAgJ2duYy1maWx0ZXItYWN0aXZhdGVkJzpcbiAgICAgICAgYWR2YW5jZWRTZWFyY2hNYXRIaW50Py5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodCA8PSBsaW5lSGVpZ2h0XG4gICAgfVwiXG4gICAgY2xhc3M9XCJnbmMtZmlsdGVyXCJcbiAgPlxuICAgIDxtYXQtbGFiZWw+XG4gICAgICA8bWF0LWljb24gYXJpYS1oaWRkZW49XCJ0cnVlXCI+ZmlsdGVyX2xpc3RfYWx0PC9tYXQtaWNvbj5cbiAgICAgIHt7IGZpbHRlckFjY2Vzc2liaWxpdHkubGFiZWwgfX1cbiAgICA8L21hdC1sYWJlbD5cbiAgICA8aW5wdXRcbiAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgIG1hdElucHV0XG4gICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFwiXG4gICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTZWFyY2goJGV2ZW50KVwiXG4gICAgICBjbGFzcz1cImZpbHRlclwiXG4gICAgLz5cbiAgICA8YnV0dG9uXG4gICAgICAqbmdJZj1cInNlYXJjaFwiXG4gICAgICBtYXRTdWZmaXhcbiAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJmaWx0ZXJBY2Nlc3NpYmlsaXR5LmNsZWFyU2VhcmNoXCJcbiAgICAgIChjbGljayk9XCJjbGVhcklucHV0RmlsdGVyKClcIlxuICAgICAgY2xhc3M9XCJyZXNldC1pbnB1dC1idG5cIlxuICAgICAgW21hdFRvb2x0aXBdPVwiZmlsdGVyQWNjZXNzaWJpbGl0eS5jbGVhclNlYXJjaFwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiBjbGVhciA8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuICA8L21hdC1mb3JtLWZpZWxkPlxuICA8ZGl2XG4gICAgKm5nSWY9XCJjYW5DcmVhdGVcIlxuICAgIGNsYXNzPVwiZGl2LWFkZC1idXR0b25cIlxuICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICdkaXYtYWRkLWJ1dHRvbi13aXRoLWFkdmFuY2VkLXNlYXJjaCc6XG4gICAgICAgIGFkdmFuY2VkU2VhcmNoTWF0SGludD8ubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgPD0gbGluZUhlaWdodFxuICAgIH1cIlxuICA+XG4gICAgPGJ1dHRvblxuICAgICAgI2NyZWF0ZUxhcmdlQnRuXG4gICAgICBtYXQtcmFpc2VkLWJ1dHRvblxuICAgICAgY29sb3I9XCJhY2NlbnRcIlxuICAgICAgKGNsaWNrKT1cImFkZE5ld1Jlc291cmNlKClcIlxuICAgICAgY2xhc3M9XCJsZy1hZGQtYnRuXCJcbiAgICAgIFtuZ0NsYXNzXT1cImxhcmdlQnRuQWRkaXRpb25uYWxDbGFzc2VzXCJcbiAgICA+XG4gICAgICB7eyBhZGRCdG5MYWJlbCB9fVxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b25cbiAgICAgICNjcmVhdGVNaW5pRmFiQnRuXG4gICAgICBtYXQtbWluaS1mYWJcbiAgICAgIGNvbG9yPVwiYWNjZW50XCJcbiAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cInJpZ2h0XCJcbiAgICAgIFttYXRUb29sdGlwXT1cImFkZEJ0bkxhYmVsXCJcbiAgICAgIChjbGljayk9XCJhZGROZXdSZXNvdXJjZSgpXCJcbiAgICAgIGNsYXNzPVwic20tYWRkLWJ0blwiXG4gICAgICBbbmdDbGFzc109XCJzbWFsbEJ0bkFkZGl0aW9ubmFsQ2xhc3Nlc1wiXG4gICAgPlxuICAgICAgPG1hdC1pY29uIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPmFkZDwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=