@covalent/dynamic-forms 6.3.0 → 6.4.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.
- package/esm2022/lib/dynamic-element.component.mjs +229 -0
- package/esm2022/lib/dynamic-elements/dynamic-checkbox/dynamic-checkbox.component.mjs +18 -0
- package/esm2022/lib/dynamic-elements/dynamic-datepicker/dynamic-datepicker.component.mjs +26 -0
- package/esm2022/lib/dynamic-elements/dynamic-file-input/dynamic-file-input.component.mjs +28 -0
- package/esm2022/lib/dynamic-elements/dynamic-input/dynamic-input.component.mjs +27 -0
- package/esm2022/lib/dynamic-elements/dynamic-select/dynamic-select.component.mjs +25 -0
- package/esm2022/lib/dynamic-elements/dynamic-slide-toggle/dynamic-slide-toggle.component.mjs +18 -0
- package/esm2022/lib/dynamic-elements/dynamic-slider/dynamic-slider.component.mjs +30 -0
- package/esm2022/lib/dynamic-elements/dynamic-textarea/dynamic-textarea.component.mjs +22 -0
- package/esm2022/lib/dynamic-forms.component.mjs +191 -0
- package/{esm2020 → esm2022}/lib/dynamic-forms.module.mjs +48 -48
- package/{esm2020 → esm2022}/lib/services/dynamic-forms.service.mjs +4 -4
- package/fesm2022/covalent-dynamic-forms.mjs +814 -0
- package/{fesm2015 → fesm2022}/covalent-dynamic-forms.mjs.map +1 -1
- package/lib/dynamic-element.component.d.ts +2 -2
- package/lib/dynamic-forms.component.d.ts +1 -1
- package/package.json +9 -17
- package/esm2020/lib/dynamic-element.component.mjs +0 -176
- package/esm2020/lib/dynamic-elements/dynamic-checkbox/dynamic-checkbox.component.mjs +0 -19
- package/esm2020/lib/dynamic-elements/dynamic-datepicker/dynamic-datepicker.component.mjs +0 -23
- package/esm2020/lib/dynamic-elements/dynamic-file-input/dynamic-file-input.component.mjs +0 -28
- package/esm2020/lib/dynamic-elements/dynamic-input/dynamic-input.component.mjs +0 -22
- package/esm2020/lib/dynamic-elements/dynamic-select/dynamic-select.component.mjs +0 -23
- package/esm2020/lib/dynamic-elements/dynamic-slide-toggle/dynamic-slide-toggle.component.mjs +0 -19
- package/esm2020/lib/dynamic-elements/dynamic-slider/dynamic-slider.component.mjs +0 -26
- package/esm2020/lib/dynamic-elements/dynamic-textarea/dynamic-textarea.component.mjs +0 -22
- package/esm2020/lib/dynamic-forms.component.mjs +0 -185
- package/fesm2015/covalent-dynamic-forms.mjs +0 -745
- package/fesm2020/covalent-dynamic-forms.mjs +0 -743
- package/fesm2020/covalent-dynamic-forms.mjs.map +0 -1
- /package/{esm2020 → esm2022}/covalent-dynamic-forms.mjs +0 -0
- /package/{esm2020 → esm2022}/public_api.mjs +0 -0
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, ContentChildren, QueryList, } from '@angular/core';
|
|
2
|
-
import { UntypedFormBuilder, } from '@angular/forms';
|
|
3
|
-
import { TdDynamicFormsService, } from './services/dynamic-forms.service';
|
|
4
|
-
import { TdDynamicFormsErrorTemplateDirective } from './dynamic-element.component';
|
|
5
|
-
import { timer, Subject } from 'rxjs';
|
|
6
|
-
import { takeUntil, filter } from 'rxjs/operators';
|
|
7
|
-
import * as i0 from "@angular/core";
|
|
8
|
-
import * as i1 from "@angular/forms";
|
|
9
|
-
import * as i2 from "./services/dynamic-forms.service";
|
|
10
|
-
import * as i3 from "@angular/common";
|
|
11
|
-
import * as i4 from "./dynamic-element.component";
|
|
12
|
-
export class TdDynamicFormsComponent {
|
|
13
|
-
/**
|
|
14
|
-
* elements: ITdDynamicElementConfig[]
|
|
15
|
-
* JS Object that will render the elements depending on its config.
|
|
16
|
-
* [name] property is required.
|
|
17
|
-
*/
|
|
18
|
-
set elements(elements) {
|
|
19
|
-
if (elements) {
|
|
20
|
-
this._elements = elements;
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
this._elements = [];
|
|
24
|
-
}
|
|
25
|
-
this._rerenderElements();
|
|
26
|
-
}
|
|
27
|
-
get elements() {
|
|
28
|
-
return this._renderedElements;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Getter property for dynamic [FormGroup].
|
|
32
|
-
*/
|
|
33
|
-
get form() {
|
|
34
|
-
return this.dynamicForm;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Getter property for [valid] of dynamic [FormGroup].
|
|
38
|
-
*/
|
|
39
|
-
get valid() {
|
|
40
|
-
if (this.dynamicForm) {
|
|
41
|
-
return this.dynamicForm.valid;
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Getter property for [value] of dynamic [FormGroup].
|
|
47
|
-
*/
|
|
48
|
-
get value() {
|
|
49
|
-
if (this.dynamicForm) {
|
|
50
|
-
return this.dynamicForm.value;
|
|
51
|
-
}
|
|
52
|
-
return {};
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Getter property for [errors] of dynamic [FormGroup].
|
|
56
|
-
*/
|
|
57
|
-
get errors() {
|
|
58
|
-
if (this.dynamicForm) {
|
|
59
|
-
const errors = {};
|
|
60
|
-
for (const name of Object.keys(this.dynamicForm.controls)) {
|
|
61
|
-
errors[name] = this.dynamicForm.controls[name].errors;
|
|
62
|
-
}
|
|
63
|
-
return errors;
|
|
64
|
-
}
|
|
65
|
-
return {};
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Getter property for [controls] of dynamic [FormGroup].
|
|
69
|
-
*/
|
|
70
|
-
get controls() {
|
|
71
|
-
if (this.dynamicForm) {
|
|
72
|
-
return this.dynamicForm.controls;
|
|
73
|
-
}
|
|
74
|
-
return {};
|
|
75
|
-
}
|
|
76
|
-
constructor(_formBuilder, _dynamicFormsService, _changeDetectorRef) {
|
|
77
|
-
this._formBuilder = _formBuilder;
|
|
78
|
-
this._dynamicFormsService = _dynamicFormsService;
|
|
79
|
-
this._changeDetectorRef = _changeDetectorRef;
|
|
80
|
-
this._renderedElements = [];
|
|
81
|
-
this._templateMap = new Map();
|
|
82
|
-
this._destroy$ = new Subject();
|
|
83
|
-
this._destroyControl$ = new Subject();
|
|
84
|
-
this.dynamicForm = this._formBuilder.group({});
|
|
85
|
-
}
|
|
86
|
-
ngAfterContentInit() {
|
|
87
|
-
this._updateErrorTemplates();
|
|
88
|
-
}
|
|
89
|
-
ngOnDestroy() {
|
|
90
|
-
this._destroy$.next(0);
|
|
91
|
-
this._destroy$.complete();
|
|
92
|
-
this._destroyControl$.complete();
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Refreshes the form and rerenders all validator/element modifications.
|
|
96
|
-
*/
|
|
97
|
-
refresh() {
|
|
98
|
-
this._rerenderElements();
|
|
99
|
-
this._updateErrorTemplates();
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Getter method for error template references
|
|
103
|
-
*/
|
|
104
|
-
getErrorTemplateRef(name) {
|
|
105
|
-
return this._templateMap.get(name);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Loads error templates and sets them in a map for faster access.
|
|
109
|
-
*/
|
|
110
|
-
_updateErrorTemplates() {
|
|
111
|
-
this._templateMap = new Map();
|
|
112
|
-
for (const errorTemplate of this._errorTemplates.toArray()) {
|
|
113
|
-
this._templateMap.set(errorTemplate.tdDynamicFormsError ?? '', errorTemplate.templateRef);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
_rerenderElements() {
|
|
117
|
-
this._clearRemovedElements();
|
|
118
|
-
this._renderedElements = [];
|
|
119
|
-
const duplicates = [];
|
|
120
|
-
this._elements.forEach((elem) => {
|
|
121
|
-
this._dynamicFormsService.validateDynamicElementName(elem.name);
|
|
122
|
-
if (duplicates.indexOf(elem.name) > -1) {
|
|
123
|
-
throw new Error(`Dynamic element name: "${elem.name}" is duplicated`);
|
|
124
|
-
}
|
|
125
|
-
duplicates.push(elem.name);
|
|
126
|
-
const dynamicElement = this.dynamicForm.get(elem.name);
|
|
127
|
-
if (!dynamicElement) {
|
|
128
|
-
this.dynamicForm.addControl(elem.name, this._dynamicFormsService.createFormControl(elem));
|
|
129
|
-
this._subscribeToControlStatusChanges(elem.name);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
dynamicElement.setValue(elem.default);
|
|
133
|
-
dynamicElement.markAsPristine();
|
|
134
|
-
dynamicElement.markAsUntouched();
|
|
135
|
-
if (elem.disabled) {
|
|
136
|
-
dynamicElement.disable();
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
dynamicElement.enable();
|
|
140
|
-
}
|
|
141
|
-
dynamicElement.setValidators(this._dynamicFormsService.createValidators(elem));
|
|
142
|
-
}
|
|
143
|
-
// copy objects so they are only changes when calling this method
|
|
144
|
-
this._renderedElements.push(Object.assign({}, elem));
|
|
145
|
-
});
|
|
146
|
-
// call a change detection since the whole form might change
|
|
147
|
-
this._changeDetectorRef.detectChanges();
|
|
148
|
-
timer(0)
|
|
149
|
-
.toPromise()
|
|
150
|
-
.then(() => {
|
|
151
|
-
// call a markForCheck so elements are rendered correctly in OnPush
|
|
152
|
-
this._changeDetectorRef.markForCheck();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
_clearRemovedElements() {
|
|
156
|
-
this._renderedElements = this._renderedElements.filter((renderedElement) => !this._elements.some((element) => element.name === renderedElement.name));
|
|
157
|
-
// remove elements that were removed from the array
|
|
158
|
-
this._renderedElements.forEach((elem) => {
|
|
159
|
-
this._destroyControl$.next(elem.name);
|
|
160
|
-
this.dynamicForm.removeControl(elem.name);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
// Updates component when manually adding errors to controls
|
|
164
|
-
_subscribeToControlStatusChanges(elementName) {
|
|
165
|
-
const control = this.controls[elementName];
|
|
166
|
-
const controlDestroyed$ = this._destroyControl$.pipe(filter((destroyedElementName) => destroyedElementName === elementName));
|
|
167
|
-
control.statusChanges
|
|
168
|
-
.pipe(takeUntil(this._destroy$), takeUntil(controlDestroyed$))
|
|
169
|
-
.subscribe(() => {
|
|
170
|
-
this._changeDetectorRef.markForCheck();
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
TdDynamicFormsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: TdDynamicFormsComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.TdDynamicFormsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
175
|
-
TdDynamicFormsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: TdDynamicFormsComponent, selector: "td-dynamic-forms", inputs: { elements: "elements" }, queries: [{ propertyName: "_errorTemplates", predicate: TdDynamicFormsErrorTemplateDirective, descendants: true }], ngImport: i0, template: "<form [formGroup]=\"dynamicForm\" novalidate>\n <div class=\"td-dynamic-form-wrapper\">\n <ng-template let-element ngFor [ngForOf]=\"elements\">\n <div\n class=\"td-dynamic-element-wrapper\"\n [style.max-width.%]=\"element.flex ? element.flex : 100\"\n [style.flex]=\"'1 1 ' + (element.flex ? element.flex : 100) + '%'\"\n [style.-ms-flex]=\"'1 1 ' + (element.flex ? element.flex : 100) + '%'\"\n [style.-webkit-box-flex]=\"1\"\n >\n <td-dynamic-element\n #dynamicElement\n *ngIf=\"dynamicForm.controls[element.name]\"\n [formControlName]=\"element.name\"\n [dynamicControl]=\"dynamicForm.controls[element.name]\"\n [id]=\"element.name\"\n [name]=\"element.name\"\n [label]=\"element.label || element.name\"\n [hint]=\"element.hint\"\n [type]=\"element.type\"\n [required]=\"element.required ?? false\"\n [min]=\"element.min\"\n [max]=\"element.max\"\n [minLength]=\"element.minLength\"\n [maxLength]=\"element.maxLength\"\n [selections]=\"element.selections\"\n [multiple]=\"element.multiple\"\n [customConfig]=\"element.customConfig\"\n [errorMessageTemplate]=\"getErrorTemplateRef(element.name)\"\n [placeholder]=\"element.placeholder\"\n ></td-dynamic-element>\n </div>\n </ng-template>\n </div>\n <ng-content></ng-content>\n</form>\n", styles: [".td-dynamic-form-wrapper{flex-flow:row wrap;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}.td-dynamic-form-wrapper ::ng-deep .mat-form-field-infix{width:auto}.td-dynamic-form-wrapper ::ng-deep .td-dynamic-element-hint{font-size:75%;display:block}.td-dynamic-form-wrapper .td-dynamic-element-wrapper{max-height:100%;box-sizing:border-box;position:relative;padding:4px 4px 8px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.TdDynamicElementComponent, selector: "td-dynamic-element", inputs: ["dynamicControl", "label", "hint", "name", "type", "required", "min", "max", "minLength", "maxLength", "selections", "multiple", "customConfig", "errorMessageTemplate", "placeholder"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
176
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: TdDynamicFormsComponent, decorators: [{
|
|
177
|
-
type: Component,
|
|
178
|
-
args: [{ selector: 'td-dynamic-forms', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"dynamicForm\" novalidate>\n <div class=\"td-dynamic-form-wrapper\">\n <ng-template let-element ngFor [ngForOf]=\"elements\">\n <div\n class=\"td-dynamic-element-wrapper\"\n [style.max-width.%]=\"element.flex ? element.flex : 100\"\n [style.flex]=\"'1 1 ' + (element.flex ? element.flex : 100) + '%'\"\n [style.-ms-flex]=\"'1 1 ' + (element.flex ? element.flex : 100) + '%'\"\n [style.-webkit-box-flex]=\"1\"\n >\n <td-dynamic-element\n #dynamicElement\n *ngIf=\"dynamicForm.controls[element.name]\"\n [formControlName]=\"element.name\"\n [dynamicControl]=\"dynamicForm.controls[element.name]\"\n [id]=\"element.name\"\n [name]=\"element.name\"\n [label]=\"element.label || element.name\"\n [hint]=\"element.hint\"\n [type]=\"element.type\"\n [required]=\"element.required ?? false\"\n [min]=\"element.min\"\n [max]=\"element.max\"\n [minLength]=\"element.minLength\"\n [maxLength]=\"element.maxLength\"\n [selections]=\"element.selections\"\n [multiple]=\"element.multiple\"\n [customConfig]=\"element.customConfig\"\n [errorMessageTemplate]=\"getErrorTemplateRef(element.name)\"\n [placeholder]=\"element.placeholder\"\n ></td-dynamic-element>\n </div>\n </ng-template>\n </div>\n <ng-content></ng-content>\n</form>\n", styles: [".td-dynamic-form-wrapper{flex-flow:row wrap;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}.td-dynamic-form-wrapper ::ng-deep .mat-form-field-infix{width:auto}.td-dynamic-form-wrapper ::ng-deep .td-dynamic-element-hint{font-size:75%;display:block}.td-dynamic-form-wrapper .td-dynamic-element-wrapper{max-height:100%;box-sizing:border-box;position:relative;padding:4px 4px 8px}\n"] }]
|
|
179
|
-
}], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2.TdDynamicFormsService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { _errorTemplates: [{
|
|
180
|
-
type: ContentChildren,
|
|
181
|
-
args: [TdDynamicFormsErrorTemplateDirective, { descendants: true }]
|
|
182
|
-
}], elements: [{
|
|
183
|
-
type: Input
|
|
184
|
-
}] } });
|
|
185
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1mb3Jtcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXItZHluYW1pYy1mb3Jtcy9zcmMvbGliL2R5bmFtaWMtZm9ybXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyLWR5bmFtaWMtZm9ybXMvc3JjL2xpYi9keW5hbWljLWZvcm1zLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsZUFBZSxFQUVmLFNBQVMsR0FHVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwsa0JBQWtCLEdBRW5CLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUNMLHFCQUFxQixHQUV0QixNQUFNLGtDQUFrQyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRW5GLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7OztBQVFuRCxNQUFNLE9BQU8sdUJBQXVCO0lBY2xDOzs7O09BSUc7SUFDSCxJQUNJLFFBQVEsQ0FBQyxRQUFtQztRQUM5QyxJQUFJLFFBQVEsRUFBRTtZQUNaLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1NBQzNCO2FBQU07WUFDTCxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztTQUNyQjtRQUNELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFDRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLElBQUk7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QUMxRCxNQUFNLE9BQU8sR0FBb0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU1RCxNQUFNLGlCQUFpQixHQUFvQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUNuRSxNQUFNLENBQ0osQ0FBQyxvQkFBNEIsRUFBRSxFQUFFLENBQUMsb0JBQW9CLEtBQUssV0FBVyxDQUN2RSxDQUNGLENBQUM7UUFFRixPQUFPLENBQUMsYUFBYTthQUNsQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQzthQUM3RCxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzs7b0hBNU1VLHVCQUF1Qjt3R0FBdkIsdUJBQXVCLDBIQVVqQixvQ0FBb0MsZ0RDMUN2RCw0OENBb0NBOzJGREphLHVCQUF1QjtrQkFObkMsU0FBUzsrQkFDRSxrQkFBa0IsbUJBR1gsdUJBQXVCLENBQUMsTUFBTTs2S0FhL0MsZUFBZTtzQkFEZCxlQUFlO3VCQUFDLG9DQUFvQyxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtnQkFVeEUsUUFBUTtzQkFEWCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIFRlbXBsYXRlUmVmLFxuICBRdWVyeUxpc3QsXG4gIEFmdGVyQ29udGVudEluaXQsXG4gIE9uRGVzdHJveSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBVbnR5cGVkRm9ybUdyb3VwLFxuICBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gIEFic3RyYWN0Q29udHJvbCxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQge1xuICBUZER5bmFtaWNGb3Jtc1NlcnZpY2UsXG4gIElUZER5bmFtaWNFbGVtZW50Q29uZmlnLFxufSBmcm9tICcuL3NlcnZpY2VzL2R5bmFtaWMtZm9ybXMuc2VydmljZSc7XG5pbXBvcnQgeyBUZER5bmFtaWNGb3Jtc0Vycm9yVGVtcGxhdGVEaXJlY3RpdmUgfSBmcm9tICcuL2R5bmFtaWMtZWxlbWVudC5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyB0aW1lciwgU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsLCBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RkLWR5bmFtaWMtZm9ybXMnLFxuICB0ZW1wbGF0ZVVybDogJy4vZHluYW1pYy1mb3Jtcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2R5bmFtaWMtZm9ybXMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFRkRHluYW1pY0Zvcm1zQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBfcmVuZGVyZWRFbGVtZW50czogSVRkRHluYW1pY0VsZW1lbnRDb25maWdbXSA9IFtdO1xuICBwcml2YXRlIF9lbGVtZW50cyE6IElUZER5bmFtaWNFbGVtZW50Q29uZmlnW107XG4gIHByaXZhdGUgX3RlbXBsYXRlTWFwOiBNYXA8c3RyaW5nLCBUZW1wbGF0ZVJlZjxhbnk+PiA9IG5ldyBNYXA8XG4gICAgc3RyaW5nLFxuICAgIFRlbXBsYXRlUmVmPGFueT5cbiAgPigpO1xuICBwcml2YXRlIF9kZXN0cm95JDogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSBfZGVzdHJveUNvbnRyb2wkOiBTdWJqZWN0PHN0cmluZz4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIEBDb250ZW50Q2hpbGRyZW4oVGREeW5hbWljRm9ybXNFcnJvclRlbXBsYXRlRGlyZWN0aXZlLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pXG4gIF9lcnJvclRlbXBsYXRlcyE6IFF1ZXJ5TGlzdDxUZER5bmFtaWNGb3Jtc0Vycm9yVGVtcGxhdGVEaXJlY3RpdmU+O1xuICBkeW5hbWljRm9ybSE6IFVudHlwZWRGb3JtR3JvdXA7XG5cbiAgLyoqXG4gICAqIGVsZW1lbnRzOiBJVGREeW5hbWljRWxlbWVudENvbmZpZ1tdXG4gICAqIEpTIE9iamVjdCB0aGF0IHdpbGwgcmVuZGVyIHRoZSBlbGVtZW50cyBkZXBlbmRpbmcgb24gaXRzIGNvbmZpZy5cbiAgICogW25hbWVdIHByb3BlcnR5IGlzIHJlcXVpcmVkLlxuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IGVsZW1lbnRzKGVsZW1lbnRzOiBJVGREeW5hbWljRWxlbWVudENvbmZpZ1tdKSB7XG4gICAgaWYgKGVsZW1lbnRzKSB7XG4gICAgICB0aGlzLl9lbGVtZW50cyA9IGVsZW1lbnRzO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9lbGVtZW50cyA9IFtdO1xuICAgIH1cbiAgICB0aGlzLl9yZXJlbmRlckVsZW1lbnRzKCk7XG4gIH1cbiAgZ2V0IGVsZW1lbnRzKCk6IElUZER5bmFtaWNFbGVtZW50Q29uZmlnW10ge1xuICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZEVsZW1lbnRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHRlciBwcm9wZXJ0eSBmb3IgZHluYW1pYyBbRm9ybUdyb3VwXS5cbiAgICovXG4gIGdldCBmb3JtKCk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmR5bmFtaWNGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHRlciBwcm9wZXJ0eSBmb3IgW3ZhbGlkXSBvZiBkeW5hbWljIFtGb3JtR3JvdXBdLlxuICAgKi9cbiAgZ2V0IHZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmR5bmFtaWNGb3JtKSB7XG4gICAgICByZXR1cm4gdGhpcy5keW5hbWljRm9ybS52YWxpZDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHRlciBwcm9wZXJ0eSBmb3IgW3ZhbHVlXSBvZiBkeW5hbWljIFtGb3JtR3JvdXBdLlxuICAgKi9cbiAgZ2V0IHZhbHVlKCk6IGFueSB7XG4gICAgaWYgKHRoaXMuZHluYW1pY0Zvcm0pIHtcbiAgICAgIHJldHVybiB0aGlzLmR5bmFtaWNGb3JtLnZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cblxuICAvKipcbiAgICogR2V0dGVyIHByb3BlcnR5IGZvciBbZXJyb3JzXSBvZiBkeW5hbWljIFtGb3JtR3JvdXBdLlxuICAgKi9cbiAgZ2V0IGVycm9ycygpOiB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfSB7XG4gICAgaWYgKHRoaXMuZHluYW1pY0Zvcm0pIHtcbiAgICAgIGNvbnN0IGVycm9yczogeyBbbmFtZTogc3RyaW5nXTogYW55IH0gPSB7fTtcbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyh0aGlzLmR5bmFtaWNGb3JtLmNvbnRyb2xzKSkge1xuICAgICAgICBlcnJvcnNbbmFtZV0gPSB0aGlzLmR5bmFtaWNGb3JtLmNvbnRyb2xzW25hbWVdLmVycm9ycztcbiAgICAgIH1cbiAgICAgIHJldHVybiBlcnJvcnM7XG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXR0ZXIgcHJvcGVydHkgZm9yIFtjb250cm9sc10gb2YgZHluYW1pYyBbRm9ybUdyb3VwXS5cbiAgICovXG4gIGdldCBjb250cm9scygpOiB7IFtrZXk6IHN0cmluZ106IEFic3RyYWN0Q29udHJvbCB9IHtcbiAgICBpZiAodGhpcy5keW5hbWljRm9ybSkge1xuICAgICAgcmV0dXJuIHRoaXMuZHluYW1pY0Zvcm0uY29udHJvbHM7XG4gICAgfVxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2Zvcm1CdWlsZGVyOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBfZHluYW1pY0Zvcm1zU2VydmljZTogVGREeW5hbWljRm9ybXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHtcbiAgICB0aGlzLmR5bmFtaWNGb3JtID0gdGhpcy5fZm9ybUJ1aWxkZXIuZ3JvdXAoe30pO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX3VwZGF0ZUVycm9yVGVtcGxhdGVzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZXN0cm95JC5uZXh0KDApO1xuICAgIHRoaXMuX2Rlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5fZGVzdHJveUNvbnRyb2wkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVmcmVzaGVzIHRoZSBmb3JtIGFuZCByZXJlbmRlcnMgYWxsIHZhbGlkYXRvci9lbGVtZW50IG1vZGlmaWNhdGlvbnMuXG4gICAqL1xuICByZWZyZXNoKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlcmVuZGVyRWxlbWVudHMoKTtcbiAgICB0aGlzLl91cGRhdGVFcnJvclRlbXBsYXRlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHRlciBtZXRob2QgZm9yIGVycm9yIHRlbXBsYXRlIHJlZmVyZW5jZXNcbiAgICovXG4gIGdldEVycm9yVGVtcGxhdGVSZWYobmFtZTogc3RyaW5nKTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3RlbXBsYXRlTWFwLmdldChuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyBlcnJvciB0ZW1wbGF0ZXMgYW5kIHNldHMgdGhlbSBpbiBhIG1hcCBmb3IgZmFzdGVyIGFjY2Vzcy5cbiAgICovXG4gIHByaXZhdGUgX3VwZGF0ZUVycm9yVGVtcGxhdGVzKCk6IHZvaWQge1xuICAgIHRoaXMuX3RlbXBsYXRlTWFwID0gbmV3IE1hcDxzdHJpbmcsIFRlbXBsYXRlUmVmPGFueT4+KCk7XG4gICAgZm9yIChjb25zdCBlcnJvclRlbXBsYXRlIG9mIHRoaXMuX2Vycm9yVGVtcGxhdGVzLnRvQXJyYXkoKSkge1xuICAgICAgdGhpcy5fdGVtcGxhdGVNYXAuc2V0KFxuICAgICAgICBlcnJvclRlbXBsYXRlLnRkRHluYW1pY0Zvcm1zRXJyb3IgPz8gJycsXG4gICAgICAgIGVycm9yVGVtcGxhdGUudGVtcGxhdGVSZWZcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfcmVyZW5kZXJFbGVtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLl9jbGVhclJlbW92ZWRFbGVtZW50cygpO1xuICAgIHRoaXMuX3JlbmRlcmVkRWxlbWVudHMgPSBbXTtcbiAgICBjb25zdCBkdXBsaWNhdGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIHRoaXMuX2VsZW1lbnRzLmZvckVhY2goKGVsZW06IElUZER5bmFtaWNFbGVtZW50Q29uZmlnKSA9PiB7XG4gICAgICB0aGlzLl9keW5hbWljRm9ybXNTZXJ2aWNlLnZhbGlkYXRlRHluYW1pY0VsZW1lbnROYW1lKGVsZW0ubmFtZSk7XG4gICAgICBpZiAoZHVwbGljYXRlcy5pbmRleE9mKGVsZW0ubmFtZSkgPiAtMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYER5bmFtaWMgZWxlbWVudCBuYW1lOiBcIiR7ZWxlbS5uYW1lfVwiIGlzIGR1cGxpY2F0ZWRgKTtcbiAgICAgIH1cbiAgICAgIGR1cGxpY2F0ZXMucHVzaChlbGVtLm5hbWUpO1xuICAgICAgY29uc3QgZHluYW1pY0VsZW1lbnQ6IEFic3RyYWN0Q29udHJvbCB8IG51bGwgPSB0aGlzLmR5bmFtaWNGb3JtLmdldChcbiAgICAgICAgZWxlbS5uYW1lXG4gICAgICApO1xuICAgICAgaWYgKCFkeW5hbWljRWxlbWVudCkge1xuICAgICAgICB0aGlzLmR5bmFtaWNGb3JtLmFkZENvbnRyb2woXG4gICAgICAgICAgZWxlbS5uYW1lLFxuICAgICAgICAgIHRoaXMuX2R5bmFtaWNGb3Jtc1NlcnZpY2UuY3JlYXRlRm9ybUNvbnRyb2woZWxlbSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fc3Vic2NyaWJlVG9Db250cm9sU3RhdHVzQ2hhbmdlcyhlbGVtLm5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZHluYW1pY0VsZW1lbnQuc2V0VmFsdWUoZWxlbS5kZWZhdWx0KTtcbiAgICAgICAgZHluYW1pY0VsZW1lbnQubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgZHluYW1pY0VsZW1lbnQubWFya0FzVW50b3VjaGVkKCk7XG4gICAgICAgIGlmIChlbGVtLmRpc2FibGVkKSB7XG4gICAgICAgICAgZHluYW1pY0VsZW1lbnQuZGlzYWJsZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGR5bmFtaWNFbGVtZW50LmVuYWJsZSgpO1xuICAgICAgICB9XG4gICAgICAgIGR5bmFtaWNFbGVtZW50LnNldFZhbGlkYXRvcnMoXG4gICAgICAgICAgdGhpcy5fZHluYW1pY0Zvcm1zU2VydmljZS5jcmVhdGVWYWxpZGF0b3JzKGVsZW0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBjb3B5IG9iamVjdHMgc28gdGhleSBhcmUgb25seSBjaGFuZ2VzIHdoZW4gY2FsbGluZyB0aGlzIG1ldGhvZFxuICAgICAgdGhpcy5fcmVuZGVyZWRFbGVtZW50cy5wdXNoKE9iamVjdC5hc3NpZ24oe30sIGVsZW0pKTtcbiAgICB9KTtcbiAgICAvLyBjYWxsIGEgY2hhbmdlIGRldGVjdGlvbiBzaW5jZSB0aGUgd2hvbGUgZm9ybSBtaWdodCBjaGFuZ2VcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgdGltZXIoMClcbiAgICAgIC50b1Byb21pc2UoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBjYWxsIGEgbWFya0ZvckNoZWNrIHNvIGVsZW1lbnRzIGFyZSByZW5kZXJlZCBjb3JyZWN0bHkgaW4gT25QdXNoXG4gICAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9jbGVhclJlbW92ZWRFbGVtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLl9yZW5kZXJlZEVsZW1lbnRzID0gdGhpcy5fcmVuZGVyZWRFbGVtZW50cy5maWx0ZXIoXG4gICAgICAocmVuZGVyZWRFbGVtZW50OiBJVGREeW5hbWljRWxlbWVudENvbmZpZykgPT5cbiAgICAgICAgIXRoaXMuX2VsZW1lbnRzLnNvbWUoXG4gICAgICAgICAgKGVsZW1lbnQ6IElUZER5bmFtaWNFbGVtZW50Q29uZmlnKSA9PlxuICAgICAgICAgICAgZWxlbWVudC5uYW1lID09PSByZW5kZXJlZEVsZW1lbnQubmFtZVxuICAgICAgICApXG4gICAgKTtcbiAgICAvLyByZW1vdmUgZWxlbWVudHMgdGhhdCB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgYXJyYXlcbiAgICB0aGlzLl9yZW5kZXJlZEVsZW1lbnRzLmZvckVhY2goKGVsZW06IElUZER5bmFtaWNFbGVtZW50Q29uZmlnKSA9PiB7XG4gICAgICB0aGlzLl9kZXN0cm95Q29udHJvbCQubmV4dChlbGVtLm5hbWUpO1xuICAgICAgdGhpcy5keW5hbWljRm9ybS5yZW1vdmVDb250cm9sKGVsZW0ubmFtZSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVcGRhdGVzIGNvbXBvbmVudCB3aGVuIG1hbnVhbGx5IGFkZGluZyBlcnJvcnMgdG8gY29udHJvbHNcbiAgcHJpdmF0ZSBfc3Vic2NyaWJlVG9Db250cm9sU3RhdHVzQ2hhbmdlcyhlbGVtZW50TmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29udHJvbDogQWJzdHJhY3RDb250cm9sID0gdGhpcy5jb250cm9sc1tlbGVtZW50TmFtZV07XG5cbiAgICBjb25zdCBjb250cm9sRGVzdHJveWVkJDogT2JzZXJ2YWJsZTxhbnk+ID0gdGhpcy5fZGVzdHJveUNvbnRyb2wkLnBpcGUoXG4gICAgICBmaWx0ZXIoXG4gICAgICAgIChkZXN0cm95ZWRFbGVtZW50TmFtZTogc3RyaW5nKSA9PiBkZXN0cm95ZWRFbGVtZW50TmFtZSA9PT0gZWxlbWVudE5hbWVcbiAgICAgIClcbiAgICApO1xuXG4gICAgY29udHJvbC5zdGF0dXNDaGFuZ2VzXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLCB0YWtlVW50aWwoY29udHJvbERlc3Ryb3llZCQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cbn1cbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZHluYW1pY0Zvcm1cIiBub3ZhbGlkYXRlPlxuICA8ZGl2IGNsYXNzPVwidGQtZHluYW1pYy1mb3JtLXdyYXBwZXJcIj5cbiAgICA8bmctdGVtcGxhdGUgbGV0LWVsZW1lbnQgbmdGb3IgW25nRm9yT2ZdPVwiZWxlbWVudHNcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJ0ZC1keW5hbWljLWVsZW1lbnQtd3JhcHBlclwiXG4gICAgICAgIFtzdHlsZS5tYXgtd2lkdGguJV09XCJlbGVtZW50LmZsZXggPyBlbGVtZW50LmZsZXggOiAxMDBcIlxuICAgICAgICBbc3R5bGUuZmxleF09XCInMSAxICcgKyAoZWxlbWVudC5mbGV4ID8gZWxlbWVudC5mbGV4IDogMTAwKSArICclJ1wiXG4gICAgICAgIFtzdHlsZS4tbXMtZmxleF09XCInMSAxICcgKyAoZWxlbWVudC5mbGV4ID8gZWxlbWVudC5mbGV4IDogMTAwKSArICclJ1wiXG4gICAgICAgIFtzdHlsZS4td2Via2l0LWJveC1mbGV4XT1cIjFcIlxuICAgICAgPlxuICAgICAgICA8dGQtZHluYW1pYy1lbGVtZW50XG4gICAgICAgICAgI2R5bmFtaWNFbGVtZW50XG4gICAgICAgICAgKm5nSWY9XCJkeW5hbWljRm9ybS5jb250cm9sc1tlbGVtZW50Lm5hbWVdXCJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImVsZW1lbnQubmFtZVwiXG4gICAgICAgICAgW2R5bmFtaWNDb250cm9sXT1cImR5bmFtaWNGb3JtLmNvbnRyb2xzW2VsZW1lbnQubmFtZV1cIlxuICAgICAgICAgIFtpZF09XCJlbGVtZW50Lm5hbWVcIlxuICAgICAgICAgIFtuYW1lXT1cImVsZW1lbnQubmFtZVwiXG4gICAgICAgICAgW2xhYmVsXT1cImVsZW1lbnQubGFiZWwgfHwgZWxlbWVudC5uYW1lXCJcbiAgICAgICAgICBbaGludF09XCJlbGVtZW50LmhpbnRcIlxuICAgICAgICAgIFt0eXBlXT1cImVsZW1lbnQudHlwZVwiXG4gICAgICAgICAgW3JlcXVpcmVkXT1cImVsZW1lbnQucmVxdWlyZWQgPz8gZmFsc2VcIlxuICAgICAgICAgIFttaW5dPVwiZWxlbWVudC5taW5cIlxuICAgICAgICAgIFttYXhdPVwiZWxlbWVudC5tYXhcIlxuICAgICAgICAgIFttaW5MZW5ndGhdPVwiZWxlbWVudC5taW5MZW5ndGhcIlxuICAgICAgICAgIFttYXhMZW5ndGhdPVwiZWxlbWVudC5tYXhMZW5ndGhcIlxuICAgICAgICAgIFtzZWxlY3Rpb25zXT1cImVsZW1lbnQuc2VsZWN0aW9uc1wiXG4gICAgICAgICAgW211bHRpcGxlXT1cImVsZW1lbnQubXVsdGlwbGVcIlxuICAgICAgICAgIFtjdXN0b21Db25maWddPVwiZWxlbWVudC5jdXN0b21Db25maWdcIlxuICAgICAgICAgIFtlcnJvck1lc3NhZ2VUZW1wbGF0ZV09XCJnZXRFcnJvclRlbXBsYXRlUmVmKGVsZW1lbnQubmFtZSlcIlxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJlbGVtZW50LnBsYWNlaG9sZGVyXCJcbiAgICAgICAgPjwvdGQtZHluYW1pYy1lbGVtZW50PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG4gIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbjwvZm9ybT5cbiJdfQ==
|