@libs-ui/components-inputs-mention 0.1.1-1

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,507 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';
3
+ import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
4
+ import { get, isNil, uuid } from '@libs-ui/utils';
5
+ import { Subject, fromEvent } from 'rxjs';
6
+ import { takeUntil, tap } from 'rxjs/operators';
7
+ import { UtilsKeyCodeConstant } from '@libs-ui/utils';
8
+ import { DEFAULT_CONFIG, buildTemplate } from './defines/template.define';
9
+ import { getCaretPosition, getTextBeforeCursor, getValue, getWindowSelection, insertTextAtCaret, insertValue, setCaretPosition } from './defines/utils.define';
10
+ import { LibsUiComponentsInputsMentionListComponent } from './list/list.component';
11
+ import * as i0 from "@angular/core";
12
+ export class LibsUiComponentsInputsMentionDirective {
13
+ // #region PROPERTY
14
+ listComponentRef = signal(undefined);
15
+ nodesInsert = signal(new Set());
16
+ activeConfig = signal(undefined);
17
+ triggerChars = signal({});
18
+ searchString = signal('');
19
+ startPos = signal(undefined);
20
+ startNode = signal(undefined);
21
+ searchList = signal(undefined);
22
+ searching = signal(false);
23
+ iframe = signal(undefined);
24
+ lastKeyCode = signal(undefined);
25
+ isEditor = signal(false);
26
+ iframeId = signal(undefined);
27
+ element = inject(ElementRef);
28
+ dynamicComponentService = inject(LibsUiDynamicComponentService);
29
+ onDestroy = new Subject();
30
+ // #region INPUT
31
+ timeDelayInit = input(0, { transform: (val) => val ?? 0 });
32
+ mentionConfig = input();
33
+ mentionListTemplate = input();
34
+ // #region OUTPUT
35
+ outSearchTerm = output();
36
+ outItemSelected = output();
37
+ outToggle = output();
38
+ outInsertMention = output();
39
+ outFunctionControl = output();
40
+ constructor() {
41
+ effect(() => {
42
+ this.mentionConfig();
43
+ untracked(() => this.updateConfig());
44
+ });
45
+ }
46
+ ngAfterViewInit() {
47
+ setTimeout(() => {
48
+ if (!this.mentionConfig()) {
49
+ return;
50
+ }
51
+ const isContentEditable = this.element.nativeElement.getAttribute('contenteditable');
52
+ this.isEditor.set(!isContentEditable);
53
+ const element = !this.isEditor() ? this.element.nativeElement : this.element.nativeElement.querySelector('.ql-editor[contenteditable="true"]');
54
+ if (element) {
55
+ element.addEventListener('keydown', (event) => {
56
+ this.handlerKeydown.bind(this)(event, element);
57
+ });
58
+ element.addEventListener('input', (event) => {
59
+ this.handlerInput.bind(this)(event, element);
60
+ });
61
+ element.addEventListener('blur', (event) => {
62
+ this.handlerBlur.bind(this)(event);
63
+ });
64
+ element.addEventListener('click', (event) => {
65
+ this.handlerFocus.bind(this)(event, element);
66
+ });
67
+ }
68
+ this.outFunctionControl.emit({
69
+ addMention: () => {
70
+ insertTextAtCaret(element, `${this.mentionConfig()?.triggerChar}`);
71
+ setTimeout(() => {
72
+ this.handlerKeydown({ key: this.mentionConfig()?.triggerChar, keyCode: UtilsKeyCodeConstant.BACKSPACE, shiftKey: true, inputEvent: true }, element);
73
+ }, 500);
74
+ },
75
+ });
76
+ }, this.timeDelayInit());
77
+ }
78
+ /* FUNCTIONS */
79
+ updateConfig() {
80
+ const mentionConfig = this.mentionConfig();
81
+ if (!mentionConfig) {
82
+ return;
83
+ }
84
+ this.triggerChars.set({});
85
+ this.addConfig(mentionConfig);
86
+ if (mentionConfig.mention) {
87
+ mentionConfig.mention.forEach((config) => this.addConfig(config));
88
+ }
89
+ }
90
+ addConfig(config) {
91
+ const defaults = Object.assign({}, DEFAULT_CONFIG);
92
+ const labelKey = config.labelKey || 'label';
93
+ config = Object.assign(defaults, config);
94
+ if (config.items && config.items.length > 0) {
95
+ if (typeof config.items[0] === 'string') {
96
+ config.items.forEach((label) => {
97
+ const object = {};
98
+ object[labelKey] = label;
99
+ return object;
100
+ });
101
+ }
102
+ if (labelKey) {
103
+ // remove items without an labelKey (as it's required to filter the list)
104
+ config.items = config.items.filter((e) => e[labelKey]);
105
+ if (!config.disableSort) {
106
+ config.items.sort((a, b) => (a[labelKey] || '').localeCompare(b[labelKey] || ''));
107
+ }
108
+ }
109
+ }
110
+ this.triggerChars.update((item) => ({
111
+ ...item,
112
+ [config.triggerChar || '@']: config,
113
+ }));
114
+ if (this.activeConfig() && this.activeConfig()?.triggerChar === config.triggerChar) {
115
+ this.activeConfig.set(config);
116
+ this.updateSearchList();
117
+ }
118
+ }
119
+ setIframe(iframe) {
120
+ this.iframe.set(iframe);
121
+ }
122
+ stopEvent(event) {
123
+ if (get(event, 'wasClick')) {
124
+ return;
125
+ }
126
+ event.preventDefault();
127
+ event.stopPropagation();
128
+ event.stopImmediatePropagation();
129
+ }
130
+ handlerBlur(event) {
131
+ setTimeout(() => {
132
+ this.stopEvent(event);
133
+ this.stopSearch();
134
+ }, 100);
135
+ }
136
+ handlerInput(event, nativeElement = this.element.nativeElement) {
137
+ const data = get(event, 'data');
138
+ if (this.lastKeyCode() === UtilsKeyCodeConstant.BUFFERED && data) {
139
+ const keyCode = data.charCodeAt(0);
140
+ this.handlerKeydown({ keyCode, inputEvent: true }, nativeElement);
141
+ }
142
+ }
143
+ handlerKeydown(event, nativeElement = this.element.nativeElement) {
144
+ this.lastKeyCode.set(event.keyCode);
145
+ if (event.isComposing || event.keyCode === UtilsKeyCodeConstant.BUFFERED) {
146
+ return;
147
+ }
148
+ const val = getValue(nativeElement);
149
+ let pos = getCaretPosition(nativeElement, this.iframe());
150
+ let charPressed = event.key;
151
+ if (!this.isEditor()) {
152
+ if (event.keyCode === UtilsKeyCodeConstant.BACKSPACE) {
153
+ this.appendEmptyToLastNode(pos, val.length, nativeElement);
154
+ }
155
+ setTimeout(() => this.addNodeZeroWidthSpace(nativeElement), 0);
156
+ }
157
+ if (!charPressed) {
158
+ const charCode = event.which || event.keyCode;
159
+ charPressed = String.fromCharCode(event.which || event.keyCode);
160
+ if (!event.shiftKey && charCode >= 65 && charCode <= 90) {
161
+ charPressed = String.fromCharCode(charCode + 32);
162
+ }
163
+ }
164
+ if (event.keyCode === UtilsKeyCodeConstant.ENTER && event.wasClick && pos < (this.startPos() || 0)) {
165
+ pos = this.startNode().length;
166
+ setCaretPosition(this.startNode(), pos, this.iframe());
167
+ }
168
+ const config = this.triggerChars()[charPressed];
169
+ if (config) {
170
+ this.activeConfig.set(config);
171
+ this.startPos.set(event.inputEvent ? pos - 1 : pos);
172
+ this.startNode.set(getWindowSelection(this.iframe())?.anchorNode);
173
+ this.searching.set(true);
174
+ this.searchString.set('');
175
+ this.showSearchList(nativeElement);
176
+ this.updateSearchList();
177
+ if (config.returnTrigger) {
178
+ this.outSearchTerm.emit(config.triggerChar);
179
+ }
180
+ return;
181
+ }
182
+ setTimeout(() => {
183
+ for (const itemSet of this.nodesInsert()) {
184
+ if (!nativeElement.contains(itemSet.elementSpan)) {
185
+ itemSet.subscription?.unsubscribe();
186
+ this.nodesInsert().delete(itemSet);
187
+ }
188
+ }
189
+ });
190
+ const startPos = this.startPos();
191
+ if (isNil(startPos) || startPos < 0 || !this.searching()) {
192
+ return;
193
+ }
194
+ const searchList = this.searchList();
195
+ if (pos <= startPos) {
196
+ if (searchList) {
197
+ searchList.hidden.set(true);
198
+ }
199
+ return;
200
+ }
201
+ if (event.keyCode === UtilsKeyCodeConstant.SHIFT || event.metaKey || event.altKey || event.ctrlKey || pos <= startPos) {
202
+ return;
203
+ }
204
+ if (!this.activeConfig()?.allowSpace && event.keyCode === UtilsKeyCodeConstant.SPACE) {
205
+ this.startPos.set(-1);
206
+ }
207
+ else if (event.keyCode === UtilsKeyCodeConstant.BACKSPACE && pos > 0) {
208
+ pos--;
209
+ if (pos === this.startPos()) {
210
+ this.stopSearch();
211
+ }
212
+ }
213
+ else if (searchList?.hidden()) {
214
+ if (event.keyCode === UtilsKeyCodeConstant.TAB || event.keyCode === UtilsKeyCodeConstant.ENTER) {
215
+ this.stopSearch();
216
+ return;
217
+ }
218
+ }
219
+ else if (!searchList?.hidden() && this.activeConfig()) {
220
+ if (event.keyCode === UtilsKeyCodeConstant.TAB || event.keyCode === UtilsKeyCodeConstant.ENTER) {
221
+ this.stopEvent(event);
222
+ // emit the selected list item
223
+ this.outItemSelected.emit(searchList?.ActiveItem);
224
+ // optional function to format the selected item before inserting the text
225
+ this.insertMention(nativeElement, pos);
226
+ // fire input event so angular bindings are updated
227
+ if ('Event' in window) {
228
+ // this seems backwards, but fire the event from this elements nativeElement (not the
229
+ // one provided that may be in an iframe, as it won't be propogate)
230
+ // Create the event using the modern Event constructor
231
+ const evt = new Event(this.iframe() ? 'change' : 'input', {
232
+ bubbles: true,
233
+ cancelable: false,
234
+ });
235
+ // Dispatch the event on the native element
236
+ nativeElement.dispatchEvent(evt);
237
+ }
238
+ this.startPos.set(-1);
239
+ this.stopSearch();
240
+ return false;
241
+ }
242
+ if (event.keyCode === UtilsKeyCodeConstant.ESCAPE) {
243
+ this.stopEvent(event);
244
+ this.stopSearch();
245
+ return false;
246
+ }
247
+ if (event.keyCode === UtilsKeyCodeConstant.DOWN_ARROW) {
248
+ this.stopEvent(event);
249
+ searchList?.activateNextItem();
250
+ return false;
251
+ }
252
+ if (event.keyCode === UtilsKeyCodeConstant.UP_ARROW) {
253
+ this.stopEvent(event);
254
+ searchList?.activatePreviousItem();
255
+ return false;
256
+ }
257
+ }
258
+ if (charPressed.length !== 1 && event.keyCode !== UtilsKeyCodeConstant.BACKSPACE) {
259
+ this.stopEvent(event);
260
+ return false;
261
+ }
262
+ if (!this.searching()) {
263
+ return;
264
+ }
265
+ let mention = val.substring((this.startPos() || 0) + 1, pos);
266
+ if (event.keyCode !== UtilsKeyCodeConstant.BACKSPACE && !event.inputEvent) {
267
+ mention += charPressed;
268
+ }
269
+ const searchString = mention.replace(String.fromCharCode(160), ' ').replace(String.fromCharCode(0), '');
270
+ this.searchString.set(searchString.trim());
271
+ const limitSpaceSearchQuery = this.activeConfig()?.limitSpaceSearchQuery;
272
+ if (limitSpaceSearchQuery && searchString.split(' ').length - 1 > limitSpaceSearchQuery) {
273
+ this.searchString.set('');
274
+ }
275
+ if (this.activeConfig()?.returnTrigger) {
276
+ const triggerChar = this.searchString() || event.keyCode === UtilsKeyCodeConstant.BACKSPACE ? val.substring(this.startPos(), (this.startPos() || 0) + 1) : '';
277
+ this.outSearchTerm.emit(triggerChar + this.searchString());
278
+ this.updateSearchList();
279
+ return;
280
+ }
281
+ this.outSearchTerm.emit(this.searchString());
282
+ this.updateSearchList();
283
+ }
284
+ handlerFocus(e, nativeElement = this.element.nativeElement) {
285
+ e?.stopPropagation();
286
+ setTimeout(() => {
287
+ const node = getWindowSelection(this.iframe())?.anchorNode;
288
+ if (node?.nodeType !== 3) {
289
+ this.stopSearch();
290
+ return;
291
+ }
292
+ const textBeforeCursor = getTextBeforeCursor() || '';
293
+ const triggerChars = Object.keys(this.triggerChars()).map((key) => {
294
+ return {
295
+ key: key,
296
+ config: this.triggerChars()[key],
297
+ index: textBeforeCursor.lastIndexOf(key),
298
+ };
299
+ });
300
+ const matchingCharacters = triggerChars.reduce((pre, current) => (pre && current && current.index > pre.index ? current : pre));
301
+ if (matchingCharacters.index < 0) {
302
+ this.stopSearch();
303
+ return;
304
+ }
305
+ const search = textBeforeCursor?.substring(matchingCharacters.index, textBeforeCursor.length);
306
+ if (!search) {
307
+ this.stopSearch();
308
+ return;
309
+ }
310
+ const pos = getCaretPosition(nativeElement, this.iframe());
311
+ this.activeConfig.set(matchingCharacters.config);
312
+ this.startPos.set(pos - (textBeforeCursor.length - matchingCharacters.index));
313
+ this.searchString.set(search.replace(matchingCharacters.key, ''));
314
+ this.searching.set(true);
315
+ this.handlerKeydown({ keyCode: ''.charCodeAt(0), inputEvent: false }, nativeElement);
316
+ const divElement = document.createElement('div');
317
+ divElement.style.width = 'max-content';
318
+ divElement.style.position = 'absolute';
319
+ divElement.innerText = search;
320
+ document.body.appendChild(divElement);
321
+ let iframe = undefined;
322
+ try {
323
+ iframe = this.mentionConfig()?.iframe ? window.parent.document.getElementById(this.mentionConfig()?.iframe) : undefined;
324
+ }
325
+ catch (error) {
326
+ console.log(error);
327
+ }
328
+ const searchList = this.searchList();
329
+ if (searchList) {
330
+ searchList.position(nativeElement, iframe, divElement.getBoundingClientRect().width);
331
+ }
332
+ divElement.remove();
333
+ nativeElement.normalize();
334
+ });
335
+ }
336
+ stopSearch() {
337
+ const searchList = this.searchList();
338
+ if (searchList && !searchList.hidden()) {
339
+ searchList.hidden.set(true);
340
+ this.outToggle.emit(false);
341
+ }
342
+ this.activeConfig.set(undefined);
343
+ this.searching.set(false);
344
+ }
345
+ updateSearchList() {
346
+ const matches = [];
347
+ const activeConfig = this.activeConfig();
348
+ const searchString = this.searchString();
349
+ const searchList = this.searchList();
350
+ // disabling the search relies on the async operation to do the filtering
351
+ if (activeConfig && activeConfig.items && !activeConfig.disableSearch && !isNil(searchString) && activeConfig.labelKey && activeConfig.mentionFilter) {
352
+ matches.push(...activeConfig.mentionFilter(searchString, activeConfig.items));
353
+ }
354
+ // update the search list
355
+ if (!searchList) {
356
+ return;
357
+ }
358
+ searchList.items.set(matches);
359
+ searchList.hidden.set(!matches.length);
360
+ searchList.activeIndex.set(0);
361
+ searchList.scrollContent();
362
+ this.outToggle.emit(matches.length ? true : false);
363
+ }
364
+ showSearchList(nativeElement) {
365
+ let iframe = undefined;
366
+ const mentionConfig = this.mentionConfig();
367
+ try {
368
+ iframe = mentionConfig?.iframe ? window.parent.document.getElementById(mentionConfig?.iframe) : undefined;
369
+ }
370
+ catch (error) {
371
+ console.log(error);
372
+ }
373
+ if (!mentionConfig) {
374
+ return;
375
+ }
376
+ this.outToggle.emit(true);
377
+ let firstTime = false;
378
+ if (!this.listComponentRef()) {
379
+ firstTime = true;
380
+ this.listComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsMentionListComponent));
381
+ this.searchList.set(this.listComponentRef()?.instance);
382
+ }
383
+ this.searchList()?.labelKey.set(this.activeConfig()?.labelKey || '');
384
+ this.searchList()?.styleOff.set(this.mentionConfig()?.disableStyle || false);
385
+ this.searchList()?.activeIndex.set(0);
386
+ this.searchList()?.zIndex.set(this.mentionConfig()?.zIndex || 2500);
387
+ this.searchList()?.isIframe.set(iframe ? true : false);
388
+ this.searchList()?.parentHandlerKeyDown.set(this.handlerKeydown.bind(this));
389
+ this.searchList()?.position(nativeElement, iframe);
390
+ if (firstTime && this.listComponentRef()) {
391
+ this.iframeId.set(this.dynamicComponentService.addToBody(this.listComponentRef(), iframe ? true : false));
392
+ }
393
+ }
394
+ destroyListSearch() {
395
+ this.dynamicComponentService.remove(this.listComponentRef, this.iframeId());
396
+ this.listComponentRef.set(undefined);
397
+ }
398
+ appendEmptyToLastNode(position, length, nativeElement = this.element.nativeElement) {
399
+ const empty = document.createTextNode('\u00A0');
400
+ const selection = getWindowSelection(this.iframe());
401
+ const anchorNode = selection?.anchorNode;
402
+ if (this.isEditor()) {
403
+ const parentNode = anchorNode?.parentNode;
404
+ if (parentNode && parentNode.getAttribute && parentNode.getAttribute('id')) {
405
+ if (!parentNode.nextSibling || !parentNode.nextSibling.textContent?.length) {
406
+ parentNode?.parentNode?.insertBefore(empty, parentNode.nextSibling);
407
+ }
408
+ const range = document.createRange();
409
+ const sel = window.getSelection();
410
+ range.setStart(parentNode.nextSibling, 0);
411
+ range.collapse(true);
412
+ sel?.removeAllRanges();
413
+ sel?.addRange(range);
414
+ }
415
+ return;
416
+ }
417
+ let preNode = null;
418
+ const anchorOffset = selection?.anchorOffset;
419
+ if (!anchorNode || !anchorOffset) {
420
+ return;
421
+ }
422
+ if (anchorNode.nodeName.toLowerCase() !== '#text') {
423
+ nativeElement.appendChild(empty);
424
+ return;
425
+ }
426
+ for (let i = 0; i < nativeElement.childNodes.length; i++) {
427
+ const node = nativeElement.childNodes[i];
428
+ if (anchorNode.nodeType === 3 && anchorNode === node && preNode && preNode.getAttribute && preNode.getAttribute('id') && (!anchorNode.textContent?.length || anchorNode.textContent.length === 1) && position === length) {
429
+ nativeElement.appendChild(empty);
430
+ break;
431
+ }
432
+ preNode = node;
433
+ }
434
+ }
435
+ addNodeZeroWidthSpace(nativeElement = this.element.nativeElement) {
436
+ const empty = document.createTextNode('\u200b');
437
+ let preNode = null;
438
+ for (let i = 0; i < nativeElement.childNodes.length; i++) {
439
+ const node = nativeElement.childNodes[i];
440
+ if (preNode && preNode.getAttribute && preNode.getAttribute('id') && node && node.getAttribute && node.getAttribute('id')) {
441
+ nativeElement.insertBefore(empty, preNode.nextSibling);
442
+ }
443
+ preNode = node;
444
+ }
445
+ }
446
+ insertMention(nativeElement, pos) {
447
+ const activeConfig = this.activeConfig();
448
+ if (!activeConfig) {
449
+ return;
450
+ }
451
+ const searchList = this.searchList();
452
+ let text = '';
453
+ const feId = uuid();
454
+ const id = searchList?.ActiveItem.id || uuid();
455
+ const itemActive = searchList?.ActiveItem;
456
+ const { triggerChar, mentionEventName, mentionActionByEvent } = activeConfig;
457
+ if (activeConfig.mentionSelect) {
458
+ text = activeConfig.mentionSelect(searchList?.ActiveItem, activeConfig.triggerChar);
459
+ }
460
+ if (!this.isEditor()) {
461
+ let span = document.createElement('TEXTAREA');
462
+ span.innerText = text;
463
+ text = span.innerHTML;
464
+ span.remove();
465
+ text = buildTemplate(text, id, feId);
466
+ span = insertValue(nativeElement, this.startPos() || 0, pos, text, this.iframe());
467
+ if (span) {
468
+ const data = {
469
+ elementSpan: span,
470
+ subscription: undefined,
471
+ item: itemActive,
472
+ triggerChar: triggerChar,
473
+ manualAdd: true,
474
+ };
475
+ this.nodesInsert().add(data);
476
+ if (mentionEventName) {
477
+ data.subscription = fromEvent(span, mentionEventName)
478
+ .pipe(tap((e) => e.stopPropagation()), takeUntil(this.onDestroy))
479
+ .subscribe(() => {
480
+ if (mentionActionByEvent) {
481
+ mentionActionByEvent(itemActive, triggerChar);
482
+ }
483
+ });
484
+ }
485
+ }
486
+ }
487
+ else {
488
+ this.outInsertMention.emit({ data: { id, value: text, feId }, lengthKey: pos - (this.startPos() || 0) });
489
+ }
490
+ }
491
+ ngOnDestroy() {
492
+ this.destroyListSearch();
493
+ this.onDestroy.next();
494
+ this.onDestroy.complete();
495
+ }
496
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsMentionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
497
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: LibsUiComponentsInputsMentionDirective, isStandalone: true, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: { timeDelayInit: { classPropertyName: "timeDelayInit", publicName: "timeDelayInit", isSignal: true, isRequired: false, transformFunction: null }, mentionConfig: { classPropertyName: "mentionConfig", publicName: "mentionConfig", isSignal: true, isRequired: false, transformFunction: null }, mentionListTemplate: { classPropertyName: "mentionListTemplate", publicName: "mentionListTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outSearchTerm: "outSearchTerm", outItemSelected: "outItemSelected", outToggle: "outToggle", outInsertMention: "outInsertMention", outFunctionControl: "outFunctionControl" }, ngImport: i0 });
498
+ }
499
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiComponentsInputsMentionDirective, decorators: [{
500
+ type: Directive,
501
+ args: [{
502
+ // eslint-disable-next-line @angular-eslint/directive-selector
503
+ selector: '[LibsUiComponentsInputsMentionDirective]',
504
+ standalone: true,
505
+ }]
506
+ }], ctorParameters: () => [] });
507
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbi5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW5wdXRzL21lbnRpb24vc3JjL21lbnRpb24uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQStCLFNBQVMsRUFBRSxVQUFVLEVBQTBCLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdKLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRS9KLE9BQU8sRUFBRSwwQ0FBMEMsRUFBRSxNQUFNLHVCQUF1QixDQUFDOztBQU9uRixNQUFNLE9BQU8sc0NBQXNDO0lBQ2pELG1CQUFtQjtJQUNYLGdCQUFnQixHQUFHLE1BQU0sQ0FBdUUsU0FBUyxDQUFDLENBQUM7SUFDM0csV0FBVyxHQUFHLE1BQU0sQ0FBbUIsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lB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QUMsQ0FDMUI7eUJBQ0EsU0FBUyxDQUFDLEdBQUcsRUFBRTt3QkFDZCxJQUFJLG9CQUFvQixFQUFFLENBQUM7NEJBQ3pCLG9CQUFvQixDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQzt3QkFDaEQsQ0FBQztvQkFDSCxDQUFDLENBQUMsQ0FBQztnQkFDUCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNHLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM1QixDQUFDO3dHQXZoQlUsc0NBQXNDOzRGQUF0QyxzQ0FBc0M7OzRGQUF0QyxzQ0FBc0M7a0JBTGxELFNBQVM7bUJBQUM7b0JBQ1QsOERBQThEO29CQUM5RCxRQUFRLEVBQUUsMENBQTBDO29CQUNwRCxVQUFVLEVBQUUsSUFBSTtpQkFDakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnRSZWYsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgT25EZXN0cm95LCBUZW1wbGF0ZVJlZiwgZWZmZWN0LCBpbmplY3QsIGlucHV0LCBvdXRwdXQsIHNpZ25hbCwgdW50cmFja2VkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJRXZlbnQsIFRZUEVfVEVNUExBVEVfUkVGIH0gZnJvbSAnQGxpYnMtdWkvaW50ZXJmYWNlcy10eXBlcyc7XG5pbXBvcnQgeyBMaWJzVWlEeW5hbWljQ29tcG9uZW50U2VydmljZSB9IGZyb20gJ0BsaWJzLXVpL3NlcnZpY2VzLWR5bmFtaWMtY29tcG9uZW50JztcbmltcG9ydCB7IGdldCwgaXNOaWwsIHV1aWQgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBmcm9tRXZlbnQgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVXRpbHNLZXlDb2RlQ29uc3RhbnQgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJRywgYnVpbGRUZW1wbGF0ZSB9IGZyb20gJy4vZGVmaW5lcy90ZW1wbGF0ZS5kZWZpbmUnO1xuaW1wb3J0IHsgZ2V0Q2FyZXRQb3NpdGlvbiwgZ2V0VGV4dEJlZm9yZUN1cnNvciwgZ2V0VmFsdWUsIGdldFdpbmRvd1NlbGVjdGlvbiwgaW5zZXJ0VGV4dEF0Q2FyZXQsIGluc2VydFZhbHVlLCBzZXRDYXJldFBvc2l0aW9uIH0gZnJvbSAnLi9kZWZpbmVzL3V0aWxzLmRlZmluZSc7XG5pbXBvcnQgeyBJTWVudGlvbkNvbmZpZywgSU1lbnRpb25GdW5jdGlvbkNvbnRyb2xFdmVudCwgSU1lbnRpb25JbnNlcnQsIElOb2RlSW5zZXJ0IH0gZnJvbSAnLi9pbnRlcmZhY2VzL21lbnRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uTGlzdENvbXBvbmVudCB9IGZyb20gJy4vbGlzdC9saXN0LmNvbXBvbmVudCc7XG5cbkBEaXJlY3RpdmUoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2RpcmVjdGl2ZS1zZWxlY3RvclxuICBzZWxlY3RvcjogJ1tMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkRpcmVjdGl2ZV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkRpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIC8vICNyZWdpb24gUFJPUEVSVFlcbiAgcHJpdmF0ZSBsaXN0Q29tcG9uZW50UmVmID0gc2lnbmFsPENvbXBvbmVudFJlZjxMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkxpc3RDb21wb25lbnQ+IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIG5vZGVzSW5zZXJ0ID0gc2lnbmFsPFNldDxJTm9kZUluc2VydD4+KG5ldyBTZXQoKSk7XG4gIHByaXZhdGUgYWN0aXZlQ29uZmlnID0gc2lnbmFsPElNZW50aW9uQ29uZmlnIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHRyaWdnZXJDaGFycyA9IHNpZ25hbDxSZWNvcmQ8c3RyaW5nLCBJTWVudGlvbkNvbmZpZz4+KHt9KTtcbiAgcHJpdmF0ZSBzZWFyY2hTdHJpbmcgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHByaXZhdGUgc3RhcnRQb3MgPSBzaWduYWw8bnVtYmVyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHN0YXJ0Tm9kZSA9IHNpZ25hbDxhbnk+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgc2VhcmNoTGlzdCA9IHNpZ25hbDxMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkxpc3RDb21wb25lbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgc2VhcmNoaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBpZnJhbWUgPSBzaWduYWw8YW55Pih1bmRlZmluZWQpO1xuICBwcml2YXRlIGxhc3RLZXlDb2RlID0gc2lnbmFsPG51bWJlciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBpc0VkaXRvciA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHByaXZhdGUgaWZyYW1lSWQgPSBzaWduYWw8c3RyaW5nIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIGVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gIHByaXZhdGUgZHluYW1pY0NvbXBvbmVudFNlcnZpY2UgPSBpbmplY3QoTGlic1VpRHluYW1pY0NvbXBvbmVudFNlcnZpY2UpO1xuICBwcml2YXRlIG9uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gI3JlZ2lvbiBJTlBVVFxuICByZWFkb25seSB0aW1lRGVsYXlJbml0ID0gaW5wdXQ8bnVtYmVyLCBudW1iZXIgfCB1bmRlZmluZWQ+KDAsIHsgdHJhbnNmb3JtOiAodmFsKSA9PiB2YWwgPz8gMCB9KTtcbiAgcmVhZG9ubHkgbWVudGlvbkNvbmZpZyA9IGlucHV0PElNZW50aW9uQ29uZmlnPigpO1xuICByZWFkb25seSBtZW50aW9uTGlzdFRlbXBsYXRlID0gaW5wdXQ8VGVtcGxhdGVSZWY8VFlQRV9URU1QTEFURV9SRUY+PigpO1xuXG4gIC8vICNyZWdpb24gT1VUUFVUXG4gIHJlYWRvbmx5IG91dFNlYXJjaFRlcm0gPSBvdXRwdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuICByZWFkb25seSBvdXRJdGVtU2VsZWN0ZWQgPSBvdXRwdXQ8dW5rbm93bj4oKTtcbiAgcmVhZG9ubHkgb3V0VG9nZ2xlID0gb3V0cHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IG91dEluc2VydE1lbnRpb24gPSBvdXRwdXQ8SU1lbnRpb25JbnNlcnQ+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uQ29udHJvbCA9IG91dHB1dDxJTWVudGlvbkZ1bmN0aW9uQ29udHJvbEV2ZW50PigpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICB0aGlzLm1lbnRpb25Db25maWcoKTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnVwZGF0ZUNvbmZpZygpKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5tZW50aW9uQ29uZmlnKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaXNDb250ZW50RWRpdGFibGUgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScpO1xuICAgICAgdGhpcy5pc0VkaXRvci5zZXQoIWlzQ29udGVudEVkaXRhYmxlKTtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSAhdGhpcy5pc0VkaXRvcigpID8gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQgOiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcucWwtZWRpdG9yW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKTtcbiAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICB0aGlzLmhhbmRsZXJLZXlkb3duLmJpbmQodGhpcykoZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIChldmVudDogSW5wdXRFdmVudCkgPT4ge1xuICAgICAgICAgIHRoaXMuaGFuZGxlcklucHV0LmJpbmQodGhpcykoZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgIHRoaXMuaGFuZGxlckJsdXIuYmluZCh0aGlzKShldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgIHRoaXMuaGFuZGxlckZvY3VzLmJpbmQodGhpcykoZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3V0RnVuY3Rpb25Db250cm9sLmVtaXQoe1xuICAgICAgICBhZGRNZW50aW9uOiAoKSA9PiB7XG4gICAgICAgICAgaW5zZXJ0VGV4dEF0Q2FyZXQoZWxlbWVudCwgYCR7dGhpcy5tZW50aW9uQ29uZmlnKCk/LnRyaWdnZXJDaGFyfWApO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVyS2V5ZG93bih7IGtleTogdGhpcy5tZW50aW9uQ29uZmlnKCk/LnRyaWdnZXJDaGFyLCBrZXlDb2RlOiBVdGlsc0tleUNvZGVDb25zdGFudC5CQUNLU1BBQ0UsIHNoaWZ0S2V5OiB0cnVlLCBpbnB1dEV2ZW50OiB0cnVlIH0sIGVsZW1lbnQpO1xuICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9LCB0aGlzLnRpbWVEZWxheUluaXQoKSk7XG4gIH1cblxuICAvKiBGVU5DVElPTlMgKi9cbiAgcHJvdGVjdGVkIHVwZGF0ZUNvbmZpZygpIHtcbiAgICBjb25zdCBtZW50aW9uQ29uZmlnID0gdGhpcy5tZW50aW9uQ29uZmlnKCk7XG4gICAgaWYgKCFtZW50aW9uQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudHJpZ2dlckNoYXJzLnNldCh7fSk7XG4gICAgdGhpcy5hZGRDb25maWcobWVudGlvbkNvbmZpZyk7XG4gICAgaWYgKG1lbnRpb25Db25maWcubWVudGlvbikge1xuICAgICAgbWVudGlvbkNvbmZpZy5tZW50aW9uLmZvckVhY2goKGNvbmZpZykgPT4gdGhpcy5hZGRDb25maWcoY29uZmlnKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRDb25maWcoY29uZmlnOiBJTWVudGlvbkNvbmZpZykge1xuICAgIGNvbnN0IGRlZmF1bHRzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9DT05GSUcpO1xuICAgIGNvbnN0IGxhYmVsS2V5ID0gY29uZmlnLmxhYmVsS2V5IHx8ICdsYWJlbCc7XG4gICAgY29uZmlnID0gT2JqZWN0LmFzc2lnbihkZWZhdWx0cywgY29uZmlnKTtcbiAgICBpZiAoY29uZmlnLml0ZW1zICYmIGNvbmZpZy5pdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZy5pdGVtc1swXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uZmlnLml0ZW1zLmZvckVhY2goKGxhYmVsKSA9PiB7XG4gICAgICAgICAgY29uc3Qgb2JqZWN0OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+PiA9IHt9O1xuICAgICAgICAgIG9iamVjdFtsYWJlbEtleV0gPSBsYWJlbDtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChsYWJlbEtleSkge1xuICAgICAgICAvLyByZW1vdmUgaXRlbXMgd2l0aG91dCBhbiBsYWJlbEtleSAoYXMgaXQncyByZXF1aXJlZCB0byBmaWx0ZXIgdGhlIGxpc3QpXG4gICAgICAgIGNvbmZpZy5pdGVtcyA9IGNvbmZpZy5pdGVtcy5maWx0ZXIoKGUpID0+IGVbbGFiZWxLZXldKTtcbiAgICAgICAgaWYgKCFjb25maWcuZGlzYWJsZVNvcnQpIHtcbiAgICAgICAgICBjb25maWcuaXRlbXMuc29ydCgoYSwgYikgPT4gKGFbbGFiZWxLZXldIHx8ICcnKS5sb2NhbGVDb21wYXJlKGJbbGFiZWxLZXldIHx8ICcnKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy50cmlnZ2VyQ2hhcnMudXBkYXRlKChpdGVtKSA9PiAoe1xuICAgICAgLi4uaXRlbSxcbiAgICAgIFtjb25maWcudHJpZ2dlckNoYXIgfHwgJ0AnXTogY29uZmlnLFxuICAgIH0pKTtcbiAgICBpZiAodGhpcy5hY3RpdmVDb25maWcoKSAmJiB0aGlzLmFjdGl2ZUNvbmZpZygpPy50cmlnZ2VyQ2hhciA9PT0gY29uZmlnLnRyaWdnZXJDaGFyKSB7XG4gICAgICB0aGlzLmFjdGl2ZUNvbmZpZy5zZXQoY29uZmlnKTtcbiAgICAgIHRoaXMudXBkYXRlU2VhcmNoTGlzdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRJZnJhbWUoaWZyYW1lOiBIVE1MSUZyYW1lRWxlbWVudCkge1xuICAgIHRoaXMuaWZyYW1lLnNldChpZnJhbWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRXZlbnQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKGdldDx1bmtub3duPihldmVudCwgJ3dhc0NsaWNrJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQmx1cihldmVudDogRXZlbnQpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgIHRoaXMuc3RvcFNlYXJjaCgpO1xuICAgIH0sIDEwMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlcklucHV0KGV2ZW50OiBJbnB1dEV2ZW50LCBuYXRpdmVFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICBjb25zdCBkYXRhID0gZ2V0KGV2ZW50LCAnZGF0YScpO1xuICAgIGlmICh0aGlzLmxhc3RLZXlDb2RlKCkgPT09IFV0aWxzS2V5Q29kZUNvbnN0YW50LkJVRkZFUkVEICYmIGRhdGEpIHtcbiAgICAgIGNvbnN0IGtleUNvZGUgPSBkYXRhLmNoYXJDb2RlQXQoMCk7XG4gICAgICB0aGlzLmhhbmRsZXJLZXlkb3duKHsga2V5Q29kZSwgaW5wdXRFdmVudDogdHJ1ZSB9LCBuYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlcktleWRvd24oZXZlbnQ6IGFueSwgbmF0aXZlRWxlbWVudDogSFRNTElucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KTogYW55IHtcbiAgICB0aGlzLmxhc3RLZXlDb2RlLnNldChldmVudC5rZXlDb2RlKTtcbiAgICBpZiAoZXZlbnQuaXNDb21wb3NpbmcgfHwgZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuQlVGRkVSRUQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2YWw6IGFueSA9IGdldFZhbHVlKG5hdGl2ZUVsZW1lbnQpO1xuICAgIGxldCBwb3M6IGFueSA9IGdldENhcmV0UG9zaXRpb24obmF0aXZlRWxlbWVudCwgdGhpcy5pZnJhbWUoKSk7XG4gICAgbGV0IGNoYXJQcmVzc2VkID0gZXZlbnQua2V5O1xuICAgIGlmICghdGhpcy5pc0VkaXRvcigpKSB7XG4gICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuQkFDS1NQQUNFKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kRW1wdHlUb0xhc3ROb2RlKHBvcywgdmFsLmxlbmd0aCwgbmF0aXZlRWxlbWVudCk7XG4gICAgICB9XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuYWRkTm9kZVplcm9XaWR0aFNwYWNlKG5hdGl2ZUVsZW1lbnQpLCAwKTtcbiAgICB9XG4gICAgaWYgKCFjaGFyUHJlc3NlZCkge1xuICAgICAgY29uc3QgY2hhckNvZGUgPSBldmVudC53aGljaCB8fCBldmVudC5rZXlDb2RlO1xuICAgICAgY2hhclByZXNzZWQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LndoaWNoIHx8IGV2ZW50LmtleUNvZGUpO1xuICAgICAgaWYgKCFldmVudC5zaGlmdEtleSAmJiBjaGFyQ29kZSA+PSA2NSAmJiBjaGFyQ29kZSA8PSA5MCkge1xuICAgICAgICBjaGFyUHJlc3NlZCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUgKyAzMik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSBVdGlsc0tleUNvZGVDb25zdGFudC5FTlRFUiAmJiBldmVudC53YXNDbGljayAmJiBwb3MgPCAodGhpcy5zdGFydFBvcygpIHx8IDApKSB7XG4gICAgICBwb3MgPSB0aGlzLnN0YXJ0Tm9kZSgpLmxlbmd0aDtcbiAgICAgIHNldENhcmV0UG9zaXRpb24odGhpcy5zdGFydE5vZGUoKSwgcG9zLCB0aGlzLmlmcmFtZSgpKTtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy50cmlnZ2VyQ2hhcnMoKVtjaGFyUHJlc3NlZF07XG4gICAgaWYgKGNvbmZpZykge1xuICAgICAgdGhpcy5hY3RpdmVDb25maWcuc2V0KGNvbmZpZyk7XG4gICAgICB0aGlzLnN0YXJ0UG9zLnNldChldmVudC5pbnB1dEV2ZW50ID8gcG9zIC0gMSA6IHBvcyk7XG4gICAgICB0aGlzLnN0YXJ0Tm9kZS5zZXQoZ2V0V2luZG93U2VsZWN0aW9uKHRoaXMuaWZyYW1lKCkpPy5hbmNob3JOb2RlKTtcbiAgICAgIHRoaXMuc2VhcmNoaW5nLnNldCh0cnVlKTtcbiAgICAgIHRoaXMuc2VhcmNoU3RyaW5nLnNldCgnJyk7XG4gICAgICB0aGlzLnNob3dTZWFyY2hMaXN0KG5hdGl2ZUVsZW1lbnQpO1xuICAgICAgdGhpcy51cGRhdGVTZWFyY2hMaXN0KCk7XG4gICAgICBpZiAoY29uZmlnLnJldHVyblRyaWdnZXIpIHtcbiAgICAgICAgdGhpcy5vdXRTZWFyY2hUZXJtLmVtaXQoY29uZmlnLnRyaWdnZXJDaGFyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW1TZXQgb2YgdGhpcy5ub2Rlc0luc2VydCgpKSB7XG4gICAgICAgIGlmICghbmF0aXZlRWxlbWVudC5jb250YWlucyhpdGVtU2V0LmVsZW1lbnRTcGFuKSkge1xuICAgICAgICAgIGl0ZW1TZXQuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICAgIHRoaXMubm9kZXNJbnNlcnQoKS5kZWxldGUoaXRlbVNldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBzdGFydFBvcyA9IHRoaXMuc3RhcnRQb3MoKTtcbiAgICBpZiAoaXNOaWwoc3RhcnRQb3MpIHx8IHN0YXJ0UG9zIDwgMCB8fCAhdGhpcy5zZWFyY2hpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgaWYgKHBvcyA8PSBzdGFydFBvcykge1xuICAgICAgaWYgKHNlYXJjaExpc3QpIHtcbiAgICAgICAgc2VhcmNoTGlzdC5oaWRkZW4uc2V0KHRydWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuU0hJRlQgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5hbHRLZXkgfHwgZXZlbnQuY3RybEtleSB8fCBwb3MgPD0gc3RhcnRQb3MpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmFjdGl2ZUNvbmZpZygpPy5hbGxvd1NwYWNlICYmIGV2ZW50LmtleUNvZGUgPT09IFV0aWxzS2V5Q29kZUNvbnN0YW50LlNQQUNFKSB7XG4gICAgICB0aGlzLnN0YXJ0UG9zLnNldCgtMSk7XG4gICAgfSBlbHNlIGlmIChldmVudC5rZXlDb2RlID09PSBVdGlsc0tleUNvZGVDb25zdGFudC5CQUNLU1BBQ0UgJiYgcG9zID4gMCkge1xuICAgICAgcG9zLS07XG4gICAgICBpZiAocG9zID09PSB0aGlzLnN0YXJ0UG9zKCkpIHtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzZWFyY2hMaXN0Py5oaWRkZW4oKSkge1xuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IFV0aWxzS2V5Q29kZUNvbnN0YW50LlRBQiB8fCBldmVudC5rZXlDb2RlID09PSBVdGlsc0tleUNvZGVDb25zdGFudC5FTlRFUikge1xuICAgICAgICB0aGlzLnN0b3BTZWFyY2goKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIXNlYXJjaExpc3Q/LmhpZGRlbigpICYmIHRoaXMuYWN0aXZlQ29uZmlnKCkpIHtcbiAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSBVdGlsc0tleUNvZGVDb25zdGFudC5UQUIgfHwgZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuRU5URVIpIHtcbiAgICAgICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICAvLyBlbWl0IHRoZSBzZWxlY3RlZCBsaXN0IGl0ZW1cbiAgICAgICAgdGhpcy5vdXRJdGVtU2VsZWN0ZWQuZW1pdChzZWFyY2hMaXN0Py5BY3RpdmVJdGVtKTtcbiAgICAgICAgLy8gb3B0aW9uYWwgZnVuY3Rpb24gdG8gZm9ybWF0IHRoZSBzZWxlY3RlZCBpdGVtIGJlZm9yZSBpbnNlcnRpbmcgdGhlIHRleHRcbiAgICAgICAgdGhpcy5pbnNlcnRNZW50aW9uKG5hdGl2ZUVsZW1lbnQsIHBvcyk7XG4gICAgICAgIC8vIGZpcmUgaW5wdXQgZXZlbnQgc28gYW5ndWxhciBiaW5kaW5ncyBhcmUgdXBkYXRlZFxuICAgICAgICBpZiAoJ0V2ZW50JyBpbiB3aW5kb3cpIHtcbiAgICAgICAgICAvLyB0aGlzIHNlZW1zIGJhY2t3YXJkcywgYnV0IGZpcmUgdGhlIGV2ZW50IGZyb20gdGhpcyBlbGVtZW50cyBuYXRpdmVFbGVtZW50IChub3QgdGhlXG4gICAgICAgICAgLy8gb25lIHByb3ZpZGVkIHRoYXQgbWF5IGJlIGluIGFuIGlmcmFtZSwgYXMgaXQgd29uJ3QgYmUgcHJvcG9nYXRlKVxuICAgICAgICAgIC8vIENyZWF0ZSB0aGUgZXZlbnQgdXNpbmcgdGhlIG1vZGVybiBFdmVudCBjb25zdHJ1Y3RvclxuICAgICAgICAgIGNvbnN0IGV2dCA9IG5ldyBFdmVudCh0aGlzLmlmcmFtZSgpID8gJ2NoYW5nZScgOiAnaW5wdXQnLCB7XG4gICAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gRGlzcGF0Y2ggdGhlIGV2ZW50IG9uIHRoZSBuYXRpdmUgZWxlbWVudFxuICAgICAgICAgIG5hdGl2ZUVsZW1lbnQuZGlzcGF0Y2hFdmVudChldnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhcnRQb3Muc2V0KC0xKTtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuRVNDQVBFKSB7XG4gICAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IFV0aWxzS2V5Q29kZUNvbnN0YW50LkRPV05fQVJST1cpIHtcbiAgICAgICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICBzZWFyY2hMaXN0Py5hY3RpdmF0ZU5leHRJdGVtKCk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IFV0aWxzS2V5Q29kZUNvbnN0YW50LlVQX0FSUk9XKSB7XG4gICAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcbiAgICAgICAgc2VhcmNoTGlzdD8uYWN0aXZhdGVQcmV2aW91c0l0ZW0oKTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjaGFyUHJlc3NlZC5sZW5ndGggIT09IDEgJiYgZXZlbnQua2V5Q29kZSAhPT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuQkFDS1NQQUNFKSB7XG4gICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlYXJjaGluZygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBtZW50aW9uID0gdmFsLnN1YnN0cmluZygodGhpcy5zdGFydFBvcygpIHx8IDApICsgMSwgcG9zKTtcblxuICAgIGlmIChldmVudC5rZXlDb2RlICE9PSBVdGlsc0tleUNvZGVDb25zdGFudC5CQUNLU1BBQ0UgJiYgIWV2ZW50LmlucHV0RXZlbnQpIHtcbiAgICAgIG1lbnRpb24gKz0gY2hhclByZXNzZWQ7XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaFN0cmluZyA9IG1lbnRpb24ucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKDE2MCksICcgJykucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKDApLCAnJyk7XG4gICAgdGhpcy5zZWFyY2hTdHJpbmcuc2V0KHNlYXJjaFN0cmluZy50cmltKCkpO1xuICAgIGNvbnN0IGxpbWl0U3BhY2VTZWFyY2hRdWVyeSA9IHRoaXMuYWN0aXZlQ29uZmlnKCk/LmxpbWl0U3BhY2VTZWFyY2hRdWVyeTtcbiAgICBpZiAobGltaXRTcGFjZVNlYXJjaFF1ZXJ5ICYmIHNlYXJjaFN0cmluZy5zcGxpdCgnICcpLmxlbmd0aCAtIDEgPiBsaW1pdFNwYWNlU2VhcmNoUXVlcnkpIHtcbiAgICAgIHRoaXMuc2VhcmNoU3RyaW5nLnNldCgnJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmFjdGl2ZUNvbmZpZygpPy5yZXR1cm5UcmlnZ2VyKSB7XG4gICAgICBjb25zdCB0cmlnZ2VyQ2hhciA9IHRoaXMuc2VhcmNoU3RyaW5nKCkgfHwgZXZlbnQua2V5Q29kZSA9PT0gVXRpbHNLZXlDb2RlQ29uc3RhbnQuQkFDS1NQQUNFID8gdmFsLnN1YnN0cmluZyh0aGlzLnN0YXJ0UG9zKCksICh0aGlzLnN0YXJ0UG9zKCkgfHwgMCkgKyAxKSA6ICcnO1xuXG4gICAgICB0aGlzLm91dFNlYXJjaFRlcm0uZW1pdCh0cmlnZ2VyQ2hhciArIHRoaXMuc2VhcmNoU3RyaW5nKCkpO1xuICAgICAgdGhpcy51cGRhdGVTZWFyY2hMaXN0KCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5vdXRTZWFyY2hUZXJtLmVtaXQodGhpcy5zZWFyY2hTdHJpbmcoKSk7XG4gICAgdGhpcy51cGRhdGVTZWFyY2hMaXN0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlckZvY3VzKGU/OiBFdmVudCwgbmF0aXZlRWxlbWVudDogSFRNTElucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XG4gICAgZT8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBub2RlID0gZ2V0V2luZG93U2VsZWN0aW9uKHRoaXMuaWZyYW1lKCkpPy5hbmNob3JOb2RlO1xuXG4gICAgICBpZiAobm9kZT8ubm9kZVR5cGUgIT09IDMpIHtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IGdldFRleHRCZWZvcmVDdXJzb3IoKSB8fCAnJztcblxuICAgICAgY29uc3QgdHJpZ2dlckNoYXJzID0gT2JqZWN0LmtleXModGhpcy50cmlnZ2VyQ2hhcnMoKSkubWFwKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgIGNvbmZpZzogdGhpcy50cmlnZ2VyQ2hhcnMoKVtrZXldLFxuICAgICAgICAgIGluZGV4OiB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKGtleSkgYXMgbnVtYmVyLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgICBjb25zdCBtYXRjaGluZ0NoYXJhY3RlcnMgPSB0cmlnZ2VyQ2hhcnMucmVkdWNlKChwcmUsIGN1cnJlbnQpID0+IChwcmUgJiYgY3VycmVudCAmJiBjdXJyZW50LmluZGV4ID4gcHJlLmluZGV4ID8gY3VycmVudCA6IHByZSkpO1xuXG4gICAgICBpZiAobWF0Y2hpbmdDaGFyYWN0ZXJzLmluZGV4IDwgMCkge1xuICAgICAgICB0aGlzLnN0b3BTZWFyY2goKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBzZWFyY2ggPSB0ZXh0QmVmb3JlQ3Vyc29yPy5zdWJzdHJpbmcobWF0Y2hpbmdDaGFyYWN0ZXJzLmluZGV4LCB0ZXh0QmVmb3JlQ3Vyc29yLmxlbmd0aCk7XG5cbiAgICAgIGlmICghc2VhcmNoKSB7XG4gICAgICAgIHRoaXMuc3RvcFNlYXJjaCgpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvcyA9IGdldENhcmV0UG9zaXRpb24obmF0aXZlRWxlbWVudCwgdGhpcy5pZnJhbWUoKSk7XG5cbiAgICAgIHRoaXMuYWN0aXZlQ29uZmlnLnNldChtYXRjaGluZ0NoYXJhY3RlcnMuY29uZmlnKTtcbiAgICAgIHRoaXMuc3RhcnRQb3Muc2V0KHBvcyAtICh0ZXh0QmVmb3JlQ3Vyc29yLmxlbmd0aCAtIG1hdGNoaW5nQ2hhcmFjdGVycy5pbmRleCkpO1xuICAgICAgdGhpcy5zZWFyY2hTdHJpbmcuc2V0KHNlYXJjaC5yZXBsYWNlKG1hdGNoaW5nQ2hhcmFjdGVycy5rZXksICcnKSk7XG4gICAgICB0aGlzLnNlYXJjaGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmhhbmRsZXJLZXlkb3duKHsga2V5Q29kZTogJycuY2hhckNvZGVBdCgwKSwgaW5wdXRFdmVudDogZmFsc2UgfSwgbmF0aXZlRWxlbWVudCk7XG4gICAgICBjb25zdCBkaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cbiAgICAgIGRpdkVsZW1lbnQuc3R5bGUud2lkdGggPSAnbWF4LWNvbnRlbnQnO1xuICAgICAgZGl2RWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICBkaXZFbGVtZW50LmlubmVyVGV4dCA9IHNlYXJjaDtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2RWxlbWVudCk7XG4gICAgICBsZXQgaWZyYW1lID0gdW5kZWZpbmVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWZyYW1lID0gdGhpcy5tZW50aW9uQ29uZmlnKCk/LmlmcmFtZSA/ICh3aW5kb3cucGFyZW50LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMubWVudGlvbkNvbmZpZygpPy5pZnJhbWUgYXMgc3RyaW5nKSBhcyBIVE1MSUZyYW1lRWxlbWVudCkgOiB1bmRlZmluZWQ7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICB9XG4gICAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgICBpZiAoc2VhcmNoTGlzdCkge1xuICAgICAgICBzZWFyY2hMaXN0LnBvc2l0aW9uKG5hdGl2ZUVsZW1lbnQsIGlmcmFtZSwgZGl2RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCk7XG4gICAgICB9XG4gICAgICBkaXZFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgbmF0aXZlRWxlbWVudC5ub3JtYWxpemUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFNlYXJjaCgpIHtcbiAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgaWYgKHNlYXJjaExpc3QgJiYgIXNlYXJjaExpc3QuaGlkZGVuKCkpIHtcbiAgICAgIHNlYXJjaExpc3QuaGlkZGVuLnNldCh0cnVlKTtcbiAgICAgIHRoaXMub3V0VG9nZ2xlLmVtaXQoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUNvbmZpZy5zZXQodW5kZWZpbmVkKTtcbiAgICB0aGlzLnNlYXJjaGluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTZWFyY2hMaXN0KCkge1xuICAgIGNvbnN0IG1hdGNoZXM6IGFueVtdID0gW107XG4gICAgY29uc3QgYWN0aXZlQ29uZmlnID0gdGhpcy5hY3RpdmVDb25maWcoKTtcbiAgICBjb25zdCBzZWFyY2hTdHJpbmcgPSB0aGlzLnNlYXJjaFN0cmluZygpO1xuICAgIGNvbnN0IHNlYXJjaExpc3QgPSB0aGlzLnNlYXJjaExpc3QoKTtcbiAgICAvLyBkaXNhYmxpbmcgdGhlIHNlYXJjaCByZWxpZXMgb24gdGhlIGFzeW5jIG9wZXJhdGlvbiB0byBkbyB0aGUgZmlsdGVyaW5nXG4gICAgaWYgKGFjdGl2ZUNvbmZpZyAmJiBhY3RpdmVDb25maWcuaXRlbXMgJiYgIWFjdGl2ZUNvbmZpZy5kaXNhYmxlU2VhcmNoICYmICFpc05pbChzZWFyY2hTdHJpbmcpICYmIGFjdGl2ZUNvbmZpZy5sYWJlbEtleSAmJiBhY3RpdmVDb25maWcubWVudGlvbkZpbHRlcikge1xuICAgICAgbWF0Y2hlcy5wdXNoKC4uLihhY3RpdmVDb25maWcubWVudGlvbkZpbHRlcihzZWFyY2hTdHJpbmcsIGFjdGl2ZUNvbmZpZy5pdGVtcykgYXMgYW55KSk7XG4gICAgfVxuICAgIC8vIHVwZGF0ZSB0aGUgc2VhcmNoIGxpc3RcbiAgICBpZiAoIXNlYXJjaExpc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2VhcmNoTGlzdC5pdGVtcy5zZXQobWF0Y2hlcyk7XG4gICAgc2VhcmNoTGlzdC5oaWRkZW4uc2V0KCFtYXRjaGVzLmxlbmd0aCk7XG4gICAgc2VhcmNoTGlzdC5hY3RpdmVJbmRleC5zZXQoMCk7XG4gICAgc2VhcmNoTGlzdC5zY3JvbGxDb250ZW50KCk7XG4gICAgdGhpcy5vdXRUb2dnbGUuZW1pdChtYXRjaGVzLmxlbmd0aCA/IHRydWUgOiBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIHNob3dTZWFyY2hMaXN0KG5hdGl2ZUVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQpIHtcbiAgICBsZXQgaWZyYW1lID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1lbnRpb25Db25maWcgPSB0aGlzLm1lbnRpb25Db25maWcoKTtcbiAgICB0cnkge1xuICAgICAgaWZyYW1lID0gbWVudGlvbkNvbmZpZz8uaWZyYW1lID8gKHdpbmRvdy5wYXJlbnQuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobWVudGlvbkNvbmZpZz8uaWZyYW1lIGFzIHN0cmluZykgYXMgSFRNTElGcmFtZUVsZW1lbnQpIDogdW5kZWZpbmVkO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgfVxuICAgIGlmICghbWVudGlvbkNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm91dFRvZ2dsZS5lbWl0KHRydWUpO1xuICAgIGxldCBmaXJzdFRpbWUgPSBmYWxzZTtcblxuICAgIGlmICghdGhpcy5saXN0Q29tcG9uZW50UmVmKCkpIHtcbiAgICAgIGZpcnN0VGltZSA9IHRydWU7XG4gICAgICB0aGlzLmxpc3RDb21wb25lbnRSZWYuc2V0KHRoaXMuZHluYW1pY0NvbXBvbmVudFNlcnZpY2UucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoTGlic1VpQ29tcG9uZW50c0lucHV0c01lbnRpb25MaXN0Q29tcG9uZW50KSk7XG4gICAgICB0aGlzLnNlYXJjaExpc3Quc2V0KHRoaXMubGlzdENvbXBvbmVudFJlZigpPy5pbnN0YW5jZSk7XG4gICAgfVxuICAgIHRoaXMuc2VhcmNoTGlzdCgpPy5sYWJlbEtleS5zZXQodGhpcy5hY3RpdmVDb25maWcoKT8ubGFiZWxLZXkgfHwgJycpO1xuICAgIHRoaXMuc2VhcmNoTGlzdCgpPy5zdHlsZU9mZi5zZXQodGhpcy5tZW50aW9uQ29uZmlnKCk/LmRpc2FibGVTdHlsZSB8fCBmYWxzZSk7XG4gICAgdGhpcy5zZWFyY2hMaXN0KCk/LmFjdGl2ZUluZGV4LnNldCgwKTtcbiAgICB0aGlzLnNlYXJjaExpc3QoKT8uekluZGV4LnNldCh0aGlzLm1lbnRpb25Db25maWcoKT8uekluZGV4IHx8IDI1MDApO1xuICAgIHRoaXMuc2VhcmNoTGlzdCgpPy5pc0lmcmFtZS5zZXQoaWZyYW1lID8gdHJ1ZSA6IGZhbHNlKTtcbiAgICB0aGlzLnNlYXJjaExpc3QoKT8ucGFyZW50SGFuZGxlcktleURvd24uc2V0KHRoaXMuaGFuZGxlcktleWRvd24uYmluZCh0aGlzKSk7XG4gICAgdGhpcy5zZWFyY2hMaXN0KCk/LnBvc2l0aW9uKG5hdGl2ZUVsZW1lbnQsIGlmcmFtZSk7XG4gICAgaWYgKGZpcnN0VGltZSAmJiB0aGlzLmxpc3RDb21wb25lbnRSZWYoKSkge1xuICAgICAgdGhpcy5pZnJhbWVJZC5zZXQodGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5hZGRUb0JvZHkodGhpcy5saXN0Q29tcG9uZW50UmVmKCksIGlmcmFtZSA/IHRydWUgOiBmYWxzZSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUxpc3RTZWFyY2goKSB7XG4gICAgdGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5yZW1vdmUodGhpcy5saXN0Q29tcG9uZW50UmVmLCB0aGlzLmlmcmFtZUlkKCkpO1xuICAgIHRoaXMubGlzdENvbXBvbmVudFJlZi5zZXQodW5kZWZpbmVkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhcHBlbmRFbXB0eVRvTGFzdE5vZGUocG9zaXRpb246IG51bWJlciwgbGVuZ3RoOiBudW1iZXIsIG5hdGl2ZUVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xuICAgIGNvbnN0IGVtcHR5ID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ1xcdTAwQTAnKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBnZXRXaW5kb3dTZWxlY3Rpb24odGhpcy5pZnJhbWUoKSk7XG4gICAgY29uc3QgYW5jaG9yTm9kZSA9IHNlbGVjdGlvbj8uYW5jaG9yTm9kZTtcblxuICAgIGlmICh0aGlzLmlzRWRpdG9yKCkpIHtcbiAgICAgIGNvbnN0IHBhcmVudE5vZGUgPSBhbmNob3JOb2RlPy5wYXJlbnROb2RlIGFzIEVsZW1lbnQ7XG5cbiAgICAgIGlmIChwYXJlbnROb2RlICYmIHBhcmVudE5vZGUuZ2V0QXR0cmlidXRlICYmIHBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCdpZCcpKSB7XG4gICAgICAgIGlmICghcGFyZW50Tm9kZS5uZXh0U2libGluZyB8fCAhcGFyZW50Tm9kZS5uZXh0U2libGluZy50ZXh0Q29udGVudD8ubGVuZ3RoKSB7XG4gICAgICAgICAgcGFyZW50Tm9kZT8ucGFyZW50Tm9kZT8uaW5zZXJ0QmVmb3JlKGVtcHR5LCBwYXJlbnROb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIGNvbnN0IHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblxuICAgICAgICByYW5nZS5zZXRTdGFydChwYXJlbnROb2RlLm5leHRTaWJsaW5nIGFzIE5vZGUsIDApO1xuICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICAgICAgc2VsPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgc2VsPy5hZGRSYW5nZShyYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHByZU5vZGUgPSBudWxsO1xuICAgIGNvbnN0IGFuY2hvck9mZnNldCA9IHNlbGVjdGlvbj8uYW5jaG9yT2Zmc2V0O1xuXG4gICAgaWYgKCFhbmNob3JOb2RlIHx8ICFhbmNob3JPZmZzZXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYW5jaG9yTm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnI3RleHQnKSB7XG4gICAgICBuYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKGVtcHR5KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gbmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuXG4gICAgICBpZiAoYW5jaG9yTm9kZS5ub2RlVHlwZSA9PT0gMyAmJiBhbmNob3JOb2RlID09PSBub2RlICYmIHByZU5vZGUgJiYgcHJlTm9kZS5nZXRBdHRyaWJ1dGUgJiYgcHJlTm9kZS5nZXRBdHRyaWJ1dGUoJ2lkJykgJiYgKCFhbmNob3JOb2RlLnRleHRDb250ZW50Py5sZW5ndGggfHwgYW5jaG9yTm9kZS50ZXh0Q29udGVudC5sZW5ndGggPT09IDEpICYmIHBvc2l0aW9uID09PSBsZW5ndGgpIHtcbiAgICAgICAgbmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZChlbXB0eSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcHJlTm9kZSA9IG5vZGUgYXMgRWxlbWVudDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYWRkTm9kZVplcm9XaWR0aFNwYWNlKG5hdGl2ZUVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xuICAgIGNvbnN0IGVtcHR5ID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ1xcdTIwMGInKTtcbiAgICBsZXQgcHJlTm9kZSA9IG51bGw7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hdGl2ZUVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZTogYW55ID0gbmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuXG4gICAgICBpZiAocHJlTm9kZSAmJiBwcmVOb2RlLmdldEF0dHJpYnV0ZSAmJiBwcmVOb2RlLmdldEF0dHJpYnV0ZSgnaWQnKSAmJiBub2RlICYmIG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKCdpZCcpKSB7XG4gICAgICAgIG5hdGl2ZUVsZW1lbnQuaW5zZXJ0QmVmb3JlKGVtcHR5LCBwcmVOb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cblxuICAgICAgcHJlTm9kZSA9IG5vZGU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRNZW50aW9uKG5hdGl2ZUVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQsIHBvczogbnVtYmVyKSB7XG4gICAgY29uc3QgYWN0aXZlQ29uZmlnID0gdGhpcy5hY3RpdmVDb25maWcoKTtcbiAgICBpZiAoIWFjdGl2ZUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgbGV0IHRleHQgPSAnJztcbiAgICBjb25zdCBmZUlkID0gdXVpZCgpO1xuICAgIGNvbnN0IGlkID0gc2VhcmNoTGlzdD8uQWN0aXZlSXRlbS5pZCB8fCB1dWlkKCk7XG4gICAgY29uc3QgaXRlbUFjdGl2ZSA9IHNlYXJjaExpc3Q/LkFjdGl2ZUl0ZW07XG4gICAgY29uc3QgeyB0cmlnZ2VyQ2hhciwgbWVudGlvbkV2ZW50TmFtZSwgbWVudGlvbkFjdGlvbkJ5RXZlbnQgfSA9IGFjdGl2ZUNvbmZpZztcblxuICAgIGlmIChhY3RpdmVDb25maWcubWVudGlvblNlbGVjdCkge1xuICAgICAgdGV4dCA9IGFjdGl2ZUNvbmZpZy5tZW50aW9uU2VsZWN0KHNlYXJjaExpc3Q/LkFjdGl2ZUl0ZW0sIGFjdGl2ZUNvbmZpZy50cmlnZ2VyQ2hhcik7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc0VkaXRvcigpKSB7XG4gICAgICBsZXQgc3BhbjogSFRNTFNwYW5FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnVEVYVEFSRUEnKTtcblxuICAgICAgc3Bhbi5pbm5lclRleHQgPSB0ZXh0O1xuICAgICAgdGV4dCA9IHNwYW4uaW5uZXJIVE1MO1xuICAgICAgc3Bhbi5yZW1vdmUoKTtcbiAgICAgIHRleHQgPSBidWlsZFRlbXBsYXRlKHRleHQsIGlkLCBmZUlkKTtcbiAgICAgIHNwYW4gPSBpbnNlcnRWYWx1ZShuYXRpdmVFbGVtZW50LCB0aGlzLnN0YXJ0UG9zKCkgfHwgMCwgcG9zLCB0ZXh0LCB0aGlzLmlmcmFtZSgpKSBhcyBIVE1MU3BhbkVsZW1lbnQ7XG4gICAgICBpZiAoc3Bhbikge1xuICAgICAgICBjb25zdCBkYXRhOiBJTm9kZUluc2VydCA9IHtcbiAgICAgICAgICBlbGVtZW50U3Bhbjogc3BhbixcbiAgICAgICAgICBzdWJzY3JpcHRpb246IHVuZGVmaW5lZCxcbiAgICAgICAgICBpdGVtOiBpdGVtQWN0aXZlLFxuICAgICAgICAgIHRyaWdnZXJDaGFyOiB0cmlnZ2VyQ2hhcixcbiAgICAgICAgICBtYW51YWxBZGQ6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5ub2Rlc0luc2VydCgpLmFkZChkYXRhKTtcbiAgICAgICAgaWYgKG1lbnRpb25FdmVudE5hbWUpIHtcbiAgICAgICAgICBkYXRhLnN1YnNjcmlwdGlvbiA9IGZyb21FdmVudDxJRXZlbnQ+KHNwYW4sIG1lbnRpb25FdmVudE5hbWUpXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgdGFwKChlKSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpKSxcbiAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMub25EZXN0cm95KVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChtZW50aW9uQWN0aW9uQnlFdmVudCkge1xuICAgICAgICAgICAgICAgIG1lbnRpb25BY3Rpb25CeUV2ZW50KGl0ZW1BY3RpdmUsIHRyaWdnZXJDaGFyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vdXRJbnNlcnRNZW50aW9uLmVtaXQoeyBkYXRhOiB7IGlkLCB2YWx1ZTogdGV4dCwgZmVJZCB9LCBsZW5ndGhLZXk6IHBvcyAtICh0aGlzLnN0YXJ0UG9zKCkgfHwgMCkgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95TGlzdFNlYXJjaCgpO1xuICAgIHRoaXMub25EZXN0cm95Lm5leHQoKTtcbiAgICB0aGlzLm9uRGVzdHJveS5jb21wbGV0ZSgpO1xuICB9XG59XG4iXX0=