ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
399 lines • 43.9 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, ViewChild, ViewEncapsulation } from '@angular/core';
import { fromEvent } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { fadeMotion } from 'ng-zorro-antd/core/animation';
import { NzDestroyService } from 'ng-zorro-antd/core/services';
import { isNotNil } from 'ng-zorro-antd/core/util';
import { FADE_CLASS_NAME_MAP, NZ_CONFIG_MODULE_NAME } from './image-config';
import { getClientSize, getFitContentPosition, getOffset } from './utils';
import * as i0 from "@angular/core";
import * as i1 from "ng-zorro-antd/core/config";
import * as i2 from "./image-preview-options";
import * as i3 from "@angular/cdk/overlay";
import * as i4 from "ng-zorro-antd/core/services";
import * as i5 from "@angular/common";
import * as i6 from "ng-zorro-antd/icon";
import * as i7 from "@angular/cdk/drag-drop";
const initialPosition = {
x: 0,
y: 0
};
export class NzImagePreviewComponent {
constructor(ngZone, host, cdr, nzConfigService, config, overlayRef, destroy$) {
this.ngZone = ngZone;
this.host = host;
this.cdr = cdr;
this.nzConfigService = nzConfigService;
this.config = config;
this.overlayRef = overlayRef;
this.destroy$ = destroy$;
this.images = [];
this.index = 0;
this.isDragging = false;
this.visible = true;
this.animationState = 'enter';
this.animationStateChanged = new EventEmitter();
this.previewImageTransform = '';
this.previewImageWrapperTransform = '';
this.operations = [
{
icon: 'close',
onClick: () => {
this.onClose();
},
type: 'close'
},
{
icon: 'zoom-in',
onClick: () => {
this.onZoomIn();
},
type: 'zoomIn'
},
{
icon: 'zoom-out',
onClick: () => {
this.onZoomOut();
},
type: 'zoomOut'
},
{
icon: 'rotate-right',
onClick: () => {
this.onRotateRight();
},
type: 'rotateRight'
},
{
icon: 'rotate-left',
onClick: () => {
this.onRotateLeft();
},
type: 'rotateLeft'
}
];
this.zoomOutDisabled = false;
this.position = { ...initialPosition };
this.containerClick = new EventEmitter();
this.closeClick = new EventEmitter();
this.zoom = this.config.nzZoom ?? 1;
this.rotate = this.config.nzRotate ?? 0;
this.updateZoomOutDisabled();
this.updatePreviewImageTransform();
this.updatePreviewImageWrapperTransform();
}
get animationDisabled() {
return this.config.nzNoAnimation ?? false;
}
get maskClosable() {
const defaultConfig = this.nzConfigService.getConfigForComponent(NZ_CONFIG_MODULE_NAME) || {};
return this.config.nzMaskClosable ?? defaultConfig.nzMaskClosable ?? true;
}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
fromEvent(this.host.nativeElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
if (event.target === event.currentTarget && this.maskClosable && this.containerClick.observers.length) {
this.ngZone.run(() => this.containerClick.emit());
}
});
fromEvent(this.imagePreviewWrapper.nativeElement, 'mousedown')
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.isDragging = true;
});
});
}
setImages(images) {
this.images = images;
this.cdr.markForCheck();
}
switchTo(index) {
this.index = index;
this.cdr.markForCheck();
}
next() {
if (this.index < this.images.length - 1) {
this.reset();
this.index++;
this.updatePreviewImageTransform();
this.updatePreviewImageWrapperTransform();
this.updateZoomOutDisabled();
this.cdr.markForCheck();
}
}
prev() {
if (this.index > 0) {
this.reset();
this.index--;
this.updatePreviewImageTransform();
this.updatePreviewImageWrapperTransform();
this.updateZoomOutDisabled();
this.cdr.markForCheck();
}
}
markForCheck() {
this.cdr.markForCheck();
}
onClose() {
this.closeClick.emit();
}
onZoomIn() {
this.zoom += 1;
this.updatePreviewImageTransform();
this.updateZoomOutDisabled();
this.position = { ...initialPosition };
}
onZoomOut() {
if (this.zoom > 1) {
this.zoom -= 1;
this.updatePreviewImageTransform();
this.updateZoomOutDisabled();
this.position = { ...initialPosition };
}
}
onRotateRight() {
this.rotate += 90;
this.updatePreviewImageTransform();
}
onRotateLeft() {
this.rotate -= 90;
this.updatePreviewImageTransform();
}
onSwitchLeft(event) {
event.preventDefault();
event.stopPropagation();
this.prev();
}
onSwitchRight(event) {
event.preventDefault();
event.stopPropagation();
this.next();
}
onAnimationStart(event) {
if (event.toState === 'enter') {
this.setEnterAnimationClass();
}
else if (event.toState === 'leave') {
this.setLeaveAnimationClass();
}
this.animationStateChanged.emit(event);
}
onAnimationDone(event) {
if (event.toState === 'enter') {
this.setEnterAnimationClass();
}
else if (event.toState === 'leave') {
this.setLeaveAnimationClass();
}
this.animationStateChanged.emit(event);
}
startLeaveAnimation() {
this.animationState = 'leave';
this.cdr.markForCheck();
}
onDragReleased() {
this.isDragging = false;
const width = this.imageRef.nativeElement.offsetWidth * this.zoom;
const height = this.imageRef.nativeElement.offsetHeight * this.zoom;
const { left, top } = getOffset(this.imageRef.nativeElement);
const { width: clientWidth, height: clientHeight } = getClientSize();
const isRotate = this.rotate % 180 !== 0;
const fitContentParams = {
width: isRotate ? height : width,
height: isRotate ? width : height,
left,
top,
clientWidth,
clientHeight
};
const fitContentPos = getFitContentPosition(fitContentParams);
if (isNotNil(fitContentPos.x) || isNotNil(fitContentPos.y)) {
this.position = { ...this.position, ...fitContentPos };
}
}
updatePreviewImageTransform() {
this.previewImageTransform = `scale3d(${this.zoom}, ${this.zoom}, 1) rotate(${this.rotate}deg)`;
}
updatePreviewImageWrapperTransform() {
this.previewImageWrapperTransform = `translate3d(${this.position.x}px, ${this.position.y}px, 0)`;
}
updateZoomOutDisabled() {
this.zoomOutDisabled = this.zoom <= 1;
}
setEnterAnimationClass() {
if (this.animationDisabled) {
return;
}
const backdropElement = this.overlayRef.backdropElement;
if (backdropElement) {
backdropElement.classList.add(FADE_CLASS_NAME_MAP.enter);
backdropElement.classList.add(FADE_CLASS_NAME_MAP.enterActive);
}
}
setLeaveAnimationClass() {
if (this.animationDisabled) {
return;
}
const backdropElement = this.overlayRef.backdropElement;
if (backdropElement) {
backdropElement.classList.add(FADE_CLASS_NAME_MAP.leave);
backdropElement.classList.add(FADE_CLASS_NAME_MAP.leaveActive);
}
}
reset() {
this.zoom = 1;
this.rotate = 0;
this.position = { ...initialPosition };
}
}
NzImagePreviewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzImagePreviewComponent, deps: [{ token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.NzConfigService }, { token: i2.NzImagePreviewOptions }, { token: i3.OverlayRef }, { token: i4.NzDestroyService }], target: i0.ɵɵFactoryTarget.Component });
NzImagePreviewComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: NzImagePreviewComponent, selector: "nz-image-preview", host: { attributes: { "tabindex": "-1", "role": "document" }, listeners: { "@fadeMotion.start": "onAnimationStart($event)", "@fadeMotion.done": "onAnimationDone($event)" }, properties: { "class.ant-image-preview-moving": "isDragging", "style.zIndex": "config.nzZIndex", "@.disabled": "config.nzNoAnimation", "@fadeMotion": "animationState" }, classAttribute: "ant-image-preview-wrap" }, providers: [NzDestroyService], viewQueries: [{ propertyName: "imageRef", first: true, predicate: ["imgRef"], descendants: true }, { propertyName: "imagePreviewWrapper", first: true, predicate: ["imagePreviewWrapper"], descendants: true, static: true }], exportAs: ["nzImagePreview"], ngImport: i0, template: `
<div class="ant-image-preview">
<div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div>
<div class="ant-image-preview-content">
<div class="ant-image-preview-body">
<ul class="ant-image-preview-operations">
<li
class="ant-image-preview-operations-operation"
[class.ant-image-preview-operations-operation-disabled]="zoomOutDisabled && option.type === 'zoomOut'"
(click)="option.onClick()"
*ngFor="let option of operations"
>
<span class="ant-image-preview-operations-icon" nz-icon [nzType]="option.icon" nzTheme="outline"></span>
</li>
</ul>
<div
class="ant-image-preview-img-wrapper"
#imagePreviewWrapper
cdkDrag
[style.transform]="previewImageWrapperTransform"
[cdkDragFreeDragPosition]="position"
(cdkDragReleased)="onDragReleased()"
>
<ng-container *ngFor="let image of images; index as imageIndex">
<img
cdkDragHandle
class="ant-image-preview-img"
#imgRef
*ngIf="index === imageIndex"
[attr.src]="image.src"
[attr.srcset]="image.srcset"
[attr.alt]="image.alt"
[style.width]="image.width"
[style.height]="image.height"
[style.transform]="previewImageTransform"
/>
</ng-container>
</div>
<ng-container *ngIf="images.length > 1">
<div
class="ant-image-preview-switch-left"
[class.ant-image-preview-switch-left-disabled]="index <= 0"
(click)="onSwitchLeft($event)"
>
<span nz-icon nzType="left" nzTheme="outline"></span>
</div>
<div
class="ant-image-preview-switch-right"
[class.ant-image-preview-switch-right-disabled]="index >= images.length - 1"
(click)="onSwitchRight($event)"
>
<span nz-icon nzType="right" nzTheme="outline"></span>
</div>
</ng-container>
</div>
</div>
<div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div>
</div>
`, isInline: true, directives: [{ type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { type: i7.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }], animations: [fadeMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: NzImagePreviewComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-image-preview',
exportAs: 'nzImagePreview',
animations: [fadeMotion],
template: `
<div class="ant-image-preview">
<div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div>
<div class="ant-image-preview-content">
<div class="ant-image-preview-body">
<ul class="ant-image-preview-operations">
<li
class="ant-image-preview-operations-operation"
[class.ant-image-preview-operations-operation-disabled]="zoomOutDisabled && option.type === 'zoomOut'"
(click)="option.onClick()"
*ngFor="let option of operations"
>
<span class="ant-image-preview-operations-icon" nz-icon [nzType]="option.icon" nzTheme="outline"></span>
</li>
</ul>
<div
class="ant-image-preview-img-wrapper"
#imagePreviewWrapper
cdkDrag
[style.transform]="previewImageWrapperTransform"
[cdkDragFreeDragPosition]="position"
(cdkDragReleased)="onDragReleased()"
>
<ng-container *ngFor="let image of images; index as imageIndex">
<img
cdkDragHandle
class="ant-image-preview-img"
#imgRef
*ngIf="index === imageIndex"
[attr.src]="image.src"
[attr.srcset]="image.srcset"
[attr.alt]="image.alt"
[style.width]="image.width"
[style.height]="image.height"
[style.transform]="previewImageTransform"
/>
</ng-container>
</div>
<ng-container *ngIf="images.length > 1">
<div
class="ant-image-preview-switch-left"
[class.ant-image-preview-switch-left-disabled]="index <= 0"
(click)="onSwitchLeft($event)"
>
<span nz-icon nzType="left" nzTheme="outline"></span>
</div>
<div
class="ant-image-preview-switch-right"
[class.ant-image-preview-switch-right-disabled]="index >= images.length - 1"
(click)="onSwitchRight($event)"
>
<span nz-icon nzType="right" nzTheme="outline"></span>
</div>
</ng-container>
</div>
</div>
<div tabindex="0" aria-hidden="true" style="width: 0; height: 0; overflow: hidden; outline: none;"></div>
</div>
`,
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'ant-image-preview-wrap',
'[class.ant-image-preview-moving]': 'isDragging',
'[style.zIndex]': 'config.nzZIndex',
'[@.disabled]': 'config.nzNoAnimation',
'[@fadeMotion]': 'animationState',
'(@fadeMotion.start)': 'onAnimationStart($event)',
'(@fadeMotion.done)': 'onAnimationDone($event)',
tabindex: '-1',
role: 'document'
},
providers: [NzDestroyService]
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.NzConfigService }, { type: i2.NzImagePreviewOptions }, { type: i3.OverlayRef }, { type: i4.NzDestroyService }]; }, propDecorators: { imageRef: [{
type: ViewChild,
args: ['imgRef']
}], imagePreviewWrapper: [{
type: ViewChild,
args: ['imagePreviewWrapper', { static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtcHJldmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2ltYWdlL2ltYWdlLXByZXZpZXcuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFHWixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUUxRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUUvRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFbkQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHNUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxxQkFBcUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7Ozs7Ozs7OztBQVMxRSxNQUFNLGVBQWUsR0FBRztJQUN0QixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMsRUFBRSxDQUFDO0NBQ0wsQ0FBQztBQWlGRixNQUFNLE9BQU8sdUJBQXVCO0lBcUVsQyxZQUNVLE1BQWMsRUFDZCxJQUE2QixFQUM3QixHQUFzQixFQUN2QixlQUFnQyxFQUNoQyxNQUE2QixFQUM1QixVQUFzQixFQUN0QixRQUEwQjtRQU4xQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDdkIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLFdBQU0sR0FBTixNQUFNLENBQXVC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bnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgQW5pbWF0aW9uRXZlbnQgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBOZ1pvbmUsXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBmYWRlTW90aW9uIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2FuaW1hdGlvbic7XG5pbXBvcnQgeyBOekNvbmZpZ1NlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IE56RGVzdHJveVNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvc2VydmljZXMnO1xuaW1wb3J0IHsgTnpTYWZlQW55IH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IGlzTm90TmlsIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuXG5pbXBvcnQgeyBGQURFX0NMQVNTX05BTUVfTUFQLCBOWl9DT05GSUdfTU9EVUxFX05BTUUgfSBmcm9tICcuL2ltYWdlLWNvbmZpZyc7XG5pbXBvcnQgeyBOekltYWdlLCBOekltYWdlUHJldmlld09wdGlvbnMgfSBmcm9tICcuL2ltYWdlLXByZXZpZXctb3B0aW9ucyc7XG5pbXBvcnQgeyBOekltYWdlUHJldmlld1JlZiB9IGZyb20gJy4vaW1hZ2UtcHJldmlldy1yZWYnO1xuaW1wb3J0IHsgZ2V0Q2xpZW50U2l6ZSwgZ2V0Rml0Q29udGVudFBvc2l0aW9uLCBnZXRPZmZzZXQgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBOekltYWdlQ29udGFpbmVyT3BlcmF0aW9uIHtcbiAgaWNvbjogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG5cbiAgb25DbGljaygpOiB2b2lkO1xufVxuXG5jb25zdCBpbml0aWFsUG9zaXRpb24gPSB7XG4gIHg6IDAsXG4gIHk6IDBcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ256LWltYWdlLXByZXZpZXcnLFxuICBleHBvcnRBczogJ256SW1hZ2VQcmV2aWV3JyxcbiAgYW5pbWF0aW9uczogW2ZhZGVNb3Rpb25dLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhbnQtaW1hZ2UtcHJldmlld1wiPlxuICAgICAgPGRpdiB0YWJpbmRleD1cIjBcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBzdHlsZT1cIndpZHRoOiAwOyBoZWlnaHQ6IDA7IG92ZXJmbG93OiBoaWRkZW47IG91dGxpbmU6IG5vbmU7XCI+PC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXctY29udGVudFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXctYm9keVwiPlxuICAgICAgICAgIDx1bCBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LW9wZXJhdGlvbnNcIj5cbiAgICAgICAgICAgIDxsaVxuICAgICAgICAgICAgICBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LW9wZXJhdGlvbnMtb3BlcmF0aW9uXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmFudC1pbWFnZS1wcmV2aWV3LW9wZXJhdGlvbnMtb3BlcmF0aW9uLWRpc2FibGVkXT1cInpvb21PdXREaXNhYmxlZCAmJiBvcHRpb24udHlwZSA9PT0gJ3pvb21PdXQnXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wdGlvbi5vbkNsaWNrKClcIlxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIG9wZXJhdGlvbnNcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LW9wZXJhdGlvbnMtaWNvblwiIG56LWljb24gW256VHlwZV09XCJvcHRpb24uaWNvblwiIG56VGhlbWU9XCJvdXRsaW5lXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICA8L3VsPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiYW50LWltYWdlLXByZXZpZXctaW1nLXdyYXBwZXJcIlxuICAgICAgICAgICAgI2ltYWdlUHJldmlld1dyYXBwZXJcbiAgICAgICAgICAgIGNka0RyYWdcbiAgICAgICAgICAgIFtzdHlsZS50cmFuc2Zvcm1dPVwicHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybVwiXG4gICAgICAgICAgICBbY2RrRHJhZ0ZyZWVEcmFnUG9zaXRpb25dPVwicG9zaXRpb25cIlxuICAgICAgICAgICAgKGNka0RyYWdSZWxlYXNlZCk9XCJvbkRyYWdSZWxlYXNlZCgpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpbWFnZSBvZiBpbWFnZXM7IGluZGV4IGFzIGltYWdlSW5kZXhcIj5cbiAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgIGNka0RyYWdIYW5kbGVcbiAgICAgICAgICAgICAgICBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LWltZ1wiXG4gICAgICAgICAgICAgICAgI2ltZ1JlZlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaW5kZXggPT09IGltYWdlSW5kZXhcIlxuICAgICAgICAgICAgICAgIFthdHRyLnNyY109XCJpbWFnZS5zcmNcIlxuICAgICAgICAgICAgICAgIFthdHRyLnNyY3NldF09XCJpbWFnZS5zcmNzZXRcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFsdF09XCJpbWFnZS5hbHRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJpbWFnZS53aWR0aFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodF09XCJpbWFnZS5oZWlnaHRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS50cmFuc2Zvcm1dPVwicHJldmlld0ltYWdlVHJhbnNmb3JtXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpbWFnZXMubGVuZ3RoID4gMVwiPlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LXN3aXRjaC1sZWZ0XCJcbiAgICAgICAgICAgICAgW2NsYXNzLmFudC1pbWFnZS1wcmV2aWV3LXN3aXRjaC1sZWZ0LWRpc2FibGVkXT1cImluZGV4IDw9IDBcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwib25Td2l0Y2hMZWZ0KCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhbiBuei1pY29uIG56VHlwZT1cImxlZnRcIiBuelRoZW1lPVwib3V0bGluZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBjbGFzcz1cImFudC1pbWFnZS1wcmV2aWV3LXN3aXRjaC1yaWdodFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5hbnQtaW1hZ2UtcHJldmlldy1zd2l0Y2gtcmlnaHQtZGlzYWJsZWRdPVwiaW5kZXggPj0gaW1hZ2VzLmxlbmd0aCAtIDFcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwib25Td2l0Y2hSaWdodCgkZXZlbnQpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHNwYW4gbnotaWNvbiBuelR5cGU9XCJyaWdodFwiIG56VGhlbWU9XCJvdXRsaW5lXCI+PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IHRhYmluZGV4PVwiMFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiIHN0eWxlPVwid2lkdGg6IDA7IGhlaWdodDogMDsgb3ZlcmZsb3c6IGhpZGRlbjsgb3V0bGluZTogbm9uZTtcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdhbnQtaW1hZ2UtcHJldmlldy13cmFwJyxcbiAgICAnW2NsYXNzLmFudC1pbWFnZS1wcmV2aWV3LW1vdmluZ10nOiAnaXNEcmFnZ2luZycsXG4gICAgJ1tzdHlsZS56SW5kZXhdJzogJ2NvbmZpZy5uelpJbmRleCcsXG4gICAgJ1tALmRpc2FibGVkXSc6ICdjb25maWcubnpOb0FuaW1hdGlvbicsXG4gICAgJ1tAZmFkZU1vdGlvbl0nOiAnYW5pbWF0aW9uU3RhdGUnLFxuICAgICcoQGZhZGVNb3Rpb24uc3RhcnQpJzogJ29uQW5pbWF0aW9uU3RhcnQoJGV2ZW50KScsXG4gICAgJyhAZmFkZU1vdGlvbi5kb25lKSc6ICdvbkFuaW1hdGlvbkRvbmUoJGV2ZW50KScsXG4gICAgdGFiaW5kZXg6ICctMScsXG4gICAgcm9sZTogJ2RvY3VtZW50J1xuICB9LFxuICBwcm92aWRlcnM6IFtOekRlc3Ryb3lTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBOekltYWdlUHJldmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIGltYWdlczogTnpJbWFnZVtdID0gW107XG4gIGluZGV4ID0gMDtcbiAgaXNEcmFnZ2luZyA9IGZhbHNlO1xuICB2aXNpYmxlID0gdHJ1ZTtcbiAgYW5pbWF0aW9uU3RhdGU6ICd2b2lkJyB8ICdlbnRlcicgfCAnbGVhdmUnID0gJ2VudGVyJztcbiAgYW5pbWF0aW9uU3RhdGVDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxBbmltYXRpb25FdmVudD4oKTtcblxuICBwcmV2aWV3SW1hZ2VUcmFuc2Zvcm0gPSAnJztcbiAgcHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybSA9ICcnO1xuICBvcGVyYXRpb25zOiBOekltYWdlQ29udGFpbmVyT3BlcmF0aW9uW10gPSBbXG4gICAge1xuICAgICAgaWNvbjogJ2Nsb3NlJyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vbkNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ2Nsb3NlJ1xuICAgIH0sXG4gICAge1xuICAgICAgaWNvbjogJ3pvb20taW4nLFxuICAgICAgb25DbGljazogKCkgPT4ge1xuICAgICAgICB0aGlzLm9uWm9vbUluKCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3pvb21JbidcbiAgICB9LFxuICAgIHtcbiAgICAgIGljb246ICd6b29tLW91dCcsXG4gICAgICBvbkNsaWNrOiAoKSA9PiB7XG4gICAgICAgIHRoaXMub25ab29tT3V0KCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3pvb21PdXQnXG4gICAgfSxcbiAgICB7XG4gICAgICBpY29uOiAncm90YXRlLXJpZ2h0JyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vblJvdGF0ZVJpZ2h0KCk7XG4gICAgICB9LFxuICAgICAgdHlwZTogJ3JvdGF0ZVJpZ2h0J1xuICAgIH0sXG4gICAge1xuICAgICAgaWNvbjogJ3JvdGF0ZS1sZWZ0JyxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHtcbiAgICAgICAgdGhpcy5vblJvdGF0ZUxlZnQoKTtcbiAgICAgIH0sXG4gICAgICB0eXBlOiAncm90YXRlTGVmdCdcbiAgICB9XG4gIF07XG5cbiAgem9vbU91dERpc2FibGVkID0gZmFsc2U7XG4gIHBvc2l0aW9uID0geyAuLi5pbml0aWFsUG9zaXRpb24gfTtcbiAgcHJldmlld1JlZiE6IE56SW1hZ2VQcmV2aWV3UmVmO1xuICBjb250YWluZXJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgY2xvc2VDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBAVmlld0NoaWxkKCdpbWdSZWYnKSBpbWFnZVJlZiE6IEVsZW1lbnRSZWY8SFRNTEltYWdlRWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ2ltYWdlUHJldmlld1dyYXBwZXInLCB7IHN0YXRpYzogdHJ1ZSB9KSBpbWFnZVByZXZpZXdXcmFwcGVyITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgcHJpdmF0ZSB6b29tOiBudW1iZXI7XG4gIHByaXZhdGUgcm90YXRlOiBudW1iZXI7XG5cbiAgZ2V0IGFuaW1hdGlvbkRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5uek5vQW5pbWF0aW9uID8/IGZhbHNlO1xuICB9XG5cbiAgZ2V0IG1hc2tDbG9zYWJsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkZWZhdWx0Q29uZmlnOiBOelNhZmVBbnkgPSB0aGlzLm56Q29uZmlnU2VydmljZS5nZXRDb25maWdGb3JDb21wb25lbnQoTlpfQ09ORklHX01PRFVMRV9OQU1FKSB8fCB7fTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcubnpNYXNrQ2xvc2FibGUgPz8gZGVmYXVsdENvbmZpZy5uek1hc2tDbG9zYWJsZSA/PyB0cnVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgcHVibGljIGNvbmZpZzogTnpJbWFnZVByZXZpZXdPcHRpb25zLFxuICAgIHByaXZhdGUgb3ZlcmxheVJlZjogT3ZlcmxheVJlZixcbiAgICBwcml2YXRlIGRlc3Ryb3kkOiBOekRlc3Ryb3lTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuem9vbSA9IHRoaXMuY29uZmlnLm56Wm9vbSA/PyAxO1xuICAgIHRoaXMucm90YXRlID0gdGhpcy5jb25maWcubnpSb3RhdGUgPz8gMDtcbiAgICB0aGlzLnVwZGF0ZVpvb21PdXREaXNhYmxlZCgpO1xuICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlVHJhbnNmb3JtKCk7XG4gICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VXcmFwcGVyVHJhbnNmb3JtKCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBmcm9tRXZlbnQodGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQsICdjbGljaycpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCAmJiB0aGlzLm1hc2tDbG9zYWJsZSAmJiB0aGlzLmNvbnRhaW5lckNsaWNrLm9ic2VydmVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNvbnRhaW5lckNsaWNrLmVtaXQoKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgZnJvbUV2ZW50KHRoaXMuaW1hZ2VQcmV2aWV3V3JhcHBlci5uYXRpdmVFbGVtZW50LCAnbW91c2Vkb3duJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldEltYWdlcyhpbWFnZXM6IE56SW1hZ2VbXSk6IHZvaWQge1xuICAgIHRoaXMuaW1hZ2VzID0gaW1hZ2VzO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgc3dpdGNoVG8oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG5leHQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW5kZXggPCB0aGlzLmltYWdlcy5sZW5ndGggLSAxKSB7XG4gICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICB0aGlzLmluZGV4Kys7XG4gICAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpO1xuICAgICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VXcmFwcGVyVHJhbnNmb3JtKCk7XG4gICAgICB0aGlzLnVwZGF0ZVpvb21PdXREaXNhYmxlZCgpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgcHJldigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbmRleCA+IDApIHtcbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIHRoaXMuaW5kZXgtLTtcbiAgICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlVHJhbnNmb3JtKCk7XG4gICAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVdyYXBwZXJUcmFuc2Zvcm0oKTtcbiAgICAgIHRoaXMudXBkYXRlWm9vbU91dERpc2FibGVkKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICBtYXJrRm9yQ2hlY2soKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvbkNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDbGljay5lbWl0KCk7XG4gIH1cblxuICBvblpvb21JbigpOiB2b2lkIHtcbiAgICB0aGlzLnpvb20gKz0gMTtcbiAgICB0aGlzLnVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpO1xuICAgIHRoaXMudXBkYXRlWm9vbU91dERpc2FibGVkKCk7XG4gICAgdGhpcy5wb3NpdGlvbiA9IHsgLi4uaW5pdGlhbFBvc2l0aW9uIH07XG4gIH1cblxuICBvblpvb21PdXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuem9vbSA+IDEpIHtcbiAgICAgIHRoaXMuem9vbSAtPSAxO1xuICAgICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTtcbiAgICAgIHRoaXMudXBkYXRlWm9vbU91dERpc2FibGVkKCk7XG4gICAgICB0aGlzLnBvc2l0aW9uID0geyAuLi5pbml0aWFsUG9zaXRpb24gfTtcbiAgICB9XG4gIH1cblxuICBvblJvdGF0ZVJpZ2h0KCk6IHZvaWQge1xuICAgIHRoaXMucm90YXRlICs9IDkwO1xuICAgIHRoaXMudXBkYXRlUHJldmlld0ltYWdlVHJhbnNmb3JtKCk7XG4gIH1cblxuICBvblJvdGF0ZUxlZnQoKTogdm9pZCB7XG4gICAgdGhpcy5yb3RhdGUgLT0gOTA7XG4gICAgdGhpcy51cGRhdGVQcmV2aWV3SW1hZ2VUcmFuc2Zvcm0oKTtcbiAgfVxuXG4gIG9uU3dpdGNoTGVmdChldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5wcmV2KCk7XG4gIH1cblxuICBvblN3aXRjaFJpZ2h0KGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm5leHQoKTtcbiAgfVxuXG4gIG9uQW5pbWF0aW9uU3RhcnQoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuc2V0RW50ZXJBbmltYXRpb25DbGFzcygpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudG9TdGF0ZSA9PT0gJ2xlYXZlJykge1xuICAgICAgdGhpcy5zZXRMZWF2ZUFuaW1hdGlvbkNsYXNzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRpb25TdGF0ZUNoYW5nZWQuZW1pdChldmVudCk7XG4gIH1cblxuICBvbkFuaW1hdGlvbkRvbmUoZXZlbnQ6IEFuaW1hdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuc2V0RW50ZXJBbmltYXRpb25DbGFzcygpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudG9TdGF0ZSA9PT0gJ2xlYXZlJykge1xuICAgICAgdGhpcy5zZXRMZWF2ZUFuaW1hdGlvbkNsYXNzKCk7XG4gICAgfVxuICAgIHRoaXMuYW5pbWF0aW9uU3RhdGVDaGFuZ2VkLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgc3RhcnRMZWF2ZUFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gJ2xlYXZlJztcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uRHJhZ1JlbGVhc2VkKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5pbWFnZVJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoICogdGhpcy56b29tO1xuICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuaW1hZ2VSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKiB0aGlzLnpvb207XG4gICAgY29uc3QgeyBsZWZ0LCB0b3AgfSA9IGdldE9mZnNldCh0aGlzLmltYWdlUmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgIGNvbnN0IHsgd2lkdGg6IGNsaWVudFdpZHRoLCBoZWlnaHQ6IGNsaWVudEhlaWdodCB9ID0gZ2V0Q2xpZW50U2l6ZSgpO1xuICAgIGNvbnN0IGlzUm90YXRlID0gdGhpcy5yb3RhdGUgJSAxODAgIT09IDA7XG4gICAgY29uc3QgZml0Q29udGVudFBhcmFtcyA9IHtcbiAgICAgIHdpZHRoOiBpc1JvdGF0ZSA/IGhlaWdodCA6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBpc1JvdGF0ZSA/IHdpZHRoIDogaGVpZ2h0LFxuICAgICAgbGVmdCxcbiAgICAgIHRvcCxcbiAgICAgIGNsaWVudFdpZHRoLFxuICAgICAgY2xpZW50SGVpZ2h0XG4gICAgfTtcbiAgICBjb25zdCBmaXRDb250ZW50UG9zID0gZ2V0Rml0Q29udGVudFBvc2l0aW9uKGZpdENvbnRlbnRQYXJhbXMpO1xuICAgIGlmIChpc05vdE5pbChmaXRDb250ZW50UG9zLngpIHx8IGlzTm90TmlsKGZpdENvbnRlbnRQb3MueSkpIHtcbiAgICAgIHRoaXMucG9zaXRpb24gPSB7IC4uLnRoaXMucG9zaXRpb24sIC4uLmZpdENvbnRlbnRQb3MgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVByZXZpZXdJbWFnZVRyYW5zZm9ybSgpOiB2b2lkIHtcbiAgICB0aGlzLnByZXZpZXdJbWFnZVRyYW5zZm9ybSA9IGBzY2FsZTNkKCR7dGhpcy56b29tfSwgJHt0aGlzLnpvb219LCAxKSByb3RhdGUoJHt0aGlzLnJvdGF0ZX1kZWcpYDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUHJldmlld0ltYWdlV3JhcHBlclRyYW5zZm9ybSgpOiB2b2lkIHtcbiAgICB0aGlzLnByZXZpZXdJbWFnZVdyYXBwZXJUcmFuc2Zvcm0gPSBgdHJhbnNsYXRlM2QoJHt0aGlzLnBvc2l0aW9uLnh9cHgsICR7dGhpcy5wb3NpdGlvbi55fXB4LCAwKWA7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVpvb21PdXREaXNhYmxlZCgpOiB2b2lkIHtcbiAgICB0aGlzLnpvb21PdXREaXNhYmxlZCA9IHRoaXMuem9vbSA8PSAxO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRFbnRlckFuaW1hdGlvbkNsYXNzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFuaW1hdGlvbkRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGJhY2tkcm9wRWxlbWVudCA9IHRoaXMub3ZlcmxheVJlZi5iYWNrZHJvcEVsZW1lbnQ7XG4gICAgaWYgKGJhY2tkcm9wRWxlbWVudCkge1xuICAgICAgYmFja2Ryb3BFbGVtZW50LmNsYXNzTGlzdC5hZGQoRkFERV9DTEFTU19OQU1FX01BUC5lbnRlcik7XG4gICAgICBiYWNrZHJvcEVsZW1lbnQuY2xhc3NMaXN0LmFkZChGQURFX0NMQVNTX05BTUVfTUFQLmVudGVyQWN0aXZlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldExlYXZlQW5pbWF0aW9uQ2xhc3MoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uRGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYmFja2Ryb3BFbGVtZW50ID0gdGhpcy5vdmVybGF5UmVmLmJhY2tkcm9wRWxlbWVudDtcbiAgICBpZiAoYmFja2Ryb3BFbGVtZW50KSB7XG4gICAgICBiYWNrZHJvcEVsZW1lbnQuY2xhc3NMaXN0LmFkZChGQURFX0NMQVNTX05BTUVfTUFQLmxlYXZlKTtcbiAgICAgIGJhY2tkcm9wRWxlbWVudC5jbGFzc0xpc3QuYWRkKEZBREVfQ0xBU1NfTkFNRV9NQVAubGVhdmVBY3RpdmUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy56b29tID0gMTtcbiAgICB0aGlzLnJvdGF0ZSA9IDA7XG4gICAgdGhpcy5wb3NpdGlvbiA9IHsgLi4uaW5pdGlhbFBvc2l0aW9uIH07XG4gIH1cbn1cbiJdfQ==