@energycap/components 0.39.21-ECAP-25650-file-upload-validation-support.20240806-1029 → 0.39.21-ECAP-25650-file-upload-validation-support.20240806-1534

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.
@@ -17,7 +17,9 @@ export const FileTypeExtensions = {
17
17
  };
18
18
  export class FileUploadComponent extends FormControlBase {
19
19
  // static class to create the form group from a parent component
20
- static getFormModel(validators, disabled = false, fileValidators) {
20
+ static getFormModel(validators, disabled = false,
21
+ /** Any validators required to make sure the selected file is valid. It is recommended that you use `FileUploadComponent.getFileValidator` to help construct the validator(s). NOTE: This currently only works when multiSelect is false. */
22
+ fileValidators) {
21
23
  let formGroup = new FormGroup({
22
24
  file: new FormControl({ value: null, disabled: disabled }, { validators: validators, asyncValidators: fileValidators }),
23
25
  name: new FormControl({ value: null, disabled: disabled }, validators),
@@ -29,10 +31,18 @@ export class FileUploadComponent extends FormControlBase {
29
31
  }
30
32
  return formGroup;
31
33
  }
34
+ /**
35
+ * Helper function that returns an async validator to be used with the file upload control.
36
+ * This is useful for when the file needs to be validated before it can be uploaded.
37
+ *
38
+ * @param callback The callback function that will be called to validate the file. Parameters for the callback are the file and the base64 string for the file.
39
+ * base64 is null if the fileOutput input on the FileUploadComponent is set to raw. Using fileOutput set to base64 is recommended for images.
40
+ */
32
41
  static getFileValidator(callback) {
33
42
  return async (control) => {
34
43
  if (control.value && control.parent) {
35
44
  let file = control.value;
45
+ // For images, we need the base64 string to validate image dimensions
36
46
  let base64 = control.parent.get('base64FileString')?.value;
37
47
  return await callback(file, base64);
38
48
  }
@@ -84,7 +94,8 @@ export class FileUploadComponent extends FormControlBase {
84
94
  });
85
95
  }
86
96
  });
87
- // Sync errors from the file control to the name control whenever the file control status changes
97
+ // Sync errors from the file control to the name control whenever the file control status changes.
98
+ // The name control is the only one displayed to the user so we need to show the errors there.
88
99
  this.formModel.get('file')?.statusChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(() => {
89
100
  const errors = this.formModel.get('file')?.errors ?? null;
90
101
  this.formModel.get('name')?.setErrors(errors);
@@ -129,26 +140,47 @@ export class FileUploadComponent extends FormControlBase {
129
140
  * @param file
130
141
  * @param base64FileString Optional: Will have a value provided if the fileOutput is set to base64
131
142
  */
132
- async processFile(file, base64FileString) {
143
+ async processFile(file, base64FileString = null) {
144
+ // If we have async validators on the file control we need to do validation before we trigger the upload
145
+ const validateBeforeUpload = !!this.formModel.controls.file.asyncValidator;
146
+ if (validateBeforeUpload) {
147
+ await this.validateFile(file, base64FileString);
148
+ }
149
+ if (this.onFileSelected) {
150
+ // Only call the onFileSelected callback to upload the file if the form group is valid
151
+ if (this.formModel.valid) {
152
+ try {
153
+ let result = await this.onFileSelected(file);
154
+ // If we did validation, just patch the form result because the file is already in the form
155
+ if (validateBeforeUpload) {
156
+ this.formModel.patchValue({ uploadResult: result ?? null });
157
+ }
158
+ else {
159
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: result ?? null });
160
+ }
161
+ }
162
+ catch (e) {
163
+ // Bummer, we're not going to do anything about it though.
164
+ // We are not patching any of the result so any existing information remains
165
+ }
166
+ }
167
+ // If we don't have an onFileSelected callback we just patch the form model.
168
+ // In the case of pre-upload validation the form already has the file so we don't want to patch again.
169
+ }
170
+ else if (!validateBeforeUpload) {
171
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: null });
172
+ }
173
+ }
174
+ /** Patches the form with the selected file in order to trigger control validation */
175
+ async validateFile(file, base64FileString = null) {
133
176
  // Patch the file first to trigger any file validators
134
- this.patchProcessedFile(file, base64FileString);
177
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: null });
135
178
  // If we have any async validators pending we need to wait for them to complete before we know if the form is valid
136
179
  if (this.formModel.pending) {
137
180
  await this.formModel.statusChanges.pipe(filter(status => status !== 'PENDING'), take(1), takeUntil(this.componentDestroyed)).toPromise();
138
181
  }
139
182
  // Mark the name control as touched so that any validation errors will show
140
183
  this.formModel.controls.name.markAsTouched();
141
- // Only call the onFileSelected callback to upload the file if the form is valid
142
- if (this.onFileSelected && this.formModel.valid) {
143
- try {
144
- let result = await this.onFileSelected(file);
145
- this.formModel.patchValue({ uploadResult: result ?? null });
146
- }
147
- catch (e) {
148
- // Bummer, we're not going to do anything about it though.
149
- // We are not patching any of the result so any existing information remains
150
- }
151
- }
152
184
  }
153
185
  /**
154
186
  * Based on the fileOutput return whether this component is expected to deliver a base64 output
@@ -157,21 +189,6 @@ export class FileUploadComponent extends FormControlBase {
157
189
  isBase64FileOutput() {
158
190
  return this.fileOutput === 'base64';
159
191
  }
160
- /**
161
- * When the file was selected and processed patch the file information that the hosting form will
162
- * be looking for.
163
- * @param file
164
- * @param base64FileString
165
- * @param onFileSelectedResult
166
- */
167
- patchProcessedFile(file, base64FileString) {
168
- this.formModel?.patchValue({
169
- file: file,
170
- name: file?.name,
171
- base64FileString: base64FileString ?? null,
172
- uploadResult: null
173
- });
174
- }
175
192
  /** Maps the files to an array of File objects and sends them along
176
193
  * to the derived onMultipleFileSelected method in the hosting component
177
194
  */
@@ -232,4 +249,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
232
249
  type: ViewChild,
233
250
  args: ["fileInput", { read: ElementRef, static: true }]
234
251
  }] } });
235
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2NvbnRyb2xzL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9maWxlLXVwbG9hZC9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQW9DLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQXFDLFdBQVcsRUFBRSxTQUFTLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RyxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7Ozs7QUFLdkQsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDaEMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQztDQUN6QixDQUFDO0FBb0JGLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxlQUFlO0lBRXRELGdFQUFnRTtJQUN6RCxNQUFNLENBQUMsWUFBWSxDQUN4QixVQUF5QixFQUN6QixXQUFvQixLQUFLLEVBQ3pCLGNBQXNEO1FBRXRELElBQUksU0FBUyxHQUFHLElBQUksU0FBUyxDQUFzQjtZQUNqRCxJQUFJLEVBQUUsSUFBSSxXQUFXLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsZUFBZSxF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LFVBQVU7c0JBQXpCLEtBQUs7Z0JBR1UsZ0JBQWdCO3NCQUEvQixLQUFLO2dCQU9VLGNBQWM7c0JBQTdCLEtBQUs7Z0JBT1UsdUJBQXVCO3NCQUF0QyxLQUFLO2dCQU9VLFdBQVc7c0JBQTFCLEtBQUs7Z0JBS1UsV0FBVztzQkFBMUIsS0FBSztnQkFLVSxVQUFVO3NCQUF6QixLQUFLO2dCQUtVLFdBQVc7c0JBQTFCLEtBQUs7Z0JBRTZELFNBQVM7c0JBQTNFLFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEFzeW5jVmFsaWRhdG9yRm4sIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgVmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS92YWxpZGF0aW9uLW1lc3NhZ2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IEZvcm1Hcm91cEhlbHBlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9mb3JtLWdyb3VwLmhlbHBlcic7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sQmFzZSB9IGZyb20gJy4uL2Zvcm0tY29udHJvbC1iYXNlJztcclxuXHJcbmV4cG9ydCB0eXBlIEZpbGVUeXBlID0gJ3ppcCcgfCAnZXhjZWwnIHwgJ2N1c3RvbSc7XHJcbmV4cG9ydCB0eXBlIEZpbGVPdXRwdXQgPSAncmF3JyB8ICdiYXNlNjQnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEZpbGVUeXBlRXh0ZW5zaW9ucyA9IHtcclxuICB6aXA6IFsnLnppcCddLFxyXG4gIGV4Y2VsOiBbJy54bHMnLCAnLnhsc3gnXVxyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgRmlsZVVwbG9hZEZvcm1Hcm91cCA9IHtcclxuICBmaWxlOiBGb3JtQ29udHJvbDxGaWxlIHwgbnVsbD47XHJcbiAgbmFtZTogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgYmFzZTY0RmlsZVN0cmluZzogRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD47XHJcbiAgdXBsb2FkUmVzdWx0OiBGb3JtQ29udHJvbDxhbnk+O1xyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgSW52YWxpZEZpbGVFcnJvciA9IHtcclxuICBpbnZhbGlkRmlsZTogdHJ1ZTtcclxufTtcclxuXHJcbmV4cG9ydCB0eXBlIEZpbGVWYWxpZGF0b3JDYWxsYmFjayA9IChmaWxlOiBGaWxlIHwgbnVsbCB8IHVuZGVmaW5lZCwgYmFzZTY0OiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKSA9PiBQcm9taXNlPEludmFsaWRGaWxlRXJyb3IgfCBudWxsPjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImVjLWZpbGUtdXBsb2FkXCIsXHJcbiAgdGVtcGxhdGVVcmw6IFwiLi9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbFwiLFxyXG4gIHN0eWxlVXJsczogW1wiLi9maWxlLXVwbG9hZC5jb21wb25lbnQuc2Nzc1wiXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZENvbXBvbmVudCBleHRlbmRzIEZvcm1Db250cm9sQmFzZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcclxuXHJcbiAgLy8gc3RhdGljIGNsYXNzIHRvIGNyZWF0ZSB0aGUgZm9ybSBncm91cCBmcm9tIGEgcGFyZW50IGNvbXBvbmVudFxyXG4gIHB1YmxpYyBzdGF0aWMgZ2V0Rm9ybU1vZGVsKFxyXG4gICAgdmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXSxcclxuICAgIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2UsXHJcbiAgICBmaWxlVmFsaWRhdG9ycz86IEFzeW5jVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuW11cclxuICApOiBGb3JtR3JvdXA8RmlsZVVwbG9hZEZvcm1Hcm91cD4ge1xyXG4gICAgbGV0IGZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXA8RmlsZVVwbG9hZEZvcm1Hcm91cD4oe1xyXG4gICAgICBmaWxlOiBuZXcgRm9ybUNvbnRyb2woeyB2YWx1ZTogbnVsbCwgZGlzYWJsZWQ6IGRpc2FibGVkIH0sIHt2YWxpZGF0b3JzOiB2YWxpZGF0b3JzLCBhc3luY1ZhbGlkYXRvcnM6IGZpbGVWYWxpZGF0b3JzfSksXHJcbiAgICAgIG5hbWU6IG5ldyBGb3JtQ29udHJvbCh7IHZhbHVlOiBudWxsLCBkaXNhYmxlZDogZGlzYWJsZWQgfSwgdmFsaWRhdG9ycyksXHJcbiAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IG5ldyBGb3JtQ29udHJvbChudWxsKSxcclxuICAgICAgdXBsb2FkUmVzdWx0OiBuZXcgRm9ybUNvbnRyb2wobnVsbCksXHJcbiAgICB9KTtcclxuICAgIGlmIChkaXNhYmxlZCkge1xyXG4gICAgICBmb3JtR3JvdXAuZGlzYWJsZSgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZvcm1Hcm91cDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgZ2V0RmlsZVZhbGlkYXRvcihjYWxsYmFjazogRmlsZVZhbGlkYXRvckNhbGxiYWNrKTogQXN5bmNWYWxpZGF0b3JGbiB7XHJcbiAgICByZXR1cm4gYXN5bmMgKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4ge1xyXG4gICAgICBpZiAoY29udHJvbC52YWx1ZSAmJiBjb250cm9sLnBhcmVudCkge1xyXG4gICAgICAgIGxldCBmaWxlID0gY29udHJvbC52YWx1ZSBhcyBGaWxlO1xyXG4gICAgICAgIGxldCBiYXNlNjQgPSBjb250cm9sLnBhcmVudC5nZXQoJ2Jhc2U2NEZpbGVTdHJpbmcnKT8udmFsdWUgYXMgc3RyaW5nO1xyXG4gICAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayhmaWxlLCBiYXNlNjQpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQElucHV0KCkgcHVibGljIGZvcm1Nb2RlbCE6IEZvcm1Hcm91cDxGaWxlVXBsb2FkRm9ybUdyb3VwPjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHZhbHVlIG9mIHRoZSB0ZXh0Ym94IGlucHV0J3MgcGxhY2Vob2xkZXJcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgcGxhY2Vob2xkZXI/OiBzdHJpbmcgPSBcIkNob29zZSBmaWxlLi4uXCI7XHJcblxyXG4gIC8qKiBDb21tb24gZXh0ZW5zaW9ucyBmb3IgYSBmaWxlIGJyb3dzaW5nIGRpYWxvZ1xyXG4gICAqICBOb3RlOiBFZGdlIGRvZXMgbm90IHN1cHBvcnQgdGhlIGFjY2VwdCBhdHRyaWJ1dGUgb24gZmlsZSBpbnB1dHMsIHRoZXJlZm9yIGFsbCBmaWxlIHR5cGVzXHJcbiAgICogICAgICAgIHdpbGwgYmUgc2hvd24uICBGaXJlZm94IGFuZCBDaHJvbWUgYm90aCBzdXBwb3J0IHRoaXMgZmVhdHVyZS5cclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZmlsZVR5cGU/OiBGaWxlVHlwZSB8IHVuZGVmaW5lZDtcclxuXHJcbiAgLyoqXHJcbiAgICogRmlsZSBvdXRwdXQsIGRldGVybWluZXMgd2hpY2ggcHJvcGVydGllcyBhcmUgc3VwcGxpZWQgb24gdGhlIGZvcm1Nb2RlbFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBmaWxlT3V0cHV0PzogRmlsZU91dHB1dCA9ICdiYXNlNjQnO1xyXG5cclxuICAvKiogSWYgZmlsZVR5cGUgaXMgc2V0IHRvIGN1c3RvbSBzZXQgdGhlIGFjY2VwdGFibGUgZmlsZSB0eXBlcyBiYXNlZCBvbiB0aGUgY3VzdG9tIGFycmF5ICovXHJcbiAgQElucHV0KCkgcHVibGljIGN1c3RvbUV4dGVuc2lvbnM/OiBBcnJheTxzdHJpbmc+IHwgdW5kZWZpbmVkO1xyXG5cclxuICAvKipcclxuICAgKiBPcHRpb25hbCBjYWxsYmFjayBzdXBwb3J0ZWQgaWYgdGhlIGhvc3RpbmcgcGFnZSBuZWVkcyB0byBwcm9jZXNzIHRoZSBmaWxlIGJlZm9yZVxyXG4gICAqIHNldHRpbmcgdGhlIGZvcm1Nb2RlbCB3aXRoIHRoZSBmaWxlIGluZm9ybWF0aW9uLiBJZiB0aGUgcHJvbWlzZSByZXNvbHZlcyBpdCB3aWxsIGNvbnRpbnVlXHJcbiAgICogYW5kIHNldCB0aGUgZmlsZSBuYW1lIGFuZCBjb250ZW50cyB0byB0aGUgZm9ybU1vZGVsLCBvdGhlcndpc2Ugb24gZmFpbHVyZSBpdCdsbCBkbyBub3RoaW5nLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBvbkZpbGVTZWxlY3RlZD86IChmaWxlOiBGaWxlKSA9PiBQcm9taXNlPGFueT47XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIHN1cHBvcnRlZCBmb3Igd2hlbiB0aGUgaG9zdGluZyBwYWdlIG5lZWRzIHRvIHByb2Nlc3MgbXVsdGlwbGUgZmlsZXNcclxuICAgKiBXZSBzaW1wbHkgbWFwIHRoZSBGaWxlTGlzdCB0byBhbiBhcnJheSBvZiBGaWxlIG9iamVjdHMgYW5kIHBhc3MgdGhhdCBhcnJheSB0byB0aGUgXHJcbiAgICogY2FsbGJhY2sgYW5kIGxldCB0aGUgaG9zdGluZyBwYWdlIGhhbmRsZSB0aGUgcHJvY2Vzc2luZ1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBvbk11bHRpcGxlRmlsZXNTZWxlY3RlZD86IChmaWxlczogRmlsZVtdKSA9PiBQcm9taXNlPGFueT47XHJcblxyXG4gIC8qKiBcclxuICAgKiBPcHRpb25hbCBkaXNwbGF5IHR5cGUgdGhhdCBjb250cm9scyB3aGV0aGVyIHRoZSBmaWxlIGlucHV0IHRleHRib3ggaXMgZGlzcGxheWVkIG9yXHJcbiAgICogc2ltcGx5IGEgYnV0dG9uIHRoZSB1c2VyIGNsaWNrcyB0byBsYXVuY2ggdGhlIE9TIGZpbGUgc3RvcmFnZSBkaWFsb2cuXHJcbiAgICogRGVmYXVsdDogZmlsZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkaXNwbGF5VHlwZT86ICdmaWxlJyB8ICdidXR0b24nID0gJ2ZpbGUnO1xyXG5cclxuICAvKiogXHJcbiAgICogV2hlbiBkaXNwbGF5IHR5cGUgaXMgc2V0IHRvIGJ1dHRvbiB0aGlzIHByb3BlcnR5IHdpbGwgY29udHJvbCB0aGUgYnV0dG9uIGxhYmVsXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGJ1dHRvbkxhYmVsPzogc3RyaW5nO1xyXG5cclxuICAvKiogXHJcbiAgICogV2hlbiBkaXNwbGF5IHR5cGUgaXMgc2V0IHRvIGJ1dHRvbiB0aGlzIHByb3BlcnR5IHdpbGwgY29udHJvbCB0aGUgYnV0dG9uIHR5cGVcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgYnV0dG9uVHlwZT86IHN0cmluZyA9ICdwcmltYXJ5JztcclxuXHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWwgcHJvcGVydHkgdG8gY29udHJvbCB3aGV0aGVyIHRoZSB1c2VyIGNhbiBzZWxlY3QgbXVsdGlwbGUgZmlsZXNcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbXVsdGlTZWxlY3Q/OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIEBWaWV3Q2hpbGQoXCJmaWxlSW5wdXRcIiwgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IHRydWUgfSkgcHVibGljIGZpbGVJbnB1dD86IEVsZW1lbnRSZWY7XHJcblxyXG4gIC8qKiBQcm9wZXJ0eSBib3VuZCB0byB0aGUgZmlsZSBpbnB1dCB0byBmaWx0ZXIgd2hhdCBmaWxlIHR5cGVzIGFyZSBzaG93biBpbiB0aGUgZGlhbG9nICovXHJcbiAgcHVibGljIGZpbGVUeXBlQWNjZXB0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRpb25NZXNzYWdlU2VydmljZTogVmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLFxyXG4gICAgcHJvdGVjdGVkIGZvcm1Hcm91cEhlbHBlcjogRm9ybUdyb3VwSGVscGVyLFxyXG4gICkge1xyXG4gICAgc3VwZXIodmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLCBmb3JtR3JvdXBIZWxwZXIpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIHN1cGVyLm5nT25DaGFuZ2VzKGNoYW5nZXMpO1xyXG5cclxuICAgIHRoaXMudXBkYXRlRmlsZVR5cGVBY2NlcHQoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHN1cGVyLm5nT25Jbml0KCk7XHJcblxyXG4gICAgLy8gV2F0Y2ggZm9yIG5hbWUgdG8gY2hhbmdlLCBpZiB0aGUgdmFsdWUgaXMgY2xlYXJlZCB3ZSB3aWxsIGNsZWFyIHRoZSBvdGhlclxyXG4gICAgLy8gc3VwcG9ydGluZyBtb2RlbCBwcm9wZXJ0aWVzLiBUaGUgbmFtZSBjYW4gYmUgY2xlYXJlZCBieSB0aGUgdXNlciBtYW51YWxseSBvciB2aWFcclxuICAgIC8vIHRoZSBjbGVhciBidXR0b25cclxuICAgIHRoaXMuZm9ybU1vZGVsPy5nZXQoJ25hbWUnKT8udmFsdWVDaGFuZ2VzLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUoe1xyXG4gICAgICAgICAgZmlsZTogbnVsbCxcclxuICAgICAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IG51bGwsXHJcbiAgICAgICAgICB1cGxvYWRSZXN1bHQ6IG51bGxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gU3luYyBlcnJvcnMgZnJvbSB0aGUgZmlsZSBjb250cm9sIHRvIHRoZSBuYW1lIGNvbnRyb2wgd2hlbmV2ZXIgdGhlIGZpbGUgY29udHJvbCBzdGF0dXMgY2hhbmdlc1xyXG4gICAgdGhpcy5mb3JtTW9kZWwuZ2V0KCdmaWxlJyk/LnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICBjb25zdCBlcnJvcnMgPSB0aGlzLmZvcm1Nb2RlbC5nZXQoJ2ZpbGUnKT8uZXJyb3JzID8/IG51bGw7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLmdldCgnbmFtZScpPy5zZXRFcnJvcnMoZXJyb3JzKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIGZpbGVDaGFuZ2UoZmlsZXM6IEZpbGVMaXN0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBpZiAodGhpcy5tdWx0aVNlbGVjdCkge1xyXG4gICAgICB0aGlzLmhhbmRsZU11bHRpcGxlRmlsZXMoZmlsZXMpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZmlsZTogRmlsZSB8IG51bGwgPSBmaWxlcy5pdGVtKDApO1xyXG4gICAgICBpZiAoZmlsZSkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMucmVhZEZpbGUoZmlsZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBDbGVhciB0aGUgZmlsZSBpbnB1dHMgdmFsdWUsIHRoaXMgd2lsbCBhbGxvdyB0aGUgdXNlciB0byBwaWNrIHRoZSBzYW1lIGZpbGVuYW1lcyBhZ2FpblxyXG4gICAgLy8gYW5kIGNhdXNlIGZpbGVDaGFuZ2UgdG8gcmUtdHJpZ2dlci5cclxuICAgIGlmICh0aGlzLmZpbGVJbnB1dCkge1xyXG4gICAgICB0aGlzLmZpbGVJbnB1dC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVja3MgdGhlIGZpbGUgdHlwZSBhbmQgdXBkYXRlcyB0aGUgZmlsZSB0eXBlIGFjY2VwdCBwcm9wZXJ0eS4gVGhpcyBpcyB3aGF0IGRldGVybWluZXMgdGhlIGZpbGVcclxuICAgKiB0eXBlIGNob2ljZXMgdGhhdCB0aGUgdXNlciB3aWxsIGJlIGxpbWl0ZWQgdG8gaW4gdGhlIGZpbGUgYnJvd3NlIGRpYWxvZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgdXBkYXRlRmlsZVR5cGVBY2NlcHQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5maWxlVHlwZSkge1xyXG4gICAgICBpZiAodGhpcy5maWxlVHlwZSAhPT0gXCJjdXN0b21cIikge1xyXG4gICAgICAgIHRoaXMuZmlsZVR5cGVBY2NlcHQgPSBGaWxlVHlwZUV4dGVuc2lvbnNbdGhpcy5maWxlVHlwZV0uam9pbihcIixcIik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VzdG9tRXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgdGhpcy5maWxlVHlwZUFjY2VwdCA9IHRoaXMuY3VzdG9tRXh0ZW5zaW9ucy5qb2luKFwiLFwiKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRha2UgYSBmaWxlIHRoYXQgd2FzIHNlbGVjdGVkIGJ5IHRoZSB1c2VyIGFuZCBwcm9jZXNzL3BhdGNoIG91ciBmb3JtIG1vZGVsXHJcbiAgICogSWYgdGhlIGhvc3QgY29tcG9uZW50IHJlcXVpcmVzIGFuIGFjdGlvbiB0byBvY2N1ciB3aXRoIHRoZSBmaWxlIHByaW9yIHRvIHRoZSBwYXRjaCBpdCB3aWxsIGNhbGxcclxuICAgKiBhbmQgd2FpdCBmb3IgaXQgdG8gcmV0dXJuLlxyXG4gICAqIEBwYXJhbSBmaWxlIFxyXG4gICAqIEBwYXJhbSBiYXNlNjRGaWxlU3RyaW5nIE9wdGlvbmFsOiBXaWxsIGhhdmUgYSB2YWx1ZSBwcm92aWRlZCBpZiB0aGUgZmlsZU91dHB1dCBpcyBzZXQgdG8gYmFzZTY0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzRmlsZShmaWxlOiBGaWxlLCBiYXNlNjRGaWxlU3RyaW5nPzogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBQYXRjaCB0aGUgZmlsZSBmaXJzdCB0byB0cmlnZ2VyIGFueSBmaWxlIHZhbGlkYXRvcnNcclxuICAgIHRoaXMucGF0Y2hQcm9jZXNzZWRGaWxlKGZpbGUsIGJhc2U2NEZpbGVTdHJpbmcpO1xyXG5cclxuICAgIC8vIElmIHdlIGhhdmUgYW55IGFzeW5jIHZhbGlkYXRvcnMgcGVuZGluZyB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZW0gdG8gY29tcGxldGUgYmVmb3JlIHdlIGtub3cgaWYgdGhlIGZvcm0gaXMgdmFsaWRcclxuICAgIGlmICh0aGlzLmZvcm1Nb2RlbC5wZW5kaW5nKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuZm9ybU1vZGVsLnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgICBmaWx0ZXIoc3RhdHVzID0+IHN0YXR1cyAhPT0gJ1BFTkRJTkcnKSxcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICAgKS50b1Byb21pc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBNYXJrIHRoZSBuYW1lIGNvbnRyb2wgYXMgdG91Y2hlZCBzbyB0aGF0IGFueSB2YWxpZGF0aW9uIGVycm9ycyB3aWxsIHNob3dcclxuICAgIHRoaXMuZm9ybU1vZGVsLmNvbnRyb2xzLm5hbWUubWFya0FzVG91Y2hlZCgpO1xyXG5cclxuICAgIC8vIE9ubHkgY2FsbCB0aGUgb25GaWxlU2VsZWN0ZWQgY2FsbGJhY2sgdG8gdXBsb2FkIHRoZSBmaWxlIGlmIHRoZSBmb3JtIGlzIHZhbGlkXHJcbiAgICBpZiAodGhpcy5vbkZpbGVTZWxlY3RlZCAmJiB0aGlzLmZvcm1Nb2RlbC52YWxpZCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLm9uRmlsZVNlbGVjdGVkKGZpbGUpO1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUoeyB1cGxvYWRSZXN1bHQ6IHJlc3VsdCA/PyBudWxsIH0pO1xyXG4gICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgLy8gQnVtbWVyLCB3ZSdyZSBub3QgZ29pbmcgdG8gZG8gYW55dGhpbmcgYWJvdXQgaXQgdGhvdWdoLlxyXG4gICAgICAgIC8vIFdlIGFyZSBub3QgcGF0Y2hpbmcgYW55IG9mIHRoZSByZXN1bHQgc28gYW55IGV4aXN0aW5nIGluZm9ybWF0aW9uIHJlbWFpbnNcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQmFzZWQgb24gdGhlIGZpbGVPdXRwdXQgcmV0dXJuIHdoZXRoZXIgdGhpcyBjb21wb25lbnQgaXMgZXhwZWN0ZWQgdG8gZGVsaXZlciBhIGJhc2U2NCBvdXRwdXRcclxuICAgKiBAcmV0dXJucyBcclxuICAgKi9cclxuICBwcml2YXRlIGlzQmFzZTY0RmlsZU91dHB1dCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVPdXRwdXQgPT09ICdiYXNlNjQnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV2hlbiB0aGUgZmlsZSB3YXMgc2VsZWN0ZWQgYW5kIHByb2Nlc3NlZCBwYXRjaCB0aGUgZmlsZSBpbmZvcm1hdGlvbiB0aGF0IHRoZSBob3N0aW5nIGZvcm0gd2lsbFxyXG4gICAqIGJlIGxvb2tpbmcgZm9yLiBcclxuICAgKiBAcGFyYW0gZmlsZSBcclxuICAgKiBAcGFyYW0gYmFzZTY0RmlsZVN0cmluZyBcclxuICAgKiBAcGFyYW0gb25GaWxlU2VsZWN0ZWRSZXN1bHQgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXRjaFByb2Nlc3NlZEZpbGUoZmlsZTogRmlsZSB8IG51bGwsIGJhc2U2NEZpbGVTdHJpbmc/OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuZm9ybU1vZGVsPy5wYXRjaFZhbHVlKHsgXHJcbiAgICAgIGZpbGU6IGZpbGUsIFxyXG4gICAgICBuYW1lOiBmaWxlPy5uYW1lLCBcclxuICAgICAgYmFzZTY0RmlsZVN0cmluZzogYmFzZTY0RmlsZVN0cmluZyA/PyBudWxsLFxyXG4gICAgICB1cGxvYWRSZXN1bHQ6IG51bGxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqIE1hcHMgdGhlIGZpbGVzIHRvIGFuIGFycmF5IG9mIEZpbGUgb2JqZWN0cyBhbmQgc2VuZHMgdGhlbSBhbG9uZ1xyXG4gICAqIHRvIHRoZSBkZXJpdmVkIG9uTXVsdGlwbGVGaWxlU2VsZWN0ZWQgbWV0aG9kIGluIHRoZSBob3N0aW5nIGNvbXBvbmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlTXVsdGlwbGVGaWxlcyhmaWxlczogRmlsZUxpc3QpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGZpbGVzQXJyYXkgPSBBcnJheS5mcm9tKGZpbGVzKTtcclxuXHJcbiAgICBpZiAodGhpcy5vbk11bHRpcGxlRmlsZXNTZWxlY3RlZCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLm9uTXVsdGlwbGVGaWxlc1NlbGVjdGVkKGZpbGVzQXJyYXkpO1xyXG4gICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yOiAnLCBlKTtcclxuICAgICAgfSAgXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBhc3luYyByZWFkRmlsZShmaWxlOiBGaWxlKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCByZWFkZXI6IEZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG5cclxuICAgIHJlYWRlci5vbmxvYWRlbmQgPSBhc3luYyBlID0+IHtcclxuICAgICAgbGV0IGJhc2U2NEZpbGVTdHJpbmc6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHJlYWRlcj8ucmVzdWx0Py50b1N0cmluZygpLnNwbGl0KFwiLFwiKVsxXTtcclxuICAgICAgYXdhaXQgdGhpcy5wcm9jZXNzRmlsZShmaWxlLCBiYXNlNjRGaWxlU3RyaW5nKTtcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMuaXNCYXNlNjRGaWxlT3V0cHV0KCkpIHtcclxuICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBhd2FpdCB0aGlzLnByb2Nlc3NGaWxlKGZpbGUpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZWMtZm9ybS1ncm91cCBbbGFiZWxdPVwibGFiZWxcIlxyXG4gICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZvcm1Nb2RlbFwiXHJcbiAgICAgICAgICAgICAgIFtoZWxwUG9wb3Zlcl09XCJoZWxwUG9wb3ZlclwiXHJcbiAgICAgICAgICAgICAgIFtoZWxwUG9wb3ZlclBvc2l0aW9uXT1cImhlbHBQb3BvdmVyUG9zaXRpb25cIlxyXG4gICAgICAgICAgICAgICBjbGFzcz1cIm1iLTBcIj5cclxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGNvbnRyb2wtZ3JvdXBcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1ncm93IHBvc2l0aW9uLXJlbGF0aXZlXCI+XHJcbiAgICAgIDxpbnB1dCAjZmlsZUlucHV0XHJcbiAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2lucHV0XCJcclxuICAgICAgICAgICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxyXG4gICAgICAgICAgICAgW2F0dHIuYWNjZXB0XT1cImZpbGVUeXBlQWNjZXB0XCJcclxuICAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsZUNoYW5nZSgkZXZlbnQudGFyZ2V0LmZpbGVzKVwiXHJcbiAgICAgICAgICAgICBbY2xhc3MuaGFzLXZhbHVlXT1cImRpc3BsYXlUeXBlID09PSAnZmlsZScgPyBmb3JtTW9kZWw/LmdldCgnbmFtZScpLnZhbHVlIDogdW5kZWZpbmVkXCJcclxuICAgICAgICAgICAgIFthdHRyLm11bHRpcGxlXT1cIm11bHRpU2VsZWN0ID8gJ211bHRpcGxlJyA6IHVuZGVmaW5lZFwiPlxyXG4gICAgICA8ZWMtZm9ybS1jb250cm9sICpuZ0lmPVwiZGlzcGxheVR5cGUgPT09ICdmaWxlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7e2lucHV0SWR9fV9mb3JtQ29udHJvbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmcgfHwgZm9ybU1vZGVsPy5wZW5kaW5nXCI+XHJcbiAgICAgICAgPGlucHV0IGlkPVwie3tpbnB1dElkfX1fbmFtZVwiXHJcbiAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtTW9kZWw/LmdldCgnbmFtZScpXCJcclxuICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwiLTFcIj5cclxuICAgICAgPC9lYy1mb3JtLWNvbnRyb2w+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxlYy1idXR0b24gKm5nSWY9XCJkaXNwbGF5VHlwZSA9PT0gJ2ZpbGUnXCJcclxuICAgICAgICAgICAgICAgI2Jyb3dzZUJ0blxyXG4gICAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2Jyb3dzZUJ0blwiXHJcbiAgICAgICAgICAgICAgIChjbGlja2VkKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAgICAgICAgICAgICAgdHlwZT1cInNlY29uZGFyeVwiXHJcbiAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXHJcbiAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmb3JtTW9kZWw/LmdldCgnbmFtZScpLmRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAgbGFiZWw9XCJCcm93c2VcIlxyXG4gICAgICAgICAgICAgICBbYXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiPlxyXG4gICAgPC9lYy1idXR0b24+XHJcbiAgPC9kaXY+XHJcbiAgPGVjLWJ1dHRvbiAqbmdJZj1cImRpc3BsYXlUeXBlID09PSAnYnV0dG9uJ1wiXHJcbiAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2J0blwiXHJcbiAgICAgICAgICAgICBbcGVuZGluZ109XCJwZW5kaW5nXCJcclxuICAgICAgICAgICAgIFt0eXBlXT1cImJ1dHRvblR5cGVcIlxyXG4gICAgICAgICAgICAgW2xhYmVsXT1cImJ1dHRvbkxhYmVsID8/ICdCcm93c2VfVEMnIHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgIChjbGlja2VkKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7XCI+XHJcbiAgPC9lYy1idXR0b24+XHJcbjwvZWMtZm9ybS1ncm91cD4iXX0=
252
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2NvbnRyb2xzL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9maWxlLXVwbG9hZC9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQW9DLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQXFDLFdBQVcsRUFBRSxTQUFTLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4RyxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7Ozs7QUFLdkQsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDaEMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2IsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQztDQUN6QixDQUFDO0FBb0JGLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxlQUFlO0lBRXRELGdFQUFnRTtJQUN6RCxNQUFNLENBQUMsWUFBWSxDQUN4QixVQUF5QixFQUN6QixXQUFvQixLQUFLO0lBQ3pCLDRPQUE0TztJQUM1TyxjQUFzRDtRQUV0RCxJQUFJLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBc0I7WUFDakQsSUFBSSxFQUFFLElBQUksV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBQyxVQUFVLEVBQUUsVUFB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QUFFLENBQUM7UUFFNUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxLQUFLLEVBQUMsQ0FBQyxFQUFDLEVBQUU7WUFDM0IsSUFBSSxnQkFBZ0IsR0FBdUIsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEYsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQztRQUVGLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUU7WUFDN0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM1QjthQUFNO1lBQ0wsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzlCO0lBQ0gsQ0FBQzs7Z0hBNVFVLG1CQUFtQjtvR0FBbkIsbUJBQW1CLG1lQWlHRSxVQUFVLHVGQ2xJNUMsaWlFQThDZ0I7MkZEYkgsbUJBQW1CO2tCQUwvQixTQUFTOytCQUNFLGdCQUFnQjs2SUE0Q1YsU0FBUztzQkFBeEIsS0FBSztnQkFLVSxXQUFXO3NCQUExQixLQUFLO2dCQU1VLFFBQVE7c0JBQXZCLEtBQUs7Z0JBS1UsVUFBVTtzQkFBekIsS0FBSztnQkFHVSxnQkFBZ0I7c0JBQS9CLEtBQUs7Z0JBT1UsY0FBYztzQkFBN0IsS0FBSztnQkFPVSx1QkFBdUI7c0JBQXRDLEtBQUs7Z0JBT1UsV0FBVztzQkFBMUIsS0FBSztnQkFLVSxXQUFXO3NCQUExQixLQUFLO2dCQUtVLFVBQVU7c0JBQXpCLEtBQUs7Z0JBS1UsV0FBVztzQkFBMUIsS0FBSztnQkFFNkQsU0FBUztzQkFBM0UsU0FBUzt1QkFBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgQXN5bmNWYWxpZGF0b3JGbiwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9yRm4gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IGZpbHRlciwgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBWYWxpZGF0aW9uTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb3JlL3ZhbGlkYXRpb24tbWVzc2FnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRm9ybUdyb3VwSGVscGVyIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Zvcm0tZ3JvdXAuaGVscGVyJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xCYXNlIH0gZnJvbSAnLi4vZm9ybS1jb250cm9sLWJhc2UnO1xyXG5cclxuZXhwb3J0IHR5cGUgRmlsZVR5cGUgPSAnemlwJyB8ICdleGNlbCcgfCAnY3VzdG9tJztcclxuZXhwb3J0IHR5cGUgRmlsZU91dHB1dCA9ICdyYXcnIHwgJ2Jhc2U2NCc7XHJcblxyXG5leHBvcnQgY29uc3QgRmlsZVR5cGVFeHRlbnNpb25zID0ge1xyXG4gIHppcDogWycuemlwJ10sXHJcbiAgZXhjZWw6IFsnLnhscycsICcueGxzeCddXHJcbn07XHJcblxyXG5leHBvcnQgdHlwZSBGaWxlVXBsb2FkRm9ybUdyb3VwID0ge1xyXG4gIGZpbGU6IEZvcm1Db250cm9sPEZpbGUgfCBudWxsPjtcclxuICBuYW1lOiBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPjtcclxuICBiYXNlNjRGaWxlU3RyaW5nOiBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPjtcclxuICB1cGxvYWRSZXN1bHQ6IEZvcm1Db250cm9sPGFueT47XHJcbn07XHJcblxyXG5leHBvcnQgdHlwZSBJbnZhbGlkRmlsZUVycm9yID0ge1xyXG4gIGludmFsaWRGaWxlOiB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgRmlsZVZhbGlkYXRvckNhbGxiYWNrID0gKGZpbGU6IEZpbGUgfCBudWxsIHwgdW5kZWZpbmVkLCBiYXNlNjQ6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpID0+IFByb21pc2U8SW52YWxpZEZpbGVFcnJvciB8IG51bGw+O1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IFwiZWMtZmlsZS11cGxvYWRcIixcclxuICB0ZW1wbGF0ZVVybDogXCIuL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC5zY3NzXCJdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBGaWxlVXBsb2FkQ29tcG9uZW50IGV4dGVuZHMgRm9ybUNvbnRyb2xCYXNlIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xyXG5cclxuICAvLyBzdGF0aWMgY2xhc3MgdG8gY3JlYXRlIHRoZSBmb3JtIGdyb3VwIGZyb20gYSBwYXJlbnQgY29tcG9uZW50XHJcbiAgcHVibGljIHN0YXRpYyBnZXRGb3JtTW9kZWwoXHJcbiAgICB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdLFxyXG4gICAgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZSxcclxuICAgIC8qKiBBbnkgdmFsaWRhdG9ycyByZXF1aXJlZCB0byBtYWtlIHN1cmUgdGhlIHNlbGVjdGVkIGZpbGUgaXMgdmFsaWQuIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgeW91IHVzZSBgRmlsZVVwbG9hZENvbXBvbmVudC5nZXRGaWxlVmFsaWRhdG9yYCB0byBoZWxwIGNvbnN0cnVjdCB0aGUgdmFsaWRhdG9yKHMpLiBOT1RFOiBUaGlzIGN1cnJlbnRseSBvbmx5IHdvcmtzIHdoZW4gbXVsdGlTZWxlY3QgaXMgZmFsc2UuICovXHJcbiAgICBmaWxlVmFsaWRhdG9ycz86IEFzeW5jVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuW11cclxuICApOiBGb3JtR3JvdXA8RmlsZVVwbG9hZEZvcm1Hcm91cD4ge1xyXG4gICAgbGV0IGZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXA8RmlsZVVwbG9hZEZvcm1Hcm91cD4oe1xyXG4gICAgICBmaWxlOiBuZXcgRm9ybUNvbnRyb2woeyB2YWx1ZTogbnVsbCwgZGlzYWJsZWQ6IGRpc2FibGVkIH0sIHt2YWxpZGF0b3JzOiB2YWxpZGF0b3JzLCBhc3luY1ZhbGlkYXRvcnM6IGZpbGVWYWxpZGF0b3JzfSksXHJcbiAgICAgIG5hbWU6IG5ldyBGb3JtQ29udHJvbCh7IHZhbHVlOiBudWxsLCBkaXNhYmxlZDogZGlzYWJsZWQgfSwgdmFsaWRhdG9ycyksXHJcbiAgICAgIGJhc2U2NEZpbGVTdHJpbmc6IG5ldyBGb3JtQ29udHJvbChudWxsKSxcclxuICAgICAgdXBsb2FkUmVzdWx0OiBuZXcgRm9ybUNvbnRyb2wobnVsbCksXHJcbiAgICB9KTtcclxuICAgIGlmIChkaXNhYmxlZCkge1xyXG4gICAgICBmb3JtR3JvdXAuZGlzYWJsZSgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZvcm1Hcm91cDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYW4gYXN5bmMgdmFsaWRhdG9yIHRvIGJlIHVzZWQgd2l0aCB0aGUgZmlsZSB1cGxvYWQgY29udHJvbC5cclxuICAgKiBUaGlzIGlzIHVzZWZ1bCBmb3Igd2hlbiB0aGUgZmlsZSBuZWVkcyB0byBiZSB2YWxpZGF0ZWQgYmVmb3JlIGl0IGNhbiBiZSB1cGxvYWRlZC5cclxuICAgKiBcclxuICAgKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgdG8gdmFsaWRhdGUgdGhlIGZpbGUuIFBhcmFtZXRlcnMgZm9yIHRoZSBjYWxsYmFjayBhcmUgdGhlIGZpbGUgYW5kIHRoZSBiYXNlNjQgc3RyaW5nIGZvciB0aGUgZmlsZS5cclxuICAgKiBiYXNlNjQgaXMgbnVsbCBpZiB0aGUgZmlsZU91dHB1dCBpbnB1dCBvbiB0aGUgRmlsZVVwbG9hZENvbXBvbmVudCBpcyBzZXQgdG8gcmF3LiBVc2luZyBmaWxlT3V0cHV0IHNldCB0byBiYXNlNjQgaXMgcmVjb21tZW5kZWQgZm9yIGltYWdlcy5cclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIGdldEZpbGVWYWxpZGF0b3IoY2FsbGJhY2s6IEZpbGVWYWxpZGF0b3JDYWxsYmFjayk6IEFzeW5jVmFsaWRhdG9yRm4ge1xyXG4gICAgcmV0dXJuIGFzeW5jIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IHtcclxuICAgICAgaWYgKGNvbnRyb2wudmFsdWUgJiYgY29udHJvbC5wYXJlbnQpIHtcclxuICAgICAgICBsZXQgZmlsZSA9IGNvbnRyb2wudmFsdWUgYXMgRmlsZTtcclxuICAgICAgICAvLyBGb3IgaW1hZ2VzLCB3ZSBuZWVkIHRoZSBiYXNlNjQgc3RyaW5nIHRvIHZhbGlkYXRlIGltYWdlIGRpbWVuc2lvbnNcclxuICAgICAgICBsZXQgYmFzZTY0ID0gY29udHJvbC5wYXJlbnQuZ2V0KCdiYXNlNjRGaWxlU3RyaW5nJyk/LnZhbHVlIGFzIHN0cmluZztcclxuICAgICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soZmlsZSwgYmFzZTY0KTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBmb3JtTW9kZWwhOiBGb3JtR3JvdXA8RmlsZVVwbG9hZEZvcm1Hcm91cD47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSB2YWx1ZSBvZiB0aGUgdGV4dGJveCBpbnB1dCdzIHBsYWNlaG9sZGVyXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIHBsYWNlaG9sZGVyPzogc3RyaW5nID0gXCJDaG9vc2UgZmlsZS4uLlwiO1xyXG5cclxuICAvKiogQ29tbW9uIGV4dGVuc2lvbnMgZm9yIGEgZmlsZSBicm93c2luZyBkaWFsb2dcclxuICAgKiAgTm90ZTogRWRnZSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBhY2NlcHQgYXR0cmlidXRlIG9uIGZpbGUgaW5wdXRzLCB0aGVyZWZvciBhbGwgZmlsZSB0eXBlc1xyXG4gICAqICAgICAgICB3aWxsIGJlIHNob3duLiAgRmlyZWZveCBhbmQgQ2hyb21lIGJvdGggc3VwcG9ydCB0aGlzIGZlYXR1cmUuXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGZpbGVUeXBlPzogRmlsZVR5cGUgfCB1bmRlZmluZWQ7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpbGUgb3V0cHV0LCBkZXRlcm1pbmVzIHdoaWNoIHByb3BlcnRpZXMgYXJlIHN1cHBsaWVkIG9uIHRoZSBmb3JtTW9kZWxcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZmlsZU91dHB1dD86IEZpbGVPdXRwdXQgPSAnYmFzZTY0JztcclxuXHJcbiAgLyoqIElmIGZpbGVUeXBlIGlzIHNldCB0byBjdXN0b20gc2V0IHRoZSBhY2NlcHRhYmxlIGZpbGUgdHlwZXMgYmFzZWQgb24gdGhlIGN1c3RvbSBhcnJheSAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBjdXN0b21FeHRlbnNpb25zPzogQXJyYXk8c3RyaW5nPiB8IHVuZGVmaW5lZDtcclxuXHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWwgY2FsbGJhY2sgc3VwcG9ydGVkIGlmIHRoZSBob3N0aW5nIHBhZ2UgbmVlZHMgdG8gcHJvY2VzcyB0aGUgZmlsZSBiZWZvcmVcclxuICAgKiBzZXR0aW5nIHRoZSBmb3JtTW9kZWwgd2l0aCB0aGUgZmlsZSBpbmZvcm1hdGlvbi4gSWYgdGhlIHByb21pc2UgcmVzb2x2ZXMgaXQgd2lsbCBjb250aW51ZVxyXG4gICAqIGFuZCBzZXQgdGhlIGZpbGUgbmFtZSBhbmQgY29udGVudHMgdG8gdGhlIGZvcm1Nb2RlbCwgb3RoZXJ3aXNlIG9uIGZhaWx1cmUgaXQnbGwgZG8gbm90aGluZy5cclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgb25GaWxlU2VsZWN0ZWQ/OiAoZmlsZTogRmlsZSkgPT4gUHJvbWlzZTxhbnk+O1xyXG5cclxuICAvKipcclxuICAgKiBPcHRpb25hbCBjYWxsYmFjayBzdXBwb3J0ZWQgZm9yIHdoZW4gdGhlIGhvc3RpbmcgcGFnZSBuZWVkcyB0byBwcm9jZXNzIG11bHRpcGxlIGZpbGVzXHJcbiAgICogV2Ugc2ltcGx5IG1hcCB0aGUgRmlsZUxpc3QgdG8gYW4gYXJyYXkgb2YgRmlsZSBvYmplY3RzIGFuZCBwYXNzIHRoYXQgYXJyYXkgdG8gdGhlIFxyXG4gICAqIGNhbGxiYWNrIGFuZCBsZXQgdGhlIGhvc3RpbmcgcGFnZSBoYW5kbGUgdGhlIHByb2Nlc3NpbmdcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgb25NdWx0aXBsZUZpbGVzU2VsZWN0ZWQ/OiAoZmlsZXM6IEZpbGVbXSkgPT4gUHJvbWlzZTxhbnk+O1xyXG5cclxuICAvKiogXHJcbiAgICogT3B0aW9uYWwgZGlzcGxheSB0eXBlIHRoYXQgY29udHJvbHMgd2hldGhlciB0aGUgZmlsZSBpbnB1dCB0ZXh0Ym94IGlzIGRpc3BsYXllZCBvclxyXG4gICAqIHNpbXBseSBhIGJ1dHRvbiB0aGUgdXNlciBjbGlja3MgdG8gbGF1bmNoIHRoZSBPUyBmaWxlIHN0b3JhZ2UgZGlhbG9nLlxyXG4gICAqIERlZmF1bHQ6IGZpbGVcclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZGlzcGxheVR5cGU/OiAnZmlsZScgfCAnYnV0dG9uJyA9ICdmaWxlJztcclxuXHJcbiAgLyoqIFxyXG4gICAqIFdoZW4gZGlzcGxheSB0eXBlIGlzIHNldCB0byBidXR0b24gdGhpcyBwcm9wZXJ0eSB3aWxsIGNvbnRyb2wgdGhlIGJ1dHRvbiBsYWJlbFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBidXR0b25MYWJlbD86IHN0cmluZztcclxuXHJcbiAgLyoqIFxyXG4gICAqIFdoZW4gZGlzcGxheSB0eXBlIGlzIHNldCB0byBidXR0b24gdGhpcyBwcm9wZXJ0eSB3aWxsIGNvbnRyb2wgdGhlIGJ1dHRvbiB0eXBlXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGJ1dHRvblR5cGU/OiBzdHJpbmcgPSAncHJpbWFyeSc7XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIHByb3BlcnR5IHRvIGNvbnRyb2wgd2hldGhlciB0aGUgdXNlciBjYW4gc2VsZWN0IG11bHRpcGxlIGZpbGVzXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIG11bHRpU2VsZWN0PzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBAVmlld0NoaWxkKFwiZmlsZUlucHV0XCIsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBmaWxlSW5wdXQ/OiBFbGVtZW50UmVmO1xyXG5cclxuICAvKiogUHJvcGVydHkgYm91bmQgdG8gdGhlIGZpbGUgaW5wdXQgdG8gZmlsdGVyIHdoYXQgZmlsZSB0eXBlcyBhcmUgc2hvd24gaW4gdGhlIGRpYWxvZyAqL1xyXG4gIHB1YmxpYyBmaWxlVHlwZUFjY2VwdDogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByb3RlY3RlZCB2YWxpZGF0aW9uTWVzc2FnZVNlcnZpY2U6IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSxcclxuICAgIHByb3RlY3RlZCBmb3JtR3JvdXBIZWxwZXI6IEZvcm1Hcm91cEhlbHBlcixcclxuICApIHtcclxuICAgIHN1cGVyKHZhbGlkYXRpb25NZXNzYWdlU2VydmljZSwgZm9ybUdyb3VwSGVscGVyKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZUZpbGVUeXBlQWNjZXB0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xyXG5cclxuICAgIC8vIFdhdGNoIGZvciBuYW1lIHRvIGNoYW5nZSwgaWYgdGhlIHZhbHVlIGlzIGNsZWFyZWQgd2Ugd2lsbCBjbGVhciB0aGUgb3RoZXJcclxuICAgIC8vIHN1cHBvcnRpbmcgbW9kZWwgcHJvcGVydGllcy4gVGhlIG5hbWUgY2FuIGJlIGNsZWFyZWQgYnkgdGhlIHVzZXIgbWFudWFsbHkgb3IgdmlhXHJcbiAgICAvLyB0aGUgY2xlYXIgYnV0dG9uXHJcbiAgICB0aGlzLmZvcm1Nb2RlbD8uZ2V0KCduYW1lJyk/LnZhbHVlQ2hhbmdlcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95ZWQpXHJcbiAgICApLnN1YnNjcmliZSh2YWx1ZSA9PiB7XHJcbiAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHtcclxuICAgICAgICAgIGZpbGU6IG51bGwsXHJcbiAgICAgICAgICBiYXNlNjRGaWxlU3RyaW5nOiBudWxsLFxyXG4gICAgICAgICAgdXBsb2FkUmVzdWx0OiBudWxsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIFN5bmMgZXJyb3JzIGZyb20gdGhlIGZpbGUgY29udHJvbCB0byB0aGUgbmFtZSBjb250cm9sIHdoZW5ldmVyIHRoZSBmaWxlIGNvbnRyb2wgc3RhdHVzIGNoYW5nZXMuXHJcbiAgICAvLyBUaGUgbmFtZSBjb250cm9sIGlzIHRoZSBvbmx5IG9uZSBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIgc28gd2UgbmVlZCB0byBzaG93IHRoZSBlcnJvcnMgdGhlcmUuXHJcbiAgICB0aGlzLmZvcm1Nb2RlbC5nZXQoJ2ZpbGUnKT8uc3RhdHVzQ2hhbmdlcy5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5jb21wb25lbnREZXN0cm95ZWQpXHJcbiAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGVycm9ycyA9IHRoaXMuZm9ybU1vZGVsLmdldCgnZmlsZScpPy5lcnJvcnMgPz8gbnVsbDtcclxuICAgICAgdGhpcy5mb3JtTW9kZWwuZ2V0KCduYW1lJyk/LnNldEVycm9ycyhlcnJvcnMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYXN5bmMgZmlsZUNoYW5nZShmaWxlczogRmlsZUxpc3QpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLm11bHRpU2VsZWN0KSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlTXVsdGlwbGVGaWxlcyhmaWxlcyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBmaWxlOiBGaWxlIHwgbnVsbCA9IGZpbGVzLml0ZW0oMCk7XHJcbiAgICAgIGlmIChmaWxlKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5yZWFkRmlsZShmaWxlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENsZWFyIHRoZSBmaWxlIGlucHV0cyB2YWx1ZSwgdGhpcyB3aWxsIGFsbG93IHRoZSB1c2VyIHRvIHBpY2sgdGhlIHNhbWUgZmlsZW5hbWVzIGFnYWluXHJcbiAgICAvLyBhbmQgY2F1c2UgZmlsZUNoYW5nZSB0byByZS10cmlnZ2VyLlxyXG4gICAgaWYgKHRoaXMuZmlsZUlucHV0KSB7XHJcbiAgICAgIHRoaXMuZmlsZUlucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyB0aGUgZmlsZSB0eXBlIGFuZCB1cGRhdGVzIHRoZSBmaWxlIHR5cGUgYWNjZXB0IHByb3BlcnR5LiBUaGlzIGlzIHdoYXQgZGV0ZXJtaW5lcyB0aGUgZmlsZVxyXG4gICAqIHR5cGUgY2hvaWNlcyB0aGF0IHRoZSB1c2VyIHdpbGwgYmUgbGltaXRlZCB0byBpbiB0aGUgZmlsZSBicm93c2UgZGlhbG9nXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB1cGRhdGVGaWxlVHlwZUFjY2VwdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmZpbGVUeXBlKSB7XHJcbiAgICAgIGlmICh0aGlzLmZpbGVUeXBlICE9PSBcImN1c3RvbVwiKSB7XHJcbiAgICAgICAgdGhpcy5maWxlVHlwZUFjY2VwdCA9IEZpbGVUeXBlRXh0ZW5zaW9uc1t0aGlzLmZpbGVUeXBlXS5qb2luKFwiLFwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAodGhpcy5jdXN0b21FeHRlbnNpb25zKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbGVUeXBlQWNjZXB0ID0gdGhpcy5jdXN0b21FeHRlbnNpb25zLmpvaW4oXCIsXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGFrZSBhIGZpbGUgdGhhdCB3YXMgc2VsZWN0ZWQgYnkgdGhlIHVzZXIgYW5kIHByb2Nlc3MvcGF0Y2ggb3VyIGZvcm0gbW9kZWxcclxuICAgKiBJZiB0aGUgaG9zdCBjb21wb25lbnQgcmVxdWlyZXMgYW4gYWN0aW9uIHRvIG9jY3VyIHdpdGggdGhlIGZpbGUgcHJpb3IgdG8gdGhlIHBhdGNoIGl0IHdpbGwgY2FsbFxyXG4gICAqIGFuZCB3YWl0IGZvciBpdCB0byByZXR1cm4uXHJcbiAgICogQHBhcmFtIGZpbGUgXHJcbiAgICogQHBhcmFtIGJhc2U2NEZpbGVTdHJpbmcgT3B0aW9uYWw6IFdpbGwgaGF2ZSBhIHZhbHVlIHByb3ZpZGVkIGlmIHRoZSBmaWxlT3V0cHV0IGlzIHNldCB0byBiYXNlNjRcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NGaWxlKGZpbGU6IEZpbGUsIGJhc2U2NEZpbGVTdHJpbmc6IHN0cmluZyB8IG51bGwgPSBudWxsKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBJZiB3ZSBoYXZlIGFzeW5jIHZhbGlkYXRvcnMgb24gdGhlIGZpbGUgY29udHJvbCB3ZSBuZWVkIHRvIGRvIHZhbGlkYXRpb24gYmVmb3JlIHdlIHRyaWdnZXIgdGhlIHVwbG9hZFxyXG4gICAgY29uc3QgdmFsaWRhdGVCZWZvcmVVcGxvYWQgPSAhIXRoaXMuZm9ybU1vZGVsLmNvbnRyb2xzLmZpbGUuYXN5bmNWYWxpZGF0b3I7XHJcbiAgICBpZiAodmFsaWRhdGVCZWZvcmVVcGxvYWQpIHtcclxuICAgICAgYXdhaXQgdGhpcy52YWxpZGF0ZUZpbGUoZmlsZSwgYmFzZTY0RmlsZVN0cmluZyk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGlmICh0aGlzLm9uRmlsZVNlbGVjdGVkKSB7XHJcbiAgICAgIC8vIE9ubHkgY2FsbCB0aGUgb25GaWxlU2VsZWN0ZWQgY2FsbGJhY2sgdG8gdXBsb2FkIHRoZSBmaWxlIGlmIHRoZSBmb3JtIGdyb3VwIGlzIHZhbGlkXHJcbiAgICAgIGlmICh0aGlzLmZvcm1Nb2RlbC52YWxpZCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5vbkZpbGVTZWxlY3RlZChmaWxlKTtcclxuICBcclxuICAgICAgICAgIC8vIElmIHdlIGRpZCB2YWxpZGF0aW9uLCBqdXN0IHBhdGNoIHRoZSBmb3JtIHJlc3VsdCBiZWNhdXNlIHRoZSBmaWxlIGlzIGFscmVhZHkgaW4gdGhlIGZvcm1cclxuICAgICAgICAgIGlmICh2YWxpZGF0ZUJlZm9yZVVwbG9hZCkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHsgdXBsb2FkUmVzdWx0OiByZXN1bHQgPz8gbnVsbCB9KTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybU1vZGVsLnBhdGNoVmFsdWUoeyBmaWxlLCBuYW1lOiBmaWxlLm5hbWUsIGJhc2U2NEZpbGVTdHJpbmcsIHVwbG9hZFJlc3VsdDogcmVzdWx0ID8/IG51bGwgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgLy8gQnVtbWVyLCB3ZSdyZSBub3QgZ29pbmcgdG8gZG8gYW55dGhpbmcgYWJvdXQgaXQgdGhvdWdoLlxyXG4gICAgICAgICAgLy8gV2UgYXJlIG5vdCBwYXRjaGluZyBhbnkgb2YgdGhlIHJlc3VsdCBzbyBhbnkgZXhpc3RpbmcgaW5mb3JtYXRpb24gcmVtYWluc1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbiBvbkZpbGVTZWxlY3RlZCBjYWxsYmFjayB3ZSBqdXN0IHBhdGNoIHRoZSBmb3JtIG1vZGVsLlxyXG4gICAgLy8gSW4gdGhlIGNhc2Ugb2YgcHJlLXVwbG9hZCB2YWxpZGF0aW9uIHRoZSBmb3JtIGFscmVhZHkgaGFzIHRoZSBmaWxlIHNvIHdlIGRvbid0IHdhbnQgdG8gcGF0Y2ggYWdhaW4uXHJcbiAgICB9IGVsc2UgaWYgKCF2YWxpZGF0ZUJlZm9yZVVwbG9hZCkge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHsgZmlsZSwgbmFtZTogZmlsZS5uYW1lLCBiYXNlNjRGaWxlU3RyaW5nLCB1cGxvYWRSZXN1bHQ6IG51bGwgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogUGF0Y2hlcyB0aGUgZm9ybSB3aXRoIHRoZSBzZWxlY3RlZCBmaWxlIGluIG9yZGVyIHRvIHRyaWdnZXIgY29udHJvbCB2YWxpZGF0aW9uICovXHJcbiAgcHJpdmF0ZSBhc3luYyB2YWxpZGF0ZUZpbGUoZmlsZTogRmlsZSwgYmFzZTY0RmlsZVN0cmluZzogc3RyaW5nIHwgbnVsbCA9IG51bGwpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIC8vIFBhdGNoIHRoZSBmaWxlIGZpcnN0IHRvIHRyaWdnZXIgYW55IGZpbGUgdmFsaWRhdG9yc1xyXG4gICAgdGhpcy5mb3JtTW9kZWwucGF0Y2hWYWx1ZSh7IGZpbGUsIG5hbWU6IGZpbGUubmFtZSwgYmFzZTY0RmlsZVN0cmluZywgdXBsb2FkUmVzdWx0OiBudWxsIH0pO1xyXG5cclxuICAgIC8vIElmIHdlIGhhdmUgYW55IGFzeW5jIHZhbGlkYXRvcnMgcGVuZGluZyB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZW0gdG8gY29tcGxldGUgYmVmb3JlIHdlIGtub3cgaWYgdGhlIGZvcm0gaXMgdmFsaWRcclxuICAgIGlmICh0aGlzLmZvcm1Nb2RlbC5wZW5kaW5nKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuZm9ybU1vZGVsLnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgICBmaWx0ZXIoc3RhdHVzID0+IHN0YXR1cyAhPT0gJ1BFTkRJTkcnKSxcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICAgKS50b1Byb21pc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBNYXJrIHRoZSBuYW1lIGNvbnRyb2wgYXMgdG91Y2hlZCBzbyB0aGF0IGFueSB2YWxpZGF0aW9uIGVycm9ycyB3aWxsIHNob3dcclxuICAgIHRoaXMuZm9ybU1vZGVsLmNvbnRyb2xzLm5hbWUubWFya0FzVG91Y2hlZCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQmFzZWQgb24gdGhlIGZpbGVPdXRwdXQgcmV0dXJuIHdoZXRoZXIgdGhpcyBjb21wb25lbnQgaXMgZXhwZWN0ZWQgdG8gZGVsaXZlciBhIGJhc2U2NCBvdXRwdXRcclxuICAgKiBAcmV0dXJucyBcclxuICAgKi9cclxuICBwcml2YXRlIGlzQmFzZTY0RmlsZU91dHB1dCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVPdXRwdXQgPT09ICdiYXNlNjQnO1xyXG4gIH1cclxuXHJcbiAgLyoqIE1hcHMgdGhlIGZpbGVzIHRvIGFuIGFycmF5IG9mIEZpbGUgb2JqZWN0cyBhbmQgc2VuZHMgdGhlbSBhbG9uZ1xyXG4gICAqIHRvIHRoZSBkZXJpdmVkIG9uTXVsdGlwbGVGaWxlU2VsZWN0ZWQgbWV0aG9kIGluIHRoZSBob3N0aW5nIGNvbXBvbmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlTXVsdGlwbGVGaWxlcyhmaWxlczogRmlsZUxpc3QpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGZpbGVzQXJyYXkgPSBBcnJheS5mcm9tKGZpbGVzKTtcclxuXHJcbiAgICBpZiAodGhpcy5vbk11bHRpcGxlRmlsZXNTZWxlY3RlZCkge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLm9uTXVsdGlwbGVGaWxlc1NlbGVjdGVkKGZpbGVzQXJyYXkpO1xyXG4gICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yOiAnLCBlKTtcclxuICAgICAgfSAgXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBhc3luYyByZWFkRmlsZShmaWxlOiBGaWxlKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCByZWFkZXI6IEZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xyXG5cclxuICAgIHJlYWRlci5vbmxvYWRlbmQgPSBhc3luYyBlID0+IHtcclxuICAgICAgbGV0IGJhc2U2NEZpbGVTdHJpbmc6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHJlYWRlcj8ucmVzdWx0Py50b1N0cmluZygpLnNwbGl0KFwiLFwiKVsxXTtcclxuICAgICAgYXdhaXQgdGhpcy5wcm9jZXNzRmlsZShmaWxlLCBiYXNlNjRGaWxlU3RyaW5nKTtcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMuaXNCYXNlNjRGaWxlT3V0cHV0KCkpIHtcclxuICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBhd2FpdCB0aGlzLnByb2Nlc3NGaWxlKGZpbGUpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZWMtZm9ybS1ncm91cCBbbGFiZWxdPVwibGFiZWxcIlxyXG4gICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZvcm1Nb2RlbFwiXHJcbiAgICAgICAgICAgICAgIFtoZWxwUG9wb3Zlcl09XCJoZWxwUG9wb3ZlclwiXHJcbiAgICAgICAgICAgICAgIFtoZWxwUG9wb3ZlclBvc2l0aW9uXT1cImhlbHBQb3BvdmVyUG9zaXRpb25cIlxyXG4gICAgICAgICAgICAgICBjbGFzcz1cIm1iLTBcIj5cclxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGNvbnRyb2wtZ3JvdXBcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1ncm93IHBvc2l0aW9uLXJlbGF0aXZlXCI+XHJcbiAgICAgIDxpbnB1dCAjZmlsZUlucHV0XHJcbiAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2lucHV0XCJcclxuICAgICAgICAgICAgIHR5cGU9XCJmaWxlXCJcclxuICAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIlxyXG4gICAgICAgICAgICAgW2F0dHIuYWNjZXB0XT1cImZpbGVUeXBlQWNjZXB0XCJcclxuICAgICAgICAgICAgIChjaGFuZ2UpPVwiZmlsZUNoYW5nZSgkZXZlbnQudGFyZ2V0LmZpbGVzKVwiXHJcbiAgICAgICAgICAgICBbY2xhc3MuaGFzLXZhbHVlXT1cImRpc3BsYXlUeXBlID09PSAnZmlsZScgPyBmb3JtTW9kZWw/LmdldCgnbmFtZScpLnZhbHVlIDogdW5kZWZpbmVkXCJcclxuICAgICAgICAgICAgIFthdHRyLm11bHRpcGxlXT1cIm11bHRpU2VsZWN0ID8gJ211bHRpcGxlJyA6IHVuZGVmaW5lZFwiPlxyXG4gICAgICA8ZWMtZm9ybS1jb250cm9sICpuZ0lmPVwiZGlzcGxheVR5cGUgPT09ICdmaWxlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJ7e2lucHV0SWR9fV9mb3JtQ29udHJvbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgIFtwZW5kaW5nXT1cInBlbmRpbmcgfHwgZm9ybU1vZGVsPy5wZW5kaW5nXCI+XHJcbiAgICAgICAgPGlucHV0IGlkPVwie3tpbnB1dElkfX1fbmFtZVwiXHJcbiAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtTW9kZWw/LmdldCgnbmFtZScpXCJcclxuICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgICAgICAgICAgICBbdGFiaW5kZXhdPVwiLTFcIj5cclxuICAgICAgPC9lYy1mb3JtLWNvbnRyb2w+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxlYy1idXR0b24gKm5nSWY9XCJkaXNwbGF5VHlwZSA9PT0gJ2ZpbGUnXCJcclxuICAgICAgICAgICAgICAgI2Jyb3dzZUJ0blxyXG4gICAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2Jyb3dzZUJ0blwiXHJcbiAgICAgICAgICAgICAgIChjbGlja2VkKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAgICAgICAgICAgICAgdHlwZT1cInNlY29uZGFyeVwiXHJcbiAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXHJcbiAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmb3JtTW9kZWw/LmdldCgnbmFtZScpLmRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAgbGFiZWw9XCJCcm93c2VcIlxyXG4gICAgICAgICAgICAgICBbYXV0b2ZvY3VzXT1cImF1dG9mb2N1c1wiPlxyXG4gICAgPC9lYy1idXR0b24+XHJcbiAgPC9kaXY+XHJcbiAgPGVjLWJ1dHRvbiAqbmdJZj1cImRpc3BsYXlUeXBlID09PSAnYnV0dG9uJ1wiXHJcbiAgICAgICAgICAgICBpZD1cInt7aW5wdXRJZH19X2J0blwiXHJcbiAgICAgICAgICAgICBbcGVuZGluZ109XCJwZW5kaW5nXCJcclxuICAgICAgICAgICAgIFt0eXBlXT1cImJ1dHRvblR5cGVcIlxyXG4gICAgICAgICAgICAgW2xhYmVsXT1cImJ1dHRvbkxhYmVsID8/ICdCcm93c2VfVEMnIHwgdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgIChjbGlja2VkKT1cImZpbGVJbnB1dC5jbGljaygpXCJcclxuICAgICAgICAgICAgIHN0eWxlPVwid2lkdGg6IDEwMCU7XCI+XHJcbiAgPC9lYy1idXR0b24+XHJcbjwvZWMtZm9ybS1ncm91cD4iXX0=
@@ -4135,7 +4135,9 @@ const FileTypeExtensions = {
4135
4135
  };
4136
4136
  class FileUploadComponent extends FormControlBase {
4137
4137
  // static class to create the form group from a parent component
4138
- static getFormModel(validators, disabled = false, fileValidators) {
4138
+ static getFormModel(validators, disabled = false,
4139
+ /** Any validators required to make sure the selected file is valid. It is recommended that you use `FileUploadComponent.getFileValidator` to help construct the validator(s). NOTE: This currently only works when multiSelect is false. */
4140
+ fileValidators) {
4139
4141
  let formGroup = new FormGroup({
4140
4142
  file: new FormControl({ value: null, disabled: disabled }, { validators: validators, asyncValidators: fileValidators }),
4141
4143
  name: new FormControl({ value: null, disabled: disabled }, validators),
@@ -4147,11 +4149,19 @@ class FileUploadComponent extends FormControlBase {
4147
4149
  }
4148
4150
  return formGroup;
4149
4151
  }
4152
+ /**
4153
+ * Helper function that returns an async validator to be used with the file upload control.
4154
+ * This is useful for when the file needs to be validated before it can be uploaded.
4155
+ *
4156
+ * @param callback The callback function that will be called to validate the file. Parameters for the callback are the file and the base64 string for the file.
4157
+ * base64 is null if the fileOutput input on the FileUploadComponent is set to raw. Using fileOutput set to base64 is recommended for images.
4158
+ */
4150
4159
  static getFileValidator(callback) {
4151
4160
  return (control) => __awaiter(this, void 0, void 0, function* () {
4152
4161
  var _a;
4153
4162
  if (control.value && control.parent) {
4154
4163
  let file = control.value;
4164
+ // For images, we need the base64 string to validate image dimensions
4155
4165
  let base64 = (_a = control.parent.get('base64FileString')) === null || _a === void 0 ? void 0 : _a.value;
4156
4166
  return yield callback(file, base64);
4157
4167
  }
@@ -4204,7 +4214,8 @@ class FileUploadComponent extends FormControlBase {
4204
4214
  });
4205
4215
  }
4206
4216
  });
4207
- // Sync errors from the file control to the name control whenever the file control status changes
4217
+ // Sync errors from the file control to the name control whenever the file control status changes.
4218
+ // The name control is the only one displayed to the user so we need to show the errors there.
4208
4219
  (_c = this.formModel.get('file')) === null || _c === void 0 ? void 0 : _c.statusChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(() => {
4209
4220
  var _a, _b, _c;
4210
4221
  const errors = (_b = (_a = this.formModel.get('file')) === null || _a === void 0 ? void 0 : _a.errors) !== null && _b !== void 0 ? _b : null;
@@ -4252,27 +4263,50 @@ class FileUploadComponent extends FormControlBase {
4252
4263
  * @param file
4253
4264
  * @param base64FileString Optional: Will have a value provided if the fileOutput is set to base64
4254
4265
  */
4255
- processFile(file, base64FileString) {
4266
+ processFile(file, base64FileString = null) {
4267
+ return __awaiter(this, void 0, void 0, function* () {
4268
+ // If we have async validators on the file control we need to do validation before we trigger the upload
4269
+ const validateBeforeUpload = !!this.formModel.controls.file.asyncValidator;
4270
+ if (validateBeforeUpload) {
4271
+ yield this.validateFile(file, base64FileString);
4272
+ }
4273
+ if (this.onFileSelected) {
4274
+ // Only call the onFileSelected callback to upload the file if the form group is valid
4275
+ if (this.formModel.valid) {
4276
+ try {
4277
+ let result = yield this.onFileSelected(file);
4278
+ // If we did validation, just patch the form result because the file is already in the form
4279
+ if (validateBeforeUpload) {
4280
+ this.formModel.patchValue({ uploadResult: result !== null && result !== void 0 ? result : null });
4281
+ }
4282
+ else {
4283
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: result !== null && result !== void 0 ? result : null });
4284
+ }
4285
+ }
4286
+ catch (e) {
4287
+ // Bummer, we're not going to do anything about it though.
4288
+ // We are not patching any of the result so any existing information remains
4289
+ }
4290
+ }
4291
+ // If we don't have an onFileSelected callback we just patch the form model.
4292
+ // In the case of pre-upload validation the form already has the file so we don't want to patch again.
4293
+ }
4294
+ else if (!validateBeforeUpload) {
4295
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: null });
4296
+ }
4297
+ });
4298
+ }
4299
+ /** Patches the form with the selected file in order to trigger control validation */
4300
+ validateFile(file, base64FileString = null) {
4256
4301
  return __awaiter(this, void 0, void 0, function* () {
4257
4302
  // Patch the file first to trigger any file validators
4258
- this.patchProcessedFile(file, base64FileString);
4303
+ this.formModel.patchValue({ file, name: file.name, base64FileString, uploadResult: null });
4259
4304
  // If we have any async validators pending we need to wait for them to complete before we know if the form is valid
4260
4305
  if (this.formModel.pending) {
4261
4306
  yield this.formModel.statusChanges.pipe(filter(status => status !== 'PENDING'), take(1), takeUntil(this.componentDestroyed)).toPromise();
4262
4307
  }
4263
4308
  // Mark the name control as touched so that any validation errors will show
4264
4309
  this.formModel.controls.name.markAsTouched();
4265
- // Only call the onFileSelected callback to upload the file if the form is valid
4266
- if (this.onFileSelected && this.formModel.valid) {
4267
- try {
4268
- let result = yield this.onFileSelected(file);
4269
- this.formModel.patchValue({ uploadResult: result !== null && result !== void 0 ? result : null });
4270
- }
4271
- catch (e) {
4272
- // Bummer, we're not going to do anything about it though.
4273
- // We are not patching any of the result so any existing information remains
4274
- }
4275
- }
4276
4310
  });
4277
4311
  }
4278
4312
  /**
@@ -4282,22 +4316,6 @@ class FileUploadComponent extends FormControlBase {
4282
4316
  isBase64FileOutput() {
4283
4317
  return this.fileOutput === 'base64';
4284
4318
  }
4285
- /**
4286
- * When the file was selected and processed patch the file information that the hosting form will
4287
- * be looking for.
4288
- * @param file
4289
- * @param base64FileString
4290
- * @param onFileSelectedResult
4291
- */
4292
- patchProcessedFile(file, base64FileString) {
4293
- var _a;
4294
- (_a = this.formModel) === null || _a === void 0 ? void 0 : _a.patchValue({
4295
- file: file,
4296
- name: file === null || file === void 0 ? void 0 : file.name,
4297
- base64FileString: base64FileString !== null && base64FileString !== void 0 ? base64FileString : null,
4298
- uploadResult: null
4299
- });
4300
- }
4301
4319
  /** Maps the files to an array of File objects and sends them along
4302
4320
  * to the derived onMultipleFileSelected method in the hosting component
4303
4321
  */