igniteui-angular 12.2.4 → 12.3.0-alpha.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 (41) hide show
  1. package/README.md +12 -11
  2. package/bundles/igniteui-angular.umd.js +1773 -1462
  3. package/bundles/igniteui-angular.umd.js.map +1 -1
  4. package/esm2015/igniteui-angular.js +97 -97
  5. package/esm2015/lib/combo/combo-dropdown.component.js +9 -4
  6. package/esm2015/lib/combo/combo-item.component.js +4 -3
  7. package/esm2015/lib/combo/combo.api.js +3 -3
  8. package/esm2015/lib/combo/combo.common.js +999 -2
  9. package/esm2015/lib/combo/combo.component.js +92 -1124
  10. package/esm2015/lib/combo/combo.pipes.js +3 -3
  11. package/esm2015/lib/data-operations/data-util.js +2 -3
  12. package/esm2015/lib/data-operations/grouping-strategy.js +1 -1
  13. package/esm2015/lib/grids/grid/grid.component.js +19 -2
  14. package/esm2015/lib/grids/grid/grid.pipes.js +3 -3
  15. package/esm2015/lib/services/exporter-common/base-export-service.js +2 -2
  16. package/esm2015/lib/simple-combo/public_api.js +2 -0
  17. package/esm2015/lib/simple-combo/simple-combo.component.js +298 -0
  18. package/esm2015/lib/toast/toast.component.js +46 -21
  19. package/esm2015/public_api.js +2 -1
  20. package/fesm2015/igniteui-angular.js +1305 -1025
  21. package/fesm2015/igniteui-angular.js.map +1 -1
  22. package/igniteui-angular.d.ts +96 -96
  23. package/igniteui-angular.metadata.json +1 -1
  24. package/lib/combo/combo-dropdown.component.d.ts +2 -0
  25. package/lib/combo/combo-item.component.d.ts +2 -0
  26. package/lib/combo/combo.common.d.ts +717 -4
  27. package/lib/combo/combo.component.d.ts +39 -782
  28. package/lib/combo/combo.pipes.d.ts +1 -1
  29. package/lib/data-operations/data-util.d.ts +2 -1
  30. package/lib/data-operations/grouping-strategy.d.ts +5 -2
  31. package/lib/grids/grid/grid.component.d.ts +17 -0
  32. package/lib/grids/grid/grid.pipes.d.ts +2 -1
  33. package/lib/simple-combo/public_api.d.ts +1 -0
  34. package/lib/simple-combo/simple-combo.component.d.ts +109 -0
  35. package/lib/toast/toast.component.d.ts +8 -4
  36. package/migrations/migration-collection.json +5 -0
  37. package/migrations/update-12_3_0/changes/members.json +26 -0
  38. package/migrations/update-12_3_0/index.d.ts +3 -0
  39. package/migrations/update-12_3_0/index.js +9 -0
  40. package/package.json +1 -1
  41. package/public_api.d.ts +1 -0
@@ -1,3 +1,1000 @@
1
- import { InjectionToken } from '@angular/core';
1
+ import { ChangeDetectorRef, ContentChild, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Inject, InjectionToken, Injector, Input, Optional, Output, TemplateRef, ViewChild } from '@angular/core';
2
+ import { NgControl } from '@angular/forms';
3
+ import { caseSensitive } from '@igniteui/material-icons-extended';
4
+ import { noop, Subject } from 'rxjs';
5
+ import { takeUntil } from 'rxjs/operators';
6
+ import { DisplayDensityBase, DisplayDensityToken } from '../core/displayDensity';
7
+ import { IgxSelectionAPIService } from '../core/selection';
8
+ import { cloneArray } from '../core/utils';
9
+ import { IgxForOfDirective } from '../directives/for-of/for_of.directive';
10
+ import { IgxIconService } from '../icon/public_api';
11
+ import { IGX_INPUT_GROUP_TYPE } from '../input-group/inputGroupType';
12
+ import { IgxInputDirective, IgxInputGroupComponent, IgxInputState } from '../input-group/public_api';
13
+ import { AbsoluteScrollStrategy, AutoPositionStrategy } from '../services/public_api';
14
+ import { IgxComboAPIService } from './combo.api';
15
+ import { IgxComboAddItemDirective, IgxComboClearIconDirective, IgxComboEmptyDirective, IgxComboFooterDirective, IgxComboHeaderDirective, IgxComboHeaderItemDirective, IgxComboItemDirective, IgxComboToggleIconDirective } from './combo.directives';
2
16
  export const IGX_COMBO_COMPONENT = new InjectionToken('IgxComboComponentToken');
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm8uY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaWduaXRldWktYW5ndWxhci9zcmMvbGliL2NvbWJvL2NvbWJvLmNvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTRCLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd6RSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLGNBQWMsQ0FBZSx3QkFBd0IsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3MsIElCYXNlRXZlbnRBcmdzIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBJR1hfQ09NQk9fQ09NUE9ORU5UID0gbmV3IEluamVjdGlvblRva2VuPElneENvbWJvQmFzZT4oJ0lneENvbWJvQ29tcG9uZW50VG9rZW4nKTtcblxuLyoqIEBoaWRkZW4gQGludGVybmFsIFRPRE86IEV2YWx1YXRlICovXG5leHBvcnQgaW50ZXJmYWNlIElneENvbWJvQmFzZSB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBkYXRhOiBhbnlbXSB8IG51bGw7XG4gICAgdmFsdWVLZXk6IHN0cmluZztcbiAgICBncm91cEtleTogc3RyaW5nO1xuICAgIGlzUmVtb3RlOiBib29sZWFuO1xuICAgIGZpbHRlcmVkRGF0YTogYW55W10gfCBudWxsO1xuICAgIHRvdGFsSXRlbUNvdW50OiBudW1iZXI7XG4gICAgaXRlbXNNYXhIZWlnaHQ6IG51bWJlcjtcbiAgICBpdGVtSGVpZ2h0OiBudW1iZXI7XG4gICAgc2VhcmNoVmFsdWU6IHN0cmluZztcbiAgICBzZWFyY2hJbnB1dDogRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PjtcbiAgICBjb21ib0lucHV0OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuICAgIG9wZW5lZDogRXZlbnRFbWl0dGVyPElCYXNlRXZlbnRBcmdzPjtcbiAgICBvcGVuaW5nOiBFdmVudEVtaXR0ZXI8Q2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3M+O1xuICAgIGNsb3Npbmc6IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncz47XG4gICAgY2xvc2VkOiBFdmVudEVtaXR0ZXI8SUJhc2VFdmVudEFyZ3M+O1xuICAgIGZvY3VzU2VhcmNoSW5wdXQob3BlbmluZz86IGJvb2xlYW4pOiB2b2lkO1xuICAgIHRyaWdnZXJDaGVjaygpOiB2b2lkO1xuICAgIGFkZEl0ZW1Ub0NvbGxlY3Rpb24oKTogdm9pZDtcbiAgICBpc0FkZEJ1dHRvblZpc2libGUoKTogYm9vbGVhbjtcbiAgICBoYW5kbGVJbnB1dENoYW5nZShldmVudD86IHN0cmluZyk6IHZvaWQ7XG4gICAgaXNJdGVtU2VsZWN0ZWQoaXRlbUlEOiBhbnkpOiBib29sZWFuO1xuICAgIHNlbGVjdEl0ZW1zKGl0ZW1JRHM6IGFueVtdLCBjbGVhclNlbGVjdGlvbj86IGJvb2xlYW4sIGV2ZW50PzogRXZlbnQpOiB2b2lkO1xuICAgIGRlc2VsZWN0SXRlbXMoaXRlbUlEczogYW55W10sIGV2ZW50PzogRXZlbnQpOiB2b2lkO1xufVxuIl19
17
+ let NEXT_ID = 0;
18
+ /**
19
+ * @hidden
20
+ * The default number of items that should be in the combo's
21
+ * drop-down list if no `[itemsMaxHeight]` is specified
22
+ */
23
+ const itemsInContainer = 10; // TODO: make private readonly
24
+ /** @hidden @internal */
25
+ const ItemHeights = {
26
+ comfortable: 40,
27
+ cosy: 32,
28
+ compact: 28,
29
+ };
30
+ /** @hidden @internal */
31
+ export var DataTypes;
32
+ (function (DataTypes) {
33
+ DataTypes["EMPTY"] = "empty";
34
+ DataTypes["PRIMITIVE"] = "primitive";
35
+ DataTypes["COMPLEX"] = "complex";
36
+ DataTypes["PRIMARYKEY"] = "valueKey";
37
+ })(DataTypes || (DataTypes = {}));
38
+ export var IgxComboState;
39
+ (function (IgxComboState) {
40
+ /**
41
+ * Combo with initial state.
42
+ */
43
+ IgxComboState[IgxComboState["INITIAL"] = 0] = "INITIAL";
44
+ /**
45
+ * Combo with valid state.
46
+ */
47
+ IgxComboState[IgxComboState["VALID"] = 1] = "VALID";
48
+ /**
49
+ * Combo with invalid state.
50
+ */
51
+ IgxComboState[IgxComboState["INVALID"] = 2] = "INVALID";
52
+ })(IgxComboState || (IgxComboState = {}));
53
+ export class IgxComboBaseDirective extends DisplayDensityBase {
54
+ constructor(elementRef, cdr, selectionService, comboAPI, _iconService, _displayDensityOptions, _inputGroupType, _injector) {
55
+ super(_displayDensityOptions);
56
+ this.elementRef = elementRef;
57
+ this.cdr = cdr;
58
+ this.selectionService = selectionService;
59
+ this.comboAPI = comboAPI;
60
+ this._iconService = _iconService;
61
+ this._displayDensityOptions = _displayDensityOptions;
62
+ this._inputGroupType = _inputGroupType;
63
+ this._injector = _injector;
64
+ /**
65
+ * Set custom overlay settings that control how the combo's list of items is displayed.
66
+ * Set:
67
+ * ```html
68
+ * <igx-combo [overlaySettings] = "customOverlaySettings"></igx-combo>
69
+ * ```
70
+ *
71
+ * ```typescript
72
+ * const customSettings = { positionStrategy: { settings: { target: myTarget } } };
73
+ * combo.overlaySettings = customSettings;
74
+ * ```
75
+ * Get any custom overlay settings used by the combo:
76
+ * ```typescript
77
+ * const comboOverlaySettings: OverlaySettings = myCombo.overlaySettings;
78
+ * ```
79
+ */
80
+ this.overlaySettings = null;
81
+ /**
82
+ * Gets/gets combo id.
83
+ *
84
+ * ```typescript
85
+ * // get
86
+ * let id = this.combo.id;
87
+ * ```
88
+ *
89
+ * ```html
90
+ * <!--set-->
91
+ * <igx-combo [id]='combo1'></igx-combo>
92
+ * ```
93
+ */
94
+ this.id = `igx-combo-${NEXT_ID++}`;
95
+ /**
96
+ * Controls whether custom values can be added to the collection
97
+ *
98
+ * ```typescript
99
+ * // get
100
+ * let comboAllowsCustomValues = this.combo.allowCustomValues;
101
+ * ```
102
+ *
103
+ * ```html
104
+ * <!--set-->
105
+ * <igx-combo [allowCustomValues]='true'></igx-combo>
106
+ * ```
107
+ */
108
+ this.allowCustomValues = false;
109
+ /**
110
+ * Determines which column in the data source is used to determine the value.
111
+ *
112
+ * ```typescript
113
+ * // get
114
+ * let myComboValueKey = this.combo.valueKey;
115
+ * ```
116
+ *
117
+ * ```html
118
+ * <!--set-->
119
+ * <igx-combo [valueKey]='myKey'></igx-combo>
120
+ * ```
121
+ */
122
+ this.valueKey = null;
123
+ /** @hidden @internal */
124
+ this.cssClass = 'igx-combo'; // Independent of display density for the time being
125
+ /** @hidden @internal */
126
+ this.role = 'combobox';
127
+ /**
128
+ * An @Input property that enabled/disables combo. The default is `false`.
129
+ * ```html
130
+ * <igx-combo [disabled]="'true'">
131
+ * ```
132
+ */
133
+ this.disabled = false;
134
+ /**
135
+ * Emitted when item selection is changing, before the selection completes
136
+ *
137
+ * ```html
138
+ * <igx-combo (selectionChanging)='handleSelection()'></igx-combo>
139
+ * ```
140
+ */
141
+ // TODO: any for old/new selection?
142
+ this.selectionChanging = new EventEmitter();
143
+ /**
144
+ * Emitted before the dropdown is opened
145
+ *
146
+ * ```html
147
+ * <igx-combo opening='handleOpening($event)'></igx-combo>
148
+ * ```
149
+ */
150
+ this.opening = new EventEmitter();
151
+ /**
152
+ * Emitted after the dropdown is opened
153
+ *
154
+ * ```html
155
+ * <igx-combo (opened)='handleOpened($event)'></igx-combo>
156
+ * ```
157
+ */
158
+ this.opened = new EventEmitter();
159
+ /**
160
+ * Emitted before the dropdown is closed
161
+ *
162
+ * ```html
163
+ * <igx-combo (closing)='handleClosing($event)'></igx-combo>
164
+ * ```
165
+ */
166
+ this.closing = new EventEmitter();
167
+ /**
168
+ * Emitted after the dropdown is closed
169
+ *
170
+ * ```html
171
+ * <igx-combo (closed)='handleClosed($event)'></igx-combo>
172
+ * ```
173
+ */
174
+ this.closed = new EventEmitter();
175
+ /**
176
+ * Emitted when an item is being added to the data collection
177
+ *
178
+ * ```html
179
+ * <igx-combo (addition)='handleAdditionEvent($event)'></igx-combo>
180
+ * ```
181
+ */
182
+ this.addition = new EventEmitter();
183
+ /**
184
+ * Emitted when the value of the search input changes (e.g. typing, pasting, clear, etc.)
185
+ *
186
+ * ```html
187
+ * <igx-combo (searchInputUpdate)='handleSearchInputEvent($event)'></igx-combo>
188
+ * ```
189
+ */
190
+ this.searchInputUpdate = new EventEmitter();
191
+ /**
192
+ * Emitted when new chunk of data is loaded from the virtualization
193
+ *
194
+ * ```html
195
+ * <igx-combo (dataPreLoad)='handleDataPreloadEvent($event)'></igx-combo>
196
+ * ```
197
+ */
198
+ this.dataPreLoad = new EventEmitter();
199
+ /**
200
+ * The custom template, if any, that should be used when rendering ITEMS in the combo list
201
+ *
202
+ * ```typescript
203
+ * // Set in typescript
204
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
205
+ * myComponent.combo.itemTemplate = myCustomTemplate;
206
+ * ```
207
+ * ```html
208
+ * <!-- Set in markup -->
209
+ * <igx-combo #combo>
210
+ * ...
211
+ * <ng-template igxComboItem>
212
+ * <div class="custom-item" let-item let-key="valueKey">
213
+ * <div class="custom-item__name">{{ item[key] }}</div>
214
+ * <div class="custom-item__cost">{{ item.cost }}</div>
215
+ * </div>
216
+ * </ng-template>
217
+ * </igx-combo>
218
+ * ```
219
+ */
220
+ this.itemTemplate = null;
221
+ /**
222
+ * The custom template, if any, that should be used when rendering the HEADER for the combo items list
223
+ *
224
+ * ```typescript
225
+ * // Set in typescript
226
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
227
+ * myComponent.combo.headerTemplate = myCustomTemplate;
228
+ * ```
229
+ * ```html
230
+ * <!-- Set in markup -->
231
+ * <igx-combo #combo>
232
+ * ...
233
+ * <ng-template igxComboHeader>
234
+ * <div class="combo__header">
235
+ * This is a custom header
236
+ * </div>
237
+ * </ng-template>
238
+ * </igx-combo>
239
+ * ```
240
+ */
241
+ this.headerTemplate = null;
242
+ /**
243
+ * The custom template, if any, that should be used when rendering the FOOTER for the combo items list
244
+ *
245
+ * ```typescript
246
+ * // Set in typescript
247
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
248
+ * myComponent.combo.footerTemplate = myCustomTemplate;
249
+ * ```
250
+ * ```html
251
+ * <!-- Set in markup -->
252
+ * <igx-combo #combo>
253
+ * ...
254
+ * <ng-template igxComboFooter>
255
+ * <div class="combo__footer">
256
+ * This is a custom footer
257
+ * </div>
258
+ * </ng-template>
259
+ * </igx-combo>
260
+ * ```
261
+ */
262
+ this.footerTemplate = null;
263
+ /**
264
+ * The custom template, if any, that should be used when rendering HEADER ITEMS for groups in the combo list
265
+ *
266
+ * ```typescript
267
+ * // Set in typescript
268
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
269
+ * myComponent.combo.headerItemTemplate = myCustomTemplate;
270
+ * ```
271
+ * ```html
272
+ * <!-- Set in markup -->
273
+ * <igx-combo #combo>
274
+ * ...
275
+ * <ng-template igxComboHeaderItem let-item let-key="groupKey">
276
+ * <div class="custom-item--group">Group header for {{ item[key] }}</div>
277
+ * </ng-template>
278
+ * </igx-combo>
279
+ * ```
280
+ */
281
+ this.headerItemTemplate = null;
282
+ /**
283
+ * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down
284
+ *
285
+ * ```typescript
286
+ * // Set in typescript
287
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
288
+ * myComponent.combo.addItemTemplate = myCustomTemplate;
289
+ * ```
290
+ * ```html
291
+ * <!-- Set in markup -->
292
+ * <igx-combo #combo>
293
+ * ...
294
+ * <ng-template igxComboAddItem>
295
+ * <button class="combo__add-button">
296
+ * Click to add item
297
+ * </button>
298
+ * </ng-template>
299
+ * </igx-combo>
300
+ * ```
301
+ */
302
+ this.addItemTemplate = null;
303
+ /**
304
+ * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down
305
+ *
306
+ * ```typescript
307
+ * // Set in typescript
308
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
309
+ * myComponent.combo.emptyTemplate = myCustomTemplate;
310
+ * ```
311
+ * ```html
312
+ * <!-- Set in markup -->
313
+ * <igx-combo #combo>
314
+ * ...
315
+ * <ng-template igxComboEmpty>
316
+ * <div class="combo--empty">
317
+ * There are no items to display
318
+ * </div>
319
+ * </ng-template>
320
+ * </igx-combo>
321
+ * ```
322
+ */
323
+ this.emptyTemplate = null;
324
+ /**
325
+ * The custom template, if any, that should be used when rendering the combo TOGGLE(open/close) button
326
+ *
327
+ * ```typescript
328
+ * // Set in typescript
329
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
330
+ * myComponent.combo.toggleIconTemplate = myCustomTemplate;
331
+ * ```
332
+ * ```html
333
+ * <!-- Set in markup -->
334
+ * <igx-combo #combo>
335
+ * ...
336
+ * <ng-template igxComboToggleIcon let-collapsed>
337
+ * <igx-icon>{{ collapsed ? 'remove_circle' : 'remove_circle_outline'}}</igx-icon>
338
+ * </ng-template>
339
+ * </igx-combo>
340
+ * ```
341
+ */
342
+ this.toggleIconTemplate = null;
343
+ /**
344
+ * The custom template, if any, that should be used when rendering the combo CLEAR button
345
+ *
346
+ * ```typescript
347
+ * // Set in typescript
348
+ * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate;
349
+ * myComponent.combo.clearIconTemplate = myCustomTemplate;
350
+ * ```
351
+ * ```html
352
+ * <!-- Set in markup -->
353
+ * <igx-combo #combo>
354
+ * ...
355
+ * <ng-template igxComboClearIcon>
356
+ * <igx-icon>clear</igx-icon>
357
+ * </ng-template>
358
+ * </igx-combo>
359
+ * ```
360
+ */
361
+ this.clearIconTemplate = null;
362
+ /** @hidden @internal */
363
+ this.searchInput = null;
364
+ this.dropdownContainer = null;
365
+ /** @hidden @internal */
366
+ this.customValueFlag = true;
367
+ /** @hidden @internal */
368
+ this.filterValue = '';
369
+ /** @hidden @internal */
370
+ this.defaultFallbackGroup = 'Other';
371
+ /** @hidden @internal */
372
+ this.filteringOptions = {
373
+ caseSensitive: false
374
+ };
375
+ this._data = [];
376
+ this._value = '';
377
+ this._groupKey = '';
378
+ this._filteredData = [];
379
+ this._remoteSelection = {};
380
+ this._valid = IgxComboState.INITIAL;
381
+ this.ngControl = null;
382
+ this.destroy$ = new Subject();
383
+ this._onTouchedCallback = noop;
384
+ this._onChangeCallback = noop;
385
+ this._type = null;
386
+ this._dataType = '';
387
+ this._searchValue = '';
388
+ this._itemHeight = null;
389
+ this._itemsMaxHeight = null;
390
+ this.onStatusChanged = () => {
391
+ if ((this.ngControl.control.touched || this.ngControl.control.dirty) &&
392
+ (this.ngControl.control.validator || this.ngControl.control.asyncValidator)) {
393
+ if (!this.collapsed || this.inputGroup.isFocused) {
394
+ this.valid = this.ngControl.invalid ? IgxComboState.INVALID : IgxComboState.VALID;
395
+ }
396
+ else {
397
+ this.valid = this.ngControl.invalid ? IgxComboState.INVALID : IgxComboState.INITIAL;
398
+ }
399
+ }
400
+ else {
401
+ // B.P. 18 May 2021: IgxDatePicker does not reset its state upon resetForm #9526
402
+ this.valid = IgxComboState.INITIAL;
403
+ }
404
+ this.manageRequiredAsterisk();
405
+ };
406
+ this.findMatch = (element) => {
407
+ const value = this.displayKey ? element[this.displayKey] : element;
408
+ return value.toString().toLowerCase() === this.searchValue.trim().toLowerCase();
409
+ };
410
+ }
411
+ /**
412
+ * Configures the drop down list height
413
+ *
414
+ * ```typescript
415
+ * // get
416
+ * let myComboItemsMaxHeight = this.combo.itemsMaxHeight;
417
+ * ```
418
+ *
419
+ * ```html
420
+ * <!--set-->
421
+ * <igx-combo [itemsMaxHeight]='320'></igx-combo>
422
+ * ```
423
+ */
424
+ get itemsMaxHeight() {
425
+ if (this._itemsMaxHeight === null || this._itemsMaxHeight === undefined) {
426
+ return this.itemHeight * itemsInContainer;
427
+ }
428
+ return this._itemsMaxHeight;
429
+ }
430
+ set itemsMaxHeight(val) {
431
+ this._itemsMaxHeight = val;
432
+ }
433
+ /**
434
+ * Configures the drop down list item height
435
+ *
436
+ * ```typescript
437
+ * // get
438
+ * let myComboItemHeight = this.combo.itemHeight;
439
+ * ```
440
+ *
441
+ * ```html
442
+ * <!--set-->
443
+ * <igx-combo [itemHeight]='32'></igx-combo>
444
+ * ```
445
+ */
446
+ get itemHeight() {
447
+ if (this._itemHeight === null || this._itemHeight === undefined) {
448
+ return ItemHeights[this.displayDensity];
449
+ }
450
+ return this._itemHeight;
451
+ }
452
+ set itemHeight(val) {
453
+ this._itemHeight = val;
454
+ }
455
+ /**
456
+ * Combo data source.
457
+ *
458
+ * ```html
459
+ * <!--set-->
460
+ * <igx-combo [data]='items'></igx-combo>
461
+ * ```
462
+ */
463
+ get data() {
464
+ return this._data;
465
+ }
466
+ set data(val) {
467
+ this._data = (val) ? val : [];
468
+ }
469
+ set displayKey(val) {
470
+ this._displayKey = val;
471
+ }
472
+ /**
473
+ * Determines which column in the data source is used to determine the display value.
474
+ *
475
+ * ```typescript
476
+ * // get
477
+ * let myComboDisplayKey = this.combo.displayKey;
478
+ *
479
+ * // set
480
+ * this.combo.displayKey = 'val';
481
+ *
482
+ * ```
483
+ *
484
+ * ```html
485
+ * <!--set-->
486
+ * <igx-combo [displayKey]='myDisplayKey'></igx-combo>
487
+ * ```
488
+ */
489
+ get displayKey() {
490
+ return this._displayKey ? this._displayKey : this.valueKey;
491
+ }
492
+ /**
493
+ * The item property by which items should be grouped inside the items list. Not usable if data is not of type Object[].
494
+ *
495
+ * ```html
496
+ * <!--set-->
497
+ * <igx-combo [groupKey]='newGroupKey'></igx-combo>
498
+ * ```
499
+ */
500
+ set groupKey(val) {
501
+ this._groupKey = val;
502
+ }
503
+ /**
504
+ * The item property by which items should be grouped inside the items list. Not usable if data is not of type Object[].
505
+ *
506
+ * ```typescript
507
+ * // get
508
+ * let currentGroupKey = this.combo.groupKey;
509
+ * ```
510
+ */
511
+ get groupKey() {
512
+ return this._groupKey;
513
+ }
514
+ /** @hidden @internal */
515
+ get ariaExpanded() {
516
+ return !this.dropdown.collapsed;
517
+ }
518
+ /** @hidden @internal */
519
+ get hasPopUp() {
520
+ return 'listbox';
521
+ }
522
+ /** @hidden @internal */
523
+ get ariaOwns() {
524
+ return this.dropdown.id;
525
+ }
526
+ /**
527
+ * An @Input property that sets how the combo will be styled.
528
+ * The allowed values are `line`, `box`, `border` and `search`. The default is `box`.
529
+ * ```html
530
+ * <igx-combo [type]="'line'">
531
+ * ```
532
+ */
533
+ get type() {
534
+ return this._type || this._inputGroupType || 'box';
535
+ }
536
+ set type(val) {
537
+ this._type = val;
538
+ }
539
+ /** @hidden @internal */
540
+ get searchValue() {
541
+ return this._searchValue;
542
+ }
543
+ set searchValue(val) {
544
+ this.filterValue = val;
545
+ this._searchValue = val;
546
+ }
547
+ /** @hidden @internal */
548
+ get isRemote() {
549
+ return this.totalItemCount > 0 &&
550
+ this.valueKey &&
551
+ this.dataType === DataTypes.COMPLEX;
552
+ }
553
+ /** @hidden @internal */
554
+ get dataType() {
555
+ if (this.displayKey) {
556
+ return DataTypes.COMPLEX;
557
+ }
558
+ return DataTypes.PRIMITIVE;
559
+ }
560
+ /**
561
+ * Gets if control is valid, when used in a form
562
+ *
563
+ * ```typescript
564
+ * // get
565
+ * let valid = this.combo.valid;
566
+ * ```
567
+ */
568
+ get valid() {
569
+ return this._valid;
570
+ }
571
+ /**
572
+ * Sets if control is valid, when used in a form
573
+ *
574
+ * ```typescript
575
+ * // set
576
+ * this.combo.valid = IgxComboState.INVALID;
577
+ * ```
578
+ */
579
+ set valid(valid) {
580
+ this._valid = valid;
581
+ this.comboInput.valid = IgxInputState[IgxComboState[valid]];
582
+ }
583
+ /**
584
+ * The text displayed in the combo input
585
+ *
586
+ * ```typescript
587
+ * // get
588
+ * let comboValue = this.combo.value;
589
+ * ```
590
+ */
591
+ get value() {
592
+ return this._value;
593
+ }
594
+ /**
595
+ * Defines the current state of the virtualized data. It contains `startIndex` and `chunkSize`
596
+ *
597
+ * ```typescript
598
+ * // get
599
+ * let state = this.combo.virtualizationState;
600
+ * ```
601
+ */
602
+ get virtualizationState() {
603
+ return this.virtDir.state;
604
+ }
605
+ /**
606
+ * Sets the current state of the virtualized data.
607
+ *
608
+ * ```typescript
609
+ * // set
610
+ * this.combo.virtualizationState(state);
611
+ * ```
612
+ */
613
+ set virtualizationState(state) {
614
+ this.virtDir.state = state;
615
+ }
616
+ /**
617
+ * Gets drop down state.
618
+ *
619
+ * ```typescript
620
+ * let state = this.combo.collapsed;
621
+ * ```
622
+ */
623
+ get collapsed() {
624
+ return this.dropdown.collapsed;
625
+ }
626
+ /**
627
+ * Gets total count of the virtual data items, when using remote service.
628
+ *
629
+ * ```typescript
630
+ * // get
631
+ * let count = this.combo.totalItemCount;
632
+ * ```
633
+ */
634
+ get totalItemCount() {
635
+ return this.virtDir.totalItemCount;
636
+ }
637
+ /**
638
+ * Sets total count of the virtual data items, when using remote service.
639
+ *
640
+ * ```typescript
641
+ * // set
642
+ * this.combo.totalItemCount(remoteService.count);
643
+ * ```
644
+ */
645
+ set totalItemCount(count) {
646
+ this.virtDir.totalItemCount = count;
647
+ }
648
+ /** @hidden @internal */
649
+ get template() {
650
+ this._dataType = this.dataType;
651
+ if (this.itemTemplate) {
652
+ return this.itemTemplate;
653
+ }
654
+ if (this._dataType === DataTypes.COMPLEX) {
655
+ return this.complexTemplate;
656
+ }
657
+ return this.primitiveTemplate;
658
+ }
659
+ /** @hidden @internal */
660
+ onArrowDown(event) {
661
+ event.preventDefault();
662
+ event.stopPropagation();
663
+ this.open();
664
+ }
665
+ /** @hidden @internal */
666
+ ngOnInit() {
667
+ this.ngControl = this._injector.get(NgControl, null);
668
+ const targetElement = this.elementRef.nativeElement;
669
+ this._overlaySettings = {
670
+ target: targetElement,
671
+ scrollStrategy: new AbsoluteScrollStrategy(),
672
+ positionStrategy: new AutoPositionStrategy(),
673
+ modal: false,
674
+ closeOnOutsideClick: true,
675
+ excludeFromOutsideClick: [targetElement]
676
+ };
677
+ this.selectionService.set(this.id, new Set());
678
+ this._iconService.addSvgIconFromText(caseSensitive.name, caseSensitive.value, 'imx-icons');
679
+ }
680
+ /** @hidden @internal */
681
+ ngAfterViewInit() {
682
+ this.filteredData = [...this.data];
683
+ if (this.ngControl) {
684
+ this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged);
685
+ this.manageRequiredAsterisk();
686
+ this.cdr.detectChanges();
687
+ }
688
+ this.virtDir.chunkPreload.pipe(takeUntil(this.destroy$)).subscribe((e) => {
689
+ const eventArgs = Object.assign({}, e, { owner: this });
690
+ this.dataPreLoad.emit(eventArgs);
691
+ });
692
+ }
693
+ /** @hidden @internal */
694
+ ngOnDestroy() {
695
+ this.destroy$.next();
696
+ this.destroy$.complete();
697
+ this.comboAPI.clear();
698
+ this.selectionService.clear(this.id);
699
+ }
700
+ /**
701
+ * A method that opens/closes the combo.
702
+ *
703
+ * ```html
704
+ * <button (click)="combo.toggle()">Toggle Combo</button>
705
+ * <igx-combo #combo></igx-combo>
706
+ * ```
707
+ */
708
+ toggle() {
709
+ const overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings);
710
+ this.dropdown.toggle(overlaySettings);
711
+ }
712
+ /**
713
+ * A method that opens the combo.
714
+ *
715
+ * ```html
716
+ * <button (click)="combo.open()">Open Combo</button>
717
+ * <igx-combo #combo></igx-combo>
718
+ * ```
719
+ */
720
+ open() {
721
+ const overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings);
722
+ this.dropdown.open(overlaySettings);
723
+ }
724
+ /**
725
+ * A method that closes the combo.
726
+ *
727
+ * ```html
728
+ * <button (click)="combo.close()">Close Combo</button>
729
+ * <igx-combo #combo></igx-combo>
730
+ * ```
731
+ */
732
+ close() {
733
+ this.dropdown.close();
734
+ }
735
+ /**
736
+ * Triggers change detection on the combo view
737
+ */
738
+ triggerCheck() {
739
+ this.cdr.detectChanges();
740
+ }
741
+ /**
742
+ * Get current selection state
743
+ *
744
+ * @returns Array of selected items
745
+ * ```typescript
746
+ * let selectedItems = this.combo.selectedItems();
747
+ * ```
748
+ */
749
+ get selection() {
750
+ const items = Array.from(this.selectionService.get(this.id));
751
+ return items;
752
+ }
753
+ /**
754
+ * Returns if the specified itemID is selected
755
+ *
756
+ * @hidden
757
+ * @internal
758
+ */
759
+ isItemSelected(item) {
760
+ return this.selectionService.is_item_selected(this.id, item);
761
+ }
762
+ /** @hidden @internal */
763
+ addItemToCollection() {
764
+ var _a;
765
+ if (!this.searchValue) {
766
+ return;
767
+ }
768
+ const newValue = this.searchValue.trim();
769
+ const addedItem = this.displayKey ? {
770
+ [this.valueKey]: newValue,
771
+ [this.displayKey]: newValue
772
+ } : newValue;
773
+ if (this.groupKey) {
774
+ Object.assign(addedItem, { [this.groupKey]: this.defaultFallbackGroup });
775
+ }
776
+ // expose shallow copy instead of this.data in event args so this.data can't be mutated
777
+ const oldCollection = [...this.data];
778
+ const newCollection = [...this.data, addedItem];
779
+ const args = {
780
+ oldCollection, addedItem, newCollection, owner: this, cancel: false
781
+ };
782
+ this.addition.emit(args);
783
+ if (args.cancel) {
784
+ return;
785
+ }
786
+ this.data.push(args.addedItem);
787
+ // trigger re-render
788
+ this.data = cloneArray(this.data);
789
+ this.select(this.valueKey !== null && this.valueKey !== undefined ?
790
+ [args.addedItem[this.valueKey]] : [args.addedItem], false);
791
+ this.customValueFlag = false;
792
+ (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a.nativeElement.focus();
793
+ this.dropdown.focusedItem = null;
794
+ this.virtDir.scrollTo(0);
795
+ }
796
+ /** @hidden @internal */
797
+ isAddButtonVisible() {
798
+ // This should always return a boolean value. If this.searchValue was '', it returns '' instead of false;
799
+ return this.searchValue !== '' && this.customValueFlag;
800
+ }
801
+ /** @hidden @internal */
802
+ handleInputChange(event) {
803
+ if (event !== undefined) {
804
+ const args = {
805
+ searchText: typeof event === 'string' ? event : event.target.value,
806
+ owner: this,
807
+ cancel: false
808
+ };
809
+ this.searchInputUpdate.emit(args);
810
+ if (args.cancel) {
811
+ this.filterValue = null;
812
+ }
813
+ }
814
+ this.checkMatch();
815
+ }
816
+ /**
817
+ * Event handlers
818
+ *
819
+ * @hidden
820
+ * @internal
821
+ */
822
+ handleOpening(e) {
823
+ const args = { owner: this, event: e.event, cancel: e.cancel };
824
+ this.opening.emit(args);
825
+ e.cancel = args.cancel;
826
+ }
827
+ /** @hidden @internal */
828
+ handleClosing(e) {
829
+ var _a;
830
+ const args = { owner: this, event: e.event, cancel: e.cancel };
831
+ this.closing.emit(args);
832
+ e.cancel = args.cancel;
833
+ if (e.cancel) {
834
+ return;
835
+ }
836
+ this.searchValue = '';
837
+ if (!e.event) {
838
+ (_a = this.comboInput) === null || _a === void 0 ? void 0 : _a.nativeElement.focus();
839
+ }
840
+ }
841
+ /** @hidden @internal */
842
+ handleClosed() {
843
+ this.closed.emit({ owner: this });
844
+ }
845
+ /** @hidden @internal */
846
+ handleKeyDown(event) {
847
+ if (event.key === 'ArrowUp' || event.key === 'Up') {
848
+ event.preventDefault();
849
+ event.stopPropagation();
850
+ this.close();
851
+ }
852
+ }
853
+ /** @hidden @internal */
854
+ registerOnChange(fn) {
855
+ this._onChangeCallback = fn;
856
+ }
857
+ /** @hidden @internal */
858
+ registerOnTouched(fn) {
859
+ this._onTouchedCallback = fn;
860
+ }
861
+ /** @hidden @internal */
862
+ setDisabledState(isDisabled) {
863
+ this.disabled = isDisabled;
864
+ }
865
+ /** @hidden @internal */
866
+ onClick(event) {
867
+ event.stopPropagation();
868
+ event.preventDefault();
869
+ if (!this.disabled) {
870
+ this.toggle();
871
+ }
872
+ }
873
+ /** @hidden @internal */
874
+ onBlur() {
875
+ if (this.collapsed) {
876
+ this._onTouchedCallback();
877
+ if (this.ngControl && this.ngControl.invalid) {
878
+ this.valid = IgxComboState.INVALID;
879
+ }
880
+ else {
881
+ this.valid = IgxComboState.INITIAL;
882
+ }
883
+ }
884
+ }
885
+ /** if there is a valueKey - map the keys to data items, else - just return the keys */
886
+ convertKeysToItems(keys) {
887
+ if (this.comboAPI.valueKey === null) {
888
+ return keys;
889
+ }
890
+ // map keys vs. filter data to retain the order of the selected items
891
+ return keys.map(key => this.data.find(entry => entry[this.valueKey] === key)).filter(e => e !== undefined);
892
+ }
893
+ checkMatch() {
894
+ const itemMatch = this.filteredData.some(this.findMatch);
895
+ this.customValueFlag = this.allowCustomValues && !itemMatch;
896
+ }
897
+ manageRequiredAsterisk() {
898
+ if (this.ngControl && this.ngControl.control.validator) {
899
+ // Run the validation with empty object to check if required is enabled.
900
+ const error = this.ngControl.control.validator({});
901
+ this.inputGroup.isRequired = error && error.required;
902
+ }
903
+ }
904
+ /** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */
905
+ registerRemoteEntries(ids, add = true) {
906
+ if (add) {
907
+ const selection = this.getValueDisplayPairs(ids);
908
+ for (const entry of selection) {
909
+ this._remoteSelection[entry[this.valueKey]] = entry[this.displayKey];
910
+ }
911
+ }
912
+ else {
913
+ for (const entry of ids) {
914
+ delete this._remoteSelection[entry];
915
+ }
916
+ }
917
+ }
918
+ /**
919
+ * For `id: any[]` returns a mapped `{ [combo.valueKey]: any, [combo.displayKey]: any }[]`
920
+ */
921
+ getValueDisplayPairs(ids) {
922
+ return this.data.filter(entry => ids.indexOf(entry[this.valueKey]) > -1).map(e => ({
923
+ [this.valueKey]: e[this.valueKey],
924
+ [this.displayKey]: e[this.displayKey]
925
+ }));
926
+ }
927
+ getRemoteSelection(newSelection, oldSelection) {
928
+ if (!newSelection.length) {
929
+ // If new selection is empty, clear all items
930
+ this.registerRemoteEntries(oldSelection, false);
931
+ return '';
932
+ }
933
+ const removedItems = oldSelection.filter(e => newSelection.indexOf(e) < 0);
934
+ const addedItems = newSelection.filter(e => oldSelection.indexOf(e) < 0);
935
+ this.registerRemoteEntries(addedItems);
936
+ this.registerRemoteEntries(removedItems, false);
937
+ return Object.keys(this._remoteSelection).map(e => this._remoteSelection[e]).join(', ');
938
+ }
939
+ }
940
+ IgxComboBaseDirective.decorators = [
941
+ { type: Directive }
942
+ ];
943
+ IgxComboBaseDirective.ctorParameters = () => [
944
+ { type: ElementRef },
945
+ { type: ChangeDetectorRef },
946
+ { type: IgxSelectionAPIService },
947
+ { type: IgxComboAPIService },
948
+ { type: IgxIconService },
949
+ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] },
950
+ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [IGX_INPUT_GROUP_TYPE,] }] },
951
+ { type: Injector, decorators: [{ type: Optional }] }
952
+ ];
953
+ IgxComboBaseDirective.propDecorators = {
954
+ overlaySettings: [{ type: Input }],
955
+ id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }],
956
+ width: [{ type: HostBinding, args: ['style.width',] }, { type: Input }],
957
+ allowCustomValues: [{ type: Input }],
958
+ itemsMaxHeight: [{ type: Input }],
959
+ itemHeight: [{ type: Input }],
960
+ itemsWidth: [{ type: Input }],
961
+ placeholder: [{ type: Input }],
962
+ data: [{ type: Input }],
963
+ valueKey: [{ type: Input }],
964
+ displayKey: [{ type: Input }],
965
+ groupKey: [{ type: Input }],
966
+ ariaLabelledBy: [{ type: Input }, { type: HostBinding, args: ['attr.aria-labelledby',] }],
967
+ cssClass: [{ type: HostBinding, args: ['class.igx-combo',] }],
968
+ role: [{ type: HostBinding, args: [`attr.role`,] }],
969
+ ariaExpanded: [{ type: HostBinding, args: ['attr.aria-expanded',] }],
970
+ hasPopUp: [{ type: HostBinding, args: ['attr.aria-haspopup',] }],
971
+ ariaOwns: [{ type: HostBinding, args: ['attr.aria-owns',] }],
972
+ disabled: [{ type: Input }],
973
+ type: [{ type: Input }],
974
+ selectionChanging: [{ type: Output }],
975
+ opening: [{ type: Output }],
976
+ opened: [{ type: Output }],
977
+ closing: [{ type: Output }],
978
+ closed: [{ type: Output }],
979
+ addition: [{ type: Output }],
980
+ searchInputUpdate: [{ type: Output }],
981
+ dataPreLoad: [{ type: Output }],
982
+ itemTemplate: [{ type: ContentChild, args: [IgxComboItemDirective, { read: TemplateRef },] }],
983
+ headerTemplate: [{ type: ContentChild, args: [IgxComboHeaderDirective, { read: TemplateRef },] }],
984
+ footerTemplate: [{ type: ContentChild, args: [IgxComboFooterDirective, { read: TemplateRef },] }],
985
+ headerItemTemplate: [{ type: ContentChild, args: [IgxComboHeaderItemDirective, { read: TemplateRef },] }],
986
+ addItemTemplate: [{ type: ContentChild, args: [IgxComboAddItemDirective, { read: TemplateRef },] }],
987
+ emptyTemplate: [{ type: ContentChild, args: [IgxComboEmptyDirective, { read: TemplateRef },] }],
988
+ toggleIconTemplate: [{ type: ContentChild, args: [IgxComboToggleIconDirective, { read: TemplateRef },] }],
989
+ clearIconTemplate: [{ type: ContentChild, args: [IgxComboClearIconDirective, { read: TemplateRef },] }],
990
+ inputGroup: [{ type: ViewChild, args: ['inputGroup', { read: IgxInputGroupComponent, static: true },] }],
991
+ comboInput: [{ type: ViewChild, args: ['comboInput', { read: IgxInputDirective, static: true },] }],
992
+ searchInput: [{ type: ViewChild, args: ['searchInput',] }],
993
+ virtualScrollContainer: [{ type: ViewChild, args: [IgxForOfDirective, { static: true },] }],
994
+ virtDir: [{ type: ViewChild, args: [IgxForOfDirective, { read: IgxForOfDirective, static: true },] }],
995
+ dropdownContainer: [{ type: ViewChild, args: ['dropdownItemContainer', { static: true },] }],
996
+ primitiveTemplate: [{ type: ViewChild, args: ['primitive', { read: TemplateRef, static: true },] }],
997
+ complexTemplate: [{ type: ViewChild, args: ['complex', { read: TemplateRef, static: true },] }],
998
+ onArrowDown: [{ type: HostListener, args: ['keydown.ArrowDown', ['$event'],] }, { type: HostListener, args: ['keydown.Alt.ArrowDown', ['$event'],] }]
999
+ };
1000
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tYm8uY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaWduaXRldWktYW5ndWxhci9zcmMvbGliL2NvbWJvL2NvbWJvLmNvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ1ksaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBVyxVQUFVLEVBQUUsWUFBWSxFQUM1RixXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBcUIsUUFBUSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUNsSSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXlDLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUEwQixNQUFNLHdCQUF3QixDQUFDO0FBQ3pHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNELE9BQU8sRUFBOEIsVUFBVSxFQUFtRCxNQUFNLGVBQWUsQ0FBQztBQUV4SCxPQUFPLEVBQWUsaUJBQWlCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUV2RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFxQixvQkFBb0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsc0JBQXNCLEVB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dEUsU0FBUyxTQUFDLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFOzBCQUlqRSxTQUFTLFNBQUMsYUFBYTtxQ0FJdkIsU0FBUyxTQUFDLGlCQUFpQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtzQkFHN0MsU0FBUyxTQUFDLGlCQUFpQixFQUFFLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0NBR3RFLFNBQVMsU0FBQyx1QkFBdUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0NBR25ELFNBQVMsU0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7OEJBRzFELFNBQVMsU0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7MEJBa0x4RCxZQUFZLFNBQUMsbUJBQW1CLEVBQUUsQ0FBQyxRQUFRLENBQUMsY0FDNUMsWUFBWSxTQUFDLHVCQUF1QixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29udGVudENoaWxkLCBEaXJlY3RpdmUsIERvQ2hlY2ssIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0QmluZGluZywgSG9zdExpc3RlbmVyLCBJbmplY3QsIEluamVjdGlvblRva2VuLCBJbmplY3RvciwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPcHRpb25hbCwgT3V0cHV0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgTmdDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgY2FzZVNlbnNpdGl2ZSB9IGZyb20gJ0BpZ25pdGV1aS9tYXRlcmlhbC1pY29ucy1leHRlbmRlZCc7XG5pbXBvcnQgeyBub29wLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBEaXNwbGF5RGVuc2l0eUJhc2UsIERpc3BsYXlEZW5zaXR5VG9rZW4sIElEaXNwbGF5RGVuc2l0eU9wdGlvbnMgfSBmcm9tICcuLi9jb3JlL2Rpc3BsYXlEZW5zaXR5JztcbmltcG9ydCB7IElneFNlbGVjdGlvbkFQSVNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL3NlbGVjdGlvbic7XG5pbXBvcnQgeyBDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncywgY2xvbmVBcnJheSwgSUJhc2VDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncywgSUJhc2VFdmVudEFyZ3MgfSBmcm9tICcuLi9jb3JlL3V0aWxzJztcbmltcG9ydCB7IFNvcnRpbmdEaXJlY3Rpb24gfSBmcm9tICcuLi9kYXRhLW9wZXJhdGlvbnMvc29ydGluZy1leHByZXNzaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBJRm9yT2ZTdGF0ZSwgSWd4Rm9yT2ZEaXJlY3RpdmUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL2Zvci1vZi9mb3Jfb2YuZGlyZWN0aXZlJztcbmltcG9ydCB7IElTZWxlY3Rpb25FdmVudEFyZ3MgfSBmcm9tICcuLi9kcm9wLWRvd24vcHVibGljX2FwaSc7XG5pbXBvcnQgeyBJZ3hJY29uU2VydmljZSB9IGZyb20gJy4uL2ljb24vcHVibGljX2FwaSc7XG5pbXBvcnQgeyBJZ3hJbnB1dEdyb3VwVHlwZSwgSUdYX0lOUFVUX0dST1VQX1RZUEUgfSBmcm9tICcuLi9pbnB1dC1ncm91cC9pbnB1dEdyb3VwVHlwZSc7XG5pbXBvcnQgeyBJZ3hJbnB1dERpcmVjdGl2ZSwgSWd4SW5wdXRHcm91cENvbXBvbmVudCwgSWd4SW5wdXRTdGF0ZSB9IGZyb20gJy4uL2lucHV0LWdyb3VwL3B1YmxpY19hcGknO1xuaW1wb3J0IHsgQWJzb2x1dGVTY3JvbGxTdHJhdGVneSwgQXV0b1Bvc2l0aW9uU3RyYXRlZ3ksIE92ZXJsYXlTZXR0aW5ncyB9IGZyb20gJy4uL3NlcnZpY2VzL3B1YmxpY19hcGknO1xuaW1wb3J0IHsgSWd4Q29tYm9Ecm9wRG93bkNvbXBvbmVudCB9IGZyb20gJy4vY29tYm8tZHJvcGRvd24uY29tcG9uZW50JztcbmltcG9ydCB7IElneENvbWJvQVBJU2VydmljZSB9IGZyb20gJy4vY29tYm8uYXBpJztcbmltcG9ydCB7XG4gICAgSWd4Q29tYm9BZGRJdGVtRGlyZWN0aXZlLCBJZ3hDb21ib0NsZWFySWNvbkRpcmVjdGl2ZSwgSWd4Q29tYm9FbXB0eURpcmVjdGl2ZSxcbiAgICBJZ3hDb21ib0Zvb3RlckRpcmVjdGl2ZSwgSWd4Q29tYm9IZWFkZXJEaXJlY3RpdmUsIElneENvbWJvSGVhZGVySXRlbURpcmVjdGl2ZSwgSWd4Q29tYm9JdGVtRGlyZWN0aXZlLCBJZ3hDb21ib1RvZ2dsZUljb25EaXJlY3RpdmVcbn0gZnJvbSAnLi9jb21iby5kaXJlY3RpdmVzJztcbmltcG9ydCB7XG4gICAgSUNvbWJvRmlsdGVyaW5nT3B0aW9ucywgSUNvbWJvSXRlbUFkZGl0aW9uRXZlbnQsIElDb21ib1NlYXJjaElucHV0RXZlbnRBcmdzLFxuICAgIElDb21ib1NlbGVjdGlvbkNoYW5naW5nRXZlbnRBcmdzXG59IGZyb20gJy4vcHVibGljX2FwaSc7XG5cbmV4cG9ydCBjb25zdCBJR1hfQ09NQk9fQ09NUE9ORU5UID0gbmV3IEluamVjdGlvblRva2VuPElneENvbWJvQmFzZT4oJ0lneENvbWJvQ29tcG9uZW50VG9rZW4nKTtcblxuLyoqIEBoaWRkZW4gQGludGVybmFsIFRPRE86IEV2YWx1YXRlICovXG5leHBvcnQgaW50ZXJmYWNlIElneENvbWJvQmFzZSB7XG4gICAgaWQ6IHN0cmluZztcbiAgICBkYXRhOiBhbnlbXSB8IG51bGw7XG4gICAgdmFsdWVLZXk6IHN0cmluZztcbiAgICBncm91cEtleTogc3RyaW5nO1xuICAgIGlzUmVtb3RlOiBib29sZWFuO1xuICAgIGZpbHRlcmVkRGF0YTogYW55W10gfCBudWxsO1xuICAgIHRvdGFsSXRlbUNvdW50OiBudW1iZXI7XG4gICAgaXRlbXNNYXhIZWlnaHQ6IG51bWJlcjtcbiAgICBpdGVtSGVpZ2h0OiBudW1iZXI7XG4gICAgc2VhcmNoVmFsdWU6IHN0cmluZztcbiAgICBzZWFyY2hJbnB1dDogRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PjtcbiAgICBjb21ib0lucHV0OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuICAgIG9wZW5lZDogRXZlbnRFbWl0dGVyPElCYXNlRXZlbnRBcmdzPjtcbiAgICBvcGVuaW5nOiBFdmVudEVtaXR0ZXI8Q2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3M+O1xuICAgIGNsb3Npbmc6IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncz47XG4gICAgY2xvc2VkOiBFdmVudEVtaXR0ZXI8SUJhc2VFdmVudEFyZ3M+O1xuICAgIGZvY3VzU2VhcmNoSW5wdXQob3BlbmluZz86IGJvb2xlYW4pOiB2b2lkO1xuICAgIHRyaWdnZXJDaGVjaygpOiB2b2lkO1xuICAgIGFkZEl0ZW1Ub0NvbGxlY3Rpb24oKTogdm9pZDtcbiAgICBpc0FkZEJ1dHRvblZpc2libGUoKTogYm9vbGVhbjtcbiAgICBoYW5kbGVJbnB1dENoYW5nZShldmVudD86IHN0cmluZyk6IHZvaWQ7XG4gICAgaXNJdGVtU2VsZWN0ZWQoaXRlbUlEOiBhbnkpOiBib29sZWFuO1xuICAgIHNlbGVjdChpdGVtOiBhbnkpOiB2b2lkO1xuICAgIHNlbGVjdChpdGVtSURzOiBhbnlbXSwgY2xlYXJTZWxlY3Rpb24/OiBib29sZWFuLCBldmVudD86IEV2ZW50KTogdm9pZDtcbiAgICBkZXNlbGVjdChpdGVtOiBhbnkpOiB2b2lkO1xuICAgIGRlc2VsZWN0KGl0ZW1JRHM6IGFueVtdLCBldmVudD86IEV2ZW50KTogdm9pZDtcbn1cblxubGV0IE5FWFRfSUQgPSAwO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqIFRoZSBkZWZhdWx0IG51bWJlciBvZiBpdGVtcyB0aGF0IHNob3VsZCBiZSBpbiB0aGUgY29tYm8nc1xuICogZHJvcC1kb3duIGxpc3QgaWYgbm8gYFtpdGVtc01heEhlaWdodF1gIGlzIHNwZWNpZmllZFxuICovXG5jb25zdCBpdGVtc0luQ29udGFpbmVyID0gMTA7IC8vIFRPRE86IG1ha2UgcHJpdmF0ZSByZWFkb25seVxuXG4vKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbmNvbnN0IEl0ZW1IZWlnaHRzID0ge1xuICAgIGNvbWZvcnRhYmxlOiA0MCxcbiAgICBjb3N5OiAzMixcbiAgICBjb21wYWN0OiAyOCxcbn07XG5cbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gRGF0YVR5cGVzIHtcbiAgICBFTVBUWSA9ICdlbXB0eScsXG4gICAgUFJJTUlUSVZFID0gJ3ByaW1pdGl2ZScsXG4gICAgQ09NUExFWCA9ICdjb21wbGV4JyxcbiAgICBQUklNQVJZS0VZID0gJ3ZhbHVlS2V5J1xufVxuXG5leHBvcnQgZW51bSBJZ3hDb21ib1N0YXRlIHtcbiAgICAvKipcbiAgICAgKiBDb21ibyB3aXRoIGluaXRpYWwgc3RhdGUuXG4gICAgICovXG4gICAgSU5JVElBTCA9IElneElucHV0U3RhdGUuSU5JVElBTCxcbiAgICAvKipcbiAgICAgKiBDb21ibyB3aXRoIHZhbGlkIHN0YXRlLlxuICAgICAqL1xuICAgIFZBTElEID0gSWd4SW5wdXRTdGF0ZS5WQUxJRCxcbiAgICAvKipcbiAgICAgKiBDb21ibyB3aXRoIGludmFsaWQgc3RhdGUuXG4gICAgICovXG4gICAgSU5WQUxJRCA9IElneElucHV0U3RhdGUuSU5WQUxJRFxufVxuXG5ARGlyZWN0aXZlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBJZ3hDb21ib0Jhc2VEaXJlY3RpdmUgZXh0ZW5kcyBEaXNwbGF5RGVuc2l0eUJhc2UgaW1wbGVtZW50cyBJZ3hDb21ib0Jhc2UsIE9uSW5pdCwgRG9DaGVjayxcbiAgICBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgICAvKipcbiAgICAgKiBTZXQgY3VzdG9tIG92ZXJsYXkgc2V0dGluZ3MgdGhhdCBjb250cm9sIGhvdyB0aGUgY29tYm8ncyBsaXN0IG9mIGl0ZW1zIGlzIGRpc3BsYXllZC5cbiAgICAgKiBTZXQ6XG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY29tYm8gW292ZXJsYXlTZXR0aW5nc10gPSBcImN1c3RvbU92ZXJsYXlTZXR0aW5nc1wiPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqICBjb25zdCBjdXN0b21TZXR0aW5ncyA9IHsgcG9zaXRpb25TdHJhdGVneTogeyBzZXR0aW5nczogeyB0YXJnZXQ6IG15VGFyZ2V0IH0gfSB9O1xuICAgICAqICBjb21iby5vdmVybGF5U2V0dGluZ3MgPSBjdXN0b21TZXR0aW5ncztcbiAgICAgKiBgYGBcbiAgICAgKiBHZXQgYW55IGN1c3RvbSBvdmVybGF5IHNldHRpbmdzIHVzZWQgYnkgdGhlIGNvbWJvOlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAgY29uc3QgY29tYm9PdmVybGF5U2V0dGluZ3M6IE92ZXJsYXlTZXR0aW5ncyA9IG15Q29tYm8ub3ZlcmxheVNldHRpbmdzO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIG92ZXJsYXlTZXR0aW5nczogT3ZlcmxheVNldHRpbmdzID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEdldHMvZ2V0cyBjb21ibyBpZC5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgaWQgPSB0aGlzLmNvbWJvLmlkO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWNvbWJvIFtpZF09J2NvbWJvMSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpZCA9IGBpZ3gtY29tYm8tJHtORVhUX0lEKyt9YDtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHN0eWxlIHdpZHRoIG9mIHRoZSBlbGVtZW50XG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IG15Q29tYm9XaWR0aCA9IHRoaXMuY29tYm8ud2lkdGg7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLXNldC0tPlxuICAgICAqIDxpZ3gtY29tYm8gW3dpZHRoXT0nMjUwcHgnPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnc3R5bGUud2lkdGgnKVxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHdpZHRoOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDb250cm9scyB3aGV0aGVyIGN1c3RvbSB2YWx1ZXMgY2FuIGJlIGFkZGVkIHRvIHRoZSBjb2xsZWN0aW9uXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IGNvbWJvQWxsb3dzQ3VzdG9tVmFsdWVzID0gdGhpcy5jb21iby5hbGxvd0N1c3RvbVZhbHVlcztcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tc2V0LS0+XG4gICAgICogPGlneC1jb21ibyBbYWxsb3dDdXN0b21WYWx1ZXNdPSd0cnVlJz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBhbGxvd0N1c3RvbVZhbHVlcyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlcyB0aGUgZHJvcCBkb3duIGxpc3QgaGVpZ2h0XG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IG15Q29tYm9JdGVtc01heEhlaWdodCA9IHRoaXMuY29tYm8uaXRlbXNNYXhIZWlnaHQ7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLXNldC0tPlxuICAgICAqIDxpZ3gtY29tYm8gW2l0ZW1zTWF4SGVpZ2h0XT0nMzIwJz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgaXRlbXNNYXhIZWlnaHQoKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKHRoaXMuX2l0ZW1zTWF4SGVpZ2h0ID09PSBudWxsIHx8IHRoaXMuX2l0ZW1zTWF4SGVpZ2h0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLml0ZW1IZWlnaHQgKiBpdGVtc0luQ29udGFpbmVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9pdGVtc01heEhlaWdodDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IGl0ZW1zTWF4SGVpZ2h0KHZhbDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX2l0ZW1zTWF4SGVpZ2h0ID0gdmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyZXMgdGhlIGRyb3AgZG93biBsaXN0IGl0ZW0gaGVpZ2h0XG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IG15Q29tYm9JdGVtSGVpZ2h0ID0gdGhpcy5jb21iby5pdGVtSGVpZ2h0O1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWNvbWJvIFtpdGVtSGVpZ2h0XT0nMzInPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGdldCBpdGVtSGVpZ2h0KCk6IG51bWJlciB7XG4gICAgICAgIGlmICh0aGlzLl9pdGVtSGVpZ2h0ID09PSBudWxsIHx8IHRoaXMuX2l0ZW1IZWlnaHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIEl0ZW1IZWlnaHRzW3RoaXMuZGlzcGxheURlbnNpdHldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9pdGVtSGVpZ2h0O1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgaXRlbUhlaWdodCh2YWw6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9pdGVtSGVpZ2h0ID0gdmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbmZpZ3VyZXMgdGhlIGRyb3AgZG93biBsaXN0IHdpZHRoXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IG15Q29tYm9JdGVtc1dpZHRoID0gdGhpcy5jb21iby5pdGVtc1dpZHRoO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWNvbWJvIFtpdGVtc1dpZHRoXSA9ICdcIjE4MHB4XCInPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGl0ZW1zV2lkdGg6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlIGZvciB0aGUgY29tYm8gdmFsdWUgZmllbGRcbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgbXlDb21ib1BsYWNlaG9sZGVyID0gdGhpcy5jb21iby5wbGFjZWhvbGRlcjtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tc2V0LS0+XG4gICAgICogPGlneC1jb21ibyBbcGxhY2Vob2xkZXJdPSduZXdQbGFjZUhvbGRlcic+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIENvbWJvIGRhdGEgc291cmNlLlxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWNvbWJvIFtkYXRhXT0naXRlbXMnPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGdldCBkYXRhKCk6IGFueVtdIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IGRhdGEodmFsOiBhbnlbXSB8IG51bGwpIHtcbiAgICAgICAgdGhpcy5fZGF0YSA9ICh2YWwpID8gdmFsIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lcyB3aGljaCBjb2x1bW4gaW4gdGhlIGRhdGEgc291cmNlIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgbXlDb21ib1ZhbHVlS2V5ID0gdGhpcy5jb21iby52YWx1ZUtleTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tc2V0LS0+XG4gICAgICogPGlneC1jb21ibyBbdmFsdWVLZXldPSdteUtleSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgdmFsdWVLZXk6IHN0cmluZyA9IG51bGw7XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgZGlzcGxheUtleSh2YWw6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9kaXNwbGF5S2V5ID0gdmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgd2hpY2ggY29sdW1uIGluIHRoZSBkYXRhIHNvdXJjZSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgZGlzcGxheSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgbXlDb21ib0Rpc3BsYXlLZXkgPSB0aGlzLmNvbWJvLmRpc3BsYXlLZXk7XG4gICAgICpcbiAgICAgKiAvLyBzZXRcbiAgICAgKiB0aGlzLmNvbWJvLmRpc3BsYXlLZXkgPSAndmFsJztcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWNvbWJvIFtkaXNwbGF5S2V5XT0nbXlEaXNwbGF5S2V5Jz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGRpc3BsYXlLZXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNwbGF5S2V5ID8gdGhpcy5fZGlzcGxheUtleSA6IHRoaXMudmFsdWVLZXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGl0ZW0gcHJvcGVydHkgYnkgd2hpY2ggaXRlbXMgc2hvdWxkIGJlIGdyb3VwZWQgaW5zaWRlIHRoZSBpdGVtcyBsaXN0LiBOb3QgdXNhYmxlIGlmIGRhdGEgaXMgbm90IG9mIHR5cGUgT2JqZWN0W10uXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLXNldC0tPlxuICAgICAqIDxpZ3gtY29tYm8gW2dyb3VwS2V5XT0nbmV3R3JvdXBLZXknPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBncm91cEtleSh2YWw6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9ncm91cEtleSA9IHZhbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaXRlbSBwcm9wZXJ0eSBieSB3aGljaCBpdGVtcyBzaG91bGQgYmUgZ3JvdXBlZCBpbnNpZGUgdGhlIGl0ZW1zIGxpc3QuIE5vdCB1c2FibGUgaWYgZGF0YSBpcyBub3Qgb2YgdHlwZSBPYmplY3RbXS5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgY3VycmVudEdyb3VwS2V5ID0gdGhpcy5jb21iby5ncm91cEtleTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGdyb3VwS2V5KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ncm91cEtleTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBzZXQgYXJpYS1sYWJlbGxlZGJ5IGF0dHJpYnV0ZVxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNvbWJvIFthcmlhTGFiZWxsZWRCeV09XCInbGFiZWwxJ1wiPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtbGFiZWxsZWRieScpXG4gICAgcHVibGljIGFyaWFMYWJlbGxlZEJ5OiBzdHJpbmc7XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1jb21ibycpXG4gICAgcHVibGljIGNzc0NsYXNzID0gJ2lneC1jb21ibyc7IC8vIEluZGVwZW5kZW50IG9mIGRpc3BsYXkgZGVuc2l0eSBmb3IgdGhlIHRpbWUgYmVpbmdcblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZyhgYXR0ci5yb2xlYClcbiAgICBwdWJsaWMgcm9sZSA9ICdjb21ib2JveCc7XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1leHBhbmRlZCcpXG4gICAgcHVibGljIGdldCBhcmlhRXhwYW5kZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhdGhpcy5kcm9wZG93bi5jb2xsYXBzZWQ7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtaGFzcG9wdXAnKVxuICAgIHB1YmxpYyBnZXQgaGFzUG9wVXAoKSB7XG4gICAgICAgIHJldHVybiAnbGlzdGJveCc7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtb3ducycpXG4gICAgcHVibGljIGdldCBhcmlhT3ducygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZHJvcGRvd24uaWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgZW5hYmxlZC9kaXNhYmxlcyBjb21iby4gVGhlIGRlZmF1bHQgaXMgYGZhbHNlYC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jb21ibyBbZGlzYWJsZWRdPVwiJ3RydWUnXCI+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZGlzYWJsZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgaG93IHRoZSBjb21ibyB3aWxsIGJlIHN0eWxlZC5cbiAgICAgKiBUaGUgYWxsb3dlZCB2YWx1ZXMgYXJlIGBsaW5lYCwgYGJveGAsIGBib3JkZXJgIGFuZCBgc2VhcmNoYC4gVGhlIGRlZmF1bHQgaXMgYGJveGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY29tYm8gW3R5cGVdPVwiJ2xpbmUnXCI+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IHR5cGUoKTogSWd4SW5wdXRHcm91cFR5cGUge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZSB8fCB0aGlzLl9pbnB1dEdyb3VwVHlwZSB8fCAnYm94JztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHR5cGUodmFsOiBJZ3hJbnB1dEdyb3VwVHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdmFsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgd2hlbiBpdGVtIHNlbGVjdGlvbiBpcyBjaGFuZ2luZywgYmVmb3JlIHRoZSBzZWxlY3Rpb24gY29tcGxldGVzXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jb21ibyAoc2VsZWN0aW9uQ2hhbmdpbmcpPSdoYW5kbGVTZWxlY3Rpb24oKSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gVE9ETzogYW55IGZvciBvbGQvbmV3IHNlbGVjdGlvbj9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgc2VsZWN0aW9uQ2hhbmdpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPElDb21ib1NlbGVjdGlvbkNoYW5naW5nRXZlbnRBcmdzIHwgSVNlbGVjdGlvbkV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYmVmb3JlIHRoZSBkcm9wZG93biBpcyBvcGVuZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNvbWJvIG9wZW5pbmc9J2hhbmRsZU9wZW5pbmcoJGV2ZW50KSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9wZW5pbmcgPSBuZXcgRXZlbnRFbWl0dGVyPElCYXNlQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIGFmdGVyIHRoZSBkcm9wZG93biBpcyBvcGVuZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNvbWJvIChvcGVuZWQpPSdoYW5kbGVPcGVuZWQoJGV2ZW50KSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9wZW5lZCA9IG5ldyBFdmVudEVtaXR0ZXI8SUJhc2VFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIGJlZm9yZSB0aGUgZHJvcGRvd24gaXMgY2xvc2VkXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jb21ibyAoY2xvc2luZyk9J2hhbmRsZUNsb3NpbmcoJGV2ZW50KSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIGNsb3NpbmcgPSBuZXcgRXZlbnRFbWl0dGVyPElCYXNlQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIGFmdGVyIHRoZSBkcm9wZG93biBpcyBjbG9zZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWNvbWJvIChjbG9zZWQpPSdoYW5kbGVDbG9zZWQoJGV2ZW50KSc+PC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIGNsb3NlZCA9IG5ldyBFdmVudEVtaXR0ZXI8SUJhc2VFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYW4gaXRlbSBpcyBiZWluZyBhZGRlZCB0byB0aGUgZGF0YSBjb2xsZWN0aW9uXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1jb21ibyAoYWRkaXRpb24pPSdoYW5kbGVBZGRpdGlvbkV2ZW50KCRldmVudCknPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBhZGRpdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8SUNvbWJvSXRlbUFkZGl0aW9uRXZlbnQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBzZWFyY2ggaW5wdXQgY2hhbmdlcyAoZS5nLiB0eXBpbmcsIHBhc3RpbmcsIGNsZWFyLCBldGMuKVxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY29tYm8gKHNlYXJjaElucHV0VXBkYXRlKT0naGFuZGxlU2VhcmNoSW5wdXRFdmVudCgkZXZlbnQpJz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgc2VhcmNoSW5wdXRVcGRhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPElDb21ib1NlYXJjaElucHV0RXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCB3aGVuIG5ldyBjaHVuayBvZiBkYXRhIGlzIGxvYWRlZCBmcm9tIHRoZSB2aXJ0dWFsaXphdGlvblxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtY29tYm8gKGRhdGFQcmVMb2FkKT0naGFuZGxlRGF0YVByZWxvYWRFdmVudCgkZXZlbnQpJz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgZGF0YVByZUxvYWQgPSBuZXcgRXZlbnRFbWl0dGVyPElGb3JPZlN0YXRlPigpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGN1c3RvbSB0ZW1wbGF0ZSwgaWYgYW55LCB0aGF0IHNob3VsZCBiZSB1c2VkIHdoZW4gcmVuZGVyaW5nIElURU1TIGluIHRoZSBjb21ibyBsaXN0XG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gU2V0IGluIHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBteUN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbXlDb21wb25lbnQuY3VzdG9tVGVtcGxhdGU7XG4gICAgICogbXlDb21wb25lbnQuY29tYm8uaXRlbVRlbXBsYXRlID0gbXlDdXN0b21UZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLSBTZXQgaW4gbWFya3VwIC0tPlxuICAgICAqICA8aWd4LWNvbWJvICNjb21ibz5cbiAgICAgKiAgICAgIC4uLlxuICAgICAqICAgICAgPG5nLXRlbXBsYXRlIGlneENvbWJvSXRlbT5cbiAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3VzdG9tLWl0ZW1cIiBsZXQtaXRlbSBsZXQta2V5PVwidmFsdWVLZXlcIj5cbiAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1pdGVtX19uYW1lXCI+e3sgaXRlbVtrZXldIH19PC9kaXY+XG4gICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjdXN0b20taXRlbV9fY29zdFwiPnt7IGl0ZW0uY29zdCB9fTwvZGl2PlxuICAgICAqICAgICAgICAgIDwvZGl2PlxuICAgICAqICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgKiAgPC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hDb21ib0l0ZW1EaXJlY3RpdmUsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwdWJsaWMgaXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXN0b20gdGVtcGxhdGUsIGlmIGFueSwgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgSEVBREVSIGZvciB0aGUgY29tYm8gaXRlbXMgbGlzdFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIFNldCBpbiB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgbXlDdXN0b21UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiA9IG15Q29tcG9uZW50LmN1c3RvbVRlbXBsYXRlO1xuICAgICAqIG15Q29tcG9uZW50LmNvbWJvLmhlYWRlclRlbXBsYXRlID0gbXlDdXN0b21UZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLSBTZXQgaW4gbWFya3VwIC0tPlxuICAgICAqICA8aWd4LWNvbWJvICNjb21ibz5cbiAgICAgKiAgICAgIC4uLlxuICAgICAqICAgICAgPG5nLXRlbXBsYXRlIGlneENvbWJvSGVhZGVyPlxuICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib19faGVhZGVyXCI+XG4gICAgICogICAgICAgICAgICAgIFRoaXMgaXMgYSBjdXN0b20gaGVhZGVyXG4gICAgICogICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAqICA8L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneENvbWJvSGVhZGVyRGlyZWN0aXZlLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pXG4gICAgcHVibGljIGhlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXN0b20gdGVtcGxhdGUsIGlmIGFueSwgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgRk9PVEVSIGZvciB0aGUgY29tYm8gaXRlbXMgbGlzdFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIFNldCBpbiB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgbXlDdXN0b21UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiA9IG15Q29tcG9uZW50LmN1c3RvbVRlbXBsYXRlO1xuICAgICAqIG15Q29tcG9uZW50LmNvbWJvLmZvb3RlclRlbXBsYXRlID0gbXlDdXN0b21UZW1wbGF0ZTtcbiAgICAgKiBgYGBcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLSBTZXQgaW4gbWFya3VwIC0tPlxuICAgICAqICA8aWd4LWNvbWJvICNjb21ibz5cbiAgICAgKiAgICAgIC4uLlxuICAgICAqICAgICAgPG5nLXRlbXBsYXRlIGlneENvbWJvRm9vdGVyPlxuICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib19fZm9vdGVyXCI+XG4gICAgICogICAgICAgICAgICAgIFRoaXMgaXMgYSBjdXN0b20gZm9vdGVyXG4gICAgICogICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAqICA8L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneENvbWJvRm9vdGVyRGlyZWN0aXZlLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pXG4gICAgcHVibGljIGZvb3RlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXN0b20gdGVtcGxhdGUsIGlmIGFueSwgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIHJlbmRlcmluZyBIRUFERVIgSVRFTVMgZm9yIGdyb3VwcyBpbiB0aGUgY29tYm8gbGlzdFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIFNldCBpbiB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgbXlDdXN0b21UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiA9IG15Q29tcG9uZW50LmN1c3RvbVRlbXBsYXRlO1xuICAgICAqIG15Q29tcG9uZW50LmNvbWJvLmhlYWRlckl0ZW1UZW1wbGF0ZSA9IG15Q3VzdG9tVGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS0gU2V0IGluIG1hcmt1cCAtLT5cbiAgICAgKiAgPGlneC1jb21ibyAjY29tYm8+XG4gICAgICogICAgICAuLi5cbiAgICAgKiAgICAgIDxuZy10ZW1wbGF0ZSBpZ3hDb21ib0hlYWRlckl0ZW0gbGV0LWl0ZW0gbGV0LWtleT1cImdyb3VwS2V5XCI+XG4gICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1pdGVtLS1ncm91cFwiPkdyb3VwIGhlYWRlciBmb3Ige3sgaXRlbVtrZXldIH19PC9kaXY+XG4gICAgICogICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAqICA8L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneENvbWJvSGVhZGVySXRlbURpcmVjdGl2ZSwgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHB1YmxpYyBoZWFkZXJJdGVtVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGN1c3RvbSB0ZW1wbGF0ZSwgaWYgYW55LCB0aGF0IHNob3VsZCBiZSB1c2VkIHdoZW4gcmVuZGVyaW5nIHRoZSBBREQgQlVUVE9OIGluIHRoZSBjb21ibyBkcm9wIGRvd25cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBTZXQgaW4gdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IG15Q3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gPSBteUNvbXBvbmVudC5jdXN0b21UZW1wbGF0ZTtcbiAgICAgKiBteUNvbXBvbmVudC5jb21iby5hZGRJdGVtVGVtcGxhdGUgPSBteUN1c3RvbVRlbXBsYXRlO1xuICAgICAqIGBgYFxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tIFNldCBpbiBtYXJrdXAgLS0+XG4gICAgICogIDxpZ3gtY29tYm8gI2NvbWJvPlxuICAgICAqICAgICAgLi4uXG4gICAgICogICAgICA8bmctdGVtcGxhdGUgaWd4Q29tYm9BZGRJdGVtPlxuICAgICAqICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb21ib19fYWRkLWJ1dHRvblwiPlxuICAgICAqICAgICAgICAgICAgICBDbGljayB0byBhZGQgaXRlbVxuICAgICAqICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAqICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgKiAgPC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hDb21ib0FkZEl0ZW1EaXJlY3RpdmUsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwdWJsaWMgYWRkSXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXN0b20gdGVtcGxhdGUsIGlmIGFueSwgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgQUREIEJVVFRPTiBpbiB0aGUgY29tYm8gZHJvcCBkb3duXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gU2V0IGluIHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBteUN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbXlDb21wb25lbnQuY3VzdG9tVGVtcGxhdGU7XG4gICAgICogbXlDb21wb25lbnQuY29tYm8uZW1wdHlUZW1wbGF0ZSA9IG15Q3VzdG9tVGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS0gU2V0IGluIG1hcmt1cCAtLT5cbiAgICAgKiAgPGlneC1jb21ibyAjY29tYm8+XG4gICAgICogICAgICAuLi5cbiAgICAgKiAgICAgIDxuZy10ZW1wbGF0ZSBpZ3hDb21ib0VtcHR5PlxuICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21iby0tZW1wdHlcIj5cbiAgICAgKiAgICAgICAgICAgICAgVGhlcmUgYXJlIG5vIGl0ZW1zIHRvIGRpc3BsYXlcbiAgICAgKiAgICAgICAgICA8L2Rpdj5cbiAgICAgKiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICogIDwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGQoSWd4Q29tYm9FbXB0eURpcmVjdGl2ZSwgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHB1YmxpYyBlbXB0eVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+ID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjdXN0b20gdGVtcGxhdGUsIGlmIGFueSwgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIHJlbmRlcmluZyB0aGUgY29tYm8gVE9HR0xFKG9wZW4vY2xvc2UpIGJ1dHRvblxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIFNldCBpbiB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgbXlDdXN0b21UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiA9IG15Q29tcG9uZW50LmN1c3RvbVRlbXBsYXRlO1xuICAgICAqIG15Q29tcG9uZW50LmNvbWJvLnRvZ2dsZUljb25UZW1wbGF0ZSA9IG15Q3VzdG9tVGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS0gU2V0IGluIG1hcmt1cCAtLT5cbiAgICAgKiAgPGlneC1jb21ibyAjY29tYm8+XG4gICAgICogICAgICAuLi5cbiAgICAgKiAgICAgIDxuZy10ZW1wbGF0ZSBpZ3hDb21ib1RvZ2dsZUljb24gbGV0LWNvbGxhcHNlZD5cbiAgICAgKiAgICAgICAgICA8aWd4LWljb24+e3sgY29sbGFwc2VkID8gJ3JlbW92ZV9jaXJjbGUnIDogJ3JlbW92ZV9jaXJjbGVfb3V0bGluZSd9fTwvaWd4LWljb24+XG4gICAgICogICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAqICA8L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkKElneENvbWJvVG9nZ2xlSWNvbkRpcmVjdGl2ZSwgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHB1YmxpYyB0b2dnbGVJY29uVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGN1c3RvbSB0ZW1wbGF0ZSwgaWYgYW55LCB0aGF0IHNob3VsZCBiZSB1c2VkIHdoZW4gcmVuZGVyaW5nIHRoZSBjb21ibyBDTEVBUiBidXR0b25cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBTZXQgaW4gdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IG15Q3VzdG9tVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gPSBteUNvbXBvbmVudC5jdXN0b21UZW1wbGF0ZTtcbiAgICAgKiBteUNvbXBvbmVudC5jb21iby5jbGVhckljb25UZW1wbGF0ZSA9IG15Q3VzdG9tVGVtcGxhdGU7XG4gICAgICogYGBgXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS0gU2V0IGluIG1hcmt1cCAtLT5cbiAgICAgKiAgPGlneC1jb21ibyAjY29tYm8+XG4gICAgICogICAgICAuLi5cbiAgICAgKiAgICAgIDxuZy10ZW1wbGF0ZSBpZ3hDb21ib0NsZWFySWNvbj5cbiAgICAgKiAgICAgICAgICA8aWd4LWljb24+Y2xlYXI8L2lneC1pY29uPlxuICAgICAqICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgKiAgPC9pZ3gtY29tYm8+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZChJZ3hDb21ib0NsZWFySWNvbkRpcmVjdGl2ZSwgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHB1YmxpYyBjbGVhckljb25UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiA9IG51bGw7XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBAVmlld0NoaWxkKCdpbnB1dEdyb3VwJywgeyByZWFkOiBJZ3hJbnB1dEdyb3VwQ29tcG9uZW50LCBzdGF0aWM6IHRydWUgfSlcbiAgICBwdWJsaWMgaW5wdXRHcm91cDogSWd4SW5wdXRHcm91cENvbXBvbmVudDtcblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIEBWaWV3Q2hpbGQoJ2NvbWJvSW5wdXQnLCB7IHJlYWQ6IElneElucHV0RGlyZWN0aXZlLCBzdGF0aWM6IHRydWUgfSlcbiAgICBwdWJsaWMgY29tYm9JbnB1dDogSWd4SW5wdXREaXJlY3RpdmU7XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBAVmlld0NoaWxkKCdzZWFyY2hJbnB1dCcpXG4gICAgcHVibGljIHNlYXJjaElucHV0OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+ID0gbnVsbDtcblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIEBWaWV3Q2hpbGQoSWd4Rm9yT2ZEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIHZpcnR1YWxTY3JvbGxDb250YWluZXI6IElneEZvck9mRGlyZWN0aXZlPGFueT47XG5cbiAgICBAVmlld0NoaWxkKElneEZvck9mRGlyZWN0aXZlLCB7IHJlYWQ6IElneEZvck9mRGlyZWN0aXZlLCBzdGF0aWM6IHRydWUgfSlcbiAgICBwcm90ZWN0ZWQgdmlydERpcjogSWd4Rm9yT2ZEaXJlY3RpdmU8YW55PjtcblxuICAgIEBWaWV3Q2hpbGQoJ2Ryb3Bkb3duSXRlbUNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIGRyb3Bkb3duQ29udGFpbmVyOiBFbGVtZW50UmVmID0gbnVsbDtcblxuICAgIEBWaWV3Q2hpbGQoJ3ByaW1pdGl2ZScsIHsgcmVhZDogVGVtcGxhdGVSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByb3RlY3RlZCBwcmltaXRpdmVUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbXBsZXgnLCB7IHJlYWQ6IFRlbXBsYXRlUmVmLCBzdGF0aWM6IHRydWUgfSlcbiAgICBwcm90ZWN0ZWQgY29tcGxleFRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGdldCBzZWFyY2hWYWx1ZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VhcmNoVmFsdWU7XG4gICAgfVxuICAgIHB1YmxpYyBzZXQgc2VhcmNoVmFsdWUodmFsOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5maWx0ZXJWYWx1ZSA9IHZhbDtcbiAgICAgICAgdGhpcy5fc2VhcmNoVmFsdWUgPSB2YWw7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGdldCBpc1JlbW90ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG90YWxJdGVtQ291bnQgPiAwICYmXG4gICAgICAgICAgICB0aGlzLnZhbHVlS2V5ICYmXG4gICAgICAgICAgICB0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZXMuQ09NUExFWDtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZ2V0IGRhdGFUeXBlKCk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLmRpc3BsYXlLZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBEYXRhVHlwZXMuQ09NUExFWDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gRGF0YVR5cGVzLlBSSU1JVElWRTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGlmIGNvbnRyb2wgaXMgdmFsaWQsIHdoZW4gdXNlZCBpbiBhIGZvcm1cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBnZXRcbiAgICAgKiBsZXQgdmFsaWQgPSB0aGlzLmNvbWJvLnZhbGlkO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdmFsaWQoKTogSWd4Q29tYm9TdGF0ZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIGlmIGNvbnRyb2wgaXMgdmFsaWQsIHdoZW4gdXNlZCBpbiBhIGZvcm1cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiAvLyBzZXRcbiAgICAgKiB0aGlzLmNvbWJvLnZhbGlkID0gSWd4Q29tYm9TdGF0ZS5JTlZBTElEO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgdmFsaWQodmFsaWQ6IElneENvbWJvU3RhdGUpIHtcbiAgICAgICAgdGhpcy5fdmFsaWQgPSB2YWxpZDtcbiAgICAgICAgdGhpcy5jb21ib0lucHV0LnZhbGlkID0gSWd4SW5wdXRTdGF0ZVtJZ3hDb21ib1N0YXRlW3ZhbGlkXV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIHRleHQgZGlzcGxheWVkIGluIHRoZSBjb21ibyBpbnB1dFxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIGdldFxuICAgICAqIGxldCBjb21ib1ZhbHVlID0gdGhpcy5jb21iby52YWx1ZTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB2aXJ0dWFsaXplZCBkYXRhLiBJdCBjb250YWlucyBgc3RhcnRJbmRleGAgYW5kIGBjaHVua1NpemVgXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IHN0YXRlID0gdGhpcy5jb21iby52aXJ0dWFsaXphdGlvblN0YXRlO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdmlydHVhbGl6YXRpb25TdGF0ZSgpOiBJRm9yT2ZTdGF0ZSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZpcnREaXIuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHZpcnR1YWxpemVkIGRhdGEuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gc2V0XG4gICAgICogdGhpcy5jb21iby52aXJ0dWFsaXphdGlvblN0YXRlKHN0YXRlKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IHZpcnR1YWxpemF0aW9uU3RhdGUoc3RhdGU6IElGb3JPZlN0YXRlKSB7XG4gICAgICAgIHRoaXMudmlydERpci5zdGF0ZSA9IHN0YXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgZHJvcCBkb3duIHN0YXRlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCBzdGF0ZSA9IHRoaXMuY29tYm8uY29sbGFwc2VkO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY29sbGFwc2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kcm9wZG93bi5jb2xsYXBzZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0b3RhbCBjb3VudCBvZiB0aGUgdmlydHVhbCBkYXRhIGl0ZW1zLCB3aGVuIHVzaW5nIHJlbW90ZSBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIGdldFxuICAgICAqIGxldCBjb3VudCA9IHRoaXMuY29tYm8udG90YWxJdGVtQ291bnQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCB0b3RhbEl0ZW1Db3VudCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy52aXJ0RGlyLnRvdGFsSXRlbUNvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRvdGFsIGNvdW50IG9mIHRoZSB2aXJ0dWFsIGRhdGEgaXRlbXMsIHdoZW4gdXNpbmcgcmVtb3RlIHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gc2V0XG4gICAgICogdGhpcy5jb21iby50b3RhbEl0ZW1Db3VudChyZW1vdGVTZXJ2aWNlLmNvdW50KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IHRvdGFsSXRlbUNvdW50KGNvdW50OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy52aXJ0RGlyLnRvdGFsSXRlbUNvdW50ID0gY291bnQ7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGdldCB0ZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgdGhpcy5fZGF0YVR5cGUgPSB0aGlzLmRhdGFUeXBlO1xuICAgICAgICBpZiAodGhpcy5pdGVtVGVtcGxhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLml0ZW1UZW1wbGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fZGF0YVR5cGUgPT09IERhdGFUeXBlcy5DT01QTEVYKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV4VGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucHJpbWl0aXZlVGVtcGxhdGU7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGN1c3RvbVZhbHVlRmxhZyA9IHRydWU7XG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGZpbHRlclZhbHVlID0gJyc7XG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGRlZmF1bHRGYWxsYmFja0dyb3VwID0gJ090aGVyJztcbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZmlsdGVyaW5nT3B0aW9uczogSUNvbWJvRmlsdGVyaW5nT3B0aW9ucyA9IHtcbiAgICAgICAgY2FzZVNlbnNpdGl2ZTogZmFsc2VcbiAgICB9O1xuXG4gICAgcHJvdGVjdGVkIF9kYXRhID0gW107XG4gICAgcHJvdGVjdGVkIF92YWx1ZSA9ICcnO1xuICAgIHByb3RlY3RlZCBfZ3JvdXBLZXkgPSAnJztcbiAgICBwcm90ZWN0ZWQgX2ZpbHRlcmVkRGF0YSA9IFtdO1xuICAgIHByb3RlY3RlZCBfZGlzcGxheUtleTogc3RyaW5nO1xuICAgIHByb3RlY3RlZCBfcmVtb3RlU2VsZWN0aW9uID0ge307XG4gICAgcHJvdGVjdGVkIF92YWxpZCA9IElneENvbWJvU3RhdGUuSU5JVElBTDtcbiAgICBwcm90ZWN0ZWQgbmdDb250cm9sOiBOZ0NvbnRyb2wgPSBudWxsO1xuICAgIHByb3RlY3RlZCBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PGFueT4oKTtcbiAgICBwcm90ZWN0ZWQgX29uVG91Y2hlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gbm9vcDtcbiAgICBwcm90ZWN0ZWQgX29uQ2hhbmdlQ2FsbGJhY2s6IChfOiBhbnkpID0+IHZvaWQgPSBub29wO1xuXG4gICAgcHJpdmF0ZSBfdHlwZSA9IG51bGw7XG4gICAgcHJpdmF0ZSBfZGF0YVR5cGUgPSAnJztcbiAgICBwcml2YXRlIF9zZWFyY2hWYWx1ZSA9ICcnO1xuICAgIHByaXZhdGUgX2l0ZW1IZWlnaHQgPSBudWxsO1xuICAgIHByaXZhdGUgX2l0ZW1zTWF4SGVpZ2h0ID0gbnVsbDtcbiAgICBwcml2YXRlIF9vdmVybGF5U2V0dGluZ3M6IE92ZXJsYXlTZXR0aW5ncztcblxuICAgIHB1YmxpYyBhYnN0cmFjdCBkcm9wZG93bjogSWd4Q29tYm9Ecm9wRG93bkNvbXBvbmVudDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJvdGVjdGVkIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByb3RlY3RlZCBzZWxlY3Rpb25TZXJ2aWNlOiBJZ3hTZWxlY3Rpb25BUElTZXJ2aWNlLFxuICAgICAgICBwcm90ZWN0ZWQgY29tYm9BUEk6IElneENvbWJvQVBJU2VydmljZSxcbiAgICAgICAgcHJvdGVjdGVkIF9pY29uU2VydmljZTogSWd4SWNvblNlcnZpY2UsXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRGlzcGxheURlbnNpdHlUb2tlbikgcHJvdGVjdGVkIF9kaXNwbGF5RGVuc2l0eU9wdGlvbnM6IElEaXNwbGF5RGVuc2l0eU9wdGlvbnMsXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoSUdYX0lOUFVUX0dST1VQX1RZUEUpIHByb3RlY3RlZCBfaW5wdXRHcm91cFR5cGU6IElneElucHV0R3JvdXBUeXBlLFxuICAgICAgICBAT3B0aW9uYWwoKSBwcm90ZWN0ZWQgX2luamVjdG9yOiBJbmplY3Rvcikge1xuICAgICAgICBzdXBlcihfZGlzcGxheURlbnNpdHlPcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duLkFycm93RG93bicsIFsnJGV2ZW50J10pXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bi5BbHQuQXJyb3dEb3duJywgWyckZXZlbnQnXSlcbiAgICBwdWJsaWMgb25BcnJvd0Rvd24oZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLm9wZW4oKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMubmdDb250cm9sID0gdGhpcy5faW5qZWN0b3IuZ2V0PE5nQ29udHJvbD4oTmdDb250cm9sLCBudWxsKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLl9vdmVybGF5U2V0dGluZ3MgPSB7XG4gICAgICAgICAgICB0YXJnZXQ6IHRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgICBzY3JvbGxTdHJhdGVneTogbmV3IEFic29sdXRlU2Nyb2xsU3RyYXRlZ3koKSxcbiAgICAgICAgICAgIHBvc2l0aW9uU3RyYXRlZ3k6IG5ldyBBdXRvUG9zaXRpb25TdHJhdGVneSgpLFxuICAgICAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICAgICAgY2xvc2VPbk91dHNpZGVDbGljazogdHJ1ZSxcbiAgICAgICAgICAgIGV4Y2x1ZGVGcm9tT3V0c2lkZUNsaWNrOiBbdGFyZ2V0RWxlbWVudCBhcyBIVE1MRWxlbWVudF1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnNldCh0aGlzLmlkLCBuZXcgU2V0KCkpO1xuICAgICAgICB0aGlzLl9pY29uU2VydmljZS5hZGRTdmdJY29uRnJvbVRleHQoY2FzZVNlbnNpdGl2ZS5uYW1lLCBjYXNlU2Vuc2l0aXZlLnZhbHVlLCAnaW14LWljb25zJyk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5maWx0ZXJlZERhdGEgPSBbLi4udGhpcy5kYXRhXTtcblxuICAgICAgICBpZiAodGhpcy5uZ0NvbnRyb2wpIHtcbiAgICAgICAgICAgIHRoaXMubmdDb250cm9sLnN0YXR1c0NoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh0aGlzLm9uU3RhdHVzQ2hhbmdlZCk7XG4gICAgICAgICAgICB0aGlzLm1hbmFnZVJlcXVpcmVkQXN0ZXJpc2soKTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpcnREaXIuY2h1bmtQcmVsb2FkLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGU6IElGb3JPZlN0YXRlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudEFyZ3M6IElGb3JPZlN0YXRlID0gT2JqZWN0LmFzc2lnbih7fSwgZSwgeyBvd25lcjogdGhpcyB9KTtcbiAgICAgICAgICAgIHRoaXMuZGF0YVByZUxvYWQuZW1pdChldmVudEFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuY29tYm9BUEkuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmNsZWFyKHRoaXMuaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgbWV0aG9kIHRoYXQgb3BlbnMvY2xvc2VzIHRoZSBjb21iby5cbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8YnV0dG9uIChjbGljayk9XCJjb21iby50b2dnbGUoKVwiPlRvZ2dsZSBDb21ibzwvYnV0dG9uPlxuICAgICAqIDxpZ3gtY29tYm8gI2NvbWJvPjwvaWd4LWNvbWJvPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGUoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG92ZXJsYXlTZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuX292ZXJsYXlTZXR0aW5ncywgdGhpcy5vdmVybGF5U2V0dGluZ3MpO1xuICAgICAgICB0aGlzLmRyb3Bkb3duLnRvZ2dsZShvdmVybGF5U2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgbWV0aG9kIHRoYXQgb3BlbnMgdGhlIGNvbWJvLlxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxidXR0b24gKGNsaWNrKT1cImNvbWJvLm9wZW4oKVwiPk9wZW4gQ29tYm88L2J1dHRvbj5cbiAgICAgKiA8aWd4LWNvbWJvICNjb21ibz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgb3BlbigpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3ZlcmxheVNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fb3ZlcmxheVNldHRpbmdzLCB0aGlzLm92ZXJsYXlTZXR0aW5ncyk7XG4gICAgICAgIHRoaXMuZHJvcGRvd24ub3BlbihvdmVybGF5U2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgbWV0aG9kIHRoYXQgY2xvc2VzIHRoZSBjb21iby5cbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8YnV0dG9uIChjbGljayk9XCJjb21iby5jbG9zZSgpXCI+Q2xvc2UgQ29tYm88L2J1dHRvbj5cbiAgICAgKiA8aWd4LWNvbWJvICNjb21ibz48L2lneC1jb21ibz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgY2xvc2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZHJvcGRvd24uY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIHRoZSBjb21ibyB2aWV3XG4gICAgICovXG4gICAgcHVibGljIHRyaWdnZXJDaGVjaygpIHtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBjdXJyZW50IHNlbGVjdGlvbiBzdGF0ZVxuICAgICAqXG4gICAgICogQHJldHVybnMgQXJyYXkgb2Ygc2VsZWN0ZWQgaXRlbXNcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IHNlbGVjdGVkSXRlbXMgPSB0aGlzLmNvbWJvLnNlbGVjdGVkSXRlbXMoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGlvbigpIHtcbiAgICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5mcm9tKHRoaXMuc2VsZWN0aW9uU2VydmljZS5nZXQodGhpcy5pZCkpO1xuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBpZiB0aGUgc3BlY2lmaWVkIGl0ZW1JRCBpcyBzZWxlY3RlZFxuICAgICAqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBpc0l0ZW1TZWxlY3RlZChpdGVtOiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0aW9uU2VydmljZS5pc19pdGVtX3NlbGVjdGVkKHRoaXMuaWQsIGl0ZW0pO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBhZGRJdGVtVG9Db2xsZWN0aW9uKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2VhcmNoVmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXMuc2VhcmNoVmFsdWUudHJpbSgpO1xuICAgICAgICBjb25zdCBhZGRlZEl0ZW0gPSB0aGlzLmRpc3BsYXlLZXkgPyB7XG4gICAgICAgICAgICBbdGhpcy52YWx1ZUtleV06IG5ld1ZhbHVlLFxuICAgICAgICAgICAgW3RoaXMuZGlzcGxheUtleV06IG5ld1ZhbHVlXG4gICAgICAgIH0gOiBuZXdWYWx1ZTtcbiAgICAgICAgaWYgKHRoaXMuZ3JvdXBLZXkpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oYWRkZWRJdGVtLCB7IFt0aGlzLmdyb3VwS2V5XTogdGhpcy5kZWZhdWx0RmFsbGJhY2tHcm91cCB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBleHBvc2Ugc2hhbGxvdyBjb3B5IGluc3RlYWQgb2YgdGhpcy5kYXRhIGluIGV2ZW50IGFyZ3Mgc28gdGhpcy5kYXRhIGNhbid0IGJlIG11dGF0ZWRcbiAgICAgICAgY29uc3Qgb2xkQ29sbGVjdGlvbiA9IFsuLi50aGlzLmRhdGFdO1xuICAgICAgICBjb25zdCBuZXdDb2xsZWN0aW9uID0gWy4uLnRoaXMuZGF0YSwgYWRkZWRJdGVtXTtcbiAgICAgICAgY29uc3QgYXJnczogSUNvbWJvSXRlbUFkZGl0aW9uRXZlbnQgPSB7XG4gICAgICAgICAgICBvbGRDb2xsZWN0aW9uLCBhZGRlZEl0ZW0sIG5ld0NvbGxlY3Rpb24sIG93bmVyOiB0aGlzLCBjYW5jZWw6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYWRkaXRpb24uZW1pdChhcmdzKTtcbiAgICAgICAgaWYgKGFyZ3MuY2FuY2VsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXRhLnB1c2goYXJncy5hZGRlZEl0ZW0pO1xuICAgICAgICAvLyB0cmlnZ2VyIHJlLXJlbmRlclxuICAgICAgICB0aGlzLmRhdGEgPSBjbG9uZUFycmF5KHRoaXMuZGF0YSk7XG4gICAgICAgIHRoaXMuc2VsZWN0KHRoaXMudmFsdWVLZXkgIT09IG51bGwgJiYgdGhpcy52YWx1ZUtleSAhPT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIFthcmdzLmFkZGVkSXRlbVt0aGlzLnZhbHVlS2V5XV0gOiBbYXJncy5hZGRlZEl0ZW1dLCBmYWxzZSk7XG4gICAgICAgIHRoaXMuY3VzdG9tVmFsdWVGbGFnID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VhcmNoSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgdGhpcy5kcm9wZG93bi5mb2N1c2VkSXRlbSA9IG51bGw7XG4gICAgICAgIHRoaXMudmlydERpci5zY3JvbGxUbygwKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgaXNBZGRCdXR0b25WaXNpYmxlKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBUaGlzIHNob3VsZCBhbHdheXMgcmV0dXJuIGEgYm9vbGVhbiB2YWx1ZS4gSWYgdGhpcy5zZWFyY2hWYWx1ZSB3YXMgJycsIGl0IHJldHVybnMgJycgaW5zdGVhZCBvZiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VhcmNoVmFsdWUgIT09ICcnICYmIHRoaXMuY3VzdG9tVmFsdWVGbGFnO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBoYW5kbGVJbnB1dENoYW5nZShldmVudD86IGFueSkge1xuICAgICAgICBpZiAoZXZlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgYXJnczogSUNvbWJvU2VhcmNoSW5wdXRFdmVudEFyZ3MgPSB7XG4gICAgICAgICAgICAgICAgc2VhcmNoVGV4dDogdHlwZW9mIGV2ZW50ID09PSAnc3RyaW5nJyA/IGV2ZW50IDogZXZlbnQudGFyZ2V0LnZhbHVlLFxuICAgICAgICAgICAgICAgIG93bmVyOiB0aGlzLFxuICAgICAgICAgICAgICAgIGNhbmNlbDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnNlYXJjaElucHV0VXBkYXRlLmVtaXQoYXJncyk7XG4gICAgICAgICAgICBpZiAoYXJncy5jYW5jZWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrTWF0Y2goKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFdmVudCBoYW5kbGVyc1xuICAgICAqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVPcGVuaW5nKGU6IElCYXNlQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3MpIHtcbiAgICAgICAgY29uc3QgYXJnczogSUJhc2VDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncyA9IHsgb3duZXI6IHRoaXMsIGV2ZW50OiBlLmV2ZW50LCBjYW5jZWw6IGUuY2FuY2VsIH07XG4gICAgICAgIHRoaXMub3BlbmluZy5lbWl0KGFyZ3MpO1xuICAgICAgICBlLmNhbmNlbCA9IGFyZ3MuY2FuY2VsO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBoYW5kbGVDbG9zaW5nKGU6IElCYXNlQ2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3MpIHtcbiAgICAgICAgY29uc3QgYXJnczogSUJhc2VDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncyA9IHsgb3duZXI6IHRoaXMsIGV2ZW50OiBlLmV2ZW50LCBjYW5jZWw6IGUuY2FuY2VsIH07XG4gICAgICAgIHRoaXMuY2xvc2luZy5lbWl0KGFyZ3MpO1xuICAgICAgICBlLmNhbmNlbCA9IGFyZ3MuY2FuY2VsO1xuICAgICAgICBpZiAoZS5jYW5jZWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlYXJjaFZhbHVlID0gJyc7XG4gICAgICAgIGlmICghZS5ldmVudCkge1xuICAgICAgICAgICAgdGhpcy5jb21ib0lucHV0Py5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgaGFuZGxlQ2xvc2VkKCkge1xuICAgICAgICB0aGlzLmNsb3NlZC5lbWl0KHsgb3duZXI6IHRoaXMgfSk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIGhhbmRsZUtleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0Fycm93VXAnIHx8IGV2ZW50LmtleSA9PT0gJ1VwJykge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2sgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xuICAgIHB1YmxpYyBvbkNsaWNrKGV2ZW50OiBFdmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXG4gICAgcHVibGljIG9uQmx1cigpIHtcbiAgICAgICAgaWYgKHRoaXMuY29sbGFwc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9vblRvdWNoZWRDYWxsYmFjaygpO1xuICAgICAgICAgICAgaWYgKHRoaXMubmdDb250cm9sICYmIHRoaXMubmdDb250cm9sLmludmFsaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkID0gSWd4Q29tYm9TdGF0ZS5JTlZBTElEO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkID0gSWd4Q29tYm9TdGF0ZS5JTklUSUFMO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIG9uU3RhdHVzQ2hhbmdlZCA9ICgpID0+IHtcbiAgICAgICAgaWYgKCh0aGlzLm5nQ29udHJvbC5jb250cm9sLnRvdWNoZWQgfHwgdGhpcy5uZ0NvbnRyb2wuY29udHJvbC5kaXJ0eSkgJiZcbiAgICAgICAgICAgICh0aGlzLm5nQ29udHJvbC5jb250cm9sLnZhbGlkYXRvciB8fCB0aGlzLm5nQ29udHJvbC5jb250cm9sLmFzeW5jVmFsaWRhdG9yKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbGxhcHNlZCB8fCB0aGlzLmlucHV0R3JvdXAuaXNGb2N1c2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWxpZCA9IHRoaXMubmdDb250cm9sLmludmFsaWQgPyBJZ3hDb21ib1N0YXRlLklOVkFMSUQgOiBJZ3hDb21ib1N0YXRlLlZBTElEO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkID0gdGhpcy5uZ0NvbnRyb2wuaW52YWxpZCA/IElneENvbWJvU3RhdGUuSU5WQUxJRCA6IElneENvbWJvU3RhdGUuSU5JVElBTDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEIuUC4gMTggTWF5IDIwMjE6IElneERhdGVQaWNrZXIgZG9lcyBub3QgcmVzZXQgaXRzIHN0YXRlIHVwb24gcmVzZXRGb3JtICM5NTI2XG4gICAgICAgICAgICB0aGlzLnZhbGlkID0gSWd4Q29tYm9TdGF0ZS5JTklUSUFMO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFuYWdlUmVxdWlyZWRBc3RlcmlzaygpO1xuICAgIH07XG5cbiAgICAvKiogaWYgdGhlcmUgaXMgYSB2YWx1ZUtleSAtIG1hcCB0aGUga2V5cyB0byBkYXRhIGl0ZW1zLCBlbHNlIC0ganVzdCByZXR1cm4gdGhlIGtleXMgKi9cbiAgICBwcm90ZWN0ZWQgY29udmVydEtleXNUb0l0ZW1zKGtleXM6IGFueVtdKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbWJvQVBJLnZhbHVlS2V5ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgfVxuICAgICAgICAvLyBtYXAga2V5cyB2cy4gZmlsdGVyIGRhdGEgdG8gcmV0YWluIHRoZSBvcmRlciBvZiB0aGUgc2VsZWN0ZWQgaXRlbXNcbiAgICAgICAgcmV0dXJuIGtleXMubWFwKGtleSA9PiB0aGlzLmRhdGEuZmluZChlbnRyeSA9PiBlbnRyeVt0aGlzLnZhbHVlS2V5XSA9PT0ga2V5KSkuZmlsdGVyKGUgPT4gZSAhPT0gdW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY2hlY2tNYXRjaCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaXRlbU1hdGNoID0gdGhpcy5maWx0ZXJlZERhdGEuc29tZSh0aGlzLmZpbmRNYXRjaCk7XG4gICAgICAgIHRoaXMuY3VzdG9tVmFsdWVGbGFnID0gdGhpcy5hbGxvd0N1c3RvbVZhbHVlcyAmJiAhaXRlbU1hdGNoO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBmaW5kTWF0Y2ggPSAoZWxlbWVudDogYW55KTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5kaXNwbGF5S2V5ID8gZWxlbWVudFt0aGlzLmRpc3BsYXlLZXldIDogZWxlbWVudDtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKSA9PT0gdGhpcy5zZWFyY2hWYWx1ZS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICB9O1xuXG4gICAgcHJvdGVjdGVkIG1hbmFnZVJlcXVpcmVkQXN0ZXJpc2soKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm5nQ29udHJvbCAmJiB0aGlzLm5nQ29udHJvbC5jb250cm9sLnZhbGlkYXRvcikge1xuICAgICAgICAgICAgLy8gUnVuIHRoZSB2YWxpZGF0aW9uIHdpdGggZW1wdHkgb2JqZWN0IHRvIGNoZWNrIGlmIHJlcXVpcmVkIGlzIGVuYWJsZWQuXG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IHRoaXMubmdDb250cm9sLmNvbnRyb2wudmFsaWRhdG9yKHt9IGFzIEFic3RyYWN0Q29udHJvbCk7XG4gICAgICAgICAgICB0aGlzLmlucHV0R3JvdXAuaXNSZXF1aXJlZCA9IGVycm9yICYmIGVycm9yLnJlcXVpcmVkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENvbnRhaW5zIGtleS12YWx1ZSBwYWlycyBvZiB0aGUgc2VsZWN0ZWQgdmFsdWVLZXlzIGFuZCB0aGVpciByZXNwLiBkaXNwbGF5S2V5cyAqL1xuICAgIHByb3RlY3RlZCByZWdpc3RlclJlbW90ZUVudHJpZXMoaWRzOiBhbnlbXSwgYWRkID0gdHJ1ZSkge1xuICAgICAgICBpZiAoYWRkKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSB0aGlzLmdldFZhbHVlRGlzcGxheVBhaXJzKGlkcyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlbW90ZVNlbGVjdGlvbltlbnRyeVt0aGlzLnZhbHVlS2V5XV0gPSBlbnRyeVt0aGlzLmRpc3BsYXlLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBpZHMpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fcmVtb3RlU2VsZWN0aW9uW2VudHJ5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvciBgaWQ6IGFueVtdYCByZXR1cm5zIGEgbWFwcGVkIGB7IFtjb21iby52YWx1ZUtleV06IGFueSwgW2NvbWJvLmRpc3BsYXlLZXldOiBhbnkgfVtdYFxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXRWYWx1ZURpc3BsYXlQYWlycyhpZHM6IGFueVtdKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZmlsdGVyKGVudHJ5ID0+IGlkcy5pbmRleE9mKGVudHJ5W3RoaXMudmFsdWVLZXldKSA+IC0xKS5tYXAoZSA9PiAoe1xuICAgICAgICAgICAgW3RoaXMudmFsdWVLZXldOiBlW3RoaXMudmFsdWVLZXldLFxuICAgICAgICAgICAgW3RoaXMuZGlzcGxheUtleV06IGVbdGhpcy5kaXNwbGF5S2V5XVxuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldFJlbW90ZVNlbGVjdGlvbihuZXdTZWxlY3Rpb246IGFueVtdLCBvbGRTZWxlY3Rpb246IGFueVtdKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKCFuZXdTZWxlY3Rpb24ubGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBJZiBuZXcgc2VsZWN0aW9uIGlzIGVtcHR5LCBjbGVhciBhbGwgaXRlbXNcbiAgICAgICAgICAgIHRoaXMucmVnaXN0ZXJSZW1vdGVFbnRyaWVzKG9sZFNlbGVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlbW92ZWRJdGVtcyA9IG9sZFNlbGVjdGlvbi5maWx0ZXIoZSA9PiBuZXdTZWxlY3Rpb24uaW5kZXhPZihlKSA8IDApO1xuICAgICAgICBjb25zdCBhZGRlZEl0ZW1zID0gbmV3U2VsZWN0aW9uLmZpbHRlcihlID0+IG9sZFNlbGVjdGlvbi5pbmRleE9mKGUpIDwgMCk7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJSZW1vdGVFbnRyaWVzKGFkZGVkSXRlbXMpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyUmVtb3RlRW50cmllcyhyZW1vdmVkSXRlbXMsIGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX3JlbW90ZVNlbGVjdGlvbikubWFwKGUgPT4gdGhpcy5fcmVtb3RlU2VsZWN0aW9uW2VdKS5qb2luKCcsICcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhYnN0cmFjdCBnZXQgZmlsdGVyZWREYXRhKCk6IGFueVtdIHwgbnVsbDtcbiAgICBwdWJsaWMgYWJzdHJhY3Qgc2V0IGZpbHRlcmVkRGF0YSh2YWw6IGFueVtdIHwgbnVsbCk7XG5cbiAgICBwdWJsaWMgYWJzdHJhY3QgaGFuZGxlT3BlbmVkKCk7XG4gICAgcHVibGljIGFic3RyYWN0IGZvY3VzU2VhcmNoSW5wdXQob3BlbmluZz86IGJvb2xlYW4pO1xuXG4gICAgcHVibGljIGFic3RyYWN0IHNlbGVjdChuZXdJdGVtOiBhbnkpOiB2b2lkO1xuICAgIHB1YmxpYyBhYnN0cmFjdCBzZWxlY3QobmV3SXRlbXM6IEFycmF5PGFueT4gfCBhbnksIGNsZWFyQ3VycmVudFNlbGVjdGlvbj86IGJvb2xlYW4sIGV2ZW50PzogRXZlbnQpOiB2b2lkO1xuXG4gICAgcHVibGljIGFic3RyYWN0IGRlc2VsZWN0KGl0ZW06IGFueSk6IHZvaWQ7XG4gICAgcHVibGljIGFic3RyYWN0IGRlc2VsZWN0KGl0ZW1zOiBBcnJheTxhbnk+LCBldmVudD86IEV2ZW50KTogdm9pZDtcblxuICAgIHB1YmxpYyBhYnN0cmFjdCB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkO1xuXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IHNldFNlbGVjdGlvbihuZXdTZWxlY3Rpb246IFNldDxhbnk+LCBldmVudD86IEV2ZW50KTogdm9pZDtcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgY3JlYXRlRGlzcGxheVRleHQobmV3U2VsZWN0aW9uOiBhbnlbXSwgb2xkU2VsZWN0aW9uOiBhbnlbXSk7XG59XG4iXX0=