@libs-ui/components-tags 0.2.66

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.
@@ -0,0 +1,716 @@
1
+ import { NgStyle, NgTemplateOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, computed, effect, inject, input, model, output, signal, untracked, viewChild } from '@angular/core';
3
+ import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
4
+ import { LibsUiComponentsInputsInputComponent } from '@libs-ui/components-inputs-input';
5
+ import { LibsUiComponentsLabelComponent } from '@libs-ui/components-label';
6
+ import { getFieldKeyByType, LibsUiComponentsListComponent } from '@libs-ui/components-list';
7
+ import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
8
+ import { LibsUiHttpRequestService } from '@libs-ui/services-http-request';
9
+ import { cloneDeep, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_VALID, ERROR_MESSAGE_PATTEN_VALID, escapeHtml, get, isNil, set, uuid } from '@libs-ui/utils';
10
+ import { TranslateModule } from '@ngx-translate/core';
11
+ import { debounceTime, Subject, takeUntil } from 'rxjs';
12
+ import { LibsUiComponentsTagsGetColorPipe } from './pipes/get-color.pipe';
13
+ import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "@ngx-translate/core";
16
+ export class LibsUiComponentsTagsComponent {
17
+ /* PROPERTY */
18
+ flagMouse = signal({ isMouseEnter: false, isMouseEnterContent: false });
19
+ loading = signal(false);
20
+ loadingDetail = signal(false);
21
+ keySearch = signal('');
22
+ valueInput = signal('');
23
+ itemsSelected = signal([]);
24
+ showList = signal(false);
25
+ positionList = signal(undefined);
26
+ keysSelected = signal([]);
27
+ disableWhenMaxItem = signal(false);
28
+ itemChangeUnSelect = signal(undefined);
29
+ focus = signal(false);
30
+ error = signal(undefined);
31
+ fieldKey = signal('id');
32
+ functionGetItemAutoAddList = computed(() => {
33
+ if (!this.enterAutoAddTagToList()) {
34
+ return;
35
+ }
36
+ return () => this.itemsSelected().filter(item => `${item[this.fieldKey()]}`.search(this.fakeId()) === 0).reverse();
37
+ });
38
+ fakeId = signal(uuid());
39
+ timeOutFlag = signal(undefined);
40
+ timeOutChangeSearch = signal(undefined);
41
+ timeOutCheckViewChange = signal(undefined);
42
+ timeoutClickOutside = signal(undefined);
43
+ clientHeight = signal(undefined);
44
+ itemsOfList = signal([]);
45
+ keySearchChange = new Subject();
46
+ keySearchChangeSub = signal(undefined);
47
+ tempIgnoreEmit = signal(false);
48
+ popoverFunctionControl = signal(undefined);
49
+ inputFunctionControl = signal(undefined);
50
+ typePopover = signal(undefined);
51
+ listFunctionControl = signal(undefined);
52
+ defaultItemsSelectedCurrent = signal(undefined);
53
+ onDestroy = new Subject();
54
+ /* INPUT */
55
+ classIncludePopover = input();
56
+ enterAutoAddTagToList = input(false);
57
+ checkExitIsLabelInclude = input();
58
+ checkExitByFields = input();
59
+ parentBorderWidth = input();
60
+ functionCheckPermissionCreateTag = input(() => true);
61
+ placeholder = input();
62
+ httpRequestDetailItemByIds = input();
63
+ fieldLabel = input('label');
64
+ maxItemInput = input();
65
+ zIndex = input();
66
+ config = input();
67
+ disable = input();
68
+ readonly = input();
69
+ labelConfig = input();
70
+ defaultItemsSelected = input();
71
+ defaultKeysSelected = input();
72
+ listSearchConfig = input();
73
+ isSearchOnline = input(false);
74
+ listSearchPadding = input();
75
+ listDividerClassInclude = input();
76
+ listConfig = input();
77
+ listButtonsOther = input();
78
+ listClickExactly = input();
79
+ listBackgroundListCustom = input();
80
+ listMaxItemShow = input();
81
+ listHiddenInputSearchWhenHasSearchConfig = input();
82
+ removeTextSearchWhenBlurInput = input(true);
83
+ keysHiddenItem = model();
84
+ keysDisableItem = input();
85
+ ignoreEmitWhenSameDataSelected = input();
86
+ singleSelected = input();
87
+ classIncludeTagItem = input();
88
+ classIconRemoveTagItem = input();
89
+ showBorderActiveWhenFocusInput = input();
90
+ fieldGetImage = input();
91
+ imageSize = input(16);
92
+ fieldGetTextAvatar = input('user');
93
+ classAvatarInclude = input();
94
+ getLastTextAfterSpace = input();
95
+ validRequired = input();
96
+ validMaxItemSelected = input();
97
+ validPattern = input();
98
+ showListBellow = input();
99
+ hiddenInputWhenReadonly = input();
100
+ /* OUTPUT */
101
+ outSelectMultiItem = output();
102
+ outValidEvent = output();
103
+ outFunctionsControl = output();
104
+ outClickButtonOther = output();
105
+ outShowListEvent = output();
106
+ outChangStageFlagMouse = output();
107
+ outLoadingGetDetailSelected = output();
108
+ /* VIEW CHILD */
109
+ tagsEl = viewChild.required('tagsEl');
110
+ /* INJECT*/
111
+ httpRequestService = inject(LibsUiHttpRequestService);
112
+ constructor() {
113
+ effect(() => {
114
+ const maxItemInput = this.maxItemInput();
115
+ untracked(() => {
116
+ this.disableWhenMaxItem.set(false);
117
+ if (maxItemInput && maxItemInput <= this.itemsSelected().length) {
118
+ this.disableWhenMaxItem.set(true);
119
+ }
120
+ });
121
+ });
122
+ effect(() => {
123
+ const listConfig = this.listConfig();
124
+ untracked(() => {
125
+ if (listConfig) {
126
+ this.fieldKey.set(getFieldKeyByType(listConfig, 'id'));
127
+ }
128
+ });
129
+ });
130
+ effect(() => {
131
+ const currentItems = this.defaultItemsSelected() || [];
132
+ untracked(() => {
133
+ const previousItems = this.defaultItemsSelectedCurrent() || [];
134
+ this.defaultItemsSelectedCurrent.set(this.defaultItemsSelected());
135
+ if (previousItems.length !== currentItems.length) {
136
+ this.updateItemsSelected(currentItems);
137
+ return;
138
+ }
139
+ for (const prevItem of previousItems) {
140
+ if (!currentItems.some(item => get(item, this.fieldKey()) === get(prevItem, this.fieldKey()))) {
141
+ this.updateItemsSelected(currentItems);
142
+ break;
143
+ }
144
+ }
145
+ });
146
+ });
147
+ effect(() => {
148
+ const currentValue = this.defaultKeysSelected() || [];
149
+ untracked(() => {
150
+ const previousValue = this.keysSelected() || [];
151
+ if (previousValue.length !== currentValue.length) {
152
+ this.getDetailByIds(currentValue);
153
+ return;
154
+ }
155
+ const keysNew = currentValue.filter(key => !this.itemsSelected().some(item => item[this.fieldKey()] === key));
156
+ if (keysNew.length) {
157
+ this.getDetailByIds(keysNew);
158
+ }
159
+ });
160
+ });
161
+ }
162
+ ngOnInit() {
163
+ if (!this.config()) {
164
+ return;
165
+ }
166
+ const httpRequestDetailItemByIds = this.httpRequestDetailItemByIds();
167
+ if (httpRequestDetailItemByIds && (!httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue || !httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue?.detailById)) {
168
+ throw 'Config getDetailByIds yêu cầu tối thiểu các tham số guideAutoUpdateArgumentsValue, detailById';
169
+ }
170
+ const preprocessor = (keys) => {
171
+ if (!keys || !(keys instanceof Array) || !keys.length) {
172
+ return '';
173
+ }
174
+ return keys.join(';');
175
+ };
176
+ if (httpRequestDetailItemByIds?.guideAutoUpdateArgumentsValue?.detailById) {
177
+ httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue.detailById.fieldGetValue = httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue.detailById.fieldGetValue ?? 'keys';
178
+ httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue.detailById.preprocessor = httpRequestDetailItemByIds.guideAutoUpdateArgumentsValue.detailById.preprocessor ?? preprocessor;
179
+ }
180
+ this.outFunctionsControl.emit({
181
+ valid: this.checkValid.bind(this),
182
+ removeList: async () => this.popoverFunctionControl()?.removePopoverOverlay(),
183
+ updateLabel: this.updateLabel.bind(this),
184
+ clearItemSelected: this.clearItemSelected.bind(this),
185
+ clearKeySearch: () => this.handlerValueChangeSearch(''),
186
+ focusInput: () => this.focusInput(),
187
+ getFakeId: async () => this.fakeId(),
188
+ createTag: this.handlerEnterEvent.bind(this),
189
+ removeItemSelected: this.handlerRemoveItemSelected.bind(this),
190
+ resetError: this.resetError.bind(this),
191
+ resetToDefaultDataSelected: this.resetToDefaultDataSelected.bind(this),
192
+ updateItemSelectedDisable: this.updateItemSelectedDisable.bind(this),
193
+ refreshListData: this.refreshListData.bind(this),
194
+ setError: this.setError.bind(this)
195
+ });
196
+ }
197
+ async setError(message) {
198
+ this.error.set({ message });
199
+ }
200
+ handlerPopoverFunctionControlEvent(event) {
201
+ this.popoverFunctionControl.set(event);
202
+ }
203
+ async updateLabel() {
204
+ if (!this.itemsSelected() || !this.itemsSelected().length) {
205
+ return;
206
+ }
207
+ this.itemsSelected.update(items => {
208
+ items.forEach(item => this.updateFieldLabel(item));
209
+ return [...items];
210
+ });
211
+ }
212
+ updateFieldLabel(item) {
213
+ const ref = get(item, 'ref') || item;
214
+ const getValue = this.config()?.getValue;
215
+ set(item, 'fieldLabel', `${get(ref, this.fieldLabel()) || ref.label || ref.name || ' '}`);
216
+ if (getValue) {
217
+ set(item, 'fieldLabel', getValue(ref) || ' ');
218
+ }
219
+ }
220
+ async clearItemSelected(ignoreValid = false) {
221
+ if (!this.itemsSelected() || !this.itemsSelected().length) {
222
+ return;
223
+ }
224
+ const length = this.itemsSelected().length - 1;
225
+ this.tempIgnoreEmit.set(true);
226
+ this.itemsSelected().forEach((item, index) => {
227
+ if (index === length) {
228
+ this.tempIgnoreEmit.set(false);
229
+ }
230
+ this.handlerRemoveItemSelected({ stopPropagation: () => { return; } }, item, ignoreValid);
231
+ });
232
+ }
233
+ updateItemsSelected(itemsSelected, ignoreValidate = true, ignoreEmitKeySelectedWhenItemsNotExitsEmpty) {
234
+ if (!itemsSelected || !itemsSelected.length) {
235
+ return;
236
+ }
237
+ const itemsNotExits = [];
238
+ itemsSelected.forEach(item => {
239
+ if (!item) {
240
+ return;
241
+ }
242
+ let fieldLabel = `${get(item, this.fieldLabel()) || get(item, 'label') || get(item, 'name') || ' '}`;
243
+ const getValue = this.config()?.getValue;
244
+ if (getValue) {
245
+ fieldLabel = getValue(item) || ' ';
246
+ }
247
+ const itemExits = this.checkExits(fieldLabel, get(item, this.fieldKey()));
248
+ if (itemExits?.isItemSelected) {
249
+ Object.assign(itemExits.item, item);
250
+ return;
251
+ }
252
+ itemsNotExits.push(item);
253
+ });
254
+ this.processData(itemsNotExits, ignoreValidate, ignoreEmitKeySelectedWhenItemsNotExitsEmpty);
255
+ }
256
+ handlerPopoverEvent(type) {
257
+ this.typePopover.set(type);
258
+ if (type === 'click') {
259
+ return;
260
+ }
261
+ if (type === 'remove') {
262
+ this.showList.set(false);
263
+ this.outShowListEvent.emit(false);
264
+ this.inputFunctionControl()?.blur();
265
+ return;
266
+ }
267
+ this.showList.set(true);
268
+ this.outShowListEvent.emit(true);
269
+ this.inputFunctionControl()?.focus();
270
+ }
271
+ handlerPopoverContentEvent(position) {
272
+ if (this.positionList() === position) {
273
+ return;
274
+ }
275
+ this.positionList.set(position);
276
+ }
277
+ async handlerRemoveItemSelected(event, itemRemove, ignoreValid) {
278
+ event.stopPropagation();
279
+ this.flagMouse.set({ isMouseEnter: true, isMouseEnterContent: true });
280
+ this.timeOutFlag.set(setTimeout(() => this.flagMouse.set({ isMouseEnter: false, isMouseEnterContent: false }), 250));
281
+ this.itemsSelected.update(items => items.filter(item => ((isNil(get(itemRemove, this.fieldKey())) || isNil(get(item, this.fieldKey()))) && get(itemRemove, 'fieldLabel').trim() !== item.fieldLabel.trim() || (!isNil(get(itemRemove, this.fieldKey())) && !isNil(get(item, this.fieldKey())) && get(itemRemove, this.fieldKey()) !== get(item, this.fieldKey())))));
282
+ this.itemChangeUnSelect.set(itemRemove);
283
+ if (itemRemove && !isNil(get(itemRemove, this.fieldKey())) && `${get(itemRemove, this.fieldKey())}`.search(this.fakeId()) >= 0) {
284
+ this.keysHiddenItem.update(items => ([...items || [], get(itemRemove, this.fieldKey())]));
285
+ }
286
+ this.keysSelected.set(Array.from(new Set(this.itemsSelected().map(item => get(item, this.fieldKey())))));
287
+ this.disableWhenMaxItem.set(false);
288
+ const maxItemInput = this.maxItemInput();
289
+ if (maxItemInput && maxItemInput <= this.itemsSelected().length) {
290
+ this.disableWhenMaxItem.set(true);
291
+ }
292
+ if (!this.showList()) {
293
+ this.outSelectMultiItem.emit(this.getItemSelected());
294
+ this.checkViewChange(true, ignoreValid);
295
+ return;
296
+ }
297
+ if (this.showList()) {
298
+ this.tempIgnoreEmit.set(true);
299
+ }
300
+ if (!ignoreValid) {
301
+ this.checkValid();
302
+ }
303
+ this.tempIgnoreEmit.set(false);
304
+ }
305
+ handlerInputFunctionControl(event) {
306
+ this.inputFunctionControl.set(event);
307
+ }
308
+ handlerFocusAndBlurEvent(event) {
309
+ this.focus.set(false);
310
+ if (event.name === 'focus') {
311
+ this.focus.set(true);
312
+ }
313
+ if (event.name === 'blur' && this.typePopover()?.includes('mouseleave') && this.validRequired() && (!this.itemsSelected() || !this.itemsSelected().length)) {
314
+ this.checkValid();
315
+ }
316
+ }
317
+ handlerClickOutside(event) {
318
+ event.stopPropagation();
319
+ clearTimeout(this.timeoutClickOutside());
320
+ this.timeoutClickOutside.set(setTimeout(() => {
321
+ if (this.showList() || !this.removeTextSearchWhenBlurInput()) {
322
+ return;
323
+ }
324
+ this.valueInput.set('');
325
+ this.keySearch.set('');
326
+ this.inputFunctionControl()?.resetValue();
327
+ }, 250));
328
+ }
329
+ async handlerEnterEvent() {
330
+ if (!this.valueInput() || !`${this.valueInput()}`.trim()) {
331
+ return;
332
+ }
333
+ if (this.config()?.ignoreEnterCreateNewItem) {
334
+ const itemExits = this.checkExits();
335
+ if (!itemExits || itemExits.isItemSelected) {
336
+ return;
337
+ }
338
+ this.processData([itemExits.item]);
339
+ this.handlerValueChangeSearch('');
340
+ return;
341
+ }
342
+ if (!this.functionCheckPermissionCreateTag()()) {
343
+ return;
344
+ }
345
+ const itemExits = this.checkExits();
346
+ const valueInput = `${this.valueInput()}`.trim();
347
+ const newItem = { [this.fieldLabel()]: valueInput };
348
+ if (this.fieldKey()) {
349
+ newItem[this.fieldKey()] = `${this.fakeId()}${valueInput}${uuid()}`;
350
+ }
351
+ if (!itemExits) {
352
+ if (this.checkPattern([newItem])) {
353
+ const itemBuildValue = { ...newItem };
354
+ const buildValue = this.config()?.buildValue;
355
+ if (buildValue) {
356
+ buildValue(itemBuildValue, newItem[this.fieldLabel()]);
357
+ }
358
+ newItem[this.fieldLabel()] = itemBuildValue[this.fieldLabel()];
359
+ if (this.enterAutoAddTagToList()) {
360
+ this.listFunctionControl()?.updateData({ newData: [newItem], functionCustomAddDataToStore: (newData, store) => store.update(value => ([...newData, ...value])) });
361
+ }
362
+ this.processData([newItem]);
363
+ this.handlerValueChangeSearch('');
364
+ }
365
+ return;
366
+ }
367
+ if (itemExits.isItemSelected) {
368
+ return;
369
+ }
370
+ this.processData([itemExits.item]);
371
+ this.handlerValueChangeSearch('');
372
+ }
373
+ async handlerValueChangeSearch(value) {
374
+ this.valueInput.set(`${value}`);
375
+ if (!`${value || ''}`.trim()) {
376
+ this.keySearchChangeSub()?.unsubscribe();
377
+ this.keySearchChangeSub.set(undefined);
378
+ this.timeOutChangeSearch.set(setTimeout(() => this.keySearch.set('')));
379
+ if (!this.config()?.ignoreEnterCreateNewItem) {
380
+ this.checkValid();
381
+ }
382
+ return;
383
+ }
384
+ if (this.config()?.ignoreInput) {
385
+ return;
386
+ }
387
+ if (!this.keySearchChangeSub()) {
388
+ this.setEventKeySearch();
389
+ }
390
+ this.keySearchChange.next(`${(value || '')}`.trim());
391
+ }
392
+ setEventKeySearch() {
393
+ if (this.keySearchChangeSub()) {
394
+ return;
395
+ }
396
+ this.keySearchChangeSub.set(this.keySearchChange.pipe(debounceTime(1500), takeUntil(this.onDestroy)).subscribe(value => this.keySearch.set(`${(value || '')}`.trim())));
397
+ }
398
+ processData(items, ignoreValidate = false, ignoreEmitKeySelectedWhenItemsNotExitsEmpty) {
399
+ if (!items || !items.length) {
400
+ const itemsSelected = this.getItemSelected();
401
+ if (!ignoreEmitKeySelectedWhenItemsNotExitsEmpty) {
402
+ this.outSelectMultiItem.emit(itemsSelected);
403
+ }
404
+ this.keysSelected.set(Array.from(new Set(itemsSelected?.map(item => get(item, this.fieldKey())))));
405
+ this.checkViewChange(false, ignoreValidate);
406
+ return;
407
+ }
408
+ const itemsMapping = items.map(item => {
409
+ const ref = get(item, 'ref') || item;
410
+ item = cloneDeep(ref);
411
+ set(item, 'ref', ref);
412
+ this.updateFieldLabel(item);
413
+ const getDisableItem = this.config()?.getDisableItem;
414
+ const getStyles = this.config()?.getStyles;
415
+ const getStylesTagSpecific = this.config()?.getStylesTagSpecific;
416
+ if (getDisableItem) {
417
+ set(item, 'disableItem', getDisableItem(item));
418
+ }
419
+ if (getStyles) {
420
+ set(item, 'ngStyles', getStyles(item));
421
+ }
422
+ if (getStylesTagSpecific) {
423
+ const type = getStylesTagSpecific(item);
424
+ if (type === 'specific_violet_color') {
425
+ set(item, 'ngStyles', { color: '#7239EA', backgroundColor: '#F1EBFD' });
426
+ }
427
+ }
428
+ return item;
429
+ });
430
+ this.itemsSelected.update(items => [...items, ...itemsMapping]);
431
+ this.keysSelected.set(Array.from(new Set(this.itemsSelected().map(item => get(item, this.fieldKey())))));
432
+ this.outSelectMultiItem.emit(this.getItemSelected());
433
+ this.checkViewChange(false, ignoreValidate);
434
+ }
435
+ handlerDataChange(items) {
436
+ this.itemsOfList.set(items);
437
+ this.popoverFunctionControl()?.updatePopoverOverlayPosition();
438
+ if (!this.config()?.ignoreInput) {
439
+ this.inputFunctionControl()?.focus();
440
+ }
441
+ }
442
+ handlerLoading(event) {
443
+ this.loading.set(event);
444
+ }
445
+ checkViewChange(ignoreScrollBottom, ignoreValidate = false) {
446
+ this.disableWhenMaxItem.set(false);
447
+ const maxItemInput = this.maxItemInput();
448
+ if (maxItemInput && maxItemInput <= this.itemsSelected().length) {
449
+ this.disableWhenMaxItem.set(true);
450
+ }
451
+ this.timeOutCheckViewChange.set((setTimeout(() => {
452
+ const scrollHeight = this.tagsEl()?.nativeElement.scrollHeight;
453
+ if (!isNil(scrollHeight) && this.clientHeight() !== scrollHeight && this.positionList() !== 'top') {
454
+ this.popoverFunctionControl()?.updatePopoverOverlayPosition();
455
+ }
456
+ if (!ignoreScrollBottom && this.tagsEl() && this.tagsEl().nativeElement) {
457
+ this.tagsEl().nativeElement.scrollTop = scrollHeight;
458
+ }
459
+ this.clientHeight.set(scrollHeight);
460
+ }, 250)));
461
+ if (!ignoreValidate) {
462
+ this.checkValid();
463
+ }
464
+ }
465
+ checkExits(label, id) {
466
+ let itemExits;
467
+ if (!isNil(id) && !`${id}`.includes(this.fakeId()) && this.fieldKey()) {
468
+ itemExits = this.itemsSelected().find(item => !isNil(get(item, this.fieldKey())) && `${get(item, this.fieldKey())}`.trim() === `${id}`);
469
+ if (itemExits) {
470
+ return { item: itemExits, isItemSelected: !!itemExits };
471
+ }
472
+ return;
473
+ }
474
+ if (!label) {
475
+ label = `${(this.valueInput || '')}`.trim();
476
+ }
477
+ itemExits = this.itemsSelected().find(item => !isNil(get(item, 'fieldLabel')) && (get(item, 'fieldLabel').trim() === label?.trim()) || (this.checkExitIsLabelInclude() && get(item, 'fieldLabel').trim().includes(label?.trim())) || (this.checkExitByFields() && this.checkExitByFields()?.some(field => get(item, field)?.trim() === label?.trim() || get(item, field)?.trim() === escapeHtml(label?.trim() || '') || escapeHtml(get(item, field)?.trim() || ' ') === escapeHtml(label?.trim() || ''))));
478
+ if (itemExits) {
479
+ return { item: itemExits, isItemSelected: true };
480
+ }
481
+ itemExits = this.itemsOfList().find(item => !isNil(get(item, 'fieldLabel')) && (get(item, 'fieldLabel').trim().includes() === label?.trim()) || (this.checkExitIsLabelInclude() && get(item, 'fieldLabel').trim().includes(label?.trim())) || (this.checkExitByFields() && this.checkExitByFields()?.some(field => get(item, field)?.trim() === label?.trim() || escapeHtml(get(item, field)?.trim() || ' ') === escapeHtml(label?.trim() || '') || get(item, field)?.trim() === escapeHtml(label?.trim() || ''))));
482
+ if (itemExits) {
483
+ return { item: itemExits, isItemSelected: false };
484
+ }
485
+ return;
486
+ }
487
+ handlerSelectedKey(event) {
488
+ if (!event || !event.item) {
489
+ return;
490
+ }
491
+ if (!isNil(event?.key)) {
492
+ this.popoverFunctionControl()?.removePopoverOverlay();
493
+ }
494
+ if (this.itemsSelected()[0]) {
495
+ this.tempIgnoreEmit.set(true);
496
+ this.handlerRemoveItemSelected({ stopPropagation: () => { return; } }, this.itemsSelected()[0], this.itemsSelected()[0].disableItem);
497
+ this.tempIgnoreEmit.set(false);
498
+ }
499
+ this.updateItemsSelected([event.item], !!this.itemsSelected()[0]); // Bug #36075
500
+ }
501
+ getFlagEmitSelectedItem(keys) {
502
+ if (!this.ignoreEmitWhenSameDataSelected() || keys.length !== this.itemsSelected().length) {
503
+ return false;
504
+ }
505
+ for (const key of keys) {
506
+ if (!this.itemsSelected().some(item => get(item, this.fieldKey()) === key)) {
507
+ return false;
508
+ }
509
+ }
510
+ return true;
511
+ }
512
+ async handlerSelectMultiKey(event) {
513
+ if (!event) {
514
+ return;
515
+ }
516
+ const keys = [];
517
+ const items = [];
518
+ if (event.keys && event.keys.length && (!event.mapKeys || !event.mapKeys.length)) {
519
+ keys.push(...event.keys);
520
+ }
521
+ const ignoreEmitKeySelectedWhenItemsNotExitsEmpty = this.getFlagEmitSelectedItem(cloneDeep(event.keys ?? []));
522
+ event.mapKeys.forEach(mapKey => {
523
+ if (isNil(mapKey.key)) {
524
+ return;
525
+ }
526
+ if (mapKey.item) {
527
+ return items.push(mapKey.item);
528
+ }
529
+ if (!Array.isArray(this.itemsSelected)) {
530
+ return keys.push(mapKey.key);
531
+ }
532
+ const item = this.itemsSelected.find(item => get(item, this.fieldKey()) === mapKey.key);
533
+ if (item) {
534
+ return items.push(item);
535
+ }
536
+ return keys.push(mapKey.key);
537
+ });
538
+ if (keys.length) {
539
+ const resultData = await this.getDetailByIds(keys, true);
540
+ items.push(...resultData);
541
+ }
542
+ const messageEmpty = this.validRequired()?.message || ERROR_MESSAGE_EMPTY_VALID;
543
+ let ignoreValidate = true;
544
+ if (messageEmpty === this.error()?.message) {
545
+ ignoreValidate = false;
546
+ }
547
+ const itemRemove = this.itemsSelected().find(itemSelected => get(itemSelected, this.fieldKey()) && !(items.some(item => get(itemSelected, this.fieldKey()) === get(item, this.fieldKey()))));
548
+ this.itemsSelected.update(itemsSelected => itemsSelected.filter(itemSelected => !get(itemSelected, this.fieldKey()) || (event.keys.length && items.some(item => get(itemSelected, this.fieldKey()) === get(item, this.fieldKey())))));
549
+ if (itemRemove) {
550
+ if (this.enterAutoAddTagToList() && !isNil(get(itemRemove, this.fieldKey())) && `${get(itemRemove, this.fieldKey())}`.search(this.fakeId()) >= 0) {
551
+ this.keysHiddenItem.update(items => [...(items || []), get(itemRemove, this.fieldKey())]);
552
+ }
553
+ }
554
+ if (!event.keys.length) {
555
+ this.checkValid();
556
+ this.keysSelected.set(Array.from(new Set(this.itemsSelected()?.map(item => get(item, this.fieldKey())))));
557
+ this.outSelectMultiItem.emit(this.getItemSelected());
558
+ this.checkViewChange(false, ignoreValidate);
559
+ return;
560
+ }
561
+ this.updateItemsSelected(items, ignoreValidate, ignoreEmitKeySelectedWhenItemsNotExitsEmpty);
562
+ this.checkValid();
563
+ }
564
+ async getDetailByIds(keys, isResponseData) {
565
+ const httpRequestDetailItemByIds = this.httpRequestDetailItemByIds();
566
+ if (!httpRequestDetailItemByIds || this.loadingDetail() || !(keys instanceof Array) || !keys.length) {
567
+ return [];
568
+ }
569
+ this.updateLoadingDetail(true);
570
+ const cloneHttpDetailConfig = cloneDeep(httpRequestDetailItemByIds);
571
+ try {
572
+ const { argumentsValue, guideAutoUpdateArgumentsValue } = cloneHttpDetailConfig;
573
+ if (!guideAutoUpdateArgumentsValue || !guideAutoUpdateArgumentsValue.detailById) {
574
+ return [];
575
+ }
576
+ guideAutoUpdateArgumentsValue.detailById.fieldGetValue = 'keys';
577
+ this.httpRequestService.updateArguments(argumentsValue, { keys: keys }, {}, '', false, false, guideAutoUpdateArgumentsValue);
578
+ const result = (await this.httpRequestService.callApi(cloneHttpDetailConfig));
579
+ if (!isResponseData) {
580
+ this.updateItemsSelected(result.data || []);
581
+ this.updateLoadingDetail(false);
582
+ return [];
583
+ }
584
+ this.updateLoadingDetail(false);
585
+ return result.data || [];
586
+ }
587
+ catch (error) {
588
+ console.log(error);
589
+ this.updateLoadingDetail(false);
590
+ }
591
+ return [];
592
+ }
593
+ async checkValid() {
594
+ const valid = this.itemsSelected() && this.itemsSelected().length ? true : false;
595
+ const stateError = !!this.error();
596
+ this.error.set(undefined);
597
+ if (this.validRequired() && !valid) {
598
+ this.error.set({ ...this.validRequired(), message: this.validRequired()?.message || ERROR_MESSAGE_EMPTY_VALID });
599
+ }
600
+ if (!this.error()) {
601
+ this.checkPattern(this.itemsSelected());
602
+ this.checkMaxItemSelectedValid();
603
+ }
604
+ if (!this.tempIgnoreEmit()) {
605
+ this.outValidEvent.emit(!this.error());
606
+ }
607
+ if (stateError !== !!this.error()) {
608
+ this.popoverFunctionControl()?.updatePopoverOverlayPosition();
609
+ }
610
+ return !this.error();
611
+ }
612
+ checkMaxItemSelectedValid() {
613
+ const validMaxItemSelected = this.validMaxItemSelected();
614
+ if (validMaxItemSelected && this.itemsSelected().length > validMaxItemSelected.value) {
615
+ this.error.set({ ...validMaxItemSelected, message: validMaxItemSelected.message || ERROR_MESSAGE_MAX_VALID, interpolateParams: { value: validMaxItemSelected.value } });
616
+ return false;
617
+ }
618
+ return true;
619
+ }
620
+ checkPattern(items) {
621
+ const validPattern = this.validPattern();
622
+ if (!validPattern || !validPattern.length || !items || !items.length) {
623
+ return true;
624
+ }
625
+ for (const valid of validPattern) {
626
+ if (valid.pattern && items.some(item => !valid.pattern.test(get(item, this.fieldLabel())))) {
627
+ this.error.set({ ...valid, message: valid.message || ERROR_MESSAGE_PATTEN_VALID });
628
+ return false;
629
+ }
630
+ }
631
+ return true;
632
+ }
633
+ handlerClickButtonOther(event) {
634
+ this.outClickButtonOther.emit(event);
635
+ }
636
+ getItemSelected() {
637
+ return this.itemsSelected().map(item => {
638
+ const itemMap = { ...item };
639
+ if (!isNil(get(itemMap, this.fieldKey())) && `${get(itemMap, this.fieldKey())}`.search(this.fakeId()) === 0) {
640
+ set(itemMap, this.fieldKey(), '');
641
+ }
642
+ return itemMap;
643
+ });
644
+ }
645
+ async resetToDefaultDataSelected(itemSelected) {
646
+ if (itemSelected && Array.isArray(itemSelected)) {
647
+ this.itemsSelected.set([]);
648
+ this.updateItemsSelected(itemSelected);
649
+ return;
650
+ }
651
+ itemSelected = new Array();
652
+ if (!this.fieldKey()) {
653
+ return;
654
+ }
655
+ const defaultKeysSelected = this.defaultKeysSelected();
656
+ if (defaultKeysSelected && Array.isArray(defaultKeysSelected)) {
657
+ this.itemsSelected.set([]);
658
+ this.getDetailByIds(defaultKeysSelected);
659
+ return;
660
+ }
661
+ const defaultItemsSelected = this.defaultItemsSelected();
662
+ if (defaultItemsSelected && Array.isArray(defaultItemsSelected)) {
663
+ this.itemsSelected.set([]);
664
+ this.updateItemsSelected(defaultItemsSelected);
665
+ return;
666
+ }
667
+ }
668
+ handlerFunctionControlList(event) {
669
+ this.listFunctionControl.set(event);
670
+ }
671
+ async focusInput() {
672
+ this.inputFunctionControl()?.focus();
673
+ }
674
+ handlerChangeFlagMouse(event) {
675
+ this.outChangStageFlagMouse.emit(event);
676
+ }
677
+ handlerChangStageFlagMouse(flag) {
678
+ this.flagMouse.set(flag);
679
+ }
680
+ async resetError() {
681
+ this.error.set(undefined);
682
+ }
683
+ updateLoadingDetail(event) {
684
+ this.loadingDetail.set(event);
685
+ this.outLoadingGetDetailSelected.emit(event);
686
+ }
687
+ async updateItemSelectedDisable() {
688
+ const getDisableItem = this.config()?.getDisableItem;
689
+ if (!getDisableItem) {
690
+ return;
691
+ }
692
+ this.itemsSelected.update(itemsSelected => itemsSelected.map(item => ({ ...item, disableItem: getDisableItem(item) })));
693
+ }
694
+ async refreshListData() {
695
+ this.listFunctionControl()?.refresh();
696
+ }
697
+ ngOnDestroy() {
698
+ this.onDestroy.next();
699
+ clearTimeout(this.timeOutFlag());
700
+ clearTimeout(this.timeOutChangeSearch());
701
+ clearTimeout(this.timeOutCheckViewChange());
702
+ clearTimeout(this.timeoutClickOutside());
703
+ }
704
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTagsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsTagsComponent, isStandalone: true, selector: "libs_ui-components-tags", inputs: { classIncludePopover: { classPropertyName: "classIncludePopover", publicName: "classIncludePopover", isSignal: true, isRequired: false, transformFunction: null }, enterAutoAddTagToList: { classPropertyName: "enterAutoAddTagToList", publicName: "enterAutoAddTagToList", isSignal: true, isRequired: false, transformFunction: null }, checkExitIsLabelInclude: { classPropertyName: "checkExitIsLabelInclude", publicName: "checkExitIsLabelInclude", isSignal: true, isRequired: false, transformFunction: null }, checkExitByFields: { classPropertyName: "checkExitByFields", publicName: "checkExitByFields", isSignal: true, isRequired: false, transformFunction: null }, parentBorderWidth: { classPropertyName: "parentBorderWidth", publicName: "parentBorderWidth", isSignal: true, isRequired: false, transformFunction: null }, functionCheckPermissionCreateTag: { classPropertyName: "functionCheckPermissionCreateTag", publicName: "functionCheckPermissionCreateTag", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, httpRequestDetailItemByIds: { classPropertyName: "httpRequestDetailItemByIds", publicName: "httpRequestDetailItemByIds", isSignal: true, isRequired: false, transformFunction: null }, fieldLabel: { classPropertyName: "fieldLabel", publicName: "fieldLabel", isSignal: true, isRequired: false, transformFunction: null }, maxItemInput: { classPropertyName: "maxItemInput", publicName: "maxItemInput", isSignal: true, isRequired: false, transformFunction: null }, zIndex: { classPropertyName: "zIndex", publicName: "zIndex", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, disable: { classPropertyName: "disable", publicName: "disable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, labelConfig: { classPropertyName: "labelConfig", publicName: "labelConfig", isSignal: true, isRequired: false, transformFunction: null }, defaultItemsSelected: { classPropertyName: "defaultItemsSelected", publicName: "defaultItemsSelected", isSignal: true, isRequired: false, transformFunction: null }, defaultKeysSelected: { classPropertyName: "defaultKeysSelected", publicName: "defaultKeysSelected", isSignal: true, isRequired: false, transformFunction: null }, listSearchConfig: { classPropertyName: "listSearchConfig", publicName: "listSearchConfig", isSignal: true, isRequired: false, transformFunction: null }, isSearchOnline: { classPropertyName: "isSearchOnline", publicName: "isSearchOnline", isSignal: true, isRequired: false, transformFunction: null }, listSearchPadding: { classPropertyName: "listSearchPadding", publicName: "listSearchPadding", isSignal: true, isRequired: false, transformFunction: null }, listDividerClassInclude: { classPropertyName: "listDividerClassInclude", publicName: "listDividerClassInclude", isSignal: true, isRequired: false, transformFunction: null }, listConfig: { classPropertyName: "listConfig", publicName: "listConfig", isSignal: true, isRequired: false, transformFunction: null }, listButtonsOther: { classPropertyName: "listButtonsOther", publicName: "listButtonsOther", isSignal: true, isRequired: false, transformFunction: null }, listClickExactly: { classPropertyName: "listClickExactly", publicName: "listClickExactly", isSignal: true, isRequired: false, transformFunction: null }, listBackgroundListCustom: { classPropertyName: "listBackgroundListCustom", publicName: "listBackgroundListCustom", isSignal: true, isRequired: false, transformFunction: null }, listMaxItemShow: { classPropertyName: "listMaxItemShow", publicName: "listMaxItemShow", isSignal: true, isRequired: false, transformFunction: null }, listHiddenInputSearchWhenHasSearchConfig: { classPropertyName: "listHiddenInputSearchWhenHasSearchConfig", publicName: "listHiddenInputSearchWhenHasSearchConfig", isSignal: true, isRequired: false, transformFunction: null }, removeTextSearchWhenBlurInput: { classPropertyName: "removeTextSearchWhenBlurInput", publicName: "removeTextSearchWhenBlurInput", isSignal: true, isRequired: false, transformFunction: null }, keysHiddenItem: { classPropertyName: "keysHiddenItem", publicName: "keysHiddenItem", isSignal: true, isRequired: false, transformFunction: null }, keysDisableItem: { classPropertyName: "keysDisableItem", publicName: "keysDisableItem", isSignal: true, isRequired: false, transformFunction: null }, ignoreEmitWhenSameDataSelected: { classPropertyName: "ignoreEmitWhenSameDataSelected", publicName: "ignoreEmitWhenSameDataSelected", isSignal: true, isRequired: false, transformFunction: null }, singleSelected: { classPropertyName: "singleSelected", publicName: "singleSelected", isSignal: true, isRequired: false, transformFunction: null }, classIncludeTagItem: { classPropertyName: "classIncludeTagItem", publicName: "classIncludeTagItem", isSignal: true, isRequired: false, transformFunction: null }, classIconRemoveTagItem: { classPropertyName: "classIconRemoveTagItem", publicName: "classIconRemoveTagItem", isSignal: true, isRequired: false, transformFunction: null }, showBorderActiveWhenFocusInput: { classPropertyName: "showBorderActiveWhenFocusInput", publicName: "showBorderActiveWhenFocusInput", isSignal: true, isRequired: false, transformFunction: null }, fieldGetImage: { classPropertyName: "fieldGetImage", publicName: "fieldGetImage", isSignal: true, isRequired: false, transformFunction: null }, imageSize: { classPropertyName: "imageSize", publicName: "imageSize", isSignal: true, isRequired: false, transformFunction: null }, fieldGetTextAvatar: { classPropertyName: "fieldGetTextAvatar", publicName: "fieldGetTextAvatar", isSignal: true, isRequired: false, transformFunction: null }, classAvatarInclude: { classPropertyName: "classAvatarInclude", publicName: "classAvatarInclude", isSignal: true, isRequired: false, transformFunction: null }, getLastTextAfterSpace: { classPropertyName: "getLastTextAfterSpace", publicName: "getLastTextAfterSpace", isSignal: true, isRequired: false, transformFunction: null }, validRequired: { classPropertyName: "validRequired", publicName: "validRequired", isSignal: true, isRequired: false, transformFunction: null }, validMaxItemSelected: { classPropertyName: "validMaxItemSelected", publicName: "validMaxItemSelected", isSignal: true, isRequired: false, transformFunction: null }, validPattern: { classPropertyName: "validPattern", publicName: "validPattern", isSignal: true, isRequired: false, transformFunction: null }, showListBellow: { classPropertyName: "showListBellow", publicName: "showListBellow", isSignal: true, isRequired: false, transformFunction: null }, hiddenInputWhenReadonly: { classPropertyName: "hiddenInputWhenReadonly", publicName: "hiddenInputWhenReadonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { keysHiddenItem: "keysHiddenItemChange", outSelectMultiItem: "outSelectMultiItem", outValidEvent: "outValidEvent", outFunctionsControl: "outFunctionsControl", outClickButtonOther: "outClickButtonOther", outShowListEvent: "outShowListEvent", outChangStageFlagMouse: "outChangStageFlagMouse", outLoadingGetDetailSelected: "outLoadingGetDetailSelected" }, viewQueries: [{ propertyName: "tagsEl", first: true, predicate: ["tagsEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col w-full h-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label [classInclude]=\"labelConfig.classInclude\"\n [labelLeft]=\"labelConfig.labelLeft\"\n [labelLeftClass]=\"labelConfig.labelLeftClass\"\n [required]=\"labelConfig.required\"\n [description]=\"labelConfig.description\"\n [descriptionClass]=\"labelConfig.descriptionClass\"\n [labelRight]=\"labelConfig.labelRight\"\n [labelRightClass]=\"labelConfig.labelRightClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [buttonsLeft]=\"labelConfig.buttonsLeft\"\n [buttonsRight]=\"labelConfig.buttonsRight\"\n [disableButtonsLeft]=\"labelConfig.disableButtonsLeft || disable() || loading() || loadingDetail()\"\n [disableButtonsRight]=\"labelConfig.disableButtonsRight || disable() || loading() || loadingDetail()\"\n [hasToggle]=\"labelConfig.hasToggle\"\n [toggleActive]=\"labelConfig.toggleActive\"\n [toggleActive]=\"labelConfig.toggleDisable || disable() || loading() || loadingDetail()\"\n [popover]=\"labelConfig.popover\"\n [iconPopoverClass]=\"labelConfig.iconPopoverClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [limitLength]=\"labelConfig.limitLength\"\n [buttonsDescription]=\"labelConfig.buttonsDescription\"\n [disableButtonsDescription]=\"labelConfig.disableButtonsDescription || disable()\"\n [buttonsDescriptionContainerClass]=\"labelConfig.buttonsDescriptionContainerClass\"\n [count]=\"labelConfig.count\" />\n }\n <libs_ui-components-popover class=\"w-full h-full\"\n [ignoreShowPopover]=\"disable() || readonly() || !!config()?.ignoreShowList || false\"\n [ignoreCursorPointerModeLikeClick]=\"true\"\n [elementRefCustom]=\"tagsEl\"\n [mode]=\"!config()?.ignoreInput ? 'click' : 'click-toggle'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [flagMouse]=\"flagMouse()\"\n [config]=\"{\n animationConfig: config()?.animationConfig || {},\n zIndex: zIndex() || 1000,\n widthByParent: true,\n parentBorderWidth: parentBorderWidth() ?? 0,\n maxHeight: 2048,\n maxWidth: 2048,\n direction: config()?.directionList || 'bottom',\n directionDistance: 2,\n template: !showListBellow() ? listViewEl : undefined,\n whiteTheme: true,\n ignoreArrow: true,\n classInclude: 'rounded-[4px] ' + classIncludePopover() + ((!listConfig()?.ignoreShowDataWhenNotSearch || keySearch()) ? ' libs-ui-border-general' : ''),\n position: { mode: 'start', distance: 0 }\n }\"\n (outFunctionsControl)=\"handlerPopoverFunctionControlEvent($event)\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outEventPopoverContent)=\"handlerPopoverContentEvent($event)\"\n (outChangStageFlagMouse)=\"handlerChangeFlagMouse($event)\">\n <div class=\"relative\"\n [class.cursor-pointer]=\"!disable() && !readonly()\">\n @if (config()?.uiLikeDropdown) {\n <i class=\"flex text-[16px] absolute right-[16px] top-[8px] libs-ui-icon-move-right rotate-90 z-[1]\"\n [class.text-[#6a7383]]=\"!readonly() && !readonly()\"\n [class.libs-ui-readonly]=\"readonly()\"\n [class.libs-ui-disable]=\"disable()\">\n </i>\n }\n <div #tagsEl\n [class]=\"'libs-ui-tags ' + (config()?.classInclude || '') + (readonly() ? (config()?.classCustomWhenReadOnly || ' libs-ui-readonly') : '')\"\n [class.libs-ui-tags-not-popup]=\"(!showList() && !showBorderActiveWhenFocusInput()) || (!focus() && showBorderActiveWhenFocusInput())\"\n [class.libs-ui-tags-error]=\"!!error() && !config()?.ignoreShowError\"\n [class.!pr-[32px]]=\"config()?.uiLikeDropdown\"\n [class.bg-[#f8f9fa]]=\"disable() || readonly()\"\n [class.libs-ui-border-primary-general]=\"focus() && showBorderActiveWhenFocusInput()\"\n LibsUiComponentsClickOutsideDirective\n (outOutside)=\"handlerClickOutside($event)\">\n @for (item of itemsSelected(); track item[fieldKey()]) {\n <div [ngStyle]=\"item?.bullet || item?.ngStyles\"\n [class]=\"classIncludeTagItem() || ''\"\n [class.libs-ui-tags-readonly]=\"item.disableItem\"\n [class.libs-ui-tags-item]=\"!item.disableItem\"\n [class.cursor-default]=\"disable() || readonly()\">\n @if (fieldGetImage(); as fieldGetImage) {\n <div class=\"flex items-center justify-center h-full\">\n <libs_ui-components-avatar [classInclude]=\"classAvatarInclude() || 'mr-[8px]'\"\n [size]=\"imageSize()\"\n [linkAvatar]=\"item[fieldGetImage]\"\n [linkAvatarError]=\"config()?.linkImageError\"\n [idGenColor]=\"item[fieldGetTextAvatar()]\"\n [textAvatar]=\"item[fieldGetTextAvatar()]\"\n [getLastTextAfterSpace]=\"getLastTextAfterSpace()\" />\n </div>\n }\n <span class=\"libs-ui-font-h6r\"\n [innerHtml]=\"(item.fieldLabel || ' ') | translate\">\n </span>\n @if (!disable() && !item.disableItem && !readonly()) {\n <div class=\"flex items-center justify-center ml-[8px]\">\n <i #iconCloseEl\n [attr.specificStyle]=\"!!(item?.bullet || item?.ngStyles)\"\n [class]=\"'flex text-[16px] ' + (classIconRemoveTagItem() || 'libs-ui-icon-close')\"\n [class.cursor-pointer]=\"!disable() && !loading() && !loadingDetail()\"\n [class.pointer-events-none]=\"disable() || loading() || loadingDetail()\"\n [ngStyle]=\"(item?.bullet || item?.ngStyles) | LibsUiComponentsTagsGetColorPipe:iconCloseEl\"\n (click)=\"handlerRemoveItemSelected($event,item)\"></i>\n </div>\n }\n </div>\n }\n @if (!singleSelected() || (singleSelected() && !itemsSelected().length)) {\n @if (!config()?.ignoreInput && !config()?.uiLikeDropdown && (!hiddenInputWhenReadonly() || (hiddenInputWhenReadonly() && !readonly()))) {\n <libs_ui-components-inputs-input class=\"grow\"\n [class.mb-[4px]]=\"itemsSelected().length\"\n [classInclude]=\"'w-full bg-transparent' + (config()?.classInputInclude || 'px-[4px] min-w-[30px]')\"\n [defaultHeight]=\"24\"\n [placeholder]=\"readonly() ? '' : (placeholder() || 'i18n_import_content')\"\n [noBorder]=\"true\"\n [(value)]=\"valueInput\"\n [disable]=\"disable() || loading() || loadingDetail() || disableWhenMaxItem()\"\n [readonly]=\"readonly()\"\n (outEnterEvent)=\"handlerEnterEvent()\"\n (valueChange)=\"handlerValueChangeSearch($event)\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlurEvent($event)\"\n (outFunctionsControl)=\"handlerInputFunctionControl($event)\" />\n }\n @if (config()?.ignoreInput && config()?.uiLikeDropdown && !itemsSelected().length) {\n <div class=\"flex items-center pb-[4px] pt-[2px] ml-[11px] libs-ui-font-h5r\"\n [class.text-[#9ca2ad]]=\"disable()\">\n {{ (placeholder() || 'i18n_select_value') | translate }}\n </div>\n }\n }\n </div>\n @if (error() && !config()?.ignoreShowError) {\n <div class=\"text-[#ee2d41] libs-ui-font-h7r mt-[8px]\">{{ (error()?.message || ' ') | translate:(error()?.interpolateParams || {}) }}</div>\n }\n </div>\n </libs_ui-components-popover>\n</div>\n@if (showListBellow()) {\n <ng-container *ngTemplateOutlet=\"listViewEl\"></ng-container>\n}\n<ng-template #listViewEl>\n @if (listConfig(); as listConfig) {\n <libs_ui-components-list [searchConfig]=\"listSearchConfig() || {classInclude: 'hidden', iconLeftClass: 'hidden'}\"\n [isSearchOnline]=\"isSearchOnline()\"\n [zIndex]=\"zIndex()\"\n [keySearch]=\"keySearch()\"\n [config]=\"listConfig\"\n [disable]=\"disable() || loadingDetail() || disableWhenMaxItem()\"\n [searchPadding]=\"listSearchPadding()\"\n [maxItemShow]=\"listMaxItemShow() || 6\"\n [multiKeySelected]=\"keysSelected()\"\n [clickExactly]=\"false\"\n [keysHiddenItem]=\"keysHiddenItem()\"\n [keysDisableItem]=\"keysDisableItem()\"\n [dividerClassInclude]=\"listDividerClassInclude() ?? 'hidden'\"\n [buttonsOther]=\"listButtonsOther()\"\n [backgroundListCustom]=\"listBackgroundListCustom()\"\n [itemChangeUnSelect]=\"itemChangeUnSelect()\"\n [functionGetItemsAutoAddList]=\"functionGetItemAutoAddList()\"\n [hiddenInputSearch]=\"listHiddenInputSearchWhenHasSearchConfig()\"\n (outFunctionsControl)=\"handlerFunctionControlList($event)\"\n (outSelectKey)=\"handlerSelectedKey($event)\"\n (outSelectMultiKey)=\"handlerSelectMultiKey($event)\"\n (outChangeView)=\"handlerDataChange($event)\"\n (outClickButtonOther)=\"handlerClickButtonOther($event)\"\n (outChangStageFlagMousePopover)=\"handlerChangStageFlagMouse($event)\"\n (outLoading)=\"handlerLoading($event)\" />\n }\n</ng-template>\n", styles: [".libs-ui-tags{position:relative;display:flex;flex-wrap:wrap;border:1px solid var(--libs-ui-color-default, #226FF5);max-height:100px;overflow:auto;border-radius:4px;padding:3px 0 0 4px;min-height:32px}.libs-ui-tags-not-popup{border:1px solid #E6E7EA}.libs-ui-tags-error{border-color:#ff5454}.libs-ui-tags .libs-ui-tags-item{display:flex;align-items:center;margin:0 4px 3px 0;padding:4px 8px;color:var(--libs-ui-color-default, #226FF5);border-radius:20px;background-color:var(--libs-ui-color-light-2, #E9F1FE);word-break:break-word!important;overflow-wrap:break-word!important;cursor:default}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:before{border-radius:50%;font-size:16px;color:var(--libs-ui-color-default, #226FF5)}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:hover:before{background:var(--libs-ui-color-light-6, #D3E2FD)}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:active:before{background:var(--libs-ui-color-light-5, #BDD4FC)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:before{border-radius:50%;font-size:16px;color:var(--libs-ui-tags-item-icon-default)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:hover:before{color:var(--libs-ui-tags-item-icon-hover);background:var(--libs-ui-tags-item-icon-background-hover)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:active:before{color:var(--libs-ui-tags-item-icon-active);background:var(--libs-ui-tags-item-icon-background-active)}.libs-ui-tags-disable{background:#f8f9fa;color:#9ca2ad}.libs-ui-tags-readonly{background:#f1ebfd;color:#7239ea;display:flex;align-items:center;margin:0 4px 4px 0;padding:4px 8px;border-radius:20px;word-break:break-word!important;overflow-wrap:break-word!important}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: LibsUiComponentsClickOutsideDirective, selector: "[LibsUiComponentsClickOutsideDirective]", outputs: ["outOutside", "outInSide"] }, { kind: "component", type: LibsUiComponentsLabelComponent, selector: "libs_ui-components-label", inputs: ["iconPopoverClass", "classInclude", "labelLeft", "labelLeftClass", "labelLeftBehindToggleButton", "popover", "required", "buttonsLeft", "disableButtonsLeft", "buttonsRight", "disableButtonsRight", "labelRight", "labelRightClass", "labelRightRequired", "hasToggle", "toggleSize", "toggleActive", "toggleDisable", "description", "descriptionClass", "buttonsDescription", "disableButtonsDescription", "buttonsDescriptionContainerClass", "onlyShowCount", "zIndexPopover", "timerDestroyPopover", "count", "limitLength"], outputs: ["outClickButton", "outSwitchEvent", "outLabelRightClick", "outLabelLeftClick"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsInputsInputComponent, selector: "libs_ui-components-inputs-input", inputs: ["tagInput", "dataType", "tabInsertContentTagInput", "textAreaEnterNotNewLine", "emitEmptyInDataTypeNumber", "keepZeroInTypeInt", "autoAddZeroLessThan10InTypeInt", "ignoreBlockInputMaxValue", "hiddenContent", "maxValueNumber", "minValueNumber", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "classInclude", "maxLength", "readonly", "disable", "noBorder", "backgroundNone", "borderError", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "value", "autoRemoveEmoji", "defaultHeight", "minHeightTextArea", "maxHeightTextArea", "focusTimeOut", "blurTimeOut", "zIndexPopoverContent", "classContainerInput", "showCount", "ignoreStopPropagationEvent", "resize", "templateLeftBottomInput", "templateRightBottomInput", "classContainerBottomInput", "ignoreWidthInput100", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "resetAutoCompletePassword", "acceptOnlyClickIcon", "setIconRightColorSameColorDisableReadOnly", "onlyAcceptNegativeValue", "maxLengthNumberCount", "focusInput"], outputs: ["maxValueNumberChange", "minValueNumberChange", "fixedFloatChange", "acceptNegativeValueChange", "maxLengthChange", "valueChange", "maxLengthNumberCountChange", "outHeightAreaChange", "outChange", "outFocusAndBlurEvent", "outEnterEvent", "outInputEvent", "outIconLeft", "outIconRight", "outFunctionsControl", "outFilesDrop", "outFileDrop", "outChangeValueByButtonUpDown"] }, { kind: "component", type: LibsUiComponentsAvatarComponent, selector: "libs_ui-components-avatar", inputs: ["getLastTextAfterSpace", "typeShape", "classInclude", "size", "linkAvatar", "linkAvatarError", "idGenColor", "textAvatar", "classImageInclude"], outputs: ["outAvatarError"] }, { kind: "component", type: LibsUiComponentsListComponent, selector: "libs_ui-components-list", inputs: ["hiddenInputSearch", "dropdownTabKeyActive", "keySearch", "itemChangeUnSelect", "paddingLeftItem", "config", "isSearchOnline", "disable", "disableLabel", "labelConfig", "searchConfig", "searchPadding", "dividerClassInclude", "hasDivider", "buttonsOther", "hasButtonUnSelectOption", "clickExactly", "backgroundListCustom", "maxItemShow", "keySelected", "multiKeySelected", "keysDisableItem", "keysHiddenItem", "focusInputSearch", "skipFocusInputWhenKeySearchStoreUndefined", "functionGetItemsAutoAddList", "validRequired", "showValidateBottom", "zIndex", "loadingIconSize", "templateRefSearchNoData", "resetKeyWhenSelectAllKeyDropdown", "ignoreClassDisableDefaultWhenUseKeysDisableItem"], outputs: ["outSelectKey", "outSelectMultiKey", "outUnSelectMultiKey", "outClickButtonOther", "outFieldKey", "outChangeView", "outLoading", "outFunctionsControl", "outChangStageFlagMousePopover", "outLoadItemsComplete"] }, { kind: "pipe", type: LibsUiComponentsTagsGetColorPipe, name: "LibsUiComponentsTagsGetColorPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
706
+ }
707
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsTagsComponent, decorators: [{
708
+ type: Component,
709
+ args: [{ selector: 'libs_ui-components-tags', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
710
+ TranslateModule, NgTemplateOutlet, NgStyle, LibsUiComponentsClickOutsideDirective,
711
+ LibsUiComponentsLabelComponent, LibsUiComponentsPopoverComponent,
712
+ LibsUiComponentsInputsInputComponent, LibsUiComponentsAvatarComponent,
713
+ LibsUiComponentsListComponent, LibsUiComponentsTagsGetColorPipe
714
+ ], template: "<div class=\"flex flex-col w-full h-full\">\n @if (labelConfig(); as labelConfig) {\n <libs_ui-components-label [classInclude]=\"labelConfig.classInclude\"\n [labelLeft]=\"labelConfig.labelLeft\"\n [labelLeftClass]=\"labelConfig.labelLeftClass\"\n [required]=\"labelConfig.required\"\n [description]=\"labelConfig.description\"\n [descriptionClass]=\"labelConfig.descriptionClass\"\n [labelRight]=\"labelConfig.labelRight\"\n [labelRightClass]=\"labelConfig.labelRightClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [buttonsLeft]=\"labelConfig.buttonsLeft\"\n [buttonsRight]=\"labelConfig.buttonsRight\"\n [disableButtonsLeft]=\"labelConfig.disableButtonsLeft || disable() || loading() || loadingDetail()\"\n [disableButtonsRight]=\"labelConfig.disableButtonsRight || disable() || loading() || loadingDetail()\"\n [hasToggle]=\"labelConfig.hasToggle\"\n [toggleActive]=\"labelConfig.toggleActive\"\n [toggleActive]=\"labelConfig.toggleDisable || disable() || loading() || loadingDetail()\"\n [popover]=\"labelConfig.popover\"\n [iconPopoverClass]=\"labelConfig.iconPopoverClass\"\n [onlyShowCount]=\"labelConfig.onlyShowCount\"\n [limitLength]=\"labelConfig.limitLength\"\n [buttonsDescription]=\"labelConfig.buttonsDescription\"\n [disableButtonsDescription]=\"labelConfig.disableButtonsDescription || disable()\"\n [buttonsDescriptionContainerClass]=\"labelConfig.buttonsDescriptionContainerClass\"\n [count]=\"labelConfig.count\" />\n }\n <libs_ui-components-popover class=\"w-full h-full\"\n [ignoreShowPopover]=\"disable() || readonly() || !!config()?.ignoreShowList || false\"\n [ignoreCursorPointerModeLikeClick]=\"true\"\n [elementRefCustom]=\"tagsEl\"\n [mode]=\"!config()?.ignoreInput ? 'click' : 'click-toggle'\"\n [ignoreHiddenPopoverContentWhenMouseLeave]=\"true\"\n [flagMouse]=\"flagMouse()\"\n [config]=\"{\n animationConfig: config()?.animationConfig || {},\n zIndex: zIndex() || 1000,\n widthByParent: true,\n parentBorderWidth: parentBorderWidth() ?? 0,\n maxHeight: 2048,\n maxWidth: 2048,\n direction: config()?.directionList || 'bottom',\n directionDistance: 2,\n template: !showListBellow() ? listViewEl : undefined,\n whiteTheme: true,\n ignoreArrow: true,\n classInclude: 'rounded-[4px] ' + classIncludePopover() + ((!listConfig()?.ignoreShowDataWhenNotSearch || keySearch()) ? ' libs-ui-border-general' : ''),\n position: { mode: 'start', distance: 0 }\n }\"\n (outFunctionsControl)=\"handlerPopoverFunctionControlEvent($event)\"\n (outEvent)=\"handlerPopoverEvent($event)\"\n (outEventPopoverContent)=\"handlerPopoverContentEvent($event)\"\n (outChangStageFlagMouse)=\"handlerChangeFlagMouse($event)\">\n <div class=\"relative\"\n [class.cursor-pointer]=\"!disable() && !readonly()\">\n @if (config()?.uiLikeDropdown) {\n <i class=\"flex text-[16px] absolute right-[16px] top-[8px] libs-ui-icon-move-right rotate-90 z-[1]\"\n [class.text-[#6a7383]]=\"!readonly() && !readonly()\"\n [class.libs-ui-readonly]=\"readonly()\"\n [class.libs-ui-disable]=\"disable()\">\n </i>\n }\n <div #tagsEl\n [class]=\"'libs-ui-tags ' + (config()?.classInclude || '') + (readonly() ? (config()?.classCustomWhenReadOnly || ' libs-ui-readonly') : '')\"\n [class.libs-ui-tags-not-popup]=\"(!showList() && !showBorderActiveWhenFocusInput()) || (!focus() && showBorderActiveWhenFocusInput())\"\n [class.libs-ui-tags-error]=\"!!error() && !config()?.ignoreShowError\"\n [class.!pr-[32px]]=\"config()?.uiLikeDropdown\"\n [class.bg-[#f8f9fa]]=\"disable() || readonly()\"\n [class.libs-ui-border-primary-general]=\"focus() && showBorderActiveWhenFocusInput()\"\n LibsUiComponentsClickOutsideDirective\n (outOutside)=\"handlerClickOutside($event)\">\n @for (item of itemsSelected(); track item[fieldKey()]) {\n <div [ngStyle]=\"item?.bullet || item?.ngStyles\"\n [class]=\"classIncludeTagItem() || ''\"\n [class.libs-ui-tags-readonly]=\"item.disableItem\"\n [class.libs-ui-tags-item]=\"!item.disableItem\"\n [class.cursor-default]=\"disable() || readonly()\">\n @if (fieldGetImage(); as fieldGetImage) {\n <div class=\"flex items-center justify-center h-full\">\n <libs_ui-components-avatar [classInclude]=\"classAvatarInclude() || 'mr-[8px]'\"\n [size]=\"imageSize()\"\n [linkAvatar]=\"item[fieldGetImage]\"\n [linkAvatarError]=\"config()?.linkImageError\"\n [idGenColor]=\"item[fieldGetTextAvatar()]\"\n [textAvatar]=\"item[fieldGetTextAvatar()]\"\n [getLastTextAfterSpace]=\"getLastTextAfterSpace()\" />\n </div>\n }\n <span class=\"libs-ui-font-h6r\"\n [innerHtml]=\"(item.fieldLabel || ' ') | translate\">\n </span>\n @if (!disable() && !item.disableItem && !readonly()) {\n <div class=\"flex items-center justify-center ml-[8px]\">\n <i #iconCloseEl\n [attr.specificStyle]=\"!!(item?.bullet || item?.ngStyles)\"\n [class]=\"'flex text-[16px] ' + (classIconRemoveTagItem() || 'libs-ui-icon-close')\"\n [class.cursor-pointer]=\"!disable() && !loading() && !loadingDetail()\"\n [class.pointer-events-none]=\"disable() || loading() || loadingDetail()\"\n [ngStyle]=\"(item?.bullet || item?.ngStyles) | LibsUiComponentsTagsGetColorPipe:iconCloseEl\"\n (click)=\"handlerRemoveItemSelected($event,item)\"></i>\n </div>\n }\n </div>\n }\n @if (!singleSelected() || (singleSelected() && !itemsSelected().length)) {\n @if (!config()?.ignoreInput && !config()?.uiLikeDropdown && (!hiddenInputWhenReadonly() || (hiddenInputWhenReadonly() && !readonly()))) {\n <libs_ui-components-inputs-input class=\"grow\"\n [class.mb-[4px]]=\"itemsSelected().length\"\n [classInclude]=\"'w-full bg-transparent' + (config()?.classInputInclude || 'px-[4px] min-w-[30px]')\"\n [defaultHeight]=\"24\"\n [placeholder]=\"readonly() ? '' : (placeholder() || 'i18n_import_content')\"\n [noBorder]=\"true\"\n [(value)]=\"valueInput\"\n [disable]=\"disable() || loading() || loadingDetail() || disableWhenMaxItem()\"\n [readonly]=\"readonly()\"\n (outEnterEvent)=\"handlerEnterEvent()\"\n (valueChange)=\"handlerValueChangeSearch($event)\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlurEvent($event)\"\n (outFunctionsControl)=\"handlerInputFunctionControl($event)\" />\n }\n @if (config()?.ignoreInput && config()?.uiLikeDropdown && !itemsSelected().length) {\n <div class=\"flex items-center pb-[4px] pt-[2px] ml-[11px] libs-ui-font-h5r\"\n [class.text-[#9ca2ad]]=\"disable()\">\n {{ (placeholder() || 'i18n_select_value') | translate }}\n </div>\n }\n }\n </div>\n @if (error() && !config()?.ignoreShowError) {\n <div class=\"text-[#ee2d41] libs-ui-font-h7r mt-[8px]\">{{ (error()?.message || ' ') | translate:(error()?.interpolateParams || {}) }}</div>\n }\n </div>\n </libs_ui-components-popover>\n</div>\n@if (showListBellow()) {\n <ng-container *ngTemplateOutlet=\"listViewEl\"></ng-container>\n}\n<ng-template #listViewEl>\n @if (listConfig(); as listConfig) {\n <libs_ui-components-list [searchConfig]=\"listSearchConfig() || {classInclude: 'hidden', iconLeftClass: 'hidden'}\"\n [isSearchOnline]=\"isSearchOnline()\"\n [zIndex]=\"zIndex()\"\n [keySearch]=\"keySearch()\"\n [config]=\"listConfig\"\n [disable]=\"disable() || loadingDetail() || disableWhenMaxItem()\"\n [searchPadding]=\"listSearchPadding()\"\n [maxItemShow]=\"listMaxItemShow() || 6\"\n [multiKeySelected]=\"keysSelected()\"\n [clickExactly]=\"false\"\n [keysHiddenItem]=\"keysHiddenItem()\"\n [keysDisableItem]=\"keysDisableItem()\"\n [dividerClassInclude]=\"listDividerClassInclude() ?? 'hidden'\"\n [buttonsOther]=\"listButtonsOther()\"\n [backgroundListCustom]=\"listBackgroundListCustom()\"\n [itemChangeUnSelect]=\"itemChangeUnSelect()\"\n [functionGetItemsAutoAddList]=\"functionGetItemAutoAddList()\"\n [hiddenInputSearch]=\"listHiddenInputSearchWhenHasSearchConfig()\"\n (outFunctionsControl)=\"handlerFunctionControlList($event)\"\n (outSelectKey)=\"handlerSelectedKey($event)\"\n (outSelectMultiKey)=\"handlerSelectMultiKey($event)\"\n (outChangeView)=\"handlerDataChange($event)\"\n (outClickButtonOther)=\"handlerClickButtonOther($event)\"\n (outChangStageFlagMousePopover)=\"handlerChangStageFlagMouse($event)\"\n (outLoading)=\"handlerLoading($event)\" />\n }\n</ng-template>\n", styles: [".libs-ui-tags{position:relative;display:flex;flex-wrap:wrap;border:1px solid var(--libs-ui-color-default, #226FF5);max-height:100px;overflow:auto;border-radius:4px;padding:3px 0 0 4px;min-height:32px}.libs-ui-tags-not-popup{border:1px solid #E6E7EA}.libs-ui-tags-error{border-color:#ff5454}.libs-ui-tags .libs-ui-tags-item{display:flex;align-items:center;margin:0 4px 3px 0;padding:4px 8px;color:var(--libs-ui-color-default, #226FF5);border-radius:20px;background-color:var(--libs-ui-color-light-2, #E9F1FE);word-break:break-word!important;overflow-wrap:break-word!important;cursor:default}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:before{border-radius:50%;font-size:16px;color:var(--libs-ui-color-default, #226FF5)}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:hover:before{background:var(--libs-ui-color-light-6, #D3E2FD)}.libs-ui-tags .libs-ui-tags-item i[class*=libs-ui-icon-]:active:before{background:var(--libs-ui-color-light-5, #BDD4FC)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:before{border-radius:50%;font-size:16px;color:var(--libs-ui-tags-item-icon-default)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:hover:before{color:var(--libs-ui-tags-item-icon-hover);background:var(--libs-ui-tags-item-icon-background-hover)}.libs-ui-tags .libs-ui-tags-item [specificStyle=true] i[class*=libs-ui-icon-]:active:before{color:var(--libs-ui-tags-item-icon-active);background:var(--libs-ui-tags-item-icon-background-active)}.libs-ui-tags-disable{background:#f8f9fa;color:#9ca2ad}.libs-ui-tags-readonly{background:#f1ebfd;color:#7239ea;display:flex;align-items:center;margin:0 4px 4px 0;padding:4px 8px;border-radius:20px;word-break:break-word!important;overflow-wrap:break-word!important}\n"] }]
715
+ }], ctorParameters: () => [] });
716
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFncy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvdGFncy9zcmMvdGFncy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvdGFncy9zcmMvdGFncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFjLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEwsT0FBTyxFQUFFLCtCQUErQixFQUEyQixNQUFNLDRCQUE0QixDQUFDO0FBR3RHLE9BQU8sRUFBa0Qsb0NBQW9DLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUd4SSxPQUFPLEVBQVUsOEJBQThCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUJBQWlCLEVBQXVGLDZCQUE2QixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDakwsT0FBTyxFQUE0QyxnQ0FBZ0MsRUFBOEMsTUFBTSw2QkFBNkIsQ0FBQztBQUVySyxPQUFPLEVBQXNCLHdCQUF3QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUYsT0FBTyxFQUFFLFNBQVMsRUFBRSx5QkFBeUIsRUFBRSx1QkFBdUIsRUFBRSwwQkFBMEIsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUosT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVB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RSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JXLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEMsSUFBSSxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMvSCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssSUFBSSxFQUFFLEVBQUUsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RixDQUFDO1FBQ0QsSUFBSSxDQUFDLFlB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LElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsS0FBSyxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNlLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDbkQsQ0FBQztRQUNELFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUUsS0FBSyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxL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bUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLFlBQVksQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLFlBQVksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7d0dBN3RCVSw2QkFBNkI7NEZBQTdCLDZCQUE2QixtL09DbEMxQyxnaVNBc0tBLGd6REQxSUksZUFBZSw0RkFBRSxnQkFBZ0Isb0pBQUUsT0FBTywyRUFBRSxxQ0FBcUMsMEhBQ2pGLDhCQUE4Qiw0cUJBQUUsZ0NBQWdDLDBkQUNoRSxvQ0FBb0MsODlDQUFFLCtCQUErQiw2UEFDckUsNkJBQTZCLG85QkFBRSxnQ0FBZ0M7OzRGQUd0RCw2QkFBNkI7a0JBZHpDLFNBQVM7K0JBRUUseUJBQXlCLGNBR3ZCLElBQUksbUJBQ0MsdUJBQXVCLENBQUMsTUFBTSxXQUN0Qzt3QkFDUCxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLHFDQUFxQzt3QkFDakYsOEJBQThCLEVBQUUsZ0NBQWdDO3dCQUNoRSxvQ0FBb0MsRUFBRSwrQkFBK0I7d0JBQ3JFLDZCQUE2QixFQUFFLGdDQUFnQztxQkFDaEUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ1N0eWxlLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGNvbXB1dGVkLCBlZmZlY3QsIEVsZW1lbnRSZWYsIGluamVjdCwgaW5wdXQsIG1vZGVsLCBPbkRlc3Ryb3ksIE9uSW5pdCwgb3V0cHV0LCBzaWduYWwsIHVudHJhY2tlZCwgdmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzQXZhdGFyQ29tcG9uZW50LCBUWVBFX1NJWkVfQVZBVEFSX0NPTkZJRyB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYXZhdGFyJztcbmltcG9ydCB7IElCdXR0b24gfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWJ1dHRvbnMtYnV0dG9uJztcbmltcG9ydCB7IElWYWxpZE1heEl0ZW1TZWxlY3RlZCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtZHJvcGRvd24nO1xuaW1wb3J0IHsgSUZvY3VzQW5kQmx1ckV2ZW50LCBJSW5wdXRGdW5jdGlvbkNvbnRyb2xFdmVudCwgTGlic1VpQ29tcG9uZW50c0lucHV0c0lucHV0Q29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtaW5wdXQnO1xuaW1wb3J0IHsgSUlucHV0U2VhcmNoQ29uZmlnIH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1pbnB1dHMtc2VhcmNoJztcbmltcG9ydCB7IElWYWxpZCwgSVZhbGlkUGF0dGVybiB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtaW5wdXRzLXZhbGlkJztcbmltcG9ydCB7IElMYWJlbCwgTGlic1VpQ29tcG9uZW50c0xhYmVsQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1sYWJlbCc7XG5pbXBvcnQgeyBnZXRGaWVsZEtleUJ5VHlwZSwgSUxpc3RDb25maWdJdGVtLCBJTGlzdERhdGFFbWl0S2V5LCBJTGlzdERhdGFFbWl0TXVsdGlLZXksIElMaXN0RnVuY3Rpb25Db250cm9sRXZlbnQsIExpYnNVaUNvbXBvbmVudHNMaXN0Q29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1saXN0JztcbmltcG9ydCB7IElGbGFnTW91c2UsIElQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQsIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyQ29tcG9uZW50LCBUWVBFX1BPUE9WRVJfRElSRUNUSU9OLCBUWVBFX1BPUE9WRVJfRVZFTlQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXBvcG92ZXInO1xuaW1wb3J0IHsgSUh0dHBSZXNwb25zZSB9IGZyb20gJ0BsaWJzLXVpL2ludGVyZmFjZXMtdHlwZXMnO1xuaW1wb3J0IHsgSUh0dHBSZXF1ZXN0Q29uZmlnLCBMaWJzVWlIdHRwUmVxdWVzdFNlcnZpY2UgfSBmcm9tICdAbGlicy11aS9zZXJ2aWNlcy1odHRwLXJlcXVlc3QnO1xuaW1wb3J0IHsgY2xvbmVEZWVwLCBFUlJPUl9NRVNTQUdFX0VNUFRZX1ZBTElELCBFUlJPUl9NRVNTQUdFX01BWF9WQUxJRCwgRVJST1JfTUVTU0FHRV9QQVRURU5fVkFMSUQsIGVzY2FwZUh0bWwsIGdldCwgaXNOaWwsIHNldCwgdXVpZCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSVRhZ3NDb25maWcsIElUYWdzRnVuY3Rpb25Db250cm9sRXZlbnQgfSBmcm9tICcuL2ludGVyZmFjZXMvdGFncy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1RhZ3NHZXRDb2xvclBpcGUgfSBmcm9tICcuL3BpcGVzL2dldC1jb2xvci5waXBlJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNDbGlja091dHNpZGVEaXJlY3RpdmUgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWNsaWNrLW91dHNpZGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdsaWJzX3VpLWNvbXBvbmVudHMtdGFncycsXG4gIHRlbXBsYXRlVXJsOiAnLi90YWdzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3RhZ3MuY29tcG9uZW50LnNjc3MnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW1xuICAgIFRyYW5zbGF0ZU1vZHVsZSwgTmdUZW1wbGF0ZU91dGxldCwgTmdTdHlsZSwgTGlic1VpQ29tcG9uZW50c0NsaWNrT3V0c2lkZURpcmVjdGl2ZSxcbiAgICBMaWJzVWlDb21wb25lbnRzTGFiZWxDb21wb25lbnQsIExpYnNVaUNvbXBvbmVudHNQb3BvdmVyQ29tcG9uZW50LFxuICAgIExpYnNVaUNvbXBvbmVudHNJbnB1dHNJbnB1dENvbXBvbmVudCwgTGlic1VpQ29tcG9uZW50c0F2YXRhckNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzTGlzdENvbXBvbmVudCwgTGlic1VpQ29tcG9uZW50c1RhZ3NHZXRDb2xvclBpcGVcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpQ29tcG9uZW50c1RhZ3NDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLyogUFJPUEVSVFkgKi9cbiAgcHJvdGVjdGVkIGZsYWdNb3VzZSA9IHNpZ25hbDxJRmxhZ01vdXNlPih7IGlzTW91c2VFbnRlcjogZmFsc2UsIGlzTW91c2VFbnRlckNvbnRlbnQ6IGZhbHNlIH0pO1xuICBwcm90ZWN0ZWQgbG9hZGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBsb2FkaW5nRGV0YWlsID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIGtleVNlYXJjaCA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcHJvdGVjdGVkIHZhbHVlSW5wdXQgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHByb3RlY3RlZCBpdGVtc1NlbGVjdGVkID0gc2lnbmFsPEFycmF5PGFueT4+KFtdKTtcbiAgcHJvdGVjdGVkIHNob3dMaXN0ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJvdGVjdGVkIHBvc2l0aW9uTGlzdCA9IHNpZ25hbDxUWVBFX1BPUE9WRVJfRElSRUNUSU9OIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcm90ZWN0ZWQga2V5c1NlbGVjdGVkID0gc2lnbmFsPEFycmF5PHVua25vd24+PihbXSk7XG4gIHByb3RlY3RlZCBkaXNhYmxlV2hlbk1heEl0ZW0gPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcm90ZWN0ZWQgaXRlbUNoYW5nZVVuU2VsZWN0ID0gc2lnbmFsPHVua25vd24gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBmb2N1cyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByb3RlY3RlZCBlcnJvciA9IHNpZ25hbDxJVmFsaWQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByb3RlY3RlZCBmaWVsZEtleSA9IHNpZ25hbDxzdHJpbmc+KCdpZCcpO1xuICBwcm90ZWN0ZWQgZnVuY3Rpb25HZXRJdGVtQXV0b0FkZExpc3QgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLmVudGVyQXV0b0FkZFRhZ1RvTGlzdCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiAoKSA9PiB0aGlzLml0ZW1zU2VsZWN0ZWQoKS5maWx0ZXIoaXRlbSA9PiBgJHtpdGVtW3RoaXMuZmllbGRLZXkoKV19YC5zZWFyY2godGhpcy5mYWtlSWQoKSkgPT09IDApLnJldmVyc2UoKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBmYWtlSWQgPSBzaWduYWw8c3RyaW5nPih1dWlkKCkpO1xuICBwcml2YXRlIHRpbWVPdXRGbGFnID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0aW1lT3V0Q2hhbmdlU2VhcmNoID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0aW1lT3V0Q2hlY2tWaWV3Q2hhbmdlID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0aW1lb3V0Q2xpY2tPdXRzaWRlID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBjbGllbnRIZWlnaHQgPSBzaWduYWw8bnVtYmVyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIGl0ZW1zT2ZMaXN0ID0gc2lnbmFsPEFycmF5PHVua25vd24+PihbXSk7XG4gIHByaXZhdGUga2V5U2VhcmNoQ2hhbmdlID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuICBwcml2YXRlIGtleVNlYXJjaENoYW5nZVN1YiA9IHNpZ25hbDxTdWJzY3JpcHRpb24gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgdGVtcElnbm9yZUVtaXQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIHBvcG92ZXJGdW5jdGlvbkNvbnRyb2wgPSBzaWduYWw8SVBvcG92ZXJGdW5jdGlvbkNvbnRyb2xFdmVudCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBpbnB1dEZ1bmN0aW9uQ29udHJvbCA9IHNpZ25hbDxJSW5wdXRGdW5jdGlvbkNvbnRyb2xFdmVudCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSB0eXBlUG9wb3ZlciA9IHNpZ25hbDxUWVBFX1BPUE9WRVJfRVZFTlQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgbGlzdEZ1bmN0aW9uQ29udHJvbCA9IHNpZ25hbDxJTGlzdEZ1bmN0aW9uQ29udHJvbEV2ZW50IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIGRlZmF1bHRJdGVtc1NlbGVjdGVkQ3VycmVudCA9IHNpZ25hbDxBcnJheTx1bmtub3duPiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qIElOUFVUICovXG4gIHJlYWRvbmx5IGNsYXNzSW5jbHVkZVBvcG92ZXIgPSBpbnB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IGVudGVyQXV0b0FkZFRhZ1RvTGlzdCA9IGlucHV0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgY2hlY2tFeGl0SXNMYWJlbEluY2x1ZGUgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBjaGVja0V4aXRCeUZpZWxkcyA9IGlucHV0PEFycmF5PHN0cmluZz4+KCk7XG4gIHJlYWRvbmx5IHBhcmVudEJvcmRlcldpZHRoID0gaW5wdXQ8bnVtYmVyPigpO1xuICByZWFkb25seSBmdW5jdGlvbkNoZWNrUGVybWlzc2lvbkNyZWF0ZVRhZyA9IGlucHV0PCgpID0+IGJvb2xlYW4+KCgpID0+IHRydWUpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGlucHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHMgPSBpbnB1dDxJSHR0cFJlcXVlc3RDb25maWc+KCk7XG4gIHJlYWRvbmx5IGZpZWxkTGFiZWwgPSBpbnB1dDxzdHJpbmc+KCdsYWJlbCcpO1xuICByZWFkb25seSBtYXhJdGVtSW5wdXQgPSBpbnB1dDxudW1iZXI+KCk7XG4gIHJlYWRvbmx5IHpJbmRleCA9IGlucHV0PG51bWJlcj4oKTtcbiAgcmVhZG9ubHkgY29uZmlnID0gaW5wdXQ8SVRhZ3NDb25maWc+KCk7XG4gIHJlYWRvbmx5IGRpc2FibGUgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSByZWFkb25seSA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGxhYmVsQ29uZmlnID0gaW5wdXQ8SUxhYmVsPigpO1xuICByZWFkb25seSBkZWZhdWx0SXRlbXNTZWxlY3RlZCA9IGlucHV0PEFycmF5PHVua25vd24+PigpO1xuICByZWFkb25seSBkZWZhdWx0S2V5c1NlbGVjdGVkID0gaW5wdXQ8QXJyYXk8dW5rbm93bj4+KCk7XG4gIHJlYWRvbmx5IGxpc3RTZWFyY2hDb25maWcgPSBpbnB1dDxJSW5wdXRTZWFyY2hDb25maWc+KCk7XG4gIHJlYWRvbmx5IGlzU2VhcmNoT25saW5lID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBsaXN0U2VhcmNoUGFkZGluZyA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGxpc3REaXZpZGVyQ2xhc3NJbmNsdWRlID0gaW5wdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBsaXN0Q29uZmlnID0gaW5wdXQ8SUxpc3RDb25maWdJdGVtPigpO1xuICByZWFkb25seSBsaXN0QnV0dG9uc090aGVyID0gaW5wdXQ8QXJyYXk8SUJ1dHRvbj4+KCk7XG4gIHJlYWRvbmx5IGxpc3RDbGlja0V4YWN0bHkgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBsaXN0QmFja2dyb3VuZExpc3RDdXN0b20gPSBpbnB1dDxzdHJpbmc+KCk7XG4gIHJlYWRvbmx5IGxpc3RNYXhJdGVtU2hvdyA9IGlucHV0PG51bWJlcj4oKTtcbiAgcmVhZG9ubHkgbGlzdEhpZGRlbklucHV0U2VhcmNoV2hlbkhhc1NlYXJjaENvbmZpZyA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IHJlbW92ZVRleHRTZWFyY2hXaGVuQmx1cklucHV0ID0gaW5wdXQ8Ym9vbGVhbj4odHJ1ZSk7XG4gIHJlYWRvbmx5IGtleXNIaWRkZW5JdGVtID0gbW9kZWw8QXJyYXk8dW5rbm93bj4+KClcbiAgcmVhZG9ubHkga2V5c0Rpc2FibGVJdGVtID0gaW5wdXQ8QXJyYXk8dW5rbm93bj4+KClcbiAgcmVhZG9ubHkgaWdub3JlRW1pdFdoZW5TYW1lRGF0YVNlbGVjdGVkID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgc2luZ2xlU2VsZWN0ZWQgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBjbGFzc0luY2x1ZGVUYWdJdGVtID0gaW5wdXQ8c3RyaW5nPigpXG4gIHJlYWRvbmx5IGNsYXNzSWNvblJlbW92ZVRhZ0l0ZW0gPSBpbnB1dDxzdHJpbmc+KClcbiAgcmVhZG9ubHkgc2hvd0JvcmRlckFjdGl2ZVdoZW5Gb2N1c0lucHV0ID0gaW5wdXQ8Ym9vbGVhbj4oKVxuICByZWFkb25seSBmaWVsZEdldEltYWdlID0gaW5wdXQ8c3RyaW5nPigpO1xuICByZWFkb25seSBpbWFnZVNpemUgPSBpbnB1dDxUWVBFX1NJWkVfQVZBVEFSX0NPTkZJRz4oMTYpO1xuICByZWFkb25seSBmaWVsZEdldFRleHRBdmF0YXIgPSBpbnB1dDxzdHJpbmc+KCd1c2VyJyk7XG4gIHJlYWRvbmx5IGNsYXNzQXZhdGFySW5jbHVkZSA9IGlucHV0PHN0cmluZz4oKTtcbiAgcmVhZG9ubHkgZ2V0TGFzdFRleHRBZnRlclNwYWNlID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgdmFsaWRSZXF1aXJlZCA9IGlucHV0PElWYWxpZD4oKTtcbiAgcmVhZG9ubHkgdmFsaWRNYXhJdGVtU2VsZWN0ZWQgPSBpbnB1dDxJVmFsaWRNYXhJdGVtU2VsZWN0ZWQ+KCk7XG4gIHJlYWRvbmx5IHZhbGlkUGF0dGVybiA9IGlucHV0PEFycmF5PElWYWxpZFBhdHRlcm4+PigpO1xuICByZWFkb25seSBzaG93TGlzdEJlbGxvdyA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGhpZGRlbklucHV0V2hlblJlYWRvbmx5ID0gaW5wdXQ8Ym9vbGVhbj4oKTtcblxuICAvKiBPVVRQVVQgKi9cbiAgcmVhZG9ubHkgb3V0U2VsZWN0TXVsdGlJdGVtID0gb3V0cHV0PEFycmF5PHVua25vd24+PigpO1xuICByZWFkb25seSBvdXRWYWxpZEV2ZW50ID0gb3V0cHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uc0NvbnRyb2wgPSBvdXRwdXQ8SVRhZ3NGdW5jdGlvbkNvbnRyb2xFdmVudD4oKTtcbiAgcmVhZG9ubHkgb3V0Q2xpY2tCdXR0b25PdGhlciA9IG91dHB1dDxJQnV0dG9uPigpO1xuICByZWFkb25seSBvdXRTaG93TGlzdEV2ZW50ID0gb3V0cHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IG91dENoYW5nU3RhZ2VGbGFnTW91c2UgPSBvdXRwdXQ8SUZsYWdNb3VzZT4oKTtcbiAgcmVhZG9ubHkgb3V0TG9hZGluZ0dldERldGFpbFNlbGVjdGVkID0gb3V0cHV0PGJvb2xlYW4+KCk7XG5cbiAgLyogVklFVyBDSElMRCAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRhZ3NFbCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPigndGFnc0VsJyk7XG5cbiAgLyogSU5KRUNUKi9cbiAgcHJpdmF0ZSBodHRwUmVxdWVzdFNlcnZpY2UgPSBpbmplY3QoTGlic1VpSHR0cFJlcXVlc3RTZXJ2aWNlKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgbWF4SXRlbUlucHV0ID0gdGhpcy5tYXhJdGVtSW5wdXQoKTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzYWJsZVdoZW5NYXhJdGVtLnNldChmYWxzZSk7XG4gICAgICAgIGlmIChtYXhJdGVtSW5wdXQgJiYgbWF4SXRlbUlucHV0IDw9IHRoaXMuaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuZGlzYWJsZVdoZW5NYXhJdGVtLnNldCh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBsaXN0Q29uZmlnID0gdGhpcy5saXN0Q29uZmlnKCk7XG4gICAgICB1bnRyYWNrZWQoKCkgPT4ge1xuICAgICAgICBpZiAobGlzdENvbmZpZykge1xuICAgICAgICAgIHRoaXMuZmllbGRLZXkuc2V0KGdldEZpZWxkS2V5QnlUeXBlKGxpc3RDb25maWcsICdpZCcpKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IHRoaXMuZGVmYXVsdEl0ZW1zU2VsZWN0ZWQoKSB8fCBbXTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzSXRlbXMgPSB0aGlzLmRlZmF1bHRJdGVtc1NlbGVjdGVkQ3VycmVudCgpIHx8IFtdO1xuICAgICAgICB0aGlzLmRlZmF1bHRJdGVtc1NlbGVjdGVkQ3VycmVudC5zZXQodGhpcy5kZWZhdWx0SXRlbXNTZWxlY3RlZCgpKTtcbiAgICAgICAgaWYgKHByZXZpb3VzSXRlbXMubGVuZ3RoICE9PSBjdXJyZW50SXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVJdGVtc1NlbGVjdGVkKGN1cnJlbnRJdGVtcyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcHJldkl0ZW0gb2YgcHJldmlvdXNJdGVtcykge1xuICAgICAgICAgIGlmICghY3VycmVudEl0ZW1zLnNvbWUoaXRlbSA9PiBnZXQoaXRlbSwgdGhpcy5maWVsZEtleSgpKSA9PT0gZ2V0KHByZXZJdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVJdGVtc1NlbGVjdGVkKGN1cnJlbnRJdGVtcyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSlcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5kZWZhdWx0S2V5c1NlbGVjdGVkKCkgfHwgW107XG4gICAgICB1bnRyYWNrZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBwcmV2aW91c1ZhbHVlID0gdGhpcy5rZXlzU2VsZWN0ZWQoKSB8fCBbXTtcbiAgICAgICAgaWYgKHByZXZpb3VzVmFsdWUubGVuZ3RoICE9PSBjdXJyZW50VmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5nZXREZXRhaWxCeUlkcyhjdXJyZW50VmFsdWUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXlzTmV3ID0gY3VycmVudFZhbHVlLmZpbHRlcihrZXkgPT4gIXRoaXMuaXRlbXNTZWxlY3RlZCgpLnNvbWUoaXRlbSA9PiBpdGVtW3RoaXMuZmllbGRLZXkoKV0gPT09IGtleSkpO1xuICAgICAgICBpZiAoa2V5c05ldy5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLmdldERldGFpbEJ5SWRzKGtleXNOZXcpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHMgPSB0aGlzLmh0dHBSZXF1ZXN0RGV0YWlsSXRlbUJ5SWRzKCk7XG4gICAgaWYgKGh0dHBSZXF1ZXN0RGV0YWlsSXRlbUJ5SWRzICYmICghaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHMuZ3VpZGVBdXRvVXBkYXRlQXJndW1lbnRzVmFsdWUgfHwgIWh0dHBSZXF1ZXN0RGV0YWlsSXRlbUJ5SWRzLmd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlPy5kZXRhaWxCeUlkKSkge1xuICAgICAgdGhyb3cgJ0NvbmZpZyBnZXREZXRhaWxCeUlkcyB5w6p1IGPhuqd1IHThu5FpIHRoaeG7g3UgY8OhYyB0aGFtIHPhu5EgIGd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlLCBkZXRhaWxCeUlkJztcbiAgICB9XG4gICAgY29uc3QgcHJlcHJvY2Vzc29yID0gKGtleXM6IEFycmF5PHVua25vd24+KSA9PiB7XG4gICAgICBpZiAoIWtleXMgfHwgIShrZXlzIGluc3RhbmNlb2YgQXJyYXkpIHx8ICFrZXlzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgICByZXR1cm4ga2V5cy5qb2luKCc7Jyk7XG4gICAgfTtcbiAgICBpZiAoaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHM/Lmd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlPy5kZXRhaWxCeUlkKSB7XG4gICAgICBodHRwUmVxdWVzdERldGFpbEl0ZW1CeUlkcy5ndWlkZUF1dG9VcGRhdGVBcmd1bWVudHNWYWx1ZS5kZXRhaWxCeUlkLmZpZWxkR2V0VmFsdWUgPSBodHRwUmVxdWVzdERldGFpbEl0ZW1CeUlkcy5ndWlkZUF1dG9VcGRhdGVBcmd1bWVudHNWYWx1ZS5kZXRhaWxCeUlkLmZpZWxkR2V0VmFsdWUgPz8gJ2tleXMnO1xuICAgICAgaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHMuZ3VpZGVBdXRvVXBkYXRlQXJndW1lbnRzVmFsdWUuZGV0YWlsQnlJZC5wcmVwcm9jZXNzb3IgPSBodHRwUmVxdWVzdERldGFpbEl0ZW1CeUlkcy5ndWlkZUF1dG9VcGRhdGVBcmd1bWVudHNWYWx1ZS5kZXRhaWxCeUlkLnByZXByb2Nlc3NvciA/PyBwcmVwcm9jZXNzb3I7XG4gICAgfVxuICAgIHRoaXMub3V0RnVuY3Rpb25zQ29udHJvbC5lbWl0KHtcbiAgICAgIHZhbGlkOiB0aGlzLmNoZWNrVmFsaWQuYmluZCh0aGlzKSxcbiAgICAgIHJlbW92ZUxpc3Q6IGFzeW5jICgpID0+IHRoaXMucG9wb3ZlckZ1bmN0aW9uQ29udHJvbCgpPy5yZW1vdmVQb3BvdmVyT3ZlcmxheSgpLFxuICAgICAgdXBkYXRlTGFiZWw6IHRoaXMudXBkYXRlTGFiZWwuYmluZCh0aGlzKSxcbiAgICAgIGNsZWFySXRlbVNlbGVjdGVkOiB0aGlzLmNsZWFySXRlbVNlbGVjdGVkLmJpbmQodGhpcyksXG4gICAgICBjbGVhcktleVNlYXJjaDogKCkgPT4gdGhpcy5oYW5kbGVyVmFsdWVDaGFuZ2VTZWFyY2goJycpLFxuICAgICAgZm9jdXNJbnB1dDogKCkgPT4gdGhpcy5mb2N1c0lucHV0KCksXG4gICAgICBnZXRGYWtlSWQ6IGFzeW5jICgpID0+IHRoaXMuZmFrZUlkKCksXG4gICAgICBjcmVhdGVUYWc6IHRoaXMuaGFuZGxlckVudGVyRXZlbnQuYmluZCh0aGlzKSxcbiAgICAgIHJlbW92ZUl0ZW1TZWxlY3RlZDogdGhpcy5oYW5kbGVyUmVtb3ZlSXRlbVNlbGVjdGVkLmJpbmQodGhpcyksXG4gICAgICByZXNldEVycm9yOiB0aGlzLnJlc2V0RXJyb3IuYmluZCh0aGlzKSxcbiAgICAgIHJlc2V0VG9EZWZhdWx0RGF0YVNlbGVjdGVkOiB0aGlzLnJlc2V0VG9EZWZhdWx0RGF0YVNlbGVjdGVkLmJpbmQodGhpcyksXG4gICAgICB1cGRhdGVJdGVtU2VsZWN0ZWREaXNhYmxlOiB0aGlzLnVwZGF0ZUl0ZW1TZWxlY3RlZERpc2FibGUuYmluZCh0aGlzKSxcbiAgICAgIHJlZnJlc2hMaXN0RGF0YTogdGhpcy5yZWZyZXNoTGlzdERhdGEuYmluZCh0aGlzKSxcbiAgICAgIHNldEVycm9yOiB0aGlzLnNldEVycm9yLmJpbmQodGhpcylcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2V0RXJyb3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgdGhpcy5lcnJvci5zZXQoeyBtZXNzYWdlIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQoZXZlbnQ6IElQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQpIHtcbiAgICB0aGlzLnBvcG92ZXJGdW5jdGlvbkNvbnRyb2wuc2V0KGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlTGFiZWwoKSB7XG4gICAgaWYgKCF0aGlzLml0ZW1zU2VsZWN0ZWQoKSB8fCAhdGhpcy5pdGVtc1NlbGVjdGVkKCkubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaXRlbXNTZWxlY3RlZC51cGRhdGUoaXRlbXMgPT4ge1xuICAgICAgaXRlbXMuZm9yRWFjaChpdGVtID0+IHRoaXMudXBkYXRlRmllbGRMYWJlbChpdGVtKSk7XG4gICAgICByZXR1cm4gWy4uLml0ZW1zXVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGaWVsZExhYmVsKGl0ZW06IHVua25vd24pIHtcbiAgICBjb25zdCByZWYgPSBnZXQoaXRlbSwgJ3JlZicpIHx8IGl0ZW07XG4gICAgY29uc3QgZ2V0VmFsdWUgPSB0aGlzLmNvbmZpZygpPy5nZXRWYWx1ZTtcbiAgICBzZXQoaXRlbSwgJ2ZpZWxkTGFiZWwnLCBgJHtnZXQocmVmLCB0aGlzLmZpZWxkTGFiZWwoKSkgfHwgcmVmLmxhYmVsIHx8IHJlZi5uYW1lIHx8ICcgJ31gKTtcbiAgICBpZiAoZ2V0VmFsdWUpIHtcbiAgICAgIHNldChpdGVtLCAnZmllbGRMYWJlbCcsIGdldFZhbHVlKHJlZikgfHwgJyAnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNsZWFySXRlbVNlbGVjdGVkKGlnbm9yZVZhbGlkID0gZmFsc2UpIHtcbiAgICBpZiAoIXRoaXMuaXRlbXNTZWxlY3RlZCgpIHx8ICF0aGlzLml0ZW1zU2VsZWN0ZWQoKS5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy5pdGVtc1NlbGVjdGVkKCkubGVuZ3RoIC0gMTtcbiAgICB0aGlzLnRlbXBJZ25vcmVFbWl0LnNldCh0cnVlKTtcbiAgICB0aGlzLml0ZW1zU2VsZWN0ZWQoKS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ID09PSBsZW5ndGgpIHtcbiAgICAgICAgdGhpcy50ZW1wSWdub3JlRW1pdC5zZXQoZmFsc2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5oYW5kbGVyUmVtb3ZlSXRlbVNlbGVjdGVkKHsgc3RvcFByb3BhZ2F0aW9uOiAoKSA9PiB7IHJldHVybiB9IH0gYXMgRXZlbnQsIGl0ZW0sIGlnbm9yZVZhbGlkKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlSXRlbXNTZWxlY3RlZChpdGVtc1NlbGVjdGVkOiBBcnJheTx1bmtub3duPiwgaWdub3JlVmFsaWRhdGUgPSB0cnVlLCBpZ25vcmVFbWl0S2V5U2VsZWN0ZWRXaGVuSXRlbXNOb3RFeGl0c0VtcHR5PzogYm9vbGVhbikge1xuICAgIGlmICghaXRlbXNTZWxlY3RlZCB8fCAhaXRlbXNTZWxlY3RlZC5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXRlbXNOb3RFeGl0czogQXJyYXk8dW5rbm93bj4gPSBbXTtcbiAgICBpdGVtc1NlbGVjdGVkLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpZiAoIWl0ZW0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbGV0IGZpZWxkTGFiZWwgPSBgJHtnZXQoaXRlbSwgdGhpcy5maWVsZExhYmVsKCkpIHx8IGdldChpdGVtLCAnbGFiZWwnKSB8fCBnZXQoaXRlbSwgJ25hbWUnKSB8fCAnICd9YDtcbiAgICAgIGNvbnN0IGdldFZhbHVlID0gdGhpcy5jb25maWcoKT8uZ2V0VmFsdWU7XG4gICAgICBpZiAoZ2V0VmFsdWUpIHtcbiAgICAgICAgZmllbGRMYWJlbCA9IGdldFZhbHVlKGl0ZW0pIHx8ICcgJztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGl0ZW1FeGl0cyA9IHRoaXMuY2hlY2tFeGl0cyhmaWVsZExhYmVsLCBnZXQoaXRlbSwgdGhpcy5maWVsZEtleSgpKSk7XG4gICAgICBpZiAoaXRlbUV4aXRzPy5pc0l0ZW1TZWxlY3RlZCkge1xuICAgICAgICBPYmplY3QuYXNzaWduKGl0ZW1FeGl0cy5pdGVtLCBpdGVtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaXRlbXNOb3RFeGl0cy5wdXNoKGl0ZW0pO1xuICAgIH0pO1xuICAgIHRoaXMucHJvY2Vzc0RhdGEoaXRlbXNOb3RFeGl0cywgaWdub3JlVmFsaWRhdGUsIGlnbm9yZUVtaXRLZXlTZWxlY3RlZFdoZW5JdGVtc05vdEV4aXRzRW1wdHkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJQb3BvdmVyRXZlbnQodHlwZTogVFlQRV9QT1BPVkVSX0VWRU5UKSB7XG4gICAgdGhpcy50eXBlUG9wb3Zlci5zZXQodHlwZSk7XG4gICAgaWYgKHR5cGUgPT09ICdjbGljaycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09ICdyZW1vdmUnKSB7XG4gICAgICB0aGlzLnNob3dMaXN0LnNldChmYWxzZSk7XG4gICAgICB0aGlzLm91dFNob3dMaXN0RXZlbnQuZW1pdChmYWxzZSk7XG4gICAgICB0aGlzLmlucHV0RnVuY3Rpb25Db250cm9sKCk/LmJsdXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zaG93TGlzdC5zZXQodHJ1ZSk7XG4gICAgdGhpcy5vdXRTaG93TGlzdEV2ZW50LmVtaXQodHJ1ZSk7XG4gICAgdGhpcy5pbnB1dEZ1bmN0aW9uQ29udHJvbCgpPy5mb2N1cygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJQb3BvdmVyQ29udGVudEV2ZW50KHBvc2l0aW9uOiBUWVBFX1BPUE9WRVJfRElSRUNUSU9OKSB7XG4gICAgaWYgKHRoaXMucG9zaXRpb25MaXN0KCkgPT09IHBvc2l0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25MaXN0LnNldChwb3NpdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclJlbW92ZUl0ZW1TZWxlY3RlZChldmVudDogRXZlbnQsIGl0ZW1SZW1vdmU6IHVua25vd24sIGlnbm9yZVZhbGlkPzogYm9vbGVhbikge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZmxhZ01vdXNlLnNldCh7IGlzTW91c2VFbnRlcjogdHJ1ZSwgaXNNb3VzZUVudGVyQ29udGVudDogdHJ1ZSB9KTtcbiAgICB0aGlzLnRpbWVPdXRGbGFnLnNldChzZXRUaW1lb3V0KCgpID0+IHRoaXMuZmxhZ01vdXNlLnNldCh7IGlzTW91c2VFbnRlcjogZmFsc2UsIGlzTW91c2VFbnRlckNvbnRlbnQ6IGZhbHNlIH0pLCAyNTApKTtcbiAgICB0aGlzLml0ZW1zU2VsZWN0ZWQudXBkYXRlKGl0ZW1zID0+IGl0ZW1zLmZpbHRlcihpdGVtID0+ICgoaXNOaWwoZ2V0KGl0ZW1SZW1vdmUsIHRoaXMuZmllbGRLZXkoKSkpIHx8IGlzTmlsKGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkgJiYgZ2V0KGl0ZW1SZW1vdmUsICdmaWVsZExhYmVsJykudHJpbSgpICE9PSBpdGVtLmZpZWxkTGFiZWwudHJpbSgpIHx8ICghaXNOaWwoZ2V0KGl0ZW1SZW1vdmUsIHRoaXMuZmllbGRLZXkoKSkpICYmICFpc05pbChnZXQoaXRlbSwgdGhpcy5maWVsZEtleSgpKSkgJiYgZ2V0KGl0ZW1SZW1vdmUsIHRoaXMuZmllbGRLZXkoKSkgIT09IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkpKTtcbiAgICB0aGlzLml0ZW1DaGFuZ2VVblNlbGVjdC5zZXQoaXRlbVJlbW92ZSk7XG4gICAgaWYgKGl0ZW1SZW1vdmUgJiYgIWlzTmlsKGdldChpdGVtUmVtb3ZlLCB0aGlzLmZpZWxkS2V5KCkpKSAmJiBgJHtnZXQoaXRlbVJlbW92ZSwgdGhpcy5maWVsZEtleSgpKX1gLnNlYXJjaCh0aGlzLmZha2VJZCgpKSA+PSAwKSB7XG4gICAgICB0aGlzLmtleXNIaWRkZW5JdGVtLnVwZGF0ZShpdGVtcyA9PiAoWy4uLml0ZW1zIHx8IFtdLCBnZXQoaXRlbVJlbW92ZSwgdGhpcy5maWVsZEtleSgpKV0pKTtcbiAgICB9XG4gICAgdGhpcy5rZXlzU2VsZWN0ZWQuc2V0KEFycmF5LmZyb20obmV3IFNldCh0aGlzLml0ZW1zU2VsZWN0ZWQoKS5tYXAoaXRlbSA9PiBnZXQoaXRlbSwgdGhpcy5maWVsZEtleSgpKSkpKSk7XG4gICAgdGhpcy5kaXNhYmxlV2hlbk1heEl0ZW0uc2V0KGZhbHNlKTtcbiAgICBjb25zdCBtYXhJdGVtSW5wdXQgPSB0aGlzLm1heEl0ZW1JbnB1dCgpO1xuICAgIGlmIChtYXhJdGVtSW5wdXQgJiYgbWF4SXRlbUlucHV0IDw9IHRoaXMuaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkge1xuICAgICAgdGhpcy5kaXNhYmxlV2hlbk1heEl0ZW0uc2V0KHRydWUpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2hvd0xpc3QoKSkge1xuICAgICAgdGhpcy5vdXRTZWxlY3RNdWx0aUl0ZW0uZW1pdCh0aGlzLmdldEl0ZW1TZWxlY3RlZCgpKTtcbiAgICAgIHRoaXMuY2hlY2tWaWV3Q2hhbmdlKHRydWUsIGlnbm9yZVZhbGlkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2hvd0xpc3QoKSkge1xuICAgICAgdGhpcy50ZW1wSWdub3JlRW1pdC5zZXQodHJ1ZSk7XG4gICAgfVxuICAgIGlmICghaWdub3JlVmFsaWQpIHtcbiAgICAgIHRoaXMuY2hlY2tWYWxpZCgpO1xuICAgIH1cbiAgICB0aGlzLnRlbXBJZ25vcmVFbWl0LnNldChmYWxzZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlcklucHV0RnVuY3Rpb25Db250cm9sKGV2ZW50OiBJSW5wdXRGdW5jdGlvbkNvbnRyb2xFdmVudCkge1xuICAgIHRoaXMuaW5wdXRGdW5jdGlvbkNvbnRyb2wuc2V0KGV2ZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyRm9jdXNBbmRCbHVyRXZlbnQoZXZlbnQ6IElGb2N1c0FuZEJsdXJFdmVudCkge1xuICAgIHRoaXMuZm9jdXMuc2V0KGZhbHNlKTtcbiAgICBpZiAoZXZlbnQubmFtZSA9PT0gJ2ZvY3VzJykge1xuICAgICAgdGhpcy5mb2N1cy5zZXQodHJ1ZSk7XG4gICAgfVxuICAgIGlmIChldmVudC5uYW1lID09PSAnYmx1cicgJiYgdGhpcy50eXBlUG9wb3ZlcigpPy5pbmNsdWRlcygnbW91c2VsZWF2ZScpICYmIHRoaXMudmFsaWRSZXF1aXJlZCgpICYmICghdGhpcy5pdGVtc1NlbGVjdGVkKCkgfHwgIXRoaXMuaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkpIHtcbiAgICAgIHRoaXMuY2hlY2tWYWxpZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2xpY2tPdXRzaWRlKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRDbGlja091dHNpZGUoKSk7XG4gICAgdGhpcy50aW1lb3V0Q2xpY2tPdXRzaWRlLnNldChzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnNob3dMaXN0KCkgfHwgIXRoaXMucmVtb3ZlVGV4dFNlYXJjaFdoZW5CbHVySW5wdXQoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnZhbHVlSW5wdXQuc2V0KCcnKTtcbiAgICAgIHRoaXMua2V5U2VhcmNoLnNldCgnJyk7XG4gICAgICB0aGlzLmlucHV0RnVuY3Rpb25Db250cm9sKCk/LnJlc2V0VmFsdWUoKTtcbiAgICB9LCAyNTApKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVyRW50ZXJFdmVudCgpIHtcbiAgICBpZiAoIXRoaXMudmFsdWVJbnB1dCgpIHx8ICFgJHt0aGlzLnZhbHVlSW5wdXQoKX1gLnRyaW0oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5jb25maWcoKT8uaWdub3JlRW50ZXJDcmVhdGVOZXdJdGVtKSB7XG4gICAgICBjb25zdCBpdGVtRXhpdHMgPSB0aGlzLmNoZWNrRXhpdHMoKTtcbiAgICAgIGlmICghaXRlbUV4aXRzIHx8IGl0ZW1FeGl0cy5pc0l0ZW1TZWxlY3RlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnByb2Nlc3NEYXRhKFtpdGVtRXhpdHMuaXRlbV0pO1xuICAgICAgdGhpcy5oYW5kbGVyVmFsdWVDaGFuZ2VTZWFyY2goJycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZnVuY3Rpb25DaGVja1Blcm1pc3Npb25DcmVhdGVUYWcoKSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1FeGl0cyA9IHRoaXMuY2hlY2tFeGl0cygpO1xuICAgIGNvbnN0IHZhbHVlSW5wdXQgPSBgJHt0aGlzLnZhbHVlSW5wdXQoKX1gLnRyaW0oKTtcbiAgICBjb25zdCBuZXdJdGVtID0geyBbdGhpcy5maWVsZExhYmVsKCldOiB2YWx1ZUlucHV0IH07XG4gICAgaWYgKHRoaXMuZmllbGRLZXkoKSkge1xuICAgICAgbmV3SXRlbVt0aGlzLmZpZWxkS2V5KCldID0gYCR7dGhpcy5mYWtlSWQoKX0ke3ZhbHVlSW5wdXR9JHt1dWlkKCl9YDtcbiAgICB9XG4gICAgaWYgKCFpdGVtRXhpdHMpIHtcbiAgICAgIGlmICh0aGlzLmNoZWNrUGF0dGVybihbbmV3SXRlbV0pKSB7XG4gICAgICAgIGNvbnN0IGl0ZW1CdWlsZFZhbHVlID0geyAuLi5uZXdJdGVtIH07XG4gICAgICAgIGNvbnN0IGJ1aWxkVmFsdWUgPSB0aGlzLmNvbmZpZygpPy5idWlsZFZhbHVlO1xuICAgICAgICBpZiAoYnVpbGRWYWx1ZSkge1xuICAgICAgICAgIGJ1aWxkVmFsdWUoaXRlbUJ1aWxkVmFsdWUsIG5ld0l0ZW1bdGhpcy5maWVsZExhYmVsKCldKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdJdGVtW3RoaXMuZmllbGRMYWJlbCgpXSA9IGl0ZW1CdWlsZFZhbHVlW3RoaXMuZmllbGRMYWJlbCgpXTtcbiAgICAgICAgaWYgKHRoaXMuZW50ZXJBdXRvQWRkVGFnVG9MaXN0KCkpIHtcbiAgICAgICAgICB0aGlzLmxpc3RGdW5jdGlvbkNvbnRyb2woKT8udXBkYXRlRGF0YSh7IG5ld0RhdGE6IFtuZXdJdGVtXSwgZnVuY3Rpb25DdXN0b21BZGREYXRhVG9TdG9yZTogKG5ld0RhdGEsIHN0b3JlKSA9PiBzdG9yZS51cGRhdGUodmFsdWUgPT4gKFsuLi5uZXdEYXRhLCAuLi52YWx1ZV0pKSB9KVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvY2Vzc0RhdGEoW25ld0l0ZW1dKTtcbiAgICAgICAgdGhpcy5oYW5kbGVyVmFsdWVDaGFuZ2VTZWFyY2goJycpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXRlbUV4aXRzLmlzSXRlbVNlbGVjdGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucHJvY2Vzc0RhdGEoW2l0ZW1FeGl0cy5pdGVtXSk7XG4gICAgdGhpcy5oYW5kbGVyVmFsdWVDaGFuZ2VTZWFyY2goJycpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGhhbmRsZXJWYWx1ZUNoYW5nZVNlYXJjaCh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgdGhpcy52YWx1ZUlucHV0LnNldChgJHt2YWx1ZX1gKTtcbiAgICBpZiAoIWAke3ZhbHVlIHx8ICcnfWAudHJpbSgpKSB7XG4gICAgICB0aGlzLmtleVNlYXJjaENoYW5nZVN1YigpPy51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5rZXlTZWFyY2hDaGFuZ2VTdWIuc2V0KHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLnRpbWVPdXRDaGFuZ2VTZWFyY2guc2V0KHNldFRpbWVvdXQoKCkgPT4gdGhpcy5rZXlTZWFyY2guc2V0KCcnKSkpO1xuICAgICAgaWYgKCF0aGlzLmNvbmZpZygpPy5pZ25vcmVFbnRlckNyZWF0ZU5ld0l0ZW0pIHtcbiAgICAgICAgdGhpcy5jaGVja1ZhbGlkKCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZygpPy5pZ25vcmVJbnB1dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMua2V5U2VhcmNoQ2hhbmdlU3ViKCkpIHtcbiAgICAgIHRoaXMuc2V0RXZlbnRLZXlTZWFyY2goKTtcbiAgICB9XG4gICAgdGhpcy5rZXlTZWFyY2hDaGFuZ2UubmV4dChgJHsodmFsdWUgfHwgJycpfWAudHJpbSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0RXZlbnRLZXlTZWFyY2goKSB7XG4gICAgaWYgKHRoaXMua2V5U2VhcmNoQ2hhbmdlU3ViKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5rZXlTZWFyY2hDaGFuZ2VTdWIuc2V0KHRoaXMua2V5U2VhcmNoQ2hhbmdlLnBpcGUoZGVib3VuY2VUaW1lKDE1MDApLCB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpKS5zdWJzY3JpYmUodmFsdWUgPT4gdGhpcy5rZXlTZWFyY2guc2V0KGAkeyh2YWx1ZSB8fCAnJyl9YC50cmltKCkpKSk7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NEYXRhKGl0ZW1zOiBBcnJheTx1bmtub3duPiwgaWdub3JlVmFsaWRhdGUgPSBmYWxzZSwgaWdub3JlRW1pdEtleVNlbGVjdGVkV2hlbkl0ZW1zTm90RXhpdHNFbXB0eT86IGJvb2xlYW4pIHtcbiAgICBpZiAoIWl0ZW1zIHx8ICFpdGVtcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGl0ZW1zU2VsZWN0ZWQgPSB0aGlzLmdldEl0ZW1TZWxlY3RlZCgpO1xuICAgICAgaWYgKCFpZ25vcmVFbWl0S2V5U2VsZWN0ZWRXaGVuSXRlbXNOb3RFeGl0c0VtcHR5KSB7XG4gICAgICAgIHRoaXMub3V0U2VsZWN0TXVsdGlJdGVtLmVtaXQoaXRlbXNTZWxlY3RlZCk7XG4gICAgICB9XG4gICAgICB0aGlzLmtleXNTZWxlY3RlZC5zZXQoQXJyYXkuZnJvbShuZXcgU2V0KGl0ZW1zU2VsZWN0ZWQ/Lm1hcChpdGVtID0+IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkpKTtcbiAgICAgIHRoaXMuY2hlY2tWaWV3Q2hhbmdlKGZhbHNlLCBpZ25vcmVWYWxpZGF0ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1zTWFwcGluZyA9IGl0ZW1zLm1hcChpdGVtID0+IHtcbiAgICAgIGNvbnN0IHJlZiA9IGdldChpdGVtLCAncmVmJykgfHwgaXRlbTtcbiAgICAgIGl0ZW0gPSBjbG9uZURlZXAocmVmKTtcbiAgICAgIHNldChpdGVtLCAncmVmJywgcmVmKTtcbiAgICAgIHRoaXMudXBkYXRlRmllbGRMYWJlbChpdGVtKTtcbiAgICAgIGNvbnN0IGdldERpc2FibGVJdGVtID0gdGhpcy5jb25maWcoKT8uZ2V0RGlzYWJsZUl0ZW07XG4gICAgICBjb25zdCBnZXRTdHlsZXMgPSB0aGlzLmNvbmZpZygpPy5nZXRTdHlsZXM7XG4gICAgICBjb25zdCBnZXRTdHlsZXNUYWdTcGVjaWZpYyA9IHRoaXMuY29uZmlnKCk/LmdldFN0eWxlc1RhZ1NwZWNpZmljO1xuICAgICAgaWYgKGdldERpc2FibGVJdGVtKSB7XG4gICAgICAgIHNldChpdGVtLCAnZGlzYWJsZUl0ZW0nLCBnZXREaXNhYmxlSXRlbShpdGVtKSk7XG4gICAgICB9XG4gICAgICBpZiAoZ2V0U3R5bGVzKSB7XG4gICAgICAgIHNldChpdGVtLCAnbmdTdHlsZXMnLCBnZXRTdHlsZXMoaXRlbSkpO1xuICAgICAgfVxuICAgICAgaWYgKGdldFN0eWxlc1RhZ1NwZWNpZmljKSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBnZXRTdHlsZXNUYWdTcGVjaWZpYyhpdGVtKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzcGVjaWZpY192aW9sZXRfY29sb3InKSB7XG4gICAgICAgICAgc2V0KGl0ZW0sICduZ1N0eWxlcycsIHsgY29sb3I6ICcjNzIzOUVBJywgYmFja2dyb3VuZENvbG9yOiAnI0YxRUJGRCcgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVtO1xuICAgIH0pO1xuICAgIHRoaXMuaXRlbXNTZWxlY3RlZC51cGRhdGUoaXRlbXMgPT4gWy4uLml0ZW1zLCAuLi5pdGVtc01hcHBpbmddKTtcbiAgICB0aGlzLmtleXNTZWxlY3RlZC5zZXQoQXJyYXkuZnJvbShuZXcgU2V0KHRoaXMuaXRlbXNTZWxlY3RlZCgpLm1hcChpdGVtID0+IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkpKTtcbiAgICB0aGlzLm91dFNlbGVjdE11bHRpSXRlbS5lbWl0KHRoaXMuZ2V0SXRlbVNlbGVjdGVkKCkpO1xuICAgIHRoaXMuY2hlY2tWaWV3Q2hhbmdlKGZhbHNlLCBpZ25vcmVWYWxpZGF0ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckRhdGFDaGFuZ2UoaXRlbXM6IEFycmF5PHVua25vd24+KSB7XG4gICAgdGhpcy5pdGVtc09mTGlzdC5zZXQoaXRlbXMpO1xuICAgIHRoaXMucG9wb3ZlckZ1bmN0aW9uQ29udHJvbCgpPy51cGRhdGVQb3BvdmVyT3ZlcmxheVBvc2l0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmNvbmZpZygpPy5pZ25vcmVJbnB1dCkge1xuICAgICAgdGhpcy5pbnB1dEZ1bmN0aW9uQ29udHJvbCgpPy5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyTG9hZGluZyhldmVudDogYm9vbGVhbikge1xuICAgIHRoaXMubG9hZGluZy5zZXQoZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja1ZpZXdDaGFuZ2UoaWdub3JlU2Nyb2xsQm90dG9tOiBib29sZWFuLCBpZ25vcmVWYWxpZGF0ZSA9IGZhbHNlKSB7XG4gICAgdGhpcy5kaXNhYmxlV2hlbk1heEl0ZW0uc2V0KGZhbHNlKTtcbiAgICBjb25zdCBtYXhJdGVtSW5wdXQgPSB0aGlzLm1heEl0ZW1JbnB1dCgpO1xuICAgIGlmIChtYXhJdGVtSW5wdXQgJiYgbWF4SXRlbUlucHV0IDw9IHRoaXMuaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkge1xuICAgICAgdGhpcy5kaXNhYmxlV2hlbk1heEl0ZW0uc2V0KHRydWUpO1xuICAgIH1cbiAgICB0aGlzLnRpbWVPdXRDaGVja1ZpZXdDaGFuZ2Uuc2V0KChzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IHNjcm9sbEhlaWdodCA9IHRoaXMudGFnc0VsKCk/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xuICAgICAgaWYgKCFpc05pbChzY3JvbGxIZWlnaHQpICYmIHRoaXMuY2xpZW50SGVpZ2h0KCkgIT09IHNjcm9sbEhlaWdodCAmJiB0aGlzLnBvc2l0aW9uTGlzdCgpICE9PSAndG9wJykge1xuICAgICAgICB0aGlzLnBvcG92ZXJGdW5jdGlvbkNvbnRyb2woKT8udXBkYXRlUG9wb3Zlck92ZXJsYXlQb3NpdGlvbigpO1xuICAgICAgfVxuICAgICAgaWYgKCFpZ25vcmVTY3JvbGxCb3R0b20gJiYgdGhpcy50YWdzRWwoKSAmJiB0aGlzLnRhZ3NFbCgpLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy50YWdzRWwoKS5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCA9IHNjcm9sbEhlaWdodFxuICAgICAgfVxuICAgICAgdGhpcy5jbGllbnRIZWlnaHQuc2V0KHNjcm9sbEhlaWdodCk7XG4gICAgfSwgMjUwKSkpO1xuICAgIGlmICghaWdub3JlVmFsaWRhdGUpIHtcbiAgICAgIHRoaXMuY2hlY2tWYWxpZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tFeGl0cyhsYWJlbD86IHN0cmluZywgaWQ/OiBzdHJpbmcpIHtcbiAgICBsZXQgaXRlbUV4aXRzO1xuICAgIGlmICghaXNOaWwoaWQpICYmICFgJHtpZH1gLmluY2x1ZGVzKHRoaXMuZmFrZUlkKCkpICYmIHRoaXMuZmllbGRLZXkoKSkge1xuICAgICAgaXRlbUV4aXRzID0gdGhpcy5pdGVtc1NlbGVjdGVkKCkuZmluZChpdGVtID0+ICFpc05pbChnZXQoaXRlbSwgdGhpcy5maWVsZEtleSgpKSkgJiYgYCR7Z2V0KGl0ZW0sIHRoaXMuZmllbGRLZXkoKSl9YC50cmltKCkgPT09IGAke2lkfWApO1xuICAgICAgaWYgKGl0ZW1FeGl0cykge1xuICAgICAgICByZXR1cm4geyBpdGVtOiBpdGVtRXhpdHMsIGlzSXRlbVNlbGVjdGVkOiAhIWl0ZW1FeGl0cyB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWxhYmVsKSB7XG4gICAgICBsYWJlbCA9IGAkeyh0aGlzLnZhbHVlSW5wdXQgfHwgJycpfWAudHJpbSgpO1xuICAgIH1cbiAgICBpdGVtRXhpdHMgPSB0aGlzLml0ZW1zU2VsZWN0ZWQoKS5maW5kKGl0ZW0gPT4gIWlzTmlsKGdldChpdGVtLCAnZmllbGRMYWJlbCcpKSAmJiAoZ2V0KGl0ZW0sICdmaWVsZExhYmVsJykudHJpbSgpID09PSBsYWJlbD8udHJpbSgpKSB8fCAodGhpcy5jaGVja0V4aXRJc0xhYmVsSW5jbHVkZSgpICYmIGdldChpdGVtLCAnZmllbGRMYWJlbCcpLnRyaW0oKS5pbmNsdWRlcyhsYWJlbD8udHJpbSgpKSkgfHwgKHRoaXMuY2hlY2tFeGl0QnlGaWVsZHMoKSAmJiB0aGlzLmNoZWNrRXhpdEJ5RmllbGRzKCk/LnNvbWUoZmllbGQgPT4gZ2V0KGl0ZW0sIGZpZWxkKT8udHJpbSgpID09PSBsYWJlbD8udHJpbSgpIHx8IGdldChpdGVtLCBmaWVsZCk/LnRyaW0oKSA9PT0gZXNjYXBlSHRtbChsYWJlbD8udHJpbSgpIHx8ICcnKSB8fCBlc2NhcGVIdG1sKGdldChpdGVtLCBmaWVsZCk/LnRyaW0oKSB8fCAnICcpID09PSBlc2NhcGVIdG1sKGxhYmVsPy50cmltKCkgfHwgJycpKSkpO1xuICAgIGlmIChpdGVtRXhpdHMpIHtcbiAgICAgIHJldHVybiB7IGl0ZW06IGl0ZW1FeGl0cywgaXNJdGVtU2VsZWN0ZWQ6IHRydWUgfTtcbiAgICB9XG4gICAgaXRlbUV4aXRzID0gdGhpcy5pdGVtc09mTGlzdCgpLmZpbmQoaXRlbSA9PiAhaXNOaWwoZ2V0KGl0ZW0sICdmaWVsZExhYmVsJykpICYmIChnZXQoaXRlbSwgJ2ZpZWxkTGFiZWwnKS50cmltKCkuaW5jbHVkZXMoKSA9PT0gbGFiZWw/LnRyaW0oKSkgfHwgKHRoaXMuY2hlY2tFeGl0SXNMYWJlbEluY2x1ZGUoKSAmJiBnZXQoaXRlbSwgJ2ZpZWxkTGFiZWwnKS50cmltKCkuaW5jbHVkZXMobGFiZWw/LnRyaW0oKSkpIHx8ICh0aGlzLmNoZWNrRXhpdEJ5RmllbGRzKCkgJiYgdGhpcy5jaGVja0V4aXRCeUZpZWxkcygpPy5zb21lKGZpZWxkID0+IGdldChpdGVtLCBmaWVsZCk/LnRyaW0oKSA9PT0gbGFiZWw/LnRyaW0oKSB8fCBlc2NhcGVIdG1sKGdldChpdGVtLCBmaWVsZCk/LnRyaW0oKSB8fCAnICcpID09PSBlc2NhcGVIdG1sKGxhYmVsPy50cmltKCkgfHwgJycpIHx8IGdldChpdGVtLCBmaWVsZCk/LnRyaW0oKSA9PT0gZXNjYXBlSHRtbChsYWJlbD8udHJpbSgpIHx8ICcnKSkpKTtcbiAgICBpZiAoaXRlbUV4aXRzKSB7XG4gICAgICByZXR1cm4geyBpdGVtOiBpdGVtRXhpdHMsIGlzSXRlbVNlbGVjdGVkOiBmYWxzZSB9O1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclNlbGVjdGVkS2V5KGV2ZW50OiBJTGlzdERhdGFFbWl0S2V5IHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFldmVudCB8fCAhZXZlbnQuaXRlbSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWlzTmlsKGV2ZW50Py5rZXkpKSB7XG4gICAgICB0aGlzLnBvcG92ZXJGdW5jdGlvbkNvbnRyb2woKT8ucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXRlbXNTZWxlY3RlZCgpWzBdKSB7XG4gICAgICB0aGlzLnRlbXBJZ25vcmVFbWl0LnNldCh0cnVlKTtcbiAgICAgIHRoaXMuaGFuZGxlclJlbW92ZUl0ZW1TZWxlY3RlZCh7IHN0b3BQcm9wYWdhdGlvbjogKCkgPT4geyByZXR1cm4gfSB9IGFzIEV2ZW50LCB0aGlzLml0ZW1zU2VsZWN0ZWQoKVswXSwgdGhpcy5pdGVtc1NlbGVjdGVkKClbMF0uZGlzYWJsZUl0ZW0pO1xuICAgICAgdGhpcy50ZW1wSWdub3JlRW1pdC5zZXQoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUl0ZW1zU2VsZWN0ZWQoW2V2ZW50Lml0ZW1dLCAhIXRoaXMuaXRlbXNTZWxlY3RlZCgpWzBdKTsgLy8gQnVnICMzNjA3NVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRGbGFnRW1pdFNlbGVjdGVkSXRlbShrZXlzOiBBcnJheTx1bmtub3duPikge1xuICAgIGlmICghdGhpcy5pZ25vcmVFbWl0V2hlblNhbWVEYXRhU2VsZWN0ZWQoKSB8fCBrZXlzLmxlbmd0aCAhPT0gdGhpcy5pdGVtc1NlbGVjdGVkKCkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGlmICghdGhpcy5pdGVtc1NlbGVjdGVkKCkuc29tZShpdGVtID0+IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpID09PSBrZXkpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgaGFuZGxlclNlbGVjdE11bHRpS2V5KGV2ZW50OiBJTGlzdERhdGFFbWl0TXVsdGlLZXkgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGtleXMgPSBbXTtcbiAgICBjb25zdCBpdGVtczogQXJyYXk8dW5rbm93bj4gPSBbXTtcbiAgICBpZiAoZXZlbnQua2V5cyAmJiBldmVudC5rZXlzLmxlbmd0aCAmJiAoIWV2ZW50Lm1hcEtleXMgfHwgIWV2ZW50Lm1hcEtleXMubGVuZ3RoKSkge1xuICAgICAga2V5cy5wdXNoKC4uLmV2ZW50LmtleXMpO1xuICAgIH1cbiAgICBjb25zdCBpZ25vcmVFbWl0S2V5U2VsZWN0ZWRXaGVuSXRlbXNOb3RFeGl0c0VtcHR5ID0gdGhpcy5nZXRGbGFnRW1pdFNlbGVjdGVkSXRlbShjbG9uZURlZXAoZXZlbnQua2V5cyA/PyBbXSkpO1xuICAgIGV2ZW50Lm1hcEtleXMuZm9yRWFjaChtYXBLZXkgPT4ge1xuICAgICAgaWYgKGlzTmlsKG1hcEtleS5rZXkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChtYXBLZXkuaXRlbSkge1xuICAgICAgICByZXR1cm4gaXRlbXMucHVzaChtYXBLZXkuaXRlbSk7XG4gICAgICB9XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5pdGVtc1NlbGVjdGVkKSkge1xuICAgICAgICByZXR1cm4ga2V5cy5wdXNoKG1hcEtleS5rZXkpO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaXRlbXNTZWxlY3RlZC5maW5kKGl0ZW0gPT4gZ2V0KGl0ZW0sIHRoaXMuZmllbGRLZXkoKSkgPT09IG1hcEtleS5rZXkpO1xuICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZW1zLnB1c2goaXRlbSk7XG4gICAgICB9XG4gICAgICByZXR1cm4ga2V5cy5wdXNoKG1hcEtleS5rZXkpO1xuICAgIH0pO1xuICAgIGlmIChrZXlzLmxlbmd0aCkge1xuICAgICAgY29uc3QgcmVzdWx0RGF0YTogQXJyYXk8dW5rbm93bj4gPSBhd2FpdCB0aGlzLmdldERldGFpbEJ5SWRzKGtleXMsIHRydWUpO1xuICAgICAgaXRlbXMucHVzaCguLi5yZXN1bHREYXRhKTtcbiAgICB9XG4gICAgY29uc3QgbWVzc2FnZUVtcHR5ID0gdGhpcy52YWxpZFJlcXVpcmVkKCk/Lm1lc3NhZ2UgfHwgRVJST1JfTUVTU0FHRV9FTVBUWV9WQUxJRDtcbiAgICBsZXQgaWdub3JlVmFsaWRhdGUgPSB0cnVlO1xuICAgIGlmIChtZXNzYWdlRW1wdHkgPT09IHRoaXMuZXJyb3IoKT8ubWVzc2FnZSkge1xuICAgICAgaWdub3JlVmFsaWRhdGUgPSBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgaXRlbVJlbW92ZSA9IHRoaXMuaXRlbXNTZWxlY3RlZCgpLmZpbmQoaXRlbVNlbGVjdGVkID0+IGdldChpdGVtU2VsZWN0ZWQsIHRoaXMuZmllbGRLZXkoKSkgJiYgIShpdGVtcy5zb21lKGl0ZW0gPT4gZ2V0KGl0ZW1TZWxlY3RlZCwgdGhpcy5maWVsZEtleSgpKSA9PT0gZ2V0KGl0ZW0sIHRoaXMuZmllbGRLZXkoKSkpKSk7XG4gICAgdGhpcy5pdGVtc1NlbGVjdGVkLnVwZGF0ZShpdGVtc1NlbGVjdGVkID0+IGl0ZW1zU2VsZWN0ZWQuZmlsdGVyKGl0ZW1TZWxlY3RlZCA9PiAhZ2V0KGl0ZW1TZWxlY3RlZCwgdGhpcy5maWVsZEtleSgpKSB8fCAoZXZlbnQua2V5cy5sZW5ndGggJiYgaXRlbXMuc29tZShpdGVtID0+IGdldChpdGVtU2VsZWN0ZWQsIHRoaXMuZmllbGRLZXkoKSkgPT09IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkpKTtcbiAgICBpZiAoaXRlbVJlbW92ZSkge1xuICAgICAgaWYgKHRoaXMuZW50ZXJBdXRvQWRkVGFnVG9MaXN0KCkgJiYgIWlzTmlsKGdldChpdGVtUmVtb3ZlLCB0aGlzLmZpZWxkS2V5KCkpKSAmJiBgJHtnZXQoaXRlbVJlbW92ZSwgdGhpcy5maWVsZEtleSgpKX1gLnNlYXJjaCh0aGlzLmZha2VJZCgpKSA+PSAwKSB7XG4gICAgICAgIHRoaXMua2V5c0hpZGRlbkl0ZW0udXBkYXRlKGl0ZW1zID0+IFsuLi4oaXRlbXMgfHwgW10pLCBnZXQoaXRlbVJlbW92ZSwgdGhpcy5maWVsZEtleSgpKV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWV2ZW50LmtleXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmNoZWNrVmFsaWQoKTtcbiAgICAgIHRoaXMua2V5c1NlbGVjdGVkLnNldChBcnJheS5mcm9tKG5ldyBTZXQodGhpcy5pdGVtc1NlbGVjdGVkKCk/Lm1hcChpdGVtID0+IGdldChpdGVtLCB0aGlzLmZpZWxkS2V5KCkpKSkpKTtcbiAgICAgIHRoaXMub3V0U2VsZWN0TXVsdGlJdGVtLmVtaXQodGhpcy5nZXRJdGVtU2VsZWN0ZWQoKSk7XG4gICAgICB0aGlzLmNoZWNrVmlld0NoYW5nZShmYWxzZSwgaWdub3JlVmFsaWRhdGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUl0ZW1zU2VsZWN0ZWQoaXRlbXMsIGlnbm9yZVZhbGlkYXRlLCBpZ25vcmVFbWl0S2V5U2VsZWN0ZWRXaGVuSXRlbXNOb3RFeGl0c0VtcHR5KTtcbiAgICB0aGlzLmNoZWNrVmFsaWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0RGV0YWlsQnlJZHMoa2V5czogQXJyYXk8dW5rbm93bj4sIGlzUmVzcG9uc2VEYXRhPzogYm9vbGVhbik6IFByb21pc2U8QXJyYXk8dW5rbm93bj4+IHtcbiAgICBjb25zdCBodHRwUmVxdWVzdERldGFpbEl0ZW1CeUlkcyA9IHRoaXMuaHR0cFJlcXVlc3REZXRhaWxJdGVtQnlJZHMoKTtcbiAgICBpZiAoIWh0dHBSZXF1ZXN0RGV0YWlsSXRlbUJ5SWRzIHx8IHRoaXMubG9hZGluZ0RldGFpbCgpIHx8ICEoa2V5cyBpbnN0YW5jZW9mIEFycmF5KSB8fCAha2V5cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVMb2FkaW5nRGV0YWlsKHRydWUpO1xuICAgIGNvbnN0IGNsb25lSHR0cERldGFpbENvbmZpZyA9IGNsb25lRGVlcChodHRwUmVxdWVzdERldGFpbEl0ZW1CeUlkcyk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgYXJndW1lbnRzVmFsdWUsIGd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlIH0gPSBjbG9uZUh0dHBEZXRhaWxDb25maWc7XG4gICAgICBpZiAoIWd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlIHx8ICFndWlkZUF1dG9VcGRhdGVBcmd1bWVudHNWYWx1ZS5kZXRhaWxCeUlkKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGd1aWRlQXV0b1VwZGF0ZUFyZ3VtZW50c1ZhbHVlLmRldGFpbEJ5SWQuZmllbGRHZXRWYWx1ZSA9ICdrZXlzJztcbiAgICAgIHRoaXMuaHR0cFJlcXVlc3RTZXJ2aWNlLnVwZGF0ZUFyZ3VtZW50cyhhcmd1bWVudHNWYWx1ZSwgeyBrZXlzOiBrZXlzIH0sIHt9LCAnJywgZmFsc2UsIGZhbHNlLCBndWlkZUF1dG9VcGRhdGVBcmd1bWVudHNWYWx1ZSk7XG4gICAgICBjb25zdCByZXN1bHQgPSAoYXdhaXQgdGhpcy5odHRwUmVxdWVzdFNlcnZpY2UuY2FsbEFwaShjbG9uZUh0dHBEZXRhaWxDb25maWcpKSBhcyBJSHR0cFJlc3BvbnNlPEFycmF5PHVua25vd24+PjtcbiAgICAgIGlmICghaXNSZXNwb25zZURhdGEpIHtcbiAgICAgICAgdGhpcy51cGRhdGVJdGVtc1NlbGVjdGVkKHJlc3VsdC5kYXRhIHx8IFtdKTtcbiAgICAgICAgdGhpcy51cGRhdGVMb2FkaW5nRGV0YWlsKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVMb2FkaW5nRGV0YWlsKGZhbHNlKTtcbiAgICAgIHJldHVybiByZXN1bHQuZGF0YSB8fCBbXTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgdGhpcy51cGRhdGVMb2FkaW5nRGV0YWlsKGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjaGVja1ZhbGlkKCkge1xuICAgIGNvbnN0IHZhbGlkID0gdGhpcy5pdGVtc1NlbGVjdGVkKCkgJiYgdGhpcy5pdGVtc1NlbGVjdGVkKCkubGVuZ3RoID8gdHJ1ZSA6IGZhbHNlO1xuICAgIGNvbnN0IHN0YXRlRXJyb3IgPSAhIXRoaXMuZXJyb3IoKTtcbiAgICB0aGlzLmVycm9yLnNldCh1bmRlZmluZWQpO1xuICAgIGlmICh0aGlzLnZhbGlkUmVxdWlyZWQoKSAmJiAhdmFsaWQpIHtcbiAgICAgIHRoaXMuZXJyb3Iuc2V0KHsgLi4udGhpcy52YWxpZFJlcXVpcmVkKCksIG1lc3NhZ2U6IHRoaXMudmFsaWRSZXF1aXJlZCgpPy5tZXNzYWdlIHx8IEVSUk9SX01FU1NBR0VfRU1QVFlfVkFMSUQgfSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5lcnJvcigpKSB7XG4gICAgICB0aGlzLmNoZWNrUGF0dGVybih0aGlzLml0ZW1zU2VsZWN0ZWQoKSk7XG4gICAgICB0aGlzLmNoZWNrTWF4SXRlbVNlbGVjdGVkVmFsaWQoKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnRlbXBJZ25vcmVFbWl0KCkpIHtcbiAgICAgIHRoaXMub3V0VmFsaWRFdmVudC5lbWl0KCF0aGlzLmVycm9yKCkpO1xuICAgIH1cbiAgICBpZiAoc3RhdGVFcnJvciAhPT0gISF0aGlzLmVycm9yKCkpIHtcbiAgICAgIHRoaXMucG9wb3ZlckZ1bmN0aW9uQ29udHJvbCgpPy51cGRhdGVQb3BvdmVyT3ZlcmxheVBvc2l0aW9uKCk7XG4gICAgfVxuICAgIHJldHVybiAhdGhpcy5lcnJvcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja01heEl0ZW1TZWxlY3RlZFZhbGlkKCkge1xuICAgIGNvbnN0IHZhbGlkTWF4SXRlbVNlbGVjdGVkID0gdGhpcy52YWxpZE1heEl0ZW1TZWxlY3RlZCgpO1xuICAgIGlmICh2YWxpZE1heEl0ZW1TZWxlY3RlZCAmJiB0aGlzLml0ZW1zU2VsZWN0ZWQoKS5sZW5ndGggPiB2YWxpZE1heEl0ZW1TZWxlY3RlZC52YWx1ZSkge1xuICAgICAgdGhpcy5lcnJvci5zZXQoeyAuLi52YWxpZE1heEl0ZW1TZWxlY3RlZCwgbWVzc2FnZTogdmFsaWRNYXhJdGVtU2VsZWN0ZWQubWVzc2FnZSB8fCBFUlJPUl9NRVNTQUdFX01BWF9WQUxJRCwgaW50ZXJwb2xhdGVQYXJhbXM6IHsgdmFsdWU6IHZhbGlkTWF4SXRlbVNlbGVjdGVkLnZhbHVlIH0gfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja1BhdHRlcm4oaXRlbXM6IEFycmF5PHVua25vd24+KTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmFsaWRQYXR0ZXJuID0gdGhpcy52YWxpZFBhdHRlcm4oKTtcbiAgICBpZiAoIXZhbGlkUGF0dGVybiB8fCAhdmFsaWRQYXR0ZXJuLmxlbmd0aCB8fCAhaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgdmFsaWQgb2YgdmFsaWRQYXR0ZXJuKSB7XG4gICAgICBpZiAodmFsaWQucGF0dGVybiAmJiBpdGVtcy5zb21lKGl0ZW0gPT4gIXZhbGlkLnBhdHRlcm4udGVzdChnZXQoaXRlbSwgdGhpcy5maWVsZExhYmVsKCkpKSkpIHtcbiAgICAgICAgdGhpcy5lcnJvci5zZXQoeyAuLi52YWxpZCwgbWVzc2FnZTogdmFsaWQubWVzc2FnZSB8fCBFUlJPUl9NRVNTQUdFX1BBVFRFTl9WQUxJRCB9KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2xpY2tCdXR0b25PdGhlcihldmVudDogSUJ1dHRvbikge1xuICAgIHRoaXMub3V0Q2xpY2tCdXR0b25PdGhlci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SXRlbVNlbGVjdGVkKCk6IEFycmF5PHVua25vd24+IHtcbiAgICByZXR1cm4gdGhpcy5pdGVtc1NlbGVjdGVkKCkubWFwKGl0ZW0gPT4ge1xuICAgICAgY29uc3QgaXRlbU1hcCA9IHsgLi4uaXRlbSB9O1xuICAgICAgaWYgKCFpc05pbChnZXQoaXRlbU1hcCwgdGhpcy5maWVsZEtleSgpKSkgJiYgYCR7Z2V0KGl0ZW1NYXAsIHRoaXMuZmllbGRLZXkoKSl9YC5zZWFyY2godGhpcy5mYWtlSWQoKSkgPT09IDApIHtcbiAgICAgICAgc2V0KGl0ZW1NYXAsIHRoaXMuZmllbGRLZXkoKSwgJycpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGl0ZW1NYXA7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgcmVzZXRUb0RlZmF1bHREYXRhU2VsZWN0ZWQoaXRlbVNlbGVjdGVkPzogQXJyYXk8dW5rbm93bj4pIHtcbiAgICBpZiAoaXRlbVNlbGVjdGVkICYmIEFycmF5LmlzQXJyYXkoaXRlbVNlbGVjdGVkKSkge1xuICAgICAgdGhpcy5pdGVtc1NlbGVjdGVkLnNldChbXSk7XG4gICAgICB0aGlzLnVwZGF0ZUl0ZW1zU2VsZWN0ZWQoaXRlbVNlbGVjdGVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaXRlbVNlbGVjdGVkID0gbmV3IEFycmF5PHVua25vd24+KCk7XG4gICAgaWYgKCF0aGlzLmZpZWxkS2V5KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZGVmYXVsdEtleXNTZWxlY3RlZCA9IHRoaXMuZGVmYXVsdEtleXNTZWxlY3RlZCgpO1xuICAgIGlmIChkZWZhdWx0S2V5c1NlbGVjdGVkICYmIEFycmF5LmlzQXJyYXkoZGVmYXVsdEtleXNTZWxlY3RlZCkpIHtcbiAgICAgIHRoaXMuaXRlbXNTZWxlY3RlZC5zZXQoW10pO1xuICAgICAgdGhpcy5nZXREZXRhaWxCeUlkcyhkZWZhdWx0S2V5c1NlbGVjdGVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZGVmYXVsdEl0ZW1zU2VsZWN0ZWQgPSB0aGlzLmRlZmF1bHRJdGVtc1NlbGVjdGVkKCk7XG4gICAgaWYgKGRlZmF1bHRJdGVtc1NlbGVjdGVkICYmIEFycmF5LmlzQXJyYXkoZGVmYXVsdEl0ZW1zU2VsZWN0ZWQpKSB7XG4gICAgICB0aGlzLml0ZW1zU2VsZWN0ZWQuc2V0KFtdKTtcbiAgICAgIHRoaXMudXBkYXRlSXRlbXNTZWxlY3RlZChkZWZhdWx0SXRlbXNTZWxlY3RlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJGdW5jdGlvbkNvbnRyb2xMaXN0KGV2ZW50OiBJTGlzdEZ1bmN0aW9uQ29udHJvbEV2ZW50KSB7XG4gICAgdGhpcy5saXN0RnVuY3Rpb25Db250cm9sLnNldChldmVudCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZm9jdXNJbnB1dCgpIHtcbiAgICB0aGlzLmlucHV0RnVuY3Rpb25Db250cm9sKCk/LmZvY3VzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckNoYW5nZUZsYWdNb3VzZShldmVudDogSUZsYWdNb3VzZSkge1xuICAgIHRoaXMub3V0Q2hhbmdTdGFnZUZsYWdNb3VzZS5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2hhbmdTdGFnZUZsYWdNb3VzZShmbGFnOiBJRmxhZ01vdXNlKSB7XG4gICAgdGhpcy5mbGFnTW91c2Uuc2V0KGZsYWcpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZXNldEVycm9yKCkge1xuICAgIHRoaXMuZXJyb3Iuc2V0KHVuZGVmaW5lZCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUxvYWRpbmdEZXRhaWwoZXZlbnQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmxvYWRpbmdEZXRhaWwuc2V0KGV2ZW50KTtcbiAgICB0aGlzLm91dExvYWRpbmdHZXREZXRhaWxTZWxlY3RlZC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlSXRlbVNlbGVjdGVkRGlzYWJsZSgpIHtcbiAgICBjb25zdCBnZXREaXNhYmxlSXRlbSA9IHRoaXMuY29uZmlnKCk/LmdldERpc2FibGVJdGVtO1xuICAgIGlmICghZ2V0RGlzYWJsZUl0ZW0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pdGVtc1NlbGVjdGVkLnVwZGF0ZShpdGVtc1NlbGVjdGVkID0+IGl0ZW1zU2VsZWN0ZWQubWFwKGl0ZW0gPT4gKHsgLi4uaXRlbSwgZGlzYWJsZUl0ZW06IGdldERpc2FibGVJdGVtKGl0ZW0pIH0pKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZnJlc2hMaXN0RGF0YSgpIHtcbiAgICB0aGlzLmxpc3RGdW5jdGlvbkNvbnRyb2woKT8ucmVmcmVzaCgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kubmV4dCgpO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVPdXRGbGFnKCkpO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVPdXRDaGFuZ2VTZWFyY2goKSk7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZU91dENoZWNrVmlld0NoYW5nZSgpKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0Q2xpY2tPdXRzaWRlKCkpO1xuICB9XG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHctZnVsbCBoLWZ1bGxcIj5cbiAgQGlmIChsYWJlbENvbmZpZygpOyBhcyBsYWJlbENvbmZpZykge1xuICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtbGFiZWwgW2NsYXNzSW5jbHVkZV09XCJsYWJlbENvbmZpZy5jbGFzc0luY2x1ZGVcIlxuICAgICAgW2xhYmVsTGVmdF09XCJsYWJlbENvbmZpZy5sYWJlbExlZnRcIlxuICAgICAgW2xhYmVsTGVmdENsYXNzXT1cImxhYmVsQ29uZmlnLmxhYmVsTGVmdENsYXNzXCJcbiAgICAgIFtyZXF1aXJlZF09XCJsYWJlbENvbmZpZy5yZXF1aXJlZFwiXG4gICAgICBbZGVzY3JpcHRpb25dPVwibGFiZWxDb25maWcuZGVzY3JpcHRpb25cIlxuICAgICAgW2Rlc2NyaXB0aW9uQ2xhc3NdPVwibGFiZWxDb25maWcuZGVzY3JpcHRpb25DbGFzc1wiXG4gICAgICBbbGFiZWxSaWdodF09XCJsYWJlbENvbmZpZy5sYWJlbFJpZ2h0XCJcbiAgICAgIFtsYWJlbFJpZ2h0Q2xhc3NdPVwibGFiZWxDb25maWcubGFiZWxSaWdodENsYXNzXCJcbiAgICAgIFtvbmx5U2hvd0NvdW50XT1cImxhYmVsQ29uZmlnLm9ubHlTaG93Q291bnRcIlxuICAgICAgW2J1dHRvbnNMZWZ0XT1cImxhYmVsQ29uZmlnLmJ1dHRvbnNMZWZ0XCJcbiAgICAgIFtidXR0b25zUmlnaHRdPVwibGFiZWxDb25maWcuYnV0dG9uc1JpZ2h0XCJcbiAgICAgIFtkaXNhYmxlQnV0dG9uc0xlZnRdPVwibGFiZWxDb25maWcuZGlzYWJsZUJ1dHRvbnNMZWZ0IHx8IGRpc2FibGUoKSB8fCBsb2FkaW5nKCkgfHwgbG9hZGluZ0RldGFpbCgpXCJcbiAgICAgIFtkaXNhYmxlQnV0dG9uc1JpZ2h0XT1cImxhYmVsQ29uZmlnLmRpc2FibGVCdXR0b25zUmlnaHQgfHwgZGlzYWJsZSgpIHx8IGxvYWRpbmcoKSB8fCBsb2FkaW5nRGV0YWlsKClcIlxuICAgICAgW2hhc1RvZ2dsZV09XCJsYWJlbENvbmZpZy5oYXNUb2dnbGVcIlxuICAgICAgW3RvZ2dsZUFjdGl2ZV09XCJsYWJlbENvbmZpZy50b2dnbGVBY3RpdmVcIlxuICAgICAgW3RvZ2dsZUFjdGl2ZV09XCJsYWJlbENvbmZpZy50b2dnbGVEaXNhYmxlIHx8IGRpc2FibGUoKSB8fCBsb2FkaW5nKCkgfHwgbG9hZGluZ0RldGFpbCgpXCJcbiAgICAgIFtwb3BvdmVyXT1cImxhYmVsQ29uZmlnLnBvcG92ZXJcIlxuICAgICAgW2ljb25Qb3BvdmVyQ2xhc3NdPVwibGFiZWxDb25maWcuaWNvblBvcG92ZXJDbGFzc1wiXG4gICAgICBbb25seVNob3dDb3VudF09XCJsYWJlbENvbmZpZy5vbmx5U2hvd0NvdW50XCJcbiAgICAgIFtsaW1pdExlbmd0aF09XCJsYWJlbENvbmZpZy5saW1pdExlbmd0aFwiXG4gICAgICBbYnV0dG9uc0Rlc2NyaXB0aW9uXT1cImxhYmVsQ29uZmlnLmJ1dHRvbnNEZXNjcmlwdGlvblwiXG4gICAgICBbZGlzYWJsZUJ1dHRvbnNEZXNjcmlwdGlvbl09XCJsYWJlbENvbmZpZy5kaXNhYmxlQnV0dG9uc0Rlc2NyaXB0aW9uIHx8IGRpc2FibGUoKVwiXG4gICAgICBbYnV0dG9uc0Rlc2NyaXB0aW9uQ29udGFpbmVyQ2xhc3NdPVwibGFiZWxDb25maWcuYnV0dG9uc0Rlc2NyaXB0aW9uQ29udGFpbmVyQ2xhc3NcIlxuICAgICAgW2NvdW50XT1cImxhYmVsQ29uZmlnLmNvdW50XCIgLz5cbiAgfVxuICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXIgY2xhc3M9XCJ3LWZ1bGwgaC1mdWxsXCJcbiAgICBbaWdub3JlU2hvd1BvcG92ZXJdPVwiZGlzYWJsZSgpIHx8IHJlYWRvbmx5KCkgfHwgISFjb25maWcoKT8uaWdub3JlU2hvd0xpc3QgfHwgZmFsc2VcIlxuICAgIFtpZ25vcmVDdXJzb3JQb2ludGVyTW9kZUxpa2VDbGlja109XCJ0cnVlXCJcbiAgICBbZWxlbWVudFJlZkN1c3RvbV09XCJ0YWdzRWxcIlxuICAgIFttb2RlXT1cIiFjb25maWcoKT8uaWdub3JlSW5wdXQgPyAnY2xpY2snIDogJ2NsaWNrLXRvZ2dsZSdcIlxuICAgIFtpZ25vcmVIaWRkZW5Qb3BvdmVyQ29udGVudFdoZW5Nb3VzZUxlYXZlXT1cInRydWVcIlxuICAgIFtmbGFnTW91c2VdPVwiZmxhZ01vdXNlKClcIlxuICAgIFtjb25maWddPVwie1xuICAgICAgYW5pbWF0aW9uQ29uZmlnOiBjb25maWcoKT8uYW5pbWF0aW9uQ29uZmlnIHx8IHt9LFxuICAgICAgekluZGV4OiB6SW5kZXgoKSB8fCAxMDAwLFxuICAgICAgd2lkdGhCeVBhcmVudDogdHJ1ZSxcbiAgICAgIHBhcmVudEJvcmRlcldpZHRoOiBwYXJlbnRCb3JkZXJXaWR0aCgpID8/IDAsXG4gICAgICBtYXhIZWlnaHQ6IDIwNDgsXG4gICAgICBtYXhXaWR0aDogMjA0OCxcbiAgICAgIGRpcmVjdGlvbjogY29uZmlnKCk/LmRpcmVjdGlvbkxpc3QgfHwgJ2JvdHRvbScsXG4gICAgICBkaXJlY3Rpb25EaXN0YW5jZTogMixcbiAgICAgIHRlbXBsYXRlOiAhc2hvd0xpc3RCZWxsb3coKSA/IGxpc3RWaWV3RWwgOiB1bmRlZmluZWQsXG4gICAgICB3aGl0ZVRoZW1lOiB0cnVlLFxuICAgICAgaWdub3JlQXJyb3c6IHRydWUsXG4gICAgICBjbGFzc0luY2x1ZGU6ICdyb3VuZGVkLVs0cHhdICcgKyBjbGFzc0luY2x1ZGVQb3BvdmVyKCkgKyAoKCFsaXN0Q29uZmlnKCk/Lmlnbm9yZVNob3dEYXRhV2hlbk5vdFNlYXJjaCB8fCBrZXlTZWFyY2goKSkgPyAnIGxpYnMtdWktYm9yZGVyLWdlbmVyYWwnIDogJycpLFxuICAgICAgcG9zaXRpb246IHsgbW9kZTogJ3N0YXJ0JywgZGlzdGFuY2U6IDAgfVxuICAgIH1cIlxuICAgIChvdXRGdW5jdGlvbnNDb250cm9sKT1cImhhbmRsZXJQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQoJGV2ZW50KVwiXG4gICAgKG91dEV2ZW50KT1cImhhbmRsZXJQb3BvdmVyRXZlbnQoJGV2ZW50KVwiXG4gICAgKG91dEV2ZW50UG9wb3ZlckNvbnRlbnQpPVwiaGFuZGxlclBvcG92ZXJDb250ZW50RXZlbnQoJGV2ZW50KVwiXG4gICAgKG91dENoYW5nU3RhZ2VGbGFnTW91c2UpPVwiaGFuZGxlckNoYW5nZUZsYWdNb3VzZSgkZXZlbnQpXCI+XG4gICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlXCJcbiAgICAgIFtjbGFzcy5jdXJzb3ItcG9pbnRlcl09XCIhZGlzYWJsZSgpICYmICFyZWFkb25seSgpXCI+XG4gICAgICBAaWYgKGNvbmZpZygpPy51aUxpa2VEcm9wZG93bikge1xuICAgICAgICA8aSBjbGFzcz1cImZsZXggdGV4dC1bMTZweF0gYWJzb2x1dGUgcmlnaHQtWzE2cHhdIHRvcC1bOHB4XSBsaWJzLXVpLWljb24tbW92ZS1yaWdodCByb3RhdGUtOTAgei1bMV1cIlxuICAgICAgICAgIFtjbGFzcy50ZXh0LVsjNmE3MzgzXV09XCIhcmVhZG9ubHkoKSAmJiAhcmVhZG9ubHkoKVwiXG4gICAgICAgICAgW2NsYXNzLmxpYnMtdWktcmVhZG9ubHldPVwicmVhZG9ubHkoKVwiXG4gICAgICAgICAgW2NsYXNzLmxpYnMtdWktZGlzYWJsZV09XCJkaXNhYmxlKClcIj5cbiAgICAgICAgPC9pPlxuICAgICAgfVxuICAgICAgPGRpdiAjdGFnc0VsXG4gICAgICAgIFtjbGFzc109XCInbGlicy11aS10YWdzICcgKyAoY29uZmlnKCk/LmNsYXNzSW5jbHVkZSB8fCAnJykgKyAocmVhZG9ubHkoKSA/IChjb25maWcoKT8uY2xhc3NDdXN0b21XaGVuUmVhZE9ubHkgfHwgJyBsaWJzLXVpLXJlYWRvbmx5JykgOiAnJylcIlxuICAgICAgICBbY2xhc3MubGlicy11aS10YWdzLW5vdC1wb3B1cF09XCIoIXNob3dMaXN0KCkgJiYgIXNob3dCb3JkZXJBY3RpdmVXaGVuRm9jdXNJbnB1dCgpKSB8fCAoIWZvY3VzKCkgJiYgc2hvd0JvcmRlckFjdGl2ZVdoZW5Gb2N1c0lucHV0KCkpXCJcbiAgICAgICAgW2NsYXNzLmxpYnMtdWktdGFncy1lcnJvcl09XCIhIWVycm9yKCkgJiYgIWNvbmZpZygpPy5pZ25vcmVTaG93RXJyb3JcIlxuICAgICAgICBbY2xhc3MuIXByLVszMnB4XV09XCJjb25maWcoKT8udWlMaWtlRHJvcGRvd25cIlxuICAgICAgICBbY2xhc3MuYmctWyNmOGY5ZmFdXT1cImRpc2FibGUoKSB8fCByZWFkb25seSgpXCJcbiAgICAgICAgW2NsYXNzLmxpYnMtdWktYm9yZGVyLXByaW1hcnktZ2VuZXJhbF09XCJmb2N1cygpICYmIHNob3dCb3JkZXJBY3RpdmVXaGVuRm9jdXNJbnB1dCgpXCJcbiAgICAgICAgTGlic1VpQ29tcG9uZW50c0NsaWNrT3V0c2lkZURpcmVjdGl2ZVxuICAgICAgICAob3V0T3V0c2lkZSk9XCJoYW5kbGVyQ2xpY2tPdXRzaWRlKCRldmVudClcIj5cbiAgICAgICAgQGZvciAoaXRlbSBvZiBpdGVtc1NlbGVjdGVkKCk7IHRyYWNrIGl0ZW1bZmllbGRLZXkoKV0pIHtcbiAgICAgICAgICA8ZGl2IFtuZ1N0eWxlXT1cIml0ZW0/LmJ1bGxldCB8fCBpdGVtPy5uZ1N0eWxlc1wiXG4gICAgICAgICAgICBbY2xhc3NdPVwiY2xhc3NJbmNsdWRlVGFnSXRlbSgpIHx8ICcnXCJcbiAgICAgICAgICAgIFtjbGFzcy5saWJzLXVpLXRhZ3MtcmVhZG9ubHldPVwiaXRlbS5kaXNhYmxlSXRlbVwiXG4gICAgICAgICAgICBbY2xhc3MubGlicy11aS10YWdzLWl0ZW1dPVwiIWl0ZW0uZGlzYWJsZUl0ZW1cIlxuICAgICAgICAgICAgW2NsYXNzLmN1cnNvci1kZWZhdWx0XT1cImRpc2FibGUoKSB8fCByZWFkb25seSgpXCI+XG4gICAgICAgICAgICBAaWYgKGZpZWxkR2V0SW1hZ2UoKTsgYXMgZmllbGRHZXRJbWFnZSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgaC1mdWxsXCI+XG4gICAgICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1hdmF0YXIgW2NsYXNzSW5jbHVkZV09XCJjbGFzc0F2YXRhckluY2x1ZGUoKSB8fCAnbXItWzhweF0nXCJcbiAgICAgICAgICAgICAgICAgIFtzaXplXT1cImltYWdlU2l6ZSgpXCJcbiAgICAgICAgICAgICAgICAgIFtsaW5rQXZhdGFyXT1cIml0ZW1bZmllbGRHZXRJbWFnZV1cIlxuICAgICAgICAgICAgICAgICAgW2xpbmtBdmF0YXJFcnJvcl09XCJjb25maWcoKT8ubGlua0ltYWdlRXJyb3JcIlxuICAgICAgICAgICAgICAgICAgW2lkR2VuQ29sb3JdPVwiaXRlbVtmaWVsZEdldFRleHRBdmF0YXIoKV1cIlxuICAgICAgICAgICAgICAgICAgW3RleHRBdmF0YXJdPVwiaXRlbVtmaWVsZEdldFRleHRBdmF0YXIoKV1cIlxuICAgICAgICAgICAgICAgICAgW2dldExhc3RUZXh0QWZ0ZXJTcGFjZV09XCJnZXRMYXN0VGV4dEFmdGVyU3BhY2UoKVwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsaWJzLXVpLWZvbnQtaDZyXCJcbiAgICAgICAgICAgICAgW2lubmVySHRtbF09XCIoaXRlbS5maWVsZExhYmVsIHx8ICcgJykgfCB0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIEBpZiAoIWRpc2FibGUoKSAmJiAhaXRlbS5kaXNhYmxlSXRlbSAmJiAhcmVhZG9ubHkoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgbWwtWzhweF1cIj5cbiAgICAgICAgICAgICAgICA8aSAjaWNvbkNsb3NlRWxcbiAgICAgICAgICAgICAgICAgIFthdHRyLnNwZWNpZmljU3R5bGVdPVwiISEoaXRlbT8uYnVsbGV0IHx8IGl0ZW0/Lm5nU3R5bGVzKVwiXG4gICAgICAgICAgICAgICAgICBbY2xhc3NdPVwiJ2ZsZXggdGV4dC1bMTZweF0gJyArIChjbGFzc0ljb25SZW1vdmVUYWdJdGVtKCkgfHwgJ2xpYnMtdWktaWNvbi1jbG9zZScpXCJcbiAgICAgICAgICAgICAgICAgIFtjbGFzcy5jdXJzb3ItcG9pbnRlcl09XCIhZGlzYWJsZSgpICYmICFsb2FkaW5nKCkgJiYgIWxvYWRpbmdEZXRhaWwoKVwiXG4gICAgICAgICAgICAgICAgICBbY2xhc3MucG9pbnRlci1ldmVudHMtbm9uZV09XCJkaXNhYmxlKCkgfHwgbG9hZGluZygpIHx8IGxvYWRpbmdEZXRhaWwoKVwiXG4gICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCIoaXRlbT8uYnVsbGV0IHx8IGl0ZW0/Lm5nU3R5bGVzKSB8IExpYnNVaUNvbXBvbmVudHNUYWdzR2V0Q29sb3JQaXBlOmljb25DbG9zZUVsXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJoYW5kbGVyUmVtb3ZlSXRlbVNlbGVjdGVkKCRldmVudCxpdGVtKVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgQGlmICghc2luZ2xlU2VsZWN0ZWQoKSB8fCAoc2luZ2xlU2VsZWN0ZWQoKSAmJiAhaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkpIHtcbiAgICAgICAgICBAaWYgKCFjb25maWcoKT8uaWdub3JlSW5wdXQgJiYgIWNvbmZpZygpPy51aUxpa2VEcm9wZG93biAmJiAoIWhpZGRlbklucHV0V2hlblJlYWRvbmx5KCkgfHwgKGhpZGRlbklucHV0V2hlblJlYWRvbmx5KCkgJiYgIXJlYWRvbmx5KCkpKSkge1xuICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1pbnB1dHMtaW5wdXQgY2xhc3M9XCJncm93XCJcbiAgICAgICAgICAgICAgW2NsYXNzLm1iLVs0cHhdXT1cIml0ZW1zU2VsZWN0ZWQoKS5sZW5ndGhcIlxuICAgICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cIid3LWZ1bGwgYmctdHJhbnNwYXJlbnQnICsgKGNvbmZpZygpPy5jbGFzc0lucHV0SW5jbHVkZSB8fCAncHgtWzRweF0gbWluLXctWzMwcHhdJylcIlxuICAgICAgICAgICAgICBbZGVmYXVsdEhlaWdodF09XCIyNFwiXG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJyZWFkb25seSgpID8gJycgOiAocGxhY2Vob2xkZXIoKSB8fCAnaTE4bl9pbXBvcnRfY29udGVudCcpXCJcbiAgICAgICAgICAgICAgW25vQm9yZGVyXT1cInRydWVcIlxuICAgICAgICAgICAgICBbKHZhbHVlKV09XCJ2YWx1ZUlucHV0XCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVdPVwiZGlzYWJsZSgpIHx8IGxvYWRpbmcoKSB8fCBsb2FkaW5nRGV0YWlsKCkgfHwgZGlzYWJsZVdoZW5NYXhJdGVtKClcIlxuICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHkoKVwiXG4gICAgICAgICAgICAgIChvdXRFbnRlckV2ZW50KT1cImhhbmRsZXJFbnRlckV2ZW50KClcIlxuICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwiaGFuZGxlclZhbHVlQ2hhbmdlU2VhcmNoKCRldmVudClcIlxuICAgICAgICAgICAgICAob3V0Rm9jdXNBbmRCbHVyRXZlbnQpPVwiaGFuZGxlckZvY3VzQW5kQmx1ckV2ZW50KCRldmVudClcIlxuICAgICAgICAgICAgICAob3V0RnVuY3Rpb25zQ29udHJvbCk9XCJoYW5kbGVySW5wdXRGdW5jdGlvbkNvbnRyb2woJGV2ZW50KVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBpZiAoY29uZmlnKCk/Lmlnbm9yZUlucHV0ICYmIGNvbmZpZygpPy51aUxpa2VEcm9wZG93biAmJiAhaXRlbXNTZWxlY3RlZCgpLmxlbmd0aCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHBiLVs0cHhdIHB0LVsycHhdIG1sLVsxMXB4XSBsaWJzLXVpLWZvbnQtaDVyXCJcbiAgICAgICAgICAgICAgW2NsYXNzLnRleHQtWyM5Y2EyYWRdXT1cImRpc2FibGUoKVwiPlxuICAgICAgICAgICAgICB7eyAocGxhY2Vob2xkZXIoKSB8fCAnaTE4bl9zZWxlY3RfdmFsdWUnKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICAgIEBpZiAoZXJyb3IoKSAmJiAhY29uZmlnKCk/Lmlnbm9yZVNob3dFcnJvcikge1xuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1bI2VlMmQ0MV0gbGlicy11aS1mb250LWg3ciBtdC1bOHB4XVwiPnt7IChlcnJvcigpPy5tZXNzYWdlIHx8ICcgJykgfCB0cmFuc2xhdGU6KGVycm9yKCk/LmludGVycG9sYXRlUGFyYW1zIHx8IHt9KSB9fTwvZGl2PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICA8L2xpYnNfdWktY29tcG9uZW50cy1wb3BvdmVyPlxuPC9kaXY+XG5AaWYgKHNob3dMaXN0QmVsbG93KCkpIHtcbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxpc3RWaWV3RWxcIj48L25nLWNvbnRhaW5lcj5cbn1cbjxuZy10ZW1wbGF0ZSAjbGlzdFZpZXdFbD5cbiAgQGlmIChsaXN0Q29uZmlnKCk7IGFzIGxpc3RDb25maWcpIHtcbiAgICA8bGlic191aS1jb21wb25lbnRzLWxpc3QgW3NlYXJjaENvbmZpZ109XCJsaXN0U2VhcmNoQ29uZmlnKCkgfHwge2NsYXNzSW5jbHVkZTogJ2hpZGRlbicsIGljb25MZWZ0Q2xhc3M6ICdoaWRkZW4nfVwiXG4gICAgICBbaXNTZWFyY2hPbmxpbmVdPVwiaXNTZWFyY2hPbmxpbmUoKVwiXG4gICAgICBbekluZGV4XT1cInpJbmRleCgpXCJcbiAgICAgIFtrZXlTZWFyY2hdPVwia2V5U2VhcmNoKClcIlxuICAgICAgW2NvbmZpZ109XCJsaXN0Q29uZmlnXCJcbiAgICAgIFtkaXNhYmxlXT1cImRpc2FibGUoKSB8fCBsb2FkaW5nRGV0YWlsKCkgfHwgZGlzYWJsZVdoZW5NYXhJdGVtKClcIlxuICAgICAgW3NlYXJjaFBhZGRpbmddPVwibGlzdFNlYXJjaFBhZGRpbmcoKVwiXG4gICAgICBbbWF4SXRlbVNob3ddPVwibGlzdE1heEl0ZW1TaG93KCkgfHwgNlwiXG4gICAgICBbbXVsdGlLZXlTZWxlY3RlZF09XCJrZXlzU2VsZWN0ZWQoKVwiXG4gICAgICBbY2xpY2tFeGFjdGx5XT1cImZhbHNlXCJcbiAgICAgIFtrZXlzSGlkZGVuSXRlbV09XCJrZXlzSGlkZGVuSXRlbSgpXCJcbiAgICAgIFtrZXlzRGlzYWJsZUl0ZW1dPVwia2V5c0Rpc2FibGVJdGVtKClcIlxuICAgICAgW2RpdmlkZXJDbGFzc0luY2x1ZGVdPVwibGlzdERpdmlkZXJDbGFzc0luY2x1ZGUoKSA/PyAnaGlkZGVuJ1wiXG4gICAgICBbYnV0dG9uc090aGVyXT1cImxpc3RCdXR0b25zT3RoZXIoKVwiXG4gICAgICBbYmFja2dyb3VuZExpc3RDdXN0b21dPVwibGlzdEJhY2tncm91bmRMaXN0Q3VzdG9tKClcIlxuICAgICAgW2l0ZW1DaGFuZ2VVblNlbGVjdF09XCJpdGVtQ2hhbmdlVW5TZWxlY3QoKVwiXG4gICAgICBbZnVuY3Rpb25HZXRJdGVtc0F1dG9BZGRMaXN0XT1cImZ1bmN0aW9uR2V0SXRlbUF1dG9BZGRMaXN0KClcIlxuICAgICAgW2hpZGRlbklucHV0U2VhcmNoXT1cImxpc3RIaWRkZW5JbnB1dFNlYXJjaFdoZW5IYXNTZWFyY2hDb25maWcoKVwiXG4gICAgICAob3V0RnVuY3Rpb25zQ29udHJvbCk9XCJoYW5kbGVyRnVuY3Rpb25Db250cm9sTGlzdCgkZXZlbnQpXCJcbiAgICAgIChvdXRTZWxlY3RLZXkpPVwiaGFuZGxlclNlbGVjdGVkS2V5KCRldmVudClcIlxuICAgICAgKG91dFNlbGVjdE11bHRpS2V5KT1cImhhbmRsZXJTZWxlY3RNdWx0aUtleSgkZXZlbnQpXCJcbiAgICAgIChvdXRDaGFuZ2VWaWV3KT1cImhhbmRsZXJEYXRhQ2hhbmdlKCRldmVudClcIlxuICAgICAgKG91dENsaWNrQnV0dG9uT3RoZXIpPVwiaGFuZGxlckNsaWNrQnV0dG9uT3RoZXIoJGV2ZW50KVwiXG4gICAgICAob3V0Q2hhbmdTdGFnZUZsYWdNb3VzZVBvcG92ZXIpPVwiaGFuZGxlckNoYW5nU3RhZ2VGbGFnTW91c2UoJGV2ZW50KVwiXG4gICAgICAob3V0TG9hZGluZyk9XCJoYW5kbGVyTG9hZGluZygkZXZlbnQpXCIgLz5cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==