@zodiac-ui/editor
Version:
A rich text editor for Angular based on `@atlaskit/editor-core`.
211 lines • 30.2 kB
JavaScript
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostListener, Injectable, Injector, } from "@angular/core";
import { InsertStatus, pluginKey } from "../../../plugins/link/pm/hyperlink";
import { ConnectionPositionPair, OverlayRef } from "@angular/cdk/overlay";
import { ComponentPortal } from "@angular/cdk/portal";
import { EditorToolbar } from "../../../lib/editor-toolbar/interfaces";
import { insertLink, removeLink, setLinkHref, setLinkText } from "../../../plugins/link/link.commands";
import { cascadeCommands } from "../../../plugins/alignment/alignment.command";
import { EditorService } from "../../../lib/editor.service";
export class FloatingToolbar {
constructor(editor, overlay) {
this.viewChange = editor.viewChange;
this.stateChange = editor.stateChange;
this.editor = editor;
this.overlay = overlay;
}
runTool(tool) {
this.editor.runTool(tool);
}
returnFocusToEditor() {
this.editor.view.focus();
}
}
FloatingToolbar.decorators = [
{ type: Injectable }
];
/** @nocollapse */
FloatingToolbar.ctorParameters = () => [
{ type: EditorService },
{ type: OverlayRef }
];
export const removeLinkTool = {
tooltip: 'Remove Link',
icon: 'fa-unlink',
run: (state, dispatch) => {
const pluginState = pluginKey.getState(state);
if (pluginState.activeLinkMark.type === InsertStatus.EDIT_LINK_TOOLBAR) {
return removeLink(pluginState.activeLinkMark.pos)(state, dispatch);
}
}
};
export class LinkPanelComponent {
constructor(toolbar, cdr, el) {
this.cdr = cdr;
this.url = '';
this.insertLink = {
tooltip: 'Add Link',
icon: 'fa-link',
run: (state, dispatch) => {
const pluginState = pluginKey.getState(state);
if (pluginState.activeLinkMark.type === InsertStatus.EDIT_LINK_TOOLBAR) {
const pos = pluginState.activeLinkMark.pos;
return cascadeCommands([
setLinkHref(this.url, pos),
setLinkText(this.linkText, pos),
])(state, dispatch);
}
if (pluginState.activeLinkMark.type === InsertStatus.INSERT_LINK_TOOLBAR) {
const { from, to } = pluginState.activeLinkMark;
return insertLink(from, to, this.url, this.linkText || this.url)(state, dispatch);
}
}
};
this.removeLink = removeLinkTool;
this.el = el;
this.openLink = {
tooltip: 'Open Link',
icon: 'fa-external-link-alt',
run: () => {
window.open(this.url, '_blank');
return false;
}
};
this.toolbar = toolbar;
this.sub = toolbar.stateChange.subscribe((editor) => {
const pluginState = pluginKey.getState(editor.state);
const linkMark = editor.state.schema.marks.link;
switch (pluginState.activeLinkMark.type) {
case InsertStatus.EDIT_LINK_TOOLBAR: {
const mark = linkMark.isInSet(pluginState.activeLinkMark.node.marks);
this.url = mark.attrs.href.trim();
this.linkText = pluginState.activeLinkMark.node.text.trim();
this.insert = false;
this.wrapLinkAroundText = true;
break;
}
case InsertStatus.INSERT_LINK_TOOLBAR: {
this.url = '';
this.linkText = '';
this.insert = true;
this.wrapLinkAroundText = pluginState.activeLinkMark.from !== pluginState.activeLinkMark.to;
break;
}
default:
}
this.cdr.markForCheck();
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
handleEnter(event) {
event.preventDefault();
this.setLink();
this.toolbar.returnFocusToEditor();
}
handleEsc() {
this.toolbar.returnFocusToEditor();
}
handleGlobalClick(target) {
if (!this.el.nativeElement.contains(target)) {
this.setLink();
}
}
setLink() {
this.toolbar.runTool(this.insertLink);
}
}
LinkPanelComponent.decorators = [
{ type: Component, args: [{
selector: "z-link-panel",
template: `
<mat-form-field *ngIf="!wrapLinkAroundText">
<input matInput placeholder="Link Text" [value]="linkText" (input)="linkText = $event.target.value" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="URL" [value]="url" (input)="url = $event.target.value" spellcheck="false" />
</mat-form-field>
<ng-container *ngIf="insert">
<z-editor-toolbar-button [tool]="insertLink"></z-editor-toolbar-button>
</ng-container>
<ng-container *ngIf="!insert">
<z-editor-toolbar-button [tool]="openLink"></z-editor-toolbar-button>
<z-editor-toolbar-button [tool]="removeLink"></z-editor-toolbar-button>
</ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [":host{display:block;padding:1rem .25rem 0;background:#fff;box-shadow:0 .5rem 2rem rgba(0,0,0,.2);margin:.5rem 0;text-align:right}mat-form-field{display:block;margin:0 .5rem}"]
}] }
];
/** @nocollapse */
LinkPanelComponent.ctorParameters = () => [
{ type: FloatingToolbar },
{ type: ChangeDetectorRef },
{ type: ElementRef }
];
LinkPanelComponent.propDecorators = {
handleEnter: [{ type: HostListener, args: ['keydown.enter', ['$event'],] }],
handleEsc: [{ type: HostListener, args: ['keydown.esc',] }],
handleGlobalClick: [{ type: HostListener, args: ['document:mousedown', ['$event.target'],] }]
};
export function attachLinkPanel(componentFactoryResolver, overlay, parentInjector) {
const overlayRef = overlay.create();
return (editor) => {
const pluginState = pluginKey.getState(editor.state);
const { link } = editor.state.schema.marks;
let origin;
let previousOrigin;
if (!pluginState.activeLinkMark || !link) {
overlayRef.detach();
return;
}
const toolbar = new FloatingToolbar(editor, overlayRef);
const injector = Injector.create({
parent: parentInjector,
providers: [{
provide: FloatingToolbar,
useValue: toolbar
}, {
provide: EditorToolbar,
useValue: toolbar
}]
});
const linkPanelPortal = new ComponentPortal(LinkPanelComponent, null, injector);
const positions = [
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }),
new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
];
switch (pluginState.activeLinkMark.type) {
case InsertStatus.EDIT_LINK_TOOLBAR: {
const el = editor.view.nodeDOM(pluginState.activeLinkMark.pos);
origin = el.parentElement;
break;
}
case InsertStatus.INSERT_LINK_TOOLBAR: {
const el = editor.view.domAtPos(pluginState.activeLinkMark.from);
origin = el.node;
break;
}
default:
}
if (previousOrigin !== origin) {
overlayRef.detach();
}
if (!overlayRef.hasAttached()) {
overlayRef.attach(linkPanelPortal);
const strategy = overlay.position()
.flexibleConnectedTo(origin)
.withFlexibleDimensions(false)
.withPush(false)
.withPositions(positions);
const scrollStrategy = overlay.scrollStrategies.reposition();
strategy.attach(overlayRef);
strategy.apply();
scrollStrategy.attach(overlayRef);
scrollStrategy.enable();
overlayRef.updatePositionStrategy(strategy);
previousOrigin = origin;
}
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluay1wYW5lbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Aem9kaWFjLXVpL2VkaXRvci8iLCJzb3VyY2VzIjpbInRvb2xzL2xpbmstdG9vbC9saW5rLXBhbmVsL2xpbmstcGFuZWwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDaUIsVUFBVSxFQUFFLFlBQVksRUFDbEQsVUFBVSxFQUNWLFFBQVEsR0FFWCxNQUFNLGVBQWUsQ0FBQTtBQUN0QixPQUFPLEVBQWtCLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQTtBQUU1RixPQUFPLEVBQUUsc0JBQXNCLEVBQVcsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDbEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3JELE9BQU8sRUFBYyxhQUFhLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQTtBQUNsRixPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUE7QUFHdEcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhDQUE4QyxDQUFBO0FBQzlFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQU8zRCxNQUFNLE9BQU8sZUFBZTtJQU14QixZQUFZLE1BQXFCLEVBQUUsT0FBbUI7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFBO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQTtRQUNyQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTtJQUMxQixDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWdCO1FBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQzdCLENBQUM7SUFFRCxtQkFBbUI7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUM1QixDQUFDOzs7WUFwQkosVUFBVTs7OztZQU5GLGFBQWE7WUFQb0IsVUFBVTs7QUFvQ3BELE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBZTtJQUN0QyxPQUFPLEVBQUUsYUFBYTtJQUN0QixJQUFJLEVBQUUsV0FBVztJQUNqQixHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUU7UUFDckIsTUFBTSxXQUFXLEdBQW1CLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDN0QsSUFBSSxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsaUJBQWlCLEVBQUU7WUFDcEUsT0FBTyxVQUFVLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUE7U0FDckU7SUFDTCxDQUFDO0NBQ0osQ0FBQTtBQXNCRCxNQUFNLE9BQU8sa0JBQWtCO0lBYzNCLFlBQVksT0FBd0IsRUFBRSxHQUFzQixFQUFFLEVBQWM7UUFDeEUsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUE7UUFDZCxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQTtRQUNiLElBQUksQ0FBQyxVQUFVLEdBQUc7WUFDZCxPQUFPLEVBQUUsVUFBVTtZQUNuQixJQUFJLEVBQUUsU0FBUztZQUNmLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRTtnQkFDckIsTUFBTSxXQUFXLEdBQW1CLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7Z0JBQzdELElBQUksV0FBVyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEtBQUssWUFBWSxDQUFDLGlCQUFpQixFQUFFO29CQUNwRSxNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQTtvQkFFMUMsT0FBTyxlQUFlLENBQUM7d0JBQ25CLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQzt3QkFDMUIsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDO3FCQUNsQyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2lCQUN0QjtnQkFDRCxJQUFJLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxtQkFBbUIsRUFBRTtvQkFDdEUsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFBO29CQUUvQyxPQUFPLFVBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2lCQUNwRjtZQUNMLENBQUM7U0FDSixDQUFBO1FBQ0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxjQUFjLENBQUE7UUFDaEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUE7UUFFWixJQUFJLENBQUMsUUFBUSxHQUFHO1lBQ1osT0FBTyxFQUFFLFdBQVc7WUFDcEIsSUFBSSxFQUFFLHNCQUFzQjtZQUM1QixHQUFHLEVBQUUsR0FBRyxFQUFFO2dCQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQTtnQkFDL0IsT0FBTyxLQUFLLENBQUE7WUFDaEIsQ0FBQztTQUNKLENBQUE7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTtRQUV0QixJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDaEQsTUFBTSxXQUFXLEdBQW1CLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3BFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFFaEQsUUFBUSxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRTtnQkFDckMsS0FBSyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDakMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQVMsQ0FBQTtvQkFDNUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQTtvQkFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUE7b0JBQzNELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFBO29CQUNuQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO29CQUU5QixNQUFLO2lCQUNSO2dCQUNELEtBQUssWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7b0JBQ25DLElBQUksQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFBO29CQUNiLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFBO29CQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQTtvQkFDbEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxLQUFLLFdBQVcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFBO29CQUUzRixNQUFLO2lCQUNSO2dCQUNELFFBQVE7YUFDWDtZQUVELElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDM0IsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDMUIsQ0FBQztJQUdELFdBQVcsQ0FBQyxLQUFLO1FBQ2IsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFBO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNkLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtJQUN0QyxDQUFDO0lBR0QsU0FBUztRQUNMLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtJQUN0QyxDQUFDO0lBR0QsaUJBQWlCLENBQUMsTUFBZTtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3pDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtTQUNqQjtJQUNMLENBQUM7SUFFRCxPQUFPO1FBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3pDLENBQUM7OztZQTdISixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7S0FjVDtnQkFFRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTs7YUFDbEQ7Ozs7WUFld0IsZUFBZTtZQTFGcEMsaUJBQWlCO1lBRVMsVUFBVTs7OzBCQThKbkMsWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQzt3QkFPeEMsWUFBWSxTQUFDLGFBQWE7Z0NBSzFCLFlBQVksU0FBQyxvQkFBb0IsRUFBRSxDQUFDLGVBQWUsQ0FBQzs7QUFZekQsTUFBTSxVQUFVLGVBQWUsQ0FBQyx3QkFBa0QsRUFBRSxPQUFnQixFQUFFLGNBQXdCO0lBQzFILE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUVuQyxPQUFPLENBQUMsTUFBcUIsRUFBRSxFQUFFO1FBQzdCLE1BQU0sV0FBVyxHQUFtQixTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNwRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFBO1FBQzFDLElBQUksTUFBTSxDQUFBO1FBQ1YsSUFBSSxjQUFjLENBQUE7UUFFbEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDdEMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFBO1lBQ25CLE9BQU07U0FDVDtRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksZUFBZSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUN2RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQzdCLE1BQU0sRUFBRSxjQUFjO1lBQ3RCLFNBQVMsRUFBRSxDQUFDO29CQUNSLE9BQU8sRUFBRSxlQUFlO29CQUN4QixRQUFRLEVBQUUsT0FBTztpQkFDcEIsRUFBQztvQkFDRSxPQUFPLEVBQUUsYUFBYTtvQkFDdEIsUUFBUSxFQUFFLE9BQU87aUJBQ3BCLENBQUM7U0FDTCxDQUFDLENBQUE7UUFDRixNQUFNLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDaEYsTUFBTSxTQUFTLEdBQUc7WUFDZCxJQUFJLHNCQUFzQixDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUMzRyxJQUFJLHNCQUFzQixDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztTQUM5RyxDQUFDO1FBRUYsUUFBUSxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRTtZQUNyQyxLQUFLLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUNqQyxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUM5RCxNQUFNLEdBQUcsRUFBRSxDQUFDLGFBQTRCLENBQUE7Z0JBRXhDLE1BQUs7YUFDUjtZQUNELEtBQUssWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7Z0JBQ25DLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQ2hFLE1BQU0sR0FBRyxFQUFFLENBQUMsSUFBbUIsQ0FBQTtnQkFDL0IsTUFBSzthQUNSO1lBQ0QsUUFBUTtTQUNYO1FBRUQsSUFBSSxjQUFjLEtBQUssTUFBTSxFQUFFO1lBQzNCLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQTtTQUN0QjtRQUVELElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDM0IsVUFBVSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUVsQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFO2lCQUM5QixtQkFBbUIsQ0FBQyxNQUFNLENBQUM7aUJBQzNCLHNCQUFzQixDQUFDLEtBQUssQ0FBQztpQkFDN0IsUUFBUSxDQUFDLEtBQUssQ0FBQztpQkFDZixhQUFhLENBQUMsU0FBUyxDQUFDLENBQUE7WUFFN0IsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxDQUFBO1lBRTVELFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDM0IsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFBO1lBRWhCLGNBQWMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDakMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFBO1lBRXZCLFVBQVUsQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUUzQyxjQUFjLEdBQUcsTUFBTSxDQUFBO1NBQzFCO0lBQ0wsQ0FBQyxDQUFBO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcclxuICAgIENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbmplY3RhYmxlLFxyXG4gICAgSW5qZWN0b3IsXHJcbiAgICBPbkRlc3Ryb3ksXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIlxyXG5pbXBvcnQgeyBIeXBlcmxpbmtTdGF0ZSwgSW5zZXJ0U3RhdHVzLCBwbHVnaW5LZXkgfSBmcm9tIFwiLi4vLi4vLi4vcGx1Z2lucy9saW5rL3BtL2h5cGVybGlua1wiXHJcbmltcG9ydCB7IEVkaXRvckV2ZW50IH0gZnJvbSBcIi4uLy4uLy4uL2xpYi9pbnRlcmZhY2VzXCJcclxuaW1wb3J0IHsgQ29ubmVjdGlvblBvc2l0aW9uUGFpciwgT3ZlcmxheSwgT3ZlcmxheVJlZiB9IGZyb20gXCJAYW5ndWxhci9jZGsvb3ZlcmxheVwiXHJcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gXCJAYW5ndWxhci9jZGsvcG9ydGFsXCJcclxuaW1wb3J0IHsgRWRpdG9yVG9vbCwgRWRpdG9yVG9vbGJhciB9IGZyb20gXCIuLi8uLi8uLi9saWIvZWRpdG9yLXRvb2xiYXIvaW50ZXJmYWNlc1wiXHJcbmltcG9ydCB7IGluc2VydExpbmssIHJlbW92ZUxpbmssIHNldExpbmtIcmVmLCBzZXRMaW5rVGV4dCB9IGZyb20gXCIuLi8uLi8uLi9wbHVnaW5zL2xpbmsvbGluay5jb21tYW5kc1wiXHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCJcclxuaW1wb3J0IHsgTWFyayB9IGZyb20gXCJwcm9zZW1pcnJvci1tb2RlbFwiXHJcbmltcG9ydCB7IGNhc2NhZGVDb21tYW5kcyB9IGZyb20gXCIuLi8uLi8uLi9wbHVnaW5zL2FsaWdubWVudC9hbGlnbm1lbnQuY29tbWFuZFwiXHJcbmltcG9ydCB7IEVkaXRvclNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vbGliL2VkaXRvci5zZXJ2aWNlXCJcclxuaW1wb3J0IHsgZnJvbUV2ZW50IH0gZnJvbSBcInJ4anMvaW50ZXJuYWwvb2JzZXJ2YWJsZS9mcm9tRXZlbnRcIlxyXG5pbXBvcnQgeyB0YWtlIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCJcclxuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSBcInJ4anMvaW50ZXJuYWwvb3BlcmF0b3JzL3N3aXRjaE1hcFwiXHJcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gXCJyeGpzL2ludGVybmFsL29wZXJhdG9ycy9maWx0ZXJcIlxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRmxvYXRpbmdUb29sYmFyIGltcGxlbWVudHMgRWRpdG9yVG9vbGJhciB7XHJcbiAgICB2aWV3Q2hhbmdlOiBPYnNlcnZhYmxlPEVkaXRvckV2ZW50PlxyXG4gICAgc3RhdGVDaGFuZ2U6IE9ic2VydmFibGU8RWRpdG9yRXZlbnQ+XHJcbiAgICBlZGl0b3I6IEVkaXRvclNlcnZpY2VcclxuICAgIG92ZXJsYXk6IE92ZXJsYXlSZWZcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihlZGl0b3I6IEVkaXRvclNlcnZpY2UsIG92ZXJsYXk6IE92ZXJsYXlSZWYpIHtcclxuICAgICAgICB0aGlzLnZpZXdDaGFuZ2UgPSBlZGl0b3Iudmlld0NoYW5nZVxyXG4gICAgICAgIHRoaXMuc3RhdGVDaGFuZ2UgPSBlZGl0b3Iuc3RhdGVDaGFuZ2VcclxuICAgICAgICB0aGlzLmVkaXRvciA9IGVkaXRvclxyXG4gICAgICAgIHRoaXMub3ZlcmxheSA9IG92ZXJsYXlcclxuICAgIH1cclxuXHJcbiAgICBydW5Ub29sKHRvb2w6IEVkaXRvclRvb2wpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmVkaXRvci5ydW5Ub29sKHRvb2wpXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuRm9jdXNUb0VkaXRvcigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmVkaXRvci52aWV3LmZvY3VzKClcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHJlbW92ZUxpbmtUb29sOiBFZGl0b3JUb29sID0ge1xyXG4gICAgdG9vbHRpcDogJ1JlbW92ZSBMaW5rJyxcclxuICAgIGljb246ICdmYS11bmxpbmsnLFxyXG4gICAgcnVuOiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XHJcbiAgICAgICAgY29uc3QgcGx1Z2luU3RhdGU6IEh5cGVybGlua1N0YXRlID0gcGx1Z2luS2V5LmdldFN0YXRlKHN0YXRlKVxyXG4gICAgICAgIGlmIChwbHVnaW5TdGF0ZS5hY3RpdmVMaW5rTWFyay50eXBlID09PSBJbnNlcnRTdGF0dXMuRURJVF9MSU5LX1RPT0xCQVIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlbW92ZUxpbmsocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsucG9zKShzdGF0ZSwgZGlzcGF0Y2gpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiBcInotbGluay1wYW5lbFwiLFxyXG4gICAgdGVtcGxhdGU6IGBcclxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCIhd3JhcExpbmtBcm91bmRUZXh0XCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIkxpbmsgVGV4dFwiIFt2YWx1ZV09XCJsaW5rVGV4dFwiIChpbnB1dCk9XCJsaW5rVGV4dCA9ICRldmVudC50YXJnZXQudmFsdWVcIiAvPlxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgcGxhY2Vob2xkZXI9XCJVUkxcIiBbdmFsdWVdPVwidXJsXCIgKGlucHV0KT1cInVybCA9ICRldmVudC50YXJnZXQudmFsdWVcIiBzcGVsbGNoZWNrPVwiZmFsc2VcIiAvPlxyXG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImluc2VydFwiPlxyXG4gICAgICAgICAgICA8ei1lZGl0b3ItdG9vbGJhci1idXR0b24gW3Rvb2xdPVwiaW5zZXJ0TGlua1wiPjwvei1lZGl0b3ItdG9vbGJhci1idXR0b24+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpbnNlcnRcIj5cclxuICAgICAgICAgICAgPHotZWRpdG9yLXRvb2xiYXItYnV0dG9uIFt0b29sXT1cIm9wZW5MaW5rXCI+PC96LWVkaXRvci10b29sYmFyLWJ1dHRvbj5cclxuICAgICAgICAgICAgPHotZWRpdG9yLXRvb2xiYXItYnV0dG9uIFt0b29sXT1cInJlbW92ZUxpbmtcIj48L3otZWRpdG9yLXRvb2xiYXItYnV0dG9uPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgYCxcclxuICAgIHN0eWxlVXJsczogW1wiLi9saW5rLXBhbmVsLmNvbXBvbmVudC5zY3NzXCJdLFxyXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMaW5rUGFuZWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gICAgcHVibGljIGluc2VydExpbms6IEVkaXRvclRvb2xcclxuICAgIHB1YmxpYyBvcGVuTGluazogRWRpdG9yVG9vbFxyXG4gICAgcHVibGljIHJlbW92ZUxpbms6IEVkaXRvclRvb2xcclxuICAgIHB1YmxpYyB1cmw6IHN0cmluZ1xyXG4gICAgcHVibGljIGxpbmtUZXh0OiBzdHJpbmdcclxuICAgIHB1YmxpYyBpbnNlcnQ6IGJvb2xlYW5cclxuICAgIHB1YmxpYyB3cmFwTGlua0Fyb3VuZFRleHQ6IGJvb2xlYW5cclxuXHJcbiAgICBwcml2YXRlIHRvb2xiYXI6IEZsb2F0aW5nVG9vbGJhclxyXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXHJcbiAgICBwcml2YXRlIHN1YjogU3Vic2NyaXB0aW9uXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PlxyXG5cclxuICAgIGNvbnN0cnVjdG9yKHRvb2xiYXI6IEZsb2F0aW5nVG9vbGJhciwgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgZWw6IEVsZW1lbnRSZWYpIHtcclxuICAgICAgICB0aGlzLmNkciA9IGNkclxyXG4gICAgICAgIHRoaXMudXJsID0gJydcclxuICAgICAgICB0aGlzLmluc2VydExpbmsgPSB7XHJcbiAgICAgICAgICAgIHRvb2x0aXA6ICdBZGQgTGluaycsXHJcbiAgICAgICAgICAgIGljb246ICdmYS1saW5rJyxcclxuICAgICAgICAgICAgcnVuOiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwbHVnaW5TdGF0ZTogSHlwZXJsaW5rU3RhdGUgPSBwbHVnaW5LZXkuZ2V0U3RhdGUoc3RhdGUpXHJcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsudHlwZSA9PT0gSW5zZXJ0U3RhdHVzLkVESVRfTElOS19UT09MQkFSKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zID0gcGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsucG9zXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYXNjYWRlQ29tbWFuZHMoW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRMaW5rSHJlZih0aGlzLnVybCwgcG9zKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0TGlua1RleHQodGhpcy5saW5rVGV4dCwgcG9zKSxcclxuICAgICAgICAgICAgICAgICAgICBdKShzdGF0ZSwgZGlzcGF0Y2gpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsudHlwZSA9PT0gSW5zZXJ0U3RhdHVzLklOU0VSVF9MSU5LX1RPT0xCQVIpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGZyb20sIHRvIH0gPSBwbHVnaW5TdGF0ZS5hY3RpdmVMaW5rTWFya1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5zZXJ0TGluayhmcm9tLCB0bywgdGhpcy51cmwsIHRoaXMubGlua1RleHQgfHwgdGhpcy51cmwpKHN0YXRlLCBkaXNwYXRjaClcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlbW92ZUxpbmsgPSByZW1vdmVMaW5rVG9vbFxyXG4gICAgICAgIHRoaXMuZWwgPSBlbFxyXG5cclxuICAgICAgICB0aGlzLm9wZW5MaW5rID0ge1xyXG4gICAgICAgICAgICB0b29sdGlwOiAnT3BlbiBMaW5rJyxcclxuICAgICAgICAgICAgaWNvbjogJ2ZhLWV4dGVybmFsLWxpbmstYWx0JyxcclxuICAgICAgICAgICAgcnVuOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub3Blbih0aGlzLnVybCwgJ19ibGFuaycpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy50b29sYmFyID0gdG9vbGJhclxyXG5cclxuICAgICAgICB0aGlzLnN1YiA9IHRvb2xiYXIuc3RhdGVDaGFuZ2Uuc3Vic2NyaWJlKChlZGl0b3IpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcGx1Z2luU3RhdGU6IEh5cGVybGlua1N0YXRlID0gcGx1Z2luS2V5LmdldFN0YXRlKGVkaXRvci5zdGF0ZSlcclxuICAgICAgICAgICAgY29uc3QgbGlua01hcmsgPSBlZGl0b3Iuc3RhdGUuc2NoZW1hLm1hcmtzLmxpbms7XHJcblxyXG4gICAgICAgICAgICBzd2l0Y2ggKHBsdWdpblN0YXRlLmFjdGl2ZUxpbmtNYXJrLnR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgSW5zZXJ0U3RhdHVzLkVESVRfTElOS19UT09MQkFSOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWFyayA9IGxpbmtNYXJrLmlzSW5TZXQocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsubm9kZS5tYXJrcykgYXMgTWFya1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXJsID0gbWFyay5hdHRycy5ocmVmLnRyaW0oKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGlua1RleHQgPSBwbHVnaW5TdGF0ZS5hY3RpdmVMaW5rTWFyay5ub2RlLnRleHQudHJpbSgpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnQgPSBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud3JhcExpbmtBcm91bmRUZXh0ID0gdHJ1ZVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2FzZSBJbnNlcnRTdGF0dXMuSU5TRVJUX0xJTktfVE9PTEJBUjoge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXJsID0gJydcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxpbmtUZXh0ID0gJydcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydCA9IHRydWVcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLndyYXBMaW5rQXJvdW5kVGV4dCA9IHBsdWdpblN0YXRlLmFjdGl2ZUxpbmtNYXJrLmZyb20gIT09IHBsdWdpblN0YXRlLmFjdGl2ZUxpbmtNYXJrLnRvXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24uZW50ZXInLCBbJyRldmVudCddKVxyXG4gICAgaGFuZGxlRW50ZXIoZXZlbnQpIHtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXHJcbiAgICAgICAgdGhpcy5zZXRMaW5rKClcclxuICAgICAgICB0aGlzLnRvb2xiYXIucmV0dXJuRm9jdXNUb0VkaXRvcigpXHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bi5lc2MnKVxyXG4gICAgaGFuZGxlRXNjKCkge1xyXG4gICAgICAgIHRoaXMudG9vbGJhci5yZXR1cm5Gb2N1c1RvRWRpdG9yKClcclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZWRvd24nLCBbJyRldmVudC50YXJnZXQnXSlcclxuICAgIGhhbmRsZUdsb2JhbENsaWNrKHRhcmdldDogRWxlbWVudCkge1xyXG4gICAgICAgIGlmICghdGhpcy5lbC5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRMaW5rKClcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2V0TGluaygpIHtcclxuICAgICAgICB0aGlzLnRvb2xiYXIucnVuVG9vbCh0aGlzLmluc2VydExpbmspXHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2hMaW5rUGFuZWwoY29tcG9uZW50RmFjdG9yeVJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIG92ZXJsYXk6IE92ZXJsYXksIHBhcmVudEluamVjdG9yOiBJbmplY3Rvcikge1xyXG4gICAgY29uc3Qgb3ZlcmxheVJlZiA9IG92ZXJsYXkuY3JlYXRlKClcclxuXHJcbiAgICByZXR1cm4gKGVkaXRvcjogRWRpdG9yU2VydmljZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHBsdWdpblN0YXRlOiBIeXBlcmxpbmtTdGF0ZSA9IHBsdWdpbktleS5nZXRTdGF0ZShlZGl0b3Iuc3RhdGUpXHJcbiAgICAgICAgY29uc3QgeyBsaW5rIH0gPSBlZGl0b3Iuc3RhdGUuc2NoZW1hLm1hcmtzXHJcbiAgICAgICAgbGV0IG9yaWdpblxyXG4gICAgICAgIGxldCBwcmV2aW91c09yaWdpblxyXG5cclxuICAgICAgICBpZiAoIXBsdWdpblN0YXRlLmFjdGl2ZUxpbmtNYXJrIHx8ICFsaW5rKSB7XHJcbiAgICAgICAgICAgIG92ZXJsYXlSZWYuZGV0YWNoKClcclxuICAgICAgICAgICAgcmV0dXJuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0b29sYmFyID0gbmV3IEZsb2F0aW5nVG9vbGJhcihlZGl0b3IsIG92ZXJsYXlSZWYpXHJcbiAgICAgICAgY29uc3QgaW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUoe1xyXG4gICAgICAgICAgICBwYXJlbnQ6IHBhcmVudEluamVjdG9yLFxyXG4gICAgICAgICAgICBwcm92aWRlcnM6IFt7XHJcbiAgICAgICAgICAgICAgICBwcm92aWRlOiBGbG9hdGluZ1Rvb2xiYXIsXHJcbiAgICAgICAgICAgICAgICB1c2VWYWx1ZTogdG9vbGJhclxyXG4gICAgICAgICAgICB9LHtcclxuICAgICAgICAgICAgICAgIHByb3ZpZGU6IEVkaXRvclRvb2xiYXIsXHJcbiAgICAgICAgICAgICAgICB1c2VWYWx1ZTogdG9vbGJhclxyXG4gICAgICAgICAgICB9XVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgY29uc3QgbGlua1BhbmVsUG9ydGFsID0gbmV3IENvbXBvbmVudFBvcnRhbChMaW5rUGFuZWxDb21wb25lbnQsIG51bGwsIGluamVjdG9yKTtcclxuICAgICAgICBjb25zdCBwb3NpdGlvbnMgPSBbXHJcbiAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uUG9zaXRpb25QYWlyKHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ2JvdHRvbScgfSwgeyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICd0b3AnIH0pLFxyXG4gICAgICAgICAgICBuZXcgQ29ubmVjdGlvblBvc2l0aW9uUGFpcih7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnIH0sIHsgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAnYm90dG9tJyB9KVxyXG4gICAgICAgIF07XHJcblxyXG4gICAgICAgIHN3aXRjaCAocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsudHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIEluc2VydFN0YXR1cy5FRElUX0xJTktfVE9PTEJBUjoge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZWwgPSBlZGl0b3Iudmlldy5ub2RlRE9NKHBsdWdpblN0YXRlLmFjdGl2ZUxpbmtNYXJrLnBvcylcclxuICAgICAgICAgICAgICAgIG9yaWdpbiA9IGVsLnBhcmVudEVsZW1lbnQgYXMgSFRNTEVsZW1lbnRcclxuXHJcbiAgICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgSW5zZXJ0U3RhdHVzLklOU0VSVF9MSU5LX1RPT0xCQVI6IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsID0gZWRpdG9yLnZpZXcuZG9tQXRQb3MocGx1Z2luU3RhdGUuYWN0aXZlTGlua01hcmsuZnJvbSlcclxuICAgICAgICAgICAgICAgIG9yaWdpbiA9IGVsLm5vZGUgYXMgSFRNTEVsZW1lbnRcclxuICAgICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcmV2aW91c09yaWdpbiAhPT0gb3JpZ2luKSB7XHJcbiAgICAgICAgICAgIG92ZXJsYXlSZWYuZGV0YWNoKClcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghb3ZlcmxheVJlZi5oYXNBdHRhY2hlZCgpKSB7XHJcbiAgICAgICAgICAgIG92ZXJsYXlSZWYuYXR0YWNoKGxpbmtQYW5lbFBvcnRhbClcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0cmF0ZWd5ID0gb3ZlcmxheS5wb3NpdGlvbigpXHJcbiAgICAgICAgICAgICAgICAuZmxleGlibGVDb25uZWN0ZWRUbyhvcmlnaW4pXHJcbiAgICAgICAgICAgICAgICAud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcclxuICAgICAgICAgICAgICAgIC53aXRoUHVzaChmYWxzZSlcclxuICAgICAgICAgICAgICAgIC53aXRoUG9zaXRpb25zKHBvc2l0aW9ucylcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHNjcm9sbFN0cmF0ZWd5ID0gb3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLnJlcG9zaXRpb24oKVxyXG5cclxuICAgICAgICAgICAgc3RyYXRlZ3kuYXR0YWNoKG92ZXJsYXlSZWYpXHJcbiAgICAgICAgICAgIHN0cmF0ZWd5LmFwcGx5KClcclxuXHJcbiAgICAgICAgICAgIHNjcm9sbFN0cmF0ZWd5LmF0dGFjaChvdmVybGF5UmVmKVxyXG4gICAgICAgICAgICBzY3JvbGxTdHJhdGVneS5lbmFibGUoKVxyXG5cclxuICAgICAgICAgICAgb3ZlcmxheVJlZi51cGRhdGVQb3NpdGlvblN0cmF0ZWd5KHN0cmF0ZWd5KVxyXG5cclxuICAgICAgICAgICAgcHJldmlvdXNPcmlnaW4gPSBvcmlnaW5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19