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.
@@ -1,404 +0,0 @@
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 (this._failFilterIndex) {
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 (this._failFilterIndex) {
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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SUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDckQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGaWxlTGlrZU9iamVjdCB9IGZyb20gJy4vZmlsZS1saWtlLW9iamVjdC5jbGFzcyc7XG5pbXBvcnQgeyBGaWxlSXRlbSB9IGZyb20gJy4vZmlsZS1pdGVtLmNsYXNzJztcbmltcG9ydCB7IEZpbGVUeXBlIH0gZnJvbSAnLi9maWxlLXR5cGUuY2xhc3MnO1xuXG5mdW5jdGlvbiBpc0ZpbGUodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKEZpbGUgJiYgdmFsdWUgaW5zdGFuY2VvZiBGaWxlKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIZWFkZXJzIHtcbiAgbmFtZTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZFJlc3BvbnNlSGVhZGVycyB7IFsgaGVhZGVyRmllbGROYW1lOiBzdHJpbmcgXTogc3RyaW5nIH1cblxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJGdW5jdGlvbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgZm4oaXRlbTogRmlsZUxpa2VPYmplY3QsIG9wdGlvbnM/OiBGaWxlVXBsb2FkZXJPcHRpb25zKTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlVXBsb2FkZXJPcHRpb25zIHtcbiAgYWxsb3dlZE1pbWVUeXBlPzogc3RyaW5nW107XG4gIGFsbG93ZWRGaWxlVHlwZT86IHN0cmluZ1tdO1xuICBhdXRvVXBsb2FkPzogYm9vbGVhbjtcbiAgaXNIVE1MNT86IGJvb2xlYW47XG4gIGZpbHRlcnM/OiBGaWx0ZXJGdW5jdGlvbltdO1xuICBoZWFkZXJzPzogSGVhZGVyc1tdO1xuICBtZXRob2Q/OiBzdHJpbmc7XG4gIGF1dGhUb2tlbj86IHN0cmluZztcbiAgbWF4RmlsZVNpemU/OiBudW1iZXI7XG4gIHF1ZXVlTGltaXQ/OiBudW1iZXI7XG4gIHJlbW92ZUFmdGVyVXBsb2FkPzogYm9vbGVhbjtcbiAgdXJsOiBzdHJpbmc7XG4gIGRpc2FibGVNdWx0aXBhcnQ/OiBib29sZWFuO1xuICBpdGVtQWxpYXM/OiBzdHJpbmc7XG4gIGF1dGhUb2tlbkhlYWRlcj86IHN0cmluZztcbiAgYWRkaXRpb25hbFBhcmFtZXRlcj86IHsgWyBrZXk6IHN0cmluZyBdOiBhbnkgfTtcbiAgcGFyYW1ldGVyc0JlZm9yZUZpbGVzPzogYm9vbGVhbjtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgZm9ybWF0RGF0YUZ1bmN0aW9uPzogRnVuY3Rpb247XG4gIGZvcm1hdERhdGFGdW5jdGlvbklzQXN5bmM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZGVyIHtcblxuICBhdXRoVG9rZW4/OiBzdHJpbmc7XG4gIGlzVXBsb2FkaW5nID0gZmFsc2U7XG4gIHF1ZXVlOiBGaWxlSXRlbVtdID0gW107XG4gIHByb2dyZXNzID0gMDtcbiAgX25leHRJbmRleCA9IDA7XG4gIGF1dG9VcGxvYWQ6IGFueTtcbiAgYXV0aFRva2VuSGVhZGVyPzogc3RyaW5nO1xuICByZXNwb25zZTogRXZlbnRFbWl0dGVyPGFueT47XG5cbiAgb3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucyA9IHtcbiAgICBhdXRvVXBsb2FkOiBmYWxzZSxcbiAgICBpc0hUTUw1OiB0cnVlLFxuICAgIGZpbHRlcnM6IFtdLFxuICAgIHJlbW92ZUFmdGVyVXBsb2FkOiBmYWxzZSxcbiAgICBkaXNhYmxlTXVsdGlwYXJ0OiBmYWxzZSxcbiAgICBmb3JtYXREYXRhRnVuY3Rpb246IChpdGVtOiBGaWxlSXRlbSkgPT4gaXRlbS5fZmlsZSxcbiAgICBmb3JtYXREYXRhRnVuY3Rpb25Jc0FzeW5jOiBmYWxzZSxcbiAgICB1cmw6ICcnXG4gIH07XG5cbiAgcHJvdGVjdGVkIF9mYWlsRmlsdGVySW5kZXg/OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogRmlsZVVwbG9hZGVyT3B0aW9ucykge1xuICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICB0aGlzLnJlc3BvbnNlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIH1cblxuICBzZXRPcHRpb25zKG9wdGlvbnM6IEZpbGVVcGxvYWRlck9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHRoaXMub3B0aW9ucywgb3B0aW9ucyk7XG5cbiAgICB0aGlzLmF1dGhUb2tlbiA9IHRoaXMub3B0aW9ucy5hdXRoVG9rZW47XG4gICAgdGhpcy5hdXRoVG9rZW5IZWFkZXIgPSB0aGlzLm9wdGlvbnMuYXV0aFRva2VuSGVhZGVyIHx8ICdBdXRob3JpemF0aW9uJztcbiAgICB0aGlzLmF1dG9VcGxvYWQgPSB0aGlzLm9wdGlvbnMuYXV0b1VwbG9hZDtcbiAgICB0aGlzLm9wdGlvbnMuZmlsdGVycz8udW5zaGlmdCh7IG5hbWU6ICdxdWV1ZUxpbWl0JywgZm46IHRoaXMuX3F1ZXVlTGltaXRGaWx0ZXIgfSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm1heEZpbGVTaXplKSB7XG4gICAgICB0aGlzLm9wdGlvbnMuZmlsdGVycz8udW5zaGlmdCh7IG5hbWU6ICdmaWxlU2l6ZScsIGZuOiB0aGlzLl9maWxlU2l6ZUZpbHRlciB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93ZWRGaWxlVHlwZSkge1xuICAgICAgdGhpcy5vcHRpb25zLmZpbHRlcnM/LnVuc2hpZnQoeyBuYW1lOiAnZmlsZVR5cGUnLCBmbjogdGhpcy5fZmlsZVR5cGVGaWx0ZXIgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hbGxvd2VkTWltZVR5cGUpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5maWx0ZXJzPy51bnNoaWZ0KHsgbmFtZTogJ21pbWVUeXBlJywgZm46IHRoaXMuX21pbWVUeXBlRmlsdGVyIH0pO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5xdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5xdWV1ZVsgaSBdLnVybCA9IHRoaXMub3B0aW9ucy51cmw7XG4gICAgfVxuICB9XG5cbiAgYWRkVG9RdWV1ZShmaWxlczogRmlsZVtdLCBfb3B0aW9ucz86IEZpbGVVcGxvYWRlck9wdGlvbnMsIGZpbHRlcnM/OiBbXSB8IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBvcHRpb25zID0gX29wdGlvbnM7XG4gICAgY29uc3QgbGlzdDogRmlsZVtdID0gW107XG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBsaXN0LnB1c2goZmlsZSk7XG4gICAgfVxuICAgIGNvbnN0IGFycmF5T2ZGaWx0ZXJzID0gdGhpcy5fZ2V0RmlsdGVycyhmaWx0ZXJzKTtcbiAgICBjb25zdCBjb3VudCA9IHRoaXMucXVldWUubGVuZ3RoO1xuICAgIGNvbnN0IGFkZGVkRmlsZUl0ZW1zOiBGaWxlSXRlbVtdID0gW107XG4gICAgbGlzdC5tYXAoKHNvbWU6IEZpbGUpID0+IHtcbiAgICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0ZW1wID0gbmV3IEZpbGVMaWtlT2JqZWN0KHNvbWUpO1xuICAgICAgaWYgKHRoaXMuX2lzVmFsaWRGaWxlKHRlbXAsIGFycmF5T2ZGaWx0ZXJzLCBvcHRpb25zKSkge1xuICAgICAgICBjb25zdCBmaWxlSXRlbSA9IG5ldyBGaWxlSXRlbSh0aGlzLCBzb21lLCBvcHRpb25zKTtcbiAgICAgICAgYWRkZWRGaWxlSXRlbXMucHVzaChmaWxlSXRlbSk7XG4gICAgICAgIHRoaXMucXVldWUucHVzaChmaWxlSXRlbSk7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJBZGRpbmdGaWxlKGZpbGVJdGVtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLl9mYWlsRmlsdGVySW5kZXgpIHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBhcnJheU9mRmlsdGVyc1sgdGhpcy5fZmFpbEZpbHRlckluZGV4IF07XG4gICAgICAgICAgdGhpcy5fb25XaGVuQWRkaW5nRmlsZUZhaWxlZCh0ZW1wLCBmaWx0ZXIsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHRoaXMucXVldWUubGVuZ3RoICE9PSBjb3VudCkge1xuICAgICAgdGhpcy5fb25BZnRlckFkZGluZ0FsbChhZGRlZEZpbGVJdGVtcyk7XG4gICAgICB0aGlzLnByb2dyZXNzID0gdGhpcy5fZ2V0VG90YWxQcm9ncmVzcygpO1xuICAgIH1cbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9VcGxvYWQpIHtcbiAgICAgIHRoaXMudXBsb2FkQWxsKCk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlRnJvbVF1ZXVlKHZhbHVlOiBGaWxlSXRlbSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRJbmRleE9mSXRlbSh2YWx1ZSk7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMucXVldWVbIGluZGV4IF07XG4gICAgaWYgKGl0ZW0uaXNVcGxvYWRpbmcpIHtcbiAgICAgIGl0ZW0uY2FuY2VsKCk7XG4gICAgfVxuICAgIHRoaXMucXVldWUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLnByb2dyZXNzID0gdGhpcy5fZ2V0VG90YWxQcm9ncmVzcygpO1xuICB9XG5cbiAgY2xlYXJRdWV1ZSgpOiB2b2lkIHtcbiAgICB3aGlsZSAodGhpcy5xdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMucXVldWVbIDAgXS5yZW1vdmUoKTtcbiAgICB9XG4gICAgdGhpcy5wcm9ncmVzcyA9IDA7XG4gIH1cblxuICB1cGxvYWRJdGVtKHZhbHVlOiBGaWxlSXRlbSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRJbmRleE9mSXRlbSh2YWx1ZSk7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMucXVldWVbIGluZGV4IF07XG4gICAgY29uc3QgdHJhbnNwb3J0ID0gdGhpcy5vcHRpb25zLmlzSFRNTDUgPyAnX3hoclRyYW5zcG9ydCcgOiAnX2lmcmFtZVRyYW5zcG9ydCc7XG4gICAgaXRlbS5fcHJlcGFyZVRvVXBsb2FkaW5nKCk7XG4gICAgaWYgKHRoaXMuaXNVcGxvYWRpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pc1VwbG9hZGluZyA9IHRydWU7XG4gICAgKHRoaXMgYXMgYW55KVsgdHJhbnNwb3J0IF0oaXRlbSk7XG4gIH1cblxuICBjYW5jZWxJdGVtKHZhbHVlOiBGaWxlSXRlbSk6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRJbmRleE9mSXRlbSh2YWx1ZSk7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMucXVldWVbIGluZGV4IF07XG4gICAgY29uc3QgcHJvcCA9IHRoaXMub3B0aW9ucy5pc0hUTUw1ID8gaXRlbS5feGhyIDogaXRlbS5fZm9ybTtcbiAgICBpZiAoaXRlbSAmJiBpdGVtLmlzVXBsb2FkaW5nKSB7XG4gICAgICBwcm9wLmFib3J0KCk7XG4gICAgfVxuICB9XG5cbiAgdXBsb2FkQWxsKCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5nZXROb3RVcGxvYWRlZEl0ZW1zKCkuZmlsdGVyKChpdGVtOiBGaWxlSXRlbSkgPT4gIWl0ZW0uaXNVcGxvYWRpbmcpO1xuICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGl0ZW1zLm1hcCgoaXRlbTogRmlsZUl0ZW0pID0+IGl0ZW0uX3ByZXBhcmVUb1VwbG9hZGluZygpKTtcbiAgICBpdGVtc1sgMCBdLnVwbG9hZCgpO1xuICB9XG5cbiAgY2FuY2VsQWxsKCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5nZXROb3RVcGxvYWRlZEl0ZW1zKCk7XG4gICAgaXRlbXMubWFwKChpdGVtOiBGaWxlSXRlbSkgPT4gaXRlbS5jYW5jZWwoKSk7XG4gIH1cblxuICBpc0ZpbGUodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc0ZpbGUodmFsdWUpO1xuICB9XG5cbiAgaXNGaWxlTGlrZU9iamVjdCh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRmlsZUxpa2VPYmplY3Q7XG4gIH1cblxuICBnZXRJbmRleE9mSXRlbSh2YWx1ZTogYW55KTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogdGhpcy5xdWV1ZS5pbmRleE9mKHZhbHVlKTtcbiAgfVxuXG4gIGdldE5vdFVwbG9hZGVkSXRlbXMoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmZpbHRlcigoaXRlbTogRmlsZUl0ZW0pID0+ICFpdGVtLmlzVXBsb2FkZWQpO1xuICB9XG5cbiAgZ2V0UmVhZHlJdGVtcygpOiBhbnlbXSB7XG4gICAgcmV0dXJuIHRoaXMucXVldWVcbiAgICAgIC5maWx0ZXIoKGl0ZW06IEZpbGVJdGVtKSA9PiAoaXRlbS5pc1JlYWR5ICYmICFpdGVtLmlzVXBsb2FkaW5nKSlcbiAgICAgIC5zb3J0KChpdGVtMTogYW55LCBpdGVtMjogYW55KSA9PiBpdGVtMS5pbmRleCAtIGl0ZW0yLmluZGV4KTtcbiAgfVxuXG4gIG9uQWZ0ZXJBZGRpbmdBbGwoZmlsZUl0ZW1zOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB7IGZpbGVJdGVtcyB9O1xuICB9XG5cbiAgb25CdWlsZEl0ZW1Gb3JtKGZpbGVJdGVtOiBGaWxlSXRlbSwgZm9ybTogYW55KTogYW55IHtcbiAgICByZXR1cm4geyBmaWxlSXRlbSwgZm9ybSB9O1xuICB9XG5cbiAgb25BZnRlckFkZGluZ0ZpbGUoZmlsZUl0ZW06IEZpbGVJdGVtKTogYW55IHtcbiAgICByZXR1cm4geyBmaWxlSXRlbSB9O1xuICB9XG5cbiAgb25XaGVuQWRkaW5nRmlsZUZhaWxlZChpdGVtOiBGaWxlTGlrZU9iamVjdCwgZmlsdGVyOiBhbnksIG9wdGlvbnM6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHsgaXRlbSwgZmlsdGVyLCBvcHRpb25zIH07XG4gIH1cblxuICBvbkJlZm9yZVVwbG9hZEl0ZW0oZmlsZUl0ZW06IEZpbGVJdGVtKTogYW55IHtcbiAgICByZXR1cm4geyBmaWxlSXRlbSB9O1xuICB9XG5cbiAgb25Qcm9ncmVzc0l0ZW0oZmlsZUl0ZW06IEZpbGVJdGVtLCBwcm9ncmVzczogYW55KTogYW55IHtcbiAgICByZXR1cm4geyBmaWxlSXRlbSwgcHJvZ3Jlc3MgfTtcbiAgfVxuXG4gIG9uUHJvZ3Jlc3NBbGwocHJvZ3Jlc3M6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHsgcHJvZ3Jlc3MgfTtcbiAgfVxuXG4gIG9uU3VjY2Vzc0l0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBhbnkge1xuICAgIHJldHVybiB7IGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMgfTtcbiAgfVxuXG4gIG9uRXJyb3JJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogYW55IHtcbiAgICByZXR1cm4geyBpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzIH07XG4gIH1cblxuICBvbkNhbmNlbEl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBhbnkge1xuICAgIHJldHVybiB7IGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMgfTtcbiAgfVxuXG4gIG9uQ29tcGxldGVJdGVtKGl0ZW06IEZpbGVJdGVtLCByZXNwb25zZTogc3RyaW5nLCBzdGF0dXM6IG51bWJlciwgaGVhZGVyczogUGFyc2VkUmVzcG9uc2VIZWFkZXJzKTogYW55IHtcbiAgICByZXR1cm4geyBpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzIH07XG4gIH1cblxuICBvbkNvbXBsZXRlQWxsKCk6IGFueSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIF9taW1lVHlwZUZpbHRlcihpdGVtOiBGaWxlTGlrZU9iamVjdCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKGl0ZW0/LnR5cGUgJiYgdGhpcy5vcHRpb25zLmFsbG93ZWRNaW1lVHlwZSAmJiB0aGlzLm9wdGlvbnMuYWxsb3dlZE1pbWVUeXBlPy5pbmRleE9mKGl0ZW0udHlwZSkgPT09IC0xKTtcbiAgfVxuXG4gIF9maWxlU2l6ZUZpbHRlcihpdGVtOiBGaWxlTGlrZU9iamVjdCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhKHRoaXMub3B0aW9ucy5tYXhGaWxlU2l6ZSAmJiBpdGVtLnNpemUgPiB0aGlzLm9wdGlvbnMubWF4RmlsZVNpemUpO1xuICB9XG5cbiAgX2ZpbGVUeXBlRmlsdGVyKGl0ZW06IEZpbGVMaWtlT2JqZWN0KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEodGhpcy5vcHRpb25zLmFsbG93ZWRGaWxlVHlwZSAmJlxuICAgICAgdGhpcy5vcHRpb25zLmFsbG93ZWRGaWxlVHlwZS5pbmRleE9mKEZpbGVUeXBlLmdldE1pbWVDbGFzcyhpdGVtKSkgPT09IC0xKTtcbiAgfVxuXG4gIF9vbkVycm9ySXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IHZvaWQge1xuICAgIGl0ZW0uX29uRXJyb3IocmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gICAgdGhpcy5vbkVycm9ySXRlbShpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgfVxuXG4gIF9vbkNvbXBsZXRlSXRlbShpdGVtOiBGaWxlSXRlbSwgcmVzcG9uc2U6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGhlYWRlcnM6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyk6IHZvaWQge1xuICAgIGl0ZW0uX29uQ29tcGxldGUocmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gICAgdGhpcy5vbkNvbXBsZXRlSXRlbShpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICBjb25zdCBuZXh0SXRlbSA9IHRoaXMuZ2V0UmVhZHlJdGVtcygpWyAwIF07XG4gICAgdGhpcy5pc1VwbG9hZGluZyA9IGZhbHNlO1xuICAgIGlmIChuZXh0SXRlbSkge1xuICAgICAgbmV4dEl0ZW0udXBsb2FkKCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5vbkNvbXBsZXRlQWxsKCk7XG4gICAgdGhpcy5wcm9ncmVzcyA9IHRoaXMuX2dldFRvdGFsUHJvZ3Jlc3MoKTtcbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfaGVhZGVyc0dldHRlcihwYXJzZWRIZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBhbnkge1xuICAgIHJldHVybiAobmFtZTogYW55KTogYW55ID0+IHtcbiAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgIHJldHVybiBwYXJzZWRIZWFkZXJzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fCB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZWRIZWFkZXJzO1xuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgX3hoclRyYW5zcG9ydChpdGVtOiBGaWxlSXRlbSk6IGFueSB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXRoaXMtYXNzaWdubWVudFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIGNvbnN0IHhociA9IGl0ZW0uX3hociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIGxldCBzZW5kYWJsZTogYW55O1xuICAgIHRoaXMuX29uQmVmb3JlVXBsb2FkSXRlbShpdGVtKTtcblxuICAgIGlmICh0eXBlb2YgaXRlbS5fZmlsZS5zaXplICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGZpbGUgc3BlY2lmaWVkIGlzIG5vIGxvbmdlciB2YWxpZCcpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlTXVsdGlwYXJ0KSB7XG4gICAgICBzZW5kYWJsZSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgdGhpcy5fb25CdWlsZEl0ZW1Gb3JtKGl0ZW0sIHNlbmRhYmxlKTtcbiAgICAgIGNvbnN0IGFwcGVuZEZpbGUgPSAoKSA9PiBzZW5kYWJsZS5hcHBlbmQoaXRlbS5hbGlhcywgaXRlbS5fZmlsZSwgaXRlbS5maWxlLm5hbWUpO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMucGFyYW1ldGVyc0JlZm9yZUZpbGVzKSB7XG4gICAgICAgIGFwcGVuZEZpbGUoKTtcbiAgICAgIH1cblxuICAgICAgLy8gRm9yIEFXUywgQWRkaXRpb25hbCBQYXJhbWV0ZXJzIG11c3QgY29tZSBCRUZPUkUgRmlsZXNcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWRkaXRpb25hbFBhcmFtZXRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMub3B0aW9ucy5hZGRpdGlvbmFsUGFyYW1ldGVyKS5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGxldCBwYXJhbVZhbCA9IHRoaXMub3B0aW9ucy5hZGRpdGlvbmFsUGFyYW1ldGVyPy5bIGtleSBdO1xuICAgICAgICAgIC8vIEFsbG93IGFuIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIGluY2x1ZGUgdGhlIGZpbGVuYW1lXG4gICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbVZhbCA9PT0gJ3N0cmluZycgJiYgcGFyYW1WYWwuaW5kZXhPZigne3tmaWxlX25hbWV9fScpID49IDAgJiYgaXRlbS5maWxlPy5uYW1lKSB7XG4gICAgICAgICAgICBwYXJhbVZhbCA9IHBhcmFtVmFsLnJlcGxhY2UoJ3t7ZmlsZV9uYW1lfX0nLCBpdGVtLmZpbGUubmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlbmRhYmxlLmFwcGVuZChrZXksIHBhcmFtVmFsKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhcHBlbmRGaWxlICYmIHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzQmVmb3JlRmlsZXMpIHtcbiAgICAgICAgYXBwZW5kRmlsZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmZvcm1hdERhdGFGdW5jdGlvbikge1xuICAgICAgICBzZW5kYWJsZSA9IHRoaXMub3B0aW9ucy5mb3JtYXREYXRhRnVuY3Rpb24oaXRlbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgeGhyLnVwbG9hZC5vbnByb2dyZXNzID0gKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IHByb2dyZXNzID0gTWF0aC5yb3VuZChldmVudC5sZW5ndGhDb21wdXRhYmxlID8gZXZlbnQubG9hZGVkICogMTAwIC8gZXZlbnQudG90YWwgOiAwKTtcbiAgICAgIHRoaXMuX29uUHJvZ3Jlc3NJdGVtKGl0ZW0sIHByb2dyZXNzKTtcbiAgICB9O1xuICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBoZWFkZXJzID0gdGhpcy5fcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuX3RyYW5zZm9ybVJlc3BvbnNlKHhoci5yZXNwb25zZSwgaGVhZGVycyk7XG4gICAgICBjb25zdCBnaXN0ID0gdGhpcy5faXNTdWNjZXNzQ29kZSh4aHIuc3RhdHVzKSA/ICdTdWNjZXNzJyA6ICdFcnJvcic7XG4gICAgICBjb25zdCBtZXRob2QgPSBgX29uJHtnaXN0fUl0ZW1gO1xuICAgICAgKHRoaXMgYXMgYW55KVsgbWV0aG9kIF0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5fb25Db21wbGV0ZUl0ZW0oaXRlbSwgcmVzcG9uc2UsIHhoci5zdGF0dXMsIGhlYWRlcnMpO1xuICAgIH07XG4gICAgeGhyLm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICBjb25zdCBoZWFkZXJzID0gdGhpcy5fcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuX3RyYW5zZm9ybVJlc3BvbnNlKHhoci5yZXNwb25zZSwgaGVhZGVycyk7XG4gICAgICB0aGlzLl9vbkVycm9ySXRlbShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgICB0aGlzLl9vbkNvbXBsZXRlSXRlbShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgfTtcbiAgICB4aHIub25hYm9ydCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9wYXJzZUhlYWRlcnMoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5fdHJhbnNmb3JtUmVzcG9uc2UoeGhyLnJlc3BvbnNlLCBoZWFkZXJzKTtcbiAgICAgIHRoaXMuX29uQ2FuY2VsSXRlbShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgICB0aGlzLl9vbkNvbXBsZXRlSXRlbShpdGVtLCByZXNwb25zZSwgeGhyLnN0YXR1cywgaGVhZGVycyk7XG4gICAgfTtcbiAgICBpZiAoaXRlbS5tZXRob2QgJiYgaXRlbS51cmwpIHtcbiAgICAgIHhoci5vcGVuKGl0ZW0ubWV0aG9kLCBpdGVtLnVybCwgdHJ1ZSk7XG4gICAgfVxuICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSBpdGVtLndpdGhDcmVkZW50aWFscztcbiAgICBpZiAodGhpcy5vcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIHRoaXMub3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGhlYWRlci5uYW1lLCBoZWFkZXIudmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXRlbS5oZWFkZXJzLmxlbmd0aCkge1xuICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaXRlbS5oZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGhlYWRlci5uYW1lLCBoZWFkZXIudmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5hdXRoVG9rZW4gJiYgdGhpcy5hdXRoVG9rZW5IZWFkZXIpIHtcbiAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKHRoaXMuYXV0aFRva2VuSGVhZGVyLCB0aGlzLmF1dGhUb2tlbik7XG4gICAgfVxuICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gWE1MSHR0cFJlcXVlc3QuRE9ORSkge1xuICAgICAgICB0aGF0LnJlc3BvbnNlLmVtaXQoeGhyLnJlc3BvbnNlVGV4dCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmZvcm1hdERhdGFGdW5jdGlvbklzQXN5bmMpIHtcbiAgICAgIHNlbmRhYmxlLnRoZW4oXG4gICAgICAgIChyZXN1bHQ6IGFueSkgPT4geGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkocmVzdWx0KSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5zZW5kKHNlbmRhYmxlKTtcbiAgICB9XG4gICAgdGhpcy5fcmVuZGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2dldFRvdGFsUHJvZ3Jlc3ModmFsdWUgPSAwKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbW92ZUFmdGVyVXBsb2FkKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNvbnN0IG5vdFVwbG9hZGVkID0gdGhpcy5nZXROb3RVcGxvYWRlZEl0ZW1zKCkubGVuZ3RoO1xuICAgIGNvbnN0IHVwbG9hZGVkID0gbm90VXBsb2FkZWQgPyB0aGlzLnF1ZXVlLmxlbmd0aCAtIG5vdFVwbG9hZGVkIDogdGhpcy5xdWV1ZS5sZW5ndGg7XG4gICAgY29uc3QgcmF0aW8gPSAxMDAgLyB0aGlzLnF1ZXVlLmxlbmd0aDtcbiAgICBjb25zdCBjdXJyZW50ID0gdmFsdWUgKiByYXRpbyAvIDEwMDtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh1cGxvYWRlZCAqIHJhdGlvICsgY3VycmVudCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2dldEZpbHRlcnMoZmlsdGVycz86IEZpbHRlckZ1bmN0aW9uW10gfCBzdHJpbmcpOiBGaWx0ZXJGdW5jdGlvbltdIHwgW10ge1xuICAgIGlmICghZmlsdGVycykge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucz8uZmlsdGVycyB8fCBbXTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZmlsdGVycykpIHtcbiAgICAgIHJldHVybiBmaWx0ZXJzO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZpbHRlcnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBuYW1lcyA9IGZpbHRlcnMubWF0Y2goL1teXFxzLF0rL2cpO1xuXG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zPy5maWx0ZXJzIHx8IFtdXG4gICAgICAgIC5maWx0ZXIoKGZpbHRlcjogYW55KSA9PiBuYW1lcz8uaW5kZXhPZihmaWx0ZXIubmFtZSkgIT09IC0xKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vcHRpb25zPy5maWx0ZXJzIHx8IFtdO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9yZW5kZXIoKTogYW55IHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9xdWV1ZUxpbWl0RmlsdGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMucXVldWVMaW1pdCA9PT0gdW5kZWZpbmVkIHx8IHRoaXMucXVldWUubGVuZ3RoIDwgdGhpcy5vcHRpb25zLnF1ZXVlTGltaXQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2lzVmFsaWRGaWxlKGZpbGU6IEZpbGVMaWtlT2JqZWN0LCBmaWx0ZXJzOiBGaWx0ZXJGdW5jdGlvbltdLCBvcHRpb25zOiBGaWxlVXBsb2FkZXJPcHRpb25zKTogYm9vbGVhbiB7XG4gICAgdGhpcy5fZmFpbEZpbHRlckluZGV4ID0gLTE7XG5cbiAgICByZXR1cm4gIWZpbHRlcnMubGVuZ3RoID8gdHJ1ZSA6IGZpbHRlcnMuZXZlcnkoKGZpbHRlcjogRmlsdGVyRnVuY3Rpb24pID0+IHtcbiAgICAgIGlmICh0aGlzLl9mYWlsRmlsdGVySW5kZXgpIHtcbiAgICAgICAgdGhpcy5fZmFpbEZpbHRlckluZGV4Kys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmaWx0ZXIuZm4uY2FsbCh0aGlzLCBmaWxlLCBvcHRpb25zKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfaXNTdWNjZXNzQ29kZShzdGF0dXM6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PT0gMzA0O1xuICB9XG5cbiAgcHJvdGVjdGVkIF90cmFuc2Zvcm1SZXNwb25zZShyZXNwb25zZTogc3RyaW5nLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNwb25zZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfcGFyc2VIZWFkZXJzKGhlYWRlcnM6IHN0cmluZyk6IFBhcnNlZFJlc3BvbnNlSGVhZGVycyB7XG4gICAgY29uc3QgcGFyc2VkOiBhbnkgPSB7fTtcbiAgICBsZXQga2V5OiBhbnk7XG4gICAgbGV0IHZhbDogYW55O1xuICAgIGxldCBpOiBhbnk7XG4gICAgaWYgKCFoZWFkZXJzKSB7XG4gICAgICByZXR1cm4gcGFyc2VkO1xuICAgIH1cbiAgICBoZWFkZXJzLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmU6IGFueSkgPT4ge1xuICAgICAgaSA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgICAga2V5ID0gbGluZS5zbGljZSgwLCBpKS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhbCA9IGxpbmUuc2xpY2UoaSArIDEpLnRyaW0oKTtcbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgcGFyc2VkWyBrZXkgXSA9IHBhcnNlZFsga2V5IF0gPyBwYXJzZWRbIGtleSBdICsgJywgJyArIHZhbCA6IHZhbDtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uV2hlbkFkZGluZ0ZpbGVGYWlsZWQoaXRlbTogRmlsZUxpa2VPYmplY3QsIGZpbHRlcjogYW55LCBvcHRpb25zOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uV2hlbkFkZGluZ0ZpbGVGYWlsZWQoaXRlbSwgZmlsdGVyLCBvcHRpb25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfb25BZnRlckFkZGluZ0ZpbGUoaXRlbTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICB0aGlzLm9uQWZ0ZXJBZGRpbmdGaWxlKGl0ZW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkFmdGVyQWRkaW5nQWxsKGl0ZW1zOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQWZ0ZXJBZGRpbmdBbGwoaXRlbXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkJlZm9yZVVwbG9hZEl0ZW0oaXRlbTogRmlsZUl0ZW0pOiB2b2lkIHtcbiAgICBpdGVtLl9vbkJlZm9yZVVwbG9hZCgpO1xuICAgIHRoaXMub25CZWZvcmVVcGxvYWRJdGVtKGl0ZW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkJ1aWxkSXRlbUZvcm0oaXRlbTogRmlsZUl0ZW0sIGZvcm06IGFueSk6IHZvaWQge1xuICAgIGl0ZW0uX29uQnVpbGRGb3JtKGZvcm0pO1xuICAgIHRoaXMub25CdWlsZEl0ZW1Gb3JtKGl0ZW0sIGZvcm0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vblByb2dyZXNzSXRlbShpdGVtOiBGaWxlSXRlbSwgcHJvZ3Jlc3M6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IHRvdGFsID0gdGhpcy5fZ2V0VG90YWxQcm9ncmVzcyhwcm9ncmVzcyk7XG4gICAgdGhpcy5wcm9ncmVzcyA9IHRvdGFsO1xuICAgIGl0ZW0uX29uUHJvZ3Jlc3MocHJvZ3Jlc3MpO1xuICAgIHRoaXMub25Qcm9ncmVzc0l0ZW0oaXRlbSwgcHJvZ3Jlc3MpO1xuICAgIHRoaXMub25Qcm9ncmVzc0FsbCh0b3RhbCk7XG4gICAgdGhpcy5fcmVuZGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uU3VjY2Vzc0l0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vblN1Y2Nlc3MocmVzcG9uc2UsIHN0YXR1cywgaGVhZGVycyk7XG4gICAgdGhpcy5vblN1Y2Nlc3NJdGVtKGl0ZW0sIHJlc3BvbnNlLCBzdGF0dXMsIGhlYWRlcnMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9vbkNhbmNlbEl0ZW0oaXRlbTogRmlsZUl0ZW0sIHJlc3BvbnNlOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBQYXJzZWRSZXNwb25zZUhlYWRlcnMpOiB2b2lkIHtcbiAgICBpdGVtLl9vbkNhbmNlbChyZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgICB0aGlzLm9uQ2FuY2VsSXRlbShpdGVtLCByZXNwb25zZSwgc3RhdHVzLCBoZWFkZXJzKTtcbiAgfVxufVxuIl19