@sumaris-net/ngx-components 2.7.3-rc71 → 2.7.3-rc72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -314,11 +314,11 @@ export class SettingsPage extends AppForm {
314
314
  this.cd.markForCheck();
315
315
  }
316
316
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.3", ngImport: i0, type: SettingsPage, deps: [{ token: i0.Injector }, { token: i1.PlatformService }, { token: i2.NavController }, { token: i3.LocalSettingsValidatorService }, { token: i2.AlertController }, { token: i4.TranslateService }, { token: i5.UntypedFormBuilder }, { token: i6.AccountService }, { token: i7.LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: i8.NetworkService }, { token: APP_LOCALES }, { token: APP_SETTINGS_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
317
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.3", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n @if(settings.enableDarkMode) {\n <ion-button (click)=\"toggleDarkMode()\" [title]=\"'SETTINGS.BTN_DARK_MODE' | translate\">\n <ion-icon slot=\"icon-only\" [name]=\"darkMode ? 'sunny' : 'moon'\"></ion-icon>\n </ion-button>\n }\n\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\" [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"!dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngFor=\"let item of menuItems\">\n <a\n *ngIf=\"item.path\"\n mat-menu-item\n class=\"{{ item.cssClass }} {{ item.color }}\"\n (click)=\"executeAction($event, item)\"\n >\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n <!-- divider -->\n <mat-divider *ngIf=\"!item.path && !item.action\" class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n </ng-container>\n </ng-container>\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header translate>SETTINGS.DESCRIPTION</ion-list-header>\n<!-- <p [innerHTML]=\"'SETTINGS.DESCRIPTION' | translate\"></p>-->\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if(!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n >\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n\n <ion-item lines=\"none\">\n <!-- locale -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if(mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select formControlName=\"key\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\"\n ></app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removePropertyAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i11.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: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i15.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i15.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i15.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i16.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i17.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i18.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i19.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i20.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i21.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "appearance", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"], outputs: ["keyup.enter"] }, { kind: "component", type: i22.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: i23.FormGetControlPipe, name: "formGetControl" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.2.3", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n @if(settings.enableDarkMode) {\n <ion-button (click)=\"toggleDarkMode()\" [title]=\"'SETTINGS.BTN_DARK_MODE' | translate\">\n <ion-icon slot=\"icon-only\" [name]=\"darkMode ? 'sunny' : 'moon'\"></ion-icon>\n </ion-button>\n }\n\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item\n class=\"{{ item.cssClass }} {{ item.color }}\"\n (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if(!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if(!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n >\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n\n <ion-item lines=\"none\">\n <!-- locale -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if(mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select formControlName=\"key\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\"\n ></app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removePropertyAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i9.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i5.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i11.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: "component", type: i12.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i15.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i15.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i15.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i16.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i17.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i18.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i19.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i20.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i21.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "appearance", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug"], outputs: ["keyup.enter"] }, { kind: "component", type: i22.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }, { kind: "pipe", type: i23.FormGetControlPipe, name: "formGetControl" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
318
318
  }
319
319
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.3", ngImport: i0, type: SettingsPage, decorators: [{
320
320
  type: Component,
321
- args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n @if(settings.enableDarkMode) {\n <ion-button (click)=\"toggleDarkMode()\" [title]=\"'SETTINGS.BTN_DARK_MODE' | translate\">\n <ion-icon slot=\"icon-only\" [name]=\"darkMode ? 'sunny' : 'moon'\"></ion-icon>\n </ion-button>\n }\n\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\" [disabled]=\"saving\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"!dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n <ng-container *ngIf=\"!loading\">\n <ng-container *ngFor=\"let item of menuItems\">\n <a\n *ngIf=\"item.path\"\n mat-menu-item\n class=\"{{ item.cssClass }} {{ item.color }}\"\n (click)=\"executeAction($event, item)\"\n >\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n <!-- divider -->\n <mat-divider *ngIf=\"!item.path && !item.action\" class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n </ng-container>\n </ng-container>\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header translate>SETTINGS.DESCRIPTION</ion-list-header>\n<!-- <p [innerHTML]=\"'SETTINGS.DESCRIPTION' | translate\"></p>-->\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if(!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n >\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n\n <ion-item lines=\"none\">\n <!-- locale -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if(mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select formControlName=\"key\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\"\n ></app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removePropertyAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
321
+ args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n @if(settings.enableDarkMode) {\n <ion-button (click)=\"toggleDarkMode()\" [title]=\"'SETTINGS.BTN_DARK_MODE' | translate\">\n <ion-icon slot=\"icon-only\" [name]=\"darkMode ? 'sunny' : 'moon'\"></ion-icon>\n </ion-button>\n }\n\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item\n class=\"{{ item.cssClass }} {{ item.color }}\"\n (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if(!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row class=\"ion-no-padding\">\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if(!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n >\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n\n <ion-item lines=\"none\">\n <!-- locale -->\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if(mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <ion-grid formArrayName=\"properties\" class=\"ion-padding\">\n <ion-row class=\"ion-no-padding\">\n <ion-col class=\"ion-no-padding ion-align-self-end\" size=\"12\">\n <span class=\"toolbar-spacer\"></span>\n\n <!-- Show more options -->\n <ion-button\n color=\"light\"\n *ngIf=\"propertiesForm?.length === 0\"\n [title]=\"'SETTINGS.BTN_SHOW_MORE_HELP' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n <mat-icon slot=\"end\">arrow_drop_down</mat-icon>\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- Fields options -->\n <ng-container *ngFor=\"let propertyForm of propertiesForm?.controls; let i = index\">\n <ion-row class=\"ion-no-padding\" [formGroupName]=\"i\">\n <!-- property key -->\n <ion-col class=\"ion-no-padding\">\n <mat-form-field>\n <mat-label>{{ 'SETTINGS.PROPERTY_KEY' | translate }}</mat-label>\n <mat-select formControlName=\"key\">\n <mat-option *ngFor=\"let item of propertyDefinitions\" [value]=\"item.key\">\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </ion-col>\n\n <!-- property value -->\n <ion-col class=\"ion-no-padding\" padding-left>\n <app-form-field\n *ngIf=\"getPropertyDefinition(i); let definition\"\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"propertyForm | formGetControl: 'value'\"\n [placeholder]=\"'SETTINGS.PROPERTY_VALUE' | translate\"\n [required]=\"true\"\n ></app-form-field>\n </ion-col>\n <ion-col size=\"2\" class=\"ion-no-padding\">\n <button\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"removePropertyAt(i)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n <button\n *ngIf=\"propertiesFormHelper.isLast(i)\"\n type=\"button\"\n mat-icon-button\n color=\"light\"\n [disabled]=\"loading\"\n [title]=\"'SETTINGS.BTN_ADD_PROPERTY' | translate\"\n (click)=\"propertiesFormHelper.add()\"\n >\n <mat-icon>add</mat-icon>\n </button>\n </ion-col>\n </ion-row>\n </ng-container>\n </ion-grid>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
322
322
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.PlatformService }, { type: i2.NavController }, { type: i3.LocalSettingsValidatorService }, { type: i2.AlertController }, { type: i4.TranslateService }, { type: i5.UntypedFormBuilder }, { type: i6.AccountService }, { type: i7.LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: i8.NetworkService }, { type: undefined, decorators: [{
323
323
  type: Inject,
324
324
  args: [APP_LOCALES]
@@ -328,4 +328,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.3", ngImpor
328
328
  type: Inject,
329
329
  args: [APP_SETTINGS_MENU_ITEMS]
330
330
  }] }] });
331
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MucGFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9zZXR0aW5ncy9zZXR0aW5ncy5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL3NldHRpbmdzL3NldHRpbmdzLnBhZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQXFCLFNBQVMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUErQixRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFckosT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQTBDLE1BQU0sa0NBQWtDLENBQUM7QUFDdkcsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRXBELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBRy9GLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTTdDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLElBQUksY0FBYyxDQUFjLG1CQUFtQixDQUFDLENBQUM7QUFRNUYsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFzQjtJQWlDMUM7SUFDQTtJQUNBO0lBQ0E7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LGNBQWM7UUFDNUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFUyxZQUFZO1FBQ3BCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekIsQ0FBQzt1R0EzVVUsWUFBWSxxWEEyQ2IsV0FBVyxhQUNDLHVCQUF1QjsyRkE1Q2xDLFlBQVksd0NBSFosQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsNkJBQTZCLEVBQUUsQ0FBQyxpREM3QnhGLDJyWUF5U0E7OzJGRHpRYSxZQUFZO2tCQU54QixTQUFTOytCQUNFLGVBQWUsYUFFZCxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSw2QkFBNkIsRUFBRSxDQUFDLG1CQUNyRSx1QkFBdUIsQ0FBQyxNQUFNOzswQkE2QzVDLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjY291bnRTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7IEVudGl0eVV0aWxzIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvZW50aXR5Lm1vZGVsJztcbmltcG9ydCB7IEFQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MsIFVzYWdlTW9kZSB9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL3NldHRpbmdzLm1vZGVsJztcbmltcG9ydCB7IFBlZXIgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9wZWVyLm1vZGVsJztcbmltcG9ydCB7IFVudHlwZWRGb3JtQXJyYXksIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Db250cm9sLCBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQXBwRm9ybSB9IGZyb20gJy4uL2Zvcm0vZm9ybS5jbGFzcyc7XG5pbXBvcnQgeyBBcHBGb3JtVXRpbHMsIEZvcm1BcnJheUhlbHBlciB9IGZyb20gJy4uL2Zvcm0vZm9ybS51dGlscyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnQGUtaXMvbmd4LW1hdGVyaWFsLXRhYmxlJztcbmltcG9ydCB7IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL2xvY2FsLXNldHRpbmdzLnZhbGlkYXRvcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9wbGF0Zm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IE5ldHdvcmtTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvbmV0d29yay5zZXJ2aWNlJztcbmltcG9ydCB7IGlzTmlsLCBpc05pbE9yQmxhbmssIHRvQm9vbGVhbiB9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgTG9jYWxTZXR0aW5nc1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9sb2NhbC1zZXR0aW5ncy5zZXJ2aWNlJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24sIEZvcm1GaWVsZERlZmluaXRpb25NYXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBtZXJnZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQWxlcnRDb250cm9sbGVyLCBOYXZDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgQWxlcnRzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FsZXJ0cyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBDYW5MZWF2ZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9ndWFyZC9jb21wb25lbnQtZGlydHkuZ3VhcmQnO1xuaW1wb3J0IHsgSVNlbGVjdFBlZXJNb2RhbE9wdGlvbnMgfSBmcm9tICcuLi9wZWVyL3NlbGVjdC1wZWVyLm1vZGFsJztcbmltcG9ydCB7IElNZW51SXRlbSB9IGZyb20gJy4uL21lbnUvbWVudS5tb2RlbCc7XG5cbmV4cG9ydCBjb25zdCBBUFBfU0VUVElOR1NfTUVOVV9JVEVNUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxJTWVudUl0ZW1bXT4oJ3NldHRpbmdzTWVudUl0ZW1zJyk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3BhZ2Utc2V0dGluZ3MnLFxuICB0ZW1wbGF0ZVVybDogJ3NldHRpbmdzLnBhZ2UuaHRtbCcsXG4gIHByb3ZpZGVyczogW3sgcHJvdmlkZTogVmFsaWRhdG9yU2VydmljZSwgdXNlRXhpc3Rpbmc6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlIH1dLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2V0dGluZ3NQYWdlIGV4dGVuZHMgQXBwRm9ybTxMb2NhbFNldHRpbmdzPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDYW5MZWF2ZSB7XG4gIHByaXZhdGUgZGF0YTogTG9jYWxTZXR0aW5ncztcblxuICBtb2JpbGU6IGJvb2xlYW47XG4gIHNhdmluZyA9IGZhbHNlO1xuICB1c2FnZU1vZGVzOiBVc2FnZU1vZGVbXSA9IFsnRklFTEQnLCAnREVTSyddO1xuICBtZW51SXRlbXM6IElNZW51SXRlbVtdO1xuXG4gIHByb3BlcnR5RGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcbiAgcHJvcGVydHlEZWZpbml0aW9uc0J5S2V5OiBGb3JtRmllbGREZWZpbml0aW9uTWFwID0ge307XG4gIHByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4OiB7IFtpbmRleDogbnVtYmVyXTogRm9ybUZpZWxkRGVmaW5pdGlvbiB9ID0ge307XG4gIHByb3BlcnRpZXNGb3JtSGVscGVyOiBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+O1xuXG4gIGxhdExvbmdGb3JtYXRzID0gWydERE1NU1MnLCAnRERNTScsICdERCddO1xuXG4gIGdldCBhY2NvdW50SW5oZXJpdGFuY2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybS5jb250cm9sc1snYWNjb3VudEluaGVyaXRhbmNlJ10udmFsdWU7XG4gIH1cblxuICBnZXQgaXNMb2dpbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hY2NvdW50U2VydmljZS5pc0xvZ2luKCk7XG4gIH1cblxuICBnZXQgcHJvcGVydGllc0Zvcm0oKTogVW50eXBlZEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybS5nZXQoJ3Byb3BlcnRpZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5O1xuICB9XG5cbiAgZ2V0IGRhcmtNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmZvcm0uY29udHJvbHNbJ2RhcmtNb2RlJ10udmFsdWU7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJvdGVjdGVkIHBsYXRmb3JtOiBQbGF0Zm9ybVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIG5hdkNvbnRyb2xsZXI6IE5hdkNvbnRyb2xsZXIsXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRvclNlcnZpY2U6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBhbGVydEN0cmw6IEFsZXJ0Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHByb3RlY3RlZCBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHNldHRpbmdzOiBMb2NhbFNldHRpbmdzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBASW5qZWN0KEFQUF9MT0NBTEVTKSBwdWJsaWMgbG9jYWxlczogTG9jYWxlQ29uZmlnW10sXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfU0VUVElOR1NfTUVOVV9JVEVNUykgbWVudUl0ZW1zPzogSU1lbnVJdGVtW11cbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IsIHZhbGlkYXRvclNlcnZpY2UuZ2V0Rm9ybUdyb3VwKCkpO1xuXG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlciA9IG5ldyBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+KFxuICAgICAgdGhpcy5mb3JtLmdldCgncHJvcGVydGllcycpIGFzIFVudHlwZWRGb3JtQXJyYXksXG4gICAgICAodmFsdWUpID0+IHRoaXMudmFsaWRhdG9yU2VydmljZS5nZXRQcm9wZXJ0eUZvcm1Hcm91cCh2YWx1ZSksXG4gICAgICAodjEsIHYyKSA9PiAoIXYxICYmICF2MikgfHwgdjEua2V5ID09PSB2Mi5rZXksXG4gICAgICAodmFsdWUpID0+IGlzTmlsKHZhbHVlKSB8fCAoaXNOaWwodmFsdWUua2V5KSAmJiBpc05pbCh2YWx1ZS52YWx1ZSkpLFxuICAgICAge1xuICAgICAgICBhbGxvd0VtcHR5QXJyYXk6IHRydWUsXG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMubWVudUl0ZW1zID0gbWVudUl0ZW1zIHx8IFtdO1xuICAgIHRoaXMubW9iaWxlID0gdGhpcy5wbGF0Zm9ybS5tb2JpbGU7XG5cbiAgICAvLyBCeSBkZWZhdWx0LCBkaXNhYmxlIHRoZSBmb3JtXG4gICAgdGhpcy5fZW5hYmxlID0gZmFsc2U7XG4gIH1cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHBsYXRmb3JtIGlzIHJlYWR5XG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5yZWFkeSgpO1xuXG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zID0gdGhpcy5zZXR0aW5ncy5vcHRpb25EZWZzLnNsaWNlKCk7IC8vIGNvcHkgb3B0aW9uc1xuICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9ucy5mb3JFYWNoKChvKSA9PiAodGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlbby5rZXldID0gbykpOyAvLyBmaWxsIG1hcFxuXG4gICAgLy8gTG9hZCBzZXR0aW5nc1xuICAgIGF3YWl0IHRoaXMubG9hZCgpO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIG1lcmdlKHRoaXMuYWNjb3VudFNlcnZpY2Uub25Mb2dpbiwgdGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ291dCkuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKHRoaXMuYWNjb3VudEluaGVyaXRhbmNlKSlcbiAgICApO1xuICB9XG5cbiAgZ2V0UHJvcGVydHlEZWZpbml0aW9uKGluZGV4OiBudW1iZXIpOiBGb3JtRmllbGREZWZpbml0aW9uIHtcbiAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdO1xuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgZGVmaW5pdGlvbiA9IHRoaXMudXBkYXRlUHJvcGVydHlEZWZpbml0aW9uKGluZGV4KTtcbiAgICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdID0gZGVmaW5pdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmluaXRpb247XG4gIH1cblxuICB1cGRhdGVQcm9wZXJ0eURlZmluaXRpb24oaW5kZXg6IG51bWJlcik6IEZvcm1GaWVsZERlZmluaXRpb24ge1xuICAgIGNvbnN0IGtleSA9ICh0aGlzLnByb3BlcnRpZXNGb3JtLmF0KGluZGV4KSBhcyBVbnR5cGVkRm9ybUdyb3VwKS5jb250cm9scy5rZXkudmFsdWU7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IChrZXkgJiYgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlba2V5XSkgfHwgbnVsbDtcbiAgICB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4W2luZGV4XSA9IGRlZmluaXRpb247IC8vIHVwZGF0ZSBtYXAgYnkgaW5kZXhcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgcmVtb3ZlUHJvcGVydHlBdChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlci5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlJbmRleCA9IHt9OyAvLyBjbGVhciBjYWNoZSBieSBpbmRleFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBhc3luYyBsb2FkKCkge1xuICAgIHRoaXMubWFya0FzTG9hZGluZygpO1xuICAgIGNvbnNvbGUuZGVidWcoJ1tzZXR0aW5nc10gTG9hZGluZyBzZXR0aW5ncy4uLicpO1xuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc2V0dGluZ3Muc2V0dGluZ3M7XG5cbiAgICAvLyBTZXQgZGVmYXVsdHNcbiAgICBkYXRhLmFjY291bnRJbmhlcml0YW5jZSA9IHRvQm9vbGVhbihkYXRhLmFjY291bnRJbmhlcml0YW5jZSwgdHJ1ZSk7XG4gICAgZGF0YS5sb2NhbGUgPSBkYXRhLmxvY2FsZSB8fCB0aGlzLnRyYW5zbGF0ZS5jdXJyZW50TGFuZyB8fCB0aGlzLnRyYW5zbGF0ZS5kZWZhdWx0TGFuZztcbiAgICBkYXRhLmxhdExvbmdGb3JtYXQgPSBkYXRhLmxhdExvbmdGb3JtYXQgfHwgJ0RETU1TUyc7XG4gICAgZGF0YS51c2FnZU1vZGUgPSBkYXRhLnVzYWdlTW9kZSB8fCAnREVTSyc7XG5cbiAgICAvLyBTZXQgcGVlclxuICAgIGlmIChpc05pbE9yQmxhbmsoZGF0YS5wZWVyVXJsKSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLnJlYWR5KCk7XG4gICAgICBjb25zdCBwZWVyID0gdGhpcy5uZXR3b3JrLnBlZXI7XG4gICAgICBkYXRhLnBlZXJVcmwgPSBwZWVyICYmIHBlZXIudXJsO1xuICAgIH1cblxuICAgIC8vIFJlbWVtYmVyIGRhdGFcbiAgICB0aGlzLnVwZGF0ZVZpZXcoZGF0YSk7XG4gIH1cblxuICB1cGRhdGVWaWV3KGRhdGE6IExvY2FsU2V0dGluZ3MpIHtcbiAgICBpZiAoIWRhdGEpIHJldHVybjsgLy9za2lwXG4gICAgdGhpcy5kYXRhID0gZGF0YTtcblxuICAgIGNvbnN0IGpzb246IGFueSA9IHsgLi4uZGF0YSB9O1xuXG4gICAgLy8gVHJhbnNmb3JtIHByb3BlcnRpZXMgbWFwIGludG8gYXJyYXlcbiAgICBqc29uLnByb3BlcnRpZXMgPSBFbnRpdHlVdGlscy5nZXRNYXBBc0FycmF5KGRhdGEucHJvcGVydGllcyB8fCB7fSk7XG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlci5yZXNpemUoanNvbi5wcm9wZXJ0aWVzLmxlbmd0aCk7XG5cbiAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZShqc29uLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgdGhpcy5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICB0aGlzLnNldEFjY291bnRJbmhlcml0YW5jZShkYXRhLmFjY291bnRJbmhlcml0YW5jZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgYXN5bmMgc2F2ZShldmVudD86IEV2ZW50LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuc2F2aW5nKSByZXR1cm47IC8vIFNraXBcblxuICAgIGlmIChldmVudCkgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIFJlbW92ZSBhbGwgZW1wdHkgY29udHJvbHNcbiAgICB0aGlzLnByb3BlcnRpZXNGb3JtSGVscGVyLnJlbW92ZUFsbEVtcHR5KCk7XG5cbiAgICBpZiAoIXRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgYXdhaXQgQXBwRm9ybVV0aWxzLndhaXRXaGlsZVBlbmRpbmcodGhpcy5mb3JtKTtcblxuICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkKSB7XG4gICAgICAgIEFwcEZvcm1VdGlscy5sb2dGb3JtRXJyb3JzKHRoaXMuZm9ybSk7XG4gICAgICAgIHRoaXMuZm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmRlYnVnKCdbc2V0dGluZ3NdIFNhdmluZyBsb2NhbCBzZXR0aW5ncy4uLicpO1xuXG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdldFZhbHVlKCk7XG5cbiAgICAvLyBDaGVjayBwZWVyIGFsaXZlLCBiZWZvcmUgc2F2aW5nXG4gICAgY29uc3QgcGVlckNoYW5nZWQgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykuZGlydHk7XG5cbiAgICAvLyBDbGVhbiBwYWdlIGhpc3RvcnksIHdoZW4gcGVlciBjaGFuZ2VkXG4gICAgaWYgKHBlZXJDaGFuZ2VkKSBkYXRhLnBhZ2VIaXN0b3J5ID0gW107XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuc2V0dGluZ3MuYXBwbHkoZGF0YSk7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgICAvLyBJZiBwZWVyIGNoYW5nZWRcbiAgICAgIGlmIChwZWVyQ2hhbmdlZCkge1xuICAgICAgICAvLyBSZXN0YXJ0IHRoZSBuZXR3b3JrXG4gICAgICAgIHRoaXMubmV0d29yay5wZWVyID0gUGVlci5wYXJzZVVybChkYXRhLnBlZXJVcmwpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHRoaXMuZXJyb3IgPSAoZXJyICYmIGVyci5tZXNzYWdlKSB8fCBlcnI7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuZW5hYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICAgIHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKGRhdGEuYWNjb3VudEluaGVyaXRhbmNlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICAgIC8vIEFkZCBhIGRlbGF5LCBiZWNhdXNlIG9mIG9wdGlvbiBtZW51IHRoYXQgaXMgYWx3YXlzIG9wZW5lZCBhZnRlciBzYXZlISFcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSwgNDAwKTtcbiAgICB9XG4gIH1cblxuICBzZXRBY2NvdW50SW5oZXJpdGFuY2UoZW5hYmxlOiBib29sZWFuLCBvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICAvLyBNYWtlIHN1cmUgdG8gdXBkYXRlIHRoZSB2YWx1ZSBpbiBjb250cm9sXG4gICAgdGhpcy5mb3JtLmNvbnRyb2xzWydhY2NvdW50SW5oZXJpdGFuY2UnXS5zZXRWYWx1ZShlbmFibGUsIG9wdHMpO1xuICAgIGlmICh0aGlzLmRhdGEuYWNjb3VudEluaGVyaXRhbmNlICE9PSBlbmFibGUpIHtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9sc1snYWNjb3VudEluaGVyaXRhbmNlJ10ubWFya0FzRGlydHkoeyBvbmx5U2VsZjogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgaWYgKGVuYWJsZSkge1xuICAgICAgaWYgKHRoaXMuaXNMb2dpbikge1xuICAgICAgICAvLyBGb3JjZSB1c2luZyBhY2NvdW50IHNldHRpbmdzXG4gICAgICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQ7XG5cbiAgICAgICAgLy8gQ29weSB2YWx1ZXNcbiAgICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MpIHtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sb2NhbGUpIHRoaXMuZm9ybS5nZXQoJ2xvY2FsZScpLnNldFZhbHVlKGFjY291bnQuc2V0dGluZ3MubG9jYWxlLCBvcHRzKTtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0KSB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0LCBvcHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBEaXNhYmxlIGZpZWxkc1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5kaXNhYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZGlzYWJsZShvcHRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEVuYWJsZSBmaWVsZHNcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuZW5hYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXN0b3JlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuc2V0VmFsdWUodGhpcy5kYXRhLmxvY2FsZSwgb3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUodGhpcy5kYXRhLmxhdExvbmdGb3JtYXQsIG9wdHMpO1xuXG4gICAgICAvLyBFbmFibGUgZmllbGRzXG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5lbmFibGUob3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgIH1cblxuICAgIC8vIE1hcmsgZm9yIGNoZWNrLCBpZiBuZWVkXG4gICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50KSB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNob3dTZWxlY3RQZWVyTW9kYWwob3B0cz86IFBhcnRpYWw8SVNlbGVjdFBlZXJNb2RhbE9wdGlvbnM+KSB7XG4gICAgY29uc3QgcGVlciA9IGF3YWl0IHRoaXMubmV0d29yay5zaG93U2VsZWN0UGVlck1vZGFsKHtcbiAgICAgIHNob3dTZXRNYW51YWxseUJ1dHRvbjogZmFsc2UsIC8vIE1ha2Ugbm8gc2Vuc2UgaGVyZSwgYmVjYXVzZSBzYW1lIGFzIGNhbmNlbCAoYWxyZWFkeSBpbnNpZGUgdGhlIHNldHRpbmdzIHBhZ2UpXG4gICAgICAuLi5vcHRzLFxuICAgIH0pO1xuICAgIGlmIChwZWVyPy51cmwpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykgYXMgVW50eXBlZEZvcm1Db250cm9sO1xuICAgICAgY29udHJvbC5zZXRWYWx1ZShwZWVyLnVybCwgeyBlbWl0RXZlbnQ6IHRydWUsIG9ubHlTZWxmOiBmYWxzZSB9KTtcbiAgICAgIGNvbnRyb2wubWFya0FzRGlydHkoeyBvbmx5U2VsZjogZmFsc2UgfSk7XG4gICAgICB0aGlzLm1hcmtBc0RpcnR5KCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2FuY2VsKGV2ZW50PzogRXZlbnQpIHtcbiAgICBhd2FpdCB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlKF8/OiBFdmVudCkge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuO1xuXG4gICAgLy8gQmFjayB0byBob21lXG4gICAgcmV0dXJuIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKGV2ZW50PzogRXZlbnQpIHtcbiAgICBjb25zdCBjb25maXJtID0gYXdhaXQgQWxlcnRzLmFza0FjdGlvbkNvbmZpcm1hdGlvbih0aGlzLmFsZXJ0Q3RybCwgdGhpcy50cmFuc2xhdGUsIHRydWUsIGV2ZW50KTtcbiAgICBpZiAoY29uZmlybSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLmNsZWFyQ2FjaGUoKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MucmVtb3ZlT2ZmbGluZUZlYXR1cmVzKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZUFjdGlvbihldmVudDogRXZlbnQsIGl0ZW06IElNZW51SXRlbSkge1xuICAgIGlmICghaXRlbSkgcmV0dXJuO1xuICAgIGlmIChldmVudD8uZGVmYXVsdFByZXZlbnRlZCkgcmV0dXJuO1xuXG4gICAgaWYgKGl0ZW0ucGF0aCkge1xuICAgICAgYXdhaXQgdGhpcy5uYXZDb250cm9sbGVyLm5hdmlnYXRlRm9yd2FyZChpdGVtLnBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbc2V0dGluZ3NdIFVua25vd24gaXRlbSB0eXBlIChubyBwYXRoKScsIGl0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIC8qIC0tIHByb3RlY3RlZCBmdW5jdGlvbnMgLS0gKi9cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0VmFsdWUoKTogUHJvbWlzZTxMb2NhbFNldHRpbmdzPiB7XG4gICAgY29uc3QganNvbiA9IGF3YWl0IHRoaXMuZ2V0SnNvblZhbHVlVG9TYXZlKCk7XG5cbiAgICAvLyBPdmVycmlkZSBwcm9wZXJ0aWVzIGZyb20gYWNjb3VudFxuICAgIGlmIChqc29uLmFjY291bnRJbmhlcml0YW5jZSAmJiB0aGlzLmlzTG9naW4pIHtcbiAgICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQ7XG4gICAgICBjb25zdCB1c2VyU2V0dGluZ3MgPSBhY2NvdW50ICYmIGFjY291bnQuc2V0dGluZ3M7XG4gICAgICBjb25zb2xlLmRlYnVnKGBbc2V0dGluZ3NdIEFwcGx5aW5nIGFjY291bnQgaW5oZXJpdGFuY2Uge2xvY2FsZTogJyR7dXNlclNldHRpbmdzLmxvY2FsZX0nLCBsYXRMb25nRm9ybWF0OiAnJHt1c2VyU2V0dGluZ3MubGF0TG9uZ0Zvcm1hdH0nfS4uLmApO1xuICAgICAganNvbi5sb2NhbGUgPSB1c2VyU2V0dGluZ3MubG9jYWxlIHx8IGpzb24ubG9jYWxlO1xuICAgICAganNvbi5sYXRMb25nRm9ybWF0ID0gdXNlclNldHRpbmdzLmxhdExvbmdGb3JtYXQgfHwganNvbi5sYXRMb25nRm9ybWF0O1xuICAgIH1cblxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEpzb25WYWx1ZVRvU2F2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGpzb24gPSB0aGlzLmZvcm0udmFsdWU7XG4gICAganNvbi5wcm9wZXJ0aWVzID0gRW50aXR5VXRpbHMuZ2V0UHJvcGVydHlBcnJheUFzT2JqZWN0KGpzb24ucHJvcGVydGllcyk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGpzb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHRvZ2dsZURhcmtNb2RlKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5mb3JtLmdldCgnZGFya01vZGUnKS52YWx1ZTtcbiAgICB0aGlzLmZvcm0uZ2V0KCdkYXJrTW9kZScpLnNldFZhbHVlKCF2YWx1ZSk7XG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIjxhcHAtdG9vbGJhclxuICBbdGl0bGVdPVwiJ1NFVFRJTkdTLlRJVExFJyB8IHRyYW5zbGF0ZVwiXG4gIGNvbG9yPVwicHJpbWFyeVwiXG4gIFtoYXNWYWxpZGF0ZV09XCJkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgW2hhc0Nsb3NlXT1cIiFkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgKG9uVmFsaWRhdGUpPVwic2F2ZSgkZXZlbnQpXCJcbiAgKG9uQ2xvc2UpPVwiY2xvc2UoJGV2ZW50KVwiXG4+XG4gIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgQGlmKHNldHRpbmdzLmVuYWJsZURhcmtNb2RlKSB7XG4gICAgICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwidG9nZ2xlRGFya01vZGUoKVwiIFt0aXRsZV09XCInU0VUVElOR1MuQlROX0RBUktfTU9ERScgfCB0cmFuc2xhdGVcIj5cbiAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIiBbbmFtZV09XCJkYXJrTW9kZSA/ICdzdW5ueScgOiAnbW9vbidcIj48L2lvbi1pY29uPlxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgIH1cblxuICAgIDwhLS0gb3B0aW9ucyBtZW51IC0tPlxuICAgIDxpb24tYnV0dG9uIFttYXRNZW51VHJpZ2dlckZvcl09XCJvcHRpb25zTWVudVwiIFtkaXNhYmxlZF09XCJzYXZpbmdcIj5cbiAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCI+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICA8L2lvbi1idXR0b24+XG4gIDwvaW9uLWJ1dHRvbnM+XG48L2FwcC10b29sYmFyPlxuXG48IS0tIE9wdGlvbnMgbWVudSAtLT5cbjxtYXQtbWVudSAjb3B0aW9uc01lbnU9XCJtYXRNZW51XCI+XG4gIDwhLS0gQ2xlYXIgY2FjaGUgLS0+XG4gIDxidXR0b24gbWF0LW1lbnUtaXRlbSAoY2xpY2spPVwiY2xlYXJDYWNoZSgkZXZlbnQpXCI+XG4gICAgPG1hdC1pY29uPjxpb24taWNvbiBuYW1lPVwidHJhc2gtb3V0bGluZVwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5TRVRUSU5HUy5CVE5fQ0xFQVJfQ0FDSEU8L2lvbi1sYWJlbD5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBSZXNldCAtLT5cbiAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIFtkaXNhYmxlZF09XCIhZGlydHlcIiAoY2xpY2spPVwiY2FuY2VsKCRldmVudClcIj5cbiAgICA8bWF0LWljb24+PGlvbi1pY29uIG5hbWU9XCJyZWZyZXNoXCI+PC9pb24taWNvbj48L21hdC1pY29uPlxuICAgIDxtYXQtbGFiZWwgdHJhbnNsYXRlPkNPTU1PTi5CVE5fUkVTRVQ8L21hdC1sYWJlbD5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBhZGRpdGlvbmFsIGl0ZW1zIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvYWRpbmdcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIG1lbnVJdGVtc1wiPlxuICAgICAgPGFcbiAgICAgICAgKm5nSWY9XCJpdGVtLnBhdGhcIlxuICAgICAgICBtYXQtbWVudS1pdGVtXG4gICAgICAgIGNsYXNzPVwie3sgaXRlbS5jc3NDbGFzcyB9fSB7eyBpdGVtLmNvbG9yIH19XCJcbiAgICAgICAgKGNsaWNrKT1cImV4ZWN1dGVBY3Rpb24oJGV2ZW50LCBpdGVtKVwiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIml0ZW0uaWNvblwiPjxpb24taWNvbiBbbmFtZV09XCJpdGVtLmljb25cIj48L2lvbi1pY29uPjwvbWF0LWljb24+XG4gICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIml0ZW0ubWF0SWNvblwiPnt7IGl0ZW0ubWF0SWNvbiB9fTwvbWF0LWljb24+XG4gICAgICAgIDxtYXQtbGFiZWwgdHJhbnNsYXRlPnt7IGl0ZW0udGl0bGUgfX08L21hdC1sYWJlbD5cbiAgICAgIDwvYT5cbiAgICAgIDwhLS0gZGl2aWRlciAtLT5cbiAgICAgIDxtYXQtZGl2aWRlciAqbmdJZj1cIiFpdGVtLnBhdGggJiYgIWl0ZW0uYWN0aW9uXCIgY2xhc3M9XCJ7eyBpdGVtLmNzc0NsYXNzIH19IHt7IGl0ZW0uY29sb3IgfX1cIj5cbiAgICAgICAgPG1hdC1sYWJlbCB0cmFuc2xhdGU+e3sgaXRlbS50aXRsZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgPC9tYXQtZGl2aWRlcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L21hdC1tZW51PlxuXG48aW9uLWNvbnRlbnQ+XG4gIDxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIG5vdmFsaWRhdGUgKG5nU3VibWl0KT1cInNhdmUoJGV2ZW50KVwiIGNsYXNzPVwiZm9ybS1jb250YWluZXJcIj5cbiAgICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICA8IS0tIGxlZnQgIG1hcmdpbiAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjBcIiBzaXplLWxnPVwiMVwiIHNpemUteGw9XCIyXCI+Jm5ic3A7PC9pb24tY29sPlxuXG4gICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgICAgICA8IS0tIGVycm9yIC0tPlxuICAgICAgICAgIDxpb24taXRlbSAqbmdJZj1cImVycm9yXCIgbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cImVycm9yXCIgW2lubmVySFRNTF09XCJlcnJvciB8IHRyYW5zbGF0ZVwiPjwvaW9uLWxhYmVsPlxuICAgICAgICAgIDwvaW9uLWl0ZW0+XG5cbiAgICAgICAgICA8aW9uLWxpc3QtaGVhZGVyIHRyYW5zbGF0ZT5TRVRUSU5HUy5ERVNDUklQVElPTjwvaW9uLWxpc3QtaGVhZGVyPlxuPCEtLSAgICAgICAgICA8cCBbaW5uZXJIVE1MXT1cIidTRVRUSU5HUy5ERVNDUklQVElPTicgfCB0cmFuc2xhdGVcIj48L3A+LS0+XG5cbiAgICAgICAgICA8aW9uLWxpc3QgW2luc2V0XT1cIm1vYmlsZVwiPlxuICAgICAgICAgICAgPGlvbi1pdGVtIGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgICA8IS0tIGFjY291bnQgaW5oZXJpdGFuY2UgKGRlc2t0b3ApIC0tPlxuICAgICAgICAgICAgICBAaWYoIW1vYmlsZSkge1xuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBbaGlkZGVuXT1cIiFpc0xvZ2luXCI+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIGZvcm1Db250cm9sTmFtZT1cImFjY291bnRJbmhlcml0YW5jZVwiIHR5cGU9XCJ0ZXh0XCIgLz5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBjaGVjayBib3ggKGlmIGRlc2t0b3ApIC0tPlxuICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldEFjY291bnRJbmhlcml0YW5jZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJhY2NvdW50SW5oZXJpdGFuY2VcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+U0VUVElOR1MuSU5IRVJJVF9GUk9NX0FDQ09VTlQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cblxuICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuYWNjb3VudEluaGVyaXRhbmNlLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgICAgICAgICBFUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPCEtLSBhY2NvdW50IGluaGVyaXRhbmNlIChpZiBtb2JpbGUpIC0tPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBbaGlkZGVuXT1cIiFpc0xvZ2luXCI+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIGZvcm1Db250cm9sTmFtZT1cImFjY291bnRJbmhlcml0YW5jZVwiIHR5cGU9XCJ0ZXh0XCIgLz5cblxuICAgICAgICAgICAgICAgICAgPCEtLSBzbGlkZSB0b2dnbGUgIC0tPlxuICAgICAgICAgICAgICAgICAgPGlvbi10ZXh0IHRyYW5zbGF0ZT5TRVRUSU5HUy5JTkhFUklUX0ZST01fQUNDT1VOVDwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZXRBY2NvdW50SW5oZXJpdGFuY2UoJGV2ZW50LmNoZWNrZWQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiYWNjb3VudEluaGVyaXRhbmNlXCJcbiAgICAgICAgICAgICAgICAgID48L21hdC1zbGlkZS10b2dnbGU+XG4gICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5hY2NvdW50SW5oZXJpdGFuY2UuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICAgICAgICAgIEVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDwhLS0gbG9jYWxlIC0tPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyAnU0VUVElOR1MuTE9DQUxFJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IGZvcm1Db250cm9sTmFtZT1cImxvY2FsZVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbG9jYWxlc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLnZhbHVlIH19XG4gICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmxvY2FsZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICA8L2lvbi1saXN0PlxuXG4gICAgICAgICAgPCEtLSBOZXR3b3JrIGVudHJ5IC0tPlxuICAgICAgICAgIDxpb24tbGlzdC1oZWFkZXI+PGgzIHRyYW5zbGF0ZT5TRVRUSU5HUy5ORVRXT1JLX0RJVklERVI8L2gzPjwvaW9uLWxpc3QtaGVhZGVyPlxuXG4gICAgICAgICAgPGlvbi1saXN0IFtpbnNldF09XCJtb2JpbGVcIj5cbiAgICAgICAgICAgIDwhLS0gUGVlciBhZGRyZXNzIC0tPlxuICAgICAgICAgICAgPGlvbi1pdGVtIGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyAnU0VUVElOR1MuUEVFUl9VUkwnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwicGVlclVybFwiIHJlcXVpcmVkIC8+XG5cbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgbWF0U3VmZml4XG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd1NlbGVjdFBlZXJNb2RhbCgpXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fQ0hBTkdFX1BFRVInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24+c2VhcmNoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnBlZXJVcmwuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5wZWVyVXJsLmhhc0Vycm9yKCdwZWVyQWxpdmUnKVwiIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgICAgIFNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX1JFQUNIQUJMRVxuICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnBlZXJVcmwuaGFzRXJyb3IoJ3BlZXJOb3RDb21wYXRpYmxlJylcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICAgICAgICBTRVRUSU5HUy5FUlJPUi5QRUVSX05PVF9DT01QQVRJQkxFXG4gICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgICA8IS0tIE9mZmxpbmUgbW9kZSAoaWYgbW9iaWxlKSAtLT5cbiAgICAgICAgICAgIEBpZihtb2JpbGUpIHtcbiAgICAgICAgICAgICAgPGlvbi1pdGVtIGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gZm9ybUNvbnRyb2xOYW1lPVwiYWNjb3VudEluaGVyaXRhbmNlXCIgdHlwZT1cInRleHRcIiAvPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIHNsaWRlIHRvZ2dsZSAgLS0+XG4gICAgICAgICAgICAgICAgICA8aW9uLXRleHQgdHJhbnNsYXRlPlNFVFRJTkdTLk9GRkxJTkVfTU9ERTwvaW9uLXRleHQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJuZXR3b3JrLnNldEZvcmNlT2ZmbGluZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJuZXR3b3JrLm9mZmxpbmVcIlxuICAgICAgICAgICAgICAgICAgPjwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvaW9uLWxpc3Q+XG5cbiAgICAgICAgICA8IS0tIERhdGEgZW50cnkgLS0+XG4gICAgICAgICAgPGlvbi1saXN0LWhlYWRlcj5cbiAgICAgICAgICAgIDxoMyB0cmFuc2xhdGU+U0VUVElOR1MuREFUQV9FTlRSWV9ESVZJREVSPC9oMz5cbiAgICAgICAgICA8L2lvbi1saXN0LWhlYWRlcj5cblxuICAgICAgICAgIDxpb24tbGlzdCBbaW5zZXRdPVwibW9iaWxlXCI+XG4gICAgICAgICAgICA8IS0tIFVzYWdlIG1vZGUgLS0+XG4gICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5VU0FHRV9NT0RFJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IGZvcm1Db250cm9sTmFtZT1cInVzYWdlTW9kZVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgdXNhZ2VNb2Rlc1wiIFt2YWx1ZV09XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdTRVRUSU5HUy5VU0FHRV9NT0RFUy4nICsgaXRlbSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy51c2FnZU1vZGUuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRUQ8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG5cbiAgICAgICAgICAgIDwhLS0gbGF0L2xvbmcgZm9ybWF0LS0+XG4gICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5MQVRfTE9OR19GT1JNQVQnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwibGF0TG9uZ0Zvcm1hdFwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGF0TG9uZ0Zvcm1hdHNcIiBbdmFsdWVdPVwiaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICB7eyAnQ09NTU9OLkxBVF9MT05HLicgKyBpdGVtICsgJ19QTEFDRUhPTERFUicgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMubGF0TG9uZ0Zvcm1hdC5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgICAgIEVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgIDwvaW9uLWxpc3Q+XG5cbiAgICAgICAgICA8IS0tIGZpZWxkcyBvcHRpb25zIC0tPlxuICAgICAgICAgIDxpb24tZ3JpZCBmb3JtQXJyYXlOYW1lPVwicHJvcGVydGllc1wiIGNsYXNzPVwiaW9uLXBhZGRpbmdcIj5cbiAgICAgICAgICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgPGlvbi1jb2wgY2xhc3M9XCJpb24tbm8tcGFkZGluZyBpb24tYWxpZ24tc2VsZi1lbmRcIiBzaXplPVwiMTJcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRvb2xiYXItc3BhY2VyXCI+PC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgPCEtLSBTaG93IG1vcmUgb3B0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICA8aW9uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY29sb3I9XCJsaWdodFwiXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cInByb3BlcnRpZXNGb3JtPy5sZW5ndGggPT09IDBcIlxuICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidTRVRUSU5HUy5CVE5fU0hPV19NT1JFX0hFTFAnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJwcm9wZXJ0aWVzRm9ybUhlbHBlci5hZGQoKVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9TSE9XX01PUkU8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwiZW5kXCI+YXJyb3dfZHJvcF9kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDwvaW9uLXJvdz5cblxuICAgICAgICAgICAgPCEtLSBGaWVsZHMgb3B0aW9ucyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHByb3BlcnR5Rm9ybSBvZiBwcm9wZXJ0aWVzRm9ybT8uY29udHJvbHM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiIFtmb3JtR3JvdXBOYW1lXT1cImlcIj5cbiAgICAgICAgICAgICAgICA8IS0tIHByb3BlcnR5IGtleSAtLT5cbiAgICAgICAgICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgJ1NFVFRJTkdTLlBST1BFUlRZX0tFWScgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwia2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgcHJvcGVydHlEZWZpbml0aW9uc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgICAgICAgICA8IS0tIHByb3BlcnR5IHZhbHVlIC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBwYWRkaW5nLWxlZnQ+XG4gICAgICAgICAgICAgICAgICA8YXBwLWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJnZXRQcm9wZXJ0eURlZmluaXRpb24oaSk7IGxldCBkZWZpbml0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRMYWJlbD1cIm5ldmVyXCJcbiAgICAgICAgICAgICAgICAgICAgW2RlZmluaXRpb25dPVwiZGVmaW5pdGlvblwiXG4gICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJwcm9wZXJ0eUZvcm0gfCBmb3JtR2V0Q29udHJvbDogJ3ZhbHVlJ1wiXG4gICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInU0VUVElOR1MuUFJPUEVSVFlfVkFMVUUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgPjwvYXBwLWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIHNpemU9XCIyXCIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibGlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQ09NTU9OLkJUTl9ERUxFVEUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZVByb3BlcnR5QXQoaSlcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuaXNMYXN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1NFVFRJTkdTLkJUTl9BRERfUFJPUEVSVFknIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInByb3BlcnRpZXNGb3JtSGVscGVyLmFkZCgpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICA8IS0tIHJpZ2h0IG1hcmdpbiAtLT5cbiAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjBcIiBzaXplLWxnPVwiMVwiIHNpemUteGw9XCIyXCI+Jm5ic3A7PC9pb24tY29sPlxuICAgICAgPC9pb24tcm93PlxuICAgIDwvaW9uLWdyaWQ+XG4gIDwvZm9ybT5cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZm9vdGVyIGhpZGRlbi14cyBoaWRkZW4tc20gaGlkZGVuLW1vYmlsZT5cbiAgPGFwcC1mb3JtLWJ1dHRvbnMtYmFyXG4gICAgKG9uQ2FuY2VsKT1cImNhbmNlbCgpXCJcbiAgICAob25TYXZlKT1cInNhdmUoJGV2ZW50KVwiXG4gICAgW2Rpc2FibGVkXT1cIiFmb3JtLmRpcnR5IHx8IHNhdmluZ1wiXG4gID48L2FwcC1mb3JtLWJ1dHRvbnMtYmFyPlxuPC9pb24tZm9vdGVyPlxuIl19
331
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MucGFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9zZXR0aW5ncy9zZXR0aW5ncy5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL3NldHRpbmdzL3NldHRpbmdzLnBhZ2UuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQXFCLFNBQVMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUErQixRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFckosT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQTBDLE1BQU0sa0NBQWtDLENBQUM7QUFDdkcsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRXBELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBRy9GLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTTdDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLElBQUksY0FBYyxDQUFjLG1CQUFtQixDQUFDLENBQUM7QUFRNUYsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFzQjtJQWlDMUM7SUFDQTtJQUNBO0lBQ0E7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LGNBQWM7UUFDNUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFUyxZQUFZO1FBQ3BCLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDekIsQ0FBQzt1R0EzVVUsWUFBWSxxWEEyQ2IsV0FBVyxhQUNDLHVCQUF1QjsyRkE1Q2xDLFlBQVksd0NBSFosQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsNkJBQTZCLEVBQUUsQ0FBQyxpREM3QnhGLDJrWUF3U0E7OzJGRHhRYSxZQUFZO2tCQU54QixTQUFTOytCQUNFLGVBQWUsYUFFZCxDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSw2QkFBNkIsRUFBRSxDQUFDLG1CQUNyRSx1QkFBdUIsQ0FBQyxNQUFNOzswQkE2QzVDLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjY291bnRTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7IEVudGl0eVV0aWxzIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvZW50aXR5Lm1vZGVsJztcbmltcG9ydCB7IEFQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3MsIFVzYWdlTW9kZSB9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL3NldHRpbmdzLm1vZGVsJztcbmltcG9ydCB7IFBlZXIgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9wZWVyLm1vZGVsJztcbmltcG9ydCB7IFVudHlwZWRGb3JtQXJyYXksIFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Db250cm9sLCBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQXBwRm9ybSB9IGZyb20gJy4uL2Zvcm0vZm9ybS5jbGFzcyc7XG5pbXBvcnQgeyBBcHBGb3JtVXRpbHMsIEZvcm1BcnJheUhlbHBlciB9IGZyb20gJy4uL2Zvcm0vZm9ybS51dGlscyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnQGUtaXMvbmd4LW1hdGVyaWFsLXRhYmxlJztcbmltcG9ydCB7IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL2xvY2FsLXNldHRpbmdzLnZhbGlkYXRvcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9wbGF0Zm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IE5ldHdvcmtTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvbmV0d29yay5zZXJ2aWNlJztcbmltcG9ydCB7IGlzTmlsLCBpc05pbE9yQmxhbmssIHRvQm9vbGVhbiB9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuaW1wb3J0IHsgTG9jYWxTZXR0aW5nc1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9sb2NhbC1zZXR0aW5ncy5zZXJ2aWNlJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24sIEZvcm1GaWVsZERlZmluaXRpb25NYXAgfSBmcm9tICcuLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBtZXJnZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQWxlcnRDb250cm9sbGVyLCBOYXZDb250cm9sbGVyIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgQWxlcnRzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FsZXJ0cyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBDYW5MZWF2ZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9ndWFyZC9jb21wb25lbnQtZGlydHkuZ3VhcmQnO1xuaW1wb3J0IHsgSVNlbGVjdFBlZXJNb2RhbE9wdGlvbnMgfSBmcm9tICcuLi9wZWVyL3NlbGVjdC1wZWVyLm1vZGFsJztcbmltcG9ydCB7IElNZW51SXRlbSB9IGZyb20gJy4uL21lbnUvbWVudS5tb2RlbCc7XG5cbmV4cG9ydCBjb25zdCBBUFBfU0VUVElOR1NfTUVOVV9JVEVNUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxJTWVudUl0ZW1bXT4oJ3NldHRpbmdzTWVudUl0ZW1zJyk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3BhZ2Utc2V0dGluZ3MnLFxuICB0ZW1wbGF0ZVVybDogJ3NldHRpbmdzLnBhZ2UuaHRtbCcsXG4gIHByb3ZpZGVyczogW3sgcHJvdmlkZTogVmFsaWRhdG9yU2VydmljZSwgdXNlRXhpc3Rpbmc6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlIH1dLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2V0dGluZ3NQYWdlIGV4dGVuZHMgQXBwRm9ybTxMb2NhbFNldHRpbmdzPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDYW5MZWF2ZSB7XG4gIHByaXZhdGUgZGF0YTogTG9jYWxTZXR0aW5ncztcblxuICBtb2JpbGU6IGJvb2xlYW47XG4gIHNhdmluZyA9IGZhbHNlO1xuICB1c2FnZU1vZGVzOiBVc2FnZU1vZGVbXSA9IFsnRklFTEQnLCAnREVTSyddO1xuICBtZW51SXRlbXM6IElNZW51SXRlbVtdO1xuXG4gIHByb3BlcnR5RGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcbiAgcHJvcGVydHlEZWZpbml0aW9uc0J5S2V5OiBGb3JtRmllbGREZWZpbml0aW9uTWFwID0ge307XG4gIHByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4OiB7IFtpbmRleDogbnVtYmVyXTogRm9ybUZpZWxkRGVmaW5pdGlvbiB9ID0ge307XG4gIHByb3BlcnRpZXNGb3JtSGVscGVyOiBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+O1xuXG4gIGxhdExvbmdGb3JtYXRzID0gWydERE1NU1MnLCAnRERNTScsICdERCddO1xuXG4gIGdldCBhY2NvdW50SW5oZXJpdGFuY2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybS5jb250cm9sc1snYWNjb3VudEluaGVyaXRhbmNlJ10udmFsdWU7XG4gIH1cblxuICBnZXQgaXNMb2dpbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hY2NvdW50U2VydmljZS5pc0xvZ2luKCk7XG4gIH1cblxuICBnZXQgcHJvcGVydGllc0Zvcm0oKTogVW50eXBlZEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybS5nZXQoJ3Byb3BlcnRpZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5O1xuICB9XG5cbiAgZ2V0IGRhcmtNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmZvcm0uY29udHJvbHNbJ2RhcmtNb2RlJ10udmFsdWU7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJvdGVjdGVkIHBsYXRmb3JtOiBQbGF0Zm9ybVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIG5hdkNvbnRyb2xsZXI6IE5hdkNvbnRyb2xsZXIsXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRvclNlcnZpY2U6IExvY2FsU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBhbGVydEN0cmw6IEFsZXJ0Q29udHJvbGxlcixcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHByb3RlY3RlZCBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHNldHRpbmdzOiBMb2NhbFNldHRpbmdzU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBuZXR3b3JrOiBOZXR3b3JrU2VydmljZSxcbiAgICBASW5qZWN0KEFQUF9MT0NBTEVTKSBwdWJsaWMgbG9jYWxlczogTG9jYWxlQ29uZmlnW10sXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBUFBfU0VUVElOR1NfTUVOVV9JVEVNUykgbWVudUl0ZW1zPzogSU1lbnVJdGVtW11cbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IsIHZhbGlkYXRvclNlcnZpY2UuZ2V0Rm9ybUdyb3VwKCkpO1xuXG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlciA9IG5ldyBGb3JtQXJyYXlIZWxwZXI8UHJvcGVydHk+KFxuICAgICAgdGhpcy5mb3JtLmdldCgncHJvcGVydGllcycpIGFzIFVudHlwZWRGb3JtQXJyYXksXG4gICAgICAodmFsdWUpID0+IHRoaXMudmFsaWRhdG9yU2VydmljZS5nZXRQcm9wZXJ0eUZvcm1Hcm91cCh2YWx1ZSksXG4gICAgICAodjEsIHYyKSA9PiAoIXYxICYmICF2MikgfHwgdjEua2V5ID09PSB2Mi5rZXksXG4gICAgICAodmFsdWUpID0+IGlzTmlsKHZhbHVlKSB8fCAoaXNOaWwodmFsdWUua2V5KSAmJiBpc05pbCh2YWx1ZS52YWx1ZSkpLFxuICAgICAge1xuICAgICAgICBhbGxvd0VtcHR5QXJyYXk6IHRydWUsXG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMubWVudUl0ZW1zID0gbWVudUl0ZW1zIHx8IFtdO1xuICAgIHRoaXMubW9iaWxlID0gdGhpcy5wbGF0Zm9ybS5tb2JpbGU7XG5cbiAgICAvLyBCeSBkZWZhdWx0LCBkaXNhYmxlIHRoZSBmb3JtXG4gICAgdGhpcy5fZW5hYmxlID0gZmFsc2U7XG4gIH1cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHBsYXRmb3JtIGlzIHJlYWR5XG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5yZWFkeSgpO1xuXG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zID0gdGhpcy5zZXR0aW5ncy5vcHRpb25EZWZzLnNsaWNlKCk7IC8vIGNvcHkgb3B0aW9uc1xuICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9ucy5mb3JFYWNoKChvKSA9PiAodGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlbby5rZXldID0gbykpOyAvLyBmaWxsIG1hcFxuXG4gICAgLy8gTG9hZCBzZXR0aW5nc1xuICAgIGF3YWl0IHRoaXMubG9hZCgpO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIG1lcmdlKHRoaXMuYWNjb3VudFNlcnZpY2Uub25Mb2dpbiwgdGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ291dCkuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKHRoaXMuYWNjb3VudEluaGVyaXRhbmNlKSlcbiAgICApO1xuICB9XG5cbiAgZ2V0UHJvcGVydHlEZWZpbml0aW9uKGluZGV4OiBudW1iZXIpOiBGb3JtRmllbGREZWZpbml0aW9uIHtcbiAgICBsZXQgZGVmaW5pdGlvbiA9IHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdO1xuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgZGVmaW5pdGlvbiA9IHRoaXMudXBkYXRlUHJvcGVydHlEZWZpbml0aW9uKGluZGV4KTtcbiAgICAgIHRoaXMucHJvcGVydHlEZWZpbml0aW9uc0J5SW5kZXhbaW5kZXhdID0gZGVmaW5pdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmluaXRpb247XG4gIH1cblxuICB1cGRhdGVQcm9wZXJ0eURlZmluaXRpb24oaW5kZXg6IG51bWJlcik6IEZvcm1GaWVsZERlZmluaXRpb24ge1xuICAgIGNvbnN0IGtleSA9ICh0aGlzLnByb3BlcnRpZXNGb3JtLmF0KGluZGV4KSBhcyBVbnR5cGVkRm9ybUdyb3VwKS5jb250cm9scy5rZXkudmFsdWU7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IChrZXkgJiYgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlLZXlba2V5XSkgfHwgbnVsbDtcbiAgICB0aGlzLnByb3BlcnR5RGVmaW5pdGlvbnNCeUluZGV4W2luZGV4XSA9IGRlZmluaXRpb247IC8vIHVwZGF0ZSBtYXAgYnkgaW5kZXhcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgcmVtb3ZlUHJvcGVydHlBdChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlci5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5wcm9wZXJ0eURlZmluaXRpb25zQnlJbmRleCA9IHt9OyAvLyBjbGVhciBjYWNoZSBieSBpbmRleFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBhc3luYyBsb2FkKCkge1xuICAgIHRoaXMubWFya0FzTG9hZGluZygpO1xuICAgIGNvbnNvbGUuZGVidWcoJ1tzZXR0aW5nc10gTG9hZGluZyBzZXR0aW5ncy4uLicpO1xuXG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc2V0dGluZ3Muc2V0dGluZ3M7XG5cbiAgICAvLyBTZXQgZGVmYXVsdHNcbiAgICBkYXRhLmFjY291bnRJbmhlcml0YW5jZSA9IHRvQm9vbGVhbihkYXRhLmFjY291bnRJbmhlcml0YW5jZSwgdHJ1ZSk7XG4gICAgZGF0YS5sb2NhbGUgPSBkYXRhLmxvY2FsZSB8fCB0aGlzLnRyYW5zbGF0ZS5jdXJyZW50TGFuZyB8fCB0aGlzLnRyYW5zbGF0ZS5kZWZhdWx0TGFuZztcbiAgICBkYXRhLmxhdExvbmdGb3JtYXQgPSBkYXRhLmxhdExvbmdGb3JtYXQgfHwgJ0RETU1TUyc7XG4gICAgZGF0YS51c2FnZU1vZGUgPSBkYXRhLnVzYWdlTW9kZSB8fCAnREVTSyc7XG5cbiAgICAvLyBTZXQgcGVlclxuICAgIGlmIChpc05pbE9yQmxhbmsoZGF0YS5wZWVyVXJsKSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLnJlYWR5KCk7XG4gICAgICBjb25zdCBwZWVyID0gdGhpcy5uZXR3b3JrLnBlZXI7XG4gICAgICBkYXRhLnBlZXJVcmwgPSBwZWVyICYmIHBlZXIudXJsO1xuICAgIH1cblxuICAgIC8vIFJlbWVtYmVyIGRhdGFcbiAgICB0aGlzLnVwZGF0ZVZpZXcoZGF0YSk7XG4gIH1cblxuICB1cGRhdGVWaWV3KGRhdGE6IExvY2FsU2V0dGluZ3MpIHtcbiAgICBpZiAoIWRhdGEpIHJldHVybjsgLy9za2lwXG4gICAgdGhpcy5kYXRhID0gZGF0YTtcblxuICAgIGNvbnN0IGpzb246IGFueSA9IHsgLi4uZGF0YSB9O1xuXG4gICAgLy8gVHJhbnNmb3JtIHByb3BlcnRpZXMgbWFwIGludG8gYXJyYXlcbiAgICBqc29uLnByb3BlcnRpZXMgPSBFbnRpdHlVdGlscy5nZXRNYXBBc0FycmF5KGRhdGEucHJvcGVydGllcyB8fCB7fSk7XG4gICAgdGhpcy5wcm9wZXJ0aWVzRm9ybUhlbHBlci5yZXNpemUoanNvbi5wcm9wZXJ0aWVzLmxlbmd0aCk7XG5cbiAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZShqc29uLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgdGhpcy5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICB0aGlzLnNldEFjY291bnRJbmhlcml0YW5jZShkYXRhLmFjY291bnRJbmhlcml0YW5jZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgYXN5bmMgc2F2ZShldmVudD86IEV2ZW50LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuc2F2aW5nKSByZXR1cm47IC8vIFNraXBcblxuICAgIGlmIChldmVudCkgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIFJlbW92ZSBhbGwgZW1wdHkgY29udHJvbHNcbiAgICB0aGlzLnByb3BlcnRpZXNGb3JtSGVscGVyLnJlbW92ZUFsbEVtcHR5KCk7XG5cbiAgICBpZiAoIXRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgYXdhaXQgQXBwRm9ybVV0aWxzLndhaXRXaGlsZVBlbmRpbmcodGhpcy5mb3JtKTtcblxuICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkKSB7XG4gICAgICAgIEFwcEZvcm1VdGlscy5sb2dGb3JtRXJyb3JzKHRoaXMuZm9ybSk7XG4gICAgICAgIHRoaXMuZm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmRlYnVnKCdbc2V0dGluZ3NdIFNhdmluZyBsb2NhbCBzZXR0aW5ncy4uLicpO1xuXG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmdldFZhbHVlKCk7XG5cbiAgICAvLyBDaGVjayBwZWVyIGFsaXZlLCBiZWZvcmUgc2F2aW5nXG4gICAgY29uc3QgcGVlckNoYW5nZWQgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykuZGlydHk7XG5cbiAgICAvLyBDbGVhbiBwYWdlIGhpc3RvcnksIHdoZW4gcGVlciBjaGFuZ2VkXG4gICAgaWYgKHBlZXJDaGFuZ2VkKSBkYXRhLnBhZ2VIaXN0b3J5ID0gW107XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuc2V0dGluZ3MuYXBwbHkoZGF0YSk7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuXG4gICAgICAvLyBJZiBwZWVyIGNoYW5nZWRcbiAgICAgIGlmIChwZWVyQ2hhbmdlZCkge1xuICAgICAgICAvLyBSZXN0YXJ0IHRoZSBuZXR3b3JrXG4gICAgICAgIHRoaXMubmV0d29yay5wZWVyID0gUGVlci5wYXJzZVVybChkYXRhLnBlZXJVcmwpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHRoaXMuZXJyb3IgPSAoZXJyICYmIGVyci5tZXNzYWdlKSB8fCBlcnI7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuZW5hYmxlKHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgICAgLy8gQXBwbHkgaW5oZXJpdGFuY2VcbiAgICAgIHRoaXMuc2V0QWNjb3VudEluaGVyaXRhbmNlKGRhdGEuYWNjb3VudEluaGVyaXRhbmNlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICAgIC8vIEFkZCBhIGRlbGF5LCBiZWNhdXNlIG9mIG9wdGlvbiBtZW51IHRoYXQgaXMgYWx3YXlzIG9wZW5lZCBhZnRlciBzYXZlISFcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSwgNDAwKTtcbiAgICB9XG4gIH1cblxuICBzZXRBY2NvdW50SW5oZXJpdGFuY2UoZW5hYmxlOiBib29sZWFuLCBvcHRzPzogeyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICAvLyBNYWtlIHN1cmUgdG8gdXBkYXRlIHRoZSB2YWx1ZSBpbiBjb250cm9sXG4gICAgdGhpcy5mb3JtLmNvbnRyb2xzWydhY2NvdW50SW5oZXJpdGFuY2UnXS5zZXRWYWx1ZShlbmFibGUsIG9wdHMpO1xuICAgIGlmICh0aGlzLmRhdGEuYWNjb3VudEluaGVyaXRhbmNlICE9PSBlbmFibGUpIHtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9sc1snYWNjb3VudEluaGVyaXRhbmNlJ10ubWFya0FzRGlydHkoeyBvbmx5U2VsZjogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgaWYgKGVuYWJsZSkge1xuICAgICAgaWYgKHRoaXMuaXNMb2dpbikge1xuICAgICAgICAvLyBGb3JjZSB1c2luZyBhY2NvdW50IHNldHRpbmdzXG4gICAgICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQ7XG5cbiAgICAgICAgLy8gQ29weSB2YWx1ZXNcbiAgICAgICAgaWYgKGFjY291bnQuc2V0dGluZ3MpIHtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sb2NhbGUpIHRoaXMuZm9ybS5nZXQoJ2xvY2FsZScpLnNldFZhbHVlKGFjY291bnQuc2V0dGluZ3MubG9jYWxlLCBvcHRzKTtcbiAgICAgICAgICBpZiAoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0KSB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUoYWNjb3VudC5zZXR0aW5ncy5sYXRMb25nRm9ybWF0LCBvcHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBEaXNhYmxlIGZpZWxkc1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5kaXNhYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZGlzYWJsZShvcHRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEVuYWJsZSBmaWVsZHNcbiAgICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuZW5hYmxlKG9wdHMpO1xuICAgICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXN0b3JlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgdGhpcy5mb3JtLmdldCgnbG9jYWxlJykuc2V0VmFsdWUodGhpcy5kYXRhLmxvY2FsZSwgb3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0Jykuc2V0VmFsdWUodGhpcy5kYXRhLmxhdExvbmdGb3JtYXQsIG9wdHMpO1xuXG4gICAgICAvLyBFbmFibGUgZmllbGRzXG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsb2NhbGUnKS5lbmFibGUob3B0cyk7XG4gICAgICB0aGlzLmZvcm0uZ2V0KCdsYXRMb25nRm9ybWF0JykuZW5hYmxlKG9wdHMpO1xuICAgIH1cblxuICAgIC8vIE1hcmsgZm9yIGNoZWNrLCBpZiBuZWVkXG4gICAgaWYgKCFvcHRzIHx8IG9wdHMuZW1pdEV2ZW50KSB7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNob3dTZWxlY3RQZWVyTW9kYWwob3B0cz86IFBhcnRpYWw8SVNlbGVjdFBlZXJNb2RhbE9wdGlvbnM+KSB7XG4gICAgY29uc3QgcGVlciA9IGF3YWl0IHRoaXMubmV0d29yay5zaG93U2VsZWN0UGVlck1vZGFsKHtcbiAgICAgIHNob3dTZXRNYW51YWxseUJ1dHRvbjogZmFsc2UsIC8vIE1ha2Ugbm8gc2Vuc2UgaGVyZSwgYmVjYXVzZSBzYW1lIGFzIGNhbmNlbCAoYWxyZWFkeSBpbnNpZGUgdGhlIHNldHRpbmdzIHBhZ2UpXG4gICAgICAuLi5vcHRzLFxuICAgIH0pO1xuICAgIGlmIChwZWVyPy51cmwpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KCdwZWVyVXJsJykgYXMgVW50eXBlZEZvcm1Db250cm9sO1xuICAgICAgY29udHJvbC5zZXRWYWx1ZShwZWVyLnVybCwgeyBlbWl0RXZlbnQ6IHRydWUsIG9ubHlTZWxmOiBmYWxzZSB9KTtcbiAgICAgIGNvbnRyb2wubWFya0FzRGlydHkoeyBvbmx5U2VsZjogZmFsc2UgfSk7XG4gICAgICB0aGlzLm1hcmtBc0RpcnR5KCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgY2FuY2VsKGV2ZW50PzogRXZlbnQpIHtcbiAgICBhd2FpdCB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlKF8/OiBFdmVudCkge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuO1xuXG4gICAgLy8gQmFjayB0byBob21lXG4gICAgcmV0dXJuIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBhc3luYyBjbGVhckNhY2hlKGV2ZW50PzogRXZlbnQpIHtcbiAgICBjb25zdCBjb25maXJtID0gYXdhaXQgQWxlcnRzLmFza0FjdGlvbkNvbmZpcm1hdGlvbih0aGlzLmFsZXJ0Q3RybCwgdGhpcy50cmFuc2xhdGUsIHRydWUsIGV2ZW50KTtcbiAgICBpZiAoY29uZmlybSkge1xuICAgICAgYXdhaXQgdGhpcy5uZXR3b3JrLmNsZWFyQ2FjaGUoKTtcbiAgICAgIHRoaXMuc2V0dGluZ3MucmVtb3ZlT2ZmbGluZUZlYXR1cmVzKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXhlY3V0ZUFjdGlvbihldmVudDogRXZlbnQsIGl0ZW06IElNZW51SXRlbSkge1xuICAgIGlmICghaXRlbSkgcmV0dXJuO1xuICAgIGlmIChldmVudD8uZGVmYXVsdFByZXZlbnRlZCkgcmV0dXJuO1xuXG4gICAgaWYgKGl0ZW0ucGF0aCkge1xuICAgICAgYXdhaXQgdGhpcy5uYXZDb250cm9sbGVyLm5hdmlnYXRlRm9yd2FyZChpdGVtLnBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbc2V0dGluZ3NdIFVua25vd24gaXRlbSB0eXBlIChubyBwYXRoKScsIGl0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIC8qIC0tIHByb3RlY3RlZCBmdW5jdGlvbnMgLS0gKi9cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0VmFsdWUoKTogUHJvbWlzZTxMb2NhbFNldHRpbmdzPiB7XG4gICAgY29uc3QganNvbiA9IGF3YWl0IHRoaXMuZ2V0SnNvblZhbHVlVG9TYXZlKCk7XG5cbiAgICAvLyBPdmVycmlkZSBwcm9wZXJ0aWVzIGZyb20gYWNjb3VudFxuICAgIGlmIChqc29uLmFjY291bnRJbmhlcml0YW5jZSAmJiB0aGlzLmlzTG9naW4pIHtcbiAgICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQ7XG4gICAgICBjb25zdCB1c2VyU2V0dGluZ3MgPSBhY2NvdW50ICYmIGFjY291bnQuc2V0dGluZ3M7XG4gICAgICBjb25zb2xlLmRlYnVnKGBbc2V0dGluZ3NdIEFwcGx5aW5nIGFjY291bnQgaW5oZXJpdGFuY2Uge2xvY2FsZTogJyR7dXNlclNldHRpbmdzLmxvY2FsZX0nLCBsYXRMb25nRm9ybWF0OiAnJHt1c2VyU2V0dGluZ3MubGF0TG9uZ0Zvcm1hdH0nfS4uLmApO1xuICAgICAganNvbi5sb2NhbGUgPSB1c2VyU2V0dGluZ3MubG9jYWxlIHx8IGpzb24ubG9jYWxlO1xuICAgICAganNvbi5sYXRMb25nRm9ybWF0ID0gdXNlclNldHRpbmdzLmxhdExvbmdGb3JtYXQgfHwganNvbi5sYXRMb25nRm9ybWF0O1xuICAgIH1cblxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEpzb25WYWx1ZVRvU2F2ZSgpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IGpzb24gPSB0aGlzLmZvcm0udmFsdWU7XG4gICAganNvbi5wcm9wZXJ0aWVzID0gRW50aXR5VXRpbHMuZ2V0UHJvcGVydHlBcnJheUFzT2JqZWN0KGpzb24ucHJvcGVydGllcyk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGpzb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHRvZ2dsZURhcmtNb2RlKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5mb3JtLmdldCgnZGFya01vZGUnKS52YWx1ZTtcbiAgICB0aGlzLmZvcm0uZ2V0KCdkYXJrTW9kZScpLnNldFZhbHVlKCF2YWx1ZSk7XG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIjxhcHAtdG9vbGJhclxuICBbdGl0bGVdPVwiJ1NFVFRJTkdTLlRJVExFJyB8IHRyYW5zbGF0ZVwiXG4gIGNvbG9yPVwicHJpbWFyeVwiXG4gIFtoYXNWYWxpZGF0ZV09XCJkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgW2hhc0Nsb3NlXT1cIiFkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgKG9uVmFsaWRhdGUpPVwic2F2ZSgkZXZlbnQpXCJcbiAgKG9uQ2xvc2UpPVwiY2xvc2UoJGV2ZW50KVwiXG4+XG4gIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgQGlmKHNldHRpbmdzLmVuYWJsZURhcmtNb2RlKSB7XG4gICAgICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwidG9nZ2xlRGFya01vZGUoKVwiIFt0aXRsZV09XCInU0VUVElOR1MuQlROX0RBUktfTU9ERScgfCB0cmFuc2xhdGVcIj5cbiAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIiBbbmFtZV09XCJkYXJrTW9kZSA/ICdzdW5ueScgOiAnbW9vbidcIj48L2lvbi1pY29uPlxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgIH1cblxuICAgIDwhLS0gb3B0aW9ucyBtZW51IC0tPlxuICAgIDxpb24tYnV0dG9uIFttYXRNZW51VHJpZ2dlckZvcl09XCJvcHRpb25zTWVudVwiPlxuICAgICAgPG1hdC1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxuICAgIDwvaW9uLWJ1dHRvbj5cbiAgPC9pb24tYnV0dG9ucz5cbjwvYXBwLXRvb2xiYXI+XG5cbjwhLS0gT3B0aW9ucyBtZW51IC0tPlxuPG1hdC1tZW51ICNvcHRpb25zTWVudT1cIm1hdE1lbnVcIj5cbiAgPCEtLSBDbGVhciBjYWNoZSAtLT5cbiAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIFtkaXNhYmxlZF09XCJzYXZpbmdcIiAoY2xpY2spPVwiY2xlYXJDYWNoZSgkZXZlbnQpXCI+XG4gICAgPG1hdC1pY29uPjxpb24taWNvbiBuYW1lPVwidHJhc2gtb3V0bGluZVwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5TRVRUSU5HUy5CVE5fQ0xFQVJfQ0FDSEU8L2lvbi1sYWJlbD5cbiAgPC9idXR0b24+XG5cbiAgPCEtLSBSZXNldCAtLT5cbiAgPGJ1dHRvbiBtYXQtbWVudS1pdGVtIFtkaXNhYmxlZF09XCJzYXZpbmcgfHwgIWRpcnR5XCIgKGNsaWNrKT1cImNhbmNlbCgkZXZlbnQpXCI+XG4gICAgPG1hdC1pY29uPjxpb24taWNvbiBuYW1lPVwicmVmcmVzaFwiPjwvaW9uLWljb24+PC9tYXQtaWNvbj5cbiAgICA8bWF0LWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1JFU0VUPC9tYXQtbGFiZWw+XG4gIDwvYnV0dG9uPlxuXG4gIDwhLS0gYWRkaXRpb25hbCBpdGVtcyAtLT5cbiAgQGlmICghbG9hZGluZykge1xuICAgIEBmb3IgKGl0ZW0gb2YgbWVudUl0ZW1zOyB0cmFjayBpdGVtKSB7XG4gICAgICBAaWYgKGl0ZW0ucGF0aCkge1xuICAgICAgICA8YSBtYXQtbWVudS1pdGVtXG4gICAgICAgICAgIGNsYXNzPVwie3sgaXRlbS5jc3NDbGFzcyB9fSB7eyBpdGVtLmNvbG9yIH19XCJcbiAgICAgICAgICAgKGNsaWNrKT1cImV4ZWN1dGVBY3Rpb24oJGV2ZW50LCBpdGVtKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIml0ZW0uaWNvblwiPjxpb24taWNvbiBbbmFtZV09XCJpdGVtLmljb25cIj48L2lvbi1pY29uPjwvbWF0LWljb24+XG4gICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiaXRlbS5tYXRJY29uXCI+e3sgaXRlbS5tYXRJY29uIH19PC9tYXQtaWNvbj5cbiAgICAgICAgICA8bWF0LWxhYmVsIHRyYW5zbGF0ZT57eyBpdGVtLnRpdGxlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgIDwvYT5cbiAgICAgIH0gQGVsc2UgaWYoIWl0ZW0uYWN0aW9uKSB7XG4gICAgICAgIDwhLS0gZGl2aWRlciAtLT5cbiAgICAgICAgPG1hdC1kaXZpZGVyIGNsYXNzPVwie3sgaXRlbS5jc3NDbGFzcyB9fSB7eyBpdGVtLmNvbG9yIH19XCI+XG4gICAgICAgICAgPG1hdC1sYWJlbCB0cmFuc2xhdGU+e3sgaXRlbS50aXRsZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICA8L21hdC1kaXZpZGVyPlxuICAgICAgfVxuICAgIH1cbiAgfVxuPC9tYXQtbWVudT5cblxuPGlvbi1jb250ZW50PlxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiBub3ZhbGlkYXRlIChuZ1N1Ym1pdCk9XCJzYXZlKCRldmVudClcIiBjbGFzcz1cImZvcm0tY29udGFpbmVyXCI+XG4gICAgPGlvbi1ncmlkIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgPCEtLSBsZWZ0ICBtYXJnaW4gLS0+XG4gICAgICAgIDxpb24tY29sIHNpemU9XCIwXCIgc2l6ZS1sZz1cIjFcIiBzaXplLXhsPVwiMlwiPiZuYnNwOzwvaW9uLWNvbD5cblxuICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gICAgICAgICAgPCEtLSBlcnJvciAtLT5cbiAgICAgICAgICA8aW9uLWl0ZW0gKm5nSWY9XCJlcnJvclwiIGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgPGlvbi1pY29uIGNvbG9yPVwiZGFuZ2VyXCIgc2xvdD1cInN0YXJ0XCIgbmFtZT1cImFsZXJ0LWNpcmNsZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3IgfCB0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgPGlvbi1saXN0LWhlYWRlciB0cmFuc2xhdGU+U0VUVElOR1MuREVTQ1JJUFRJT048L2lvbi1saXN0LWhlYWRlcj5cblxuICAgICAgICAgIDxpb24tbGlzdCBbaW5zZXRdPVwibW9iaWxlXCI+XG4gICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDwhLS0gYWNjb3VudCBpbmhlcml0YW5jZSAoZGVza3RvcCkgLS0+XG4gICAgICAgICAgICAgIEBpZighbW9iaWxlKSB7XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gZm9ybUNvbnRyb2xOYW1lPVwiYWNjb3VudEluaGVyaXRhbmNlXCIgdHlwZT1cInRleHRcIiAvPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIGNoZWNrIGJveCAoaWYgZGVza3RvcCkgLS0+XG4gICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwic2V0QWNjb3VudEluaGVyaXRhbmNlKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImFjY291bnRJbmhlcml0YW5jZVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5TRVRUSU5HUy5JTkhFUklUX0ZST01fQUNDT1VOVDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuXG4gICAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5hY2NvdW50SW5oZXJpdGFuY2UuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICAgICAgICAgIEVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICA8IS0tIGFjY291bnQgaW5oZXJpdGFuY2UgKGlmIG1vYmlsZSkgLS0+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtoaWRkZW5dPVwiIWlzTG9naW5cIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBoaWRkZW4gZm9ybUNvbnRyb2xOYW1lPVwiYWNjb3VudEluaGVyaXRhbmNlXCIgdHlwZT1cInRleHRcIiAvPlxuXG4gICAgICAgICAgICAgICAgICA8IS0tIHNsaWRlIHRvZ2dsZSAgLS0+XG4gICAgICAgICAgICAgICAgICA8aW9uLXRleHQgdHJhbnNsYXRlPlNFVFRJTkdTLklOSEVSSVRfRlJPTV9BQ0NPVU5UPC9pb24tdGV4dD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIG1hdFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInNldEFjY291bnRJbmhlcml0YW5jZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJhY2NvdW50SW5oZXJpdGFuY2VcIlxuICAgICAgICAgICAgICAgICAgPjwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmFjY291bnRJbmhlcml0YW5jZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgRVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG5cbiAgICAgICAgICAgIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgPCEtLSBsb2NhbGUgLS0+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5MT0NBTEUnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwibG9jYWxlXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsb2NhbGVzXCIgW3ZhbHVlXT1cIml0ZW0ua2V5XCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0udmFsdWUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMubG9jYWxlLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgIDwvaW9uLWxpc3Q+XG5cbiAgICAgICAgICA8IS0tIE5ldHdvcmsgZW50cnkgLS0+XG4gICAgICAgICAgPGlvbi1saXN0LWhlYWRlcj48aDMgdHJhbnNsYXRlPlNFVFRJTkdTLk5FVFdPUktfRElWSURFUjwvaDM+PC9pb24tbGlzdC1oZWFkZXI+XG5cbiAgICAgICAgICA8aW9uLWxpc3QgW2luc2V0XT1cIm1vYmlsZVwiPlxuICAgICAgICAgICAgPCEtLSBQZWVyIGFkZHJlc3MgLS0+XG4gICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7ICdTRVRUSU5HUy5QRUVSX1VSTCcgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJwZWVyVXJsXCIgcmVxdWlyZWQgLz5cblxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzaG93U2VsZWN0UGVlck1vZGFsKClcIlxuICAgICAgICAgICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1NFVFRJTkdTLkJUTl9DSEFOR0VfUEVFUicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5zZWFyY2g8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMucGVlclVybC5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnBlZXJVcmwuaGFzRXJyb3IoJ3BlZXJBbGl2ZScpXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgICAgICAgU0VUVElOR1MuRVJST1IuUEVFUl9OT1RfUkVBQ0hBQkxFXG4gICAgICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMucGVlclVybC5oYXNFcnJvcigncGVlck5vdENvbXBhdGlibGUnKVwiIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgICAgIFNFVFRJTkdTLkVSUk9SLlBFRVJfTk9UX0NPTVBBVElCTEVcbiAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG5cbiAgICAgICAgICAgIDwhLS0gT2ZmbGluZSBtb2RlIChpZiBtb2JpbGUpIC0tPlxuICAgICAgICAgICAgQGlmKG1vYmlsZSkge1xuICAgICAgICAgICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiBmb3JtQ29udHJvbE5hbWU9XCJhY2NvdW50SW5oZXJpdGFuY2VcIiB0eXBlPVwidGV4dFwiIC8+XG5cbiAgICAgICAgICAgICAgICAgIDwhLS0gc2xpZGUgdG9nZ2xlICAtLT5cbiAgICAgICAgICAgICAgICAgIDxpb24tdGV4dCB0cmFuc2xhdGU+U0VUVElOR1MuT0ZGTElORV9NT0RFPC9pb24tdGV4dD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIG1hdFN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm5ldHdvcmsuc2V0Rm9yY2VPZmZsaW5lKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cIm5ldHdvcmsub2ZmbGluZVwiXG4gICAgICAgICAgICAgICAgICA+PC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9pb24tbGlzdD5cblxuICAgICAgICAgIDwhLS0gRGF0YSBlbnRyeSAtLT5cbiAgICAgICAgICA8aW9uLWxpc3QtaGVhZGVyPlxuICAgICAgICAgICAgPGgzIHRyYW5zbGF0ZT5TRVRUSU5HUy5EQVRBX0VOVFJZX0RJVklERVI8L2gzPlxuICAgICAgICAgIDwvaW9uLWxpc3QtaGVhZGVyPlxuXG4gICAgICAgICAgPGlvbi1saXN0IFtpbnNldF09XCJtb2JpbGVcIj5cbiAgICAgICAgICAgIDwhLS0gVXNhZ2UgbW9kZSAtLT5cbiAgICAgICAgICAgIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgJ1NFVFRJTkdTLlVTQUdFX01PREUnIHwgdHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwidXNhZ2VNb2RlXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiB1c2FnZU1vZGVzXCIgW3ZhbHVlXT1cIml0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAge3sgJ1NFVFRJTkdTLlVTQUdFX01PREVTLicgKyBpdGVtIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLnVzYWdlTW9kZS5oYXNFcnJvcigncmVxdWlyZWQnKVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPC9pb24taXRlbT5cblxuICAgICAgICAgICAgPCEtLSBsYXQvbG9uZyBmb3JtYXQtLT5cbiAgICAgICAgICAgIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+e3sgJ1NFVFRJTkdTLkxBVF9MT05HX0ZPUk1BVCcgfCB0cmFuc2xhdGUgfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBmb3JtQ29udHJvbE5hbWU9XCJsYXRMb25nRm9ybWF0XCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsYXRMb25nRm9ybWF0c1wiIFt2YWx1ZV09XCJpdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7ICdDT01NT04uTEFUX0xPTkcuJyArIGl0ZW0gKyAnX1BMQUNFSE9MREVSJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5sYXRMb25nRm9ybWF0Lmhhc0Vycm9yKCdyZXF1aXJlZCcpXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgICAgICAgRVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgPC9pb24tbGlzdD5cblxuICAgICAgICAgIDwhLS0gZmllbGRzIG9wdGlvbnMgLS0+XG4gICAgICAgICAgPGlvbi1ncmlkIGZvcm1BcnJheU5hbWU9XCJwcm9wZXJ0aWVzXCIgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuICAgICAgICAgICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi1uby1wYWRkaW5nIGlvbi1hbGlnbi1zZWxmLWVuZFwiIHNpemU9XCIxMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidG9vbGJhci1zcGFjZXJcIj48L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFNob3cgbW9yZSBvcHRpb25zIC0tPlxuICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICBjb2xvcj1cImxpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvcGVydGllc0Zvcm0/Lmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ1NFVFRJTkdTLkJUTl9TSE9XX01PUkVfSEVMUCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInByb3BlcnRpZXNGb3JtSGVscGVyLmFkZCgpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1NIT1dfTU9SRTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJlbmRcIj5hcnJvd19kcm9wX2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuXG4gICAgICAgICAgICA8IS0tIEZpZWxkcyBvcHRpb25zIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJvcGVydHlGb3JtIG9mIHByb3BlcnRpZXNGb3JtPy5jb250cm9sczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICA8aW9uLXJvdyBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gcHJvcGVydHkga2V5IC0tPlxuICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyAnU0VUVElOR1MuUFJPUEVSVFlfS0VZJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBmb3JtQ29udHJvbE5hbWU9XCJrZXlcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBwcm9wZXJ0eURlZmluaXRpb25zXCIgW3ZhbHVlXT1cIml0ZW0ua2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBpdGVtLmxhYmVsIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDwvaW9uLWNvbD5cblxuICAgICAgICAgICAgICAgIDwhLS0gcHJvcGVydHkgdmFsdWUgLS0+XG4gICAgICAgICAgICAgICAgPGlvbi1jb2wgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiIHBhZGRpbmctbGVmdD5cbiAgICAgICAgICAgICAgICAgIDxhcHAtZm9ybS1maWVsZFxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImdldFByb3BlcnR5RGVmaW5pdGlvbihpKTsgbGV0IGRlZmluaXRpb25cIlxuICAgICAgICAgICAgICAgICAgICBmbG9hdExhYmVsPVwibmV2ZXJcIlxuICAgICAgICAgICAgICAgICAgICBbZGVmaW5pdGlvbl09XCJkZWZpbml0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInByb3BlcnR5Rm9ybSB8IGZvcm1HZXRDb250cm9sOiAndmFsdWUnXCJcbiAgICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidTRVRUSU5HUy5QUk9QRVJUWV9WQUxVRScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICA+PC9hcHAtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjJcIiBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJsaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cIidDT01NT04uQlROX0RFTEVURScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlUHJvcGVydHlBdChpKVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwcm9wZXJ0aWVzRm9ybUhlbHBlci5pc0xhc3QoaSlcIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwibGlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInU0VUVElOR1MuQlROX0FERF9QUk9QRVJUWScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicHJvcGVydGllc0Zvcm1IZWxwZXIuYWRkKClcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9pb24tZ3JpZD5cbiAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgIDwhLS0gcmlnaHQgbWFyZ2luIC0tPlxuICAgICAgICA8aW9uLWNvbCBzaXplPVwiMFwiIHNpemUtbGc9XCIxXCIgc2l6ZS14bD1cIjJcIj4mbmJzcDs8L2lvbi1jb2w+XG4gICAgICA8L2lvbi1yb3c+XG4gICAgPC9pb24tZ3JpZD5cbiAgPC9mb3JtPlxuPC9pb24tY29udGVudD5cblxuPGlvbi1mb290ZXIgaGlkZGVuLXhzIGhpZGRlbi1zbSBoaWRkZW4tbW9iaWxlPlxuICA8YXBwLWZvcm0tYnV0dG9ucy1iYXJcbiAgICAob25DYW5jZWwpPVwiY2FuY2VsKClcIlxuICAgIChvblNhdmUpPVwic2F2ZSgkZXZlbnQpXCJcbiAgICBbZGlzYWJsZWRdPVwiIWZvcm0uZGlydHkgfHwgc2F2aW5nXCJcbiAgPjwvYXBwLWZvcm0tYnV0dG9ucy1iYXI+XG48L2lvbi1mb290ZXI+XG4iXX0=