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.

85 lines 27.9 kB
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, Output, ViewChildren, ViewEncapsulation } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PreviewIconComponent } from '../components'; import { PreviewDirective } from "../directives"; import { PreviewUtils } from "../utils"; import { PreviewService, ThemeService } from '../services'; import { I18nPipe } from "../i18n/i18n.pipe"; import { FileSizePipe } from "./file-size.pipe"; import * as i0 from "@angular/core"; import * as i1 from "../services"; import * as i2 from "@angular/common"; export class PreviewListComponent { get files() { return this._files; } set files(value) { this._files = PreviewUtils.normalizeFiles(value); } get themeMode() { return this._themeMode; } set themeMode(value) { this._themeMode = value; this.themeService.setMode(this._themeMode); if (this._themeMode === 'auto' && this.autoConfig) { this.themeService.setAutoConfig(this.autoConfig); } } get lang() { return this._lang; } set lang(value) { this._lang = value; this.previewService.setLang(value); } constructor(themeService, previewService, elementRef) { this.themeService = themeService; this.previewService = previewService; this.elementRef = elementRef; this.trigger = 'click'; // 默认触发方式 this._files = []; this.index = 0; this._themeMode = 'auto'; this._lang = 'zh'; this.previewEvent = new EventEmitter(); this.themeService.bindElement(this.elementRef.nativeElement); } triggerSelect(index) { this.index = index; this.previewEvent.emit({ type: 'select', event: this.files[index] }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PreviewListComponent, deps: [{ token: i1.ThemeService }, { token: i1.PreviewService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PreviewListComponent, isStandalone: true, selector: "ngx-preview-list", inputs: { trigger: "trigger", files: "files", index: "index", themeMode: "themeMode", autoConfig: "autoConfig", lang: "lang" }, outputs: { previewEvent: "previewEvent" }, providers: [ThemeService, PreviewService], queries: [{ propertyName: "itemTemplate", first: true, predicate: ["itemTemplate"], descendants: true }], viewQueries: [{ propertyName: "previewTriggers", predicate: ["previewTrigger"], descendants: true }], ngImport: i0, template: "<div class=\"ngx-preview-list\">\n <div class=\"ngx-preview-list__header\">\n <span>{{ 'list.title'|i18n }}</span>\n <span class=\"count\">\n @if (files?.length) {\n {{ 'list.total'|i18n:files?.length }}\n }\n </span>\n </div>\n <div class=\"ngx-preview-list__content\">\n @for (file of files; let i = $index; track file.name) {\n <ng-container *ngIf=\"itemTemplate; else defaultTemplate\">\n <div style=\"display: none\" #previewTrigger\n [ngxFilePreview]=\"file\"\n [trigger]=\"trigger\"\n [themeMode]=\"themeMode\"\n [lang]=\"lang\"></div>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: file,\n index: i,\n isActive: i === index,\n themeMode: themeMode,\n type: ('types.'+file.type)|i18n,\n select: triggerSelect.bind(this,i),\n preview: previewTrigger.click.bind(previewTrigger)\n }\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultTemplate>\n <div class=\"item\"\n (click)=\"triggerSelect(i)\"\n [ngxFilePreview]=\"file\"\n [trigger]=\"trigger\"\n [themeMode]=\"themeMode\"\n [lang]=\"lang\"\n [class.active]=\"i === index\">\n <span class=\"icon\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"40\" [svg]=\"file.type\"></preview-icon>\n </span>\n <div class=\"info\">\n <div class=\"main-info\">\n <span class=\"name\">{{ file.name }}</span>\n <span class=\"size\">{{ file.size|fileSize }}</span>\n </div>\n <div class=\"sub-info\">\n <span class=\"type\">{{ ('types.' + file.type)|i18n }}</span>\n <span class=\"date\" *ngIf=\"file.lastModified\">\n {{ file.lastModified|date:'yyyy-MM-dd HH:mm:ss' }}\n </span>\n </div>\n </div>\n </div>\n </ng-template>\n } @empty {\n <div class=\"empty\">{{ 'list.empty'|i18n }}</div>\n }\n </div>\n</div>\n<ng-content></ng-content>\n", 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;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif}.ngx-preview-list__header{padding:16px;border-bottom:1px solid var(--nfp-border-color);display:flex;justify-content:space-between;align-items:center;color:var(--nfp-text-primary);background-color:var(--nfp-bg-container)}.ngx-preview-list__header .count{color:var(--nfp-text-secondary);font-size:14px}.ngx-preview-list__content{background:var(--nfp-bg-container);transition:all .3s ease;overflow-y:auto}.ngx-preview-list__content::-webkit-scrollbar{width:6px;height:6px}.ngx-preview-list__content::-webkit-scrollbar-track{background-color:var(--nfp-scrollbar-bg)}.ngx-preview-list__content::-webkit-scrollbar-thumb{border-radius:3px;background-color:var(--nfp-scrollbar-thumb)}.ngx-preview-list__content .empty{padding:32px;text-align:center;color:var(--nfp-text-secondary);font-size:14px}.ngx-preview-list__content:not(:last-child){border-bottom:1px solid var(--nfp-border-color)}.ngx-preview-list__content .item{padding:12px 16px;display:flex;align-items:center;gap:12px;transition:background-color .3s;cursor:pointer}.ngx-preview-list__content .item:hover{background-color:var(--nfp-hover-bg)}.ngx-preview-list__content .item.active{background-color:var(--nfp-toolbar-hover)}.ngx-preview-list__content .item .icon{font-size:24px;color:var(--nfp-primary-active)}.ngx-preview-list__content .item .info{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.ngx-preview-list__content .item .info .main-info{display:flex;align-items:center;gap:8px}.ngx-preview-list__content .item .info .main-info .name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--nfp-text-primary);font-size:14px;font-weight:400}.ngx-preview-list__content .item .info .main-info .size{flex-shrink:0;color:var(--nfp-text-secondary);font-size:12px}.ngx-preview-list__content .item .info .sub-info{display:flex;align-items:center;gap:16px}.ngx-preview-list__content .item .info .sub-info .type,.ngx-preview-list__content .item .info .sub-info .date{color:var(--nfp-text-secondary);font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "component", type: PreviewIconComponent, selector: "preview-icon", inputs: ["name", "svg", "size", "color", "themeMode", "title", "cursor"] }, { kind: "directive", type: PreviewDirective, selector: "[ngxFilePreview]", inputs: ["ngxFilePreview", "previewIndex", "trigger", "themeMode", "autoConfig", "lang"], outputs: ["previewEvent"] }, { kind: "pipe", type: I18nPipe, name: "i18n" }, { kind: "pipe", type: FileSizePipe, name: "fileSize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PreviewListComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-preview-list', standalone: true, imports: [ CommonModule, PreviewIconComponent, PreviewDirective, I18nPipe, FileSizePipe ], providers: [ThemeService, PreviewService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"ngx-preview-list\">\n <div class=\"ngx-preview-list__header\">\n <span>{{ 'list.title'|i18n }}</span>\n <span class=\"count\">\n @if (files?.length) {\n {{ 'list.total'|i18n:files?.length }}\n }\n </span>\n </div>\n <div class=\"ngx-preview-list__content\">\n @for (file of files; let i = $index; track file.name) {\n <ng-container *ngIf=\"itemTemplate; else defaultTemplate\">\n <div style=\"display: none\" #previewTrigger\n [ngxFilePreview]=\"file\"\n [trigger]=\"trigger\"\n [themeMode]=\"themeMode\"\n [lang]=\"lang\"></div>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: file,\n index: i,\n isActive: i === index,\n themeMode: themeMode,\n type: ('types.'+file.type)|i18n,\n select: triggerSelect.bind(this,i),\n preview: previewTrigger.click.bind(previewTrigger)\n }\"\n ></ng-container>\n </ng-container>\n <ng-template #defaultTemplate>\n <div class=\"item\"\n (click)=\"triggerSelect(i)\"\n [ngxFilePreview]=\"file\"\n [trigger]=\"trigger\"\n [themeMode]=\"themeMode\"\n [lang]=\"lang\"\n [class.active]=\"i === index\">\n <span class=\"icon\">\n <preview-icon [themeMode]=\"themeMode\" [size]=\"40\" [svg]=\"file.type\"></preview-icon>\n </span>\n <div class=\"info\">\n <div class=\"main-info\">\n <span class=\"name\">{{ file.name }}</span>\n <span class=\"size\">{{ file.size|fileSize }}</span>\n </div>\n <div class=\"sub-info\">\n <span class=\"type\">{{ ('types.' + file.type)|i18n }}</span>\n <span class=\"date\" *ngIf=\"file.lastModified\">\n {{ file.lastModified|date:'yyyy-MM-dd HH:mm:ss' }}\n </span>\n </div>\n </div>\n </div>\n </ng-template>\n } @empty {\n <div class=\"empty\">{{ 'list.empty'|i18n }}</div>\n }\n </div>\n</div>\n<ng-content></ng-content>\n", 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;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif}.ngx-preview-list__header{padding:16px;border-bottom:1px solid var(--nfp-border-color);display:flex;justify-content:space-between;align-items:center;color:var(--nfp-text-primary);background-color:var(--nfp-bg-container)}.ngx-preview-list__header .count{color:var(--nfp-text-secondary);font-size:14px}.ngx-preview-list__content{background:var(--nfp-bg-container);transition:all .3s ease;overflow-y:auto}.ngx-preview-list__content::-webkit-scrollbar{width:6px;height:6px}.ngx-preview-list__content::-webkit-scrollbar-track{background-color:var(--nfp-scrollbar-bg)}.ngx-preview-list__content::-webkit-scrollbar-thumb{border-radius:3px;background-color:var(--nfp-scrollbar-thumb)}.ngx-preview-list__content .empty{padding:32px;text-align:center;color:var(--nfp-text-secondary);font-size:14px}.ngx-preview-list__content:not(:last-child){border-bottom:1px solid var(--nfp-border-color)}.ngx-preview-list__content .item{padding:12px 16px;display:flex;align-items:center;gap:12px;transition:background-color .3s;cursor:pointer}.ngx-preview-list__content .item:hover{background-color:var(--nfp-hover-bg)}.ngx-preview-list__content .item.active{background-color:var(--nfp-toolbar-hover)}.ngx-preview-list__content .item .icon{font-size:24px;color:var(--nfp-primary-active)}.ngx-preview-list__content .item .info{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.ngx-preview-list__content .item .info .main-info{display:flex;align-items:center;gap:8px}.ngx-preview-list__content .item .info .main-info .name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--nfp-text-primary);font-size:14px;font-weight:400}.ngx-preview-list__content .item .info .main-info .size{flex-shrink:0;color:var(--nfp-text-secondary);font-size:12px}.ngx-preview-list__content .item .info .sub-info{display:flex;align-items:center;gap:16px}.ngx-preview-list__content .item .info .sub-info .type,.ngx-preview-list__content .item .info .sub-info .date{color:var(--nfp-text-secondary);font-size:12px}\n"] }] }], ctorParameters: () => [{ type: i1.ThemeService }, { type: i1.PreviewService }, { type: i0.ElementRef }], propDecorators: { trigger: [{ type: Input }], files: [{ type: Input }], index: [{ type: Input }], themeMode: [{ type: Input }], autoConfig: [{ type: Input }], lang: [{ type: Input }], previewEvent: [{ type: Output }], itemTemplate: [{ type: ContentChild, args: ['itemTemplate'] }], previewTriggers: [{ type: ViewChildren, args: ['previewTrigger'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldmlldy1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvbmd4LWZpbGUtcHJldmlldy9zcmMvbGliL3ByZXZpZXctbGlzdC9wcmV2aWV3LWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vbGlicy9uZ3gtZmlsZS1wcmV2aWV3L3NyYy9saWIvcHJldmlldy1saXN0L3ByZXZpZXctbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBRVosWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBR04sWUFBWSxFQUNaLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvQyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ3RDLE9BQU8sRUFBQyxjQUFjLEVBQUUsWUFBWSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3pELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQyxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sa0JBQWtCLENBQUM7Ozs7QUFxQjlDLE1BQU0sT0FBTyxvQkFBb0I7SUFHL0IsSUFDSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxJQUFJLEtBQUssQ0FBQyxLQUF1QjtRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUlELElBQ0ksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBQ0QsSUFBSSxTQUFTLENBQUMsS0FBZ0I7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNDLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUdELElBQ0ksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsS0FBYTtRQUNwQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNwQyxDQUFDO0lBS0QsWUFBb0IsWUFBMEIsRUFBUSxjQUE2QixFQUFTLFVBQXNCO1FBQTlGLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQVEsbUJBQWMsR0FBZCxjQUFjLENBQWU7UUFBUyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBckN6RyxZQUFPLEdBQUcsT0FBTyxDQUFDLENBQUMsU0FBUztRQUM3QixXQUFNLEdBQWtCLEVBQUUsQ0FBQztRQVMxQixVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsZUFBVSxHQUFjLE1BQU0sQ0FBQztRQWEvQixVQUFLLEdBQVUsSUFBSSxDQUFBO1FBU2pCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQWdCLENBQUM7UUFLeEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQWE7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDOytHQTdDVSxvQkFBb0I7bUdBQXBCLG9CQUFvQiwwT0FUcEIsQ0FBQyxZQUFZLEVBQUMsY0FBYyxDQUFDLDBPQ2pDMUMsd3ZFQTZEQSxzbklEbENJLFlBQVksNlZBQ1osb0JBQW9CLG1JQUNwQixnQkFBZ0IsNktBQ2hCLFFBQVEsd0NBQ1IsWUFBWTs7NEZBV0gsb0JBQW9CO2tCQW5CaEMsU0FBUzsrQkFDRSxrQkFBa0IsY0FDaEIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osb0JBQW9CO3dCQUNwQixnQkFBZ0I7d0JBQ2hCLFFBQVE7d0JBQ1IsWUFBWTtxQkFDYixhQUNVLENBQUMsWUFBWSxFQUFDLGNBQWMsQ0FBQyxtQkFNdkIsdUJBQXVCLENBQUMsTUFBTSxpQkFDaEMsaUJBQWlCLENBQUMsSUFBSTt1SUFHNUIsT0FBTztzQkFBZixLQUFLO2dCQUdGLEtBQUs7c0JBRFIsS0FBSztnQkFRRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0YsU0FBUztzQkFEWixLQUFLO2dCQVdHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0YsSUFBSTtzQkFEUCxLQUFLO2dCQVFJLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ3VCLFlBQVk7c0JBQXpDLFlBQVk7dUJBQUMsY0FBYztnQkFDSSxlQUFlO3NCQUE5QyxZQUFZO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZHJlbixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7QXV0b1RoZW1lQ29uZmlnLCBQcmV2aWV3RXZlbnQsIFByZXZpZXdGaWxlLCBQcmV2aWV3RmlsZUlucHV0LCBUaGVtZU1vZGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7UHJldmlld0ljb25Db21wb25lbnR9IGZyb20gJy4uL2NvbXBvbmVudHMnO1xuaW1wb3J0IHtQcmV2aWV3RGlyZWN0aXZlfSBmcm9tIFwiLi4vZGlyZWN0aXZlc1wiO1xuaW1wb3J0IHtQcmV2aWV3VXRpbHN9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHtQcmV2aWV3U2VydmljZSwgVGhlbWVTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5pbXBvcnQge0kxOG5QaXBlfSBmcm9tIFwiLi4vaTE4bi9pMThuLnBpcGVcIjtcbmltcG9ydCB7RmlsZVNpemVQaXBlfSBmcm9tIFwiLi9maWxlLXNpemUucGlwZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtcHJldmlldy1saXN0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBQcmV2aWV3SWNvbkNvbXBvbmVudCxcbiAgICBQcmV2aWV3RGlyZWN0aXZlLFxuICAgIEkxOG5QaXBlLFxuICAgIEZpbGVTaXplUGlwZVxuICBdLFxuICBwcm92aWRlcnM6IFtUaGVtZVNlcnZpY2UsUHJldmlld1NlcnZpY2VdLFxuICB0ZW1wbGF0ZVVybDogJ3ByZXZpZXctbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW1xuICAgICcuLi9zdHlsZXMvX3RoZW1lLnNjc3MnLFxuICAgICdwcmV2aWV3LWxpc3QuY29tcG9uZW50LnNjc3MnXG4gIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIFByZXZpZXdMaXN0Q29tcG9uZW50IHtcbiAgQElucHV0KCkgdHJpZ2dlciA9ICdjbGljayc7IC8vIOm7mOiupOinpuWPkeaWueW8j1xuICBwcml2YXRlIF9maWxlczogUHJldmlld0ZpbGVbXSA9IFtdO1xuICBASW5wdXQoKVxuICBnZXQgZmlsZXMoKTogUHJldmlld0ZpbGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2ZpbGVzO1xuICB9XG4gIHNldCBmaWxlcyh2YWx1ZTogUHJldmlld0ZpbGVJbnB1dCkge1xuICAgIHRoaXMuX2ZpbGVzID0gUHJldmlld1V0aWxzLm5vcm1hbGl6ZUZpbGVzKHZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dCgpIGluZGV4ID0gMDtcbiAgcHJpdmF0ZSBfdGhlbWVNb2RlOiBUaGVtZU1vZGUgPSAnYXV0byc7XG4gIEBJbnB1dCgpXG4gIGdldCB0aGVtZU1vZGUoKTogVGhlbWVNb2RlIHtcbiAgICByZXR1cm4gdGhpcy5fdGhlbWVNb2RlO1xuICB9XG4gIHNldCB0aGVtZU1vZGUodmFsdWU6IFRoZW1lTW9kZSkge1xuICAgIHRoaXMuX3RoZW1lTW9kZSA9IHZhbHVlO1xuICAgIHRoaXMudGhlbWVTZXJ2aWNlLnNldE1vZGUodGhpcy5fdGhlbWVNb2RlKTtcbiAgICBpZiAodGhpcy5fdGhlbWVNb2RlID09PSAnYXV0bycgJiYgdGhpcy5hdXRvQ29uZmlnKSB7XG4gICAgICB0aGlzLnRoZW1lU2VydmljZS5zZXRBdXRvQ29uZmlnKHRoaXMuYXV0b0NvbmZpZyk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpIGF1dG9Db25maWc/OiBBdXRvVGhlbWVDb25maWc7XG4gIHByaXZhdGUgX2xhbmc6c3RyaW5nID0gJ3poJ1xuICBASW5wdXQoKVxuICBnZXQgbGFuZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9sYW5nO1xuICB9XG4gIHNldCBsYW5nKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9sYW5nID0gdmFsdWU7XG4gICAgdGhpcy5wcmV2aWV3U2VydmljZS5zZXRMYW5nKHZhbHVlKVxuICB9XG4gIEBPdXRwdXQoKSBwcmV2aWV3RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPFByZXZpZXdFdmVudD4oKTtcbiAgQENvbnRlbnRDaGlsZCgnaXRlbVRlbXBsYXRlJykgaXRlbVRlbXBsYXRlPzogVGVtcGxhdGVSZWY8YW55PjtcbiAgQFZpZXdDaGlsZHJlbigncHJldmlld1RyaWdnZXInKSBwcmV2aWV3VHJpZ2dlcnMhOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0aGVtZVNlcnZpY2U6IFRoZW1lU2VydmljZSxwdWJsaWMgcHJldmlld1NlcnZpY2U6UHJldmlld1NlcnZpY2UscHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7XG4gICAgdGhpcy50aGVtZVNlcnZpY2UuYmluZEVsZW1lbnQodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgdHJpZ2dlclNlbGVjdChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMucHJldmlld0V2ZW50LmVtaXQoe3R5cGU6ICdzZWxlY3QnLCBldmVudDogdGhpcy5maWxlc1tpbmRleF19KTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm5neC1wcmV2aWV3LWxpc3RcIj5cbiAgPGRpdiBjbGFzcz1cIm5neC1wcmV2aWV3LWxpc3RfX2hlYWRlclwiPlxuICAgIDxzcGFuPnt7ICdsaXN0LnRpdGxlJ3xpMThuIH19PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwiY291bnRcIj5cbiAgICAgIEBpZiAoZmlsZXM/Lmxlbmd0aCkge1xuICAgICAgICB7eyAnbGlzdC50b3RhbCd8aTE4bjpmaWxlcz8ubGVuZ3RoIH19XG4gICAgICB9XG4gICAgPC9zcGFuPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cIm5neC1wcmV2aWV3LWxpc3RfX2NvbnRlbnRcIj5cbiAgICBAZm9yIChmaWxlIG9mIGZpbGVzOyBsZXQgaSA9ICRpbmRleDsgdHJhY2sgZmlsZS5uYW1lKSB7XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbVRlbXBsYXRlOyBlbHNlIGRlZmF1bHRUZW1wbGF0ZVwiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogbm9uZVwiICNwcmV2aWV3VHJpZ2dlclxuICAgICAgICAgICAgIFtuZ3hGaWxlUHJldmlld109XCJmaWxlXCJcbiAgICAgICAgICAgICBbdHJpZ2dlcl09XCJ0cmlnZ2VyXCJcbiAgICAgICAgICAgICBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiXG4gICAgICAgICAgICAgW2xhbmddPVwibGFuZ1wiPjwvZGl2PlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbVRlbXBsYXRlXCJcbiAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgICRpbXBsaWNpdDogZmlsZSxcbiAgICAgICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgICAgICBpc0FjdGl2ZTogaSA9PT0gaW5kZXgsXG4gICAgICAgICAgICAgICAgdGhlbWVNb2RlOiB0aGVtZU1vZGUsXG4gICAgICAgICAgICAgICAgdHlwZTogKCd0eXBlcy4nK2ZpbGUudHlwZSl8aTE4bixcbiAgICAgICAgICAgICAgICBzZWxlY3Q6IHRyaWdnZXJTZWxlY3QuYmluZCh0aGlzLGkpLFxuICAgICAgICAgICAgICAgIHByZXZpZXc6IHByZXZpZXdUcmlnZ2VyLmNsaWNrLmJpbmQocHJldmlld1RyaWdnZXIpXG4gICAgICAgICAgICAgIH1cIlxuICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFRlbXBsYXRlPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbVwiXG4gICAgICAgICAgICAgKGNsaWNrKT1cInRyaWdnZXJTZWxlY3QoaSlcIlxuICAgICAgICAgICAgIFtuZ3hGaWxlUHJldmlld109XCJmaWxlXCJcbiAgICAgICAgICAgICBbdHJpZ2dlcl09XCJ0cmlnZ2VyXCJcbiAgICAgICAgICAgICBbdGhlbWVNb2RlXT1cInRoZW1lTW9kZVwiXG4gICAgICAgICAgICAgW2xhbmddPVwibGFuZ1wiXG4gICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpID09PSBpbmRleFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImljb25cIj5cbiAgICAgICAgICAgICAgICA8cHJldmlldy1pY29uIFt0aGVtZU1vZGVdPVwidGhlbWVNb2RlXCIgW3NpemVdPVwiNDBcIiBbc3ZnXT1cImZpbGUudHlwZVwiPjwvcHJldmlldy1pY29uPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImluZm9cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYWluLWluZm9cIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuYW1lXCI+e3sgZmlsZS5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNpemVcIj57eyBmaWxlLnNpemV8ZmlsZVNpemUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdWItaW5mb1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR5cGVcIj57eyAoJ3R5cGVzLicgKyBmaWxlLnR5cGUpfGkxOG4gfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGF0ZVwiICpuZ0lmPVwiZmlsZS5sYXN0TW9kaWZpZWRcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgZmlsZS5sYXN0TW9kaWZpZWR8ZGF0ZToneXl5eS1NTS1kZCBISDptbTpzcycgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgfSBAZW1wdHkge1xuICAgICAgPGRpdiBjbGFzcz1cImVtcHR5XCI+e3sgJ2xpc3QuZW1wdHknfGkxOG4gfX08L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuPC9kaXY+XG48bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4iXX0=