@hestia-earth/ui-components 0.0.9 → 0.0.12

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.
Files changed (64) hide show
  1. package/README.md +5 -22
  2. package/bibliographies/bibliographies-search-confirm/bibliographies-search-confirm.component.d.ts +1 -1
  3. package/bundles/hestia-earth-ui-components.umd.js +1736 -165
  4. package/bundles/hestia-earth-ui-components.umd.js.map +1 -1
  5. package/common/blank-node-state/blank-node-state.component.d.ts +2 -2
  6. package/common/delta-utils.d.ts +1 -1
  7. package/common/link-key-value/link-key-value.component.d.ts +1 -1
  8. package/common/maps-utils.d.ts +2 -2
  9. package/common/precision.pipe.d.ts +1 -1
  10. package/common/tags-input.directive.d.ts +1 -1
  11. package/common/utils.d.ts +7 -7
  12. package/cycles/cycles-emissions-chart/cycles-emissions-chart.component.d.ts +2 -2
  13. package/cycles/cycles-suggest-form/cycles-suggest-form.component.d.ts +1 -2
  14. package/cycles/cycles.model.d.ts +1 -1
  15. package/engine/aggregation-engine.service.d.ts +2 -2
  16. package/engine/engine.service.d.ts +3 -3
  17. package/esm2015/common/tags-input.directive.js +3 -3
  18. package/esm2015/files/files-error-summary.model.js +55 -0
  19. package/esm2015/files/files-error.model.js +2 -2
  20. package/esm2015/files/files-form.model.js +6 -6
  21. package/esm2015/files/index.js +2 -1
  22. package/esm2015/tags-input/defaultOptions.js +26 -0
  23. package/esm2015/tags-input/index.js +1053 -0
  24. package/esm2015/tags-input/templates/dropdown-item.js +3 -0
  25. package/esm2015/tags-input/templates/tag.js +6 -0
  26. package/esm2015/tags-input/templates/wrapper.js +10 -0
  27. package/esm2015/tags-input/utils/component.js +80 -0
  28. package/esm2015/tags-input/utils/dom.js +98 -0
  29. package/esm2015/tags-input/utils/events.js +147 -0
  30. package/esm2015/tags-input/utils/type.js +41 -0
  31. package/esm2015/tags-input/utils/uuid.js +3 -0
  32. package/fesm2015/hestia-earth-ui-components.js +1575 -75
  33. package/fesm2015/hestia-earth-ui-components.js.map +1 -1
  34. package/files/files-error-summary.model.d.ts +27 -0
  35. package/files/files-error.model.d.ts +6 -6
  36. package/files/files-form/files-form.component.d.ts +7 -7
  37. package/files/files-form.model.d.ts +11 -11
  38. package/files/index.d.ts +1 -0
  39. package/impact-assessments/impact-assessments-indicators-chart/impact-assessments-indicators-chart.component.d.ts +2 -2
  40. package/impact-assessments/impact-assessments-products/impact-assessments-products.component.d.ts +2 -2
  41. package/node/node-icon/node-icon.component.d.ts +1 -1
  42. package/node/node-link/node-link.component.d.ts +1 -1
  43. package/node/node-logs-models/node-logs-models.component.d.ts +1 -1
  44. package/node/node.service.d.ts +2 -2
  45. package/package.json +1 -2
  46. package/schema/schema.service.d.ts +1 -1
  47. package/search/search.model.d.ts +18 -17
  48. package/search/search.service.d.ts +7 -7
  49. package/sites/sites-maps/sites-maps.component.d.ts +1 -1
  50. package/sites/sites-measurements/sites-measurements.component.d.ts +1 -1
  51. package/sites/sites.model.d.ts +1 -1
  52. package/styles.scss +1 -1
  53. package/tags-input/defaultOptions.d.ts +25 -0
  54. package/tags-input/index.d.ts +277 -0
  55. package/tags-input/styles.sass +154 -0
  56. package/tags-input/templates/dropdown-item.d.ts +2 -0
  57. package/tags-input/templates/tag.d.ts +2 -0
  58. package/tags-input/templates/wrapper.d.ts +2 -0
  59. package/tags-input/utils/component.d.ts +22 -0
  60. package/tags-input/utils/dom.d.ts +38 -0
  61. package/tags-input/utils/events.d.ts +72 -0
  62. package/tags-input/utils/type.d.ts +17 -0
  63. package/tags-input/utils/uuid.d.ts +2 -0
  64. package/terms/terms.model.d.ts +1 -1
@@ -0,0 +1,1053 @@
1
+ /* eslint-disable */
2
+ import Component from './utils/component';
3
+ import { cloneAttributes } from './utils/dom';
4
+ import { isString, BooleanParse, isObject, isPromise, isFunction } from './utils/type';
5
+ import defaultOptions from './defaultOptions';
6
+ import tagTemplate from './templates/tag';
7
+ import containerTemplate from './templates/wrapper';
8
+ import dropdownItemTemplate from './templates/dropdown-item';
9
+ // TODO: add pattern or function to valdiate value before adding
10
+ export default class BulmaTagsInput extends Component {
11
+ constructor(element, options = {}) {
12
+ super(element, options, defaultOptions);
13
+ // Convert Boolean string options to full Boolean
14
+ this.options.allowDuplicates = BooleanParse(this.options.allowDuplicates);
15
+ this.options.caseSensitive = BooleanParse(this.options.caseSensitive);
16
+ this.options.clearSelectionOnTyping = BooleanParse(this.options.clearSelectionOnTyping);
17
+ this.options.closeDropdownOnItemSelect = BooleanParse(this.options.closeDropdownOnItemSelect);
18
+ this.options.freeInput = BooleanParse(this.options.freeInput);
19
+ this.options.highlightDuplicate = BooleanParse(this.options.highlightDuplicate);
20
+ this.options.highlightMatchesString = BooleanParse(this.options.highlightMatchesString);
21
+ this.options.removable = BooleanParse(this.options.removable);
22
+ this.options.searchOn = this.options.searchOn.toLowerCase();
23
+ this.options.selectable = BooleanParse(this.options.selectable);
24
+ this.options.trim = BooleanParse(this.options.trim);
25
+ //Bind events to current class
26
+ this._onDocumentClick = this._onDocumentClick.bind(this);
27
+ this._onInputChange = this._onInputChange.bind(this);
28
+ this._onInputClick = this._onInputClick.bind(this);
29
+ this._onInputFocusOut = this._onInputFocusOut.bind(this);
30
+ this._onInputFocusIn = this._onInputFocusIn.bind(this);
31
+ this._onInputKeyDown = this._onInputKeyDown.bind(this);
32
+ this._onInputKeyPress = this._onInputKeyPress.bind(this);
33
+ this._onOriginalInputChange = this._onOriginalInputChange.bind(this);
34
+ this._onTagDeleteClick = this._onTagDeleteClick.bind(this);
35
+ this._onTagClick = this._onTagClick.bind(this);
36
+ this._onDropdownItemClick = this._onDropdownItemClick.bind(this);
37
+ // Define internal variables
38
+ this._items = [];
39
+ this._selected = -1; // index of selected item
40
+ // Initiate plugin
41
+ this._init();
42
+ }
43
+ /**
44
+ * Initiate all DOM element corresponding to selector
45
+ *
46
+ * @method
47
+ * @return Array of all Plugin instances
48
+ */
49
+ static attach(selector = 'input[data-type="tags"], input[type="tags"], select[data-type="tags"], select[type="tags"]', options = {}, container = null) {
50
+ return super.attach(selector, options, container);
51
+ }
52
+ /**
53
+ * Initiate plugin
54
+ *
55
+ * @method init
56
+ * @return
57
+ */
58
+ _init() {
59
+ // Detect if original input was a Select element
60
+ this._isSelect = (this.element.tagName === 'SELECT');
61
+ this._isMultiple = (this._isSelect && this.element.hasAttribute('multiple'));
62
+ // Detect if we work with Object items or not
63
+ // Object Items is forced when working with select element
64
+ this._objectItems = (typeof this.options.itemValue !== 'undefined') || this._isSelect;
65
+ this.options.itemValue = this.options.itemValue ? this.options.itemValue : (this._isSelect ? 'value' : undefined);
66
+ this.options.itemText = this.options.itemText ? this.options.itemText : (this._isSelect ? 'text' : undefined);
67
+ // If no itemText pass then use itemValue as itemText
68
+ if (typeof this.options.itemText === 'undefined') {
69
+ this.options.itemText = this.options.itemValue;
70
+ }
71
+ // Force freeInput to False if working with object items
72
+ this.options.freeInput = this._objectItems ? false : this.options.freeInput;
73
+ // Init search engine
74
+ this.source = null;
75
+ if (typeof this.options.source !== 'undefined') {
76
+ // Fix searchOn option if wrong
77
+ if (!['value', 'text'].includes(this.options.searchOn)) {
78
+ this.options.searchOn = defaultOptions.searchOn;
79
+ }
80
+ if (isPromise(this.options.source)) {
81
+ this.source = this.options.source;
82
+ }
83
+ else if (isFunction(this.options.source)) {
84
+ this.source = value => Promise.resolve(this.options.source(value));
85
+ }
86
+ else if (Array.isArray(this.options.source)) {
87
+ this.source = value => Promise.resolve(this.options.source.filter(i => {
88
+ const val = (this._objectItems ? i[this.options.itemValue] : i);
89
+ return this.options.caseSensitive ? val.includes(value) : val.toLowerCase().includes(value.toLowerCase());
90
+ }));
91
+ }
92
+ }
93
+ // Determine allowed input modes
94
+ this._manualInputAllowed = !this._isSelect && this.options.freeInput;
95
+ this._filterInputAllowed = this._isSelect || this.source;
96
+ this._build();
97
+ }
98
+ /**
99
+ * Build TagsInput DOM elements
100
+ */
101
+ _build() {
102
+ // Create TagsInput DOM
103
+ const containerFragment = document.createRange().createContextualFragment(containerTemplate({
104
+ emptyTitle: typeof this.options.noResultsLabel !== 'undefined' ? this.options.noResultsLabel : 'No results found',
105
+ placeholder: this.element.placeholder ? this.element.placeholder : this.options.placeholder,
106
+ uuid: this.id
107
+ }));
108
+ this.container = containerFragment.firstElementChild;
109
+ this._input = this.container.querySelector('input');
110
+ this.dropdown = this.container.querySelector(`#${this.id}-list .dropdown-content`);
111
+ this.dropdownEmptyOption = this.dropdown.querySelector('.empty-title');
112
+ // Clone attributes between original and new input
113
+ cloneAttributes(this._input, this.element, 'data-type multiple name type value');
114
+ if (this.element.disabled) {
115
+ this.container.setAttribute('disabled', 'disabled');
116
+ this.options.removable = false;
117
+ this.options.selectable = false;
118
+ }
119
+ // Propagate original input disabled attribute to the container
120
+ if (this._input.getAttribute('disabled') || this._input.classList.contains('is-disabled')) {
121
+ this.container.setAttribute('disabled', 'disabled');
122
+ }
123
+ if (!this._manualInputAllowed) {
124
+ this.container.classList.add(this._filterInputAllowed ? 'is-filter' : 'no-input');
125
+ }
126
+ // Remove dropdown if no source or original input is not a select element
127
+ if (!this._isSelect && typeof this.options.source === 'undefined') {
128
+ this.dropdown.remove();
129
+ this.dropdown = null;
130
+ this._input.setAttribute('list', null);
131
+ }
132
+ // Initialize plugin value from original input value
133
+ if (this._isSelect) {
134
+ Array.from(this.element.options).forEach((option) => {
135
+ if (option.selected) {
136
+ // HTML Option element contains value and text properties
137
+ // Add it silently to not propagate to the original element
138
+ this.add(option.value ? option : {
139
+ value: option.text,
140
+ text: option.text
141
+ }, true);
142
+ }
143
+ this._createDropdownItem(option);
144
+ });
145
+ }
146
+ else {
147
+ // We have on input element
148
+ if (this.element.value.length) {
149
+ this.add(this._objectItems ? JSON.parse(this.element.value) : this.element.value, true);
150
+ }
151
+ }
152
+ this._bindEvents();
153
+ // Insert container right before original input and make original input hidden
154
+ this.element.parentNode.insertBefore(this.container, this.element);
155
+ // Hide original input (type="hidden" only works on select)
156
+ this.element.style.display = 'none';
157
+ }
158
+ /**
159
+ * Bind all events listener
160
+ */
161
+ _bindEvents() {
162
+ // Bind document click event to close dropdown
163
+ document.addEventListener('click', this._onDocumentClick);
164
+ // Bind event handlers to orginal input
165
+ this.element.addEventListener('change', this._onOriginalInputChange);
166
+ // Bind event handlers to internal input
167
+ this._input.addEventListener('input', this._onInputChange);
168
+ this._input.addEventListener('click', this._onInputClick);
169
+ this._input.addEventListener('keydown', this._onInputKeyDown);
170
+ this._input.addEventListener('keypress', this._onInputKeyPress);
171
+ this._input.addEventListener('focusout', this._onInputFocusOut);
172
+ this._input.addEventListener('focusin', this._onInputFocusIn);
173
+ }
174
+ /**
175
+ * Check if caret is at the beginning of the input value
176
+ */
177
+ _caretAtStart() {
178
+ try {
179
+ return this._input.selectionStart === 0 && this._input.selectionEnd === 0;
180
+ }
181
+ catch (e) {
182
+ return this._input.value === '';
183
+ }
184
+ }
185
+ /**
186
+ * Check value length constraint if option activated
187
+ *
188
+ * @param item
189
+ */
190
+ _checkLength(item) {
191
+ const value = this._objectItems ? item[this.options.itemValue] : item;
192
+ if (!isString(value)) {
193
+ return true;
194
+ }
195
+ return value.length >= this.options.minChars && (typeof this.options.maxChars === 'undefined' || value.length <= this.options.maxChars);
196
+ }
197
+ /**
198
+ * Close dropdown
199
+ */
200
+ _closeDropdown() {
201
+ if (this.dropdown) {
202
+ this.emit('before.dropdown.close', this);
203
+ this.container.classList.remove('is-active');
204
+ this.emit('after.dropdown.close', this);
205
+ }
206
+ }
207
+ /**
208
+ * Create a new dropdown item based on given item data
209
+ *
210
+ * @param item
211
+ */
212
+ _createDropdownItem(item) {
213
+ if (this.dropdown) {
214
+ // TODO: add possibility to provide template through options
215
+ const dropdownItemFragment = document.createRange().createContextualFragment(dropdownItemTemplate({
216
+ text: item.text,
217
+ value: item.value
218
+ }));
219
+ const dropdownItem = dropdownItemFragment.firstElementChild;
220
+ // Save item data into dataset
221
+ dropdownItem.dataset.value = item.value;
222
+ dropdownItem.dataset.text = item.text;
223
+ dropdownItem.addEventListener('click', this._onDropdownItemClick);
224
+ this.dropdown.append(dropdownItem);
225
+ }
226
+ }
227
+ /**
228
+ * Create a new tag and add it to the DOM
229
+ *
230
+ * @param string value
231
+ */
232
+ _createTag(item) {
233
+ const tagFragment = document.createRange().createContextualFragment(tagTemplate({
234
+ removable: this.options.removable,
235
+ style: this.options.tagClass,
236
+ text: item.text,
237
+ value: item.value
238
+ }));
239
+ const tag = tagFragment.firstElementChild;
240
+ // Attach tag click event to select it
241
+ tag.addEventListener('click', this._onTagClick);
242
+ if (this.options.removable) {
243
+ // Find delete button and attach click event
244
+ const deleteButton = tag.querySelector('.delete');
245
+ if (deleteButton) {
246
+ deleteButton.addEventListener('click', this._onTagDeleteClick);
247
+ }
248
+ }
249
+ // insert new tag at the end (ie just before input)
250
+ this.container.insertBefore(tag, this._input);
251
+ }
252
+ /**
253
+ * Remove all dropdown items except the empty title
254
+ */
255
+ _emptyDropdown() {
256
+ if (this.dropdown) {
257
+ Array.from(this.dropdown.children).filter((child) => !child.classList.contains('empty-title')).forEach((child) => {
258
+ child.remove();
259
+ });
260
+ }
261
+ }
262
+ /**
263
+ * Find needle into a string and wrap it with <mark> HTML tag
264
+ *
265
+ * @param string
266
+ * @param needle
267
+ */
268
+ _highlightMatchesInString(string, needle) {
269
+ const reg = '(' + needle + ')(?![^<]*>|[^<>]*</)'; // explanation: http://stackoverflow.com/a/18622606/1147859
270
+ const regex = new RegExp(reg, 'i');
271
+ // If the regex doesn't match the string just return initial string
272
+ if (!string.match(regex)) {
273
+ return string;
274
+ }
275
+ // Otherwise, get to highlighting
276
+ const matchStartPosition = string.match(regex).index;
277
+ const matchEndPosition = matchStartPosition + string.match(regex)[0].toString().length;
278
+ const originalTextFoundByRegex = string.substring(matchStartPosition, matchEndPosition);
279
+ string = string.replace(regex, `<mark class="is-highlighted">${originalTextFoundByRegex}</mark>`);
280
+ return string;
281
+ }
282
+ /**
283
+ * Open dropdown
284
+ */
285
+ _openDropdown() {
286
+ if (this.dropdown) {
287
+ this.container.classList.add('is-active');
288
+ }
289
+ }
290
+ /**
291
+ * Propagate internal input changes to the original input
292
+ */
293
+ _propagateChange() {
294
+ if (!this._isSelect) {
295
+ // If original element is an input element
296
+ this.element.value = this.value;
297
+ }
298
+ else {
299
+ // If original element is a select element
300
+ Array.from(this.element.options).forEach((option) => {
301
+ option.setAttribute('selected', undefined);
302
+ option.selected = false;
303
+ // If option has been added by TagsInput then we remove it
304
+ // Otherwise it is an original option
305
+ if (typeof option.dataset.source !== 'undefined') {
306
+ option.remove();
307
+ }
308
+ });
309
+ // Update original element options selected attributes
310
+ this._items.forEach(item => {
311
+ this._updateSelectOptions({
312
+ value: this._objectItems ? item[this.options.itemValue] : item,
313
+ text: this._objectItems ? item[this.options.itemText] : item
314
+ });
315
+ });
316
+ }
317
+ // Trigger Change event manually (because original input is now hidden)
318
+ // Trick: Passes current class constructor name to prevent loop with _onOriginalInputChange handler)
319
+ const changeEvent = new CustomEvent('change', {
320
+ detail: this.constructor.name
321
+ });
322
+ this.element.dispatchEvent(changeEvent);
323
+ }
324
+ /**
325
+ * Trim value if option activated
326
+ *
327
+ * @param item
328
+ */
329
+ _trim(item) {
330
+ if (this.options.trim) {
331
+ if (this._objectItems) {
332
+ if (isString(item[this.options.itemValue])) {
333
+ item[this.options.itemValue] = item[this.options.itemValue].trim();
334
+ }
335
+ if (isString(item[this.options.itemText])) {
336
+ item[this.options.itemText] = item[this.options.itemText].trim();
337
+ }
338
+ }
339
+ else {
340
+ item = item.trim();
341
+ }
342
+ }
343
+ return item;
344
+ }
345
+ /**
346
+ * Filter Dropdown items to be compliant with already selected items and current input value
347
+ * Filtering is made on Text by default (can be changed with option)
348
+ */
349
+ _filterDropdownItems(value = null) {
350
+ if (this.dropdown) {
351
+ if (this.emit('before.dropdown.filter', this)) {
352
+ Array.from(this.dropdown.children).filter((child) => !child.classList.contains('empty-title')).forEach((child) => {
353
+ const childValue = child.dataset[this.options.searchOn];
354
+ // Remove highlights
355
+ if (this.options.highlightMatchesString) {
356
+ child.textContent = child.textContent.replace(/<\/?(mark\s?(class="is\-highlighted")?)?>]*>?/gm, '');
357
+ }
358
+ // If value is found in dropdown
359
+ if ((value && value.length)) {
360
+ if (this.options.caseSensitive) {
361
+ child.style.display = childValue.includes(value) ? 'block' : 'none';
362
+ }
363
+ else {
364
+ child.style.display = childValue.toLowerCase().includes(value.toLowerCase()) ? 'block' : 'none';
365
+ }
366
+ if (this.options.highlightMatchesString) {
367
+ child.innerHTML = this._highlightMatchesInString(child.innerHTML, value);
368
+ }
369
+ }
370
+ else {
371
+ child.style.display = 'block';
372
+ }
373
+ if (!this.options.allowDuplicates || (this._isSelect && !this._isMultiple)) {
374
+ const hasValue = this.options.searchOn === 'value' ? this.hasValue(childValue) : this.hasText(childValue);
375
+ child.style.display = hasValue ? 'none' : child.style.display;
376
+ }
377
+ });
378
+ const hasActiveItems = Array.from(this.dropdown.children).filter((child) => !child.classList.contains('empty-title')).some((child) => child.style.display !== 'none');
379
+ if (hasActiveItems) {
380
+ this.dropdownEmptyOption.style.display = 'none';
381
+ }
382
+ else {
383
+ this.dropdownEmptyOption.style.display = 'block';
384
+ }
385
+ this.emit('after.dropdown.filter', this);
386
+ return hasActiveItems;
387
+ }
388
+ }
389
+ return true;
390
+ }
391
+ /**
392
+ * Update original select option based on given item
393
+ *
394
+ * @param item
395
+ */
396
+ _updateSelectOptions(item) {
397
+ if (this._isSelect) {
398
+ // Check to see if the tag exists in its raw or uri-encoded form
399
+ let option = this.element.querySelector(`option[value="${encodeURIComponent(item.value)}"]`) || this.element.querySelector(`option[value="${item.value}"]`);
400
+ // add <option /> if item represents a value not present in one of the <select />'s options
401
+ if (!option) {
402
+ const optionFragment = document.createRange().createContextualFragment(`<option value="${item.value}" data-source="${this.id}" selected>${item.text}</option>`);
403
+ option = optionFragment.firstElementChild;
404
+ this.element.add(option);
405
+ }
406
+ // mark option as selected
407
+ option.setAttribute('selected', 'selected');
408
+ option.selected = true;
409
+ }
410
+ }
411
+ /**
412
+ * Add given item
413
+ * item = 'john'
414
+ * item = 'john,jane'
415
+ * item = ['john', 'jane']
416
+ * item = [{
417
+ * "value": "1",
418
+ * "text": "John"
419
+ * }, {
420
+ * "value": "2",
421
+ * "text": "Jane"
422
+ * }]
423
+ *
424
+ * @param item
425
+ * @param silently Should the change be propagated to the original element
426
+ */
427
+ add(items, silently = false) {
428
+ // Check if number of items is limited ans reached
429
+ if (typeof this.options.maxTags !== 'undefined' && this._items.length >= this.options.maxTags) {
430
+ return this;
431
+ }
432
+ // Make sure to work with an array of items
433
+ items = Array.isArray(items) ? items : isObject(items) ? [items] : items.split(this.options.delimiter);
434
+ // If string items are expected then check every item is a string
435
+ if (!this._objectItems && (items.filter(item => isString(item)).length !== items.length)) {
436
+ throw ('Item must be a string or an array of strings');
437
+ }
438
+ // If object items are expected then check every item is an object
439
+ if (this._objectItems && (items.filter(item => isObject(item)).length !== items.length)) {
440
+ throw ('Item must be an object or an array of objects');
441
+ }
442
+ items.forEach(item => {
443
+ item = this._trim(item);
444
+ // Check if item respects min/max chars
445
+ if (this._checkLength(item)) {
446
+ // If original input is a non multiple select element
447
+ if (this._isSelect && !this._isMultiple && this._items.length > 0) {
448
+ this.removeAtIndex(0);
449
+ this.element.remove(this.element.selectedIndex);
450
+ }
451
+ // check if duplicates are allowed or not
452
+ if (item = this.emit('before.add', item)) {
453
+ if (this.options.allowDuplicates || !this.has(item)) {
454
+ const itemData = {
455
+ value: this._objectItems ? item[this.options.itemValue] : item,
456
+ text: this._objectItems ? item[this.options.itemText] : item
457
+ };
458
+ const tag = this._createTag(itemData);
459
+ // save item into the internal array
460
+ this._items.push(item);
461
+ if (!silently) {
462
+ // Propagate change event to the original input
463
+ this._propagateChange();
464
+ this.emit('after.add', {
465
+ item,
466
+ tag
467
+ });
468
+ }
469
+ }
470
+ else {
471
+ if (this.options.highlightDuplicate) {
472
+ const duplicateTag = Array.from(this.container.children).filter((child) => child.classList.contains('tag'))[this.indexOf(item)];
473
+ if (duplicateTag) {
474
+ duplicateTag.classList.add('is-duplicate');
475
+ setTimeout(() => {
476
+ duplicateTag.classList.remove('is-duplicate');
477
+ }, 1250);
478
+ }
479
+ }
480
+ this.emit('item.duplicate', item);
481
+ }
482
+ }
483
+ }
484
+ });
485
+ return this;
486
+ }
487
+ /**
488
+ * Unselect the selected item
489
+ */
490
+ clearSelection() {
491
+ if (this._selected >= 0) {
492
+ const item = this._items[this._selected];
493
+ const tag = Array.from(this.container.children).filter((child) => child.classList.contains('tag'))[this._selected];
494
+ if (this.emit('before.unselect', {
495
+ item,
496
+ tag
497
+ })) {
498
+ if (tag) {
499
+ tag.classList.remove('is-selected');
500
+ }
501
+ this._selected = -1;
502
+ this.emit('after.unselect', {
503
+ item,
504
+ tag
505
+ });
506
+ }
507
+ }
508
+ return this;
509
+ }
510
+ /**
511
+ * Shortcut to removeAll method
512
+ */
513
+ flush() {
514
+ return this.removeAll();
515
+ }
516
+ /**
517
+ * Sets focus on the input
518
+ */
519
+ focus() {
520
+ this.container.classList.add('is-focused');
521
+ this._input.focus();
522
+ return this;
523
+ }
524
+ /**
525
+ * Check if given item is present
526
+ *
527
+ * @param item
528
+ */
529
+ has(item) {
530
+ item = this._trim(item);
531
+ if (this._objectItems) {
532
+ return this._items.some(i => this.options.caseSensitive || !isString(i[this.options.itemValue]) ? i[this.options.itemValue] === item[this.options.itemValue] : i[this.options.itemValue].toLowerCase() === item[this.options.itemValue].toLowerCase());
533
+ }
534
+ else {
535
+ return this.hasValue(item);
536
+ }
537
+ }
538
+ /**
539
+ * Check if given text is present
540
+ *
541
+ * @param value
542
+ */
543
+ hasText(value) {
544
+ if (this.options.trim) {
545
+ value = value.trim();
546
+ }
547
+ return this._items.some(i => {
548
+ const val = (this._objectItems ? i[this.options.itemText] : i);
549
+ return this.options.caseSensitive ? val === value : val.toLowerCase() === value.toLowerCase();
550
+ });
551
+ }
552
+ /**
553
+ * Check if given value is present
554
+ *
555
+ * @param value
556
+ */
557
+ hasValue(value) {
558
+ if (this.options.trim) {
559
+ value = value.trim();
560
+ }
561
+ return this._items.some(i => {
562
+ const val = (this._objectItems ? i[this.options.itemValue] : i);
563
+ return this.options.caseSensitive ? val === value : val.toLowerCase() === value.toLowerCase();
564
+ });
565
+ }
566
+ /**
567
+ * Get index of given item
568
+ *
569
+ * @param item
570
+ */
571
+ indexOf(item) {
572
+ item = this._trim(item);
573
+ if (this._objectItems) {
574
+ if (!isObject(item)) {
575
+ throw ('Item must be an object');
576
+ }
577
+ return this._items.map(function (e) { return e.value; }).indexOf(item.value);
578
+ }
579
+ else {
580
+ return this._items.indexOf(item);
581
+ }
582
+ }
583
+ /**
584
+ * Returns the internal input element
585
+ */
586
+ input() {
587
+ return this._input;
588
+ }
589
+ /**
590
+ * Get items
591
+ */
592
+ items() {
593
+ return this._items;
594
+ }
595
+ /**
596
+ * Remove given item
597
+ * item = 'john'
598
+ * item = 'john,jane'
599
+ *
600
+ * @param String item
601
+ */
602
+ remove(items) {
603
+ if (this.options.removable) {
604
+ // Make sure to work with an array of items
605
+ items = Array.isArray(items) ? items : isObject(items) ? [items] : items.split(this.options.delimiter);
606
+ // If string items are expected then check every item is a string
607
+ if (!this._objectItems && (items.filter(item => isString(item)).length !== items.length)) {
608
+ throw ('Item must be a string or an array of strings');
609
+ }
610
+ // If object items are expected then check every item is an object
611
+ if (this._objectItems && (items.filter(item => isObject(item)).length !== items.length)) {
612
+ throw ('Item must be an object or an array of objects');
613
+ }
614
+ items.forEach(item => {
615
+ let index = this.indexOf(item);
616
+ while (index >= 0) {
617
+ this.removeAtIndex(index);
618
+ index = this.indexOf(item);
619
+ }
620
+ });
621
+ }
622
+ return this;
623
+ }
624
+ /**
625
+ * Remove all tags at once
626
+ */
627
+ removeAll() {
628
+ if (this.options.removable) {
629
+ if (this.emit('before.flush', this._items)) {
630
+ this.clearSelection();
631
+ Array.from(this.container.children).filter((child) => child.classList.contains('tag')).forEach((tag) => tag.remove());
632
+ this._items = [];
633
+ this._filterDropdownItems();
634
+ this._propagateChange();
635
+ this.emit('after.flush', this._items);
636
+ }
637
+ }
638
+ return this;
639
+ }
640
+ /**
641
+ * Remove item at given index
642
+ *
643
+ * @param Integer index
644
+ */
645
+ removeAtIndex(index, clearSelection = true) {
646
+ if (this.options.removable && !isNaN(index) && index >= 0 && index < this._items.length) {
647
+ const tag = Array.from(this.container.children).filter((child) => child.classList.contains('tag'))[index];
648
+ const item = this._items[index];
649
+ if (this.emit('before.remove', item)) {
650
+ if (clearSelection) {
651
+ this.clearSelection();
652
+ }
653
+ if (tag) {
654
+ tag.remove();
655
+ }
656
+ // If original input is a select element
657
+ // then deselect related option
658
+ if (this._isSelect) {
659
+ this.element.options[index].selected = false;
660
+ }
661
+ if (this._selected == index) {
662
+ this._selected = -1;
663
+ }
664
+ else if (this._selected >= 0) {
665
+ // One item less so selected index is
666
+ this._selected -= 1;
667
+ }
668
+ this._items.splice(index, 1);
669
+ this._filterDropdownItems();
670
+ this._propagateChange();
671
+ this.emit('after.remove', item);
672
+ }
673
+ }
674
+ return this;
675
+ }
676
+ /**
677
+ * Select given item
678
+ *
679
+ * @param item
680
+ */
681
+ select(items) {
682
+ if (this.options.selectable) {
683
+ // Make sure to work with an array of items
684
+ items = Array.isArray(items) ? items : isObject(items) ? [items] : items.split(this.options.delimiter);
685
+ // If string items are expected then check every item is a string
686
+ if (!this._objectItems && (items.filter(item => isString(item)).length !== items.length)) {
687
+ throw ('Item must be a string or an array of strings');
688
+ }
689
+ // If object items are expected then check every item is an object
690
+ if (this._objectItems && (items.filter(item => isObject(item)).length !== items.length)) {
691
+ throw ('Item must be an object or an array of objects');
692
+ }
693
+ items.forEach(item => {
694
+ this.selectAtIndex(this.indexOf(item));
695
+ });
696
+ }
697
+ return this;
698
+ }
699
+ /**
700
+ * Select tag at given index
701
+ *
702
+ * @param Integer index
703
+ */
704
+ selectAtIndex(index) {
705
+ if (this.options.selectable) {
706
+ // Clear selection
707
+ this.clearSelection();
708
+ if (!isNaN(index) && index >= 0 && index < this._items.length) {
709
+ const tag = Array.from(this.container.children).filter((child) => child.classList.contains('tag'))[index];
710
+ const item = this._items[index];
711
+ if (this.emit('before.select', {
712
+ item,
713
+ tag
714
+ })) {
715
+ if (tag) {
716
+ tag.classList.add('is-selected');
717
+ }
718
+ this._selected = index;
719
+ this.emit('after.select', {
720
+ item,
721
+ tag
722
+ });
723
+ }
724
+ }
725
+ }
726
+ return this;
727
+ }
728
+ /**
729
+ * Get selected item
730
+ */
731
+ get selected() {
732
+ if (this._selected >= 0) {
733
+ return this._items[this._selected];
734
+ }
735
+ else {
736
+ return null;
737
+ }
738
+ }
739
+ /**
740
+ * Get selected item index
741
+ */
742
+ get selectedIndex() {
743
+ return this._selected;
744
+ }
745
+ /**
746
+ * Get value
747
+ */
748
+ get value() {
749
+ if (!this._isSelect) {
750
+ if (this._objectItems) {
751
+ return this._items.map(item => item.value).join(this.options.delimiter);
752
+ }
753
+ else {
754
+ return this._items.join(this.options.delimiter);
755
+ }
756
+ }
757
+ else {
758
+ return Array.from(this.element.options).filter((option) => option.selected).map((option) => option.value);
759
+ }
760
+ }
761
+ /**
762
+ * Set value
763
+ */
764
+ set value(string) {
765
+ this.removeAll();
766
+ this.add(string);
767
+ }
768
+ /**
769
+ * Document click event handler
770
+ *
771
+ * @param e
772
+ */
773
+ _onDocumentClick(e) {
774
+ if (this.dropdown) {
775
+ // If we click on element inside container then do nothing
776
+ if (this.container.contains(e.target)) {
777
+ return;
778
+ }
779
+ // Tag and delete button already deleted when event triggered
780
+ // So we check if target is a tag delete button
781
+ if (e.target.dataset.tag && e.target.dataset.tag === 'delete') {
782
+ return;
783
+ }
784
+ // Click outside dropdown so close it
785
+ this._closeDropdown();
786
+ }
787
+ }
788
+ /**
789
+ * Input focus lost event handler
790
+ *
791
+ * @param e
792
+ */
793
+ _onDropdownItemClick(e) {
794
+ e.preventDefault();
795
+ if (this.dropdown) {
796
+ if (this._objectItems) {
797
+ const item = {};
798
+ item[this.options.itemText] = e.currentTarget.dataset.text;
799
+ item[this.options.itemValue] = e.currentTarget.dataset.value;
800
+ this.add(item);
801
+ }
802
+ else {
803
+ this.add(e.currentTarget.dataset.value);
804
+ }
805
+ this._filterDropdownItems();
806
+ this._input.value = '';
807
+ this._input.focus();
808
+ if (this.options.closeDropdownOnItemSelect) {
809
+ this._closeDropdown();
810
+ }
811
+ }
812
+ }
813
+ /**
814
+ * Input change event handler
815
+ *
816
+ * @param e
817
+ */
818
+ _onInputChange(e) {
819
+ this._filterDropdownItems(this._input.value);
820
+ }
821
+ /**
822
+ * Input click event handler
823
+ *
824
+ * @param e
825
+ */
826
+ _onInputClick(e) {
827
+ e.preventDefault();
828
+ if (!this.source || this._input.value.length >= this.options.searchMinChars) {
829
+ this._openDropdown();
830
+ this._filterDropdownItems();
831
+ }
832
+ }
833
+ /**
834
+ * Input focus event handler
835
+ *
836
+ * @param e
837
+ */
838
+ _onInputFocusIn(e) {
839
+ e.preventDefault();
840
+ if (this.container.getAttribute('disabled') !== null || this.container.classList.contains('is-disabled')) {
841
+ this._input.blur();
842
+ return false;
843
+ }
844
+ this.container.classList.add('is-focused');
845
+ }
846
+ /**
847
+ * Input focus lost event handler
848
+ *
849
+ * @param e
850
+ */
851
+ _onInputFocusOut(e) {
852
+ e.preventDefault();
853
+ this.container.classList.remove('is-focused');
854
+ }
855
+ /**
856
+ * Input Keydown event handler
857
+ *
858
+ * @param e
859
+ */
860
+ _onInputKeyDown(e) {
861
+ const key = e.charCode || e.keyCode || e.which;
862
+ switch (key) {
863
+ // BACKSPACE
864
+ case 8:
865
+ if (this.options.removable) {
866
+ if (this._caretAtStart() && this._selected >= 0) {
867
+ const currentItemIndex = this._selected;
868
+ // If tag was selected then select next (or previous if next does not exists)
869
+ if (currentItemIndex >= 0) {
870
+ this.selectAtIndex(currentItemIndex + 1 < this._items.length ? currentItemIndex + 1 : currentItemIndex - 1);
871
+ }
872
+ this.removeAtIndex(currentItemIndex, false);
873
+ }
874
+ }
875
+ if (this.source && (this._input.value.length) < this.options.searchMinChars) {
876
+ this._closeDropdown();
877
+ }
878
+ break;
879
+ // ESCAPE
880
+ case 27:
881
+ if (this._selected >= 0) {
882
+ this.clearSelection();
883
+ }
884
+ this._closeDropdown();
885
+ break;
886
+ // DELETE
887
+ case 46:
888
+ if (this.options.removable) {
889
+ if (this._caretAtStart() && this._selected >= 0) {
890
+ const currentItemIndex = this._selected;
891
+ // If tag was selected then select next (or previous if next does not exists)
892
+ if (currentItemIndex >= 0) {
893
+ this.selectAtIndex(currentItemIndex + 1 < this._items.length ? currentItemIndex + 1 : currentItemIndex - 1);
894
+ }
895
+ this.removeAtIndex(currentItemIndex, false);
896
+ }
897
+ }
898
+ if (this.source && (this._input.value.length) < this.options.searchMinChars) {
899
+ this._closeDropdown();
900
+ }
901
+ break;
902
+ // LEFT ARROW
903
+ case 37:
904
+ if (!this._input.value.length) {
905
+ if (this._selected < 0) {
906
+ this.selectAtIndex(this._items.length - 1);
907
+ }
908
+ else {
909
+ this.selectAtIndex(this._selected - 1 >= 0 ? this._selected - 1 : this._items.length - 1);
910
+ }
911
+ }
912
+ break;
913
+ // RIGHT ARROW
914
+ case 39:
915
+ if (!this._input.value.length) {
916
+ if (this._selected < 0) {
917
+ this.selectAtIndex(0);
918
+ }
919
+ else {
920
+ this.selectAtIndex(this._selected + 1 >= this._items.length ? 0 : this._selected + 1);
921
+ }
922
+ }
923
+ break;
924
+ default:
925
+ if (this.options.clearSelectionOnTyping) {
926
+ this.clearSelection();
927
+ }
928
+ // ignore
929
+ }
930
+ }
931
+ /**
932
+ * Input Keypress event handler
933
+ *
934
+ * @param e
935
+ */
936
+ _onInputKeyPress(e) {
937
+ const key = e.charCode || e.keyCode || e.which;
938
+ let value = this._trim(this._input.value) + String.fromCharCode(key);
939
+ if (!this._manualInputAllowed && !this._filterInputAllowed) {
940
+ e.preventDefault();
941
+ return false;
942
+ }
943
+ // ENTER
944
+ if (!value.length && key !== 13) {
945
+ return false;
946
+ }
947
+ if (this._filterInputAllowed) {
948
+ this._filterDropdownItems(value);
949
+ }
950
+ if (this._filterInputAllowed && this.source && value.length >= this.options.searchMinChars && key !== 13) {
951
+ this._openDropdown();
952
+ this.dropdown.classList.add('is-loading');
953
+ this._emptyDropdown();
954
+ this.source(value).then(results => {
955
+ results = this.emit('on.results.received', results);
956
+ if (results.length) {
957
+ results.forEach(result => {
958
+ const item = {
959
+ value: null,
960
+ text: null
961
+ };
962
+ if (!isObject(result)) {
963
+ item.value = result;
964
+ item.text = result;
965
+ }
966
+ else {
967
+ item.value = result[this.options.itemValue];
968
+ item.text = result[this.options.itemText];
969
+ }
970
+ this._createDropdownItem(item);
971
+ });
972
+ }
973
+ this._filterDropdownItems(value);
974
+ this.dropdown.classList.remove('is-loading');
975
+ });
976
+ }
977
+ if (this._manualInputAllowed && (value.includes(this.options.delimiter) || key == 13)) {
978
+ // Prevent default behavior (ie: add char into input value)
979
+ e.preventDefault();
980
+ // Split value by delimiter in case we copy/paste multiple values
981
+ const values = value.split(this.options.delimiter);
982
+ values.forEach(value => {
983
+ // check if empty text when delimiter is removed
984
+ if ((value = value.replace(this.options.delimiter, '')) != '') {
985
+ // push to array and remove delimiter
986
+ this.add(value);
987
+ }
988
+ });
989
+ value = '';
990
+ // clear input
991
+ this._input.value = '';
992
+ this._closeDropdown();
993
+ return false;
994
+ }
995
+ }
996
+ /**
997
+ * Original input change event handler
998
+ * CAUTION: because original input is now hidden the change event must be triggered manually on change
999
+ * Example how to trigger change event manually
1000
+ * var changeEvent = new Event('change');
1001
+ * input.dispatchEvent(changeEvent);
1002
+ *
1003
+ * @param e
1004
+ */
1005
+ _onOriginalInputChange(e) {
1006
+ if (!e.detail || isString(e.detail) && e.detail !== this.constructor.name) {
1007
+ this.value = e.currentTarget.value;
1008
+ }
1009
+ }
1010
+ /**
1011
+ * Tag click event handler
1012
+ *
1013
+ * @param e
1014
+ */
1015
+ _onTagClick(e) {
1016
+ e.preventDefault();
1017
+ if (e.currentTarget.classList.contains('delete')) {
1018
+ return false;
1019
+ }
1020
+ if (this.container.getAttribute('disabled') !== null || this.container.classList.contains('is-disabled')) {
1021
+ return false;
1022
+ }
1023
+ this._input.focus();
1024
+ if (this.options.selectable) {
1025
+ const tag = e.currentTarget.closest('.tag');
1026
+ if (tag) {
1027
+ const tagIndex = Array.from(this.container.children).indexOf(tag);
1028
+ if (tagIndex === this._selected) {
1029
+ this.clearSelection();
1030
+ }
1031
+ else {
1032
+ this.selectAtIndex(tagIndex);
1033
+ }
1034
+ }
1035
+ }
1036
+ }
1037
+ /**
1038
+ * Delete tag button click event handler
1039
+ *
1040
+ * @param e
1041
+ */
1042
+ _onTagDeleteClick(e) {
1043
+ e.preventDefault();
1044
+ if (this.container.getAttribute('disabled') !== null || this.container.classList.contains('is-disabled')) {
1045
+ return false;
1046
+ }
1047
+ const tag = e.currentTarget.closest('.tag');
1048
+ if (tag) {
1049
+ this.removeAtIndex(Array.from(this.container.children).indexOf(tag));
1050
+ }
1051
+ }
1052
+ }
1053
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGFncy1pbnB1dC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxvQkFBb0I7QUFDcEIsT0FBTyxTQUFTLE1BQU0sbUJBQW1CLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2RixPQUFPLGNBQWMsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLFdBQVcsTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLGlCQUFpQixNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sb0JBQW9CLE1BQU0sMkJBQTJCLENBQUM7QUFFN0QsZ0VBQWdFO0FBRWhFLE1BQU0sQ0FBQyxPQUFPLE9BQU8sY0FBZSxTQUFRLFNBQVM7SUFjbkQsWUFBWSxPQUFPLEVBQUUsT0FBTyxHQUFHLEVBQUU7UUFDL0IsS0FBSyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFFeEMsaURBQWlEO1FBQ2pELElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsT0FBTyxDQUFDLHlCQUF5QixHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLHlCQUF5QixDQUFD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LGNBQWMsRUFBRSxDQUFDO1FBRW5CLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRTtZQUN4RyxPQUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFNUMsSUFBSSxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUN0RTtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgQ29tcG9uZW50IGZyb20gJy4vdXRpbHMvY29tcG9uZW50JztcbmltcG9ydCB7IGNsb25lQXR0cmlidXRlcyB9IGZyb20gJy4vdXRpbHMvZG9tJztcbmltcG9ydCB7IGlzU3RyaW5nLCBCb29sZWFuUGFyc2UsIGlzT2JqZWN0LCBpc1Byb21pc2UsIGlzRnVuY3Rpb24gfSBmcm9tICcuL3V0aWxzL3R5cGUnO1xuaW1wb3J0IGRlZmF1bHRPcHRpb25zIGZyb20gJy4vZGVmYXVsdE9wdGlvbnMnO1xuaW1wb3J0IHRhZ1RlbXBsYXRlIGZyb20gJy4vdGVtcGxhdGVzL3RhZyc7XG5pbXBvcnQgY29udGFpbmVyVGVtcGxhdGUgZnJvbSAnLi90ZW1wbGF0ZXMvd3JhcHBlcic7XG5pbXBvcnQgZHJvcGRvd25JdGVtVGVtcGxhdGUgZnJvbSAnLi90ZW1wbGF0ZXMvZHJvcGRvd24taXRlbSc7XG5cbi8vIFRPRE86IGFkZCBwYXR0ZXJuIG9yIGZ1bmN0aW9uIHRvIHZhbGRpYXRlIHZhbHVlIGJlZm9yZSBhZGRpbmdcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnVsbWFUYWdzSW5wdXQgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwcml2YXRlIF9pdGVtczogYW55W107XG4gIHByaXZhdGUgX3NlbGVjdGVkO1xuICBwcml2YXRlIF9pc1NlbGVjdDtcbiAgcHJpdmF0ZSBfaXNNdWx0aXBsZTtcbiAgcHJpdmF0ZSBfb2JqZWN0SXRlbXM7XG4gIHByaXZhdGUgX2lucHV0O1xuICBwcml2YXRlIF9tYW51YWxJbnB1dEFsbG93ZWQ7XG4gIHByaXZhdGUgX2ZpbHRlcklucHV0QWxsb3dlZDtcbiAgcHJpdmF0ZSBzb3VyY2U7XG4gIHByaXZhdGUgY29udGFpbmVyO1xuICBwcml2YXRlIGRyb3Bkb3duO1xuICBwcml2YXRlIGRyb3Bkb3duRW1wdHlPcHRpb247XG5cbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoZWxlbWVudCwgb3B0aW9ucywgZGVmYXVsdE9wdGlvbnMpO1xuXG4gICAgLy8gQ29udmVydCBCb29sZWFuIHN0cmluZyBvcHRpb25zIHRvIGZ1bGwgQm9vbGVhblxuICAgIHRoaXMub3B0aW9ucy5hbGxvd0R1cGxpY2F0ZXMgPSBCb29sZWFuUGFyc2UodGhpcy5vcHRpb25zLmFsbG93RHVwbGljYXRlcyk7XG4gICAgdGhpcy5vcHRpb25zLmNhc2VTZW5zaXRpdmUgPSBCb29sZWFuUGFyc2UodGhpcy5vcHRpb25zLmNhc2VTZW5zaXRpdmUpO1xuICAgIHRoaXMub3B0aW9ucy5jbGVhclNlbGVjdGlvbk9uVHlwaW5nID0gQm9vbGVhblBhcnNlKHRoaXMub3B0aW9ucy5jbGVhclNlbGVjdGlvbk9uVHlwaW5nKTtcbiAgICB0aGlzLm9wdGlvbnMuY2xvc2VEcm9wZG93bk9uSXRlbVNlbGVjdCA9IEJvb2xlYW5QYXJzZSh0aGlzLm9wdGlvbnMuY2xvc2VEcm9wZG93bk9uSXRlbVNlbGVjdCk7XG4gICAgdGhpcy5vcHRpb25zLmZyZWVJbnB1dCA9IEJvb2xlYW5QYXJzZSh0aGlzLm9wdGlvbnMuZnJlZUlucHV0KTtcbiAgICB0aGlzLm9wdGlvbnMuaGlnaGxpZ2h0RHVwbGljYXRlID0gQm9vbGVhblBhcnNlKHRoaXMub3B0aW9ucy5oaWdobGlnaHREdXBsaWNhdGUpO1xuICAgIHRoaXMub3B0aW9ucy5oaWdobGlnaHRNYXRjaGVzU3RyaW5nID0gQm9vbGVhblBhcnNlKHRoaXMub3B0aW9ucy5oaWdobGlnaHRNYXRjaGVzU3RyaW5nKTtcbiAgICB0aGlzLm9wdGlvbnMucmVtb3ZhYmxlID0gQm9vbGVhblBhcnNlKHRoaXMub3B0aW9ucy5yZW1vdmFibGUpO1xuICAgIHRoaXMub3B0aW9ucy5zZWFyY2hPbiA9IHRoaXMub3B0aW9ucy5zZWFyY2hPbi50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMub3B0aW9ucy5zZWxlY3RhYmxlID0gQm9vbGVhblBhcnNlKHRoaXMub3B0aW9ucy5zZWxlY3RhYmxlKTtcbiAgICB0aGlzLm9wdGlvbnMudHJpbSA9IEJvb2xlYW5QYXJzZSh0aGlzLm9wdGlvbnMudHJpbSk7XG5cbiAgICAvL0JpbmQgZXZlbnRzIHRvIGN1cnJlbnQgY2xhc3NcbiAgICB0aGlzLl9vbkRvY3VtZW50Q2xpY2sgPSB0aGlzLl9vbkRvY3VtZW50Q2xpY2suYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbklucHV0Q2hhbmdlID0gdGhpcy5fb25JbnB1dENoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uSW5wdXRDbGljayA9IHRoaXMuX29uSW5wdXRDbGljay5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uSW5wdXRGb2N1c091dCA9IHRoaXMuX29uSW5wdXRGb2N1c091dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uSW5wdXRGb2N1c0luID0gdGhpcy5fb25JbnB1dEZvY3VzSW4uYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbklucHV0S2V5RG93biA9IHRoaXMuX29uSW5wdXRLZXlEb3duLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25JbnB1dEtleVByZXNzID0gdGhpcy5fb25JbnB1dEtleVByZXNzLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25PcmlnaW5hbElucHV0Q2hhbmdlID0gdGhpcy5fb25PcmlnaW5hbElucHV0Q2hhbmdlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25UYWdEZWxldGVDbGljayA9IHRoaXMuX29uVGFnRGVsZXRlQ2xpY2suYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vblRhZ0NsaWNrID0gdGhpcy5fb25UYWdDbGljay5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uRHJvcGRvd25JdGVtQ2xpY2sgPSB0aGlzLl9vbkRyb3Bkb3duSXRlbUNsaWNrLmJpbmQodGhpcyk7XG5cbiAgICAvLyBEZWZpbmUgaW50ZXJuYWwgdmFyaWFibGVzXG4gICAgdGhpcy5faXRlbXMgPSBbXTtcbiAgICB0aGlzLl9zZWxlY3RlZCA9IC0xOyAvLyBpbmRleCBvZiBzZWxlY3RlZCBpdGVtXG5cbiAgICAvLyBJbml0aWF0ZSBwbHVnaW5cbiAgICB0aGlzLl9pbml0KCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhdGUgYWxsIERPTSBlbGVtZW50IGNvcnJlc3BvbmRpbmcgdG8gc2VsZWN0b3JcbiAgICpcbiAgICogQG1ldGhvZFxuICAgKiBAcmV0dXJuIEFycmF5IG9mIGFsbCBQbHVnaW4gaW5zdGFuY2VzXG4gICAqL1xuICBzdGF0aWMgYXR0YWNoKHNlbGVjdG9yID0gJ2lucHV0W2RhdGEtdHlwZT1cInRhZ3NcIl0sIGlucHV0W3R5cGU9XCJ0YWdzXCJdLCBzZWxlY3RbZGF0YS10eXBlPVwidGFnc1wiXSwgc2VsZWN0W3R5cGU9XCJ0YWdzXCJdJywgb3B0aW9ucyA9IHt9LCBjb250YWluZXIgPSBudWxsKSB7XG4gICAgcmV0dXJuIHN1cGVyLmF0dGFjaChzZWxlY3Rvciwgb3B0aW9ucywgY29udGFpbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWF0ZSBwbHVnaW5cbiAgICpcbiAgICogQG1ldGhvZCBpbml0XG4gICAqIEByZXR1cm5cbiAgICovXG4gIF9pbml0KCkge1xuICAgIC8vIERldGVjdCBpZiBvcmlnaW5hbCBpbnB1dCB3YXMgYSBTZWxlY3QgZWxlbWVudFxuICAgIHRoaXMuX2lzU2VsZWN0ID0gKHRoaXMuZWxlbWVudC50YWdOYW1lID09PSAnU0VMRUNUJyk7XG4gICAgdGhpcy5faXNNdWx0aXBsZSA9ICh0aGlzLl9pc1NlbGVjdCAmJiB0aGlzLmVsZW1lbnQuaGFzQXR0cmlidXRlKCdtdWx0aXBsZScpKTtcblxuICAgIC8vIERldGVjdCBpZiB3ZSB3b3JrIHdpdGggT2JqZWN0IGl0ZW1zIG9yIG5vdFxuICAgIC8vIE9iamVjdCBJdGVtcyBpcyBmb3JjZWQgd2hlbiB3b3JraW5nIHdpdGggc2VsZWN0IGVsZW1lbnRcbiAgICB0aGlzLl9vYmplY3RJdGVtcyA9ICh0eXBlb2YgdGhpcy5vcHRpb25zLml0ZW1WYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHx8IHRoaXMuX2lzU2VsZWN0O1xuICAgIHRoaXMub3B0aW9ucy5pdGVtVmFsdWUgPSB0aGlzLm9wdGlvbnMuaXRlbVZhbHVlID8gdGhpcy5vcHRpb25zLml0ZW1WYWx1ZSA6ICh0aGlzLl9pc1NlbGVjdCA/ICd2YWx1ZScgOiB1bmRlZmluZWQpO1xuICAgIHRoaXMub3B0aW9ucy5pdGVtVGV4dCA9IHRoaXMub3B0aW9ucy5pdGVtVGV4dCA/IHRoaXMub3B0aW9ucy5pdGVtVGV4dCA6ICh0aGlzLl9pc1NlbGVjdCA/ICd0ZXh0JyA6IHVuZGVmaW5lZCk7XG4gICAgLy8gSWYgbm8gaXRlbVRleHQgcGFzcyB0aGVuIHVzZSBpdGVtVmFsdWUgYXMgaXRlbVRleHRcbiAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9ucy5pdGVtVGV4dCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5pdGVtVGV4dCA9IHRoaXMub3B0aW9ucy5pdGVtVmFsdWU7XG4gICAgfVxuXG4gICAgLy8gRm9yY2UgZnJlZUlucHV0IHRvIEZhbHNlIGlmIHdvcmtpbmcgd2l0aCBvYmplY3QgaXRlbXNcbiAgICB0aGlzLm9wdGlvbnMuZnJlZUlucHV0ID0gdGhpcy5fb2JqZWN0SXRlbXMgPyBmYWxzZSA6IHRoaXMub3B0aW9ucy5mcmVlSW5wdXQ7XG5cbiAgICAvLyBJbml0IHNlYXJjaCBlbmdpbmVcbiAgICB0aGlzLnNvdXJjZSA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuc291cmNlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgLy8gRml4IHNlYXJjaE9uIG9wdGlvbiBpZiB3cm9uZ1xuICAgICAgaWYgKCFbJ3ZhbHVlJywgJ3RleHQnXS5pbmNsdWRlcyh0aGlzLm9wdGlvbnMuc2VhcmNoT24pKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucy5zZWFyY2hPbiA9IGRlZmF1bHRPcHRpb25zLnNlYXJjaE9uO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNQcm9taXNlKHRoaXMub3B0aW9ucy5zb3VyY2UpKSB7XG4gICAgICAgIHRoaXMuc291cmNlID0gdGhpcy5vcHRpb25zLnNvdXJjZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLm9wdGlvbnMuc291cmNlKSkge1xuICAgICAgICB0aGlzLnNvdXJjZSA9IHZhbHVlID0+IFByb21pc2UucmVzb2x2ZSh0aGlzLm9wdGlvbnMuc291cmNlKHZhbHVlKSk7XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5vcHRpb25zLnNvdXJjZSkpIHtcbiAgICAgICAgdGhpcy5zb3VyY2UgPSB2YWx1ZSA9PiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRpb25zLnNvdXJjZS5maWx0ZXIoaSA9PiB7XG4gICAgICAgICAgY29uc3QgdmFsID0gKHRoaXMuX29iamVjdEl0ZW1zID8gaVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXSA6IGkpO1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5jYXNlU2Vuc2l0aXZlID8gdmFsLmluY2x1ZGVzKHZhbHVlKSA6IHZhbC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIGFsbG93ZWQgaW5wdXQgbW9kZXNcbiAgICB0aGlzLl9tYW51YWxJbnB1dEFsbG93ZWQgPSAhdGhpcy5faXNTZWxlY3QgJiYgdGhpcy5vcHRpb25zLmZyZWVJbnB1dDtcbiAgICB0aGlzLl9maWx0ZXJJbnB1dEFsbG93ZWQgPSB0aGlzLl9pc1NlbGVjdCB8fCB0aGlzLnNvdXJjZTtcblxuICAgIHRoaXMuX2J1aWxkKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgVGFnc0lucHV0IERPTSBlbGVtZW50c1xuICAgKi9cbiAgX2J1aWxkKCkge1xuICAgIC8vIENyZWF0ZSBUYWdzSW5wdXQgRE9NXG4gICAgY29uc3QgY29udGFpbmVyRnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChjb250YWluZXJUZW1wbGF0ZSh7XG4gICAgICBlbXB0eVRpdGxlOiB0eXBlb2YgdGhpcy5vcHRpb25zLm5vUmVzdWx0c0xhYmVsICE9PSAndW5kZWZpbmVkJyA/IHRoaXMub3B0aW9ucy5ub1Jlc3VsdHNMYWJlbCA6ICdObyByZXN1bHRzIGZvdW5kJyxcbiAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmVsZW1lbnQucGxhY2Vob2xkZXIgPyB0aGlzLmVsZW1lbnQucGxhY2Vob2xkZXIgOiB0aGlzLm9wdGlvbnMucGxhY2Vob2xkZXIsXG4gICAgICB1dWlkOiB0aGlzLmlkXG4gICAgfSkpO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXJGcmFnbWVudC5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB0aGlzLl9pbnB1dCA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ2lucHV0Jyk7XG4gICAgdGhpcy5kcm9wZG93biA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYCMke3RoaXMuaWR9LWxpc3QgLmRyb3Bkb3duLWNvbnRlbnRgKTtcbiAgICB0aGlzLmRyb3Bkb3duRW1wdHlPcHRpb24gPSB0aGlzLmRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoJy5lbXB0eS10aXRsZScpO1xuXG4gICAgLy8gQ2xvbmUgYXR0cmlidXRlcyBiZXR3ZWVuIG9yaWdpbmFsIGFuZCBuZXcgaW5wdXRcbiAgICBjbG9uZUF0dHJpYnV0ZXModGhpcy5faW5wdXQsIHRoaXMuZWxlbWVudCwgJ2RhdGEtdHlwZSBtdWx0aXBsZSBuYW1lIHR5cGUgdmFsdWUnKTtcblxuICAgIGlmICh0aGlzLmVsZW1lbnQuZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuY29udGFpbmVyLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICAgIHRoaXMub3B0aW9ucy5yZW1vdmFibGUgPSBmYWxzZTtcbiAgICAgIHRoaXMub3B0aW9ucy5zZWxlY3RhYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUHJvcGFnYXRlIG9yaWdpbmFsIGlucHV0IGRpc2FibGVkIGF0dHJpYnV0ZSB0byB0aGUgY29udGFpbmVyXG4gICAgaWYgKHRoaXMuX2lucHV0LmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCB0aGlzLl9pbnB1dC5jbGFzc0xpc3QuY29udGFpbnMoJ2lzLWRpc2FibGVkJykpIHtcbiAgICAgIHRoaXMuY29udGFpbmVyLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX21hbnVhbElucHV0QWxsb3dlZCkge1xuICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCh0aGlzLl9maWx0ZXJJbnB1dEFsbG93ZWQgPyAnaXMtZmlsdGVyJyA6ICduby1pbnB1dCcpO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBkcm9wZG93biBpZiBubyBzb3VyY2Ugb3Igb3JpZ2luYWwgaW5wdXQgaXMgbm90IGEgc2VsZWN0IGVsZW1lbnRcbiAgICBpZiAoIXRoaXMuX2lzU2VsZWN0ICYmIHR5cGVvZiB0aGlzLm9wdGlvbnMuc291cmNlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5kcm9wZG93bi5yZW1vdmUoKTtcbiAgICAgIHRoaXMuZHJvcGRvd24gPSBudWxsO1xuICAgICAgdGhpcy5faW5wdXQuc2V0QXR0cmlidXRlKCdsaXN0JywgbnVsbCk7XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6ZSBwbHVnaW4gdmFsdWUgZnJvbSBvcmlnaW5hbCBpbnB1dCB2YWx1ZVxuICAgIGlmICh0aGlzLl9pc1NlbGVjdCkge1xuICAgICAgQXJyYXkuZnJvbSh0aGlzLmVsZW1lbnQub3B0aW9ucykuZm9yRWFjaCgob3B0aW9uOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbi5zZWxlY3RlZCkge1xuICAgICAgICAgIC8vIEhUTUwgT3B0aW9uIGVsZW1lbnQgY29udGFpbnMgdmFsdWUgYW5kIHRleHQgcHJvcGVydGllc1xuICAgICAgICAgIC8vIEFkZCBpdCBzaWxlbnRseSB0byBub3QgcHJvcGFnYXRlIHRvIHRoZSBvcmlnaW5hbCBlbGVtZW50XG4gICAgICAgICAgdGhpcy5hZGQob3B0aW9uLnZhbHVlID8gb3B0aW9uIDoge1xuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbi50ZXh0LFxuICAgICAgICAgICAgdGV4dDogb3B0aW9uLnRleHRcbiAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2NyZWF0ZURyb3Bkb3duSXRlbShvcHRpb24pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIGhhdmUgb24gaW5wdXQgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuZWxlbWVudC52YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hZGQodGhpcy5fb2JqZWN0SXRlbXMgPyBKU09OLnBhcnNlKHRoaXMuZWxlbWVudC52YWx1ZSkgOiB0aGlzLmVsZW1lbnQudmFsdWUsIHRydWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2JpbmRFdmVudHMoKTtcblxuICAgIC8vIEluc2VydCBjb250YWluZXIgcmlnaHQgYmVmb3JlIG9yaWdpbmFsIGlucHV0IGFuZCBtYWtlIG9yaWdpbmFsIGlucHV0IGhpZGRlblxuICAgIHRoaXMuZWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmNvbnRhaW5lciwgdGhpcy5lbGVtZW50KTtcblxuICAgIC8vIEhpZGUgb3JpZ2luYWwgaW5wdXQgKHR5cGU9XCJoaWRkZW5cIiBvbmx5IHdvcmtzIG9uIHNlbGVjdClcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kIGFsbCBldmVudHMgbGlzdGVuZXJcbiAgICovXG4gIF9iaW5kRXZlbnRzKCkge1xuICAgIC8vIEJpbmQgZG9jdW1lbnQgY2xpY2sgZXZlbnQgdG8gY2xvc2UgZHJvcGRvd25cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uRG9jdW1lbnRDbGljayk7XG5cbiAgICAvLyBCaW5kIGV2ZW50IGhhbmRsZXJzIHRvIG9yZ2luYWwgaW5wdXRcbiAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fb25PcmlnaW5hbElucHV0Q2hhbmdlKTtcblxuICAgIC8vIEJpbmQgZXZlbnQgaGFuZGxlcnMgdG8gaW50ZXJuYWwgaW5wdXRcbiAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMuX29uSW5wdXRDaGFuZ2UpO1xuICAgIHRoaXMuX2lucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25JbnB1dENsaWNrKTtcbiAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5fb25JbnB1dEtleURvd24pO1xuICAgIHRoaXMuX2lucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgdGhpcy5fb25JbnB1dEtleVByZXNzKTtcbiAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIHRoaXMuX29uSW5wdXRGb2N1c091dCk7XG4gICAgdGhpcy5faW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIHRoaXMuX29uSW5wdXRGb2N1c0luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjYXJldCBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBpbnB1dCB2YWx1ZVxuICAgKi9cbiAgX2NhcmV0QXRTdGFydCgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuX2lucHV0LnNlbGVjdGlvblN0YXJ0ID09PSAwICYmIHRoaXMuX2lucHV0LnNlbGVjdGlvbkVuZCA9PT0gMDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gdGhpcy5faW5wdXQudmFsdWUgPT09ICcnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB2YWx1ZSBsZW5ndGggY29uc3RyYWludCBpZiBvcHRpb24gYWN0aXZhdGVkXG4gICAqXG4gICAqIEBwYXJhbSBpdGVtXG4gICAqL1xuICBfY2hlY2tMZW5ndGgoaXRlbSkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fb2JqZWN0SXRlbXMgPyBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVmFsdWVdIDogaXRlbTtcblxuICAgIGlmICghaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUubGVuZ3RoID49IHRoaXMub3B0aW9ucy5taW5DaGFycyAmJiAodHlwZW9mIHRoaXMub3B0aW9ucy5tYXhDaGFycyA9PT0gJ3VuZGVmaW5lZCcgfHwgdmFsdWUubGVuZ3RoIDw9IHRoaXMub3B0aW9ucy5tYXhDaGFycyk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgZHJvcGRvd25cbiAgICovXG4gIF9jbG9zZURyb3Bkb3duKCkge1xuICAgIGlmICh0aGlzLmRyb3Bkb3duKSB7XG4gICAgICB0aGlzLmVtaXQoJ2JlZm9yZS5kcm9wZG93bi5jbG9zZScsIHRoaXMpO1xuXG4gICAgICB0aGlzLmNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdpcy1hY3RpdmUnKTtcblxuICAgICAgdGhpcy5lbWl0KCdhZnRlci5kcm9wZG93bi5jbG9zZScsIHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgZHJvcGRvd24gaXRlbSBiYXNlZCBvbiBnaXZlbiBpdGVtIGRhdGFcbiAgICpcbiAgICogQHBhcmFtIGl0ZW1cbiAgICovXG4gIF9jcmVhdGVEcm9wZG93bkl0ZW0oaXRlbSkge1xuICAgIGlmICh0aGlzLmRyb3Bkb3duKSB7XG4gICAgICAvLyBUT0RPOiBhZGQgcG9zc2liaWxpdHkgdG8gcHJvdmlkZSB0ZW1wbGF0ZSB0aHJvdWdoIG9wdGlvbnNcbiAgICAgIGNvbnN0IGRyb3Bkb3duSXRlbUZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoZHJvcGRvd25JdGVtVGVtcGxhdGUoe1xuICAgICAgICB0ZXh0OiBpdGVtLnRleHQsXG4gICAgICAgIHZhbHVlOiBpdGVtLnZhbHVlXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBkcm9wZG93bkl0ZW0gPSBkcm9wZG93bkl0ZW1GcmFnbWVudC5maXJzdEVsZW1lbnRDaGlsZDtcblxuICAgICAgLy8gU2F2ZSBpdGVtIGRhdGEgaW50byBkYXRhc2V0XG4gICAgICAoZHJvcGRvd25JdGVtIGFzIGFueSkuZGF0YXNldC52YWx1ZSA9IGl0ZW0udmFsdWU7XG4gICAgICAoZHJvcGRvd25JdGVtIGFzIGFueSkuZGF0YXNldC50ZXh0ID0gaXRlbS50ZXh0O1xuXG4gICAgICBkcm9wZG93bkl0ZW0hLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25Ecm9wZG93bkl0ZW1DbGljayk7XG5cbiAgICAgIHRoaXMuZHJvcGRvd24uYXBwZW5kKGRyb3Bkb3duSXRlbSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyB0YWcgYW5kIGFkZCBpdCB0byB0aGUgRE9NXG4gICAqXG4gICAqIEBwYXJhbSBzdHJpbmcgdmFsdWVcbiAgICovXG4gIF9jcmVhdGVUYWcoaXRlbSkge1xuICAgIGNvbnN0IHRhZ0ZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQodGFnVGVtcGxhdGUoe1xuICAgICAgcmVtb3ZhYmxlOiB0aGlzLm9wdGlvbnMucmVtb3ZhYmxlLFxuICAgICAgc3R5bGU6IHRoaXMub3B0aW9ucy50YWdDbGFzcyxcbiAgICAgIHRleHQ6IGl0ZW0udGV4dCxcbiAgICAgIHZhbHVlOiBpdGVtLnZhbHVlXG4gICAgfSkpO1xuICAgIGNvbnN0IHRhZyA9IHRhZ0ZyYWdtZW50LmZpcnN0RWxlbWVudENoaWxkO1xuXG4gICAgLy8gQXR0YWNoIHRhZyBjbGljayBldmVudCB0byBzZWxlY3QgaXRcbiAgICB0YWchLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25UYWdDbGljayk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnJlbW92YWJsZSkge1xuICAgICAgLy8gRmluZCBkZWxldGUgYnV0dG9uIGFuZCBhdHRhY2ggY2xpY2sgZXZlbnRcbiAgICAgIGNvbnN0IGRlbGV0ZUJ1dHRvbiA9IHRhZyEucXVlcnlTZWxlY3RvcignLmRlbGV0ZScpO1xuICAgICAgaWYgKGRlbGV0ZUJ1dHRvbikge1xuICAgICAgICBkZWxldGVCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vblRhZ0RlbGV0ZUNsaWNrKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpbnNlcnQgbmV3IHRhZyBhdCB0aGUgZW5kIChpZSBqdXN0IGJlZm9yZSBpbnB1dClcbiAgICB0aGlzLmNvbnRhaW5lci5pbnNlcnRCZWZvcmUodGFnLCB0aGlzLl9pbnB1dCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBkcm9wZG93biBpdGVtcyBleGNlcHQgdGhlIGVtcHR5IHRpdGxlXG4gICAqL1xuICBfZW1wdHlEcm9wZG93bigpIHtcbiAgICBpZiAodGhpcy5kcm9wZG93bikge1xuICAgICAgQXJyYXkuZnJvbSh0aGlzLmRyb3Bkb3duLmNoaWxkcmVuKS5maWx0ZXIoKGNoaWxkOiBhbnkpID0+ICFjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ2VtcHR5LXRpdGxlJykpLmZvckVhY2goKGNoaWxkOiBhbnkpID0+IHtcbiAgICAgICAgY2hpbGQucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZCBuZWVkbGUgaW50byBhIHN0cmluZyBhbmQgd3JhcCBpdCB3aXRoIDxtYXJrPiBIVE1MIHRhZ1xuICAgKlxuICAgKiBAcGFyYW0gc3RyaW5nXG4gICAqIEBwYXJhbSBuZWVkbGVcbiAgICovXG4gIF9oaWdobGlnaHRNYXRjaGVzSW5TdHJpbmcoc3RyaW5nLCBuZWVkbGUpIHtcbiAgICBjb25zdCByZWcgPSAnKCcgKyBuZWVkbGUgKyAnKSg/IVtePF0qPnxbXjw+XSo8LyknOyAvLyBleHBsYW5hdGlvbjogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTg2MjI2MDYvMTE0Nzg1OVxuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWcsICdpJyk7XG5cbiAgICAvLyBJZiB0aGUgcmVnZXggZG9lc24ndCBtYXRjaCB0aGUgc3RyaW5nIGp1c3QgcmV0dXJuIGluaXRpYWwgc3RyaW5nXG4gICAgaWYgKCFzdHJpbmcubWF0Y2gocmVnZXgpKSB7XG4gICAgICByZXR1cm4gc3RyaW5nO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgZ2V0IHRvIGhpZ2hsaWdodGluZ1xuICAgIGNvbnN0IG1hdGNoU3RhcnRQb3NpdGlvbiA9IHN0cmluZy5tYXRjaChyZWdleCkuaW5kZXg7XG4gICAgY29uc3QgbWF0Y2hFbmRQb3NpdGlvbiA9IG1hdGNoU3RhcnRQb3NpdGlvbiArIHN0cmluZy5tYXRjaChyZWdleClbMF0udG9TdHJpbmcoKS5sZW5ndGg7XG4gICAgY29uc3Qgb3JpZ2luYWxUZXh0Rm91bmRCeVJlZ2V4ID0gc3RyaW5nLnN1YnN0cmluZyhtYXRjaFN0YXJ0UG9zaXRpb24sIG1hdGNoRW5kUG9zaXRpb24pO1xuICAgIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKHJlZ2V4LCBgPG1hcmsgY2xhc3M9XCJpcy1oaWdobGlnaHRlZFwiPiR7b3JpZ2luYWxUZXh0Rm91bmRCeVJlZ2V4fTwvbWFyaz5gKTtcblxuICAgIHJldHVybiBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogT3BlbiBkcm9wZG93blxuICAgKi9cbiAgX29wZW5Ecm9wZG93bigpIHtcbiAgICBpZiAodGhpcy5kcm9wZG93bikge1xuICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnaXMtYWN0aXZlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb3BhZ2F0ZSBpbnRlcm5hbCBpbnB1dCBjaGFuZ2VzIHRvIHRoZSBvcmlnaW5hbCBpbnB1dFxuICAgKi9cbiAgX3Byb3BhZ2F0ZUNoYW5nZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzU2VsZWN0KSB7XG4gICAgICAvLyBJZiBvcmlnaW5hbCBlbGVtZW50IGlzIGFuIGlucHV0IGVsZW1lbnRcbiAgICAgIHRoaXMuZWxlbWVudC52YWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIG9yaWdpbmFsIGVsZW1lbnQgaXMgYSBzZWxlY3QgZWxlbWVudFxuICAgICAgQXJyYXkuZnJvbSh0aGlzLmVsZW1lbnQub3B0aW9ucykuZm9yRWFjaCgob3B0aW9uOiBhbnkpID0+IHtcbiAgICAgICAgb3B0aW9uLnNldEF0dHJpYnV0ZSgnc2VsZWN0ZWQnLCB1bmRlZmluZWQpO1xuICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICAvLyBJZiBvcHRpb24gaGFzIGJlZW4gYWRkZWQgYnkgVGFnc0lucHV0IHRoZW4gd2UgcmVtb3ZlIGl0XG4gICAgICAgIC8vIE90aGVyd2lzZSBpdCBpcyBhbiBvcmlnaW5hbCBvcHRpb25cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb24uZGF0YXNldC5zb3VyY2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgb3B0aW9uLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gVXBkYXRlIG9yaWdpbmFsIGVsZW1lbnQgb3B0aW9ucyBzZWxlY3RlZCBhdHRyaWJ1dGVzXG4gICAgICB0aGlzLl9pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RPcHRpb25zKHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy5fb2JqZWN0SXRlbXMgPyBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVmFsdWVdIDogaXRlbSxcbiAgICAgICAgICB0ZXh0OiB0aGlzLl9vYmplY3RJdGVtcyA/IGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1UZXh0XSA6IGl0ZW1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBUcmlnZ2VyIENoYW5nZSBldmVudCBtYW51YWxseSAoYmVjYXVzZSBvcmlnaW5hbCBpbnB1dCBpcyBub3cgaGlkZGVuKVxuICAgIC8vIFRyaWNrOiBQYXNzZXMgY3VycmVudCBjbGFzcyBjb25zdHJ1Y3RvciBuYW1lIHRvIHByZXZlbnQgbG9vcCB3aXRoIF9vbk9yaWdpbmFsSW5wdXRDaGFuZ2UgaGFuZGxlcilcbiAgICBjb25zdCBjaGFuZ2VFdmVudCA9IG5ldyBDdXN0b21FdmVudCgnY2hhbmdlJywge1xuICAgICAgZGV0YWlsOiB0aGlzLmNvbnN0cnVjdG9yLm5hbWVcbiAgICB9KTtcbiAgICB0aGlzLmVsZW1lbnQuZGlzcGF0Y2hFdmVudChjaGFuZ2VFdmVudCk7XG4gIH1cblxuICAvKipcbiAgICogVHJpbSB2YWx1ZSBpZiBvcHRpb24gYWN0aXZhdGVkXG4gICAqXG4gICAqIEBwYXJhbSBpdGVtXG4gICAqL1xuICBfdHJpbShpdGVtKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50cmltKSB7XG4gICAgICBpZiAodGhpcy5fb2JqZWN0SXRlbXMpIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV0pKSB7XG4gICAgICAgICAgaXRlbVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXSA9IGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV0udHJpbSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzU3RyaW5nKGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1UZXh0XSkpIHtcbiAgICAgICAgICBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVGV4dF0gPSBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVGV4dF0udHJpbSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtID0gaXRlbS50cmltKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGl0ZW07XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVyIERyb3Bkb3duIGl0ZW1zIHRvIGJlIGNvbXBsaWFudCB3aXRoIGFscmVhZHkgc2VsZWN0ZWQgaXRlbXMgYW5kIGN1cnJlbnQgaW5wdXQgdmFsdWVcbiAgICogRmlsdGVyaW5nIGlzIG1hZGUgb24gVGV4dCBieSBkZWZhdWx0IChjYW4gYmUgY2hhbmdlZCB3aXRoIG9wdGlvbilcbiAgICovXG4gIF9maWx0ZXJEcm9wZG93bkl0ZW1zKHZhbHVlOiBhbnkgPSBudWxsKSB7XG4gICAgaWYgKHRoaXMuZHJvcGRvd24pIHtcbiAgICAgIGlmICh0aGlzLmVtaXQoJ2JlZm9yZS5kcm9wZG93bi5maWx0ZXInLCB0aGlzKSkge1xuICAgICAgICBBcnJheS5mcm9tKHRoaXMuZHJvcGRvd24uY2hpbGRyZW4pLmZpbHRlcigoY2hpbGQ6IGFueSkgPT4gIWNoaWxkLmNsYXNzTGlzdC5jb250YWlucygnZW1wdHktdGl0bGUnKSkuZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNoaWxkVmFsdWUgPSBjaGlsZC5kYXRhc2V0W3RoaXMub3B0aW9ucy5zZWFyY2hPbl07XG5cbiAgICAgICAgICAvLyBSZW1vdmUgaGlnaGxpZ2h0c1xuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuaGlnaGxpZ2h0TWF0Y2hlc1N0cmluZykge1xuICAgICAgICAgICAgY2hpbGQudGV4dENvbnRlbnQgPSBjaGlsZC50ZXh0Q29udGVudC5yZXBsYWNlKC88XFwvPyhtYXJrXFxzPyhjbGFzcz1cImlzXFwtaGlnaGxpZ2h0ZWRcIik/KT8+XSo+Py9nbSwgJycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIElmIHZhbHVlIGlzIGZvdW5kIGluIGRyb3Bkb3duXG4gICAgICAgICAgaWYgKCh2YWx1ZSAmJiB2YWx1ZS5sZW5ndGgpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgICAgICAgY2hpbGQuc3R5bGUuZGlzcGxheSA9IGNoaWxkVmFsdWUuaW5jbHVkZXModmFsdWUpID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNoaWxkLnN0eWxlLmRpc3BsYXkgPSBjaGlsZFZhbHVlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModmFsdWUudG9Mb3dlckNhc2UoKSkgPyAnYmxvY2snIDogJ25vbmUnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmhpZ2hsaWdodE1hdGNoZXNTdHJpbmcpIHtcbiAgICAgICAgICAgICAgY2hpbGQuaW5uZXJIVE1MID0gdGhpcy5faGlnaGxpZ2h0TWF0Y2hlc0luU3RyaW5nKGNoaWxkLmlubmVySFRNTCwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaGlsZC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5hbGxvd0R1cGxpY2F0ZXMgfHwgKHRoaXMuX2lzU2VsZWN0ICYmICF0aGlzLl9pc011bHRpcGxlKSkge1xuICAgICAgICAgICAgY29uc3QgaGFzVmFsdWUgPSB0aGlzLm9wdGlvbnMuc2VhcmNoT24gPT09ICd2YWx1ZScgPyB0aGlzLmhhc1ZhbHVlKGNoaWxkVmFsdWUpIDogdGhpcy5oYXNUZXh0KGNoaWxkVmFsdWUpO1xuXG4gICAgICAgICAgICBjaGlsZC5zdHlsZS5kaXNwbGF5ID0gaGFzVmFsdWUgPyAnbm9uZScgOiBjaGlsZC5zdHlsZS5kaXNwbGF5O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgaGFzQWN0aXZlSXRlbXMgPSBBcnJheS5mcm9tKHRoaXMuZHJvcGRvd24uY2hpbGRyZW4pLmZpbHRlcigoY2hpbGQ6IGFueSkgPT4gIWNoaWxkLmNsYXNzTGlzdC5jb250YWlucygnZW1wdHktdGl0bGUnKSkuc29tZSgoY2hpbGQ6IGFueSkgPT4gY2hpbGQuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnKTtcbiAgICAgICAgaWYgKGhhc0FjdGl2ZUl0ZW1zKSB7XG4gICAgICAgICAgdGhpcy5kcm9wZG93bkVtcHR5T3B0aW9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5kcm9wZG93bkVtcHR5T3B0aW9uLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5lbWl0KCdhZnRlci5kcm9wZG93bi5maWx0ZXInLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gaGFzQWN0aXZlSXRlbXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIG9yaWdpbmFsIHNlbGVjdCBvcHRpb24gYmFzZWQgb24gZ2l2ZW4gaXRlbVxuICAgKlxuICAgKiBAcGFyYW0gaXRlbVxuICAgKi9cbiAgX3VwZGF0ZVNlbGVjdE9wdGlvbnMoaXRlbSkge1xuICAgIGlmICh0aGlzLl9pc1NlbGVjdCkge1xuICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSB0YWcgZXhpc3RzIGluIGl0cyByYXcgb3IgdXJpLWVuY29kZWQgZm9ybVxuICAgICAgbGV0IG9wdGlvbiA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKGBvcHRpb25bdmFsdWU9XCIke2VuY29kZVVSSUNvbXBvbmVudChpdGVtLnZhbHVlKX1cIl1gKSB8fCB0aGlzLmVsZW1lbnQucXVlcnlTZWxlY3Rvcihgb3B0aW9uW3ZhbHVlPVwiJHtpdGVtLnZhbHVlfVwiXWApO1xuXG4gICAgICAvLyBhZGQgPG9wdGlvbiAvPiBpZiBpdGVtIHJlcHJlc2VudHMgYSB2YWx1ZSBub3QgcHJlc2VudCBpbiBvbmUgb2YgdGhlIDxzZWxlY3QgLz4ncyBvcHRpb25zXG4gICAgICBpZiAoIW9wdGlvbikge1xuICAgICAgICBjb25zdCBvcHRpb25GcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCkuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGA8b3B0aW9uIHZhbHVlPVwiJHtpdGVtLnZhbHVlfVwiIGRhdGEtc291cmNlPVwiJHt0aGlzLmlkfVwiIHNlbGVjdGVkPiR7aXRlbS50ZXh0fTwvb3B0aW9uPmApO1xuICAgICAgICBvcHRpb24gPSBvcHRpb25GcmFnbWVudC5maXJzdEVsZW1lbnRDaGlsZDtcblxuICAgICAgICB0aGlzLmVsZW1lbnQuYWRkKG9wdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIG1hcmsgb3B0aW9uIGFzIHNlbGVjdGVkXG4gICAgICBvcHRpb24uc2V0QXR0cmlidXRlKCdzZWxlY3RlZCcsICdzZWxlY3RlZCcpO1xuICAgICAgb3B0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkIGdpdmVuIGl0ZW1cbiAgICogaXRlbSA9ICdqb2huJ1xuICAgKiBpdGVtID0gJ2pvaG4samFuZSdcbiAgICogaXRlbSA9IFsnam9obicsICdqYW5lJ11cbiAgICogaXRlbSA9IFt7XG4gICAqICBcInZhbHVlXCI6IFwiMVwiLFxuICAgKiAgXCJ0ZXh0XCI6IFwiSm9oblwiXG4gICAqIH0sIHtcbiAgICogIFwidmFsdWVcIjogXCIyXCIsXG4gICAqICBcInRleHRcIjogXCJKYW5lXCJcbiAgICogfV1cbiAgICpcbiAgICogQHBhcmFtIGl0ZW1cbiAgICogQHBhcmFtIHNpbGVudGx5IFNob3VsZCB0aGUgY2hhbmdlIGJlIHByb3BhZ2F0ZWQgdG8gdGhlIG9yaWdpbmFsIGVsZW1lbnRcbiAgICovXG4gIGFkZChpdGVtcywgc2lsZW50bHkgPSBmYWxzZSkge1xuICAgIC8vIENoZWNrIGlmIG51bWJlciBvZiBpdGVtcyBpcyBsaW1pdGVkIGFucyByZWFjaGVkXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMubWF4VGFncyAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5faXRlbXMubGVuZ3RoID49IHRoaXMub3B0aW9ucy5tYXhUYWdzKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBNYWtlIHN1cmUgdG8gd29yayB3aXRoIGFuIGFycmF5IG9mIGl0ZW1zXG4gICAgaXRlbXMgPSBBcnJheS5pc0FycmF5KGl0ZW1zKSA/IGl0ZW1zIDogaXNPYmplY3QoaXRlbXMpID8gW2l0ZW1zXSA6IGl0ZW1zLnNwbGl0KHRoaXMub3B0aW9ucy5kZWxpbWl0ZXIpO1xuXG4gICAgLy8gSWYgc3RyaW5nIGl0ZW1zIGFyZSBleHBlY3RlZCB0aGVuIGNoZWNrIGV2ZXJ5IGl0ZW0gaXMgYSBzdHJpbmdcbiAgICBpZiAoIXRoaXMuX29iamVjdEl0ZW1zICYmIChpdGVtcy5maWx0ZXIoaXRlbSA9PiBpc1N0cmluZyhpdGVtKSkubGVuZ3RoICE9PSBpdGVtcy5sZW5ndGgpKSB7XG4gICAgICB0aHJvdyAoJ0l0ZW0gbXVzdCBiZSBhIHN0cmluZyBvciBhbiBhcnJheSBvZiBzdHJpbmdzJyk7XG4gICAgfVxuXG4gICAgLy8gSWYgb2JqZWN0IGl0ZW1zIGFyZSBleHBlY3RlZCB0aGVuIGNoZWNrIGV2ZXJ5IGl0ZW0gaXMgYW4gb2JqZWN0XG4gICAgaWYgKHRoaXMuX29iamVjdEl0ZW1zICYmIChpdGVtcy5maWx0ZXIoaXRlbSA9PiBpc09iamVjdChpdGVtKSkubGVuZ3RoICE9PSBpdGVtcy5sZW5ndGgpKSB7XG4gICAgICB0aHJvdyAoJ0l0ZW0gbXVzdCBiZSBhbiBvYmplY3Qgb3IgYW4gYXJyYXkgb2Ygb2JqZWN0cycpO1xuICAgIH1cblxuICAgIGl0ZW1zLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpdGVtID0gdGhpcy5fdHJpbShpdGVtKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgaXRlbSByZXNwZWN0cyBtaW4vbWF4IGNoYXJzXG4gICAgICBpZiAodGhpcy5fY2hlY2tMZW5ndGgoaXRlbSkpIHtcblxuICAgICAgICAvLyBJZiBvcmlnaW5hbCBpbnB1dCBpcyBhIG5vbiBtdWx0aXBsZSBzZWxlY3QgZWxlbWVudFxuICAgICAgICBpZiAodGhpcy5faXNTZWxlY3QgJiYgIXRoaXMuX2lzTXVsdGlwbGUgJiYgdGhpcy5faXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlQXRJbmRleCgwKTtcbiAgICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlKHRoaXMuZWxlbWVudC5zZWxlY3RlZEluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIGlmIGR1cGxpY2F0ZXMgYXJlIGFsbG93ZWQgb3Igbm90XG4gICAgICAgIGlmIChpdGVtID0gdGhpcy5lbWl0KCdiZWZvcmUuYWRkJywgaXRlbSkpIHtcbiAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93RHVwbGljYXRlcyB8fCAhdGhpcy5oYXMoaXRlbSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1EYXRhID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogdGhpcy5fb2JqZWN0SXRlbXMgPyBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVmFsdWVdIDogaXRlbSxcbiAgICAgICAgICAgICAgdGV4dDogdGhpcy5fb2JqZWN0SXRlbXMgPyBpdGVtW3RoaXMub3B0aW9ucy5pdGVtVGV4dF0gOiBpdGVtXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCB0YWcgPSB0aGlzLl9jcmVhdGVUYWcoaXRlbURhdGEpO1xuXG4gICAgICAgICAgICAvLyBzYXZlIGl0ZW0gaW50byB0aGUgaW50ZXJuYWwgYXJyYXlcbiAgICAgICAgICAgIHRoaXMuX2l0ZW1zLnB1c2goaXRlbSk7XG5cbiAgICAgICAgICAgIGlmICghc2lsZW50bHkpIHtcbiAgICAgICAgICAgICAgLy8gUHJvcGFnYXRlIGNoYW5nZSBldmVudCB0byB0aGUgb3JpZ2luYWwgaW5wdXRcbiAgICAgICAgICAgICAgdGhpcy5fcHJvcGFnYXRlQ2hhbmdlKCk7XG5cbiAgICAgICAgICAgICAgdGhpcy5lbWl0KCdhZnRlci5hZGQnLCB7XG4gICAgICAgICAgICAgICAgaXRlbSxcbiAgICAgICAgICAgICAgICB0YWdcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuaGlnaGxpZ2h0RHVwbGljYXRlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGR1cGxpY2F0ZVRhZzogYW55ID0gQXJyYXkuZnJvbSh0aGlzLmNvbnRhaW5lci5jaGlsZHJlbikuZmlsdGVyKChjaGlsZDogYW55KSA9PiBjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ3RhZycpKVt0aGlzLmluZGV4T2YoaXRlbSldO1xuXG4gICAgICAgICAgICAgIGlmIChkdXBsaWNhdGVUYWcpIHtcbiAgICAgICAgICAgICAgICBkdXBsaWNhdGVUYWcuY2xhc3NMaXN0LmFkZCgnaXMtZHVwbGljYXRlJyk7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICBkdXBsaWNhdGVUYWcuY2xhc3NMaXN0LnJlbW92ZSgnaXMtZHVwbGljYXRlJyk7XG4gICAgICAgICAgICAgICAgfSwgMTI1MCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5lbWl0KCdpdGVtLmR1cGxpY2F0ZScsIGl0ZW0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogVW5zZWxlY3QgdGhlIHNlbGVjdGVkIGl0ZW1cbiAgICovXG4gIGNsZWFyU2VsZWN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9zZWxlY3RlZCA+PSAwKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5faXRlbXNbdGhpcy5fc2VsZWN0ZWRdO1xuICAgICAgY29uc3QgdGFnOiBhbnkgPSBBcnJheS5mcm9tKHRoaXMuY29udGFpbmVyLmNoaWxkcmVuKS5maWx0ZXIoKGNoaWxkOiBhbnkpID0+IGNoaWxkLmNsYXNzTGlzdC5jb250YWlucygndGFnJykpW3RoaXMuX3NlbGVjdGVkXTtcblxuICAgICAgaWYgKHRoaXMuZW1pdCgnYmVmb3JlLnVuc2VsZWN0Jywge1xuICAgICAgICBpdGVtLFxuICAgICAgICB0YWdcbiAgICAgIH0pKSB7XG4gICAgICAgIGlmICh0YWcpIHtcbiAgICAgICAgICB0YWcuY2xhc3NMaXN0LnJlbW92ZSgnaXMtc2VsZWN0ZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkID0gLTE7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdhZnRlci51bnNlbGVjdCcsIHtcbiAgICAgICAgICBpdGVtLFxuICAgICAgICAgIHRhZ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTaG9ydGN1dCB0byByZW1vdmVBbGwgbWV0aG9kXG4gICAqL1xuICBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW1vdmVBbGwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGZvY3VzIG9uIHRoZSBpbnB1dFxuICAgKi9cbiAgZm9jdXMoKSB7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnaXMtZm9jdXNlZCcpO1xuICAgIHRoaXMuX2lucHV0LmZvY3VzKCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBnaXZlbiBpdGVtIGlzIHByZXNlbnRcbiAgICpcbiAgICogQHBhcmFtIGl0ZW1cbiAgICovXG4gIGhhcyhpdGVtKSB7XG4gICAgaXRlbSA9IHRoaXMuX3RyaW0oaXRlbSk7XG5cbiAgICBpZiAodGhpcy5fb2JqZWN0SXRlbXMpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVtcy5zb21lKGkgPT4gdGhpcy5vcHRpb25zLmNhc2VTZW5zaXRpdmUgfHwgIWlzU3RyaW5nKGlbdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV0pID8gaVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXSA9PT0gaXRlbVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXSA6IGlbdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV0udG9Mb3dlckNhc2UoKSA9PT0gaXRlbVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzVmFsdWUoaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGdpdmVuIHRleHQgaXMgcHJlc2VudFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWVcbiAgICovXG4gIGhhc1RleHQodmFsdWUpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnRyaW0pIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9pdGVtcy5zb21lKGkgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKHRoaXMuX29iamVjdEl0ZW1zID8gaVt0aGlzLm9wdGlvbnMuaXRlbVRleHRdIDogaSk7XG5cbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuY2FzZVNlbnNpdGl2ZSA/IHZhbCA9PT0gdmFsdWUgOiB2YWwudG9Mb3dlckNhc2UoKSA9PT0gdmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBnaXZlbiB2YWx1ZSBpcyBwcmVzZW50XG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgaGFzVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnRyaW0pIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9pdGVtcy5zb21lKGkgPT4ge1xuICAgICAgY29uc3QgdmFsID0gKHRoaXMuX29iamVjdEl0ZW1zID8gaVt0aGlzLm9wdGlvbnMuaXRlbVZhbHVlXSA6IGkpO1xuXG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmNhc2VTZW5zaXRpdmUgPyB2YWwgPT09IHZhbHVlIDogdmFsLnRvTG93ZXJDYXNlKCkgPT09IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGluZGV4IG9mIGdpdmVuIGl0ZW1cbiAgICpcbiAgICogQHBhcmFtIGl0ZW1cbiAgICovXG4gIGluZGV4T2YoaXRlbSkge1xuICAgIGl0ZW0gPSB0aGlzLl90cmltKGl0ZW0pO1xuXG4gICAgaWYgKHRoaXMuX29iamVjdEl0ZW1zKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICAgIHRocm93ICgnSXRlbSBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5faXRlbXMubWFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBlLnZhbHVlOyB9KS5pbmRleE9mKGl0ZW0udmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5faXRlbXMuaW5kZXhPZihpdGVtKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgaW5wdXQgZWxlbWVudFxuICAgKi9cbiAgaW5wdXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lucHV0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBpdGVtc1xuICAgKi9cbiAgaXRlbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2l0ZW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBnaXZlbiBpdGVtXG4gICAqIGl0ZW0gPSAnam9obidcbiAgICogaXRlbSA9ICdqb2huLGphbmUnXG4gICAqXG4gICAqIEBwYXJhbSBTdHJpbmcgaXRlbVxuICAgKi9cbiAgcmVtb3ZlKGl0ZW1zKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZW1vdmFibGUpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB0byB3b3JrIHdpdGggYW4gYXJyYXkgb2YgaXRlbXNcbiAgICAgIGl0ZW1zID0gQXJyYXkuaXNBcnJheShpdGVtcykgPyBpdGVtcyA6IGlzT2JqZWN0KGl0ZW1zKSA/IFtpdGVtc10gOiBpdGVtcy5zcGxpdCh0aGlzLm9wdGlvbnMuZGVsaW1pdGVyKTtcblxuICAgICAgLy8gSWYgc3RyaW5nIGl0ZW1zIGFyZSBleHBlY3RlZCB0aGVuIGNoZWNrIGV2ZXJ5IGl0ZW0gaXMgYSBzdHJpbmdcbiAgICAgIGlmICghdGhpcy5fb2JqZWN0SXRlbXMgJiYgKGl0ZW1zLmZpbHRlcihpdGVtID0+IGlzU3RyaW5nKGl0ZW0pKS5sZW5ndGggIT09IGl0ZW1zLmxlbmd0aCkpIHtcbiAgICAgICAgdGhyb3cgKCdJdGVtIG11c3QgYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncycpO1xuICAgICAgfVxuICAgICAgLy8gSWYgb2JqZWN0IGl0ZW1zIGFyZSBleHBlY3RlZCB0aGVuIGNoZWNrIGV2ZXJ5IGl0ZW0gaXMgYW4gb2JqZWN0XG4gICAgICBpZiAodGhpcy5fb2JqZWN0SXRlbXMgJiYgKGl0ZW1zLmZpbHRlcihpdGVtID0+IGlzT2JqZWN0KGl0ZW0pKS5sZW5ndGggIT09IGl0ZW1zLmxlbmd0aCkpIHtcbiAgICAgICAgdGhyb3cgKCdJdGVtIG11c3QgYmUgYW4gb2JqZWN0IG9yIGFuIGFycmF5IG9mIG9iamVjdHMnKTtcbiAgICAgIH1cblxuICAgICAgaXRlbXMuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5pbmRleE9mKGl0ZW0pO1xuXG4gICAgICAgIHdoaWxlIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBdEluZGV4KGluZGV4KTtcblxuICAgICAgICAgIGluZGV4ID0gdGhpcy5pbmRleE9mKGl0ZW0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIHRhZ3MgYXQgb25jZVxuICAgKi9cbiAgcmVtb3ZlQWxsKCkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMucmVtb3ZhYmxlKSB7XG4gICAgICBpZiAodGhpcy5lbWl0KCdiZWZvcmUuZmx1c2gnLCB0aGlzLl9pdGVtcykpIHtcbiAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuXG4gICAgICAgIEFycmF5LmZyb20odGhpcy5jb250YWluZXIuY2hpbGRyZW4pLmZpbHRlcigoY2hpbGQ6IGFueSkgPT4gY2hpbGQuY2xhc3NMaXN0LmNvbnRhaW5zKCd0YWcnKSkuZm9yRWFjaCgodGFnOiBhbnkpID0+IHRhZy5yZW1vdmUoKSk7XG5cbiAgICAgICAgdGhpcy5faXRlbXMgPSBbXTtcblxuICAgICAgICB0aGlzLl9maWx0ZXJEcm9wZG93bkl0ZW1zKCk7XG5cbiAgICAgICAgdGhpcy5fcHJvcGFnYXRlQ2hhbmdlKCk7XG5cbiAgICAgICAgdGhpcy5lbWl0KCdhZnRlci5mbHVzaCcsIHRoaXMuX2l0ZW1zKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgaXRlbSBhdCBnaXZlbiBpbmRleFxuICAgKlxuICAgKiBAcGFyYW0gSW50ZWdlciBpbmRleFxuICAgKi9cbiAgcmVtb3ZlQXRJbmRleChpbmRleCwgY2xlYXJTZWxlY3Rpb24gPSB0cnVlKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZW1vdmFibGUgJiYgIWlzTmFOKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5faXRlbXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0YWc6IGFueSA9IEFycmF5LmZyb20odGhpcy5jb250YWluZXIuY2hpbGRyZW4pLmZpbHRlcigoY2hpbGQ6IGFueSkgPT4gY2hpbGQuY2xhc3NMaXN0LmNvbnRhaW5zKCd0YWcnKSlbaW5kZXhdO1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuX2l0ZW1zW2luZGV4XTtcblxuICAgICAgaWYgKHRoaXMuZW1pdCgnYmVmb3JlLnJlbW92ZScsIGl0ZW0pKSB7XG4gICAgICAgIGlmIChjbGVhclNlbGVjdGlvbikge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0YWcpIHtcbiAgICAgICAgICB0YWcucmVtb3ZlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBvcmlnaW5hbCBpbnB1dCBpcyBhIHNlbGVjdCBlbGVtZW50XG4gICAgICAgIC8vIHRoZW4gZGVzZWxlY3QgcmVsYXRlZCBvcHRpb25cbiAgICAgICAgaWYgKHRoaXMuX2lzU2VsZWN0KSB7XG4gICAgICAgICAgdGhpcy5lbGVtZW50Lm9wdGlvbnNbaW5kZXhdLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fc2VsZWN0ZWQgPT0gaW5kZXgpIHtcbiAgICAgICAgICB0aGlzLl9zZWxlY3RlZCA9IC0xO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3NlbGVjdGVkID49IDApIHtcbiAgICAgICAgICAvLyBPbmUgaXRlbSBsZXNzIHNvIHNlbGVjdGVkIGluZGV4IGlzXG4gICAgICAgICAgdGhpcy5fc2VsZWN0ZWQgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2l0ZW1zLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICAgICAgdGhpcy5fZmlsdGVyRHJvcGRvd25JdGVtcygpO1xuXG4gICAgICAgIHRoaXMuX3Byb3BhZ2F0ZUNoYW5nZSgpO1xuXG4gICAgICAgIHRoaXMuZW1pdCgnYWZ0ZXIucmVtb3ZlJywgaXRlbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0IGdpdmVuIGl0ZW1cbiAgICpcbiAgICogQHBhcmFtIGl0ZW1cbiAgICovXG4gIHNlbGVjdChpdGVtcykge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuc2VsZWN0YWJsZSkge1xuICAgICAgLy8gTWFrZSBzdXJlIHRvIHdvcmsgd2l0aCBhbiBhcnJheSBvZiBpdGVtc1xuICAgICAgaXRlbXMgPSBBcnJheS5pc0FycmF5KGl0ZW1zKSA/IGl0ZW1zIDogaXNPYmplY3QoaXRlbXMpID8gW2l0ZW1zXSA6IGl0ZW1zLnNwbGl0KHRoaXMub3B0aW9ucy5kZWxpbWl0ZXIpO1xuXG4gICAgICAvLyBJZiBzdHJpbmcgaXRlbXMgYXJlIGV4cGVjdGVkIHRoZW4gY2hlY2sgZXZlcnkgaXRlbSBpcyBhIHN0cmluZ1xuICAgICAgaWYgKCF0aGlzLl9vYmplY3RJdGVtcyAmJiAoaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXNTdHJpbmcoaXRlbSkpLmxlbmd0aCAhPT0gaXRlbXMubGVuZ3RoKSkge1xuICAgICAgICB0aHJvdyAoJ0l0ZW0gbXVzdCBiZSBhIHN0cmluZyBvciBhbiBhcnJheSBvZiBzdHJpbmdzJyk7XG4gICAgICB9XG4gICAgICAvLyBJZiBvYmplY3QgaXRlbXMgYXJlIGV4cGVjdGVkIHRoZW4gY2hlY2sgZXZlcnkgaXRlbSBpcyBhbiBvYmplY3RcbiAgICAgIGlmICh0aGlzLl9vYmplY3RJdGVtcyAmJiAoaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXNPYmplY3QoaXRlbSkpLmxlbmd0aCAhPT0gaXRlbXMubGVuZ3RoKSkge1xuICAgICAgICB0aHJvdyAoJ0l0ZW0gbXVzdCBiZSBhbiBvYmplY3Qgb3IgYW4gYXJyYXkgb2Ygb2JqZWN0cycpO1xuICAgICAgfVxuXG4gICAgICBpdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdEF0SW5kZXgodGhpcy5pbmRleE9mKGl0ZW0pKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0YWcgYXQgZ2l2ZW4gaW5kZXhcbiAgICpcbiAgICogQHBhcmFtIEludGVnZXIgaW5kZXhcbiAgICovXG4gIHNlbGVjdEF0SW5kZXgoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnNlbGVjdGFibGUpIHtcbiAgICAgIC8vIENsZWFyIHNlbGVjdGlvblxuICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuXG4gICAgICBpZiAoIWlzTmFOKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5faXRlbXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHRhZzogYW55ID0gQXJyYXkuZnJvbSh0aGlzLmNvbnRhaW5lci5jaGlsZHJlbikuZmlsdGVyKChjaGlsZDogYW55KSA9PiBjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ3RhZycpKVtpbmRleF07XG4gICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9pdGVtc1tpbmRleF07XG5cbiAgICAgICAgaWYgKHRoaXMuZW1pdCgnYmVmb3JlLnNlbGVjdCcsIHtcbiAgICAgICAgICBpdGVtLFxuICAgICAgICAgIHRhZ1xuICAgICAgICB9KSkge1xuICAgICAgICAgIGlmICh0YWcpIHtcbiAgICAgICAgICAgIHRhZy5jbGFzc0xpc3QuYWRkKCdpcy1zZWxlY3RlZCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX3NlbGVjdGVkID0gaW5kZXg7XG5cbiAgICAgICAgICB0aGlzLmVtaXQoJ2FmdGVyLnNlbGVjdCcsIHtcbiAgICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgICB0YWdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzZWxlY3RlZCBpdGVtXG4gICAqL1xuICBnZXQgc2VsZWN0ZWQoKSB7XG4gICAgaWYgKHRoaXMuX3NlbGVjdGVkID49IDApIHtcbiAgICAgIHJldHVybiB0aGlzLl9pdGVtc1t0aGlzLl9zZWxlY3RlZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2VsZWN0ZWQgaXRlbSBpbmRleFxuICAgKi9cbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB2YWx1ZVxuICAgKi9cbiAgZ2V0IHZhbHVlKCkge1xuICAgIGlmICghdGhpcy5faXNTZWxlY3QpIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3RJdGVtcykge1xuICAgICAgICByZXR1cm4gdGhpcy5faXRlbXMubWFwKGl0ZW0gPT4gaXRlbS52YWx1ZSkuam9pbih0aGlzLm9wdGlvbnMuZGVsaW1pdGVyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pdGVtcy5qb2luKHRoaXMub3B0aW9ucy5kZWxpbWl0ZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVsZW1lbnQub3B0aW9ucykuZmlsdGVyKChvcHRpb246IGFueSkgPT4gb3B0aW9uLnNlbGVjdGVkKS5tYXAoKG9wdGlvbjogYW55KSA9PiBvcHRpb24udmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdmFsdWVcbiAgICovXG4gIHNldCB2YWx1ZShzdHJpbmcpIHtcbiAgICB0aGlzLnJlbW92ZUFsbCgpO1xuICAgIHRoaXMuYWRkKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogRG9jdW1lbnQgY2xpY2sgZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uRG9jdW1lbnRDbGljayhlKSB7XG4gICAgaWYgKHRoaXMuZHJvcGRvd24pIHtcbiAgICAgIC8vIElmIHdlIGNsaWNrIG9uIGVsZW1lbnQgaW5zaWRlIGNvbnRhaW5lciB0aGVuIGRvIG5vdGhpbmdcbiAgICAgIGlmICh0aGlzLmNvbnRhaW5lci5jb250YWlucyhlLnRhcmdldCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUYWcgYW5kIGRlbGV0ZSBidXR0b24gYWxyZWFkeSBkZWxldGVkIHdoZW4gZXZlbnQgdHJpZ2dlcmVkXG4gICAgICAvLyBTbyB3ZSBjaGVjayBpZiB0YXJnZXQgaXMgYSB0YWcgZGVsZXRlIGJ1dHRvblxuICAgICAgaWYgKGUudGFyZ2V0LmRhdGFzZXQudGFnICYmIGUudGFyZ2V0LmRhdGFzZXQudGFnID09PSAnZGVsZXRlJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIENsaWNrIG91dHNpZGUgZHJvcGRvd24gc28gY2xvc2UgaXRcbiAgICAgIHRoaXMuX2Nsb3NlRHJvcGRvd24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5wdXQgZm9jdXMgbG9zdCBldmVudCBoYW5kbGVyXG4gICAqXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBfb25Ecm9wZG93bkl0ZW1DbGljayhlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKHRoaXMuZHJvcGRvd24pIHtcbiAgICAgIGlmICh0aGlzLl9vYmplY3RJdGVtcykge1xuICAgICAgICBjb25zdCBpdGVtID0ge307XG4gICAgICAgIGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1UZXh0XSA9IGUuY3VycmVudFRhcmdldC5kYXRhc2V0LnRleHQ7XG4gICAgICAgIGl0ZW1bdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV0gPSBlLmN1cnJlbnRUYXJnZXQuZGF0YXNldC52YWx1ZTtcblxuICAgICAgICB0aGlzLmFkZChpdGVtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRkKGUuY3VycmVudFRhcmdldC5kYXRhc2V0LnZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fZmlsdGVyRHJvcGRvd25JdGVtcygpO1xuICAgICAgdGhpcy5faW5wdXQudmFsdWUgPSAnJztcbiAgICAgIHRoaXMuX2lucHV0LmZvY3VzKCk7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuY2xvc2VEcm9wZG93bk9uSXRlbVNlbGVjdCkge1xuICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElucHV0IGNoYW5nZSBldmVudCBoYW5kbGVyXG4gICAqXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBfb25JbnB1dENoYW5nZShlKSB7XG4gICAgdGhpcy5fZmlsdGVyRHJvcGRvd25JdGVtcyh0aGlzLl9pbnB1dC52YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogSW5wdXQgY2xpY2sgZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uSW5wdXRDbGljayhlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKCF0aGlzLnNvdXJjZSB8fCB0aGlzLl9pbnB1dC52YWx1ZS5sZW5ndGggPj0gdGhpcy5vcHRpb25zLnNlYXJjaE1pbkNoYXJzKSB7XG4gICAgICB0aGlzLl9vcGVuRHJvcGRvd24oKTtcbiAgICAgIHRoaXMuX2ZpbHRlckRyb3Bkb3duSXRlbXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5wdXQgZm9jdXMgZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uSW5wdXRGb2N1c0luKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAodGhpcy5jb250YWluZXIuZ2V0QXR0cmlidXRlKCdkaXNhYmxlZCcpICE9PSBudWxsIHx8IHRoaXMuY29udGFpbmVyLmNsYXNzTGlzdC5jb250YWlucygnaXMtZGlzYWJsZWQnKSkge1xuICAgICAgdGhpcy5faW5wdXQuYmx1cigpO1xuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgnaXMtZm9jdXNlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIElucHV0IGZvY3VzIGxvc3QgZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uSW5wdXRGb2N1c091dChlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnaXMtZm9jdXNlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIElucHV0IEtleWRvd24gZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uSW5wdXRLZXlEb3duKGUpIHtcbiAgICBjb25zdCBrZXkgPSBlLmNoYXJDb2RlIHx8IGUua2V5Q29kZSB8fCBlLndoaWNoO1xuXG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIC8vIEJBQ0tTUEFDRVxuICAgICAgY2FzZSA4OlxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlbW92YWJsZSkge1xuICAgICAgICAgIGlmICh0aGlzLl9jYXJldEF0U3RhcnQoKSAmJiB0aGlzLl9zZWxlY3RlZCA+PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50SXRlbUluZGV4ID0gdGhpcy5fc2VsZWN0ZWQ7XG4gICAgICAgICAgICAvLyBJZiB0YWcgd2FzIHNlbGVjdGVkIHRoZW4gc2VsZWN0IG5leHQgKG9yIHByZXZpb3VzIGlmIG5leHQgZG9lcyBub3QgZXhpc3RzKVxuICAgICAgICAgICAgaWYgKGN1cnJlbnRJdGVtSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdEF0SW5kZXgoY3VycmVudEl0ZW1JbmRleCArIDEgPCB0aGlzLl9pdGVtcy5sZW5ndGggPyBjdXJyZW50SXRlbUluZGV4ICsgMSA6IGN1cnJlbnRJdGVtSW5kZXggLSAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdmVBdEluZGV4KGN1cnJlbnRJdGVtSW5kZXgsIGZhbHNlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zb3VyY2UgJiYgKHRoaXMuX2lucHV0LnZhbHVlLmxlbmd0aCkgPCB0aGlzLm9wdGlvbnMuc2VhcmNoTWluQ2hhcnMpIHtcbiAgICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBFU0NBUEVcbiAgICAgIGNhc2UgMjc6XG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3RlZCA+PSAwKSB7XG4gICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIERFTEVURVxuICAgICAgY2FzZSA0NjpcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZW1vdmFibGUpIHtcbiAgICAgICAgICBpZiAodGhpcy5fY2FyZXRBdFN0YXJ0KCkgJiYgdGhpcy5fc2VsZWN0ZWQgPj0gMCkge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudEl0ZW1JbmRleCA9IHRoaXMuX3NlbGVjdGVkO1xuXG4gICAgICAgICAgICAvLyBJZiB0YWcgd2FzIHNlbGVjdGVkIHRoZW4gc2VsZWN0IG5leHQgKG9yIHByZXZpb3VzIGlmIG5leHQgZG9lcyBub3QgZXhpc3RzKVxuICAgICAgICAgICAgaWYgKGN1cnJlbnRJdGVtSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdEF0SW5kZXgoY3VycmVudEl0ZW1JbmRleCArIDEgPCB0aGlzLl9pdGVtcy5sZW5ndGggPyBjdXJyZW50SXRlbUluZGV4ICsgMSA6IGN1cnJlbnRJdGVtSW5kZXggLSAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZW1vdmVBdEluZGV4KGN1cnJlbnRJdGVtSW5kZXgsIGZhbHNlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zb3VyY2UgJiYgKHRoaXMuX2lucHV0LnZhbHVlLmxlbmd0aCkgPCB0aGlzLm9wdGlvbnMuc2VhcmNoTWluQ2hhcnMpIHtcbiAgICAgICAgICB0aGlzLl9jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBMRUZUIEFSUk9XXG4gICAgICBjYXNlIDM3OlxuICAgICAgICBpZiAoIXRoaXMuX2lucHV0LnZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgIGlmICh0aGlzLl9zZWxlY3RlZCA8IDApIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0QXRJbmRleCh0aGlzLl9pdGVtcy5sZW5ndGggLSAxKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RBdEluZGV4KHRoaXMuX3NlbGVjdGVkIC0gMSA+PSAwID8gdGhpcy5fc2VsZWN0ZWQgLSAxIDogdGhpcy5faXRlbXMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gUklHSFQgQVJST1dcbiAgICAgIGNhc2UgMzk6XG4gICAgICAgIGlmICghdGhpcy5faW5wdXQudmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RBdEluZGV4KDApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdEF0SW5kZXgodGhpcy5fc2VsZWN0ZWQgKyAxID49IHRoaXMuX2l0ZW1zLmxlbmd0aCA/IDAgOiB0aGlzLl9zZWxlY3RlZCArIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY2xlYXJTZWxlY3Rpb25PblR5cGluZykge1xuICAgICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgLy8gaWdub3JlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElucHV0IEtleXByZXNzIGV2ZW50IGhhbmRsZXJcbiAgICpcbiAgICogQHBhcmFtIGVcbiAgICovXG4gIF9vbklucHV0S2V5UHJlc3MoZSkge1xuICAgIGNvbnN0IGtleSA9IGUuY2hhckNvZGUgfHwgZS5rZXlDb2RlIHx8IGUud2hpY2g7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5fdHJpbSh0aGlzLl9pbnB1dC52YWx1ZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleSk7XG5cbiAgICBpZiAoIXRoaXMuX21hbnVhbElucHV0QWxsb3dlZCAmJiAhdGhpcy5fZmlsdGVySW5wdXRBbGxvd2VkKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBFTlRFUlxuICAgIGlmICghdmFsdWUubGVuZ3RoICYmIGtleSAhPT0gMTMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZmlsdGVySW5wdXRBbGxvd2VkKSB7XG4gICAgICB0aGlzLl9maWx0ZXJEcm9wZG93bkl0ZW1zKHZhbHVlIGFzIGFueSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2ZpbHRlcklucHV0QWxsb3dlZCAmJiB0aGlzLnNvdXJjZSAmJiB2YWx1ZS5sZW5ndGggPj0gdGhpcy5vcHRpb25zLnNlYXJjaE1pbkNoYXJzICYmIGtleSAhPT0gMTMpIHtcbiAgICAgIHRoaXMuX29wZW5Ecm9wZG93bigpO1xuICAgICAgdGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuYWRkKCdpcy1sb2FkaW5nJyk7XG4gICAgICB0aGlzLl9lbXB0eURyb3Bkb3duKCk7XG5cbiAgICAgIHRoaXMuc291cmNlKHZhbHVlKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXN1bHRzID0gdGhpcy5lbWl0KCdvbi5yZXN1bHRzLnJlY2VpdmVkJywgcmVzdWx0cyk7XG5cbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgICAgICAgdGV4dDogbnVsbFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCFpc09iamVjdChyZXN1bHQpKSB7XG4gICAgICAgICAgICAgIGl0ZW0udmFsdWUgPSByZXN1bHQ7XG4gICAgICAgICAgICAgIGl0ZW0udGV4dCA9IHJlc3VsdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGl0ZW0udmFsdWUgPSByZXN1bHRbdGhpcy5vcHRpb25zLml0ZW1WYWx1ZV07XG4gICAgICAgICAgICAgIGl0ZW0udGV4dCA9IHJlc3VsdFt0aGlzLm9wdGlvbnMuaXRlbVRleHRdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVEcm9wZG93bkl0ZW0oaXRlbSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9maWx0ZXJEcm9wZG93bkl0ZW1zKHZhbHVlIGFzIGFueSk7XG5cbiAgICAgICAgdGhpcy5kcm9wZG93bi5jbGFzc0xpc3QucmVtb3ZlKCdpcy1sb2FkaW5nJyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbWFudWFsSW5wdXRBbGxvd2VkICYmICh2YWx1ZS5pbmNsdWRlcyh0aGlzLm9wdGlvbnMuZGVsaW1pdGVyKSB8fCBrZXkgPT0gMTMpKSB7XG4gICAgICAvLyBQcmV2ZW50IGRlZmF1bHQgYmVoYXZpb3IgKGllOiBhZGQgY2hhciBpbnRvIGlucHV0IHZhbHVlKVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAvLyBTcGxpdCB2YWx1ZSBieSBkZWxpbWl0ZXIgaW4gY2FzZSB3ZSBjb3B5L3Bhc3RlIG11bHRpcGxlIHZhbHVlc1xuICAgICAgY29uc3QgdmFsdWVzID0gdmFsdWUuc3BsaXQodGhpcy5vcHRpb25zLmRlbGltaXRlcik7XG4gICAgICB2YWx1ZXMuZm9yRWFjaCh2YWx1ZSA9PiB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGVtcHR5IHRleHQgd2hlbiBkZWxpbWl0ZXIgaXMgcmVtb3ZlZFxuICAgICAgICBpZiAoKHZhbHVlID0gdmFsdWUucmVwbGFjZSh0aGlzLm9wdGlvbnMuZGVsaW1pdGVyLCAnJykpICE9ICcnKSB7XG4gICAgICAgICAgLy8gcHVzaCB0byBhcnJheSBhbmQgcmVtb3ZlIGRlbGltaXRlclxuICAgICAgICAgIHRoaXMuYWRkKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhbHVlID0gJyc7XG4gICAgICAvLyBjbGVhciBpbnB1dFxuICAgICAgdGhpcy5faW5wdXQudmFsdWUgPSAnJztcblxuICAgICAgdGhpcy5fY2xvc2VEcm9wZG93bigpO1xuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9yaWdpbmFsIGlucHV0IGNoYW5nZSBldmVudCBoYW5kbGVyXG4gICAqIENBVVRJT046IGJlY2F1c2Ugb3JpZ2luYWwgaW5wdXQgaXMgbm93IGhpZGRlbiB0aGUgY2hhbmdlIGV2ZW50IG11c3QgYmUgdHJpZ2dlcmVkIG1hbnVhbGx5IG9uIGNoYW5nZVxuICAgKiBFeGFtcGxlIGhvdyB0byB0cmlnZ2VyIGNoYW5nZSBldmVudCBtYW51YWxseVxuICAgKiB2YXIgY2hhbmdlRXZlbnQgPSBuZXcgRXZlbnQoJ2NoYW5nZScpO1xuICAgKiBpbnB1dC5kaXNwYXRjaEV2ZW50KGNoYW5nZUV2ZW50KTtcbiAgICpcbiAgICogQHBhcmFtIGVcbiAgICovXG4gIF9vbk9yaWdpbmFsSW5wdXRDaGFuZ2UoZSkge1xuICAgIGlmICghZS5kZXRhaWwgfHwgaXNTdHJpbmcoZS5kZXRhaWwpICYmIGUuZGV0YWlsICE9PSB0aGlzLmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgIHRoaXMudmFsdWUgPSBlLmN1cnJlbnRUYXJnZXQudmFsdWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRhZyBjbGljayBldmVudCBoYW5kbGVyXG4gICAqXG4gICAqIEBwYXJhbSBlXG4gICAqL1xuICBfb25UYWdDbGljayhlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKGUuY3VycmVudFRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoJ2RlbGV0ZScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29udGFpbmVyLmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSAhPT0gbnVsbCB8fCB0aGlzLmNvbnRhaW5lci5jbGFzc0xpc3QuY29udGFpbnMoJ2lzLWRpc2FibGVkJykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLl9pbnB1dC5mb2N1cygpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5zZWxlY3RhYmxlKSB7XG4gICAgICBjb25zdCB0YWcgPSBlLmN1cnJlbnRUYXJnZXQuY2xvc2VzdCgnLnRhZycpO1xuXG4gICAgICBpZiAodGFnKSB7XG4gICAgICAgIGNvbnN0IHRhZ0luZGV4ID0gQXJyYXkuZnJvbSh0aGlzLmNvbnRhaW5lci5jaGlsZHJlbikuaW5kZXhPZih0YWcpO1xuICAgICAgICBpZiAodGFnSW5kZXggPT09IHRoaXMuX3NlbGVjdGVkKSB7XG4gICAgICAgICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc2VsZWN0QXRJbmRleCh0YWdJbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRhZyBidXR0b24gY2xpY2sgZXZlbnQgaGFuZGxlclxuICAgKlxuICAgKiBAcGFyYW0gZVxuICAgKi9cbiAgX29uVGFnRGVsZXRlQ2xpY2soZSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICh0aGlzLmNvbnRhaW5lci5nZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJykgIT09IG51bGwgfHwgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdpcy1kaXNhYmxlZCcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgdGFnID0gZS5jdXJyZW50VGFyZ2V0LmNsb3Nlc3QoJy50YWcnKTtcblxuICAgIGlmICh0YWcpIHtcbiAgICAgIHRoaXMucmVtb3ZlQXRJbmRleChBcnJheS5mcm9tKHRoaXMuY29udGFpbmVyLmNoaWxkcmVuKS5pbmRleE9mKHRhZykpO1xuICAgIH1cbiAgfVxufVxuIl19