UNPKG

ng-cw-v12

Version:

Angular UI component library

164 lines 24.8 kB
import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "@angular/common"; export class DockComponent { constructor(sanitizer) { this.sanitizer = sanitizer; // 图标尺寸 this.ncSize = 40; // 鼠标到最远放大图标的距离 this.ncDistance = 140; // 展示模式 this.ncMode = 'distance'; // 相对于ncSize放大或间隙的倍数 this.ncMultiple = 1.5; // 主题 this.ncTheme = 'light'; // 方向 this.ncDirection = 'horizontal'; // 分割线 this.ncDividerIndex = []; // 提示文本 this.ncTooltip = []; // 提示文本位置 this.ncTooltipPosition = 'top'; // hover效果 this._hover = false; // 图标列表 this._items = []; // 图标点击事件 this.ncClick = new EventEmitter(); this.mouseXY = Infinity; this.iconScales = []; this.isAnimating = false; this.animationFrameId = null; } set ncHover(val) { this._hover = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncHover() { return this._hover; } set ncItems(value) { this._items = value; setTimeout(() => { this.resetIconScales(); }); } get ncItems() { return this._items; } ngOnInit() { } ngOnDestroy() { if (this.animationFrameId !== null) { cancelAnimationFrame(this.animationFrameId); } } resetIconScales() { this.iconScales = this.ncItems.map(() => this.ncSize); } onMouseMove(event) { if (this.ncDirection === 'horizontal') { this.mouseXY = event.clientX; } else { this.mouseXY = event.clientY; } // 使用requestAnimationFrame优化性能 if (!this.isAnimating) { this.isAnimating = true; this.animationFrameId = requestAnimationFrame(() => { this.updateIconScales(); this.isAnimating = false; }); } } onMouseLeave() { this.mouseXY = Infinity; this.resetIconScales(); } updateIconScales() { const icons = this.dockContainer.nativeElement.querySelectorAll('.dock-icon'); icons.forEach((icon, index) => { const iconRect = icon.getBoundingClientRect(); let iconCenter = 0; if (this.ncDirection == 'horizontal') { iconCenter = iconRect.left + iconRect.width / 2; } else { iconCenter = iconRect.top + iconRect.height / 2; } const distance = Math.abs(this.mouseXY - iconCenter); let scale = this.ncSize; if (distance < this.ncDistance) { const magnificationDelta = this.ncMultiple * this.ncSize - this.ncSize; // 使用平滑的二次函数曲线使效果更自然 const distanceRatio = 1 - Math.pow(distance / this.ncDistance, 2); scale = this.ncSize + (magnificationDelta * distanceRatio); } // 不再使用Angular动画API,改为直接设置样式值让CSS过渡处理 this.iconScales[index] = scale; }); } onIconClick(index) { this.ncClick.emit(index); } /** * 检查项目是否为SVG内容 */ isSvgContent(item) { return !!item && (typeof item === 'string') && (item.trim().startsWith('<svg') || item.trim().startsWith('<?xml')); } /** * 返回安全处理后的SVG内容 */ getSanitizedSvg(svg) { return this.sanitizer.bypassSecurityTrustHtml(svg); } } DockComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: DockComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component }); DockComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: DockComponent, selector: "nc-dock", inputs: { ncSize: "ncSize", ncDistance: "ncDistance", ncMode: "ncMode", ncMultiple: "ncMultiple", ncTheme: "ncTheme", ncDirection: "ncDirection", ncDividerIndex: "ncDividerIndex", ncTooltip: "ncTooltip", ncTooltipPosition: "ncTooltipPosition", ncHover: "ncHover", ncItems: "ncItems" }, outputs: { ncClick: "ncClick" }, host: { listeners: { "mousemove": "onMouseMove($event)", "mouseleave": "onMouseLeave()" } }, viewQueries: [{ propertyName: "dockContainer", first: true, predicate: ["dockContainer"], descendants: true }], ngImport: i0, template: "<div #dockContainer style=\"--size: {{ncSize}};\" class=\"dock-container\"\r\n [ngClass]=\"{'light-mode': ncTheme === 'light', 'dark-mode': ncTheme === 'dark', 'horizontal-mode': ncDirection === 'horizontal', 'vertical-mode': ncDirection === 'vertical'}\">\r\n <ng-container *ngFor=\"let item of ncItems; let i = index\">\r\n <div class=\"dock-icon\" [ngStyle]=\"{'width': iconScales[i] + 'px', 'height': iconScales[i] + 'px'}\">\r\n <div class=\"icon-image-container\"\r\n [ngClass]=\"{'magnification-mode': ncMode === 'magnification', 'distance-mode': ncMode === 'distance', 'hover-mode': ncHover}\"\r\n (click)=\"onIconClick(i)\">\r\n <ng-container *ngIf=\"isSvgContent(item); else imageTemplate\">\r\n <div class=\"dock-icon-image\" [innerHTML]=\"getSanitizedSvg(item)\"></div>\r\n </ng-container>\r\n <ng-template #imageTemplate>\r\n <img [src]=\"item\" class=\"dock-icon-image\">\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"ncTooltip && ncTooltip[i]\" class=\"dock-tooltip\" [ngClass]=\"'tooltip-' + ncTooltipPosition\">\r\n {{ ncTooltip[i] }}\r\n </div>\r\n </div>\r\n <div class=\"dock-divider\" *ngIf=\"ncDividerIndex.includes(i)\"></div>\r\n </ng-container>\r\n</div>", styles: [".dock-container{display:flex;align-items:center;justify-content:center;grid-gap:calc(var(--size) * .2px);gap:calc(var(--size) * .2px);border-radius:calc(var(--size) * .4px);padding:calc(var(--size) * .2px);-webkit-backdrop-filter:blur(calc(var(--size) * .3px));backdrop-filter:blur(calc(var(--size) * .3px));position:relative;will-change:contents}.dock-container.horizontal-mode{flex-direction:row;height:calc(var(--size) * 1.4px + 2px);width:max-content}.dock-container.horizontal-mode .dock-divider{width:1px;height:100%}.dock-container.vertical-mode{flex-direction:column;height:max-content;width:calc(var(--size) * 1.4px + 2px)}.dock-container.vertical-mode .dock-divider{width:100%;height:1px}.dock-container.light-mode{background-color:#ffffff1a;border:1px solid rgba(0,0,0,.1)}.dock-container.light-mode .icon-image-container.hover-mode:hover{background-color:#0000001a}.dock-container.light-mode .dock-divider{background-color:#0000001a}.dock-container.light-mode .dock-tooltip{background-color:#000000bf;color:#fff}.dock-container.dark-mode{background-color:#0000001a;border:1px solid rgba(255,255,255,.2)}.dock-container.dark-mode .icon-image-container.hover-mode:hover{background-color:#fff3}.dock-container.dark-mode .dock-divider{background-color:#fff3}.dock-container.dark-mode .dock-tooltip{background-color:#434343;color:#fff}.dock-container .dock-icon{display:flex;align-items:center;justify-content:center;aspect-ratio:1;transition:width .3s cubic-bezier(.34,1.56,.64,1),height .3s cubic-bezier(.34,1.56,.64,1);overflow:visible;position:relative;transform:translateZ(0)}.dock-container .dock-icon:hover .dock-tooltip{opacity:1}.dock-container .dock-icon .icon-image-container{display:flex;align-items:center;justify-content:center;padding:calc(var(--size) * .2px);border-radius:50%;cursor:pointer;transition:background-color .2s ease;position:relative}.dock-container .dock-icon .icon-image-container.distance-mode .dock-icon-image{width:calc(var(--size) * .6px);height:calc(var(--size) * .6px)}.dock-container .dock-icon .icon-image-container.magnification-mode{width:100%;height:100%}.dock-container .dock-icon .icon-image-container.magnification-mode .dock-icon-image{width:100%;height:100%}.dock-container .dock-icon .icon-image-container .dock-icon-image{object-fit:contain;pointer-events:none;transform:translateZ(0);display:flex;align-items:center;justify-content:center}.dock-container .dock-icon .dock-tooltip{position:absolute;padding:calc(var(--size) * .15px) calc(var(--size) * .3px);border-radius:calc(var(--size) * .15px);font-size:calc(var(--size) * .35px);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .2s ease,transform .2s ease;z-index:100;box-shadow:0 calc(var(--size) * .05px) calc(var(--size) * .1px) #0003}.dock-container .dock-icon .dock-tooltip.tooltip-top{bottom:100%;left:50%;transform:translate(-50%) translateY(0)}.dock-container .dock-icon .dock-tooltip.tooltip-bottom{top:100%;left:50%;transform:translate(-50%) translateY(0)}.dock-container .dock-icon .dock-tooltip.tooltip-left{right:100%;top:50%;transform:translateY(-50%) translate(0)}.dock-container .dock-icon .dock-tooltip.tooltip-right{left:100%;top:50%;transform:translateY(-50%) translate(0)}\n"], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: DockComponent, decorators: [{ type: Component, args: [{ selector: 'nc-dock', templateUrl: './dock.component.html', styleUrls: ['./dock.component.less'], }] }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; }, propDecorators: { ncSize: [{ type: Input }], ncDistance: [{ type: Input }], ncMode: [{ type: Input }], ncMultiple: [{ type: Input }], ncTheme: [{ type: Input }], ncDirection: [{ type: Input }], ncDividerIndex: [{ type: Input }], ncTooltip: [{ type: Input }], ncTooltipPosition: [{ type: Input }], ncHover: [{ type: Input }], ncItems: [{ type: Input }], ncClick: [{ type: Output }], dockContainer: [{ type: ViewChild, args: ['dockContainer'] }], onMouseMove: [{ type: HostListener, args: ['mousemove', ['$event']] }], onMouseLeave: [{ type: HostListener, args: ['mouseleave'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2RvY2svZG9jay5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2RvY2svZG9jay5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7O0FBUS9ILE1BQU0sT0FBTyxhQUFhO0lBa0R4QixZQUFvQixTQUF1QjtRQUF2QixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBakQzQyxPQUFPO1FBQ0UsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQUM3QixlQUFlO1FBQ04sZUFBVSxHQUFXLEdBQUcsQ0FBQztRQUNsQyxPQUFPO1FBQ0UsV0FBTSxHQUFpQyxVQUFVLENBQUE7UUFDMUQsb0JBQW9CO1FBQ1gsZUFBVSxHQUFXLEdBQUcsQ0FBQztRQUNsQyxLQUFLO1FBQ0ksWUFBTyxHQUFxQixPQUFPLENBQUM7UUFDN0MsS0FBSztRQUNJLGdCQUFXLEdBQThCLFlBQVksQ0FBQztRQUMvRCxNQUFNO1FBQ0csbUJBQWMsR0FBYSxFQUFFLENBQUM7UUFDdkMsT0FBTztRQUNFLGNBQVMsR0FBYSxFQUFFLENBQUM7UUFDbEMsU0FBUztRQUNBLHNCQUFpQixHQUF3QyxLQUFLLENBQUM7UUFDeEUsVUFBVTtRQUNGLFdBQU0sR0FBWSxLQUFLLENBQUM7UUFRaEMsT0FBTztRQUNDLFdBQU0sR0FBYSxFQUFFLENBQUM7UUFXOUIsU0FBUztRQUNDLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBSXZDLFlBQU8sR0FBRyxRQUFRLENBQUM7UUFDM0IsZUFBVSxHQUFhLEVBQUUsQ0FBQztRQUNsQixnQkFBVyxHQUFHLEtBQUssQ0FBQztR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ZCxLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsY0FBYztzQkFBdEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFJRixPQUFPO3NCQURWLEtBQUs7Z0JBVUYsT0FBTztzQkFEVixLQUFLO2dCQVdJLE9BQU87c0JBQWhCLE1BQU07Z0JBRXFCLGFBQWE7c0JBQXhDLFNBQVM7dUJBQUMsZUFBZTtnQkF1QjFCLFdBQVc7c0JBRFYsWUFBWTt1QkFBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBbUJyQyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlSHRtbCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYy1kb2NrJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZG9jay5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZG9jay5jb21wb25lbnQubGVzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRG9ja0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAvLyDlm77moIflsLrlr7hcclxuICBASW5wdXQoKSBuY1NpemU6IG51bWJlciA9IDQwO1xyXG4gIC8vIOm8oOagh+WIsOacgOi/nOaUvuWkp+Wbvuagh+eahOi3neemu1xyXG4gIEBJbnB1dCgpIG5jRGlzdGFuY2U6IG51bWJlciA9IDE0MDtcclxuICAvLyDlsZXnpLrmqKHlvI9cclxuICBASW5wdXQoKSBuY01vZGU6ICdkaXN0YW5jZScgfCAnbWFnbmlmaWNhdGlvbicgPSAnZGlzdGFuY2UnXHJcbiAgLy8g55u45a+55LqObmNTaXpl5pS+5aSn5oiW6Ze06ZqZ55qE5YCN5pWwXHJcbiAgQElucHV0KCkgbmNNdWx0aXBsZTogbnVtYmVyID0gMS41O1xyXG4gIC8vIOS4u+mimFxyXG4gIEBJbnB1dCgpIG5jVGhlbWU6ICdsaWdodCcgfCAnZGFyaycgPSAnbGlnaHQnO1xyXG4gIC8vIOaWueWQkVxyXG4gIEBJbnB1dCgpIG5jRGlyZWN0aW9uOiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnID0gJ2hvcml6b250YWwnO1xyXG4gIC8vIOWIhuWJsue6v1xyXG4gIEBJbnB1dCgpIG5jRGl2aWRlckluZGV4OiBudW1iZXJbXSA9IFtdO1xyXG4gIC8vIOaPkOekuuaWh+acrFxyXG4gIEBJbnB1dCgpIG5jVG9vbHRpcDogc3RyaW5nW10gPSBbXTtcclxuICAvLyDmj5DnpLrmlofmnKzkvY3nva5cclxuICBASW5wdXQoKSBuY1Rvb2x0aXBQb3NpdGlvbjogJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JyB8ICdyaWdodCcgPSAndG9wJztcclxuICAvLyBob3ZlcuaViOaenFxyXG4gIHByaXZhdGUgX2hvdmVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KClcclxuICBzZXQgbmNIb3Zlcih2YWw6IGJvb2xlYW4gfCBzdHJpbmcpIHtcclxuICAgIHRoaXMuX2hvdmVyID0gdmFsICE9PSBudWxsICYmIHZhbCAhPT0gdW5kZWZpbmVkICYmIHZhbCAhPT0gZmFsc2UgJiYgdmFsICE9PSAnZmFsc2UnO1xyXG4gIH1cclxuICBnZXQgbmNIb3ZlcigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLl9ob3ZlcjtcclxuICB9XHJcbiAgLy8g5Zu+5qCH5YiX6KGoXHJcbiAgcHJpdmF0ZSBfaXRlbXM6IHN0cmluZ1tdID0gW107XHJcbiAgQElucHV0KClcclxuICBzZXQgbmNJdGVtcyh2YWx1ZTogc3RyaW5nW10pIHtcclxuICAgIHRoaXMuX2l0ZW1zID0gdmFsdWU7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgdGhpcy5yZXNldEljb25TY2FsZXMoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuICBnZXQgbmNJdGVtcygpOiBzdHJpbmdbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5faXRlbXM7XHJcbiAgfVxyXG4gIC8vIOWbvuagh+eCueWHu+S6i+S7tlxyXG4gIEBPdXRwdXQoKSBuY0NsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2RvY2tDb250YWluZXInKSBkb2NrQ29udGFpbmVyITogRWxlbWVudFJlZjtcclxuXHJcbiAgcHJpdmF0ZSBtb3VzZVhZID0gSW5maW5pdHk7XHJcbiAgaWNvblNjYWxlczogbnVtYmVyW10gPSBbXTtcclxuICBwcml2YXRlIGlzQW5pbWF0aW5nID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBhbmltYXRpb25GcmFtZUlkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcikgeyB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5hbmltYXRpb25GcmFtZUlkICE9PSBudWxsKSB7XHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0aW9uRnJhbWVJZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0SWNvblNjYWxlcygpOiB2b2lkIHtcclxuICAgIHRoaXMuaWNvblNjYWxlcyA9IHRoaXMubmNJdGVtcy5tYXAoKCkgPT4gdGhpcy5uY1NpemUpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlTW92ZShldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMubmNEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xyXG4gICAgICB0aGlzLm1vdXNlWFkgPSBldmVudC5jbGllbnRYO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5tb3VzZVhZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDkvb/nlKhyZXF1ZXN0QW5pbWF0aW9uRnJhbWXkvJjljJbmgKfog71cclxuICAgIGlmICghdGhpcy5pc0FuaW1hdGluZykge1xyXG4gICAgICB0aGlzLmlzQW5pbWF0aW5nID0gdHJ1ZTtcclxuICAgICAgdGhpcy5hbmltYXRpb25GcmFtZUlkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICB0aGlzLnVwZGF0ZUljb25TY2FsZXMoKTtcclxuICAgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScpXHJcbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5tb3VzZVhZID0gSW5maW5pdHk7XHJcbiAgICB0aGlzLnJlc2V0SWNvblNjYWxlcygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVJY29uU2NhbGVzKCk6IHZvaWQge1xyXG4gICAgY29uc3QgaWNvbnMgPSB0aGlzLmRvY2tDb250YWluZXIubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZG9jay1pY29uJyk7XHJcblxyXG4gICAgaWNvbnMuZm9yRWFjaCgoaWNvbjogSFRNTEVsZW1lbnQsIGluZGV4OiBudW1iZXIpID0+IHtcclxuICAgICAgY29uc3QgaWNvblJlY3QgPSBpY29uLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBsZXQgaWNvbkNlbnRlciA9IDA7XHJcbiAgICAgIGlmICh0aGlzLm5jRGlyZWN0aW9uID09ICdob3Jpem9udGFsJykge1xyXG4gICAgICAgIGljb25DZW50ZXIgPSBpY29uUmVjdC5sZWZ0ICsgaWNvblJlY3Qud2lkdGggLyAyO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGljb25DZW50ZXIgPSBpY29uUmVjdC50b3AgKyBpY29uUmVjdC5oZWlnaHQgLyAyO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tb3VzZVhZIC0gaWNvbkNlbnRlcik7XHJcblxyXG4gICAgICBsZXQgc2NhbGUgPSB0aGlzLm5jU2l6ZTtcclxuICAgICAgaWYgKGRpc3RhbmNlIDwgdGhpcy5uY0Rpc3RhbmNlKSB7XHJcbiAgICAgICAgY29uc3QgbWFnbmlmaWNhdGlvbkRlbHRhID0gdGhpcy5uY011bHRpcGxlICogdGhpcy5uY1NpemUgLSB0aGlzLm5jU2l6ZTtcclxuICAgICAgICAvLyDkvb/nlKjlubPmu5HnmoTkuozmrKHlh73mlbDmm7Lnur/kvb/mlYjmnpzmm7Toh6rnhLZcclxuICAgICAgICBjb25zdCBkaXN0YW5jZVJhdGlvID0gMSAtIE1hdGgucG93KGRpc3RhbmNlIC8gdGhpcy5uY0Rpc3RhbmNlLCAyKTtcclxuICAgICAgICBzY2FsZSA9IHRoaXMubmNTaXplICsgKG1hZ25pZmljYXRpb25EZWx0YSAqIGRpc3RhbmNlUmF0aW8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyDkuI3lho3kvb/nlKhBbmd1bGFy5Yqo55S7QVBJ77yM5pS55Li655u05o6l6K6+572u5qC35byP5YC86K6pQ1NT6L+H5rih5aSE55CGXHJcbiAgICAgIHRoaXMuaWNvblNjYWxlc1tpbmRleF0gPSBzY2FsZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25JY29uQ2xpY2soaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5uY0NsaWNrLmVtaXQoaW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5qOA5p+l6aG555uu5piv5ZCm5Li6U1ZH5YaF5a65XHJcbiAgICovXHJcbiAgaXNTdmdDb250ZW50KGl0ZW06IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuICEhaXRlbSAmJiAodHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSAmJiAoaXRlbS50cmltKCkuc3RhcnRzV2l0aCgnPHN2ZycpIHx8IGl0ZW0udHJpbSgpLnN0YXJ0c1dpdGgoJzw/eG1sJykpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog6L+U5Zue5a6J5YWo5aSE55CG5ZCO55qEU1ZH5YaF5a65XHJcbiAgICovXHJcbiAgZ2V0U2FuaXRpemVkU3ZnKHN2Zzogc3RyaW5nKTogU2FmZUh0bWwge1xyXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKHN2Zyk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgI2RvY2tDb250YWluZXIgc3R5bGU9XCItLXNpemU6IHt7bmNTaXplfX07XCIgY2xhc3M9XCJkb2NrLWNvbnRhaW5lclwiXHJcbiAgICBbbmdDbGFzc109XCJ7J2xpZ2h0LW1vZGUnOiBuY1RoZW1lID09PSAnbGlnaHQnLCAnZGFyay1tb2RlJzogbmNUaGVtZSA9PT0gJ2RhcmsnLCAnaG9yaXpvbnRhbC1tb2RlJzogbmNEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJywgJ3ZlcnRpY2FsLW1vZGUnOiBuY0RpcmVjdGlvbiA9PT0gJ3ZlcnRpY2FsJ31cIj5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbmNJdGVtczsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkb2NrLWljb25cIiBbbmdTdHlsZV09XCJ7J3dpZHRoJzogaWNvblNjYWxlc1tpXSArICdweCcsICdoZWlnaHQnOiBpY29uU2NhbGVzW2ldICsgJ3B4J31cIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImljb24taW1hZ2UtY29udGFpbmVyXCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbWFnbmlmaWNhdGlvbi1tb2RlJzogbmNNb2RlID09PSAnbWFnbmlmaWNhdGlvbicsICdkaXN0YW5jZS1tb2RlJzogbmNNb2RlID09PSAnZGlzdGFuY2UnLCAnaG92ZXItbW9kZSc6IG5jSG92ZXJ9XCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkljb25DbGljayhpKVwiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzU3ZnQ29udGVudChpdGVtKTsgZWxzZSBpbWFnZVRlbXBsYXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvY2staWNvbi1pbWFnZVwiIFtpbm5lckhUTUxdPVwiZ2V0U2FuaXRpemVkU3ZnKGl0ZW0pXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjaW1hZ2VUZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiaXRlbVwiIGNsYXNzPVwiZG9jay1pY29uLWltYWdlXCI+XHJcbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIm5jVG9vbHRpcCAmJiBuY1Rvb2x0aXBbaV1cIiBjbGFzcz1cImRvY2stdG9vbHRpcFwiIFtuZ0NsYXNzXT1cIid0b29sdGlwLScgKyBuY1Rvb2x0aXBQb3NpdGlvblwiPlxyXG4gICAgICAgICAgICAgICAge3sgbmNUb29sdGlwW2ldIH19XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkb2NrLWRpdmlkZXJcIiAqbmdJZj1cIm5jRGl2aWRlckluZGV4LmluY2x1ZGVzKGkpXCI+PC9kaXY+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuPC9kaXY+Il19