@acrodata/gui 0.4.2 → 1.0.0

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.
Files changed (45) hide show
  1. package/README.md +25 -13
  2. package/button-toggle/button-toggle.d.ts +1 -1
  3. package/button-toggle/button-toggle.scss +1 -0
  4. package/button-toggle/icon.d.ts +1 -1
  5. package/esm2022/button-toggle/button-toggle.mjs +23 -15
  6. package/esm2022/button-toggle/icon.mjs +16 -11
  7. package/esm2022/field-group/field-group.mjs +7 -8
  8. package/esm2022/field-label/field-label.mjs +6 -7
  9. package/esm2022/file-uploader/file-uploader-config.mjs +9 -6
  10. package/esm2022/file-uploader/file-uploader.mjs +33 -17
  11. package/esm2022/fill/fill.mjs +25 -14
  12. package/esm2022/gui-form.mjs +67 -31
  13. package/esm2022/gui-module.mjs +35 -35
  14. package/esm2022/gui-utils.mjs +10 -8
  15. package/esm2022/image-select/image-select.mjs +35 -15
  16. package/esm2022/inline-group/inline-group.mjs +6 -6
  17. package/esm2022/input-number/input-number.mjs +21 -13
  18. package/esm2022/input-text/input-text.mjs +21 -13
  19. package/esm2022/select/select.mjs +23 -14
  20. package/esm2022/slider/slider.mjs +25 -14
  21. package/esm2022/switch/switch.mjs +12 -13
  22. package/esm2022/textarea/textarea.mjs +21 -13
  23. package/fesm2022/acrodata-gui.mjs +575 -434
  24. package/fesm2022/acrodata-gui.mjs.map +1 -1
  25. package/field-group/field-group.d.ts +1 -1
  26. package/field-group/field-group.scss +49 -0
  27. package/field-label/field-label.d.ts +1 -1
  28. package/file-uploader/file-uploader.d.ts +5 -3
  29. package/file-uploader/file-uploader.scss +0 -1
  30. package/fill/fill.d.ts +1 -1
  31. package/gui-form.d.ts +5 -1
  32. package/gui-form.scss +5 -35
  33. package/gui-module.d.ts +32 -35
  34. package/gui-utils.d.ts +2 -2
  35. package/image-select/image-select.d.ts +7 -4
  36. package/image-select/image-select.scss +3 -3
  37. package/inline-group/inline-group.d.ts +1 -1
  38. package/input-number/input-number.d.ts +1 -1
  39. package/input-text/input-text.d.ts +1 -1
  40. package/package.json +7 -7
  41. package/select/select.d.ts +1 -1
  42. package/slider/slider.d.ts +1 -1
  43. package/switch/switch.d.ts +1 -1
  44. package/switch/switch.scss +7 -7
  45. package/textarea/textarea.d.ts +1 -1
@@ -1,30 +1,33 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
1
2
  import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
2
- import { FormArray, FormControl, FormGroup } from '@angular/forms';
3
+ import { FormArray, FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
4
+ import { MatIconButton } from '@angular/material/button';
5
+ import { MatExpansionPanel, MatExpansionPanelContent, MatExpansionPanelHeader, } from '@angular/material/expansion';
6
+ import { MatIcon } from '@angular/material/icon';
7
+ import { MatTab, MatTabContent, MatTabGroup, MatTabLabel } from '@angular/material/tabs';
3
8
  import { Subscription, mergeWith, of } from 'rxjs';
4
- import { compareValues, getValueByPath } from './gui-utils';
9
+ import { GuiButtonToggle } from './button-toggle/button-toggle';
10
+ import { GuiFieldGroup } from './field-group/field-group';
11
+ import { GuiFieldLabel } from './field-label/field-label';
12
+ import { GuiFileUploader } from './file-uploader/file-uploader';
13
+ import { GuiFill } from './fill/fill';
14
+ import { GuiEjsPipe, GuiFlexDirective, compareValues, getValueByPath } from './gui-utils';
15
+ import { GuiImageSelect } from './image-select/image-select';
16
+ import { GuiInlineGroup } from './inline-group/inline-group';
17
+ import { GuiInputNumber } from './input-number/input-number';
18
+ import { GuiInputText } from './input-text/input-text';
19
+ import { GuiSelect } from './select/select';
20
+ import { GuiSlider } from './slider/slider';
21
+ import { GuiSwitch } from './switch/switch';
22
+ import { GuiTextarea } from './textarea/textarea';
23
+ import { svgIcons } from './gui-icons';
5
24
  import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/common";
7
- import * as i2 from "@angular/forms";
8
- import * as i3 from "@angular/material/icon";
9
- import * as i4 from "@angular/material/button";
10
- import * as i5 from "@angular/material/tabs";
11
- import * as i6 from "@angular/material/expansion";
12
- import * as i7 from "./input-text/input-text";
13
- import * as i8 from "./input-number/input-number";
14
- import * as i9 from "./select/select";
15
- import * as i10 from "./switch/switch";
16
- import * as i11 from "./slider/slider";
17
- import * as i12 from "./button-toggle/button-toggle";
18
- import * as i13 from "./fill/fill";
19
- import * as i14 from "./field-group/field-group";
20
- import * as i15 from "./field-label/field-label";
21
- import * as i16 from "./inline-group/inline-group";
22
- import * as i17 from "./image-select/image-select";
23
- import * as i18 from "./textarea/textarea";
24
- import * as i19 from "./file-uploader/file-uploader";
25
- import * as i20 from "./gui-utils";
25
+ import * as i1 from "@angular/material/icon";
26
+ import * as i2 from "@angular/platform-browser";
27
+ import * as i3 from "@angular/forms";
28
+ let nextUniqueId = 0;
26
29
  export class GuiForm {
27
- constructor() {
30
+ constructor(iconRegistry, sanitizer) {
28
31
  /**
29
32
  * The form instance which allow to track model value and validation status.
30
33
  */
@@ -44,6 +47,11 @@ export class GuiForm {
44
47
  this.formFields = [];
45
48
  this.formSubscription = Subscription.EMPTY;
46
49
  this.controlSubscriptions = [];
50
+ // Unique id for this form
51
+ this.uid = `gui-form-${nextUniqueId++}`;
52
+ ['dots_horizontal', 'dots_vertical', 'content_copy', 'plus', 'delete'].forEach(k => {
53
+ iconRegistry.addSvgIconLiteral(k, sanitizer.bypassSecurityTrustHtml(svgIcons[k]));
54
+ });
47
55
  }
48
56
  ngOnChanges(changes) {
49
57
  if (changes['config']) {
@@ -89,7 +97,7 @@ export class GuiForm {
89
97
  parentType,
90
98
  model: model[key],
91
99
  default: defaultValue?.[key],
92
- index: Number(key),
100
+ index: Number(key), // the string key will be `NaN`
93
101
  show: true,
94
102
  ...config[key],
95
103
  };
@@ -246,15 +254,43 @@ export class GuiForm {
246
254
  e.stopPropagation();
247
255
  tabs.mode = mode;
248
256
  }
249
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.8", ngImport: i0, type: GuiForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
250
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.8", type: GuiForm, selector: "gui-form", inputs: { form: "form", config: "config", model: "model" }, outputs: { modelChange: "modelChange" }, host: { classAttribute: "gui-form" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n <div *ngFor=\"let item of formFields\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: item, formGroup: form}\">\n </ng-template>\n </div>\n</form>\n\n<ng-template #controlType let-item let-parent=\"parent\" let-form=\"formGroup\">\n <ng-container *ngIf=\"item.show\" [ngSwitch]=\"item.type\" [formGroup]=\"form\">\n <!-- Text -->\n <gui-field-group *ngSwitchCase=\"'text'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-input-text [formControlName]=\"item.key\" [config]=\"item\"></gui-input-text>\n </gui-field-group>\n <!-- Number -->\n <gui-field-group *ngSwitchCase=\"'number'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-input-number [formControlName]=\"item.key\" [config]=\"item\"></gui-input-number>\n </gui-field-group>\n <!-- Select -->\n <gui-field-group *ngSwitchCase=\"'select'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-select [formControlName]=\"item.key\" [config]=\"item\"></gui-select>\n </gui-field-group>\n <!-- Switch -->\n <gui-field-group *ngSwitchCase=\"'switch'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-switch [formControlName]=\"item.key\" [config]=\"item\"></gui-switch>\n </gui-field-group>\n <!-- Slider -->\n <gui-field-group *ngSwitchCase=\"'slider'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-slider [formControlName]=\"item.key\" [config]=\"item\"></gui-slider>\n </gui-field-group>\n <!-- Button Toggle -->\n <gui-field-group *ngSwitchCase=\"'buttonToggle'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-button-toggle [formControlName]=\"item.key\" [config]=\"item\"></gui-button-toggle>\n </gui-field-group>\n <!-- Fill -->\n <gui-field-group *ngSwitchCase=\"'fill'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-fill [formControlName]=\"item.key\" [config]=\"item\"></gui-fill>\n </gui-field-group>\n <!-- File -->\n <gui-field-group *ngSwitchCase=\"'file'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Image -->\n <gui-field-group *ngSwitchCase=\"'image'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"image\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Video -->\n <gui-field-group *ngSwitchCase=\"'video'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"video\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Audio -->\n <gui-field-group *ngSwitchCase=\"'audio'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"audio\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Image Select -->\n <gui-field-group *ngSwitchCase=\"'imageSelect'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-image-select [formControlName]=\"item.key\" [config]=\"item\"></gui-image-select>\n </gui-field-group>\n <!-- Textarea -->\n <gui-field-group *ngSwitchCase=\"'textarea'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-textarea [formControlName]=\"item.key\" [config]=\"item\"></gui-textarea>\n </gui-field-group>\n <!-- Hidden Input -->\n <input *ngSwitchCase=\"'hidden'\" type=\"hidden\" [formControlName]=\"item.key\">\n\n <!-- Inline Group -->\n <gui-inline-group *ngSwitchCase=\"'inline'\" [config]=\"item\" [formGroupName]=\"item.key\">\n <ng-container *ngFor=\"let child of item.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </ng-container>\n </gui-inline-group>\n\n <!-- Group -->\n <mat-expansion-panel *ngSwitchCase=\"'group'\" [formGroupName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\"></gui-field-label>\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n <div *ngFor=\"let child of item.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </div>\n </ng-template>\n </mat-expansion-panel>\n\n <!-- Tabs -->\n <mat-expansion-panel *ngSwitchCase=\"'tabs'\" [formArrayName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\"></gui-field-label>\n <!-- Show operation buttons after panel opened -->\n <ng-container *ngIf=\"item.expanded\">\n <button mat-icon-button type=\"button\" [color]=\"item.mode!=='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'normal')\">\n <mat-icon svgIcon=\"dots_horizontal\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [color]=\"item.mode==='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'list')\">\n <mat-icon svgIcon=\"dots_vertical\"></mat-icon>\n </button>\n <ng-container *ngIf=\"item.template && (item.addable || item.addable===undefined)\">\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true)\">\n <mat-icon svgIcon=\"content_copy\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"plus\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"delete\"></mat-icon>\n </button>\n </ng-container>\n </ng-container>\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n <!-- Horizontal mode -->\n <mat-tab-group *ngIf=\"item.mode!=='list'\" class=\"gui-tabs\" disableRipple\n [mat-stretch-tabs]=\"false\" [(selectedIndex)]=\"item.selectedIndex\">\n <mat-tab *ngFor=\"let tab of item.children; index as i\" [disabled]=\"tab.disabled\">\n <ng-template mat-tab-label>\n <div>{{tab.name | ejs:{i} }}</div>\n </ng-template>\n <!-- FormControl & FormArray -->\n <ng-container *ngIf=\"!tab.children || tab.children.length===0 || tab.type==='tabs'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n </ng-container>\n <!-- FormGroup -->\n <ng-container *ngIf=\"tab.children?.length>0 && tab.type!=='tabs'\">\n <div *ngFor=\"let child of tab.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n </ng-container>\n </mat-tab>\n </mat-tab-group>\n\n <!-- Vertical mode -->\n <div class=\"gui-list\" *ngIf=\"item.mode==='list'\">\n <div class=\"gui-list-item\" *ngFor=\"let tab of item.children; index as i\"\n [class.gui-list-item-active]=\"item.selectedIndex===i\">\n <div class=\"gui-list-item-heading\">\n <span class=\"gui-list-item-title\"\n (click)=\"item.selectedIndex=i\">{{tab.name | ejs:{i} }}</span>\n <ng-container *ngIf=\"item.template && (item.addable || item.addable===undefined)\">\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true, i)\">\n <mat-icon svgIcon=\"content_copy\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, false, i)\">\n <mat-icon svgIcon=\"plus\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item, i)\">\n <mat-icon svgIcon=\"delete\"></mat-icon>\n </button>\n </ng-container>\n </div>\n <div class=\"gui-list-item-content\">\n <!-- FormControl & FormArray -->\n <ng-container *ngIf=\"!tab.children || tab.children.length===0 || tab.type==='tabs'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n </ng-container>\n <!-- FormGroup -->\n <ng-container *ngIf=\"tab.children?.length>0 && tab.type!=='tabs'\">\n <div *ngFor=\"let child of tab.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </mat-expansion-panel>\n\n <!-- Menu -->\n <mat-tab-group class=\"gui-menu\" *ngSwitchCase=\"'menu'\" [formGroupName]=\"item.key\" disableRipple>\n <mat-tab *ngFor=\"let menuChild of item.children\" [label]=\"menuChild.name\"\n [disabled]=\"menuChild.disabled\">\n <ng-template matTabContent>\n <ng-container *ngIf=\"menuChild.type==='menuItem'\">\n <!-- Must wrap with div -->\n <div *ngFor=\"let controlItem of menuChild.children\" [formGroupName]=\"menuChild.key\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: controlItem, formGroup: form.get([item.key, menuChild.key])}\">\n </ng-template>\n </div>\n </ng-container>\n <!-- Support for unlimited nesting -->\n <ng-container *ngIf=\"menuChild.type==='menu'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: menuChild, formGroup: form.get(item.key)}\">\n </ng-template>\n </ng-container>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n\n </ng-container>\n</ng-template>\n", styles: [".gui-form{--mat-form-field-container-text-size: 12px;--mat-expansion-header-text-size: 12px;--mat-expansion-container-text-size: 12px;--mat-expansion-header-collapsed-state-height: 32px;--mat-expansion-header-expanded-state-height: 32px;position:relative;display:block;font-size:12px}.gui-form .mat-expansion-panel{--mat-expansion-container-shape: 0;box-shadow:none!important}.gui-form .mat-expansion-panel-body{padding:0}.gui-form .mat-expansion-panel-header{padding:0 12px}.gui-form .mat-expansion-panel-header .mat-content{align-items:center;padding-right:8px}[dir=rtl] .gui-form .mat-expansion-panel-header .mat-content{padding-right:0;padding-left:8px}.gui-form .mat-expansion-panel-header .mat-content gui-field-label{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gui-form .mat-expansion-indicator:after{vertical-align:2px}.gui-form .mat-mdc-tab-header{--mat-tab-header-label-text-size: 12px;--mdc-secondary-navigation-tab-container-height: 24px}.gui-form .mat-mdc-tab-header-pagination{min-width:var(--mdc-secondary-navigation-tab-container-height)}.gui-form .mat-mdc-tab{min-width:auto;padding:0 12px}.gui-form .mat-icon{display:inline-flex;justify-content:center;align-items:center;padding:0!important}.gui-form .mat-icon svg{width:14px;height:14px}.gui-form .mat-mdc-icon-button{--mdc-icon-button-state-layer-size: 24px;--mdc-icon-button-icon-size: 14px;padding:0}.gui-form .mat-mdc-icon-button .mat-mdc-button-touch-target{width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size)}.gui-form .mat-mdc-text-field-wrapper,.gui-form .mat-mdc-form-field-hint-wrapper{position:relative;padding:0 8px;border-radius:var(--mdc-filled-text-field-container-shape)}[dir=rtl] .gui-form .mat-mdc-text-field-wrapper,[dir=rtl] .gui-form .mat-mdc-form-field-hint-wrapper{padding:0 8px}.gui-form .mat-mdc-form-field-infix{min-height:auto;padding:0!important}.gui-form .mat-mdc-form-field-hint-spacer,.gui-form .mat-mdc-form-field-bottom-align:before,.gui-form .mdc-line-ripple{display:none}.gui-list-item-heading{display:flex;align-items:center;position:relative;padding:0 12px;line-height:24px}.gui-list-item-heading:before{position:absolute;left:0;width:2px;height:16px;background-color:var(--mat-expansion-header-text-color);content:\"\"}[dir=rtl] .gui-list-item-heading:before{left:auto;right:0}.gui-list-item-title{flex:1;cursor:pointer}.gui-list-item-active .gui-list-item-title{font-weight:700}.gui-menu .mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-shape: 4px;padding:4px;background-color:var(--mdc-filled-text-field-container-color)}.gui-menu .mat-mdc-tab-header .mdc-tab__ripple:before{border-radius:var(--mdc-tab-indicator-active-indicator-shape)}.gui-menu .mat-mdc-tab-labels{gap:4px}.gui-menu .mdc-tab-indicator .mdc-tab-indicator__content{height:100%;border-width:0;border-radius:var(--mdc-tab-indicator-active-indicator-shape);background-color:var(--mdc-tab-indicator-active-indicator-color)}.gui-menu .mdc-tab-indicator--active .mdc-tab-indicator__content{opacity:.24}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i5.MatTabContent, selector: "[matTabContent]" }, { kind: "directive", type: i5.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i5.MatTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "component", type: i5.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple", "fitInkBarToContent", "mat-stretch-tabs"], exportAs: ["matTabGroup"] }, { kind: "component", type: i6.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i6.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "directive", type: i6.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "component", type: i7.GuiInputText, selector: "gui-input-text", inputs: ["config", "disabled"] }, { kind: "component", type: i8.GuiInputNumber, selector: "gui-input-number", inputs: ["config", "disabled"] }, { kind: "component", type: i9.GuiSelect, selector: "gui-select", inputs: ["config", "disabled"] }, { kind: "component", type: i10.GuiSwitch, selector: "gui-switch", inputs: ["config", "disabled"] }, { kind: "component", type: i11.GuiSlider, selector: "gui-slider", inputs: ["config", "disabled"] }, { kind: "component", type: i12.GuiButtonToggle, selector: "gui-button-toggle", inputs: ["config", "disabled"] }, { kind: "component", type: i13.GuiFill, selector: "gui-fill", inputs: ["config", "disabled"] }, { kind: "component", type: i14.GuiFieldGroup, selector: "gui-field-group", inputs: ["config"] }, { kind: "component", type: i15.GuiFieldLabel, selector: "gui-field-label", inputs: ["config", "index"] }, { kind: "component", type: i16.GuiInlineGroup, selector: "gui-inline-group", inputs: ["config"] }, { kind: "component", type: i17.GuiImageSelect, selector: "gui-image-select", inputs: ["config", "disabled"] }, { kind: "component", type: i18.GuiTextarea, selector: "gui-textarea", inputs: ["config", "disabled"] }, { kind: "component", type: i19.GuiFileUploader, selector: "gui-file-uploader", inputs: ["config", "disabled", "type", "name", "accept"], outputs: ["fileChange"] }, { kind: "directive", type: i20.GuiFlexDirective, selector: "[flex]", inputs: ["flex"] }, { kind: "pipe", type: i20.GuiEjsPipe, name: "ejs" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
257
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: GuiForm, deps: [{ token: i1.MatIconRegistry }, { token: i2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); }
258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.6", type: GuiForm, isStandalone: true, selector: "gui-form", inputs: { form: "form", config: "config", model: "model" }, outputs: { modelChange: "modelChange" }, host: { properties: { "attr.id": "uid" }, classAttribute: "gui-form" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"form\">\n @for (item of formFields; track item) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: item, formGroup: form}\">\n </ng-template>\n </div>\n }\n</form>\n\n<ng-template #controlType let-item let-parent=\"parent\" let-form=\"formGroup\">\n @if (item.show) {\n <ng-container [formGroup]=\"form\">\n @switch (item.type) {\n @case ('text') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-input-text [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('number') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-input-number [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('select') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-select [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('switch') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-switch [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('slider') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-slider [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('buttonToggle') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-button-toggle [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('fill') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-fill [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('file') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('image') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"image\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('video') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"video\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('audio') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"audio\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('imageSelect') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-image-select [formControlName]=\"item.key\" [config]=\"item\" [appendTo]=\"'#'+uid\" />\n </gui-field-group>\n }\n @case ('textarea') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-textarea [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('hidden') {\n <input type=\"hidden\" [formControlName]=\"item.key\">\n }\n @case ('inline') {\n <gui-inline-group [config]=\"item\" [formGroupName]=\"item.key\">\n @for (child of item.children; track child) {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n }\n </gui-inline-group>\n }\n @case ('group') {\n <mat-expansion-panel [formGroupName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\" />\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n @for (child of item.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </div>\n }\n </ng-template>\n </mat-expansion-panel>\n }\n @case ('tabs') {\n <mat-expansion-panel [formArrayName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\" />\n <!-- Show operation buttons when panel opened -->\n @if (item.expanded) {\n <button mat-icon-button type=\"button\" [color]=\"item.mode!=='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'normal')\">\n <mat-icon svgIcon=\"dots_horizontal\" />\n </button>\n <button mat-icon-button type=\"button\" [color]=\"item.mode==='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'list')\">\n <mat-icon svgIcon=\"dots_vertical\" />\n </button>\n @if (item.template && (item.addable || item.addable===undefined)) {\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true)\">\n <mat-icon svgIcon=\"content_copy\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"plus\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"delete\" />\n </button>\n }\n }\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n @if (item.mode!=='list') {\n <!-- Horizontal mode -->\n <mat-tab-group class=\"gui-tabs\" disableRipple\n [mat-stretch-tabs]=\"false\" [(selectedIndex)]=\"item.selectedIndex\">\n @for (tab of item.children; track tab; let i = $index) {\n <mat-tab [disabled]=\"tab.disabled\">\n <ng-template mat-tab-label>\n <div>{{tab.name | ejs:{i} }}</div>\n </ng-template>\n <!-- FormControl & FormArray -->\n @if (!tab.children || tab.children.length===0 || tab.type==='tabs') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n }\n <!-- FormGroup -->\n @if (tab.children?.length>0 && tab.type!=='tabs') {\n @for (child of tab.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n }\n }\n </mat-tab>\n }\n </mat-tab-group>\n } @else {\n <!-- Vertical mode -->\n <div class=\"gui-list\">\n @for (tab of item.children; track tab; let i = $index) {\n <div class=\"gui-list-item\"\n [class.gui-list-item-active]=\"item.selectedIndex===i\">\n <div class=\"gui-list-item-heading\">\n <span class=\"gui-list-item-title\"\n (click)=\"item.selectedIndex=i\">{{tab.name | ejs:{i} }}</span>\n @if (item.template && (item.addable || item.addable===undefined)) {\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true, i)\">\n <mat-icon svgIcon=\"content_copy\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, false, i)\">\n <mat-icon svgIcon=\"plus\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item, i)\">\n <mat-icon svgIcon=\"delete\" />\n </button>\n }\n </div>\n <div class=\"gui-list-item-content\">\n <!-- FormControl & FormArray -->\n @if (!tab.children || tab.children.length===0 || tab.type==='tabs') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n }\n <!-- FormGroup -->\n @if (tab.children?.length>0 && tab.type!=='tabs') {\n @for (child of tab.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n }\n </ng-template>\n </mat-expansion-panel>\n }\n @case ('menu') {\n <mat-tab-group class=\"gui-menu\" [formGroupName]=\"item.key\" disableRipple>\n @for (menuChild of item.children; track menuChild) {\n <mat-tab [label]=\"menuChild.name\"\n [disabled]=\"menuChild.disabled\">\n <ng-template matTabContent>\n @if (menuChild.type==='menuItem') {\n <!-- Must wrap with div -->\n @for (controlItem of menuChild.children; track controlItem) {\n <div [formGroupName]=\"menuChild.key\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: controlItem, formGroup: form.get([item.key, menuChild.key])}\">\n </ng-template>\n </div>\n }\n }\n <!-- Support for unlimited nesting -->\n @if (menuChild.type==='menu') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: menuChild, formGroup: form.get(item.key)}\">\n </ng-template>\n }\n </ng-template>\n </mat-tab>\n }\n </mat-tab-group>\n }\n }\n </ng-container>\n }\n</ng-template>\n", styles: [".gui-form{--mat-expansion-header-text-size: 12px;--mat-expansion-container-text-size: 12px;--mat-expansion-header-collapsed-state-height: 32px;--mat-expansion-header-expanded-state-height: 32px;--mat-expansion-container-shape: 0;position:relative;display:block;font-size:12px}.gui-form .mat-expansion-panel{box-shadow:none!important}.gui-form .mat-expansion-panel-body{padding:0}.gui-form .mat-expansion-panel-header{padding:0 12px}.gui-form .mat-expansion-panel-header .mat-content{align-items:center;padding-right:8px}[dir=rtl] .gui-form .mat-expansion-panel-header .mat-content{padding-right:0;padding-left:8px}.gui-form .mat-expansion-panel-header .mat-content gui-field-label{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gui-form .mat-expansion-indicator:after{vertical-align:2px}.gui-form .mat-mdc-tab-header{--mat-tab-header-label-text-size: 12px;--mdc-secondary-navigation-tab-container-height: 24px}.gui-form .mat-mdc-tab-header-pagination{min-width:var(--mdc-secondary-navigation-tab-container-height)}.gui-form .mat-mdc-tab{min-width:auto;padding:0 12px}.gui-form .mat-mdc-icon-button{--mdc-icon-button-state-layer-size: 24px;--mdc-icon-button-icon-size: 14px;padding:0}.gui-form .mat-mdc-icon-button .mat-mdc-button-touch-target{width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size)}.gui-form .mat-mdc-icon-button .mat-icon{display:inline-flex;justify-content:center;align-items:center}.gui-list-item-heading{display:flex;align-items:center;position:relative;padding:0 12px;line-height:24px}.gui-list-item-heading:before{position:absolute;left:0;width:2px;height:16px;background-color:var(--mat-expansion-header-text-color);content:\"\"}[dir=rtl] .gui-list-item-heading:before{left:auto;right:0}.gui-list-item-title{flex:1;cursor:pointer}.gui-list-item-active .gui-list-item-title{font-weight:700}.gui-menu .mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-shape: 4px;padding:4px;background-color:var(--mdc-filled-text-field-container-color)}.gui-menu .mat-mdc-tab-header .mdc-tab__ripple:before{border-radius:var(--mdc-tab-indicator-active-indicator-shape)}.gui-menu .mat-mdc-tab-labels{gap:4px}.gui-menu .mdc-tab-indicator .mdc-tab-indicator__content{height:100%;border-width:0;border-radius:var(--mdc-tab-indicator-active-indicator-shape);background-color:var(--mdc-tab-indicator-active-indicator-color)}.gui-menu .mdc-tab-indicator--active .mdc-tab-indicator__content{opacity:.24}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "directive", type: MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "directive", type: MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: GuiFieldGroup, selector: "gui-field-group", inputs: ["config"] }, { kind: "directive", type: GuiFlexDirective, selector: "[flex]", inputs: ["flex"] }, { kind: "component", type: GuiInputText, selector: "gui-input-text", inputs: ["config", "disabled"] }, { kind: "component", type: GuiInputNumber, selector: "gui-input-number", inputs: ["config", "disabled"] }, { kind: "component", type: GuiSelect, selector: "gui-select", inputs: ["config", "disabled"] }, { kind: "component", type: GuiSwitch, selector: "gui-switch", inputs: ["config", "disabled"] }, { kind: "component", type: GuiSlider, selector: "gui-slider", inputs: ["config", "disabled"] }, { kind: "component", type: GuiButtonToggle, selector: "gui-button-toggle", inputs: ["config", "disabled"] }, { kind: "component", type: GuiFill, selector: "gui-fill", inputs: ["config", "disabled"] }, { kind: "component", type: GuiFileUploader, selector: "gui-file-uploader", inputs: ["config", "disabled", "type", "name", "accept"], outputs: ["fileChange"] }, { kind: "component", type: GuiImageSelect, selector: "gui-image-select", inputs: ["config", "disabled", "appendTo"] }, { kind: "component", type: GuiTextarea, selector: "gui-textarea", inputs: ["config", "disabled"] }, { kind: "component", type: GuiInlineGroup, selector: "gui-inline-group", inputs: ["config"] }, { kind: "component", type: GuiFieldLabel, selector: "gui-field-label", inputs: ["config", "index"] }, { kind: "pipe", type: GuiEjsPipe, name: "ejs" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
251
259
  }
252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.8", ngImport: i0, type: GuiForm, decorators: [{
260
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: GuiForm, decorators: [{
253
261
  type: Component,
254
262
  args: [{ selector: 'gui-form', host: {
255
- class: 'gui-form',
256
- }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\">\n <div *ngFor=\"let item of formFields\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: item, formGroup: form}\">\n </ng-template>\n </div>\n</form>\n\n<ng-template #controlType let-item let-parent=\"parent\" let-form=\"formGroup\">\n <ng-container *ngIf=\"item.show\" [ngSwitch]=\"item.type\" [formGroup]=\"form\">\n <!-- Text -->\n <gui-field-group *ngSwitchCase=\"'text'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-input-text [formControlName]=\"item.key\" [config]=\"item\"></gui-input-text>\n </gui-field-group>\n <!-- Number -->\n <gui-field-group *ngSwitchCase=\"'number'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-input-number [formControlName]=\"item.key\" [config]=\"item\"></gui-input-number>\n </gui-field-group>\n <!-- Select -->\n <gui-field-group *ngSwitchCase=\"'select'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-select [formControlName]=\"item.key\" [config]=\"item\"></gui-select>\n </gui-field-group>\n <!-- Switch -->\n <gui-field-group *ngSwitchCase=\"'switch'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-switch [formControlName]=\"item.key\" [config]=\"item\"></gui-switch>\n </gui-field-group>\n <!-- Slider -->\n <gui-field-group *ngSwitchCase=\"'slider'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-slider [formControlName]=\"item.key\" [config]=\"item\"></gui-slider>\n </gui-field-group>\n <!-- Button Toggle -->\n <gui-field-group *ngSwitchCase=\"'buttonToggle'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-button-toggle [formControlName]=\"item.key\" [config]=\"item\"></gui-button-toggle>\n </gui-field-group>\n <!-- Fill -->\n <gui-field-group *ngSwitchCase=\"'fill'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-fill [formControlName]=\"item.key\" [config]=\"item\"></gui-fill>\n </gui-field-group>\n <!-- File -->\n <gui-field-group *ngSwitchCase=\"'file'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Image -->\n <gui-field-group *ngSwitchCase=\"'image'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"image\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Video -->\n <gui-field-group *ngSwitchCase=\"'video'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"video\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Audio -->\n <gui-field-group *ngSwitchCase=\"'audio'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"audio\"\n [formControlName]=\"item.key\" [config]=\"item\"></gui-file-uploader>\n </gui-field-group>\n <!-- Image Select -->\n <gui-field-group *ngSwitchCase=\"'imageSelect'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-image-select [formControlName]=\"item.key\" [config]=\"item\"></gui-image-select>\n </gui-field-group>\n <!-- Textarea -->\n <gui-field-group *ngSwitchCase=\"'textarea'\" [config]=\"item\" [flex]=\"item.col\">\n <gui-textarea [formControlName]=\"item.key\" [config]=\"item\"></gui-textarea>\n </gui-field-group>\n <!-- Hidden Input -->\n <input *ngSwitchCase=\"'hidden'\" type=\"hidden\" [formControlName]=\"item.key\">\n\n <!-- Inline Group -->\n <gui-inline-group *ngSwitchCase=\"'inline'\" [config]=\"item\" [formGroupName]=\"item.key\">\n <ng-container *ngFor=\"let child of item.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </ng-container>\n </gui-inline-group>\n\n <!-- Group -->\n <mat-expansion-panel *ngSwitchCase=\"'group'\" [formGroupName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\"></gui-field-label>\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n <div *ngFor=\"let child of item.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </div>\n </ng-template>\n </mat-expansion-panel>\n\n <!-- Tabs -->\n <mat-expansion-panel *ngSwitchCase=\"'tabs'\" [formArrayName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\"></gui-field-label>\n <!-- Show operation buttons after panel opened -->\n <ng-container *ngIf=\"item.expanded\">\n <button mat-icon-button type=\"button\" [color]=\"item.mode!=='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'normal')\">\n <mat-icon svgIcon=\"dots_horizontal\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [color]=\"item.mode==='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'list')\">\n <mat-icon svgIcon=\"dots_vertical\"></mat-icon>\n </button>\n <ng-container *ngIf=\"item.template && (item.addable || item.addable===undefined)\">\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true)\">\n <mat-icon svgIcon=\"content_copy\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"plus\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"delete\"></mat-icon>\n </button>\n </ng-container>\n </ng-container>\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n <!-- Horizontal mode -->\n <mat-tab-group *ngIf=\"item.mode!=='list'\" class=\"gui-tabs\" disableRipple\n [mat-stretch-tabs]=\"false\" [(selectedIndex)]=\"item.selectedIndex\">\n <mat-tab *ngFor=\"let tab of item.children; index as i\" [disabled]=\"tab.disabled\">\n <ng-template mat-tab-label>\n <div>{{tab.name | ejs:{i} }}</div>\n </ng-template>\n <!-- FormControl & FormArray -->\n <ng-container *ngIf=\"!tab.children || tab.children.length===0 || tab.type==='tabs'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n </ng-container>\n <!-- FormGroup -->\n <ng-container *ngIf=\"tab.children?.length>0 && tab.type!=='tabs'\">\n <div *ngFor=\"let child of tab.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n </ng-container>\n </mat-tab>\n </mat-tab-group>\n\n <!-- Vertical mode -->\n <div class=\"gui-list\" *ngIf=\"item.mode==='list'\">\n <div class=\"gui-list-item\" *ngFor=\"let tab of item.children; index as i\"\n [class.gui-list-item-active]=\"item.selectedIndex===i\">\n <div class=\"gui-list-item-heading\">\n <span class=\"gui-list-item-title\"\n (click)=\"item.selectedIndex=i\">{{tab.name | ejs:{i} }}</span>\n <ng-container *ngIf=\"item.template && (item.addable || item.addable===undefined)\">\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true, i)\">\n <mat-icon svgIcon=\"content_copy\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, false, i)\">\n <mat-icon svgIcon=\"plus\"></mat-icon>\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item, i)\">\n <mat-icon svgIcon=\"delete\"></mat-icon>\n </button>\n </ng-container>\n </div>\n <div class=\"gui-list-item-content\">\n <!-- FormControl & FormArray -->\n <ng-container *ngIf=\"!tab.children || tab.children.length===0 || tab.type==='tabs'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n </ng-container>\n <!-- FormGroup -->\n <ng-container *ngIf=\"tab.children?.length>0 && tab.type!=='tabs'\">\n <div *ngFor=\"let child of tab.children\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-template>\n </mat-expansion-panel>\n\n <!-- Menu -->\n <mat-tab-group class=\"gui-menu\" *ngSwitchCase=\"'menu'\" [formGroupName]=\"item.key\" disableRipple>\n <mat-tab *ngFor=\"let menuChild of item.children\" [label]=\"menuChild.name\"\n [disabled]=\"menuChild.disabled\">\n <ng-template matTabContent>\n <ng-container *ngIf=\"menuChild.type==='menuItem'\">\n <!-- Must wrap with div -->\n <div *ngFor=\"let controlItem of menuChild.children\" [formGroupName]=\"menuChild.key\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: controlItem, formGroup: form.get([item.key, menuChild.key])}\">\n </ng-template>\n </div>\n </ng-container>\n <!-- Support for unlimited nesting -->\n <ng-container *ngIf=\"menuChild.type==='menu'\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: menuChild, formGroup: form.get(item.key)}\">\n </ng-template>\n </ng-container>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n\n </ng-container>\n</ng-template>\n", styles: [".gui-form{--mat-form-field-container-text-size: 12px;--mat-expansion-header-text-size: 12px;--mat-expansion-container-text-size: 12px;--mat-expansion-header-collapsed-state-height: 32px;--mat-expansion-header-expanded-state-height: 32px;position:relative;display:block;font-size:12px}.gui-form .mat-expansion-panel{--mat-expansion-container-shape: 0;box-shadow:none!important}.gui-form .mat-expansion-panel-body{padding:0}.gui-form .mat-expansion-panel-header{padding:0 12px}.gui-form .mat-expansion-panel-header .mat-content{align-items:center;padding-right:8px}[dir=rtl] .gui-form .mat-expansion-panel-header .mat-content{padding-right:0;padding-left:8px}.gui-form .mat-expansion-panel-header .mat-content gui-field-label{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gui-form .mat-expansion-indicator:after{vertical-align:2px}.gui-form .mat-mdc-tab-header{--mat-tab-header-label-text-size: 12px;--mdc-secondary-navigation-tab-container-height: 24px}.gui-form .mat-mdc-tab-header-pagination{min-width:var(--mdc-secondary-navigation-tab-container-height)}.gui-form .mat-mdc-tab{min-width:auto;padding:0 12px}.gui-form .mat-icon{display:inline-flex;justify-content:center;align-items:center;padding:0!important}.gui-form .mat-icon svg{width:14px;height:14px}.gui-form .mat-mdc-icon-button{--mdc-icon-button-state-layer-size: 24px;--mdc-icon-button-icon-size: 14px;padding:0}.gui-form .mat-mdc-icon-button .mat-mdc-button-touch-target{width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size)}.gui-form .mat-mdc-text-field-wrapper,.gui-form .mat-mdc-form-field-hint-wrapper{position:relative;padding:0 8px;border-radius:var(--mdc-filled-text-field-container-shape)}[dir=rtl] .gui-form .mat-mdc-text-field-wrapper,[dir=rtl] .gui-form .mat-mdc-form-field-hint-wrapper{padding:0 8px}.gui-form .mat-mdc-form-field-infix{min-height:auto;padding:0!important}.gui-form .mat-mdc-form-field-hint-spacer,.gui-form .mat-mdc-form-field-bottom-align:before,.gui-form .mdc-line-ripple{display:none}.gui-list-item-heading{display:flex;align-items:center;position:relative;padding:0 12px;line-height:24px}.gui-list-item-heading:before{position:absolute;left:0;width:2px;height:16px;background-color:var(--mat-expansion-header-text-color);content:\"\"}[dir=rtl] .gui-list-item-heading:before{left:auto;right:0}.gui-list-item-title{flex:1;cursor:pointer}.gui-list-item-active .gui-list-item-title{font-weight:700}.gui-menu .mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-shape: 4px;padding:4px;background-color:var(--mdc-filled-text-field-container-color)}.gui-menu .mat-mdc-tab-header .mdc-tab__ripple:before{border-radius:var(--mdc-tab-indicator-active-indicator-shape)}.gui-menu .mat-mdc-tab-labels{gap:4px}.gui-menu .mdc-tab-indicator .mdc-tab-indicator__content{height:100%;border-width:0;border-radius:var(--mdc-tab-indicator-active-indicator-shape);background-color:var(--mdc-tab-indicator-active-indicator-color)}.gui-menu .mdc-tab-indicator--active .mdc-tab-indicator__content{opacity:.24}\n"] }]
257
- }], propDecorators: { form: [{
263
+ '[attr.id]': 'uid',
264
+ 'class': 'gui-form',
265
+ }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
266
+ ReactiveFormsModule,
267
+ NgTemplateOutlet,
268
+ MatExpansionPanel,
269
+ MatExpansionPanelHeader,
270
+ MatExpansionPanelContent,
271
+ MatIconButton,
272
+ MatIcon,
273
+ MatTabGroup,
274
+ MatTab,
275
+ MatTabLabel,
276
+ MatTabContent,
277
+ GuiFieldGroup,
278
+ GuiFlexDirective,
279
+ GuiInputText,
280
+ GuiInputNumber,
281
+ GuiSelect,
282
+ GuiSwitch,
283
+ GuiSlider,
284
+ GuiButtonToggle,
285
+ GuiFill,
286
+ GuiFileUploader,
287
+ GuiImageSelect,
288
+ GuiTextarea,
289
+ GuiInlineGroup,
290
+ GuiFieldLabel,
291
+ GuiEjsPipe,
292
+ ], template: "<form [formGroup]=\"form\">\n @for (item of formFields; track item) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: item, formGroup: form}\">\n </ng-template>\n </div>\n }\n</form>\n\n<ng-template #controlType let-item let-parent=\"parent\" let-form=\"formGroup\">\n @if (item.show) {\n <ng-container [formGroup]=\"form\">\n @switch (item.type) {\n @case ('text') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-input-text [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('number') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-input-number [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('select') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-select [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('switch') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-switch [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('slider') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-slider [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('buttonToggle') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-button-toggle [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('fill') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-fill [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('file') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('image') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"image\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('video') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"video\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('audio') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-file-uploader type=\"audio\" [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('imageSelect') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-image-select [formControlName]=\"item.key\" [config]=\"item\" [appendTo]=\"'#'+uid\" />\n </gui-field-group>\n }\n @case ('textarea') {\n <gui-field-group [config]=\"item\" [flex]=\"item.col\">\n <gui-textarea [formControlName]=\"item.key\" [config]=\"item\" />\n </gui-field-group>\n }\n @case ('hidden') {\n <input type=\"hidden\" [formControlName]=\"item.key\">\n }\n @case ('inline') {\n <gui-inline-group [config]=\"item\" [formGroupName]=\"item.key\">\n @for (child of item.children; track child) {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n }\n </gui-inline-group>\n }\n @case ('group') {\n <mat-expansion-panel [formGroupName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\" />\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n @for (child of item.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get(item.key)}\">\n </ng-template>\n </div>\n }\n </ng-template>\n </mat-expansion-panel>\n }\n @case ('tabs') {\n <mat-expansion-panel [formArrayName]=\"item.key\"\n [(expanded)]=\"item.expanded\" [disabled]=\"item.disabled\">\n <mat-expansion-panel-header>\n <gui-field-label [config]=\"item\" />\n <!-- Show operation buttons when panel opened -->\n @if (item.expanded) {\n <button mat-icon-button type=\"button\" [color]=\"item.mode!=='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'normal')\">\n <mat-icon svgIcon=\"dots_horizontal\" />\n </button>\n <button mat-icon-button type=\"button\" [color]=\"item.mode==='list'?'primary':''\"\n (click)=\"changeTabsMode($event, item, 'list')\">\n <mat-icon svgIcon=\"dots_vertical\" />\n </button>\n @if (item.template && (item.addable || item.addable===undefined)) {\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true)\">\n <mat-icon svgIcon=\"content_copy\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"plus\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item)\">\n <mat-icon svgIcon=\"delete\" />\n </button>\n }\n }\n </mat-expansion-panel-header>\n <!-- Lazy rendering -->\n <ng-template matExpansionPanelContent>\n @if (item.mode!=='list') {\n <!-- Horizontal mode -->\n <mat-tab-group class=\"gui-tabs\" disableRipple\n [mat-stretch-tabs]=\"false\" [(selectedIndex)]=\"item.selectedIndex\">\n @for (tab of item.children; track tab; let i = $index) {\n <mat-tab [disabled]=\"tab.disabled\">\n <ng-template mat-tab-label>\n <div>{{tab.name | ejs:{i} }}</div>\n </ng-template>\n <!-- FormControl & FormArray -->\n @if (!tab.children || tab.children.length===0 || tab.type==='tabs') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n }\n <!-- FormGroup -->\n @if (tab.children?.length>0 && tab.type!=='tabs') {\n @for (child of tab.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n }\n }\n </mat-tab>\n }\n </mat-tab-group>\n } @else {\n <!-- Vertical mode -->\n <div class=\"gui-list\">\n @for (tab of item.children; track tab; let i = $index) {\n <div class=\"gui-list-item\"\n [class.gui-list-item-active]=\"item.selectedIndex===i\">\n <div class=\"gui-list-item-heading\">\n <span class=\"gui-list-item-title\"\n (click)=\"item.selectedIndex=i\">{{tab.name | ejs:{i} }}</span>\n @if (item.template && (item.addable || item.addable===undefined)) {\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, true, i)\">\n <mat-icon svgIcon=\"content_copy\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"addTab($event, form.get(item.key), item, false, i)\">\n <mat-icon svgIcon=\"plus\" />\n </button>\n <button mat-icon-button type=\"button\" [disabled]=\"item.disabled\"\n (click)=\"removeTab($event, form.get(item.key), item, i)\">\n <mat-icon svgIcon=\"delete\" />\n </button>\n }\n </div>\n <div class=\"gui-list-item-content\">\n <!-- FormControl & FormArray -->\n @if (!tab.children || tab.children.length===0 || tab.type==='tabs') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: tab, parent: item, formGroup: form.get([item.key])}\">\n </ng-template>\n }\n <!-- FormGroup -->\n @if (tab.children?.length>0 && tab.type!=='tabs') {\n @for (child of tab.children; track child) {\n <div>\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: child, parent: item, formGroup: form.get([item.key, i])}\">\n </ng-template>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n }\n </ng-template>\n </mat-expansion-panel>\n }\n @case ('menu') {\n <mat-tab-group class=\"gui-menu\" [formGroupName]=\"item.key\" disableRipple>\n @for (menuChild of item.children; track menuChild) {\n <mat-tab [label]=\"menuChild.name\"\n [disabled]=\"menuChild.disabled\">\n <ng-template matTabContent>\n @if (menuChild.type==='menuItem') {\n <!-- Must wrap with div -->\n @for (controlItem of menuChild.children; track controlItem) {\n <div [formGroupName]=\"menuChild.key\">\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: controlItem, formGroup: form.get([item.key, menuChild.key])}\">\n </ng-template>\n </div>\n }\n }\n <!-- Support for unlimited nesting -->\n @if (menuChild.type==='menu') {\n <ng-template [ngTemplateOutlet]=\"controlType\"\n [ngTemplateOutletContext]=\"{$implicit: menuChild, formGroup: form.get(item.key)}\">\n </ng-template>\n }\n </ng-template>\n </mat-tab>\n }\n </mat-tab-group>\n }\n }\n </ng-container>\n }\n</ng-template>\n", styles: [".gui-form{--mat-expansion-header-text-size: 12px;--mat-expansion-container-text-size: 12px;--mat-expansion-header-collapsed-state-height: 32px;--mat-expansion-header-expanded-state-height: 32px;--mat-expansion-container-shape: 0;position:relative;display:block;font-size:12px}.gui-form .mat-expansion-panel{box-shadow:none!important}.gui-form .mat-expansion-panel-body{padding:0}.gui-form .mat-expansion-panel-header{padding:0 12px}.gui-form .mat-expansion-panel-header .mat-content{align-items:center;padding-right:8px}[dir=rtl] .gui-form .mat-expansion-panel-header .mat-content{padding-right:0;padding-left:8px}.gui-form .mat-expansion-panel-header .mat-content gui-field-label{flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.gui-form .mat-expansion-indicator:after{vertical-align:2px}.gui-form .mat-mdc-tab-header{--mat-tab-header-label-text-size: 12px;--mdc-secondary-navigation-tab-container-height: 24px}.gui-form .mat-mdc-tab-header-pagination{min-width:var(--mdc-secondary-navigation-tab-container-height)}.gui-form .mat-mdc-tab{min-width:auto;padding:0 12px}.gui-form .mat-mdc-icon-button{--mdc-icon-button-state-layer-size: 24px;--mdc-icon-button-icon-size: 14px;padding:0}.gui-form .mat-mdc-icon-button .mat-mdc-button-touch-target{width:var(--mdc-icon-button-state-layer-size);height:var(--mdc-icon-button-state-layer-size)}.gui-form .mat-mdc-icon-button .mat-icon{display:inline-flex;justify-content:center;align-items:center}.gui-list-item-heading{display:flex;align-items:center;position:relative;padding:0 12px;line-height:24px}.gui-list-item-heading:before{position:absolute;left:0;width:2px;height:16px;background-color:var(--mat-expansion-header-text-color);content:\"\"}[dir=rtl] .gui-list-item-heading:before{left:auto;right:0}.gui-list-item-title{flex:1;cursor:pointer}.gui-list-item-active .gui-list-item-title{font-weight:700}.gui-menu .mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-shape: 4px;padding:4px;background-color:var(--mdc-filled-text-field-container-color)}.gui-menu .mat-mdc-tab-header .mdc-tab__ripple:before{border-radius:var(--mdc-tab-indicator-active-indicator-shape)}.gui-menu .mat-mdc-tab-labels{gap:4px}.gui-menu .mdc-tab-indicator .mdc-tab-indicator__content{height:100%;border-width:0;border-radius:var(--mdc-tab-indicator-active-indicator-shape);background-color:var(--mdc-tab-indicator-active-indicator-color)}.gui-menu .mdc-tab-indicator--active .mdc-tab-indicator__content{opacity:.24}\n"] }]
293
+ }], ctorParameters: () => [{ type: i1.MatIconRegistry }, { type: i2.DomSanitizer }], propDecorators: { form: [{
258
294
  type: Input
259
295
  }], config: [{
260
296
  type: Input
@@ -263,4 +299,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.8", ngImpor
263
299
  }], modelChange: [{
264
300
  type: Output
265
301
  }] } });
266
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VpLWZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9ndWkvZ3VpLWZvcm0udHMiLCIuLi8uLi8uLi9wcm9qZWN0cy9ndWkvZ3VpLWZvcm0uaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFFTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBYTVELE1BQU0sT0FBTyxPQUFPO0lBVnBCO1FBV0U7O1dBRUc7UUFDTSxTQUFJLEdBQUcsSUFBSSxTQUFTLENBQU0sRUFBRSxDQUFDLENBQUM7UUFFdkM7O1dBRUc7UUFDTSxXQUFNLEdBQWMsRUFBRSxDQUFDO1FBRWhDOztXQUVHO1FBQ00sVUFBSyxHQUFRLEVBQUUsQ0FBQztRQUV6Qjs7V0FFRztRQUNPLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUUzQyxlQUFVLEdBQWlCLEVBQUUsQ0FBQztRQUU5QixxQkFBZ0IsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDO1FBRXRDLHlCQUFvQixHQUFtQixFQUFFLENBQUM7S0FzUDNDO0lBcFBDLFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUMsQ0FBQyxpQkFBaUI7WUFDMUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJ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LENBQUMsQ0FBQztRQUN0QyxTQUFTLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxjQUFjLENBQUMsQ0FBYSxFQUFFLElBQWdCLEVBQUUsSUFBa0I7UUFDaEUsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7OEdBOVFVLE9BQU87a0dBQVAsT0FBTyxnTkMzQnBCLG14V0EwTkE7OzJGRC9MYSxPQUFPO2tCQVZuQixTQUFTOytCQUNFLFVBQVUsUUFHZDt3QkFDSixLQUFLLEVBQUUsVUFBVTtxQkFDbEIsaUJBQ2MsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTs4QkFNdEMsSUFBSTtzQkFBWixLQUFLO2dCQUtHLE1BQU07c0JBQWQsS0FBSztnQkFLRyxLQUFLO3NCQUFiLEtBQUs7Z0JBS0ksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUFycmF5LCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uLCBtZXJnZVdpdGgsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjb21wYXJlVmFsdWVzLCBnZXRWYWx1ZUJ5UGF0aCB9IGZyb20gJy4vZ3VpLXV0aWxzJztcbmltcG9ydCB7IEd1aUNvbmRpdGlvbiwgR3VpQ29udHJvbCwgR3VpRmllbGRUeXBlLCBHdWlGaWVsZHMsIEd1aVRhYnNNb2RlIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdndWktZm9ybScsXG4gIHRlbXBsYXRlVXJsOiAnLi9ndWktZm9ybS5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZ3VpLWZvcm0uc2NzcyddLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdndWktZm9ybScsXG4gIH0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBHdWlGb3JtIGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBUaGUgZm9ybSBpbnN0YW5jZSB3aGljaCBhbGxvdyB0byB0cmFjayBtb2RlbCB2YWx1ZSBhbmQgdmFsaWRhdGlvbiBzdGF0dXMuXG4gICAqL1xuICBASW5wdXQoKSBmb3JtID0gbmV3IEZvcm1Hcm91cDxhbnk+KHt9KTtcblxuICAvKipcbiAgICogVGhlIGZpZWxkIGNvbmZpZ3VyYXRpb25zIGZvciBidWlsZGluZyB0aGUgZm9ybS5cbiAgICovXG4gIEBJbnB1dCgpIGNvbmZpZzogR3VpRmllbGRzID0ge307XG5cbiAgLyoqXG4gICAqIFRoZSBtb2RlbCB0byBiZSByZXByZXNlbnRlZCBieSB0aGUgZm9ybS5cbiAgICovXG4gIEBJbnB1dCgpIG1vZGVsOiBhbnkgPSB7fTtcblxuICAvKipcbiAgICogRmlyZWQgb24gbW9kZWwgdmFsdWUgY2hhbmdlXG4gICAqL1xuICBAT3V0cHV0KCkgbW9kZWxDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgZm9ybUZpZWxkczogR3VpQ29udHJvbFtdID0gW107XG5cbiAgZm9ybVN1YnNjcmlwdGlvbiA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcblxuICBjb250cm9sU3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2NvbmZpZyddKSB7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMgPSB7fTsgLy8gcmVzZXQgY29udHJvbHNcbiAgICAgIHRoaXMuZm9ybUZpZWxkcyA9IHRoaXMuZ2V0Rm9ybUZpZWxkQXJyYXkodGhpcy5mb3JtLCB0aGlzLmNvbmZpZywgdGhpcy5tb2RlbCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ21vZGVsJ10gJiYgdGhpcy5tb2RlbCAmJiBPYmplY3Qua2V5cyh0aGlzLm1vZGVsKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh0aGlzLm1vZGVsKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb24gPSB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMubW9kZWwsIHZhbHVlKTtcbiAgICAgIHRoaXMubW9kZWxDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmNvbnRyb2xTdWJzY3JpcHRpb25zLmZvckVhY2gocyA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdGhlIG9iamVjdCBjb25maWcgdG8gYXJyYXkgY29uZmlnIGFuZCByZWdpc3RlciBpbnRvIHRoZSByZWFjdGl2ZSBmb3JtLlxuICAgKlxuICAgKiBAcGFyYW0gZm9ybSAgICAgICAgIFRoZSByZWFjdGl2ZSBmb3JtIGluc3RhbmNlXG4gICAqIEBwYXJhbSBjb25maWcgICAgICAgVGhlIGNvbmZpZyBvZiB0aGUgZm9ybSBmaWVsZHNcbiAgICogQHBhcmFtIG1vZGVsICAgICAgICBUaGUgdmFsdWUgb2YgdGhlIGZvcm0gY29udHJvbFxuICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSBmb3JtIGZpZWxkXG4gICAqIEBwYXJhbSBwYXJlbnRUeXBlICAgVGhlIHR5cGUgb2YgdGhlIGZvcm0gZmllbGQgcGFyZW50XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBnZXRGb3JtRmllbGRBcnJheShcbiAgICBmb3JtOiBGb3JtR3JvdXAgfCBGb3JtQXJyYXksXG4gICAgY29uZmlnOiBHdWlGaWVsZHMgfCBHdWlDb250cm9sW10gPSB7fSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuICAgIGRlZmF1bHRWYWx1ZTogYW55ID0gbnVsbCxcbiAgICBwYXJlbnRUeXBlOiBHdWlGaWVsZFR5cGUgPSAnZ3JvdXAnXG4gICkge1xuICAgIGNvbnN0IHRlbXBBcnIgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpIHtcbiAgICAgIC8vIEluZmVycmluZyB0aGUgZm9ybSB0eXBlIGJ5IHRoZSBkYXRhIHR5cGUgb2YgYGNoaWxkcmVuYFxuICAgICAgLy8gMS4gYHVuZGVmaW5lZGAgPT4gRm9ybUNvbnRyb2xcbiAgICAgIC8vIDIuIGBhcnJheWAgICAgID0+IEZvcm1BcnJheVxuICAgICAgLy8gMy4gYG9iamVjdGAgICAgPT4gRm9ybUdyb3VwXG4gICAgICBjb25zdCBfY2hpbGRyZW4gPSAoY29uZmlnIGFzIGFueSlba2V5XS50ZW1wbGF0ZSA/IFtdIDogKGNvbmZpZyBhcyBhbnkpW2tleV0uY2hpbGRyZW47XG4gICAgICBjb25zdCBfdHlwZSA9ICFfY2hpbGRyZW4gPyAnY29udHJvbCcgOiBBcnJheS5pc0FycmF5KF9jaGlsZHJlbikgPyAnYXJyYXknIDogJ2dyb3VwJztcblxuICAgICAgY29uc3QgaXRlbTogR3VpQ29udHJvbCA9IHtcbiAgICAgICAgX3R5cGUsXG4gICAgICAgIGtleSxcbiAgICAgICAgcGFyZW50VHlwZSxcbiAgICAgICAgbW9kZWw6IG1vZGVsW2tleV0sXG4gICAgICAgIGRlZmF1bHQ6IGRlZmF1bHRWYWx1ZT8uW2tleV0sXG4gICAgICAgIGluZGV4OiBOdW1iZXIoa2V5KSwgLy8gdGhlIHN0cmluZyBrZXkgd2lsbCBiZSBgTmFOYFxuICAgICAgICBzaG93OiB0cnVlLFxuICAgICAgICAuLi4oY29uZmlnIGFzIGFueSlba2V5XSxcbiAgICAgIH07XG5cbiAgICAgIC8vIFRoZSBgZ3JvdXBgIHR5cGUgZ2VuZXJhbGx5IGhhdmUgbm8gYGRlZmF1bHRgLCBzbyB3ZSBzaG91bGRcbiAgICAgIC8vIHNldCB0aGUgZGVmYXVsdCB2YWx1ZSBtYW51YWxseVxuICAgICAgaWYgKGl0ZW0uY2hpbGRyZW4gJiYgbW9kZWxba2V5XSA9PSBudWxsICYmIGl0ZW0uZGVmYXVsdCA9PSBudWxsKSB7XG4gICAgICAgIGl0ZW0ubW9kZWwgPSBtb2RlbFtrZXldID0gaXRlbS5fdHlwZSA9PT0gJ2FycmF5JyA/IFtdIDoge307XG4gICAgICB9XG5cbiAgICAgIC8vIEdlbmVyYXRlIG1vZGVsIGJ5IHRoZSBgZGVmYXVsdGAga2V5IG9mIHRoZSBmaWVsZCBjb25maWdcbiAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT09ICdvYmplY3QnICYmIG1vZGVsW2tleV0gPT0gbnVsbCkge1xuICAgICAgICBtb2RlbFtrZXldID0gaXRlbS5kZWZhdWx0O1xuICAgICAgfVxuXG4gICAgICAvLyBTcGVjaWFsIGp1ZGdtZW50IG9uIGB0YWJzYCB0eXBlLCB0aGUgYGNoaWxkcmVuYCBrZXkgd2lsbCBiZSBpZ25vcmVkIGlmXG4gICAgICAvLyB0aGVyZSBoYXMgYSBgdGVtcGxhdGVgIGtleVxuICAgICAgaWYgKGl0ZW0udGVtcGxhdGUpIHtcbiAgICAgICAgLy8gSWYgbW9kZWwgaXMgYW4gYXJyYXkgYW5kIG5vdCBlbXB0eSwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGZvcm0gZmllbGRcbiAgICAgICAgLy8gd2lsbCB1c2UgdGhlIG1vZGVsJ3MgdmFsdWVcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaXRlbS5tb2RlbCkgJiYgaXRlbS5tb2RlbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaXRlbS5kZWZhdWx0ID0gaXRlbS5tb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5kZWZhdWx0Py5sZW5ndGgpIHtcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuID0gaXRlbS5kZWZhdWx0Lm1hcCgodmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih2YWx1ZSwgaXRlbS50ZW1wbGF0ZT8uZGVmYXVsdCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkZWZhdWx0OiB2YWx1ZSxcbiAgICAgICAgICAgICAgLi4uaXRlbS50ZW1wbGF0ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbS5jaGlsZHJlbiA9IFtdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFBhcnNlIHRoZSBgc2hvd0lmYCBjb25kaXRpb25zXG4gICAgICBpZiAoaXRlbS5zaG93SWYpIHtcbiAgICAgICAgY29uc3Qgc2V0VmlzaWJpbGl0eSA9IChjb21wYXJlV2l0aDogKGNvbmRpdGlvbjogR3VpQ29uZGl0aW9uKSA9PiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgaWYgKGl0ZW0uc2hvd0lmIS5sb2dpY2FsVHlwZSA9PT0gJyRvcicpIHtcbiAgICAgICAgICAgIGl0ZW0uc2hvdyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLnNvbWUoYyA9PiBjb21wYXJlV2l0aChjKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW0uc2hvdyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLmV2ZXJ5KGMgPT4gY29tcGFyZVdpdGgoYykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdGhlIGluaXQgdmlzaWJpbGl0eSBvZiB0aGUgZmllbGRcbiAgICAgICAgc2V0VmlzaWJpbGl0eShjID0+IHtcbiAgICAgICAgICBjb25zdCBjZmcgPSBnZXRWYWx1ZUJ5UGF0aChjb25maWcsIGNbMF0pID8/IGdldFZhbHVlQnlQYXRoKHRoaXMuY29uZmlnLCBjWzBdKTtcbiAgICAgICAgICBjb25zdCB2YWwgPSBnZXRWYWx1ZUJ5UGF0aChtb2RlbCwgY1swXSkgPz8gZ2V0VmFsdWVCeVBhdGgodGhpcy5tb2RlbCwgY1swXSk7XG4gICAgICAgICAgcmV0dXJuIGNvbXBhcmVWYWx1ZXMoY2ZnPy5bJ2RlZmF1bHQnXSA/PyB2YWwsIGNbMl0sIGNbMV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZWxheSB0aGUgc3Vic2NyaXB0aW9uIHRvIG1ha2Ugc3VyZSBhbGwgdGhlIGZvcm0gY29udHJvbHMgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ2V0Q29udHJvbCA9IChwYXRoOiBzdHJpbmcpID0+IGZvcm0uZ2V0KHBhdGgpIHx8IHRoaXMuZm9ybS5nZXQocGF0aCk7XG5cbiAgICAgICAgICBjb25zdCBjb250cm9scyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLm1hcChjID0+IGdldENvbnRyb2woY1swXSkpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlQ2hhbmdlcyQgPSBjb250cm9scy5tYXAoY29udHJvbCA9PiBjb250cm9sPy52YWx1ZUNoYW5nZXMgfHwgb2YoKSk7XG4gICAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gb2YoKVxuICAgICAgICAgICAgLnBpcGUobWVyZ2VXaXRoKHZhbHVlQ2hhbmdlcyQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoYyA9PiBjb21wYXJlVmFsdWVzKGdldENvbnRyb2woY1swXSk/LnZhbHVlLCBjWzJdLCBjWzFdKSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuY29udHJvbFN1YnNjcmlwdGlvbnMucHVzaChzdWJzY3JpcHRpb24pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGl0ZW0uX3R5cGUgPT09ICdjb250cm9sJykge1xuICAgICAgICBjb25zdCBmb3JtU3RhdGUgPSB7IHZhbHVlOiBpdGVtLmRlZmF1bHQsIGRpc2FibGVkOiBpdGVtLmRpc2FibGVkIH07XG4gICAgICAgIGlmIChmb3JtIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgICAgZm9ybS5yZWdpc3RlckNvbnRyb2woaXRlbS5rZXksIG5ldyBGb3JtQ29udHJvbChmb3JtU3RhdGUpKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgICAgZm9ybS5pbnNlcnQoaXRlbS5pbmRleCB8fCBmb3JtLmxlbmd0aCwgbmV3IEZvcm1Db250cm9sKGZvcm1TdGF0ZSksIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpdGVtLl90eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgIGxldCBmb3JtQXJyYXkgPSBuZXcgRm9ybUFycmF5PGFueT4oW10pO1xuICAgICAgICBpZiAoZm9ybSBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgIGZvcm1BcnJheSA9IGZvcm0ucmVnaXN0ZXJDb250cm9sKGl0ZW0ua2V5LCBuZXcgRm9ybUFycmF5KFtdKSkgYXMgRm9ybUFycmF5O1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm0gaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgICAgICBmb3JtLmluc2VydChpdGVtLmluZGV4IHx8IGZvcm0ubGVuZ3RoLCBmb3JtQXJyYXksIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0ZW0uY2hpbGRyZW4gPSB0aGlzLmdldEZvcm1GaWVsZEFycmF5KFxuICAgICAgICAgIGZvcm1BcnJheSxcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuLFxuICAgICAgICAgIGl0ZW0ubW9kZWwsXG4gICAgICAgICAgaXRlbS5kZWZhdWx0LFxuICAgICAgICAgIGl0ZW0udHlwZVxuICAgICAgICApO1xuXG4gICAgICAgIGl0ZW0uc2VsZWN0ZWRJbmRleCA9IDA7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW0uX3R5cGUgPT09ICdncm91cCcpIHtcbiAgICAgICAgbGV0IGZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICAgICAgICBpZiAoZm9ybSBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgIGZvcm1Hcm91cCA9IGZvcm0ucmVnaXN0ZXJDb250cm9sKGl0ZW0ua2V5LCBuZXcgRm9ybUdyb3VwKHt9KSkgYXMgRm9ybUdyb3VwO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm0gaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgICAgICBmb3JtLmluc2VydChpdGVtLmluZGV4IHx8IGZvcm0ubGVuZ3RoLCBmb3JtR3JvdXAsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0ZW0uY2hpbGRyZW4gPSB0aGlzLmdldEZvcm1GaWVsZEFycmF5KFxuICAgICAgICAgIGZvcm1Hcm91cCxcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuLFxuICAgICAgICAgIGl0ZW0ubW9kZWwsXG4gICAgICAgICAgaXRlbS5kZWZhdWx0LFxuICAgICAgICAgIGl0ZW0udHlwZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0ZW1wQXJyLnB1c2goaXRlbSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRlbXBBcnI7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgdGFiIGl0ZW0uXG4gICAqXG4gICAqIEBwYXJhbSBlICAgICAgICAgVGhlIG1vdXNlIGV2ZW50XG4gICAqIEBwYXJhbSBmb3JtQXJyYXkgVGhlIHJlYWN0aXZlIGZvcm0gaW5zdGFuY2VcbiAgICogQHBhcmFtIHRhYnMgICAgICBUaGUgY29uZmlnIG9mIHRoZSB0YWJzIGZpZWxkXG4gICAqIEBwYXJhbSBjb3B5ICAgICAgV2hldGhlciB0byBjb3B5IHRoZSBjdXJyZW50IHRhYlxuICAgKiBAcGFyYW0gaW5kZXggICAgIFRoZSBpbmRleCBvZiB0aGUgdGFicyBhcnJheVxuICAgKi9cbiAgYWRkVGFiKGU6IE1vdXNlRXZlbnQsIGZvcm1BcnJheTogRm9ybUFycmF5LCB0YWJzOiBHdWlDb250cm9sLCBjb3B5PzogYm9vbGVhbiwgaW5kZXg/OiBudW1iZXIpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGluc2VydEluZGV4ID1cbiAgICAgIGluZGV4ICE9PSB2b2lkIDAgPyBpbmRleCArIDEgOiBjb3B5ID8gdGFicy5zZWxlY3RlZEluZGV4ISArIDEgOiB0YWJzLmNoaWxkcmVuIS5sZW5ndGg7XG4gICAgLy8gU2F2ZSB0aGUgaW5kZXggb2YgdGhlIGluc2VydGlvbiBpbiB0aGUgY29uZmlnXG4gICAgdGFicy50ZW1wbGF0ZSEuaW5kZXggPSBpbnNlcnRJbmRleDtcbiAgICAvLyBUaGUga2V5IGluIHRoZSBvYmplY3QgYW5kIHRoZSBpbmRleCBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIHRoZSBzYW1lXG4gICAgdGFicy5jaGlsZHJlbiEuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPj0gaW5zZXJ0SW5kZXgpIHtcbiAgICAgICAgY2hpbGQuaW5kZXghICs9IDE7XG4gICAgICAgIGNoaWxkLmtleSA9IGNoaWxkLmluZGV4ICsgJyc7IC8vIGNvbnZlcnQgdG8gc3RyaW5nXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBmb3JtVmFsdWUgPSBmb3JtQXJyYXkuZ2V0KGluc2VydEluZGV4IC0gMSArICcnKT8udmFsdWU7XG4gICAgLy8gVGhlIGNvbnN0cnVjdGVkIG9iamVjdCBsb29rcyBsaWtlIHRoaXMgYFt7IGtleTogJ3RhYicsIGNoaWxkcmVuOiB0ZW1wbGF0ZSB9XWBcbiAgICAvLyBUaGUga2V5IHNob3VsZCBwcmVmZXJhYmx5IGJlIGBudWxsYFxuICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMuZ2V0Rm9ybUZpZWxkQXJyYXkoXG4gICAgICBmb3JtQXJyYXksXG4gICAgICB7IFtpbnNlcnRJbmRleF06IHRhYnMudGVtcGxhdGUgfSBhcyBHdWlGaWVsZHMsXG4gICAgICBjb3B5ID8geyBbaW5zZXJ0SW5kZXhdOiBmb3JtVmFsdWUgfSA6IHt9LFxuICAgICAgY29weSA/IHsgW2luc2VydEluZGV4XTogZm9ybVZhbHVlIH0gOiBudWxsLFxuICAgICAgJ3RhYnMnXG4gICAgKTtcbiAgICB0YWJzLmNoaWxkcmVuIS5zcGxpY2UoaW5zZXJ0SW5kZXgsIDAsIG5ld1RhYlswXSk7XG5cbiAgICAvLyB1cGRhdGUgdGhlIGZvcm0gbW9kZWxcbiAgICBmb3JtQXJyYXkucGF0Y2hWYWx1ZShmb3JtQXJyYXkudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHRhYiBpdGVtLlxuICAgKlxuICAgKiBAcGFyYW0gZSAgICAgICAgIFRoZSBtb3VzZSBldmVudFxuICAgKiBAcGFyYW0gZm9ybUFycmF5IFRoZSByZWFjdGl2ZSBmb3JtIGluc3RhbmNlXG4gICAqIEBwYXJhbSB0YWJzICAgICAgVGhlIGNvbmZpZyBvZiB0aGUgdGFicyBmaWVsZFxuICAgKiBAcGFyYW0gaW5kZXggICAgIFRoZSBpbmRleCBvZiB0aGUgdGFicyBhcnJheVxuICAgKi9cbiAgcmVtb3ZlVGFiKGU6IE1vdXNlRXZlbnQsIGZvcm1BcnJheTogRm9ybUFycmF5LCB0YWJzOiBHdWlDb250cm9sLCBpbmRleD86IG51bWJlcikge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgcmVtb3ZlSW5kZXggPSBpbmRleCA9PT0gdm9pZCAwID8gdGFicy5zZWxlY3RlZEluZGV4ISA6IGluZGV4O1xuICAgIHRhYnMuY2hpbGRyZW4hLmZvckVhY2goKGNoaWxkLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ID4gcmVtb3ZlSW5kZXgpIHtcbiAgICAgICAgY2hpbGQuaW5kZXghIC09IDE7XG4gICAgICAgIGNoaWxkLmtleSA9IGNoaWxkLmluZGV4ICsgJyc7IC8vIGNvbnZlcnQgdG8gc3RyaW5nXG4gICAgICB9XG4gICAgfSk7XG4gICAgdGFicy5jaGlsZHJlbiEuc3BsaWNlKHJlbW92ZUluZGV4LCAxKTtcbiAgICBmb3JtQXJyYXkucmVtb3ZlQXQocmVtb3ZlSW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZSB0aGUgZGlzcGxheSBtb2RlIG9mIHRhYnMuXG4gICAqXG4gICAqIEBwYXJhbSBlICAgIFRoZSBtb3VzZSBldmVudFxuICAgKiBAcGFyYW0gdGFicyBUaGUgY29uZmlnIG9mIHRoZSB0YWJzIGZpZWxkXG4gICAqIEBwYXJhbSBtb2RlIFRoZSBkaXNwbGF5IG1vZGUgb2YgdGFic1xuICAgKi9cbiAgY2hhbmdlVGFic01vZGUoZTogTW91c2VFdmVudCwgdGFiczogR3VpQ29udHJvbCwgbW9kZT86IEd1aVRhYnNNb2RlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0YWJzLm1vZGUgPSBtb2RlO1xuICB9XG59XG4iLCI8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBmb3JtRmllbGRzXCI+XG4gICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybX1cIj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L2Rpdj5cbjwvZm9ybT5cblxuPG5nLXRlbXBsYXRlICNjb250cm9sVHlwZSBsZXQtaXRlbSBsZXQtcGFyZW50PVwicGFyZW50XCIgbGV0LWZvcm09XCJmb3JtR3JvdXBcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0uc2hvd1wiIFtuZ1N3aXRjaF09XCJpdGVtLnR5cGVcIiBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICA8IS0tIFRleHQgLS0+XG4gICAgPGd1aS1maWVsZC1ncm91cCAqbmdTd2l0Y2hDYXNlPVwiJ3RleHQnXCIgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgIDxndWktaW5wdXQtdGV4dCBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCI+PC9ndWktaW5wdXQtdGV4dD5cbiAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICA8IS0tIE51bWJlciAtLT5cbiAgICA8Z3VpLWZpZWxkLWdyb3VwICpuZ1N3aXRjaENhc2U9XCInbnVtYmVyJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWlucHV0LW51bWJlciBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCI+PC9ndWktaW5wdXQtbnVtYmVyPlxuICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgIDwhLS0gU2VsZWN0IC0tPlxuICAgIDxndWktZmllbGQtZ3JvdXAgKm5nU3dpdGNoQ2FzZT1cIidzZWxlY3QnXCIgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgIDxndWktc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIj48L2d1aS1zZWxlY3Q+XG4gICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgPCEtLSBTd2l0Y2ggLS0+XG4gICAgPGd1aS1maWVsZC1ncm91cCAqbmdTd2l0Y2hDYXNlPVwiJ3N3aXRjaCdcIiBbY29uZmlnXT1cIml0ZW1cIiBbZmxleF09XCJpdGVtLmNvbFwiPlxuICAgICAgPGd1aS1zd2l0Y2ggW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLXN3aXRjaD5cbiAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICA8IS0tIFNsaWRlciAtLT5cbiAgICA8Z3VpLWZpZWxkLWdyb3VwICpuZ1N3aXRjaENhc2U9XCInc2xpZGVyJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLXNsaWRlciBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCI+PC9ndWktc2xpZGVyPlxuICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgIDwhLS0gQnV0dG9uIFRvZ2dsZSAtLT5cbiAgICA8Z3VpLWZpZWxkLWdyb3VwICpuZ1N3aXRjaENhc2U9XCInYnV0dG9uVG9nZ2xlJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWJ1dHRvbi10b2dnbGUgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLWJ1dHRvbi10b2dnbGU+XG4gICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgPCEtLSBGaWxsIC0tPlxuICAgIDxndWktZmllbGQtZ3JvdXAgKm5nU3dpdGNoQ2FzZT1cIidmaWxsJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWZpbGwgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLWZpbGw+XG4gICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgPCEtLSBGaWxlIC0tPlxuICAgIDxndWktZmllbGQtZ3JvdXAgKm5nU3dpdGNoQ2FzZT1cIidmaWxlJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLWZpbGUtdXBsb2FkZXI+XG4gICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgPCEtLSBJbWFnZSAtLT5cbiAgICA8Z3VpLWZpZWxkLWdyb3VwICpuZ1N3aXRjaENhc2U9XCInaW1hZ2UnXCIgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgIDxndWktZmlsZS11cGxvYWRlciB0eXBlPVwiaW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIj48L2d1aS1maWxlLXVwbG9hZGVyPlxuICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgIDwhLS0gVmlkZW8gLS0+XG4gICAgPGd1aS1maWVsZC1ncm91cCAqbmdTd2l0Y2hDYXNlPVwiJ3ZpZGVvJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgdHlwZT1cInZpZGVvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCI+PC9ndWktZmlsZS11cGxvYWRlcj5cbiAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICA8IS0tIEF1ZGlvIC0tPlxuICAgIDxndWktZmllbGQtZ3JvdXAgKm5nU3dpdGNoQ2FzZT1cIidhdWRpbydcIiBbY29uZmlnXT1cIml0ZW1cIiBbZmxleF09XCJpdGVtLmNvbFwiPlxuICAgICAgPGd1aS1maWxlLXVwbG9hZGVyIHR5cGU9XCJhdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLWZpbGUtdXBsb2FkZXI+XG4gICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgPCEtLSBJbWFnZSBTZWxlY3QgLS0+XG4gICAgPGd1aS1maWVsZC1ncm91cCAqbmdTd2l0Y2hDYXNlPVwiJ2ltYWdlU2VsZWN0J1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLWltYWdlLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCI+PC9ndWktaW1hZ2Utc2VsZWN0PlxuICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgIDwhLS0gVGV4dGFyZWEgLS0+XG4gICAgPGd1aS1maWVsZC1ncm91cCAqbmdTd2l0Y2hDYXNlPVwiJ3RleHRhcmVhJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICA8Z3VpLXRleHRhcmVhIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIj48L2d1aS10ZXh0YXJlYT5cbiAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICA8IS0tIEhpZGRlbiBJbnB1dCAtLT5cbiAgICA8aW5wdXQgKm5nU3dpdGNoQ2FzZT1cIidoaWRkZW4nXCIgdHlwZT1cImhpZGRlblwiIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIj5cblxuICAgIDwhLS0gSW5saW5lIEdyb3VwIC0tPlxuICAgIDxndWktaW5saW5lLWdyb3VwICpuZ1N3aXRjaENhc2U9XCInaW5saW5lJ1wiIFtjb25maWddPVwiaXRlbVwiIFtmb3JtR3JvdXBOYW1lXT1cIml0ZW0ua2V5XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBpdGVtLmNoaWxkcmVuXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY2hpbGQsIHBhcmVudDogaXRlbSwgZm9ybUdyb3VwOiBmb3JtLmdldChpdGVtLmtleSl9XCI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2d1aS1pbmxpbmUtZ3JvdXA+XG5cbiAgICA8IS0tIEdyb3VwIC0tPlxuICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsICpuZ1N3aXRjaENhc2U9XCInZ3JvdXAnXCIgW2Zvcm1Hcm91cE5hbWVdPVwiaXRlbS5rZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFsoZXhwYW5kZWQpXT1cIml0ZW0uZXhwYW5kZWRcIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiPlxuICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxuICAgICAgICA8Z3VpLWZpZWxkLWxhYmVsIFtjb25maWddPVwiaXRlbVwiPjwvZ3VpLWZpZWxkLWxhYmVsPlxuICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cbiAgICAgIDwhLS0gTGF6eSByZW5kZXJpbmcgLS0+XG4gICAgICA8bmctdGVtcGxhdGUgbWF0RXhwYW5zaW9uUGFuZWxDb250ZW50PlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBpdGVtLmNoaWxkcmVuXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGNoaWxkLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoaXRlbS5rZXkpfVwiPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L21hdC1leHBhbnNpb24tcGFuZWw+XG5cbiAgICA8IS0tIFRhYnMgLS0+XG4gICAgPG1hdC1leHBhbnNpb24tcGFuZWwgKm5nU3dpdGNoQ2FzZT1cIid0YWJzJ1wiIFtmb3JtQXJyYXlOYW1lXT1cIml0ZW0ua2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbKGV4cGFuZGVkKV09XCJpdGVtLmV4cGFuZGVkXCIgW2Rpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIj5cbiAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cbiAgICAgICAgPGd1aS1maWVsZC1sYWJlbCBbY29uZmlnXT1cIml0ZW1cIj48L2d1aS1maWVsZC1sYWJlbD5cbiAgICAgICAgPCEtLSBTaG93IG9wZXJhdGlvbiBidXR0b25zIGFmdGVyIHBhbmVsIG9wZW5lZCAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0uZXhwYW5kZWRcIj5cbiAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2NvbG9yXT1cIml0ZW0ubW9kZSE9PSdsaXN0Jz8ncHJpbWFyeSc6JydcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNoYW5nZVRhYnNNb2RlKCRldmVudCwgaXRlbSwgJ25vcm1hbCcpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImRvdHNfaG9yaXpvbnRhbFwiPjwvbWF0LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gdHlwZT1cImJ1dHRvblwiIFtjb2xvcl09XCJpdGVtLm1vZGU9PT0nbGlzdCc/J3ByaW1hcnknOicnXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjaGFuZ2VUYWJzTW9kZSgkZXZlbnQsIGl0ZW0sICdsaXN0JylcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwiZG90c192ZXJ0aWNhbFwiPjwvbWF0LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udGVtcGxhdGUgJiYgKGl0ZW0uYWRkYWJsZSB8fCBpdGVtLmFkZGFibGU9PT11bmRlZmluZWQpXCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2Rpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkVGFiKCRldmVudCwgZm9ybS5nZXQoaXRlbS5rZXkpLCBpdGVtLCB0cnVlKVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImNvbnRlbnRfY29weVwiPjwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0pXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwicGx1c1wiPjwvbWF0LWljb24+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0pXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwiZGVsZXRlXCI+PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG4gICAgICA8IS0tIExhenkgcmVuZGVyaW5nIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlIG1hdEV4cGFuc2lvblBhbmVsQ29udGVudD5cbiAgICAgICAgPCEtLSBIb3Jpem9udGFsIG1vZGUgLS0+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwiaXRlbS5tb2RlIT09J2xpc3QnXCIgY2xhc3M9XCJndWktdGFic1wiIGRpc2FibGVSaXBwbGVcbiAgICAgICAgICAgICAgICAgICAgICAgW21hdC1zdHJldGNoLXRhYnNdPVwiZmFsc2VcIiBbKHNlbGVjdGVkSW5kZXgpXT1cIml0ZW0uc2VsZWN0ZWRJbmRleFwiPlxuICAgICAgICAgIDxtYXQtdGFiICpuZ0Zvcj1cImxldCB0YWIgb2YgaXRlbS5jaGlsZHJlbjsgaW5kZXggYXMgaVwiIFtkaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXQtdGFiLWxhYmVsPlxuICAgICAgICAgICAgICA8ZGl2Pnt7dGFiLm5hbWUgfCBlanM6e2l9IH19PC9kaXY+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPCEtLSBGb3JtQ29udHJvbCAmIEZvcm1BcnJheSAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhdGFiLmNoaWxkcmVuIHx8IHRhYi5jaGlsZHJlbi5sZW5ndGg9PT0wIHx8IHRhYi50eXBlPT09J3RhYnMnXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogdGFiLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5XSl9XCI+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwhLS0gRm9ybUdyb3VwIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYi5jaGlsZHJlbj8ubGVuZ3RoPjAgJiYgdGFiLnR5cGUhPT0ndGFicydcIj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY2hpbGQgb2YgdGFiLmNoaWxkcmVuXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGNoaWxkLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5LCBpXSl9XCI+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDwvbWF0LXRhYi1ncm91cD5cblxuICAgICAgICA8IS0tIFZlcnRpY2FsIG1vZGUgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJndWktbGlzdFwiICpuZ0lmPVwiaXRlbS5tb2RlPT09J2xpc3QnXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImd1aS1saXN0LWl0ZW1cIiAqbmdGb3I9XCJsZXQgdGFiIG9mIGl0ZW0uY2hpbGRyZW47IGluZGV4IGFzIGlcIlxuICAgICAgICAgICAgICAgW2NsYXNzLmd1aS1saXN0LWl0ZW0tYWN0aXZlXT1cIml0ZW0uc2VsZWN0ZWRJbmRleD09PWlcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndWktbGlzdC1pdGVtLWhlYWRpbmdcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndWktbGlzdC1pdGVtLXRpdGxlXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIml0ZW0uc2VsZWN0ZWRJbmRleD1pXCI+e3t0YWIubmFtZSB8IGVqczp7aX0gfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnRlbXBsYXRlICYmIChpdGVtLmFkZGFibGUgfHwgaXRlbS5hZGRhYmxlPT09dW5kZWZpbmVkKVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkVGFiKCRldmVudCwgZm9ybS5nZXQoaXRlbS5rZXkpLCBpdGVtLCB0cnVlLCBpKVwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJjb250ZW50X2NvcHlcIj48L21hdC1pY29uPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkVGFiKCRldmVudCwgZm9ybS5nZXQoaXRlbS5rZXkpLCBpdGVtLCBmYWxzZSwgaSlcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwicGx1c1wiPjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJpdGVtLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0sIGkpXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImRlbGV0ZVwiPjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3VpLWxpc3QtaXRlbS1jb250ZW50XCI+XG4gICAgICAgICAgICAgIDwhLS0gRm9ybUNvbnRyb2wgJiBGb3JtQXJyYXkgLS0+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhdGFiLmNoaWxkcmVuIHx8IHRhYi5jaGlsZHJlbi5sZW5ndGg9PT0wIHx8IHRhYi50eXBlPT09J3RhYnMnXCI+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IHRhYiwgcGFyZW50OiBpdGVtLCBmb3JtR3JvdXA6IGZvcm0uZ2V0KFtpdGVtLmtleV0pfVwiPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8IS0tIEZvcm1Hcm91cCAtLT5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInRhYi5jaGlsZHJlbj8ubGVuZ3RoPjAgJiYgdGFiLnR5cGUhPT0ndGFicydcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjaGlsZCBvZiB0YWIuY2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGNoaWxkLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5LCBpXSl9XCI+XG4gICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuXG4gICAgPCEtLSBNZW51IC0tPlxuICAgIDxtYXQtdGFiLWdyb3VwIGNsYXNzPVwiZ3VpLW1lbnVcIiAqbmdTd2l0Y2hDYXNlPVwiJ21lbnUnXCIgW2Zvcm1Hcm91cE5hbWVdPVwiaXRlbS5rZXlcIiBkaXNhYmxlUmlwcGxlPlxuICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IG1lbnVDaGlsZCBvZiBpdGVtLmNoaWxkcmVuXCIgW2xhYmVsXT1cIm1lbnVDaGlsZC5uYW1lXCJcbiAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJtZW51Q2hpbGQuZGlzYWJsZWRcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIG1hdFRhYkNvbnRlbnQ+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lbnVDaGlsZC50eXBlPT09J21lbnVJdGVtJ1wiPlxuICAgICAgICAgICAgPCEtLSBNdXN0IHdyYXAgd2l0aCBkaXYgLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb250cm9sSXRlbSBvZiBtZW51Q2hpbGQuY2hpbGRyZW5cIiBbZm9ybUdyb3VwTmFtZV09XCJtZW51Q2hpbGQua2V5XCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY29udHJvbEl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5LCBtZW51Q2hpbGQua2V5XSl9XCI+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8IS0tIFN1cHBvcnQgZm9yIHVubGltaXRlZCBuZXN0aW5nIC0tPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtZW51Q2hpbGQudHlwZT09PSdtZW51J1wiPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogbWVudUNoaWxkLCBmb3JtR3JvdXA6IGZvcm0uZ2V0KGl0ZW0ua2V5KX1cIj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L21hdC10YWI+XG4gICAgPC9tYXQtdGFiLWdyb3VwPlxuXG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
302
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3VpLWZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9ndWkvZ3VpLWZvcm0udHMiLCIuLi8uLi8uLi9wcm9qZWN0cy9ndWkvZ3VpLWZvcm0uaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFFTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsd0JBQXdCLEVBQ3hCLHVCQUF1QixHQUN4QixNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxPQUFPLEVBQW1CLE1BQU0sd0JBQXdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXpGLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEVBQUUsVUFB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aVpBQ1gsTUFBTSxxS0FDTixXQUFXLDJFQUNYLGFBQWEsNERBQ2IsYUFBYSxnRkFDYixnQkFBZ0IscUVBQ2hCLFlBQVksMkZBQ1osY0FBYyw2RkFDZCxTQUFTLHVGQUNULFNBQVMsdUZBQ1QsU0FBUyx1RkFDVCxlQUFlLDhGQUNmLE9BQU8scUZBQ1AsZUFBZSxpSkFDZixjQUFjLHlHQUNkLFdBQVcseUZBQ1gsY0FBYyxpRkFDZCxhQUFhLG9GQUNiLFVBQVU7OzJGQUdELE9BQU87a0JBeENuQixTQUFTOytCQUNFLFVBQVUsUUFHZDt3QkFDSixXQUFXLEVBQUUsS0FBSzt3QkFDbEIsT0FBTyxFQUFFLFVBQVU7cUJBQ3BCLGlCQUNjLGlCQUFpQixDQUFDLElBQUksbUJBQ3BCLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQO3dCQUNQLG1CQUFtQjt3QkFDbkIsZ0JBQWdCO3dCQUNoQixpQkFBaUI7d0JBQ2pCLHVCQUF1Qjt3QkFDdkIsd0JBQXdCO3dCQUN4QixhQUFhO3dCQUNiLE9BQU87d0JBQ1AsV0FBVzt3QkFDWCxNQUFNO3dCQUNOLFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixhQUFhO3dCQUNiLGdCQUFnQjt3QkFDaEIsWUFBWTt3QkFDWixjQUFjO3dCQUNkLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCxTQUFTO3dCQUNULGVBQWU7d0JBQ2YsT0FBTzt3QkFDUCxlQUFlO3dCQUNmLGNBQWM7d0JBQ2QsV0FBVzt3QkFDWCxjQUFjO3dCQUNkLGFBQWE7d0JBQ2IsVUFBVTtxQkFDWDsrR0FNUSxJQUFJO3NCQUFaLEtBQUs7Z0JBS0csTUFBTTtzQkFBZCxLQUFLO2dCQUtHLEtBQUs7c0JBQWIsS0FBSztnQkFLSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1BcnJheSwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdEljb25CdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHtcbiAgTWF0RXhwYW5zaW9uUGFuZWwsXG4gIE1hdEV4cGFuc2lvblBhbmVsQ29udGVudCxcbiAgTWF0RXhwYW5zaW9uUGFuZWxIZWFkZXIsXG59IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2V4cGFuc2lvbic7XG5pbXBvcnQgeyBNYXRJY29uLCBNYXRJY29uUmVnaXN0cnkgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRhYiwgTWF0VGFiQ29udGVudCwgTWF0VGFiR3JvdXAsIE1hdFRhYkxhYmVsIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgbWVyZ2VXaXRoLCBvZiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBHdWlCdXR0b25Ub2dnbGUgfSBmcm9tICcuL2J1dHRvbi10b2dnbGUvYnV0dG9uLXRvZ2dsZSc7XG5pbXBvcnQgeyBHdWlGaWVsZEdyb3VwIH0gZnJvbSAnLi9maWVsZC1ncm91cC9maWVsZC1ncm91cCc7XG5pbXBvcnQgeyBHdWlGaWVsZExhYmVsIH0gZnJvbSAnLi9maWVsZC1sYWJlbC9maWVsZC1sYWJlbCc7XG5pbXBvcnQgeyBHdWlGaWxlVXBsb2FkZXIgfSBmcm9tICcuL2ZpbGUtdXBsb2FkZXIvZmlsZS11cGxvYWRlcic7XG5pbXBvcnQgeyBHdWlGaWxsIH0gZnJvbSAnLi9maWxsL2ZpbGwnO1xuaW1wb3J0IHsgR3VpRWpzUGlwZSwgR3VpRmxleERpcmVjdGl2ZSwgY29tcGFyZVZhbHVlcywgZ2V0VmFsdWVCeVBhdGggfSBmcm9tICcuL2d1aS11dGlscyc7XG5pbXBvcnQgeyBHdWlJbWFnZVNlbGVjdCB9IGZyb20gJy4vaW1hZ2Utc2VsZWN0L2ltYWdlLXNlbGVjdCc7XG5pbXBvcnQgeyBHdWlJbmxpbmVHcm91cCB9IGZyb20gJy4vaW5saW5lLWdyb3VwL2lubGluZS1ncm91cCc7XG5pbXBvcnQgeyBHdWlJbnB1dE51bWJlciB9IGZyb20gJy4vaW5wdXQtbnVtYmVyL2lucHV0LW51bWJlcic7XG5pbXBvcnQgeyBHdWlJbnB1dFRleHQgfSBmcm9tICcuL2lucHV0LXRleHQvaW5wdXQtdGV4dCc7XG5pbXBvcnQgeyBHdWlDb25kaXRpb24sIEd1aUNvbnRyb2wsIEd1aUZpZWxkVHlwZSwgR3VpRmllbGRzLCBHdWlUYWJzTW9kZSB9IGZyb20gJy4vaW50ZXJmYWNlJztcbmltcG9ydCB7IEd1aVNlbGVjdCB9IGZyb20gJy4vc2VsZWN0L3NlbGVjdCc7XG5pbXBvcnQgeyBHdWlTbGlkZXIgfSBmcm9tICcuL3NsaWRlci9zbGlkZXInO1xuaW1wb3J0IHsgR3VpU3dpdGNoIH0gZnJvbSAnLi9zd2l0Y2gvc3dpdGNoJztcbmltcG9ydCB7IEd1aVRleHRhcmVhIH0gZnJvbSAnLi90ZXh0YXJlYS90ZXh0YXJlYSc7XG5cbmltcG9ydCB7IHN2Z0ljb25zIH0gZnJvbSAnLi9ndWktaWNvbnMnO1xuXG5sZXQgbmV4dFVuaXF1ZUlkID0gMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZ3VpLWZvcm0nLFxuICB0ZW1wbGF0ZVVybDogJy4vZ3VpLWZvcm0uaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9ndWktZm9ybS5zY3NzJyxcbiAgaG9zdDoge1xuICAgICdbYXR0ci5pZF0nOiAndWlkJyxcbiAgICAnY2xhc3MnOiAnZ3VpLWZvcm0nLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgTmdUZW1wbGF0ZU91dGxldCxcbiAgICBNYXRFeHBhbnNpb25QYW5lbCxcbiAgICBNYXRFeHBhbnNpb25QYW5lbEhlYWRlcixcbiAgICBNYXRFeHBhbnNpb25QYW5lbENvbnRlbnQsXG4gICAgTWF0SWNvbkJ1dHRvbixcbiAgICBNYXRJY29uLFxuICAgIE1hdFRhYkdyb3VwLFxuICAgIE1hdFRhYixcbiAgICBNYXRUYWJMYWJlbCxcbiAgICBNYXRUYWJDb250ZW50LFxuICAgIEd1aUZpZWxkR3JvdXAsXG4gICAgR3VpRmxleERpcmVjdGl2ZSxcbiAgICBHdWlJbnB1dFRleHQsXG4gICAgR3VpSW5wdXROdW1iZXIsXG4gICAgR3VpU2VsZWN0LFxuICAgIEd1aVN3aXRjaCxcbiAgICBHdWlTbGlkZXIsXG4gICAgR3VpQnV0dG9uVG9nZ2xlLFxuICAgIEd1aUZpbGwsXG4gICAgR3VpRmlsZVVwbG9hZGVyLFxuICAgIEd1aUltYWdlU2VsZWN0LFxuICAgIEd1aVRleHRhcmVhLFxuICAgIEd1aUlubGluZUdyb3VwLFxuICAgIEd1aUZpZWxkTGFiZWwsXG4gICAgR3VpRWpzUGlwZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgR3VpRm9ybSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogVGhlIGZvcm0gaW5zdGFuY2Ugd2hpY2ggYWxsb3cgdG8gdHJhY2sgbW9kZWwgdmFsdWUgYW5kIHZhbGlkYXRpb24gc3RhdHVzLlxuICAgKi9cbiAgQElucHV0KCkgZm9ybSA9IG5ldyBGb3JtR3JvdXA8YW55Pih7fSk7XG5cbiAgLyoqXG4gICAqIFRoZSBmaWVsZCBjb25maWd1cmF0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIGZvcm0uXG4gICAqL1xuICBASW5wdXQoKSBjb25maWc6IEd1aUZpZWxkcyA9IHt9O1xuXG4gIC8qKlxuICAgKiBUaGUgbW9kZWwgdG8gYmUgcmVwcmVzZW50ZWQgYnkgdGhlIGZvcm0uXG4gICAqL1xuICBASW5wdXQoKSBtb2RlbDogYW55ID0ge307XG5cbiAgLyoqXG4gICAqIEZpcmVkIG9uIG1vZGVsIHZhbHVlIGNoYW5nZVxuICAgKi9cbiAgQE91dHB1dCgpIG1vZGVsQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGZvcm1GaWVsZHM6IEd1aUNvbnRyb2xbXSA9IFtdO1xuXG4gIGZvcm1TdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgY29udHJvbFN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgLy8gVW5pcXVlIGlkIGZvciB0aGlzIGZvcm1cbiAgdWlkID0gYGd1aS1mb3JtLSR7bmV4dFVuaXF1ZUlkKyt9YDtcblxuICBjb25zdHJ1Y3RvcihpY29uUmVnaXN0cnk6IE1hdEljb25SZWdpc3RyeSwgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIpIHtcbiAgICBbJ2RvdHNfaG9yaXpvbnRhbCcsICdkb3RzX3ZlcnRpY2FsJywgJ2NvbnRlbnRfY29weScsICdwbHVzJywgJ2RlbGV0ZSddLmZvckVhY2goayA9PiB7XG4gICAgICBpY29uUmVnaXN0cnkuYWRkU3ZnSWNvbkxpdGVyYWwoaywgc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKHN2Z0ljb25zW2tdKSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ2NvbmZpZyddKSB7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMgPSB7fTsgLy8gcmVzZXQgY29udHJvbHNcbiAgICAgIHRoaXMuZm9ybUZpZWxkcyA9IHRoaXMuZ2V0Rm9ybUZpZWxkQXJyYXkodGhpcy5mb3JtLCB0aGlzLmNvbmZpZywgdGhpcy5tb2RlbCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ21vZGVsJ10gJiYgdGhpcy5tb2RlbCAmJiBPYmplY3Qua2V5cyh0aGlzLm1vZGVsKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh0aGlzLm1vZGVsKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb24gPSB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMubW9kZWwsIHZhbHVlKTtcbiAgICAgIHRoaXMubW9kZWxDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmNvbnRyb2xTdWJzY3JpcHRpb25zLmZvckVhY2gocyA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdGhlIG9iamVjdCBjb25maWcgdG8gYXJyYXkgY29uZmlnIGFuZCByZWdpc3RlciBpbnRvIHRoZSByZWFjdGl2ZSBmb3JtLlxuICAgKlxuICAgKiBAcGFyYW0gZm9ybSAgICAgICAgIFRoZSByZWFjdGl2ZSBmb3JtIGluc3RhbmNlXG4gICAqIEBwYXJhbSBjb25maWcgICAgICAgVGhlIGNvbmZpZyBvZiB0aGUgZm9ybSBmaWVsZHNcbiAgICogQHBhcmFtIG1vZGVsICAgICAgICBUaGUgdmFsdWUgb2YgdGhlIGZvcm0gY29udHJvbFxuICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSBmb3JtIGZpZWxkXG4gICAqIEBwYXJhbSBwYXJlbnRUeXBlICAgVGhlIHR5cGUgb2YgdGhlIGZvcm0gZmllbGQgcGFyZW50XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBnZXRGb3JtRmllbGRBcnJheShcbiAgICBmb3JtOiBGb3JtR3JvdXAgfCBGb3JtQXJyYXksXG4gICAgY29uZmlnOiBHdWlGaWVsZHMgfCBHdWlDb250cm9sW10gPSB7fSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuICAgIGRlZmF1bHRWYWx1ZTogYW55ID0gbnVsbCxcbiAgICBwYXJlbnRUeXBlOiBHdWlGaWVsZFR5cGUgPSAnZ3JvdXAnXG4gICkge1xuICAgIGNvbnN0IHRlbXBBcnIgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpIHtcbiAgICAgIC8vIEluZmVycmluZyB0aGUgZm9ybSB0eXBlIGJ5IHRoZSBkYXRhIHR5cGUgb2YgYGNoaWxkcmVuYFxuICAgICAgLy8gMS4gYHVuZGVmaW5lZGAgPT4gRm9ybUNvbnRyb2xcbiAgICAgIC8vIDIuIGBhcnJheWAgICAgID0+IEZvcm1BcnJheVxuICAgICAgLy8gMy4gYG9iamVjdGAgICAgPT4gRm9ybUdyb3VwXG4gICAgICBjb25zdCBfY2hpbGRyZW4gPSAoY29uZmlnIGFzIGFueSlba2V5XS50ZW1wbGF0ZSA/IFtdIDogKGNvbmZpZyBhcyBhbnkpW2tleV0uY2hpbGRyZW47XG4gICAgICBjb25zdCBfdHlwZSA9ICFfY2hpbGRyZW4gPyAnY29udHJvbCcgOiBBcnJheS5pc0FycmF5KF9jaGlsZHJlbikgPyAnYXJyYXknIDogJ2dyb3VwJztcblxuICAgICAgY29uc3QgaXRlbTogR3VpQ29udHJvbCA9IHtcbiAgICAgICAgX3R5cGUsXG4gICAgICAgIGtleSxcbiAgICAgICAgcGFyZW50VHlwZSxcbiAgICAgICAgbW9kZWw6IG1vZGVsW2tleV0sXG4gICAgICAgIGRlZmF1bHQ6IGRlZmF1bHRWYWx1ZT8uW2tleV0sXG4gICAgICAgIGluZGV4OiBOdW1iZXIoa2V5KSwgLy8gdGhlIHN0cmluZyBrZXkgd2lsbCBiZSBgTmFOYFxuICAgICAgICBzaG93OiB0cnVlLFxuICAgICAgICAuLi4oY29uZmlnIGFzIGFueSlba2V5XSxcbiAgICAgIH07XG5cbiAgICAgIC8vIFRoZSBgZ3JvdXBgIHR5cGUgZ2VuZXJhbGx5IGhhdmUgbm8gYGRlZmF1bHRgLCBzbyB3ZSBzaG91bGRcbiAgICAgIC8vIHNldCB0aGUgZGVmYXVsdCB2YWx1ZSBtYW51YWxseVxuICAgICAgaWYgKGl0ZW0uY2hpbGRyZW4gJiYgbW9kZWxba2V5XSA9PSBudWxsICYmIGl0ZW0uZGVmYXVsdCA9PSBudWxsKSB7XG4gICAgICAgIGl0ZW0ubW9kZWwgPSBtb2RlbFtrZXldID0gaXRlbS5fdHlwZSA9PT0gJ2FycmF5JyA/IFtdIDoge307XG4gICAgICB9XG5cbiAgICAgIC8vIEdlbmVyYXRlIG1vZGVsIGJ5IHRoZSBgZGVmYXVsdGAga2V5IG9mIHRoZSBmaWVsZCBjb25maWdcbiAgICAgIGlmICh0eXBlb2YgbW9kZWwgPT09ICdvYmplY3QnICYmIG1vZGVsW2tleV0gPT0gbnVsbCkge1xuICAgICAgICBtb2RlbFtrZXldID0gaXRlbS5kZWZhdWx0O1xuICAgICAgfVxuXG4gICAgICAvLyBTcGVjaWFsIGp1ZGdtZW50IG9uIGB0YWJzYCB0eXBlLCB0aGUgYGNoaWxkcmVuYCBrZXkgd2lsbCBiZSBpZ25vcmVkIGlmXG4gICAgICAvLyB0aGVyZSBoYXMgYSBgdGVtcGxhdGVgIGtleVxuICAgICAgaWYgKGl0ZW0udGVtcGxhdGUpIHtcbiAgICAgICAgLy8gSWYgbW9kZWwgaXMgYW4gYXJyYXkgYW5kIG5vdCBlbXB0eSwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGZvcm0gZmllbGRcbiAgICAgICAgLy8gd2lsbCB1c2UgdGhlIG1vZGVsJ3MgdmFsdWVcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaXRlbS5tb2RlbCkgJiYgaXRlbS5tb2RlbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaXRlbS5kZWZhdWx0ID0gaXRlbS5tb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5kZWZhdWx0Py5sZW5ndGgpIHtcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuID0gaXRlbS5kZWZhdWx0Lm1hcCgodmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih2YWx1ZSwgaXRlbS50ZW1wbGF0ZT8uZGVmYXVsdCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkZWZhdWx0OiB2YWx1ZSxcbiAgICAgICAgICAgICAgLi4uaXRlbS50ZW1wbGF0ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbS5jaGlsZHJlbiA9IFtdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFBhcnNlIHRoZSBgc2hvd0lmYCBjb25kaXRpb25zXG4gICAgICBpZiAoaXRlbS5zaG93SWYpIHtcbiAgICAgICAgY29uc3Qgc2V0VmlzaWJpbGl0eSA9IChjb21wYXJlV2l0aDogKGNvbmRpdGlvbjogR3VpQ29uZGl0aW9uKSA9PiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgaWYgKGl0ZW0uc2hvd0lmIS5sb2dpY2FsVHlwZSA9PT0gJyRvcicpIHtcbiAgICAgICAgICAgIGl0ZW0uc2hvdyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLnNvbWUoYyA9PiBjb21wYXJlV2l0aChjKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW0uc2hvdyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLmV2ZXJ5KGMgPT4gY29tcGFyZVdpdGgoYykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdGhlIGluaXQgdmlzaWJpbGl0eSBvZiB0aGUgZmllbGRcbiAgICAgICAgc2V0VmlzaWJpbGl0eShjID0+IHtcbiAgICAgICAgICBjb25zdCBjZmcgPSBnZXRWYWx1ZUJ5UGF0aChjb25maWcsIGNbMF0pID8/IGdldFZhbHVlQnlQYXRoKHRoaXMuY29uZmlnLCBjWzBdKTtcbiAgICAgICAgICBjb25zdCB2YWwgPSBnZXRWYWx1ZUJ5UGF0aChtb2RlbCwgY1swXSkgPz8gZ2V0VmFsdWVCeVBhdGgodGhpcy5tb2RlbCwgY1swXSk7XG4gICAgICAgICAgcmV0dXJuIGNvbXBhcmVWYWx1ZXMoY2ZnPy5bJ2RlZmF1bHQnXSA/PyB2YWwsIGNbMl0sIGNbMV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBEZWxheSB0aGUgc3Vic2NyaXB0aW9uIHRvIG1ha2Ugc3VyZSBhbGwgdGhlIGZvcm0gY29udHJvbHMgaGF2ZSBiZWVuIGNyZWF0ZWRcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ2V0Q29udHJvbCA9IChwYXRoOiBzdHJpbmcpID0+IGZvcm0uZ2V0KHBhdGgpIHx8IHRoaXMuZm9ybS5nZXQocGF0aCk7XG5cbiAgICAgICAgICBjb25zdCBjb250cm9scyA9IGl0ZW0uc2hvd0lmIS5jb25kaXRpb25zLm1hcChjID0+IGdldENvbnRyb2woY1swXSkpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlQ2hhbmdlcyQgPSBjb250cm9scy5tYXAoY29udHJvbCA9PiBjb250cm9sPy52YWx1ZUNoYW5nZXMgfHwgb2YoKSk7XG4gICAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gb2YoKVxuICAgICAgICAgICAgLnBpcGUobWVyZ2VXaXRoKHZhbHVlQ2hhbmdlcyQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIHNldFZpc2liaWxpdHkoYyA9PiBjb21wYXJlVmFsdWVzKGdldENvbnRyb2woY1swXSk/LnZhbHVlLCBjWzJdLCBjWzFdKSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuY29udHJvbFN1YnNjcmlwdGlvbnMucHVzaChzdWJzY3JpcHRpb24pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGl0ZW0uX3R5cGUgPT09ICdjb250cm9sJykge1xuICAgICAgICBjb25zdCBmb3JtU3RhdGUgPSB7IHZhbHVlOiBpdGVtLmRlZmF1bHQsIGRpc2FibGVkOiBpdGVtLmRpc2FibGVkIH07XG4gICAgICAgIGlmIChmb3JtIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgICAgZm9ybS5yZWdpc3RlckNvbnRyb2woaXRlbS5rZXksIG5ldyBGb3JtQ29udHJvbChmb3JtU3RhdGUpKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgICAgZm9ybS5pbnNlcnQoaXRlbS5pbmRleCB8fCBmb3JtLmxlbmd0aCwgbmV3IEZvcm1Db250cm9sKGZvcm1TdGF0ZSksIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpdGVtLl90eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAgIGxldCBmb3JtQXJyYXkgPSBuZXcgRm9ybUFycmF5PGFueT4oW10pO1xuICAgICAgICBpZiAoZm9ybSBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgIGZvcm1BcnJheSA9IGZvcm0ucmVnaXN0ZXJDb250cm9sKGl0ZW0ua2V5LCBuZXcgRm9ybUFycmF5KFtdKSkgYXMgRm9ybUFycmF5O1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm0gaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgICAgICBmb3JtLmluc2VydChpdGVtLmluZGV4IHx8IGZvcm0ubGVuZ3RoLCBmb3JtQXJyYXksIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0ZW0uY2hpbGRyZW4gPSB0aGlzLmdldEZvcm1GaWVsZEFycmF5KFxuICAgICAgICAgIGZvcm1BcnJheSxcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuLFxuICAgICAgICAgIGl0ZW0ubW9kZWwsXG4gICAgICAgICAgaXRlbS5kZWZhdWx0LFxuICAgICAgICAgIGl0ZW0udHlwZVxuICAgICAgICApO1xuXG4gICAgICAgIGl0ZW0uc2VsZWN0ZWRJbmRleCA9IDA7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW0uX3R5cGUgPT09ICdncm91cCcpIHtcbiAgICAgICAgbGV0IGZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICAgICAgICBpZiAoZm9ybSBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICAgIGZvcm1Hcm91cCA9IGZvcm0ucmVnaXN0ZXJDb250cm9sKGl0ZW0ua2V5LCBuZXcgRm9ybUdyb3VwKHt9KSkgYXMgRm9ybUdyb3VwO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm0gaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgICAgICBmb3JtLmluc2VydChpdGVtLmluZGV4IHx8IGZvcm0ubGVuZ3RoLCBmb3JtR3JvdXAsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0ZW0uY2hpbGRyZW4gPSB0aGlzLmdldEZvcm1GaWVsZEFycmF5KFxuICAgICAgICAgIGZvcm1Hcm91cCxcbiAgICAgICAgICBpdGVtLmNoaWxkcmVuLFxuICAgICAgICAgIGl0ZW0ubW9kZWwsXG4gICAgICAgICAgaXRlbS5kZWZhdWx0LFxuICAgICAgICAgIGl0ZW0udHlwZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0ZW1wQXJyLnB1c2goaXRlbSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRlbXBBcnI7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgdGFiIGl0ZW0uXG4gICAqXG4gICAqIEBwYXJhbSBlICAgICAgICAgVGhlIG1vdXNlIGV2ZW50XG4gICAqIEBwYXJhbSBmb3JtQXJyYXkgVGhlIHJlYWN0aXZlIGZvcm0gaW5zdGFuY2VcbiAgICogQHBhcmFtIHRhYnMgICAgICBUaGUgY29uZmlnIG9mIHRoZSB0YWJzIGZpZWxkXG4gICAqIEBwYXJhbSBjb3B5ICAgICAgV2hldGhlciB0byBjb3B5IHRoZSBjdXJyZW50IHRhYlxuICAgKiBAcGFyYW0gaW5kZXggICAgIFRoZSBpbmRleCBvZiB0aGUgdGFicyBhcnJheVxuICAgKi9cbiAgYWRkVGFiKGU6IE1vdXNlRXZlbnQsIGZvcm1BcnJheTogRm9ybUFycmF5LCB0YWJzOiBHdWlDb250cm9sLCBjb3B5PzogYm9vbGVhbiwgaW5kZXg/OiBudW1iZXIpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGluc2VydEluZGV4ID1cbiAgICAgIGluZGV4ICE9PSB2b2lkIDAgPyBpbmRleCArIDEgOiBjb3B5ID8gdGFicy5zZWxlY3RlZEluZGV4ISArIDEgOiB0YWJzLmNoaWxkcmVuIS5sZW5ndGg7XG4gICAgLy8gU2F2ZSB0aGUgaW5kZXggb2YgdGhlIGluc2VydGlvbiBpbiB0aGUgY29uZmlnXG4gICAgdGFicy50ZW1wbGF0ZSEuaW5kZXggPSBpbnNlcnRJbmRleDtcbiAgICAvLyBUaGUga2V5IGluIHRoZSBvYmplY3QgYW5kIHRoZSBpbmRleCBpbiB0aGUgYXJyYXkgc2hvdWxkIGJlIHRoZSBzYW1lXG4gICAgdGFicy5jaGlsZHJlbiEuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPj0gaW5zZXJ0SW5kZXgpIHtcbiAgICAgICAgY2hpbGQuaW5kZXghICs9IDE7XG4gICAgICAgIGNoaWxkLmtleSA9IGNoaWxkLmluZGV4ICsgJyc7IC8vIGNvbnZlcnQgdG8gc3RyaW5nXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBmb3JtVmFsdWUgPSBmb3JtQXJyYXkuZ2V0KGluc2VydEluZGV4IC0gMSArICcnKT8udmFsdWU7XG4gICAgLy8gVGhlIGNvbnN0cnVjdGVkIG9iamVjdCBsb29rcyBsaWtlIHRoaXMgYFt7IGtleTogJ3RhYicsIGNoaWxkcmVuOiB0ZW1wbGF0ZSB9XWBcbiAgICAvLyBUaGUga2V5IHNob3VsZCBwcmVmZXJhYmx5IGJlIGBudWxsYFxuICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMuZ2V0Rm9ybUZpZWxkQXJyYXkoXG4gICAgICBmb3JtQXJyYXksXG4gICAgICB7IFtpbnNlcnRJbmRleF06IHRhYnMudGVtcGxhdGUgfSBhcyBHdWlGaWVsZHMsXG4gICAgICBjb3B5ID8geyBbaW5zZXJ0SW5kZXhdOiBmb3JtVmFsdWUgfSA6IHt9LFxuICAgICAgY29weSA/IHsgW2luc2VydEluZGV4XTogZm9ybVZhbHVlIH0gOiBudWxsLFxuICAgICAgJ3RhYnMnXG4gICAgKTtcbiAgICB0YWJzLmNoaWxkcmVuIS5zcGxpY2UoaW5zZXJ0SW5kZXgsIDAsIG5ld1RhYlswXSk7XG5cbiAgICAvLyB1cGRhdGUgdGhlIGZvcm0gbW9kZWxcbiAgICBmb3JtQXJyYXkucGF0Y2hWYWx1ZShmb3JtQXJyYXkudmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHRhYiBpdGVtLlxuICAgKlxuICAgKiBAcGFyYW0gZSAgICAgICAgIFRoZSBtb3VzZSBldmVudFxuICAgKiBAcGFyYW0gZm9ybUFycmF5IFRoZSByZWFjdGl2ZSBmb3JtIGluc3RhbmNlXG4gICAqIEBwYXJhbSB0YWJzICAgICAgVGhlIGNvbmZpZyBvZiB0aGUgdGFicyBmaWVsZFxuICAgKiBAcGFyYW0gaW5kZXggICAgIFRoZSBpbmRleCBvZiB0aGUgdGFicyBhcnJheVxuICAgKi9cbiAgcmVtb3ZlVGFiKGU6IE1vdXNlRXZlbnQsIGZvcm1BcnJheTogRm9ybUFycmF5LCB0YWJzOiBHdWlDb250cm9sLCBpbmRleD86IG51bWJlcikge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgcmVtb3ZlSW5kZXggPSBpbmRleCA9PT0gdm9pZCAwID8gdGFicy5zZWxlY3RlZEluZGV4ISA6IGluZGV4O1xuICAgIHRhYnMuY2hpbGRyZW4hLmZvckVhY2goKGNoaWxkLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ID4gcmVtb3ZlSW5kZXgpIHtcbiAgICAgICAgY2hpbGQuaW5kZXghIC09IDE7XG4gICAgICAgIGNoaWxkLmtleSA9IGNoaWxkLmluZGV4ICsgJyc7IC8vIGNvbnZlcnQgdG8gc3RyaW5nXG4gICAgICB9XG4gICAgfSk7XG4gICAgdGFicy5jaGlsZHJlbiEuc3BsaWNlKHJlbW92ZUluZGV4LCAxKTtcbiAgICBmb3JtQXJyYXkucmVtb3ZlQXQocmVtb3ZlSW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZSB0aGUgZGlzcGxheSBtb2RlIG9mIHRhYnMuXG4gICAqXG4gICAqIEBwYXJhbSBlICAgIFRoZSBtb3VzZSBldmVudFxuICAgKiBAcGFyYW0gdGFicyBUaGUgY29uZmlnIG9mIHRoZSB0YWJzIGZpZWxkXG4gICAqIEBwYXJhbSBtb2RlIFRoZSBkaXNwbGF5IG1vZGUgb2YgdGFic1xuICAgKi9cbiAgY2hhbmdlVGFic01vZGUoZTogTW91c2VFdmVudCwgdGFiczogR3VpQ29udHJvbCwgbW9kZT86IEd1aVRhYnNNb2RlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0YWJzLm1vZGUgPSBtb2RlO1xuICB9XG59XG4iLCI8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgQGZvciAoaXRlbSBvZiBmb3JtRmllbGRzOyB0cmFjayBpdGVtKSB7XG4gICAgPGRpdj5cbiAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBpdGVtLCBmb3JtR3JvdXA6IGZvcm19XCI+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICB9XG48L2Zvcm0+XG5cbjxuZy10ZW1wbGF0ZSAjY29udHJvbFR5cGUgbGV0LWl0ZW0gbGV0LXBhcmVudD1cInBhcmVudFwiIGxldC1mb3JtPVwiZm9ybUdyb3VwXCI+XG4gIEBpZiAoaXRlbS5zaG93KSB7XG4gICAgPG5nLWNvbnRhaW5lciBbZm9ybUdyb3VwXT1cImZvcm1cIj5cbiAgICAgIEBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICBAY2FzZSAoJ3RleHQnKSB7XG4gICAgICAgICAgPGd1aS1maWVsZC1ncm91cCBbY29uZmlnXT1cIml0ZW1cIiBbZmxleF09XCJpdGVtLmNvbFwiPlxuICAgICAgICAgICAgPGd1aS1pbnB1dC10ZXh0IFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnbnVtYmVyJykge1xuICAgICAgICAgIDxndWktZmllbGQtZ3JvdXAgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgICAgICAgIDxndWktaW5wdXQtbnVtYmVyIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnc2VsZWN0Jykge1xuICAgICAgICAgIDxndWktZmllbGQtZ3JvdXAgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgICAgICAgIDxndWktc2VsZWN0IFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnc3dpdGNoJykge1xuICAgICAgICAgIDxndWktZmllbGQtZ3JvdXAgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgICAgICAgIDxndWktc3dpdGNoIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnc2xpZGVyJykge1xuICAgICAgICAgIDxndWktZmllbGQtZ3JvdXAgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgICAgICAgIDxndWktc2xpZGVyIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnYnV0dG9uVG9nZ2xlJykge1xuICAgICAgICAgIDxndWktZmllbGQtZ3JvdXAgW2NvbmZpZ109XCJpdGVtXCIgW2ZsZXhdPVwiaXRlbS5jb2xcIj5cbiAgICAgICAgICAgIDxndWktYnV0dG9uLXRvZ2dsZSBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCIgLz5cbiAgICAgICAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoJ2ZpbGwnKSB7XG4gICAgICAgICAgPGd1aS1maWVsZC1ncm91cCBbY29uZmlnXT1cIml0ZW1cIiBbZmxleF09XCJpdGVtLmNvbFwiPlxuICAgICAgICAgICAgPGd1aS1maWxsIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIiBbY29uZmlnXT1cIml0ZW1cIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnZmlsZScpIHtcbiAgICAgICAgICA8Z3VpLWZpZWxkLWdyb3VwIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICAgICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiIC8+XG4gICAgICAgICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKCdpbWFnZScpIHtcbiAgICAgICAgICA8Z3VpLWZpZWxkLWdyb3VwIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICAgICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgdHlwZT1cImltYWdlXCIgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiIC8+XG4gICAgICAgICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKCd2aWRlbycpIHtcbiAgICAgICAgICA8Z3VpLWZpZWxkLWdyb3VwIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICAgICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgdHlwZT1cInZpZGVvXCIgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiIC8+XG4gICAgICAgICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKCdhdWRpbycpIHtcbiAgICAgICAgICA8Z3VpLWZpZWxkLWdyb3VwIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICAgICAgICA8Z3VpLWZpbGUtdXBsb2FkZXIgdHlwZT1cImF1ZGlvXCIgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiIFtjb25maWddPVwiaXRlbVwiIC8+XG4gICAgICAgICAgPC9ndWktZmllbGQtZ3JvdXA+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKCdpbWFnZVNlbGVjdCcpIHtcbiAgICAgICAgICA8Z3VpLWZpZWxkLWdyb3VwIFtjb25maWddPVwiaXRlbVwiIFtmbGV4XT1cIml0ZW0uY29sXCI+XG4gICAgICAgICAgICA8Z3VpLWltYWdlLXNlbGVjdCBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCIgW2FwcGVuZFRvXT1cIicjJyt1aWRcIiAvPlxuICAgICAgICAgIDwvZ3VpLWZpZWxkLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgndGV4dGFyZWEnKSB7XG4gICAgICAgICAgPGd1aS1maWVsZC1ncm91cCBbY29uZmlnXT1cIml0ZW1cIiBbZmxleF09XCJpdGVtLmNvbFwiPlxuICAgICAgICAgICAgPGd1aS10ZXh0YXJlYSBbZm9ybUNvbnRyb2xOYW1lXT1cIml0ZW0ua2V5XCIgW2NvbmZpZ109XCJpdGVtXCIgLz5cbiAgICAgICAgICA8L2d1aS1maWVsZC1ncm91cD5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoJ2hpZGRlbicpIHtcbiAgICAgICAgICA8aW5wdXQgdHlwZT1cImhpZGRlblwiIFtmb3JtQ29udHJvbE5hbWVdPVwiaXRlbS5rZXlcIj5cbiAgICAgICAgfVxuICAgICAgICBAY2FzZSAoJ2lubGluZScpIHtcbiAgICAgICAgICA8Z3VpLWlubGluZS1ncm91cCBbY29uZmlnXT1cIml0ZW1cIiBbZm9ybUdyb3VwTmFtZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgQGZvciAoY2hpbGQgb2YgaXRlbS5jaGlsZHJlbjsgdHJhY2sgY2hpbGQpIHtcbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY2hpbGQsIHBhcmVudDogaXRlbSwgZm9ybUdyb3VwOiBmb3JtLmdldChpdGVtLmtleSl9XCI+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9ndWktaW5saW5lLWdyb3VwPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnZ3JvdXAnKSB7XG4gICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwgW2Zvcm1Hcm91cE5hbWVdPVwiaXRlbS5rZXlcIlxuICAgICAgICAgICAgWyhleHBhbmRlZCldPVwiaXRlbS5leHBhbmRlZFwiIFtkaXNhYmxlZF09XCJpdGVtLmRpc2FibGVkXCI+XG4gICAgICAgICAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG4gICAgICAgICAgICAgIDxndWktZmllbGQtbGFiZWwgW2NvbmZpZ109XCJpdGVtXCIgLz5cbiAgICAgICAgICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XG4gICAgICAgICAgICA8IS0tIExhenkgcmVuZGVyaW5nIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG1hdEV4cGFuc2lvblBhbmVsQ29udGVudD5cbiAgICAgICAgICAgICAgQGZvciAoY2hpbGQgb2YgaXRlbS5jaGlsZHJlbjsgdHJhY2sgY2hpbGQpIHtcbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbnRyb2xUeXBlXCJcbiAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGNoaWxkLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoaXRlbS5rZXkpfVwiPlxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWw+XG4gICAgICAgIH1cbiAgICAgICAgQGNhc2UgKCd0YWJzJykge1xuICAgICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsIFtmb3JtQXJyYXlOYW1lXT1cIml0ZW0ua2V5XCJcbiAgICAgICAgICAgIFsoZXhwYW5kZWQpXT1cIml0ZW0uZXhwYW5kZWRcIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiPlxuICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxuICAgICAgICAgICAgICA8Z3VpLWZpZWxkLWxhYmVsIFtjb25maWddPVwiaXRlbVwiIC8+XG4gICAgICAgICAgICAgIDwhLS0gU2hvdyBvcGVyYXRpb24gYnV0dG9ucyB3aGVuIHBhbmVsIG9wZW5lZCAtLT5cbiAgICAgICAgICAgICAgQGlmIChpdGVtLmV4cGFuZGVkKSB7XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gdHlwZT1cImJ1dHRvblwiIFtjb2xvcl09XCJpdGVtLm1vZGUhPT0nbGlzdCc/J3ByaW1hcnknOicnXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjaGFuZ2VUYWJzTW9kZSgkZXZlbnQsIGl0ZW0sICdub3JtYWwnKVwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJkb3RzX2hvcml6b250YWxcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbY29sb3JdPVwiaXRlbS5tb2RlPT09J2xpc3QnPydwcmltYXJ5JzonJ1wiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hhbmdlVGFic01vZGUoJGV2ZW50LCBpdGVtLCAnbGlzdCcpXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImRvdHNfdmVydGljYWxcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIEBpZiAoaXRlbS50ZW1wbGF0ZSAmJiAoaXRlbS5hZGRhYmxlIHx8IGl0ZW0uYWRkYWJsZT09PXVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0sIHRydWUpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwiY29udGVudF9jb3B5XCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJpdGVtLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFRhYigkZXZlbnQsIGZvcm0uZ2V0KGl0ZW0ua2V5KSwgaXRlbSlcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJwbHVzXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJpdGVtLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZVRhYigkZXZlbnQsIGZvcm0uZ2V0KGl0ZW0ua2V5KSwgaXRlbSlcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJkZWxldGVcIiAvPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxuICAgICAgICAgICAgPCEtLSBMYXp5IHJlbmRlcmluZyAtLT5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBtYXRFeHBhbnNpb25QYW5lbENvbnRlbnQ+XG4gICAgICAgICAgICAgIEBpZiAoaXRlbS5tb2RlIT09J2xpc3QnKSB7XG4gICAgICAgICAgICAgICAgPCEtLSBIb3Jpem9udGFsIG1vZGUgLS0+XG4gICAgICAgICAgICAgICAgPG1hdC10YWItZ3JvdXAgY2xhc3M9XCJndWktdGFic1wiIGRpc2FibGVSaXBwbGVcbiAgICAgICAgICAgICAgICAgIFttYXQtc3RyZXRjaC10YWJzXT1cImZhbHNlXCIgWyhzZWxlY3RlZEluZGV4KV09XCJpdGVtLnNlbGVjdGVkSW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKHRhYiBvZiBpdGVtLmNoaWxkcmVuOyB0cmFjayB0YWI7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtdGFiIFtkaXNhYmxlZF09XCJ0YWIuZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbWF0LXRhYi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+e3t0YWIubmFtZSB8IGVqczp7aX0gfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRm9ybUNvbnRyb2wgJiBGb3JtQXJyYXkgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgQGlmICghdGFiLmNoaWxkcmVuIHx8IHRhYi5jaGlsZHJlbi5sZW5ndGg9PT0wIHx8IHRhYi50eXBlPT09J3RhYnMnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udHJvbFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogdGFiLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5XSl9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm1Hcm91cCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHRhYi5jaGlsZHJlbj8ubGVuZ3RoPjAgJiYgdGFiLnR5cGUhPT0ndGFicycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKGNoaWxkIG9mIHRhYi5jaGlsZHJlbjsgdHJhY2sgY2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udHJvbFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IGNoaWxkLCBwYXJlbnQ6IGl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5LCBpXSl9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICA8IS0tIFZlcnRpY2FsIG1vZGUgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd1aS1saXN0XCI+XG4gICAgICAgICAgICAgICAgICBAZm9yICh0YWIgb2YgaXRlbS5jaGlsZHJlbjsgdHJhY2sgdGFiOyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3VpLWxpc3QtaXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmd1aS1saXN0LWl0ZW0tYWN0aXZlXT1cIml0ZW0uc2VsZWN0ZWRJbmRleD09PWlcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3VpLWxpc3QtaXRlbS1oZWFkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImd1aS1saXN0LWl0ZW0tdGl0bGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIml0ZW0uc2VsZWN0ZWRJbmRleD1pXCI+e3t0YWIubmFtZSB8IGVqczp7aX0gfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGl0ZW0udGVtcGxhdGUgJiYgKGl0ZW0uYWRkYWJsZSB8fCBpdGVtLmFkZGFibGU9PT11bmRlZmluZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWljb24tYnV0dG9uIHR5cGU9XCJidXR0b25cIiBbZGlzYWJsZWRdPVwiaXRlbS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFRhYigkZXZlbnQsIGZvcm0uZ2V0KGl0ZW0ua2V5KSwgaXRlbSwgdHJ1ZSwgaSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gc3ZnSWNvbj1cImNvbnRlbnRfY29weVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2Rpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0sIGZhbHNlLCBpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwicGx1c1wiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2Rpc2FibGVkXT1cIml0ZW0uZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVUYWIoJGV2ZW50LCBmb3JtLmdldChpdGVtLmtleSksIGl0ZW0sIGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJkZWxldGVcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ3VpLWxpc3QtaXRlbS1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEZvcm1Db250cm9sICYgRm9ybUFycmF5IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghdGFiLmNoaWxkcmVuIHx8IHRhYi5jaGlsZHJlbi5sZW5ndGg9PT0wIHx8IHRhYi50eXBlPT09J3RhYnMnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250cm9sVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInskaW1wbGljaXQ6IHRhYiwgcGFyZW50OiBpdGVtLCBmb3JtR3JvdXA6IGZvcm0uZ2V0KFtpdGVtLmtleV0pfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3JtR3JvdXAgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHRhYi5jaGlsZHJlbj8ubGVuZ3RoPjAgJiYgdGFiLnR5cGUhPT0ndGFicycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoY2hpbGQgb2YgdGFiLmNoaWxkcmVuOyB0cmFjayBjaGlsZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udHJvbFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY2hpbGQsIHBhcmVudDogaXRlbSwgZm9ybUdyb3VwOiBmb3JtLmdldChbaXRlbS5rZXksIGldKX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxuICAgICAgICB9XG4gICAgICAgIEBjYXNlICgnbWVudScpIHtcbiAgICAgICAgICA8bWF0LXRhYi1ncm91cCBjbGFzcz1cImd1aS1tZW51XCIgW2Zvcm1Hcm91cE5hbWVdPVwiaXRlbS5rZXlcIiBkaXNhYmxlUmlwcGxlPlxuICAgICAgICAgICAgQGZvciAobWVudUNoaWxkIG9mIGl0ZW0uY2hpbGRyZW47IHRyYWNrIG1lbnVDaGlsZCkge1xuICAgICAgICAgICAgICA8bWF0LXRhYiBbbGFiZWxdPVwibWVudUNoaWxkLm5hbWVcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJtZW51Q2hpbGQuZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbWF0VGFiQ29udGVudD5cbiAgICAgICAgICAgICAgICAgIEBpZiAobWVudUNoaWxkLnR5cGU9PT0nbWVudUl0ZW0nKSB7XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTXVzdCB3cmFwIHdpdGggZGl2IC0tPlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChjb250cm9sSXRlbSBvZiBtZW51Q2hpbGQuY2hpbGRyZW47IHRyYWNrIGNvbnRyb2xJdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBbZm9ybUdyb3VwTmFtZV09XCJtZW51Q2hpbGQua2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udHJvbFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY29udHJvbEl0ZW0sIGZvcm1Hcm91cDogZm9ybS5nZXQoW2l0ZW0ua2V5LCBtZW51Q2hpbGQua2V5XSl9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8IS0tIFN1cHBvcnQgZm9yIHVubGltaXRlZCBuZXN0aW5nIC0tPlxuICAgICAgICAgICAgICAgICAgQGlmIChtZW51Q2hpbGQudHlwZT09PSdtZW51Jykge1xuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udHJvbFR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7JGltcGxpY2l0OiBtZW51Q2hpbGQsIGZvcm1Hcm91cDogZm9ybS5nZXQoaXRlbS5rZXkpfVwiPlxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==