UNPKG

@foblex/core

Version:

A core library providing a set of utilities and interfaces for various projects.

147 lines 23.2 kB
import { IMouseEvent, ITouchDownEvent, ITouchMoveEvent, ITouchUpEvent } from './pointer-events'; import { EventExtensions, PointExtensions } from '../types'; export const MOUSE_EVENT_IGNORE_TIME = 800; export class IDragAndDropBase { constructor(ngZone) { this.ngZone = ngZone; this.mouseListeners = EventExtensions.emptyListener(); this.touchListeners = EventExtensions.emptyListener(); this.startListeners = EventExtensions.emptyListener(); this.lastTouchEventTime = 0; this.isDragStarted = false; this.dragStartThreshold = 5; this.dragStartDelay = 0; this.dragStartTime = 0; this.dragStartPosition = PointExtensions.initialize(); this.moveHandler = this.checkDragSequenceToStart; this.onMouseDown = (event) => { const isSyntheticEvent = this.isSyntheticEvent(event); const isFakeEvent = isFakeMousedownFromScreenReader(event); const mouseEvent = new IMouseEvent(event); if (isSyntheticEvent || isFakeEvent || this.disabled) { return; } let result = this.onPointerDown(mouseEvent); if (result) { this.dragStartTime = Date.now(); this.dragStartPosition = mouseEvent.getPosition(); this.ngZone.runOutsideAngular(() => { this.element.addEventListener('mousemove', this.onMouseMove); this.element.addEventListener('mouseup', this.onMouseUp); }); this.mouseListeners = () => { this.element.removeEventListener('mousemove', this.onMouseMove); this.element.removeEventListener('mouseup', this.onMouseUp); }; } }; this.onTouchDown = (event) => { const isFakeEvent = isFakeTouchstartFromScreenReader(event); const touchEvent = new ITouchDownEvent(event); if (isFakeEvent || this.disabled) { return; } let result = this.onPointerDown(new ITouchDownEvent(event)); if (result) { this.dragStartTime = Date.now(); this.dragStartPosition = touchEvent.getPosition(); this.ngZone.runOutsideAngular(() => { this.element.addEventListener('touchmove', this.onTouchMove); this.element.addEventListener('touchend', this.onTouchUp); }); this.touchListeners = () => { this.element.removeEventListener('touchmove', this.onTouchMove); this.element.removeEventListener('touchend', this.onTouchUp); }; } }; this.onMouseMove = (event) => { this.moveHandler(new IMouseEvent(event)); }; this.onTouchMove = (event) => { this.moveHandler(new ITouchMoveEvent(event)); }; this.onMouseUp = (event) => { if (this.isDragStarted) { this.onPointerUp(new IMouseEvent(event)); } this.endDragSequence(); }; this.onTouchUp = (event) => { if (this.isDragStarted) { this.onPointerUp(new ITouchUpEvent(event)); } this.endDragSequence(); }; } isSyntheticEvent(event) { return !!this.lastTouchEventTime && (this.lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now()); } checkDragSequenceToStart(event) { const pointerPosition = event.getPosition(); if (!this.isDragStarted) { const distanceX = Math.abs(pointerPosition.x - this.dragStartPosition.x); const distanceY = Math.abs(pointerPosition.y - this.dragStartPosition.y); const isOverThreshold = distanceX + distanceY >= this.dragStartThreshold; if (isOverThreshold) { const isDelayElapsed = Date.now() >= this.dragStartTime + this.dragStartDelay; if (!isDelayElapsed) { this.endDragSequence(); return; } event.preventDefault(); this.prepareDragSequence(event); this.isDragStarted = true; this.moveHandler = this.onPointerMove; if (isTouchEvent(event.originalEvent)) { this.lastTouchEventTime = Date.now(); } } } } endDragSequence() { this.isDragStarted = false; this.moveHandler = this.checkDragSequenceToStart; this.mouseListeners(); this.mouseListeners = EventExtensions.emptyListener(); this.touchListeners(); this.touchListeners = EventExtensions.emptyListener(); } subscribe(elementToSubscribe) { if (this.element) { this.unsubscribe(); } this.element = elementToSubscribe; this.ngZone.runOutsideAngular(() => { this.element.addEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener()); this.element.addEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener()); }); this.startListeners = () => { this.element.removeEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener()); this.element.removeEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener()); }; } unsubscribe() { this.startListeners(); this.startListeners = EventExtensions.emptyListener(); this.touchListeners(); this.touchListeners = EventExtensions.emptyListener(); this.mouseListeners(); this.mouseListeners = EventExtensions.emptyListener(); } } function isTouchEvent(event) { return event.type[0] === 't'; } function isFakeMousedownFromScreenReader(event) { return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0); } function isFakeTouchstartFromScreenReader(event) { const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0]); return (!!touch && touch.identifier === -1 && (touch.radiusX == null || touch.radiusX === 1) && (touch.radiusY == null || touch.radiusY === 1)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaS1kcmFnLWFuZC1kcm9wLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9mLWNvcmUvc3JjL2RyYWctYW5kLWRyb3AvaS1kcmFnLWFuZC1kcm9wLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBaUIsZUFBZSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRyxPQUFPLEVBQUUsZUFBZSxFQUFVLGVBQWUsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUdwRSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsTUFBTSxPQUFnQixnQkFBZ0I7SUEyQnBDLFlBQ2MsTUFBNkI7UUFBN0IsV0FBTSxHQUFOLE1BQU0sQ0FBdUI7UUF4Qm5DLG1CQUFjLEdBQWEsZUFBZSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzNELG1CQUFjLEdBQWEsZUFBZSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRTNELG1CQUFjLEdBQWEsZUFBZSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBTzNELHVCQUFrQixHQUFXLENBQUMsQ0FBQztRQUVoQyxrQkFBYSxHQUFZLEtBQUssQ0FBQztRQUM5Qix1QkFBa0IsR0FBVyxDQUFDLENBQUM7UUFDL0IsbUJBQWMsR0FBVyxDQUFDLENBQUM7UUFFM0Isa0JBQWEsR0FBVyxDQUFDLENBQUM7UUFDMUIsc0JBQWlCLEdBQVcsZUFBZSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBSXpELGdCQUFXLEdBQWEsSUFBSSxDQUFDLHdCQUF3QixDQUFDO1FBT3RELGdCQUFXLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEQsTUFBTSxXQUFXLEdBQUcsK0JBQStCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFD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S0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzdFLENBQUM7QUFFRCxTQUFTLGdDQUFnQyxDQUFDLEtBQWlCO0lBQ3pELE1BQU0sS0FBSyxHQUNQLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFFLENBQUMsQ0FBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUUsQ0FBQyxDQUFFLENBQUMsQ0FBQztJQUNqRyxPQUFPLENBQ0gsQ0FBQyxDQUFDLEtBQUs7UUFDUCxLQUFLLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQztRQUN2QixDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksSUFBSSxJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssQ0FBQyxDQUFDO1FBQzlDLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FDakQsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJTW91c2VFdmVudCwgSVBvaW50ZXJFdmVudCwgSVRvdWNoRG93bkV2ZW50LCBJVG91Y2hNb3ZlRXZlbnQsIElUb3VjaFVwRXZlbnQgfSBmcm9tICcuL3BvaW50ZXItZXZlbnRzJztcbmltcG9ydCB7IEV2ZW50RXh0ZW5zaW9ucywgSVBvaW50LCBQb2ludEV4dGVuc2lvbnMgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBJQ2FuUnVuT3V0c2lkZUFuZ3VsYXIgfSBmcm9tICcuL2ktY2FuLXJ1bi1vdXRzaWRlLWFuZ3VsYXInO1xuXG5leHBvcnQgY29uc3QgTU9VU0VfRVZFTlRfSUdOT1JFX1RJTUUgPSA4MDA7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBJRHJhZ0FuZERyb3BCYXNlIHtcblxuICBwcml2YXRlIGVsZW1lbnQhOiBEb2N1bWVudDtcblxuICBwcml2YXRlIG1vdXNlTGlzdGVuZXJzOiBGdW5jdGlvbiA9IEV2ZW50RXh0ZW5zaW9ucy5lbXB0eUxpc3RlbmVyKCk7XG4gIHByaXZhdGUgdG91Y2hMaXN0ZW5lcnM6IEZ1bmN0aW9uID0gRXZlbnRFeHRlbnNpb25zLmVtcHR5TGlzdGVuZXIoKTtcblxuICBwcml2YXRlIHN0YXJ0TGlzdGVuZXJzOiBGdW5jdGlvbiA9IEV2ZW50RXh0ZW5zaW9ucy5lbXB0eUxpc3RlbmVyKCk7XG5cbiAgcHVibGljIGlzU3ludGhldGljRXZlbnQoZXZlbnQ6IE1vdXNlRXZlbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmxhc3RUb3VjaEV2ZW50VGltZSAmJlxuICAgICAgKHRoaXMubGFzdFRvdWNoRXZlbnRUaW1lICsgTU9VU0VfRVZFTlRfSUdOT1JFX1RJTUUgPiBEYXRlLm5vdygpKTtcbiAgfVxuXG4gIHByaXZhdGUgbGFzdFRvdWNoRXZlbnRUaW1lOiBudW1iZXIgPSAwO1xuXG4gIHB1YmxpYyBpc0RyYWdTdGFydGVkOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgZHJhZ1N0YXJ0VGhyZXNob2xkOiBudW1iZXIgPSA1O1xuICBwcml2YXRlIGRyYWdTdGFydERlbGF5OiBudW1iZXIgPSAwO1xuXG4gIHByaXZhdGUgZHJhZ1N0YXJ0VGltZTogbnVtYmVyID0gMDtcbiAgcHJpdmF0ZSBkcmFnU3RhcnRQb3NpdGlvbjogSVBvaW50ID0gUG9pbnRFeHRlbnNpb25zLmluaXRpYWxpemUoKTtcblxuICBwdWJsaWMgYWJzdHJhY3QgZGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBtb3ZlSGFuZGxlcjogRnVuY3Rpb24gPSB0aGlzLmNoZWNrRHJhZ1NlcXVlbmNlVG9TdGFydDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgICBwcm90ZWN0ZWQgbmdab25lOiBJQ2FuUnVuT3V0c2lkZUFuZ3VsYXJcbiAgKSB7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VEb3duID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgaXNTeW50aGV0aWNFdmVudCA9IHRoaXMuaXNTeW50aGV0aWNFdmVudChldmVudCk7XG4gICAgY29uc3QgaXNGYWtlRXZlbnQgPSBpc0Zha2VNb3VzZWRvd25Gcm9tU2NyZWVuUmVhZGVyKGV2ZW50KTtcbiAgICBjb25zdCBtb3VzZUV2ZW50ID0gbmV3IElNb3VzZUV2ZW50KGV2ZW50KTtcblxuICAgIGlmIChpc1N5bnRoZXRpY0V2ZW50IHx8IGlzRmFrZUV2ZW50IHx8IHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMub25Qb2ludGVyRG93bihtb3VzZUV2ZW50KTtcbiAgICBpZiAocmVzdWx0KSB7XG5cbiAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0aGlzLmRyYWdTdGFydFBvc2l0aW9uID0gbW91c2VFdmVudC5nZXRQb3NpdGlvbigpO1xuXG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm9uTW91c2VNb3ZlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5tb3VzZUxpc3RlbmVycyA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZVVwKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblRvdWNoRG93biA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGNvbnN0IGlzRmFrZUV2ZW50ID0gaXNGYWtlVG91Y2hzdGFydEZyb21TY3JlZW5SZWFkZXIoZXZlbnQgYXMgVG91Y2hFdmVudClcbiAgICBjb25zdCB0b3VjaEV2ZW50ID0gbmV3IElUb3VjaERvd25FdmVudChldmVudCk7XG5cbiAgICBpZiAoaXNGYWtlRXZlbnQgfHwgdGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5vblBvaW50ZXJEb3duKG5ldyBJVG91Y2hEb3duRXZlbnQoZXZlbnQpKTtcbiAgICBpZiAocmVzdWx0KSB7XG5cbiAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0aGlzLmRyYWdTdGFydFBvc2l0aW9uID0gdG91Y2hFdmVudC5nZXRQb3NpdGlvbigpO1xuXG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoVXApO1xuICAgICAgfSk7XG5cbiAgICAgIHRoaXMudG91Y2hMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoVXApO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgdGhpcy5tb3ZlSGFuZGxlcihuZXcgSU1vdXNlRXZlbnQoZXZlbnQpKTtcbiAgfVxuXG4gIHByaXZhdGUgb25Ub3VjaE1vdmUgPSAoZXZlbnQ6IFRvdWNoRXZlbnQpID0+IHtcbiAgICB0aGlzLm1vdmVIYW5kbGVyKG5ldyBJVG91Y2hNb3ZlRXZlbnQoZXZlbnQpKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tEcmFnU2VxdWVuY2VUb1N0YXJ0KGV2ZW50OiBJUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgcG9pbnRlclBvc2l0aW9uID0gZXZlbnQuZ2V0UG9zaXRpb24oKTtcblxuICAgIGlmICghdGhpcy5pc0RyYWdTdGFydGVkKSB7XG4gICAgICBjb25zdCBkaXN0YW5jZVggPSBNYXRoLmFicyhwb2ludGVyUG9zaXRpb24ueCAtIHRoaXMuZHJhZ1N0YXJ0UG9zaXRpb24ueCk7XG4gICAgICBjb25zdCBkaXN0YW5jZVkgPSBNYXRoLmFicyhwb2ludGVyUG9zaXRpb24ueSAtIHRoaXMuZHJhZ1N0YXJ0UG9zaXRpb24ueSk7XG4gICAgICBjb25zdCBpc092ZXJUaHJlc2hvbGQgPSBkaXN0YW5jZVggKyBkaXN0YW5jZVkgPj0gdGhpcy5kcmFnU3RhcnRUaHJlc2hvbGQ7XG5cbiAgICAgIGlmIChpc092ZXJUaHJlc2hvbGQpIHtcbiAgICAgICAgY29uc3QgaXNEZWxheUVsYXBzZWQgPSBEYXRlLm5vdygpID49IHRoaXMuZHJhZ1N0YXJ0VGltZSArIHRoaXMuZHJhZ1N0YXJ0RGVsYXk7XG5cbiAgICAgICAgaWYgKCFpc0RlbGF5RWxhcHNlZCkge1xuICAgICAgICAgIHRoaXMuZW5kRHJhZ1NlcXVlbmNlKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5wcmVwYXJlRHJhZ1NlcXVlbmNlKGV2ZW50KTtcbiAgICAgICAgdGhpcy5pc0RyYWdTdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5tb3ZlSGFuZGxlciA9IHRoaXMub25Qb2ludGVyTW92ZTtcbiAgICAgICAgaWYgKGlzVG91Y2hFdmVudChldmVudC5vcmlnaW5hbEV2ZW50KSkge1xuICAgICAgICAgIHRoaXMubGFzdFRvdWNoRXZlbnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwcmVwYXJlRHJhZ1NlcXVlbmNlKGV2ZW50OiBJUG9pbnRlckV2ZW50KTogdm9pZDtcblxuICBwcml2YXRlIG9uTW91c2VVcCA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgIGlmICh0aGlzLmlzRHJhZ1N0YXJ0ZWQpIHtcbiAgICAgIHRoaXMub25Qb2ludGVyVXAobmV3IElNb3VzZUV2ZW50KGV2ZW50KSk7XG4gICAgfVxuICAgIHRoaXMuZW5kRHJhZ1NlcXVlbmNlKCk7XG4gIH1cblxuICBwcml2YXRlIG9uVG91Y2hVcCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmICh0aGlzLmlzRHJhZ1N0YXJ0ZWQpIHtcbiAgICAgIHRoaXMub25Qb2ludGVyVXAobmV3IElUb3VjaFVwRXZlbnQoZXZlbnQpKTtcbiAgICB9XG4gICAgdGhpcy5lbmREcmFnU2VxdWVuY2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5kRHJhZ1NlcXVlbmNlKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEcmFnU3RhcnRlZCA9IGZhbHNlO1xuICAgIHRoaXMubW92ZUhhbmRsZXIgPSB0aGlzLmNoZWNrRHJhZ1NlcXVlbmNlVG9TdGFydDtcbiAgICB0aGlzLm1vdXNlTGlzdGVuZXJzKCk7XG4gICAgdGhpcy5tb3VzZUxpc3RlbmVycyA9IEV2ZW50RXh0ZW5zaW9ucy5lbXB0eUxpc3RlbmVyKCk7XG4gICAgdGhpcy50b3VjaExpc3RlbmVycygpO1xuICAgIHRoaXMudG91Y2hMaXN0ZW5lcnMgPSBFdmVudEV4dGVuc2lvbnMuZW1wdHlMaXN0ZW5lcigpO1xuICB9XG5cbiAgcHVibGljIGFic3RyYWN0IG9uUG9pbnRlckRvd24oZXZlbnQ6IElQb2ludGVyRXZlbnQpOiBib29sZWFuO1xuXG4gIHB1YmxpYyBhYnN0cmFjdCBvblBvaW50ZXJNb3ZlKGV2ZW50OiBJUG9pbnRlckV2ZW50KTogdm9pZDtcblxuICBwdWJsaWMgYWJzdHJhY3Qgb25Qb2ludGVyVXAoZXZlbnQ6IElQb2ludGVyRXZlbnQpOiB2b2lkO1xuXG4gIHB1YmxpYyBzdWJzY3JpYmUoZWxlbWVudFRvU3Vic2NyaWJlOiBEb2N1bWVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVsZW1lbnQpIHtcbiAgICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudFRvU3Vic2NyaWJlO1xuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMub25Nb3VzZURvd24sIEV2ZW50RXh0ZW5zaW9ucy5hY3RpdmVMaXN0ZW5lcigpKTtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoRG93biwgRXZlbnRFeHRlbnNpb25zLnBhc3NpdmVMaXN0ZW5lcigpKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhcnRMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93biwgRXZlbnRFeHRlbnNpb25zLmFjdGl2ZUxpc3RlbmVyKCkpO1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLm9uVG91Y2hEb3duLCBFdmVudEV4dGVuc2lvbnMucGFzc2l2ZUxpc3RlbmVyKCkpO1xuICAgIH07XG4gIH1cblxuICBwdWJsaWMgdW5zdWJzY3JpYmUoKTogdm9pZCB7XG5cbiAgICB0aGlzLnN0YXJ0TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5zdGFydExpc3RlbmVycyA9IEV2ZW50RXh0ZW5zaW9ucy5lbXB0eUxpc3RlbmVyKCk7XG4gICAgdGhpcy50b3VjaExpc3RlbmVycygpO1xuICAgIHRoaXMudG91Y2hMaXN0ZW5lcnMgPSBFdmVudEV4dGVuc2lvbnMuZW1wdHlMaXN0ZW5lcigpO1xuICAgIHRoaXMubW91c2VMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLm1vdXNlTGlzdGVuZXJzID0gRXZlbnRFeHRlbnNpb25zLmVtcHR5TGlzdGVuZXIoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1RvdWNoRXZlbnQoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogZXZlbnQgaXMgVG91Y2hFdmVudCB7XG4gIHJldHVybiBldmVudC50eXBlWyAwIF0gPT09ICd0Jztcbn1cblxuZnVuY3Rpb24gaXNGYWtlTW91c2Vkb3duRnJvbVNjcmVlblJlYWRlcihldmVudDogTW91c2VFdmVudCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZXZlbnQuYnV0dG9ucyA9PT0gMCB8fCAoZXZlbnQub2Zmc2V0WCA9PT0gMCAmJiBldmVudC5vZmZzZXRZID09PSAwKTtcbn1cblxuZnVuY3Rpb24gaXNGYWtlVG91Y2hzdGFydEZyb21TY3JlZW5SZWFkZXIoZXZlbnQ6IFRvdWNoRXZlbnQpOiBib29sZWFuIHtcbiAgY29uc3QgdG91Y2g6IFRvdWNoIHwgdW5kZWZpbmVkID1cbiAgICAgIChldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXNbIDAgXSkgfHwgKGV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzWyAwIF0pO1xuICByZXR1cm4gKFxuICAgICAgISF0b3VjaCAmJlxuICAgICAgdG91Y2guaWRlbnRpZmllciA9PT0gLTEgJiZcbiAgICAgICh0b3VjaC5yYWRpdXNYID09IG51bGwgfHwgdG91Y2gucmFkaXVzWCA9PT0gMSkgJiZcbiAgICAgICh0b3VjaC5yYWRpdXNZID09IG51bGwgfHwgdG91Y2gucmFkaXVzWSA9PT0gMSlcbiAgKTtcbn1cbiJdfQ==