UNPKG

@eternalheart/ngx-file-preview

Version:

A powerful Angular file preview component library supporting multiple file formats including images, videos, PDFs, Office documents, text files and more.

358 lines (356 loc) 53.3 kB
import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core'; import { CommonModule } from '@angular/common'; import { BasePreviewComponent } from '../base-preview/base-preview.component'; import { PreviewIconComponent } from '../../components/preview-icon/preview-icon.component'; import * as XLSX from 'xlsx'; import { I18nPipe } from "../../i18n"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class ExcelPreviewComponent extends BasePreviewComponent { constructor() { super(...arguments); this.scale = 1; this.sheets = []; this.currentSheet = ''; this.tableData = { headers: [], rows: [] }; this.displayRows = []; this.extraRows = 100; // 增加额外显示的空行数 this.extraColumns = Array(5).fill(0); this.visibleRows = []; this.SCALE_STEP = 0.1; this.MAX_SCALE = 3; this.MIN_SCALE = 0.1; this.isDragging = false; this.startX = 0; this.startY = 0; this.scrollLeft = 0; this.scrollTop = 0; this.DEFAULT_SCALE = 1; } get totalColumns() { const total = (this.tableData.headers.length + this.extraColumns.length) || 0; return Array(total).fill(0); } ngOnChanges(changes) { if (changes['file'] && this.file) { this.loadFile(); } } ngAfterViewInit() { this.setupDragListeners(); this.setupKeyboardListeners(); } ngOnDestroy() { this.removeDragListeners(); this.removeKeyboardListeners(); } async handleFileContent(content) { const { data } = content; this.workbook = XLSX.read(data, { type: 'array' }); this.sheets = this.workbook.SheetNames; if (this.sheets.length > 0) { await this.switchSheet(this.sheets[0]); } } setupDragListeners() { this.mouseMoveListener = (e) => this.onDrag(e); this.mouseUpListener = () => this.stopDrag(); document.addEventListener('mousemove', this.mouseMoveListener); document.addEventListener('mouseup', this.mouseUpListener); } removeDragListeners() { if (this.mouseMoveListener) { document.removeEventListener('mousemove', this.mouseMoveListener); } if (this.mouseUpListener) { document.removeEventListener('mouseup', this.mouseUpListener); } } startDrag(e) { // 如果点击的是滚动条,不启动拖动 const wrapper = this.tableWrapper.nativeElement; const rect = wrapper.getBoundingClientRect(); const isClickOnScrollbarX = e.clientY > (rect.bottom - 12); const isClickOnScrollbarY = e.clientX > (rect.right - 12); if (isClickOnScrollbarX || isClickOnScrollbarY) { return; } this.isDragging = true; this.startX = e.pageX - wrapper.offsetLeft; this.startY = e.pageY - wrapper.offsetTop; this.scrollLeft = wrapper.scrollLeft; this.scrollTop = wrapper.scrollTop; } onDrag(e) { if (!this.isDragging) return; e.preventDefault(); const wrapper = this.tableWrapper.nativeElement; const x = e.pageX - wrapper.offsetLeft; const y = e.pageY - wrapper.offsetTop; const walkX = (x - this.startX) * 1.5; // 增加一些移动速度 const walkY = (y - this.startY) * 1.5; wrapper.scrollLeft = this.scrollLeft - walkX; wrapper.scrollTop = this.scrollTop - walkY; } stopDrag() { this.isDragging = false; } async switchSheet(sheetName) { if (!this.workbook) return; try { const worksheet = this.workbook.Sheets[sheetName]; const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 确保所有行的长度一致 const maxLength = Math.max(...jsonData.map((row) => row?.length || 0), 0); this.displayRows = jsonData.map((row) => { const paddedRow = Array.isArray(row) ? [...row] : []; while (paddedRow.length < maxLength) { paddedRow.push(null); } return paddedRow; }); // 添加额外的空行 const emptyRows = Array(this.extraRows).fill(0).map(() => Array(maxLength).fill(null)); this.visibleRows = [...this.displayRows, ...emptyRows]; this.tableData = { headers: Array(maxLength).fill(''), rows: this.displayRows }; this.currentSheet = sheetName; this.cdr.markForCheck(); } catch (error) { console.error('切换工作表失败:', error); } } zoomIn() { if (this.scale < this.MAX_SCALE) { this.scale = Math.min(this.MAX_SCALE, this.scale + this.SCALE_STEP); this.applyZoom(); } } zoomOut() { if (this.scale > this.MIN_SCALE) { this.scale = Math.max(this.MIN_SCALE, this.scale - this.SCALE_STEP); this.applyZoom(); } } toggleFullscreen() { if (!document.fullscreenElement) { document.documentElement.requestFullscreen(); } else { document.exitFullscreen(); } } getColumnName(index) { let name = ''; let num = index; do { name = String.fromCharCode(65 + (num % 26)) + name; num = Math.floor(num / 26) - 1; } while (num >= 0); return name; } getRowNumber(index) { return index + 1; } handleWheel(event) { if (event.ctrlKey || event.metaKey) { event.preventDefault(); const delta = event.deltaY || event.detail || 0; if (delta < 0) { this.zoomIn(); } else { this.zoomOut(); } } } applyZoom() { if (this.tableWrapper) { const wrapper = this.tableWrapper.nativeElement; // 保存当前滚动位置的相对百分比 const scrollLeftPercent = wrapper.scrollLeft / (wrapper.scrollWidth - wrapper.clientWidth); const scrollTopPercent = wrapper.scrollTop / (wrapper.scrollHeight - wrapper.clientHeight); // 应用缩放 wrapper.style.transform = `scale(${this.scale})`; // 在下一个事件循环中恢复滚动位置 setTimeout(() => { wrapper.scrollLeft = scrollLeftPercent * (wrapper.scrollWidth - wrapper.clientWidth); wrapper.scrollTop = scrollTopPercent * (wrapper.scrollHeight - wrapper.clientHeight); }); } this.cdr.markForCheck(); } setupKeyboardListeners() { this.keydownListener = (e) => { // 按下 Ctrl/Command + 0 重置缩放 if ((e.ctrlKey || e.metaKey) && e.key === '0') { e.preventDefault(); this.resetZoom(); } }; document.addEventListener('keydown', this.keydownListener); } removeKeyboardListeners() { if (this.keydownListener) { document.removeEventListener('keydown', this.keydownListener); } } resetZoom() { this.scale = this.DEFAULT_SCALE; this.applyZoom(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ExcelPreviewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ExcelPreviewComponent, isStandalone: true, selector: "ngx-excel-preview", viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "tableWrapper", first: true, predicate: ["tableWrapper"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: ` <div class="excel-container" #container> <div class="toolbar"> <div class="left-controls"> <button class="tool-btn" (click)="zoomOut()"> <preview-icon [themeMode]="themeMode" name="zoom-out" [title]="'preview.toolbar.zoomOut'|i18n"></preview-icon> </button> <span class="zoom-text" (click)="resetZoom()" [title]="'preview.toolbar.resetZoom'|i18n"> {{ (scale * 100).toFixed(0) }}% </span> <button class="tool-btn" (click)="zoomIn()"> <preview-icon [themeMode]="themeMode" name="zoom-in" [title]="'preview.toolbar.zoomIn'|i18n"></preview-icon> </button> </div> <div class="sheet-controls" *ngIf="sheets.length > 0"> <button class="sheet-btn" *ngFor="let sheet of sheets" [class.active]="currentSheet === sheet" (click)="switchSheet(sheet)"> {{ sheet }} </button> </div> <div class="right-controls"> <button class="tool-btn" (click)="toggleFullscreen()"> <preview-icon [themeMode]="themeMode" name="fullscreen" [title]="'preview.toolbar.fullscreen'|i18n"></preview-icon> </button> </div> </div> <div class="preview-container"> <div class="preview-content"> <div class="table-wrapper" #tableWrapper (mousedown)="startDrag($event)" (wheel)="handleWheel($event)" [class.dragging]="isDragging" [style.transform]="'scale(' + scale + ')'"> <table *ngIf="tableData"> <colgroup> <col class="row-header-col"> <col *ngFor="let header of tableData.headers" class="data-col"> <col *ngFor="let i of extraColumns" class="data-col"> </colgroup> <thead> <tr> <th class="corner-cell"></th> <th *ngFor="let header of tableData.headers; let i = index"> {{ getColumnName(i) }} </th> <th *ngFor="let i of extraColumns;let j=index" class="empty-column"> {{ getColumnName(tableData.headers.length + j) }} </th> </tr> </thead> <tbody> <tr *ngFor="let row of visibleRows; let rowIndex = index"> <td class="row-header">{{ getRowNumber(rowIndex) }}</td> <td *ngFor="let cell of row; let colIndex = index" [class.empty-cell]="!cell && cell !== 0"> {{ cell }} </td> <td *ngFor="let i of extraColumns" class="empty-cell"></td> </tr> </tbody> </table> </div> </div> </div> </div> `, isInline: true, styles: [":root{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #d32029;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(0, 0, 0, .85);--nfp-text-secondary: rgba(0, 0, 0, .65);--nfp-text-disabled: rgba(0, 0, 0, .25);--nfp-bg-container: #ffffff;--nfp-bg-elevated: #fafafa;--nfp-bg-layout: #f0f2f5;--nfp-hover-bg: rgba(0, 0, 0, .04);--nfp-border-color: #d9d9d9;--nfp-split-color: rgba(0, 0, 0, .06);--nfp-scrollbar-bg: #ffffff;--nfp-scrollbar-thumb: #d9d9d9;--nfp-toolbar-bg: #fafafa;--nfp-toolbar-border: #d9d9d9;--nfp-toolbar-hover: rgba(0, 0, 0, .04);--nfp-toolbar-active: #e6f4ff;--nfp-preview-mask: rgba(0, 0, 0, .3);--nfp-preview-loading-bg: rgba(255, 255, 255, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .1);--nfp-theme-transition-duration: .3s}[data-nfp-theme=dark]{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #a61d24;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(255, 255, 255, .85);--nfp-text-secondary: rgba(255, 255, 255, .65);--nfp-text-disabled: rgba(255, 255, 255, .25);--nfp-bg-container: #1a1a1a;--nfp-bg-elevated: #262626;--nfp-bg-layout: #141414;--nfp-hover-bg: rgba(255, 255, 255, .08);--nfp-border-color: #303030;--nfp-split-color: rgba(255, 255, 255, .12);--nfp-scrollbar-bg: #1a1a1a;--nfp-scrollbar-thumb: #404040;--nfp-toolbar-bg: #262626;--nfp-toolbar-border: #303030;--nfp-toolbar-hover: rgba(255, 255, 255, .08);--nfp-toolbar-active: #111b26;--nfp-preview-mask: rgba(0, 0, 0, .65);--nfp-preview-loading-bg: rgba(0, 0, 0, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .4);--nfp-theme-transition-duration: .3s}*{transition:background-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),border-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),color var(--nfp-theme-transition-duration) var(--theme-transition-timing)}.no-transition,.no-transition *{transition:none!important}\n", ":host{display:block;width:100%;height:100%}.excel-container{width:100%;height:100%;background:var(--nfp-bg-container);display:flex;flex-direction:column;border-radius:8px;overflow:hidden}.toolbar{height:48px;min-height:48px;background:var(--nfp-toolbar-bg);display:flex;justify-content:space-between;align-items:center;padding:0 16px;border-bottom:1px solid var(--nfp-toolbar-border);gap:16px}.left-controls{display:flex;align-items:center;gap:8px}.sheet-controls{flex:1;display:flex;align-items:center;gap:1px;overflow-x:auto;scrollbar-width:none}.sheet-controls::-webkit-scrollbar{display:none}.sheet-btn{background:var(--nfp-bg-container);border:none;color:var(--nfp-text-primary);padding:6px 16px;font-size:13px;cursor:pointer;white-space:nowrap;height:32px;display:flex;align-items:center;position:relative}.sheet-btn:hover{background:var(--nfp-toolbar-hover)}.sheet-btn.active{background:var(--nfp-toolbar-bg);color:var(--nfp-primary-color)}.sheet-btn.active:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--nfp-primary-color)}.preview-container{flex:1;position:relative;background:var(--nfp-toolbar-bg);display:flex;height:100%;flex-direction:column}.preview-content{width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-toolbar-bg);overflow:hidden}.preview-content .table-wrapper{width:100%;height:100%;overflow:auto;cursor:default;transform-origin:0 0}.preview-content .table-wrapper.dragging,.preview-content .table-wrapper.dragging *{cursor:grab;-webkit-user-select:none;user-select:none}.preview-content .table-wrapper table{border-collapse:collapse;table-layout:fixed;background:var(--nfp-toolbar-bg);color:var(--nfp-text-primary);-webkit-user-select:none;user-select:none;width:max-content;min-width:100%}.preview-content .table-wrapper table .row-header-col{width:50px;min-width:50px}.preview-content .table-wrapper table .data-col{width:120px;min-width:120px}.preview-content .table-wrapper table thead{position:sticky;top:-1px;z-index:2;background:var(--nfp-toolbar-bg);margin-bottom:-1px}.preview-content .table-wrapper table tbody{background:var(--nfp-toolbar-bg)}.preview-content .table-wrapper table th,.preview-content .table-wrapper table td{height:24px;padding:4px 8px;border:1px solid var(--nfp-border-color);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-content .table-wrapper table th{background:var(--nfp-bg-elevated);font-weight:500;text-align:center;border-bottom:2px solid var(--nfp-border-color);color:var(--nfp-text-primary)}.preview-content .table-wrapper table .corner-cell{position:sticky;left:0;z-index:3;background:var(--nfp-toolbar-bg);border-right:2px solid var(--nfp-border-color);border-bottom:2px solid var(--nfp-border-color)}.preview-content .table-wrapper table .row-header{position:sticky;left:0;background:var(--nfp-bg-elevated);text-align:center;font-weight:500;z-index:1;border-right:2px solid var(--nfp-border-color);color:var(--nfp-text-primary)}.preview-content .table-wrapper table td{background:var(--nfp-toolbar-bg);text-align:left}.preview-content .table-wrapper table td.empty-cell{color:transparent;background:var(--nfp-bg-container)}.preview-content .table-wrapper table tbody tr:hover td{background:var(--nfp-hover-bg)}.preview-content .table-wrapper table tbody tr:hover td.empty-cell{background:var(--nfp-bg-container)}.preview-content .table-wrapper table tbody tr:hover td.row-header{background:var(--nfp-bg-elevated)}.preview-content .table-wrapper::-webkit-scrollbar{width:12px;height:12px}.preview-content .table-wrapper::-webkit-scrollbar-track{background:var(--nfp-scrollbar-bg)}.preview-content .table-wrapper::-webkit-scrollbar-thumb{background:var(--nfp-scrollbar-thumb);border:2px solid var(--nfp-scrollbar-bg);border-radius:6px}.preview-content .table-wrapper::-webkit-scrollbar-thumb:hover{background:var(--nfp-primary-color)}.tool-btn{background:transparent;border:none;color:var(--nfp-text-primary);width:32px;height:32px;padding:0;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:all .2s}.tool-btn:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}.zoom-text{color:var(--nfp-text-primary);font-size:13px;min-width:48px;text-align:center;cursor:pointer;padding:4px;border-radius:4px}.zoom-text:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PreviewIconComponent, selector: "preview-icon", inputs: ["name", "svg", "size", "color", "themeMode", "title", "cursor"] }, { kind: "pipe", type: I18nPipe, name: "i18n" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ExcelPreviewComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-excel-preview', standalone: true, imports: [CommonModule, PreviewIconComponent, I18nPipe], template: ` <div class="excel-container" #container> <div class="toolbar"> <div class="left-controls"> <button class="tool-btn" (click)="zoomOut()"> <preview-icon [themeMode]="themeMode" name="zoom-out" [title]="'preview.toolbar.zoomOut'|i18n"></preview-icon> </button> <span class="zoom-text" (click)="resetZoom()" [title]="'preview.toolbar.resetZoom'|i18n"> {{ (scale * 100).toFixed(0) }}% </span> <button class="tool-btn" (click)="zoomIn()"> <preview-icon [themeMode]="themeMode" name="zoom-in" [title]="'preview.toolbar.zoomIn'|i18n"></preview-icon> </button> </div> <div class="sheet-controls" *ngIf="sheets.length > 0"> <button class="sheet-btn" *ngFor="let sheet of sheets" [class.active]="currentSheet === sheet" (click)="switchSheet(sheet)"> {{ sheet }} </button> </div> <div class="right-controls"> <button class="tool-btn" (click)="toggleFullscreen()"> <preview-icon [themeMode]="themeMode" name="fullscreen" [title]="'preview.toolbar.fullscreen'|i18n"></preview-icon> </button> </div> </div> <div class="preview-container"> <div class="preview-content"> <div class="table-wrapper" #tableWrapper (mousedown)="startDrag($event)" (wheel)="handleWheel($event)" [class.dragging]="isDragging" [style.transform]="'scale(' + scale + ')'"> <table *ngIf="tableData"> <colgroup> <col class="row-header-col"> <col *ngFor="let header of tableData.headers" class="data-col"> <col *ngFor="let i of extraColumns" class="data-col"> </colgroup> <thead> <tr> <th class="corner-cell"></th> <th *ngFor="let header of tableData.headers; let i = index"> {{ getColumnName(i) }} </th> <th *ngFor="let i of extraColumns;let j=index" class="empty-column"> {{ getColumnName(tableData.headers.length + j) }} </th> </tr> </thead> <tbody> <tr *ngFor="let row of visibleRows; let rowIndex = index"> <td class="row-header">{{ getRowNumber(rowIndex) }}</td> <td *ngFor="let cell of row; let colIndex = index" [class.empty-cell]="!cell && cell !== 0"> {{ cell }} </td> <td *ngFor="let i of extraColumns" class="empty-cell"></td> </tr> </tbody> </table> </div> </div> </div> </div> `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":root{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #d32029;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(0, 0, 0, .85);--nfp-text-secondary: rgba(0, 0, 0, .65);--nfp-text-disabled: rgba(0, 0, 0, .25);--nfp-bg-container: #ffffff;--nfp-bg-elevated: #fafafa;--nfp-bg-layout: #f0f2f5;--nfp-hover-bg: rgba(0, 0, 0, .04);--nfp-border-color: #d9d9d9;--nfp-split-color: rgba(0, 0, 0, .06);--nfp-scrollbar-bg: #ffffff;--nfp-scrollbar-thumb: #d9d9d9;--nfp-toolbar-bg: #fafafa;--nfp-toolbar-border: #d9d9d9;--nfp-toolbar-hover: rgba(0, 0, 0, .04);--nfp-toolbar-active: #e6f4ff;--nfp-preview-mask: rgba(0, 0, 0, .3);--nfp-preview-loading-bg: rgba(255, 255, 255, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .1);--nfp-theme-transition-duration: .3s}[data-nfp-theme=dark]{--nfp-primary-color: #177ddc;--nfp-primary-hover: #1890ff;--nfp-primary-active: #0050b3;--nfp-error-color: #a61d24;--nfp-warning-color: #d89614;--nfp-success-color: #49aa19;--nfp-text-primary: rgba(255, 255, 255, .85);--nfp-text-secondary: rgba(255, 255, 255, .65);--nfp-text-disabled: rgba(255, 255, 255, .25);--nfp-bg-container: #1a1a1a;--nfp-bg-elevated: #262626;--nfp-bg-layout: #141414;--nfp-hover-bg: rgba(255, 255, 255, .08);--nfp-border-color: #303030;--nfp-split-color: rgba(255, 255, 255, .12);--nfp-scrollbar-bg: #1a1a1a;--nfp-scrollbar-thumb: #404040;--nfp-toolbar-bg: #262626;--nfp-toolbar-border: #303030;--nfp-toolbar-hover: rgba(255, 255, 255, .08);--nfp-toolbar-active: #111b26;--nfp-preview-mask: rgba(0, 0, 0, .65);--nfp-preview-loading-bg: rgba(0, 0, 0, .8);--nfp-preview-toolbar-bg: rgba(0, 0, 0, .4);--nfp-theme-transition-duration: .3s}*{transition:background-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),border-color var(--nfp-theme-transition-duration) var(--theme-transition-timing),color var(--nfp-theme-transition-duration) var(--theme-transition-timing)}.no-transition,.no-transition *{transition:none!important}\n", ":host{display:block;width:100%;height:100%}.excel-container{width:100%;height:100%;background:var(--nfp-bg-container);display:flex;flex-direction:column;border-radius:8px;overflow:hidden}.toolbar{height:48px;min-height:48px;background:var(--nfp-toolbar-bg);display:flex;justify-content:space-between;align-items:center;padding:0 16px;border-bottom:1px solid var(--nfp-toolbar-border);gap:16px}.left-controls{display:flex;align-items:center;gap:8px}.sheet-controls{flex:1;display:flex;align-items:center;gap:1px;overflow-x:auto;scrollbar-width:none}.sheet-controls::-webkit-scrollbar{display:none}.sheet-btn{background:var(--nfp-bg-container);border:none;color:var(--nfp-text-primary);padding:6px 16px;font-size:13px;cursor:pointer;white-space:nowrap;height:32px;display:flex;align-items:center;position:relative}.sheet-btn:hover{background:var(--nfp-toolbar-hover)}.sheet-btn.active{background:var(--nfp-toolbar-bg);color:var(--nfp-primary-color)}.sheet-btn.active:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--nfp-primary-color)}.preview-container{flex:1;position:relative;background:var(--nfp-toolbar-bg);display:flex;height:100%;flex-direction:column}.preview-content{width:100%;height:100%;display:flex;flex-direction:column;background:var(--nfp-toolbar-bg);overflow:hidden}.preview-content .table-wrapper{width:100%;height:100%;overflow:auto;cursor:default;transform-origin:0 0}.preview-content .table-wrapper.dragging,.preview-content .table-wrapper.dragging *{cursor:grab;-webkit-user-select:none;user-select:none}.preview-content .table-wrapper table{border-collapse:collapse;table-layout:fixed;background:var(--nfp-toolbar-bg);color:var(--nfp-text-primary);-webkit-user-select:none;user-select:none;width:max-content;min-width:100%}.preview-content .table-wrapper table .row-header-col{width:50px;min-width:50px}.preview-content .table-wrapper table .data-col{width:120px;min-width:120px}.preview-content .table-wrapper table thead{position:sticky;top:-1px;z-index:2;background:var(--nfp-toolbar-bg);margin-bottom:-1px}.preview-content .table-wrapper table tbody{background:var(--nfp-toolbar-bg)}.preview-content .table-wrapper table th,.preview-content .table-wrapper table td{height:24px;padding:4px 8px;border:1px solid var(--nfp-border-color);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-content .table-wrapper table th{background:var(--nfp-bg-elevated);font-weight:500;text-align:center;border-bottom:2px solid var(--nfp-border-color);color:var(--nfp-text-primary)}.preview-content .table-wrapper table .corner-cell{position:sticky;left:0;z-index:3;background:var(--nfp-toolbar-bg);border-right:2px solid var(--nfp-border-color);border-bottom:2px solid var(--nfp-border-color)}.preview-content .table-wrapper table .row-header{position:sticky;left:0;background:var(--nfp-bg-elevated);text-align:center;font-weight:500;z-index:1;border-right:2px solid var(--nfp-border-color);color:var(--nfp-text-primary)}.preview-content .table-wrapper table td{background:var(--nfp-toolbar-bg);text-align:left}.preview-content .table-wrapper table td.empty-cell{color:transparent;background:var(--nfp-bg-container)}.preview-content .table-wrapper table tbody tr:hover td{background:var(--nfp-hover-bg)}.preview-content .table-wrapper table tbody tr:hover td.empty-cell{background:var(--nfp-bg-container)}.preview-content .table-wrapper table tbody tr:hover td.row-header{background:var(--nfp-bg-elevated)}.preview-content .table-wrapper::-webkit-scrollbar{width:12px;height:12px}.preview-content .table-wrapper::-webkit-scrollbar-track{background:var(--nfp-scrollbar-bg)}.preview-content .table-wrapper::-webkit-scrollbar-thumb{background:var(--nfp-scrollbar-thumb);border:2px solid var(--nfp-scrollbar-bg);border-radius:6px}.preview-content .table-wrapper::-webkit-scrollbar-thumb:hover{background:var(--nfp-primary-color)}.tool-btn{background:transparent;border:none;color:var(--nfp-text-primary);width:32px;height:32px;padding:0;cursor:pointer;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:all .2s}.tool-btn:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}.zoom-text{color:var(--nfp-text-primary);font-size:13px;min-width:48px;text-align:center;cursor:pointer;padding:4px;border-radius:4px}.zoom-text:hover{background:var(--nfp-toolbar-hover);color:var(--nfp-primary-color)}\n"] }] }], propDecorators: { container: [{ type: ViewChild, args: ['container'] }], tableWrapper: [{ type: ViewChild, args: ['tableWrapper'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjZWwtcHJldmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25neC1maWxlLXByZXZpZXcvc3JjL2xpYi9wcmV2aWV3LXR5cGVzL2V4Y2VsLXByZXZpZXcvZXhjZWwtcHJldmlldy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBS1QsU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSx3Q0FBd0MsQ0FBQztBQUM1RSxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSxzREFBc0QsQ0FBQztBQUMxRixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sWUFBWSxDQUFDOzs7QUFvRnBDLE1BQU0sT0FBTyxxQkFBc0IsU0FBUSxvQkFBb0I7SUE3RS9EOztRQWlGRSxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUN0QixpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQUNsQixjQUFTLEdBQWMsRUFBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUMsQ0FBQztRQUMvQyxnQkFBVyxHQUFZLEVBQUUsQ0FBQztRQUMxQixjQUFTLEdBQUcsR0FBRyxDQUFDLENBQUMsYUFBYTtRQUM5QixpQkFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsZ0JBQVcsR0FBWSxFQUFFLENBQUM7UUFHVCxlQUFVLEdBQUcsR0FBRyxDQUFDO1FBQ2pCLGNBQVMsR0FBRyxDQUFDLENBQUM7UUFDZCxjQUFTLEdBQUcsR0FBRyxDQUFD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Z0JBQ25CLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVPLHVCQUF1QjtRQUM3QixJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6QixRQUFRLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNoRSxDQUFDO0lBQ0gsQ0FBQztJQUVELFNBQVM7UUFDUCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ25CLENBQUM7K0dBN09VLHFCQUFxQjttR0FBckIscUJBQXFCLGdVQXpFdEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFFVCw4M01BdEVTLFlBQVksZ1FBQUUsb0JBQW9CLDhIQUFFLFFBQVE7OzRGQTBFM0MscUJBQXFCO2tCQTdFakMsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFFBQVEsQ0FBQyxZQUM3Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUVULG1CQUVnQix1QkFBdUIsQ0FBQyxNQUFNOzhCQUd2QixTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBQ0ssWUFBWTtzQkFBdEMsU0FBUzt1QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtCYXNlUHJldmlld0NvbXBvbmVudH0gZnJvbSAnLi4vYmFzZS1wcmV2aWV3L2Jhc2UtcHJldmlldy5jb21wb25lbnQnO1xuaW1wb3J0IHtQcmV2aWV3SWNvbkNvbXBvbmVudH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9wcmV2aWV3LWljb24vcHJldmlldy1pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgKiBhcyBYTFNYIGZyb20gJ3hsc3gnO1xuaW1wb3J0IHtGaWxlUmVhZGVyUmVzcG9uc2V9IGZyb20gXCIuLi8uLi9zZXJ2aWNlc1wiO1xuaW1wb3J0IHtJMThuUGlwZX0gZnJvbSBcIi4uLy4uL2kxOG5cIjtcblxuaW50ZXJmYWNlIFRhYmxlRGF0YSB7XG4gIGhlYWRlcnM6IHN0cmluZ1tdO1xuICByb3dzOiBhbnlbXVtdO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZXhjZWwtcHJldmlldycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFByZXZpZXdJY29uQ29tcG9uZW50LCBJMThuUGlwZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImV4Y2VsLWNvbnRhaW5lclwiICNjb250YWluZXI+XG4gICAgICA8ZGl2IGNsYXNzPVwidG9vbGJhclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVmdC1jb250cm9sc1wiPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0b29sLWJ0blwiIChjbGljayk9XCJ6b29tT3V0KClcIj5cbiAgICAgICAgICAgIDxwcmV2aWV3LWljb24gW3RoZW1lTW9kZV09XCJ0aGVtZU1vZGVcIiBuYW1lPVwiem9vbS1vdXRcIiBbdGl0bGVdPVwiJ3ByZXZpZXcudG9vbGJhci56b29tT3V0J3xpMThuXCI+PC9wcmV2aWV3LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ6b29tLXRleHRcIiAoY2xpY2spPVwicmVzZXRab29tKClcIiBbdGl0bGVdPVwiJ3ByZXZpZXcudG9vbGJhci5yZXNldFpvb20nfGkxOG5cIj5cbiAgICAgICAgICAgIHt7IChzY2FsZSAqIDEwMCkudG9GaXhlZCgwKSB9fSVcbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRvb2wtYnRuXCIgKGNsaWNrKT1cInpvb21JbigpXCI+XG4gICAgICAgICAgICA8cHJldmlldy1pY29uIFt0aGVtZU1vZGVdPVwidGhlbWVNb2RlXCIgbmFtZT1cInpvb20taW5cIiBbdGl0bGVdPVwiJ3ByZXZpZXcudG9vbGJhci56b29tSW4nfGkxOG5cIj48L3ByZXZpZXctaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzaGVldC1jb250cm9sc1wiICpuZ0lmPVwic2hlZXRzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic2hlZXQtYnRuXCJcbiAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBzaGVldCBvZiBzaGVldHNcIlxuICAgICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJjdXJyZW50U2hlZXQgPT09IHNoZWV0XCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzd2l0Y2hTaGVldChzaGVldClcIj5cbiAgICAgICAgICAgIHt7IHNoZWV0IH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmlnaHQtY29udHJvbHNcIj5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidG9vbC1idG5cIiAoY2xpY2spPVwidG9nZ2xlRnVsbHNjcmVlbigpXCI+XG4gICAgICAgICAgICA8cHJldmlldy1pY29uIFt0aGVtZU1vZGVdPVwidGhlbWVNb2RlXCIgbmFtZT1cImZ1bGxzY3JlZW5cIiBbdGl0bGVdPVwiJ3ByZXZpZXcudG9vbGJhci5mdWxsc2NyZWVuJ3xpMThuXCI+PC9wcmV2aWV3LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJwcmV2aWV3LWNvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJldmlldy1jb250ZW50XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXdyYXBwZXJcIlxuICAgICAgICAgICAgICAgI3RhYmxlV3JhcHBlclxuICAgICAgICAgICAgICAgKG1vdXNlZG93bik9XCJzdGFydERyYWcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAod2hlZWwpPVwiaGFuZGxlV2hlZWwoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICBbY2xhc3MuZHJhZ2dpbmddPVwiaXNEcmFnZ2luZ1wiXG4gICAgICAgICAgICAgICBbc3R5bGUudHJhbnNmb3JtXT1cIidzY2FsZSgnICsgc2NhbGUgKyAnKSdcIj5cbiAgICAgICAgICAgIDx0YWJsZSAqbmdJZj1cInRhYmxlRGF0YVwiPlxuICAgICAgICAgICAgICA8Y29sZ3JvdXA+XG4gICAgICAgICAgICAgICAgPGNvbCBjbGFzcz1cInJvdy1oZWFkZXItY29sXCI+XG4gICAgICAgICAgICAgICAgPGNvbCAqbmdGb3I9XCJsZXQgaGVhZGVyIG9mIHRhYmxlRGF0YS5oZWFkZXJzXCIgY2xhc3M9XCJkYXRhLWNvbFwiPlxuICAgICAgICAgICAgICAgIDxjb2wgKm5nRm9yPVwibGV0IGkgb2YgZXh0cmFDb2x1bW5zXCIgY2xhc3M9XCJkYXRhLWNvbFwiPlxuICAgICAgICAgICAgICA8L2NvbGdyb3VwPlxuICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJjb3JuZXItY2VsbFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBoZWFkZXIgb2YgdGFibGVEYXRhLmhlYWRlcnM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGdldENvbHVtbk5hbWUoaSkgfX1cbiAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgIDx0aCAqbmdGb3I9XCJsZXQgaSBvZiBleHRyYUNvbHVtbnM7bGV0IGo9aW5kZXhcIiBjbGFzcz1cImVtcHR5LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAge3sgZ2V0Q29sdW1uTmFtZSh0YWJsZURhdGEuaGVhZGVycy5sZW5ndGggKyBqKSB9fVxuICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgdmlzaWJsZVJvd3M7IGxldCByb3dJbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicm93LWhlYWRlclwiPnt7IGdldFJvd051bWJlcihyb3dJbmRleCkgfX08L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY2VsbCBvZiByb3c7IGxldCBjb2xJbmRleCA9IGluZGV4XCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmVtcHR5LWNlbGxdPVwiIWNlbGwgJiYgY2VsbCAhPT0gMFwiPlxuICAgICAgICAgICAgICAgICAge3sgY2VsbCB9fVxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBpIG9mIGV4dHJhQ29sdW1uc1wiIGNsYXNzPVwiZW1wdHktY2VsbFwiPjwvdGQ+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZVVybHM6IFtcIi4uLy4uL3N0eWxlcy9fdGhlbWUuc2Nzc1wiLCBcImV4Y2VsLXByZXZpZXcuY29tcG9uZW50LnNjc3NcIl0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIEV4Y2VsUHJldmlld0NvbXBvbmVudCBleHRlbmRzIEJhc2VQcmV2aWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBAVmlld0NoaWxkKCdjb250YWluZXInKSBjb250YWluZXIhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgndGFibGVXcmFwcGVyJykgdGFibGVXcmFwcGVyITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgc2NhbGUgPSAxO1xuICBzaGVldHM6IHN0cmluZ1tdID0gW107XG4gIGN1cnJlbnRTaGVldCA9ICcnO1xuICB0YWJsZURhdGE6IFRhYmxlRGF0YSA9IHtoZWFkZXJzOiBbXSwgcm93czogW119O1xuICBkaXNwbGF5Um93czogYW55W11bXSA9IFtdO1xuICBleHRyYVJvd3MgPSAxMDA7IC8vIOWinuWKoOmineWkluaYvuekuueahOepuuihjOaVsFxuICBleHRyYUNvbHVtbnMgPSBBcnJheSg1KS5maWxsKDApO1xuICB2aXNpYmxlUm93czogYW55W11bXSA9IFtdO1xuXG4gIHByaXZhdGUgd29ya2Jvb2s/OiBYTFNYLldvcmtCb29rO1xuICBwcml2YXRlIHJlYWRvbmx5IFNDQUxFX1NURVAgPSAwLjE7XG4gIHByaXZhdGUgcmVhZG9ubHkgTUFYX1NDQUxFID0gMztcbiAgcHJpdmF0ZSByZWFkb25seSBNSU5fU0NBTEUgPSAwLjE7XG5cbiAgaXNEcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHN0YXJ0WCA9IDA7XG4gIHByaXZhdGUgc3RhcnRZID0gMDtcbiAgcHJpdmF0ZSBzY3JvbGxMZWZ0ID0gMDtcbiAgcHJpdmF0ZSBzY3JvbGxUb3AgPSAwO1xuICBwcml2YXRlIG1vdXNlTW92ZUxpc3RlbmVyPzogKGU6IE1vdXNlRXZlbnQpID0+IHZvaWQ7XG4gIHByaXZhdGUgbW91c2VVcExpc3RlbmVyPzogKGU6IE1vdXNlRXZlbnQpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBERUZBVUxUX1NDQUxFID0gMTtcbiAgcHJpdmF0ZSBrZXlkb3duTGlzdGVuZXI/OiAoZTogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZDtcblxuICBnZXQgdG90YWxDb2x1bW5zKCk6IG51bWJlcltdIHtcbiAgICBjb25zdCB0b3RhbCA9ICh0aGlzLnRhYmxlRGF0YS5oZWFkZXJzLmxlbmd0aCArIHRoaXMuZXh0cmFDb2x1bW5zLmxlbmd0aCkgfHwgMDtcbiAgICByZXR1cm4gQXJyYXkodG90YWwpLmZpbGwoMCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXNbJ2ZpbGUnXSAmJiB0aGlzLmZpbGUpIHtcbiAgICAgIHRoaXMubG9hZEZpbGUoKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5zZXR1cERyYWdMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnNldHVwS2V5Ym9hcmRMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMucmVtb3ZlRHJhZ0xpc3RlbmVycygpO1xuICAgIHRoaXMucmVtb3ZlS2V5Ym9hcmRMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBoYW5kbGVGaWxlQ29udGVudChjb250ZW50OiBGaWxlUmVhZGVyUmVzcG9uc2UpIHtcbiAgICBjb25zdCB7ZGF0YX0gPSBjb250ZW50XG4gICAgdGhpcy53b3JrYm9vayA9IFhMU1gucmVhZChkYXRhLCB7dHlwZTogJ2FycmF5J30pO1xuICAgIHRoaXMuc2hlZXRzID0gdGhpcy53b3JrYm9vay5TaGVldE5hbWVzO1xuICAgIGlmICh0aGlzLnNoZWV0cy5sZW5ndGggPiAwKSB7XG4gICAgICBhd2FpdCB0aGlzLnN3aXRjaFNoZWV0KHRoaXMuc2hlZXRzWzBdKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldHVwRHJhZ0xpc3RlbmVycygpIHtcbiAgICB0aGlzLm1vdXNlTW92ZUxpc3RlbmVyID0gKGU6IE1vdXNlRXZlbnQpID0+IHRoaXMub25EcmFnKGUpO1xuICAgIHRoaXMubW91c2VVcExpc3RlbmVyID0gKCkgPT4gdGhpcy5zdG9wRHJhZygpO1xuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5tb3VzZU1vdmVMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMubW91c2VVcExpc3RlbmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlRHJhZ0xpc3RlbmVycygpIHtcbiAgICBpZiAodGhpcy5tb3VzZU1vdmVMaXN0ZW5lcikge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5tb3VzZU1vdmVMaXN0ZW5lcik7XG4gICAgfVxuICAgIGlmICh0aGlzLm1vdXNlVXBMaXN0ZW5lcikge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMubW91c2VVcExpc3RlbmVyKTtcbiAgICB9XG4gIH1cblxuICBzdGFydERyYWcoZTogTW91c2VFdmVudCkge1xuICAgIC8vIOWmguaenOeCueWHu+eahOaYr+a7muWKqOadoe+8jOS4jeWQr+WKqOaLluWKqFxuICAgIGNvbnN0IHdyYXBwZXIgPSB0aGlzLnRhYmxlV3JhcHBlci5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHJlY3QgPSB3cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IGlzQ2xpY2tPblNjcm9sbGJhclggPSBlLmNsaWVudFkgPiAocmVjdC5ib3R0b20gLSAxMik7XG4gICAgY29uc3QgaXNDbGlja09uU2Nyb2xsYmFyWSA9IGUuY2xpZW50WCA+IChyZWN0LnJpZ2h0IC0gMTIpO1xuXG4gICAgaWYgKGlzQ2xpY2tPblNjcm9sbGJhclggfHwgaXNDbGlja09uU2Nyb2xsYmFyWSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaXNEcmFnZ2luZyA9IHRydWU7XG4gICAgdGhpcy5zdGFydFggPSBlLnBhZ2VYIC0gd3JhcHBlci5vZmZzZXRMZWZ0O1xuICAgIHRoaXMuc3RhcnRZID0gZS5wYWdlWSAtIHdyYXBwZXIub2Zmc2V0VG9wO1xuICAgIHRoaXMuc2Nyb2xsTGVmdCA9IHdyYXBwZXIuc2Nyb2xsTGVmdDtcbiAgICB0aGlzLnNjcm9sbFRvcCA9IHdyYXBwZXIuc2Nyb2xsVG9wO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkRyYWcoZTogTW91c2VFdmVudCkge1xuICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSByZXR1cm47XG5cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3Qgd3JhcHBlciA9IHRoaXMudGFibGVXcmFwcGVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgeCA9IGUucGFnZVggLSB3cmFwcGVyLm9mZnNldExlZnQ7XG4gICAgY29uc3QgeSA9IGUucGFnZVkgLSB3cmFwcGVyLm9mZnNldFRvcDtcbiAgICBjb25zdCB3YWxrWCA9ICh4IC0gdGhpcy5zdGFydFgpICogMS41OyAvLyDlop7liqDkuIDkupvnp7vliqjpgJ/luqZcbiAgICBjb25zdCB3YWxrWSA9ICh5IC0gdGhpcy5zdGFydFkpICogMS41O1xuXG4gICAgd3JhcHBlci5zY3JvbGxMZWZ0ID0gdGhpcy5zY3JvbGxMZWZ0IC0gd2Fsa1g7XG4gICAgd3JhcHBlci5zY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcCAtIHdhbGtZO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wRHJhZygpIHtcbiAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIHN3aXRjaFNoZWV0KHNoZWV0TmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLndvcmtib29rKSByZXR1cm47XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgd29ya3NoZWV0ID0gdGhpcy53b3JrYm9vay5TaGVldHNbc2hlZXROYW1lXTtcbiAgICAgIGNvbnN0IGpzb25EYXRhID0gWExTWC51dGlscy5zaGVldF90b19qc29uPGFueVtdPih3b3Jrc2hlZXQsIHtoZWFkZXI6IDF9KTtcblxuICAgICAgLy8g56Gu5L+d5omA5pyJ6KGM55qE6ZW/5bqm5LiA6Ie0XG4gICAgICBjb25zdCBtYXhMZW5ndGggPSBNYXRoLm1heCguLi5qc29uRGF0YS5tYXAoKHJvdzogYW55W10pID0+IHJvdz8ubGVuZ3RoIHx8IDApLCAwKTtcbiAgICAgIHRoaXMuZGlzcGxheVJvd3MgPSBqc29uRGF0YS5tYXAoKHJvdzogYW55W10pID0+IHtcbiAgICAgICAgY29uc3QgcGFkZGVkUm93ID0gQXJyYXkuaXNBcnJheShyb3cpID8gWy4uLnJvd10gOiBbXTtcbiAgICAgICAgd2hpbGUgKHBhZGRlZFJvdy5sZW5ndGggPCBtYXhMZW5ndGgpIHtcbiAgICAgICAgICBwYWRkZWRSb3cucHVzaChudWxsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFkZGVkUm93O1xuICAgICAgfSk7XG5cbiAgICAgIC8vIOa3u+WKoOmineWklueahOepuuihjFxuICAgICAgY29uc3QgZW1wdHlSb3dzID0gQXJyYXkodGhpcy5leHRyYVJvd3MpLmZpbGwoMCkubWFwKCgpID0+IEFycmF5KG1heExlbmd0aCkuZmlsbChudWxsKSk7XG4gICAgICB0aGlzLnZpc2libGVSb3dzID0gWy4uLnRoaXMuZGlzcGxheVJvd3MsIC4uLmVtcHR5Um93c107XG5cbiAgICAgIHRoaXMudGFibGVEYXRhID0ge1xuICAgICAgICBoZWFkZXJzOiBBcnJheShtYXhMZW5ndGgpLmZpbGwoJycpLFxuICAgICAgICByb3dzOiB0aGlzLmRpc3BsYXlSb3dzXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmN1cnJlbnRTaGVldCA9IHNoZWV0TmFtZTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCfliIfmjaLlt6XkvZzooajlpLHotKU6JywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMuTUFYX1NDQUxFKSB7XG4gICAgICB0aGlzLnNjYWxlID0gTWF0aC5taW4odGhpcy5NQVhfU0NBTEUsIHRoaXMuc2NhbGUgKyB0aGlzLlNDQUxFX1NURVApO1xuICAgICAgdGhpcy5hcHBseVpvb20oKTtcbiAgICB9XG4gIH1