@energycap/components 0.39.4 → 0.39.5
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/esm2020/lib/controls/file-upload/file-upload.component.mjs +76 -27
- package/fesm2015/energycap-components.mjs +74 -23
- package/fesm2015/energycap-components.mjs.map +1 -1
- package/fesm2020/energycap-components.mjs +69 -22
- package/fesm2020/energycap-components.mjs.map +1 -1
- package/lib/controls/file-upload/file-upload.component.d.ts +30 -1
- package/package.json +1 -1
- package/src/assets/locales/en_US.json +3 -1
@@ -5,10 +5,12 @@ import { FormControlBase } from '../form-control-base';
|
|
5
5
|
import * as i0 from "@angular/core";
|
6
6
|
import * as i1 from "../../core/validation-message.service";
|
7
7
|
import * as i2 from "../../shared/form-group.helper";
|
8
|
-
import * as i3 from "@angular/
|
9
|
-
import * as i4 from "
|
10
|
-
import * as i5 from "../
|
11
|
-
import * as i6 from "../form-
|
8
|
+
import * as i3 from "@angular/common";
|
9
|
+
import * as i4 from "@angular/forms";
|
10
|
+
import * as i5 from "../button/button.component";
|
11
|
+
import * as i6 from "../form-control/form-control.component";
|
12
|
+
import * as i7 from "../form-group/form-group.component";
|
13
|
+
import * as i8 from "@ngx-translate/core";
|
12
14
|
export const FileTypeExtensions = {
|
13
15
|
zip: ['.zip'],
|
14
16
|
excel: ['.xls', '.xlsx']
|
@@ -20,7 +22,7 @@ export class FileUploadComponent extends FormControlBase {
|
|
20
22
|
file: new UntypedFormControl({ value: null, disabled: disabled }, validators),
|
21
23
|
name: new UntypedFormControl({ value: null, disabled: disabled }, validators),
|
22
24
|
base64FileString: new UntypedFormControl(null),
|
23
|
-
uploadResult: new UntypedFormControl(null)
|
25
|
+
uploadResult: new UntypedFormControl(null),
|
24
26
|
});
|
25
27
|
if (disabled) {
|
26
28
|
formGroup.disable();
|
@@ -39,6 +41,20 @@ export class FileUploadComponent extends FormControlBase {
|
|
39
41
|
* File output, determines which properties are supplied on the formModel
|
40
42
|
*/
|
41
43
|
this.fileOutput = 'base64';
|
44
|
+
/**
|
45
|
+
* Optional display type that controls whether the file input textbox is displayed or
|
46
|
+
* simply a button the user clicks to launch the OS file storage dialog.
|
47
|
+
* Default: file
|
48
|
+
*/
|
49
|
+
this.displayType = 'file';
|
50
|
+
/**
|
51
|
+
* When display type is set to button this property will control the button type
|
52
|
+
*/
|
53
|
+
this.buttonType = 'primary';
|
54
|
+
/**
|
55
|
+
* Optional property to control whether the user can select multiple files
|
56
|
+
*/
|
57
|
+
this.multiSelect = false;
|
42
58
|
}
|
43
59
|
ngOnChanges(changes) {
|
44
60
|
super.ngOnChanges(changes);
|
@@ -53,6 +69,7 @@ export class FileUploadComponent extends FormControlBase {
|
|
53
69
|
if (!value) {
|
54
70
|
this.formModel.patchValue({
|
55
71
|
file: null,
|
72
|
+
name: null,
|
56
73
|
base64FileString: null,
|
57
74
|
uploadResult: null
|
58
75
|
});
|
@@ -60,26 +77,20 @@ export class FileUploadComponent extends FormControlBase {
|
|
60
77
|
});
|
61
78
|
}
|
62
79
|
async fileChange(files) {
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
this.
|
70
|
-
};
|
71
|
-
if (this.isBase64FileOutput()) {
|
72
|
-
reader.readAsDataURL(file);
|
73
|
-
}
|
74
|
-
else {
|
75
|
-
await this.processFile(file);
|
76
|
-
}
|
77
|
-
// Clear the file inputs value, this will allow the user to pick the same filename and cause
|
78
|
-
// the fileChange to trigger.
|
79
|
-
if (this.fileInput) {
|
80
|
-
this.fileInput.nativeElement.value = '';
|
80
|
+
if (this.multiSelect) {
|
81
|
+
this.handleMultipleFiles(files);
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
const file = files.item(0);
|
85
|
+
if (file) {
|
86
|
+
await this.readFile(file);
|
81
87
|
}
|
82
88
|
}
|
89
|
+
// Clear the file inputs value, this will allow the user to pick the same filenames again
|
90
|
+
// and cause fileChange to re-trigger.
|
91
|
+
if (this.fileInput) {
|
92
|
+
this.fileInput.nativeElement.value = '';
|
93
|
+
}
|
83
94
|
}
|
84
95
|
/**
|
85
96
|
* Checks the file type and updates the file type accept property. This is what determines the file
|
@@ -111,7 +122,7 @@ export class FileUploadComponent extends FormControlBase {
|
|
111
122
|
this.patchFileResult(file, base64FileString, result);
|
112
123
|
}
|
113
124
|
catch (e) {
|
114
|
-
// Bummer, we're not going to do anything about it though.
|
125
|
+
// Bummer, we're not going to do anything about it though.
|
115
126
|
// We are not patching any of the result so any existing information remains
|
116
127
|
}
|
117
128
|
}
|
@@ -146,12 +157,40 @@ export class FileUploadComponent extends FormControlBase {
|
|
146
157
|
this.formModel.patchValue({ uploadResult: null });
|
147
158
|
}
|
148
159
|
}
|
160
|
+
/** Maps the files to an array of File objects and sends them along
|
161
|
+
* to the derived onMultipleFileSelected method in the hosting component
|
162
|
+
*/
|
163
|
+
async handleMultipleFiles(files) {
|
164
|
+
const filesArray = Array.from(files);
|
165
|
+
if (this.onMultipleFilesSelected) {
|
166
|
+
try {
|
167
|
+
let result = await this.onMultipleFilesSelected(filesArray);
|
168
|
+
}
|
169
|
+
catch (e) {
|
170
|
+
console.log('error: ', e);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
;
|
175
|
+
async readFile(file) {
|
176
|
+
const reader = new FileReader();
|
177
|
+
reader.onloadend = async (e) => {
|
178
|
+
let base64FileString = reader?.result?.toString().split(",")[1];
|
179
|
+
await this.processFile(file, base64FileString);
|
180
|
+
};
|
181
|
+
if (this.isBase64FileOutput()) {
|
182
|
+
reader.readAsDataURL(file);
|
183
|
+
}
|
184
|
+
else {
|
185
|
+
await this.processFile(file);
|
186
|
+
}
|
187
|
+
}
|
149
188
|
}
|
150
189
|
FileUploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileUploadComponent, deps: [{ token: i1.ValidationMessageService }, { token: i2.FormGroupHelper }], target: i0.ɵɵFactoryTarget.Component });
|
151
|
-
FileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FileUploadComponent, selector: "ec-file-upload", inputs: { placeholder: "placeholder", fileType: "fileType", fileOutput: "fileOutput", customExtensions: "customExtensions", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (
|
190
|
+
FileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FileUploadComponent, selector: "ec-file-upload", inputs: { placeholder: "placeholder", fileType: "fileType", fileOutput: "fileOutput", customExtensions: "customExtensions", onFileSelected: "onFileSelected", onMultipleFilesSelected: "onMultipleFilesSelected", displayType: "displayType", buttonLabel: "buttonLabel", buttonType: "buttonType", multiSelect: "multiSelect" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (change)=\"fileChange($event.target.files)\"\r\n [class.has-value]=\"displayType === 'file' ? formModel?.get('name').value : undefined\"\r\n [attr.multiple]=\"multiSelect ? 'multiple' : undefined\">\r\n <ec-form-control *ngIf=\"displayType === 'file'\"\r\n id=\"{{inputId}}_formControl\"\r\n class=\"text-truncate\"\r\n [required]=\"required\"\r\n [pending]=\"pending\">\r\n <input id=\"{{inputId}}_name\"\r\n [formControl]=\"formModel?.get('name')\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [tabindex]=\"-1\">\r\n </ec-form-control>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'file'\"\r\n #browseBtn\r\n id=\"{{inputId}}_browseBtn\"\r\n (clicked)=\"fileInput.click()\"\r\n type=\"secondary\"\r\n [tabindex]=\"tabindex\"\r\n [disabled]=\"formModel?.get('name').disabled\"\r\n label=\"Browse\"\r\n [autofocus]=\"autofocus\">\r\n </ec-button>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'button'\"\r\n id=\"{{inputId}}_btn\"\r\n [pending]=\"pending\"\r\n [type]=\"buttonType\"\r\n [label]=\"buttonLabel ?? 'Browse_TC' | translate\"\r\n (clicked)=\"fileInput.click()\"\r\n style=\"width: 100%;\">\r\n </ec-button>\r\n</ec-form-group>", styles: [":host{display:block;margin-bottom:1rem}ec-form-control{margin-bottom:0}ec-form-control ::ng-deep>.ec-focus-ring{display:none!important}input[type=file]{opacity:0;display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;cursor:pointer}input[type=file].has-value{width:calc(100% - 1.5rem)}ec-button{--ec-button-border-color-secondary: var(--ec-form-control-border-color);--ec-button-color-icon-secondary: var(--ec-color-icon)}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "icon", "label", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: i6.FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "pending", "required", "readonly"], outputs: ["actionClicked"] }, { kind: "component", type: i7.FormGroupComponent, selector: "ec-form-group", inputs: ["id", "label", "formGroup", "labelPosition", "overrideValidationError", "hideValidationMessage"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
|
152
191
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileUploadComponent, decorators: [{
|
153
192
|
type: Component,
|
154
|
-
args: [{ selector: "ec-file-upload", template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (
|
193
|
+
args: [{ selector: "ec-file-upload", template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (change)=\"fileChange($event.target.files)\"\r\n [class.has-value]=\"displayType === 'file' ? formModel?.get('name').value : undefined\"\r\n [attr.multiple]=\"multiSelect ? 'multiple' : undefined\">\r\n <ec-form-control *ngIf=\"displayType === 'file'\"\r\n id=\"{{inputId}}_formControl\"\r\n class=\"text-truncate\"\r\n [required]=\"required\"\r\n [pending]=\"pending\">\r\n <input id=\"{{inputId}}_name\"\r\n [formControl]=\"formModel?.get('name')\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [tabindex]=\"-1\">\r\n </ec-form-control>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'file'\"\r\n #browseBtn\r\n id=\"{{inputId}}_browseBtn\"\r\n (clicked)=\"fileInput.click()\"\r\n type=\"secondary\"\r\n [tabindex]=\"tabindex\"\r\n [disabled]=\"formModel?.get('name').disabled\"\r\n label=\"Browse\"\r\n [autofocus]=\"autofocus\">\r\n </ec-button>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'button'\"\r\n id=\"{{inputId}}_btn\"\r\n [pending]=\"pending\"\r\n [type]=\"buttonType\"\r\n [label]=\"buttonLabel ?? 'Browse_TC' | translate\"\r\n (clicked)=\"fileInput.click()\"\r\n style=\"width: 100%;\">\r\n </ec-button>\r\n</ec-form-group>", styles: [":host{display:block;margin-bottom:1rem}ec-form-control{margin-bottom:0}ec-form-control ::ng-deep>.ec-focus-ring{display:none!important}input[type=file]{opacity:0;display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;cursor:pointer}input[type=file].has-value{width:calc(100% - 1.5rem)}ec-button{--ec-button-border-color-secondary: var(--ec-form-control-border-color);--ec-button-color-icon-secondary: var(--ec-color-icon)}\n"] }]
|
155
194
|
}], ctorParameters: function () { return [{ type: i1.ValidationMessageService }, { type: i2.FormGroupHelper }]; }, propDecorators: { placeholder: [{
|
156
195
|
type: Input
|
157
196
|
}], fileType: [{
|
@@ -162,8 +201,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
162
201
|
type: Input
|
163
202
|
}], onFileSelected: [{
|
164
203
|
type: Input
|
204
|
+
}], onMultipleFilesSelected: [{
|
205
|
+
type: Input
|
206
|
+
}], displayType: [{
|
207
|
+
type: Input
|
208
|
+
}], buttonLabel: [{
|
209
|
+
type: Input
|
210
|
+
}], buttonType: [{
|
211
|
+
type: Input
|
212
|
+
}], multiSelect: [{
|
213
|
+
type: Input
|
165
214
|
}], fileInput: [{
|
166
215
|
type: ViewChild,
|
167
216
|
args: ["fileInput", { read: ElementRef, static: true }]
|
168
217
|
}] } });
|
169
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2NvbnRyb2xzL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9maWxlLXVwbG9hZC9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQW9DLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7OztBQUt2RCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRztJQUNoQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUM7SUFDYixLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDO0NBQ3pCLENBQUM7QUFPRixNQUFNLE9BQU8sbUJBQW9CLFNBQVEsZUFBZTtJQUV0RCxnRUFBZ0U7SUFDekQsTUFBTSxDQUFDLFlBQVksQ0FDeEIsVUFBeUIsRUFDekIsV0FBb0IsS0FBSztRQUV6QixJQUFJLFNBQVMsR0FBRyxJQUFJLGdCQUFnQixDQUFDO1lBQ25DLElBQUksRUFBRSxJQUFJLGtCQUFrQixDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsVUFBVSxDQUFDO1lBQzdFLElBQUksRUFBRSxJQUFJLGtCQUFrQixDQUFDLEVBQUUsS0FBSyxFQUFFLElB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SUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNuRDtJQUNILENBQUM7O2dIQTVLVSxtQkFBbUI7b0dBQW5CLG1CQUFtQix5U0E2Q0UsVUFBVSx1RkNqRTVDLDQ1Q0FrQ2dCOzJGRGRILG1CQUFtQjtrQkFML0IsU0FBUzsrQkFDRSxnQkFBZ0I7NklBMEJWLFdBQVc7c0JBQTFCLEtBQUs7Z0JBTVUsUUFBUTtzQkFBdkIsS0FBSztnQkFLVSxVQUFVO3NCQUF6QixLQUFLO2dCQUdVLGdCQUFnQjtzQkFBL0IsS0FBSztnQkFPVSxjQUFjO3NCQUE3QixLQUFLO2dCQUU2RCxTQUFTO3NCQUEzRSxTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVW50eXBlZEZvcm1Db250cm9sLCBVbnR5cGVkRm9ybUdyb3VwLCBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBWYWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3ZhbGlkYXRpb24tbWVzc2FnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRm9ybUdyb3VwSGVscGVyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Zvcm0tZ3JvdXAuaGVscGVyJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xCYXNlIH0gZnJvbSAnLi4vZm9ybS1jb250cm9sLWJhc2UnO1xyXG5cclxuZXhwb3J0IHR5cGUgRmlsZVR5cGUgPSAnemlwJyB8ICdleGNlbCcgfCAnY3VzdG9tJztcclxuZXhwb3J0IHR5cGUgRmlsZU91dHB1dCA9ICdyYXcnIHwgJ2Jhc2U2NCc7XHJcblxyXG5leHBvcnQgY29uc3QgRmlsZVR5cGVFeHRlbnNpb25zID0ge1xyXG4gIHppcDogWycuemlwJ10sXHJcbiAgZXhjZWw6IFsnLnhscycsICcueGxzeCddXHJcbn07XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogXCJlYy1maWxlLXVwbG9hZFwiLFxyXG4gIHRlbXBsYXRlVXJsOiBcIi4vZmlsZS11cGxvYWQuY29tcG9uZW50Lmh0bWxcIixcclxuICBzdHlsZVVybHM6IFtcIi4vZmlsZS11cGxvYWQuY29tcG9uZW50LnNjc3NcIl1cclxufSlcclxuZXhwb3J0IGNsYXNzIEZpbGVVcGxvYWRDb21wb25lbnQgZXh0ZW5kcyBGb3JtQ29udHJvbEJhc2UgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcblxyXG4gIC8vIHN0YXRpYyBjbGFzcyB0byBjcmVhdGUgdGhlIGZvcm0gZ3JvdXAgZnJvbSBhIHBhcmVudCBjb21wb25lbnRcclxuICBwdWJsaWMgc3RhdGljIGdldEZvcm1Nb2RlbChcclxuICAgIHZhbGlkYXRvcnM6IFZhbGlkYXRvckZuW10sXHJcbiAgICBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlXHJcbiAgKTogVW50eXBlZEZvcm1Hcm91cCB7XHJcbiAgICBsZXQgZm9ybUdyb3VwID0gbmV3IFVudHlwZWRGb3JtR3JvdXAoe1xyXG4gICAgICBmaWxlOiBuZXcgVW50eXBlZEZvcm1Db250cm9sKHsgdmFsdWU6IG51bGwsIGRpc2FibGVkOiBkaXNhYmxlZCB9LCB2YWxpZGF0b3JzKSxcclxuICAgICAgbmFtZTogbmV3IFVudHlwZWRGb3JtQ29udHJvbCh7IHZhbHVlOiBudWxsLCBkaXNhYmxlZDogZGlzYWJsZWQgfSwgdmFsaWRhdG9ycyksXHJcbiAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2wobnVsbCksXHJcbiAgICAgIHVwbG9hZFJlc3VsdDogbmV3IFVudHlwZWRGb3JtQ29udHJvbChudWxsKVxyXG4gICAgfSk7XHJcbiAgICBpZiAoZGlzYWJsZWQpIHtcclxuICAgICAgZm9ybUdyb3VwLmRpc2FibGUoKTtcclxuICAgIH1cclxuICAgIHJldHVybiBmb3JtR3JvdXA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGUgdmFsdWUgb2YgdGhlIHRleHRib3ggaW5wdXQncyBwbGFjZWhvbGRlclxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBwbGFjZWhvbGRlcj86IHN0cmluZyA9IFwiQ2hvb3NlIGZpbGUuLi5cIjtcclxuXHJcbiAgLyoqIENvbW1vbiBleHRlbnNpb25zIGZvciBhIGZpbGUgYnJvd3NpbmcgZGlhbG9nXHJcbiAgICogIE5vdGU6IEVkZ2UgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYWNjZXB0IGF0dHJpYnV0ZSBvbiBmaWxlIGlucHV0cywgdGhlcmVmb3IgYWxsIGZpbGUgdHlwZXNcclxuICAgKiAgICAgICAgd2lsbCBiZSBzaG93bi4gIEZpcmVmb3ggYW5kIENocm9tZSBib3RoIHN1cHBvcnQgdGhpcyBmZWF0dXJlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBmaWxlVHlwZT86IEZpbGVUeXBlIHwgdW5kZWZpbmVkO1xyXG5cclxuICAvKipcclxuICAgKiBGaWxlIG91dHB1dCwgZGV0ZXJtaW5lcyB3aGljaCBwcm9wZXJ0aWVzIGFyZSBzdXBwbGllZCBvbiB0aGUgZm9ybU1vZGVsXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGZpbGVPdXRwdXQ/OiBGaWxlT3V0cHV0ID0gJ2Jhc2U2NCc7XHJcblxyXG4gIC8qKiBJZiBmaWxlVHlwZSBpcyBzZXQgdG8gY3VzdG9tIHNldCB0aGUgYWNjZXB0YWJsZSBmaWxlIHR5cGVzIGJhc2VkIG9uIHRoZSBjdXN0b20gYXJyYXkgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgY3VzdG9tRXh0ZW5zaW9ucz86IEFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQ7XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIHN1cHBvcnRlZCBpZiB0aGUgaG9zdGluZyBwYWdlIG5lZWRzIHRvIHByb2Nlc3MgdGhlIGZpbGUgYmVmb3JlXHJcbiAgICogc2V0dGluZyB0aGUgZm9ybU1vZGVsIHdpdGggdGhlIGZpbGUgaW5mb3JtYXRpb24uIElmIHRoZSBwcm9taXNlIHJlc29sdmVzIGl0IHdpbGwgY29udGludWVcclxuICAgKiBhbmQgc2V0IHRoZSBmaWxlIG5hbWUgYW5kIGNvbnRlbnRzIHRvIHRoZSBmb3JtTW9kZWwsIG90aGVyd2lzZSBvbiBmYWlsdXJlIGl0J2xsIGRvIG5vdGhpbmcuXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIG9uRmlsZVNlbGVjdGVkPzogKGZpbGU6IEZpbGUpID0+IFByb21pc2U8YW55PjtcclxuXHJcbiAgQFZpZXdDaGlsZChcImZpbGVJbnB1dFwiLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgZmlsZUlucHV0PzogRWxlbWVudFJlZjtcclxuXHJcbiAgLyoqIFByb3BlcnR5IGJvdW5kIHRvIHRoZSBmaWxlIGlucHV0IHRvIGZpbHRlciB3aGF0IGZpbGUgdHlwZXMgYXJlIHNob3duIGluIHRoZSBkaWFsb2cgKi9cclxuICBwdWJsaWMgZmlsZVR5cGVBY2NlcHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcm90ZWN0ZWQgdmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlOiBWYWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UsXHJcbiAgICBwcm90ZWN0ZWQgZm9ybUdyb3VwSGVscGVyOiBGb3JtR3JvdXBIZWxwZXJcclxuICApIHtcclxuICAgIHN1cGVyKHZhbGlkYXRpb25NZXNzYWdlU2VydmljZSwgZm9ybUdyb3VwSGVscGVyKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZUZpbGVUeXBlQWNjZXB0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xyXG5cclxuICAgIC8vIFdhdGNoIGZvciBuYW1lIHRvIGNoYW5nZSwgaWYgdGhlIHZhbHVlIGlzIGNsZWFyZWQgd2Ugd2lsbCBjbGVhciB0aGUgb3RoZXJcclxuICAgIC8vIHN1cHBvcnRpbmcgbW9kZWwgcHJvcGVydGllcy4gVGhlIG5hbWUgY2FuIGJlIGNsZWFyZWQgYnkgdGhlIHVzZXIgbWFudWFsbHkgb3IgdmlhXHJcbiAgICAvLyB0aGUgY2xlYXIgYnV0dG9uXHJcbiAgICB0aGlzLmZvcm1Nb2RlbD8uZ2V0KCduYW1lJyk/LnZhbHVlQ2hhbmdlcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95ZWQpXHJcbiAgICApLnN1YnNjcmliZSh2YWx1ZSA9PiB7XHJcbiAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHtcclxuICAgICAgICAgIGZpbGU6IG51bGwsXHJcbiAgICAgICAgICBiYXNlNjRGaWxlU3RyaW5nOiBudWxsLFxyXG4gICAgICAgICAgdXBsb2FkUmVzdWx0OiBudWxsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGZpbGVDaGFuZ2UoZmlsZXM6IEZpbGVMaXN0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBsZXQgZmlsZTogRmlsZSB8IG51bGwgPSBmaWxlcy5pdGVtKDApO1xyXG5cclxuICAgIC8vIElmIHRoZXJlIGlzIGEgZmlsZSBzZWxlY3RlZCBhbmQgdGhlbiBvcGVuZWQgYWdhaW4gYW5kIGNsaWNrIGNhbmNlbCB5b3UgZ2V0IG51bGwgc28gZG9uJ3QgdHJ5IGFuZCBzZXQgYW55dGhpbmdcclxuICAgIGlmIChmaWxlKSB7XHJcbiAgICAgIGxldCByZWFkZXI6IEZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG5cclxuICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9IGFzeW5jIGUgPT4ge1xyXG4gICAgICAgIGxldCBiYXNlNjRGaWxlU3RyaW5nOiBzdHJpbmcgfCB1bmRlZmluZWQgPSByZWFkZXI/LnJlc3VsdD8udG9TdHJpbmcoKS5zcGxpdChcIixcIilbMV07XHJcbiAgICAgICAgdGhpcy5wcm9jZXNzRmlsZShmaWxlISwgYmFzZTY0RmlsZVN0cmluZyk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAodGhpcy5pc0Jhc2U2NEZpbGVPdXRwdXQoKSkge1xyXG4gICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc0ZpbGUoZmlsZSEpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDbGVhciB0aGUgZmlsZSBpbnB1dHMgdmFsdWUsIHRoaXMgd2lsbCBhbGxvdyB0aGUgdXNlciB0byBwaWNrIHRoZSBzYW1lIGZpbGVuYW1lIGFuZCBjYXVzZVxyXG4gICAgICAvLyB0aGUgZmlsZUNoYW5nZSB0byB0cmlnZ2VyLlxyXG4gICAgICBpZiAodGhpcy5maWxlSW5wdXQpIHtcclxuICAgICAgICB0aGlzLmZpbGVJbnB1dC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyB0aGUgZmlsZSB0eXBlIGFuZCB1cGRhdGVzIHRoZSBmaWxlIHR5cGUgYWNjZXB0IHByb3BlcnR5LiBUaGlzIGlzIHdoYXQgZGV0ZXJtaW5lcyB0aGUgZmlsZVxyXG4gICAqIHR5cGUgY2hvaWNlcyB0aGF0IHRoZSB1c2VyIHdpbGwgYmUgbGltaXRlZCB0byBpbiB0aGUgZmlsZSBicm93c2UgZGlhbG9nXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVGaWxlVHlwZUFjY2VwdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZpbGVUeXBlKSB7XHJcbiAgICAgIGlmICh0aGlzLmZpbGVUeXBlICE9PSBcImN1c3RvbVwiKSB7XHJcbiAgICAgICAgdGhpcy5maWxlVHlwZUFjY2VwdCA9IEZpbGVUeXBlRXh0ZW5zaW9uc1t0aGlzLmZpbGVUeXBlXS5qb2luKFwiLFwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAodGhpcy5jdXN0b21FeHRlbnNpb25zKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbGVUeXBlQWNjZXB0ID0gdGhpcy5jdXN0b21FeHRlbnNpb25zLmpvaW4oXCIsXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGFrZSBhIGZpbGUgdGhhdCB3YXMgc2VsZWN0ZWQgYnkgdGhlIHVzZXIgYW5kIHByb2Nlc3MvcGF0Y2ggb3VyIGZvcm0gbW9kZWxcclxuICAgKiBJZiB0aGUgaG9zdCBjb21wb25lbnQgcmVxdWlyZXMgYW4gYWN0aW9uIHRvIG9jY3VyIHdpdGggdGhlIGZpbGUgcHJpb3IgdG8gdGhlIHBhdGNoIGl0IHdpbGwgY2FsbFxyXG4gICAqIGFuZCB3YWl0IGZvciBpdCB0byByZXR1cm4uXHJcbiAgICogQHBhcmFtIGZpbGUgXHJcbiAgICogQHBhcmFtIGJhc2U2NEZpbGVTdHJpbmcgT3B0aW9uYWw6IFdpbGwgaGF2ZSBhIHZhbHVlIHByb3ZpZGVkIGlmIHRoZSBmaWxlT3V0cHV0IGlzIHNldCB0byBiYXNlNjRcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NGaWxlKGZpbGU6IEZpbGUsIGJhc2U2NEZpbGVTdHJpbmc/OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLm9uRmlsZVNlbGVjdGVkKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMub25GaWxlU2VsZWN0ZWQoZmlsZSk7XHJcbiAgICAgICAgdGhpcy5wYXRjaEZpbGVSZXN1bHQoZmlsZSwgYmFzZTY0RmlsZVN0cmluZywgcmVzdWx0KTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIC8vIEJ1bW1lciwgd2UncmUgbm90IGdvaW5nIHRvIGRvIGFueXRoaW5nIGFib3V0IGl0IHRob3VnaC4gXHJcbiAgICAgICAgLy8gV2UgYXJlIG5vdCBwYXRjaGluZyBhbnkgb2YgdGhlIHJlc3VsdCBzbyBhbnkgZXhpc3RpbmcgaW5mb3JtYXRpb24gcmVtYWluc1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnBhdGNoRmlsZVJlc3VsdChmaWxlLCBiYXNlNjRGaWxlU3RyaW5nKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJhc2VkIG9uIHRoZSBmaWxlT3V0cHV0IHJldHVybiB3aGV0aGVyIHRoaXMgY29tcG9uZW50IGlzIGV4cGVjdGVkIHRvIGRlbGl2ZXIgYSBiYXNlNjQgb3V0cHV0XHJcbiAgICogQHJldHVybnMgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc0Jhc2U2NEZpbGVPdXRwdXQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5maWxlT3V0cHV0ID09PSAnYmFzZTY0JztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFdoZW4gdGhlIGZpbGUgd2FzIHNlbGVjdGVkIGFuZCBwcm9jZXNzZWQgcGF0Y2ggdGhlIGZpbGUgaW5mb3JtYXRpb24gdGhhdCB0aGUgaG9zdGluZyBmb3JtIHdpbGxcclxuICAgKiBiZSBsb29raW5nIGZvci4gXHJcbiAgICogQHBhcmFtIGZpbGUgXHJcbiAgICogQHBhcmFtIGJhc2U2NEZpbGVTdHJpbmcgXHJcbiAgICogQHBhcmFtIG9uRmlsZVNlbGVjdGVkUmVzdWx0IFxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGF0Y2hGaWxlUmVzdWx0KGZpbGU6IEZpbGUgfCBudWxsLCBiYXNlNjRGaWxlU3RyaW5nPzogc3RyaW5nLCBvbkZpbGVTZWxlY3RlZFJlc3VsdD86IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5mb3JtTW9kZWw/LnBhdGNoVmFsdWUoeyBcclxuICAgICAgZmlsZTogZmlsZSwgXHJcbiAgICAgIG5hbWU6IGZpbGU/Lm5hbWUsIFxyXG4gICAgICBiYXNlNjRGaWxlU3RyaW5nOiBiYXNlNjRGaWxlU3RyaW5nID8/IG51bGxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmIChvbkZpbGVTZWxlY3RlZFJlc3VsdCkge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHsgdXBsb2FkUmVzdWx0OiBvbkZpbGVTZWxlY3RlZFJlc3VsdCB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUoeyB1cGxvYWRSZXN1bHQ6IG51bGwgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxlYy1mb3JtLWdyb3VwIFtsYWJlbF09XCJsYWJlbFwiXHJcbiAgICAgICAgICAgICAgIFtmb3JtR3JvdXBdPVwiZm9ybU1vZGVsXCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJtYi0wXCI+XHJcbiAgPGRpdiBjbGFzcz1cImQtZmxleCBjb250cm9sLWdyb3VwXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtZ3JvdyBwb3NpdGlvbi1yZWxhdGl2ZVwiPlxyXG4gICAgICA8aW5wdXQgI2ZpbGVJbnB1dFxyXG4gICAgICAgICAgICAgaWQ9XCJ7e2lucHV0SWR9fV9pbnB1dFwiXHJcbiAgICAgICAgICAgICB0eXBlPVwiZmlsZVwiXHJcbiAgICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcclxuICAgICAgICAgICAgIFthdHRyLmFjY2VwdF09XCJmaWxlVHlwZUFjY2VwdFwiXHJcbiAgICAgICAgICAgICAoY2xpY2spPVwiYnJvd3NlQnRuLmZvY3VzKClcIlxyXG4gICAgICAgICAgICAgKGNoYW5nZSk9XCJmaWxlQ2hhbmdlKCRldmVudC50YXJnZXQuZmlsZXMpXCJcclxuICAgICAgICAgICAgIFtjbGFzcy5oYXMtdmFsdWVdPVwiZm9ybU1vZGVsPy5nZXQoJ25hbWUnKT8udmFsdWVcIj5cclxuICAgICAgPGVjLWZvcm0tY29udHJvbCBpZD1cInt7aW5wdXRJZH19X2Zvcm1Db250cm9sXCJcclxuICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJyZXF1aXJlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgW3BlbmRpbmddPVwicGVuZGluZ1wiPlxyXG4gICAgICAgIDxpbnB1dCBpZD1cInt7aW5wdXRJZH19X25hbWVcIlxyXG4gICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZm9ybU1vZGVsPy5nZXQoJ25hbWUnKVwiXHJcbiAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcclxuICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cIi0xXCI+XHJcbiAgICAgIDwvZWMtZm9ybS1jb250cm9sPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZWMtYnV0dG9uICNicm93c2VCdG5cclxuICAgICAgICAgICAgICAgaWQ9XCJ7e2lucHV0SWR9fV9icm93c2VCdG5cIlxyXG4gICAgICAgICAgICAgICAoY2xpY2tlZCk9XCJmaWxlSW5wdXQuY2xpY2soKVwiXHJcbiAgICAgICAgICAgICAgIHR5cGU9XCJzZWNvbmRhcnlcIlxyXG4gICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwidGFiaW5kZXhcIlxyXG4gICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybU1vZGVsPy5nZXQoJ25hbWUnKT8uZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICBsYWJlbD1cIkJyb3dzZVwiXHJcbiAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCI+XHJcbiAgICA8L2VjLWJ1dHRvbj5cclxuICA8L2Rpdj5cclxuPC9lYy1mb3JtLWdyb3VwPiJdfQ==
|
218
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2NvbnRyb2xzL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9maWxlLXVwbG9hZC9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQW9DLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7Ozs7O0FBS3ZELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHO0lBQ2hDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNiLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7Q0FDekIsQ0FBQztBQU9GLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxlQUFlO0lBRXRELGdFQUFnRTtJQUN6RCxNQUFNLENBQUMsWUFBWSxDQUN4QixVQUF5QixFQUN6QixXQUFvQixLQUFLO1FBRXpCLElBQUksU0FBUyxHQUFHLElBQUksZ0JBQWdCLENBQUM7WUFDbkMsSUFBSSxFQUFFLElBQUksa0JBQWtCLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxVQUFVLENBQUM7WUFDN0UsSUFBSSxFQUFFLElBQUksa0JBQWtCLENBQUMsRUFBRSxLQUFLLEVBQUUs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c0JBQTdCLEtBQUs7Z0JBT1UsdUJBQXVCO3NCQUF0QyxLQUFLO2dCQU9VLFdBQVc7c0JBQTFCLEtBQUs7Z0JBS1UsV0FBVztzQkFBMUIsS0FBSztnQkFLVSxVQUFVO3NCQUF6QixLQUFLO2dCQUtVLFdBQVc7c0JBQTFCLEtBQUs7Z0JBRTZELFNBQVM7c0JBQTNFLFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBVbnR5cGVkRm9ybUNvbnRyb2wsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvdmFsaWRhdGlvbi1tZXNzYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGb3JtR3JvdXBIZWxwZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvZm9ybS1ncm91cC5oZWxwZXInO1xyXG5pbXBvcnQgeyBGb3JtQ29udHJvbEJhc2UgfSBmcm9tICcuLi9mb3JtLWNvbnRyb2wtYmFzZSc7XHJcblxyXG5leHBvcnQgdHlwZSBGaWxlVHlwZSA9ICd6aXAnIHwgJ2V4Y2VsJyB8ICdjdXN0b20nO1xyXG5leHBvcnQgdHlwZSBGaWxlT3V0cHV0ID0gJ3JhdycgfCAnYmFzZTY0JztcclxuXHJcbmV4cG9ydCBjb25zdCBGaWxlVHlwZUV4dGVuc2lvbnMgPSB7XHJcbiAgemlwOiBbJy56aXAnXSxcclxuICBleGNlbDogWycueGxzJywgJy54bHN4J11cclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImVjLWZpbGUtdXBsb2FkXCIsXHJcbiAgdGVtcGxhdGVVcmw6IFwiLi9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbFwiLFxyXG4gIHN0eWxlVXJsczogW1wiLi9maWxlLXVwbG9hZC5jb21wb25lbnQuc2Nzc1wiXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZENvbXBvbmVudCBleHRlbmRzIEZvcm1Db250cm9sQmFzZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcclxuXHJcbiAgLy8gc3RhdGljIGNsYXNzIHRvIGNyZWF0ZSB0aGUgZm9ybSBncm91cCBmcm9tIGEgcGFyZW50IGNvbXBvbmVudFxyXG4gIHB1YmxpYyBzdGF0aWMgZ2V0Rm9ybU1vZGVsKFxyXG4gICAgdmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXSxcclxuICAgIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2VcclxuICApOiBVbnR5cGVkRm9ybUdyb3VwIHtcclxuICAgIGxldCBmb3JtR3JvdXAgPSBuZXcgVW50eXBlZEZvcm1Hcm91cCh7XHJcbiAgICAgIGZpbGU6IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woeyB2YWx1ZTogbnVsbCwgZGlzYWJsZWQ6IGRpc2FibGVkIH0sIHZhbGlkYXRvcnMpLFxyXG4gICAgICBuYW1lOiBuZXcgVW50eXBlZEZvcm1Db250cm9sKHsgdmFsdWU6IG51bGwsIGRpc2FibGVkOiBkaXNhYmxlZCB9LCB2YWxpZGF0b3JzKSxcclxuICAgICAgYmFzZTY0RmlsZVN0cmluZzogbmV3IFVudHlwZWRGb3JtQ29udHJvbChudWxsKSxcclxuICAgICAgdXBsb2FkUmVzdWx0OiBuZXcgVW50eXBlZEZvcm1Db250cm9sKG51bGwpLFxyXG4gICAgfSk7XHJcbiAgICBpZiAoZGlzYWJsZWQpIHtcclxuICAgICAgZm9ybUdyb3VwLmRpc2FibGUoKTtcclxuICAgIH1cclxuICAgIHJldHVybiBmb3JtR3JvdXA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGUgdmFsdWUgb2YgdGhlIHRleHRib3ggaW5wdXQncyBwbGFjZWhvbGRlclxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBwbGFjZWhvbGRlcj86IHN0cmluZyA9IFwiQ2hvb3NlIGZpbGUuLi5cIjtcclxuXHJcbiAgLyoqIENvbW1vbiBleHRlbnNpb25zIGZvciBhIGZpbGUgYnJvd3NpbmcgZGlhbG9nXHJcbiAgICogIE5vdGU6IEVkZ2UgZG9lcyBub3Qgc3VwcG9ydCB0aGUgYWNjZXB0IGF0dHJpYnV0ZSBvbiBmaWxlIGlucHV0cywgdGhlcmVmb3IgYWxsIGZpbGUgdHlwZXNcclxuICAgKiAgICAgICAgd2lsbCBiZSBzaG93bi4gIEZpcmVmb3ggYW5kIENocm9tZSBib3RoIHN1cHBvcnQgdGhpcyBmZWF0dXJlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBmaWxlVHlwZT86IEZpbGVUeXBlIHwgdW5kZWZpbmVkO1xyXG5cclxuICAvKipcclxuICAgKiBGaWxlIG91dHB1dCwgZGV0ZXJtaW5lcyB3aGljaCBwcm9wZXJ0aWVzIGFyZSBzdXBwbGllZCBvbiB0aGUgZm9ybU1vZGVsXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGZpbGVPdXRwdXQ/OiBGaWxlT3V0cHV0ID0gJ2Jhc2U2NCc7XHJcblxyXG4gIC8qKiBJZiBmaWxlVHlwZSBpcyBzZXQgdG8gY3VzdG9tIHNldCB0aGUgYWNjZXB0YWJsZSBmaWxlIHR5cGVzIGJhc2VkIG9uIHRoZSBjdXN0b20gYXJyYXkgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgY3VzdG9tRXh0ZW5zaW9ucz86IEFycmF5PHN0cmluZz4gfCB1bmRlZmluZWQ7XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIHN1cHBvcnRlZCBpZiB0aGUgaG9zdGluZyBwYWdlIG5lZWRzIHRvIHByb2Nlc3MgdGhlIGZpbGUgYmVmb3JlXHJcbiAgICogc2V0dGluZyB0aGUgZm9ybU1vZGVsIHdpdGggdGhlIGZpbGUgaW5mb3JtYXRpb24uIElmIHRoZSBwcm9taXNlIHJlc29sdmVzIGl0IHdpbGwgY29udGludWVcclxuICAgKiBhbmQgc2V0IHRoZSBmaWxlIG5hbWUgYW5kIGNvbnRlbnRzIHRvIHRoZSBmb3JtTW9kZWwsIG90aGVyd2lzZSBvbiBmYWlsdXJlIGl0J2xsIGRvIG5vdGhpbmcuXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIG9uRmlsZVNlbGVjdGVkPzogKGZpbGU6IEZpbGUpID0+IFByb21pc2U8YW55PjtcclxuXHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWwgY2FsbGJhY2sgc3VwcG9ydGVkIGZvciB3aGVuIHRoZSBob3N0aW5nIHBhZ2UgbmVlZHMgdG8gcHJvY2VzcyBtdWx0aXBsZSBmaWxlc1xyXG4gICAqIFdlIHNpbXBseSBtYXAgdGhlIEZpbGVMaXN0IHRvIGFuIGFycmF5IG9mIEZpbGUgb2JqZWN0cyBhbmQgcGFzcyB0aGF0IGFycmF5IHRvIHRoZSBcclxuICAgKiBjYWxsYmFjayBhbmQgbGV0IHRoZSBob3N0aW5nIHBhZ2UgaGFuZGxlIHRoZSBwcm9jZXNzaW5nXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIG9uTXVsdGlwbGVGaWxlc1NlbGVjdGVkPzogKGZpbGVzOiBGaWxlW10pID0+IFByb21pc2U8YW55PjtcclxuXHJcbiAgLyoqIFxyXG4gICAqIE9wdGlvbmFsIGRpc3BsYXkgdHlwZSB0aGF0IGNvbnRyb2xzIHdoZXRoZXIgdGhlIGZpbGUgaW5wdXQgdGV4dGJveCBpcyBkaXNwbGF5ZWQgb3JcclxuICAgKiBzaW1wbHkgYSBidXR0b24gdGhlIHVzZXIgY2xpY2tzIHRvIGxhdW5jaCB0aGUgT1MgZmlsZSBzdG9yYWdlIGRpYWxvZy5cclxuICAgKiBEZWZhdWx0OiBmaWxlXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGRpc3BsYXlUeXBlPzogJ2ZpbGUnIHwgJ2J1dHRvbicgPSAnZmlsZSc7XHJcblxyXG4gIC8qKiBcclxuICAgKiBXaGVuIGRpc3BsYXkgdHlwZSBpcyBzZXQgdG8gYnV0dG9uIHRoaXMgcHJvcGVydHkgd2lsbCBjb250cm9sIHRoZSBidXR0b24gbGFiZWxcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgYnV0dG9uTGFiZWw/OiBzdHJpbmc7XHJcblxyXG4gIC8qKiBcclxuICAgKiBXaGVuIGRpc3BsYXkgdHlwZSBpcyBzZXQgdG8gYnV0dG9uIHRoaXMgcHJvcGVydHkgd2lsbCBjb250cm9sIHRoZSBidXR0b24gdHlwZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBidXR0b25UeXBlPzogc3RyaW5nID0gJ3ByaW1hcnknO1xyXG5cclxuICAvKipcclxuICAgKiBPcHRpb25hbCBwcm9wZXJ0eSB0byBjb250cm9sIHdoZXRoZXIgdGhlIHVzZXIgY2FuIHNlbGVjdCBtdWx0aXBsZSBmaWxlc1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBtdWx0aVNlbGVjdD86IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQFZpZXdDaGlsZChcImZpbGVJbnB1dFwiLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgZmlsZUlucHV0PzogRWxlbWVudFJlZjtcclxuXHJcbiAgLyoqIFByb3BlcnR5IGJvdW5kIHRvIHRoZSBmaWxlIGlucHV0IHRvIGZpbHRlciB3aGF0IGZpbGUgdHlwZXMgYXJlIHNob3duIGluIHRoZSBkaWFsb2cgKi9cclxuICBwdWJsaWMgZmlsZVR5cGVBY2NlcHQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcm90ZWN0ZWQgdmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlOiBWYWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UsXHJcbiAgICBwcm90ZWN0ZWQgZm9ybUdyb3VwSGVscGVyOiBGb3JtR3JvdXBIZWxwZXIsXHJcbiAgKSB7XHJcbiAgICBzdXBlcih2YWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UsIGZvcm1Hcm91cEhlbHBlcik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgc3VwZXIubmdPbkNoYW5nZXMoY2hhbmdlcyk7XHJcblxyXG4gICAgdGhpcy51cGRhdGVGaWxlVHlwZUFjY2VwdCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgc3VwZXIubmdPbkluaXQoKTtcclxuXHJcbiAgICAvLyBXYXRjaCBmb3IgbmFtZSB0byBjaGFuZ2UsIGlmIHRoZSB2YWx1ZSBpcyBjbGVhcmVkIHdlIHdpbGwgY2xlYXIgdGhlIG90aGVyXHJcbiAgICAvLyBzdXBwb3J0aW5nIG1vZGVsIHByb3BlcnRpZXMuIFRoZSBuYW1lIGNhbiBiZSBjbGVhcmVkIGJ5IHRoZSB1c2VyIG1hbnVhbGx5IG9yIHZpYVxyXG4gICAgLy8gdGhlIGNsZWFyIGJ1dHRvblxyXG4gICAgdGhpcy5mb3JtTW9kZWw/LmdldCgnbmFtZScpPy52YWx1ZUNoYW5nZXMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUodmFsdWUgPT4ge1xyXG4gICAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5mb3JtTW9kZWwucGF0Y2hWYWx1ZSh7XHJcbiAgICAgICAgICBmaWxlOiBudWxsLFxyXG4gICAgICAgICAgbmFtZTogbnVsbCxcclxuICAgICAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IG51bGwsXHJcbiAgICAgICAgICB1cGxvYWRSZXN1bHQ6IG51bGxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgZmlsZUNoYW5nZShmaWxlczogRmlsZUxpc3QpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLm11bHRpU2VsZWN0KSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlTXVsdGlwbGVGaWxlcyhmaWxlcyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBmaWxlOiBGaWxlIHwgbnVsbCA9IGZpbGVzLml0ZW0oMCk7XHJcbiAgICAgIGlmIChmaWxlKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5yZWFkRmlsZShmaWxlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENsZWFyIHRoZSBmaWxlIGlucHV0cyB2YWx1ZSwgdGhpcyB3aWxsIGFsbG93IHRoZSB1c2VyIHRvIHBpY2sgdGhlIHNhbWUgZmlsZW5hbWVzIGFnYWluXHJcbiAgICAvLyBhbmQgY2F1c2UgZmlsZUNoYW5nZSB0byByZS10cmlnZ2VyLlxyXG4gICAgaWYgKHRoaXMuZmlsZUlucHV0KSB7XHJcbiAgICAgIHRoaXMuZmlsZUlucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyB0aGUgZmlsZSB0eXBlIGFuZCB1cGRhdGVzIHRoZSBmaWxlIHR5cGUgYWNjZXB0IHByb3BlcnR5LiBUaGlzIGlzIHdoYXQgZGV0ZXJtaW5lcyB0aGUgZmlsZVxyXG4gICAqIHR5cGUgY2hvaWNlcyB0aGF0IHRoZSB1c2VyIHdpbGwgYmUgbGltaXRlZCB0byBpbiB0aGUgZmlsZSBicm93c2UgZGlhbG9nXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVGaWxlVHlwZUFjY2VwdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZpbGVUeXBlKSB7XHJcbiAgICAgIGlmICh0aGlzLmZpbGVUeXBlICE9PSBcImN1c3RvbVwiKSB7XHJcbiAgICAgICAgdGhpcy5maWxlVHlwZUFjY2VwdCA9IEZpbGVUeXBlRXh0ZW5zaW9uc1t0aGlzLmZpbGVUeXBlXS5qb2luKFwiLFwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAodGhpcy5jdXN0b21FeHRlbnNpb25zKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbGVUeXBlQWNjZXB0ID0gdGhpcy5jdXN0b21FeHRlbnNpb25zLmpvaW4oXCIsXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGFrZSBhIGZpbGUgdGhhdCB3YXMgc2VsZWN0ZWQgYnkgdGhlIHVzZXIgYW5kIHByb2Nlc3MvcGF0Y2ggb3VyIGZvcm0gbW9kZWxcclxuICAgKiBJZiB0aGUgaG9zdCBjb21wb25lbnQgcmVxdWlyZXMgYW4gYWN0aW9uIHRvIG9jY3VyIHdpdGggdGhlIGZpbGUgcHJpb3IgdG8gdGhlIHBhdGNoIGl0IHdpbGwgY2FsbFxyXG4gICAqIGFuZCB3YWl0IGZvciBpdCB0byByZXR1cm4uXHJcbiAgICogQHBhcmFtIGZpbGUgXHJcbiAgICogQHBhcmFtIGJhc2U2NEZpbGVTdHJpbmcgT3B0aW9uYWw6IFdpbGwgaGF2ZSBhIHZhbHVlIHByb3ZpZGVkIGlmIHRoZSBmaWxlT3V0cHV0IGlzIHNldCB0byBiYXNlNjRcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NGaWxlKGZpbGU6IEZpbGUsIGJhc2U2NEZpbGVTdHJpbmc/OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLm9uRmlsZVNlbGVjdGVkKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMub25GaWxlU2VsZWN0ZWQoZmlsZSk7XHJcbiAgICAgICAgdGhpcy5wYXRjaEZpbGVSZXN1bHQoZmlsZSwgYmFzZTY0RmlsZVN0cmluZywgcmVzdWx0KTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIC8vIEJ1bW1lciwgd2UncmUgbm90IGdvaW5nIHRvIGRvIGFueXRoaW5nIGFib3V0IGl0IHRob3VnaC5cclxuICAgICAgICAvLyBXZSBhcmUgbm90IHBhdGNoaW5nIGFueSBvZiB0aGUgcmVzdWx0IHNvIGFueSBleGlzdGluZyBpbmZvcm1hdGlvbiByZW1haW5zXHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucGF0Y2hGaWxlUmVzdWx0KGZpbGUsIGJhc2U2NEZpbGVTdHJpbmcpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQmFzZWQgb24gdGhlIGZpbGVPdXRwdXQgcmV0dXJuIHdoZXRoZXIgdGhpcyBjb21wb25lbnQgaXMgZXhwZWN0ZWQgdG8gZGVsaXZlciBhIGJhc2U2NCBvdXRwdXRcclxuICAgKiBAcmV0dXJucyBcclxuICAgKi9cclxuICBwcml2YXRlIGlzQmFzZTY0RmlsZU91dHB1dCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVPdXRwdXQgPT09ICdiYXNlNjQnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV2hlbiB0aGUgZmlsZSB3YXMgc2VsZWN0ZWQgYW5kIHByb2Nlc3NlZCBwYXRjaCB0aGUgZmlsZSBpbmZvcm1hdGlvbiB0aGF0IHRoZSBob3N0aW5nIGZvcm0gd2lsbFxyXG4gICAqIGJlIGxvb2tpbmcgZm9yLiBcclxuICAgKiBAcGFyYW0gZmlsZSBcclxuICAgKiBAcGFyYW0gYmFzZTY0RmlsZVN0cmluZyBcclxuICAgKiBAcGFyYW0gb25GaWxlU2VsZWN0ZWRSZXN1bHQgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXRjaEZpbGVSZXN1bHQoZmlsZTogRmlsZSB8IG51bGwsIGJhc2U2NEZpbGVTdHJpbmc/OiBzdHJpbmcsIG9uRmlsZVNlbGVjdGVkUmVzdWx0PzogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLmZvcm1Nb2RlbD8ucGF0Y2hWYWx1ZSh7IFxyXG4gICAgICBmaWxlOiBmaWxlLCBcclxuICAgICAgbmFtZTogZmlsZT8ubmFtZSwgXHJcbiAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IGJhc2U2NEZpbGVTdHJpbmcgPz8gbnVsbFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKG9uRmlsZVNlbGVjdGVkUmVzdWx0KSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUoeyB1cGxvYWRSZXN1bHQ6IG9uRmlsZVNlbGVjdGVkUmVzdWx0IH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5mb3JtTW9kZWwucGF0Y2hWYWx1ZSh7IHVwbG9hZFJlc3VsdDogbnVsbCB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBNYXBzIHRoZSBmaWxlcyB0byBhbiBhcnJheSBvZiBGaWxlIG9iamVjdHMgYW5kIHNlbmRzIHRoZW0gYWxvbmdcclxuICAgKiB0byB0aGUgZGVyaXZlZCBvbk11bHRpcGxlRmlsZVNlbGVjdGVkIG1ldGhvZCBpbiB0aGUgaG9zdGluZyBjb21wb25lbnRcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGhhbmRsZU11bHRpcGxlRmlsZXMoZmlsZXM6IEZpbGVMaXN0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBmaWxlc0FycmF5ID0gQXJyYXkuZnJvbShmaWxlcyk7XHJcblxyXG4gICAgaWYgKHRoaXMub25NdWx0aXBsZUZpbGVzU2VsZWN0ZWQpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5vbk11bHRpcGxlRmlsZXNTZWxlY3RlZChmaWxlc0FycmF5KTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCdlcnJvcjogJywgZSk7XHJcbiAgICAgIH0gIFxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgcmVhZEZpbGUoZmlsZTogRmlsZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgY29uc3QgcmVhZGVyOiBGaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuXHJcbiAgICByZWFkZXIub25sb2FkZW5kID0gYXN5bmMgZSA9PiB7XHJcbiAgICAgIGxldCBiYXNlNjRGaWxlU3RyaW5nOiBzdHJpbmcgfCB1bmRlZmluZWQgPSByZWFkZXI/LnJlc3VsdD8udG9TdHJpbmcoKS5zcGxpdChcIixcIilbMV07XHJcbiAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc0ZpbGUoZmlsZSwgYmFzZTY0RmlsZVN0cmluZyk7XHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLmlzQmFzZTY0RmlsZU91dHB1dCgpKSB7XHJcbiAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYXdhaXQgdGhpcy5wcm9jZXNzRmlsZShmaWxlKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGVjLWZvcm0tZ3JvdXAgW2xhYmVsXT1cImxhYmVsXCJcclxuICAgICAgICAgICAgICAgW2Zvcm1Hcm91cF09XCJmb3JtTW9kZWxcIlxyXG4gICAgICAgICAgICAgICBjbGFzcz1cIm1iLTBcIj5cclxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGNvbnRyb2wtZ3JvdXBcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1ncm93IHBvc2l0aW9uLXJlbGF0aXZlXCI+XHJcbiAgICAgIDxpbnB1dCAjZmlsZUlucHV0XHJcbiAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2lucHV0XCJcclxuICAgICAgICAgICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxyXG4gICAgICAgICAgICAgW2F0dHIuYWNjZXB0XT1cImZpbGVUeXBlQWNjZXB0XCJcclxuICAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsZUNoYW5nZSgkZXZlbnQudGFyZ2V0LmZpbGVzKVwiXHJcbiAgICAgICAgICAgICBbY2xhc3MuaGFzLXZhbHVlXT1cImRpc3BsYXlUeXBlID09PSAnZmlsZScgPyBmb3JtTW9kZWw/LmdldCgnbmFtZScpLnZhbHVlIDogdW5kZWZpbmVkXCJcclxuICAgICAgICAgICAgIFthdHRyLm11bHRpcGxlXT1cIm11bHRpU2VsZWN0ID8gJ211bHRpcGxlJyA6IHVuZGVmaW5lZFwiPlxyXG4gICAgICAgICAgICA8ZWMtZm9ybS1jb250cm9sICpuZ0lmPVwiZGlzcGxheVR5cGUgPT09ICdmaWxlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7e2lucHV0SWR9fV9mb3JtQ29udHJvbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmdcIj5cclxuICAgICAgICA8aW5wdXQgaWQ9XCJ7e2lucHV0SWR9fV9uYW1lXCJcclxuICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImZvcm1Nb2RlbD8uZ2V0KCduYW1lJylcIlxyXG4gICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXHJcbiAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCItMVwiPlxyXG4gICAgICA8L2VjLWZvcm0tY29udHJvbD5cclxuICAgIDwvZGl2PlxyXG4gICAgPGVjLWJ1dHRvbiAqbmdJZj1cImRpc3BsYXlUeXBlID09PSAnZmlsZSdcIlxyXG4gICAgICAgICAgICAgICAjYnJvd3NlQnRuXHJcbiAgICAgICAgICAgICAgIGlkPVwie3tpbnB1dElkfX1fYnJvd3NlQnRuXCJcclxuICAgICAgICAgICAgICAgKGNsaWNrZWQpPVwiZmlsZUlucHV0LmNsaWNrKClcIlxyXG4gICAgICAgICAgICAgICB0eXBlPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcclxuICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImZvcm1Nb2RlbD8uZ2V0KCduYW1lJykuZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICBsYWJlbD1cIkJyb3dzZVwiXHJcbiAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCI+XHJcbiAgICA8L2VjLWJ1dHRvbj5cclxuICA8L2Rpdj5cclxuICA8ZWMtYnV0dG9uICpuZ0lmPVwiZGlzcGxheVR5cGUgPT09ICdidXR0b24nXCJcclxuICAgICAgICAgICAgIGlkPVwie3tpbnB1dElkfX1fYnRuXCJcclxuICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmdcIlxyXG4gICAgICAgICAgICAgW3R5cGVdPVwiYnV0dG9uVHlwZVwiXHJcbiAgICAgICAgICAgICBbbGFiZWxdPVwiYnV0dG9uTGFiZWwgPz8gJ0Jyb3dzZV9UQycgfCB0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICAgKGNsaWNrZWQpPVwiZmlsZUlucHV0LmNsaWNrKClcIlxyXG4gICAgICAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTtcIj5cclxuICA8L2VjLWJ1dHRvbj5cclxuPC9lYy1mb3JtLWdyb3VwPiJdfQ==
|
@@ -3783,7 +3783,7 @@ class FileUploadComponent extends FormControlBase {
|
|
3783
3783
|
file: new UntypedFormControl({ value: null, disabled: disabled }, validators),
|
3784
3784
|
name: new UntypedFormControl({ value: null, disabled: disabled }, validators),
|
3785
3785
|
base64FileString: new UntypedFormControl(null),
|
3786
|
-
uploadResult: new UntypedFormControl(null)
|
3786
|
+
uploadResult: new UntypedFormControl(null),
|
3787
3787
|
});
|
3788
3788
|
if (disabled) {
|
3789
3789
|
formGroup.disable();
|
@@ -3802,6 +3802,20 @@ class FileUploadComponent extends FormControlBase {
|
|
3802
3802
|
* File output, determines which properties are supplied on the formModel
|
3803
3803
|
*/
|
3804
3804
|
this.fileOutput = 'base64';
|
3805
|
+
/**
|
3806
|
+
* Optional display type that controls whether the file input textbox is displayed or
|
3807
|
+
* simply a button the user clicks to launch the OS file storage dialog.
|
3808
|
+
* Default: file
|
3809
|
+
*/
|
3810
|
+
this.displayType = 'file';
|
3811
|
+
/**
|
3812
|
+
* When display type is set to button this property will control the button type
|
3813
|
+
*/
|
3814
|
+
this.buttonType = 'primary';
|
3815
|
+
/**
|
3816
|
+
* Optional property to control whether the user can select multiple files
|
3817
|
+
*/
|
3818
|
+
this.multiSelect = false;
|
3805
3819
|
}
|
3806
3820
|
ngOnChanges(changes) {
|
3807
3821
|
super.ngOnChanges(changes);
|
@@ -3817,6 +3831,7 @@ class FileUploadComponent extends FormControlBase {
|
|
3817
3831
|
if (!value) {
|
3818
3832
|
this.formModel.patchValue({
|
3819
3833
|
file: null,
|
3834
|
+
name: null,
|
3820
3835
|
base64FileString: null,
|
3821
3836
|
uploadResult: null
|
3822
3837
|
});
|
@@ -3825,27 +3840,20 @@ class FileUploadComponent extends FormControlBase {
|
|
3825
3840
|
}
|
3826
3841
|
fileChange(files) {
|
3827
3842
|
return __awaiter(this, void 0, void 0, function* () {
|
3828
|
-
|
3829
|
-
|
3830
|
-
|
3831
|
-
|
3832
|
-
|
3833
|
-
|
3834
|
-
|
3835
|
-
this.processFile(file, base64FileString);
|
3836
|
-
});
|
3837
|
-
if (this.isBase64FileOutput()) {
|
3838
|
-
reader.readAsDataURL(file);
|
3839
|
-
}
|
3840
|
-
else {
|
3841
|
-
yield this.processFile(file);
|
3842
|
-
}
|
3843
|
-
// Clear the file inputs value, this will allow the user to pick the same filename and cause
|
3844
|
-
// the fileChange to trigger.
|
3845
|
-
if (this.fileInput) {
|
3846
|
-
this.fileInput.nativeElement.value = '';
|
3843
|
+
if (this.multiSelect) {
|
3844
|
+
this.handleMultipleFiles(files);
|
3845
|
+
}
|
3846
|
+
else {
|
3847
|
+
const file = files.item(0);
|
3848
|
+
if (file) {
|
3849
|
+
yield this.readFile(file);
|
3847
3850
|
}
|
3848
3851
|
}
|
3852
|
+
// Clear the file inputs value, this will allow the user to pick the same filenames again
|
3853
|
+
// and cause fileChange to re-trigger.
|
3854
|
+
if (this.fileInput) {
|
3855
|
+
this.fileInput.nativeElement.value = '';
|
3856
|
+
}
|
3849
3857
|
});
|
3850
3858
|
}
|
3851
3859
|
/**
|
@@ -3879,7 +3887,7 @@ class FileUploadComponent extends FormControlBase {
|
|
3879
3887
|
this.patchFileResult(file, base64FileString, result);
|
3880
3888
|
}
|
3881
3889
|
catch (e) {
|
3882
|
-
// Bummer, we're not going to do anything about it though.
|
3890
|
+
// Bummer, we're not going to do anything about it though.
|
3883
3891
|
// We are not patching any of the result so any existing information remains
|
3884
3892
|
}
|
3885
3893
|
}
|
@@ -3916,12 +3924,45 @@ class FileUploadComponent extends FormControlBase {
|
|
3916
3924
|
this.formModel.patchValue({ uploadResult: null });
|
3917
3925
|
}
|
3918
3926
|
}
|
3927
|
+
/** Maps the files to an array of File objects and sends them along
|
3928
|
+
* to the derived onMultipleFileSelected method in the hosting component
|
3929
|
+
*/
|
3930
|
+
handleMultipleFiles(files) {
|
3931
|
+
return __awaiter(this, void 0, void 0, function* () {
|
3932
|
+
const filesArray = Array.from(files);
|
3933
|
+
if (this.onMultipleFilesSelected) {
|
3934
|
+
try {
|
3935
|
+
let result = yield this.onMultipleFilesSelected(filesArray);
|
3936
|
+
}
|
3937
|
+
catch (e) {
|
3938
|
+
console.log('error: ', e);
|
3939
|
+
}
|
3940
|
+
}
|
3941
|
+
});
|
3942
|
+
}
|
3943
|
+
;
|
3944
|
+
readFile(file) {
|
3945
|
+
return __awaiter(this, void 0, void 0, function* () {
|
3946
|
+
const reader = new FileReader();
|
3947
|
+
reader.onloadend = (e) => __awaiter(this, void 0, void 0, function* () {
|
3948
|
+
var _a;
|
3949
|
+
let base64FileString = (_a = reader === null || reader === void 0 ? void 0 : reader.result) === null || _a === void 0 ? void 0 : _a.toString().split(",")[1];
|
3950
|
+
yield this.processFile(file, base64FileString);
|
3951
|
+
});
|
3952
|
+
if (this.isBase64FileOutput()) {
|
3953
|
+
reader.readAsDataURL(file);
|
3954
|
+
}
|
3955
|
+
else {
|
3956
|
+
yield this.processFile(file);
|
3957
|
+
}
|
3958
|
+
});
|
3959
|
+
}
|
3919
3960
|
}
|
3920
3961
|
FileUploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileUploadComponent, deps: [{ token: ValidationMessageService }, { token: FormGroupHelper }], target: i0.ɵɵFactoryTarget.Component });
|
3921
|
-
FileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FileUploadComponent, selector: "ec-file-upload", inputs: { placeholder: "placeholder", fileType: "fileType", fileOutput: "fileOutput", customExtensions: "customExtensions", onFileSelected: "onFileSelected" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (
|
3962
|
+
FileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: FileUploadComponent, selector: "ec-file-upload", inputs: { placeholder: "placeholder", fileType: "fileType", fileOutput: "fileOutput", customExtensions: "customExtensions", onFileSelected: "onFileSelected", onMultipleFilesSelected: "onMultipleFilesSelected", displayType: "displayType", buttonLabel: "buttonLabel", buttonType: "buttonType", multiSelect: "multiSelect" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (change)=\"fileChange($event.target.files)\"\r\n [class.has-value]=\"displayType === 'file' ? formModel?.get('name').value : undefined\"\r\n [attr.multiple]=\"multiSelect ? 'multiple' : undefined\">\r\n <ec-form-control *ngIf=\"displayType === 'file'\"\r\n id=\"{{inputId}}_formControl\"\r\n class=\"text-truncate\"\r\n [required]=\"required\"\r\n [pending]=\"pending\">\r\n <input id=\"{{inputId}}_name\"\r\n [formControl]=\"formModel?.get('name')\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [tabindex]=\"-1\">\r\n </ec-form-control>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'file'\"\r\n #browseBtn\r\n id=\"{{inputId}}_browseBtn\"\r\n (clicked)=\"fileInput.click()\"\r\n type=\"secondary\"\r\n [tabindex]=\"tabindex\"\r\n [disabled]=\"formModel?.get('name').disabled\"\r\n label=\"Browse\"\r\n [autofocus]=\"autofocus\">\r\n </ec-button>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'button'\"\r\n id=\"{{inputId}}_btn\"\r\n [pending]=\"pending\"\r\n [type]=\"buttonType\"\r\n [label]=\"buttonLabel ?? 'Browse_TC' | translate\"\r\n (clicked)=\"fileInput.click()\"\r\n style=\"width: 100%;\">\r\n </ec-button>\r\n</ec-form-group>", styles: [":host{display:block;margin-bottom:1rem}ec-form-control{margin-bottom:0}ec-form-control ::ng-deep>.ec-focus-ring{display:none!important}input[type=file]{opacity:0;display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;cursor:pointer}input[type=file].has-value{width:calc(100% - 1.5rem)}ec-button{--ec-button-border-color-secondary: var(--ec-form-control-border-color);--ec-button-color-icon-secondary: var(--ec-color-icon)}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "icon", "label", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "pending", "required", "readonly"], outputs: ["actionClicked"] }, { kind: "component", type: FormGroupComponent, selector: "ec-form-group", inputs: ["id", "label", "formGroup", "labelPosition", "overrideValidationError", "hideValidationMessage"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
3922
3963
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileUploadComponent, decorators: [{
|
3923
3964
|
type: Component,
|
3924
|
-
args: [{ selector: "ec-file-upload", template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (
|
3965
|
+
args: [{ selector: "ec-file-upload", template: "<ec-form-group [label]=\"label\"\r\n [formGroup]=\"formModel\"\r\n class=\"mb-0\">\r\n <div class=\"d-flex control-group\">\r\n <div class=\"d-flex flex-grow position-relative\">\r\n <input #fileInput\r\n id=\"{{inputId}}_input\"\r\n type=\"file\"\r\n tabindex=\"-1\"\r\n [attr.accept]=\"fileTypeAccept\"\r\n (change)=\"fileChange($event.target.files)\"\r\n [class.has-value]=\"displayType === 'file' ? formModel?.get('name').value : undefined\"\r\n [attr.multiple]=\"multiSelect ? 'multiple' : undefined\">\r\n <ec-form-control *ngIf=\"displayType === 'file'\"\r\n id=\"{{inputId}}_formControl\"\r\n class=\"text-truncate\"\r\n [required]=\"required\"\r\n [pending]=\"pending\">\r\n <input id=\"{{inputId}}_name\"\r\n [formControl]=\"formModel?.get('name')\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [tabindex]=\"-1\">\r\n </ec-form-control>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'file'\"\r\n #browseBtn\r\n id=\"{{inputId}}_browseBtn\"\r\n (clicked)=\"fileInput.click()\"\r\n type=\"secondary\"\r\n [tabindex]=\"tabindex\"\r\n [disabled]=\"formModel?.get('name').disabled\"\r\n label=\"Browse\"\r\n [autofocus]=\"autofocus\">\r\n </ec-button>\r\n </div>\r\n <ec-button *ngIf=\"displayType === 'button'\"\r\n id=\"{{inputId}}_btn\"\r\n [pending]=\"pending\"\r\n [type]=\"buttonType\"\r\n [label]=\"buttonLabel ?? 'Browse_TC' | translate\"\r\n (clicked)=\"fileInput.click()\"\r\n style=\"width: 100%;\">\r\n </ec-button>\r\n</ec-form-group>", styles: [":host{display:block;margin-bottom:1rem}ec-form-control{margin-bottom:0}ec-form-control ::ng-deep>.ec-focus-ring{display:none!important}input[type=file]{opacity:0;display:block;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;cursor:pointer}input[type=file].has-value{width:calc(100% - 1.5rem)}ec-button{--ec-button-border-color-secondary: var(--ec-form-control-border-color);--ec-button-color-icon-secondary: var(--ec-color-icon)}\n"] }]
|
3925
3966
|
}], ctorParameters: function () { return [{ type: ValidationMessageService }, { type: FormGroupHelper }]; }, propDecorators: { placeholder: [{
|
3926
3967
|
type: Input
|
3927
3968
|
}], fileType: [{
|
@@ -3932,6 +3973,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
3932
3973
|
type: Input
|
3933
3974
|
}], onFileSelected: [{
|
3934
3975
|
type: Input
|
3976
|
+
}], onMultipleFilesSelected: [{
|
3977
|
+
type: Input
|
3978
|
+
}], displayType: [{
|
3979
|
+
type: Input
|
3980
|
+
}], buttonLabel: [{
|
3981
|
+
type: Input
|
3982
|
+
}], buttonType: [{
|
3983
|
+
type: Input
|
3984
|
+
}], multiSelect: [{
|
3985
|
+
type: Input
|
3935
3986
|
}], fileInput: [{
|
3936
3987
|
type: ViewChild,
|
3937
3988
|
args: ["fileInput", { read: ElementRef, static: true }]
|