@nova-ui/bits
Version:
SolarWinds Nova Framework
260 lines • 38.2 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { DOCUMENT } from "@angular/common";
import { Directive, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Input, NgZone, Output, } from "@angular/core";
import throttle from "lodash/throttle";
import { DragAndDropService } from "./drag-and-drop.service";
import { scrollConstants } from "./dragdrop.constants";
import { UtilService } from "../../../services/util.service";
import * as i0 from "@angular/core";
import * as i1 from "../../../services/util.service";
import * as i2 from "./drag-and-drop.service";
/**
* Directive that provides draggable behavior for an element
*
* __Usage:__
*
* Bind this directive to an element to add a draggable behavior to it.
*
* `<div nuiDraggable>Some content</div>`
*
* Make sure that this zone has some content, because draggable directive doesn't set any height
* to the element. This won't work:
*
* `<div nuiDraggable></div>`
*
* Don't forget to assign some payload (data for transmission from draggable to droppable).
* It can be an `Object`, string or whatever can be converted to a string:
*
* `<div nuiDraggable [payload]="myData"></div>`
*
* To subscribe to an event `dragStart, dragEnd` just transmit an attribute
*
* `<div nuiDroppable (dragStart)="dragStart($event)"></div>`
*
* And `dragStart` method will look like that:
*
* `public dragStart(dropEvent: DragEvent) {
* //dropEvent - HTML 5 drag event (native)
* };`
*
* <example-url>./../examples/index.html#/dragdrop</example-url>
*
* @dynamic
* @ignore
*/
export class DraggableDirective {
static { this.draggableClass = "nui-drag__draggable"; }
static { this.draggingClass = "nui-drag--dragging"; }
static { this.dragSourceClass = "nui-drag__drag-source"; }
static { this.adornerClass = "nui-drag__drag-container"; }
static { this.adornerHaloClass = "nui-drag__drag-halo"; }
static { this.dragsourceOverlayClass = "nui-drag__drag-source--overlay"; }
onDragStart(event) {
this.dragStart.emit(event);
this.document.defaultView?.getSelection()?.removeAllRanges();
window.getSelection()?.removeAllRanges();
this.dragsourceOverlay = this.createDragVisuals(event);
this.setImageAndData(event);
/*
runOutsideAngular is used when some action has to be performed outside
angular zone. Therefore, this action won't trigger change detection.
*/
this.zone.runOutsideAngular(() => {
this.document.addEventListener("dragover", this.mouseHook);
});
event.stopPropagation();
}
onDragEnd(event) {
this.dragEnd.emit(event);
this.elRef.nativeElement.classList.remove(DraggableDirective.dragSourceClass);
if (this.adorner) {
this.adorner.remove();
this.adorner = undefined;
}
if (this.dragsourceOverlay) {
this.dragsourceOverlay.remove();
this.dragsourceOverlay = undefined;
}
this.dragAndDropService.resetPayload();
event.stopPropagation();
this.zone.runOutsideAngular(() => {
this.document.removeEventListener("dragover", this.mouseHook);
});
}
constructor(elRef, zone, utilService, dragAndDropService, document) {
this.elRef = elRef;
this.zone = zone;
this.utilService = utilService;
this.dragAndDropService = dragAndDropService;
this.document = document;
this.dragStart = new EventEmitter();
this.dragEnd = new EventEmitter();
this.moveDragAdorner = throttle((coordinates) => {
requestAnimationFrame(() => {
if (this.adorner) {
this.adorner.style.left = coordinates.x + "px";
this.adorner.style.top = coordinates.y + "px";
}
this.autoScroll(coordinates.x, coordinates.y);
});
}, scrollConstants.adornerUpdateThrottleInMs);
this.mouseHook = (event) => {
const clientX = event.clientX;
const clientY = event.clientY;
this.moveDragAdorner({ x: clientX, y: clientY });
};
this.createDragVisuals = (event) => {
// copy the node being dragged, and add effects
this.adorner = this.document.createElement("div");
this.adorner.style.left = event.clientX + "px";
this.adorner.style.top = event.clientY + "px";
this.adorner.classList.add(DraggableDirective.adornerClass);
if (this.adornerDragClass) {
this.adorner.classList.add(this.adornerDragClass);
}
const adornerHalo = this.document.createElement("div");
adornerHalo.classList.add(DraggableDirective.adornerHaloClass);
this.adorner.appendChild(adornerHalo);
// Safari shows the dragImage natively, so we don't have to fake it
if (!this.utilService.browser?.isSafari()) {
const copiedNode = event.currentTarget.cloneNode(true);
copiedNode.style.width =
this.elRef.nativeElement.offsetWidth + "px";
copiedNode.style.height =
this.elRef.nativeElement.offsetHeight + "px";
copiedNode.classList.add(DraggableDirective.draggingClass);
copiedNode.removeAttribute("draggable");
this.adorner.appendChild(copiedNode);
}
// if there is a place to attach to, do it. Otherwise, place it after the copied node
this.elRef.nativeElement.parentNode.appendChild(this.adorner);
// this should be the overlay that fades out the existing node
const dragSourceOverlay = this.document.createElement("div");
dragSourceOverlay.classList.add(DraggableDirective.dragsourceOverlayClass);
// Fix for Google Chrome, appending of overlay in regular way cause unreasonable dispatch of "dragend" event
setTimeout(() => {
this.elRef.nativeElement.appendChild(dragSourceOverlay);
}, 0);
this.elRef.nativeElement.classList.add(DraggableDirective.dragSourceClass);
return dragSourceOverlay;
};
}
ngOnInit() {
this.draggable = true;
}
setImageAndData(event) {
if ((typeof DragEvent !== "undefined" && event instanceof DragEvent) ||
event.dataTransfer) {
if (event.dataTransfer?.setDragImage) {
if (this.utilService.browser?.isSafari()) {
// Safari supports dragImage in a usable way
event.dataTransfer.setDragImage(this.elRef.nativeElement, 0, -10);
}
else {
// but other browsers don't so we have to disable it
const emptyItem = this.document.createElement("div");
event.dataTransfer.setDragImage(emptyItem, 0, 0);
}
}
if (!event.dataTransfer) {
throw new Error("Event do not contain dataTransfer property");
}
event.dataTransfer.dropEffect = "copy";
this.dragAndDropService.setDragPayload(this.payload, event);
}
}
autoScroll(clientX, clientY) {
if (!clientX || !clientY) {
return;
}
if (!this.document.defaultView) {
throw new Error("Document does not contain defaultView property");
}
const verticalDistPercentage = (clientY / this.document.defaultView.innerHeight) * 100;
const horizontalDistPercentage = (clientX / this.document.defaultView.innerWidth) * 100;
const topScrollBoundary = scrollConstants.verticalScrollPercentage;
const bottomScrollBoundary = 100 - scrollConstants.verticalScrollPercentage;
const leftScrollBoundary = scrollConstants.horizontalScrollPercentage;
const rightScrollBoundary = 100 - scrollConstants.horizontalScrollPercentage;
let newX = this.document.defaultView.pageXOffset;
let newY = this.document.defaultView.pageYOffset;
let scrollNeeded = false;
if (verticalDistPercentage < topScrollBoundary) {
const throttleDistance = (topScrollBoundary - verticalDistPercentage) *
scrollConstants.accelerationFactor;
newY = newY - throttleDistance;
scrollNeeded = true;
}
if (verticalDistPercentage > bottomScrollBoundary) {
const throttleDistance = (verticalDistPercentage - bottomScrollBoundary) *
scrollConstants.accelerationFactor;
newY = newY + throttleDistance;
scrollNeeded = true;
}
if (horizontalDistPercentage < leftScrollBoundary) {
const throttleDistance = (leftScrollBoundary - horizontalDistPercentage) *
scrollConstants.accelerationFactor;
newX = newX - throttleDistance;
scrollNeeded = true;
}
if (horizontalDistPercentage > rightScrollBoundary) {
const throttleDistance = (horizontalDistPercentage - rightScrollBoundary) *
scrollConstants.accelerationFactor;
newX = newX + throttleDistance;
scrollNeeded = true;
}
if (scrollNeeded) {
this.document.defaultView.scrollTo(newX, newY);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i1.UtilService }, { token: i2.DragAndDropService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DraggableDirective, selector: "[nuiDraggable]", inputs: { adornerDragClass: "adornerDragClass", payload: "payload" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd" }, host: { listeners: { "dragstart": "onDragStart($event)", "dragend": "onDragEnd($event)" }, properties: { "class.nui-drag__draggable": "this.draggable", "attr.draggable": "this.draggable" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DraggableDirective, decorators: [{
type: Directive,
args: [{
selector: "[nuiDraggable]",
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i1.UtilService }, { type: i2.DragAndDropService }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { adornerDragClass: [{
type: Input
}], payload: [{
type: Input
}], dragStart: [{
type: Output
}], dragEnd: [{
type: Output
}], draggable: [{
type: HostBinding,
args: [`class.${DraggableDirective.draggableClass}`]
}, {
type: HostBinding,
args: ["attr.draggable"]
}], onDragStart: [{
type: HostListener,
args: ["dragstart", ["$event"]]
}], onDragEnd: [{
type: HostListener,
args: ["dragend", ["$event"]]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21tb24vZGlyZWN0aXZlcy9kcmFnZHJvcC9kcmFnZ2FibGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBRU4sTUFBTSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sUUFBUSxNQUFNLGlCQUFpQixDQUFDO0FBRXZDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7Ozs7QUFFN0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDRztBQUlILE1BQU0sT0FBTyxrQkFBa0I7YUFDWixtQkFBYyxHQUFHLHFCQUFxQixBQUF4QixDQUF5QjthQUN2QyxrQkFBYSxHQUFHLG9CQUFvQixBQUF2QixDQUF3QjthQUNyQyxvQkFBZSxHQUFHLHVCQUF1QixBQUEx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aEIsTUFBTTtnQkFtQlAsU0FBUztzQkFGUixXQUFXO3VCQUFDLFNBQVMsa0JBQWtCLENBQUMsY0FBYyxFQUFFOztzQkFDeEQsV0FBVzt1QkFBQyxnQkFBZ0I7Z0JBSTdCLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBa0JyQyxTQUFTO3NCQURSLFlBQVk7dUJBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgICBEaXJlY3RpdmUsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIEluamVjdCxcbiAgICBJbnB1dCxcbiAgICBOZ1pvbmUsXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB0aHJvdHRsZSBmcm9tIFwibG9kYXNoL3Rocm90dGxlXCI7XG5cbmltcG9ydCB7IERyYWdBbmREcm9wU2VydmljZSB9IGZyb20gXCIuL2RyYWctYW5kLWRyb3Auc2VydmljZVwiO1xuaW1wb3J0IHsgc2Nyb2xsQ29uc3RhbnRzIH0gZnJvbSBcIi4vZHJhZ2Ryb3AuY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJRHJhZ0V2ZW50IH0gZnJvbSBcIi4vcHVibGljLWFwaVwiO1xuaW1wb3J0IHsgVXRpbFNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vc2VydmljZXMvdXRpbC5zZXJ2aWNlXCI7XG5cbi8qKlxuICogRGlyZWN0aXZlIHRoYXQgcHJvdmlkZXMgZHJhZ2dhYmxlIGJlaGF2aW9yIGZvciBhbiBlbGVtZW50XG4gKlxuICogIF9fVXNhZ2U6X19cbiAqXG4gKiBCaW5kIHRoaXMgZGlyZWN0aXZlIHRvIGFuIGVsZW1lbnQgdG8gYWRkIGEgZHJhZ2dhYmxlIGJlaGF2aW9yIHRvIGl0LlxuICpcbiAqICAgICAgICBgPGRpdiBudWlEcmFnZ2FibGU+U29tZSBjb250ZW50PC9kaXY+YFxuICpcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoaXMgem9uZSBoYXMgc29tZSBjb250ZW50LCBiZWNhdXNlIGRyYWdnYWJsZSBkaXJlY3RpdmUgZG9lc24ndCBzZXQgYW55IGhlaWdodFxuICogdG8gdGhlIGVsZW1lbnQuIFRoaXMgd29uJ3Qgd29yazpcbiAqXG4gKiAgICAgICAgYDxkaXYgbnVpRHJhZ2dhYmxlPjwvZGl2PmBcbiAqXG4gKiBEb24ndCBmb3JnZXQgdG8gYXNzaWduIHNvbWUgcGF5bG9hZCAoZGF0YSBmb3IgdHJhbnNtaXNzaW9uIGZyb20gZHJhZ2dhYmxlIHRvIGRyb3BwYWJsZSkuXG4gKiBJdCBjYW4gYmUgYW4gYE9iamVjdGAsIHN0cmluZyBvciB3aGF0ZXZlciBjYW4gYmUgY29udmVydGVkIHRvIGEgc3RyaW5nOlxuICpcbiAqICAgICAgICBgPGRpdiBudWlEcmFnZ2FibGUgW3BheWxvYWRdPVwibXlEYXRhXCI+PC9kaXY+YFxuICpcbiAqIFRvIHN1YnNjcmliZSB0byBhbiBldmVudCBgZHJhZ1N0YXJ0LCBkcmFnRW5kYCBqdXN0IHRyYW5zbWl0IGFuIGF0dHJpYnV0ZVxuICpcbiAqICAgICAgICAgYDxkaXYgbnVpRHJvcHBhYmxlIChkcmFnU3RhcnQpPVwiZHJhZ1N0YXJ0KCRldmVudClcIj48L2Rpdj5gXG4gKlxuICogQW5kIGBkcmFnU3RhcnRgIG1ldGhvZCB3aWxsIGxvb2sgbGlrZSB0aGF0OlxuICpcbiAqICAgICAgICAgYHB1YmxpYyBkcmFnU3RhcnQoZHJvcEV2ZW50OiBEcmFnRXZlbnQpIHtcbiAqICAgICAgICAgICAgICAvL2Ryb3BFdmVudCAtIEhUTUwgNSBkcmFnIGV2ZW50IChuYXRpdmUpXG4gKiAgICAgICAgICB9O2BcbiAqXG4gKiA8ZXhhbXBsZS11cmw+Li8uLi9leGFtcGxlcy9pbmRleC5odG1sIy9kcmFnZHJvcDwvZXhhbXBsZS11cmw+XG4gKlxuICogQGR5bmFtaWNcbiAqIEBpZ25vcmVcbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6IFwiW251aURyYWdnYWJsZV1cIixcbn0pXG5leHBvcnQgY2xhc3MgRHJhZ2dhYmxlRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBwcml2YXRlIHN0YXRpYyBkcmFnZ2FibGVDbGFzcyA9IFwibnVpLWRyYWdfX2RyYWdnYWJsZVwiO1xuICAgIHByaXZhdGUgc3RhdGljIGRyYWdnaW5nQ2xhc3MgPSBcIm51aS1kcmFnLS1kcmFnZ2luZ1wiO1xuICAgIHByaXZhdGUgc3RhdGljIGRyYWdTb3VyY2VDbGFzcyA9IFwibnVpLWRyYWdfX2RyYWctc291cmNlXCI7XG4gICAgcHJpdmF0ZSBzdGF0aWMgYWRvcm5lckNsYXNzID0gXCJudWktZHJhZ19fZHJhZy1jb250YWluZXJcIjtcbiAgICBwcml2YXRlIHN0YXRpYyBhZG9ybmVySGFsb0NsYXNzID0gXCJudWktZHJhZ19fZHJhZy1oYWxvXCI7XG4gICAgcHJpdmF0ZSBzdGF0aWMgZHJhZ3NvdXJjZU92ZXJsYXlDbGFzcyA9IFwibnVpLWRyYWdfX2RyYWctc291cmNlLS1vdmVybGF5XCI7XG5cbiAgICBASW5wdXQoKSBhZG9ybmVyRHJhZ0NsYXNzOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcGF5bG9hZDogYW55O1xuICAgIEBPdXRwdXQoKSBkcmFnU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIGRyYWdFbmQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwcml2YXRlIGFkb3JuZXI/OiBIVE1MRWxlbWVudDtcbiAgICBwcml2YXRlIGRyYWdzb3VyY2VPdmVybGF5PzogSFRNTEVsZW1lbnQ7XG4gICAgcHJpdmF0ZSBtb3ZlRHJhZ0Fkb3JuZXIgPSB0aHJvdHRsZShcbiAgICAgICAgKGNvb3JkaW5hdGVzOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0pID0+IHtcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYWRvcm5lcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkb3JuZXIuc3R5bGUubGVmdCA9IGNvb3JkaW5hdGVzLnggKyBcInB4XCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRvcm5lci5zdHlsZS50b3AgPSBjb29yZGluYXRlcy55ICsgXCJweFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmF1dG9TY3JvbGwoY29vcmRpbmF0ZXMueCwgY29vcmRpbmF0ZXMueSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2Nyb2xsQ29uc3RhbnRzLmFkb3JuZXJVcGRhdGVUaHJvdHRsZUluTXNcbiAgICApO1xuXG4gICAgQEhvc3RCaW5kaW5nKGBjbGFzcy4ke0RyYWdnYWJsZURpcmVjdGl2ZS5kcmFnZ2FibGVDbGFzc31gKVxuICAgIEBIb3N0QmluZGluZyhcImF0dHIuZHJhZ2dhYmxlXCIpXG4gICAgZHJhZ2dhYmxlOiBib29sZWFuO1xuXG4gICAgQEhvc3RMaXN0ZW5lcihcImRyYWdzdGFydFwiLCBbXCIkZXZlbnRcIl0pXG4gICAgb25EcmFnU3RhcnQoZXZlbnQ6IElEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kcmFnU3RhcnQuZW1pdChldmVudCk7XG4gICAgICAgIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXc/LmdldFNlbGVjdGlvbigpPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgd2luZG93LmdldFNlbGVjdGlvbigpPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgdGhpcy5kcmFnc291cmNlT3ZlcmxheSA9IHRoaXMuY3JlYXRlRHJhZ1Zpc3VhbHMoZXZlbnQpO1xuICAgICAgICB0aGlzLnNldEltYWdlQW5kRGF0YShldmVudCk7XG4gICAgICAgIC8qXG4gICAgICAgICAgICBydW5PdXRzaWRlQW5ndWxhciBpcyB1c2VkIHdoZW4gc29tZSBhY3Rpb24gaGFzIHRvIGJlIHBlcmZvcm1lZCBvdXRzaWRlXG4gICAgICAgICAgICBhbmd1bGFyIHpvbmUuIFRoZXJlZm9yZSwgdGhpcyBhY3Rpb24gd29uJ3QgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiZHJhZ292ZXJcIiwgdGhpcy5tb3VzZUhvb2spO1xuICAgICAgICB9KTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcihcImRyYWdlbmRcIiwgW1wiJGV2ZW50XCJdKVxuICAgIG9uRHJhZ0VuZChldmVudDogSURyYWdFdmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRyYWdFbmQuZW1pdChldmVudCk7XG4gICAgICAgIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFxuICAgICAgICAgICAgRHJhZ2dhYmxlRGlyZWN0aXZlLmRyYWdTb3VyY2VDbGFzc1xuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5hZG9ybmVyKSB7XG4gICAgICAgICAgICB0aGlzLmFkb3JuZXIucmVtb3ZlKCk7XG4gICAgICAgICAgICB0aGlzLmFkb3JuZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5kcmFnc291cmNlT3ZlcmxheSkge1xuICAgICAgICAgICAgdGhpcy5kcmFnc291cmNlT3ZlcmxheS5yZW1vdmUoKTtcbiAgICAgICAgICAgIHRoaXMuZHJhZ3NvdXJjZU92ZXJsYXkgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kcmFnQW5kRHJvcFNlcnZpY2UucmVzZXRQYXlsb2FkKCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJkcmFnb3ZlclwiLCB0aGlzLm1vdXNlSG9vayk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGVsUmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSxcbiAgICAgICAgcHJpdmF0ZSB1dGlsU2VydmljZTogVXRpbFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgZHJhZ0FuZERyb3BTZXJ2aWNlOiBEcmFnQW5kRHJvcFNlcnZpY2UsXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50XG4gICAgKSB7fVxuXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRyYWdnYWJsZSA9IHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtb3VzZUhvb2sgPSAoZXZlbnQ6IERyYWdFdmVudCkgPT4ge1xuICAgICAgICBjb25zdCBjbGllbnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICAgICAgY29uc3QgY2xpZW50WSA9IGV2ZW50LmNsaWVudFk7XG4gICAgICAgIHRoaXMubW92ZURyYWdBZG9ybmVyKHsgeDogY2xpZW50WCwgeTogY2xpZW50WSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBjcmVhdGVEcmFnVmlzdWFscyA9IChldmVudDogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICAgIC8vIGNvcHkgdGhlIG5vZGUgYmVpbmcgZHJhZ2dlZCwgYW5kIGFkZCBlZmZlY3RzXG4gICAgICAgIHRoaXMuYWRvcm5lciA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdGhpcy5hZG9ybmVyLnN0eWxlLmxlZnQgPSBldmVudC5jbGllbnRYICsgXCJweFwiO1xuICAgICAgICB0aGlzLmFkb3JuZXIuc3R5bGUudG9wID0gZXZlbnQuY2xpZW50WSArIFwicHhcIjtcbiAgICAgICAgdGhpcy5hZG9ybmVyLmNsYXNzTGlzdC5hZGQoRHJhZ2dhYmxlRGlyZWN0aXZlLmFkb3JuZXJDbGFzcyk7XG4gICAgICAgIGlmICh0aGlzLmFkb3JuZXJEcmFnQ2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuYWRvcm5lci5jbGFzc0xpc3QuYWRkKHRoaXMuYWRvcm5lckRyYWdDbGFzcyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWRvcm5lckhhbG8gPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIGFkb3JuZXJIYWxvLmNsYXNzTGlzdC5hZGQoRHJhZ2dhYmxlRGlyZWN0aXZlLmFkb3JuZXJIYWxvQ2xhc3MpO1xuICAgICAgICB0aGlzLmFkb3JuZXIuYXBwZW5kQ2hpbGQoYWRvcm5lckhhbG8pO1xuXG4gICAgICAgIC8vIFNhZmFyaSBzaG93cyB0aGUgZHJhZ0ltYWdlIG5hdGl2ZWx5LCBzbyB3ZSBkb24ndCBoYXZlIHRvIGZha2UgaXRcbiAgICAgICAgaWYgKCF0aGlzLnV0aWxTZXJ2aWNlLmJyb3dzZXI/LmlzU2FmYXJpKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvcGllZE5vZGUgPSAoPGFueT5ldmVudC5jdXJyZW50VGFyZ2V0KS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICAgICAgICBjb3BpZWROb2RlLnN0eWxlLndpZHRoID1cbiAgICAgICAgICAgICAgICB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggKyBcInB4XCI7XG4gICAgICAgICAgICBjb3BpZWROb2RlLnN0eWxlLmhlaWdodCA9XG4gICAgICAgICAgICAgICAgdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodCArIFwicHhcIjtcbiAgICAgICAgICAgIGNvcGllZE5vZGUuY2xhc3NMaXN0LmFkZChEcmFnZ2FibGVEaXJlY3RpdmUuZHJhZ2dpbmdDbGFzcyk7XG4gICAgICAgICAgICBjb3BpZWROb2RlLnJlbW92ZUF0dHJpYnV0ZShcImRyYWdnYWJsZVwiKTtcbiAgICAgICAgICAgIHRoaXMuYWRvcm5lci5hcHBlbmRDaGlsZChjb3BpZWROb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIGEgcGxhY2UgdG8gYXR0YWNoIHRvLCBkbyBpdC4gIE90aGVyd2lzZSwgcGxhY2UgaXQgYWZ0ZXIgdGhlIGNvcGllZCBub2RlXG5cbiAgICAgICAgdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50LnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5hZG9ybmVyKTtcblxuICAgICAgICAvLyB0aGlzIHNob3VsZCBiZSB0aGUgb3ZlcmxheSB0aGF0IGZhZGVzIG91dCB0aGUgZXhpc3Rpbmcgbm9kZVxuICAgICAgICBjb25zdCBkcmFnU291cmNlT3ZlcmxheSA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgZHJhZ1NvdXJjZU92ZXJsYXkuY2xhc3NMaXN0LmFkZChcbiAgICAgICAgICAgIERyYWdnYWJsZURpcmVjdGl2ZS5kcmFnc291cmNlT3ZlcmxheUNsYXNzXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gRml4IGZvciBHb29nbGUgQ2hyb21lLCBhcHBlbmRpbmcgb2Ygb3ZlcmxheSBpbiByZWd1bGFyIHdheSBjYXVzZSB1bnJlYXNvbmFibGUgZGlzcGF0Y2ggb2YgXCJkcmFnZW5kXCIgZXZlbnRcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZHJhZ1NvdXJjZU92ZXJsYXkpO1xuICAgICAgICB9LCAwKTtcblxuICAgICAgICB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZChcbiAgICAgICAgICAgIERyYWdnYWJsZURpcmVjdGl2ZS5kcmFnU291cmNlQ2xhc3NcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gZHJhZ1NvdXJjZU92ZXJsYXk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgc2V0SW1hZ2VBbmREYXRhKGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgKHR5cGVvZiBEcmFnRXZlbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgZXZlbnQgaW5zdGFuY2VvZiBEcmFnRXZlbnQpIHx8XG4gICAgICAgICAgICBldmVudC5kYXRhVHJhbnNmZXJcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZGF0YVRyYW5zZmVyPy5zZXREcmFnSW1hZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51dGlsU2VydmljZS5icm93c2VyPy5pc1NhZmFyaSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBzdXBwb3J0cyBkcmFnSW1hZ2UgaW4gYSB1c2FibGUgd2F5XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREcmFnSW1hZ2UoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgLTEwXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYnV0IG90aGVyIGJyb3dzZXJzIGRvbid0IHNvIHdlIGhhdmUgdG8gZGlzYWJsZSBpdFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbXB0eUl0ZW0gPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREcmFnSW1hZ2UoZW1wdHlJdGVtLCAwLCAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghZXZlbnQuZGF0YVRyYW5zZmVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXZlbnQgZG8gbm90IGNvbnRhaW4gZGF0YVRyYW5zZmVyIHByb3BlcnR5XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSBcImNvcHlcIjtcblxuICAgICAgICAgICAgdGhpcy5kcmFnQW5kRHJvcFNlcnZpY2Uuc2V0RHJhZ1BheWxvYWQodGhpcy5wYXlsb2FkLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGF1dG9TY3JvbGwoY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKCFjbGllbnRYIHx8ICFjbGllbnRZKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkRvY3VtZW50IGRvZXMgbm90IGNvbnRhaW4gZGVmYXVsdFZpZXcgcHJvcGVydHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmVydGljYWxEaXN0UGVyY2VudGFnZSA9XG4gICAgICAgICAgICAoY2xpZW50WSAvIHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcuaW5uZXJIZWlnaHQpICogMTAwO1xuICAgICAgICBjb25zdCBob3Jpem9udGFsRGlzdFBlcmNlbnRhZ2UgPVxuICAgICAgICAgICAgKGNsaWVudFggLyB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LmlubmVyV2lkdGgpICogMTAwO1xuICAgICAgICBjb25zdCB0b3BTY3JvbGxCb3VuZGFyeSA9IHNjcm9sbENvbnN0YW50cy52ZXJ0aWNhbFNjcm9sbFBlcmNlbnRhZ2U7XG4gICAgICAgIGNvbnN0IGJvdHRvbVNjcm9sbEJvdW5kYXJ5ID1cbiAgICAgICAgICAgIDEwMCAtIHNjcm9sbENvbnN0YW50cy52ZXJ0aWNhbFNjcm9sbFBlcmNlbnRhZ2U7XG4gICAgICAgIGNvbnN0IGxlZnRTY3JvbGxCb3VuZGFyeSA9IHNjcm9sbENvbnN0YW50cy5ob3Jpem9udGFsU2Nyb2xsUGVyY2VudGFnZTtcbiAgICAgICAgY29uc3QgcmlnaHRTY3JvbGxCb3VuZGFyeSA9XG4gICAgICAgICAgICAxMDAgLSBzY3JvbGxDb25zdGFudHMuaG9yaXpvbnRhbFNjcm9sbFBlcmNlbnRhZ2U7XG5cbiAgICAgICAgbGV0IG5ld1ggPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LnBhZ2VYT2Zmc2V0O1xuICAgICAgICBsZXQgbmV3WSA9IHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXcucGFnZVlPZmZzZXQ7XG5cbiAgICAgICAgbGV0IHNjcm9sbE5lZWRlZCA9IGZhbHNlO1xuICAgICAgICBpZiAodmVydGljYWxEaXN0UGVyY2VudGFnZSA8IHRvcFNjcm9sbEJvdW5kYXJ5KSB7XG4gICAgICAgICAgICBjb25zdCB0aHJvdHRsZURpc3RhbmNlID1cbiAgICAgICAgICAgICAgICAodG9wU2Nyb2xsQm91bmRhcnkgLSB2ZXJ0aWNhbERpc3RQZXJjZW50YWdlKSAqXG4gICAgICAgICAgICAgICAgc2Nyb2xsQ29uc3RhbnRzLmFjY2VsZXJhdGlvbkZhY3RvcjtcbiAgICAgICAgICAgIG5ld1kgPSBuZXdZIC0gdGhyb3R0bGVEaXN0YW5jZTtcbiAgICAgICAgICAgIHNjcm9sbE5lZWRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZlcnRpY2FsRGlzdFBlcmNlbnRhZ2UgPiBib3R0b21TY3JvbGxCb3VuZGFyeSkge1xuICAgICAgICAgICAgY29uc3QgdGhyb3R0bGVEaXN0YW5jZSA9XG4gICAgICAgICAgICAgICAgKHZlcnRpY2FsRGlzdFBlcmNlbnRhZ2UgLSBib3R0b21TY3JvbGxCb3VuZGFyeSkgKlxuICAgICAgICAgICAgICAgIHNjcm9sbENvbnN0YW50cy5hY2NlbGVyYXRpb25GYWN0b3I7XG4gICAgICAgICAgICBuZXdZID0gbmV3WSArIHRocm90dGxlRGlzdGFuY2U7XG4gICAgICAgICAgICBzY3JvbGxOZWVkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChob3Jpem9udGFsRGlzdFBlcmNlbnRhZ2UgPCBsZWZ0U2Nyb2xsQm91bmRhcnkpIHtcbiAgICAgICAgICAgIGNvbnN0IHRocm90dGxlRGlzdGFuY2UgPVxuICAgICAgICAgICAgICAgIChsZWZ0U2Nyb2xsQm91bmRhcnkgLSBob3Jpem9udGFsRGlzdFBlcmNlbnRhZ2UpICpcbiAgICAgICAgICAgICAgICBzY3JvbGxDb25zdGFudHMuYWNjZWxlcmF0aW9uRmFjdG9yO1xuICAgICAgICAgICAgbmV3WCA9IG5ld1ggLSB0aHJvdHRsZURpc3RhbmNlO1xuICAgICAgICAgICAgc2Nyb2xsTmVlZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaG9yaXpvbnRhbERpc3RQZXJjZW50YWdlID4gcmlnaHRTY3JvbGxCb3VuZGFyeSkge1xuICAgICAgICAgICAgY29uc3QgdGhyb3R0bGVEaXN0YW5jZSA9XG4gICAgICAgICAgICAgICAgKGhvcml6b250YWxEaXN0UGVyY2VudGFnZSAtIHJpZ2h0U2Nyb2xsQm91bmRhcnkpICpcbiAgICAgICAgICAgICAgICBzY3JvbGxDb25zdGFudHMuYWNjZWxlcmF0aW9uRmFjdG9yO1xuICAgICAgICAgICAgbmV3WCA9IG5ld1ggKyB0aHJvdHRsZURpc3RhbmNlO1xuICAgICAgICAgICAgc2Nyb2xsTmVlZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2Nyb2xsTmVlZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3LnNjcm9sbFRvKG5ld1gsIG5ld1kpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19