UNPKG

ng-devui

Version:

DevUI components based on Angular

224 lines 38 kB
import { DOCUMENT } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, Input, Output, TemplateRef, } from '@angular/core'; import { Subscription, fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class BackTopComponent { constructor(cdr, el, doc) { this.cdr = cdr; this.el = el; this.doc = doc; this.visibleHeight = 300; this.bottom = '50px'; this.right = '30px'; this.draggable = false; this.backTopEvent = new EventEmitter(); this.dragEvent = new EventEmitter(); this.currScrollTop = 0; this.duration = 0; this.moveCursor = false; this.moveToggle = false; this.isVisible = false; this.subs = new Subscription(); this.SCROLL_REFRESH_INTERVAL = 100; this.MOUSEDOWN_DELAY = 180; this.RESIZE_DELAY = 300; this.document = this.doc; } ngOnChanges(changes) { if (changes.scrollTarget) { if (this.subs) { this.subs.unsubscribe(); } this.subs = new Subscription(); this.addScrollEvent(); } } ngOnInit() { this.addScrollEvent(); this.showButton(); } ngAfterViewInit() { if (this.draggable) { // 窗口大小改变时,如缩放比例或组件超出显示范围重置到默认位置 this.subs.add(fromEvent(window, 'resize') .pipe(debounceTime(this.RESIZE_DELAY)) .subscribe(() => { const dom = this.dragBoundary?.dom || this.el.nativeElement.querySelector('div.devui-backtop'); if (dom) { // 不显示时无法获取getBoundingClientRect,使用style获取 const style = getComputedStyle(dom); const left = parseInt(style.left, 10) || 0; const top = parseInt(style.top, 10) || 0; if (window.devicePixelRatio !== 1 || left > window.innerWidth || top > window.innerHeight) { this.onMouseUp(); this.duration = 0; dom.style.left = 'unset'; dom.style.top = 'unset'; } } })); } } ngOnDestroy() { if (this.subs) { this.subs.unsubscribe(); } } addScrollEvent() { this.subs.add(fromEvent(this.getScrollTarget(), 'scroll') .pipe(debounceTime(this.SCROLL_REFRESH_INTERVAL)) .subscribe(() => { this.showButton(); this.cdr.detectChanges(); })); } getScrollTarget() { if (this.scrollTarget) { this.el.nativeElement.querySelector('.devui-backtop').style.position = 'absolute'; this.scrollTarget.parentElement.style.position = 'relative'; } this.target = this.scrollTarget || window; return this.target; } showButton() { this.currScrollTop = this.target === window ? window.pageYOffset || this.document.documentElement.scrollTop || this.document.body.scrollTop : this.scrollTarget.scrollTop; if (this.isVisible !== this.currScrollTop >= this.visibleHeight) { this.isVisible = !this.isVisible; } } goTop() { if (this.draggable && this.duration > this.MOUSEDOWN_DELAY) { this.duration = 0; return; } if (this.target === window) { this.document.documentElement.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); this.document.body.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }); } else { this.scrollTarget.style.scrollBehavior = 'smooth'; this.scrollTarget.scrollTop = 0; } this.duration = 0; this.backTopEvent.emit(true); } setDragBoundary() { const dom = this.el.nativeElement.querySelector('div.devui-backtop'); let boxRect; let minLeft; let minTop; let maxLeft; let maxTop; if (dom) { const { width, height } = dom.getBoundingClientRect(); if (this.scrollTarget) { boxRect = this.scrollTarget.getBoundingClientRect(); minLeft = -1 * boxRect.x; minTop = -1 * boxRect.y; maxLeft = window.innerWidth - boxRect.x - width; maxTop = window.innerHeight - boxRect.y - height; } else { boxRect = { x: 0, y: 0 }; minLeft = 0; minTop = 0; maxLeft = window.innerWidth - width; maxTop = window.innerHeight - height; } this.dragBoundary = { dom, boxRect, minLeft, minTop, maxLeft, maxTop }; } } // mousedown mouseup click 按顺序触发且前一个结束触发下一个 mousedownEvent(event) { if (this.draggable) { event.preventDefault(); this.setDragBoundary(); this.duration = new Date().getTime(); this.moveToggle = true; this.cursorTimer = setTimeout(() => { this.moveCursor = true; this.dragEvent.emit(true); }, this.MOUSEDOWN_DELAY); } } mouseleaveEvent() { if (this.draggable && this.cursorTimer) { clearTimeout(this.cursorTimer); } } onMouseUp() { if (this.draggable) { if (this.cursorTimer) { clearTimeout(this.cursorTimer); } if (this.moveToggle) { this.moveToggle = false; this.moveCursor = false; this.dragEvent.emit(false); } this.duration = this.duration && new Date().getTime() - this.duration; } } onMouseMove(event) { if (this.draggable && this.moveToggle && this.dragBoundary) { // 先判断再执行阻止默认事件,否则可能影响鼠标拖选功能 event.preventDefault(); this.moveCursor = true; const posX = event.movementX; const posY = event.movementY; const rect = this.dragBoundary.dom.getBoundingClientRect(); const left = rect.x - this.dragBoundary.boxRect.x + posX; const top = rect.y - this.dragBoundary.boxRect.y + posY; const isLeft = left < this.dragBoundary.minLeft; const isRight = left > this.dragBoundary.maxLeft; const isTop = top < this.dragBoundary.minTop; const isBottom = top > this.dragBoundary.maxTop; const leftResult = isLeft ? this.dragBoundary.minLeft : left; const topResult = isTop ? this.dragBoundary.minTop : top; this.dragBoundary.dom.style.left = `${isRight ? this.dragBoundary.maxLeft : leftResult}px`; this.dragBoundary.dom.style.top = `${isBottom ? this.dragBoundary.maxTop : topResult}px`; // 如到达边界释放拖拽动作,避免鼠标偏移较大距离后返回主视窗仍可拖拽 if ([isLeft, isRight, isTop, isBottom].includes(true)) { this.onMouseUp(); this.duration = 0; } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BackTopComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BackTopComponent, selector: "d-back-top", inputs: { customTemplate: "customTemplate", visibleHeight: "visibleHeight", bottom: "bottom", right: "right", scrollTarget: "scrollTarget", draggable: "draggable" }, outputs: { backTopEvent: "backTopEvent", dragEvent: "dragEvent" }, host: { listeners: { "document:mouseup": "onMouseUp()", "document:mousemove": "onMouseMove($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"devui-backtop\"\n [ngStyle]=\"{\n display: isVisible ? 'block' : 'none',\n bottom: bottom,\n right: right,\n cursor: moveCursor && draggable ? 'move' : 'pointer'\n }\"\n (click)=\"goTop()\"\n>\n <div class=\"devui-backtop-drag-handle\" (mousedown)=\"mousedownEvent($event)\" (mouseleave)=\"mouseleaveEvent()\">\n <ng-template [ngTemplateOutlet]=\"customTemplate ? customTemplate : default\"></ng-template>\n <ng-template #default>\n <div class=\"devui-backtop-content\">\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M8.71335931,15.2865297 C8.61179683,16.2090609 7.32293758,16.1267953 7.27304695,15.2865297 C7.27175008,14.6475142 7.27175008,5.26479636 7.27175008,5.26479636 L2.83675052,9.54548344 C2.14185995,10.1440615 1.3143288,9.18731159 1.83135998,8.55773353 C3.79557855,6.65310872 7.3202657,3.24515592 7.40179694,3.16632781 C7.72696878,2.81306222 8.23887498,2.79476534 8.58495308,3.16632781 C9.23193739,3.7919215 14.0334057,8.42146792 14.1791557,8.58804603 C14.66614,9.19338972 13.8787807,10.0892021 13.2066089,9.58451469 C13.0329683,9.43717095 8.71468744,5.26462448 8.71468744,5.26462448 L8.71335931,15.2865297 Z M1.81868811,-8.54871729e-14 L14.1075619,-8.54871729e-14 L14.1075619,1.39509361 L1.81868811,1.39509361 L1.81868811,-8.54871729e-14 Z\"\n fill=\"#FFFFFF\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".devui-backtop{width:40px;height:40px;position:fixed;z-index:1}.devui-backtop .devui-backtop-drag-handle{cursor:unset!important}.devui-backtop-content{width:40px;height:40px;background-color:var(--devui-text-weak, #333333);opacity:.4;border-radius:50%;display:flex;align-items:center;justify-content:center}.devui-backtop-content:hover{opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BackTopComponent, decorators: [{ type: Component, args: [{ selector: 'd-back-top', changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, template: "<div\n class=\"devui-backtop\"\n [ngStyle]=\"{\n display: isVisible ? 'block' : 'none',\n bottom: bottom,\n right: right,\n cursor: moveCursor && draggable ? 'move' : 'pointer'\n }\"\n (click)=\"goTop()\"\n>\n <div class=\"devui-backtop-drag-handle\" (mousedown)=\"mousedownEvent($event)\" (mouseleave)=\"mouseleaveEvent()\">\n <ng-template [ngTemplateOutlet]=\"customTemplate ? customTemplate : default\"></ng-template>\n <ng-template #default>\n <div class=\"devui-backtop-content\">\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n <path\n d=\"M8.71335931,15.2865297 C8.61179683,16.2090609 7.32293758,16.1267953 7.27304695,15.2865297 C7.27175008,14.6475142 7.27175008,5.26479636 7.27175008,5.26479636 L2.83675052,9.54548344 C2.14185995,10.1440615 1.3143288,9.18731159 1.83135998,8.55773353 C3.79557855,6.65310872 7.3202657,3.24515592 7.40179694,3.16632781 C7.72696878,2.81306222 8.23887498,2.79476534 8.58495308,3.16632781 C9.23193739,3.7919215 14.0334057,8.42146792 14.1791557,8.58804603 C14.66614,9.19338972 13.8787807,10.0892021 13.2066089,9.58451469 C13.0329683,9.43717095 8.71468744,5.26462448 8.71468744,5.26462448 L8.71335931,15.2865297 Z M1.81868811,-8.54871729e-14 L14.1075619,-8.54871729e-14 L14.1075619,1.39509361 L1.81868811,1.39509361 L1.81868811,-8.54871729e-14 Z\"\n fill=\"#FFFFFF\"\n fill-rule=\"nonzero\"\n ></path>\n </g>\n </svg>\n </div>\n </ng-template>\n </div>\n</div>\n", styles: [".devui-backtop{width:40px;height:40px;position:fixed;z-index:1}.devui-backtop .devui-backtop-drag-handle{cursor:unset!important}.devui-backtop-content{width:40px;height:40px;background-color:var(--devui-text-weak, #333333);opacity:.4;border-radius:50%;display:flex;align-items:center;justify-content:center}.devui-backtop-content:hover{opacity:1}\n"] }] }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }], propDecorators: { customTemplate: [{ type: Input }], visibleHeight: [{ type: Input }], bottom: [{ type: Input }], right: [{ type: Input }], scrollTarget: [{ type: Input }], draggable: [{ type: Input }], backTopEvent: [{ type: Output }], dragEvent: [{ type: Output }], onMouseUp: [{ type: HostListener, args: ['document:mouseup', []] }], onMouseMove: [{ type: HostListener, args: ['document:mousemove', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFjay10b3AuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2dWkvYmFjay10b3AvYmFjay10b3AuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vZGV2dWkvYmFjay10b3AvYmFjay10b3AuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUlMLE1BQU0sRUFFTixXQUFXLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUFTOUMsTUFBTSxPQUFPLGdCQUFnQjtJQXlCM0IsWUFBb0IsR0FBc0IsRUFBVSxFQUFjLEVBQTRCLEdBQVE7UUFBbEYsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQTRCLFFBQUcsR0FBSCxHQUFHLENBQUs7UUF2QjdGLGtCQUFhLEdBQUcsR0FBRyxDQUFDO1FBQ3BCLFdBQU0sR0FBRyxNQUFNLENBQUM7UUFDaEIsVUFBSyxHQUFHLE1BQU0sQ0FBQztRQUVmLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDakIsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBQzNDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBRWxELGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFHYixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsY0FB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O1lBQ25DLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNwQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7K0dBL01VLGdCQUFnQiw2RUF5QmlELFFBQVE7bUdBekJ6RSxnQkFBZ0IseVpDNUI3Qixrd0RBa0NBOzs0RkROYSxnQkFBZ0I7a0JBUDVCLFNBQVM7K0JBQ0UsWUFBWSxtQkFHTCx1QkFBdUIsQ0FBQyxNQUFNLHVCQUMxQixLQUFLOzswQkEyQjJDLE1BQU07MkJBQUMsUUFBUTt5Q0F4QjNFLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBZ0tQLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxFQUFFO2dCQWdCcEMsV0FBVztzQkFEVixZQUFZO3VCQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uRGVzdHJveSxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZC1iYWNrLXRvcCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2JhY2stdG9wLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9iYWNrLXRvcC5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQmFja1RvcENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xyXG4gIEBJbnB1dCgpIGN1c3RvbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBJbnB1dCgpIHZpc2libGVIZWlnaHQgPSAzMDA7XHJcbiAgQElucHV0KCkgYm90dG9tID0gJzUwcHgnO1xyXG4gIEBJbnB1dCgpIHJpZ2h0ID0gJzMwcHgnO1xyXG4gIEBJbnB1dCgpIHNjcm9sbFRhcmdldDogSFRNTEVsZW1lbnQ7XHJcbiAgQElucHV0KCkgZHJhZ2dhYmxlID0gZmFsc2U7XHJcbiAgQE91dHB1dCgpIGJhY2tUb3BFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuICBAT3V0cHV0KCkgZHJhZ0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG5cclxuICBjdXJyU2Nyb2xsVG9wID0gMDtcclxuICBkdXJhdGlvbiA9IDA7XHJcbiAgY3Vyc29yVGltZXI6IGFueTtcclxuICBkcmFnQm91bmRhcnk6IGFueTtcclxuICBtb3ZlQ3Vyc29yID0gZmFsc2U7XHJcbiAgbW92ZVRvZ2dsZSA9IGZhbHNlO1xyXG4gIGlzVmlzaWJsZSA9IGZhbHNlO1xyXG4gIHRhcmdldDogSFRNTEVsZW1lbnQgfCBXaW5kb3c7XHJcbiAgc3ViczogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG4gIGRvY3VtZW50OiBEb2N1bWVudDtcclxuXHJcbiAgU0NST0xMX1JFRlJFU0hfSU5URVJWQUwgPSAxMDA7XHJcbiAgTU9VU0VET1dOX0RFTEFZID0gMTgwO1xyXG4gIFJFU0laRV9ERUxBWSA9IDMwMDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIGVsOiBFbGVtZW50UmVmLCBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYzogYW55KSB7XHJcbiAgICB0aGlzLmRvY3VtZW50ID0gdGhpcy5kb2M7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlcy5zY3JvbGxUYXJnZXQpIHtcclxuICAgICAgaWYgKHRoaXMuc3Vicykge1xyXG4gICAgICAgIHRoaXMuc3Vicy51bnN1YnNjcmliZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuICAgICAgdGhpcy5hZGRTY3JvbGxFdmVudCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmFkZFNjcm9sbEV2ZW50KCk7XHJcbiAgICB0aGlzLnNob3dCdXR0b24oKTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRyYWdnYWJsZSkge1xyXG4gICAgICAvLyDnqpflj6PlpKflsI/mlLnlj5jml7bvvIzlpoLnvKnmlL7mr5TkvovmiJbnu4Tku7botoXlh7rmmL7npLrojIPlm7Tph43nva7liLDpu5jorqTkvY3nva5cclxuICAgICAgdGhpcy5zdWJzLmFkZChcclxuICAgICAgICBmcm9tRXZlbnQod2luZG93LCAncmVzaXplJylcclxuICAgICAgICAgIC5waXBlKGRlYm91bmNlVGltZSh0aGlzLlJFU0laRV9ERUxBWSkpXHJcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZG9tID0gdGhpcy5kcmFnQm91bmRhcnk/LmRvbSB8fCB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignZGl2LmRldnVpLWJhY2t0b3AnKTtcclxuICAgICAgICAgICAgaWYgKGRvbSkge1xyXG4gICAgICAgICAgICAgIC8vIOS4jeaYvuekuuaXtuaXoOazleiOt+WPlmdldEJvdW5kaW5nQ2xpZW50UmVjdCzkvb/nlKhzdHlsZeiOt+WPllxyXG4gICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShkb20pO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBwYXJzZUludChzdHlsZS5sZWZ0LCAxMCkgfHwgMDtcclxuICAgICAgICAgICAgICBjb25zdCB0b3AgPSBwYXJzZUludChzdHlsZS50b3AsIDEwKSB8fCAwO1xyXG4gICAgICAgICAgICAgIGlmICh3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyAhPT0gMSB8fCBsZWZ0ID4gd2luZG93LmlubmVyV2lkdGggfHwgdG9wID4gd2luZG93LmlubmVySGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uTW91c2VVcCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUubGVmdCA9ICd1bnNldCc7XHJcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUudG9wID0gJ3Vuc2V0JztcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnN1YnMpIHtcclxuICAgICAgdGhpcy5zdWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhZGRTY3JvbGxFdmVudCgpIHtcclxuICAgIHRoaXMuc3Vicy5hZGQoXHJcbiAgICAgIGZyb21FdmVudCh0aGlzLmdldFNjcm9sbFRhcmdldCgpLCAnc2Nyb2xsJylcclxuICAgICAgICAucGlwZShkZWJvdW5jZVRpbWUodGhpcy5TQ1JPTExfUkVGUkVTSF9JTlRFUlZBTCkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLnNob3dCdXR0b24oKTtcclxuICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGdldFNjcm9sbFRhcmdldCgpIHtcclxuICAgIGlmICh0aGlzLnNjcm9sbFRhcmdldCkge1xyXG4gICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmRldnVpLWJhY2t0b3AnKS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XHJcbiAgICAgIHRoaXMuc2Nyb2xsVGFyZ2V0LnBhcmVudEVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xyXG4gICAgfVxyXG4gICAgdGhpcy50YXJnZXQgPSB0aGlzLnNjcm9sbFRhcmdldCB8fCB3aW5kb3c7XHJcbiAgICByZXR1cm4gdGhpcy50YXJnZXQ7XHJcbiAgfVxyXG5cclxuICBzaG93QnV0dG9uKCkge1xyXG4gICAgdGhpcy5jdXJyU2Nyb2xsVG9wID1cclxuICAgICAgdGhpcy50YXJnZXQgPT09IHdpbmRvd1xyXG4gICAgICAgID8gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCB0aGlzLmRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wXHJcbiAgICAgICAgOiB0aGlzLnNjcm9sbFRhcmdldC5zY3JvbGxUb3A7XHJcbiAgICBpZiAodGhpcy5pc1Zpc2libGUgIT09IHRoaXMuY3VyclNjcm9sbFRvcCA+PSB0aGlzLnZpc2libGVIZWlnaHQpIHtcclxuICAgICAgdGhpcy5pc1Zpc2libGUgPSAhdGhpcy5pc1Zpc2libGU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnb1RvcCgpIHtcclxuICAgIGlmICh0aGlzLmRyYWdnYWJsZSAmJiB0aGlzLmR1cmF0aW9uID4gdGhpcy5NT1VTRURPV05fREVMQVkpIHtcclxuICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnRhcmdldCA9PT0gd2luZG93KSB7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ3N0YXJ0JywgaW5saW5lOiAnbmVhcmVzdCcgfSk7XHJcbiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdzdGFydCcsIGlubGluZTogJ25lYXJlc3QnIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zY3JvbGxUYXJnZXQuc3R5bGUuc2Nyb2xsQmVoYXZpb3IgPSAnc21vb3RoJztcclxuICAgICAgdGhpcy5zY3JvbGxUYXJnZXQuc2Nyb2xsVG9wID0gMDtcclxuICAgIH1cclxuICAgIHRoaXMuZHVyYXRpb24gPSAwO1xyXG4gICAgdGhpcy5iYWNrVG9wRXZlbnQuZW1pdCh0cnVlKTtcclxuICB9XHJcblxyXG4gIHNldERyYWdCb3VuZGFyeSgpIHtcclxuICAgIGNvbnN0IGRvbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdkaXYuZGV2dWktYmFja3RvcCcpO1xyXG4gICAgbGV0IGJveFJlY3Q7XHJcbiAgICBsZXQgbWluTGVmdDtcclxuICAgIGxldCBtaW5Ub3A7XHJcbiAgICBsZXQgbWF4TGVmdDtcclxuICAgIGxldCBtYXhUb3A7XHJcbiAgICBpZiAoZG9tKSB7XHJcbiAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBpZiAodGhpcy5zY3JvbGxUYXJnZXQpIHtcclxuICAgICAgICBib3hSZWN0ID0gdGhpcy5zY3JvbGxUYXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgbWluTGVmdCA9IC0xICogYm94UmVjdC54O1xyXG4gICAgICAgIG1pblRvcCA9IC0xICogYm94UmVjdC55O1xyXG4gICAgICAgIG1heExlZnQgPSB3aW5kb3cuaW5uZXJXaWR0aCAtIGJveFJlY3QueCAtIHdpZHRoO1xyXG4gICAgICAgIG1heFRvcCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIGJveFJlY3QueSAtIGhlaWdodDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBib3hSZWN0ID0geyB4OiAwLCB5OiAwIH07XHJcbiAgICAgICAgbWluTGVmdCA9IDA7XHJcbiAgICAgICAgbWluVG9wID0gMDtcclxuICAgICAgICBtYXhMZWZ0ID0gd2luZG93LmlubmVyV2lkdGggLSB3aWR0aDtcclxuICAgICAgICBtYXhUb3AgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSBoZWlnaHQ7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5kcmFnQm91bmRhcnkgPSB7IGRvbSwgYm94UmVjdCwgbWluTGVmdCwgbWluVG9wLCBtYXhMZWZ0LCBtYXhUb3AgfTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIG1vdXNlZG93biBtb3VzZXVwIGNsaWNrIOaMiemhuuW6j+inpuWPkeS4lOWJjeS4gOS4que7k+adn+inpuWPkeS4i+S4gOS4qlxyXG4gIG1vdXNlZG93bkV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdGhpcy5zZXREcmFnQm91bmRhcnkoKTtcclxuICAgICAgdGhpcy5kdXJhdGlvbiA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xyXG4gICAgICB0aGlzLm1vdmVUb2dnbGUgPSB0cnVlO1xyXG4gICAgICB0aGlzLmN1cnNvclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5tb3ZlQ3Vyc29yID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmRyYWdFdmVudC5lbWl0KHRydWUpO1xyXG4gICAgICB9LCB0aGlzLk1PVVNFRE9XTl9ERUxBWSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBtb3VzZWxlYXZlRXZlbnQoKSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUgJiYgdGhpcy5jdXJzb3JUaW1lcikge1xyXG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jdXJzb3JUaW1lcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZXVwJywgW10pXHJcbiAgb25Nb3VzZVVwKCkge1xyXG4gICAgaWYgKHRoaXMuZHJhZ2dhYmxlKSB7XHJcbiAgICAgIGlmICh0aGlzLmN1cnNvclRpbWVyKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuY3Vyc29yVGltZXIpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLm1vdmVUb2dnbGUpIHtcclxuICAgICAgICB0aGlzLm1vdmVUb2dnbGUgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLm1vdmVDdXJzb3IgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmRyYWdFdmVudC5lbWl0KGZhbHNlKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmR1cmF0aW9uID0gdGhpcy5kdXJhdGlvbiAmJiBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuZHVyYXRpb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnZ2FibGUgJiYgdGhpcy5tb3ZlVG9nZ2xlICYmIHRoaXMuZHJhZ0JvdW5kYXJ5KSB7XHJcbiAgICAgIC8vIOWFiOWIpOaWreWGjeaJp+ihjOmYu+atoum7mOiupOS6i+S7tu+8jOWQpuWImeWPr+iDveW9seWTjem8oOagh+aLlumAieWKn+iDvVxyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB0aGlzLm1vdmVDdXJzb3IgPSB0cnVlO1xyXG4gICAgICBjb25zdCBwb3NYID0gZXZlbnQubW92ZW1lbnRYO1xyXG4gICAgICBjb25zdCBwb3NZID0gZXZlbnQubW92ZW1lbnRZO1xyXG4gICAgICBjb25zdCByZWN0ID0gdGhpcy5kcmFnQm91bmRhcnkuZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBjb25zdCBsZWZ0ID0gcmVjdC54IC0gdGhpcy5kcmFnQm91bmRhcnkuYm94UmVjdC54ICsgcG9zWDtcclxuICAgICAgY29uc3QgdG9wID0gcmVjdC55IC0gdGhpcy5kcmFnQm91bmRhcnkuYm94UmVjdC55ICsgcG9zWTtcclxuICAgICAgY29uc3QgaXNMZWZ0ID0gbGVmdCA8IHRoaXMuZHJhZ0JvdW5kYXJ5Lm1pbkxlZnQ7XHJcbiAgICAgIGNvbnN0IGlzUmlnaHQgPSBsZWZ0ID4gdGhpcy5kcmFnQm91bmRhcnkubWF4TGVmdDtcclxuICAgICAgY29uc3QgaXNUb3AgPSB0b3AgPCB0aGlzLmRyYWdCb3VuZGFyeS5taW5Ub3A7XHJcbiAgICAgIGNvbnN0IGlzQm90dG9tID0gdG9wID4gdGhpcy5kcmFnQm91bmRhcnkubWF4VG9wO1xyXG4gICAgICBjb25zdCBsZWZ0UmVzdWx0ID0gaXNMZWZ0ID8gdGhpcy5kcmFnQm91bmRhcnkubWluTGVmdCA6IGxlZnQ7XHJcbiAgICAgIGNvbnN0IHRvcFJlc3VsdCA9IGlzVG9wID8gdGhpcy5kcmFnQm91bmRhcnkubWluVG9wIDogdG9wO1xyXG4gICAgICB0aGlzLmRyYWdCb3VuZGFyeS5kb20uc3R5bGUubGVmdCA9IGAke2lzUmlnaHQgPyB0aGlzLmRyYWdCb3VuZGFyeS5tYXhMZWZ0IDogbGVmdFJlc3VsdH1weGA7XHJcbiAgICAgIHRoaXMuZHJhZ0JvdW5kYXJ5LmRvbS5zdHlsZS50b3AgPSBgJHtpc0JvdHRvbSA/IHRoaXMuZHJhZ0JvdW5kYXJ5Lm1heFRvcCA6IHRvcFJlc3VsdH1weGA7XHJcbiAgICAgIC8vIOWmguWIsOi+vui+ueeVjOmHiuaUvuaLluaLveWKqOS9nO+8jOmBv+WFjem8oOagh+WBj+enu+i+g+Wkp+i3neemu+WQjui/lOWbnuS4u+inhueql+S7jeWPr+aLluaLvVxyXG4gICAgICBpZiAoW2lzTGVmdCwgaXNSaWdodCwgaXNUb3AsIGlzQm90dG9tXS5pbmNsdWRlcyh0cnVlKSkge1xyXG4gICAgICAgIHRoaXMub25Nb3VzZVVwKCk7XHJcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDA7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdlxuICBjbGFzcz1cImRldnVpLWJhY2t0b3BcIlxuICBbbmdTdHlsZV09XCJ7XG4gICAgZGlzcGxheTogaXNWaXNpYmxlID8gJ2Jsb2NrJyA6ICdub25lJyxcbiAgICBib3R0b206IGJvdHRvbSxcbiAgICByaWdodDogcmlnaHQsXG4gICAgY3Vyc29yOiBtb3ZlQ3Vyc29yICYmIGRyYWdnYWJsZSA/ICdtb3ZlJyA6ICdwb2ludGVyJ1xuICB9XCJcbiAgKGNsaWNrKT1cImdvVG9wKClcIlxuPlxuICA8ZGl2IGNsYXNzPVwiZGV2dWktYmFja3RvcC1kcmFnLWhhbmRsZVwiIChtb3VzZWRvd24pPVwibW91c2Vkb3duRXZlbnQoJGV2ZW50KVwiIChtb3VzZWxlYXZlKT1cIm1vdXNlbGVhdmVFdmVudCgpXCI+XG4gICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImN1c3RvbVRlbXBsYXRlID8gY3VzdG9tVGVtcGxhdGUgOiBkZWZhdWx0XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHQ+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGV2dWktYmFja3RvcC1jb250ZW50XCI+XG4gICAgICAgIDxzdmdcbiAgICAgICAgICB3aWR0aD1cIjE2cHhcIlxuICAgICAgICAgIGhlaWdodD1cIjE2cHhcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuICAgICAgICAgIHZlcnNpb249XCIxLjFcIlxuICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICAgIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICAgID5cbiAgICAgICAgICA8ZyBzdHJva2U9XCJub25lXCIgc3Ryb2tlLXdpZHRoPVwiMVwiIGZpbGw9XCJub25lXCIgZmlsbC1ydWxlPVwiZXZlbm9kZFwiPlxuICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgZD1cIk04LjcxMzM1OTMxLDE1LjI4NjUyOTcgQzguNjExNzk2ODMsMTYuMjA5MDYwOSA3LjMyMjkzNzU4LDE2LjEyNjc5NTMgNy4yNzMwNDY5NSwxNS4yODY1Mjk3IEM3LjI3MTc1MDA4LDE0LjY0NzUxNDIgNy4yNzE3NTAwOCw1LjI2NDc5NjM2IDcuMjcxNzUwMDgsNS4yNjQ3OTYzNiBMMi44MzY3NTA1Miw5LjU0NTQ4MzQ0IEMyLjE0MTg1OTk1LDEwLjE0NDA2MTUgMS4zMTQzMjg4LDkuMTg3MzExNTkgMS44MzEzNTk5OCw4LjU1NzczMzUzIEMzLjc5NTU3ODU1LDYuNjUzMTA4NzIgNy4zMjAyNjU3LDMuMjQ1MTU1OTIgNy40MDE3OTY5NCwzLjE2NjMyNzgxIEM3LjcyNjk2ODc4LDIuODEzMDYyMjIgOC4yMzg4NzQ5OCwyLjc5NDc2NTM0IDguNTg0OTUzMDgsMy4xNjYzMjc4MSBDOS4yMzE5MzczOSwzLjc5MTkyMTUgMTQuMDMzNDA1Nyw4LjQyMTQ2NzkyIDE0LjE3OTE1NTcsOC41ODgwNDYwMyBDMTQuNjY2MTQsOS4xOTMzODk3MiAxMy44Nzg3ODA3LDEwLjA4OTIwMjEgMTMuMjA2NjA4OSw5LjU4NDUxNDY5IEMxMy4wMzI5NjgzLDkuNDM3MTcwOTUgOC43MTQ2ODc0NCw1LjI2NDYyNDQ4IDguNzE0Njg3NDQsNS4yNjQ2MjQ0OCBMOC43MTMzNTkzMSwxNS4yODY1Mjk3IFogTTEuODE4Njg4MTEsLTguNTQ4NzE3MjllLTE0IEwxNC4xMDc1NjE5LC04LjU0ODcxNzI5ZS0xNCBMMTQuMTA3NTYxOSwxLjM5NTA5MzYxIEwxLjgxODY4ODExLDEuMzk1MDkzNjEgTDEuODE4Njg4MTEsLTguNTQ4NzE3MjllLTE0IFpcIlxuICAgICAgICAgICAgICBmaWxsPVwiI0ZGRkZGRlwiXG4gICAgICAgICAgICAgIGZpbGwtcnVsZT1cIm5vbnplcm9cIlxuICAgICAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgICA8L2c+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==