ng-cw-v12
Version:
Angular UI Component Library
158 lines • 24.7 kB
JavaScript
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.ncItems = [];
/** 图标点击事件 */
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;
}
ngOnChanges(changes) {
if (changes['ncItems']) {
this.resetIconScales();
}
}
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 }], usesOnChanges: true, ngImport: i0, template: "<div #dockContainer style=\"--size: {{ncSize}};\" class=\"dock-container\"\n [ngClass]=\"{'light-mode': ncTheme === 'light', 'dark-mode': ncTheme === 'dark', 'horizontal-mode': ncDirection === 'horizontal', 'vertical-mode': ncDirection === 'vertical'}\">\n <ng-container *ngFor=\"let item of ncItems; let i = index\">\n <div class=\"dock-icon\" [ngStyle]=\"{'width': iconScales[i] + 'px', 'height': iconScales[i] + 'px'}\">\n <div class=\"icon-image-container\"\n [ngClass]=\"{'magnification-mode': ncMode === 'magnification', 'distance-mode': ncMode === 'distance', 'hover-mode': ncHover}\"\n (click)=\"onIconClick(i)\">\n <ng-container *ngIf=\"isSvgContent(item); else imageTemplate\">\n <div class=\"dock-icon-image\" [innerHTML]=\"getSanitizedSvg(item)\"></div>\n </ng-container>\n <ng-template #imageTemplate>\n <img [src]=\"item\" class=\"dock-icon-image\">\n </ng-template>\n </div>\n <div *ngIf=\"ncTooltip && ncTooltip[i]\" class=\"dock-tooltip\" [ngClass]=\"'tooltip-' + ncTooltipPosition\">\n {{ ncTooltip[i] }}\n </div>\n </div>\n <div class=\"dock-divider\" *ngIf=\"ncDividerIndex.includes(i)\"></div>\n </ng-container>\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2RvY2svZG9jay5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL2RvY2svZG9jay5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBaUIsU0FBUyxFQUFhLE1BQU0sZUFBZSxDQUFDOzs7O0FBYWpKLE1BQU0sT0FBTyxhQUFhO0lBd0N4QixZQUFvQixTQUF1QjtRQUF2QixjQUFTLEdBQVQsU0FBUyxDQUFjO1FBdkMzQyxXQUFXO1FBQ0YsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQUM3QixtQkFBbUI7UUFDVixlQUFVLEdBQVcsR0FBRyxDQUFDO1FBQ2xDLFdBQVc7UUFDRixXQUFNLEdBQWUsVUFBVSxDQUFBO1FBQ3hDLHdCQUF3QjtRQUNmLGVBQVUsR0FBVyxHQUFHLENBQUM7UUFDbEMsU0FBUztRQUNBLFlBQU8sR0FBZ0IsT0FBTyxDQUFDO1FBQ3hDLFNBQVM7UUFDQSxnQkFBVyxHQUFvQixZQUFZLENBQUM7UUFDckQsVUFBVTtRQUNELG1CQUFjLEdBQWEsRUFBRSxDQUFDO1FBQ3ZDLFdBQVc7UUFDRixjQUFTLEdBQWEsRUFBRSxDQUFDO1FBQ2xDLGFBQWE7UUFDSixzQkFBaUIsR0FBMEIsS0FBSyxDQUFDO1FBQzFELGNBQWM7UUFDTixXQUFNLEdBQVksS0FBSyxDQUFDO1FBUWhDLFdBQVc7UUFDRixZQUFPLEdBQWEsRUFBRSxDQUFDO1FBQ2hDLGFBQWE7UUFDSCxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUl2QyxZQUFPLEdBQUcsUUFBUSxDQUFDO1FBQzNCLGVBQVUsR0FBYSxFQUFFLENBQUM7UUFDbEIsZ0JBQVcsR0FBRyxLQUFLLENBQUM7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O2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBSUYsT0FBTztzQkFEVixLQUFLO2dCQVFHLE9BQU87c0JBQWYsS0FBSztnQkFFSSxPQUFPO3NCQUFoQixNQUFNO2dCQUVxQixhQUFhO3NCQUF4QyxTQUFTO3VCQUFDLGVBQWU7Z0JBMEIxQixXQUFXO3NCQURWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQW1CckMsWUFBWTtzQkFEWCxZQUFZO3VCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZUh0bWwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcclxuXHJcbmV4cG9ydCB0eXBlIE5jTW9kZVR5cGUgPSAnZGlzdGFuY2UnIHwgJ21hZ25pZmljYXRpb24nO1xyXG5leHBvcnQgdHlwZSBOY1RoZW1lVHlwZSA9ICdsaWdodCcgfCAnZGFyayc7XHJcbmV4cG9ydCB0eXBlIE5jRGlyZWN0aW9uVHlwZSA9ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCc7XHJcbmV4cG9ydCB0eXBlIE5jVG9vbHRpcFBvc2l0aW9uVHlwZSA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYy1kb2NrJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZG9jay5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZG9jay5jb21wb25lbnQubGVzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRG9ja0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcclxuICAvKiog5Zu+5qCH5bC65a+4ICovXHJcbiAgQElucHV0KCkgbmNTaXplOiBudW1iZXIgPSA0MDtcclxuICAvKiog6byg5qCH5Yiw5pyA6L+c5pS+5aSn5Zu+5qCH55qE6Led56a7ICovXHJcbiAgQElucHV0KCkgbmNEaXN0YW5jZTogbnVtYmVyID0gMTQwO1xyXG4gIC8qKiDlsZXnpLrmqKHlvI8gKi9cclxuICBASW5wdXQoKSBuY01vZGU6IE5jTW9kZVR5cGUgPSAnZGlzdGFuY2UnXHJcbiAgLyoqIOebuOWvueS6jm5jU2l6ZeaUvuWkp+aIlumXtOmameeahOWAjeaVsCAqL1xyXG4gIEBJbnB1dCgpIG5jTXVsdGlwbGU6IG51bWJlciA9IDEuNTtcclxuICAvKiog5Li76aKYICovXHJcbiAgQElucHV0KCkgbmNUaGVtZTogTmNUaGVtZVR5cGUgPSAnbGlnaHQnO1xyXG4gIC8qKiDmlrnlkJEgKi9cclxuICBASW5wdXQoKSBuY0RpcmVjdGlvbjogTmNEaXJlY3Rpb25UeXBlID0gJ2hvcml6b250YWwnO1xyXG4gIC8qKiDliIblibLnur8gKi9cclxuICBASW5wdXQoKSBuY0RpdmlkZXJJbmRleDogbnVtYmVyW10gPSBbXTtcclxuICAvKiog5o+Q56S65paH5pysICovXHJcbiAgQElucHV0KCkgbmNUb29sdGlwOiBzdHJpbmdbXSA9IFtdO1xyXG4gIC8qKiDmj5DnpLrmlofmnKzkvY3nva4gKi9cclxuICBASW5wdXQoKSBuY1Rvb2x0aXBQb3NpdGlvbjogTmNUb29sdGlwUG9zaXRpb25UeXBlID0gJ3RvcCc7XHJcbiAgLyoqIGhvdmVy5pWI5p6cICovXHJcbiAgcHJpdmF0ZSBfaG92ZXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKVxyXG4gIHNldCBuY0hvdmVyKHZhbDogYm9vbGVhbiB8IHN0cmluZykge1xyXG4gICAgdGhpcy5faG92ZXIgPSB2YWwgIT09IG51bGwgJiYgdmFsICE9PSB1bmRlZmluZWQgJiYgdmFsICE9PSBmYWxzZSAmJiB2YWwgIT09ICdmYWxzZSc7XHJcbiAgfVxyXG4gIGdldCBuY0hvdmVyKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2hvdmVyO1xyXG4gIH1cclxuICAvKiog5Zu+5qCH5YiX6KGoICovXHJcbiAgQElucHV0KCkgbmNJdGVtczogc3RyaW5nW10gPSBbXTtcclxuICAvKiog5Zu+5qCH54K55Ye75LqL5Lu2ICovXHJcbiAgQE91dHB1dCgpIG5jQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnZG9ja0NvbnRhaW5lcicpIGRvY2tDb250YWluZXIhOiBFbGVtZW50UmVmO1xyXG5cclxuICBwcml2YXRlIG1vdXNlWFkgPSBJbmZpbml0eTtcclxuICBpY29uU2NhbGVzOiBudW1iZXJbXSA9IFtdO1xyXG4gIHByaXZhdGUgaXNBbmltYXRpbmcgPSBmYWxzZTtcclxuICBwcml2YXRlIGFuaW1hdGlvbkZyYW1lSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyKSB7IH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXNbJ25jSXRlbXMnXSkge1xyXG4gICAgICB0aGlzLnJlc2V0SWNvblNjYWxlcygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5hbmltYXRpb25GcmFtZUlkICE9PSBudWxsKSB7XHJcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0aW9uRnJhbWVJZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0SWNvblNjYWxlcygpOiB2b2lkIHtcclxuICAgIHRoaXMuaWNvblNjYWxlcyA9IHRoaXMubmNJdGVtcy5tYXAoKCkgPT4gdGhpcy5uY1NpemUpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlTW92ZShldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMubmNEaXJlY3Rpb24gPT09ICdob3Jpem9udGFsJykge1xyXG4gICAgICB0aGlzLm1vdXNlWFkgPSBldmVudC5jbGllbnRYO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5tb3VzZVhZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDkvb/nlKhyZXF1ZXN0QW5pbWF0aW9uRnJhbWXkvJjljJbmgKfog71cclxuICAgIGlmICghdGhpcy5pc0FuaW1hdGluZykge1xyXG4gICAgICB0aGlzLmlzQW5pbWF0aW5nID0gdHJ1ZTtcclxuICAgICAgdGhpcy5hbmltYXRpb25GcmFtZUlkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICB0aGlzLnVwZGF0ZUljb25TY2FsZXMoKTtcclxuICAgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScpXHJcbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5tb3VzZVhZID0gSW5maW5pdHk7XHJcbiAgICB0aGlzLnJlc2V0SWNvblNjYWxlcygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVJY29uU2NhbGVzKCk6IHZvaWQge1xyXG4gICAgY29uc3QgaWNvbnMgPSB0aGlzLmRvY2tDb250YWluZXIubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZG9jay1pY29uJyk7XHJcblxyXG4gICAgaWNvbnMuZm9yRWFjaCgoaWNvbjogSFRNTEVsZW1lbnQsIGluZGV4OiBudW1iZXIpID0+IHtcclxuICAgICAgY29uc3QgaWNvblJlY3QgPSBpY29uLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBsZXQgaWNvbkNlbnRlciA9IDA7XHJcbiAgICAgIGlmICh0aGlzLm5jRGlyZWN0aW9uID09ICdob3Jpem9udGFsJykge1xyXG4gICAgICAgIGljb25DZW50ZXIgPSBpY29uUmVjdC5sZWZ0ICsgaWNvblJlY3Qud2lkdGggLyAyO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGljb25DZW50ZXIgPSBpY29uUmVjdC50b3AgKyBpY29uUmVjdC5oZWlnaHQgLyAyO1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnModGhpcy5tb3VzZVhZIC0gaWNvbkNlbnRlcik7XHJcblxyXG4gICAgICBsZXQgc2NhbGUgPSB0aGlzLm5jU2l6ZTtcclxuICAgICAgaWYgKGRpc3RhbmNlIDwgdGhpcy5uY0Rpc3RhbmNlKSB7XHJcbiAgICAgICAgY29uc3QgbWFnbmlmaWNhdGlvbkRlbHRhID0gdGhpcy5uY011bHRpcGxlICogdGhpcy5uY1NpemUgLSB0aGlzLm5jU2l6ZTtcclxuICAgICAgICAvLyDkvb/nlKjlubPmu5HnmoTkuozmrKHlh73mlbDmm7Lnur/kvb/mlYjmnpzmm7Toh6rnhLZcclxuICAgICAgICBjb25zdCBkaXN0YW5jZVJhdGlvID0gMSAtIE1hdGgucG93KGRpc3RhbmNlIC8gdGhpcy5uY0Rpc3RhbmNlLCAyKTtcclxuICAgICAgICBzY2FsZSA9IHRoaXMubmNTaXplICsgKG1hZ25pZmljYXRpb25EZWx0YSAqIGRpc3RhbmNlUmF0aW8pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyDkuI3lho3kvb/nlKhBbmd1bGFy5Yqo55S7QVBJ77yM5pS55Li655u05o6l6K6+572u5qC35byP5YC86K6pQ1NT6L+H5rih5aSE55CGXHJcbiAgICAgIHRoaXMuaWNvblNjYWxlc1tpbmRleF0gPSBzY2FsZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgb25JY29uQ2xpY2soaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5uY0NsaWNrLmVtaXQoaW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog5qOA5p+l6aG555uu5piv5ZCm5Li6U1ZH5YaF5a65XHJcbiAgICovXHJcbiAgaXNTdmdDb250ZW50KGl0ZW06IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuICEhaXRlbSAmJiAodHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSAmJiAoaXRlbS50cmltKCkuc3RhcnRzV2l0aCgnPHN2ZycpIHx8IGl0ZW0udHJpbSgpLnN0YXJ0c1dpdGgoJzw/eG1sJykpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICog6L+U5Zue5a6J5YWo5aSE55CG5ZCO55qEU1ZH5YaF5a65XHJcbiAgICovXHJcbiAgZ2V0U2FuaXRpemVkU3ZnKHN2Zzogc3RyaW5nKTogU2FmZUh0bWwge1xyXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKHN2Zyk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgI2RvY2tDb250YWluZXIgc3R5bGU9XCItLXNpemU6IHt7bmNTaXplfX07XCIgY2xhc3M9XCJkb2NrLWNvbnRhaW5lclwiXG4gICAgW25nQ2xhc3NdPVwieydsaWdodC1tb2RlJzogbmNUaGVtZSA9PT0gJ2xpZ2h0JywgJ2RhcmstbW9kZSc6IG5jVGhlbWUgPT09ICdkYXJrJywgJ2hvcml6b250YWwtbW9kZSc6IG5jRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcsICd2ZXJ0aWNhbC1tb2RlJzogbmNEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCd9XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBuY0l0ZW1zOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkb2NrLWljb25cIiBbbmdTdHlsZV09XCJ7J3dpZHRoJzogaWNvblNjYWxlc1tpXSArICdweCcsICdoZWlnaHQnOiBpY29uU2NhbGVzW2ldICsgJ3B4J31cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uLWltYWdlLWNvbnRhaW5lclwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtYWduaWZpY2F0aW9uLW1vZGUnOiBuY01vZGUgPT09ICdtYWduaWZpY2F0aW9uJywgJ2Rpc3RhbmNlLW1vZGUnOiBuY01vZGUgPT09ICdkaXN0YW5jZScsICdob3Zlci1tb2RlJzogbmNIb3Zlcn1cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkljb25DbGljayhpKVwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1N2Z0NvbnRlbnQoaXRlbSk7IGVsc2UgaW1hZ2VUZW1wbGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG9jay1pY29uLWltYWdlXCIgW2lubmVySFRNTF09XCJnZXRTYW5pdGl6ZWRTdmcoaXRlbSlcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2ltYWdlVGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCJpdGVtXCIgY2xhc3M9XCJkb2NrLWljb24taW1hZ2VcIj5cbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibmNUb29sdGlwICYmIG5jVG9vbHRpcFtpXVwiIGNsYXNzPVwiZG9jay10b29sdGlwXCIgW25nQ2xhc3NdPVwiJ3Rvb2x0aXAtJyArIG5jVG9vbHRpcFBvc2l0aW9uXCI+XG4gICAgICAgICAgICAgICAge3sgbmNUb29sdGlwW2ldIH19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkb2NrLWRpdmlkZXJcIiAqbmdJZj1cIm5jRGl2aWRlckluZGV4LmluY2x1ZGVzKGkpXCI+PC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG48L2Rpdj4iXX0=