angular2gridsterv3
Version:
246 lines • 42.8 kB
JavaScript
import { fromEvent, merge } from 'rxjs';
import { share, map, filter, tap, switchMap, takeUntil, take, skip } from 'rxjs/operators';
import { DraggableEvent } from './DraggableEvent';
import { utils } from './utils';
export class Draggable {
constructor(element, config = {}) {
this.mousemove = merge(fromEvent(document, 'mousemove'), fromEvent(document, 'touchmove', { passive: false })).pipe(share());
this.mouseup = merge(fromEvent(document, 'mouseup'), fromEvent(document, 'touchend'), fromEvent(document, 'touchcancel')).pipe(share());
this.config = {
handlerClass: null,
scroll: true,
scrollEdge: 36,
scrollDirection: null
};
// reference to auto scrolling listeners
this.autoScrollingInterval = [];
this.element = element;
this.mousedown = merge(fromEvent(element, 'mousedown'), fromEvent(element, 'touchstart')).pipe(share());
this.config = { ...this.config, ...config };
this.dragStart = this.createDragStartObservable().pipe(share());
this.dragMove = this.createDragMoveObservable(this.dragStart);
this.dragStop = this.createDragStopObservable(this.dragStart);
this.fixProblemWithDnDForIE(element);
this.requestAnimationFrame =
window.requestAnimationFrame || (callback => setTimeout(callback, 1000 / 60));
this.cancelAnimationFrame = window.cancelAnimationFrame || (cafID => clearTimeout(cafID));
}
createDragStartObservable() {
return this.mousedown.pipe(map(md => new DraggableEvent(md)), filter((event) => this.isDragingByHandler(event)), tap(e => {
if (!e.isTouchEvent()) {
e.pauseEvent();
}
if (document.activeElement) {
document.activeElement.blur();
}
// prevents rendering performance issues while dragging item with selection inside
utils.clearSelection();
}), switchMap((startEvent) => {
return this.mousemove.pipe(map(mm => new DraggableEvent(mm)), filter((moveEvent) => this.inRange(startEvent, moveEvent, 5)), map(() => startEvent), takeUntil(this.mouseup), take(1));
}));
}
createDragMoveObservable(dragStart) {
return dragStart.pipe(tap(event => {
this.addTouchActionNone(event.target);
}), switchMap(startEvent => {
return this.mousemove.pipe(skip(1), map(mm => new DraggableEvent(mm)), tap(event => {
event.pauseEvent();
startEvent.pauseEvent();
}), takeUntil(this.mouseup));
}), filter(val => !!val), tap((event) => {
if (this.config.scroll) {
this.startScroll(this.element, event);
}
}));
}
createDragStopObservable(dragStart) {
return dragStart.pipe(switchMap(() => {
return this.mouseup.pipe(take(1));
}), map(e => new DraggableEvent(e)), tap(e => {
if (e.target) {
this.removeTouchActionNone(e.target);
}
this.autoScrollingInterval.forEach(raf => this.cancelAnimationFrame(raf));
}));
}
startScroll(item, event) {
const scrollContainer = this.getScrollContainer(item);
this.autoScrollingInterval.forEach(raf => this.cancelAnimationFrame(raf));
if (scrollContainer) {
this.startScrollForContainer(event, scrollContainer);
}
else {
this.startScrollForWindow(event);
}
}
startScrollForContainer(event, scrollContainer) {
if (!this.config.scrollDirection || this.config.scrollDirection === 'vertical') {
this.startScrollVerticallyForContainer(event, scrollContainer);
}
if (!this.config.scrollDirection || this.config.scrollDirection === 'horizontal') {
this.startScrollHorizontallyForContainer(event, scrollContainer);
}
}
startScrollVerticallyForContainer(event, scrollContainer) {
if (event.pageY - this.getOffset(scrollContainer).top < this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, -Draggable.SCROLL_SPEED, 'scrollTop');
}
else if (this.getOffset(scrollContainer).top +
scrollContainer.getBoundingClientRect().height -
event.pageY <
this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, Draggable.SCROLL_SPEED, 'scrollTop');
}
}
startScrollHorizontallyForContainer(event, scrollContainer) {
if (event.pageX - scrollContainer.getBoundingClientRect().left < this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, -Draggable.SCROLL_SPEED, 'scrollLeft');
}
else if (this.getOffset(scrollContainer).left +
scrollContainer.getBoundingClientRect().width -
event.pageX <
this.config.scrollEdge) {
this.startAutoScrolling(scrollContainer, Draggable.SCROLL_SPEED, 'scrollLeft');
}
}
startScrollForWindow(event) {
if (!this.config.scrollDirection || this.config.scrollDirection === 'vertical') {
this.startScrollVerticallyForWindow(event);
}
if (!this.config.scrollDirection || this.config.scrollDirection === 'horizontal') {
this.startScrollHorizontallyForWindow(event);
}
}
startScrollVerticallyForWindow(event) {
const scrollingElement = document.scrollingElement || document.documentElement || document.body;
// NOTE: Using `window.pageYOffset` here because IE doesn't have `window.scrollY`.
if (event.pageY - window.pageYOffset < this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, -Draggable.SCROLL_SPEED, 'scrollTop');
}
else if (window.innerHeight - (event.pageY - window.pageYOffset) <
this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, Draggable.SCROLL_SPEED, 'scrollTop');
}
}
startScrollHorizontallyForWindow(event) {
const scrollingElement = document.scrollingElement || document.documentElement || document.body;
// NOTE: Using `window.pageXOffset` here because IE doesn't have `window.scrollX`.
if (event.pageX - window.pageXOffset < this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, -Draggable.SCROLL_SPEED, 'scrollLeft');
}
else if (window.innerWidth - (event.pageX - window.pageXOffset) <
this.config.scrollEdge) {
this.startAutoScrolling(scrollingElement, Draggable.SCROLL_SPEED, 'scrollLeft');
}
}
getScrollContainer(node) {
const nodeOuterHeight = utils.getElementOuterHeight(node);
if (node.scrollHeight > Math.ceil(nodeOuterHeight)) {
return node;
}
if (!new RegExp('(body|html)', 'i').test(node.parentNode.tagName)) {
return this.getScrollContainer(node.parentNode);
}
return null;
}
startAutoScrolling(node, amount, direction) {
this.autoScrollingInterval.push(this.requestAnimationFrame(function () {
this.startAutoScrolling(node, amount, direction);
}.bind(this)));
return (node[direction] += amount * 0.25);
}
getOffset(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + this.getScroll('scrollLeft', 'pageXOffset'),
top: rect.top + this.getScroll('scrollTop', 'pageYOffset')
};
}
getScroll(scrollProp, offsetProp) {
if (typeof window[offsetProp] !== 'undefined') {
return window[offsetProp];
}
if (document.documentElement.clientHeight) {
return document.documentElement[scrollProp];
}
return document.body[scrollProp];
}
isDragingByHandler(event) {
if (!this.isValidDragHandler(event.target)) {
return false;
}
return (!this.config.handlerClass ||
(this.config.handlerClass &&
this.hasElementWithClass(this.config.handlerClass, event.target)));
}
isValidDragHandler(targetEl) {
return ['input', 'textarea'].indexOf(targetEl.tagName.toLowerCase()) === -1;
}
inRange(startEvent, moveEvent, range) {
return (Math.abs(moveEvent.clientX - startEvent.clientX) > range ||
Math.abs(moveEvent.clientY - startEvent.clientY) > range);
}
hasElementWithClass(className, target) {
while (target !== this.element) {
if (target.classList.contains(className)) {
return true;
}
target = target.parentElement;
}
return false;
}
pauseEvent(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (e.preventDefault) {
e.preventDefault();
}
e.cancelBubble = true;
e.returnValue = false;
}
fixProblemWithDnDForIE(element) {
if (this.isTouchDevice() && this.isIEorEdge() && element.style) {
element.style['touch-action'] = 'none';
}
}
removeTouchActionNone(element) {
if (!element.style) {
return;
}
element.style['touch-action'] = '';
}
addTouchActionNone(element) {
if (!element.style) {
return;
}
element.style['touch-action'] = 'none';
}
isTouchDevice() {
return ('ontouchstart' in window || navigator.maxTouchPoints // works on most browsers
); // works on IE10/11 and Surface
}
isIEorEdge() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
const trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
const rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
const edge = ua.indexOf('Edge/');
if (edge > 0) {
// Edge (IE 12+) => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
}
}
Draggable.SCROLL_SPEED = 20;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhcjJncmlkc3RlcnYzL3NyYy9saWIvdXRpbHMvZHJhZ2dhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBYyxTQUFTLEVBQUUsS0FBSyxFQUFRLE1BQU0sTUFBTSxDQUFDO0FBQzFELE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0YsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFaEMsTUFBTSxPQUFPLFNBQVM7SUE2QmxCLFlBQVksT0FBZ0IsRUFBRSxNQUFNLEdBQUcsRUFBRTtRQW5CakMsY0FBUyxHQUEyQixLQUFLLENBQzdDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLEVBQ2hDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQ3ZELENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDUixZQUFPLEdBQTJCLEtBQUssQ0FDM0MsU0FBUyxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsRUFDOUIsU0FBUyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsRUFDL0IsU0FBUyxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FDckMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUVSLFdBQU0sR0FBRztZQUNiLFlBQVksRUFBRSxJQUFJO1lBQ2xCLE1BQU0sRUFBRSxJQUFJO1lBQ1osVUFBVSxFQUFFLEVBQUU7WUFDZCxlQUFlLEVBQUUsSUFBSTtTQUN4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N0IsT0FBTyxRQUFRLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDbEU7UUFFRCxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLElBQUksSUFBSSxHQUFHLENBQUMsRUFBRTtZQUNWLHlDQUF5QztZQUN6QyxPQUFPLFFBQVEsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUN0RTtRQUVELGdCQUFnQjtRQUNoQixPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDOztBQTNWTSxzQkFBWSxHQUFHLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUsIGZyb21FdmVudCwgbWVyZ2UsIHBpcGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgc2hhcmUsIG1hcCwgZmlsdGVyLCB0YXAsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB0YWtlLCBza2lwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgRHJhZ2dhYmxlRXZlbnQgfSBmcm9tICcuL0RyYWdnYWJsZUV2ZW50JztcclxuaW1wb3J0IHsgdXRpbHMgfSBmcm9tICcuL3V0aWxzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBEcmFnZ2FibGUge1xyXG4gICAgc3RhdGljIFNDUk9MTF9TUEVFRCA9IDIwO1xyXG4gICAgZWxlbWVudDogRWxlbWVudDtcclxuXHJcbiAgICBkcmFnU3RhcnQ6IE9ic2VydmFibGU8RHJhZ2dhYmxlRXZlbnQ+O1xyXG4gICAgZHJhZ01vdmU6IE9ic2VydmFibGU8RHJhZ2dhYmxlRXZlbnQ+O1xyXG4gICAgZHJhZ1N0b3A6IE9ic2VydmFibGU8RHJhZ2dhYmxlRXZlbnQ+O1xyXG4gICAgLy8gQSBzaW1wbGUgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIHBvbHlmaWxsXHJcbiAgICBwcml2YXRlIHJlcXVlc3RBbmltYXRpb25GcmFtZTogRnVuY3Rpb247XHJcbiAgICBwcml2YXRlIGNhbmNlbEFuaW1hdGlvbkZyYW1lOiBGdW5jdGlvbjtcclxuICAgIHByaXZhdGUgbW91c2Vtb3ZlOiBPYnNlcnZhYmxlPHt9IHwgRXZlbnQ+ID0gbWVyZ2UoXHJcbiAgICAgICAgZnJvbUV2ZW50KGRvY3VtZW50LCAnbW91c2Vtb3ZlJyksXHJcbiAgICAgICAgZnJvbUV2ZW50KGRvY3VtZW50LCAndG91Y2htb3ZlJywgeyBwYXNzaXZlOiBmYWxzZSB9KVxyXG4gICAgKS5waXBlKHNoYXJlKCkpO1xyXG4gICAgcHJpdmF0ZSBtb3VzZXVwOiBPYnNlcnZhYmxlPHt9IHwgRXZlbnQ+ID0gbWVyZ2UoXHJcbiAgICAgICAgZnJvbUV2ZW50KGRvY3VtZW50LCAnbW91c2V1cCcpLFxyXG4gICAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ3RvdWNoZW5kJyksXHJcbiAgICAgICAgZnJvbUV2ZW50KGRvY3VtZW50LCAndG91Y2hjYW5jZWwnKVxyXG4gICAgKS5waXBlKHNoYXJlKCkpO1xyXG4gICAgcHJpdmF0ZSBtb3VzZWRvd246IE9ic2VydmFibGU8e30gfCBFdmVudD47XHJcbiAgICBwcml2YXRlIGNvbmZpZyA9IHtcclxuICAgICAgICBoYW5kbGVyQ2xhc3M6IG51bGwsXHJcbiAgICAgICAgc2Nyb2xsOiB0cnVlLFxyXG4gICAgICAgIHNjcm9sbEVkZ2U6IDM2LFxyXG4gICAgICAgIHNjcm9sbERpcmVjdGlvbjogbnVsbFxyXG4gICAgfTtcclxuICAgIC8vIHJlZmVyZW5jZSB0byBhdXRvIHNjcm9sbGluZyBsaXN0ZW5lcnNcclxuICAgIHByaXZhdGUgYXV0b1Njcm9sbGluZ0ludGVydmFsID0gW107XHJcblxyXG4gICAgY29uc3RydWN0b3IoZWxlbWVudDogRWxlbWVudCwgY29uZmlnID0ge30pIHtcclxuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgICAgIHRoaXMubW91c2Vkb3duID0gbWVyZ2UoXHJcbiAgICAgICAgICAgIGZyb21FdmVudChlbGVtZW50LCAnbW91c2Vkb3duJyksXHJcbiAgICAgICAgICAgIGZyb21FdmVudChlbGVtZW50LCAndG91Y2hzdGFydCcpXHJcbiAgICAgICAgKS5waXBlKHNoYXJlKCkpO1xyXG5cclxuICAgICAgICB0aGlzLmNvbmZpZyA9IHsgLi4udGhpcy5jb25maWcsIC4uLmNvbmZpZyB9O1xyXG5cclxuICAgICAgICB0aGlzLmRyYWdTdGFydCA9IHRoaXMuY3JlYXRlRHJhZ1N0YXJ0T2JzZXJ2YWJsZSgpLnBpcGUoc2hhcmUoKSk7XHJcbiAgICAgICAgdGhpcy5kcmFnTW92ZSA9IHRoaXMuY3JlYXRlRHJhZ01vdmVPYnNlcnZhYmxlKHRoaXMuZHJhZ1N0YXJ0KTtcclxuICAgICAgICB0aGlzLmRyYWdTdG9wID0gdGhpcy5jcmVhdGVEcmFnU3RvcE9ic2VydmFibGUodGhpcy5kcmFnU3RhcnQpO1xyXG5cclxuICAgICAgICB0aGlzLmZpeFByb2JsZW1XaXRoRG5ERm9ySUUoZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lID1cclxuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCAoY2FsbGJhY2sgPT4gc2V0VGltZW91dChjYWxsYmFjaywgMTAwMCAvIDYwKSk7XHJcbiAgICAgICAgdGhpcy5jYW5jZWxBbmltYXRpb25GcmFtZSA9IHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSB8fCAoY2FmSUQgPT4gY2xlYXJUaW1lb3V0KGNhZklEKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVEcmFnU3RhcnRPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8RHJhZ2dhYmxlRXZlbnQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tb3VzZWRvd24ucGlwZShcclxuICAgICAgICAgICAgbWFwKG1kID0+IG5ldyBEcmFnZ2FibGVFdmVudChtZCkpLFxyXG4gICAgICAgICAgICBmaWx0ZXIoKGV2ZW50OiBEcmFnZ2FibGVFdmVudCkgPT4gdGhpcy5pc0RyYWdpbmdCeUhhbmRsZXIoZXZlbnQpKSxcclxuICAgICAgICAgICAgdGFwKGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFlLmlzVG91Y2hFdmVudCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wYXVzZUV2ZW50KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICg8YW55PmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpLmJsdXIoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHByZXZlbnRzIHJlbmRlcmluZyBwZXJmb3JtYW5jZSBpc3N1ZXMgd2hpbGUgZHJhZ2dpbmcgaXRlbSB3aXRoIHNlbGVjdGlvbiBpbnNpZGVcclxuICAgICAgICAgICAgICAgIHV0aWxzLmNsZWFyU2VsZWN0aW9uKCk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHN0YXJ0RXZlbnQ6IERyYWdnYWJsZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tb3VzZW1vdmUucGlwZShcclxuICAgICAgICAgICAgICAgICAgICBtYXAobW0gPT4gbmV3IERyYWdnYWJsZUV2ZW50KG1tKSksXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKChtb3ZlRXZlbnQ6IERyYWdnYWJsZUV2ZW50KSA9PiB0aGlzLmluUmFuZ2Uoc3RhcnRFdmVudCwgbW92ZUV2ZW50LCA1KSksXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKCgpID0+IHN0YXJ0RXZlbnQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLm1vdXNldXApLFxyXG4gICAgICAgICAgICAgICAgICAgIHRha2UoMSlcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNyZWF0ZURyYWdNb3ZlT2JzZXJ2YWJsZShcclxuICAgICAgICBkcmFnU3RhcnQ6IE9ic2VydmFibGU8RHJhZ2dhYmxlRXZlbnQ+XHJcbiAgICApOiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50PiB7XHJcbiAgICAgICAgcmV0dXJuIGRyYWdTdGFydC5waXBlKFxyXG4gICAgICAgICAgICB0YXAoZXZlbnQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRUb3VjaEFjdGlvbk5vbmUoZXZlbnQudGFyZ2V0KTtcclxuICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgIHN3aXRjaE1hcChzdGFydEV2ZW50ID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1vdXNlbW92ZS5waXBlKFxyXG4gICAgICAgICAgICAgICAgICAgIHNraXAoMSksXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKG1tID0+IG5ldyBEcmFnZ2FibGVFdmVudChtbSkpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRhcChldmVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnBhdXNlRXZlbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRFdmVudC5wYXVzZUV2ZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMubW91c2V1cClcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICBmaWx0ZXIodmFsID0+ICEhdmFsKSxcclxuICAgICAgICAgICAgdGFwKChldmVudDogRHJhZ2dhYmxlRXZlbnQpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5zY3JvbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0U2Nyb2xsKHRoaXMuZWxlbWVudCwgZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjcmVhdGVEcmFnU3RvcE9ic2VydmFibGUoZHJhZ1N0YXJ0OiBPYnNlcnZhYmxlPERyYWdnYWJsZUV2ZW50Pik6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICAgICAgcmV0dXJuIGRyYWdTdGFydC5waXBlKFxyXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW91c2V1cC5waXBlKHRha2UoMSkpO1xyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICAgICAgbWFwKGUgPT4gbmV3IERyYWdnYWJsZUV2ZW50KGUpKSxcclxuICAgICAgICAgICAgdGFwKGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVUb3VjaEFjdGlvbk5vbmUoZS50YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hdXRvU2Nyb2xsaW5nSW50ZXJ2YWwuZm9yRWFjaChyYWYgPT4gdGhpcy5jYW5jZWxBbmltYXRpb25GcmFtZShyYWYpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTY3JvbGwoaXRlbTogRWxlbWVudCwgZXZlbnQ6IERyYWdnYWJsZUV2ZW50KSB7XHJcbiAgICAgICAgY29uc3Qgc2Nyb2xsQ29udGFpbmVyID0gdGhpcy5nZXRTY3JvbGxDb250YWluZXIoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5hdXRvU2Nyb2xsaW5nSW50ZXJ2YWwuZm9yRWFjaChyYWYgPT4gdGhpcy5jYW5jZWxBbmltYXRpb25GcmFtZShyYWYpKTtcclxuXHJcbiAgICAgICAgaWYgKHNjcm9sbENvbnRhaW5lcikge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0U2Nyb2xsRm9yQ29udGFpbmVyKGV2ZW50LCBzY3JvbGxDb250YWluZXIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRTY3JvbGxGb3JXaW5kb3coZXZlbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsRm9yQ29udGFpbmVyKGV2ZW50OiBEcmFnZ2FibGVFdmVudCwgc2Nyb2xsQ29udGFpbmVyOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuc2Nyb2xsRGlyZWN0aW9uIHx8IHRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJykge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0U2Nyb2xsVmVydGljYWxseUZvckNvbnRhaW5lcihldmVudCwgc2Nyb2xsQ29udGFpbmVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuc2Nyb2xsRGlyZWN0aW9uIHx8IHRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRTY3JvbGxIb3Jpem9udGFsbHlGb3JDb250YWluZXIoZXZlbnQsIHNjcm9sbENvbnRhaW5lcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTY3JvbGxWZXJ0aWNhbGx5Rm9yQ29udGFpbmVyKFxyXG4gICAgICAgIGV2ZW50OiBEcmFnZ2FibGVFdmVudCxcclxuICAgICAgICBzY3JvbGxDb250YWluZXI6IEhUTUxFbGVtZW50XHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBpZiAoZXZlbnQucGFnZVkgLSB0aGlzLmdldE9mZnNldChzY3JvbGxDb250YWluZXIpLnRvcCA8IHRoaXMuY29uZmlnLnNjcm9sbEVkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsQ29udGFpbmVyLCAtRHJhZ2dhYmxlLlNDUk9MTF9TUEVFRCwgJ3Njcm9sbFRvcCcpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0T2Zmc2V0KHNjcm9sbENvbnRhaW5lcikudG9wICtcclxuICAgICAgICAgICAgICAgIHNjcm9sbENvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgLVxyXG4gICAgICAgICAgICAgICAgZXZlbnQucGFnZVkgPFxyXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5zY3JvbGxFZGdlXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsaW5nKHNjcm9sbENvbnRhaW5lciwgRHJhZ2dhYmxlLlNDUk9MTF9TUEVFRCwgJ3Njcm9sbFRvcCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN0YXJ0U2Nyb2xsSG9yaXpvbnRhbGx5Rm9yQ29udGFpbmVyKFxyXG4gICAgICAgIGV2ZW50OiBEcmFnZ2FibGVFdmVudCxcclxuICAgICAgICBzY3JvbGxDb250YWluZXI6IEhUTUxFbGVtZW50XHJcbiAgICApOiB2b2lkIHtcclxuICAgICAgICBpZiAoZXZlbnQucGFnZVggLSBzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCA8IHRoaXMuY29uZmlnLnNjcm9sbEVkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsQ29udGFpbmVyLCAtRHJhZ2dhYmxlLlNDUk9MTF9TUEVFRCwgJ3Njcm9sbExlZnQnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICB0aGlzLmdldE9mZnNldChzY3JvbGxDb250YWluZXIpLmxlZnQgK1xyXG4gICAgICAgICAgICAgICAgc2Nyb2xsQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIC1cclxuICAgICAgICAgICAgICAgIGV2ZW50LnBhZ2VYIDxcclxuICAgICAgICAgICAgdGhpcy5jb25maWcuc2Nyb2xsRWRnZVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhzY3JvbGxDb250YWluZXIsIERyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxMZWZ0Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTY3JvbGxGb3JXaW5kb3coZXZlbnQpIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnNjcm9sbERpcmVjdGlvbiB8fCB0aGlzLmNvbmZpZy5zY3JvbGxEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNjcm9sbFZlcnRpY2FsbHlGb3JXaW5kb3coZXZlbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5zY3JvbGxEaXJlY3Rpb24gfHwgdGhpcy5jb25maWcuc2Nyb2xsRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNjcm9sbEhvcml6b250YWxseUZvcldpbmRvdyhldmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRTY3JvbGxWZXJ0aWNhbGx5Rm9yV2luZG93KGV2ZW50OiBEcmFnZ2FibGVFdmVudCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbGluZ0VsZW1lbnQgPVxyXG4gICAgICAgICAgICBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5O1xyXG5cclxuICAgICAgICAvLyBOT1RFOiBVc2luZyBgd2luZG93LnBhZ2VZT2Zmc2V0YCBoZXJlIGJlY2F1c2UgSUUgZG9lc24ndCBoYXZlIGB3aW5kb3cuc2Nyb2xsWWAuXHJcbiAgICAgICAgaWYgKGV2ZW50LnBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0IDwgdGhpcy5jb25maWcuc2Nyb2xsRWRnZSkge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhzY3JvbGxpbmdFbGVtZW50LCAtRHJhZ2dhYmxlLlNDUk9MTF9TUEVFRCwgJ3Njcm9sbFRvcCcpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgIHdpbmRvdy5pbm5lckhlaWdodCAtIChldmVudC5wYWdlWSAtIHdpbmRvdy5wYWdlWU9mZnNldCkgPFxyXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5zY3JvbGxFZGdlXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhcnRBdXRvU2Nyb2xsaW5nKHNjcm9sbGluZ0VsZW1lbnQsIERyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxUb3AnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGFydFNjcm9sbEhvcml6b250YWxseUZvcldpbmRvdyhldmVudDogRHJhZ2dhYmxlRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBzY3JvbGxpbmdFbGVtZW50ID1cclxuICAgICAgICAgICAgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keTtcclxuXHJcbiAgICAgICAgLy8gTk9URTogVXNpbmcgYHdpbmRvdy5wYWdlWE9mZnNldGAgaGVyZSBiZWNhdXNlIElFIGRvZXNuJ3QgaGF2ZSBgd2luZG93LnNjcm9sbFhgLlxyXG4gICAgICAgIGlmIChldmVudC5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCA8IHRoaXMuY29uZmlnLnNjcm9sbEVkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9TY3JvbGxpbmcoc2Nyb2xsaW5nRWxlbWVudCwgLURyYWdnYWJsZS5TQ1JPTExfU1BFRUQsICdzY3JvbGxMZWZ0Jyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgd2luZG93LmlubmVyV2lkdGggLSAoZXZlbnQucGFnZVggLSB3aW5kb3cucGFnZVhPZmZzZXQpIDxcclxuICAgICAgICAgICAgdGhpcy5jb25maWcuc2Nyb2xsRWRnZVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhzY3JvbGxpbmdFbGVtZW50LCBEcmFnZ2FibGUuU0NST0xMX1NQRUVELCAnc2Nyb2xsTGVmdCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFNjcm9sbENvbnRhaW5lcihub2RlKTogSFRNTEVsZW1lbnQge1xyXG4gICAgICAgIGNvbnN0IG5vZGVPdXRlckhlaWdodCA9IHV0aWxzLmdldEVsZW1lbnRPdXRlckhlaWdodChub2RlKTtcclxuXHJcbiAgICAgICAgaWYgKG5vZGUuc2Nyb2xsSGVpZ2h0ID4gTWF0aC5jZWlsKG5vZGVPdXRlckhlaWdodCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIW5ldyBSZWdFeHAoJyhib2R5fGh0bWwpJywgJ2knKS50ZXN0KG5vZGUucGFyZW50Tm9kZS50YWdOYW1lKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxDb250YWluZXIobm9kZS5wYXJlbnROb2RlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhcnRBdXRvU2Nyb2xsaW5nKG5vZGUsIGFtb3VudCwgZGlyZWN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5hdXRvU2Nyb2xsaW5nSW50ZXJ2YWwucHVzaChcclxuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1Njcm9sbGluZyhub2RlLCBhbW91bnQsIGRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcylcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIHJldHVybiAobm9kZVtkaXJlY3Rpb25dICs9IGFtb3VudCAqIDAuMjUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0T2Zmc2V0KGVsKSB7XHJcbiAgICAgICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHRoaXMuZ2V0U2Nyb2xsKCdzY3JvbGxMZWZ0JywgJ3BhZ2VYT2Zmc2V0JyksXHJcbiAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyB0aGlzLmdldFNjcm9sbCgnc2Nyb2xsVG9wJywgJ3BhZ2VZT2Zmc2V0JylcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0U2Nyb2xsKHNjcm9sbFByb3AsIG9mZnNldFByb3ApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvd1tvZmZzZXRQcm9wXSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvd1tvZmZzZXRQcm9wXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtzY3JvbGxQcm9wXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmJvZHlbc2Nyb2xsUHJvcF07XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpc0RyYWdpbmdCeUhhbmRsZXIoZXZlbnQ6IERyYWdnYWJsZUV2ZW50KTogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWREcmFnSGFuZGxlcihldmVudC50YXJnZXQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgICF0aGlzLmNvbmZpZy5oYW5kbGVyQ2xhc3MgfHxcclxuICAgICAgICAgICAgKHRoaXMuY29uZmlnLmhhbmRsZXJDbGFzcyAmJlxyXG4gICAgICAgICAgICAgICAgdGhpcy5oYXNFbGVtZW50V2l0aENsYXNzKHRoaXMuY29uZmlnLmhhbmRsZXJDbGFzcywgZXZlbnQudGFyZ2V0KSlcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNWYWxpZERyYWdIYW5kbGVyKHRhcmdldEVsOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gWydpbnB1dCcsICd0ZXh0YXJlYSddLmluZGV4T2YodGFyZ2V0RWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSA9PT0gLTE7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpblJhbmdlKHN0YXJ0RXZlbnQ6IERyYWdnYWJsZUV2ZW50LCBtb3ZlRXZlbnQ6IERyYWdnYWJsZUV2ZW50LCByYW5nZTogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgTWF0aC5hYnMobW92ZUV2ZW50LmNsaWVudFggLSBzdGFydEV2ZW50LmNsaWVudFgpID4gcmFuZ2UgfHxcclxuICAgICAgICAgICAgTWF0aC5hYnMobW92ZUV2ZW50LmNsaWVudFkgLSBzdGFydEV2ZW50LmNsaWVudFkpID4gcmFuZ2VcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFzRWxlbWVudFdpdGhDbGFzcyhjbGFzc05hbWU6IHN0cmluZywgdGFyZ2V0OiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICB3aGlsZSAodGFyZ2V0ICE9PSB0aGlzLmVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudEVsZW1lbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHBhdXNlRXZlbnQoZTogRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIHtcclxuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGUucHJldmVudERlZmF1bHQpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlLmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgICAgICAgZS5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZml4UHJvYmxlbVdpdGhEbkRGb3JJRShlbGVtZW50OiBFbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNUb3VjaERldmljZSgpICYmIHRoaXMuaXNJRW9yRWRnZSgpICYmICg8SFRNTEVsZW1lbnQ+ZWxlbWVudCkuc3R5bGUpIHtcclxuICAgICAgICAgICAgKDxIVE1MRWxlbWVudD5lbGVtZW50KS5zdHlsZVsndG91Y2gtYWN0aW9uJ10gPSAnbm9uZSc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVtb3ZlVG91Y2hBY3Rpb25Ob25lKGVsZW1lbnQ6IEVsZW1lbnQpIHtcclxuICAgICAgICBpZiAoISg8SFRNTEVsZW1lbnQ+ZWxlbWVudCkuc3R5bGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAoPEhUTUxFbGVtZW50PmVsZW1lbnQpLnN0eWxlWyd0b3VjaC1hY3Rpb24nXSA9ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYWRkVG91Y2hBY3Rpb25Ob25lKGVsZW1lbnQpIHtcclxuICAgICAgICBpZiAoISg8SFRNTEVsZW1lbnQ+ZWxlbWVudCkuc3R5bGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAoPEhUTUxFbGVtZW50PmVsZW1lbnQpLnN0eWxlWyd0b3VjaC1hY3Rpb24nXSA9ICdub25lJztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGlzVG91Y2hEZXZpY2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgJ29udG91Y2hzdGFydCcgaW4gd2luZG93IHx8IG5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyAvLyB3b3JrcyBvbiBtb3N0IGJyb3dzZXJzXHJcbiAgICAgICAgKTsgLy8gd29ya3Mgb24gSUUxMC8xMSBhbmQgU3VyZmFjZVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNJRW9yRWRnZSgpIHtcclxuICAgICAgICBjb25zdCB1YSA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50O1xyXG5cclxuICAgICAgICBjb25zdCBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTtcclxuICAgICAgICBpZiAobXNpZSA+IDApIHtcclxuICAgICAgICAgICAgLy8gSUUgMTAgb3Igb2xkZXIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcobXNpZSArIDUsIHVhLmluZGV4T2YoJy4nLCBtc2llKSksIDEwKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpO1xyXG4gICAgICAgIGlmICh0cmlkZW50ID4gMCkge1xyXG4gICAgICAgICAgICAvLyBJRSAxMSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgY29uc3QgcnYgPSB1YS5pbmRleE9mKCdydjonKTtcclxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhydiArIDMsIHVhLmluZGV4T2YoJy4nLCBydikpLCAxMCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBlZGdlID0gdWEuaW5kZXhPZignRWRnZS8nKTtcclxuICAgICAgICBpZiAoZWRnZSA+IDApIHtcclxuICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhlZGdlICsgNSwgdWEuaW5kZXhPZignLicsIGVkZ2UpKSwgMTApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gb3RoZXIgYnJvd3NlclxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxufVxyXG4iXX0=