ngx-st-tables 17.0.111 → 17.0.113

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.
package/README.md CHANGED
@@ -2,6 +2,135 @@
2
2
 
3
3
  This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.2.0.
4
4
 
5
+ ## Usage
6
+
7
+ ### Immutable Data Pattern
8
+
9
+ The table library follows an immutable data pattern where:
10
+ - The parent component owns and controls the data
11
+ - The table works on a copy of the data
12
+ - Changes are communicated back to the parent through events
13
+ - The parent decides whether to accept/reject changes
14
+
15
+ ### Example: Using Add/Edit Row Features
16
+
17
+ ```typescript
18
+ // Parent Component
19
+ @Component({
20
+ selector: 'app-example',
21
+ template: `
22
+ <ngx-st-material-table
23
+ [data]="tableData"
24
+ [initColumns]="columns"
25
+ [allowEditRow]="true"
26
+ [createButtonUseAddRow]="true"
27
+ (saveNewCreatedRow)="onSaveNewCreatedRow($event)"
28
+ (saveNewRow)="onSaveEditedRow($event)"
29
+ />
30
+ `
31
+ })
32
+ export class ExampleComponent {
33
+ tableData: any[] = [];
34
+
35
+ columns: StMaterialTableColumnModel[] = [
36
+ { field: 'name', header: 'Name', allowEditColumn: true, editColumnRequired: true },
37
+ { field: 'email', header: 'Email', allowEditColumn: true },
38
+ ];
39
+
40
+ // Handle new row creation
41
+ onSaveNewCreatedRow(row: any) {
42
+ // The library generated an ID and validated the row
43
+ // Parent decides how to handle it (e.g., API call)
44
+ this.apiService.createRow(row).subscribe(response => {
45
+ // Update parent's data with server response
46
+ this.tableData = [...this.tableData, response];
47
+ });
48
+ }
49
+
50
+ // Handle row editing
51
+ onSaveEditedRow(row: any) {
52
+ this.apiService.updateRow(row).subscribe(response => {
53
+ const index = this.tableData.findIndex(r => r.id === row.id);
54
+ if (index !== -1) {
55
+ this.tableData[index] = response;
56
+ this.tableData = [...this.tableData];
57
+ }
58
+ });
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### Benefits
64
+ - **Single source of truth**: Parent's data is never mutated
65
+ - **No ID conflicts**: IDs are generated once in the library
66
+ - **Clear responsibility**: Library manages UI state, parent manages data
67
+ - **Flexibility**: Parent can reject/modify changes before updating
68
+
69
+ ### Auto-Save Mode (No Save/Cancel Buttons)
70
+
71
+ For tables where you want immediate updates without save/cancel buttons (e.g., quantity inputs in selection tables):
72
+
73
+ ```typescript
74
+ // Parent Component
75
+ @Component({
76
+ selector: 'app-selection-table',
77
+ template: `
78
+ <ngx-st-material-table
79
+ [data]="tableData"
80
+ [initColumns]="columns"
81
+ [allowEditRow]="true"
82
+ [allowSelectRow]="true"
83
+ [autoSaveOnChange]="true"
84
+ (fieldValueChanged)="onFieldValueChanged($event)"
85
+ (selectRowChange)="onSelectionChanged($event)"
86
+ />
87
+ `
88
+ })
89
+ export class SelectionTableComponent {
90
+ tableData: any[] = [
91
+ { id: 1, name: 'Product A', qty: 0 },
92
+ { id: 2, name: 'Product B', qty: 0 },
93
+ ];
94
+
95
+ columns: StMaterialTableColumnModel[] = [
96
+ { field: 'name', header: 'Name', type: 'string' },
97
+ {
98
+ field: 'qty',
99
+ header: 'Quantity',
100
+ type: 'number',
101
+ allowEditColumn: true // Field will be editable without save buttons
102
+ },
103
+ ];
104
+
105
+ // Handle immediate field changes
106
+ onFieldValueChanged(event: { row: any; field: string; value: any }) {
107
+ const index = this.tableData.findIndex(r => r.id === event.row.id);
108
+ if (index !== -1) {
109
+ this.tableData[index][event.field] = event.value;
110
+
111
+ // Optional: Send to API immediately or batch updates
112
+ console.log('Updated:', event.row.name, event.field, event.value);
113
+ }
114
+ }
115
+
116
+ onSelectionChanged(selectedRows: any[]) {
117
+ console.log('Selected rows with quantities:', selectedRows);
118
+ }
119
+ }
120
+ ```
121
+
122
+ **When to use autoSaveOnChange:**
123
+ - Selection tables with quantity inputs
124
+ - Toggle/checkbox columns that should update immediately
125
+ - Simple data entry without complex validation
126
+ - Better UX when users don't want to click save buttons
127
+
128
+ **Benefits:**
129
+ - ✅ No save/cancel buttons (cleaner UI)
130
+ - ✅ Immediate feedback
131
+ - ✅ Works perfectly with row selection
132
+ - ✅ Parent receives updates in real-time
133
+
5
134
  ## Code scaffolding
6
135
 
7
136
  Run `ng generate component component-name --project ngx-st-tables` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-st-tables`.
@@ -1,4 +1,6 @@
1
- import { ChangeDetectionStrategy, Component, Input, input, output, signal, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, Input, input, output, signal, ViewChild, } from '@angular/core';
2
+ import { MatInput } from '@angular/material/input';
3
+ import { MatSelect } from '@angular/material/select';
2
4
  import * as i0 from "@angular/core";
3
5
  import * as i1 from "@angular/common";
4
6
  import * as i2 from "@angular/material/button";
@@ -16,9 +18,14 @@ import * as i13 from "@angular/material/datepicker";
16
18
  import * as i14 from "ngx-st-date-format";
17
19
  export class MaterialTableRowCellComponent {
18
20
  set rowEditing(data) {
21
+ const wasNotEditing = !this._rowEditing;
19
22
  this._rowEditing = data;
20
23
  if (data) {
21
24
  this.getDynamicSelectData();
25
+ // Focus first editable field when entering edit mode
26
+ if (wasNotEditing && this.isFirstEditableColumn()) {
27
+ this.focusFirstEditableField();
28
+ }
22
29
  }
23
30
  }
24
31
  get rowEditing() {
@@ -33,6 +40,8 @@ export class MaterialTableRowCellComponent {
33
40
  this.canEditRowValidator = input(() => true);
34
41
  this.canDeleteRowValidator = input(() => true);
35
42
  this.selectRowOnlyOne = input(false);
43
+ this.isFirstEditableColumn = input(false);
44
+ this.autoSaveOnChange = input(false);
36
45
  this._rowEditing = false;
37
46
  this.rowIsSelected = input(false);
38
47
  this.rowIsExpanded = input(false);
@@ -41,6 +50,7 @@ export class MaterialTableRowCellComponent {
41
50
  this.editRowEmitter = output();
42
51
  this.deleteRowEmitter = output();
43
52
  this.selectRowChange = output();
53
+ this.fieldValueChanged = output();
44
54
  this.mobileView = false;
45
55
  this.actionIconColorDef = {
46
56
  edit: 'primary',
@@ -53,6 +63,25 @@ export class MaterialTableRowCellComponent {
53
63
  this.checkWidthSize();
54
64
  });
55
65
  }
66
+ ngAfterViewInit() {
67
+ // If row is already in edit mode on init (e.g., newly added row), focus the field
68
+ if (this.rowEditing && this.isFirstEditableColumn()) {
69
+ this.focusFirstEditableField();
70
+ }
71
+ }
72
+ focusFirstEditableField() {
73
+ // Use setTimeout to ensure the view is fully rendered
74
+ setTimeout(() => {
75
+ if (this.matInput) {
76
+ // Focus MatInput
77
+ this.matInput.focus();
78
+ }
79
+ else if (this.matSelect) {
80
+ // Focus MatSelect
81
+ this.matSelect.focus();
82
+ }
83
+ }, 150);
84
+ }
56
85
  saveRow() {
57
86
  this.saveEditRowEmitter.emit();
58
87
  }
@@ -70,6 +99,11 @@ export class MaterialTableRowCellComponent {
70
99
  this.selectRowChange.emit(event.checked);
71
100
  }
72
101
  }
102
+ onFieldChange(field, value) {
103
+ if (this.autoSaveOnChange()) {
104
+ this.fieldValueChanged.emit({ field, value });
105
+ }
106
+ }
73
107
  checkWidthSize() {
74
108
  this.mobileView = document.body.clientWidth <= 1100;
75
109
  this.changeDetectorRef.markForCheck();
@@ -83,12 +117,18 @@ export class MaterialTableRowCellComponent {
83
117
  }
84
118
  }
85
119
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MaterialTableRowCellComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
86
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MaterialTableRowCellComponent, selector: "st-material-table-row-cell", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, rowDataCopy: { classPropertyName: "rowDataCopy", publicName: "rowDataCopy", isSignal: true, isRequired: false, transformFunction: null }, canEditRowValidator: { classPropertyName: "canEditRowValidator", publicName: "canEditRowValidator", isSignal: true, isRequired: false, transformFunction: null }, canDeleteRowValidator: { classPropertyName: "canDeleteRowValidator", publicName: "canDeleteRowValidator", isSignal: true, isRequired: false, transformFunction: null }, selectRowOnlyOne: { classPropertyName: "selectRowOnlyOne", publicName: "selectRowOnlyOne", isSignal: true, isRequired: false, transformFunction: null }, rowEditing: { classPropertyName: "rowEditing", publicName: "rowEditing", isSignal: false, isRequired: false, transformFunction: null }, rowIsSelected: { classPropertyName: "rowIsSelected", publicName: "rowIsSelected", isSignal: true, isRequired: false, transformFunction: null }, rowIsExpanded: { classPropertyName: "rowIsExpanded", publicName: "rowIsExpanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saveEditRowEmitter: "saveEditRowEmitter", cancelEditRowEmitter: "cancelEditRowEmitter", editRowEmitter: "editRowEmitter", deleteRowEmitter: "deleteRowEmitter", selectRowChange: "selectRowChange" }, ngImport: i0, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView) ||\r\n (mobileView && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateTimeFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if (rowEditing && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string' || column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [type]=\"column.rowEditType === 'string' ? 'text' : 'number'\"\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n (keydown.enter)=\"saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n (keydown.enter)=\"saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox [(ngModel)]=\"rowDataCopy()![column.field]\"></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.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: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i9.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: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.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: i10.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: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { 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.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i13.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i13.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "pipe", type: i14.DateTimeFormatPipe, name: "stDateTimeFormatPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
120
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MaterialTableRowCellComponent, selector: "st-material-table-row-cell", inputs: { column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, rowData: { classPropertyName: "rowData", publicName: "rowData", isSignal: true, isRequired: true, transformFunction: null }, rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, rowDataCopy: { classPropertyName: "rowDataCopy", publicName: "rowDataCopy", isSignal: true, isRequired: false, transformFunction: null }, canEditRowValidator: { classPropertyName: "canEditRowValidator", publicName: "canEditRowValidator", isSignal: true, isRequired: false, transformFunction: null }, canDeleteRowValidator: { classPropertyName: "canDeleteRowValidator", publicName: "canDeleteRowValidator", isSignal: true, isRequired: false, transformFunction: null }, selectRowOnlyOne: { classPropertyName: "selectRowOnlyOne", publicName: "selectRowOnlyOne", isSignal: true, isRequired: false, transformFunction: null }, isFirstEditableColumn: { classPropertyName: "isFirstEditableColumn", publicName: "isFirstEditableColumn", isSignal: true, isRequired: false, transformFunction: null }, autoSaveOnChange: { classPropertyName: "autoSaveOnChange", publicName: "autoSaveOnChange", isSignal: true, isRequired: false, transformFunction: null }, rowEditing: { classPropertyName: "rowEditing", publicName: "rowEditing", isSignal: false, isRequired: false, transformFunction: null }, rowIsSelected: { classPropertyName: "rowIsSelected", publicName: "rowIsSelected", isSignal: true, isRequired: false, transformFunction: null }, rowIsExpanded: { classPropertyName: "rowIsExpanded", publicName: "rowIsExpanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saveEditRowEmitter: "saveEditRowEmitter", cancelEditRowEmitter: "cancelEditRowEmitter", editRowEmitter: "editRowEmitter", deleteRowEmitter: "deleteRowEmitter", selectRowChange: "selectRowChange", fieldValueChanged: "fieldValueChanged" }, viewQueries: [{ propertyName: "matInput", first: true, predicate: MatInput, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView) ||\r\n (mobileView && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateTimeFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string' || column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [type]=\"column.rowEditType === 'string' ? 'text' : 'number'\"\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i6.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.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: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i9.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: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.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: i10.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: i11.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { 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.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i13.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i13.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "pipe", type: i14.DateTimeFormatPipe, name: "stDateTimeFormatPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
87
121
  }
88
122
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MaterialTableRowCellComponent, decorators: [{
89
123
  type: Component,
90
- args: [{ selector: 'st-material-table-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView) ||\r\n (mobileView && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateTimeFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if (rowEditing && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string' || column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [type]=\"column.rowEditType === 'string' ? 'text' : 'number'\"\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n (keydown.enter)=\"saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n (keydown.enter)=\"saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox [(ngModel)]=\"rowDataCopy()![column.field]\"></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"rowDataCopy()![column.field]\"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n" }]
91
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { rowEditing: [{
124
+ args: [{ selector: 'st-material-table-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, template: "@switch (column().type || 'string') {\r\n @case ('custom-template') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"column().customTemplate!\"\r\n [ngTemplateOutletContext]=\"{ data: rowData() }\"\r\n ></ng-container>\r\n }\r\n }\r\n\r\n @case ('actions') {\r\n @if (column().actions) {\r\n @if (\r\n (!column().actionsInMenu && !mobileView) ||\r\n (mobileView && column().actions!.length <= 1)\r\n ) {\r\n <div [ngStyle]=\"{ float: column().flexRight ? 'right' : 'none' }\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n (click)=\"\r\n $event.stopPropagation();\r\n action.action!(rowData(), rowIndex())\r\n \"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button\r\n class=\"action-icon-button\"\r\n type=\"button\"\r\n mat-icon-button\r\n [color]=\"\r\n actionIconColorDef[action.iconName]\r\n ? actionIconColorDef[action.iconName]\r\n : action.iconColor\r\n \"\r\n [matTooltip]=\"action.tooltipName || ''\"\r\n [matTooltipDisabled]=\"!action.tooltipName\"\r\n >\r\n <mat-icon>{{ action.iconName }}</mat-icon>\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </div>\r\n }\r\n @if (\r\n column().actionsInMenu || (mobileView && column().actions!.length > 1)\r\n ) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n [matMenuTriggerFor]=\"menu\"\r\n (click)=\"$event.stopPropagation()\"\r\n >\r\n <mat-icon>more_vert</mat-icon>\r\n </button>\r\n <mat-menu #menu=\"matMenu\">\r\n @for (action of column().actions; track action) {\r\n @if ((action.show && action.show(rowData())) || !action.show) {\r\n @if (!action.url && action.action) {\r\n <button\r\n type=\"button\"\r\n mat-menu-item\r\n (click)=\"$event.stopPropagation(); action.action!(rowData())\"\r\n >\r\n {{ action.tooltipName }}\r\n </button>\r\n }\r\n @if (action.url) {\r\n <a [routerLink]=\"action.url\">\r\n <button type=\"button\" mat-menu-item>\r\n {{ action.tooltipName }}\r\n </button>\r\n </a>\r\n }\r\n }\r\n }\r\n </mat-menu>\r\n }\r\n }\r\n }\r\n\r\n @case ('string') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('number') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('boolean') {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n }\r\n\r\n @case ('date') {\r\n @if (rowEditing && column().allowEditColumn) {\r\n <ng-container\r\n *ngTemplateOutlet=\"baseFieldCell; context: { $implicit: column() }\"\r\n ></ng-container>\r\n } @else {\r\n {{ rowData()[column().field] | stDateTimeFormatPipe }}\r\n }\r\n }\r\n\r\n @case ('actions-row-editing') {\r\n <div class=\"row justify-content-end\">\r\n @if (rowEditing) {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"accent\"\r\n (click)=\"saveRow()\"\r\n [matTooltip]=\"'Save row'\"\r\n >\r\n <mat-icon>done</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"cancelRow()\"\r\n [matTooltip]=\"'Cancel row'\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"primary\"\r\n (click)=\"editRow()\"\r\n [matTooltip]=\"'Edit row'\"\r\n [disabled]=\"\r\n canEditRowValidator() ? !canEditRowValidator()(rowData()) : false\r\n \"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n color=\"warn\"\r\n (click)=\"deleteRow()\"\r\n [matTooltip]=\"'Delete row'\"\r\n [disabled]=\"\r\n canDeleteRowValidator()\r\n ? !canDeleteRowValidator()(rowData())\r\n : false\r\n \"\r\n >\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @case ('actions-row-selecting') {\r\n <!-- @if (selectRowOnlyOne()) {-->\r\n <!-- <mat-radio-button-->\r\n <!-- color=\"primary\"-->\r\n <!-- (click)=\"$event.stopPropagation()\"-->\r\n <!-- (change)=\"selectRow({ checked: true })\"-->\r\n <!-- [checked]=\"rowIsSelected()\"-->\r\n <!-- ></mat-radio-button>-->\r\n <!-- } @else {-->\r\n <mat-checkbox\r\n color=\"primary\"\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"selectRow($event)\"\r\n [checked]=\"rowIsSelected()\"\r\n ></mat-checkbox>\r\n <!-- }-->\r\n }\r\n\r\n @case ('actions-row-extending') {\r\n @if (rowIsExpanded()) {\r\n <mat-icon>keyboard_arrow_up</mat-icon>\r\n } @else {\r\n <mat-icon>keyboard_arrow_down</mat-icon>\r\n }\r\n }\r\n}\r\n\r\n<ng-template #baseFieldCell let-column>\r\n @if ((rowEditing || autoSaveOnChange()) && column.allowEditColumn) {\r\n @if (column.rowEditType === 'string' || column.rowEditType === 'number') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [type]=\"column.rowEditType === 'string' ? 'text' : 'number'\"\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'date') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <input\r\n matInput\r\n [matDatepicker]=\"picker1\"\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n (keydown.enter)=\"!autoSaveOnChange() && saveRow()\"\r\n [required]=\"column.editColumnRequired\"\r\n />\r\n <mat-datepicker-toggle\r\n matIconSuffix\r\n [for]=\"picker1\"\r\n ></mat-datepicker-toggle>\r\n <mat-datepicker #picker1></mat-datepicker>\r\n </mat-form-field>\r\n }\r\n @if (column.rowEditType === 'boolean') {\r\n <mat-checkbox\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n ></mat-checkbox>\r\n }\r\n\r\n @if (column.rowEditType === 'custom') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n <mat-option value=\"\"></mat-option>\r\n @for (option of column.customRowEditOptions; track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n\r\n @if (column.rowEditType === 'custom-dynamic-select') {\r\n <mat-form-field\r\n appearance=\"outline\"\r\n [ngStyle]=\"{ width: column.width || 'auto' }\"\r\n >\r\n <mat-select\r\n [(ngModel)]=\"\r\n autoSaveOnChange()\r\n ? rowData()[column.field]\r\n : rowDataCopy()![column.field]\r\n \"\r\n (ngModelChange)=\"\r\n autoSaveOnChange() && onFieldChange(column.field, $event)\r\n \"\r\n [required]=\"column.editColumnRequired\"\r\n >\r\n @if (!column.editColumnRequired) {\r\n <mat-option value=\"\"></mat-option>\r\n }\r\n\r\n @for (option of dynamicSelectOptions(); track option) {\r\n <mat-option [value]=\"option.value\">\r\n {{ option.label }}\r\n </mat-option>\r\n }\r\n </mat-select>\r\n </mat-form-field>\r\n }\r\n } @else {\r\n <div>\r\n @if (column.translateValue) {\r\n {{ column.translateValue![rowData()[column.field]] || '' }}\r\n }\r\n @if (column.customValueDisplay) {\r\n {{ column.customValueDisplay(rowData()[column.field]) }}\r\n }\r\n @if (!column.translateValue && !column.customValueDisplay) {\r\n {{ rowData()[column.field] }}\r\n }\r\n </div>\r\n }\r\n</ng-template>\r\n" }]
125
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { matInput: [{
126
+ type: ViewChild,
127
+ args: [MatInput]
128
+ }], matSelect: [{
129
+ type: ViewChild,
130
+ args: [MatSelect]
131
+ }], rowEditing: [{
92
132
  type: Input
93
133
  }] } });
94
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsS0FBSyxFQUVMLEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0FBVXZCLE1BQU0sT0FBTyw2QkFBNkI7SUFtQnhDLElBQ0ksVUFBVSxDQUFDLElBQWE7UUFDMUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFFeEIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzlCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUE2QkQsWUFBb0IsaUJBQW9DO1FBQXBDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUExRHhELFdBQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUE4QixDQUFDO1FBRXRELFlBQU8sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUVwQixDQUFDO1FBRUwsYUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUVwQyxnQkFBVyxHQUFHLEtBQUssRUFFZixDQUFDO1FBRUwsd0JBQW1CLEdBQUcsS0FBSyxDQUF3QixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvRCwwQkFBcUIsR0FBRyxLQUFLLENBQXdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpFLHFCQUFnQixHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQWVqQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUVyQyxrQkFBYSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV0QyxrQkFBYSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV0Qyx1QkFBa0IsR0FBRyxNQUFNLEVBQVEsQ0FBQztRQUVwQyx5QkFBb0IsR0FBRyxNQUFNLEVBQVEsQ0FBQztRQUV0QyxtQkFBYyxHQUFHLE1BQU0sRUFBUSxDQUFDO1FBRWhDLHFCQUFnQixHQUFHLE1BQU0sRUFBUSxDQUFDO1FBRWxDLG9CQUFlLEdBQUcsTUFBTSxFQUFXLENBQUM7UUFFcEMsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUVuQix1QkFBa0IsR0FFZDtZQUNGLElBQUksRUFBRSxTQUFTO1lBQ2YsTUFBTSxFQUFFLE1BQU07U0FDZixDQUFDO1FBRUYseUJBQW9CLEdBQUcsTUFBTSxDQUFrQyxFQUFFLENBQUMsQ0FBQztJQUVSLENBQUM7SUFFNUQsUUFBUTtRQUNOLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUU7WUFDeEMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBMkI7UUFDbkMsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUM7UUFDcEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsSUFDRSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLGVBQWU7WUFDN0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFdBQVcsS0FBSyx1QkFBdUI7WUFDckQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLHFCQUFxQixFQUNuQyxDQUFDO1lBQ0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FDM0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLHFCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUNyRCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7K0dBekdVLDZCQUE2QjttR0FBN0IsNkJBQTZCLDJxRENuQjFDLG82VEE4U0E7OzRGRDNSYSw2QkFBNkI7a0JBTnpDLFNBQVM7K0JBQ0UsNEJBQTRCLG1CQUdyQix1QkFBdUIsQ0FBQyxNQUFNO3NGQXNCM0MsVUFBVTtzQkFEYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBDb21wb25lbnQsXHJcbiAgSW5wdXQsXHJcbiAgT25Jbml0LFxyXG4gIGlucHV0LFxyXG4gIG91dHB1dCxcclxuICBzaWduYWwsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN0TWF0ZXJpYWxUYWJsZUNvbHVtbk1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3N0LW1hdGVyaWFsLXRhYmxlLWNvbHVtbi5tb2RlbCc7XHJcbmltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc3QtbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9tYXRlcmlhbC10YWJsZS1yb3ctY2VsbC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnNjc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hdGVyaWFsVGFibGVSb3dDZWxsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICBjb2x1bW4gPSBpbnB1dC5yZXF1aXJlZDxTdE1hdGVyaWFsVGFibGVDb2x1bW5Nb2RlbD4oKTtcclxuXHJcbiAgcm93RGF0YSA9IGlucHV0LnJlcXVpcmVkPHtcclxuICAgIFtwcm9wOiBzdHJpbmddOiBhbnk7XHJcbiAgfT4oKTtcclxuXHJcbiAgcm93SW5kZXggPSBpbnB1dC5yZXF1aXJlZDxudW1iZXI+KCk7XHJcblxyXG4gIHJvd0RhdGFDb3B5ID0gaW5wdXQ8e1xyXG4gICAgW3Byb3A6IHN0cmluZ106IGFueTtcclxuICB9PigpO1xyXG5cclxuICBjYW5FZGl0Um93VmFsaWRhdG9yID0gaW5wdXQ8KHJvdzogYW55KSA9PiBib29sZWFuPigoKSA9PiB0cnVlKTtcclxuXHJcbiAgY2FuRGVsZXRlUm93VmFsaWRhdG9yID0gaW5wdXQ8KHJvdzogYW55KSA9PiBib29sZWFuPigoKSA9PiB0cnVlKTtcclxuXHJcbiAgc2VsZWN0Um93T25seU9uZSA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgQElucHV0KClcclxuICBzZXQgcm93RWRpdGluZyhkYXRhOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLl9yb3dFZGl0aW5nID0gZGF0YTtcclxuXHJcbiAgICBpZiAoZGF0YSkge1xyXG4gICAgICB0aGlzLmdldER5bmFtaWNTZWxlY3REYXRhKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgcm93RWRpdGluZygpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9yb3dFZGl0aW5nO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfcm93RWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICByb3dJc1NlbGVjdGVkID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG5cclxuICByb3dJc0V4cGFuZGVkID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG5cclxuICBzYXZlRWRpdFJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuXHJcbiAgY2FuY2VsRWRpdFJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuXHJcbiAgZWRpdFJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuXHJcbiAgZGVsZXRlUm93RW1pdHRlciA9IG91dHB1dDx2b2lkPigpO1xyXG5cclxuICBzZWxlY3RSb3dDaGFuZ2UgPSBvdXRwdXQ8Ym9vbGVhbj4oKTtcclxuXHJcbiAgbW9iaWxlVmlldyA9IGZhbHNlO1xyXG5cclxuICBhY3Rpb25JY29uQ29sb3JEZWY6IHtcclxuICAgIFtrZXk6IHN0cmluZ106ICdwcmltYXJ5JyB8ICd3YXJuJztcclxuICB9ID0ge1xyXG4gICAgZWRpdDogJ3ByaW1hcnknLFxyXG4gICAgZGVsZXRlOiAnd2FybicsXHJcbiAgfTtcclxuXHJcbiAgZHluYW1pY1NlbGVjdE9wdGlvbnMgPSBzaWduYWw8eyB2YWx1ZTogYW55OyBsYWJlbDogc3RyaW5nIH1bXT4oW10pO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge31cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgZXZlbnQgPT4ge1xyXG4gICAgICB0aGlzLmNoZWNrV2lkdGhTaXplKCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNhdmVSb3coKSB7XHJcbiAgICB0aGlzLnNhdmVFZGl0Um93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBjYW5jZWxSb3coKSB7XHJcbiAgICB0aGlzLmNhbmNlbEVkaXRSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGVkaXRSb3coKSB7XHJcbiAgICB0aGlzLmVkaXRSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGRlbGV0ZVJvdygpIHtcclxuICAgIHRoaXMuZGVsZXRlUm93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RSb3coZXZlbnQ6IHsgY2hlY2tlZDogYm9vbGVhbiB9KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgdGhpcy5zZWxlY3RSb3dDaGFuZ2UuZW1pdChldmVudC5jaGVja2VkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hlY2tXaWR0aFNpemUoKSB7XHJcbiAgICB0aGlzLm1vYmlsZVZpZXcgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDw9IDExMDA7XHJcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXREeW5hbWljU2VsZWN0RGF0YSgpIHtcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5jb2x1bW4oKSAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLmFsbG93RWRpdENvbHVtbiAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLnJvd0VkaXRUeXBlID09PSAnY3VzdG9tLWR5bmFtaWMtc2VsZWN0JyAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLmR5bmFtaWNSb3dFZGl0T3B0aW9uc1xyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuZHluYW1pY1NlbGVjdE9wdGlvbnMuc2V0KFxyXG4gICAgICAgIHRoaXMuY29sdW1uKCkuZHluYW1pY1Jvd0VkaXRPcHRpb25zISh0aGlzLnJvd0RhdGEoKSlcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiQHN3aXRjaCAoY29sdW1uKCkudHlwZSB8fCAnc3RyaW5nJykge1xyXG4gIEBjYXNlICgnY3VzdG9tLXRlbXBsYXRlJykge1xyXG4gICAgQGlmIChyb3dFZGl0aW5nICYmIGNvbHVtbigpLmFsbG93RWRpdENvbHVtbikge1xyXG4gICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJiYXNlRmllbGRDZWxsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogY29sdW1uKCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH0gQGVsc2Uge1xyXG4gICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sdW1uKCkuY3VzdG9tVGVtcGxhdGUhXCJcclxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBkYXRhOiByb3dEYXRhKCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBjYXNlICgnYWN0aW9ucycpIHtcclxuICAgIEBpZiAoY29sdW1uKCkuYWN0aW9ucykge1xyXG4gICAgICBAaWYgKFxyXG4gICAgICAgICghY29sdW1uKCkuYWN0aW9uc0luTWVudSAmJiAhbW9iaWxlVmlldykgfHxcclxuICAgICAgICAobW9iaWxlVmlldyAmJiBjb2x1bW4oKS5hY3Rpb25zIS5sZW5ndGggPD0gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJ7IGZsb2F0OiBjb2x1bW4oKS5mbGV4UmlnaHQgPyAncmlnaHQnIDogJ25vbmUnIH1cIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWN0aW9uLWljb24tYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICBbY29sb3JdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgID8gYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgIDogYWN0aW9uLmljb25Db2xvclxyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJhY3Rpb24udG9vbHRpcE5hbWUgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcERpc2FibGVkXT1cIiFhY3Rpb24udG9vbHRpcE5hbWVcIlxyXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSwgcm93SW5kZXgoKSlcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7IGFjdGlvbi5pY29uTmFtZSB9fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgQGlmIChhY3Rpb24udXJsKSB7XHJcbiAgICAgICAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJhY3Rpb24udXJsXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1pY29uLWJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgW2NvbG9yXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBhY3Rpb25JY29uQ29sb3JEZWZbYWN0aW9uLmljb25OYW1lXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFjdGlvbi5pY29uQ29sb3JcclxuICAgICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImFjdGlvbi50b29sdGlwTmFtZSB8fCAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBEaXNhYmxlZF09XCIhYWN0aW9uLnRvb2x0aXBOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57eyBhY3Rpb24uaWNvbk5hbWUgfX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG4gICAgICBAaWYgKFxyXG4gICAgICAgIGNvbHVtbigpLmFjdGlvbnNJbk1lbnUgfHwgKG1vYmlsZVZpZXcgJiYgY29sdW1uKCkuYWN0aW9ucyEubGVuZ3RoID4gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJtZW51XCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxtYXQtbWVudSAjbWVudT1cIm1hdE1lbnVcIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBtYXQtbWVudS1pdGVtXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSlcIlxyXG4gICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBAaWYgKGFjdGlvbi51cmwpIHtcclxuICAgICAgICAgICAgICAgIDxhIFtyb3V0ZXJMaW5rXT1cImFjdGlvbi51cmxcIj5cclxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LW1lbnUtaXRlbT5cclxuICAgICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9tYXQtbWVudT5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdzdHJpbmcnKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdudW1iZXInKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdib29sZWFuJykge1xyXG4gICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImJhc2VGaWVsZENlbGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4oKSB9XCJcclxuICAgID48L25nLWNvbnRhaW5lcj5cclxuICB9XHJcblxyXG4gIEBjYXNlICgnZGF0ZScpIHtcclxuICAgIEBpZiAocm93RWRpdGluZyAmJiBjb2x1bW4oKS5hbGxvd0VkaXRDb2x1bW4pIHtcclxuICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgICA+PC9uZy1jb250YWluZXI+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgICAge3sgcm93RGF0YSgpW2NvbHVtbigpLmZpZWxkXSB8IHN0RGF0ZVRpbWVGb3JtYXRQaXBlIH19XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LWVkaXRpbmcnKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwicm93IGp1c3RpZnktY29udGVudC1lbmRcIj5cclxuICAgICAgQGlmIChyb3dFZGl0aW5nKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwiYWNjZW50XCJcclxuICAgICAgICAgIChjbGljayk9XCJzYXZlUm93KClcIlxyXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ1NhdmUgcm93J1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPmRvbmU8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b25cclxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICBjb2xvcj1cIndhcm5cIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImNhbmNlbFJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidDYW5jZWwgcm93J1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiZWRpdFJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidFZGl0IHJvdydcIlxyXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxyXG4gICAgICAgICAgICBjYW5FZGl0Um93VmFsaWRhdG9yKCkgPyAhY2FuRWRpdFJvd1ZhbGlkYXRvcigpKHJvd0RhdGEoKSkgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24+ZWRpdDwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlUm93KClcIlxyXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0RlbGV0ZSByb3cnXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY2FuRGVsZXRlUm93VmFsaWRhdG9yKClcclxuICAgICAgICAgICAgICA/ICFjYW5EZWxldGVSb3dWYWxpZGF0b3IoKShyb3dEYXRhKCkpXHJcbiAgICAgICAgICAgICAgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgfVxyXG4gICAgPC9kaXY+XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LXNlbGVjdGluZycpIHtcclxuICAgIDwhLS0gICAgQGlmIChzZWxlY3RSb3dPbmx5T25lKCkpIHstLT5cclxuICAgIDwhLS0gICAgICA8bWF0LXJhZGlvLWJ1dHRvbi0tPlxyXG4gICAgPCEtLSAgICAgICAgY29sb3I9XCJwcmltYXJ5XCItLT5cclxuICAgIDwhLS0gICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIi0tPlxyXG4gICAgPCEtLSAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RSb3coeyBjaGVja2VkOiB0cnVlIH0pXCItLT5cclxuICAgIDwhLS0gICAgICAgIFtjaGVja2VkXT1cInJvd0lzU2VsZWN0ZWQoKVwiLS0+XHJcbiAgICA8IS0tICAgICAgPjwvbWF0LXJhZGlvLWJ1dHRvbj4tLT5cclxuICAgIDwhLS0gICAgfSBAZWxzZSB7LS0+XHJcbiAgICA8bWF0LWNoZWNrYm94XHJcbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAoY2hhbmdlKT1cInNlbGVjdFJvdygkZXZlbnQpXCJcclxuICAgICAgW2NoZWNrZWRdPVwicm93SXNTZWxlY3RlZCgpXCJcclxuICAgID48L21hdC1jaGVja2JveD5cclxuICAgIDwhLS0gICAgfS0tPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zLXJvdy1leHRlbmRpbmcnKSB7XHJcbiAgICBAaWYgKHJvd0lzRXhwYW5kZWQoKSkge1xyXG4gICAgICA8bWF0LWljb24+a2V5Ym9hcmRfYXJyb3dfdXA8L21hdC1pY29uPlxyXG4gICAgfSBAZWxzZSB7XHJcbiAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbjxuZy10ZW1wbGF0ZSAjYmFzZUZpZWxkQ2VsbCBsZXQtY29sdW1uPlxyXG4gIEBpZiAocm93RWRpdGluZyAmJiBjb2x1bW4uYWxsb3dFZGl0Q29sdW1uKSB7XHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ3N0cmluZycgfHwgY29sdW1uLnJvd0VkaXRUeXBlID09PSAnbnVtYmVyJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFt0eXBlXT1cImNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ3N0cmluZycgPyAndGV4dCcgOiAnbnVtYmVyJ1wiXHJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvd0RhdGFDb3B5KCkhW2NvbHVtbi5maWVsZF1cIlxyXG4gICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwic2F2ZVJvdygpXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgfVxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdkYXRlJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFttYXREYXRlcGlja2VyXT1cInBpY2tlcjFcIlxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhQ29weSgpIVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cInNhdmVSb3coKVwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgLz5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXItdG9nZ2xlXHJcbiAgICAgICAgICBtYXRJY29uU3VmZml4XHJcbiAgICAgICAgICBbZm9yXT1cInBpY2tlcjFcIlxyXG4gICAgICAgID48L21hdC1kYXRlcGlja2VyLXRvZ2dsZT5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI3BpY2tlcjE+PC9tYXQtZGF0ZXBpY2tlcj5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgPG1hdC1jaGVja2JveCBbKG5nTW9kZWwpXT1cInJvd0RhdGFDb3B5KCkhW2NvbHVtbi5maWVsZF1cIj48L21hdC1jaGVja2JveD5cclxuICAgIH1cclxuXHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ2N1c3RvbScpIHtcclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgYXBwZWFyYW5jZT1cIm91dGxpbmVcIlxyXG4gICAgICAgIFtuZ1N0eWxlXT1cInsgd2lkdGg6IGNvbHVtbi53aWR0aCB8fCAnYXV0bycgfVwiXHJcbiAgICAgID5cclxuICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3dEYXRhQ29weSgpIVtjb2x1bW4uZmllbGRdXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBjb2x1bW4uY3VzdG9tUm93RWRpdE9wdGlvbnM7IHRyYWNrIG9wdGlvbikge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcblxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdjdXN0b20tZHluYW1pYy1zZWxlY3QnKSB7XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggfHwgJ2F1dG8nIH1cIlxyXG4gICAgICA+XHJcbiAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwicm93RGF0YUNvcHkoKSFbY29sdW1uLmZpZWxkXVwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgQGlmICghY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZCkge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZHluYW1pY1NlbGVjdE9wdGlvbnMoKTsgdHJhY2sgb3B0aW9uKSB7XHJcbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cclxuICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cclxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICB9IEBlbHNlIHtcclxuICAgIDxkaXY+XHJcbiAgICAgIEBpZiAoY29sdW1uLnRyYW5zbGF0ZVZhbHVlKSB7XHJcbiAgICAgICAge3sgY29sdW1uLnRyYW5zbGF0ZVZhbHVlIVtyb3dEYXRhKClbY29sdW1uLmZpZWxkXV0gfHwgJycgfX1cclxuICAgICAgfVxyXG4gICAgICBAaWYgKGNvbHVtbi5jdXN0b21WYWx1ZURpc3BsYXkpIHtcclxuICAgICAgICB7eyBjb2x1bW4uY3VzdG9tVmFsdWVEaXNwbGF5KHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdKSB9fVxyXG4gICAgICB9XHJcbiAgICAgIEBpZiAoIWNvbHVtbi50cmFuc2xhdGVWYWx1ZSAmJiAhY29sdW1uLmN1c3RvbVZhbHVlRGlzcGxheSkge1xyXG4gICAgICAgIHt7IHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdIH19XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuPC9uZy10ZW1wbGF0ZT5cclxuIl19
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0LXRhYmxlcy9zcmMvbGliL2NvbXBvbmVudHMvbWF0ZXJpYWwtdGFibGUvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwvbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsS0FBSyxFQUVMLEtBQUssRUFDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsR0FFVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0FBUXJELE1BQU0sT0FBTyw2QkFBNkI7SUF5QnhDLElBQ0ksVUFBVSxDQUFDLElBQWE7UUFDMUIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBRXhCLElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUU1QixxREFBcUQ7WUFDckQsSUFBSSxhQUFhLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUErQkQsWUFBb0IsaUJBQW9DO1FBQXBDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUF0RXhELFdBQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUE4QixDQUFDO1FBRXRELFlBQU8sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUVwQixDQUFDO1FBRUwsYUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUVwQyxnQkFBVyxHQUFHLEtBQUssRUFFZixDQUFDO1FBRUwsd0JBQW1CLEdBQUcsS0FBSyxDQUF3QixHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUvRCwwQkFBcUIsR0FBRyxLQUFLLENBQXdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpFLHFCQUFnQixHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV6QywwQkFBcUIsR0FBRyxLQUFLLENBQVUsS0FBSyxDQUFDLENBQUM7UUFFOUMscUJBQWdCLEdBQUcsS0FBSyxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBcUJqQyxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUVyQyxrQkFBYSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV0QyxrQkFBYSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV0Qyx1QkFBa0IsR0FBRyxNQUFNLEVBQVEsQ0FBQztRQUVwQyx5QkFBb0IsR0FBRyxNQUFNLEVBQVEsQ0FBQztRQUV0QyxtQkFBYyxHQUFHLE1BQU0sRUFBUSxDQUFDO1FBRWhDLHFCQUFnQixHQUFHLE1BQU0sRUFBUSxDQUFDO1FBRWxDLG9CQUFlLEdBQUcsTUFBTSxFQUFXLENBQUM7UUFFcEMsc0JBQWlCLEdBQUcsTUFBTSxFQUFpQyxDQUFDO1FBRTVELGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFbkIsdUJBQWtCLEdBRWQ7WUFDRixJQUFJLEVBQUUsU0FBUztZQUNmLE1BQU0sRUFBRSxNQUFNO1NBQ2YsQ0FBQztRQUVGLHlCQUFvQixHQUFHLE1BQU0sQ0FBa0MsRUFBRSxDQUFDLENBQUM7SUFFUixDQUFDO0lBRTVELFFBQVE7UUFDTixNQUFNLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxlQUFlO1FBQ2Isa0ZBQWtGO1FBQ2xGLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsRUFBRSxDQUFDO1lBQ3BELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0lBRU8sdUJBQXVCO1FBQzdCLHNEQUFzRDtRQUN0RCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2xCLGlCQUFpQjtnQkFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4QixDQUFDO2lCQUFNLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUMxQixrQkFBa0I7Z0JBQ2xCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNWLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsU0FBUztRQUNQLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQsU0FBUyxDQUFDLEtBQTJCO1FBQ25DLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRCxhQUFhLENBQUMsS0FBYSxFQUFFLEtBQVU7UUFDckMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNoRCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGNBQWM7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUM7UUFDcEQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsSUFDRSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLGVBQWU7WUFDN0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFdBQVcsS0FBSyx1QkFBdUI7WUFDckQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLHFCQUFxQixFQUNuQyxDQUFDO1lBQ0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FDM0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLHFCQUFzQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUNyRCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7K0dBakpVLDZCQUE2QjttR0FBN0IsNkJBQTZCLDhqRUFDN0IsUUFBUSw0RUFDUixTQUFTLGdEQ3hCdEIseW5XQW1WQTs7NEZEN1RhLDZCQUE2QjtrQkFOekMsU0FBUzsrQkFDRSw0QkFBNEIsbUJBR3JCLHVCQUF1QixDQUFDLE1BQU07c0ZBRzFCLFFBQVE7c0JBQTVCLFNBQVM7dUJBQUMsUUFBUTtnQkFDRyxTQUFTO3NCQUE5QixTQUFTO3VCQUFDLFNBQVM7Z0JBd0JoQixVQUFVO3NCQURiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgaW5wdXQsXHJcbiAgb3V0cHV0LFxyXG4gIHNpZ25hbCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3RNYXRlcmlhbFRhYmxlQ29sdW1uTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvc3QtbWF0ZXJpYWwtdGFibGUtY29sdW1uLm1vZGVsJztcclxuaW1wb3J0IHsgTWF0SW5wdXQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XHJcbmltcG9ydCB7IE1hdFNlbGVjdCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3N0LW1hdGVyaWFsLXRhYmxlLXJvdy1jZWxsJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vbWF0ZXJpYWwtdGFibGUtcm93LWNlbGwuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL21hdGVyaWFsLXRhYmxlLXJvdy1jZWxsLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRlcmlhbFRhYmxlUm93Q2VsbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XHJcbiAgQFZpZXdDaGlsZChNYXRJbnB1dCkgbWF0SW5wdXQ/OiBNYXRJbnB1dDtcclxuICBAVmlld0NoaWxkKE1hdFNlbGVjdCkgbWF0U2VsZWN0PzogTWF0U2VsZWN0O1xyXG4gIGNvbHVtbiA9IGlucHV0LnJlcXVpcmVkPFN0TWF0ZXJpYWxUYWJsZUNvbHVtbk1vZGVsPigpO1xyXG5cclxuICByb3dEYXRhID0gaW5wdXQucmVxdWlyZWQ8e1xyXG4gICAgW3Byb3A6IHN0cmluZ106IGFueTtcclxuICB9PigpO1xyXG5cclxuICByb3dJbmRleCA9IGlucHV0LnJlcXVpcmVkPG51bWJlcj4oKTtcclxuXHJcbiAgcm93RGF0YUNvcHkgPSBpbnB1dDx7XHJcbiAgICBbcHJvcDogc3RyaW5nXTogYW55O1xyXG4gIH0+KCk7XHJcblxyXG4gIGNhbkVkaXRSb3dWYWxpZGF0b3IgPSBpbnB1dDwocm93OiBhbnkpID0+IGJvb2xlYW4+KCgpID0+IHRydWUpO1xyXG5cclxuICBjYW5EZWxldGVSb3dWYWxpZGF0b3IgPSBpbnB1dDwocm93OiBhbnkpID0+IGJvb2xlYW4+KCgpID0+IHRydWUpO1xyXG5cclxuICBzZWxlY3RSb3dPbmx5T25lID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xyXG5cclxuICBpc0ZpcnN0RWRpdGFibGVDb2x1bW4gPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcblxyXG4gIGF1dG9TYXZlT25DaGFuZ2UgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHJvd0VkaXRpbmcoZGF0YTogYm9vbGVhbikge1xyXG4gICAgY29uc3Qgd2FzTm90RWRpdGluZyA9ICF0aGlzLl9yb3dFZGl0aW5nO1xyXG4gICAgdGhpcy5fcm93RWRpdGluZyA9IGRhdGE7XHJcblxyXG4gICAgaWYgKGRhdGEpIHtcclxuICAgICAgdGhpcy5nZXREeW5hbWljU2VsZWN0RGF0YSgpO1xyXG5cclxuICAgICAgLy8gRm9jdXMgZmlyc3QgZWRpdGFibGUgZmllbGQgd2hlbiBlbnRlcmluZyBlZGl0IG1vZGVcclxuICAgICAgaWYgKHdhc05vdEVkaXRpbmcgJiYgdGhpcy5pc0ZpcnN0RWRpdGFibGVDb2x1bW4oKSkge1xyXG4gICAgICAgIHRoaXMuZm9jdXNGaXJzdEVkaXRhYmxlRmllbGQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IHJvd0VkaXRpbmcoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fcm93RWRpdGluZztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3Jvd0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcm93SXNTZWxlY3RlZCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgcm93SXNFeHBhbmRlZCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgc2F2ZUVkaXRSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcblxyXG4gIGNhbmNlbEVkaXRSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcblxyXG4gIGVkaXRSb3dFbWl0dGVyID0gb3V0cHV0PHZvaWQ+KCk7XHJcblxyXG4gIGRlbGV0ZVJvd0VtaXR0ZXIgPSBvdXRwdXQ8dm9pZD4oKTtcclxuXHJcbiAgc2VsZWN0Um93Q2hhbmdlID0gb3V0cHV0PGJvb2xlYW4+KCk7XHJcblxyXG4gIGZpZWxkVmFsdWVDaGFuZ2VkID0gb3V0cHV0PHsgZmllbGQ6IHN0cmluZzsgdmFsdWU6IGFueSB9PigpO1xyXG5cclxuICBtb2JpbGVWaWV3ID0gZmFsc2U7XHJcblxyXG4gIGFjdGlvbkljb25Db2xvckRlZjoge1xyXG4gICAgW2tleTogc3RyaW5nXTogJ3ByaW1hcnknIHwgJ3dhcm4nO1xyXG4gIH0gPSB7XHJcbiAgICBlZGl0OiAncHJpbWFyeScsXHJcbiAgICBkZWxldGU6ICd3YXJuJyxcclxuICB9O1xyXG5cclxuICBkeW5hbWljU2VsZWN0T3B0aW9ucyA9IHNpZ25hbDx7IHZhbHVlOiBhbnk7IGxhYmVsOiBzdHJpbmcgfVtdPihbXSk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBldmVudCA9PiB7XHJcbiAgICAgIHRoaXMuY2hlY2tXaWR0aFNpemUoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgLy8gSWYgcm93IGlzIGFscmVhZHkgaW4gZWRpdCBtb2RlIG9uIGluaXQgKGUuZy4sIG5ld2x5IGFkZGVkIHJvdyksIGZvY3VzIHRoZSBmaWVsZFxyXG4gICAgaWYgKHRoaXMucm93RWRpdGluZyAmJiB0aGlzLmlzRmlyc3RFZGl0YWJsZUNvbHVtbigpKSB7XHJcbiAgICAgIHRoaXMuZm9jdXNGaXJzdEVkaXRhYmxlRmllbGQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZm9jdXNGaXJzdEVkaXRhYmxlRmllbGQoKSB7XHJcbiAgICAvLyBVc2Ugc2V0VGltZW91dCB0byBlbnN1cmUgdGhlIHZpZXcgaXMgZnVsbHkgcmVuZGVyZWRcclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5tYXRJbnB1dCkge1xyXG4gICAgICAgIC8vIEZvY3VzIE1hdElucHV0XHJcbiAgICAgICAgdGhpcy5tYXRJbnB1dC5mb2N1cygpO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMubWF0U2VsZWN0KSB7XHJcbiAgICAgICAgLy8gRm9jdXMgTWF0U2VsZWN0XHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3QuZm9jdXMoKTtcclxuICAgICAgfVxyXG4gICAgfSwgMTUwKTtcclxuICB9XHJcblxyXG4gIHNhdmVSb3coKSB7XHJcbiAgICB0aGlzLnNhdmVFZGl0Um93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBjYW5jZWxSb3coKSB7XHJcbiAgICB0aGlzLmNhbmNlbEVkaXRSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGVkaXRSb3coKSB7XHJcbiAgICB0aGlzLmVkaXRSb3dFbWl0dGVyLmVtaXQoKTtcclxuICB9XHJcblxyXG4gIGRlbGV0ZVJvdygpIHtcclxuICAgIHRoaXMuZGVsZXRlUm93RW1pdHRlci5lbWl0KCk7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RSb3coZXZlbnQ6IHsgY2hlY2tlZDogYm9vbGVhbiB9KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgdGhpcy5zZWxlY3RSb3dDaGFuZ2UuZW1pdChldmVudC5jaGVja2VkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uRmllbGRDaGFuZ2UoZmllbGQ6IHN0cmluZywgdmFsdWU6IGFueSkge1xyXG4gICAgaWYgKHRoaXMuYXV0b1NhdmVPbkNoYW5nZSgpKSB7XHJcbiAgICAgIHRoaXMuZmllbGRWYWx1ZUNoYW5nZWQuZW1pdCh7IGZpZWxkLCB2YWx1ZSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hlY2tXaWR0aFNpemUoKSB7XHJcbiAgICB0aGlzLm1vYmlsZVZpZXcgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDw9IDExMDA7XHJcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXREeW5hbWljU2VsZWN0RGF0YSgpIHtcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5jb2x1bW4oKSAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLmFsbG93RWRpdENvbHVtbiAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLnJvd0VkaXRUeXBlID09PSAnY3VzdG9tLWR5bmFtaWMtc2VsZWN0JyAmJlxyXG4gICAgICB0aGlzLmNvbHVtbigpLmR5bmFtaWNSb3dFZGl0T3B0aW9uc1xyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuZHluYW1pY1NlbGVjdE9wdGlvbnMuc2V0KFxyXG4gICAgICAgIHRoaXMuY29sdW1uKCkuZHluYW1pY1Jvd0VkaXRPcHRpb25zISh0aGlzLnJvd0RhdGEoKSlcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiQHN3aXRjaCAoY29sdW1uKCkudHlwZSB8fCAnc3RyaW5nJykge1xyXG4gIEBjYXNlICgnY3VzdG9tLXRlbXBsYXRlJykge1xyXG4gICAgQGlmIChyb3dFZGl0aW5nICYmIGNvbHVtbigpLmFsbG93RWRpdENvbHVtbikge1xyXG4gICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJiYXNlRmllbGRDZWxsOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogY29sdW1uKCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH0gQGVsc2Uge1xyXG4gICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sdW1uKCkuY3VzdG9tVGVtcGxhdGUhXCJcclxuICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyBkYXRhOiByb3dEYXRhKCkgfVwiXHJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBjYXNlICgnYWN0aW9ucycpIHtcclxuICAgIEBpZiAoY29sdW1uKCkuYWN0aW9ucykge1xyXG4gICAgICBAaWYgKFxyXG4gICAgICAgICghY29sdW1uKCkuYWN0aW9uc0luTWVudSAmJiAhbW9iaWxlVmlldykgfHxcclxuICAgICAgICAobW9iaWxlVmlldyAmJiBjb2x1bW4oKS5hY3Rpb25zIS5sZW5ndGggPD0gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGRpdiBbbmdTdHlsZV09XCJ7IGZsb2F0OiBjb2x1bW4oKS5mbGV4UmlnaHQgPyAncmlnaHQnIDogJ25vbmUnIH1cIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWN0aW9uLWljb24tYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICBbY29sb3JdPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgID8gYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgIDogYWN0aW9uLmljb25Db2xvclxyXG4gICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJhY3Rpb24udG9vbHRpcE5hbWUgfHwgJydcIlxyXG4gICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcERpc2FibGVkXT1cIiFhY3Rpb24udG9vbHRpcE5hbWVcIlxyXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiXHJcbiAgICAgICAgICAgICAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSwgcm93SW5kZXgoKSlcclxuICAgICAgICAgICAgICAgICAgXCJcclxuICAgICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPnt7IGFjdGlvbi5pY29uTmFtZSB9fTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgQGlmIChhY3Rpb24udXJsKSB7XHJcbiAgICAgICAgICAgICAgICA8YSBbcm91dGVyTGlua109XCJhY3Rpb24udXJsXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjdGlvbi1pY29uLWJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgW2NvbG9yXT1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWNvbkNvbG9yRGVmW2FjdGlvbi5pY29uTmFtZV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBhY3Rpb25JY29uQ29sb3JEZWZbYWN0aW9uLmljb25OYW1lXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFjdGlvbi5pY29uQ29sb3JcclxuICAgICAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImFjdGlvbi50b29sdGlwTmFtZSB8fCAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBEaXNhYmxlZF09XCIhYWN0aW9uLnRvb2x0aXBOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj57eyBhY3Rpb24uaWNvbk5hbWUgfX08L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgfVxyXG4gICAgICBAaWYgKFxyXG4gICAgICAgIGNvbHVtbigpLmFjdGlvbnNJbk1lbnUgfHwgKG1vYmlsZVZpZXcgJiYgY29sdW1uKCkuYWN0aW9ucyEubGVuZ3RoID4gMSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIFttYXRNZW51VHJpZ2dlckZvcl09XCJtZW51XCJcclxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxtYXQtbWVudSAjbWVudT1cIm1hdE1lbnVcIj5cclxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBjb2x1bW4oKS5hY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcclxuICAgICAgICAgICAgQGlmICgoYWN0aW9uLnNob3cgJiYgYWN0aW9uLnNob3cocm93RGF0YSgpKSkgfHwgIWFjdGlvbi5zaG93KSB7XHJcbiAgICAgICAgICAgICAgQGlmICghYWN0aW9uLnVybCAmJiBhY3Rpb24uYWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICBtYXQtbWVudS1pdGVtXHJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGFjdGlvbi5hY3Rpb24hKHJvd0RhdGEoKSlcIlxyXG4gICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBAaWYgKGFjdGlvbi51cmwpIHtcclxuICAgICAgICAgICAgICAgIDxhIFtyb3V0ZXJMaW5rXT1cImFjdGlvbi51cmxcIj5cclxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LW1lbnUtaXRlbT5cclxuICAgICAgICAgICAgICAgICAgICB7eyBhY3Rpb24udG9vbHRpcE5hbWUgfX1cclxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgPC9tYXQtbWVudT5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdzdHJpbmcnKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdudW1iZXInKSB7XHJcbiAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgPjwvbmctY29udGFpbmVyPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdib29sZWFuJykge1xyXG4gICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAqbmdUZW1wbGF0ZU91dGxldD1cImJhc2VGaWVsZENlbGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBjb2x1bW4oKSB9XCJcclxuICAgID48L25nLWNvbnRhaW5lcj5cclxuICB9XHJcblxyXG4gIEBjYXNlICgnZGF0ZScpIHtcclxuICAgIEBpZiAocm93RWRpdGluZyAmJiBjb2x1bW4oKS5hbGxvd0VkaXRDb2x1bW4pIHtcclxuICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYmFzZUZpZWxkQ2VsbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGNvbHVtbigpIH1cIlxyXG4gICAgICA+PC9uZy1jb250YWluZXI+XHJcbiAgICB9IEBlbHNlIHtcclxuICAgICAge3sgcm93RGF0YSgpW2NvbHVtbigpLmZpZWxkXSB8IHN0RGF0ZVRpbWVGb3JtYXRQaXBlIH19XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LWVkaXRpbmcnKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwicm93IGp1c3RpZnktY29udGVudC1lbmRcIj5cclxuICAgICAgQGlmIChyb3dFZGl0aW5nKSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwiYWNjZW50XCJcclxuICAgICAgICAgIChjbGljayk9XCJzYXZlUm93KClcIlxyXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ1NhdmUgcm93J1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPmRvbmU8L21hdC1pY29uPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b25cclxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICBjb2xvcj1cIndhcm5cIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImNhbmNlbFJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidDYW5jZWwgcm93J1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiZWRpdFJvdygpXCJcclxuICAgICAgICAgIFttYXRUb29sdGlwXT1cIidFZGl0IHJvdydcIlxyXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxyXG4gICAgICAgICAgICBjYW5FZGl0Um93VmFsaWRhdG9yKCkgPyAhY2FuRWRpdFJvd1ZhbGlkYXRvcigpKHJvd0RhdGEoKSkgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24+ZWRpdDwvbWF0LWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cclxuICAgICAgICAgIGNvbG9yPVwid2FyblwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlUm93KClcIlxyXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0RlbGV0ZSByb3cnXCJcclxuICAgICAgICAgIFtkaXNhYmxlZF09XCJcclxuICAgICAgICAgICAgY2FuRGVsZXRlUm93VmFsaWRhdG9yKClcclxuICAgICAgICAgICAgICA/ICFjYW5EZWxldGVSb3dWYWxpZGF0b3IoKShyb3dEYXRhKCkpXHJcbiAgICAgICAgICAgICAgOiBmYWxzZVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LWljb24+ZGVsZXRlPC9tYXQtaWNvbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgfVxyXG4gICAgPC9kaXY+XHJcbiAgfVxyXG5cclxuICBAY2FzZSAoJ2FjdGlvbnMtcm93LXNlbGVjdGluZycpIHtcclxuICAgIDwhLS0gICAgQGlmIChzZWxlY3RSb3dPbmx5T25lKCkpIHstLT5cclxuICAgIDwhLS0gICAgICA8bWF0LXJhZGlvLWJ1dHRvbi0tPlxyXG4gICAgPCEtLSAgICAgICAgY29sb3I9XCJwcmltYXJ5XCItLT5cclxuICAgIDwhLS0gICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIi0tPlxyXG4gICAgPCEtLSAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RSb3coeyBjaGVja2VkOiB0cnVlIH0pXCItLT5cclxuICAgIDwhLS0gICAgICAgIFtjaGVja2VkXT1cInJvd0lzU2VsZWN0ZWQoKVwiLS0+XHJcbiAgICA8IS0tICAgICAgPjwvbWF0LXJhZGlvLWJ1dHRvbj4tLT5cclxuICAgIDwhLS0gICAgfSBAZWxzZSB7LS0+XHJcbiAgICA8bWF0LWNoZWNrYm94XHJcbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXHJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gICAgICAoY2hhbmdlKT1cInNlbGVjdFJvdygkZXZlbnQpXCJcclxuICAgICAgW2NoZWNrZWRdPVwicm93SXNTZWxlY3RlZCgpXCJcclxuICAgID48L21hdC1jaGVja2JveD5cclxuICAgIDwhLS0gICAgfS0tPlxyXG4gIH1cclxuXHJcbiAgQGNhc2UgKCdhY3Rpb25zLXJvdy1leHRlbmRpbmcnKSB7XHJcbiAgICBAaWYgKHJvd0lzRXhwYW5kZWQoKSkge1xyXG4gICAgICA8bWF0LWljb24+a2V5Ym9hcmRfYXJyb3dfdXA8L21hdC1pY29uPlxyXG4gICAgfSBAZWxzZSB7XHJcbiAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbjxuZy10ZW1wbGF0ZSAjYmFzZUZpZWxkQ2VsbCBsZXQtY29sdW1uPlxyXG4gIEBpZiAoKHJvd0VkaXRpbmcgfHwgYXV0b1NhdmVPbkNoYW5nZSgpKSAmJiBjb2x1bW4uYWxsb3dFZGl0Q29sdW1uKSB7XHJcbiAgICBAaWYgKGNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ3N0cmluZycgfHwgY29sdW1uLnJvd0VkaXRUeXBlID09PSAnbnVtYmVyJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFt0eXBlXT1cImNvbHVtbi5yb3dFZGl0VHlwZSA9PT0gJ3N0cmluZycgPyAndGV4dCcgOiAnbnVtYmVyJ1wiXHJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cIlxyXG4gICAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKClcclxuICAgICAgICAgICAgICA/IHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdXHJcbiAgICAgICAgICAgICAgOiByb3dEYXRhQ29weSgpIVtjb2x1bW4uZmllbGRdXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cIiFhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgc2F2ZVJvdygpXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgfVxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdkYXRlJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFttYXREYXRlcGlja2VyXT1cInBpY2tlcjFcIlxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJcclxuICAgICAgICAgICAgYXV0b1NhdmVPbkNoYW5nZSgpXHJcbiAgICAgICAgICAgICAgPyByb3dEYXRhKClbY29sdW1uLmZpZWxkXVxyXG4gICAgICAgICAgICAgIDogcm93RGF0YUNvcHkoKSFbY29sdW1uLmZpZWxkXVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxyXG4gICAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKCkgJiYgb25GaWVsZENoYW5nZShjb2x1bW4uZmllbGQsICRldmVudClcclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCIhYXV0b1NhdmVPbkNoYW5nZSgpICYmIHNhdmVSb3coKVwiXHJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwiY29sdW1uLmVkaXRDb2x1bW5SZXF1aXJlZFwiXHJcbiAgICAgICAgLz5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXItdG9nZ2xlXHJcbiAgICAgICAgICBtYXRJY29uU3VmZml4XHJcbiAgICAgICAgICBbZm9yXT1cInBpY2tlcjFcIlxyXG4gICAgICAgID48L21hdC1kYXRlcGlja2VyLXRvZ2dsZT5cclxuICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI3BpY2tlcjE+PC9tYXQtZGF0ZXBpY2tlcj5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgIH1cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgPG1hdC1jaGVja2JveFxyXG4gICAgICAgIFsobmdNb2RlbCldPVwiXHJcbiAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKClcclxuICAgICAgICAgICAgPyByb3dEYXRhKClbY29sdW1uLmZpZWxkXVxyXG4gICAgICAgICAgICA6IHJvd0RhdGFDb3B5KCkhW2NvbHVtbi5maWVsZF1cclxuICAgICAgICBcIlxyXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIlxyXG4gICAgICAgICAgYXV0b1NhdmVPbkNoYW5nZSgpICYmIG9uRmllbGRDaGFuZ2UoY29sdW1uLmZpZWxkLCAkZXZlbnQpXHJcbiAgICAgICAgXCJcclxuICAgICAgPjwvbWF0LWNoZWNrYm94PlxyXG4gICAgfVxyXG5cclxuICAgIEBpZiAoY29sdW1uLnJvd0VkaXRUeXBlID09PSAnY3VzdG9tJykge1xyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICBhcHBlYXJhbmNlPVwib3V0bGluZVwiXHJcbiAgICAgICAgW25nU3R5bGVdPVwieyB3aWR0aDogY29sdW1uLndpZHRoIHx8ICdhdXRvJyB9XCJcclxuICAgICAgPlxyXG4gICAgICAgIDxtYXQtc2VsZWN0XHJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cIlxyXG4gICAgICAgICAgICBhdXRvU2F2ZU9uQ2hhbmdlKClcclxuICAgICAgICAgICAgICA/IHJvd0RhdGEoKVtjb2x1bW4uZmllbGRdXHJcbiAgICAgICAgICAgICAgOiByb3dEYXRhQ29weSgpIVtjb2x1bW4uZmllbGRdXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiXHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKSAmJiBvbkZpZWxkQ2hhbmdlKGNvbHVtbi5maWVsZCwgJGV2ZW50KVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAgIFtyZXF1aXJlZF09XCJjb2x1bW4uZWRpdENvbHVtblJlcXVpcmVkXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIlwiPjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBjb2x1bW4uY3VzdG9tUm93RWRpdE9wdGlvbnM7IHRyYWNrIG9wdGlvbikge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcblxyXG4gICAgQGlmIChjb2x1bW4ucm93RWRpdFR5cGUgPT09ICdjdXN0b20tZHluYW1pYy1zZWxlY3QnKSB7XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCJcclxuICAgICAgICBbbmdTdHlsZV09XCJ7IHdpZHRoOiBjb2x1bW4ud2lkdGggfHwgJ2F1dG8nIH1cIlxyXG4gICAgICA+XHJcbiAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwiXHJcbiAgICAgICAgICAgIGF1dG9TYXZlT25DaGFuZ2UoKVxyXG4gICAgICAgICAgICAgID8gcm93RGF0YSgpW2NvbHVtbi5maWVsZF1cclxuICAgICAgICAgICAgICA6IHJvd0RhdGFDb3B5KCkhW2NvbHVtbi5maWVsZF1cclxuICAgICAgICAgIFwiXHJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJcclxuICAgICAgICAgICAgYXV0b1NhdmVPbkNoYW5nZSgpICYmIG9uRmllbGRDaGFuZ2UoY29sdW1uLmZpZWxkLCAkZXZlbnQpXHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgICAgW3JlcXVpcmVkXT1cImNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWRcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIEBpZiAoIWNvbHVtbi5lZGl0Q29sdW1uUmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCJcIj48L21hdC1vcHRpb24+XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgQGZvciAob3B0aW9uIG9mIGR5bmFtaWNTZWxlY3RPcHRpb25zKCk7IHRyYWNrIG9wdGlvbikge1xyXG4gICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XHJcbiAgICAgICAgICAgICAge3sgb3B0aW9uLmxhYmVsIH19XHJcbiAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgIH1cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICB9XHJcbiAgfSBAZWxzZSB7XHJcbiAgICA8ZGl2PlxyXG4gICAgICBAaWYgKGNvbHVtbi50cmFuc2xhdGVWYWx1ZSkge1xyXG4gICAgICAgIHt7IGNvbHVtbi50cmFuc2xhdGVWYWx1ZSFbcm93RGF0YSgpW2NvbHVtbi5maWVsZF1dIHx8ICcnIH19XHJcbiAgICAgIH1cclxuICAgICAgQGlmIChjb2x1bW4uY3VzdG9tVmFsdWVEaXNwbGF5KSB7XHJcbiAgICAgICAge3sgY29sdW1uLmN1c3RvbVZhbHVlRGlzcGxheShyb3dEYXRhKClbY29sdW1uLmZpZWxkXSkgfX1cclxuICAgICAgfVxyXG4gICAgICBAaWYgKCFjb2x1bW4udHJhbnNsYXRlVmFsdWUgJiYgIWNvbHVtbi5jdXN0b21WYWx1ZURpc3BsYXkpIHtcclxuICAgICAgICB7eyByb3dEYXRhKClbY29sdW1uLmZpZWxkXSB9fVxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==