ngx-dropdown-list 1.1.0 → 1.2.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 (65) hide show
  1. package/README.md +2 -2
  2. package/esm2020/ngx-dropdown-list.mjs +5 -0
  3. package/esm2020/public_api.mjs +2 -0
  4. package/esm2020/src/ngx-dropdown-list/anchor/anchor.component.mjs +149 -0
  5. package/esm2020/src/ngx-dropdown-list/dropdown/dropdown.component.mjs +252 -0
  6. package/esm2020/src/ngx-dropdown-list/dropdown-list.component.mjs +233 -0
  7. package/esm2020/src/ngx-dropdown-list/dropdown-list.module.mjs +38 -0
  8. package/esm2020/src/ngx-dropdown-list/filter/input-filter.component.mjs +44 -0
  9. package/esm2020/src/ngx-dropdown-list/group-item/group-item.component.mjs +25 -0
  10. package/esm2020/src/ngx-dropdown-list/index.mjs +3 -0
  11. package/esm2020/src/ngx-dropdown-list/item/item.component.mjs +77 -0
  12. package/esm2020/src/ngx-dropdown-list/types/index.mjs +3 -0
  13. package/esm2020/src/ngx-dropdown-list/types/selection-group-items.types.mjs +2 -0
  14. package/esm2020/src/ngx-dropdown-list/types/selection-item.types.mjs +2 -0
  15. package/esm2020/src/ngx-dropdown-list/utils/util.mjs +59 -0
  16. package/fesm2015/ngx-dropdown-list.mjs +854 -0
  17. package/fesm2015/ngx-dropdown-list.mjs.map +1 -0
  18. package/fesm2020/ngx-dropdown-list.mjs +854 -0
  19. package/fesm2020/ngx-dropdown-list.mjs.map +1 -0
  20. package/ngx-dropdown-list.d.ts +1 -5
  21. package/package.json +26 -48
  22. package/src/ngx-dropdown-list/anchor/anchor.component.d.ts +6 -3
  23. package/src/ngx-dropdown-list/dropdown/dropdown.component.d.ts +5 -2
  24. package/src/ngx-dropdown-list/dropdown-list.component.d.ts +7 -4
  25. package/src/ngx-dropdown-list/dropdown-list.module.d.ts +12 -0
  26. package/src/ngx-dropdown-list/filter/input-filter.component.d.ts +3 -0
  27. package/src/ngx-dropdown-list/group-item/group-item.component.d.ts +3 -0
  28. package/src/ngx-dropdown-list/item/item.component.d.ts +3 -0
  29. package/bundles/ngx-dropdown-list.umd.js +0 -1180
  30. package/bundles/ngx-dropdown-list.umd.js.map +0 -1
  31. package/bundles/ngx-dropdown-list.umd.min.js +0 -2
  32. package/bundles/ngx-dropdown-list.umd.min.js.map +0 -1
  33. package/esm2015/ngx-dropdown-list.js +0 -14
  34. package/esm2015/public_api.js +0 -6
  35. package/esm2015/src/ngx-dropdown-list/anchor/anchor.component.js +0 -226
  36. package/esm2015/src/ngx-dropdown-list/dropdown/dropdown.component.js +0 -339
  37. package/esm2015/src/ngx-dropdown-list/dropdown-list.component.js +0 -290
  38. package/esm2015/src/ngx-dropdown-list/dropdown-list.module.js +0 -32
  39. package/esm2015/src/ngx-dropdown-list/filter/input-filter.component.js +0 -64
  40. package/esm2015/src/ngx-dropdown-list/group-item/group-item.component.js +0 -37
  41. package/esm2015/src/ngx-dropdown-list/index.js +0 -7
  42. package/esm2015/src/ngx-dropdown-list/item/item.component.js +0 -104
  43. package/esm2015/src/ngx-dropdown-list/types/index.js +0 -7
  44. package/esm2015/src/ngx-dropdown-list/types/selection-group-items.types.js +0 -16
  45. package/esm2015/src/ngx-dropdown-list/types/selection-item.types.js +0 -20
  46. package/esm2015/src/ngx-dropdown-list/utils/util.js +0 -73
  47. package/esm5/ngx-dropdown-list.js +0 -14
  48. package/esm5/public_api.js +0 -6
  49. package/esm5/src/ngx-dropdown-list/anchor/anchor.component.js +0 -272
  50. package/esm5/src/ngx-dropdown-list/dropdown/dropdown.component.js +0 -408
  51. package/esm5/src/ngx-dropdown-list/dropdown-list.component.js +0 -361
  52. package/esm5/src/ngx-dropdown-list/dropdown-list.module.js +0 -36
  53. package/esm5/src/ngx-dropdown-list/filter/input-filter.component.js +0 -79
  54. package/esm5/src/ngx-dropdown-list/group-item/group-item.component.js +0 -47
  55. package/esm5/src/ngx-dropdown-list/index.js +0 -7
  56. package/esm5/src/ngx-dropdown-list/item/item.component.js +0 -120
  57. package/esm5/src/ngx-dropdown-list/types/index.js +0 -7
  58. package/esm5/src/ngx-dropdown-list/types/selection-group-items.types.js +0 -16
  59. package/esm5/src/ngx-dropdown-list/types/selection-item.types.js +0 -20
  60. package/esm5/src/ngx-dropdown-list/utils/util.js +0 -96
  61. package/fesm2015/ngx-dropdown-list.js +0 -890
  62. package/fesm2015/ngx-dropdown-list.js.map +0 -1
  63. package/fesm5/ngx-dropdown-list.js +0 -1137
  64. package/fesm5/ngx-dropdown-list.js.map +0 -1
  65. package/ngx-dropdown-list.metadata.json +0 -1
@@ -1,890 +0,0 @@
1
- import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, NgModule } from '@angular/core';
2
- import { DecimalPipe, CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
-
5
- /**
6
- * @fileoverview added by tsickle
7
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
8
- */
9
- /**
10
- * check whether the provided items contains group
11
- * @param {?} items
12
- * @return {?}
13
- */
14
- function hasGroup(items) {
15
- return items ? (items.find(item => item.group) != null) : false;
16
- }
17
- /**
18
- * clear all selections from the provide items.
19
- * @param {?} items the dropdown items, can be group or item
20
- * @return {?}
21
- */
22
- function clearAllSelection(items) {
23
- if (hasGroup(items)) {
24
- for (const groupItem of items) {
25
- if (groupItem.items) {
26
- groupItem.items.filter(item => item.selected).forEach(item => item.selected = false);
27
- }
28
- }
29
- }
30
- else {
31
- // clear the selection of previous selected item
32
- items.filter(item => item.selected).forEach(item => item.selected = false);
33
- }
34
- }
35
- /**
36
- * stop all propagation and default actions
37
- * @param {?} event
38
- * @return {?}
39
- */
40
- function stopPropagationAndDefault(event) {
41
- event.stopImmediatePropagation();
42
- event.stopPropagation();
43
- event.preventDefault();
44
- }
45
- /**
46
- * check whether the provided value is number of not
47
- * @param {?} value
48
- * @return {?}
49
- */
50
- function isNumber(value) {
51
- return !(value == null || isNaN(value) || value.length === 0);
52
- }
53
- /**
54
- * get the selected item from the items list (including item and group)
55
- * @param {?} items
56
- * @return {?}
57
- */
58
- function getFirstSelectedItem(items) {
59
- if (!items) {
60
- return undefined;
61
- }
62
- /** @type {?} */
63
- let selectedItem;
64
- if (hasGroup(items)) {
65
- for (const item of items) {
66
- selectedItem = item.items ? item.items.find(subItem => subItem.selected) : undefined;
67
- if (selectedItem) {
68
- break;
69
- }
70
- }
71
- }
72
- else {
73
- selectedItem = items ? items.find(item => item.selected) : undefined;
74
- }
75
- return selectedItem;
76
- }
77
-
78
- /**
79
- * @fileoverview added by tsickle
80
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
81
- */
82
- class DropdownListComponent {
83
- constructor() {
84
- /**
85
- * bind to [multiSelection], the flag for multi-select (checkbox) mode.
86
- */
87
- this.multiSelection = false;
88
- /**
89
- * bind to [filterBox] for displaying the filter input text box
90
- */
91
- this.filterBox = false;
92
- /**
93
- * bind to [allowClear] for enabling the clearance (clearance is not avaiable when checkbox is enabled)
94
- */
95
- this.allowClear = true;
96
- /**
97
- * bind to [formatNumber] for show formatted number text
98
- */
99
- this.formatNumber = false;
100
- /**
101
- * for 2-way binding of [selectedValue], using async event to
102
- * prevent "ExpressionChangedAfterItHasBeenCheckedError".
103
- */
104
- this.selectedValueChange = new EventEmitter(true);
105
- /**
106
- * [selectionChange] event that will be triggered when changing of the selection.
107
- * Using async event to prevent "ExpressionChangedAfterItHasBeenCheckedError".
108
- */
109
- this.selectionChange = new EventEmitter(true);
110
- /**
111
- * visibility flag of drop down
112
- */
113
- this.dropdownVisibility = false;
114
- }
115
- /**
116
- * current selected text
117
- * @return {?}
118
- */
119
- get selectedText() {
120
- if (!this.multiSelection) {
121
- /** @type {?} */
122
- const selectedItem = getFirstSelectedItem(this.items);
123
- return selectedItem ? selectedItem.text : undefined;
124
- }
125
- }
126
- /**
127
- * triggered with (selectionChange) event, emits (selectedValueChange) and (selectionChange)
128
- * @param {?} event
129
- * @return {?}
130
- */
131
- onSelectionChange(event) {
132
- this.selectedValueChange.emit(event);
133
- this.selectionChange.emit(event);
134
- }
135
- /**
136
- * triggered with (anchorClick) event, controlling the "open" and "close" of the dropdown
137
- * @param {?} event
138
- * @return {?}
139
- */
140
- onAnchorClick(event) {
141
- if (this.disabled) {
142
- stopPropagationAndDefault(event);
143
- return;
144
- }
145
- if (this._isSelectionOpen()) {
146
- this._hideItemList();
147
- }
148
- else {
149
- this._showItemsList();
150
- }
151
- stopPropagationAndDefault(event);
152
- }
153
- /**
154
- * triggered with (itemClick) event, closes the dropdown in non-checkbox mode
155
- * @return {?}
156
- */
157
- onItemClick() {
158
- if (!this.multiSelection) {
159
- this._hideItemList();
160
- }
161
- }
162
- /**
163
- * triggered with (clearanceClick) event, clearing all selections
164
- * and emits (selectedValueChange) and (selectionChange) event for empty value
165
- * @param {?} event
166
- * @return {?}
167
- */
168
- onClearanceClick(event) {
169
- if (!this.multiSelection) {
170
- this.selectedValue = void 0;
171
- this.selectedValueChange.emit(undefined);
172
- this.selectionChange.emit(undefined);
173
- clearAllSelection(this.items);
174
- }
175
- stopPropagationAndDefault(event);
176
- }
177
- /**
178
- * triggered with (dropdownBlur) event, closes the dropdown
179
- * @return {?}
180
- */
181
- onItemsBlur() {
182
- if (this._isSelectionOpen()) {
183
- this._hideItemList();
184
- }
185
- }
186
- /**
187
- * close the dropdown
188
- * @private
189
- * @return {?}
190
- */
191
- _hideItemList() {
192
- // hide the dropdown element (has some problem for using CSS directly, using this as a workaround)
193
- this._dropdownElement.classList.remove('visible');
194
- this._dropdownElement.style.display = 'none';
195
- this.dropdownVisibility = false;
196
- }
197
- /**
198
- * open the dropdown
199
- * @private
200
- * @return {?}
201
- */
202
- _showItemsList() {
203
- // display the dropdown element (has some problem for using CSS directly, using this as a workaround)
204
- this._dropdownElement.classList.add('visible');
205
- this._dropdownElement.style.display = 'block';
206
- this.dropdownVisibility = true;
207
- // scrolling to the selected item
208
- if (this._selectedElement) {
209
- this._selectedElement.scrollIntoView({ behavior: 'instant', block: 'center' });
210
- }
211
- // setting the focus
212
- if (this.filterBox && !this.multiSelection) {
213
- this._filterInputElement.focus();
214
- }
215
- else {
216
- this._dropdownElement.focus();
217
- }
218
- }
219
- /**
220
- * visibility status of dropdown
221
- * @private
222
- * @return {?}
223
- */
224
- _isSelectionOpen() {
225
- return this.dropdownVisibility;
226
- }
227
- /**
228
- * get the real dropdown element (for focusing and visibility controlling), the <span> not the <dropdown>
229
- * @private
230
- * @return {?}
231
- */
232
- get _dropdownElement() {
233
- return this.dropdownRef ? this.dropdownRef.nativeElement ? this.dropdownRef.nativeElement.firstElementChild : null : null;
234
- }
235
- /**
236
- * get the real filter element (for focusing), the <input> not the <input-filter>
237
- * @private
238
- * @return {?}
239
- */
240
- get _filterInputElement() {
241
- return this._dropdownElement ?
242
- this._dropdownElement.firstElementChild ? this._dropdownElement.firstElementChild.firstElementChild : null : null;
243
- }
244
- /**
245
- * get the HTMLElement of selected item, for doing (scrollIntoView) scrolling to the selected item
246
- * @private
247
- * @return {?}
248
- */
249
- get _selectedElement() {
250
- /** @type {?} */
251
- const selectedItem = getFirstSelectedItem(this.items);
252
- return selectedItem ? (/** @type {?} */ (document.getElementById(selectedItem.id))) : undefined;
253
- }
254
- }
255
- DropdownListComponent.decorators = [
256
- { type: Component, args: [{
257
- selector: 'ngx-dropdown-list',
258
- template: `
259
- <span class="ngx-select">
260
- <anchor (anchorClick)="onAnchorClick($event)" (clearanceClick)="onClearanceClick($event)"
261
- [checkbox]="multiSelection"
262
- [formatNumber]="formatNumber"
263
- [suffixText]="suffixText"
264
- [placeHolder]="placeHolder"
265
- [allowClear]="allowClear"
266
- [openStatus]="dropdownVisibility"
267
- [selectedText]="selectedText"
268
- [disabled]="disabled">
269
- </anchor>
270
- <dropdown #dropdown (dropdownBlur) = "onItemsBlur()" (selectionChange)="onSelectionChange($event)"
271
- [items]="items"
272
- [checkbox]="multiSelection"
273
- [filterBox]="filterBox"
274
- [formatNumber]="formatNumber"
275
- [suffixText]="suffixText"
276
- [(selectedValue)]="selectedValue"
277
- (itemClick) = "onItemClick()"
278
- [disabled]="disabled">
279
- </dropdown>
280
- </span>
281
- `,
282
- styles: [":host *,:host :after,:host :before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}:host .ngx-select{border-radius:4px;font-size:14px;position:relative;display:inline-block;width:100%;height:34px;background:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"]
283
- }] }
284
- ];
285
- DropdownListComponent.propDecorators = {
286
- dropdownRef: [{ type: ViewChild, args: ['dropdown', { read: ElementRef },] }],
287
- placeHolder: [{ type: Input }],
288
- items: [{ type: Input }],
289
- multiSelection: [{ type: Input }],
290
- selectedValue: [{ type: Input }],
291
- filterBox: [{ type: Input }],
292
- suffixText: [{ type: Input }],
293
- disabled: [{ type: Input }],
294
- allowClear: [{ type: Input }],
295
- formatNumber: [{ type: Input }],
296
- selectedValueChange: [{ type: Output }],
297
- selectionChange: [{ type: Output }]
298
- };
299
-
300
- /**
301
- * @fileoverview added by tsickle
302
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
303
- */
304
- class ItemComponent {
305
- constructor() {
306
- /**
307
- * bind to [formatNumber], the flag for formatting the number
308
- */
309
- this.formatNumber = false;
310
- /**
311
- * bind to [itemClick] event, triggers when clicking the item of dropdown
312
- */
313
- this.itemClick = new EventEmitter();
314
- /**
315
- * bind to [checkStatusChange] event, triggers when check status is changed in checkbox mode.
316
- */
317
- this.checkStatusChange = new EventEmitter();
318
- }
319
- /**
320
- * check whether needs to format number for the provided text
321
- * @param {?} value
322
- * @return {?}
323
- */
324
- needFormatNumber(value) {
325
- return isNumber(value) && this.formatNumber;
326
- }
327
- /**
328
- * triggered when clicking the item, emits the [itemClick] event
329
- * @param {?} item
330
- * @return {?}
331
- */
332
- onItemClick(item) {
333
- this.itemClick.emit(item);
334
- }
335
- /**
336
- * triggered when checking status changed in checkbox mode, emits the [checkStatusChange] event
337
- * @param {?} item
338
- * @return {?}
339
- */
340
- onCheckStatusChange(item) {
341
- this.checkStatusChange.emit(item);
342
- }
343
- }
344
- ItemComponent.decorators = [
345
- { type: Component, args: [{
346
- selector: 'item',
347
- template: `
348
- <label [class.container-checkbox]="checkbox"
349
- [class.container-selection]="!checkbox && !item.selected"
350
- [class.container-selection-selected]="!checkbox && item.selected"
351
- [id]="item.id" (mousedown)="onItemClick(item)">
352
- {{needFormatNumber(item.text)? (item.text | number:'1.0-2') : item.text}}{{suffixText? suffixText : ''}}
353
- <ng-container *ngIf="checkbox">
354
- <input type='checkbox' [id]="'checkbox-'+item.text" (change)="onCheckStatusChange(item)" [checked]="item.selected">
355
- <span class="checkmark" [id]="'checkmark-'+item.text"></span>
356
- </ng-container>
357
- </label>`,
358
- styles: ["*,:after,:before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}.container-checkbox,.container-selection,.container-selection-selected,.dropdown-item{background:0 0;display:list-item;list-style:none;position:relative;width:100%;height:auto;cursor:pointer;color:#495057;padding-bottom:5px;padding-top:5px;padding-left:12px}.container-checkbox{padding-left:35px}.container-checkbox input{position:absolute;opacity:0;cursor:pointer}.container-checkbox .checkmark{position:absolute;top:5px;left:10px;height:15px;width:15px;border:1px solid rgba(0,0,0,.3);background-color:#fff;border-radius:4px}.container-checkbox .checkmark:after{content:\"\";position:absolute;display:none;left:5px;top:2px;width:4px;height:7px;border:solid #fff;border-width:0 2px 2px 0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.container-checkbox:hover input~.checkmark{background-color:#ccc}.container-checkbox input:checked~.checkmark{background-color:#2196f3;border:1px solid #2196f3}.container-checkbox input:checked~.checkmark:after{display:block}.container-checkbox:hover{color:#66afe9}.container-selection,.container-selection-selected{padding-left:12px}.container-selection-selected:hover,.container-selection:hover{color:#495057;background:#e0ffff}.container-selection-selected{color:#fff;background:#6495ed}"]
359
- }] }
360
- ];
361
- ItemComponent.propDecorators = {
362
- checkbox: [{ type: Input }],
363
- item: [{ type: Input }],
364
- formatNumber: [{ type: Input }],
365
- suffixText: [{ type: Input }],
366
- itemClick: [{ type: Output }],
367
- checkStatusChange: [{ type: Output }]
368
- };
369
-
370
- /**
371
- * @fileoverview added by tsickle
372
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
373
- */
374
- class GroupItemComponent {
375
- /**
376
- * prevent all clicking event from happening
377
- * @param {?} event
378
- * @return {?}
379
- */
380
- onItemGroupClick(event) {
381
- event.stopImmediatePropagation();
382
- event.stopPropagation();
383
- event.preventDefault();
384
- }
385
- }
386
- GroupItemComponent.decorators = [
387
- { type: Component, args: [{
388
- selector: 'group-item',
389
- template: `
390
- <label class="dropdown-item dropdown-item-group" (mousedown)="onItemGroupClick($event)">{{item.group}}</label>
391
- `,
392
- styles: ["*,:after,:before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}.container-checkbox,.container-selection,.container-selection-selected,.dropdown-item{background:0 0;display:list-item;list-style:none;position:relative;width:100%;height:auto;cursor:pointer;color:#495057;padding-bottom:5px;padding-top:5px;padding-left:12px}.container-checkbox{padding-left:35px}.container-checkbox input{position:absolute;opacity:0;cursor:pointer}.container-checkbox .checkmark{position:absolute;top:5px;left:10px;height:15px;width:15px;border:1px solid rgba(0,0,0,.3);background-color:#fff;border-radius:4px}.container-checkbox .checkmark:after{content:\"\";position:absolute;display:none;left:5px;top:2px;width:4px;height:7px;border:solid #fff;border-width:0 2px 2px 0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.container-checkbox:hover input~.checkmark{background-color:#ccc}.container-checkbox input:checked~.checkmark{background-color:#2196f3;border:1px solid #2196f3}.container-checkbox input:checked~.checkmark:after{display:block}.container-checkbox:hover{color:#66afe9}.container-selection,.container-selection-selected{padding-left:12px}.container-selection-selected:hover,.container-selection:hover{color:#495057;background:#e0ffff}.container-selection-selected{color:#fff;background:#6495ed}.dropdown-item-group{font-weight:700}.dropdown-item-group:hover{cursor:default}"]
393
- }] }
394
- ];
395
- GroupItemComponent.propDecorators = {
396
- item: [{ type: Input }]
397
- };
398
-
399
- /**
400
- * @fileoverview added by tsickle
401
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
402
- */
403
- class InputFilterComponent {
404
- constructor() {
405
- /**
406
- * bind to [inputFilterBlur], emits with (blur) of filter input box
407
- */
408
- this.inputFilterBlur = new EventEmitter();
409
- /**
410
- * bind to [filterValueChange], for 2-way binding of filterValue
411
- */
412
- this.filterValueChange = new EventEmitter();
413
- }
414
- /**
415
- * triggers with (blur) event, emits the (inputFilterBlur) event
416
- * @param {?} event
417
- * @return {?}
418
- */
419
- onFilterTextBlur(event) {
420
- this.inputFilterBlur.emit(event);
421
- }
422
- /**
423
- * triggers with (input) event, emits the (filterValueChange) event for 2-way binding of filterValue
424
- * @return {?}
425
- */
426
- onChange() {
427
- this.filterValueChange.emit(this.filterValue);
428
- }
429
- }
430
- InputFilterComponent.decorators = [
431
- { type: Component, args: [{
432
- selector: 'input-filter',
433
- template: `
434
- <input type="text" class="filter-box" [(ngModel)]="filterValue" (input)="onChange()" (blur)="onFilterTextBlur($event)">
435
- `,
436
- styles: ["*,:after,:before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}.filter-box{width:calc(100% - 10px);height:28px;border-radius:4px;border:1px solid #ccc;margin:1px 5px 5px;padding-left:5px;font-size:12px;box-sizing:border-box;color:#495057}.filter-box:focus{outline:0;border-color:#ccc}"]
437
- }] }
438
- ];
439
- InputFilterComponent.propDecorators = {
440
- filterValue: [{ type: Input }],
441
- inputFilterBlur: [{ type: Output }],
442
- filterValueChange: [{ type: Output }]
443
- };
444
-
445
- /**
446
- * @fileoverview added by tsickle
447
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
448
- */
449
- class AnchorComponent {
450
- /**
451
- * @param {?} _decimalPipe
452
- */
453
- constructor(_decimalPipe) {
454
- this._decimalPipe = _decimalPipe;
455
- /**
456
- * bind to [checkbox] for checking whether the clearance flag should be shown or not.
457
- */
458
- this.checkbox = false;
459
- /**
460
- * bind to [allowClear] for enabling the clearance (clearance is not avaiable when checkbox is enabled)
461
- */
462
- this.allowClear = true;
463
- /**
464
- * bind to [openStatus], it's the visibility status of dropdown, for showing the arrow on anchor
465
- */
466
- this.openStatus = false;
467
- /**
468
- * bind to [disabled] for disabling the anchor
469
- */
470
- this.disabled = false;
471
- /**
472
- * will be triggered when clicking the anchor
473
- */
474
- this.anchorClick = new EventEmitter();
475
- /**
476
- * will be triggered when clicking the clearance
477
- */
478
- this.clearanceClick = new EventEmitter();
479
- }
480
- /**
481
- * flag for showing the clearance flag
482
- * @return {?}
483
- */
484
- get showClearanceFlag() {
485
- return !this.checkbox && this.selectedText && this.allowClear;
486
- }
487
- /**
488
- * the text displays on anchor
489
- * @return {?}
490
- */
491
- get anchorDisplayText() {
492
- /** @type {?} */
493
- let anchorDisplayText = this.selectedText ? (this.formatNumber ? (isNumber(this.selectedText) ?
494
- this._decimalPipe.transform(this.selectedText, '1.0-2') : this.selectedText) :
495
- this.selectedText) + (this.suffixText ? this.suffixText : '') : this.placeHolder;
496
- /** @type {?} */
497
- let charLength = 1;
498
- if (this.showClearanceFlag && this.anchorLength > 0) {
499
- charLength = Math.floor((this.anchorLength - 50) / 7);
500
- }
501
- else {
502
- charLength = Math.floor((this.anchorLength - 50) / 7);
503
- }
504
- if (anchorDisplayText.length > charLength) {
505
- anchorDisplayText = anchorDisplayText.slice(0, charLength - 2) + '...';
506
- }
507
- return anchorDisplayText;
508
- }
509
- /**
510
- * anchor CSS class
511
- * @return {?}
512
- */
513
- get anchorClass() {
514
- /** @type {?} */
515
- let anchorClassStatusPart;
516
- /** @type {?} */
517
- let anchorClassFontColor;
518
- if (this.disabled) {
519
- anchorClassStatusPart = 'selection-anchor-disabled';
520
- anchorClassFontColor = 'place-holder';
521
- }
522
- else {
523
- if (this.openStatus) {
524
- anchorClassStatusPart = 'selection-anchor-open';
525
- }
526
- else {
527
- anchorClassStatusPart = 'selection-anchor-close';
528
- }
529
- if (this.selectedText != null) {
530
- anchorClassFontColor = 'selected-item';
531
- }
532
- else {
533
- anchorClassFontColor = 'place-holder';
534
- }
535
- }
536
- return `${anchorClassStatusPart} ${anchorClassFontColor}`;
537
- }
538
- /**
539
- * triggered when clicking the anchor
540
- * @param {?} event
541
- * @return {?}
542
- */
543
- onAnchorClick(event) {
544
- this.anchorClick.emit(event);
545
- }
546
- /**
547
- * triggered with (blur) of anchor
548
- * @param {?} event
549
- * @return {?}
550
- */
551
- onAnchorBlur(event) {
552
- stopPropagationAndDefault(event);
553
- }
554
- /**
555
- * triggered when clicking the clearance
556
- * @param {?} event
557
- * @return {?}
558
- */
559
- onClearanceClick(event) {
560
- this.clearanceClick.emit(event);
561
- }
562
- /**
563
- * triggered when resizing, get the clientWidth of anchor
564
- * @return {?}
565
- */
566
- onResize() {
567
- this.anchorLength = this.anchorRef ? this.anchorRef.nativeElement ? this.anchorRef.nativeElement.clientWidth : 0 : 0;
568
- }
569
- }
570
- AnchorComponent.decorators = [
571
- { type: Component, args: [{
572
- selector: 'anchor',
573
- template: `
574
- <span #anchor tabindex="2" [ngClass]="anchorClass" (window:resize)="onResize()"
575
- (mousedown)="onAnchorClick($event)" (blur)="onAnchorBlur($event)"> {{anchorDisplayText}}
576
- <span #selectionClearance class="selection-clearance" (mousedown)="onClearanceClick($event)" *ngIf="showClearanceFlag">&times;</span>
577
- </span>
578
- `,
579
- providers: [DecimalPipe],
580
- styles: ["*,:after,:before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}.selection-anchor-close:after,.selection-anchor-disabled:after,.selection-anchor-open:after,.vertical-center{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.hover-box,.selection-anchor-close:hover{outline:0;box-shadow:0 0 6px #23adff;border-radius:4px}.anchor-box,.selection-anchor,.selection-anchor-close,.selection-anchor-disabled,.selection-anchor-open{height:100%;border-radius:4px;width:100%;position:relative;display:inline-block;padding:8px 12px 5px;border:1px solid;outline:0;box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-sizing:border-box;white-space:nowrap}.selection-anchor,.selection-anchor-close,.selection-anchor-open{cursor:pointer}.selection-anchor .selection-clearance,.selection-anchor-close .selection-clearance,.selection-anchor-open .selection-clearance{position:absolute;right:35px;font-weight:700}.selection-anchor .selection-clearance:hover,.selection-anchor-close .selection-clearance:hover,.selection-anchor-open .selection-clearance:hover{color:#000}.selection-anchor-close:focus,.selection-anchor-open:focus,.selection-anchor:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;border-color:#66afe9}.selection-anchor-disabled{border-color:#ccc;cursor:default;pointer-events:none;background:#f8f8f8;-webkit-filter:opacity(50%);filter:opacity(50%)}.selection-anchor-disabled:after{font-size:12px;content:'\\0023F7';right:10px;padding-bottom:3px}.selection-anchor-open{border-bottom:none;border-bottom-right-radius:0;border-bottom-left-radius:0;border-color:#66afe9}.selection-anchor-open:after{font-size:12px;content:\"\\0023F6\";right:10px;padding-bottom:3px}.selection-anchor-close{border-color:#ccc}.selection-anchor-close:after{font-size:12px;content:'\\0023F7';right:10px;padding-bottom:3px}.place-holder{color:#999}.selected-item{color:#495057}"]
581
- }] }
582
- ];
583
- /** @nocollapse */
584
- AnchorComponent.ctorParameters = () => [
585
- { type: DecimalPipe }
586
- ];
587
- AnchorComponent.propDecorators = {
588
- anchorRef: [{ type: ViewChild, args: ['anchor', { read: ElementRef },] }],
589
- placeHolder: [{ type: Input }],
590
- checkbox: [{ type: Input }],
591
- suffixText: [{ type: Input }],
592
- allowClear: [{ type: Input }],
593
- formatNumber: [{ type: Input }],
594
- selectedText: [{ type: Input }],
595
- openStatus: [{ type: Input }],
596
- disabled: [{ type: Input }],
597
- anchorClick: [{ type: Output }],
598
- clearanceClick: [{ type: Output }]
599
- };
600
-
601
- /**
602
- * @fileoverview added by tsickle
603
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
604
- */
605
- class DropdownComponent {
606
- constructor() {
607
- /**
608
- * bind to [checkbox], the flag for multi-select (checkbox) mode.
609
- */
610
- this.checkbox = false;
611
- /**
612
- * bind to [filterBox] for displaying the filter input text box
613
- */
614
- this.filterBox = false;
615
- /**
616
- * bind to [allowClear] for enabling the clearance (clearance is not avaiable when checkbox is enabled)
617
- */
618
- this.allowClear = true;
619
- /**
620
- * bind to [formatNumber] for show formatted number text
621
- */
622
- this.formatNumber = false;
623
- /**
624
- * for 2-way binding of [selectedValue]
625
- */
626
- this.selectedValueChange = new EventEmitter(true);
627
- /**
628
- * [selectionChange] event that will be triggered when changing of the selection
629
- */
630
- this.selectionChange = new EventEmitter(true);
631
- /**
632
- * [dropdownBlur] event that will be triggered with (blur) of dropdown
633
- */
634
- this.dropdownBlur = new EventEmitter();
635
- /**
636
- * [itemClick] event that will be triggered when clicking the option of dropdown
637
- */
638
- this.itemClick = new EventEmitter();
639
- /**
640
- * flag of clicking dropdown. It's to prevent (blur) of dropdown from happening in checkbox mode.
641
- */
642
- this._clickedItems = false;
643
- }
644
- /**
645
- * @param {?} changes
646
- * @return {?}
647
- */
648
- ngOnChanges(changes) {
649
- if (changes.items) {
650
- this._checkSelectionChange(changes.items.previousValue, changes.items.currentValue);
651
- }
652
- }
653
- /**
654
- * triggered when clicking the dropdown
655
- * @param {?} event
656
- * @return {?}
657
- */
658
- onItemsClick(event) {
659
- if (event.offsetX > (event.target.clientWidth + event.target.clientLeft)) {
660
- stopPropagationAndDefault(event);
661
- return;
662
- }
663
- // should ignore clicking on filter
664
- if (this.checkbox && event.target.type !== 'text') {
665
- this._clickedItems = true;
666
- }
667
- }
668
- /**
669
- * triggered when clicking the item
670
- * @param {?} currentItem
671
- * @return {?}
672
- */
673
- onItemClick(currentItem) {
674
- if (!this.checkbox) {
675
- this.selectedValue = this._getItemValue(currentItem); // currentItem.value != null ? currentItem.value : currentItem.text;
676
- clearAllSelection(this.items);
677
- // set the selection of current one
678
- currentItem.selected = true;
679
- this.itemClick.emit(currentItem);
680
- this._onSelectionChange(this.selectedValue);
681
- }
682
- }
683
- /**
684
- * triggers with (blur) event of filter input box
685
- * @param {?} event
686
- * @return {?}
687
- */
688
- onFilterTextBlur(event) {
689
- this.dropdownBlur.emit(event);
690
- }
691
- /**
692
- * triggers with (blur) event of dropdown
693
- * @param {?} event
694
- * @return {?}
695
- */
696
- onItemsBlur(event) {
697
- if (this.checkbox) {
698
- if (this._clickedItems) {
699
- // in checkbox mode, this blur event will be ignored when clicking the dropdown (check the checkbox)
700
- event.target.focus();
701
- this._clickedItems = false;
702
- return;
703
- }
704
- }
705
- this.dropdownBlur.emit(event);
706
- }
707
- /**
708
- * toggle the selection when checking status changed (in checkbox mode)
709
- * @param {?} item
710
- * @return {?}
711
- */
712
- toggleSelection(item) {
713
- item.selected = !item.selected;
714
- this.selectionChange.emit(this._getItemValue(item)); // item.value != null ? item.value : item.text);
715
- }
716
- /**
717
- * items values list after applying the filter
718
- * @return {?}
719
- */
720
- get itemsValues() {
721
- /** @type {?} */
722
- let filter;
723
- if (this.filterValue) {
724
- filter = this.filterValue.toUpperCase();
725
- }
726
- if (filter == null) {
727
- return this.items;
728
- }
729
- if (!this.items || this.items.length === 0) {
730
- return [];
731
- }
732
- if (hasGroup(this.items)) {
733
- /** @type {?} */
734
- const items = [];
735
- this.items.forEach(groupItem => {
736
- if (groupItem.group != null && groupItem.group.toString().toUpperCase().includes(filter)) {
737
- // if groupItem contains the filters, the groupItem needs to be displayed as well
738
- items.push(groupItem);
739
- }
740
- else {
741
- /** @type {?} */
742
- const filteredItems = groupItem.items.filter(item => item.text != null && item.text.toString().toUpperCase().includes(filter));
743
- if (filteredItems && filteredItems.length > 0) {
744
- items.push({ group: groupItem.group, items: filteredItems });
745
- }
746
- }
747
- });
748
- return items;
749
- }
750
- else {
751
- return this.items.filter(item => (item.text != null && item.text.toString().toUpperCase().includes(filter)));
752
- }
753
- }
754
- /**
755
- * options CSS class
756
- * @return {?}
757
- */
758
- get optionsClass() {
759
- if (this.filterBox && !this.checkbox) {
760
- return 'options with-filter';
761
- }
762
- else {
763
- return 'options no-filter';
764
- }
765
- }
766
- /**
767
- * get item value. Return text if value is not available
768
- * @private
769
- * @param {?} item
770
- * @return {?}
771
- */
772
- _getItemValue(item) {
773
- return item ? item.value != null ? item.value : item.text : undefined;
774
- }
775
- /**
776
- * selection changed, emits events: (selectedValueChange) and (selectionChange);
777
- * @private
778
- * @param {?} value
779
- * @return {?}
780
- */
781
- _onSelectionChange(value) {
782
- this.selectedValueChange.emit(value);
783
- this.selectionChange.emit(value);
784
- }
785
- /**
786
- * check whether the selection is changed. Emits relative events when if changed.
787
- * @private
788
- * @param {?} previousValue
789
- * @param {?} currentValue
790
- * @return {?}
791
- */
792
- _checkSelectionChange(previousValue, currentValue) {
793
- /** @type {?} */
794
- const curSelectedItem = getFirstSelectedItem(currentValue);
795
- /** @type {?} */
796
- const lastSelectedItem = getFirstSelectedItem(previousValue);
797
- /** @type {?} */
798
- const curSelectedItemId = curSelectedItem ? curSelectedItem.id : undefined;
799
- /** @type {?} */
800
- const lastSelectedItemId = lastSelectedItem ? lastSelectedItem.id : undefined;
801
- if (curSelectedItemId !== lastSelectedItemId && !this.checkbox) {
802
- this._onSelectionChange(this._getItemValue(curSelectedItem));
803
- }
804
- }
805
- }
806
- DropdownComponent.decorators = [
807
- { type: Component, args: [{
808
- selector: 'dropdown',
809
- template: `
810
- <span #dropdown class="dropdown" tabindex="3" (mousedown)="onItemsClick($event)" (blur)="onItemsBlur($event)" *ngIf="!disabled" >
811
- <input-filter #filterInput tabindex="4" *ngIf="filterBox && !checkbox" [(filterValue)]="filterValue" (inputFilterBlur)="onFilterTextBlur($event)"></input-filter>
812
- <span #selectionOptions [ngClass]="optionsClass">
813
- <ng-container *ngFor="let item of itemsValues" >
814
- <ng-container *ngIf="item && item.group">
815
- <group-item [item]="item"></group-item>
816
- <item *ngFor="let subItem of item.items" (itemClick)="onItemClick(subItem)" (checkStatusChange)="toggleSelection(subItem)"
817
- [item]="subItem" [checkbox]="checkbox" [formatNumber]="formatNumber" [suffixText]="suffixText">
818
- </item>
819
- </ng-container>
820
- <ng-container *ngIf="item && !item.group">
821
- <item (itemClick)="onItemClick(item)" (checkStatusChange)="toggleSelection(item)"
822
- [item]="item" [checkbox]="checkbox" [formatNumber]="formatNumber" [suffixText]="suffixText">
823
- </item>
824
- </ng-container>
825
- </ng-container>
826
- </span>
827
- </span>
828
- `,
829
- styles: ["*,:after,:before{font-size:inherit;font-weight:inherit;font-family:inherit;box-sizing:inherit;background:inherit}.dropdown{width:100%;padding:0;display:none;margin:0;border:1px solid #66afe9;border-top:none;border-bottom:none;border-top-right-radius:0;border-top-left-radius:0;box-sizing:border-box;position:relative;z-index:999}.dropdown:focus{outline:0}.dropdown .options{width:calc(100% + 2px);left:0;box-sizing:border-box;background:#fff;position:absolute;max-height:228px;overflow-y:auto;overflow-x:hidden;border:1px solid #66afe9;border-top:none;border-bottom-right-radius:4px;border-bottom-left-radius:4px;margin-left:-1px;margin-right:-1px}.dropdown .with-filter{top:32px}.dropdown .no-filter{top:0}"]
830
- }] }
831
- ];
832
- DropdownComponent.propDecorators = {
833
- dropdownRef: [{ type: ViewChild, args: ['dropdown', { read: ElementRef },] }],
834
- filterInputRef: [{ type: ViewChild, args: ['filterInput', { read: ElementRef },] }],
835
- placeHolder: [{ type: Input }],
836
- items: [{ type: Input }],
837
- checkbox: [{ type: Input }],
838
- selectedValue: [{ type: Input }],
839
- filterBox: [{ type: Input }],
840
- suffixText: [{ type: Input }],
841
- disabled: [{ type: Input }],
842
- allowClear: [{ type: Input }],
843
- formatNumber: [{ type: Input }],
844
- selectedValueChange: [{ type: Output }],
845
- selectionChange: [{ type: Output }],
846
- dropdownBlur: [{ type: Output }],
847
- itemClick: [{ type: Output }]
848
- };
849
-
850
- /**
851
- * @fileoverview added by tsickle
852
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
853
- */
854
- class DropdownListModule {
855
- }
856
- DropdownListModule.decorators = [
857
- { type: NgModule, args: [{
858
- declarations: [
859
- DropdownListComponent,
860
- ItemComponent,
861
- GroupItemComponent,
862
- InputFilterComponent,
863
- AnchorComponent,
864
- DropdownComponent
865
- ],
866
- exports: [DropdownListComponent],
867
- imports: [CommonModule, FormsModule],
868
- providers: [],
869
- bootstrap: [],
870
- },] }
871
- ];
872
-
873
- /**
874
- * @fileoverview added by tsickle
875
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
876
- */
877
-
878
- /**
879
- * @fileoverview added by tsickle
880
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
881
- */
882
-
883
- /**
884
- * @fileoverview added by tsickle
885
- * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
886
- */
887
-
888
- export { DropdownListComponent, DropdownListModule, AnchorComponent as ɵd, DropdownComponent as ɵe, InputFilterComponent as ɵc, GroupItemComponent as ɵb, ItemComponent as ɵa };
889
-
890
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRyb3Bkb3duLWxpc3QuanMubWFwIiwic291cmNlcyI6WyJuZzovL25neC1kcm9wZG93bi1saXN0L3NyYy9uZ3gtZHJvcGRvd24tbGlzdC91dGlscy91dGlsLnRzIiwibmc6Ly9uZ3gtZHJvcGRvd24tbGlzdC9zcmMvbmd4LWRyb3Bkb3duLWxpc3QvZHJvcGRvd24tbGlzdC5jb21wb25lbnQudHMiLCJuZzovL25neC1kcm9wZG93bi1saXN0L3NyYy9uZ3gtZHJvcGRvd24tbGlzdC9pdGVtL2l0ZW0uY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtZHJvcGRvd24tbGlzdC9zcmMvbmd4LWRyb3Bkb3duLWxpc3QvZ3JvdXAtaXRlbS9ncm91cC1pdGVtLmNvbXBvbmVudC50cyIsIm5nOi8vbmd4LWRyb3Bkb3duLWxpc3Qvc3JjL25neC1kcm9wZG93bi1saXN0L2ZpbHRlci9pbnB1dC1maWx0ZXIuY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtZHJvcGRvd24tbGlzdC9zcmMvbmd4LWRyb3Bkb3duLWxpc3QvYW5jaG9yL2FuY2hvci5jb21wb25lbnQudHMiLCJuZzovL25neC1kcm9wZG93bi1saXN0L3NyYy9uZ3gtZHJvcGRvd24tbGlzdC9kcm9wZG93bi9kcm9wZG93bi5jb21wb25lbnQudHMiLCJuZzovL25neC1kcm9wZG93bi1saXN0L3NyYy9uZ3gtZHJvcGRvd24tbGlzdC9kcm9wZG93bi1saXN0Lm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogY2hlY2sgd2hldGhlciB0aGUgcHJvdmlkZWQgaXRlbXMgY29udGFpbnMgZ3JvdXBcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYXNHcm91cChpdGVtcyk6IGJvb2xlYW4ge1xyXG4gIHJldHVybiBpdGVtcyA/IChpdGVtcy5maW5kKGl0ZW0gPT4gaXRlbS5ncm91cCkgIT0gbnVsbCkgOiBmYWxzZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIGNsZWFyIGFsbCBzZWxlY3Rpb25zIGZyb20gdGhlIHByb3ZpZGUgaXRlbXMuXHJcbiAqIEBwYXJhbSBpdGVtcyB0aGUgZHJvcGRvd24gaXRlbXMsIGNhbiBiZSBncm91cCBvciBpdGVtXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJBbGxTZWxlY3Rpb24oaXRlbXM6IGFueSk6IHZvaWQge1xyXG4gIGlmIChoYXNHcm91cChpdGVtcykpIHtcclxuICAgIGZvciAoY29uc3QgZ3JvdXBJdGVtIG9mIGl0ZW1zKSB7XHJcbiAgICAgIGlmIChncm91cEl0ZW0uaXRlbXMpIHtcclxuICAgICAgICBncm91cEl0ZW0uaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5zZWxlY3RlZCkuZm9yRWFjaChpdGVtID0+IGl0ZW0uc2VsZWN0ZWQgPSBmYWxzZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgLy8gY2xlYXIgdGhlIHNlbGVjdGlvbiBvZiBwcmV2aW91cyBzZWxlY3RlZCBpdGVtXHJcbiAgICBpdGVtcy5maWx0ZXIoaXRlbSA9PiBpdGVtLnNlbGVjdGVkKS5mb3JFYWNoKGl0ZW0gPT4gaXRlbS5zZWxlY3RlZCA9IGZhbHNlKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBzdG9wIGFsbCBwcm9wYWdhdGlvbiBhbmQgZGVmYXVsdCBhY3Rpb25zXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uQW5kRGVmYXVsdChldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG59XHJcblxyXG4vKipcclxuICogY2hlY2sgd2hldGhlciB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgbnVtYmVyIG9mIG5vdFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKHZhbHVlOiBhbnkpOiBib29sZWFuIHtcclxuICByZXR1cm4gISh2YWx1ZSA9PSBudWxsIHx8IGlzTmFOKHZhbHVlKSB8fCB2YWx1ZS5sZW5ndGggPT09IDApO1xyXG59XHJcblxyXG4vKipcclxuICogZ2V0IHRoZSBzZWxlY3RlZCBpdGVtIGZyb20gdGhlIGl0ZW1zIGxpc3QgKGluY2x1ZGluZyBpdGVtIGFuZCBncm91cClcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGaXJzdFNlbGVjdGVkSXRlbShpdGVtczogYW55KTogYW55IHtcclxuICBpZiAoIWl0ZW1zKSB7XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuICBsZXQgc2VsZWN0ZWRJdGVtO1xyXG4gIGlmIChoYXNHcm91cChpdGVtcykpIHtcclxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xyXG4gICAgICBzZWxlY3RlZEl0ZW0gPSBpdGVtLml0ZW1zID8gaXRlbS5pdGVtcy5maW5kKHN1Ykl0ZW0gPT4gc3ViSXRlbS5zZWxlY3RlZCkgOiB1bmRlZmluZWQ7XHJcbiAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBzZWxlY3RlZEl0ZW0gPSBpdGVtcyA/IGl0ZW1zLmZpbmQoaXRlbSA9PiBpdGVtLnNlbGVjdGVkKSA6IHVuZGVmaW5lZDtcclxuICB9XHJcbiAgcmV0dXJuIHNlbGVjdGVkSXRlbTtcclxufVxyXG4iLCJpbXBvcnQge0NvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtjbGVhckFsbFNlbGVjdGlvbiwgZ2V0Rmlyc3RTZWxlY3RlZEl0ZW0sIHN0b3BQcm9wYWdhdGlvbkFuZERlZmF1bHR9IGZyb20gJy4vdXRpbHMvdXRpbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1kcm9wZG93bi1saXN0JyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8c3BhbiBjbGFzcz1cIm5neC1zZWxlY3RcIj5cbiAgICAgICAgPGFuY2hvciAoYW5jaG9yQ2xpY2spPVwib25BbmNob3JDbGljaygkZXZlbnQpXCIgKGNsZWFyYW5jZUNsaWNrKT1cIm9uQ2xlYXJhbmNlQ2xpY2soJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgW2NoZWNrYm94XT1cIm11bHRpU2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICBbZm9ybWF0TnVtYmVyXT1cImZvcm1hdE51bWJlclwiXG4gICAgICAgICAgICAgICAgW3N1ZmZpeFRleHRdPVwic3VmZml4VGV4dFwiXG4gICAgICAgICAgICAgICAgW3BsYWNlSG9sZGVyXT1cInBsYWNlSG9sZGVyXCJcbiAgICAgICAgICAgICAgICBbYWxsb3dDbGVhcl09XCJhbGxvd0NsZWFyXCJcbiAgICAgICAgICAgICAgICBbb3BlblN0YXR1c109XCJkcm9wZG93blZpc2liaWxpdHlcIlxuICAgICAgICAgICAgICAgIFtzZWxlY3RlZFRleHRdPVwic2VsZWN0ZWRUZXh0XCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIj5cbiAgICAgICAgPC9hbmNob3I+XG4gICAgICAgIDxkcm9wZG93biAjZHJvcGRvd24gKGRyb3Bkb3duQmx1cikgPSBcIm9uSXRlbXNCbHVyKClcIiAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uU2VsZWN0aW9uQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgIFtpdGVtc109XCJpdGVtc1wiXG4gICAgICAgICAgICAgICAgW2NoZWNrYm94XT1cIm11bHRpU2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICBbZmlsdGVyQm94XT1cImZpbHRlckJveFwiXG4gICAgICAgICAgICAgICAgW2Zvcm1hdE51bWJlcl09XCJmb3JtYXROdW1iZXJcIlxuICAgICAgICAgICAgICAgIFtzdWZmaXhUZXh0XT1cInN1ZmZpeFRleHRcIlxuICAgICAgICAgICAgICAgIFsoc2VsZWN0ZWRWYWx1ZSldPVwic2VsZWN0ZWRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgKGl0ZW1DbGljaykgPSBcIm9uSXRlbUNsaWNrKClcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxuICAgICAgICA8L2Ryb3Bkb3duPlxuICAgIDwvc3Bhbj5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vZHJvcGRvd24tbGlzdC5jb21wb25lbnQuc2NzcyddLFxufSlcblxuZXhwb3J0IGNsYXNzIERyb3Bkb3duTGlzdENvbXBvbmVudCB7XG4gIEBWaWV3Q2hpbGQoJ2Ryb3Bkb3duJywgeyByZWFkOiBFbGVtZW50UmVmIH0pIGRyb3Bkb3duUmVmOiBFbGVtZW50UmVmO1xuXG4gIC8qKlxuICAgKiBiaW5kIHRvIFtwbGFjZUhvbGRlcl0gZm9yIGRpc3BsYXlpbmcgdGhlIHBsYWNlIGhvbGRlciBzdHJpbmcgb2YgdGhlIGFuY2hvci5cbiAgICovXG4gIEBJbnB1dCgpIHBsYWNlSG9sZGVyOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtpdGVtc10gZm9yIHRoZSBvcHRpb25zL2dyb3VwcyBpbiB0aGUgZHJvcGRvd25cbiAgICovXG4gIEBJbnB1dCgpIGl0ZW1zOiBhbnlbXTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW211bHRpU2VsZWN0aW9uXSwgdGhlIGZsYWcgZm9yIG11bHRpLXNlbGVjdCAoY2hlY2tib3gpIG1vZGUuXG4gICAqL1xuICBASW5wdXQoKSBtdWx0aVNlbGVjdGlvbiA9IGZhbHNlO1xuICAvKipcbiAgICogYmluZCB0byBbc2VsZWN0ZWRWYWx1ZV0gZm9yIHRoZSB2YWx1ZSBvZiB0aGUgc2VsZWN0ZWQgb3B0aW9uIGZyb20gZHJvcGRvd25cbiAgICovXG4gIEBJbnB1dCgpIHNlbGVjdGVkVmFsdWU6IGFueTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2ZpbHRlckJveF0gZm9yIGRpc3BsYXlpbmcgdGhlIGZpbHRlciBpbnB1dCB0ZXh0IGJveFxuICAgKi9cbiAgQElucHV0KCkgZmlsdGVyQm94ID0gZmFsc2U7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtzdWZmaXhUZXh0XSBmb3IgZGlzcGxheWluZyB0aGUgc3VmZml4IG9mIHRoZSBzZWxlY3RlZCB0ZXh0IG9mIGFuY2hvclxuICAgKi9cbiAgQElucHV0KCkgc3VmZml4VGV4dDogc3RyaW5nO1xuICAvKipcbiAgICogYmluZCB0byBbZGlzYWJsZWRdIGZvciBkaXNhYmxpbmcgdGhlIGRyb3Bkb3duXG4gICAqL1xuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbjtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2FsbG93Q2xlYXJdIGZvciBlbmFibGluZyB0aGUgY2xlYXJhbmNlIChjbGVhcmFuY2UgaXMgbm90IGF2YWlhYmxlIHdoZW4gY2hlY2tib3ggaXMgZW5hYmxlZClcbiAgICovXG4gIEBJbnB1dCgpIGFsbG93Q2xlYXIgPSB0cnVlO1xuICAvKipcbiAgICogYmluZCB0byBbZm9ybWF0TnVtYmVyXSBmb3Igc2hvdyBmb3JtYXR0ZWQgbnVtYmVyIHRleHRcbiAgICovXG4gIEBJbnB1dCgpIGZvcm1hdE51bWJlciA9IGZhbHNlO1xuICAvKipcbiAgICogZm9yIDItd2F5IGJpbmRpbmcgb2YgW3NlbGVjdGVkVmFsdWVdLCB1c2luZyBhc3luYyBldmVudCB0b1xuICAgKiBwcmV2ZW50IFwiRXhwcmVzc2lvbkNoYW5nZWRBZnRlckl0SGFzQmVlbkNoZWNrZWRFcnJvclwiLlxuICAgKi9cbiAgQE91dHB1dCgpIHNlbGVjdGVkVmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4odHJ1ZSk7XG4gIC8qKlxuICAgKiBbc2VsZWN0aW9uQ2hhbmdlXSBldmVudCB0aGF0IHdpbGwgYmUgdHJpZ2dlcmVkIHdoZW4gY2hhbmdpbmcgb2YgdGhlIHNlbGVjdGlvbi5cbiAgICogVXNpbmcgYXN5bmMgZXZlbnQgdG8gcHJldmVudCBcIkV4cHJlc3Npb25DaGFuZ2VkQWZ0ZXJJdEhhc0JlZW5DaGVja2VkRXJyb3JcIi5cbiAgICovXG4gIEBPdXRwdXQoKSBzZWxlY3Rpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4odHJ1ZSk7XG5cbiAgLyoqXG4gICAqIHZpc2liaWxpdHkgZmxhZyBvZiBkcm9wIGRvd25cbiAgICovXG4gIGRyb3Bkb3duVmlzaWJpbGl0eSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBjdXJyZW50IHNlbGVjdGVkIHRleHRcbiAgICovXG4gIGdldCBzZWxlY3RlZFRleHQoKTogYW55IHtcbiAgICBpZiAoIXRoaXMubXVsdGlTZWxlY3Rpb24pIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkSXRlbSA9IGdldEZpcnN0U2VsZWN0ZWRJdGVtKHRoaXMuaXRlbXMpO1xuICAgICAgcmV0dXJuIHNlbGVjdGVkSXRlbSA/IHNlbGVjdGVkSXRlbS50ZXh0IDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2l0aCAoc2VsZWN0aW9uQ2hhbmdlKSBldmVudCwgZW1pdHMgKHNlbGVjdGVkVmFsdWVDaGFuZ2UpIGFuZCAoc2VsZWN0aW9uQ2hhbmdlKVxuICAgKi9cbiAgb25TZWxlY3Rpb25DaGFuZ2UoZXZlbnQpIHtcbiAgICB0aGlzLnNlbGVjdGVkVmFsdWVDaGFuZ2UuZW1pdChldmVudCk7XG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlcmVkIHdpdGggKGFuY2hvckNsaWNrKSBldmVudCwgY29udHJvbGxpbmcgdGhlIFwib3BlblwiIGFuZCBcImNsb3NlXCIgb2YgdGhlIGRyb3Bkb3duXG4gICAqL1xuICBvbkFuY2hvckNsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICBzdG9wUHJvcGFnYXRpb25BbmREZWZhdWx0KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2lzU2VsZWN0aW9uT3BlbigpKSB7XG4gICAgICB0aGlzLl9oaWRlSXRlbUxpc3QoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2hvd0l0ZW1zTGlzdCgpO1xuICAgIH1cbiAgICBzdG9wUHJvcGFnYXRpb25BbmREZWZhdWx0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2l0aCAoaXRlbUNsaWNrKSBldmVudCwgY2xvc2VzIHRoZSBkcm9wZG93biBpbiBub24tY2hlY2tib3ggbW9kZVxuICAgKi9cbiAgb25JdGVtQ2xpY2soKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm11bHRpU2VsZWN0aW9uKSB7XG4gICAgICB0aGlzLl9oaWRlSXRlbUxpc3QoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlcmVkIHdpdGggKGNsZWFyYW5jZUNsaWNrKSBldmVudCwgY2xlYXJpbmcgYWxsIHNlbGVjdGlvbnNcbiAgICogYW5kIGVtaXRzIChzZWxlY3RlZFZhbHVlQ2hhbmdlKSBhbmQgKHNlbGVjdGlvbkNoYW5nZSkgZXZlbnQgZm9yIGVtcHR5IHZhbHVlXG4gICAqL1xuICBvbkNsZWFyYW5jZUNsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tdWx0aVNlbGVjdGlvbikge1xuICAgICAgdGhpcy5zZWxlY3RlZFZhbHVlID0gdm9pZCAwO1xuICAgICAgdGhpcy5zZWxlY3RlZFZhbHVlQ2hhbmdlLmVtaXQodW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQodW5kZWZpbmVkKTtcbiAgICAgIGNsZWFyQWxsU2VsZWN0aW9uKHRoaXMuaXRlbXMpO1xuICAgIH1cbiAgICBzdG9wUHJvcGFnYXRpb25BbmREZWZhdWx0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2l0aCAoZHJvcGRvd25CbHVyKSBldmVudCwgY2xvc2VzIHRoZSBkcm9wZG93blxuICAgKi9cbiAgb25JdGVtc0JsdXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2lzU2VsZWN0aW9uT3BlbigpKSB7XG4gICAgICB0aGlzLl9oaWRlSXRlbUxpc3QoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogY2xvc2UgdGhlIGRyb3Bkb3duXG4gICAqL1xuICBwcml2YXRlIF9oaWRlSXRlbUxpc3QoKTogdm9pZCB7XG4gICAgLy8gaGlkZSB0aGUgZHJvcGRvd24gZWxlbWVudCAoaGFzIHNvbWUgcHJvYmxlbSBmb3IgdXNpbmcgQ1NTIGRpcmVjdGx5LCB1c2luZyB0aGlzIGFzIGEgd29ya2Fyb3VuZClcbiAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgndmlzaWJsZScpO1xuICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMuZHJvcGRvd25WaXNpYmlsaXR5ID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogb3BlbiB0aGUgZHJvcGRvd25cbiAgICovXG4gIHByaXZhdGUgX3Nob3dJdGVtc0xpc3QoKTogdm9pZCB7XG4gICAgLy8gZGlzcGxheSB0aGUgZHJvcGRvd24gZWxlbWVudCAoaGFzIHNvbWUgcHJvYmxlbSBmb3IgdXNpbmcgQ1NTIGRpcmVjdGx5LCB1c2luZyB0aGlzIGFzIGEgd29ya2Fyb3VuZClcbiAgICB0aGlzLl9kcm9wZG93bkVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndmlzaWJsZScpO1xuICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgIHRoaXMuZHJvcGRvd25WaXNpYmlsaXR5ID0gdHJ1ZTtcblxuICAgIC8vIHNjcm9sbGluZyB0byB0aGUgc2VsZWN0ZWQgaXRlbVxuICAgIGlmICh0aGlzLl9zZWxlY3RlZEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkRWxlbWVudC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnaW5zdGFudCcsIGJsb2NrOiAnY2VudGVyJyB9KTtcbiAgICB9XG5cbiAgICAvLyBzZXR0aW5nIHRoZSBmb2N1c1xuICAgIGlmICh0aGlzLmZpbHRlckJveCAmJiAhdGhpcy5tdWx0aVNlbGVjdGlvbikge1xuICAgICAgdGhpcy5fZmlsdGVySW5wdXRFbGVtZW50LmZvY3VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2Ryb3Bkb3duRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB2aXNpYmlsaXR5IHN0YXR1cyBvZiBkcm9wZG93blxuICAgKi9cbiAgcHJpdmF0ZSBfaXNTZWxlY3Rpb25PcGVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRyb3Bkb3duVmlzaWJpbGl0eTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHJlYWwgZHJvcGRvd24gZWxlbWVudCAoZm9yIGZvY3VzaW5nIGFuZCB2aXNpYmlsaXR5IGNvbnRyb2xsaW5nKSwgdGhlIDxzcGFuPiBub3QgdGhlIDxkcm9wZG93bj5cbiAgICovXG4gIHByaXZhdGUgZ2V0IF9kcm9wZG93bkVsZW1lbnQoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kcm9wZG93blJlZiA/IHRoaXMuZHJvcGRvd25SZWYubmF0aXZlRWxlbWVudCA/IHRoaXMuZHJvcGRvd25SZWYubmF0aXZlRWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCA6IG51bGwgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgcmVhbCBmaWx0ZXIgZWxlbWVudCAoZm9yIGZvY3VzaW5nKSwgdGhlIDxpbnB1dD4gbm90IHRoZSA8aW5wdXQtZmlsdGVyPlxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgX2ZpbHRlcklucHV0RWxlbWVudCgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLl9kcm9wZG93bkVsZW1lbnQgP1xuICAgICAgdGhpcy5fZHJvcGRvd25FbGVtZW50LmZpcnN0RWxlbWVudENoaWxkID8gdGhpcy5fZHJvcGRvd25FbGVtZW50LmZpcnN0RWxlbWVudENoaWxkLmZpcnN0RWxlbWVudENoaWxkIDogbnVsbCA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBIVE1MRWxlbWVudCBvZiBzZWxlY3RlZCBpdGVtLCBmb3IgZG9pbmcgKHNjcm9sbEludG9WaWV3KSBzY3JvbGxpbmcgdG8gdGhlIHNlbGVjdGVkIGl0ZW1cbiAgICovXG4gIHByaXZhdGUgZ2V0IF9zZWxlY3RlZEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgIGNvbnN0IHNlbGVjdGVkSXRlbSA9IGdldEZpcnN0U2VsZWN0ZWRJdGVtKHRoaXMuaXRlbXMpO1xuICAgIHJldHVybiBzZWxlY3RlZEl0ZW0gPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzZWxlY3RlZEl0ZW0uaWQpIGFzIEhUTUxFbGVtZW50IDogdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQge0NvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7U2VsZWN0aW9uSXRlbX0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHtpc051bWJlcn0gZnJvbSAnLi4vdXRpbHMvdXRpbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2l0ZW0nLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxsYWJlbCBbY2xhc3MuY29udGFpbmVyLWNoZWNrYm94XT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgW2NsYXNzLmNvbnRhaW5lci1zZWxlY3Rpb25dPVwiIWNoZWNrYm94ICYmICFpdGVtLnNlbGVjdGVkXCJcbiAgICAgICAgICAgW2NsYXNzLmNvbnRhaW5lci1zZWxlY3Rpb24tc2VsZWN0ZWRdPVwiIWNoZWNrYm94ICYmIGl0ZW0uc2VsZWN0ZWRcIlxuICAgICAgICAgICBbaWRdPVwiaXRlbS5pZFwiIChtb3VzZWRvd24pPVwib25JdGVtQ2xpY2soaXRlbSlcIj5cbiAgICAgIHt7bmVlZEZvcm1hdE51bWJlcihpdGVtLnRleHQpPyAoaXRlbS50ZXh0IHwgbnVtYmVyOicxLjAtMicpIDogaXRlbS50ZXh0fX17e3N1ZmZpeFRleHQ/IHN1ZmZpeFRleHQgOiAnJ319XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hlY2tib3hcIj5cbiAgICAgICAgPGlucHV0IHR5cGU9J2NoZWNrYm94JyBbaWRdPVwiJ2NoZWNrYm94LScraXRlbS50ZXh0XCIgKGNoYW5nZSk9XCJvbkNoZWNrU3RhdHVzQ2hhbmdlKGl0ZW0pXCIgW2NoZWNrZWRdPVwiaXRlbS5zZWxlY3RlZFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImNoZWNrbWFya1wiIFtpZF09XCInY2hlY2ttYXJrLScraXRlbS50ZXh0XCI+PC9zcGFuPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9sYWJlbD5gLFxuICBzdHlsZVVybHM6IFsnLi9pdGVtLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5cbmV4cG9ydCBjbGFzcyBJdGVtQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2NoZWNrYm94XSwgdGhlIGZsYWcgb2YgY2hlY2tib3ggbW9kZVxuICAgKi9cbiAgQElucHV0KCkgY2hlY2tib3g6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtpdGVtXSwgdGhlIGRyb3Bkb3duIG9wdGlvbiBpdGVtXG4gICAqL1xuICBASW5wdXQoKSBpdGVtOiBTZWxlY3Rpb25JdGVtO1xuICAvKipcbiAgICogYmluZCB0byBbZm9ybWF0TnVtYmVyXSwgdGhlIGZsYWcgZm9yIGZvcm1hdHRpbmcgdGhlIG51bWJlclxuICAgKi9cbiAgQElucHV0KCkgZm9ybWF0TnVtYmVyID0gZmFsc2U7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtzdWZmaXhUZXh0XSwgdGhlIHN1ZmZpeFRleHQgdGhhdCB3aWxsIGJlIGRpc3BsYXllZCBpbiB0aGUgZHJvcGRvd25cbiAgICovXG4gIEBJbnB1dCgpIHN1ZmZpeFRleHQ6IHN0cmluZztcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2l0ZW1DbGlja10gZXZlbnQsIHRyaWdnZXJzIHdoZW4gY2xpY2tpbmcgdGhlIGl0ZW0gb2YgZHJvcGRvd25cbiAgICovXG4gIEBPdXRwdXQoKSBpdGVtQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2NoZWNrU3RhdHVzQ2hhbmdlXSBldmVudCwgdHJpZ2dlcnMgd2hlbiBjaGVjayBzdGF0dXMgaXMgY2hhbmdlZCBpbiBjaGVja2JveCBtb2RlLlxuICAgKi9cbiAgQE91dHB1dCgpIGNoZWNrU3RhdHVzQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIGNoZWNrIHdoZXRoZXIgbmVlZHMgdG8gZm9ybWF0IG51bWJlciBmb3IgdGhlIHByb3ZpZGVkIHRleHRcbiAgICovXG4gIG5lZWRGb3JtYXROdW1iZXIodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc051bWJlcih2YWx1ZSkgJiYgdGhpcy5mb3JtYXROdW1iZXI7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlcmVkIHdoZW4gY2xpY2tpbmcgdGhlIGl0ZW0sIGVtaXRzIHRoZSBbaXRlbUNsaWNrXSBldmVudFxuICAgKi9cbiAgb25JdGVtQ2xpY2soaXRlbSkge1xuICAgIHRoaXMuaXRlbUNsaWNrLmVtaXQoaXRlbSk7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlcmVkIHdoZW4gY2hlY2tpbmcgc3RhdHVzIGNoYW5nZWQgaW4gY2hlY2tib3ggbW9kZSwgZW1pdHMgdGhlIFtjaGVja1N0YXR1c0NoYW5nZV0gZXZlbnRcbiAgICovXG4gIG9uQ2hlY2tTdGF0dXNDaGFuZ2UoaXRlbSkge1xuICAgIHRoaXMuY2hlY2tTdGF0dXNDaGFuZ2UuZW1pdChpdGVtKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtDb21wb25lbnQsIElucHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7U2VsZWN0aW9uR3JvdXBJdGVtc30gZnJvbSAnLi4vdHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdncm91cC1pdGVtJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8bGFiZWwgY2xhc3M9XCJkcm9wZG93bi1pdGVtIGRyb3Bkb3duLWl0ZW0tZ3JvdXBcIiAobW91c2Vkb3duKT1cIm9uSXRlbUdyb3VwQ2xpY2soJGV2ZW50KVwiPnt7aXRlbS5ncm91cH19PC9sYWJlbD5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vZ3JvdXAtaXRlbS5jb21wb25lbnQuc2NzcyddXG59KVxuXG5leHBvcnQgY2xhc3MgR3JvdXBJdGVtQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2l0ZW1dLCB0aGUgZ3JvdXAgaXRlbSBvZiBkcm9wZG93blxuICAgKi9cbiAgQElucHV0KCkgaXRlbTogU2VsZWN0aW9uR3JvdXBJdGVtcztcblxuICAvKipcbiAgICogcHJldmVudCBhbGwgY2xpY2tpbmcgZXZlbnQgZnJvbSBoYXBwZW5pbmdcbiAgICovXG4gIG9uSXRlbUdyb3VwQ2xpY2soZXZlbnQpIHtcbiAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG59XG4iLCJpbXBvcnQge0NvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaW5wdXQtZmlsdGVyJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZpbHRlci1ib3hcIiBbKG5nTW9kZWwpXT1cImZpbHRlclZhbHVlXCIgKGlucHV0KT1cIm9uQ2hhbmdlKClcIiAoYmx1cik9XCJvbkZpbHRlclRleHRCbHVyKCRldmVudClcIj5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vaW5wdXQtZmlsdGVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5cbmV4cG9ydCBjbGFzcyBJbnB1dEZpbHRlckNvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtmaWx0ZXJWYWx1ZV0sIHRoZSB2YWx1ZSBvZiB0aGUgZmlsdGVyXG4gICAqL1xuICBASW5wdXQoKSBmaWx0ZXJWYWx1ZTogc3RyaW5nO1xuICAvKipcbiAgICogYmluZCB0byBbaW5wdXRGaWx0ZXJCbHVyXSwgZW1pdHMgd2l0aCAoYmx1cikgb2YgZmlsdGVyIGlucHV0IGJveFxuICAgKi9cbiAgQE91dHB1dCgpIGlucHV0RmlsdGVyQmx1ciA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAvKipcbiAgICogYmluZCB0byBbZmlsdGVyVmFsdWVDaGFuZ2VdLCBmb3IgMi13YXkgYmluZGluZyBvZiBmaWx0ZXJWYWx1ZVxuICAgKi9cbiAgQE91dHB1dCgpIGZpbHRlclZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJzIHdpdGggKGJsdXIpIGV2ZW50LCBlbWl0cyB0aGUgKGlucHV0RmlsdGVyQmx1cikgZXZlbnRcbiAgICovXG4gIG9uRmlsdGVyVGV4dEJsdXIoZXZlbnQpIHtcbiAgICB0aGlzLmlucHV0RmlsdGVyQmx1ci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VycyB3aXRoIChpbnB1dCkgZXZlbnQsIGVtaXRzIHRoZSAoZmlsdGVyVmFsdWVDaGFuZ2UpIGV2ZW50IGZvciAyLXdheSBiaW5kaW5nIG9mIGZpbHRlclZhbHVlXG4gICAqL1xuICBvbkNoYW5nZSgpIHtcbiAgICB0aGlzLmZpbHRlclZhbHVlQ2hhbmdlLmVtaXQodGhpcy5maWx0ZXJWYWx1ZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge3N0b3BQcm9wYWdhdGlvbkFuZERlZmF1bHQsIGlzTnVtYmVyfSBmcm9tICcuLi91dGlscy91dGlsJztcbmltcG9ydCB7RGVjaW1hbFBpcGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FuY2hvcicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPHNwYW4gI2FuY2hvciB0YWJpbmRleD1cIjJcIiBbbmdDbGFzc109XCJhbmNob3JDbGFzc1wiICh3aW5kb3c6cmVzaXplKT1cIm9uUmVzaXplKClcIlxuICAgICAgICAgIChtb3VzZWRvd24pPVwib25BbmNob3JDbGljaygkZXZlbnQpXCIgKGJsdXIpPVwib25BbmNob3JCbHVyKCRldmVudClcIj4ge3thbmNob3JEaXNwbGF5VGV4dH19XG4gICAgICA8c3BhbiAjc2VsZWN0aW9uQ2xlYXJhbmNlIGNsYXNzPVwic2VsZWN0aW9uLWNsZWFyYW5jZVwiIChtb3VzZWRvd24pPVwib25DbGVhcmFuY2VDbGljaygkZXZlbnQpXCIgKm5nSWY9XCJzaG93Q2xlYXJhbmNlRmxhZ1wiPiZ0aW1lczs8L3NwYW4+XG4gICAgPC9zcGFuPlxuICBgLFxuICBzdHlsZVVybHM6IFsnLi9hbmNob3IuY29tcG9uZW50LnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbRGVjaW1hbFBpcGVdXG59KVxuXG5leHBvcnQgY2xhc3MgQW5jaG9yQ29tcG9uZW50IHtcbiAgLyoqXG4gICAqIENoaWxkIGVsZW1lbnQgcmVmZXJlbmNlIG9mIGFuY2hvclxuICAgKi9cbiAgQFZpZXdDaGlsZCgnYW5jaG9yJywgeyByZWFkOiBFbGVtZW50UmVmIH0pIGFuY2hvclJlZjogRWxlbWVudFJlZjtcblxuICAvKipcbiAgICogYmluZCB0byBbcGxhY2VIb2xkZXJdIGZvciBkaXNwbGF5aW5nIHRoZSBwbGFjZSBob2xkZXIgc3RyaW5nIG9mIHRoZSBhbmNob3IuXG4gICAqL1xuICBASW5wdXQoKSBwbGFjZUhvbGRlcjogc3RyaW5nO1xuICAvKipcbiAgICogYmluZCB0byBbY2hlY2tib3hdIGZvciBjaGVja2luZyB3aGV0aGVyIHRoZSBjbGVhcmFuY2UgZmxhZyBzaG91bGQgYmUgc2hvd24gb3Igbm90LlxuICAgKi9cbiAgQElucHV0KCkgY2hlY2tib3ggPSBmYWxzZTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW3N1ZmZpeFRleHRdIGZvciBkaXNwbGF5aW5nIHRoZSBzdWZmaXggb2YgdGhlIHNlbGVjdGVkIHRleHQgb2YgYW5jaG9yXG4gICAqL1xuICBASW5wdXQoKSBzdWZmaXhUZXh0OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFthbGxvd0NsZWFyXSBmb3IgZW5hYmxpbmcgdGhlIGNsZWFyYW5jZSAoY2xlYXJhbmNlIGlzIG5vdCBhdmFpYWJsZSB3aGVuIGNoZWNrYm94IGlzIGVuYWJsZWQpXG4gICAqL1xuICBASW5wdXQoKSBhbGxvd0NsZWFyID0gdHJ1ZTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2Zvcm1hdE51bWJlcl0gZm9yIHNob3cgZm9ybWF0dGVkIG51bWJlciB0ZXh0XG4gICAqL1xuICBASW5wdXQoKSBmb3JtYXROdW1iZXI6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtzZWxlY3RlZFRleHRdIGZvciBkaXNwbGF5aW5nIHRoZSBzZWxlY3RlZCB0ZXh0IG9uIGFuY2hvclxuICAgKi9cbiAgQElucHV0KCkgc2VsZWN0ZWRUZXh0OiBhbnk7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtvcGVuU3RhdHVzXSwgaXQncyB0aGUgdmlzaWJpbGl0eSBzdGF0dXMgb2YgZHJvcGRvd24sIGZvciBzaG93aW5nIHRoZSBhcnJvdyBvbiBhbmNob3JcbiAgICovXG4gIEBJbnB1dCgpIG9wZW5TdGF0dXMgPSBmYWxzZTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2Rpc2FibGVkXSBmb3IgZGlzYWJsaW5nIHRoZSBhbmNob3JcbiAgICovXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIC8qKlxuICAgKiB3aWxsIGJlIHRyaWdnZXJlZCB3aGVuIGNsaWNraW5nIHRoZSBhbmNob3JcbiAgICovXG4gIEBPdXRwdXQoKSBhbmNob3JDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAvKipcbiAgICogd2lsbCBiZSB0cmlnZ2VyZWQgd2hlbiBjbGlja2luZyB0aGUgY2xlYXJhbmNlXG4gICAqL1xuICBAT3V0cHV0KCkgY2xlYXJhbmNlQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICAvKipcbiAgICogbGVuZ3RoIG9mIGFuY2hvciBlbGVtZW50LCB1c2VkIGZvciBjYWxjdWxhdGUgdGhlIHN0cmluZyBsZW5ndGggb2YgdGhlIGFuY2hvciBkaXNwbGF5ZWQgdGV4dC5cbiAgICovXG4gIGFuY2hvckxlbmd0aDogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2RlY2ltYWxQaXBlOiBEZWNpbWFsUGlwZSkge31cblxuICAvKipcbiAgICogZmxhZyBmb3Igc2hvd2luZyB0aGUgY2xlYXJhbmNlIGZsYWdcbiAgICovXG4gIGdldCBzaG93Q2xlYXJhbmNlRmxhZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuY2hlY2tib3ggJiYgdGhpcy5zZWxlY3RlZFRleHQgJiYgdGhpcy5hbGxvd0NsZWFyO1xuICB9XG5cbiAgLyoqXG4gICAqIHRoZSB0ZXh0IGRpc3BsYXlzIG9uIGFuY2hvclxuICAgKi9cbiAgZ2V0IGFuY2hvckRpc3BsYXlUZXh0KCk6IHN0cmluZyB7XG4gICAgbGV0IGFuY2hvckRpc3BsYXlUZXh0ID0gIHRoaXMuc2VsZWN0ZWRUZXh0ID8gKHRoaXMuZm9ybWF0TnVtYmVyID8gKGlzTnVtYmVyKHRoaXMuc2VsZWN0ZWRUZXh0KSA/XG4gICAgICB0aGlzLl9kZWNpbWFsUGlwZS50cmFuc2Zvcm0odGhpcy5zZWxlY3RlZFRleHQsICcxLjAtMicpIDogdGhpcy5zZWxlY3RlZFRleHQpIDpcbiAgICAgIHRoaXMuc2VsZWN0ZWRUZXh0KSArICh0aGlzLnN1ZmZpeFRleHQgPyB0aGlzLnN1ZmZpeFRleHQgOiAnJykgOiB0aGlzLnBsYWNlSG9sZGVyO1xuXG4gICAgbGV0IGNoYXJMZW5ndGggPSAxO1xuICAgIGlmICh0aGlzLnNob3dDbGVhcmFuY2VGbGFnICYmIHRoaXMuYW5jaG9yTGVuZ3RoID4gMCkge1xuICAgICAgY2hhckxlbmd0aCA9IE1hdGguZmxvb3IoKHRoaXMuYW5jaG9yTGVuZ3RoIC0gNTApIC8gNyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoYXJMZW5ndGggPSBNYXRoLmZsb29yKCh0aGlzLmFuY2hvckxlbmd0aCAtIDUwKSAvIDcpO1xuICAgIH1cblxuICAgIGlmIChhbmNob3JEaXNwbGF5VGV4dC5sZW5ndGggPiBjaGFyTGVuZ3RoKSB7XG4gICAgICBhbmNob3JEaXNwbGF5VGV4dCA9IGFuY2hvckRpc3BsYXlUZXh0LnNsaWNlKDAsIGNoYXJMZW5ndGggLSAyKSArICcuLi4nO1xuICAgIH1cbiAgICByZXR1cm4gYW5jaG9yRGlzcGxheVRleHQ7XG4gIH1cblxuICAvKipcbiAgICogYW5jaG9yIENTUyBjbGFzc1xuICAgKi9cbiAgZ2V0IGFuY2hvckNsYXNzKCk6IHN0cmluZyB7XG4gICAgbGV0IGFuY2hvckNsYXNzU3RhdHVzUGFydDtcbiAgICBsZXQgYW5jaG9yQ2xhc3NGb250Q29sb3I7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIGFuY2hvckNsYXNzU3RhdHVzUGFydCA9ICdzZWxlY3Rpb24tYW5jaG9yLWRpc2FibGVkJztcbiAgICAgIGFuY2hvckNsYXNzRm9udENvbG9yID0gJ3BsYWNlLWhvbGRlcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm9wZW5TdGF0dXMpIHtcbiAgICAgICAgYW5jaG9yQ2xhc3NTdGF0dXNQYXJ0ID0gJ3NlbGVjdGlvbi1hbmNob3Itb3Blbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbmNob3JDbGFzc1N0YXR1c1BhcnQgPSAnc2VsZWN0aW9uLWFuY2hvci1jbG9zZSc7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFRleHQgIT0gbnVsbCkge1xuICAgICAgICBhbmNob3JDbGFzc0ZvbnRDb2xvciA9ICdzZWxlY3RlZC1pdGVtJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFuY2hvckNsYXNzRm9udENvbG9yID0gJ3BsYWNlLWhvbGRlcic7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBgJHthbmNob3JDbGFzc1N0YXR1c1BhcnR9ICR7YW5jaG9yQ2xhc3NGb250Q29sb3J9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2hlbiBjbGlja2luZyB0aGUgYW5jaG9yXG4gICAqL1xuICBvbkFuY2hvckNsaWNrKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuYW5jaG9yQ2xpY2suZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlcmVkIHdpdGggKGJsdXIpIG9mIGFuY2hvclxuICAgKi9cbiAgb25BbmNob3JCbHVyKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIHN0b3BQcm9wYWdhdGlvbkFuZERlZmF1bHQoZXZlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJlZCB3aGVuIGNsaWNraW5nIHRoZSBjbGVhcmFuY2VcbiAgICovXG4gIG9uQ2xlYXJhbmNlQ2xpY2soZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5jbGVhcmFuY2VDbGljay5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2hlbiByZXNpemluZywgZ2V0IHRoZSBjbGllbnRXaWR0aCBvZiBhbmNob3JcbiAgICovXG4gIG9uUmVzaXplKCkge1xuICAgIHRoaXMuYW5jaG9yTGVuZ3RoID0gdGhpcy5hbmNob3JSZWYgPyB0aGlzLmFuY2hvclJlZi5uYXRpdmVFbGVtZW50ID8gdGhpcy5hbmNob3JSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aCA6IDAgOiAwO1xuICB9XG59XG4iLCJpbXBvcnQge0NvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge2NsZWFyQWxsU2VsZWN0aW9uLCBnZXRGaXJzdFNlbGVjdGVkSXRlbSwgaGFzR3JvdXAsIHN0b3BQcm9wYWdhdGlvbkFuZERlZmF1bHR9IGZyb20gJy4uL3V0aWxzL3V0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkcm9wZG93bicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPHNwYW4gI2Ryb3Bkb3duIGNsYXNzPVwiZHJvcGRvd25cIiB0YWJpbmRleD1cIjNcIiAobW91c2Vkb3duKT1cIm9uSXRlbXNDbGljaygkZXZlbnQpXCIgKGJsdXIpPVwib25JdGVtc0JsdXIoJGV2ZW50KVwiICpuZ0lmPVwiIWRpc2FibGVkXCIgPlxuICAgICAgPGlucHV0LWZpbHRlciAjZmlsdGVySW5wdXQgdGFiaW5kZXg9XCI0XCIgKm5nSWY9XCJmaWx0ZXJCb3ggJiYgIWNoZWNrYm94XCIgWyhmaWx0ZXJWYWx1ZSldPVwiZmlsdGVyVmFsdWVcIiAoaW5wdXRGaWx0ZXJCbHVyKT1cIm9uRmlsdGVyVGV4dEJsdXIoJGV2ZW50KVwiPjwvaW5wdXQtZmlsdGVyPlxuICAgICAgPHNwYW4gI3NlbGVjdGlvbk9wdGlvbnMgW25nQ2xhc3NdPVwib3B0aW9uc0NsYXNzXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNWYWx1ZXNcIiA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0gJiYgaXRlbS5ncm91cFwiPlxuICAgICAgICAgICAgPGdyb3VwLWl0ZW0gW2l0ZW1dPVwiaXRlbVwiPjwvZ3JvdXAtaXRlbT5cbiAgICAgICAgICAgIDxpdGVtICpuZ0Zvcj1cImxldCBzdWJJdGVtIG9mIGl0ZW0uaXRlbXNcIiAoaXRlbUNsaWNrKT1cIm9uSXRlbUNsaWNrKHN1Ykl0ZW0pXCIgKGNoZWNrU3RhdHVzQ2hhbmdlKT1cInRvZ2dsZVNlbGVjdGlvbihzdWJJdGVtKVwiXG4gICAgICAgICAgICAgICAgICBbaXRlbV09XCJzdWJJdGVtXCIgW2NoZWNrYm94XT1cImNoZWNrYm94XCIgW2Zvcm1hdE51bWJlcl09XCJmb3JtYXROdW1iZXJcIiBbc3VmZml4VGV4dF09XCJzdWZmaXhUZXh0XCI+XG4gICAgICAgICAgICA8L2l0ZW0+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0gJiYgIWl0ZW0uZ3JvdXBcIj5cbiAgICAgICAgICAgIDxpdGVtIChpdGVtQ2xpY2spPVwib25JdGVtQ2xpY2soaXRlbSlcIiAoY2hlY2tTdGF0dXNDaGFuZ2UpPVwidG9nZ2xlU2VsZWN0aW9uKGl0ZW0pXCJcbiAgICAgICAgICAgICAgICAgIFtpdGVtXT1cIml0ZW1cIiBbY2hlY2tib3hdPVwiY2hlY2tib3hcIiBbZm9ybWF0TnVtYmVyXT1cImZvcm1hdE51bWJlclwiIFtzdWZmaXhUZXh0XT1cInN1ZmZpeFRleHRcIj5cbiAgICAgICAgICAgIDwvaXRlbT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L3NwYW4+XG4gICAgPC9zcGFuPlxuICBgLFxuICBzdHlsZVVybHM6IFsnLi9kcm9wZG93bi5jb21wb25lbnQuc2NzcyddXG59KVxuXG5leHBvcnQgY2xhc3MgRHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICAvKipcbiAgICogQ2hpbGQgZWxlbWVudCByZWZlcmVuY2Ugb2YgZHJvcGRvd25cbiAgICovXG4gIEBWaWV3Q2hpbGQoJ2Ryb3Bkb3duJywgeyByZWFkOiBFbGVtZW50UmVmIH0pIGRyb3Bkb3duUmVmOiBFbGVtZW50UmVmO1xuICAvKipcbiAgICogQ2hpbGQgZWxlbWVudCByZWZlcmVuY2Ugb2YgZmlsdGVyIGlucHV0IHRleHRcbiAgICovXG4gIEBWaWV3Q2hpbGQoJ2ZpbHRlcklucHV0JywgeyByZWFkOiBFbGVtZW50UmVmIH0pIGZpbHRlcklucHV0UmVmOiBFbGVtZW50UmVmO1xuICAvKipcbiAgICogYmluZCB0byBbcGxhY2VIb2xkZXJdIGZvciBkaXNwbGF5aW5nIHRoZSBwbGFjZSBob2xkZXIgc3RyaW5nIG9mIHRoZSBhbmNob3IuXG4gICAqL1xuICBASW5wdXQoKSBwbGFjZUhvbGRlcjogc3RyaW5nO1xuICAvKipcbiAgICogYmluZCB0byBbaXRlbXNdIGZvciB0aGUgb3B0aW9ucy9ncm91cHMgaW4gdGhlIGRyb3Bkb3duXG4gICAqL1xuICBASW5wdXQoKSBpdGVtczogYW55W107XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtjaGVja2JveF0sIHRoZSBmbGFnIGZvciBtdWx0aS1zZWxlY3QgKGNoZWNrYm94KSBtb2RlLlxuICAgKi9cbiAgQElucHV0KCkgY2hlY2tib3ggPSBmYWxzZTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW3NlbGVjdGVkVmFsdWVdIGZvciB0aGUgdmFsdWUgb2YgdGhlIHNlbGVjdGVkIG9wdGlvbiBmcm9tIGRyb3Bkb3duXG4gICAqL1xuICBASW5wdXQoKSBzZWxlY3RlZFZhbHVlOiBhbnk7XG4gIC8qKlxuICAgKiBiaW5kIHRvIFtmaWx0ZXJCb3hdIGZvciBkaXNwbGF5aW5nIHRoZSBmaWx0ZXIgaW5wdXQgdGV4dCBib3hcbiAgICovXG4gIEBJbnB1dCgpIGZpbHRlckJveCA9IGZhbHNlO1xuICAvKipcbiAgICogYmluZCB0byBbc3VmZml4VGV4dF0gZm9yIGRpc3BsYXlpbmcgdGhlIHN1ZmZpeCBvZiB0aGUgc2VsZWN0ZWQgdGV4dCBvZiBhbmNob3JcbiAgICovXG4gIEBJbnB1dCgpIHN1ZmZpeFRleHQ6IHN0cmluZztcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2Rpc2FibGVkXSBmb3IgZGlzYWJsaW5nIHRoZSBkcm9wZG93blxuICAgKi9cbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBiaW5kIHRvIFthbGxvd0NsZWFyXSBmb3IgZW5hYmxpbmcgdGhlIGNsZWFyYW5jZSAoY2xlYXJhbmNlIGlzIG5vdCBhdmFpYWJsZSB3aGVuIGNoZWNrYm94IGlzIGVuYWJsZWQpXG4gICAqL1xuICBASW5wdXQoKSBhbGxvd0NsZWFyID0gdHJ1ZTtcbiAgLyoqXG4gICAqIGJpbmQgdG8gW2Zvcm1hdE51bWJlcl0gZm9yIHNob3cgZm9ybWF0dGVkIG51bWJlciB0ZXh0XG4gICAqL1xuICBASW5wdXQoKSBmb3JtYXROdW1iZXIgPSBmYWxzZTtcbiAgLyoqXG4gICAqIGZvciAyLXdheSBiaW5kaW5nIG9mIFtzZWxlY3RlZFZhbHVlXVxuICAgKi9cbiAgQE91dHB1dCgpIHNlbGVjdGVkVmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4odHJ1ZSk7XG4gIC8qKlxuICAgKiBbc2VsZWN0aW9uQ2hhbmdlXSBldmVudCB0aGF0IHdpbGwgYmUgdHJpZ2dlcmVkIHdoZW4gY2hhbmdpbmcgb2YgdGhlIHNlbGVjdGlvblxuICAgKi9cbiAgQE91dHB1dCgpIHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55Pih0cnVlKTtcbiAgLyoqXG4gICAqIFtkcm9wZG93bkJsdXJdIGV2ZW50IHRoYXQgd2lsbCBiZSB0cmlnZ2VyZWQgd2l0aCAoYmx1cikgb2YgZHJvcGRvd25cbiAgICovXG4gIEBPdXRwdXQoKSBkcm9wZG93bkJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLyoqXG4gICAqIFtpdGVtQ2xpY2tdIGV2ZW50IHRoYXQgd2lsbCBiZSB0cmlnZ2VyZWQgd2hlbiBjbGlja2luZyB0aGUgb3B0aW9uIG9mIGRyb3Bkb3duXG4gICAqL1xuICBAT3V0cHV0KCkgaXRlbUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIC8qKlxuICAgKiBmaWx0ZXIgdmFsdWVcbiAgICovXG4gIGZpbHRlclZhbHVlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBmbGFnIG9mIGNsaWNraW5nIGRyb3Bkb3duLiBJdCdzIHRvIHByZXZlbnQgKGJsdXIpIG9mIGRyb3Bkb3duIGZyb20gaGFwcGVuaW5nIGluIGNoZWNrYm94IG1vZGUuXG4gICAqL1xuICBwcml2YXRlIF9jbGlja2VkSXRlbXMgPSBmYWxzZTtcblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXMuaXRlbXMpIHtcbiAgICAgIHRoaXMuX2NoZWNrU2VsZWN0aW9uQ2hhbmdlKGNoYW5nZXMuaXRlbXMucHJldmlvdXNWYWx1ZSwgY2hhbmdlcy5pdGVtcy5jdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2hlbiBjbGlja2luZyB0aGUgZHJvcGRvd25cbiAgICovXG4gIG9uSXRlbXNDbGljayhldmVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50Lm9mZnNldFggPiAoZXZlbnQudGFyZ2V0LmNsaWVudFdpZHRoICsgZXZlbnQudGFyZ2V0LmNsaWVudExlZnQpKSB7XG4gICAgICBzdG9wUHJvcGFnYXRpb25BbmREZWZhdWx0KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gc2hvdWxkIGlnbm9yZSBjbGlja2luZyBvbiBmaWx0ZXJcbiAgICBpZiAodGhpcy5jaGVja2JveCAmJiBldmVudC50YXJnZXQudHlwZSAhPT0gJ3RleHQnKSB7XG4gICAgICB0aGlzLl9jbGlja2VkSXRlbXMgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyZWQgd2hlbiBjbGlja2luZyB0aGUgaXRlbVxuICAgKi9cbiAgb25JdGVtQ2xpY2soY3VycmVudEl0ZW0pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2hlY2tib3gpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRWYWx1ZSA9IHRoaXMuX2dldEl0ZW1WYWx1ZShjdXJyZW50SXRlbSk7IC8vIGN1cnJlbnRJdGVtLnZhbHVlICE9IG51bGwgPyBjdXJyZW50SXRlbS52YWx1ZSA6IGN1cnJlbnRJdGVtLnRleHQ7XG4gICAgICBjbGVhckFsbFNlbGVjdGlvbih0aGlzLml0ZW1zKTtcbiAgICAgIC8vIHNldCB0aGUgc2VsZWN0aW9uIG9mIGN1cnJlbnQgb25lXG4gICAgICBjdXJyZW50SXRlbS5zZWxlY3RlZCA9IHRydWU7XG4gICAgICB0aGlzLml0ZW1DbGljay5lbWl0KGN1cnJlbnRJdGVtKTtcbiAgICAgIHRoaXMuX29uU2VsZWN0aW9uQ2hhbmdlKHRoaXMuc2VsZWN0ZWRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHRyaWdnZXJzIHdpdGggKGJsdXIpIGV2ZW50IG9mIGZpbHRlciBpbnB1dCBib3hcbiAgICovXG4gIG9uRmlsdGVyVGV4dEJsdXIoZXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmRyb3Bkb3duQmx1ci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VycyB3aXRoIChibHVyKSBldmVudCBvZiBkcm9wZG93blxuICAgKi9cbiAgb25JdGVtc0JsdXIoZXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGVja2JveCkge1xuICAgICAgaWYgKHRoaXMuX2NsaWNrZWRJdGVtcykge1xuICAgICAgICAvLyBpbiBjaGVja2JveCBtb2RlLCB0aGlzIGJsdXIgZXZlbnQgd2lsbCBiZSBpZ25vcmVkIHdoZW4gY2xpY2tpbmcgdGhlIGRyb3Bkb3duIChjaGVjayB0aGUgY2hlY2tib3gpXG4gICAgICAgIGV2ZW50LnRhcmdldC5mb2N1cygpO1xuICAgICAgICB0aGlzLl9jbGlja2VkSXRlbXMgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRyb3Bkb3duQmx1ci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB0b2dnbGUgdGhlIHNlbGVjdGlvbiB3aGVuIGNoZWNraW5nIHN0YXR1cyBjaGFuZ2VkIChpbiBjaGVja2JveCBtb2RlKVxuICAgKi9cbiAgdG9nZ2xlU2VsZWN0aW9uKGl0ZW06IHtpZDogc3RyaW5nLCB2YWx1ZT86IGFueSwgdGV4dDogYW55LCBzZWxlY3RlZD86IGJvb2xlYW59KTogdm9pZCB7XG4gICAgaXRlbS5zZWxlY3RlZCA9ICFpdGVtLnNlbGVjdGVkO1xuICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlLmVtaXQodGhpcy5fZ2V0SXRlbVZhbHVlKGl0ZW0pKTsgLy8gaXRlbS52YWx1ZSAhPSBudWxsID8gaXRlbS52YWx1ZSA6IGl0ZW0udGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogaXRlbXMgdmFsdWVzIGxpc3QgYWZ0ZXIgYXBwbHlpbmcgdGhlIGZpbHRlclxuICAgKi9cbiAgZ2V0IGl0ZW1zVmFsdWVzKCk6IGFueVtdIHtcbiAgICBsZXQgZmlsdGVyO1xuICAgIGlmICh0aGlzLmZpbHRlclZhbHVlKSB7XG4gICAgICBmaWx0ZXIgPSB0aGlzLmZpbHRlclZhbHVlLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgaWYgKGZpbHRlciA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5pdGVtcztcbiAgICB9XG4gICAgaWYgKCF0aGlzLml0ZW1zIHx8IHRoaXMuaXRlbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmIChoYXNHcm91cCh0aGlzLml0ZW1zKSkge1xuICAgICAgY29uc3QgaXRlbXMgPSBbXTtcbiAgICAgIHRoaXMuaXRlbXMuZm9yRWFjaChncm91cEl0ZW0gPT4ge1xuICAgICAgICBpZiAoZ3JvdXBJdGVtLmdyb3VwICE9IG51bGwgJiYgZ3JvdXBJdGVtLmdyb3VwLnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKS5pbmNsdWRlcyhmaWx0ZXIpKSB7XG4gICAgICAgICAgLy8gaWYgZ3JvdXBJdGVtIGNvbnRhaW5zIHRoZSBmaWx0ZXJzLCB0aGUgZ3JvdXBJdGVtIG5lZWRzIHRvIGJlIGRpc3BsYXllZCBhcyB3ZWxsXG4gICAgICAgICAgaXRlbXMucHVzaChncm91cEl0ZW0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkSXRlbXMgPSBncm91cEl0ZW0uaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS50ZXh0ICE9IG51bGwgJiYgaXRlbS50ZXh0LnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKS5pbmNsdWRlcyhmaWx0ZXIpKTtcbiAgICAgICAgICBpZiAoZmlsdGVyZWRJdGVtcyAmJiBmaWx0ZXJlZEl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe2dyb3VwOiBncm91cEl0ZW0uZ3JvdXAsIGl0ZW1zOiBmaWx0ZXJlZEl0ZW1zfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBpdGVtcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gKGl0ZW0udGV4dCAhPSBudWxsICYmIGl0ZW0udGV4dC50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkuaW5jbHVkZXMoZmlsdGVyKSkpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogb3B0aW9ucyBDU1MgY2xhc3NcbiAgICovXG4gIGdldCBvcHRpb25zQ2xhc3MoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5maWx0ZXJCb3ggJiYgIXRoaXMuY2hlY2tib3gpIHtcbiAgICAgIHJldHVybiAnb3B0aW9ucyB3aXRoLWZpbHRlcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnb3B0aW9ucyBuby1maWx0ZXInO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgaXRlbSB2YWx1ZS4gUmV0dXJuIHRleHQgaWYgdmFsdWUgaXMgbm90IGF2YWlsYWJsZVxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0SXRlbVZhbHVlKGl0ZW0pOiBhbnkge1xuICAgIHJldHVybiBpdGVtID8gaXRlbS52YWx1ZSAhPSBudWxsID8gaXRlbS52YWx1ZSA6IGl0ZW0udGV4dCA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBzZWxlY3Rpb24gY2hhbmdlZCwgZW1pdHMgZXZlbnRzOiAoc2VsZWN0ZWRWYWx1ZUNoYW5nZSkgYW5kIChzZWxlY3Rpb25DaGFuZ2UpO1xuICAgKi9cbiAgcHJpdmF0ZSBfb25TZWxlY3Rpb25DaGFuZ2UodmFsdWUpIHtcbiAgICB0aGlzLnNlbGVjdGVkVmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogY2hlY2sgd2hldGhlciB0aGUgc2VsZWN0aW9uIGlzIGNoYW5nZWQuIEVtaXRzIHJlbGF0aXZlIGV2ZW50cyB3aGVuIGlmIGNoYW5nZWQuXG4gICAqL1xuICBwcml2YXRlIF9jaGVja1NlbGVjdGlvbkNoYW5nZShwcmV2aW91c1ZhbHVlLCBjdXJyZW50VmFsdWUpIHtcbiAgICBjb25zdCBjdXJTZWxlY3RlZEl0ZW0gPSBnZXRGaXJzdFNlbGVjdGVkSXRlbShjdXJyZW50VmFsdWUpO1xuICAgIGNvbnN0IGxhc3RTZWxlY3RlZEl0ZW0gPSBnZXRGaXJzdFNlbGVjdGVkSXRlbShwcmV2aW91c1ZhbHVlKTtcbiAgICBjb25zdCBjdXJTZWxlY3RlZEl0ZW1JZCA9IGN1clNlbGVjdGVkSXRlbSA/IGN1clNlbGVjdGVkSXRlbS5pZCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBsYXN0U2VsZWN0ZWRJdGVtSWQgPSBsYXN0U2VsZWN0ZWRJdGVtID8gbGFzdFNlbGVjdGVkSXRlbS5pZCA6IHVuZGVmaW5lZDtcbiAgICBpZiAoY3VyU2VsZWN0ZWRJdGVtSWQgIT09IGxhc3RTZWxlY3RlZEl0ZW1JZCAmJiAhdGhpcy5jaGVja2JveCkge1xuICAgICAgdGhpcy5fb25TZWxlY3Rpb25DaGFuZ2UodGhpcy5fZ2V0SXRlbVZhbHVlKGN1clNlbGVjdGVkSXRlbSkpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2l0ZW0vaXRlbS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBHcm91cEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2dyb3VwLWl0ZW0vZ3JvdXAtaXRlbS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBJbnB1dEZpbHRlckNvbXBvbmVudCB9IGZyb20gJy4vZmlsdGVyL2lucHV0LWZpbHRlci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBBbmNob3JDb21wb25lbnQgfSBmcm9tICcuL2FuY2hvci9hbmNob3IuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRHJvcGRvd25Db21wb25lbnQgfSBmcm9tICcuL2Ryb3Bkb3duL2Ryb3Bkb3duLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IERyb3Bkb3duTGlzdENvbXBvbmVudCB9IGZyb20gJy4vZHJvcGRvd24tbGlzdC5jb21wb25lbnQnO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBkZWNsYXJhdGlvbnM6IFtcclxuICAgIERyb3Bkb3duTGlzdENvbXBvbmVudCxcclxuICAgIEl0ZW1Db21wb25lbnQsXHJcbiAgICBHcm91cEl0ZW1Db21wb25lbnQsXHJcbiAgICBJbnB1dEZpbHRlckNvbXBvbmVudCxcclxuICAgIEFuY2hvckNvbXBvbmVudCxcclxuICAgIERyb3Bkb3duQ29tcG9uZW50XHJcbiAgXSxcclxuICBleHBvcnRzOiBbIERyb3Bkb3duTGlzdENvbXBvbmVudF0sXHJcbiAgaW1wb3J0czogWyBDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlIF0sXHJcbiAgcHJvdmlkZXJzOiBbXSxcclxuICBib290c3RyYXA6IFtdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRHJvcGRvd25MaXN0TW9kdWxlIHt9XHJcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBR0EsU0FBZ0IsUUFBUSxDQUFDLEtBQUs7SUFDNUIsT0FBTyxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFB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