UNPKG

@netgrif/components

Version:

Netgrif Application Engine frontend Angular components

178 lines 36.9 kB
import { Component, Inject, Optional } from '@angular/core'; import { GroupNavigationConstants, LoadingEmitter, SETTINGS_TRANSITION_ID, extractFilterFieldFromData, DoubleDrawerUtils, NAE_TAB_DATA, SimpleFilter, FilterType, NAE_AUTOSWITCH_TAB_TOKEN, NAE_OPEN_EXISTING_TAB, extractFieldValueFromData } from '@netgrif/components-core'; import { FormControl } from "@angular/forms"; import { forkJoin } from "rxjs"; import { map } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@netgrif/components-core"; import * as i2 from "@angular/router"; import * as i3 from "@ngx-translate/core"; import * as i4 from "@angular/common"; import * as i5 from "@ngbracket/ngx-layout"; import * as i6 from "@angular/material/card"; import * as i7 from "@angular/material/icon"; import * as i8 from "@angular/material/input"; import * as i9 from "@angular/material/form-field"; import * as i10 from "@angular/material/progress-spinner"; import * as i11 from "@angular/forms"; export class DefaultTicketViewComponent { _caseResourceService; _permissionService; _snackbar; _router; _log; _translateService; _navigationService; _taskResourceService; _processService; _injectedTabData; _autoswitchToTaskTab; _openExistingTab; loading$ = new LoadingEmitter(); createCaseLoading$ = new LoadingEmitter(); dashboardItems; filteredDashboardItems; search; constructor(_caseResourceService, _permissionService, _snackbar, _router, _log, _translateService, _navigationService, _taskResourceService, _processService, _injectedTabData, _autoswitchToTaskTab = true, _openExistingTab = true) { this._caseResourceService = _caseResourceService; this._permissionService = _permissionService; this._snackbar = _snackbar; this._router = _router; this._log = _log; this._translateService = _translateService; this._navigationService = _navigationService; this._taskResourceService = _taskResourceService; this._processService = _processService; this._injectedTabData = _injectedTabData; this._autoswitchToTaskTab = _autoswitchToTaskTab; this._openExistingTab = _openExistingTab; this.search = new FormControl(''); } ngOnInit() { if (this._autoswitchToTaskTab === null) { this._autoswitchToTaskTab = true; } if (this._openExistingTab === null) { this._openExistingTab = true; } this.loadTicketCreateContent(); this.search.valueChanges.subscribe(value => this.searchItems(value)); } loadTicketCreateContent() { this.loading$.on(); this._navigationService.rightItems$.pipe(map(navItems => this.transformItemCases(navItems).filter(itm => !!itm && !!itm.resource))).subscribe(items => { forkJoin(items.map(item => { const taskId = DoubleDrawerUtils.findTaskIdInCase(item.resource, SETTINGS_TRANSITION_ID); if (taskId === undefined) { return; } return this._taskResourceService.getData(taskId).pipe(map(dataGroups => { return { caseId: item.resource.stringId, dataGroups }; })); })).subscribe(dataGroups => { dataGroups.forEach(dataGroupPair => { if (dataGroupPair.dataGroups === undefined) { return; } let net = undefined; try { net = extractFilterFieldFromData(dataGroupPair.dataGroups)?.allowedNets[0]; } catch (error) { this._log.warn("View doesn't have a filter, skipping..."); } items.find(itm => itm.resource.stringId === dataGroupPair.caseId).petriNetId = net; }); this.dashboardItems = items.filter(item => item.petriNetId !== undefined); this.searchItems(this.search.value); this.loading$.off(); }, error => { this._log.error(error.message); this.loading$.off(); }); }, error => { this._log.error(error.message); this.loading$.off(); }); } transformItemCases(navItems) { return navItems.map(item => this.resolveItemCaseToNavigationItem(item)); } // copied from DoubleDrawerNavigationService resolveItemCaseToNavigationItem(navItem) { if (navItem.resource === undefined) { return undefined; } return { id: navItem.resource.stringId, icon: navItem.resource.immediateData.find(f => f.stringId === GroupNavigationConstants.ITEM_FIELD_ID_MENU_ICON)?.value || "add", title: navItem.navigation.title, petriNetId: undefined, resource: navItem.resource, }; } createCase(item) { if (this.isCardLoading()) { return; } this.createCaseLoading$.on(); this._processService.getNet(item.petriNetId).subscribe(petriNet => { this._caseResourceService.createCase({ netId: petriNet.stringId, title: item.title }).subscribe((caseResult) => { this.createCaseLoading$.off(); if (caseResult?.outcome?.aCase) { this.openTab(caseResult.outcome.aCase); } }, (error) => { this._snackbar.openErrorSnackBar(error); this.createCaseLoading$.off(); }); }); } isCardLoading() { return this.createCaseLoading$.isActive; } searchItems(val) { if (val && val.length === 0) { this.filteredDashboardItems = this.dashboardItems; } this.filteredDashboardItems = this.dashboardItems.filter(value => value.title.toLowerCase().includes(val.toLowerCase())); } openTab(openCase) { const transId = extractFieldValueFromData(this._injectedTabData.navigationItemTaskData, "transition_id"); this._injectedTabData.tabViewRef.openTab({ label: { text: openCase.title, icon: openCase.icon ? openCase.icon : 'check_box' }, canBeClosed: true, tabContentComponent: this._injectedTabData.tabViewComponent, injectedObject: { baseFilter: new SimpleFilter('', FilterType.TASK, { case: { id: `${openCase.stringId}` }, transitionId: transId }), allowedNets: [openCase.processIdentifier] }, order: this._injectedTabData.tabViewOrder, parentUniqueId: this._injectedTabData.tabUniqueId }, this._autoswitchToTaskTab, this._openExistingTab); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultTicketViewComponent, deps: [{ token: i1.CaseResourceService }, { token: i1.PermissionService }, { token: i1.SnackBarService }, { token: i2.Router }, { token: i1.LoggerService }, { token: i3.TranslateService }, { token: i1.DoubleDrawerNavigationService }, { token: i1.TaskResourceService }, { token: i1.ProcessService }, { token: NAE_TAB_DATA }, { token: NAE_AUTOSWITCH_TAB_TOKEN, optional: true }, { token: NAE_OPEN_EXISTING_TAB, optional: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultTicketViewComponent, selector: "nc-default-ticket-view", ngImport: i0, template: "<div fxLayout=\"column\" fxFlex=\"100\">\n <div class=\"cards-container\" fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" fxFlex=\"100\">\n\n <div *ngIf=\"(loading$ | async) || isCardLoading()\" fxLayout=\"column\" fxLayoutAlign=\"center center\"\n class=\"margin-top-default\" fxFlex=\"100\">\n <mat-spinner color=\"primary\" diameter=\"60\" mode=\"indeterminate\"></mat-spinner>\n </div>\n\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"center center\" *ngIf=\"!isCardLoading()\">\n <mat-form-field appearance=\"outline\" class=\"width-search\">\n <mat-label>Search</mat-label>\n <mat-icon matSuffix>search</mat-icon>\n <input matInput type=\"search\" [formControl]=\"search\">\n </mat-form-field>\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"center center\" class=\"width-80\">\n <div fxLayout=\"column\" *ngFor=\"let item of filteredDashboardItems\" class=\"dashboard-card\"\n (click)=\"createCase(item)\">\n <mat-card fxLayout=\"row\" fxFlex fxLayoutAlign=\"center center\"\n (click)=\"createCase(item)\">\n <mat-icon class=\"card-icon\">{{ item.icon }}</mat-icon>\n <div class=\"card-main-text\">{{ item.title }}</div>\n </mat-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dashboard-card{min-width:46%;margin:1% 2%}.card-content{text-align:center;margin-bottom:0!important}.card-main-text{font-weight:400;font-size:24px;line-height:60px;letter-spacing:.5px;text-align:center}.card-icon{height:25px;width:25px;font-size:25px}.cards-container{padding:1% 0 5% 1%}.width-80{width:80%}.width-search{width:77%}.margin-top-default{margin-top:16px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i5.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i5.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "component", type: i6.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.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: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i10.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i11.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: i11.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i11.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultTicketViewComponent, decorators: [{ type: Component, args: [{ selector: 'nc-default-ticket-view', template: "<div fxLayout=\"column\" fxFlex=\"100\">\n <div class=\"cards-container\" fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" fxFlex=\"100\">\n\n <div *ngIf=\"(loading$ | async) || isCardLoading()\" fxLayout=\"column\" fxLayoutAlign=\"center center\"\n class=\"margin-top-default\" fxFlex=\"100\">\n <mat-spinner color=\"primary\" diameter=\"60\" mode=\"indeterminate\"></mat-spinner>\n </div>\n\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"center center\" *ngIf=\"!isCardLoading()\">\n <mat-form-field appearance=\"outline\" class=\"width-search\">\n <mat-label>Search</mat-label>\n <mat-icon matSuffix>search</mat-icon>\n <input matInput type=\"search\" [formControl]=\"search\">\n </mat-form-field>\n <div fxLayout=\"row wrap\" fxLayoutAlign=\"center center\" class=\"width-80\">\n <div fxLayout=\"column\" *ngFor=\"let item of filteredDashboardItems\" class=\"dashboard-card\"\n (click)=\"createCase(item)\">\n <mat-card fxLayout=\"row\" fxFlex fxLayoutAlign=\"center center\"\n (click)=\"createCase(item)\">\n <mat-icon class=\"card-icon\">{{ item.icon }}</mat-icon>\n <div class=\"card-main-text\">{{ item.title }}</div>\n </mat-card>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".dashboard-card{min-width:46%;margin:1% 2%}.card-content{text-align:center;margin-bottom:0!important}.card-main-text{font-weight:400;font-size:24px;line-height:60px;letter-spacing:.5px;text-align:center}.card-icon{height:25px;width:25px;font-size:25px}.cards-container{padding:1% 0 5% 1%}.width-80{width:80%}.width-search{width:77%}.margin-top-default{margin-top:16px}\n"] }] }], ctorParameters: () => [{ type: i1.CaseResourceService }, { type: i1.PermissionService }, { type: i1.SnackBarService }, { type: i2.Router }, { type: i1.LoggerService }, { type: i3.TranslateService }, { type: i1.DoubleDrawerNavigationService }, { type: i1.TaskResourceService }, { type: i1.ProcessService }, { type: undefined, decorators: [{ type: Inject, args: [NAE_TAB_DATA] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NAE_AUTOSWITCH_TAB_TOKEN] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NAE_OPEN_EXISTING_TAB] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC10aWNrZXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMvc3JjL2xpYi9uYXZpZ2F0aW9uL2dyb3VwLW5hdmlnYXRpb24tY29tcG9uZW50LXJlc29sdmVyL2RlZmF1bHQtY29tcG9uZW50cy90YWJiZWQvZGVmYXVsdC10aWNrZXQtdmlldy9kZWZhdWx0LXRpY2tldC12aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy9zcmMvbGliL25hdmlnYXRpb24vZ3JvdXAtbmF2aWdhdGlvbi1jb21wb25lbnQtcmVzb2x2ZXIvZGVmYXVsdC1jb21wb25lbnRzL3RhYmJlZC9kZWZhdWx0LXRpY2tldC12aWV3L2RlZmF1bHQtdGlja2V0LXZpZXcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQVUsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRWxFLE9BQU8sRUFHSCx3QkFBd0IsRUFDeEIsY0FBYyxFQU1kLHNCQUFzQixFQUN0QiwwQkFBMEIsRUFDMUIsaUJBQWlCLEVBRWpCLFlBQVksRUFDWixZQUFZLEVBQ1osVUFBVSxFQUNWLHdCQUF3QixFQUFFLHFCQUFxQixFQUFpQyx5QkFBeUIsRUFDNUcsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUM5QixPQUFPLEVBQUMsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7Ozs7QUF1Qm5DLE1BQU0sT0FBTywwQkFBMEI7SUFTYjtJQUNBO0lBQ0E7SUFDQTtJQUNB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LE9BQU8sQ0FBQztZQUNyQyxLQUFLLEVBQUU7Z0JBQ0gsSUFBSSxFQUFFLFFBQVEsQ0FBQyxLQUFLO2dCQUNwQixJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVzthQUNwRDtZQUNELFdBQVcsRUFBRSxJQUFJO1lBQ2pCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0I7WUFDM0QsY0FBYyxFQUFFO2dCQUNaLFVBQVUsRUFBRSxJQUFJLFlBQVksQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxFQUFDLElBQUksRUFBRSxFQUFDLEVBQUUsRUFBRSxHQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUUsRUFBQyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUMsQ0FBQztnQkFDOUcsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDO2FBQzVDO1lBQ0QsS0FBSyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZO1lBQ3pDLGNBQWMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVztTQUNwRCxFQUFFLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN6RCxDQUFDO3dHQTFJUSwwQkFBMEIsc1RBa0JmLFlBQVksYUFDQSx3QkFBd0IsNkJBQ3hCLHFCQUFxQjs0RkFwQjVDLDBCQUEwQiw4REMvQ3ZDLCsrQ0EyQkE7OzRGRG9CYSwwQkFBMEI7a0JBTHRDLFNBQVM7K0JBQ0ksd0JBQXdCOzswQkFzQnJCLE1BQU07MkJBQUMsWUFBWTs7MEJBQ25CLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsd0JBQXdCOzswQkFDM0MsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgSW5qZWN0LCBPbkluaXQsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Um91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtcbiAgICBDYXNlLFxuICAgIENhc2VSZXNvdXJjZVNlcnZpY2UsXG4gICAgR3JvdXBOYXZpZ2F0aW9uQ29uc3RhbnRzLFxuICAgIExvYWRpbmdFbWl0dGVyLFxuICAgIFBlcm1pc3Npb25TZXJ2aWNlLFxuICAgIFNuYWNrQmFyU2VydmljZSxcbiAgICBEb3VibGVEcmF3ZXJOYXZpZ2F0aW9uU2VydmljZSxcbiAgICBOYXZpZ2F0aW9uSXRlbSxcbiAgICBUYXNrUmVzb3VyY2VTZXJ2aWNlLFxuICAgIFNFVFRJTkdTX1RSQU5TSVRJT05fSUQsXG4gICAgZXh0cmFjdEZpbHRlckZpZWxkRnJvbURhdGEsXG4gICAgRG91YmxlRHJhd2VyVXRpbHMsXG4gICAgRGF0YUdyb3VwLFxuICAgIE5BRV9UQUJfREFUQSxcbiAgICBTaW1wbGVGaWx0ZXIsXG4gICAgRmlsdGVyVHlwZSwgQ2FzZUV2ZW50T3V0Y29tZSxcbiAgICBOQUVfQVVUT1NXSVRDSF9UQUJfVE9LRU4sIE5BRV9PUEVOX0VYSVNUSU5HX1RBQiwgTG9nZ2VyU2VydmljZSwgUHJvY2Vzc1NlcnZpY2UsIGV4dHJhY3RGaWVsZFZhbHVlRnJvbURhdGFcbn0gZnJvbSAnQG5ldGdyaWYvY29tcG9uZW50cy1jb3JlJztcbmltcG9ydCB7VHJhbnNsYXRlU2VydmljZX0gZnJvbSBcIkBuZ3gtdHJhbnNsYXRlL2NvcmVcIjtcbmltcG9ydCB7Rm9ybUNvbnRyb2x9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHtmb3JrSm9pbn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7bWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICAgIEluamVjdGVkVGFiYmVkVGlja2V0Vmlld0RhdGFXaXRoTmF2aWdhdGlvbkl0ZW1UYXNrRGF0YVxufSBmcm9tIFwiLi4vLi4vbW9kZWwvaW5qZWN0ZWQtdGFiYmVkLXRpY2tldC12aWV3LWRhdGEtd2l0aC1uYXZpZ2F0aW9uLWl0ZW0tdGFzay1kYXRhXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja2V0SXRlbSB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBwZXRyaU5ldElkOiBzdHJpbmc7XG4gICAgdGl0bGU6IHN0cmluZztcbiAgICBpY29uOiBzdHJpbmc7XG4gICAgcmVzb3VyY2U/OiBDYXNlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFHcm91cENhc2VJZFBhaXIge1xuICAgIGNhc2VJZDogc3RyaW5nO1xuICAgIGRhdGFHcm91cHM6IERhdGFHcm91cFtdO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25jLWRlZmF1bHQtdGlja2V0LXZpZXcnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kZWZhdWx0LXRpY2tldC12aWV3LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9kZWZhdWx0LXRpY2tldC12aWV3LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRGVmYXVsdFRpY2tldFZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgcHVibGljIGxvYWRpbmckOiBMb2FkaW5nRW1pdHRlciA9IG5ldyBMb2FkaW5nRW1pdHRlcigpO1xuICAgIHB1YmxpYyBjcmVhdGVDYXNlTG9hZGluZyQ6IExvYWRpbmdFbWl0dGVyID0gbmV3IExvYWRpbmdFbWl0dGVyKCk7XG5cbiAgICBwdWJsaWMgZGFzaGJvYXJkSXRlbXM6IEFycmF5PFRpY2tldEl0ZW0+O1xuICAgIHB1YmxpYyBmaWx0ZXJlZERhc2hib2FyZEl0ZW1zOiBBcnJheTxUaWNrZXRJdGVtPjtcbiAgICBwdWJsaWMgc2VhcmNoOiBGb3JtQ29udHJvbDtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBfY2FzZVJlc291cmNlU2VydmljZTogQ2FzZVJlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3Blcm1pc3Npb25TZXJ2aWNlOiBQZXJtaXNzaW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3NuYWNrYmFyOiBTbmFja0JhclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9yb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX2xvZzogTG9nZ2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3RyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF9uYXZpZ2F0aW9uU2VydmljZTogRG91YmxlRHJhd2VyTmF2aWdhdGlvblNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJvdGVjdGVkIF90YXNrUmVzb3VyY2VTZXJ2aWNlOiBUYXNrUmVzb3VyY2VTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBfcHJvY2Vzc1NlcnZpY2U6IFByb2Nlc3NTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIEBJbmplY3QoTkFFX1RBQl9EQVRBKSBwcm90ZWN0ZWQgX2luamVjdGVkVGFiRGF0YTogSW5qZWN0ZWRUYWJiZWRUaWNrZXRWaWV3RGF0YVdpdGhOYXZpZ2F0aW9uSXRlbVRhc2tEYXRhLFxuICAgICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTkFFX0FVVE9TV0lUQ0hfVEFCX1RPS0VOKSBwcm90ZWN0ZWQgX2F1dG9zd2l0Y2hUb1Rhc2tUYWIgPSB0cnVlLFxuICAgICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTkFFX09QRU5fRVhJU1RJTkdfVEFCKSBwcm90ZWN0ZWQgX29wZW5FeGlzdGluZ1RhYiA9IHRydWUpIHtcbiAgICAgICAgdGhpcy5zZWFyY2ggPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fYXV0b3N3aXRjaFRvVGFza1RhYiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fYXV0b3N3aXRjaFRvVGFza1RhYiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX29wZW5FeGlzdGluZ1RhYiA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fb3BlbkV4aXN0aW5nVGFiID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRUaWNrZXRDcmVhdGVDb250ZW50KCk7XG4gICAgICAgIHRoaXMuc2VhcmNoLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsdWUgPT4gdGhpcy5zZWFyY2hJdGVtcyh2YWx1ZSkpXG4gICAgfVxuXG4gICAgcHVibGljIGxvYWRUaWNrZXRDcmVhdGVDb250ZW50KCkge1xuICAgICAgICB0aGlzLmxvYWRpbmckLm9uKCk7XG4gICAgICAgIHRoaXMuX25hdmlnYXRpb25TZXJ2aWNlLnJpZ2h0SXRlbXMkLnBpcGUoXG4gICAgICAgICAgICBtYXAobmF2SXRlbXMgPT4gdGhpcy50cmFuc2Zvcm1JdGVtQ2FzZXMobmF2SXRlbXMpLmZpbHRlcihpdG0gPT4gISFpdG0gJiYgISFpdG0ucmVzb3VyY2UpKVxuICAgICAgICApLnN1YnNjcmliZShpdGVtcyA9PiB7XG4gICAgICAgICAgICBmb3JrSm9pbihpdGVtcy5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFza0lkID0gRG91YmxlRHJhd2VyVXRpbHMuZmluZFRhc2tJZEluQ2FzZShpdGVtLnJlc291cmNlLCBTRVRUSU5HU19UUkFOU0lUSU9OX0lEKTtcbiAgICAgICAgICAgICAgICBpZiAodGFza0lkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGFza1Jlc291cmNlU2VydmljZS5nZXREYXRhKHRhc2tJZCkucGlwZShtYXAoZGF0YUdyb3VwcyA9PiB7cmV0dXJuIHtjYXNlSWQ6IGl0ZW0ucmVzb3VyY2Uuc3RyaW5nSWQsIGRhdGFHcm91cHN9IGFzIERhdGFHcm91cENhc2VJZFBhaXJ9KSk7XG4gICAgICAgICAgICB9KSkuc3Vic2NyaWJlKGRhdGFHcm91cHMgPT4ge1xuICAgICAgICAgICAgICAgIGRhdGFHcm91cHMuZm9yRWFjaChkYXRhR3JvdXBQYWlyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFHcm91cFBhaXIuZGF0YUdyb3VwcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGV0IG5ldCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldCA9IGV4dHJhY3RGaWx0ZXJGaWVsZEZyb21EYXRhKGRhdGFHcm91cFBhaXIuZGF0YUdyb3Vwcyk/LmFsbG93ZWROZXRzWzBdO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9nLndhcm4oXCJWaWV3IGRvZXNuJ3QgaGF2ZSBhIGZpbHRlciwgc2tpcHBpbmcuLi5cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaXRlbXMuZmluZChpdG0gPT4gaXRtLnJlc291cmNlLnN0cmluZ0lkID09PSBkYXRhR3JvdXBQYWlyLmNhc2VJZCkucGV0cmlOZXRJZCA9IG5ldDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRhc2hib2FyZEl0ZW1zID0gaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5wZXRyaU5ldElkICE9PSB1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VhcmNoSXRlbXModGhpcy5zZWFyY2gudmFsdWUpO1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyQub2ZmKClcbiAgICAgICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2cuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nJC5vZmYoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2xvZy5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgIHRoaXMubG9hZGluZyQub2ZmKClcbiAgICAgICAgfSlcblxuICAgIH1cblxuICAgIHByb3RlY3RlZCB0cmFuc2Zvcm1JdGVtQ2FzZXMobmF2SXRlbXM6IE5hdmlnYXRpb25JdGVtW10pIHtcbiAgICAgICAgcmV0dXJuIG5hdkl0ZW1zLm1hcChpdGVtID0+IHRoaXMucmVzb2x2ZUl0ZW1DYXNlVG9OYXZpZ2F0aW9uSXRlbShpdGVtKSk7XG4gICAgfVxuICAgIC8vIGNvcGllZCBmcm9tIERvdWJsZURyYXdlck5hdmlnYXRpb25TZXJ2aWNlXG4gICAgcHJvdGVjdGVkIHJlc29sdmVJdGVtQ2FzZVRvTmF2aWdhdGlvbkl0ZW0obmF2SXRlbTogTmF2aWdhdGlvbkl0ZW0pOiBUaWNrZXRJdGVtIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKG5hdkl0ZW0ucmVzb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6IG5hdkl0ZW0ucmVzb3VyY2Uuc3RyaW5nSWQsXG4gICAgICAgICAgICBpY29uOiBuYXZJdGVtLnJlc291cmNlLmltbWVkaWF0ZURhdGEuZmluZChmID0+IGYuc3RyaW5nSWQgPT09IEdyb3VwTmF2aWdhdGlvbkNvbnN0YW50cy5JVEVNX0ZJRUxEX0lEX01FTlVfSUNPTik/LnZhbHVlIHx8IFwiYWRkXCIsXG4gICAgICAgICAgICB0aXRsZTogKG5hdkl0ZW0ubmF2aWdhdGlvbiBhcyBhbnkpLnRpdGxlLFxuICAgICAgICAgICAgcGV0cmlOZXRJZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmVzb3VyY2U6IG5hdkl0ZW0ucmVzb3VyY2UsXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlQ2FzZShpdGVtOiBUaWNrZXRJdGVtKSB7XG4gICAgICAgIGlmICh0aGlzLmlzQ2FyZExvYWRpbmcoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3JlYXRlQ2FzZUxvYWRpbmckLm9uKCk7XG4gICAgICAgIHRoaXMuX3Byb2Nlc3NTZXJ2aWNlLmdldE5ldChpdGVtLnBldHJpTmV0SWQpLnN1YnNjcmliZShwZXRyaU5ldCA9PiB7XG4gICAgICAgICAgICB0aGlzLl9jYXNlUmVzb3VyY2VTZXJ2aWNlLmNyZWF0ZUNhc2Uoe1xuICAgICAgICAgICAgICAgIG5ldElkOiBwZXRyaU5ldC5zdHJpbmdJZCxcbiAgICAgICAgICAgICAgICB0aXRsZTogaXRlbS50aXRsZVxuICAgICAgICAgICAgfSkuc3Vic2NyaWJlKChjYXNlUmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVDYXNlTG9hZGluZyQub2ZmKCk7XG4gICAgICAgICAgICAgICAgaWYgKChjYXNlUmVzdWx0Py5vdXRjb21lIGFzIENhc2VFdmVudE91dGNvbWUpPy5hQ2FzZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW5UYWIoKGNhc2VSZXN1bHQub3V0Y29tZSBhcyBDYXNlRXZlbnRPdXRjb21lKS5hQ2FzZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc25hY2tiYXIub3BlbkVycm9yU25hY2tCYXIoZXJyb3IpO1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlQ2FzZUxvYWRpbmckLm9mZigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHVibGljIGlzQ2FyZExvYWRpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUNhc2VMb2FkaW5nJC5pc0FjdGl2ZTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc2VhcmNoSXRlbXModmFsOiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHZhbCAmJiB2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmVkRGFzaGJvYXJkSXRlbXMgPSB0aGlzLmRhc2hib2FyZEl0ZW1zO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsdGVyZWREYXNoYm9hcmRJdGVtcyA9IHRoaXMuZGFzaGJvYXJkSXRlbXMuZmlsdGVyKHZhbHVlID0+IHZhbHVlLnRpdGxlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsLnRvTG93ZXJDYXNlKCkpKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgb3BlblRhYihvcGVuQ2FzZTogQ2FzZSkge1xuICAgICAgICBjb25zdCB0cmFuc0lkOiBzdHJpbmcgPSBleHRyYWN0RmllbGRWYWx1ZUZyb21EYXRhKHRoaXMuX2luamVjdGVkVGFiRGF0YS5uYXZpZ2F0aW9uSXRlbVRhc2tEYXRhLCBcInRyYW5zaXRpb25faWRcIilcbiAgICAgICAgdGhpcy5faW5qZWN0ZWRUYWJEYXRhLnRhYlZpZXdSZWYub3BlblRhYih7XG4gICAgICAgICAgICBsYWJlbDoge1xuICAgICAgICAgICAgICAgIHRleHQ6IG9wZW5DYXNlLnRpdGxlLFxuICAgICAgICAgICAgICAgIGljb246IG9wZW5DYXNlLmljb24gPyBvcGVuQ2FzZS5pY29uIDogJ2NoZWNrX2JveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5CZUNsb3NlZDogdHJ1ZSxcbiAgICAgICAgICAgIHRhYkNvbnRlbnRDb21wb25lbnQ6IHRoaXMuX2luamVjdGVkVGFiRGF0YS50YWJWaWV3Q29tcG9uZW50LFxuICAgICAgICAgICAgaW5qZWN0ZWRPYmplY3Q6IHtcbiAgICAgICAgICAgICAgICBiYXNlRmlsdGVyOiBuZXcgU2ltcGxlRmlsdGVyKCcnLCBGaWx0ZXJUeXBlLlRBU0ssIHtjYXNlOiB7aWQ6IGAke29wZW5DYXNlLnN0cmluZ0lkfWB9LCB0cmFuc2l0aW9uSWQ6IHRyYW5zSWR9KSxcbiAgICAgICAgICAgICAgICBhbGxvd2VkTmV0czogW29wZW5DYXNlLnByb2Nlc3NJZGVudGlmaWVyXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9yZGVyOiB0aGlzLl9pbmplY3RlZFRhYkRhdGEudGFiVmlld09yZGVyLFxuICAgICAgICAgICAgcGFyZW50VW5pcXVlSWQ6IHRoaXMuX2luamVjdGVkVGFiRGF0YS50YWJVbmlxdWVJZFxuICAgICAgICB9LCB0aGlzLl9hdXRvc3dpdGNoVG9UYXNrVGFiLCB0aGlzLl9vcGVuRXhpc3RpbmdUYWIpO1xuICAgIH1cbn1cbiIsIjxkaXYgZnhMYXlvdXQ9XCJjb2x1bW5cIiBmeEZsZXg9XCIxMDBcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZHMtY29udGFpbmVyXCIgZnhMYXlvdXQ9XCJyb3cgd3JhcFwiIGZ4TGF5b3V0QWxpZ249XCJzdGFydCBjZW50ZXJcIiBmeEZsZXg9XCIxMDBcIj5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwiKGxvYWRpbmckIHwgYXN5bmMpIHx8IGlzQ2FyZExvYWRpbmcoKVwiIGZ4TGF5b3V0PVwiY29sdW1uXCIgZnhMYXlvdXRBbGlnbj1cImNlbnRlciBjZW50ZXJcIlxuICAgICAgICAgICAgIGNsYXNzPVwibWFyZ2luLXRvcC1kZWZhdWx0XCIgZnhGbGV4PVwiMTAwXCI+XG4gICAgICAgICAgICA8bWF0LXNwaW5uZXIgY29sb3I9XCJwcmltYXJ5XCIgZGlhbWV0ZXI9XCI2MFwiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBmeExheW91dD1cImNvbHVtblwiIGZ4RmxleD1cIjEwMFwiIGZ4TGF5b3V0QWxpZ249XCJjZW50ZXIgY2VudGVyXCIgKm5nSWY9XCIhaXNDYXJkTG9hZGluZygpXCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBjbGFzcz1cIndpZHRoLXNlYXJjaFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+U2VhcmNoPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uIG1hdFN1ZmZpeD5zZWFyY2g8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCB0eXBlPVwic2VhcmNoXCIgW2Zvcm1Db250cm9sXT1cInNlYXJjaFwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxkaXYgZnhMYXlvdXQ9XCJyb3cgd3JhcFwiIGZ4TGF5b3V0QWxpZ249XCJjZW50ZXIgY2VudGVyXCIgY2xhc3M9XCJ3aWR0aC04MFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgZnhMYXlvdXQ9XCJjb2x1bW5cIiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBmaWx0ZXJlZERhc2hib2FyZEl0ZW1zXCIgY2xhc3M9XCJkYXNoYm9hcmQtY2FyZFwiXG4gICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY3JlYXRlQ2FzZShpdGVtKVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNhcmQgZnhMYXlvdXQ9XCJyb3dcIiBmeEZsZXggZnhMYXlvdXRBbGlnbj1cImNlbnRlciBjZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY3JlYXRlQ2FzZShpdGVtKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY2FyZC1pY29uXCI+e3sgaXRlbS5pY29uIH19PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLW1haW4tdGV4dFwiPnt7IGl0ZW0udGl0bGUgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2FyZD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19