@libs-ui/components-popover 0.2.5

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,320 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { ChangeDetectionStrategy, Component, ElementRef, effect, inject, input, output, untracked } from '@angular/core';
3
+ import { LibsUiDynamicComponentService } from '@libs-ui/services-dynamic-component';
4
+ import { getViewport, isNil } from '@libs-ui/utils';
5
+ import { Subject, Subscription, fromEvent, timer } from 'rxjs';
6
+ import { debounceTime, takeUntil, tap } from 'rxjs/operators';
7
+ import { getPopoverTimerDestroyInQueryUrl } from './defines/get-popover-timer-destroy.define';
8
+ import { LibsUiComponentsPopoverOverlayComponent } from './overlay/overlay.component';
9
+ import * as i0 from "@angular/core";
10
+ export class LibsUiComponentsPopoverComponent {
11
+ /* PROPERTY */
12
+ mouseEnter;
13
+ mouseLeave;
14
+ mouseWheel;
15
+ mouseClick;
16
+ windowResize;
17
+ windowWheel;
18
+ windowMouseDown;
19
+ windowClick;
20
+ windowMouseUp;
21
+ windowTouch;
22
+ popoverOverlayComponent;
23
+ subsEventPopup = new Subscription();
24
+ firstClick;
25
+ contentInnerHtml;
26
+ timer;
27
+ directionPopover;
28
+ functionsControl;
29
+ frameId;
30
+ onDestroy = new Subject();
31
+ /* INPUT */
32
+ flagMouse = input({ isMouseEnter: false, isMouseEnterContent: false, isContainerHasScroll: false }, {
33
+ transform: (value) => value ? value : { isMouseEnter: false, isMouseEnterContent: false, isContainerHasScroll: false }
34
+ });
35
+ type = input('other');
36
+ mode = input('hover');
37
+ config = input({}, {
38
+ transform: (value) => value ? value : {}
39
+ });
40
+ ignoreShowPopover = input();
41
+ elementRefCustom = input();
42
+ classInclude = input('', { transform: (value) => value ?? '' });
43
+ ignoreHiddenPopoverContentWhenMouseLeave = input();
44
+ ignoreStopPropagationEvent = input();
45
+ ignoreCursorPointerModeLikeClick = input();
46
+ isAddContentToParentDocument = input();
47
+ ignoreClickOutside = input();
48
+ /* OUTPUT */
49
+ outEvent = output();
50
+ outChangStageFlagMouse = output();
51
+ outEventPopoverContent = output();
52
+ outFunctionsControl = output();
53
+ /* INJECT */
54
+ elementRef = inject(ElementRef);
55
+ dynamicService = inject(LibsUiDynamicComponentService);
56
+ constructor() {
57
+ this.firstClick = false;
58
+ let classDefault = undefined;
59
+ effect(() => {
60
+ if (classDefault === undefined) {
61
+ classDefault = this.Element.className;
62
+ }
63
+ this.Element.className = classDefault || '';
64
+ if (this.type() === 'text') {
65
+ this.Element.classList.add('popover-text-ellipsis');
66
+ }
67
+ if (this.mode().includes('click') && !this.ignoreCursorPointerModeLikeClick) {
68
+ this.Element.classList.add('cursor-pointer');
69
+ }
70
+ if (this.classInclude()) {
71
+ this.classInclude()?.split(' ').forEach(className => {
72
+ if (!className) {
73
+ return;
74
+ }
75
+ this.Element.classList.add(className);
76
+ });
77
+ }
78
+ });
79
+ let first = true;
80
+ effect(() => {
81
+ this.config();
82
+ untracked(() => {
83
+ if (this.popoverOverlayComponent?.instance && !first) {
84
+ this.updatePopoverOverlayPosition();
85
+ }
86
+ first = false;
87
+ });
88
+ });
89
+ }
90
+ ngOnInit() {
91
+ this.outEventPopoverContent.subscribe(direction => this.directionPopover = direction);
92
+ this.functionsControl = {
93
+ removePopoverOverlay: this.removePopoverOverlay.bind(this),
94
+ updatePopoverOverlayPosition: this.updatePopoverOverlayPosition.bind(this),
95
+ getRectContainer: async () => (this.elementRefCustom() || this.Element).getBoundingClientRect(),
96
+ getRectContent: async () => (this.popoverOverlayComponent?.instance?.ContainerElement)?.getBoundingClientRect(),
97
+ showPopover: this.addPopoverContent.bind(this),
98
+ updatePopoverOverlay: this.updatePopoverOverlay.bind(this),
99
+ };
100
+ this.outFunctionsControl.emit(this.functionsControl);
101
+ }
102
+ ngAfterContentInit() {
103
+ const nativeEl = this.Element;
104
+ this.mouseEnter = this.initObservable(nativeEl, 'mouseenter');
105
+ this.mouseLeave = this.initObservable(nativeEl, 'mouseleave');
106
+ this.mouseClick = this.initObservable(nativeEl, 'click');
107
+ this.mouseWheel = this.initObservable(window, 'wheel');
108
+ this.windowResize = this.initObservable(window, 'resize');
109
+ this.windowWheel = this.initObservable(window, 'wheel');
110
+ this.windowMouseDown = this.initObservable(window, 'mousedown');
111
+ this.windowClick = this.initObservable(window, 'click');
112
+ this.windowMouseUp = this.initObservable(window, 'mouseup');
113
+ this.windowTouch = this.initObservable(window, 'touchstart');
114
+ this.mouseEnter.subscribe(() => {
115
+ if (!this.mode().includes('hover')) {
116
+ return;
117
+ }
118
+ if (this.type() === 'text' && nativeEl?.clientWidth >= nativeEl.scrollWidth && !this.popoverOverlayComponent) {
119
+ return;
120
+ }
121
+ this.addPopoverContent(nativeEl);
122
+ });
123
+ this.mouseClick.subscribe(() => {
124
+ this.firstClick = !this.firstClick;
125
+ this.outEvent.emit('click');
126
+ if (!this.mode().startsWith('click')) {
127
+ return;
128
+ }
129
+ if (this.mode() === 'click-toggle' && !this.firstClick) {
130
+ this.removePopoverOverlay();
131
+ return;
132
+ }
133
+ this.addPopoverContent(nativeEl);
134
+ });
135
+ this.windowResize.pipe(debounceTime(500)).subscribe(() => {
136
+ if (!this.popoverOverlayComponent) {
137
+ return;
138
+ }
139
+ this.removePopoverOverlay();
140
+ this.addPopoverContent(nativeEl);
141
+ });
142
+ }
143
+ /* FUNCTIONS*/
144
+ async updatePopoverOverlay() {
145
+ const timer = setTimeout(() => {
146
+ clearTimeout(timer);
147
+ if (!this.popoverOverlayComponent?.instance || !this.config()) {
148
+ return;
149
+ }
150
+ const instance = this.popoverOverlayComponent.instance;
151
+ const nativeEl = this.elementRefCustom() || this.Element;
152
+ instance.setConfig(nativeEl.getBoundingClientRect(), this.config());
153
+ });
154
+ }
155
+ async updatePopoverOverlayPosition() {
156
+ clearTimeout(this.timer);
157
+ this.timer = setTimeout(async () => {
158
+ if (!this.popoverOverlayComponent || !this.popoverOverlayComponent.instance || !this.config() || !this.functionsControl) {
159
+ return;
160
+ }
161
+ const viewPort = getViewport();
162
+ const rectListView = await this.functionsControl.getRectContent();
163
+ if (!rectListView) {
164
+ return;
165
+ }
166
+ const rectContainer = await this.functionsControl.getRectContainer();
167
+ const distanceListViewAndContainer = this.config()?.ignoreArrow === false ? 14 : 4;
168
+ if (this.directionPopover === 'bottom' && ((rectListView.top + rectListView.height > viewPort.height) || (rectListView.top < (rectContainer.top + rectContainer.height)) || (rectListView.top - (rectContainer.top + rectContainer.height) > distanceListViewAndContainer)) || ((rectListView.left + rectListView.width > viewPort.width))) {
169
+ const instance = this.popoverOverlayComponent.instance;
170
+ const nativeEl = this.elementRefCustom() || this.Element;
171
+ instance.setConfig(nativeEl.getBoundingClientRect(), { ...(this.config() || {}), ...this.getDefaultConfigs() }, this.isAddContentToParentDocument());
172
+ return;
173
+ }
174
+ if (this.directionPopover !== 'top') {
175
+ return;
176
+ }
177
+ if ((rectContainer.top - (rectListView.top + rectListView.height) > distanceListViewAndContainer) || (rectListView.top + rectListView.height + distanceListViewAndContainer > rectContainer.top + 2) || ((rectListView.left + rectListView.width > viewPort.width))) {
178
+ const instance = this.popoverOverlayComponent.instance;
179
+ const nativeEl = this.elementRefCustom() || this.Element;
180
+ instance.setConfig(nativeEl.getBoundingClientRect(), { ...(this.config() || {}), ...this.getDefaultConfigs() }, this.isAddContentToParentDocument());
181
+ return;
182
+ }
183
+ }, 250);
184
+ }
185
+ get Element() {
186
+ return this.elementRef.nativeElement.firstElementChild || this.elementRef.nativeElement;
187
+ }
188
+ initObservable(el, eventName) {
189
+ return fromEvent(el, eventName).pipe(tap(e => !this.ignoreStopPropagationEvent && e.stopPropagation()), takeUntil(this.onDestroy));
190
+ }
191
+ async addPopoverContent(nativeEl) {
192
+ if (this.popoverOverlayComponent || this.ignoreShowPopover() || !this.config()) {
193
+ return;
194
+ }
195
+ this.popoverOverlayComponent = this.dynamicService.resolveComponentFactory(LibsUiComponentsPopoverOverlayComponent);
196
+ this.frameId = this.dynamicService.addToBody(this.popoverOverlayComponent, this.isAddContentToParentDocument() || this.config().isAddContentToParentDocument);
197
+ this.outEvent.emit('show');
198
+ const instance = this.popoverOverlayComponent.instance;
199
+ nativeEl = this.elementRefCustom() || nativeEl;
200
+ instance.setConfig(nativeEl.getBoundingClientRect(), { ...(this.config() || {}), ...this.getDefaultConfigs() }, this.isAddContentToParentDocument());
201
+ const flagsMouses = {
202
+ isMouseEnter: true,
203
+ isMouseEnterContent: false,
204
+ isContainerHasScroll: nativeEl.offsetHeight < nativeEl.scrollHeight
205
+ };
206
+ const nativeElContainer = instance.ElementRef.nativeElement;
207
+ const mouseEnterContent = this.initObservable(nativeElContainer, 'mouseenter');
208
+ const mouseLeaveContent = this.initObservable(nativeElContainer, 'mouseleave');
209
+ this.subsEventPopup.add(this.initObservable(nativeElContainer, 'touchstart').subscribe());
210
+ this.subsEventPopup.add(instance.outEvent.subscribe((direction) => {
211
+ this.outEventPopoverContent.emit(direction);
212
+ }));
213
+ this.subsEventPopup.add(mouseEnterContent.subscribe(() => {
214
+ this.outEvent.emit('mouseenter-content');
215
+ flagsMouses.isMouseEnterContent = true;
216
+ this.outChangStageFlagMouse.emit(flagsMouses);
217
+ }));
218
+ this.subsEventPopup.add(this.mouseEnter.subscribe(() => {
219
+ this.outEvent.emit('mouseenter-element');
220
+ this.outChangStageFlagMouse.emit(flagsMouses);
221
+ }));
222
+ this.subsEventPopup.add(this.mouseWheel.subscribe(() => {
223
+ flagsMouses.isContainerHasScroll = false;
224
+ if (nativeEl.offsetHeight < nativeEl.scrollHeight) {
225
+ flagsMouses.isContainerHasScroll = true;
226
+ }
227
+ if ((flagsMouses.isMouseEnter && flagsMouses.isContainerHasScroll) || flagsMouses.isMouseEnterContent || this.flagMouse().isMouseEnter || this.flagMouse().isMouseEnterContent) {
228
+ return;
229
+ }
230
+ this.removePopoverOverlay();
231
+ }));
232
+ this.subsEventPopup.add(timer(0).subscribe(() => {
233
+ this.handlerMouseLeaveRemovePopoverOverlay(mouseLeaveContent, flagsMouses, 'isMouseEnterContent', 'isMouseEnter', 'mouseleave-content');
234
+ this.handlerMouseLeaveRemovePopoverOverlay(this.mouseLeave, flagsMouses, 'isMouseEnter', 'isMouseEnterContent', 'mouseleave-element');
235
+ }));
236
+ if (this.mode() === 'click_open_and_click_panel_content_hidden') {
237
+ this.subsEventPopup.add(this.initObservable(nativeElContainer, 'click').subscribe(() => {
238
+ this.removePopoverOverlay();
239
+ }));
240
+ }
241
+ this.handlerWindowEventRemovePopoverOverlay(this.windowClick, flagsMouses);
242
+ this.handlerWindowEventRemovePopoverOverlay(this.windowMouseDown, flagsMouses);
243
+ this.handlerWindowEventRemovePopoverOverlay(this.windowMouseUp, flagsMouses);
244
+ this.handlerWindowEventRemovePopoverOverlay(this.windowWheel, flagsMouses);
245
+ this.subsEventPopup.add(this.windowTouch.subscribe(() => {
246
+ this.removePopoverOverlay();
247
+ }));
248
+ }
249
+ handlerWindowEventRemovePopoverOverlay(obs, flagsMouses) {
250
+ this.subsEventPopup.add(obs.pipe(debounceTime(10)).subscribe(() => {
251
+ if (flagsMouses.isMouseEnter || flagsMouses.isMouseEnterContent || this.ignoreClickOutside()) {
252
+ return;
253
+ }
254
+ if (this.flagMouse && (this.flagMouse().isMouseEnter || this.flagMouse().isMouseEnterContent)) {
255
+ return;
256
+ }
257
+ this.firstClick = false;
258
+ this.removePopoverOverlay();
259
+ }));
260
+ }
261
+ handlerMouseLeaveRemovePopoverOverlay(obs, flagsMouses, flagKeyChangeValue, flagKeyCheck, outEvent) {
262
+ this.subsEventPopup.add(obs.pipe(tap(() => this.outEvent.emit(outEvent)), debounceTime(getPopoverTimerDestroyInQueryUrl() || this.config()?.timerDestroy || 0)).subscribe(() => {
263
+ flagsMouses[flagKeyChangeValue] = false;
264
+ this.outChangStageFlagMouse.emit(flagsMouses);
265
+ if (this.flagMouse && (this.flagMouse().isMouseEnter || this.flagMouse().isMouseEnterContent)) {
266
+ return;
267
+ }
268
+ if (flagsMouses[flagKeyCheck] || this.ignoreHiddenPopoverContentWhenMouseLeave()) {
269
+ return;
270
+ }
271
+ this.removePopoverOverlay();
272
+ }));
273
+ }
274
+ getDefaultConfigs() {
275
+ const configValue = this.config() || {};
276
+ if ((isNil(configValue.content)) || (configValue.content === this.contentInnerHtml && this.contentInnerHtml !== this.elementRef.nativeElement.innerHTML)) {
277
+ configValue.content = this.elementRef.nativeElement.innerHTML;
278
+ }
279
+ this.contentInnerHtml = this.elementRef.nativeElement.innerHTML;
280
+ if (!configValue.maxWidth) {
281
+ configValue.maxWidth = 250;
282
+ }
283
+ if (configValue.maxHeight === undefined || configValue.maxHeight === 0) {
284
+ configValue.maxHeight = 140;
285
+ }
286
+ if (!configValue.direction) {
287
+ configValue.direction = 'bottom';
288
+ }
289
+ if (!configValue.position) {
290
+ configValue.position = {
291
+ mode: 'center',
292
+ distance: 0
293
+ };
294
+ }
295
+ return configValue;
296
+ }
297
+ async removePopoverOverlay() {
298
+ this.dynamicService.remove(this.popoverOverlayComponent, this.frameId);
299
+ this.frameId = undefined;
300
+ this.popoverOverlayComponent = undefined;
301
+ this.subsEventPopup.unsubscribe();
302
+ this.subsEventPopup = new Subscription();
303
+ this.firstClick = false;
304
+ this.outEvent.emit('remove');
305
+ }
306
+ ngOnDestroy() {
307
+ clearTimeout(this.timer);
308
+ this.removePopoverOverlay();
309
+ this.onDestroy.next();
310
+ this.onDestroy.complete();
311
+ this.subsEventPopup.unsubscribe();
312
+ }
313
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsPopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
314
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsPopoverComponent, isStandalone: true, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: { flagMouse: { classPropertyName: "flagMouse", publicName: "flagMouse", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, ignoreShowPopover: { classPropertyName: "ignoreShowPopover", publicName: "ignoreShowPopover", isSignal: true, isRequired: false, transformFunction: null }, elementRefCustom: { classPropertyName: "elementRefCustom", publicName: "elementRefCustom", isSignal: true, isRequired: false, transformFunction: null }, classInclude: { classPropertyName: "classInclude", publicName: "classInclude", isSignal: true, isRequired: false, transformFunction: null }, ignoreHiddenPopoverContentWhenMouseLeave: { classPropertyName: "ignoreHiddenPopoverContentWhenMouseLeave", publicName: "ignoreHiddenPopoverContentWhenMouseLeave", isSignal: true, isRequired: false, transformFunction: null }, ignoreStopPropagationEvent: { classPropertyName: "ignoreStopPropagationEvent", publicName: "ignoreStopPropagationEvent", isSignal: true, isRequired: false, transformFunction: null }, ignoreCursorPointerModeLikeClick: { classPropertyName: "ignoreCursorPointerModeLikeClick", publicName: "ignoreCursorPointerModeLikeClick", isSignal: true, isRequired: false, transformFunction: null }, isAddContentToParentDocument: { classPropertyName: "isAddContentToParentDocument", publicName: "isAddContentToParentDocument", isSignal: true, isRequired: false, transformFunction: null }, ignoreClickOutside: { classPropertyName: "ignoreClickOutside", publicName: "ignoreClickOutside", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outEvent: "outEvent", outChangStageFlagMouse: "outChangStageFlagMouse", outEventPopoverContent: "outEventPopoverContent", outFunctionsControl: "outFunctionsControl" }, ngImport: i0, template: "<ng-content />\n", styles: ["::ng-deep .popover-text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}::ng-deep .cursor-pointer{cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
315
+ }
316
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsPopoverComponent, decorators: [{
317
+ type: Component,
318
+ args: [{ selector: 'libs_ui-components-popover,[LibsUiComponentsPopoverDirective]', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content />\n", styles: ["::ng-deep .popover-text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}::ng-deep .cursor-pointer{cursor:pointer}\n"] }]
319
+ }], ctorParameters: () => [] });
320
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wb3Zlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvcG9wb3Zlci9zcmMvcG9wb3Zlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvcG9wb3Zlci9zcmMvcG9wb3Zlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFvQix1QkFBdUIsRUFBRSxTQUFTLEVBQWdCLFVBQVUsRUFBcUIsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1SyxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNwRixPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BELE9BQU8sRUFBYyxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFLOUYsT0FBTyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBVXRGLE1BQU0sT0FBTyxnQ0FBZ0M7SUFDM0MsY0FBYztJQUNOLFVBQVUsQ0FBMEI7SUFDcEMsVUFBVSxDQUEwQjtJQUNwQyxVQUFVLENBQTBCO0lBQ3BDLFVBQVUsQ0FBMEI7SUFDcEMsWUFBWSxDQUEwQjtJQUN0QyxXQUFXLENBQTBCO0lBQ3JDLGVBQWUsQ0FBMEI7SUFDekMsV0FBVyxDQUEwQjtJQUNyQyxhQUFhLENBQTBCO0lBQ3ZDLFdBQVcsQ0FBMEI7SUFDckMsdUJBQXVC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aW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgQ29tcG9uZW50UmVmLCBFbGVtZW50UmVmLCBPbkRlc3Ryb3ksIE9uSW5pdCwgZWZmZWN0LCBpbmplY3QsIGlucHV0LCBvdXRwdXQsIHVudHJhY2tlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlic1VpRHluYW1pY0NvbXBvbmVudFNlcnZpY2UgfSBmcm9tICdAbGlicy11aS9zZXJ2aWNlcy1keW5hbWljLWNvbXBvbmVudCc7XG5pbXBvcnQgeyBnZXRWaWV3cG9ydCwgaXNOaWwgfSBmcm9tICdAbGlicy11aS91dGlscyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGZyb21FdmVudCwgdGltZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBnZXRQb3BvdmVyVGltZXJEZXN0cm95SW5RdWVyeVVybCB9IGZyb20gJy4vZGVmaW5lcy9nZXQtcG9wb3Zlci10aW1lci1kZXN0cm95LmRlZmluZSc7XG5pbXBvcnQgeyBJRmxhZ01vdXNlIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZsYWctbW91c2UuaW50ZXJmYWNlJztcbmltcG9ydCB7IElQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQgfSBmcm9tICcuL2ludGVyZmFjZXMvZnVuY3Rpb24tY29udHJvbC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSVBvcG92ZXJPdmVybGF5IH0gZnJvbSAnLi9pbnRlcmZhY2VzL292ZXJsYXkuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRZUEVfUE9QT1ZFUl9ESVJFQ1RJT04sIFRZUEVfUE9QT1ZFUl9FVkVOVCwgVFlQRV9QT1BPVkVSX01PREUsIFRZUEVfUE9QT1ZFUl9UWVBFIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3BvcG92ZXIudHlwZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzUG9wb3Zlck92ZXJsYXlDb21wb25lbnQgfSBmcm9tICcuL292ZXJsYXkvb3ZlcmxheS5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlcixbTGlic1VpQ29tcG9uZW50c1BvcG92ZXJEaXJlY3RpdmVdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BvcG92ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcG9wb3Zlci5jb21wb25lbnQuc2NzcycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgLyogUFJPUEVSVFkgKi9cbiAgcHJpdmF0ZSBtb3VzZUVudGVyITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSBtb3VzZUxlYXZlITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSBtb3VzZVdoZWVsITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSBtb3VzZUNsaWNrITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSB3aW5kb3dSZXNpemUhOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+O1xuICBwcml2YXRlIHdpbmRvd1doZWVsITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSB3aW5kb3dNb3VzZURvd24hOiBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+O1xuICBwcml2YXRlIHdpbmRvd0NsaWNrITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSB3aW5kb3dNb3VzZVVwITogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PjtcbiAgcHJpdmF0ZSB3aW5kb3dUb3VjaCE6IE9ic2VydmFibGU8TW91c2VFdmVudD47XG4gIHByaXZhdGUgcG9wb3Zlck92ZXJsYXlDb21wb25lbnQhOiBDb21wb25lbnRSZWY8TGlic1VpQ29tcG9uZW50c1BvcG92ZXJPdmVybGF5Q29tcG9uZW50PiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBzdWJzRXZlbnRQb3B1cCA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSBmaXJzdENsaWNrOiBib29sZWFuO1xuICBwcml2YXRlIGNvbnRlbnRJbm5lckh0bWwhOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZXIhOiBudW1iZXI7XG4gIHByaXZhdGUgZGlyZWN0aW9uUG9wb3Zlcj86IFRZUEVfUE9QT1ZFUl9ESVJFQ1RJT047XG4gIHByaXZhdGUgZnVuY3Rpb25zQ29udHJvbD86IElQb3BvdmVyRnVuY3Rpb25Db250cm9sRXZlbnQ7XG4gIHByaXZhdGUgZnJhbWVJZD86IHN0cmluZztcbiAgcHJpdmF0ZSBvbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qIElOUFVUICovXG4gIGZsYWdNb3VzZSA9IGlucHV0PElGbGFnTW91c2UsIElGbGFnTW91c2U+KHsgaXNNb3VzZUVudGVyOiBmYWxzZSwgaXNNb3VzZUVudGVyQ29udGVudDogZmFsc2UsIGlzQ29udGFpbmVySGFzU2Nyb2xsOiBmYWxzZSB9LCB7XG4gICAgdHJhbnNmb3JtOiAodmFsdWU6IGFueSkgPT4gdmFsdWUgPyB2YWx1ZSA6IHsgaXNNb3VzZUVudGVyOiBmYWxzZSwgaXNNb3VzZUVudGVyQ29udGVudDogZmFsc2UsIGlzQ29udGFpbmVySGFzU2Nyb2xsOiBmYWxzZSB9XG4gIH0pO1xuICByZWFkb25seSB0eXBlID0gaW5wdXQ8VFlQRV9QT1BPVkVSX1RZUEU+KCdvdGhlcicpO1xuICByZWFkb25seSBtb2RlID0gaW5wdXQ8VFlQRV9QT1BPVkVSX01PREU+KCdob3ZlcicpO1xuICByZWFkb25seSBjb25maWcgPSBpbnB1dCh7fSwge1xuICAgIHRyYW5zZm9ybTogKHZhbHVlOiBJUG9wb3Zlck92ZXJsYXkgfCB1bmRlZmluZWQpID0+IHZhbHVlID8gdmFsdWUgOiB7fVxuICB9KTtcbiAgcmVhZG9ubHkgaWdub3JlU2hvd1BvcG92ZXIgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBlbGVtZW50UmVmQ3VzdG9tID0gaW5wdXQ8SFRNTEVsZW1lbnQ+KCk7XG4gIHJlYWRvbmx5IGNsYXNzSW5jbHVkZSA9IGlucHV0PHN0cmluZyB8IHVuZGVmaW5lZCwgc3RyaW5nIHwgdW5kZWZpbmVkPignJywgeyB0cmFuc2Zvcm06ICh2YWx1ZSkgPT4gdmFsdWUgPz8gJycgfSk7XG4gIHJlYWRvbmx5IGlnbm9yZUhpZGRlblBvcG92ZXJDb250ZW50V2hlbk1vdXNlTGVhdmUgPSBpbnB1dDxib29sZWFuPigpO1xuICByZWFkb25seSBpZ25vcmVTdG9wUHJvcGFnYXRpb25FdmVudCA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGlnbm9yZUN1cnNvclBvaW50ZXJNb2RlTGlrZUNsaWNrID0gaW5wdXQ8Ym9vbGVhbj4oKTtcbiAgcmVhZG9ubHkgaXNBZGRDb250ZW50VG9QYXJlbnREb2N1bWVudCA9IGlucHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IGlnbm9yZUNsaWNrT3V0c2lkZSA9IGlucHV0PGJvb2xlYW4+KCk7XG5cbiAgLyogT1VUUFVUICovXG4gIHJlYWRvbmx5IG91dEV2ZW50ID0gb3V0cHV0PFRZUEVfUE9QT1ZFUl9FVkVOVD4oKTtcbiAgcmVhZG9ubHkgb3V0Q2hhbmdTdGFnZUZsYWdNb3VzZSA9IG91dHB1dDxJRmxhZ01vdXNlPigpO1xuICByZWFkb25seSBvdXRFdmVudFBvcG92ZXJDb250ZW50ID0gb3V0cHV0PFRZUEVfUE9QT1ZFUl9ESVJFQ1RJT04+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uc0NvbnRyb2wgPSBvdXRwdXQ8SVBvcG92ZXJGdW5jdGlvbkNvbnRyb2xFdmVudD4oKTtcblxuICAvKiBJTkpFQ1QgKi9cbiAgcHJpdmF0ZSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICBwcml2YXRlIGR5bmFtaWNTZXJ2aWNlID0gaW5qZWN0KExpYnNVaUR5bmFtaWNDb21wb25lbnRTZXJ2aWNlKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmZpcnN0Q2xpY2sgPSBmYWxzZTtcbiAgICBsZXQgY2xhc3NEZWZhdWx0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGlmIChjbGFzc0RlZmF1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjbGFzc0RlZmF1bHQgPSB0aGlzLkVsZW1lbnQuY2xhc3NOYW1lO1xuICAgICAgfVxuICAgICAgdGhpcy5FbGVtZW50LmNsYXNzTmFtZSA9IGNsYXNzRGVmYXVsdCB8fCAnJztcbiAgICAgIGlmICh0aGlzLnR5cGUoKSA9PT0gJ3RleHQnKSB7XG4gICAgICAgIHRoaXMuRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyLXRleHQtZWxsaXBzaXMnKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1vZGUoKS5pbmNsdWRlcygnY2xpY2snKSAmJiAhdGhpcy5pZ25vcmVDdXJzb3JQb2ludGVyTW9kZUxpa2VDbGljaykge1xuICAgICAgICB0aGlzLkVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnY3Vyc29yLXBvaW50ZXInKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmNsYXNzSW5jbHVkZSgpKSB7XG4gICAgICAgIHRoaXMuY2xhc3NJbmNsdWRlKCk/LnNwbGl0KCcgJykuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgICAgIGlmICghY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuRWxlbWVudC5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgZmlyc3QgPSB0cnVlO1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICB0aGlzLmNvbmZpZygpO1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucG9wb3Zlck92ZXJsYXlDb21wb25lbnQ/Lmluc3RhbmNlICYmICFmaXJzdCkge1xuICAgICAgICAgIHRoaXMudXBkYXRlUG9wb3Zlck92ZXJsYXlQb3NpdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMub3V0RXZlbnRQb3BvdmVyQ29udGVudC5zdWJzY3JpYmUoZGlyZWN0aW9uID0+IHRoaXMuZGlyZWN0aW9uUG9wb3ZlciA9IGRpcmVjdGlvbik7XG4gICAgdGhpcy5mdW5jdGlvbnNDb250cm9sID0ge1xuICAgICAgcmVtb3ZlUG9wb3Zlck92ZXJsYXk6IHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkuYmluZCh0aGlzKSxcbiAgICAgIHVwZGF0ZVBvcG92ZXJPdmVybGF5UG9zaXRpb246IHRoaXMudXBkYXRlUG9wb3Zlck92ZXJsYXlQb3NpdGlvbi5iaW5kKHRoaXMpLFxuICAgICAgZ2V0UmVjdENvbnRhaW5lcjogYXN5bmMgKCkgPT4gKHRoaXMuZWxlbWVudFJlZkN1c3RvbSgpIHx8IHRoaXMuRWxlbWVudCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBnZXRSZWN0Q29udGVudDogYXN5bmMgKCkgPT4gKHRoaXMucG9wb3Zlck92ZXJsYXlDb21wb25lbnQ/Lmluc3RhbmNlPy5Db250YWluZXJFbGVtZW50KT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBzaG93UG9wb3ZlcjogdGhpcy5hZGRQb3BvdmVyQ29udGVudC5iaW5kKHRoaXMpLFxuICAgICAgdXBkYXRlUG9wb3Zlck92ZXJsYXk6IHRoaXMudXBkYXRlUG9wb3Zlck92ZXJsYXkuYmluZCh0aGlzKSxcbiAgICB9O1xuICAgIHRoaXMub3V0RnVuY3Rpb25zQ29udHJvbC5lbWl0KHRoaXMuZnVuY3Rpb25zQ29udHJvbCk7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgY29uc3QgbmF0aXZlRWwgPSB0aGlzLkVsZW1lbnQ7XG5cbiAgICB0aGlzLm1vdXNlRW50ZXIgPSB0aGlzLmluaXRPYnNlcnZhYmxlKG5hdGl2ZUVsLCAnbW91c2VlbnRlcicpO1xuICAgIHRoaXMubW91c2VMZWF2ZSA9IHRoaXMuaW5pdE9ic2VydmFibGUobmF0aXZlRWwsICdtb3VzZWxlYXZlJyk7XG4gICAgdGhpcy5tb3VzZUNsaWNrID0gdGhpcy5pbml0T2JzZXJ2YWJsZShuYXRpdmVFbCwgJ2NsaWNrJyk7XG4gICAgdGhpcy5tb3VzZVdoZWVsID0gdGhpcy5pbml0T2JzZXJ2YWJsZSh3aW5kb3csICd3aGVlbCcpO1xuICAgIHRoaXMud2luZG93UmVzaXplID0gdGhpcy5pbml0T2JzZXJ2YWJsZSh3aW5kb3csICdyZXNpemUnKTtcbiAgICB0aGlzLndpbmRvd1doZWVsID0gdGhpcy5pbml0T2JzZXJ2YWJsZSh3aW5kb3csICd3aGVlbCcpO1xuICAgIHRoaXMud2luZG93TW91c2VEb3duID0gdGhpcy5pbml0T2JzZXJ2YWJsZSh3aW5kb3csICdtb3VzZWRvd24nKTtcbiAgICB0aGlzLndpbmRvd0NsaWNrID0gdGhpcy5pbml0T2JzZXJ2YWJsZSh3aW5kb3csICdjbGljaycpO1xuICAgIHRoaXMud2luZG93TW91c2VVcCA9IHRoaXMuaW5pdE9ic2VydmFibGUod2luZG93LCAnbW91c2V1cCcpO1xuICAgIHRoaXMud2luZG93VG91Y2ggPSB0aGlzLmluaXRPYnNlcnZhYmxlKHdpbmRvdywgJ3RvdWNoc3RhcnQnKTtcbiAgICB0aGlzLm1vdXNlRW50ZXIuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5tb2RlKCkuaW5jbHVkZXMoJ2hvdmVyJykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudHlwZSgpID09PSAndGV4dCcgJiYgbmF0aXZlRWw/LmNsaWVudFdpZHRoID49IG5hdGl2ZUVsLnNjcm9sbFdpZHRoICYmICF0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWRkUG9wb3ZlckNvbnRlbnQobmF0aXZlRWwpO1xuICAgIH0pO1xuICAgIHRoaXMubW91c2VDbGljay5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5maXJzdENsaWNrID0gIXRoaXMuZmlyc3RDbGljaztcbiAgICAgIHRoaXMub3V0RXZlbnQuZW1pdCgnY2xpY2snKTtcblxuICAgICAgaWYgKCF0aGlzLm1vZGUoKS5zdGFydHNXaXRoKCdjbGljaycpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubW9kZSgpID09PSAnY2xpY2stdG9nZ2xlJyAmJiAhdGhpcy5maXJzdENsaWNrKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmFkZFBvcG92ZXJDb250ZW50KG5hdGl2ZUVsKTtcbiAgICB9KTtcbiAgICB0aGlzLndpbmRvd1Jlc2l6ZS5waXBlKGRlYm91bmNlVGltZSg1MDApKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgICAgIHRoaXMuYWRkUG9wb3ZlckNvbnRlbnQobmF0aXZlRWwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyogRlVOQ1RJT05TKi9cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVQb3BvdmVyT3ZlcmxheSgpIHtcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGlmICghdGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudD8uaW5zdGFuY2UgfHwgIXRoaXMuY29uZmlnKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50Lmluc3RhbmNlO1xuICAgICAgY29uc3QgbmF0aXZlRWwgPSB0aGlzLmVsZW1lbnRSZWZDdXN0b20oKSB8fCB0aGlzLkVsZW1lbnQ7XG5cbiAgICAgIGluc3RhbmNlLnNldENvbmZpZyhuYXRpdmVFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgdGhpcy5jb25maWcoKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZVBvcG92ZXJPdmVybGF5UG9zaXRpb24oKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO1xuICAgIHRoaXMudGltZXIgPSAoc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG5cbiAgICAgIGlmICghdGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudCB8fCAhdGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudC5pbnN0YW5jZSB8fCAhdGhpcy5jb25maWcoKSB8fCAhdGhpcy5mdW5jdGlvbnNDb250cm9sKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZpZXdQb3J0ID0gZ2V0Vmlld3BvcnQoKTtcbiAgICAgIGNvbnN0IHJlY3RMaXN0VmlldyA9IGF3YWl0IHRoaXMuZnVuY3Rpb25zQ29udHJvbC5nZXRSZWN0Q29udGVudCgpO1xuXG4gICAgICBpZiAoIXJlY3RMaXN0Vmlldykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCByZWN0Q29udGFpbmVyID0gYXdhaXQgdGhpcy5mdW5jdGlvbnNDb250cm9sLmdldFJlY3RDb250YWluZXIoKTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlTGlzdFZpZXdBbmRDb250YWluZXIgPSB0aGlzLmNvbmZpZygpPy5pZ25vcmVBcnJvdyA9PT0gZmFsc2UgPyAxNCA6IDQ7XG5cbiAgICAgIGlmICh0aGlzLmRpcmVjdGlvblBvcG92ZXIgPT09ICdib3R0b20nICYmICgocmVjdExpc3RWaWV3LnRvcCArIHJlY3RMaXN0Vmlldy5oZWlnaHQgPiB2aWV3UG9ydC5oZWlnaHQpIHx8IChyZWN0TGlzdFZpZXcudG9wIDwgKHJlY3RDb250YWluZXIudG9wICsgcmVjdENvbnRhaW5lci5oZWlnaHQpKSB8fCAocmVjdExpc3RWaWV3LnRvcCAtIChyZWN0Q29udGFpbmVyLnRvcCArIHJlY3RDb250YWluZXIuaGVpZ2h0KSA+IGRpc3RhbmNlTGlzdFZpZXdBbmRDb250YWluZXIpKSB8fCAoKHJlY3RMaXN0Vmlldy5sZWZ0ICsgcmVjdExpc3RWaWV3LndpZHRoID4gdmlld1BvcnQud2lkdGgpKSkge1xuXG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudC5pbnN0YW5jZTtcbiAgICAgICAgY29uc3QgbmF0aXZlRWwgPSB0aGlzLmVsZW1lbnRSZWZDdXN0b20oKSB8fCB0aGlzLkVsZW1lbnQ7XG4gICAgICAgIGluc3RhbmNlLnNldENvbmZpZyhuYXRpdmVFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgeyAuLi4gKHRoaXMuY29uZmlnKCkgfHwge30pLCAuLi50aGlzLmdldERlZmF1bHRDb25maWdzKCkgfSwgdGhpcy5pc0FkZENvbnRlbnRUb1BhcmVudERvY3VtZW50KCkpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZGlyZWN0aW9uUG9wb3ZlciAhPT0gJ3RvcCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChyZWN0Q29udGFpbmVyLnRvcCAtIChyZWN0TGlzdFZpZXcudG9wICsgcmVjdExpc3RWaWV3LmhlaWdodCkgPiBkaXN0YW5jZUxpc3RWaWV3QW5kQ29udGFpbmVyKSB8fCAocmVjdExpc3RWaWV3LnRvcCArIHJlY3RMaXN0Vmlldy5oZWlnaHQgKyBkaXN0YW5jZUxpc3RWaWV3QW5kQ29udGFpbmVyID4gcmVjdENvbnRhaW5lci50b3AgKyAyKSB8fCAoKHJlY3RMaXN0Vmlldy5sZWZ0ICsgcmVjdExpc3RWaWV3LndpZHRoID4gdmlld1BvcnQud2lkdGgpKSkge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMucG9wb3Zlck92ZXJsYXlDb21wb25lbnQuaW5zdGFuY2U7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUVsID0gdGhpcy5lbGVtZW50UmVmQ3VzdG9tKCkgfHwgdGhpcy5FbGVtZW50O1xuXG4gICAgICAgIGluc3RhbmNlLnNldENvbmZpZyhuYXRpdmVFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgeyAuLi4gKHRoaXMuY29uZmlnKCkgfHwge30pLCAuLi50aGlzLmdldERlZmF1bHRDb25maWdzKCkgfSwgdGhpcy5pc0FkZENvbnRlbnRUb1BhcmVudERvY3VtZW50KCkpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9LCAyNTApIGFzIHVua25vd24pIGFzIG51bWJlcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmZpcnN0RWxlbWVudENoaWxkIHx8IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0T2JzZXJ2YWJsZShlbDogYW55LCBldmVudE5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8TW91c2VFdmVudD4ge1xuICAgIHJldHVybiBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZWwsIGV2ZW50TmFtZSkucGlwZShcbiAgICAgIHRhcChlID0+ICF0aGlzLmlnbm9yZVN0b3BQcm9wYWdhdGlvbkV2ZW50ICYmIGUuc3RvcFByb3BhZ2F0aW9uKCkpLFxuICAgICAgdGFrZVVudGlsKHRoaXMub25EZXN0cm95KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZFBvcG92ZXJDb250ZW50KG5hdGl2ZUVsOiBIVE1MRWxlbWVudCkge1xuICAgIGlmICh0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50IHx8IHRoaXMuaWdub3JlU2hvd1BvcG92ZXIoKSB8fCAhdGhpcy5jb25maWcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50ID0gdGhpcy5keW5hbWljU2VydmljZS5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShMaWJzVWlDb21wb25lbnRzUG9wb3Zlck92ZXJsYXlDb21wb25lbnQpO1xuICAgIHRoaXMuZnJhbWVJZCA9IHRoaXMuZHluYW1pY1NlcnZpY2UuYWRkVG9Cb2R5KHRoaXMucG9wb3Zlck92ZXJsYXlDb21wb25lbnQsIHRoaXMuaXNBZGRDb250ZW50VG9QYXJlbnREb2N1bWVudCgpIHx8IHRoaXMuY29uZmlnKCkuaXNBZGRDb250ZW50VG9QYXJlbnREb2N1bWVudCk7XG4gICAgdGhpcy5vdXRFdmVudC5lbWl0KCdzaG93Jyk7XG4gICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLnBvcG92ZXJPdmVybGF5Q29tcG9uZW50Lmluc3RhbmNlO1xuXG4gICAgbmF0aXZlRWwgPSB0aGlzLmVsZW1lbnRSZWZDdXN0b20oKSB8fCBuYXRpdmVFbDtcbiAgICBpbnN0YW5jZS5zZXRDb25maWcobmF0aXZlRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIHsgLi4uICh0aGlzLmNvbmZpZygpIHx8IHt9KSwgLi4udGhpcy5nZXREZWZhdWx0Q29uZmlncygpIH0sIHRoaXMuaXNBZGRDb250ZW50VG9QYXJlbnREb2N1bWVudCgpKTtcbiAgICBjb25zdCBmbGFnc01vdXNlczogSUZsYWdNb3VzZSA9IHtcbiAgICAgIGlzTW91c2VFbnRlcjogdHJ1ZSxcbiAgICAgIGlzTW91c2VFbnRlckNvbnRlbnQ6IGZhbHNlLFxuICAgICAgaXNDb250YWluZXJIYXNTY3JvbGw6IG5hdGl2ZUVsLm9mZnNldEhlaWdodCA8IG5hdGl2ZUVsLnNjcm9sbEhlaWdodFxuICAgIH07XG4gICAgY29uc3QgbmF0aXZlRWxDb250YWluZXIgPSBpbnN0YW5jZS5FbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgbW91c2VFbnRlckNvbnRlbnQgPSB0aGlzLmluaXRPYnNlcnZhYmxlKG5hdGl2ZUVsQ29udGFpbmVyLCAnbW91c2VlbnRlcicpO1xuICAgIGNvbnN0IG1vdXNlTGVhdmVDb250ZW50ID0gdGhpcy5pbml0T2JzZXJ2YWJsZShuYXRpdmVFbENvbnRhaW5lciwgJ21vdXNlbGVhdmUnKTtcblxuICAgIHRoaXMuc3Vic0V2ZW50UG9wdXAuYWRkKHRoaXMuaW5pdE9ic2VydmFibGUobmF0aXZlRWxDb250YWluZXIsICd0b3VjaHN0YXJ0Jykuc3Vic2NyaWJlKCkpO1xuXG4gICAgdGhpcy5zdWJzRXZlbnRQb3B1cC5hZGQoaW5zdGFuY2Uub3V0RXZlbnQuc3Vic2NyaWJlKChkaXJlY3Rpb246IFRZUEVfUE9QT1ZFUl9ESVJFQ1RJT04pID0+IHtcbiAgICAgIHRoaXMub3V0RXZlbnRQb3BvdmVyQ29udGVudC5lbWl0KGRpcmVjdGlvbik7XG4gICAgfSkpO1xuXG4gICAgdGhpcy5zdWJzRXZlbnRQb3B1cC5hZGQobW91c2VFbnRlckNvbnRlbnQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMub3V0RXZlbnQuZW1pdCgnbW91c2VlbnRlci1jb250ZW50Jyk7XG4gICAgICBmbGFnc01vdXNlcy5pc01vdXNlRW50ZXJDb250ZW50ID0gdHJ1ZTtcbiAgICAgIHRoaXMub3V0Q2hhbmdTdGFnZUZsYWdNb3VzZS5lbWl0KGZsYWdzTW91c2VzKTtcbiAgICB9KSk7XG5cbiAgICB0aGlzLnN1YnNFdmVudFBvcHVwLmFkZCh0aGlzLm1vdXNlRW50ZXIuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMub3V0RXZlbnQuZW1pdCgnbW91c2VlbnRlci1lbGVtZW50Jyk7XG4gICAgICB0aGlzLm91dENoYW5nU3RhZ2VGbGFnTW91c2UuZW1pdChmbGFnc01vdXNlcyk7XG4gICAgfSkpO1xuXG4gICAgdGhpcy5zdWJzRXZlbnRQb3B1cC5hZGQodGhpcy5tb3VzZVdoZWVsLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBmbGFnc01vdXNlcy5pc0NvbnRhaW5lckhhc1Njcm9sbCA9IGZhbHNlO1xuXG4gICAgICBpZiAobmF0aXZlRWwub2Zmc2V0SGVpZ2h0IDwgbmF0aXZlRWwuc2Nyb2xsSGVpZ2h0KSB7XG4gICAgICAgIGZsYWdzTW91c2VzLmlzQ29udGFpbmVySGFzU2Nyb2xsID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICgoZmxhZ3NNb3VzZXMuaXNNb3VzZUVudGVyICYmIGZsYWdzTW91c2VzLmlzQ29udGFpbmVySGFzU2Nyb2xsKSB8fCBmbGFnc01vdXNlcy5pc01vdXNlRW50ZXJDb250ZW50IHx8IHRoaXMuZmxhZ01vdXNlKCkuaXNNb3VzZUVudGVyIHx8IHRoaXMuZmxhZ01vdXNlKCkuaXNNb3VzZUVudGVyQ29udGVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnJlbW92ZVBvcG92ZXJPdmVybGF5KCk7XG4gICAgfSkpO1xuICAgIHRoaXMuc3Vic0V2ZW50UG9wdXAuYWRkKHRpbWVyKDApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmhhbmRsZXJNb3VzZUxlYXZlUmVtb3ZlUG9wb3Zlck92ZXJsYXkobW91c2VMZWF2ZUNvbnRlbnQsIGZsYWdzTW91c2VzLCAnaXNNb3VzZUVudGVyQ29udGVudCcsICdpc01vdXNlRW50ZXInLCAnbW91c2VsZWF2ZS1jb250ZW50Jyk7XG4gICAgICB0aGlzLmhhbmRsZXJNb3VzZUxlYXZlUmVtb3ZlUG9wb3Zlck92ZXJsYXkodGhpcy5tb3VzZUxlYXZlLCBmbGFnc01vdXNlcywgJ2lzTW91c2VFbnRlcicsICdpc01vdXNlRW50ZXJDb250ZW50JywgJ21vdXNlbGVhdmUtZWxlbWVudCcpO1xuICAgIH0pKTtcblxuICAgIGlmICh0aGlzLm1vZGUoKSA9PT0gJ2NsaWNrX29wZW5fYW5kX2NsaWNrX3BhbmVsX2NvbnRlbnRfaGlkZGVuJykge1xuICAgICAgdGhpcy5zdWJzRXZlbnRQb3B1cC5hZGQodGhpcy5pbml0T2JzZXJ2YWJsZShuYXRpdmVFbENvbnRhaW5lciwgJ2NsaWNrJykuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZW1vdmVQb3BvdmVyT3ZlcmxheSgpO1xuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHRoaXMuaGFuZGxlcldpbmRvd0V2ZW50UmVtb3ZlUG9wb3Zlck92ZXJsYXkodGhpcy53aW5kb3dDbGljaywgZmxhZ3NNb3VzZXMpO1xuICAgIHRoaXMuaGFuZGxlcldpbmRvd0V2ZW50UmVtb3ZlUG9wb3Zlck92ZXJsYXkodGhpcy53aW5kb3dNb3VzZURvd24sIGZsYWdzTW91c2VzKTtcbiAgICB0aGlzLmhhbmRsZXJXaW5kb3dFdmVudFJlbW92ZVBvcG92ZXJPdmVybGF5KHRoaXMud2luZG93TW91c2VVcCwgZmxhZ3NNb3VzZXMpO1xuICAgIHRoaXMuaGFuZGxlcldpbmRvd0V2ZW50UmVtb3ZlUG9wb3Zlck92ZXJsYXkodGhpcy53aW5kb3dXaGVlbCwgZmxhZ3NNb3VzZXMpO1xuICAgIHRoaXMuc3Vic0V2ZW50UG9wdXAuYWRkKHRoaXMud2luZG93VG91Y2guc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZXJXaW5kb3dFdmVudFJlbW92ZVBvcG92ZXJPdmVybGF5KG9iczogT2JzZXJ2YWJsZTxNb3VzZUV2ZW50PiwgZmxhZ3NNb3VzZXM6IElGbGFnTW91c2UpIHtcbiAgICB0aGlzLnN1YnNFdmVudFBvcHVwLmFkZChvYnMucGlwZShkZWJvdW5jZVRpbWUoMTApKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKGZsYWdzTW91c2VzLmlzTW91c2VFbnRlciB8fCBmbGFnc01vdXNlcy5pc01vdXNlRW50ZXJDb250ZW50IHx8IHRoaXMuaWdub3JlQ2xpY2tPdXRzaWRlKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZmxhZ01vdXNlICYmICh0aGlzLmZsYWdNb3VzZSgpLmlzTW91c2VFbnRlciB8fCB0aGlzLmZsYWdNb3VzZSgpLmlzTW91c2VFbnRlckNvbnRlbnQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlyc3RDbGljayA9IGZhbHNlO1xuICAgICAgdGhpcy5yZW1vdmVQb3BvdmVyT3ZlcmxheSgpO1xuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlck1vdXNlTGVhdmVSZW1vdmVQb3BvdmVyT3ZlcmxheShvYnM6IE9ic2VydmFibGU8TW91c2VFdmVudD4sIGZsYWdzTW91c2VzOiB7IGlzTW91c2VFbnRlcjogYm9vbGVhbiwgaXNNb3VzZUVudGVyQ29udGVudDogYm9vbGVhbiB9LCBmbGFnS2V5Q2hhbmdlVmFsdWU6IHN0cmluZywgZmxhZ0tleUNoZWNrOiBzdHJpbmcsIG91dEV2ZW50OiBUWVBFX1BPUE9WRVJfRVZFTlQpIHtcbiAgICB0aGlzLnN1YnNFdmVudFBvcHVwLmFkZChvYnMucGlwZShcbiAgICAgIHRhcCgoKSA9PiB0aGlzLm91dEV2ZW50LmVtaXQob3V0RXZlbnQpKSxcbiAgICAgIGRlYm91bmNlVGltZShnZXRQb3BvdmVyVGltZXJEZXN0cm95SW5RdWVyeVVybCgpIHx8IHRoaXMuY29uZmlnKCk/LnRpbWVyRGVzdHJveSB8fCAwKVxuICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIChmbGFnc01vdXNlcyBhcyBhbnkpW2ZsYWdLZXlDaGFuZ2VWYWx1ZV0gPSBmYWxzZTtcbiAgICAgIHRoaXMub3V0Q2hhbmdTdGFnZUZsYWdNb3VzZS5lbWl0KGZsYWdzTW91c2VzKTtcbiAgICAgIGlmICh0aGlzLmZsYWdNb3VzZSAmJiAodGhpcy5mbGFnTW91c2UoKS5pc01vdXNlRW50ZXIgfHwgdGhpcy5mbGFnTW91c2UoKS5pc01vdXNlRW50ZXJDb250ZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICgoZmxhZ3NNb3VzZXMgYXMgYW55KVtmbGFnS2V5Q2hlY2tdIHx8IHRoaXMuaWdub3JlSGlkZGVuUG9wb3ZlckNvbnRlbnRXaGVuTW91c2VMZWF2ZSgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGdldERlZmF1bHRDb25maWdzKCk6IElQb3BvdmVyT3ZlcmxheSB7XG4gICAgY29uc3QgY29uZmlnVmFsdWUgPSB0aGlzLmNvbmZpZygpIHx8IHt9O1xuICAgIGlmICgoaXNOaWwoY29uZmlnVmFsdWUuY29udGVudCkpIHx8IChjb25maWdWYWx1ZS5jb250ZW50ID09PSB0aGlzLmNvbnRlbnRJbm5lckh0bWwgJiYgdGhpcy5jb250ZW50SW5uZXJIdG1sICE9PSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5pbm5lckhUTUwpKSB7XG4gICAgICBjb25maWdWYWx1ZS5jb250ZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MO1xuICAgIH1cbiAgICB0aGlzLmNvbnRlbnRJbm5lckh0bWwgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5pbm5lckhUTUw7XG4gICAgaWYgKCFjb25maWdWYWx1ZS5tYXhXaWR0aCkge1xuICAgICAgY29uZmlnVmFsdWUubWF4V2lkdGggPSAyNTA7XG4gICAgfVxuICAgIGlmIChjb25maWdWYWx1ZS5tYXhIZWlnaHQgPT09IHVuZGVmaW5lZCB8fCBjb25maWdWYWx1ZS5tYXhIZWlnaHQgPT09IDApIHtcbiAgICAgIGNvbmZpZ1ZhbHVlLm1heEhlaWdodCA9IDE0MDtcbiAgICB9XG4gICAgaWYgKCFjb25maWdWYWx1ZS5kaXJlY3Rpb24pIHtcbiAgICAgIGNvbmZpZ1ZhbHVlLmRpcmVjdGlvbiA9ICdib3R0b20nO1xuICAgIH1cbiAgICBpZiAoIWNvbmZpZ1ZhbHVlLnBvc2l0aW9uKSB7XG4gICAgICBjb25maWdWYWx1ZS5wb3NpdGlvbiA9IHtcbiAgICAgICAgbW9kZTogJ2NlbnRlcicsXG4gICAgICAgIGRpc3RhbmNlOiAwXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWdWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlUG9wb3Zlck92ZXJsYXkoKSB7XG4gICAgdGhpcy5keW5hbWljU2VydmljZS5yZW1vdmUodGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudCwgdGhpcy5mcmFtZUlkKTtcbiAgICB0aGlzLmZyYW1lSWQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5wb3BvdmVyT3ZlcmxheUNvbXBvbmVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnN1YnNFdmVudFBvcHVwLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5zdWJzRXZlbnRQb3B1cCA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgICB0aGlzLmZpcnN0Q2xpY2sgPSBmYWxzZTtcbiAgICB0aGlzLm91dEV2ZW50LmVtaXQoJ3JlbW92ZScpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO1xuICAgIHRoaXMucmVtb3ZlUG9wb3Zlck92ZXJsYXkoKTtcbiAgICB0aGlzLm9uRGVzdHJveS5uZXh0KCk7XG4gICAgdGhpcy5vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgICB0aGlzLnN1YnNFdmVudFBvcHVwLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxuZy1jb250ZW50IC8+XG4iXX0=