@acrodata/code-editor
Version:
CodeMirror 6 wrapper for Angular
319 lines • 41.3 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation, booleanAttribute, forwardRef, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { indentWithTab } from '@codemirror/commands';
import { indentUnit } from '@codemirror/language';
import { Annotation, Compartment, EditorState, StateEffect } from '@codemirror/state';
import { oneDark } from '@codemirror/theme-one-dark';
import { EditorView, highlightWhitespace, keymap, placeholder } from '@codemirror/view';
import { basicSetup, minimalSetup } from 'codemirror';
import * as i0 from "@angular/core";
export const External = Annotation.define();
export class CodeEditor {
constructor(_elementRef) {
this._elementRef = _elementRef;
/**
* Whether focus on the editor after init.
*
* Don't support change dynamically!
*/
this.autoFocus = false;
/** The editor's value. */
this.value = '';
/** Whether the editor is disabled. */
this.disabled = false;
/** Whether the editor is readonly. */
this.readonly = false;
/** The editor's theme. */
this.theme = 'light';
/** The editor's placecholder. */
this.placeholder = '';
/** Whether indent with Tab key. */
this.indentWithTab = false;
/** Should be a string consisting either entirely of the same whitespace character. */
this.indentUnit = '';
/** Whether the editor wraps lines. */
this.lineWrapping = false;
/** Whether highlight the whitespace. */
this.highlightWhitespace = false;
/**
* An array of language descriptions for known
* [language-data](https://github.com/codemirror/language-data/blob/main/src/language-data.ts).
*
* Don't support change dynamically!
*/
this.languages = [];
/** The editor's language. You should set the `languages` prop at first. */
this.language = '';
/**
* The editor's built-in setup. The value can be set to
* [`basic`](https://codemirror.net/docs/ref/#codemirror.basicSetup),
* [`minimal`](https://codemirror.net/docs/ref/#codemirror.minimalSetup) or `null`.
*/
this.setup = 'basic';
/**
* It will be appended to the root
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*/
this.extensions = [];
/** Event emitted when the editor's value changes. */
this.change = new EventEmitter();
/** Event emitted when focus on the editor. */
this.focus = new EventEmitter();
/** Event emitted when the editor has lost focus. */
this.blur = new EventEmitter();
this._onChange = () => { };
this._onTouched = () => { };
this._updateListener = EditorView.updateListener.of(vu => {
if (vu.docChanged && !vu.transactions.some(tr => tr.annotation(External))) {
const value = vu.state.doc.toString();
this._onChange(value);
this.change.emit(value);
}
});
// Extension compartments can be used to make a configuration dynamic.
// https://codemirror.net/docs/ref/#state.Compartment
this._editableConf = new Compartment();
this._readonlyConf = new Compartment();
this._themeConf = new Compartment();
this._placeholderConf = new Compartment();
this._indentWithTabConf = new Compartment();
this._indentUnitConf = new Compartment();
this._lineWrappingConf = new Compartment();
this._highlightWhitespaceConf = new Compartment();
this._languageConf = new Compartment();
}
_getAllExtensions() {
return [
this._updateListener,
this._editableConf.of([]),
this._readonlyConf.of([]),
this._themeConf.of([]),
this._placeholderConf.of([]),
this._indentWithTabConf.of([]),
this._indentUnitConf.of([]),
this._lineWrappingConf.of([]),
this._highlightWhitespaceConf.of([]),
this._languageConf.of([]),
this.setup === 'basic' ? basicSetup : this.setup === 'minimal' ? minimalSetup : [],
...this.extensions,
];
}
ngOnChanges(changes) {
if (changes['value']) {
this.setValue(this.value);
}
if (changes['disabled']) {
this.setEditable(!this.disabled);
}
if (changes['readonly']) {
this.setReadonly(this.readonly);
}
if (changes['theme']) {
this.setTheme(this.theme);
}
if (changes['placeholder']) {
this.setPlaceholder(this.placeholder);
}
if (changes['indentWithTab']) {
this.setIndentWithTab(this.indentWithTab);
}
if (changes['indentUnit']) {
this.setIndentUnit(this.indentUnit);
}
if (changes['lineWrapping']) {
this.setLineWrapping(this.lineWrapping);
}
if (changes['highlightWhitespace']) {
this.setHighlightWhitespace(this.highlightWhitespace);
}
if (changes['language']) {
this.setLanguage(this.language);
}
if (changes['setup'] || changes['extensions']) {
this.setExtensions(this._getAllExtensions());
}
}
ngOnInit() {
this.view = new EditorView({
root: this.root,
parent: this._elementRef.nativeElement,
state: EditorState.create({ doc: this.value, extensions: this._getAllExtensions() }),
});
if (this.autoFocus) {
this.view?.focus();
}
this.view?.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.focus.emit();
});
this.view?.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.blur.emit();
});
this.setEditable(!this.disabled);
this.setReadonly(this.readonly);
this.setTheme(this.theme);
this.setPlaceholder(this.placeholder);
this.setIndentWithTab(this.indentWithTab);
this.setIndentUnit(this.indentUnit);
this.setLineWrapping(this.lineWrapping);
this.setHighlightWhitespace(this.highlightWhitespace);
this.setLanguage(this.language);
}
ngOnDestroy() {
this.view?.destroy();
}
writeValue(value) {
if (this.view) {
this.setValue(value);
}
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.setEditable(!isDisabled);
}
/** Sets editor's value. */
setValue(value) {
this.view?.dispatch({
changes: { from: 0, to: this.view.state.doc.length, insert: value },
});
}
_dispatchEffects(effects) {
return this.view?.dispatch({ effects });
}
/** Sets the root extensions of the editor. */
setExtensions(value) {
this._dispatchEffects(StateEffect.reconfigure.of(value));
}
/** Sets editor's editable state. */
setEditable(value) {
this._dispatchEffects(this._editableConf.reconfigure(EditorView.editable.of(value)));
}
/** Sets editor's readonly state. */
setReadonly(value) {
this._dispatchEffects(this._readonlyConf.reconfigure(EditorState.readOnly.of(value)));
}
/** Sets editor's theme. */
setTheme(value) {
this._dispatchEffects(this._themeConf.reconfigure(value === 'light' ? [] : value === 'dark' ? oneDark : value));
}
/** Sets editor's placeholder. */
setPlaceholder(value) {
this._dispatchEffects(this._placeholderConf.reconfigure(value ? placeholder(value) : []));
}
/** Sets editor' indentWithTab. */
setIndentWithTab(value) {
this._dispatchEffects(this._indentWithTabConf.reconfigure(value ? keymap.of([indentWithTab]) : []));
}
/** Sets editor's indentUnit. */
setIndentUnit(value) {
this._dispatchEffects(this._indentUnitConf.reconfigure(value ? indentUnit.of(value) : []));
}
/** Sets editor's lineWrapping. */
setLineWrapping(value) {
this._dispatchEffects(this._lineWrappingConf.reconfigure(value ? EditorView.lineWrapping : []));
}
/** Sets editor's highlightWhitespace. */
setHighlightWhitespace(value) {
this._dispatchEffects(this._highlightWhitespaceConf.reconfigure(value ? highlightWhitespace() : []));
}
/** Sets editor's language dynamically. */
setLanguage(lang) {
if (!lang || lang == 'plaintext') {
this._dispatchEffects(this._languageConf.reconfigure([]));
return;
}
if (this.languages.length === 0) {
if (this.view) {
console.error('No supported languages. Please set the `languages` prop at first.');
}
return;
}
const langDesc = this._findLanguage(lang);
langDesc?.load().then(lang => {
this._dispatchEffects(this._languageConf.reconfigure([lang]));
});
}
/** Find the language's extension by its name. Case insensitive. */
_findLanguage(name) {
for (const lang of this.languages) {
for (const alias of [lang.name, ...lang.alias]) {
if (name.toLowerCase() === alias.toLowerCase()) {
return lang;
}
}
}
console.error('Language not found:', name);
console.info('Supported language names:', this.languages.map(lang => lang.name).join(', '));
return null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: CodeEditor, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.2.8", type: CodeEditor, isStandalone: true, selector: "code-editor", inputs: { root: "root", autoFocus: ["autoFocus", "autoFocus", booleanAttribute], value: "value", disabled: ["disabled", "disabled", booleanAttribute], readonly: ["readonly", "readonly", booleanAttribute], theme: "theme", placeholder: "placeholder", indentWithTab: ["indentWithTab", "indentWithTab", booleanAttribute], indentUnit: "indentUnit", lineWrapping: ["lineWrapping", "lineWrapping", booleanAttribute], highlightWhitespace: ["highlightWhitespace", "highlightWhitespace", booleanAttribute], languages: "languages", language: "language", setup: "setup", extensions: "extensions" }, outputs: { change: "change", focus: "focus", blur: "blur" }, host: { classAttribute: "code-editor" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeEditor),
multi: true,
},
], usesOnChanges: true, ngImport: i0, template: ``, isInline: true, styles: [".code-editor{display:block}.code-editor .cm-editor{height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: CodeEditor, decorators: [{
type: Component,
args: [{ selector: 'code-editor', standalone: true, template: ``, host: {
class: 'code-editor',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CodeEditor),
multi: true,
},
], styles: [".code-editor{display:block}.code-editor .cm-editor{height:100%}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { root: [{
type: Input
}], autoFocus: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], value: [{
type: Input
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], readonly: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], theme: [{
type: Input
}], placeholder: [{
type: Input
}], indentWithTab: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], indentUnit: [{
type: Input
}], lineWrapping: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], highlightWhitespace: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], languages: [{
type: Input
}], language: [{
type: Input
}], setup: [{
type: Input
}], extensions: [{
type: Input
}], change: [{
type: Output
}], focus: [{
type: Output
}], blur: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFFTixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLFVBQVUsR0FDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBdUIsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFhLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pHLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN4RixPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLFlBQVksQ0FBQzs7QUFLdEQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQVcsQ0FBQztBQTRCckQsTUFBTSxPQUFPLFVBQVU7SUE4RXJCLFlBQW9CLFdBQWdDO1FBQWhDLGdCQUFXLEdBQVgsV0FBVyxDQUFxQjtRQXRFcEQ7Ozs7V0FJRztRQUNxQyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRTFELDBCQUEwQjtRQUNqQixVQUFLLEdBQUcsRUFBRSxDQUFDO1FBRXBCLHVDQUF1QztRQUNDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFekQsc0NBQXNDO1FBQ0UsYUFBUSxHQUFH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QUssRUFBRSxhQUFhO3FCQUNyQixpQkFDYyxpQkFBaUIsQ0FBQyxJQUFJLG1CQUNwQix1QkFBdUIsQ0FBQyxNQUFNLGFBQ3BDO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQzs0QkFDekMsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7K0VBUVEsSUFBSTtzQkFBWixLQUFLO2dCQU9rQyxTQUFTO3NCQUFoRCxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUc3QixLQUFLO3NCQUFiLEtBQUs7Z0JBR2tDLFFBQVE7c0JBQS9DLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBR0UsUUFBUTtzQkFBL0MsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFHN0IsS0FBSztzQkFBYixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR2tDLGFBQWE7c0JBQXBELEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBRzdCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR2tDLFlBQVk7c0JBQW5ELEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBR0UsbUJBQW1CO3NCQUExRCxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQVE3QixTQUFTO3NCQUFqQixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBT0csS0FBSztzQkFBYixLQUFLO2dCQU1HLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR0ksTUFBTTtzQkFBZixNQUFNO2dCQUdHLEtBQUs7c0JBQWQsTUFBTTtnQkFHRyxJQUFJO3NCQUFiLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBib29sZWFuQXR0cmlidXRlLFxuICBmb3J3YXJkUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgaW5kZW50V2l0aFRhYiB9IGZyb20gJ0Bjb2RlbWlycm9yL2NvbW1hbmRzJztcbmltcG9ydCB7IExhbmd1YWdlRGVzY3JpcHRpb24sIGluZGVudFVuaXQgfSBmcm9tICdAY29kZW1pcnJvci9sYW5ndWFnZSc7XG5pbXBvcnQgeyBBbm5vdGF0aW9uLCBDb21wYXJ0bWVudCwgRWRpdG9yU3RhdGUsIEV4dGVuc2lvbiwgU3RhdGVFZmZlY3QgfSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSc7XG5pbXBvcnQgeyBvbmVEYXJrIH0gZnJvbSAnQGNvZGVtaXJyb3IvdGhlbWUtb25lLWRhcmsnO1xuaW1wb3J0IHsgRWRpdG9yVmlldywgaGlnaGxpZ2h0V2hpdGVzcGFjZSwga2V5bWFwLCBwbGFjZWhvbGRlciB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHsgYmFzaWNTZXR1cCwgbWluaW1hbFNldHVwIH0gZnJvbSAnY29kZW1pcnJvcic7XG5cbmV4cG9ydCB0eXBlIFRoZW1lID0gJ2xpZ2h0JyB8ICdkYXJrJyB8IEV4dGVuc2lvbjtcbmV4cG9ydCB0eXBlIFNldHVwID0gJ2Jhc2ljJyB8ICdtaW5pbWFsJyB8IG51bGw7XG5cbmV4cG9ydCBjb25zdCBFeHRlcm5hbCA9IEFubm90YXRpb24uZGVmaW5lPGJvb2xlYW4+KCk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NvZGUtZWRpdG9yJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGBgLFxuICBzdHlsZXM6IGBcbiAgICAuY29kZS1lZGl0b3Ige1xuICAgICAgZGlzcGxheTogYmxvY2s7XG5cbiAgICAgIC5jbS1lZGl0b3Ige1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICB9XG4gICAgfVxuICBgLFxuICBob3N0OiB7XG4gICAgY2xhc3M6ICdjb2RlLWVkaXRvcicsXG4gIH0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IENvZGVFZGl0b3IpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQ29kZUVkaXRvciBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgLyoqXG4gICAqIEVkaXRvclZpZXcncyBbcm9vdF0oaHR0cHM6Ly9jb2RlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JWaWV3LnJvb3QpLlxuICAgKlxuICAgKiBEb24ndCBzdXBwb3J0IGNoYW5nZSBkeW5hbWljYWxseSFcbiAgICovXG4gIEBJbnB1dCgpIHJvb3Q/OiBEb2N1bWVudCB8IFNoYWRvd1Jvb3Q7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZm9jdXMgb24gdGhlIGVkaXRvciBhZnRlciBpbml0LlxuICAgKlxuICAgKiBEb24ndCBzdXBwb3J0IGNoYW5nZSBkeW5hbWljYWxseSFcbiAgICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBhdXRvRm9jdXMgPSBmYWxzZTtcblxuICAvKiogVGhlIGVkaXRvcidzIHZhbHVlLiAqL1xuICBASW5wdXQoKSB2YWx1ZSA9ICcnO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBlZGl0b3IgaXMgZGlzYWJsZWQuICAqL1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgZWRpdG9yIGlzIHJlYWRvbmx5LiAqL1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgcmVhZG9ubHkgPSBmYWxzZTtcblxuICAvKiogVGhlIGVkaXRvcidzIHRoZW1lLiAqL1xuICBASW5wdXQoKSB0aGVtZTogVGhlbWUgPSAnbGlnaHQnO1xuXG4gIC8qKiBUaGUgZWRpdG9yJ3MgcGxhY2VjaG9sZGVyLiAqL1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICcnO1xuXG4gIC8qKiBXaGV0aGVyIGluZGVudCB3aXRoIFRhYiBrZXkuICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBpbmRlbnRXaXRoVGFiID0gZmFsc2U7XG5cbiAgLyoqIFNob3VsZCBiZSBhIHN0cmluZyBjb25zaXN0aW5nIGVpdGhlciBlbnRpcmVseSBvZiB0aGUgc2FtZSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4gKi9cbiAgQElucHV0KCkgaW5kZW50VW5pdCA9ICcnO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBlZGl0b3Igd3JhcHMgbGluZXMuICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBsaW5lV3JhcHBpbmcgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciBoaWdobGlnaHQgdGhlIHdoaXRlc3BhY2UuICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBoaWdobGlnaHRXaGl0ZXNwYWNlID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGxhbmd1YWdlIGRlc2NyaXB0aW9ucyBmb3Iga25vd25cbiAgICogW2xhbmd1YWdlLWRhdGFdKGh0dHBzOi8vZ2l0aHViLmNvbS9jb2RlbWlycm9yL2xhbmd1YWdlLWRhdGEvYmxvYi9tYWluL3NyYy9sYW5ndWFnZS1kYXRhLnRzKS5cbiAgICpcbiAgICogRG9uJ3Qgc3VwcG9ydCBjaGFuZ2UgZHluYW1pY2FsbHkhXG4gICAqL1xuICBASW5wdXQoKSBsYW5ndWFnZXM6IExhbmd1YWdlRGVzY3JpcHRpb25bXSA9IFtdO1xuXG4gIC8qKiBUaGUgZWRpdG9yJ3MgbGFuZ3VhZ2UuIFlvdSBzaG91bGQgc2V0IHRoZSBgbGFuZ3VhZ2VzYCBwcm9wIGF0IGZpcnN0LiAqL1xuICBASW5wdXQoKSBsYW5ndWFnZSA9ICcnO1xuXG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yJ3MgYnVpbHQtaW4gc2V0dXAuIFRoZSB2YWx1ZSBjYW4gYmUgc2V0IHRvXG4gICAqIFtgYmFzaWNgXShodHRwczovL2NvZGVtaXJyb3IubmV0L2RvY3MvcmVmLyNjb2RlbWlycm9yLmJhc2ljU2V0dXApLFxuICAgKiBbYG1pbmltYWxgXShodHRwczovL2NvZGVtaXJyb3IubmV0L2RvY3MvcmVmLyNjb2RlbWlycm9yLm1pbmltYWxTZXR1cCkgb3IgYG51bGxgLlxuICAgKi9cbiAgQElucHV0KCkgc2V0dXA6IFNldHVwID0gJ2Jhc2ljJztcblxuICAvKipcbiAgICogSXQgd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgcm9vdFxuICAgKiBbZXh0ZW5zaW9uc10oaHR0cHM6Ly9jb2RlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGVDb25maWcuZXh0ZW5zaW9ucykuXG4gICAqL1xuICBASW5wdXQoKSBleHRlbnNpb25zOiBFeHRlbnNpb25bXSA9IFtdO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGVkaXRvcidzIHZhbHVlIGNoYW5nZXMuICovXG4gIEBPdXRwdXQoKSBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIGZvY3VzIG9uIHRoZSBlZGl0b3IuICovXG4gIEBPdXRwdXQoKSBmb2N1cyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBlZGl0b3IgaGFzIGxvc3QgZm9jdXMuICovXG4gIEBPdXRwdXQoKSBibHVyID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByaXZhdGUgX29uQ2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBwcml2YXRlIF9vblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEVsZW1lbnQ+KSB7fVxuXG4gIC8qKlxuICAgKiBUaGUgaW5zdGFuY2Ugb2YgW0VkaXRvclZpZXddKGh0dHBzOi8vY29kZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yVmlldykuXG4gICAqL1xuICB2aWV3PzogRWRpdG9yVmlldztcblxuICBwcml2YXRlIF91cGRhdGVMaXN0ZW5lciA9IEVkaXRvclZpZXcudXBkYXRlTGlzdGVuZXIub2YodnUgPT4ge1xuICAgIGlmICh2dS5kb2NDaGFuZ2VkICYmICF2dS50cmFuc2FjdGlvbnMuc29tZSh0ciA9PiB0ci5hbm5vdGF0aW9uKEV4dGVybmFsKSkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdnUuc3RhdGUuZG9jLnRvU3RyaW5nKCk7XG4gICAgICB0aGlzLl9vbkNoYW5nZSh2YWx1ZSk7XG4gICAgICB0aGlzLmNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIEV4dGVuc2lvbiBjb21wYXJ0bWVudHMgY2FuIGJlIHVzZWQgdG8gbWFrZSBhIGNvbmZpZ3VyYXRpb24gZHluYW1pYy5cbiAgLy8gaHR0cHM6Ly9jb2RlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuQ29tcGFydG1lbnRcbiAgcHJpdmF0ZSBfZWRpdGFibGVDb25mID0gbmV3IENvbXBhcnRtZW50KCk7XG4gIHByaXZhdGUgX3JlYWRvbmx5Q29uZiA9IG5ldyBDb21wYXJ0bWVudCgpO1xuICBwcml2YXRlIF90aGVtZUNvbmYgPSBuZXcgQ29tcGFydG1lbnQoKTtcbiAgcHJpdmF0ZSBfcGxhY2Vob2xkZXJDb25mID0gbmV3IENvbXBhcnRtZW50KCk7XG4gIHByaXZhdGUgX2luZGVudFdpdGhUYWJDb25mID0gbmV3IENvbXBhcnRtZW50KCk7XG4gIHByaXZhdGUgX2luZGVudFVuaXRDb25mID0gbmV3IENvbXBhcnRtZW50KCk7XG4gIHByaXZhdGUgX2xpbmVXcmFwcGluZ0NvbmYgPSBuZXcgQ29tcGFydG1lbnQoKTtcbiAgcHJpdmF0ZSBfaGlnaGxpZ2h0V2hpdGVzcGFjZUNvbmYgPSBuZXcgQ29tcGFydG1lbnQoKTtcbiAgcHJpdmF0ZSBfbGFuZ3VhZ2VDb25mID0gbmV3IENvbXBhcnRtZW50KCk7XG5cbiAgcHJpdmF0ZSBfZ2V0QWxsRXh0ZW5zaW9ucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5fdXBkYXRlTGlzdGVuZXIsXG5cbiAgICAgIHRoaXMuX2VkaXRhYmxlQ29uZi5vZihbXSksXG4gICAgICB0aGlzLl9yZWFkb25seUNvbmYub2YoW10pLFxuICAgICAgdGhpcy5fdGhlbWVDb25mLm9mKFtdKSxcbiAgICAgIHRoaXMuX3BsYWNlaG9sZGVyQ29uZi5vZihbXSksXG4gICAgICB0aGlzLl9pbmRlbnRXaXRoVGFiQ29uZi5vZihbXSksXG4gICAgICB0aGlzLl9pbmRlbnRVbml0Q29uZi5vZihbXSksXG4gICAgICB0aGlzLl9saW5lV3JhcHBpbmdDb25mLm9mKFtdKSxcbiAgICAgIHRoaXMuX2hpZ2hsaWdodFdoaXRlc3BhY2VDb25mLm9mKFtdKSxcbiAgICAgIHRoaXMuX2xhbmd1YWdlQ29uZi5vZihbXSksXG5cbiAgICAgIHRoaXMuc2V0dXAgPT09ICdiYXNpYycgPyBiYXNpY1NldHVwIDogdGhpcy5zZXR1cCA9PT0gJ21pbmltYWwnID8gbWluaW1hbFNldHVwIDogW10sXG5cbiAgICAgIC4uLnRoaXMuZXh0ZW5zaW9ucyxcbiAgICBdO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd2YWx1ZSddKSB7XG4gICAgICB0aGlzLnNldFZhbHVlKHRoaXMudmFsdWUpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snZGlzYWJsZWQnXSkge1xuICAgICAgdGhpcy5zZXRFZGl0YWJsZSghdGhpcy5kaXNhYmxlZCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydyZWFkb25seSddKSB7XG4gICAgICB0aGlzLnNldFJlYWRvbmx5KHRoaXMucmVhZG9ubHkpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1sndGhlbWUnXSkge1xuICAgICAgdGhpcy5zZXRUaGVtZSh0aGlzLnRoZW1lKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ3BsYWNlaG9sZGVyJ10pIHtcbiAgICAgIHRoaXMuc2V0UGxhY2Vob2xkZXIodGhpcy5wbGFjZWhvbGRlcik7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydpbmRlbnRXaXRoVGFiJ10pIHtcbiAgICAgIHRoaXMuc2V0SW5kZW50V2l0aFRhYih0aGlzLmluZGVudFdpdGhUYWIpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snaW5kZW50VW5pdCddKSB7XG4gICAgICB0aGlzLnNldEluZGVudFVuaXQodGhpcy5pbmRlbnRVbml0KTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2xpbmVXcmFwcGluZyddKSB7XG4gICAgICB0aGlzLnNldExpbmVXcmFwcGluZyh0aGlzLmxpbmVXcmFwcGluZyk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydoaWdobGlnaHRXaGl0ZXNwYWNlJ10pIHtcbiAgICAgIHRoaXMuc2V0SGlnaGxpZ2h0V2hpdGVzcGFjZSh0aGlzLmhpZ2hsaWdodFdoaXRlc3BhY2UpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snbGFuZ3VhZ2UnXSkge1xuICAgICAgdGhpcy5zZXRMYW5ndWFnZSh0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ3NldHVwJ10gfHwgY2hhbmdlc1snZXh0ZW5zaW9ucyddKSB7XG4gICAgICB0aGlzLnNldEV4dGVuc2lvbnModGhpcy5fZ2V0QWxsRXh0ZW5zaW9ucygpKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXcgPSBuZXcgRWRpdG9yVmlldyh7XG4gICAgICByb290OiB0aGlzLnJvb3QsXG4gICAgICBwYXJlbnQ6IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgIHN0YXRlOiBFZGl0b3JTdGF0ZS5jcmVhdGUoeyBkb2M6IHRoaXMudmFsdWUsIGV4dGVuc2lvbnM6IHRoaXMuX2dldEFsbEV4dGVuc2lvbnMoKSB9KSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmF1dG9Gb2N1cykge1xuICAgICAgdGhpcy52aWV3Py5mb2N1cygpO1xuICAgIH1cblxuICAgIHRoaXMudmlldz8uY29udGVudERPTS5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsICgpID0+IHtcbiAgICAgIHRoaXMuX29uVG91Y2hlZCgpO1xuICAgICAgdGhpcy5mb2N1cy5lbWl0KCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnZpZXc/LmNvbnRlbnRET00uYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsICgpID0+IHtcbiAgICAgIHRoaXMuX29uVG91Y2hlZCgpO1xuICAgICAgdGhpcy5ibHVyLmVtaXQoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0RWRpdGFibGUoIXRoaXMuZGlzYWJsZWQpO1xuICAgIHRoaXMuc2V0UmVhZG9ubHkodGhpcy5yZWFkb25seSk7XG4gICAgdGhpcy5zZXRUaGVtZSh0aGlzLnRoZW1lKTtcbiAgICB0aGlzLnNldFBsYWNlaG9sZGVyKHRoaXMucGxhY2Vob2xkZXIpO1xuICAgIHRoaXMuc2V0SW5kZW50V2l0aFRhYih0aGlzLmluZGVudFdpdGhUYWIpO1xuICAgIHRoaXMuc2V0SW5kZW50VW5pdCh0aGlzLmluZGVudFVuaXQpO1xuICAgIHRoaXMuc2V0TGluZVdyYXBwaW5nKHRoaXMubGluZVdyYXBwaW5nKTtcbiAgICB0aGlzLnNldEhpZ2hsaWdodFdoaXRlc3BhY2UodGhpcy5oaWdobGlnaHRXaGl0ZXNwYWNlKTtcbiAgICB0aGlzLnNldExhbmd1YWdlKHRoaXMubGFuZ3VhZ2UpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy52aWV3Py5kZXN0cm95KCk7XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52aWV3KSB7XG4gICAgICB0aGlzLnNldFZhbHVlKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZCkge1xuICAgIHRoaXMuX29uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuX29uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5zZXRFZGl0YWJsZSghaXNEaXNhYmxlZCk7XG4gIH1cblxuICAvKiogU2V0cyBlZGl0b3IncyB2YWx1ZS4gKi9cbiAgc2V0VmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMudmlldz8uZGlzcGF0Y2goe1xuICAgICAgY2hhbmdlczogeyBmcm9tOiAwLCB0bzogdGhpcy52aWV3LnN0YXRlLmRvYy5sZW5ndGgsIGluc2VydDogdmFsdWUgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2Rpc3BhdGNoRWZmZWN0cyhlZmZlY3RzOiBTdGF0ZUVmZmVjdDxhbnk+IHwgcmVhZG9ubHkgU3RhdGVFZmZlY3Q8YW55PltdKSB7XG4gICAgcmV0dXJuIHRoaXMudmlldz8uZGlzcGF0Y2goeyBlZmZlY3RzIH0pO1xuICB9XG5cbiAgLyoqIFNldHMgdGhlIHJvb3QgZXh0ZW5zaW9ucyBvZiB0aGUgZWRpdG9yLiAqL1xuICBzZXRFeHRlbnNpb25zKHZhbHVlOiBFeHRlbnNpb25bXSkge1xuICAgIHRoaXMuX2Rpc3BhdGNoRWZmZWN0cyhTdGF0ZUVmZmVjdC5yZWNvbmZpZ3VyZS5vZih2YWx1ZSkpO1xuICB9XG5cbiAgLyoqIFNldHMgZWRpdG9yJ3MgZWRpdGFibGUgc3RhdGUuICovXG4gIHNldEVkaXRhYmxlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKHRoaXMuX2VkaXRhYmxlQ29uZi5yZWNvbmZpZ3VyZShFZGl0b3JWaWV3LmVkaXRhYmxlLm9mKHZhbHVlKSkpO1xuICB9XG5cbiAgLyoqIFNldHMgZWRpdG9yJ3MgcmVhZG9ubHkgc3RhdGUuICovXG4gIHNldFJlYWRvbmx5KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKHRoaXMuX3JlYWRvbmx5Q29uZi5yZWNvbmZpZ3VyZShFZGl0b3JTdGF0ZS5yZWFkT25seS5vZih2YWx1ZSkpKTtcbiAgfVxuXG4gIC8qKiBTZXRzIGVkaXRvcidzIHRoZW1lLiAqL1xuICBzZXRUaGVtZSh2YWx1ZTogVGhlbWUpIHtcbiAgICB0aGlzLl9kaXNwYXRjaEVmZmVjdHMoXG4gICAgICB0aGlzLl90aGVtZUNvbmYucmVjb25maWd1cmUodmFsdWUgPT09ICdsaWdodCcgPyBbXSA6IHZhbHVlID09PSAnZGFyaycgPyBvbmVEYXJrIDogdmFsdWUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBTZXRzIGVkaXRvcidzIHBsYWNlaG9sZGVyLiAqL1xuICBzZXRQbGFjZWhvbGRlcih2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKHRoaXMuX3BsYWNlaG9sZGVyQ29uZi5yZWNvbmZpZ3VyZSh2YWx1ZSA/IHBsYWNlaG9sZGVyKHZhbHVlKSA6IFtdKSk7XG4gIH1cblxuICAvKiogU2V0cyBlZGl0b3InIGluZGVudFdpdGhUYWIuICovXG4gIHNldEluZGVudFdpdGhUYWIodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9kaXNwYXRjaEVmZmVjdHMoXG4gICAgICB0aGlzLl9pbmRlbnRXaXRoVGFiQ29uZi5yZWNvbmZpZ3VyZSh2YWx1ZSA/IGtleW1hcC5vZihbaW5kZW50V2l0aFRhYl0pIDogW10pXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBTZXRzIGVkaXRvcidzIGluZGVudFVuaXQuICovXG4gIHNldEluZGVudFVuaXQodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2Rpc3BhdGNoRWZmZWN0cyh0aGlzLl9pbmRlbnRVbml0Q29uZi5yZWNvbmZpZ3VyZSh2YWx1ZSA/IGluZGVudFVuaXQub2YodmFsdWUpIDogW10pKTtcbiAgfVxuXG4gIC8qKiBTZXRzIGVkaXRvcidzIGxpbmVXcmFwcGluZy4gKi9cbiAgc2V0TGluZVdyYXBwaW5nKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKHRoaXMuX2xpbmVXcmFwcGluZ0NvbmYucmVjb25maWd1cmUodmFsdWUgPyBFZGl0b3JWaWV3LmxpbmVXcmFwcGluZyA6IFtdKSk7XG4gIH1cblxuICAvKiogU2V0cyBlZGl0b3IncyBoaWdobGlnaHRXaGl0ZXNwYWNlLiAqL1xuICBzZXRIaWdobGlnaHRXaGl0ZXNwYWNlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKFxuICAgICAgdGhpcy5faGlnaGxpZ2h0V2hpdGVzcGFjZUNvbmYucmVjb25maWd1cmUodmFsdWUgPyBoaWdobGlnaHRXaGl0ZXNwYWNlKCkgOiBbXSlcbiAgICApO1xuICB9XG5cbiAgLyoqIFNldHMgZWRpdG9yJ3MgbGFuZ3VhZ2UgZHluYW1pY2FsbHkuICovXG4gIHNldExhbmd1YWdlKGxhbmc6IHN0cmluZykge1xuICAgIGlmICghbGFuZyB8fCBsYW5nID09ICdwbGFpbnRleHQnKSB7XG4gICAgICB0aGlzLl9kaXNwYXRjaEVmZmVjdHModGhpcy5fbGFuZ3VhZ2VDb25mLnJlY29uZmlndXJlKFtdKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmxhbmd1YWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGlmICh0aGlzLnZpZXcpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignTm8gc3VwcG9ydGVkIGxhbmd1YWdlcy4gUGxlYXNlIHNldCB0aGUgYGxhbmd1YWdlc2AgcHJvcCBhdCBmaXJzdC4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGFuZ0Rlc2MgPSB0aGlzLl9maW5kTGFuZ3VhZ2UobGFuZyk7XG4gICAgbGFuZ0Rlc2M/LmxvYWQoKS50aGVuKGxhbmcgPT4ge1xuICAgICAgdGhpcy5fZGlzcGF0Y2hFZmZlY3RzKHRoaXMuX2xhbmd1YWdlQ29uZi5yZWNvbmZpZ3VyZShbbGFuZ10pKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBGaW5kIHRoZSBsYW5ndWFnZSdzIGV4dGVuc2lvbiBieSBpdHMgbmFtZS4gQ2FzZSBpbnNlbnNpdGl2ZS4gKi9cbiAgcHJpdmF0ZSBfZmluZExhbmd1YWdlKG5hbWU6IHN0cmluZykge1xuICAgIGZvciAoY29uc3QgbGFuZyBvZiB0aGlzLmxhbmd1YWdlcykge1xuICAgICAgZm9yIChjb25zdCBhbGlhcyBvZiBbbGFuZy5uYW1lLCAuLi5sYW5nLmFsaWFzXSkge1xuICAgICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSBhbGlhcy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgcmV0dXJuIGxhbmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5lcnJvcignTGFuZ3VhZ2Ugbm90IGZvdW5kOicsIG5hbWUpO1xuICAgIGNvbnNvbGUuaW5mbygnU3VwcG9ydGVkIGxhbmd1YWdlIG5hbWVzOicsIHRoaXMubGFuZ3VhZ2VzLm1hcChsYW5nID0+IGxhbmcubmFtZSkuam9pbignLCAnKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiJdfQ==