@rlucan/ui 14.2.4 → 14.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/action-button/action-button.component.mjs +99 -0
- package/esm2022/lib/action-icon/action-icon.component.mjs +37 -0
- package/esm2022/lib/autocomplete/autocomplete.component.mjs +391 -0
- package/esm2022/lib/avatar/avatar.component.mjs +34 -0
- package/esm2022/lib/button/button.component.mjs +57 -0
- package/esm2022/lib/checkbox/checkbox.component.mjs +39 -0
- package/{esm2020 → esm2022}/lib/checkbox-group/checkbox-group.component.mjs +91 -91
- package/esm2022/lib/currency/currency.component.mjs +151 -0
- package/esm2022/lib/date/date.component.mjs +68 -0
- package/{esm2020 → esm2022}/lib/dialog/dialog.component.mjs +37 -37
- package/esm2022/lib/directives/force-visibility/force-visibility.directive.mjs +104 -0
- package/esm2022/lib/editor/editor.component.mjs +119 -0
- package/{esm2020 → esm2022}/lib/elements/burger/burger.component.mjs +21 -21
- package/{esm2020 → esm2022}/lib/elements/expander/expander.component.mjs +28 -28
- package/{esm2020 → esm2022}/lib/elements/validation-message/validation-message.component.mjs +47 -47
- package/esm2022/lib/file/file.component.mjs +145 -0
- package/esm2022/lib/file-uploader/ui-file-uploader.component.mjs +405 -0
- package/esm2022/lib/input/input.component.mjs +265 -0
- package/esm2022/lib/input-autocomplete/input-autocomplete.component.mjs +277 -0
- package/esm2022/lib/layouts/base/ui-base-layout.component.mjs +22 -0
- package/esm2022/lib/layouts/base/ui-base.component.mjs +74 -0
- package/esm2022/lib/layouts/simple/ui-simple-layout.component.mjs +18 -0
- package/esm2022/lib/layouts/simple/ui-simple.component.mjs +166 -0
- package/{esm2020 → esm2022}/lib/radio/radio.component.mjs +21 -21
- package/esm2022/lib/radio-group/radio-group.component.mjs +53 -0
- package/esm2022/lib/select/select.component.mjs +115 -0
- package/esm2022/lib/services/message-box.service.mjs +149 -0
- package/{esm2020 → esm2022}/lib/services/toast.service.mjs +23 -23
- package/{esm2020 → esm2022}/lib/services/ui-file.service.mjs +71 -71
- package/{esm2020 → esm2022}/lib/services/ui-translate.service.mjs +32 -32
- package/{esm2020 → esm2022}/lib/submit-button/submit-button.component.mjs +72 -72
- package/esm2022/lib/table/table.component.mjs +97 -0
- package/esm2022/lib/text-area/text-area.component.mjs +46 -0
- package/{esm2020 → esm2022}/lib/ui.model.mjs +1 -1
- package/esm2022/lib/ui.module.mjs +269 -0
- package/esm2022/public-api.mjs +35 -0
- package/{esm2020 → esm2022}/rlucan-ui.mjs +4 -4
- package/fesm2022/rlucan-ui.mjs +3442 -0
- package/fesm2022/rlucan-ui.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/action-button/action-button.component.d.ts +32 -33
- package/lib/action-icon/action-icon.component.d.ts +15 -15
- package/lib/autocomplete/autocomplete.component.d.ts +57 -57
- package/lib/avatar/avatar.component.d.ts +14 -14
- package/lib/button/button.component.d.ts +18 -18
- package/lib/checkbox/checkbox.component.d.ts +15 -15
- package/lib/checkbox-group/checkbox-group.component.d.ts +18 -18
- package/lib/currency/currency.component.d.ts +31 -30
- package/lib/date/date.component.d.ts +24 -23
- package/lib/dialog/dialog.component.d.ts +13 -13
- package/lib/directives/force-visibility/force-visibility.directive.d.ts +22 -20
- package/lib/editor/editor.component.d.ts +24 -0
- package/lib/elements/burger/burger.component.d.ts +9 -9
- package/lib/elements/expander/expander.component.d.ts +10 -10
- package/lib/elements/validation-message/validation-message.component.d.ts +12 -12
- package/lib/file/file.component.d.ts +35 -29
- package/lib/file-uploader/ui-file-uploader.component.d.ts +102 -102
- package/lib/input/input.component.d.ts +42 -29
- package/lib/input-autocomplete/input-autocomplete.component.d.ts +44 -0
- package/lib/{base → layouts/base}/ui-base-layout.component.d.ts +8 -8
- package/lib/{base → layouts/base}/ui-base.component.d.ts +23 -23
- package/lib/{simple → layouts/simple}/ui-simple-layout.component.d.ts +8 -7
- package/lib/{simple → layouts/simple}/ui-simple.component.d.ts +40 -39
- package/lib/radio/radio.component.d.ts +8 -8
- package/lib/radio-group/radio-group.component.d.ts +18 -18
- package/lib/select/select.component.d.ts +35 -33
- package/lib/services/message-box.service.d.ts +58 -42
- package/lib/services/toast.service.d.ts +13 -13
- package/lib/services/ui-file.service.d.ts +33 -33
- package/lib/services/ui-translate.service.d.ts +11 -11
- package/lib/submit-button/submit-button.component.d.ts +21 -21
- package/lib/table/table.component.d.ts +36 -36
- package/lib/text-area/text-area.component.d.ts +18 -18
- package/lib/ui.model.d.ts +2 -2
- package/lib/ui.module.d.ts +59 -56
- package/package.json +22 -24
- package/public-api.d.ts +29 -27
- package/scss/ui-defaults.scss +19 -4
- package/src/js/editorjs.mjs +9634 -0
- package/ui.scss +70 -20
- package/esm2020/lib/action-button/action-button.component.mjs +0 -96
- package/esm2020/lib/action-icon/action-icon.component.mjs +0 -37
- package/esm2020/lib/autocomplete/autocomplete.component.mjs +0 -391
- package/esm2020/lib/avatar/avatar.component.mjs +0 -34
- package/esm2020/lib/base/ui-base-layout.component.mjs +0 -22
- package/esm2020/lib/base/ui-base.component.mjs +0 -74
- package/esm2020/lib/button/button.component.mjs +0 -57
- package/esm2020/lib/checkbox/checkbox.component.mjs +0 -39
- package/esm2020/lib/currency/currency.component.mjs +0 -148
- package/esm2020/lib/date/date.component.mjs +0 -64
- package/esm2020/lib/directives/force-visibility/force-visibility.directive.mjs +0 -96
- package/esm2020/lib/file/file.component.mjs +0 -88
- package/esm2020/lib/file-uploader/ui-file-uploader.component.mjs +0 -394
- package/esm2020/lib/input/input.component.mjs +0 -258
- package/esm2020/lib/radio-group/radio-group.component.mjs +0 -53
- package/esm2020/lib/select/select.component.mjs +0 -91
- package/esm2020/lib/services/message-box.service.mjs +0 -113
- package/esm2020/lib/simple/ui-simple-layout.component.mjs +0 -15
- package/esm2020/lib/simple/ui-simple.component.mjs +0 -154
- package/esm2020/lib/table/table.component.mjs +0 -97
- package/esm2020/lib/text-area/text-area.component.mjs +0 -46
- package/esm2020/lib/ui.module.mjs +0 -255
- package/esm2020/public-api.mjs +0 -33
- package/fesm2015/rlucan-ui.mjs +0 -2918
- package/fesm2015/rlucan-ui.mjs.map +0 -1
- package/fesm2020/rlucan-ui.mjs +0 -2886
- package/fesm2020/rlucan-ui.mjs.map +0 -1
|
@@ -1,394 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Host, Inject, Input, Optional, Output, SkipSelf } from '@angular/core';
|
|
2
|
-
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
|
-
import { UI_FILESERVICE } from '../services/ui-file.service';
|
|
4
|
-
import { UiSimpleComponent } from '../simple/ui-simple.component';
|
|
5
|
-
import { UI_TRANSLATESERVICE } from '../services/ui-translate.service';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
import * as i1 from "@angular/forms";
|
|
8
|
-
import * as i2 from "../services/ui-file.service";
|
|
9
|
-
import * as i3 from "@angular/common";
|
|
10
|
-
import * as i4 from "@angular/material/icon";
|
|
11
|
-
import * as i5 from "@angular/material/tooltip";
|
|
12
|
-
import * as i6 from "ngx-uploader";
|
|
13
|
-
import * as i7 from "@angular/material/progress-spinner";
|
|
14
|
-
import * as i8 from "ngx-image-cropper";
|
|
15
|
-
import * as i9 from "../file/file.component";
|
|
16
|
-
export class UiFileUploaderComponent extends UiSimpleComponent {
|
|
17
|
-
constructor(fileServiceConfig, translateService, controlContainer, fileService) {
|
|
18
|
-
super(null, controlContainer);
|
|
19
|
-
this.fileServiceConfig = fileServiceConfig;
|
|
20
|
-
this.translateService = translateService;
|
|
21
|
-
this.controlContainer = controlContainer;
|
|
22
|
-
this.fileService = fileService;
|
|
23
|
-
this.maxFiles = 1;
|
|
24
|
-
this.multiple = true;
|
|
25
|
-
this.crop = false;
|
|
26
|
-
this.cropRounded = false;
|
|
27
|
-
this.fileSize = 'default';
|
|
28
|
-
this.customFileMenu = false;
|
|
29
|
-
this.newFilePosition = 'last';
|
|
30
|
-
this.templates = {};
|
|
31
|
-
this.previewPosition = 'bottom';
|
|
32
|
-
this.imageCropped = new EventEmitter();
|
|
33
|
-
this.fileEvent = new EventEmitter();
|
|
34
|
-
this.uploadOptions = {
|
|
35
|
-
concurrency: this.fileServiceConfig.concurrentUploads
|
|
36
|
-
};
|
|
37
|
-
this.uploading = false;
|
|
38
|
-
this.showCropper = false;
|
|
39
|
-
this.showCropPreview = {};
|
|
40
|
-
this.cropPreviewTimeouts = {};
|
|
41
|
-
this.cropSourceImages = {};
|
|
42
|
-
this.cropperImageLoaded = {};
|
|
43
|
-
this.imagesDone = {};
|
|
44
|
-
this.transform = {};
|
|
45
|
-
this.canvasRotation = {};
|
|
46
|
-
this.refreshAddInput = false;
|
|
47
|
-
this.patchingValues = false;
|
|
48
|
-
this.inputArray = false;
|
|
49
|
-
this.dragging = false;
|
|
50
|
-
this.uploaderId = Math.round(Math.random() * 1000000);
|
|
51
|
-
this.croppedImages = {};
|
|
52
|
-
this.fileService.uploadSubscription.next({ action: 'register', data: this });
|
|
53
|
-
this.fileService.uploadSubscription.subscribe((v) => {
|
|
54
|
-
switch (v.action) {
|
|
55
|
-
case 'uploadStarted':
|
|
56
|
-
this.uploading = true;
|
|
57
|
-
break;
|
|
58
|
-
case 'uploadFailed':
|
|
59
|
-
case 'uploadSuccess':
|
|
60
|
-
setTimeout(() => {
|
|
61
|
-
this.uploading = false;
|
|
62
|
-
});
|
|
63
|
-
this.patchValues();
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
get menuTemplate() {
|
|
68
|
-
return this.templates?.menuTemplate;
|
|
69
|
-
}
|
|
70
|
-
get addFileTemplate() {
|
|
71
|
-
return this.templates?.addFileTemplate;
|
|
72
|
-
}
|
|
73
|
-
get fileTemplate() {
|
|
74
|
-
return this.templates?.fileTemplate;
|
|
75
|
-
}
|
|
76
|
-
get uploadInput() {
|
|
77
|
-
return this.fileService.uploadInput;
|
|
78
|
-
}
|
|
79
|
-
get editable() {
|
|
80
|
-
return this.componentFormControl.enabled;
|
|
81
|
-
}
|
|
82
|
-
get ngAddStyle() {
|
|
83
|
-
return {
|
|
84
|
-
width: this.fileServiceConfig.imageSizes[this.fileSize][0] + 'px',
|
|
85
|
-
height: this.fileServiceConfig.imageSizes[this.fileSize][1] + 'px',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
get aspectRatio() {
|
|
89
|
-
return this.fileServiceConfig.imageSizes[this.fileSize][0] / this.fileServiceConfig.imageSizes[this.fileSize][1];
|
|
90
|
-
}
|
|
91
|
-
get addFileImgSrc() {
|
|
92
|
-
return this.fileServiceConfig.addFileImgSrc;
|
|
93
|
-
}
|
|
94
|
-
cropDone(f) {
|
|
95
|
-
return !f.$newFile || this.imagesDone[f.$newFile.id];
|
|
96
|
-
}
|
|
97
|
-
// ngOnInit(): void {
|
|
98
|
-
// super.ngOnInit();
|
|
99
|
-
// }
|
|
100
|
-
ngOnDestroy() {
|
|
101
|
-
this.fileService.uploadSubscription.next({ action: 'destroy', data: this });
|
|
102
|
-
}
|
|
103
|
-
remove(f) {
|
|
104
|
-
if (f.$newFile) {
|
|
105
|
-
this.uploadInput.emit({ type: 'remove', id: f.$newFile.id });
|
|
106
|
-
}
|
|
107
|
-
this.files.splice(this.files.indexOf(f), 1);
|
|
108
|
-
this.prepareResponse();
|
|
109
|
-
// this.onChange(this.inputArray ? this.files : (this.files.length > 0 ? this.files[0] : null));
|
|
110
|
-
this.fileEvent.emit({ message: 'fileRemoved', data: f });
|
|
111
|
-
// this.patchValues();
|
|
112
|
-
}
|
|
113
|
-
patchValues() {
|
|
114
|
-
this.patchingValues = true;
|
|
115
|
-
// if (this.inputArray) {
|
|
116
|
-
// this.componentFormControl.setValue(this.files.map(f => f.custom));
|
|
117
|
-
// } else {
|
|
118
|
-
// this.componentFormControl.setValue(this.files.length === 0 ? null : this.files[0].custom);
|
|
119
|
-
// }
|
|
120
|
-
this.patchingValues = false;
|
|
121
|
-
}
|
|
122
|
-
get hasFilesToUpload() {
|
|
123
|
-
return !!this.files.find(f => f.$newFile && f.$newFile.progress.status !== 2);
|
|
124
|
-
}
|
|
125
|
-
canImagePreview(type) {
|
|
126
|
-
return type.startsWith('image/') || type.startsWith('video/');
|
|
127
|
-
}
|
|
128
|
-
onUploadOutput($event, skipCustomValidation = false) {
|
|
129
|
-
// console.log($event);
|
|
130
|
-
switch ($event.type) {
|
|
131
|
-
case 'start':
|
|
132
|
-
break;
|
|
133
|
-
case 'dragOver':
|
|
134
|
-
this.dragging = true;
|
|
135
|
-
break;
|
|
136
|
-
case 'dragOut':
|
|
137
|
-
case 'drop':
|
|
138
|
-
this.dragging = false;
|
|
139
|
-
break;
|
|
140
|
-
case 'addedToQueue':
|
|
141
|
-
if (this.crop && !$event.file.type.startsWith('image/')) {
|
|
142
|
-
this.uploadInput.emit({ type: 'remove', id: $event.file.id });
|
|
143
|
-
this.fileEvent.emit({ message: 'cropInvalidFileType', data: $event.file });
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (!skipCustomValidation && this.fileServiceConfig.fileValidation) {
|
|
147
|
-
this.fileServiceConfig.fileValidation(this.fileSize, $event.file).then(valid => {
|
|
148
|
-
if (valid) {
|
|
149
|
-
this.onUploadOutput($event, true);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
this.uploadInput.emit({ type: 'remove', id: $event.file.id });
|
|
153
|
-
// this.fileEvent.emit({ message: 'cropInvalidFileType', data: $event.file });
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
let f;
|
|
159
|
-
if (this.changeFileIndex !== undefined) {
|
|
160
|
-
f = this.files[this.changeFileIndex];
|
|
161
|
-
if (f.$newFile) {
|
|
162
|
-
this.uploadInput.emit({ type: 'remove', id: f.$newFile.id });
|
|
163
|
-
}
|
|
164
|
-
f.$newFile = $event.file;
|
|
165
|
-
f.custom = $event.file;
|
|
166
|
-
this.changeFileIndex = undefined;
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
f = { custom: $event.file, $newFile: $event.file };
|
|
170
|
-
if (this.newFilePosition === 'last') {
|
|
171
|
-
this.files.push(f);
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
this.files.unshift(f);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (this.canImagePreview($event.file.type)) {
|
|
178
|
-
if (this.crop) {
|
|
179
|
-
this.canvasRotation[$event.file.id] = 0;
|
|
180
|
-
this.cropSourceImages[$event.file.id] = $event.file.nativeFile;
|
|
181
|
-
this.cropperImageLoaded[$event.file.id] = false;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
this.prepareResponse();
|
|
185
|
-
this.fileEvent.emit({ message: 'fileAdded', data: f });
|
|
186
|
-
}
|
|
187
|
-
break;
|
|
188
|
-
case 'done':
|
|
189
|
-
const df = this.files.find(f => f.$newFile === $event.file);
|
|
190
|
-
if (df) {
|
|
191
|
-
if (df.$newFile.responseStatus === 200) {
|
|
192
|
-
this.files[this.files.indexOf(df)].custom = df.$newFile.response;
|
|
193
|
-
df.$newFile = null;
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
// console.log('error on upload', df.$event);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (!this.hasFilesToUpload) {
|
|
200
|
-
this.prepareResponse(false);
|
|
201
|
-
this.fileService.uploadSubscription.next({
|
|
202
|
-
action: this.files.find(f => !!f.$newFile) ? 'uploadControlFailed' : 'uploadControlSuccess'
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
prepareResponse(doemit = true) {
|
|
209
|
-
if (this.inputArray) {
|
|
210
|
-
if (!this.responseFiles) {
|
|
211
|
-
this.responseFiles = [];
|
|
212
|
-
}
|
|
213
|
-
this.responseFiles.length = 0;
|
|
214
|
-
this.files.forEach(f => this.responseFiles.push({ ...f.custom, $newFile: f.$newFile }));
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
if (this.files.length === 0) {
|
|
218
|
-
this.responseFiles = null;
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
if (!this.responseFiles) {
|
|
222
|
-
this.responseFiles = {};
|
|
223
|
-
}
|
|
224
|
-
Object.keys(this.files[0].custom).forEach(k => {
|
|
225
|
-
this.responseFiles[k] = this.files[0].custom[k];
|
|
226
|
-
});
|
|
227
|
-
this.responseFiles.$newFile = this.files[0].$newFile;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if (doemit) {
|
|
231
|
-
this.onChange(this.responseFiles);
|
|
232
|
-
}
|
|
233
|
-
// console.log('emit', this.files[1], { ...this.files[1].custom, $newFile: this.files[1].$newFile });
|
|
234
|
-
// this.onChange(this.inputArray ?
|
|
235
|
-
// this.files.map(f => ({ ...f.custom, $newFile: f.$newFile})) :
|
|
236
|
-
// (this.files.length > 0 ? { ...this.files[0].custom, $newFile: this.files[0].$newFile } : null));
|
|
237
|
-
// this.onChange(this.inputArray ?
|
|
238
|
-
// this.files :
|
|
239
|
-
// (this.files.length > 0 ? this.files[0] : null));
|
|
240
|
-
}
|
|
241
|
-
beforeSave() {
|
|
242
|
-
return new Promise((res, rej) => {
|
|
243
|
-
this.files.forEach(f => {
|
|
244
|
-
if (f.$newFile && f.$newFile.progress.status === 2) {
|
|
245
|
-
f.$newFile.progress.status = 0;
|
|
246
|
-
}
|
|
247
|
-
if (this.crop && f.$newFile && !this.imagesDone[f.$newFile.id]) {
|
|
248
|
-
this.cropperDone(f.$newFile.id);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
setTimeout(() => {
|
|
252
|
-
res('done');
|
|
253
|
-
}, 250);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
fileChangeEvent(event, f) {
|
|
257
|
-
this.changeFileIndex = this.files.indexOf(f);
|
|
258
|
-
}
|
|
259
|
-
startCropPreview(id) {
|
|
260
|
-
clearTimeout(this.cropPreviewTimeouts[id]);
|
|
261
|
-
this.showCropPreview[id] = !!this.cropSourceImages[id];
|
|
262
|
-
}
|
|
263
|
-
stopCropPreview(id) {
|
|
264
|
-
this.cropPreviewTimeouts[id] = setTimeout(() => {
|
|
265
|
-
this.showCropPreview[id] = false;
|
|
266
|
-
}, 250);
|
|
267
|
-
}
|
|
268
|
-
zoomCroppedImage(dir, id) {
|
|
269
|
-
let scale = this.transform[id].scale;
|
|
270
|
-
scale += dir;
|
|
271
|
-
if (scale < 0.1) {
|
|
272
|
-
scale = 0.1;
|
|
273
|
-
}
|
|
274
|
-
this.transform[id] = {
|
|
275
|
-
...this.transform[id],
|
|
276
|
-
scale
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
rotateCroppedImage(dir, id) {
|
|
280
|
-
this.canvasRotation[id] += dir;
|
|
281
|
-
const flippedH = this.transform[id].flipH;
|
|
282
|
-
const flippedV = this.transform[id].flipV;
|
|
283
|
-
this.transform[id] = {
|
|
284
|
-
...this.transform[id],
|
|
285
|
-
flipH: flippedV,
|
|
286
|
-
flipV: flippedH
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
onImageCropped(event, id) {
|
|
290
|
-
this.croppedImages[id] = event.base64;
|
|
291
|
-
this.imageCropped.emit(event.base64);
|
|
292
|
-
}
|
|
293
|
-
imageLoaded(id) {
|
|
294
|
-
this.showCropper = true;
|
|
295
|
-
setTimeout(() => {
|
|
296
|
-
this.transform[id] = {
|
|
297
|
-
scale: 1
|
|
298
|
-
};
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
cropperReady(sourceImageDimensions, id) {
|
|
302
|
-
this.cropperImageLoaded[id] = true;
|
|
303
|
-
}
|
|
304
|
-
loadImageFailed() {
|
|
305
|
-
}
|
|
306
|
-
toggleMenuVisibility(f) {
|
|
307
|
-
this.fileMenuOpened = f;
|
|
308
|
-
}
|
|
309
|
-
menuClick() {
|
|
310
|
-
this.fileMenuOpened = undefined;
|
|
311
|
-
}
|
|
312
|
-
writeValue(obj) {
|
|
313
|
-
this.inputArray = obj instanceof Array;
|
|
314
|
-
if (this.inputArray) {
|
|
315
|
-
this.files = obj.map(f => ({ custom: f, $newFile: null }));
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
this.files = obj ? [{ custom: obj, $newFile: null }] : [];
|
|
319
|
-
}
|
|
320
|
-
this.cropSourceImages = {};
|
|
321
|
-
}
|
|
322
|
-
cropperDone(id) {
|
|
323
|
-
const f = this.files.find(fx => fx.$newFile && fx.$newFile.id === id);
|
|
324
|
-
if (f) {
|
|
325
|
-
const url = this.croppedImages[id];
|
|
326
|
-
fetch(url)
|
|
327
|
-
.then(res => res.blob())
|
|
328
|
-
.then(blob => {
|
|
329
|
-
f.$newFile.nativeFile = new File([blob], 'crop.png', {
|
|
330
|
-
type: 'image/png'
|
|
331
|
-
});
|
|
332
|
-
f.$newFile.name = 'crop.png';
|
|
333
|
-
f.$newFile.size = f.$newFile.nativeFile.size;
|
|
334
|
-
f.$newFile.type = f.$newFile.nativeFile.type;
|
|
335
|
-
this.imagesDone[id] = true;
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
UiFileUploaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: UiFileUploaderComponent, deps: [{ token: UI_FILESERVICE, optional: true }, { token: UI_TRANSLATESERVICE }, { token: i1.ControlContainer, host: true, optional: true, skipSelf: true }, { token: i2.UiFileService }], target: i0.ɵɵFactoryTarget.Component });
|
|
341
|
-
UiFileUploaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.5", type: UiFileUploaderComponent, selector: "ui-file-uploader", inputs: { maxFiles: "maxFiles", multiple: "multiple", crop: "crop", cropRounded: "cropRounded", cropMaxWidth: "cropMaxWidth", fileSize: "fileSize", customFileMenu: "customFileMenu", addHint: "addHint", newFilePosition: "newFilePosition", templates: "templates", previewPosition: "previewPosition" }, outputs: { imageCropped: "imageCropped", fileEvent: "fileEvent" }, providers: [{
|
|
342
|
-
provide: NG_VALUE_ACCESSOR,
|
|
343
|
-
multi: true,
|
|
344
|
-
useExisting: UiFileUploaderComponent,
|
|
345
|
-
}], usesInheritance: true, ngImport: i0, template: "<div class=\"label\" *ngIf=\"label\">\r\n <div class=\"text-container\" [matTooltip]=\"required ? translateService.instant('ui.controls.validation.required') : undefined\" [matTooltipPosition]=\"'above'\">\r\n <div class=\"text\">{{label}}</div>\r\n <div *ngIf=\"required\" class=\"required\">*</div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"files-container\" [ngClass]=\"{dragging: dragging, disabled: uploading || !editable}\">\r\n\r\n <div class=\"existing-files\">\r\n\r\n <div class=\"file-container\" *ngFor=\"let f of files\">\r\n\r\n <div class=\"file-menu\" (click)=\"toggleMenuVisibility(f)\" *ngIf=\"!customFileMenu && editable && !uploading\">\r\n <mat-icon>menu</mat-icon>\r\n </div>\r\n <div class=\"file-menu-container mat-elevation-z2\" [ngClass]=\"{visible: f === fileMenuOpened}\" (click)=\"menuClick()\" (mouseleave)=\"menuClick()\">\r\n <ng-container *ngIf=\"!menuTemplate\">\r\n <label class=\"menu-item\">{{ translateService.instant('ui.controls.ui-file-uploader.menu.change') }}\r\n <input *ngIf=\"!refreshAddInput\" style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </label>\r\n <div class=\"menu-item\" (click)=\"remove(f)\">{{ translateService.instant('ui.controls.ui-file-uploader.menu.delete') }}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"menuTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"menuTemplate\" [ngTemplateOutletContext]=\"{fileInput: fileInput}\"></ng-template>\r\n <ng-template #fileInput>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"crop && !cropDone(f)\" (mouseenter)=\"startCropPreview(f.$newFile.id)\" (mouseleave)=\"stopCropPreview(f.$newFile.id)\">\r\n <div class=\"crop-container\" [ngStyle]=\"ngAddStyle\">\r\n\r\n <ui-file *ngIf=\"false && files.length > 0 && !cropSourceImages\" [fileSize]=\"fileSize\" [srcData]=\"files[0].custom\" [ngClass]=\"{rounded: cropRounded}\"></ui-file>\r\n\r\n <mat-spinner *ngIf=\"!cropperImageLoaded[f.$newFile.id] && cropSourceImages[f.$newFile.id]\" [diameter]=\"75\"></mat-spinner>\r\n\r\n <image-cropper *ngIf=\"cropSourceImages[f.$newFile.id]\"\r\n [imageFile]=\"cropSourceImages[f.$newFile.id]\"\r\n [maintainAspectRatio]=\"true\"\r\n [containWithinAspectRatio]=\"false\"\r\n [aspectRatio]=\"aspectRatio\"\r\n [resizeToWidth]=\"cropMaxWidth\"\r\n [onlyScaleDown]=\"false\"\r\n [roundCropper]=\"cropRounded\"\r\n [canvasRotation]=\"canvasRotation[f.$newFile.id]\"\r\n [transform]=\"transform[f.$newFile.id]\"\r\n [alignImage]=\"'center'\"\r\n [style.display]=\"showCropper ? null : 'none'\"\r\n [format]=\"'png'\"\r\n (imageCropped)=\"onImageCropped($event, f.$newFile.id)\"\r\n (imageLoaded)=\"imageLoaded(f.$newFile.id)\"\r\n (cropperReady)=\"cropperReady($event, f.$newFile.id)\"\r\n (loadImageFailed)=\"loadImageFailed()\"\r\n ></image-cropper>\r\n\r\n <div class=\"crop-preview mat-elevation-z2\" [class]=\"previewPosition\" *ngIf=\"true || (showCropPreview[f.$newFile.id] && cropperImageLoaded[f.$newFile.id])\">\r\n <div class=\"crop-menu\">\r\n <mat-icon (click)=\"zoomCroppedImage(.1, f.$newFile.id)\">zoom_in</mat-icon>\r\n <mat-icon (click)=\"zoomCroppedImage(- .1, f.$newFile.id)\">zoom_out</mat-icon>\r\n <mat-icon (click)=\"rotateCroppedImage(-1, f.$newFile.id)\">rotate_left</mat-icon>\r\n <mat-icon (click)=\"rotateCroppedImage(1, f.$newFile.id)\">rotate_right</mat-icon>\r\n <div style=\"flex: 1 1 100%\"></div>\r\n <label class=\"menu-item\">\r\n <mat-icon>upload_file</mat-icon>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </label>\r\n <mat-icon (click)=\"remove(f)\">delete_outline</mat-icon>\r\n <div style=\"flex: 1 1 100%\"></div>\r\n <mat-icon (click)=\"cropperDone(f.$newFile.id)\">done</mat-icon>\r\n </div>\r\n <img [src]=\"croppedImages[f.$newFile.id]\" [ngClass]=\"{rounded: cropRounded}\"/>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n </div>\r\n\r\n <ng-container *ngIf=\"!crop || cropDone(f)\">\r\n <ng-container *ngIf=\"fileTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"fileTemplate\" [ngTemplateOutletContext]=\"{file: f, fileInput: fileInput2}\"></ng-template>\r\n <ng-template #fileInput2>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </ng-template>\r\n </ng-container>\r\n\r\n <ui-file *ngIf=\"!fileTemplate\" [fileSize]=\"fileSize\" [srcData]=\"f.$newFile ? f.$newFile: f.custom\" [ngClass]=\"{rounded: crop && cropRounded}\">\r\n </ui-file>\r\n\r\n <ng-container *ngIf=\"f.$newFile\">\r\n <div *ngIf=\"f.$newFile.responseStatus && f.$newFile.responseStatus !== 200\" class=\"progress-container error\">\r\n {{ translateService.instant('ui.controls.ui-file-uploader.uploadError', f.$newFile.response) }}\r\n </div>\r\n <div *ngIf=\"!f.$newFile.responseStatus && f.$newFile.progress.status === 1\" class=\"progress-container\">\r\n <div class=\"progress\" [ngStyle]=\"{width: f.$newFile.progress.data.percentage + '%'}\"></div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"file-container add\" ngFileDrop [options]=\"uploadOptions\" (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\" [ngClass]=\"{visible: files.length < maxFiles || maxFiles === 0}\" [ngStyle]=\"addFileTemplate ? {} : ngAddStyle\">\r\n <label>\r\n <ng-container *ngIf=\"addFileTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"addFileTemplate\"></ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"!addFileTemplate\">\r\n <div class=\"upload-image-container\"></div>\r\n <img [src]=\"addFileImgSrc\" [ngClass]=\"{'with-hint': addHint}\" />\r\n <div *ngIf=\"addHint\" class=\"add-hint\">{{addHint}}</div>\r\n </ng-container>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\" [multiple]=\"maxFiles === 0 && multiple\">\r\n </label>\r\n </div>\r\n\r\n</div>\r\n", styles: [":host{display:flex;flex-wrap:wrap}:host .label .text{font-size:.9em;line-height:1em;padding:6px 0 4px}:host .files-container{display:flex;flex-wrap:wrap;border-style:solid}:host .files-container .existing-files{display:flex;flex-wrap:wrap}:host .files-container.dragging .add label{border:2px dashed grey;background-color:#0000001a}:host .files-container.disabled .add{opacity:.5;pointer-events:none}:host .file-container{max-width:100%;max-height:100%;position:relative;display:flex;align-items:center;justify-content:center}:host .file-container .progress-container{position:absolute;bottom:0;left:1px;right:1px;height:20%;max-height:20px;background-color:#0000001a}:host .file-container .progress-container.error{background-color:red;color:#fff;display:flex;align-items:center;justify-content:center}:host .file-container .progress-container .progress{background-color:#0000004d;height:100%}:host .file-container.add{display:flex;align-items:center;flex-direction:column;transition:opacity .25s;cursor:pointer}:host .file-container.add:not(.visible){display:none}:host .file-container.add img{max-width:100%;max-height:100%}:host .file-container.add img.with-hint{max-height:75%}:host .file-container.add .add-hint{margin-top:8px;font-size:80%;text-align:center}:host .file-container.add label{position:absolute;inset:0;cursor:pointer;z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .file-container.add .upload-image-container{display:none}:host .file-container .file-menu-container{display:none;position:absolute;left:calc(100% - 45px);top:27px;z-index:1000}:host .file-container .file-menu-container ::ng-deep .menu-item{position:relative;padding:12px 24px;cursor:pointer;display:block}:host .file-container .file-menu-container.visible{display:block}:host .file-container .file-menu{display:flex;position:absolute;flex-direction:column;align-items:center;justify-content:center;padding:12px;right:10px;top:10px;background-color:#fff9;border-radius:50%;cursor:pointer;transition:all .25s;z-index:999}:host .file-container:hover .file-menu{background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}:host .file-container mat-progress-bar{position:absolute;bottom:0;height:6px;left:0;right:0;z-index:1000}:host image-cropper{padding:0}:host ui-file.rounded ::ng-deep img{border-radius:50%}:host .crop-container{display:flex;align-items:center;justify-content:center;position:relative}:host .crop-container mat-spinner{position:absolute;z-index:1}:host .crop-container .crop-preview{position:absolute;top:100%;left:0;right:0;padding:6px;border:1px solid transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1000;max-width:350px;margin-right:auto;margin-left:auto}:host .crop-container .crop-preview.left{right:calc(100% + 6px);left:unset;top:0}:host .crop-container .crop-preview.above{bottom:100%;top:unset}:host .crop-container .crop-preview .crop-menu{width:100%;flex:0 0 auto;display:flex}:host .crop-container .crop-preview .crop-menu mat-icon{margin:0 3px;width:calc(1em + 6px);height:1em;font-size:2em;cursor:pointer;user-select:none;flex:1 1 100%}:host .crop-container .crop-preview img{margin:16px 0;max-width:256px;max-height:256px}:host .crop-container .crop-preview img.rounded{border-radius:50%}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i6.NgFileDropDirective, selector: "[ngFileDrop]", inputs: ["options", "uploadInput"], outputs: ["uploadOutput"] }, { kind: "directive", type: i6.NgFileSelectDirective, selector: "[ngFileSelect]", inputs: ["options", "uploadInput"], outputs: ["uploadOutput"] }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i8.ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "format", "transform", "maintainAspectRatio", "aspectRatio", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "autoCrop", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "cropper", "alignImage", "disabled"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange"] }, { kind: "component", type: i9.FileComponent, selector: "ui-file", inputs: ["fileSize", "srcOptions", "srcData", "srcUrl"] }] });
|
|
346
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.5", ngImport: i0, type: UiFileUploaderComponent, decorators: [{
|
|
347
|
-
type: Component,
|
|
348
|
-
args: [{ selector: 'ui-file-uploader', providers: [{
|
|
349
|
-
provide: NG_VALUE_ACCESSOR,
|
|
350
|
-
multi: true,
|
|
351
|
-
useExisting: UiFileUploaderComponent,
|
|
352
|
-
}], template: "<div class=\"label\" *ngIf=\"label\">\r\n <div class=\"text-container\" [matTooltip]=\"required ? translateService.instant('ui.controls.validation.required') : undefined\" [matTooltipPosition]=\"'above'\">\r\n <div class=\"text\">{{label}}</div>\r\n <div *ngIf=\"required\" class=\"required\">*</div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"files-container\" [ngClass]=\"{dragging: dragging, disabled: uploading || !editable}\">\r\n\r\n <div class=\"existing-files\">\r\n\r\n <div class=\"file-container\" *ngFor=\"let f of files\">\r\n\r\n <div class=\"file-menu\" (click)=\"toggleMenuVisibility(f)\" *ngIf=\"!customFileMenu && editable && !uploading\">\r\n <mat-icon>menu</mat-icon>\r\n </div>\r\n <div class=\"file-menu-container mat-elevation-z2\" [ngClass]=\"{visible: f === fileMenuOpened}\" (click)=\"menuClick()\" (mouseleave)=\"menuClick()\">\r\n <ng-container *ngIf=\"!menuTemplate\">\r\n <label class=\"menu-item\">{{ translateService.instant('ui.controls.ui-file-uploader.menu.change') }}\r\n <input *ngIf=\"!refreshAddInput\" style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </label>\r\n <div class=\"menu-item\" (click)=\"remove(f)\">{{ translateService.instant('ui.controls.ui-file-uploader.menu.delete') }}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"menuTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"menuTemplate\" [ngTemplateOutletContext]=\"{fileInput: fileInput}\"></ng-template>\r\n <ng-template #fileInput>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"crop && !cropDone(f)\" (mouseenter)=\"startCropPreview(f.$newFile.id)\" (mouseleave)=\"stopCropPreview(f.$newFile.id)\">\r\n <div class=\"crop-container\" [ngStyle]=\"ngAddStyle\">\r\n\r\n <ui-file *ngIf=\"false && files.length > 0 && !cropSourceImages\" [fileSize]=\"fileSize\" [srcData]=\"files[0].custom\" [ngClass]=\"{rounded: cropRounded}\"></ui-file>\r\n\r\n <mat-spinner *ngIf=\"!cropperImageLoaded[f.$newFile.id] && cropSourceImages[f.$newFile.id]\" [diameter]=\"75\"></mat-spinner>\r\n\r\n <image-cropper *ngIf=\"cropSourceImages[f.$newFile.id]\"\r\n [imageFile]=\"cropSourceImages[f.$newFile.id]\"\r\n [maintainAspectRatio]=\"true\"\r\n [containWithinAspectRatio]=\"false\"\r\n [aspectRatio]=\"aspectRatio\"\r\n [resizeToWidth]=\"cropMaxWidth\"\r\n [onlyScaleDown]=\"false\"\r\n [roundCropper]=\"cropRounded\"\r\n [canvasRotation]=\"canvasRotation[f.$newFile.id]\"\r\n [transform]=\"transform[f.$newFile.id]\"\r\n [alignImage]=\"'center'\"\r\n [style.display]=\"showCropper ? null : 'none'\"\r\n [format]=\"'png'\"\r\n (imageCropped)=\"onImageCropped($event, f.$newFile.id)\"\r\n (imageLoaded)=\"imageLoaded(f.$newFile.id)\"\r\n (cropperReady)=\"cropperReady($event, f.$newFile.id)\"\r\n (loadImageFailed)=\"loadImageFailed()\"\r\n ></image-cropper>\r\n\r\n <div class=\"crop-preview mat-elevation-z2\" [class]=\"previewPosition\" *ngIf=\"true || (showCropPreview[f.$newFile.id] && cropperImageLoaded[f.$newFile.id])\">\r\n <div class=\"crop-menu\">\r\n <mat-icon (click)=\"zoomCroppedImage(.1, f.$newFile.id)\">zoom_in</mat-icon>\r\n <mat-icon (click)=\"zoomCroppedImage(- .1, f.$newFile.id)\">zoom_out</mat-icon>\r\n <mat-icon (click)=\"rotateCroppedImage(-1, f.$newFile.id)\">rotate_left</mat-icon>\r\n <mat-icon (click)=\"rotateCroppedImage(1, f.$newFile.id)\">rotate_right</mat-icon>\r\n <div style=\"flex: 1 1 100%\"></div>\r\n <label class=\"menu-item\">\r\n <mat-icon>upload_file</mat-icon>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </label>\r\n <mat-icon (click)=\"remove(f)\">delete_outline</mat-icon>\r\n <div style=\"flex: 1 1 100%\"></div>\r\n <mat-icon (click)=\"cropperDone(f.$newFile.id)\">done</mat-icon>\r\n </div>\r\n <img [src]=\"croppedImages[f.$newFile.id]\" [ngClass]=\"{rounded: cropRounded}\"/>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n </div>\r\n\r\n <ng-container *ngIf=\"!crop || cropDone(f)\">\r\n <ng-container *ngIf=\"fileTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"fileTemplate\" [ngTemplateOutletContext]=\"{file: f, fileInput: fileInput2}\"></ng-template>\r\n <ng-template #fileInput2>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (change)=\"fileChangeEvent($event, f)\"\r\n (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\">\r\n </ng-template>\r\n </ng-container>\r\n\r\n <ui-file *ngIf=\"!fileTemplate\" [fileSize]=\"fileSize\" [srcData]=\"f.$newFile ? f.$newFile: f.custom\" [ngClass]=\"{rounded: crop && cropRounded}\">\r\n </ui-file>\r\n\r\n <ng-container *ngIf=\"f.$newFile\">\r\n <div *ngIf=\"f.$newFile.responseStatus && f.$newFile.responseStatus !== 200\" class=\"progress-container error\">\r\n {{ translateService.instant('ui.controls.ui-file-uploader.uploadError', f.$newFile.response) }}\r\n </div>\r\n <div *ngIf=\"!f.$newFile.responseStatus && f.$newFile.progress.status === 1\" class=\"progress-container\">\r\n <div class=\"progress\" [ngStyle]=\"{width: f.$newFile.progress.data.percentage + '%'}\"></div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"file-container add\" ngFileDrop [options]=\"uploadOptions\" (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\" [ngClass]=\"{visible: files.length < maxFiles || maxFiles === 0}\" [ngStyle]=\"addFileTemplate ? {} : ngAddStyle\">\r\n <label>\r\n <ng-container *ngIf=\"addFileTemplate\">\r\n <ng-template [ngTemplateOutlet]=\"addFileTemplate\"></ng-template>\r\n </ng-container>\r\n <ng-container *ngIf=\"!addFileTemplate\">\r\n <div class=\"upload-image-container\"></div>\r\n <img [src]=\"addFileImgSrc\" [ngClass]=\"{'with-hint': addHint}\" />\r\n <div *ngIf=\"addHint\" class=\"add-hint\">{{addHint}}</div>\r\n </ng-container>\r\n <input style=\"display: none;\" type=\"file\" ngFileSelect [options]=\"uploadOptions\" (uploadOutput)=\"onUploadOutput($event)\" [uploadInput]=\"uploadInput\" [multiple]=\"maxFiles === 0 && multiple\">\r\n </label>\r\n </div>\r\n\r\n</div>\r\n", styles: [":host{display:flex;flex-wrap:wrap}:host .label .text{font-size:.9em;line-height:1em;padding:6px 0 4px}:host .files-container{display:flex;flex-wrap:wrap;border-style:solid}:host .files-container .existing-files{display:flex;flex-wrap:wrap}:host .files-container.dragging .add label{border:2px dashed grey;background-color:#0000001a}:host .files-container.disabled .add{opacity:.5;pointer-events:none}:host .file-container{max-width:100%;max-height:100%;position:relative;display:flex;align-items:center;justify-content:center}:host .file-container .progress-container{position:absolute;bottom:0;left:1px;right:1px;height:20%;max-height:20px;background-color:#0000001a}:host .file-container .progress-container.error{background-color:red;color:#fff;display:flex;align-items:center;justify-content:center}:host .file-container .progress-container .progress{background-color:#0000004d;height:100%}:host .file-container.add{display:flex;align-items:center;flex-direction:column;transition:opacity .25s;cursor:pointer}:host .file-container.add:not(.visible){display:none}:host .file-container.add img{max-width:100%;max-height:100%}:host .file-container.add img.with-hint{max-height:75%}:host .file-container.add .add-hint{margin-top:8px;font-size:80%;text-align:center}:host .file-container.add label{position:absolute;inset:0;cursor:pointer;z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center}:host .file-container.add .upload-image-container{display:none}:host .file-container .file-menu-container{display:none;position:absolute;left:calc(100% - 45px);top:27px;z-index:1000}:host .file-container .file-menu-container ::ng-deep .menu-item{position:relative;padding:12px 24px;cursor:pointer;display:block}:host .file-container .file-menu-container.visible{display:block}:host .file-container .file-menu{display:flex;position:absolute;flex-direction:column;align-items:center;justify-content:center;padding:12px;right:10px;top:10px;background-color:#fff9;border-radius:50%;cursor:pointer;transition:all .25s;z-index:999}:host .file-container:hover .file-menu{background-color:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}:host .file-container mat-progress-bar{position:absolute;bottom:0;height:6px;left:0;right:0;z-index:1000}:host image-cropper{padding:0}:host ui-file.rounded ::ng-deep img{border-radius:50%}:host .crop-container{display:flex;align-items:center;justify-content:center;position:relative}:host .crop-container mat-spinner{position:absolute;z-index:1}:host .crop-container .crop-preview{position:absolute;top:100%;left:0;right:0;padding:6px;border:1px solid transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:1000;max-width:350px;margin-right:auto;margin-left:auto}:host .crop-container .crop-preview.left{right:calc(100% + 6px);left:unset;top:0}:host .crop-container .crop-preview.above{bottom:100%;top:unset}:host .crop-container .crop-preview .crop-menu{width:100%;flex:0 0 auto;display:flex}:host .crop-container .crop-preview .crop-menu mat-icon{margin:0 3px;width:calc(1em + 6px);height:1em;font-size:2em;cursor:pointer;user-select:none;flex:1 1 100%}:host .crop-container .crop-preview img{margin:16px 0;max-width:256px;max-height:256px}:host .crop-container .crop-preview img.rounded{border-radius:50%}\n"] }]
|
|
353
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
354
|
-
type: Optional
|
|
355
|
-
}, {
|
|
356
|
-
type: Inject,
|
|
357
|
-
args: [UI_FILESERVICE]
|
|
358
|
-
}] }, { type: undefined, decorators: [{
|
|
359
|
-
type: Inject,
|
|
360
|
-
args: [UI_TRANSLATESERVICE]
|
|
361
|
-
}] }, { type: i1.ControlContainer, decorators: [{
|
|
362
|
-
type: Optional
|
|
363
|
-
}, {
|
|
364
|
-
type: Host
|
|
365
|
-
}, {
|
|
366
|
-
type: SkipSelf
|
|
367
|
-
}] }, { type: i2.UiFileService }]; }, propDecorators: { maxFiles: [{
|
|
368
|
-
type: Input
|
|
369
|
-
}], multiple: [{
|
|
370
|
-
type: Input
|
|
371
|
-
}], crop: [{
|
|
372
|
-
type: Input
|
|
373
|
-
}], cropRounded: [{
|
|
374
|
-
type: Input
|
|
375
|
-
}], cropMaxWidth: [{
|
|
376
|
-
type: Input
|
|
377
|
-
}], fileSize: [{
|
|
378
|
-
type: Input
|
|
379
|
-
}], customFileMenu: [{
|
|
380
|
-
type: Input
|
|
381
|
-
}], addHint: [{
|
|
382
|
-
type: Input
|
|
383
|
-
}], newFilePosition: [{
|
|
384
|
-
type: Input
|
|
385
|
-
}], templates: [{
|
|
386
|
-
type: Input
|
|
387
|
-
}], previewPosition: [{
|
|
388
|
-
type: Input
|
|
389
|
-
}], imageCropped: [{
|
|
390
|
-
type: Output
|
|
391
|
-
}], fileEvent: [{
|
|
392
|
-
type: Output
|
|
393
|
-
}] } });
|
|
394
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktZmlsZS11cGxvYWRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL2ZpbGUtdXBsb2FkZXIvdWktZmlsZS11cGxvYWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL2ZpbGUtdXBsb2FkZXIvdWktZmlsZS11cGxvYWRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixJQUFJLEVBQ0osTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFFBQVEsRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQW9CLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckUsT0FBTyxFQUEwQyxjQUFjLEVBQWlCLE1BQU0sNkJBQTZCLENBQUM7QUFFcEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbEUsT0FBTyxFQUF1QixtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7Ozs7Ozs7OztBQTJCNUYsTUFBTSxPQUFPLHVCQUF3QixTQUFRLGlCQUFpQjtJQWdFNUQsWUFBd0QsaUJBQWlDLEVBQ3pDLGdCQUFxQyxFQUMvQixnQkFBa0MsRUFDcEUsV0FBMEI7UUFFNUMsS0FBSyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBTHdCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBZ0I7UUFDekMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFxQjtRQUMvQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ3BFLGdCQUFXLEdBQVgsV0FBVyxDQUFlO1FBakVyQyxhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsYUFBUSxHQUFHLElBQUksQ0FBQztRQUNoQixTQUFJLEdBQUcsS0FB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QkFBaUI7NEJBQzFCLEtBQUssRUFBRSxJQUFJOzRCQUNYLFdBQVcseUJBQXlCO3lCQUNyQyxDQUFDOzswQkFrRVcsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxjQUFjOzswQkFDakMsTUFBTTsyQkFBQyxtQkFBbUI7OzBCQUMxQixRQUFROzswQkFBSSxJQUFJOzswQkFBSSxRQUFRO3dFQWhFaEMsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBY0csZUFBZTtzQkFBdkIsS0FBSztnQkFFSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSG9zdCxcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBPcHRpb25hbCxcclxuICBPdXRwdXQsXHJcbiAgU2tpcFNlbGZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbENvbnRhaW5lciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IFVwbG9hZGVyT3B0aW9ucywgVXBsb2FkRmlsZSwgVXBsb2FkSW5wdXQsIFVwbG9hZE91dHB1dCB9IGZyb20gJ25neC11cGxvYWRlcic7XHJcbmltcG9ydCB7IElVaUZpbGVTZXJ2aWNlLCBJVWlGaWxlU2VydmljZU1lc3NhZ2VzLCBVSV9GSUxFU0VSVklDRSwgVWlGaWxlU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3VpLWZpbGUuc2VydmljZSc7XHJcbmltcG9ydCB7IERpbWVuc2lvbnMsIEltYWdlQ3JvcHBlZEV2ZW50LCBJbWFnZVRyYW5zZm9ybSB9IGZyb20gJ25neC1pbWFnZS1jcm9wcGVyJztcclxuaW1wb3J0IHsgVWlTaW1wbGVDb21wb25lbnQgfSBmcm9tICcuLi9zaW1wbGUvdWktc2ltcGxlLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IElVaVRyYW5zbGF0ZVNlcnZpY2UsIFVJX1RSQU5TTEFURVNFUlZJQ0UgfSBmcm9tICcuLi9zZXJ2aWNlcy91aS10cmFuc2xhdGUuc2VydmljZSc7XHJcbmltcG9ydCB7IHNraXAgfSBmcm9tICdyeGpzJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVXBsb2FkT3V0cHV0RXggZXh0ZW5kcyBVcGxvYWRPdXRwdXQge1xyXG4gIGZpbGU6IFVwbG9hZEZpbGVFeDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBVcGxvYWRGaWxlRXggZXh0ZW5kcyBVcGxvYWRGaWxlIHtcclxuICBpbWFnZVByZXZpZXc/OiBhbnk7XHJcbiAgYmFzZTY0PzogYW55O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElVaVVwbG9hZGVyVXNlck1lc3NhZ2Uge1xyXG4gIG1lc3NhZ2U6IElVaUZpbGVTZXJ2aWNlTWVzc2FnZXMsXHJcbiAgZGF0YTogYW55XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAndWktZmlsZS11cGxvYWRlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3VpLWZpbGUtdXBsb2FkZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWyAnLi91aS1maWxlLXVwbG9hZGVyLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgcHJvdmlkZXJzOiBbe1xyXG4gICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICBtdWx0aTogdHJ1ZSxcclxuICAgIHVzZUV4aXN0aW5nOiBVaUZpbGVVcGxvYWRlckNvbXBvbmVudCxcclxuICB9XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVWlGaWxlVXBsb2FkZXJDb21wb25lbnQgZXh0ZW5kcyBVaVNpbXBsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgQElucHV0KCkgbWF4RmlsZXMgPSAxO1xyXG4gIEBJbnB1dCgpIG11bHRpcGxlID0gdHJ1ZTtcclxuICBASW5wdXQoKSBjcm9wID0gZmFsc2U7XHJcbiAgQElucHV0KCkgY3JvcFJvdW5kZWQgPSBmYWxzZTtcclxuICBASW5wdXQoKSBjcm9wTWF4V2lkdGg7XHJcbiAgQElucHV0KCkgZmlsZVNpemUgPSAnZGVmYXVsdCc7XHJcbiAgQElucHV0KCkgY3VzdG9tRmlsZU1lbnUgPSBmYWxzZTtcclxuICBASW5wdXQoKSBhZGRIaW50O1xyXG4gIEBJbnB1dCgpIG5ld0ZpbGVQb3NpdGlvbjogJ2ZpcnN0JyB8ICdsYXN0JyA9ICdsYXN0JztcclxuXHJcbiAgQElucHV0KCkgdGVtcGxhdGVzOiB7IG1lbnVUZW1wbGF0ZT86IGFueSwgYWRkRmlsZVRlbXBsYXRlPzogYW55LCBmaWxlVGVtcGxhdGU/OiBhbnkgfSA9IHt9XHJcblxyXG4gIGdldCBtZW51VGVtcGxhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy50ZW1wbGF0ZXM/Lm1lbnVUZW1wbGF0ZTtcclxuICB9XHJcblxyXG4gIGdldCBhZGRGaWxlVGVtcGxhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy50ZW1wbGF0ZXM/LmFkZEZpbGVUZW1wbGF0ZTtcclxuICB9XHJcblxyXG4gIGdldCBmaWxlVGVtcGxhdGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy50ZW1wbGF0ZXM/LmZpbGVUZW1wbGF0ZTtcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHByZXZpZXdQb3NpdGlvbjogJ2xlZnQnIHwgJ2JvdHRvbScgfCAnYWJvdmUnID0gJ2JvdHRvbSc7XHJcblxyXG4gIEBPdXRwdXQoKSBpbWFnZUNyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgQE91dHB1dCgpIGZpbGVFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8SVVpVXBsb2FkZXJVc2VyTWVzc2FnZT4oKTtcclxuXHJcbiAgdXBsb2FkT3B0aW9uczogVXBsb2FkZXJPcHRpb25zID0ge1xyXG4gICAgY29uY3VycmVuY3k6IHRoaXMuZmlsZVNlcnZpY2VDb25maWcuY29uY3VycmVudFVwbG9hZHNcclxuICB9O1xyXG5cclxuICBwdWJsaWMgdXBsb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gIGNoYW5nZUZpbGVJbmRleDtcclxuXHJcbiAgc2hvd0Nyb3BwZXIgPSBmYWxzZTtcclxuICBtZW51VmlzaWJsZTogYW55O1xyXG4gIHNob3dDcm9wUHJldmlldyA9IHt9O1xyXG4gIGNyb3BQcmV2aWV3VGltZW91dHMgPSB7fTtcclxuICBjcm9wU291cmNlSW1hZ2VzID0ge307XHJcbiAgY3JvcHBlckltYWdlTG9hZGVkID0ge307XHJcbiAgaW1hZ2VzRG9uZSA9IHt9O1xyXG4gIHRyYW5zZm9ybTogSW1hZ2VUcmFuc2Zvcm0gPSB7fTtcclxuICBjYW52YXNSb3RhdGlvbiA9IHt9XHJcblxyXG4gIHB1YmxpYyBmaWxlcyA6IHsgY3VzdG9tPzogYW55LCAkbmV3RmlsZT86IFVwbG9hZEZpbGUgfVtdO1xyXG5cclxuICBwdWJsaWMgcmVzcG9uc2VGaWxlcztcclxuXHJcbiAgcmVmcmVzaEFkZElucHV0ID0gZmFsc2U7XHJcblxyXG4gIGZpbGVNZW51T3BlbmVkO1xyXG5cclxuICBwYXRjaGluZ1ZhbHVlcyA9IGZhbHNlO1xyXG5cclxuICBpbnB1dEFycmF5ID0gZmFsc2U7XHJcbiAgZHJhZ2dpbmcgPSBmYWxzZTtcclxuXHJcbiAgdXBsb2FkZXJJZCA9IE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqIDEwMDAwMDApO1xyXG5cclxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBASW5qZWN0KFVJX0ZJTEVTRVJWSUNFKSBwcml2YXRlIGZpbGVTZXJ2aWNlQ29uZmlnOiBJVWlGaWxlU2VydmljZSxcclxuICAgICAgICAgICAgICBASW5qZWN0KFVJX1RSQU5TTEFURVNFUlZJQ0UpIHB1YmxpYyB0cmFuc2xhdGVTZXJ2aWNlOiBJVWlUcmFuc2xhdGVTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBIb3N0KCkgQFNraXBTZWxmKCkgcHJvdGVjdGVkIGNvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXIsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBmaWxlU2VydmljZTogVWlGaWxlU2VydmljZSkge1xyXG5cclxuICAgIHN1cGVyKG51bGwsIGNvbnRyb2xDb250YWluZXIpO1xyXG5cclxuICAgIHRoaXMuZmlsZVNlcnZpY2UudXBsb2FkU3Vic2NyaXB0aW9uLm5leHQoe2FjdGlvbjogJ3JlZ2lzdGVyJywgZGF0YTogdGhpc30pO1xyXG5cclxuICAgIHRoaXMuZmlsZVNlcnZpY2UudXBsb2FkU3Vic2NyaXB0aW9uLnN1YnNjcmliZSgodjogYW55KSA9PiB7XHJcbiAgICAgIHN3aXRjaCAodi5hY3Rpb24pIHtcclxuICAgICAgICBjYXNlICd1cGxvYWRTdGFydGVkJzogdGhpcy51cGxvYWRpbmcgPSB0cnVlOyBicmVhaztcclxuICAgICAgICBjYXNlICd1cGxvYWRGYWlsZWQnOlxyXG4gICAgICAgIGNhc2UgJ3VwbG9hZFN1Y2Nlc3MnOlxyXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIHRoaXMucGF0Y2hWYWx1ZXMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBnZXQgdXBsb2FkSW5wdXQoKTogRXZlbnRFbWl0dGVyPFVwbG9hZElucHV0PiB7XHJcbiAgICByZXR1cm4gdGhpcy5maWxlU2VydmljZS51cGxvYWRJbnB1dDtcclxuICB9XHJcblxyXG4gIGNyb3BwZWRJbWFnZXMgPSB7fTtcclxuXHJcbiAgZ2V0IGVkaXRhYmxlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50Rm9ybUNvbnRyb2wuZW5hYmxlZDtcclxuICB9XHJcblxyXG4gIGdldCBuZ0FkZFN0eWxlKCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgd2lkdGg6IHRoaXMuZmlsZVNlcnZpY2VDb25maWcuaW1hZ2VTaXplc1t0aGlzLmZpbGVTaXplXVswXSArICdweCcsXHJcbiAgICAgIGhlaWdodDogdGhpcy5maWxlU2VydmljZUNvbmZpZy5pbWFnZVNpemVzW3RoaXMuZmlsZVNpemVdWzFdICsgJ3B4JyxcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBhc3BlY3RSYXRpbygpIHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVTZXJ2aWNlQ29uZmlnLmltYWdlU2l6ZXNbdGhpcy5maWxlU2l6ZV1bMF0gLyB0aGlzLmZpbGVTZXJ2aWNlQ29uZmlnLmltYWdlU2l6ZXNbdGhpcy5maWxlU2l6ZV1bMV07XHJcbiAgfVxyXG5cclxuICBnZXQgYWRkRmlsZUltZ1NyYygpIHtcclxuICAgIHJldHVybiB0aGlzLmZpbGVTZXJ2aWNlQ29uZmlnLmFkZEZpbGVJbWdTcmM7XHJcbiAgfVxyXG5cclxuICBjcm9wRG9uZShmKSB7XHJcbiAgICByZXR1cm4gIWYuJG5ld0ZpbGUgfHwgdGhpcy5pbWFnZXNEb25lW2YuJG5ld0ZpbGUuaWRdO1xyXG4gIH1cclxuXHJcbiAgLy8gbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgLy8gICBzdXBlci5uZ09uSW5pdCgpO1xyXG4gIC8vIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmZpbGVTZXJ2aWNlLnVwbG9hZFN1YnNjcmlwdGlvbi5uZXh0KHthY3Rpb246ICdkZXN0cm95JywgZGF0YTogdGhpc30pO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlKGY6IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKGYuJG5ld0ZpbGUpIHtcclxuICAgICAgdGhpcy51cGxvYWRJbnB1dC5lbWl0KHt0eXBlOiAncmVtb3ZlJywgaWQ6IGYuJG5ld0ZpbGUuaWR9KTtcclxuICAgIH1cclxuICAgIHRoaXMuZmlsZXMuc3BsaWNlKHRoaXMuZmlsZXMuaW5kZXhPZihmKSwgMSk7XHJcbiAgICB0aGlzLnByZXBhcmVSZXNwb25zZSgpO1xyXG4gICAgLy8gdGhpcy5vbkNoYW5nZSh0aGlzLmlucHV0QXJyYXkgPyB0aGlzLmZpbGVzIDogKHRoaXMuZmlsZXMubGVuZ3RoID4gMCA/IHRoaXMuZmlsZXNbMF0gOiBudWxsKSk7XHJcbiAgICB0aGlzLmZpbGVFdmVudC5lbWl0KHsgbWVzc2FnZTogJ2ZpbGVSZW1vdmVkJywgZGF0YTogZiB9KTtcclxuLy8gICAgIHRoaXMucGF0Y2hWYWx1ZXMoKTtcclxuICB9XHJcblxyXG4gIHBhdGNoVmFsdWVzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5wYXRjaGluZ1ZhbHVlcyA9IHRydWU7XHJcbiAgICAvLyBpZiAodGhpcy5pbnB1dEFycmF5KSB7XHJcbiAgICAvLyAgIHRoaXMuY29tcG9uZW50Rm9ybUNvbnRyb2wuc2V0VmFsdWUodGhpcy5maWxlcy5tYXAoZiA9PiBmLmN1c3RvbSkpO1xyXG4gICAgLy8gfSBlbHNlIHtcclxuICAgIC8vICAgdGhpcy5jb21wb25lbnRGb3JtQ29udHJvbC5zZXRWYWx1ZSh0aGlzLmZpbGVzLmxlbmd0aCA9PT0gMCA/IG51bGwgOiB0aGlzLmZpbGVzWzBdLmN1c3RvbSk7XHJcbiAgICAvLyB9XHJcbiAgICB0aGlzLnBhdGNoaW5nVmFsdWVzID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBnZXQgaGFzRmlsZXNUb1VwbG9hZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAhIXRoaXMuZmlsZXMuZmluZChmID0+IGYuJG5ld0ZpbGUgJiYgZi4kbmV3RmlsZS5wcm9ncmVzcy5zdGF0dXMgIT09IDIpO1xyXG4gIH1cclxuXHJcbiAgY2FuSW1hZ2VQcmV2aWV3KHR5cGU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykgfHwgdHlwZS5zdGFydHNXaXRoKCd2aWRlby8nKTtcclxuICB9XHJcblxyXG4gIG9uVXBsb2FkT3V0cHV0KCRldmVudDogVXBsb2FkT3V0cHV0LCBza2lwQ3VzdG9tVmFsaWRhdGlvbiA9IGZhbHNlKTogdm9pZCB7XHJcbiAgICAvLyBjb25zb2xlLmxvZygkZXZlbnQpO1xyXG4gICAgc3dpdGNoICgkZXZlbnQudHlwZSkge1xyXG4gICAgICBjYXNlICdzdGFydCc6XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlICdkcmFnT3Zlcic6XHJcbiAgICAgICAgdGhpcy5kcmFnZ2luZyA9IHRydWU7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2RyYWdPdXQnOlxyXG4gICAgICBjYXNlICdkcm9wJzpcclxuICAgICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlICdhZGRlZFRvUXVldWUnOlxyXG4gICAgICAgIGlmICh0aGlzLmNyb3AgJiYgISRldmVudC5maWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHtcclxuICAgICAgICAgIHRoaXMudXBsb2FkSW5wdXQuZW1pdCh7IHR5cGU6ICdyZW1vdmUnLCBpZDogJGV2ZW50LmZpbGUuaWQgfSk7XHJcbiAgICAgICAgICB0aGlzLmZpbGVFdmVudC5lbWl0KHsgbWVzc2FnZTogJ2Nyb3BJbnZhbGlkRmlsZVR5cGUnLCBkYXRhOiAkZXZlbnQuZmlsZSB9KTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc2tpcEN1c3RvbVZhbGlkYXRpb24gJiYgdGhpcy5maWxlU2VydmljZUNvbmZpZy5maWxlVmFsaWRhdGlvbikge1xyXG4gICAgICAgICAgdGhpcy5maWxlU2VydmljZUNvbmZpZy5maWxlVmFsaWRhdGlvbih0aGlzLmZpbGVTaXplLCAkZXZlbnQuZmlsZSkudGhlbih2YWxpZCA9PiB7XHJcbiAgICAgICAgICAgIGlmICh2YWxpZCkge1xyXG4gICAgICAgICAgICAgIHRoaXMub25VcGxvYWRPdXRwdXQoJGV2ZW50LCB0cnVlKVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMudXBsb2FkSW5wdXQuZW1pdCh7IHR5cGU6ICdyZW1vdmUnLCBpZDogJGV2ZW50LmZpbGUuaWQgfSk7XHJcbiAgICAgICAgICAgICAgLy8gdGhpcy5maWxlRXZlbnQuZW1pdCh7IG1lc3NhZ2U6ICdjcm9wSW52YWxpZEZpbGVUeXBlJywgZGF0YTogJGV2ZW50LmZpbGUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGxldCBmO1xyXG4gICAgICAgICAgaWYgKHRoaXMuY2hhbmdlRmlsZUluZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgZiA9IHRoaXMuZmlsZXNbdGhpcy5jaGFuZ2VGaWxlSW5kZXhdO1xyXG4gICAgICAgICAgICBpZiAoZi4kbmV3RmlsZSkge1xyXG4gICAgICAgICAgICAgIHRoaXMudXBsb2FkSW5wdXQuZW1pdCh7IHR5cGU6ICdyZW1vdmUnLCBpZDogZi4kbmV3RmlsZS5pZCB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmLiRuZXdGaWxlID0gJGV2ZW50LmZpbGU7XHJcbiAgICAgICAgICAgIGYuY3VzdG9tID0gJGV2ZW50LmZpbGU7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlRmlsZUluZGV4ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZiA9IHsgY3VzdG9tOiAkZXZlbnQuZmlsZSwgJG5ld0ZpbGU6ICRldmVudC5maWxlIH07XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm5ld0ZpbGVQb3NpdGlvbiA9PT0gJ2xhc3QnKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5maWxlcy5wdXNoKGYpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHRoaXMuZmlsZXMudW5zaGlmdChmKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHRoaXMuY2FuSW1hZ2VQcmV2aWV3KCRldmVudC5maWxlLnR5cGUpKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNyb3ApIHtcclxuICAgICAgICAgICAgICB0aGlzLmNhbnZhc1JvdGF0aW9uWyRldmVudC5maWxlLmlkXSA9IDA7XHJcbiAgICAgICAgICAgICAgdGhpcy5jcm9wU291cmNlSW1hZ2VzWyRldmVudC5maWxlLmlkXSA9ICRldmVudC5maWxlLm5hdGl2ZUZpbGU7XHJcbiAgICAgICAgICAgICAgdGhpcy5jcm9wcGVySW1hZ2VMb2FkZWRbJGV2ZW50LmZpbGUuaWRdID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMucHJlcGFyZVJlc3BvbnNlKCk7XHJcbiAgICAgICAgICB0aGlzLmZpbGVFdmVudC5lbWl0KHsgbWVzc2FnZTogJ2ZpbGVBZGRlZCcsIGRhdGE6IGYgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSAnZG9uZSc6XHJcbiAgICAgICAgY29uc3QgZGYgPSB0aGlzLmZpbGVzLmZpbmQoZiA9PiBmLiRuZXdGaWxlID09PSAkZXZlbnQuZmlsZSk7XHJcbiAgICAgICAgaWYgKGRmKSB7XHJcbiAgICAgICAgICBpZiAoZGYuJG5ld0ZpbGUucmVzcG9uc2VTdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICB0aGlzLmZpbGVzW3RoaXMuZmlsZXMuaW5kZXhPZihkZildLmN1c3RvbSA9IGRmLiRuZXdGaWxlLnJlc3BvbnNlO1xyXG4gICAgICAgICAgICBkZi4kbmV3RmlsZSA9IG51bGw7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnZXJyb3Igb24gdXBsb2FkJywgZGYuJGV2ZW50KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmhhc0ZpbGVzVG9VcGxvYWQpIHtcclxuICAgICAgICAgIHRoaXMucHJlcGFyZVJlc3BvbnNlKGZhbHNlKTtcclxuICAgICAgICAgIHRoaXMuZmlsZVNlcnZpY2UudXBsb2FkU3Vic2NyaXB0aW9uLm5leHQoe1xyXG4gICAgICAgICAgICBhY3Rpb246IHRoaXMuZmlsZXMuZmluZChmID0+ICEhZi4kbmV3RmlsZSkgPyAndXBsb2FkQ29udHJvbEZhaWxlZCcgOiAndXBsb2FkQ29udHJvbFN1Y2Nlc3MnXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcmVwYXJlUmVzcG9uc2UoZG9lbWl0ID0gdHJ1ZSkge1xyXG4gICAgaWYgKHRoaXMuaW5wdXRBcnJheSkge1xyXG4gICAgICBpZiAoIXRoaXMucmVzcG9uc2VGaWxlcykge1xyXG4gICAgICAgIHRoaXMucmVzcG9uc2VGaWxlcyA9IFtdO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMucmVzcG9uc2VGaWxlcy5sZW5ndGggPSAwO1xyXG4gICAgICB0aGlzLmZpbGVzLmZvckVhY2goZiA9PiB0aGlzLnJlc3BvbnNlRmlsZXMucHVzaCh7Li4uZi5jdXN0b20sICRuZXdGaWxlOiBmLiRuZXdGaWxlfSkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMuZmlsZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgdGhpcy5yZXNwb25zZUZpbGVzID0gbnVsbDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoIXRoaXMucmVzcG9uc2VGaWxlcykge1xyXG4gICAgICAgICAgdGhpcy5yZXNwb25zZUZpbGVzID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZmlsZXNbMF0uY3VzdG9tKS5mb3JFYWNoKGsgPT4ge1xyXG4gICAgICAgICAgdGhpcy5yZXNwb25zZUZpbGVzW2tdID0gdGhpcy5maWxlc1swXS5jdXN0b21ba107XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5yZXNwb25zZUZpbGVzLiRuZXdGaWxlID0gdGhpcy5maWxlc1swXS4kbmV3RmlsZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGRvZW1pdCkge1xyXG4gICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMucmVzcG9uc2VGaWxlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY29uc29sZS5sb2coJ2VtaXQnLCB0aGlzLmZpbGVzWzFdLCB7IC4uLnRoaXMuZmlsZXNbMV0uY3VzdG9tLCAkbmV3RmlsZTogdGhpcy5maWxlc1sxXS4kbmV3RmlsZSB9KTtcclxuICAgIC8vIHRoaXMub25DaGFuZ2UodGhpcy5pbnB1dEFycmF5ID9cclxuICAgIC8vICAgdGhpcy5maWxlcy5tYXAoZiA9PiAoeyAuLi5mLmN1c3RvbSwgJG5ld0ZpbGU6IGYuJG5ld0ZpbGV9KSkgOlxyXG4gICAgLy8gICAodGhpcy5maWxlcy5sZW5ndGggPiAwID8geyAuLi50aGlzLmZpbGVzWzBdLmN1c3RvbSwgJG5ld0ZpbGU6IHRoaXMuZmlsZXNbMF0uJG5ld0ZpbGUgfSA6IG51bGwpKTtcclxuICAgIC8vIHRoaXMub25DaGFuZ2UodGhpcy5pbnB1dEFycmF5ID9cclxuICAgIC8vICAgdGhpcy5maWxlcyA6XHJcbiAgICAvLyAgICh0aGlzLmZpbGVzLmxlbmd0aCA+IDAgPyB0aGlzLmZpbGVzWzBdIDogbnVsbCkpO1xyXG4gIH1cclxuXHJcbiAgYmVmb3JlU2F2ZSgpIHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzLCByZWopID0+IHtcclxuICAgICAgdGhpcy5maWxlcy5mb3JFYWNoKGYgPT4ge1xyXG4gICAgICAgIGlmIChmLiRuZXdGaWxlICYmIGYuJG5ld0ZpbGUucHJvZ3Jlc3Muc3RhdHVzID09PSAyKSB7XHJcbiAgICAgICAgICBmLiRuZXdGaWxlLnByb2dyZXNzLnN0YXR1cyA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNyb3AgJiYgZi4kbmV3RmlsZSAmJiAhdGhpcy5pbWFnZXNEb25lW2YuJG5ld0ZpbGUuaWRdKSB7XHJcbiAgICAgICAgICB0aGlzLmNyb3BwZXJEb25lKGYuJG5ld0ZpbGUuaWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgcmVzKCdkb25lJyk7XHJcbiAgICAgIH0sIDI1MCk7XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgZmlsZUNoYW5nZUV2ZW50KGV2ZW50OiBhbnksIGY6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5jaGFuZ2VGaWxlSW5kZXggPSB0aGlzLmZpbGVzLmluZGV4T2YoZik7XHJcbiAgfVxyXG5cclxuICBzdGFydENyb3BQcmV2aWV3KGlkKSB7XHJcbiAgICBjbGVhclRpbWVvdXQodGhpcy5jcm9wUHJldmlld1RpbWVvdXRzW2lkXSk7XHJcbiAgICB0aGlzLnNob3dDcm9wUHJldmlld1tpZF0gPSAhIXRoaXMuY3JvcFNvdXJjZUltYWdlc1tpZF07XHJcbiAgfVxyXG5cclxuICBzdG9wQ3JvcFByZXZpZXcoaWQpIHtcclxuICAgIHRoaXMuY3JvcFByZXZpZXdUaW1lb3V0c1tpZF0gPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy5zaG93Q3JvcFByZXZpZXdbaWRdID0gZmFsc2U7XHJcbiAgICB9LCAyNTApO1xyXG4gIH1cclxuXHJcbiAgem9vbUNyb3BwZWRJbWFnZShkaXIsIGlkKSB7XHJcbiAgICBsZXQgc2NhbGUgPSB0aGlzLnRyYW5zZm9ybVtpZF0uc2NhbGU7XHJcbiAgICBzY2FsZSArPSBkaXI7XHJcbiAgICBpZiAoc2NhbGUgPCAwLjEpIHtcclxuICAgICAgc2NhbGUgPSAwLjE7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRyYW5zZm9ybVtpZF0gPSB7XHJcbiAgICAgIC4uLnRoaXMudHJhbnNmb3JtW2lkXSxcclxuICAgICAgc2NhbGVcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByb3RhdGVDcm9wcGVkSW1hZ2UoZGlyLCBpZCkge1xyXG4gICAgdGhpcy5jYW52YXNSb3RhdGlvbltpZF0gKz0gZGlyO1xyXG4gICAgY29uc3QgZmxpcHBlZEggPSB0aGlzLnRyYW5zZm9ybVtpZF0uZmxpcEg7XHJcbiAgICBjb25zdCBmbGlwcGVkViA9IHRoaXMudHJhbnNmb3JtW2lkXS5mbGlwVjtcclxuICAgIHRoaXMudHJhbnNmb3JtW2lkXSA9IHtcclxuICAgICAgLi4udGhpcy50cmFuc2Zvcm1baWRdLFxyXG4gICAgICBmbGlwSDogZmxpcHBlZFYsXHJcbiAgICAgIGZsaXBWOiBmbGlwcGVkSFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIG9uSW1hZ2VDcm9wcGVkKGV2ZW50OiBJbWFnZUNyb3BwZWRFdmVudCwgaWQpIHtcclxuICAgIHRoaXMuY3JvcHBlZEltYWdlc1tpZF0gPSBldmVudC5iYXNlNjQ7XHJcbiAgICB0aGlzLmltYWdlQ3JvcHBlZC5lbWl0KGV2ZW50LmJhc2U2NCk7XHJcbiAgfVxyXG5cclxuICBpbWFnZUxvYWRlZChpZCkge1xyXG4gICAgdGhpcy5zaG93Q3JvcHBlciA9IHRydWU7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy50cmFuc2Zvcm1baWRdID0ge1xyXG4gICAgICAgIHNjYWxlOiAxXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGNyb3BwZXJSZWFkeShzb3VyY2VJbWFnZURpbWVuc2lvbnM6IERpbWVuc2lvbnMsIGlkKSB7XHJcbiAgICB0aGlzLmNyb3BwZXJJbWFnZUxvYWRlZFtpZF0gPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgbG9hZEltYWdlRmFpbGVkKCkge1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlTWVudVZpc2liaWxpdHkoZikge1xyXG4gICAgdGhpcy5maWxlTWVudU9wZW5lZCA9IGY7XHJcbiAgfVxyXG5cclxuICBtZW51Q2xpY2soKSB7XHJcbiAgICB0aGlzLmZpbGVNZW51T3BlbmVkID0gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcblxyXG4gIHdyaXRlVmFsdWUob2JqOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5wdXRBcnJheSA9IG9iaiBpbnN0YW5jZW9mIEFycmF5O1xyXG4gICAgaWYgKHRoaXMuaW5wdXRBcnJheSkge1xyXG4gICAgICB0aGlzLmZpbGVzID0gb2JqLm1hcChmID0+ICh7IGN1c3RvbTogZiwgJG5ld0ZpbGU6IG51bGwgfSkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5maWxlcyA9IG9iaiA/IFsgeyBjdXN0b206b2JqLCAkbmV3RmlsZTogbnVsbH0gXSA6IFtdO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jcm9wU291cmNlSW1hZ2VzID0ge307XHJcbiAgfVxyXG5cclxuICBjcm9wcGVyRG9uZShpZCkge1xyXG4gICAgY29uc3QgZiA9IHRoaXMuZmlsZXMuZmluZChmeCA9PiBmeC4kbmV3RmlsZSAmJiBmeC4kbmV3RmlsZS5pZCA9PT0gaWQpO1xyXG4gICAgaWYgKGYpIHtcclxuICAgICAgY29uc3QgdXJsID0gdGhpcy5jcm9wcGVkSW1hZ2VzW2lkXTtcclxuICAgICAgZmV0Y2godXJsKVxyXG4gICAgICAgIC50aGVuKHJlcyA9PiByZXMuYmxvYigpKVxyXG4gICAgICAgIC50aGVuKGJsb2IgPT4ge1xyXG4gICAgICAgICAgZi4kbmV3RmlsZS5uYXRpdmVGaWxlID0gbmV3IEZpbGUoWyBibG9iIF0sICdjcm9wLnBuZycsIHtcclxuICAgICAgICAgICAgdHlwZTogJ2ltYWdlL3BuZydcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgZi4kbmV3RmlsZS5uYW1lID0gJ2Nyb3AucG5nJztcclxuICAgICAgICAgIGYuJG5ld0ZpbGUuc2l6ZSA9IGYuJG5ld0ZpbGUubmF0aXZlRmlsZS5zaXplO1xyXG4gICAgICAgICAgZi4kbmV3RmlsZS50eXBlID0gZi4kbmV3RmlsZS5uYXRpdmVGaWxlLnR5cGU7XHJcbiAgICAgICAgICB0aGlzLmltYWdlc0RvbmVbaWRdID0gdHJ1ZTtcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwibGFiZWxcIiAqbmdJZj1cImxhYmVsXCI+XHJcbiAgPGRpdiBjbGFzcz1cInRleHQtY29udGFpbmVyXCIgW21hdFRvb2x0aXBdPVwicmVxdWlyZWQgPyB0cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoJ3VpLmNvbnRyb2xzLnZhbGlkYXRpb24ucmVxdWlyZWQnKSA6IHVuZGVmaW5lZFwiIFttYXRUb29sdGlwUG9zaXRpb25dPVwiJ2Fib3ZlJ1wiPlxyXG4gICAgPGRpdiBjbGFzcz1cInRleHRcIj57e2xhYmVsfX08L2Rpdj5cclxuICAgIDxkaXYgKm5nSWY9XCJyZXF1aXJlZFwiIGNsYXNzPVwicmVxdWlyZWRcIj4qPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cImZpbGVzLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cIntkcmFnZ2luZzogZHJhZ2dpbmcsIGRpc2FibGVkOiB1cGxvYWRpbmcgfHwgIWVkaXRhYmxlfVwiPlxyXG5cclxuICA8ZGl2IGNsYXNzPVwiZXhpc3RpbmctZmlsZXNcIj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiZmlsZS1jb250YWluZXJcIiAqbmdGb3I9XCJsZXQgZiBvZiBmaWxlc1wiPlxyXG5cclxuICAgICAgPGRpdiBjbGFzcz1cImZpbGUtbWVudVwiIChjbGljayk9XCJ0b2dnbGVNZW51VmlzaWJpbGl0eShmKVwiICpuZ0lmPVwiIWN1c3RvbUZpbGVNZW51ICYmIGVkaXRhYmxlICYmICF1cGxvYWRpbmdcIj5cclxuICAgICAgICA8bWF0LWljb24+bWVudTwvbWF0LWljb24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZmlsZS1tZW51LWNvbnRhaW5lciBtYXQtZWxldmF0aW9uLXoyXCIgW25nQ2xhc3NdPVwie3Zpc2libGU6IGYgPT09IGZpbGVNZW51T3BlbmVkfVwiIChjbGljayk9XCJtZW51Q2xpY2soKVwiIChtb3VzZWxlYXZlKT1cIm1lbnVDbGljaygpXCI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtZW51VGVtcGxhdGVcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cIm1lbnUtaXRlbVwiPnt7IHRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgndWkuY29udHJvbHMudWktZmlsZS11cGxvYWRlci5tZW51LmNoYW5nZScpIH19XHJcbiAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cIiFyZWZyZXNoQWRkSW5wdXRcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCIgdHlwZT1cImZpbGVcIiBuZ0ZpbGVTZWxlY3QgW29wdGlvbnNdPVwidXBsb2FkT3B0aW9uc1wiIChjaGFuZ2UpPVwiZmlsZUNoYW5nZUV2ZW50KCRldmVudCwgZilcIlxyXG4gICAgICAgICAgICAgICAgICAgKHVwbG9hZE91dHB1dCk9XCJvblVwbG9hZE91dHB1dCgkZXZlbnQpXCIgW3VwbG9hZElucHV0XT1cInVwbG9hZElucHV0XCI+XHJcbiAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1lbnUtaXRlbVwiIChjbGljayk9XCJyZW1vdmUoZilcIj57eyB0cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoJ3VpLmNvbnRyb2xzLnVpLWZpbGUtdXBsb2FkZXIubWVudS5kZWxldGUnKSB9fTwvZGl2PlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtZW51VGVtcGxhdGVcIj5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJtZW51VGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie2ZpbGVJbnB1dDogZmlsZUlucHV0fVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2ZpbGVJbnB1dD5cclxuICAgICAgICAgIDxpbnB1dCBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCIgdHlwZT1cImZpbGVcIiBuZ0ZpbGVTZWxlY3QgW29wdGlvbnNdPVwidXBsb2FkT3B0aW9uc1wiIChjaGFuZ2UpPVwiZmlsZUNoYW5nZUV2ZW50KCRldmVudCwgZilcIlxyXG4gICAgICAgICAgICAgICAgICh1cGxvYWRPdXRwdXQpPVwib25VcGxvYWRPdXRwdXQoJGV2ZW50KVwiIFt1cGxvYWRJbnB1dF09XCJ1cGxvYWRJbnB1dFwiPlxyXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8ZGl2ICpuZ0lmPVwiY3JvcCAmJiAhY3JvcERvbmUoZilcIiAobW91c2VlbnRlcik9XCJzdGFydENyb3BQcmV2aWV3KGYuJG5ld0ZpbGUuaWQpXCIgKG1vdXNlbGVhdmUpPVwic3RvcENyb3BQcmV2aWV3KGYuJG5ld0ZpbGUuaWQpXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImNyb3AtY29udGFpbmVyXCIgW25nU3R5bGVdPVwibmdBZGRTdHlsZVwiPlxyXG5cclxuICAgICAgICAgIDx1aS1maWxlICpuZ0lmPVwiZmFsc2UgJiYgZmlsZXMubGVuZ3RoID4gMCAmJiAhY3JvcFNvdXJjZUltYWdlc1wiIFtmaWxlU2l6ZV09XCJmaWxlU2l6ZVwiIFtzcmNEYXRhXT1cImZpbGVzWzBdLmN1c3RvbVwiIFtuZ0NsYXNzXT1cIntyb3VuZGVkOiBjcm9wUm91bmRlZH1cIj48L3VpLWZpbGU+XHJcblxyXG4gICAgICAgICAgPG1hdC1zcGlubmVyICpuZ0lmPVwiIWNyb3BwZXJJbWFnZUxvYWRlZFtmLiRuZXdGaWxlLmlkXSAmJiBjcm9wU291cmNlSW1hZ2VzW2YuJG5ld0ZpbGUuaWRdXCIgW2RpYW1ldGVyXT1cIjc1XCI+PC9tYXQtc3Bpbm5lcj5cclxuXHJcbiAgICAgICAgICA8aW1hZ2UtY3JvcHBlciAqbmdJZj1cImNyb3BTb3VyY2VJbWFnZXNbZi4kbmV3RmlsZS5pZF1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlRmlsZV09XCJjcm9wU291cmNlSW1hZ2VzW2YuJG5ld0ZpbGUuaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFttYWludGFpbkFzcGVjdFJhdGlvXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRhaW5XaXRoaW5Bc3BlY3RSYXRpb109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbYXNwZWN0UmF0aW9dPVwiYXNwZWN0UmF0aW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgW3Jlc2l6ZVRvV2lkdGhdPVwiY3JvcE1heFdpZHRoXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFtvbmx5U2NhbGVEb3duXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFtyb3VuZENyb3BwZXJdPVwiY3JvcFJvdW5kZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2NhbnZhc1JvdGF0aW9uXT1cImNhbnZhc1JvdGF0aW9uW2YuJG5ld0ZpbGUuaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFt0cmFuc2Zvcm1dPVwidHJhbnNmb3JtW2YuJG5ld0ZpbGUuaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFthbGlnbkltYWdlXT1cIidjZW50ZXInXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5kaXNwbGF5XT1cInNob3dDcm9wcGVyID8gbnVsbCA6ICdub25lJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybWF0XT1cIidwbmcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIChpbWFnZUNyb3BwZWQpPVwib25JbWFnZUNyb3BwZWQoJGV2ZW50LCBmLiRuZXdGaWxlLmlkKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAoaW1hZ2VMb2FkZWQpPVwiaW1hZ2VMb2FkZWQoZi4kbmV3RmlsZS5pZClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGNyb3BwZXJSZWFkeSk9XCJjcm9wcGVyUmVhZHkoJGV2ZW50LCBmLiRuZXdGaWxlLmlkKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAobG9hZEltYWdlRmFpbGVkKT1cImxvYWRJbWFnZUZhaWxlZCgpXCJcclxuICAgICAgICAgID48L2ltYWdlLWNyb3BwZXI+XHJcblxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNyb3AtcHJldmlldyBtYXQtZWxldmF0aW9uLXoyXCIgW2NsYXNzXT1cInByZXZpZXdQb3NpdGlvblwiICpuZ0lmPVwidHJ1ZSB8fCAoc2hvd0Nyb3BQcmV2aWV3W2YuJG5ld0ZpbGUuaWRdICYmIGNyb3BwZXJJbWFnZUxvYWRlZFtmLiRuZXdGaWxlLmlkXSlcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNyb3AtbWVudVwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbiAoY2xpY2spPVwiem9vbUNyb3BwZWRJbWFnZSguMSwgZi4kbmV3RmlsZS5pZClcIj56b29tX2luPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICA8bWF0LWljb24gKGNsaWNrKT1cInpvb21Dcm9wcGVkSW1hZ2UoLSAuMSwgZi4kbmV3RmlsZS5pZClcIj56b29tX291dDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgPG1hdC1pY29uIChjbGljayk9XCJyb3RhdGVDcm9wcGVkSW1hZ2UoLTEsIGYuJG5ld0ZpbGUuaWQpXCI+cm90YXRlX2xlZnQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbiAoY2xpY2spPVwicm90YXRlQ3JvcHBlZEltYWdlKDEsIGYuJG5ld0ZpbGUuaWQpXCI+cm90YXRlX3JpZ2h0PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMSAxIDEwMCVcIj48L2Rpdj5cclxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJtZW51LWl0ZW1cIj5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbj51cGxvYWRfZmlsZTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICA8aW5wdXQgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIHR5cGU9XCJmaWxlXCIgbmdGaWxlU2VsZWN0IFtvcHRpb25zXT1cInVwbG9hZE9wdGlvbnNcIiAoY2hhbmdlKT1cImZpbGVDaGFuZ2VFdmVudCgkZXZlbnQsIGYpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAodXBsb2FkT3V0cHV0KT1cIm9uVXBsb2FkT3V0cHV0KCRldmVudClcIiBbdXBsb2FkSW5wdXRdPVwidXBsb2FkSW5wdXRcIj5cclxuICAgICAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbiAoY2xpY2spPVwicmVtb3ZlKGYpXCI+ZGVsZXRlX291dGxpbmU8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OiAxIDEgMTAwJVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbiAoY2xpY2spPVwiY3JvcHBlckRvbmUoZi4kbmV3RmlsZS5pZClcIj5kb25lPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxpbWcgW3NyY109XCJjcm9wcGVkSW1hZ2VzW2YuJG5ld0ZpbGUuaWRdXCIgW25nQ2xhc3NdPVwie3JvdW5kZWQ6IGNyb3BSb3VuZGVkfVwiLz5cclxuICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcblxyXG5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWNyb3AgfHwgY3JvcERvbmUoZilcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZmlsZVRlbXBsYXRlXCI+XHJcbiAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZmlsZVRlbXBsYXRlXCIgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntmaWxlOiBmLCBmaWxlSW5wdXQ6IGZpbGVJbnB1dDJ9XCI+PC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZmlsZUlucHV0Mj5cclxuICAgICAgICAgICAgPGlucHV0IHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIiB0eXBlPVwiZmlsZVwiIG5nRmlsZVNlbGVjdCBbb3B0aW9uc109XCJ1cGxvYWRPcHRpb25zXCIgKGNoYW5nZSk9XCJmaWxlQ2hhbmdlRXZlbnQoJGV2ZW50LCBmKVwiXHJcbiAgICAgICAgICAgICAgICAgICAodXBsb2FkT3V0cHV0KT1cIm9uVXBsb2FkT3V0cHV0KCRldmVudClcIiBbdXBsb2FkSW5wdXRdPVwidXBsb2FkSW5wdXRcIj5cclxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgIDx1aS1maWxlICpuZ0lmPVwiIWZpbGVUZW1wbGF0ZVwiIFtmaWxlU2l6ZV09XCJmaWxlU2l6ZVwiIFtzcmNEYXRhXT1cImYuJG5ld0ZpbGUgPyBmLiRuZXdGaWxlOiBmLmN1c3RvbVwiIFtuZ0NsYXNzXT1cIntyb3VuZGVkOiBjcm9wICYmIGNyb3BSb3VuZGVkfVwiPlxyXG4gICAgICAgIDwvdWktZmlsZT5cclxuXHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImYuJG5ld0ZpbGVcIj5cclxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmLiRuZXdGaWxlLnJlc3BvbnNlU3RhdHVzICYmIGYuJG5ld0ZpbGUucmVzcG9uc2VTdGF0dXMgIT09IDIwMFwiIGNsYXNzPVwicHJvZ3Jlc3MtY29udGFpbmVyIGVycm9yXCI+XHJcbiAgICAgICAgICAgIHt7IHRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCgndWkuY29udHJvbHMudWktZmlsZS11cGxvYWRlci51cGxvYWRFcnJvcicsIGYuJG5ld0ZpbGUucmVzcG9uc2UpIH19XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZi4kbmV3RmlsZS5yZXNwb25zZVN0YXR1cyAmJiBmLiRuZXdGaWxlLnByb2dyZXNzLnN0YXR1cyA9PT0gMVwiIGNsYXNzPVwicHJvZ3Jlc3MtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzc1wiIFtuZ1N0eWxlXT1cInt3aWR0aDogZi4kbmV3RmlsZS5wcm9ncmVzcy5kYXRhLnBlcmNlbnRhZ2UgKyAnJSd9XCI+PC9kaXY+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJmaWxlLWNvbnRhaW5lciBhZGRcIiBuZ0ZpbGVEcm9wICBbb3B0aW9uc109XCJ1cGxvYWRPcHRpb25zXCIgKHVwbG9hZE91dHB1dCk9XCJvblVwbG9hZE91dHB1dCgkZXZlbnQpXCIgW3VwbG9hZElucHV0XT1cInVwbG9hZElucHV0XCIgW25nQ2xhc3NdPVwie3Zpc2libGU6IGZpbGVzLmxlbmd0aCA8IG1heEZpbGVzIHx8IG1heEZpbGVzID09PSAwfVwiIFtuZ1N0eWxlXT1cImFkZEZpbGVUZW1wbGF0ZSA/IHt9IDogbmdBZGRTdHlsZVwiPlxyXG4gICAgPGxhYmVsPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWRkRmlsZVRlbXBsYXRlXCI+XHJcbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImFkZEZpbGVUZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWFkZEZpbGVUZW1wbGF0ZVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1cGxvYWQtaW1hZ2UtY29udGFpbmVyXCI+PC9kaXY+XHJcbiAgICAgICAgPGltZyBbc3JjXT1cImFkZEZpbGVJbWdTcmNcIiBbbmdDbGFzc109XCJ7J3dpdGgtaGludCc6IGFkZEhpbnR9XCIgLz5cclxuICAgICAgICA8ZGl2ICpuZ0lmPVwiYWRkSGludFwiIGNsYXNzPVwiYWRkLWhpbnRcIj57e2FkZEhpbnR9fTwvZGl2PlxyXG4gICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPGlucHV0IHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIiB0eXBlPVwiZmlsZVwiIG5nRmlsZVNlbGVjdCBbb3B0aW9uc109XCJ1cGxvYWRPcHRpb25zXCIgKHVwbG9hZE91dHB1dCk9XCJvblVwbG9hZE91dHB1dCgkZXZlbnQpXCIgW3VwbG9hZElucHV0XT1cInVwbG9hZElucHV0XCIgW211bHRpcGxlXT1cIm1heEZpbGVzID09PSAwICYmIG11bHRpcGxlXCI+XHJcbiAgICA8L2xhYmVsPlxyXG4gIDwvZGl2PlxyXG5cclxuPC9kaXY+XHJcbiJdfQ==
|