UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

576 lines 58 kB
/** * @fileoverview added by tsickle * Generated from: directives/drop-scroll-enhance.directive.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { DropScrollEnhanceTimingFunctionGroup, DropScrollOrientation } from './drop-scroll-enhance.type'; import { Directive, ElementRef, Input, NgZone } from '@angular/core'; import { fromEvent, Subscription, merge as mergeStatic } from 'rxjs'; import { throttleTime, tap } from 'rxjs/operators'; import { DragDropService } from '../services/drag-drop.service'; var DropScrollEnhancedDirective = /** @class */ (function () { function DropScrollEnhancedDirective(el, zone, dragDropService) { this.el = el; this.zone = zone; this.dragDropService = dragDropService; this.minSpeed = 50; this.maxSpeed = 1000; this.responseEdgeWidth = '100px'; this.speedFn = DropScrollEnhanceTimingFunctionGroup.default; this.direction = 'v'; this.subscription = new Subscription(); } /** * @return {?} */ DropScrollEnhancedDirective.prototype.ngAfterViewInit = /** * @return {?} */ function () { var _this = this; // 设置父元素 this.el.nativeElement.parentNode.style.position = 'relative'; this.el.nativeElement.parentNode.style.display = 'block'; // 创建后退前进区域和对应的滚动函数 this.forwardScrollArea = this.createScrollArea(this.direction, DropScrollOrientation.forward); this.backwardScrollArea = this.createScrollArea(this.direction, DropScrollOrientation.backward); this.forwardScrollFn = this.createScrollFn(this.direction, DropScrollOrientation.forward, this.speedFn); this.backwardScrollFn = this.createScrollFn(this.direction, DropScrollOrientation.backward, this.speedFn); this.zone.runOutsideAngular((/** * @return {?} */ function () { // 拖拽到其上触发滚动 _this.subscription.add(fromEvent(_this.forwardScrollArea, 'dragover') .pipe(tap((/** * @param {?} event * @return {?} */ function (event) { event.preventDefault(); event.stopPropagation(); })), throttleTime(100, undefined, { leading: true, trailing: true })).subscribe((/** * @param {?} event * @return {?} */ function (event) { return _this.forwardScrollFn(event); }))); _this.subscription.add(fromEvent(_this.backwardScrollArea, 'dragover') .pipe(tap((/** * @param {?} event * @return {?} */ function (event) { event.preventDefault(); event.stopPropagation(); })), throttleTime(100, undefined, { leading: true, trailing: true })) .subscribe((/** * @param {?} event * @return {?} */ function (event) { return _this.backwardScrollFn(event); }))); // 拖拽离开清除参数 _this.subscription.add(mergeStatic(fromEvent(_this.forwardScrollArea, 'dragleave', { passive: true }), fromEvent(_this.backwardScrollArea, 'dragleave', { passive: true })).subscribe((/** * @param {?} event * @return {?} */ function (event) { return _this.cleanLastScrollTime(); }))); // 滚动过程计算区域有效性,滚动条贴到边缘的时候无效,无效的时候设置鼠标事件可用为none _this.subscription.add(fromEvent(_this.el.nativeElement, 'scroll', { passive: true }) .pipe(throttleTime(300, undefined, { leading: true, trailing: true })) .subscribe((/** * @param {?} event * @return {?} */ function (event) { _this.toggleScrollToOneEnd(_this.el.nativeElement, _this.forwardScrollArea, _this.direction, DropScrollOrientation.forward); _this.toggleScrollToOneEnd(_this.el.nativeElement, _this.backwardScrollArea, _this.direction, DropScrollOrientation.backward); }))); // 窗口缩放的时候重绘有效性区域 _this.subscription.add(fromEvent(window, 'resize', { passive: true }) .pipe(throttleTime(300, undefined, { leading: true, trailing: true })) .subscribe((/** * @param {?} event * @return {?} */ function (event) { return _this.resizeArea(); }))); // dragstart的时候显示拖拽滚动边缘面板 _this.subscription.add(_this.dragDropService.dragStartEvent.subscribe((/** * @return {?} */ function () { if (!_this.allowScroll()) { return; } _this.zone.runOutsideAngular((/** * @return {?} */ function () { setTimeout((/** * @return {?} */ function () { // 立马出现会打断边缘元素的拖拽 _this.forwardScrollArea.style.display = 'block'; _this.backwardScrollArea.style.display = 'block'; })); })); }))); // dragEnd或drop的时候结束了拖拽,滚动区域影藏起来 _this.subscription.add(mergeStatic(_this.dragDropService.dragEndEvent, _this.dragDropService.dropEvent) .subscribe((/** * @return {?} */ function () { _this.forwardScrollArea.style.display = 'none'; _this.backwardScrollArea.style.display = 'none'; _this.lastScrollTime = undefined; }))); })); setTimeout((/** * @return {?} */ function () { _this.resizeArea(); }), 0); }; /** * @return {?} */ DropScrollEnhancedDirective.prototype.ngOnDestroy = /** * @return {?} */ function () { this.subscription.unsubscribe(); }; /** * @param {?} direction * @param {?} orientation * @param {?} speedFn * @return {?} */ DropScrollEnhancedDirective.prototype.createScrollFn = /** * @param {?} direction * @param {?} orientation * @param {?} speedFn * @return {?} */ function (direction, orientation, speedFn) { var _this = this; /** @type {?} */ var scrollAttr = (direction === 'v') ? 'scrollTop' : 'scrollLeft'; /** @type {?} */ var eventAttr = (direction === 'v') ? 'clientY' : 'clientX'; /** @type {?} */ var scrollWidthAttr = (direction === 'v') ? 'scrollHeight' : 'scrollWidth'; /** @type {?} */ var rectWidthAttr = (direction === 'v') ? 'height' : 'width'; /** @type {?} */ var compareTarget = (orientation === DropScrollOrientation.forward) ? this.forwardScrollArea : this.backwardScrollArea; /** @type {?} */ var targetAttr = this.getCriticalEdge(direction, orientation); /** @type {?} */ var scrollElement = this.el.nativeElement; return (/** * @param {?} event * @return {?} */ function (event) { /** @type {?} */ var compareTargetRect = compareTarget.getBoundingClientRect(); /** @type {?} */ var distance = event[eventAttr] - compareTargetRect[targetAttr]; /** @type {?} */ var speed = speedFn(Math.abs(distance / (compareTargetRect[rectWidthAttr] || 1))); if (speed < _this.minSpeed) { speed = _this.minSpeed; } if (speed > _this.maxSpeed) { speed = _this.maxSpeed; } if (distance < 0) { speed = -speed; } requestAnimationFrame((/** * @return {?} */ function () { /** @type {?} */ var time = new Date().getTime(); /** @type {?} */ var moveDistance = Math.ceil(speed * (time - (_this.lastScrollTime || time)) / 1000); scrollElement[scrollAttr] -= moveDistance; _this.lastScrollTime = time; // 判断是不是到尽头 if ((scrollElement[scrollAttr] === 0 && orientation === DropScrollOrientation.backward) || ((scrollElement[scrollAttr] + (scrollElement.getBoundingClientRect())[rectWidthAttr]) === scrollElement[scrollWidthAttr] && orientation === DropScrollOrientation.forward)) { compareTarget.style.pointerEvents = 'none'; _this.toggleActiveClass(compareTarget, false); } })); }); }; /** * @param {?} direction * @param {?} orientation * @return {?} */ DropScrollEnhancedDirective.prototype.getCriticalEdge = /** * @param {?} direction * @param {?} orientation * @return {?} */ function (direction, orientation) { return (direction === 'v' && orientation === DropScrollOrientation.forward && 'bottom') || (direction === 'v' && orientation === DropScrollOrientation.backward && 'top') || (direction !== 'v' && orientation === DropScrollOrientation.forward && 'right') || (direction !== 'v' && orientation === DropScrollOrientation.backward && 'left') || 'bottom'; }; /** * @param {?} direction * @return {?} */ DropScrollEnhancedDirective.prototype.getSecondEdge = /** * @param {?} direction * @return {?} */ function (direction) { return (direction === 'v' && 'left') || (direction !== 'v' && 'top') || 'left'; }; /** * @param {?} direction * @param {?} orientation * @return {?} */ DropScrollEnhancedDirective.prototype.createScrollArea = /** * @param {?} direction * @param {?} orientation * @return {?} */ function (direction, orientation) { /** @type {?} */ var area = document.createElement('div'); area.className = 'dropover-scroll-area ' + 'dropover-scroll-area-' + this.getCriticalEdge(direction, orientation); // 处理大小 area.classList.add('active'); this.setAreaSize(area, direction, orientation); // 处理位置 area.style.position = 'absolute'; this.setAreaStyleLayout(area, direction, orientation); // 默认不展示 area.style.display = 'none'; // 附着元素 this.el.nativeElement.parentNode.appendChild(area, this.el.nativeElement); return area; }; /** * @param {?} area * @param {?} direction * @param {?} orientation * @return {?} */ DropScrollEnhancedDirective.prototype.setAreaSize = /** * @param {?} area * @param {?} direction * @param {?} orientation * @return {?} */ function (area, direction, orientation) { /** @type {?} */ var rect = this.el.nativeElement.getBoundingClientRect(); /** @type {?} */ var containerAttr = direction === 'v' ? 'height' : 'width'; /** @type {?} */ var responseEdgeWidth = (typeof this.responseEdgeWidth === 'string') ? this.responseEdgeWidth : this.responseEdgeWidth(rect[containerAttr]); /** @type {?} */ var settingOffset = this.viewOffset && (orientation === DropScrollOrientation.forward ? this.viewOffset.forward : this.viewOffset.backward); /** @type {?} */ var width = direction === 'v' ? (rect.width + 'px') : responseEdgeWidth; /** @type {?} */ var height = direction === 'v' ? responseEdgeWidth : (rect.height + 'px'); if (settingOffset) { if (settingOffset.widthOffset) { width = 'calc(' + width + ' + ' + (settingOffset.widthOffset) + 'px)'; } if (settingOffset.heightOffset) { height = 'calc(' + height + ' + ' + (settingOffset.heightOffset) + 'px)'; } } area.style.width = width; area.style.height = height; }; /** * @param {?} area * @param {?} direction * @param {?} orientation * @return {?} */ DropScrollEnhancedDirective.prototype.setAreaStyleLayout = /** * @param {?} area * @param {?} direction * @param {?} orientation * @return {?} */ function (area, direction, orientation) { var _this = this; /** @type {?} */ var target = this.el.nativeElement; /** @type {?} */ var relatedTarget = this.el.nativeElement.parentNode; /** @type {?} */ var defaultOffset = { left: 0, right: 0, top: 0, bottom: 0 }; /** @type {?} */ var settingOffset = this.viewOffset && (orientation === DropScrollOrientation.forward ? this.viewOffset.forward : this.viewOffset.backward) || defaultOffset; /** @type {?} */ var criticalEdge = this.getCriticalEdge(direction, orientation); /** @type {?} */ var secondEdge = this.getSecondEdge(direction); [criticalEdge, secondEdge].forEach((/** * @param {?} edge * @return {?} */ function (edge) { area.style[edge] = _this.getRelatedPosition(target, relatedTarget, edge, settingOffset[edge]); })); }; /** * @param {?} target * @param {?} relatedTarget * @param {?} edge * @param {?=} offsetValue * @return {?} */ DropScrollEnhancedDirective.prototype.getRelatedPosition = /** * @param {?} target * @param {?} relatedTarget * @param {?} edge * @param {?=} offsetValue * @return {?} */ function (target, relatedTarget, edge, offsetValue) { /** @type {?} */ var relatedComputedStyle = window.getComputedStyle(relatedTarget); /** @type {?} */ var relatedRect = relatedTarget.getBoundingClientRect(); /** @type {?} */ var selfRect = target.getBoundingClientRect(); /** @type {?} */ var helper = { left: ['left', 'Left'], right: ['right', 'Right'], top: ['top', 'Top'], bottom: ['bottom', 'Bottom'], }; /** @type {?} */ var factor = 1; if (edge === 'right' || edge === 'bottom') { factor = -1; } return (selfRect[helper[edge][0]] - relatedRect[helper[edge][0]] + parseInt(relatedComputedStyle['border' + helper[edge][1] + 'Width'], 10)) * factor + (offsetValue || 0) + 'px'; }; /** * @return {?} */ DropScrollEnhancedDirective.prototype.resizeArea = /** * @return {?} */ function () { var _this = this; [{ area: this.forwardScrollArea, orientation: DropScrollOrientation.forward }, { area: this.backwardScrollArea, orientation: DropScrollOrientation.backward } ] .forEach((/** * @param {?} item * @return {?} */ function (item) { _this.setAreaSize(item.area, _this.direction, item.orientation); _this.setAreaStyleLayout(item.area, _this.direction, item.orientation); })); }; /** * @param {?} scrollElement * @param {?} toggleElement * @param {?} direction * @param {?} orientation * @return {?} */ DropScrollEnhancedDirective.prototype.toggleScrollToOneEnd = /** * @param {?} scrollElement * @param {?} toggleElement * @param {?} direction * @param {?} orientation * @return {?} */ function (scrollElement, toggleElement, direction, orientation) { /** @type {?} */ var scrollAttr = (direction === 'v') ? 'scrollTop' : 'scrollLeft'; /** @type {?} */ var scrollWidthAttr = (direction === 'v') ? 'scrollHeight' : 'scrollWidth'; /** @type {?} */ var rectWidthAttr = (direction === 'v') ? 'height' : 'width'; if ((scrollElement[scrollAttr] === 0 && orientation === DropScrollOrientation.backward) || (Math.abs(scrollElement[scrollAttr] + (scrollElement.getBoundingClientRect())[rectWidthAttr] - scrollElement[scrollWidthAttr]) < 1 && orientation === DropScrollOrientation.forward)) { toggleElement.style.pointerEvents = 'none'; this.toggleActiveClass(toggleElement, false); } else { toggleElement.style.pointerEvents = 'auto'; this.toggleActiveClass(toggleElement, true); } }; /** * @return {?} */ DropScrollEnhancedDirective.prototype.cleanLastScrollTime = /** * @return {?} */ function () { this.lastScrollTime = undefined; }; /** * @param {?} target * @param {?} active * @return {?} */ DropScrollEnhancedDirective.prototype.toggleActiveClass = /** * @param {?} target * @param {?} active * @return {?} */ function (target, active) { if (active) { target.classList.remove('inactive'); target.classList.add('active'); } else { target.classList.remove('active'); target.classList.add('inactive'); } }; /** * @return {?} */ DropScrollEnhancedDirective.prototype.allowScroll = /** * @return {?} */ function () { var _this = this; if (!this.dropScrollScope) { return true; } /** @type {?} */ var allowed = false; if (typeof this.dropScrollScope === 'string') { if (typeof this.dragDropService.scope === 'string') { allowed = this.dragDropService.scope === this.dropScrollScope; } if (this.dragDropService.scope instanceof Array) { allowed = this.dragDropService.scope.indexOf(this.dropScrollScope) > -1; } } if (this.dropScrollScope instanceof Array) { if (typeof this.dragDropService.scope === 'string') { allowed = this.dropScrollScope.indexOf(this.dragDropService.scope) > -1; } if (this.dragDropService.scope instanceof Array) { allowed = this.dropScrollScope.filter((/** * @param {?} item * @return {?} */ function (item) { return _this.dragDropService.scope.indexOf(item) !== -1; })).length > 0; } } return allowed; }; DropScrollEnhancedDirective.decorators = [ { type: Directive, args: [{ selector: '[dDropScrollEnhanced]', exportAs: 'dDropScrollEnhanced' },] } ]; /** @nocollapse */ DropScrollEnhancedDirective.ctorParameters = function () { return [ { type: ElementRef }, { type: NgZone }, { type: DragDropService } ]; }; DropScrollEnhancedDirective.propDecorators = { minSpeed: [{ type: Input }], maxSpeed: [{ type: Input }], responseEdgeWidth: [{ type: Input }], speedFn: [{ type: Input }], direction: [{ type: Input }], viewOffset: [{ type: Input }], dropScrollScope: [{ type: Input }] }; return DropScrollEnhancedDirective; }()); export { DropScrollEnhancedDirective }; if (false) { /** @type {?} */ DropScrollEnhancedDirective.prototype.minSpeed; /** @type {?} */ DropScrollEnhancedDirective.prototype.maxSpeed; /** @type {?} */ DropScrollEnhancedDirective.prototype.responseEdgeWidth; /** @type {?} */ DropScrollEnhancedDirective.prototype.speedFn; /** @type {?} */ DropScrollEnhancedDirective.prototype.direction; /** @type {?} */ DropScrollEnhancedDirective.prototype.viewOffset; /** @type {?} */ DropScrollEnhancedDirective.prototype.dropScrollScope; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.forwardScrollArea; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.backwardScrollArea; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.subscription; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.forwardScrollFn; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.backwardScrollFn; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.lastScrollTime; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.el; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.zone; /** * @type {?} * @private */ DropScrollEnhancedDirective.prototype.dragDropService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1zY3JvbGwtZW5oYW5jZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy1kZXZ1aS9kcmFnZHJvcC8iLCJzb3VyY2VzIjpbImRpcmVjdGl2ZXMvZHJvcC1zY3JvbGwtZW5oYW5jZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQTRDLG9DQUFvQyxFQUMvRCxxQkFBcUIsRUFBeUIsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RyxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLElBQUksV0FBVyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRWhFO0lBdUJFLHFDQUFvQixFQUFjLEVBQVUsSUFBWSxFQUFVLGVBQWdDO1FBQTlFLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBbEJ6RixhQUFRLEdBQW9CLEVBQUUsQ0FBQztRQUMvQixhQUFRLEdBQW9CLElBQUksQ0FBQztRQUNqQyxzQkFBaUIsR0FBMEMsT0FBTyxDQUFDO1FBQ25FLFlBQU8sR0FBNEIsb0NBQW9DLENBQUMsT0FBTyxDQUFDO1FBQ2hGLGNBQVMsR0FBd0IsR0FBRyxDQUFDO1FBU3RDLGlCQUFZLEdBQWlCLElBQUksWUFBWSxFQUFFLENBQUM7SUFLNkMsQ0FBQzs7OztJQUV0RyxxREFBZTs7O0lBQWY7UUFBQSxpQkFxRUM7UUFwRUMsUUFBUTtRQUNSLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMs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cFJZLDJCQUEyQjs7O0lBQ3RDLCtDQUF3Qzs7SUFDeEMsK0NBQTBDOztJQUMxQyx3REFBNEU7O0lBQzVFLDhDQUF5Rjs7SUFDekYsZ0RBQThDOztJQUM5QyxpREFHRTs7SUFDRixzREFBaUQ7Ozs7O0lBRWpELHdEQUF1Qzs7Ozs7SUFDdkMseURBQXdDOzs7OztJQUN4QyxtREFBd0Q7Ozs7O0lBQ3hELHNEQUFnRDs7Ozs7SUFDaEQsdURBQWlEOzs7OztJQUNqRCxxREFBdUI7Ozs7O0lBRVgseUNBQXNCOzs7OztJQUFFLDJDQUFvQjs7Ozs7SUFBRSxzREFBd0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEcm9wU2Nyb2xsU3BlZWRGdW5jdGlvbiwgRHJvcFNjcm9sbFNwZWVkLCBEcm9wU2Nyb2xsRW5oYW5jZVRpbWluZ0Z1bmN0aW9uR3JvdXAsIERyb3BTY3JvbGxEaXJlY3Rpb24sXHJcbiAgRHJvcFNjcm9sbEFyZWFPZmZzZXQsIERyb3BTY3JvbGxPcmllbnRhdGlvbiwgRHJvcFNjcm9sbFRyaWdnZXJFZGdlIH0gZnJvbSAnLi9kcm9wLXNjcm9sbC1lbmhhbmNlLnR5cGUnO1xyXG5pbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YnNjcmlwdGlvbiwgbWVyZ2UgYXMgbWVyZ2VTdGF0aWMgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGhyb3R0bGVUaW1lLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IERyYWdEcm9wU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2RyYWctZHJvcC5zZXJ2aWNlJztcclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiAnW2REcm9wU2Nyb2xsRW5oYW5jZWRdJyxcclxuICBleHBvcnRBczogJ2REcm9wU2Nyb2xsRW5oYW5jZWQnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEcm9wU2Nyb2xsRW5oYW5jZWREaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIG1pblNwZWVkOiBEcm9wU2Nyb2xsU3BlZWQgPSA1MDtcclxuICBASW5wdXQoKSBtYXhTcGVlZDogRHJvcFNjcm9sbFNwZWVkID0gMTAwMDtcclxuICBASW5wdXQoKSByZXNwb25zZUVkZ2VXaWR0aDogc3RyaW5nIHwgKCh0b3RhbDogbnVtYmVyKSA9PiBzdHJpbmcpICA9ICcxMDBweCc7XHJcbiAgQElucHV0KCkgc3BlZWRGbjogRHJvcFNjcm9sbFNwZWVkRnVuY3Rpb24gPSBEcm9wU2Nyb2xsRW5oYW5jZVRpbWluZ0Z1bmN0aW9uR3JvdXAuZGVmYXVsdDtcclxuICBASW5wdXQoKSBkaXJlY3Rpb246IERyb3BTY3JvbGxEaXJlY3Rpb24gPSAndic7XHJcbiAgQElucHV0KCkgdmlld09mZnNldDoge1xyXG4gICAgZm9yd2FyZD86IERyb3BTY3JvbGxBcmVhT2Zmc2V0OyAvLyDku4Xph43opoHovrnlkozmrKHopoHovrnmnInmlYhcclxuICAgIGJhY2t3YXJkPzogRHJvcFNjcm9sbEFyZWFPZmZzZXQ7XHJcbiAgfTtcclxuICBASW5wdXQoKSBkcm9wU2Nyb2xsU2NvcGU6IHN0cmluZyB8IEFycmF5PHN0cmluZz47XHJcblxyXG4gIHByaXZhdGUgZm9yd2FyZFNjcm9sbEFyZWE6IEhUTUxFbGVtZW50O1xyXG4gIHByaXZhdGUgYmFja3dhcmRTY3JvbGxBcmVhOiBIVE1MRWxlbWVudDtcclxuICBwcml2YXRlIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG4gIHByaXZhdGUgZm9yd2FyZFNjcm9sbEZuOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xyXG4gIHByaXZhdGUgYmFja3dhcmRTY3JvbGxGbjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcclxuICBwcml2YXRlIGxhc3RTY3JvbGxUaW1lO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBwcml2YXRlIHpvbmU6IE5nWm9uZSwgcHJpdmF0ZSBkcmFnRHJvcFNlcnZpY2U6IERyYWdEcm9wU2VydmljZSkge31cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgLy8g6K6+572u54i25YWD57SgXHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucGFyZW50Tm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucGFyZW50Tm9kZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgIC8vIOWIm+W7uuWQjumAgOWJjei/m+WMuuWfn+WSjOWvueW6lOeahOa7muWKqOWHveaVsFxyXG4gICAgdGhpcy5mb3J3YXJkU2Nyb2xsQXJlYSA9IHRoaXMuY3JlYXRlU2Nyb2xsQXJlYSh0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmZvcndhcmQpO1xyXG4gICAgdGhpcy5iYWNrd2FyZFNjcm9sbEFyZWEgPSB0aGlzLmNyZWF0ZVNjcm9sbEFyZWEodGhpcy5kaXJlY3Rpb24sIERyb3BTY3JvbGxPcmllbnRhdGlvbi5iYWNrd2FyZCk7XHJcbiAgICB0aGlzLmZvcndhcmRTY3JvbGxGbiA9IHRoaXMuY3JlYXRlU2Nyb2xsRm4odGhpcy5kaXJlY3Rpb24sIERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkLCB0aGlzLnNwZWVkRm4pO1xyXG4gICAgdGhpcy5iYWNrd2FyZFNjcm9sbEZuID0gdGhpcy5jcmVhdGVTY3JvbGxGbih0aGlzLmRpcmVjdGlvbiwgRHJvcFNjcm9sbE9yaWVudGF0aW9uLmJhY2t3YXJkLCB0aGlzLnNwZWVkRm4pO1xyXG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgLy8g5ouW5ou95Yiw5YW25LiK6Kem5Y+R5rua5YqoXHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChmcm9tRXZlbnQodGhpcy5mb3J3YXJkU2Nyb2xsQXJlYSwgJ2RyYWdvdmVyJylcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIHRhcChldmVudCA9PiB7ZXZlbnQucHJldmVudERlZmF1bHQoKTsgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IH0pLFxyXG4gICAgICAgICAgdGhyb3R0bGVUaW1lKDEwMCwgdW5kZWZpbmVkLCB7bGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IHRydWV9KVxyXG4gICAgICAgICkuc3Vic2NyaWJlKGV2ZW50ID0+IHRoaXMuZm9yd2FyZFNjcm9sbEZuKGV2ZW50KSkpO1xyXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQoZnJvbUV2ZW50KHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLCAnZHJhZ292ZXInKVxyXG4gICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgdGFwKGV2ZW50ID0+IHtldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgfSksXHJcbiAgICAgICAgICB0aHJvdHRsZVRpbWUoMTAwLCB1bmRlZmluZWQsIHtsZWFkaW5nOiB0cnVlLCB0cmFpbGluZzogdHJ1ZX0pKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4gdGhpcy5iYWNrd2FyZFNjcm9sbEZuKGV2ZW50KSkpO1xyXG4gICAgICAvLyDmi5bmi73nprvlvIDmuIXpmaTlj4LmlbBcclxuICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxyXG4gICAgICAgIG1lcmdlU3RhdGljKFxyXG4gICAgICAgICAgZnJvbUV2ZW50KHRoaXMuZm9yd2FyZFNjcm9sbEFyZWEsICdkcmFnbGVhdmUnLCB7cGFzc2l2ZTogdHJ1ZX0pLFxyXG4gICAgICAgICAgZnJvbUV2ZW50KHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLCAnZHJhZ2xlYXZlJywge3Bhc3NpdmU6IHRydWV9KVxyXG4gICAgICAgICkuc3Vic2NyaWJlKGV2ZW50ID0+IHRoaXMuY2xlYW5MYXN0U2Nyb2xsVGltZSgpKVxyXG4gICAgICApO1xyXG4gICAgICAvLyDmu5rliqjov4fnqIvorqHnrpfljLrln5/mnInmlYjmgKfvvIzmu5rliqjmnaHotLTliLDovrnnvJjnmoTml7blgJnml6DmlYjvvIzml6DmlYjnmoTml7blgJnorr7nva7pvKDmoIfkuovku7blj6/nlKjkuLpub25lXHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcclxuICAgICAgICBmcm9tRXZlbnQodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnc2Nyb2xsJywge3Bhc3NpdmU6IHRydWV9KVxyXG4gICAgICAgIC5waXBlKHRocm90dGxlVGltZSgzMDAsIHVuZGVmaW5lZCwge2xlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiB0cnVlfSkpXHJcbiAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XHJcbiAgICAgICAgICB0aGlzLnRvZ2dsZVNjcm9sbFRvT25lRW5kKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgdGhpcy5mb3J3YXJkU2Nyb2xsQXJlYSwgdGhpcy5kaXJlY3Rpb24sIERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkKTtcclxuICAgICAgICAgIHRoaXMudG9nZ2xlU2Nyb2xsVG9PbmVFbmQodGhpcy5lbC5uYXRpdmVFbGVtZW50LCB0aGlzLmJhY2t3YXJkU2Nyb2xsQXJlYSwgdGhpcy5kaXJlY3Rpb24sIERyb3BTY3JvbGxPcmllbnRhdGlvbi5iYWNrd2FyZCk7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICAgICAgLy8g56qX5Y+j57yp5pS+55qE5pe25YCZ6YeN57uY5pyJ5pWI5oCn5Yy65Z+fXHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcclxuICAgICAgICBmcm9tRXZlbnQod2luZG93LCAncmVzaXplJywge3Bhc3NpdmU6IHRydWV9KVxyXG4gICAgICAgIC5waXBlKHRocm90dGxlVGltZSgzMDAsIHVuZGVmaW5lZCwge2xlYWRpbmc6IHRydWUsIHRyYWlsaW5nOiB0cnVlfSkpXHJcbiAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB0aGlzLnJlc2l6ZUFyZWEoKSlcclxuICAgICAgKTtcclxuICAgICAgLy8gZHJhZ3N0YXJ055qE5pe25YCZ5pi+56S65ouW5ou95rua5Yqo6L6557yY6Z2i5p2/XHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcclxuICAgICAgICB0aGlzLmRyYWdEcm9wU2VydmljZS5kcmFnU3RhcnRFdmVudC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dTY3JvbGwoKSkge3JldHVybjsgfVxyXG4gICAgICAgICAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8g56uL6ams5Ye6546w5Lya5omT5pat6L6557yY5YWD57Sg55qE5ouW5ou9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcndhcmRTY3JvbGxBcmVhLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5iYWNrd2FyZFNjcm9sbEFyZWEuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgICAgIC8vIGRyYWdFbmTmiJZkcm9w55qE5pe25YCZ57uT5p2f5LqG5ouW5ou977yM5rua5Yqo5Yy65Z+f5b2x6JeP6LW35p2lXHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChcclxuICAgICAgICAgIG1lcmdlU3RhdGljKCB0aGlzLmRyYWdEcm9wU2VydmljZS5kcmFnRW5kRXZlbnQsIHRoaXMuZHJhZ0Ryb3BTZXJ2aWNlLmRyb3BFdmVudClcclxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmZvcndhcmRTY3JvbGxBcmVhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgIHRoaXMuYmFja3dhcmRTY3JvbGxBcmVhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgIHRoaXMubGFzdFNjcm9sbFRpbWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMucmVzaXplQXJlYSgpO1xyXG4gICAgfSwgMCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICBjcmVhdGVTY3JvbGxGbihkaXJlY3Rpb246IERyb3BTY3JvbGxEaXJlY3Rpb24sIG9yaWVudGF0aW9uOiBEcm9wU2Nyb2xsT3JpZW50YXRpb24sXHJcbiAgICAgIHNwZWVkRm46IERyb3BTY3JvbGxTcGVlZEZ1bmN0aW9uKSB7XHJcbiAgICBjb25zdCBzY3JvbGxBdHRyID0gKGRpcmVjdGlvbiA9PT0gJ3YnKSA/ICdzY3JvbGxUb3AnIDogJ3Njcm9sbExlZnQnO1xyXG4gICAgY29uc3QgZXZlbnRBdHRyID0gKGRpcmVjdGlvbiA9PT0gJ3YnKSA/ICdjbGllbnRZJyA6ICdjbGllbnRYJztcclxuICAgIGNvbnN0IHNjcm9sbFdpZHRoQXR0ciA9IChkaXJlY3Rpb24gPT09ICd2JykgPyAnc2Nyb2xsSGVpZ2h0JyA6ICdzY3JvbGxXaWR0aCc7XHJcbiAgICBjb25zdCByZWN0V2lkdGhBdHRyID0gKGRpcmVjdGlvbiA9PT0gJ3YnKSA/ICdoZWlnaHQnIDogJ3dpZHRoJztcclxuICAgIGNvbnN0IGNvbXBhcmVUYXJnZXQgPSAob3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkKSA/IHRoaXMuZm9yd2FyZFNjcm9sbEFyZWEgOiB0aGlzLmJhY2t3YXJkU2Nyb2xsQXJlYTtcclxuICAgIGNvbnN0IHRhcmdldEF0dHIgPSB0aGlzLmdldENyaXRpY2FsRWRnZShkaXJlY3Rpb24sIG9yaWVudGF0aW9uKTtcclxuICAgIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQ7XHJcblxyXG4gICAgcmV0dXJuIChldmVudDogRXZlbnQpID0+IHtcclxuICAgICAgY29uc3QgY29tcGFyZVRhcmdldFJlY3QgPSBjb21wYXJlVGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBjb25zdCBkaXN0YW5jZSA9IGV2ZW50W2V2ZW50QXR0cl0gLSBjb21wYXJlVGFyZ2V0UmVjdFt0YXJnZXRBdHRyXTtcclxuICAgICAgbGV0IHNwZWVkID0gc3BlZWRGbihNYXRoLmFicyhkaXN0YW5jZSAvIChjb21wYXJlVGFyZ2V0UmVjdFtyZWN0V2lkdGhBdHRyXSB8fCAxKSkpO1xyXG4gICAgICBpZiAoc3BlZWQgPCB0aGlzLm1pblNwZWVkKSB7IHNwZWVkID0gdGhpcy5taW5TcGVlZDsgfVxyXG4gICAgICBpZiAoc3BlZWQgPiB0aGlzLm1heFNwZWVkKSB7IHNwZWVkID0gdGhpcy5tYXhTcGVlZDsgfVxyXG4gICAgICBpZiAoZGlzdGFuY2UgPCAwKSB7IHNwZWVkID0gLSBzcGVlZDsgfVxyXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICBjb25zdCBtb3ZlRGlzdGFuY2UgPSBNYXRoLmNlaWwoc3BlZWQgKiAodGltZSAtICh0aGlzLmxhc3RTY3JvbGxUaW1lIHx8IHRpbWUpKSAvIDEwMDApO1xyXG4gICAgICAgIHNjcm9sbEVsZW1lbnRbc2Nyb2xsQXR0cl0gLT0gbW92ZURpc3RhbmNlO1xyXG4gICAgICAgIHRoaXMubGFzdFNjcm9sbFRpbWUgPSB0aW1lO1xyXG4gICAgICAgIC8vIOWIpOaWreaYr+S4jeaYr+WIsOWwveWktFxyXG4gICAgICAgIGlmICgoc2Nyb2xsRWxlbWVudFtzY3JvbGxBdHRyXSA9PT0gMCAmJiBvcmllbnRhdGlvbiA9PT0gRHJvcFNjcm9sbE9yaWVudGF0aW9uLmJhY2t3YXJkKVxyXG4gICAgICAgIHx8ICgoc2Nyb2xsRWxlbWVudFtzY3JvbGxBdHRyXSArIChzY3JvbGxFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKVtyZWN0V2lkdGhBdHRyXSkgPT09IHNjcm9sbEVsZW1lbnRbc2Nyb2xsV2lkdGhBdHRyXVxyXG4gICAgICAgICAgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgY29tcGFyZVRhcmdldC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xyXG4gICAgICAgICAgdGhpcy50b2dnbGVBY3RpdmVDbGFzcyhjb21wYXJlVGFyZ2V0LCBmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gIH1cclxuICBnZXRDcml0aWNhbEVkZ2UoZGlyZWN0aW9uOiBEcm9wU2Nyb2xsRGlyZWN0aW9uLCBvcmllbnRhdGlvbjogRHJvcFNjcm9sbE9yaWVudGF0aW9uKTogRHJvcFNjcm9sbFRyaWdnZXJFZGdlIHtcclxuICAgIHJldHVybiAoZGlyZWN0aW9uID09PSAndicgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkICYmICdib3R0b20nKVxyXG4gICAgfHwgKGRpcmVjdGlvbiA9PT0gJ3YnICYmIG9yaWVudGF0aW9uID09PSBEcm9wU2Nyb2xsT3JpZW50YXRpb24uYmFja3dhcmQgJiYgJ3RvcCcpXHJcbiAgICB8fCAoZGlyZWN0aW9uICE9PSAndicgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5mb3J3YXJkICYmICdyaWdodCcpXHJcbiAgICB8fCAoZGlyZWN0aW9uICE9PSAndicgJiYgb3JpZW50YXRpb24gPT09IERyb3BTY3JvbGxPcmllbnRhdGlvbi5iYWNrd2FyZCAmJiAnbGVmdCcpIHx8ICdib3R0b20nO1xyXG4gIH1cclxuICBnZXRTZWNvbmRFZGdlKGRpcmVjdGlvbjogRHJvcFNjcm9sbERpcmVjdGlvbik6IERyb3BTY3JvbGxUcmlnZ2VyRWRnZSB7XHJcbiAgICByZXR1cm4gKGRpcmVjdGlvbiA9PT0gJ3YnICYmICdsZWZ0JylcclxuICAgIHx8IChkaXJlY3Rpb24gIT09ICd2JyAmJiAgJ3RvcCcpIHx8ICdsZWZ0JztcclxuICB9XHJcblxyXG4gIGNyZWF0ZVNjcm9sbEFyZWEoZGlyZWN0aW9uOiBEcm9wU2Nyb2xsRGlyZWN0aW9uLCBvcmllbnRhdGlvbjogRHJvcFNjcm9sbE9yaWVudGF0aW9uKSB7XHJcbiAgICBjb25zdCBhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICBhcmVhLmNsYXNzTmFtZSA9ICdkcm9wb3Zlci1zY3JvbGwtYXJlYSAnICsgJ2Ryb3BvdmVyLXNjcm9sbC1hcmVhLScgKyB0aGlzLmdldENyaXRpY2FsRWRnZShkaXJlY3Rpb24sIG9yaWVudGF0aW9uKTtcclxuICAgIC8vIOWkhOeQhuWkp+Wwj1xyXG4gICAgYXJlYS5jbGFzc0xpc3QuYWRkKCdhY3R