cps-ui-kit 0.73.0 → 0.75.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.
Files changed (39) hide show
  1. package/esm2020/lib/base_components/base-tree-dropdown.component.mjs +484 -0
  2. package/esm2020/lib/components/cps-autocomplete/cps-autocomplete.component.mjs +1 -1
  3. package/esm2020/lib/components/cps-datepicker/cps-datepicker.component.mjs +1 -1
  4. package/esm2020/lib/components/cps-menu/cps-menu.component.mjs +7 -3
  5. package/esm2020/lib/components/cps-select/cps-select.component.mjs +1 -1
  6. package/esm2020/lib/components/cps-sidebar-menu/cps-sidebar-menu.component.mjs +2 -2
  7. package/esm2020/lib/components/cps-table/cps-table.component.mjs +10 -4
  8. package/esm2020/lib/components/cps-table/directives/cps-table-column-sortable.directive.mjs +1 -6
  9. package/esm2020/lib/components/cps-table/directives/cps-table-row-selectable.directive.mjs +31 -0
  10. package/esm2020/lib/components/cps-table/table-column-filter/table-column-filter-constraint/table-column-filter-constraint.component.mjs +18 -11
  11. package/esm2020/lib/components/cps-table/table-column-filter/table-column-filter.component.mjs +61 -34
  12. package/esm2020/lib/components/cps-table/table-row-menu/table-row-menu.component.mjs +1 -1
  13. package/esm2020/lib/components/cps-tree-autocomplete/cps-tree-autocomplete.component.mjs +4 -4
  14. package/esm2020/lib/components/cps-tree-select/cps-tree-select.component.mjs +4 -4
  15. package/esm2020/lib/components/cps-tree-table/cps-tree-table.component.mjs +116 -63
  16. package/esm2020/lib/components/cps-tree-table/directives/cps-tree-table-column-filter.directive.mjs +70 -0
  17. package/esm2020/lib/components/cps-tree-table/directives/cps-tree-table-column-sortable.directive.mjs +1 -6
  18. package/esm2020/lib/components/cps-tree-table/directives/cps-tree-table-row-selectable.directive.mjs +31 -0
  19. package/esm2020/public-api.mjs +4 -1
  20. package/fesm2015/cps-ui-kit.mjs +337 -125
  21. package/fesm2015/cps-ui-kit.mjs.map +1 -1
  22. package/fesm2020/cps-ui-kit.mjs +330 -123
  23. package/fesm2020/cps-ui-kit.mjs.map +1 -1
  24. package/lib/base_components/{cps-tree-dropdown-base.component.d.ts → base-tree-dropdown.component.d.ts} +3 -3
  25. package/lib/components/cps-menu/cps-menu.component.d.ts +2 -1
  26. package/lib/components/cps-table/cps-table.component.d.ts +3 -1
  27. package/lib/components/cps-table/directives/cps-table-column-sortable.directive.d.ts +0 -1
  28. package/lib/components/cps-table/directives/cps-table-row-selectable.directive.d.ts +14 -0
  29. package/lib/components/cps-table/table-column-filter/table-column-filter-constraint/table-column-filter-constraint.component.d.ts +5 -2
  30. package/lib/components/cps-table/table-column-filter/table-column-filter.component.d.ts +6 -2
  31. package/lib/components/cps-tree-autocomplete/cps-tree-autocomplete.component.d.ts +2 -2
  32. package/lib/components/cps-tree-select/cps-tree-select.component.d.ts +2 -2
  33. package/lib/components/cps-tree-table/cps-tree-table.component.d.ts +17 -14
  34. package/lib/components/cps-tree-table/directives/cps-tree-table-column-filter.directive.d.ts +22 -0
  35. package/lib/components/cps-tree-table/directives/cps-tree-table-column-sortable.directive.d.ts +0 -1
  36. package/lib/components/cps-tree-table/directives/cps-tree-table-row-selectable.directive.d.ts +14 -0
  37. package/package.json +1 -1
  38. package/public-api.d.ts +3 -0
  39. package/esm2020/lib/base_components/cps-tree-dropdown-base.component.mjs +0 -484
@@ -1,484 +0,0 @@
1
- import { Component, EventEmitter, Input, Optional, Output, Self, ViewChild } from '@angular/core';
2
- import { Subscription } from 'rxjs';
3
- import { convertSize } from '../utils/internal/size-utils';
4
- import { isEqual } from 'lodash-es';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/forms";
7
- export class CpsTreeDropdownBaseComponent {
8
- set options(options) {
9
- if (options?.some((o) => o.inner)) {
10
- this._options = options;
11
- return;
12
- }
13
- this._options = this._toInnerOptions(options);
14
- }
15
- get options() {
16
- return this._options;
17
- }
18
- set value(value) {
19
- this._value = value;
20
- this.onChange(value);
21
- }
22
- get value() {
23
- return this._value;
24
- }
25
- constructor(control, cdRef) {
26
- this.control = control;
27
- this.cdRef = cdRef;
28
- this.label = '';
29
- this.placeholder = 'Please enter';
30
- this.hint = '';
31
- this.multiple = false;
32
- this.disabled = false;
33
- this.width = '100%';
34
- this.chips = true;
35
- this.closableChips = true;
36
- this.clearable = false;
37
- this.openOnClear = true;
38
- this.optionLabel = 'label';
39
- this.optionInfo = 'info';
40
- this.hideDetails = false;
41
- this.persistentClear = false;
42
- this.prefixIcon = '';
43
- this.prefixIconSize = '18px';
44
- this.loading = false;
45
- this.virtualScroll = false;
46
- this.infoTooltip = '';
47
- this.infoTooltipClass = 'cps-tooltip-content';
48
- this.infoTooltipMaxWidth = '100%';
49
- this.infoTooltipPersistent = false;
50
- this.infoTooltipPosition = 'top';
51
- this._value = undefined;
52
- this.valueChanged = new EventEmitter();
53
- this._statusChangesSubscription = new Subscription();
54
- this._options = [];
55
- this.optionsMap = new Map();
56
- this.originalOptionsMap = new Map();
57
- this.virtualListHeight = 240;
58
- this.virtualScrollItemSize = 40;
59
- this.error = '';
60
- this.cvtWidth = '';
61
- this.isOpened = false;
62
- this.optionFocused = false;
63
- this.isAutocomplete = false;
64
- this.boxWidth = 0;
65
- // eslint-disable-next-line @typescript-eslint/no-empty-function
66
- this.onChange = (event) => { };
67
- // eslint-disable-next-line @typescript-eslint/no-empty-function
68
- this.onTouched = () => { };
69
- if (this.control) {
70
- this.control.valueAccessor = this;
71
- }
72
- this.resizeObserver = new ResizeObserver((entries) => {
73
- entries.forEach((entry) => {
74
- if (entry?.target)
75
- this.boxWidth = entry.target.offsetWidth;
76
- });
77
- });
78
- }
79
- ngOnInit() {
80
- this.cvtWidth = convertSize(this.width);
81
- if (!this._value) {
82
- if (this.multiple) {
83
- this._value = [];
84
- this.treeSelection = [];
85
- }
86
- }
87
- else {
88
- this.treeSelection = this._valueToTreeSelection(this.value);
89
- }
90
- this._statusChangesSubscription = this.control?.statusChanges?.subscribe(() => {
91
- this._checkErrors();
92
- });
93
- }
94
- ngAfterViewInit() {
95
- this._initContainerClickListener();
96
- this.recalcVirtualListHeight();
97
- this.resizeObserver.observe(this.boxEl.nativeElement);
98
- this.cdRef.detectChanges();
99
- }
100
- ngOnDestroy() {
101
- this._statusChangesSubscription?.unsubscribe();
102
- this.treeContainerElement?.removeEventListener('click', this._handleOnContainerClick.bind(this));
103
- this.resizeObserver?.disconnect();
104
- }
105
- _initContainerClickListener() {
106
- this.treeContainerElement =
107
- this.treeList?.el?.nativeElement?.querySelector('.p-tree-container');
108
- if (this.treeContainerElement) {
109
- this.treeContainerElement.addEventListener('click', this._handleOnContainerClick.bind(this));
110
- }
111
- }
112
- _handleOnContainerClick(event) {
113
- function getParentWithClass(element, className) {
114
- let currentElement = element;
115
- while (currentElement) {
116
- if (currentElement.classList.contains(className)) {
117
- return currentElement;
118
- }
119
- currentElement = currentElement.parentElement;
120
- }
121
- return null;
122
- }
123
- this.optionFocused = true;
124
- const elem = event.target.classList.contains('p-treenode-content')
125
- ? event.target
126
- : getParentWithClass(event.target, 'p-treenode-content');
127
- if (elem?.parentElement?.classList?.contains('cps-tree-node-fully-expandable')) {
128
- this.onClickFullyExpandable(elem);
129
- }
130
- }
131
- registerOnChange(fn) {
132
- this.onChange = fn;
133
- }
134
- registerOnTouched(fn) {
135
- this.onTouched = fn;
136
- }
137
- writeValue(value) {
138
- this.value = value;
139
- }
140
- updateValue(value) {
141
- this.writeValue(value);
142
- this.onChange(value);
143
- this.valueChanged.emit(value);
144
- }
145
- onSelectNode() {
146
- if (!this.multiple) {
147
- this.toggleOptions(false);
148
- }
149
- }
150
- onClickFullyExpandable(elem) {
151
- const parent = elem.parentElement;
152
- const key = this._getHTMLElementKey(parent);
153
- if (!key)
154
- return;
155
- const treeNode = this.options.find((o) => o.key === key);
156
- if (!treeNode)
157
- return;
158
- treeNode.expanded = !treeNode.expanded;
159
- this.updateOptions();
160
- setTimeout(() => {
161
- this._nodeToggled(elem);
162
- });
163
- }
164
- _getHTMLElementKey(elem) {
165
- if (!elem?.classList)
166
- return '';
167
- const classList = [...elem.classList];
168
- const key = classList.find((className) => {
169
- return className.startsWith('key-');
170
- });
171
- if (!key)
172
- return '';
173
- return key.replace('key-', '');
174
- }
175
- treeSelectionChanged(selection) {
176
- this.updateValue(this.treeSelectionToValue(selection));
177
- }
178
- recalcVirtualListHeight() {
179
- if (!this.virtualScroll)
180
- return;
181
- const currentLen = this.treeList?.serializedValue?.length || 0;
182
- this.virtualListHeight = Math.min(this.virtualScrollItemSize * currentLen, 240);
183
- }
184
- toggleOptions(show) {
185
- if (this.disabled || this.isOpened === show)
186
- return;
187
- if (typeof show === 'boolean') {
188
- if (show) {
189
- this.optionsMenu.show({
190
- target: this.boxEl.nativeElement
191
- });
192
- }
193
- else {
194
- this.optionsMenu.hide();
195
- }
196
- }
197
- else {
198
- this.optionsMenu.toggle({
199
- target: this.boxEl.nativeElement
200
- });
201
- }
202
- this.isOpened = this.optionsMenu.isVisible();
203
- this.optionFocused = false;
204
- if (this.isOpened && this.treeSelection) {
205
- this._expandToNodes(this.multiple ? this.treeSelection : [this.treeSelection]);
206
- this.updateOptions();
207
- setTimeout(() => {
208
- this.recalcVirtualListHeight();
209
- const selected = this.treeContainerElement.querySelector('.p-highlight');
210
- if (selected) {
211
- selected.scrollIntoView({
212
- behavior: 'instant',
213
- block: 'nearest',
214
- inline: 'center'
215
- });
216
- }
217
- else if (this.virtualScroll && this.treeSelection) {
218
- let key = '';
219
- if (this.multiple) {
220
- if (this.treeSelection.length > 0)
221
- key = this.treeSelection[0].key;
222
- }
223
- else
224
- key = this.treeSelection.key;
225
- if (key) {
226
- const idx = this.treeList?.serializedValue?.findIndex((v) => v.node.key === key) || -1;
227
- if (idx >= 0)
228
- this.treeList.scrollToVirtualIndex(idx);
229
- }
230
- }
231
- });
232
- }
233
- }
234
- remove(option) {
235
- if (!this.multiple)
236
- return;
237
- this.treeSelection = this.treeSelection.filter((v) => !isEqual(v, option));
238
- this.updateValue(this.treeSelectionToValue(this.treeSelection));
239
- }
240
- initArrowsNavigaton() {
241
- if (!this.isOpened)
242
- return;
243
- if (!this.optionFocused) {
244
- const firstElem = this.treeContainerElement?.querySelector('.p-treenode-content');
245
- if (firstElem)
246
- firstElem.focus();
247
- this.optionFocused = true;
248
- }
249
- }
250
- _nodeToggled(elem) {
251
- this.recalcVirtualListHeight();
252
- setTimeout(() => {
253
- this.optionsMenu.align();
254
- });
255
- elem?.focus();
256
- }
257
- _nodeToggledWithChevron(elem) {
258
- this._nodeToggled(elem);
259
- // fix primeng tree event stop propagation
260
- this.optionsMenu.selfClick = false;
261
- }
262
- onNodeExpand(event) {
263
- this._nodeToggledWithChevron(event?.originalEvent?.currentTarget?.parentElement);
264
- }
265
- onNodeCollapse(event) {
266
- this._nodeToggledWithChevron(event?.originalEvent?.currentTarget?.parentElement);
267
- }
268
- clear(event) {
269
- event.stopPropagation();
270
- if ((!this.multiple && this.treeSelection) ||
271
- (this.multiple && this.treeSelection?.length > 0)) {
272
- if (this.openOnClear) {
273
- this.toggleOptions(true);
274
- }
275
- const val = this.multiple ? [] : undefined;
276
- this.treeSelection = val;
277
- this.updateValue(val);
278
- }
279
- this.optionFocused = false;
280
- }
281
- _checkErrors() {
282
- const errors = this.control?.errors;
283
- if (!this.control?.control?.touched || !errors) {
284
- this.error = '';
285
- return;
286
- }
287
- if ('required' in errors) {
288
- this.error = 'Field is required';
289
- return;
290
- }
291
- const errArr = Object.values(errors);
292
- if (errArr.length < 1) {
293
- this.error = '';
294
- return;
295
- }
296
- const message = errArr.find((msg) => typeof msg === 'string');
297
- this.error = message || 'Unknown error';
298
- }
299
- // eslint-disable-next-line @typescript-eslint/no-empty-function
300
- setDisabledState(disabled) { }
301
- onBlur() {
302
- this.control?.control?.markAsTouched();
303
- this._checkErrors();
304
- }
305
- focus() {
306
- this.componentContainer?.nativeElement?.focus();
307
- this.toggleOptions(true);
308
- }
309
- _expandToNodes(nodes) {
310
- function getParentKey(key) {
311
- const lastSeparatorIndex = key.lastIndexOf('-');
312
- if (lastSeparatorIndex !== -1) {
313
- return key.substring(0, lastSeparatorIndex);
314
- }
315
- return '';
316
- }
317
- nodes.forEach((node) => {
318
- const parentNodeKey = getParentKey(node.key);
319
- const parentNode = this.optionsMap.get(parentNodeKey) || null;
320
- if (parentNode) {
321
- parentNode.expanded = true;
322
- this._expandToNodes([parentNode]);
323
- }
324
- });
325
- }
326
- _toInnerOptions(_options) {
327
- function mapOption(o, optionLabel, optionInfo, key, originalOptionsMap) {
328
- const inner = {
329
- inner: true,
330
- label: o[optionLabel],
331
- info: o[optionInfo],
332
- key,
333
- styleClass: 'key-' + key
334
- };
335
- if (o.isDirectory) {
336
- inner.type = 'directory';
337
- inner.selectable = false;
338
- inner.styleClass += ' cps-tree-node-fully-expandable';
339
- }
340
- if (o.children) {
341
- inner.children = o.children.map((c, index) => {
342
- return mapOption(c, optionLabel, optionInfo, key + '-' + index, originalOptionsMap);
343
- });
344
- }
345
- originalOptionsMap.set(key, o);
346
- return inner;
347
- }
348
- const res = _options.map((option, index) => {
349
- return mapOption(option, this.optionLabel, this.optionInfo, '' + index, this.originalOptionsMap);
350
- });
351
- this.optionsMap = this._buildOptionsMap(res);
352
- return res;
353
- }
354
- _buildOptionsMap(options) {
355
- const nodeMap = new Map();
356
- for (const option of options) {
357
- nodeMap.set(option.key, option);
358
- if (option.children) {
359
- const childNodeMap = this._buildOptionsMap(option.children);
360
- childNodeMap.forEach((value, key) => nodeMap.set(key, value));
361
- }
362
- }
363
- return nodeMap;
364
- }
365
- treeSelectionToValue(selection) {
366
- if (!selection)
367
- return this.multiple ? [] : undefined;
368
- if (this.multiple) {
369
- return selection.map((s) => this.originalOptionsMap.get(s.key));
370
- }
371
- else {
372
- return this.originalOptionsMap.get(selection.key);
373
- }
374
- }
375
- _valueToTreeSelection(value) {
376
- function getKey(v, map) {
377
- for (const [key, val] of map.entries()) {
378
- if (isEqual(v, val)) {
379
- return key;
380
- }
381
- }
382
- return '';
383
- }
384
- if (!value)
385
- return this.multiple ? [] : undefined;
386
- if (this.multiple) {
387
- const res = [];
388
- value.forEach((v) => {
389
- const key = getKey(v, this.originalOptionsMap);
390
- if (key)
391
- res.push(this.optionsMap.get(key));
392
- });
393
- return res;
394
- }
395
- else {
396
- const key = getKey(value, this.originalOptionsMap);
397
- return key ? this.optionsMap.get(key) : undefined;
398
- }
399
- }
400
- // this is a fix of primeng change detection bug when virtual scroller is enabled
401
- updateOptions() {
402
- if (!this.virtualScroll)
403
- return;
404
- this.options = [...this.options];
405
- }
406
- }
407
- CpsTreeDropdownBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CpsTreeDropdownBaseComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
408
- CpsTreeDropdownBaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: CpsTreeDropdownBaseComponent, selector: "ng-component", inputs: { label: "label", placeholder: "placeholder", hint: "hint", multiple: "multiple", disabled: "disabled", width: "width", chips: "chips", closableChips: "closableChips", clearable: "clearable", openOnClear: "openOnClear", optionLabel: "optionLabel", optionInfo: "optionInfo", hideDetails: "hideDetails", persistentClear: "persistentClear", prefixIcon: "prefixIcon", prefixIconSize: "prefixIconSize", loading: "loading", virtualScroll: "virtualScroll", infoTooltip: "infoTooltip", infoTooltipClass: "infoTooltipClass", infoTooltipMaxWidth: "infoTooltipMaxWidth", infoTooltipPersistent: "infoTooltipPersistent", infoTooltipPosition: "infoTooltipPosition", options: "options", _value: ["value", "_value"] }, outputs: { valueChanged: "valueChanged" }, viewQueries: [{ propertyName: "componentContainer", first: true, predicate: ["componentContainer"], descendants: true }, { propertyName: "optionsMenu", first: true, predicate: ["optionsMenu"], descendants: true }, { propertyName: "treeList", first: true, predicate: ["treeList"], descendants: true }, { propertyName: "boxEl", first: true, predicate: ["boxEl"], descendants: true }], ngImport: i0, template: '', isInline: true });
409
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CpsTreeDropdownBaseComponent, decorators: [{
410
- type: Component,
411
- args: [{
412
- template: ''
413
- }]
414
- }], ctorParameters: function () { return [{ type: i1.NgControl, decorators: [{
415
- type: Self
416
- }, {
417
- type: Optional
418
- }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { label: [{
419
- type: Input
420
- }], placeholder: [{
421
- type: Input
422
- }], hint: [{
423
- type: Input
424
- }], multiple: [{
425
- type: Input
426
- }], disabled: [{
427
- type: Input
428
- }], width: [{
429
- type: Input
430
- }], chips: [{
431
- type: Input
432
- }], closableChips: [{
433
- type: Input
434
- }], clearable: [{
435
- type: Input
436
- }], openOnClear: [{
437
- type: Input
438
- }], optionLabel: [{
439
- type: Input
440
- }], optionInfo: [{
441
- type: Input
442
- }], hideDetails: [{
443
- type: Input
444
- }], persistentClear: [{
445
- type: Input
446
- }], prefixIcon: [{
447
- type: Input
448
- }], prefixIconSize: [{
449
- type: Input
450
- }], loading: [{
451
- type: Input
452
- }], virtualScroll: [{
453
- type: Input
454
- }], infoTooltip: [{
455
- type: Input
456
- }], infoTooltipClass: [{
457
- type: Input
458
- }], infoTooltipMaxWidth: [{
459
- type: Input
460
- }], infoTooltipPersistent: [{
461
- type: Input
462
- }], infoTooltipPosition: [{
463
- type: Input
464
- }], options: [{
465
- type: Input
466
- }], _value: [{
467
- type: Input,
468
- args: ['value']
469
- }], valueChanged: [{
470
- type: Output
471
- }], componentContainer: [{
472
- type: ViewChild,
473
- args: ['componentContainer']
474
- }], optionsMenu: [{
475
- type: ViewChild,
476
- args: ['optionsMenu']
477
- }], treeList: [{
478
- type: ViewChild,
479
- args: ['treeList']
480
- }], boxEl: [{
481
- type: ViewChild,
482
- args: ['boxEl']
483
- }] } });
484
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3BzLXRyZWUtZHJvcGRvd24tYmFzZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jcHMtdWkta2l0L3NyYy9saWIvYmFzZV9jb21wb25lbnRzL2Nwcy10cmVlLWRyb3Bkb3duLWJhc2UuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLElBQUksRUFDSixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFPdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQzs7O0FBT3BDLE1BQU0sT0FBTyw0QkFBNEI7SUEyQnZDLElBQWEsT0FBTyxDQUFDLE9BQWM7UUFDakMsSUFBSSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDeEIsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUlELElBQUksS0FBSyxDQUFDLEtBQVU7UUFDbEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDcEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFvQ0QsWUFDNkIsT0FBa0IsRUFDdEMsS0FBd0I7UUFESixZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ3RDLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBcEZ4QixVQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ1gsZ0JBQVcsR0FBRyxjQUFjLENBQUM7UUFDN0IsU0FBSSxHQUFHLEVBQUUsQ0FBQztRQUNWLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixVQUFLLEdBQW9CLE1BQU0sQ0FBQztRQUNoQyxVQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2Isa0JBQWEsR0FBRyxJQUFJLENBQUM7UUFDckIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixnQkFBVyxHQUFHLElBQUksQ0FBQztRQUNuQixnQkFBVyxHQUFHLE9BQU8sQ0FBQztRQUN0QixlQUFVLEdBQUcsTUFBTSxDQUFDO1FBQ3BCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGVBQVUsR0FBYSxFQUFFLENBQUM7UUFDMUIsbUJBQWMsR0FBaUIsTUFBTSxDQUFDO1FBQ3RDLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDdEIsZ0JBQVcsR0FBRyxFQUFFLENBQUM7UUFDakIscUJBQWdCLEdBQUcscUJBQXFCLENBQUM7UUFDekMsd0JBQW1CLEdBQW9CLE1BQU0sQ0FBQztRQUM5QywwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDOUIsd0JBQW1CLEdBQW9CLEtBQUssQ0FBQztRQWV0QyxXQUFNLEdBQVEsU0FBUyxDQUFDO1FBVzlCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQWF6QywrQkFBMEIsR0FBaUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUV0RSxhQUFRLEdBQWUsRUFBRSxDQUFDO1FBQzFCLGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztRQUN6Qyx1QkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBZSxDQUFDO1FBRTVDLHNCQUFpQixHQUFHLEdBQUcsQ0FBQztRQUN4QiwwQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFFM0IsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLGFBQVEsR0FBRyxFQUFFLENBQUM7UUFDZCxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBS3ZCLGFBQVEsR0FBRyxDQUFDLENBQUM7UUE0RmIsZ0VBQWdFO1FBQ2hFLGFBQVEsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBRTlCLGdFQUFnRTtRQUNoRSxjQUFTLEdBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO1FBekZuQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1NBQ25DO1FBQ0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ25ELE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDeEIsSUFBSSxLQUFLLEVBQUUsTUFBTTtvQkFBRSxJQUFJLENBQUMsUUFBUSxHQUFJLEtBQUssQ0FBQyxNQUFjLENBQUMsV0FBVyxDQUFDO1lBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNoQixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQzthQUN6QjtTQUNGO2FBQU07WUFDTCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDN0Q7UUFFRCxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxDQUN0RSxHQUFHLEVBQUU7WUFDSCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDdEIsQ0FBQyxDQUNjLENBQUM7SUFDcEIsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsMEJBQTBCLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFFL0MsSUFBSSxDQUFDLG9CQUFvQixFQUFFLG1CQUFtQixDQUM1QyxPQUFPLEVBQ1AsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDeEMsQ0FBQztRQUVGLElBQUksQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUVPLDJCQUEyQjtRQUNqQyxJQUFJLENBQUMsb0JBQW9CO1lBQ3ZCLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN2RSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUM3QixJQUFJLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQ3hDLE9BQU8sRUFDUCxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUN4QyxDQUFDO1NBQ0g7SUFDSCxDQUFDO0lBRU8sdUJBQXVCLENBQUMsS0FBVTtRQUN4QyxTQUFTLGtCQUFrQixDQUN6QixPQUEyQixFQUMzQixTQUFpQjtZQUVqQixJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUM7WUFDN0IsT0FBTyxjQUFjLEVBQUU7Z0JBQ3JCLElBQUksY0FBYyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUU7b0JBQ2hELE9BQU8sY0FBYyxDQUFDO2lCQUN2QjtnQkFDRCxjQUFjLEdBQUcsY0FBYyxDQUFDLGFBQWEsQ0FBQzthQUMvQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBRTFCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQztZQUNoRSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU07WUFDZCxDQUFDLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1FBRTNELElBQ0UsSUFBSSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLGdDQUFnQyxDQUFDLEVBQzFFO1lBQ0EsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ25DO0lBQ0gsQ0FBQztJQVFELGdCQUFnQixDQUFDLEVBQU87UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELGlCQUFpQixDQUFDLEVBQU87UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFVO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBVTtRQUNwQixJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzNCO0lBQ0gsQ0FBQztJQUVELHNCQUFzQixDQUFDLElBQWlCO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDbEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTztRQUVqQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFFdEIsUUFBUSxDQUFDLFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDdkMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGtCQUFrQixDQUFDLElBQVM7UUFDbEMsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDaEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0QyxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBaUIsRUFBRSxFQUFFO1lBQy9DLE9BQU8sU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDcEIsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsb0JBQW9CLENBQUMsU0FBYztRQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCx1QkFBdUI7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUNoQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxNQUFNLElBQUksQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUMvQixJQUFJLENBQUMscUJBQXFCLEdBQUcsVUFBVSxFQUN2QyxHQUFHLENBQ0osQ0FBQztJQUNKLENBQUM7SUFFRCxhQUFhLENBQUMsSUFBYztRQUMxQixJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxJQUFJO1lBQUUsT0FBTztRQUVwRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFNBQVMsRUFBRTtZQUM3QixJQUFJLElBQUksRUFBRTtnQkFDUixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztvQkFDcEIsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTtpQkFDakMsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUN6QjtTQUNGO2FBQU07WUFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztnQkFDdEIsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYTthQUNqQyxDQUFDLENBQUM7U0FDSjtRQUVELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUU3QyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMzQixJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QyxJQUFJLENBQUMsY0FBYyxDQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FDMUQsQ0FBQztZQUNGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQixVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2dCQUMvQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUN0RCxjQUFjLENBQ1IsQ0FBQztnQkFDVCxJQUFJLFFBQVEsRUFBRTtvQkFDWixRQUFRLENBQUMsY0FBYyxDQUFDO3dCQUN0QixRQUFRLEVBQUUsU0FBUzt3QkFDbkIsS0FBSyxFQUFFLFNBQVM7d0JBQ2hCLE1BQU0sRUFBRSxRQUFRO3FCQUNqQixDQUFDLENBQUM7aUJBQ0o7cUJBQU0sSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7b0JBQ25ELElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztvQkFDYixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7d0JBQ2pCLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQzs0QkFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7cUJBQ3BFOzt3QkFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUM7b0JBQ3BDLElBQUksR0FBRyxFQUFFO3dCQUNQLE1BQU0sR0FBRyxHQUNQLElBQUksQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLFNBQVMsQ0FDdkMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FDMUIsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDVixJQUFJLEdBQUcsSUFBSSxDQUFDOzRCQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7cUJBQ3ZEO2lCQUNGO1lBQ0gsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsTUFBZ0I7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUUzQixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM1QyxDQUFDLENBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUNyQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELG1CQUFtQjtRQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRTNCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3ZCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxhQUFhLENBQ3hELHFCQUFxQixDQUN0QixDQUFDO1lBQ0YsSUFBSSxTQUFTO2dCQUFHLFNBQXlCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbEQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7U0FDM0I7SUFDSCxDQUFDO0lBRU8sWUFBWSxDQUFDLElBQWlCO1FBQ3BDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9CLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFTyx1QkFBdUIsQ0FBQyxJQUFpQjtRQUMvQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hCLDBDQUEwQztRQUMxQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFVO1FBQ3JCLElBQUksQ0FBQyx1QkFBdUIsQ0FDMUIsS0FBSyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUNuRCxDQUFDO0lBQ0osQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFVO1FBQ3ZCLElBQUksQ0FBQyx1QkFBdUIsQ0FDMUIsS0FBSyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUNuRCxDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFVO1FBQ2QsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRXhCLElBQ0UsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQztZQUN0QyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQ2pEO1lBQ0EsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzFCO1lBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDM0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUN2QjtRQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7SUFFTyxZQUFZO1FBQ2xCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO1FBRXBDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDOUMsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDaEIsT0FBTztTQUNSO1FBRUQsSUFBSSxVQUFVLElBQUksTUFBTSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxLQUFLLEdBQUcsbUJBQW1CLENBQUM7WUFDakMsT0FBTztTQUNSO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3JCLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ2hCLE9BQU87U0FDUjtRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLE9BQU8sR0FBRyxLQUFLLFFBQVEsQ0FBQyxDQUFDO1FBRTlELElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxJQUFJLGVBQWUsQ0FBQztJQUMxQyxDQUFDO0lBRUQsZ0VBQWdFO0lBQ2hFLGdCQUFnQixDQUFDLFFBQWlCLElBQUcsQ0FBQztJQUV0QyxNQUFNO1FBQ0osSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxLQUFLO1FBQ0gsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUNoRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFTyxjQUFjLENBQUMsS0FBWTtRQUNqQyxTQUFTLFlBQVksQ0FBQyxHQUFXO1lBQy9CLE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoRCxJQUFJLGtCQUFrQixLQUFLLENBQUMsQ0FBQyxFQUFFO2dCQUM3QixPQUFPLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUM7YUFDN0M7WUFDRCxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFFRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDckIsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM3QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUM7WUFFOUQsSUFBSSxVQUFVLEVBQUU7Z0JBQ2QsVUFBVSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO2FBQ25DO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZUFBZSxDQUFDLFFBQWU7UUFDckMsU0FBUyxTQUFTLENBQ2hCLENBQU0sRUFDTixXQUFtQixFQUNuQixVQUFrQixFQUNsQixHQUFXLEVBQ1gsa0JBQXVCO1lBRXZCLE1BQU0sS0FBSyxHQUFHO2dCQUNaLEtBQUssRUFBRSxJQUFJO2dCQUNYLEtBQUssRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDO2dCQUNyQixJQUFJLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQztnQkFDbkIsR0FBRztnQkFDSCxVQUFVLEVBQUUsTUFBTSxHQUFHLEdBQUc7YUFDYixDQUFDO1lBQ2QsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFO2dCQUNqQixLQUFLLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQztnQkFDekIsS0FBSyxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7Z0JBQ3pCLEtBQUssQ0FBQyxVQUFVLElBQUksaUNBQWlDLENBQUM7YUFDdkQ7WUFDRCxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUU7Z0JBQ2QsS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxLQUFhLEVBQUUsRUFBRTtvQkFDeEQsT0FBTyxTQUFTLENBQ2QsQ0FBQyxFQUNELFdBQVcsRUFDWCxVQUFVLEVBQ1YsR0FBRyxHQUFHLEdBQUcsR0FBRyxLQUFLLEVBQ2pCLGtCQUFrQixDQUNuQixDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO2FBQ0o7WUFDRCxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDekMsT0FBTyxTQUFTLENBQ2QsTUFBTSxFQUNOLElBQUksQ0FBQyxXQUFXLEVBQ2hCLElBQUksQ0FBQyxVQUFVLEVBQ2YsRUFBRSxHQUFHLEtBQUssRUFDVixJQUFJLENBQUMsa0JBQWtCLENBQ3hCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTdDLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVPLGdCQUFnQixDQUFDLE9BQWM7UUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQWUsQ0FBQztRQUN2QyxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRTtZQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDaEMsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFO2dCQUNuQixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM1RCxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUMvRDtTQUNGO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELG9CQUFvQixDQUFDLFNBQWM7UUFDakMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3RELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNqQixPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdEU7YUFBTTtZQUNMLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDbkQ7SUFDSCxDQUFDO0lBRU8scUJBQXFCLENBQUMsS0FBVTtRQUN0QyxTQUFTLE1BQU0sQ0FBQyxDQUFNLEVBQUUsR0FBcUI7WUFDM0MsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDdEMsSUFBSSxPQUFPLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFO29CQUNuQixPQUFPLEdBQUcsQ0FBQztpQkFDWjthQUNGO1lBQ0QsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBRWxELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNqQixNQUFNLEdBQUcsR0FBRyxFQUFnQixDQUFDO1lBQzdCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRTtnQkFDdkIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxHQUFHO29CQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFhLENBQUMsQ0FBQztZQUMxRCxDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sR0FBRyxDQUFDO1NBQ1o7YUFBTTtZQUNMLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDbkQsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7U0FDbkQ7SUFDSCxDQUFDO0lBRUQsaUZBQWlGO0lBQ2pGLGFBQWE7UUFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWE7WUFBRSxPQUFPO1FBQ2hDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxDQUFDOzt5SEFuZ0JVLDRCQUE0Qjs2R0FBNUIsNEJBQTRCLHFxQ0FGN0IsRUFBRTsyRkFFRCw0QkFBNEI7a0JBSHhDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLEVBQUU7aUJBQ2I7OzBCQXVGSSxJQUFJOzswQkFBSSxRQUFROzRFQW5GVixLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFDRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBRU8sT0FBTztzQkFBbkIsS0FBSztnQkFhVSxNQUFNO3NCQUFyQixLQUFLO3VCQUFDLE9BQU87Z0JBV0osWUFBWTtzQkFBckIsTUFBTTtnQkFHUCxrQkFBa0I7c0JBRGpCLFNBQVM7dUJBQUMsb0JBQW9CO2dCQUkvQixXQUFXO3NCQURWLFNBQVM7dUJBQUMsYUFBYTtnQkFHRCxRQUFRO3NCQUE5QixTQUFTO3VCQUFDLFVBQVU7Z0JBR3JCLEtBQUs7c0JBREosU0FBUzt1QkFBQyxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFNlbGYsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBUcmVlTm9kZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7XG4gIEljb25UeXBlLFxuICBpY29uU2l6ZVR5cGVcbn0gZnJvbSAnLi4vY29tcG9uZW50cy9jcHMtaWNvbi9jcHMtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjb252ZXJ0U2l6ZSB9IGZyb20gJy4uL3V0aWxzL2ludGVybmFsL3NpemUtdXRpbHMnO1xuaW1wb3J0IHsgVHJlZSB9IGZyb20gJ3ByaW1lbmcvdHJlZSc7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IFRvb2x0aXBQb3NpdGlvbiB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvY3BzLXRvb2x0aXAuZGlyZWN0aXZlJztcbmltcG9ydCB7IENwc01lbnVDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2Nwcy1tZW51L2Nwcy1tZW51LmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogJydcbn0pXG5leHBvcnQgY2xhc3MgQ3BzVHJlZURyb3Bkb3duQmFzZUNvbXBvbmVudFxuICBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveVxue1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdQbGVhc2UgZW50ZXInO1xuICBASW5wdXQoKSBoaW50ID0gJyc7XG4gIEBJbnB1dCgpIG11bHRpcGxlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIHdpZHRoOiBudW1iZXIgfCBzdHJpbmcgPSAnMTAwJSc7XG4gIEBJbnB1dCgpIGNoaXBzID0gdHJ1ZTtcbiAgQElucHV0KCkgY2xvc2FibGVDaGlwcyA9IHRydWU7XG4gIEBJbnB1dCgpIGNsZWFyYWJsZSA9IGZhbHNlO1xuICBASW5wdXQoKSBvcGVuT25DbGVhciA9IHRydWU7XG4gIEBJbnB1dCgpIG9wdGlvbkxhYmVsID0gJ2xhYmVsJztcbiAgQElucHV0KCkgb3B0aW9uSW5mbyA9ICdpbmZvJztcbiAgQElucHV0KCkgaGlkZURldGFpbHMgPSBmYWxzZTtcbiAgQElucHV0KCkgcGVyc2lzdGVudENsZWFyID0gZmFsc2U7XG4gIEBJbnB1dCgpIHByZWZpeEljb246IEljb25UeXBlID0gJyc7XG4gIEBJbnB1dCgpIHByZWZpeEljb25TaXplOiBpY29uU2l6ZVR5cGUgPSAnMThweCc7XG4gIEBJbnB1dCgpIGxvYWRpbmcgPSBmYWxzZTtcbiAgQElucHV0KCkgdmlydHVhbFNjcm9sbCA9IGZhbHNlO1xuICBASW5wdXQoKSBpbmZvVG9vbHRpcCA9ICcnO1xuICBASW5wdXQoKSBpbmZvVG9vbHRpcENsYXNzID0gJ2Nwcy10b29sdGlwLWNvbnRlbnQnO1xuICBASW5wdXQoKSBpbmZvVG9vbHRpcE1heFdpZHRoOiBudW1iZXIgfCBzdHJpbmcgPSAnMTAwJSc7XG4gIEBJbnB1dCgpIGluZm9Ub29sdGlwUGVyc2lzdGVudCA9IGZhbHNlO1xuICBASW5wdXQoKSBpbmZvVG9vbHRpcFBvc2l0aW9uOiBUb29sdGlwUG9zaXRpb24gPSAndG9wJztcblxuICBASW5wdXQoKSBzZXQgb3B0aW9ucyhvcHRpb25zOiBhbnlbXSkge1xuICAgIGlmIChvcHRpb25zPy5zb21lKChvKSA9PiBvLmlubmVyKSkge1xuICAgICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMuX3RvSW5uZXJPcHRpb25zKG9wdGlvbnMpO1xuICB9XG5cbiAgZ2V0IG9wdGlvbnMoKTogVHJlZU5vZGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cblxuICBASW5wdXQoJ3ZhbHVlJykgX3ZhbHVlOiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgc2V0IHZhbHVlKHZhbHVlOiBhbnkpIHtcbiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG5cbiAgQE91dHB1dCgpIHZhbHVlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2NvbXBvbmVudENvbnRhaW5lcicpXG4gIGNvbXBvbmVudENvbnRhaW5lciE6IEVsZW1lbnRSZWY7XG5cbiAgQFZpZXdDaGlsZCgnb3B0aW9uc01lbnUnKVxuICBvcHRpb25zTWVudSE6IENwc01lbnVDb21wb25lbnQ7XG5cbiAgQFZpZXdDaGlsZCgndHJlZUxpc3QnKSB0cmVlTGlzdCE6IFRyZWU7XG5cbiAgQFZpZXdDaGlsZCgnYm94RWwnKVxuICBib3hFbCE6IEVsZW1lbnRSZWY7XG5cbiAgcHJpdmF0ZSBfc3RhdHVzQ2hhbmdlc1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIF9vcHRpb25zOiBUcmVlTm9kZVtdID0gW107XG4gIG9wdGlvbnNNYXAgPSBuZXcgTWFwPHN0cmluZywgVHJlZU5vZGU+KCk7XG4gIG9yaWdpbmFsT3B0aW9uc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCk7XG5cbiAgdmlydHVhbExpc3RIZWlnaHQgPSAyNDA7XG4gIHZpcnR1YWxTY3JvbGxJdGVtU2l6ZSA9IDQwO1xuXG4gIGVycm9yID0gJyc7XG4gIGN2dFdpZHRoID0gJyc7XG4gIGlzT3BlbmVkID0gZmFsc2U7XG4gIG9wdGlvbkZvY3VzZWQgPSBmYWxzZTtcbiAgaXNBdXRvY29tcGxldGUgPSBmYWxzZTtcblxuICB0cmVlQ29udGFpbmVyRWxlbWVudCE6IEhUTUxFbGVtZW50O1xuICB0cmVlU2VsZWN0aW9uOiBhbnk7XG5cbiAgYm94V2lkdGggPSAwO1xuICByZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQFNlbGYoKSBAT3B0aW9uYWwoKSBwdWJsaWMgY29udHJvbDogTmdDb250cm9sLFxuICAgIHB1YmxpYyBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7XG4gICAgaWYgKHRoaXMuY29udHJvbCkge1xuICAgICAgdGhpcy5jb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xuICAgIH1cbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzKSA9PiB7XG4gICAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgIGlmIChlbnRyeT8udGFyZ2V0KSB0aGlzLmJveFdpZHRoID0gKGVudHJ5LnRhcmdldCBhcyBhbnkpLm9mZnNldFdpZHRoO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmN2dFdpZHRoID0gY29udmVydFNpemUodGhpcy53aWR0aCk7XG4gICAgaWYgKCF0aGlzLl92YWx1ZSkge1xuICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgICAgdGhpcy5fdmFsdWUgPSBbXTtcbiAgICAgICAgdGhpcy50cmVlU2VsZWN0aW9uID0gW107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJlZVNlbGVjdGlvbiA9IHRoaXMuX3ZhbHVlVG9UcmVlU2VsZWN0aW9uKHRoaXMudmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb24gPSB0aGlzLmNvbnRyb2w/LnN0YXR1c0NoYW5nZXM/LnN1YnNjcmliZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhpcy5fY2hlY2tFcnJvcnMoKTtcbiAgICAgIH1cbiAgICApIGFzIFN1YnNjcmlwdGlvbjtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLl9pbml0Q29udGFpbmVyQ2xpY2tMaXN0ZW5lcigpO1xuICAgIHRoaXMucmVjYWxjVmlydHVhbExpc3RIZWlnaHQoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5ib3hFbC5uYXRpdmVFbGVtZW50KTtcbiAgICB0aGlzLmNkUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3N0YXR1c0NoYW5nZXNTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICB0aGlzLnRyZWVDb250YWluZXJFbGVtZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFxuICAgICAgJ2NsaWNrJyxcbiAgICAgIHRoaXMuX2hhbmRsZU9uQ29udGFpbmVyQ2xpY2suYmluZCh0aGlzKVxuICAgICk7XG5cbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICBwcml2YXRlIF9pbml0Q29udGFpbmVyQ2xpY2tMaXN0ZW5lcigpIHtcbiAgICB0aGlzLnRyZWVDb250YWluZXJFbGVtZW50ID1cbiAgICAgIHRoaXMudHJlZUxpc3Q/LmVsPy5uYXRpdmVFbGVtZW50Py5xdWVyeVNlbGVjdG9yKCcucC10cmVlLWNvbnRhaW5lcicpO1xuICAgIGlmICh0aGlzLnRyZWVDb250YWluZXJFbGVtZW50KSB7XG4gICAgICB0aGlzLnRyZWVDb250YWluZXJFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICdjbGljaycsXG4gICAgICAgIHRoaXMuX2hhbmRsZU9uQ29udGFpbmVyQ2xpY2suYmluZCh0aGlzKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9oYW5kbGVPbkNvbnRhaW5lckNsaWNrKGV2ZW50OiBhbnkpIHtcbiAgICBmdW5jdGlvbiBnZXRQYXJlbnRXaXRoQ2xhc3MoXG4gICAgICBlbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwsXG4gICAgICBjbGFzc05hbWU6IHN0cmluZ1xuICAgICkge1xuICAgICAgbGV0IGN1cnJlbnRFbGVtZW50ID0gZWxlbWVudDtcbiAgICAgIHdoaWxlIChjdXJyZW50RWxlbWVudCkge1xuICAgICAgICBpZiAoY3VycmVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4gY3VycmVudEVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudEVsZW1lbnQgPSBjdXJyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25Gb2N1c2VkID0gdHJ1ZTtcblxuICAgIGNvbnN0IGVsZW0gPSBldmVudC50YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCdwLXRyZWVub2RlLWNvbnRlbnQnKVxuICAgICAgPyBldmVudC50YXJnZXRcbiAgICAgIDogZ2V0UGFyZW50V2l0aENsYXNzKGV2ZW50LnRhcmdldCwgJ3AtdHJlZW5vZGUtY29udGVudCcpO1xuXG4gICAgaWYgKFxuICAgICAgZWxlbT8ucGFyZW50RWxlbWVudD8uY2xhc3NMaXN0Py5jb250YWlucygnY3BzLXRyZWUtbm9kZS1mdWxseS1leHBhbmRhYmxlJylcbiAgICApIHtcbiAgICAgIHRoaXMub25DbGlja0Z1bGx5RXhwYW5kYWJsZShlbGVtKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIG9uQ2hhbmdlID0gKGV2ZW50OiBhbnkpID0+IHt9O1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgb25Ub3VjaGVkID0gKCkgPT4ge307XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICB1cGRhdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy53cml0ZVZhbHVlKHZhbHVlKTtcbiAgICB0aGlzLm9uQ2hhbmdlKHZhbHVlKTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlZC5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIG9uU2VsZWN0Tm9kZSgpIHtcbiAgICBpZiAoIXRoaXMubXVsdGlwbGUpIHtcbiAgICAgIHRoaXMudG9nZ2xlT3B0aW9ucyhmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgb25DbGlja0Z1bGx5RXhwYW5kYWJsZShlbGVtOiBIVE1MRWxlbWVudCkge1xuICAgIGNvbnN0IHBhcmVudCA9IGVsZW0ucGFyZW50RWxlbWVudDtcbiAgICBjb25zdCBrZXkgPSB0aGlzLl9nZXRIVE1MRWxlbWVudEtleShwYXJlbnQpO1xuICAgIGlmICgha2V5KSByZXR1cm47XG5cbiAgICBjb25zdCB0cmVlTm9kZSA9IHRoaXMub3B0aW9ucy5maW5kKChvKSA9PiBvLmtleSA9PT0ga2V5KTtcbiAgICBpZiAoIXRyZWVOb2RlKSByZXR1cm47XG5cbiAgICB0cmVlTm9kZS5leHBhbmRlZCA9ICF0cmVlTm9kZS5leHBhbmRlZDtcbiAgICB0aGlzLnVwZGF0ZU9wdGlvbnMoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX25vZGVUb2dnbGVkKGVsZW0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0SFRNTEVsZW1lbnRLZXkoZWxlbTogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoIWVsZW0/LmNsYXNzTGlzdCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGNsYXNzTGlzdCA9IFsuLi5lbGVtLmNsYXNzTGlzdF07XG4gICAgY29uc3Qga2V5ID0gY2xhc3NMaXN0LmZpbmQoKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICByZXR1cm4gY2xhc3NOYW1lLnN0YXJ0c1dpdGgoJ2tleS0nKTtcbiAgICB9KTtcbiAgICBpZiAoIWtleSkgcmV0dXJuICcnO1xuICAgIHJldHVybiBrZXkucmVwbGFjZSgna2V5LScsICcnKTtcbiAgfVxuXG4gIHRyZWVTZWxlY3Rpb25DaGFuZ2VkKHNlbGVjdGlvbjogYW55KSB7XG4gICAgdGhpcy51cGRhdGVWYWx1ZSh0aGlzLnRyZWVTZWxlY3Rpb25Ub1ZhbHVlKHNlbGVjdGlvbikpO1xuICB9XG5cbiAgcmVjYWxjVmlydHVhbExpc3RIZWlnaHQoKSB7XG4gICAgaWYgKCF0aGlzLnZpcnR1YWxTY3JvbGwpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50TGVuID0gdGhpcy50cmVlTGlzdD8uc2VyaWFsaXplZFZhbHVlPy5sZW5ndGggfHwgMDtcbiAgICB0aGlzLnZpcnR1YWxMaXN0SGVpZ2h0ID0gTWF0aC5taW4oXG4gICAgICB0aGlzLnZpcnR1YWxTY3JvbGxJdGVtU2l6ZSAqIGN1cnJlbnRMZW4sXG4gICAgICAyNDBcbiAgICApO1xuICB9XG5cbiAgdG9nZ2xlT3B0aW9ucyhzaG93PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkIHx8IHRoaXMuaXNPcGVuZWQgPT09IHNob3cpIHJldHVybjtcblxuICAgIGlmICh0eXBlb2Ygc2hvdyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBpZiAoc2hvdykge1xuICAgICAgICB0aGlzLm9wdGlvbnNNZW51LnNob3coe1xuICAgICAgICAgIHRhcmdldDogdGhpcy5ib3hFbC5uYXRpdmVFbGVtZW50XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vcHRpb25zTWVudS5oaWRlKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3B0aW9uc01lbnUudG9nZ2xlKHtcbiAgICAgICAgdGFyZ2V0OiB0aGlzLmJveEVsLm5hdGl2ZUVsZW1lbnRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuaXNPcGVuZWQgPSB0aGlzLm9wdGlvbnNNZW51LmlzVmlzaWJsZSgpO1xuXG4gICAgdGhpcy5vcHRpb25Gb2N1c2VkID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuaXNPcGVuZWQgJiYgdGhpcy50cmVlU2VsZWN0aW9uKSB7XG4gICAgICB0aGlzLl9leHBhbmRUb05vZGVzKFxuICAgICAgICB0aGlzLm11bHRpcGxlID8gdGhpcy50cmVlU2VsZWN0aW9uIDogW3RoaXMudHJlZVNlbGVjdGlvbl1cbiAgICAgICk7XG4gICAgICB0aGlzLnVwZGF0ZU9wdGlvbnMoKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnJlY2FsY1ZpcnR1YWxMaXN0SGVpZ2h0KCk7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy50cmVlQ29udGFpbmVyRWxlbWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICcucC1oaWdobGlnaHQnXG4gICAgICAgICkgYXMgYW55O1xuICAgICAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgICAgICBzZWxlY3RlZC5zY3JvbGxJbnRvVmlldyh7XG4gICAgICAgICAgICBiZWhhdmlvcjogJ2luc3RhbnQnLFxuICAgICAgICAgICAgYmxvY2s6ICduZWFyZXN0JyxcbiAgICAgICAgICAgIGlubGluZTogJ2NlbnRlcidcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnZpcnR1YWxTY3JvbGwgJiYgdGhpcy50cmVlU2VsZWN0aW9uKSB7XG4gICAgICAgICAgbGV0IGtleSA9ICcnO1xuICAgICAgICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50cmVlU2VsZWN0aW9uLmxlbmd0aCA+IDApIGtleSA9IHRoaXMudHJlZVNlbGVjdGlvblswXS5rZXk7XG4gICAgICAgICAgfSBlbHNlIGtleSA9IHRoaXMudHJlZVNlbGVjdGlvbi5rZXk7XG4gICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgY29uc3QgaWR4ID1cbiAgICAgICAgICAgICAgdGhpcy50cmVlTGlzdD8uc2VyaWFsaXplZFZhbHVlPy5maW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgKHYpID0+IHYubm9kZS5rZXkgPT09IGtleVxuICAgICAgICAgICAgICApIHx8IC0xO1xuICAgICAgICAgICAgaWYgKGlkeCA+PSAwKSB0aGlzLnRyZWVMaXN0LnNjcm9sbFRvVmlydHVhbEluZGV4KGlkeCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZW1vdmUob3B0aW9uOiBUcmVlTm9kZSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tdWx0aXBsZSkgcmV0dXJuO1xuXG4gICAgdGhpcy50cmVlU2VsZWN0aW9uID0gdGhpcy50cmVlU2VsZWN0aW9uLmZpbHRlcihcbiAgICAgICh2OiBUcmVlTm9kZSkgPT4gIWlzRXF1YWwodiwgb3B0aW9uKVxuICAgICk7XG4gICAgdGhpcy51cGRhdGVWYWx1ZSh0aGlzLnRyZWVTZWxlY3Rpb25Ub1ZhbHVlKHRoaXMudHJlZVNlbGVjdGlvbikpO1xuICB9XG5cbiAgaW5pdEFycm93c05hdmlnYXRvbigpIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuZWQpIHJldHVybjtcblxuICAgIGlmICghdGhpcy5vcHRpb25Gb2N1c2VkKSB7XG4gICAgICBjb25zdCBmaXJzdEVsZW0gPSB0aGlzLnRyZWVDb250YWluZXJFbGVtZW50Py5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAnLnAtdHJlZW5vZGUtY29udGVudCdcbiAgICAgICk7XG4gICAgICBpZiAoZmlyc3RFbGVtKSAoZmlyc3RFbGVtIGFzIEhUTUxFbGVtZW50KS5mb2N1cygpO1xuICAgICAgdGhpcy5vcHRpb25Gb2N1c2VkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9ub2RlVG9nZ2xlZChlbGVtOiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMucmVjYWxjVmlydHVhbExpc3RIZWlnaHQoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMub3B0aW9uc01lbnUuYWxpZ24oKTtcbiAgICB9KTtcbiAgICBlbGVtPy5mb2N1cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBfbm9kZVRvZ2dsZWRXaXRoQ2hldnJvbihlbGVtOiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMuX25vZGVUb2dnbGVkKGVsZW0pO1xuICAgIC8vIGZpeCBwcmltZW5nIHRyZWUgZXZlbnQgc3RvcCBwcm9wYWdhdGlvblxuICAgIHRoaXMub3B0aW9uc01lbnUuc2VsZkNsaWNrID0gZmFsc2U7XG4gIH1cblxuICBvbk5vZGVFeHBhbmQoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuX25vZGVUb2dnbGVkV2l0aENoZXZyb24oXG4gICAgICBldmVudD8ub3JpZ2luYWxFdmVudD8uY3VycmVudFRhcmdldD8ucGFyZW50RWxlbWVudFxuICAgICk7XG4gIH1cblxuICBvbk5vZGVDb2xsYXBzZShldmVudDogYW55KSB7XG4gICAgdGhpcy5fbm9kZVRvZ2dsZWRXaXRoQ2hldnJvbihcbiAgICAgIGV2ZW50Py5vcmlnaW5hbEV2ZW50Py5jdXJyZW50VGFyZ2V0Py5wYXJlbnRFbGVtZW50XG4gICAgKTtcbiAgfVxuXG4gIGNsZWFyKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGlmIChcbiAgICAgICghdGhpcy5tdWx0aXBsZSAmJiB0aGlzLnRyZWVTZWxlY3Rpb24pIHx8XG4gICAgICAodGhpcy5tdWx0aXBsZSAmJiB0aGlzLnRyZWVTZWxlY3Rpb24/Lmxlbmd0aCA+IDApXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5vcGVuT25DbGVhcikge1xuICAgICAgICB0aGlzLnRvZ2dsZU9wdGlvbnModHJ1ZSk7XG4gICAgICB9XG4gICAgICBjb25zdCB2YWwgPSB0aGlzLm11bHRpcGxlID8gW10gOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLnRyZWVTZWxlY3Rpb24gPSB2YWw7XG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlKHZhbCk7XG4gICAgfVxuICAgIHRoaXMub3B0aW9uRm9jdXNlZCA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBfY2hlY2tFcnJvcnMoKTogdm9pZCB7XG4gICAgY29uc3QgZXJyb3JzID0gdGhpcy5jb250cm9sPy5lcnJvcnM7XG5cbiAgICBpZiAoIXRoaXMuY29udHJvbD8uY29udHJvbD8udG91Y2hlZCB8fCAhZXJyb3JzKSB7XG4gICAgICB0aGlzLmVycm9yID0gJyc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCdyZXF1aXJlZCcgaW4gZXJyb3JzKSB7XG4gICAgICB0aGlzLmVycm9yID0gJ0ZpZWxkIGlzIHJlcXVpcmVkJztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlcnJBcnIgPSBPYmplY3QudmFsdWVzKGVycm9ycyk7XG4gICAgaWYgKGVyckFyci5sZW5ndGggPCAxKSB7XG4gICAgICB0aGlzLmVycm9yID0gJyc7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJBcnIuZmluZCgobXNnKSA9PiB0eXBlb2YgbXNnID09PSAnc3RyaW5nJyk7XG5cbiAgICB0aGlzLmVycm9yID0gbWVzc2FnZSB8fCAnVW5rbm93biBlcnJvcic7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gIHNldERpc2FibGVkU3RhdGUoZGlzYWJsZWQ6IGJvb2xlYW4pIHt9XG5cbiAgb25CbHVyKCkge1xuICAgIHRoaXMuY29udHJvbD8uY29udHJvbD8ubWFya0FzVG91Y2hlZCgpO1xuICAgIHRoaXMuX2NoZWNrRXJyb3JzKCk7XG4gIH1cblxuICBmb2N1cygpIHtcbiAgICB0aGlzLmNvbXBvbmVudENvbnRhaW5lcj8ubmF0aXZlRWxlbWVudD8uZm9jdXMoKTtcbiAgICB0aGlzLnRvZ2dsZU9wdGlvbnModHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9leHBhbmRUb05vZGVzKG5vZGVzOiBhbnlbXSkge1xuICAgIGZ1bmN0aW9uIGdldFBhcmVudEtleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICBjb25zdCBsYXN0U2VwYXJhdG9ySW5kZXggPSBrZXkubGFzdEluZGV4T2YoJy0nKTtcbiAgICAgIGlmIChsYXN0U2VwYXJhdG9ySW5kZXggIT09IC0xKSB7XG4gICAgICAgIHJldHVybiBrZXkuc3Vic3RyaW5nKDAsIGxhc3RTZXBhcmF0b3JJbmRleCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgY29uc3QgcGFyZW50Tm9kZUtleSA9IGdldFBhcmVudEtleShub2RlLmtleSk7XG4gICAgICBjb25zdCBwYXJlbnROb2RlID0gdGhpcy5vcHRpb25zTWFwLmdldChwYXJlbnROb2RlS2V5KSB8fCBudWxsO1xuXG4gICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICBwYXJlbnROb2RlLmV4cGFuZGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZXhwYW5kVG9Ob2RlcyhbcGFyZW50Tm9kZV0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfdG9Jbm5lck9wdGlvbnMoX29wdGlvbnM6IGFueVtdKTogVHJlZU5vZGVbXSB7XG4gICAgZnVuY3Rpb24gbWFwT3B0aW9uKFxuICAgICAgbzogYW55LFxuICAgICAgb3B0aW9uTGFiZWw6IHN0cmluZyxcbiAgICAgIG9wdGlvbkluZm86IHN0cmluZyxcbiAgICAgIGtleTogc3RyaW5nLFxuICAgICAgb3JpZ2luYWxPcHRpb25zTWFwOiBhbnlcbiAgICApIHtcbiAgICAgIGNvbnN0IGlubmVyID0ge1xuICAgICAgICBpbm5lcjogdHJ1ZSxcbiAgICAgICAgbGFiZWw6IG9bb3B0aW9uTGFiZWxdLFxuICAgICAgICBpbmZvOiBvW29wdGlvbkluZm9dLFxuICAgICAgICBrZXksXG4gICAgICAgIHN0eWxlQ2xhc3M6ICdrZXktJyArIGtleVxuICAgICAgfSBhcyBUcmVlTm9kZTtcbiAgICAgIGlmIChvLmlzRGlyZWN0b3J5KSB7XG4gICAgICAgIGlubmVyLnR5cGUgPSAnZGlyZWN0b3J5JztcbiAgICAgICAgaW5uZXIuc2VsZWN0YWJsZSA9IGZhbHNlO1xuICAgICAgICBpbm5lci5zdHlsZUNsYXNzICs9ICcgY3BzLXRyZWUtbm9kZS1mdWxseS1leHBhbmRhYmxlJztcbiAgICAgIH1cbiAgICAgIGlmIChvLmNoaWxkcmVuKSB7XG4gICAgICAgIGlubmVyLmNoaWxkcmVuID0gby5jaGlsZHJlbi5tYXAoKGM6IGFueSwgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIHJldHVybiBtYXBPcHRpb24oXG4gICAgICAgICAgICBjLFxuICAgICAgICAgICAgb3B0aW9uTGFiZWwsXG4gICAgICAgICAgICBvcHRpb25JbmZvLFxuICAgICAgICAgICAga2V5ICsgJy0nICsgaW5kZXgsXG4gICAgICAgICAgICBvcmlnaW5hbE9wdGlvbnNNYXBcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIG9yaWdpbmFsT3B0aW9uc01hcC5zZXQoa2V5LCBvKTtcbiAgICAgIHJldHVybiBpbm5lcjtcbiAgICB9XG5cbiAgICBjb25zdCByZXMgPSBfb3B0aW9ucy5tYXAoKG9wdGlvbiwgaW5kZXgpID0+IHtcbiAgICAgIHJldHVybiBtYXBPcHRpb24oXG4gICAgICAgIG9wdGlvbixcbiAgICAgICAgdGhpcy5vcHRpb25MYWJlbCxcbiAgICAgICAgdGhpcy5vcHRpb25JbmZvLFxuICAgICAgICAnJyArIGluZGV4LFxuICAgICAgICB0aGlzLm9yaWdpbmFsT3B0aW9uc01hcFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMub3B0aW9uc01hcCA9IHRoaXMuX2J1aWxkT3B0aW9uc01hcChyZXMpO1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHByaXZhdGUgX2J1aWxkT3B0aW9uc01hcChvcHRpb25zOiBhbnlbXSk6IE1hcDxzdHJpbmcsIGFueT4ge1xuICAgIGNvbnN0IG5vZGVNYXAgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICAgIG5vZGVNYXAuc2V0KG9wdGlvbi5rZXksIG9wdGlvbik7XG4gICAgICBpZiAob3B0aW9uLmNoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkTm9kZU1hcCA9IHRoaXMuX2J1aWxkT3B0aW9uc01hcChvcHRpb24uY2hpbGRyZW4pO1xuICAgICAgICBjaGlsZE5vZGVNYXAuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gbm9kZU1hcC5zZXQoa2V5LCB2YWx1ZSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm9kZU1hcDtcbiAgfVxuXG4gIHRyZWVTZWxlY3Rpb25Ub1ZhbHVlKHNlbGVjdGlvbjogYW55KSB7XG4gICAgaWYgKCFzZWxlY3Rpb24pIHJldHVybiB0aGlzLm11bHRpcGxlID8gW10gOiB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgIHJldHVybiBzZWxlY3Rpb24ubWFwKChzOiBhbnkpID0+IHRoaXMub3JpZ2luYWxPcHRpb25zTWFwLmdldChzLmtleSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5vcmlnaW5hbE9wdGlvbnNNYXAuZ2V0KHNlbGVjdGlvbi5rZXkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3ZhbHVlVG9UcmVlU2VsZWN0aW9uKHZhbHVlOiBhbnkpIHtcbiAgICBmdW5jdGlvbiBnZXRLZXkodjogYW55LCBtYXA6IE1hcDxzdHJpbmcsIGFueT4pOiBzdHJpbmcge1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIG1hcC5lbnRyaWVzKCkpIHtcbiAgICAgICAgaWYgKGlzRXF1YWwodiwgdmFsKSkge1xuICAgICAgICAgIHJldHVybiBrZXk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBpZiAoIXZhbHVlKSByZXR1cm4gdGhpcy5tdWx0aXBsZSA/IFtdIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgIGNvbnN0IHJlcyA9IFtdIGFzIFRyZWVOb2RlW107XG4gICAgICB2YWx1ZS5mb3JFYWNoKCh2OiBhbnkpID0+IHtcbiAgICAgICAgY29uc3Qga2V5ID0gZ2V0S2V5KHYsIHRoaXMub3JpZ2luYWxPcHRpb25zTWFwKTtcbiAgICAgICAgaWYgKGtleSkgcmVzLnB1c2godGhpcy5vcHRpb25zTWFwLmdldChrZXkpIGFzIFRyZWVOb2RlKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qga2V5ID0gZ2V0S2V5KHZhbHVlLCB0aGlzLm9yaWdpbmFsT3B0aW9uc01hcCk7XG4gICAgICByZXR1cm4ga2V5ID8gdGhpcy5vcHRpb25zTWFwLmdldChrZXkpIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8vIHRoaXMgaXMgYSBmaXggb2YgcHJpbWVuZyBjaGFuZ2UgZGV0ZWN0aW9uIGJ1ZyB3aGVuIHZpcnR1YWwgc2Nyb2xsZXIgaXMgZW5hYmxlZFxuICB1cGRhdGVPcHRpb25zKCkge1xuICAgIGlmICghdGhpcy52aXJ0dWFsU2Nyb2xsKSByZXR1cm47XG4gICAgdGhpcy5vcHRpb25zID0gWy4uLnRoaXMub3B0aW9uc107XG4gIH1cbn1cbiJdfQ==