ng2-file-upload 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,404 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FileLikeObject } from './file-like-object.class';
3
+ import { FileItem } from './file-item.class';
4
+ import { FileType } from './file-type.class';
5
+ function isFile(value) {
6
+ return (File && value instanceof File);
7
+ }
8
+ export class FileUploader {
9
+ constructor(options) {
10
+ this.isUploading = false;
11
+ this.queue = [];
12
+ this.progress = 0;
13
+ this._nextIndex = 0;
14
+ this.options = {
15
+ autoUpload: false,
16
+ isHTML5: true,
17
+ filters: [],
18
+ removeAfterUpload: false,
19
+ disableMultipart: false,
20
+ formatDataFunction: (item) => item._file,
21
+ formatDataFunctionIsAsync: false,
22
+ url: ''
23
+ };
24
+ this.setOptions(options);
25
+ this.response = new EventEmitter();
26
+ }
27
+ setOptions(options) {
28
+ this.options = Object.assign(this.options, options);
29
+ this.authToken = this.options.authToken;
30
+ this.authTokenHeader = this.options.authTokenHeader || 'Authorization';
31
+ this.autoUpload = this.options.autoUpload;
32
+ this.options.filters?.unshift({ name: 'queueLimit', fn: this._queueLimitFilter });
33
+ if (this.options.maxFileSize) {
34
+ this.options.filters?.unshift({ name: 'fileSize', fn: this._fileSizeFilter });
35
+ }
36
+ if (this.options.allowedFileType) {
37
+ this.options.filters?.unshift({ name: 'fileType', fn: this._fileTypeFilter });
38
+ }
39
+ if (this.options.allowedMimeType) {
40
+ this.options.filters?.unshift({ name: 'mimeType', fn: this._mimeTypeFilter });
41
+ }
42
+ for (let i = 0; i < this.queue.length; i++) {
43
+ this.queue[i].url = this.options.url;
44
+ }
45
+ }
46
+ addToQueue(files, _options, filters) {
47
+ let options = _options;
48
+ const list = [];
49
+ for (const file of files) {
50
+ list.push(file);
51
+ }
52
+ const arrayOfFilters = this._getFilters(filters);
53
+ const count = this.queue.length;
54
+ const addedFileItems = [];
55
+ list.map((some) => {
56
+ if (!options) {
57
+ options = this.options;
58
+ }
59
+ const temp = new FileLikeObject(some);
60
+ if (this._isValidFile(temp, arrayOfFilters, options)) {
61
+ const fileItem = new FileItem(this, some, options);
62
+ addedFileItems.push(fileItem);
63
+ this.queue.push(fileItem);
64
+ this._onAfterAddingFile(fileItem);
65
+ }
66
+ else {
67
+ if (typeof this._failFilterIndex === 'number' && this._failFilterIndex >= 0) {
68
+ const filter = arrayOfFilters[this._failFilterIndex];
69
+ this._onWhenAddingFileFailed(temp, filter, options);
70
+ }
71
+ }
72
+ });
73
+ if (this.queue.length !== count) {
74
+ this._onAfterAddingAll(addedFileItems);
75
+ this.progress = this._getTotalProgress();
76
+ }
77
+ this._render();
78
+ if (this.options.autoUpload) {
79
+ this.uploadAll();
80
+ }
81
+ }
82
+ removeFromQueue(value) {
83
+ const index = this.getIndexOfItem(value);
84
+ const item = this.queue[index];
85
+ if (item.isUploading) {
86
+ item.cancel();
87
+ }
88
+ this.queue.splice(index, 1);
89
+ this.progress = this._getTotalProgress();
90
+ }
91
+ clearQueue() {
92
+ while (this.queue.length) {
93
+ this.queue[0].remove();
94
+ }
95
+ this.progress = 0;
96
+ }
97
+ uploadItem(value) {
98
+ const index = this.getIndexOfItem(value);
99
+ const item = this.queue[index];
100
+ const transport = this.options.isHTML5 ? '_xhrTransport' : '_iframeTransport';
101
+ item._prepareToUploading();
102
+ if (this.isUploading) {
103
+ return;
104
+ }
105
+ this.isUploading = true;
106
+ this[transport](item);
107
+ }
108
+ cancelItem(value) {
109
+ const index = this.getIndexOfItem(value);
110
+ const item = this.queue[index];
111
+ const prop = this.options.isHTML5 ? item._xhr : item._form;
112
+ if (item && item.isUploading) {
113
+ prop.abort();
114
+ }
115
+ }
116
+ uploadAll() {
117
+ const items = this.getNotUploadedItems().filter((item) => !item.isUploading);
118
+ if (!items.length) {
119
+ return;
120
+ }
121
+ items.map((item) => item._prepareToUploading());
122
+ items[0].upload();
123
+ }
124
+ cancelAll() {
125
+ const items = this.getNotUploadedItems();
126
+ items.map((item) => item.cancel());
127
+ }
128
+ isFile(value) {
129
+ return isFile(value);
130
+ }
131
+ isFileLikeObject(value) {
132
+ return value instanceof FileLikeObject;
133
+ }
134
+ getIndexOfItem(value) {
135
+ return typeof value === 'number' ? value : this.queue.indexOf(value);
136
+ }
137
+ getNotUploadedItems() {
138
+ return this.queue.filter((item) => !item.isUploaded);
139
+ }
140
+ getReadyItems() {
141
+ return this.queue
142
+ .filter((item) => (item.isReady && !item.isUploading))
143
+ .sort((item1, item2) => item1.index - item2.index);
144
+ }
145
+ onAfterAddingAll(fileItems) {
146
+ return { fileItems };
147
+ }
148
+ onBuildItemForm(fileItem, form) {
149
+ return { fileItem, form };
150
+ }
151
+ onAfterAddingFile(fileItem) {
152
+ return { fileItem };
153
+ }
154
+ onWhenAddingFileFailed(item, filter, options) {
155
+ return { item, filter, options };
156
+ }
157
+ onBeforeUploadItem(fileItem) {
158
+ return { fileItem };
159
+ }
160
+ onProgressItem(fileItem, progress) {
161
+ return { fileItem, progress };
162
+ }
163
+ onProgressAll(progress) {
164
+ return { progress };
165
+ }
166
+ onSuccessItem(item, response, status, headers) {
167
+ return { item, response, status, headers };
168
+ }
169
+ onErrorItem(item, response, status, headers) {
170
+ return { item, response, status, headers };
171
+ }
172
+ onCancelItem(item, response, status, headers) {
173
+ return { item, response, status, headers };
174
+ }
175
+ onCompleteItem(item, response, status, headers) {
176
+ return { item, response, status, headers };
177
+ }
178
+ onCompleteAll() {
179
+ return void 0;
180
+ }
181
+ _mimeTypeFilter(item) {
182
+ return !(item?.type && this.options.allowedMimeType && this.options.allowedMimeType?.indexOf(item.type) === -1);
183
+ }
184
+ _fileSizeFilter(item) {
185
+ return !(this.options.maxFileSize && item.size > this.options.maxFileSize);
186
+ }
187
+ _fileTypeFilter(item) {
188
+ return !(this.options.allowedFileType &&
189
+ this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
190
+ }
191
+ _onErrorItem(item, response, status, headers) {
192
+ item._onError(response, status, headers);
193
+ this.onErrorItem(item, response, status, headers);
194
+ }
195
+ _onCompleteItem(item, response, status, headers) {
196
+ item._onComplete(response, status, headers);
197
+ this.onCompleteItem(item, response, status, headers);
198
+ const nextItem = this.getReadyItems()[0];
199
+ this.isUploading = false;
200
+ if (nextItem) {
201
+ nextItem.upload();
202
+ return;
203
+ }
204
+ this.onCompleteAll();
205
+ this.progress = this._getTotalProgress();
206
+ this._render();
207
+ }
208
+ _headersGetter(parsedHeaders) {
209
+ return (name) => {
210
+ if (name) {
211
+ return parsedHeaders[name.toLowerCase()] || undefined;
212
+ }
213
+ return parsedHeaders;
214
+ };
215
+ }
216
+ _xhrTransport(item) {
217
+ // tslint:disable-next-line:no-this-assignment
218
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
219
+ const that = this;
220
+ const xhr = item._xhr = new XMLHttpRequest();
221
+ let sendable;
222
+ this._onBeforeUploadItem(item);
223
+ if (typeof item._file.size !== 'number') {
224
+ throw new TypeError('The file specified is no longer valid');
225
+ }
226
+ if (!this.options.disableMultipart) {
227
+ sendable = new FormData();
228
+ this._onBuildItemForm(item, sendable);
229
+ const appendFile = () => sendable.append(item.alias, item._file, item.file.name);
230
+ if (!this.options.parametersBeforeFiles) {
231
+ appendFile();
232
+ }
233
+ // For AWS, Additional Parameters must come BEFORE Files
234
+ if (this.options.additionalParameter !== undefined) {
235
+ Object.keys(this.options.additionalParameter).forEach((key) => {
236
+ let paramVal = this.options.additionalParameter?.[key];
237
+ // Allow an additional parameter to include the filename
238
+ if (typeof paramVal === 'string' && paramVal.indexOf('{{file_name}}') >= 0 && item.file?.name) {
239
+ paramVal = paramVal.replace('{{file_name}}', item.file.name);
240
+ }
241
+ sendable.append(key, paramVal);
242
+ });
243
+ }
244
+ if (appendFile && this.options.parametersBeforeFiles) {
245
+ appendFile();
246
+ }
247
+ }
248
+ else {
249
+ if (this.options.formatDataFunction) {
250
+ sendable = this.options.formatDataFunction(item);
251
+ }
252
+ }
253
+ xhr.upload.onprogress = (event) => {
254
+ const progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
255
+ this._onProgressItem(item, progress);
256
+ };
257
+ xhr.onload = () => {
258
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
259
+ const response = this._transformResponse(xhr.response, headers);
260
+ const gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
261
+ const method = `_on${gist}Item`;
262
+ this[method](item, response, xhr.status, headers);
263
+ this._onCompleteItem(item, response, xhr.status, headers);
264
+ };
265
+ xhr.onerror = () => {
266
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
267
+ const response = this._transformResponse(xhr.response, headers);
268
+ this._onErrorItem(item, response, xhr.status, headers);
269
+ this._onCompleteItem(item, response, xhr.status, headers);
270
+ };
271
+ xhr.onabort = () => {
272
+ const headers = this._parseHeaders(xhr.getAllResponseHeaders());
273
+ const response = this._transformResponse(xhr.response, headers);
274
+ this._onCancelItem(item, response, xhr.status, headers);
275
+ this._onCompleteItem(item, response, xhr.status, headers);
276
+ };
277
+ if (item.method && item.url) {
278
+ xhr.open(item.method, item.url, true);
279
+ }
280
+ xhr.withCredentials = item.withCredentials;
281
+ if (this.options.headers) {
282
+ for (const header of this.options.headers) {
283
+ xhr.setRequestHeader(header.name, header.value);
284
+ }
285
+ }
286
+ if (item.headers.length) {
287
+ for (const header of item.headers) {
288
+ xhr.setRequestHeader(header.name, header.value);
289
+ }
290
+ }
291
+ if (this.authToken && this.authTokenHeader) {
292
+ xhr.setRequestHeader(this.authTokenHeader, this.authToken);
293
+ }
294
+ xhr.onreadystatechange = function () {
295
+ if (xhr.readyState == XMLHttpRequest.DONE) {
296
+ that.response.emit(xhr.responseText);
297
+ }
298
+ };
299
+ if (this.options.formatDataFunctionIsAsync) {
300
+ sendable.then((result) => xhr.send(JSON.stringify(result)));
301
+ }
302
+ else {
303
+ xhr.send(sendable);
304
+ }
305
+ this._render();
306
+ }
307
+ _getTotalProgress(value = 0) {
308
+ if (this.options.removeAfterUpload) {
309
+ return value;
310
+ }
311
+ const notUploaded = this.getNotUploadedItems().length;
312
+ const uploaded = notUploaded ? this.queue.length - notUploaded : this.queue.length;
313
+ const ratio = 100 / this.queue.length;
314
+ const current = value * ratio / 100;
315
+ return Math.round(uploaded * ratio + current);
316
+ }
317
+ _getFilters(filters) {
318
+ if (!filters) {
319
+ return this.options?.filters || [];
320
+ }
321
+ if (Array.isArray(filters)) {
322
+ return filters;
323
+ }
324
+ if (typeof filters === 'string') {
325
+ const names = filters.match(/[^\s,]+/g);
326
+ return this.options?.filters || []
327
+ .filter((filter) => names?.indexOf(filter.name) !== -1);
328
+ }
329
+ return this.options?.filters || [];
330
+ }
331
+ _render() {
332
+ return void 0;
333
+ }
334
+ _queueLimitFilter() {
335
+ return this.options.queueLimit === undefined || this.queue.length < this.options.queueLimit;
336
+ }
337
+ _isValidFile(file, filters, options) {
338
+ this._failFilterIndex = -1;
339
+ return !filters.length ? true : filters.every((filter) => {
340
+ if (typeof this._failFilterIndex === 'number') {
341
+ this._failFilterIndex++;
342
+ }
343
+ return filter.fn.call(this, file, options);
344
+ });
345
+ }
346
+ _isSuccessCode(status) {
347
+ return (status >= 200 && status < 300) || status === 304;
348
+ }
349
+ _transformResponse(response, headers) {
350
+ return response;
351
+ }
352
+ _parseHeaders(headers) {
353
+ const parsed = {};
354
+ let key;
355
+ let val;
356
+ let i;
357
+ if (!headers) {
358
+ return parsed;
359
+ }
360
+ headers.split('\n').map((line) => {
361
+ i = line.indexOf(':');
362
+ key = line.slice(0, i).trim().toLowerCase();
363
+ val = line.slice(i + 1).trim();
364
+ if (key) {
365
+ parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
366
+ }
367
+ });
368
+ return parsed;
369
+ }
370
+ _onWhenAddingFileFailed(item, filter, options) {
371
+ this.onWhenAddingFileFailed(item, filter, options);
372
+ }
373
+ _onAfterAddingFile(item) {
374
+ this.onAfterAddingFile(item);
375
+ }
376
+ _onAfterAddingAll(items) {
377
+ this.onAfterAddingAll(items);
378
+ }
379
+ _onBeforeUploadItem(item) {
380
+ item._onBeforeUpload();
381
+ this.onBeforeUploadItem(item);
382
+ }
383
+ _onBuildItemForm(item, form) {
384
+ item._onBuildForm(form);
385
+ this.onBuildItemForm(item, form);
386
+ }
387
+ _onProgressItem(item, progress) {
388
+ const total = this._getTotalProgress(progress);
389
+ this.progress = total;
390
+ item._onProgress(progress);
391
+ this.onProgressItem(item, progress);
392
+ this.onProgressAll(total);
393
+ this._render();
394
+ }
395
+ _onSuccessItem(item, response, status, headers) {
396
+ item._onSuccess(response, status, headers);
397
+ this.onSuccessItem(item, response, status, headers);
398
+ }
399
+ _onCancelItem(item, response, status, headers) {
400
+ item._onCancel(response, status, headers);
401
+ this.onCancelItem(item, response, status, headers);
402
+ }
403
+ }
404
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWRlci5jbGFzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvbmcyLWZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkZXIuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU3QyxTQUFTLE1BQU0sQ0FBQyxLQUFVO0lBQ3hCLE9BQU8sQ0FBQyxJQUFJLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFxQ0QsTUFBTSxPQUFPLFlBQVk7SUF3QnZCLFlBQVksT0FBNEI7UUFyQnhDLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLFVBQUssR0FBZSxFQUFFLENBQUM7UUFDdkIsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFLZixZQUFPLEdBQXdCO1lBQzdCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLE9BQU8sRUFBRSxJQUFJO1lBQ2IsT0FBTyxFQUFFLEVBQUU7WUFDWCxpQkFBaUIsRUFBRSxLQUFLO1lBQ3hCLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsa0JBQWtCLEVBQUUsQ0FBQyxJQUFjLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQ2xELHlCQUF5QixFQUFFLEtBQUs7WUFDaEMsR0FBRyxFQUFFLEVBQUU7U0FDUixDQUFDO1FBS0EsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFDN0MsQ0FB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QUFDO0lBRVMsYUFBYSxDQUFDLElBQWMsRUFBRSxRQUFnQixFQUFFLE1BQWMsRUFBRSxPQUE4QjtRQUN0RyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZpbGVMaWtlT2JqZWN0IH0gZnJvbSAnLi9maWxlLWxpa2Utb2JqZWN0LmNsYXNzJztcbmltcG9ydCB7IEZpbGVJdGVtIH0gZnJvbSAnLi9maWxlLWl0ZW0uY2xhc3MnO1xuaW1wb3J0IHsgRmlsZVR5cGUgfSBmcm9tICcuL2ZpbGUtdHlwZS5jbGFzcyc7XG5cbmZ1bmN0aW9uIGlzRmlsZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoRmlsZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIEZpbGUpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhlYWRlcnMge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VkUmVzcG9uc2VIZWFkZXJzIHsgWyBoZWFkZXJGaWVsZE5hbWU6IHN0cmluZyBdOiBzdHJpbmcgfVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbHRlckZ1bmN0aW9uIHtcbiAgbmFtZTogc3RyaW5nO1xuICBmbihpdGVtOiBGaWxlTGlrZU9iamVjdCwgb3B0aW9ucz86IEZpbGVVcGxvYWRlck9wdGlvbnMpOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVVcGxvYWRlck9wdGlvbnMge1xuICBhbGxvd2VkTWltZVR5cGU/OiBzdHJpbmdbXTtcbiAgYWxsb3dlZEZpbGVUeXBlPzogc3RyaW5nW107XG4gIGF1dG9VcGxvYWQ/OiBib29sZWFuO1xuICBpc0hUTUw1PzogYm9vbGVhbjtcbiAgZmlsdGVycz86IEZpbHRlckZ1bmN0aW9uW107XG4gIGhlYWRlcnM/OiBIZWFkZXJzW107XG4gIG1ldGhvZD86IHN0cmluZztcbiAgYXV0aFRva2VuPzogc3RyaW5nO1xuICBtYXhGaWxlU2l6ZT86IG51bWJlcjtcbiAgcXVldWVMaW1pdD86IG51bWJlcjtcbiAgcmVtb3ZlQWZ0ZXJVcGxvYWQ/OiBib29sZWFuO1xuICB1cmw6IHN0cmluZztcbiAgZGlzYWJsZU11bHRpcGFydD86IGJvb2xlYW47XG4gIGl0ZW1BbGlhcz86IHN0cmluZztcbiAgYXV0aFRva2VuSGVhZGVyPzogc3RyaW5nO1xuICBhZGRpdGlvbmFsUGFyYW1ldGVyPzogeyBbIGtleTogc3RyaW5nIF06IGFueSB9O1xuICBwYXJhbWV0ZXJzQmVmb3JlRmlsZXM/OiBib29sZWFuO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10eXBlc1xuICBmb3JtYXREYXRhRnVuY3Rpb24/OiBGdW5jdGlvbjtcbiAgZm9ybWF0RGF0YUZ1bmN0aW9uSXNBc3luYz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBGaWxlVXBsb2FkZXIge1xuXG4gIGF1dGhUb2tlbj86IHN0cmluZztcbiAgaXNVcGxvYWRpbmcgPSBmYWxzZTtcbiAgcXVldWU6IEZpbGVJdGVtW10gPSBbXTtcbiAgcHJvZ3Jlc3MgPSAwO1xuICBfbmV4dEluZGV4ID0gMDtcbiAgYXV0b1VwbG9hZDogYW55O1xuICBhdXRoVG9rZW5IZWFkZXI/OiBzdHJpbmc7XG4gIHJlc3BvbnNlOiBFdmVudEVtaXR0ZXI8YW55PjtcblxuICBvcHRpb25zOiBGaWxlVXBsb2FkZXJPcHRpb25zID0ge1xuICAgIGF1dG9VcGxvYWQ6IGZhbHNlLFxuICAgIGlzSFRNTDU6IHRydWUsXG4gICAgZmlsdGVyczogW10sXG4gICAgcmVtb3ZlQWZ0ZXJVcGxvYWQ6IGZhbHNlLFxuICAgIGRpc2FibGVNdWx0aXBhcnQ6IGZhbHNlLFxuICAgIGZvcm1hdERhdGFGdW5jdGlvbjogKGl0ZW06IEZpbGVJdGVtKSA9PiBpdGVtLl9maWxlLFxuICAgIGZvcm1hdERhdGFGdW5jdGlvbklzQXN5bmM6IGZhbHNlLFxuICAgIHVybDogJydcbiAgfTtcblxuICBwcm90ZWN0ZWQgX2ZhaWxGaWx0ZXJJbmRleD86IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBGaWxlVXBsb2FkZXJPcHRpb25zKSB7XG4gICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgIHRoaXMucmVzcG9uc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgfVxuXG4gIHNldE9wdGlvbnMob3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24odGhpcy5vcHRpb25zLCBvcHRpb25zKTtcblxuICAgIHRoaXMuYXV0aFRva2VuID0gdGhpcy5vcHRpb25zLmF1dGhUb2tlbjtcbiAgICB0aGlzLmF1dGhUb2tlbkhlYWRlciA9IHRoaXMub3B0aW9ucy5hdXRoVG9rZW5IZWFkZXIgfHwgJ0F1dGhvcml6YXRpb24nO1xuICAgIHRoaXMuYXV0b1VwbG9hZCA9IHRoaXMub3B0aW9ucy5hdXRvVXBsb2FkO1xuICAgIHRoaXMub3B0aW9ucy5maWx0ZXJzPy51bnNoaWZ0KHsgbmFtZTogJ3F1ZXVlTGltaXQnLCBmbjogdGhpcy5fcXVldWVMaW1pdEZpbHRlciB9KTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF4RmlsZVNpemUpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5maWx0ZXJzPy51bnNoaWZ0KHsgbmFtZTogJ2ZpbGVTaXplJywgZm46IHRoaXMuX2ZpbGVTaXplRmlsdGVyIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuYWxsb3dlZEZpbGVUeXBlKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuZmlsdGVycz8udW5zaGlmdCh7IG5hbWU6ICdmaWxlVHlwZScsIGZuOiB0aGlzLl9maWxlVHlwZUZpbHRlciB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93ZWRNaW1lVHlwZSkge1xuICAgICAgdGhpcy5vcHRpb25zLmZpbHRlcnM/LnVuc2hpZnQoeyBuYW1lOiAnbWltZVR5cGUnLCBmbjogdGhpcy5fbWltZVR5cGVGaWx0ZXIgfSk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLnF1ZXVlWyBpIF0udXJsID0gdGhpcy5vcHRpb25zLnVybDtcbiAgICB9XG4gIH1cblxuICBhZGRUb1F1ZXVlKGZpbGVzOiBGaWxlW10sIF9vcHRpb25zPzogRmlsZVVwbG9hZGVyT3B0aW9ucywgZmlsdGVycz86IFtdIHwgc3RyaW5nKTogdm9pZCB7XG4gICAgbGV0IG9wdGlvbnMgPSBfb3B0aW9ucztcbiAgICBjb25zdCBsaXN0OiBGaWxlW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgIGxpc3QucHVzaChmaWxlKTtcbiAgICB9XG4gICAgY29uc3QgYXJyYXlPZkZpbHRlcnMgPSB0aGlzLl9nZXRGaWx0ZXJzKGZpbHRlcnMpO1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5xdWV1ZS5sZW5ndGg7XG4gICAgY29uc3QgYWRkZWRGaWxlSXRlbXM6IEZpbGVJdGVtW10gPSBbXTtcbiAgICBsaXN0Lm1hcCgoc29tZTogRmlsZSkgPT4ge1xuICAgICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRlbXAgPSBuZXcgRmlsZUxpa2VPYmplY3Qoc29tZSk7XG4gICAgICBpZiAodGhpcy5faXNWYWxpZEZpbGUodGVtcCwgYXJyYXlPZkZpbHRlcnMsIG9wdGlvbnMpKSB7XG4gICAgICAgIGNvbnN0IGZpbGVJdGVtID0gbmV3IEZpbGVJdGVtKHRoaXMsIHNvbWUsIG9wdGlvbnMpO1xuICAgICAgICBhZGRlZEZpbGVJdGVtcy5wdXNoKGZpbGVJdGVtKTtcbiAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKGZpbGVJdGVtKTtcbiAgICAgICAgdGhpcy5fb25BZnRlckFkZGluZ0ZpbGUoZmlsZUl0ZW0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9mYWlsRmlsdGVySW5kZXggPT09ICdudW1iZXInICYmIHRoaXMuX2ZhaWxGaWx0ZXJJbmRleCA+PSAwKSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyID0gYXJyYXlPZkZpbHRlcnNbIHRoaXMuX2ZhaWxGaWx0ZXJJbmRleCBdO1xuICAgICAgICAgIHRoaXMuX29uV2hlbkFkZGluZ0ZpbGVGYWlsZWQodGVtcCwgZmlsdGVyLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCAhPT0gY291bnQpIHtcbiAgICAgIHRoaXMuX29uQWZ0ZXJBZGRpbmdBbGwoYWRkZWRGaWxlSXRlbXMpO1xuICAgICAgdGhpcy5wcm9ncmVzcyA9IHRoaXMuX2dldFRvdGFsUHJvZ3Jlc3MoKTtcbiAgICB9XG4gICAgdGhpcy5fcmVuZGVyKCk7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5hdXRvVXBsb2FkKSB7XG4gICAgICB0aGlzLnVwbG9hZEFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUZyb21RdWV1ZSh2YWx1ZTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZ2V0SW5kZXhPZkl0ZW0odmFsdWUpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnF1ZXVlWyBpbmRleCBdO1xuICAgIGlmIChpdGVtLmlzVXBsb2FkaW5nKSB7XG4gICAgICBpdGVtLmNhbmNlbCgpO1xuICAgIH1cbiAgICB0aGlzLnF1ZXVlLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5wcm9ncmVzcyA9IHRoaXMuX2dldFRvdGFsUHJvZ3Jlc3MoKTtcbiAgfVxuXG4gIGNsZWFyUXVldWUoKTogdm9pZCB7XG4gICAgd2hpbGUgKHRoaXMucXVldWUubGVuZ3RoKSB7XG4gICAgICB0aGlzLnF1ZXVlWyAwIF0ucmVtb3ZlKCk7XG4gICAgfVxuICAgIHRoaXMucHJvZ3Jlc3MgPSAwO1xuICB9XG5cbiAgdXBsb2FkSXRlbSh2YWx1ZTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZ2V0SW5kZXhPZkl0ZW0odmFsdWUpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnF1ZXVlWyBpbmRleCBdO1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IHRoaXMub3B0aW9ucy5pc0hUTUw1ID8gJ194aHJUcmFuc3BvcnQnIDogJ19pZnJhbWVUcmFuc3BvcnQnO1xuICAgIGl0ZW0uX3ByZXBhcmVUb1VwbG9hZGluZygpO1xuICAgIGlmICh0aGlzLmlzVXBsb2FkaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaXNVcGxvYWRpbmcgPSB0cnVlO1xuICAgICh0aGlzIGFzIGFueSlbIHRyYW5zcG9ydCBdKGl0ZW0pO1xuICB9XG5cbiAgY2FuY2VsSXRlbSh2YWx1ZTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZ2V0SW5kZXhPZkl0ZW0odmFsdWUpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLnF1ZXVlWyBpbmRleCBdO1xuICAgIGNvbnN0IHByb3AgPSB0aGlzLm9wdGlvbnMuaXNIVE1MNSA/IGl0ZW0uX3hociA6IGl0ZW0uX2Zvcm07XG4gICAgaWYgKGl0ZW0gJiYgaXRlbS5pc1VwbG9hZGluZykge1xuICAgICAgcHJvcC5hYm9ydCgpO1xuICAgIH1cbiAgfVxuXG4gIHVwbG9hZEFsbCgpOiB2b2lkIHtcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuZ2V0Tm90VXBsb2FkZWRJdGVtcygpLmZpbHRlcigoaXRlbTogRmlsZUl0ZW0pID0+ICFpdGVtLmlzVXBsb2FkaW5nKTtcbiAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpdGVtcy5tYXAoKGl0ZW06IEZpbGVJdGVtKSA9PiBpdGVtLl9wcmVwYXJlVG9VcGxvYWRpbmcoKSk7XG4gICAgaXRlbXNbIDAgXS51cGxvYWQoKTtcbiAgfVxuXG4gIGNhbmNlbEFsbCgpOiB2b2lkIHtcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuZ2V0Tm90VXBsb2FkZWRJdGVtcygpO1xuICAgIGl0ZW1zLm1hcCgoaXRlbTogRmlsZUl0ZW0pID0+IGl0ZW0uY2FuY2VsKCkpO1xuICB9XG5cbiAgaXNGaWxlKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNGaWxlKHZhbHVlKTtcbiAgfVxuXG4gIGlzRmlsZUxpa2VPYmplY3QodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIEZpbGVMaWtlT2JqZWN0O1xuICB9XG5cbiAgZ2V0SW5kZXhPZkl0ZW0odmFsdWU6IGFueSk6IG51bWJlciB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyB2YWx1ZSA6IHRoaXMucXVldWUuaW5kZXhPZih2YWx1ZSk7XG4gIH1cblxuICBnZXROb3RVcGxvYWRlZEl0ZW1zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5maWx0ZXIoKGl0ZW06IEZpbGVJdGVtKSA9PiAhaXRlbS5pc1VwbG9hZGVkKTtcbiAgfVxuXG4gIGdldFJlYWR5SXRlbXMoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlXG4gICAgICAuZmlsdGVyKChpdGVtOiBGaWxlSXRlbSkgPT4gKGl0ZW0uaXNSZWFkeSAmJiAhaXRlbS5pc1VwbG9hZGluZykpXG4gICAgICAuc29ydCgoaXRlbTE6IGFueSwgaXRlbTI6IGFueSkgPT4gaXRlbTEuaW5kZXggLSBpdGVtMi5pbmRleCk7XG4gIH1cblxuICBvbkFmdGVyQWRkaW5nQWxsKGZpbGVJdGVtczogYW55KTogYW55IHtcbiAgICByZXR1cm4geyBmaWxlSXRlbXMgfTtcbiAgfVxuXG4gIG9uQnVpbGRJdGVtRm9ybShmaWxlSXRlbTogRmlsZUl0ZW0sIGZvcm06IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHsgZmlsZUl0ZW0sIGZvcm0gfTtcbiAgfVxuXG4gIG9uQWZ0ZXJBZGRpbmdGaWxlKGZpbGVJdGVtOiBGaWxlSXRlbSk6IGFueSB7XG4gICAgcmV0dXJuIHsgZmlsZUl0ZW0gfTtcbiAgfVxuXG4gIG9uV2hlbkFkZGluZ0ZpbGVGYWlsZWQoaXRlbTogRmlsZUxpa2VPYmplY3QsIGZpbHRlcjogYW55LCBvcHRpb25zOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB7IGl0ZW0sIGZpbHRlciwgb3B0aW9ucyB9O1xuICB9XG5cbiAgb25CZWZvcmVVcGxvYWRJdGVtKGZpbGVJdGVtOiBGaWxlSXRlbSk6IGFueSB7XG4gICAgcmV0dXJuIHsgZmlsZUl0ZW0gfTtcbiAgfVxuXG4gIG9uUHJvZ3Jlc3NJdGVtKGZpbGVJdGVtOiBGaWxlSXRlbSwgcHJvZ3Jlc3M6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHsgZmlsZUl0ZW0sIHByb2dyZXNzIH07XG4gIH1cblxuICBvblByb2dyZXNzQWxsKHByb2dyZXNzOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB7IHByb2dyZXNzIH07XG4gIH1cblxuICBvblN1Y2Nlc3NJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogYW55IHtcbiAgICByZXR1cm4geyBpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzIH07XG4gIH1cblxuICBvbkVycm9ySXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IGFueSB7XG4gICAgcmV0dXJuIHsgaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyB9O1xuICB9XG5cbiAgb25DYW5jZWxJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogYW55IHtcbiAgICByZXR1cm4geyBpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzIH07XG4gIH1cblxuICBvbkNvbXBsZXRlSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IGFueSB7XG4gICAgcmV0dXJuIHsgaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyB9O1xuICB9XG5cbiAgb25Db21wbGV0ZUFsbCgpOiBhbnkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBfbWltZVR5cGVGaWx0ZXIoaXRlbTogRmlsZUxpa2VPYmplY3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIShpdGVtPy50eXBlICYmIHRoaXMub3B0aW9ucy5hbGxvd2VkTWltZVR5cGUgJiYgdGhpcy5vcHRpb25zLmFsbG93ZWRNaW1lVHlwZT8uaW5kZXhPZihpdGVtLnR5cGUpID09PSAtMSk7XG4gIH1cblxuICBfZmlsZVNpemVGaWx0ZXIoaXRlbTogRmlsZUxpa2VPYmplY3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLm9wdGlvbnMubWF4RmlsZVNpemUgJiYgaXRlbS5zaXplID4gdGhpcy5vcHRpb25zLm1heEZpbGVTaXplKTtcbiAgfVxuXG4gIF9maWxlVHlwZUZpbHRlcihpdGVtOiBGaWxlTGlrZU9iamVjdCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKHRoaXMub3B0aW9ucy5hbGxvd2VkRmlsZVR5cGUgJiZcbiAgICAgIHRoaXMub3B0aW9ucy5hbGxvd2VkRmlsZVR5cGUuaW5kZXhPZihGaWxlVHlwZS5nZXRNaW1lQ2xhc3MoaXRlbSkpID09PSAtMSk7XG4gIH1cblxuICBfb25FcnJvckl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vbkVycm9yKHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICAgIHRoaXMub25FcnJvckl0ZW0oaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gIH1cblxuICBfb25Db21wbGV0ZUl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vbkNvbXBsZXRlKHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICAgIHRoaXMub25Db21wbGV0ZUl0ZW0oaXRlbSwgcmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gICAgY29uc3QgbmV4dEl0ZW0gPSB0aGlzLmdldFJlYWR5SXRlbXMoKVsgMCBdO1xuICAgIHRoaXMuaXNVcGxvYWRpbmcgPSBmYWxzZTtcbiAgICBpZiAobmV4dEl0ZW0pIHtcbiAgICAgIG5leHRJdGVtLnVwbG9hZCgpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub25Db21wbGV0ZUFsbCgpO1xuICAgIHRoaXMucHJvZ3Jlc3MgPSB0aGlzLl9nZXRUb3RhbFByb2dyZXNzKCk7XG4gICAgdGhpcy5fcmVuZGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2hlYWRlcnNHZXR0ZXIocGFyc2VkSGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogYW55IHtcbiAgICByZXR1cm4gKG5hbWU6IGFueSk6IGFueSA9PiB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICByZXR1cm4gcGFyc2VkSGVhZGVyc1sgbmFtZS50b0xvd2VyQ2FzZSgpIF0gfHwgdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VkSGVhZGVycztcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIF94aHJUcmFuc3BvcnQoaXRlbTogRmlsZUl0ZW0pOiBhbnkge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby10aGlzLWFzc2lnbm1lbnRcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCB4aHIgPSBpdGVtLl94aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICBsZXQgc2VuZGFibGU6IGFueTtcbiAgICB0aGlzLl9vbkJlZm9yZVVwbG9hZEl0ZW0oaXRlbSk7XG5cbiAgICBpZiAodHlwZW9mIGl0ZW0uX2ZpbGUuc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBmaWxlIHNwZWNpZmllZCBpcyBubyBsb25nZXIgdmFsaWQnKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuZGlzYWJsZU11bHRpcGFydCkge1xuICAgICAgc2VuZGFibGUgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgIHRoaXMuX29uQnVpbGRJdGVtRm9ybShpdGVtLCBzZW5kYWJsZSk7XG4gICAgICBjb25zdCBhcHBlbmRGaWxlID0gKCkgPT4gc2VuZGFibGUuYXBwZW5kKGl0ZW0uYWxpYXMsIGl0ZW0uX2ZpbGUsIGl0ZW0uZmlsZS5uYW1lKTtcbiAgICAgIGlmICghdGhpcy5vcHRpb25zLnBhcmFtZXRlcnNCZWZvcmVGaWxlcykge1xuICAgICAgICBhcHBlbmRGaWxlKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvciBBV1MsIEFkZGl0aW9uYWwgUGFyYW1ldGVycyBtdXN0IGNvbWUgQkVGT1JFIEZpbGVzXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFkZGl0aW9uYWxQYXJhbWV0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLm9wdGlvbnMuYWRkaXRpb25hbFBhcmFtZXRlcikuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBsZXQgcGFyYW1WYWwgPSB0aGlzLm9wdGlvbnMuYWRkaXRpb25hbFBhcmFtZXRlcj8uWyBrZXkgXTtcbiAgICAgICAgICAvLyBBbGxvdyBhbiBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byBpbmNsdWRlIHRoZSBmaWxlbmFtZVxuICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1WYWwgPT09ICdzdHJpbmcnICYmIHBhcmFtVmFsLmluZGV4T2YoJ3t7ZmlsZV9uYW1lfX0nKSA+PSAwICYmIGl0ZW0uZmlsZT8ubmFtZSkge1xuICAgICAgICAgICAgcGFyYW1WYWwgPSBwYXJhbVZhbC5yZXBsYWNlKCd7e2ZpbGVfbmFtZX19JywgaXRlbS5maWxlLm5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzZW5kYWJsZS5hcHBlbmQoa2V5LCBwYXJhbVZhbCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXBwZW5kRmlsZSAmJiB0aGlzLm9wdGlvbnMucGFyYW1ldGVyc0JlZm9yZUZpbGVzKSB7XG4gICAgICAgIGFwcGVuZEZpbGUoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5mb3JtYXREYXRhRnVuY3Rpb24pIHtcbiAgICAgICAgc2VuZGFibGUgPSB0aGlzLm9wdGlvbnMuZm9ybWF0RGF0YUZ1bmN0aW9uKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHhoci51cGxvYWQub25wcm9ncmVzcyA9IChldmVudDogYW55KSA9PiB7XG4gICAgICBjb25zdCBwcm9ncmVzcyA9IE1hdGgucm91bmQoZXZlbnQubGVuZ3RoQ29tcHV0YWJsZSA/IGV2ZW50LmxvYWRlZCAqIDEwMCAvIGV2ZW50LnRvdGFsIDogMCk7XG4gICAgICB0aGlzLl9vblByb2dyZXNzSXRlbShpdGVtLCBwcm9ncmVzcyk7XG4gICAgfTtcbiAgICB4aHIub25sb2FkID0gKCkgPT4ge1xuICAgICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX3BhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl90cmFuc2Zvcm1SZXNwb25zZSh4aHIucmVzcG9uc2UsIGhlYWRlcnMpO1xuICAgICAgY29uc3QgZ2lzdCA9IHRoaXMuX2lzU3VjY2Vzc0NvZGUoeGhyLnN0YXR1cykgPyAnU3VjY2VzcycgOiAnRXJyb3InO1xuICAgICAgY29uc3QgbWV0aG9kID0gYF9vbiR7Z2lzdH1JdGVtYDtcbiAgICAgICh0aGlzIGFzIGFueSlbIG1ldGhvZCBdKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICAgIHRoaXMuX29uQ29tcGxldGVJdGVtKGl0ZW0sIHJlc3BvbnNlLCB4aHIuc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB9O1xuICAgIHhoci5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX3BhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLl90cmFuc2Zvcm1SZXNwb25zZSh4aHIucmVzcG9uc2UsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5fb25FcnJvckl0ZW0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5fb25Db21wbGV0ZUl0ZW0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgIH07XG4gICAgeGhyLm9uYWJvcnQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBoZWFkZXJzID0gdGhpcy5fcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuX3RyYW5zZm9ybVJlc3BvbnNlKHhoci5yZXNwb25zZSwgaGVhZGVycyk7XG4gICAgICB0aGlzLl9vbkNhbmNlbEl0ZW0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5fb25Db21wbGV0ZUl0ZW0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgIH07XG4gICAgaWYgKGl0ZW0ubWV0aG9kICYmIGl0ZW0udXJsKSB7XG4gICAgICB4aHIub3BlbihpdGVtLm1ldGhvZCwgaXRlbS51cmwsIHRydWUpO1xuICAgIH1cbiAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gaXRlbS53aXRoQ3JlZGVudGlhbHM7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IGhlYWRlciBvZiB0aGlzLm9wdGlvbnMuaGVhZGVycykge1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihoZWFkZXIubmFtZSwgaGVhZGVyLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGl0ZW0uaGVhZGVycy5sZW5ndGgpIHtcbiAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGl0ZW0uaGVhZGVycykge1xuICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihoZWFkZXIubmFtZSwgaGVhZGVyLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuYXV0aFRva2VuICYmIHRoaXMuYXV0aFRva2VuSGVhZGVyKSB7XG4gICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcih0aGlzLmF1dGhUb2tlbkhlYWRlciwgdGhpcy5hdXRoVG9rZW4pO1xuICAgIH1cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09IFhNTEh0dHBSZXF1ZXN0LkRPTkUpIHtcbiAgICAgICAgdGhhdC5yZXNwb25zZS5lbWl0KHhoci5yZXNwb25zZVRleHQpO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKHRoaXMub3B0aW9ucy5mb3JtYXREYXRhRnVuY3Rpb25Jc0FzeW5jKSB7XG4gICAgICBzZW5kYWJsZS50aGVuKFxuICAgICAgICAocmVzdWx0OiBhbnkpID0+IHhoci5zZW5kKEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB4aHIuc2VuZChzZW5kYWJsZSk7XG4gICAgfVxuICAgIHRoaXMuX3JlbmRlcigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXRUb3RhbFByb2dyZXNzKHZhbHVlID0gMCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZW1vdmVBZnRlclVwbG9hZCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjb25zdCBub3RVcGxvYWRlZCA9IHRoaXMuZ2V0Tm90VXBsb2FkZWRJdGVtcygpLmxlbmd0aDtcbiAgICBjb25zdCB1cGxvYWRlZCA9IG5vdFVwbG9hZGVkID8gdGhpcy5xdWV1ZS5sZW5ndGggLSBub3RVcGxvYWRlZCA6IHRoaXMucXVldWUubGVuZ3RoO1xuICAgIGNvbnN0IHJhdGlvID0gMTAwIC8gdGhpcy5xdWV1ZS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudCA9IHZhbHVlICogcmF0aW8gLyAxMDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQodXBsb2FkZWQgKiByYXRpbyArIGN1cnJlbnQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXRGaWx0ZXJzKGZpbHRlcnM/OiBGaWx0ZXJGdW5jdGlvbltdIHwgc3RyaW5nKTogRmlsdGVyRnVuY3Rpb25bXSB8IFtdIHtcbiAgICBpZiAoIWZpbHRlcnMpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnM/LmZpbHRlcnMgfHwgW107XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KGZpbHRlcnMpKSB7XG4gICAgICByZXR1cm4gZmlsdGVycztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBmaWx0ZXJzID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgbmFtZXMgPSBmaWx0ZXJzLm1hdGNoKC9bXlxccyxdKy9nKTtcblxuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucz8uZmlsdGVycyB8fCBbXVxuICAgICAgICAuZmlsdGVyKChmaWx0ZXI6IGFueSkgPT4gbmFtZXM/LmluZGV4T2YoZmlsdGVyLm5hbWUpICE9PSAtMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucz8uZmlsdGVycyB8fCBbXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfcmVuZGVyKCk6IGFueSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIHByb3RlY3RlZCBfcXVldWVMaW1pdEZpbHRlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnF1ZXVlTGltaXQgPT09IHVuZGVmaW5lZCB8fCB0aGlzLnF1ZXVlLmxlbmd0aCA8IHRoaXMub3B0aW9ucy5xdWV1ZUxpbWl0O1xuICB9XG5cbiAgcHJvdGVjdGVkIF9pc1ZhbGlkRmlsZShmaWxlOiBGaWxlTGlrZU9iamVjdCwgZmlsdGVyczogRmlsdGVyRnVuY3Rpb25bXSwgb3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucyk6IGJvb2xlYW4ge1xuICAgIHRoaXMuX2ZhaWxGaWx0ZXJJbmRleCA9IC0xO1xuXG4gICAgcmV0dXJuICFmaWx0ZXJzLmxlbmd0aCA/IHRydWUgOiBmaWx0ZXJzLmV2ZXJ5KChmaWx0ZXI6IEZpbHRlckZ1bmN0aW9uKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMuX2ZhaWxGaWx0ZXJJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy5fZmFpbEZpbHRlckluZGV4Kys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmaWx0ZXIuZm4uY2FsbCh0aGlzLCBmaWxlLCBvcHRpb25zKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfaXNTdWNjZXNzQ29kZShzdGF0dXM6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PT0gMzA0O1xuICB9XG5cbiAgcHJvdGVjdGVkIF90cmFuc2Zvcm1SZXNwb25zZShyZXNwb25zZTogc3RyaW5nLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfcGFyc2VIZWFkZXJzKGhlYWRlcnM6IHN0cmluZyk6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyB7XG4gICAgY29uc3QgcGFyc2VkOiBhbnkgPSB7fTtcbiAgICBsZXQga2V5OiBhbnk7XG4gICAgbGV0IHZhbDogYW55O1xuICAgIGxldCBpOiBhbnk7XG4gICAgaWYgKCFoZWFkZXJzKSB7XG4gICAgICByZXR1cm4gcGFyc2VkO1xuICAgIH1cbiAgICBoZWFkZXJzLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmU6IGFueSkgPT4ge1xuICAgICAgaSA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgICAga2V5ID0gbGluZS5zbGljZSgwLCBpKS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhbCA9IGxpbmUuc2xpY2UoaSArIDEpLnRyaW0oKTtcbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgcGFyc2VkWyBrZXkgXSA9IHBhcnNlZFsga2V5IF0gPyBwYXJzZWRbIGtleSBdICsgJywgJyArIHZhbCA6IHZhbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uV2hlbkFkZGluZ0ZpbGVGYWlsZWQoaXRlbTogRmlsZUxpa2VPYmplY3QsIGZpbHRlcjogYW55LCBvcHRpb25zOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uV2hlbkFkZGluZ0ZpbGVGYWlsZWQoaXRlbSwgZmlsdGVyLCBvcHRpb25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfb25BZnRlckFkZGluZ0ZpbGUoaXRlbTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICB0aGlzLm9uQWZ0ZXJBZGRpbmdGaWxlKGl0ZW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkFmdGVyQWRkaW5nQWxsKGl0ZW1zOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQWZ0ZXJBZGRpbmdBbGwoaXRlbXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkJlZm9yZVVwbG9hZEl0ZW0oaXRlbTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICBpdGVtLl9vbkJlZm9yZVVwbG9hZCgpO1xuICAgIHRoaXMub25CZWZvcmVVcGxvYWRJdGVtKGl0ZW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkJ1aWxkSXRlbUZvcm0oaXRlbTogRmlsZUl0ZW0sIGZvcm06IGFueSk6IHZvaWQge1xuICAgIGl0ZW0uX29uQnVpbGRGb3JtKGZvcm0pO1xuICAgIHRoaXMub25CdWlsZEl0ZW1Gb3JtKGl0ZW0sIGZvcm0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vblByb2dyZXNzSXRlbShpdGVtOiBGaWxlSXRlbSwgcHJvZ3Jlc3M6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IHRvdGFsID0gdGhpcy5fZ2V0VG90YWxQcm9ncmVzcyhwcm9ncmVzcyk7XG4gICAgdGhpcy5wcm9ncmVzcyA9IHRvdGFsO1xuICAgIGl0ZW0uX29uUHJvZ3Jlc3MocHJvZ3Jlc3MpO1xuICAgIHRoaXMub25Qcm9ncmVzc0l0ZW0oaXRlbSwgcHJvZ3Jlc3MpO1xuICAgIHRoaXMub25Qcm9ncmVzc0FsbCh0b3RhbCk7XG4gICAgdGhpcy5fcmVuZGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uU3VjY2Vzc0l0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vblN1Y2Nlc3MocmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gICAgdGhpcy5vblN1Y2Nlc3NJdGVtKGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkNhbmNlbEl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vbkNhbmNlbChyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB0aGlzLm9uQ2FuY2VsSXRlbShpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgfVxufVxuIl19