ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
287 lines • 37.9 kB
JavaScript
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, forwardRef, Input, Output, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { BehaviorSubject, combineLatest, fromEvent, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, takeUntil } from 'rxjs/operators';
import { warn } from 'ng-zorro-antd/core/logger';
import { inNextTick } from 'ng-zorro-antd/core/util';
import { NzSpinComponent } from 'ng-zorro-antd/spin';
import * as i0 from "@angular/core";
import * as i1 from "./code-editor.service";
import * as i2 from "@angular/cdk/platform";
export class NzCodeEditorComponent {
set nzEditorOption(value) {
this.editorOption$.next(value);
}
constructor(nzCodeEditorService, ngZone, elementRef, platform) {
this.nzCodeEditorService = nzCodeEditorService;
this.ngZone = ngZone;
this.platform = platform;
this.nzEditorMode = 'normal';
this.nzOriginalText = '';
this.nzLoading = false;
this.nzFullControl = false;
this.nzEditorInitialized = new EventEmitter();
this.editorOptionCached = {};
this.destroy$ = new Subject();
this.resize$ = new Subject();
this.editorOption$ = new BehaviorSubject({});
this.editorInstance = null;
this.value = '';
this.modelSet = false;
this.onDidChangeContentDisposable = null;
this.onChange = (_value) => { };
this.onTouch = () => { };
this.el = elementRef.nativeElement;
this.el.classList.add('ant-code-editor');
}
/**
* Initialize a monaco editor instance.
*/
ngAfterViewInit() {
if (!this.platform.isBrowser) {
return;
}
this.nzCodeEditorService
.requestToInit()
.pipe(takeUntil(this.destroy$))
.subscribe(option => this.setup(option));
}
ngOnDestroy() {
if (this.onDidChangeContentDisposable) {
this.onDidChangeContentDisposable.dispose();
this.onDidChangeContentDisposable = null;
}
if (this.editorInstance) {
this.editorInstance.dispose();
this.editorInstance = null;
}
this.destroy$.next();
this.destroy$.complete();
}
writeValue(value) {
this.value = value;
this.setValue();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
layout() {
this.resize$.next();
}
setup(option) {
// The `setup()` is invoked when the Monaco editor is loaded. This may happen asynchronously for the first
// time, and it'll always happen synchronously afterwards. The first `setup()` invokation is outside the Angular
// zone, but further invokations will happen within the Angular zone. We call the `setModel()` on the editor
// instance, which tells Monaco to add event listeners lazily internally (`mousemove`, `mouseout`, etc.).
// We should avoid adding them within the Angular zone since this will drastically affect the performance.
this.ngZone.runOutsideAngular(() => inNextTick()
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.editorOptionCached = option;
this.registerOptionChanges();
this.initMonacoEditorInstance();
this.registerResizeChange();
this.setValue();
if (!this.nzFullControl) {
this.setValueEmitter();
}
if (this.nzEditorInitialized.observers.length) {
this.ngZone.run(() => this.nzEditorInitialized.emit(this.editorInstance));
}
}));
}
registerOptionChanges() {
combineLatest([this.editorOption$, this.nzCodeEditorService.option$])
.pipe(takeUntil(this.destroy$))
.subscribe(([selfOpt, defaultOpt]) => {
this.editorOptionCached = {
...this.editorOptionCached,
...defaultOpt,
...selfOpt
};
this.updateOptionToMonaco();
});
}
initMonacoEditorInstance() {
this.ngZone.runOutsideAngular(() => {
this.editorInstance =
this.nzEditorMode === 'normal'
? monaco.editor.create(this.el, { ...this.editorOptionCached })
: monaco.editor.createDiffEditor(this.el, {
...this.editorOptionCached
});
});
}
registerResizeChange() {
this.ngZone.runOutsideAngular(() => {
fromEvent(window, 'resize')
.pipe(debounceTime(300), takeUntil(this.destroy$))
.subscribe(() => {
this.layout();
});
this.resize$
.pipe(takeUntil(this.destroy$), filter(() => !!this.editorInstance), map(() => ({
width: this.el.clientWidth,
height: this.el.clientHeight
})), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), debounceTime(50))
.subscribe(() => {
this.editorInstance.layout();
});
});
}
setValue() {
if (!this.editorInstance) {
return;
}
if (this.nzFullControl && this.value) {
warn(`should not set value when you are using full control mode! It would result in ambiguous data flow!`);
return;
}
if (this.nzEditorMode === 'normal') {
if (this.modelSet) {
const model = this.editorInstance.getModel();
this.preservePositionAndSelections(() => model.setValue(this.value));
}
else {
this.editorInstance.setModel(monaco.editor.createModel(this.value, this.editorOptionCached.language));
this.modelSet = true;
}
}
else {
if (this.modelSet) {
const model = this.editorInstance.getModel();
this.preservePositionAndSelections(() => {
model.modified.setValue(this.value);
model.original.setValue(this.nzOriginalText);
});
}
else {
const language = this.editorOptionCached.language;
this.editorInstance.setModel({
original: monaco.editor.createModel(this.nzOriginalText, language),
modified: monaco.editor.createModel(this.value, language)
});
this.modelSet = true;
}
}
}
/**
* {@link editor.ICodeEditor}#setValue resets the cursor position to the start of the document.
* This helper memorizes the cursor position and selections and restores them after the given
* function has been called.
*/
preservePositionAndSelections(fn) {
if (!this.editorInstance) {
fn();
return;
}
const position = this.editorInstance.getPosition();
const selections = this.editorInstance.getSelections();
fn();
if (position) {
this.editorInstance.setPosition(position);
}
if (selections) {
this.editorInstance.setSelections(selections);
}
}
setValueEmitter() {
const model = (this.nzEditorMode === 'normal'
? this.editorInstance.getModel()
: this.editorInstance.getModel().modified);
// The `onDidChangeContent` returns a disposable object (an object with `dispose()` method) which will cleanup
// the listener. The callback, that we pass to `onDidChangeContent`, captures `this`. This leads to a circular reference
// (`nz-code-editor -> monaco -> nz-code-editor`) and prevents the `nz-code-editor` from being GC'd.
this.onDidChangeContentDisposable = model.onDidChangeContent(() => {
this.emitValue(model.getValue());
});
}
emitValue(value) {
if (this.value === value) {
// If the value didn't change there's no reason to send an update.
// Specifically this may happen during an update from the model (writeValue) where sending an update to the model would actually be incorrect.
return;
}
this.value = value;
// We're re-entering the Angular zone only if the value has been changed since there's a `return` expression previously.
// This won't cause "dead" change detections (basically when the `tick()` has been run, but there's nothing to update).
this.ngZone.run(() => {
this.onChange(value);
});
}
updateOptionToMonaco() {
if (this.editorInstance) {
this.editorInstance.updateOptions({ ...this.editorOptionCached });
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCodeEditorComponent, deps: [{ token: i1.NzCodeEditorService }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i2.Platform }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzCodeEditorComponent, isStandalone: true, selector: "nz-code-editor", inputs: { nzEditorMode: "nzEditorMode", nzOriginalText: "nzOriginalText", nzLoading: ["nzLoading", "nzLoading", booleanAttribute], nzFullControl: ["nzFullControl", "nzFullControl", booleanAttribute], nzToolkit: "nzToolkit", nzEditorOption: "nzEditorOption" }, outputs: { nzEditorInitialized: "nzEditorInitialized" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzCodeEditorComponent),
multi: true
}
], exportAs: ["nzCodeEditor"], ngImport: i0, template: `
(nzLoading) {
<div class="ant-code-editor-loading">
<nz-spin />
</div>
}
(nzToolkit) {
<div class="ant-code-editor-toolkit">
<ng-template [ngTemplateOutlet]="nzToolkit" />
</div>
}
`, isInline: true, dependencies: [{ kind: "component", type: NzSpinComponent, selector: "nz-spin", inputs: ["nzIndicator", "nzSize", "nzTip", "nzDelay", "nzSimple", "nzSpinning"], exportAs: ["nzSpin"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCodeEditorComponent, decorators: [{
type: Component,
args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-code-editor',
exportAs: 'nzCodeEditor',
template: `
(nzLoading) {
<div class="ant-code-editor-loading">
<nz-spin />
</div>
}
(nzToolkit) {
<div class="ant-code-editor-toolkit">
<ng-template [ngTemplateOutlet]="nzToolkit" />
</div>
}
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzCodeEditorComponent),
multi: true
}
],
imports: [NgIf, NzSpinComponent, NgTemplateOutlet],
standalone: true
}]
}], ctorParameters: () => [{ type: i1.NzCodeEditorService }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i2.Platform }], propDecorators: { nzEditorMode: [{
type: Input
}], nzOriginalText: [{
type: Input
}], nzLoading: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzFullControl: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzToolkit: [{
type: Input
}], nzEditorOption: [{
type: Input
}], nzEditorInitialized: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFFTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFHTCxNQUFNLEVBRU4saUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUUsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSTVGLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7O0FBdUNyRCxNQUFNLE9BQU8scUJBQXFCO0lBT2hDLElBQWEsY0FBYyxDQUFDLEtBQTBCO1FBQ3BELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFlRCxZQUNVLG1CQUF3QyxFQUN4QyxNQUFjLEVBQ3RCLFVBQXNCLEVBQ2QsUUFBa0I7UUFIbEIsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBRWQsYUFBUSxHQUFS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QUNoQixnQkFBZ0IsbUlBZHpCO1lBQ1Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQztnQkFDcEQsS0FBSyxFQUFFLElBQUk7YUFDWjtTQUNGLHNEQWxCUzs7Ozs7Ozs7Ozs7R0FXVCw0REFRZSxlQUFlLDJKQUFFLGdCQUFnQjs7MkZBR3RDLHFCQUFxQjtrQkEzQmpDLFNBQVM7bUJBQUM7b0JBQ1QsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO29CQUNyQyxRQUFRLEVBQUUsZ0JBQWdCO29CQUMxQixRQUFRLEVBQUUsY0FBYztvQkFDeEIsUUFBUSxFQUFFOzs7Ozs7Ozs7OztHQVdUO29CQUNELFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxzQkFBc0IsQ0FBQzs0QkFDcEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7b0JBQ0QsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsQ0FBQztvQkFDbEQsVUFBVSxFQUFFLElBQUk7aUJBQ2pCOzZKQUVVLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDa0MsU0FBUztzQkFBaEQsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFDRSxhQUFhO3NCQUFwRCxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUM3QixTQUFTO3NCQUFqQixLQUFLO2dCQUVPLGNBQWM7c0JBQTFCLEtBQUs7Z0JBSWEsbUJBQW1CO3NCQUFyQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHsgTmdJZiwgTmdUZW1wbGF0ZU91dGxldCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBib29sZWFuQXR0cmlidXRlLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgZnJvbUV2ZW50LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIsIG1hcCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgdHlwZSB7IGVkaXRvciwgSURpc3Bvc2FibGUgfSBmcm9tICdtb25hY28tZWRpdG9yJztcblxuaW1wb3J0IHsgd2FybiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9sb2dnZXInO1xuaW1wb3J0IHsgTnpTYWZlQW55LCBPbkNoYW5nZVR5cGUsIE9uVG91Y2hlZFR5cGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgaW5OZXh0VGljayB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IE56U3BpbkNvbXBvbmVudCB9IGZyb20gJ25nLXpvcnJvLWFudGQvc3Bpbic7XG5cbmltcG9ydCB7IE56Q29kZUVkaXRvclNlcnZpY2UgfSBmcm9tICcuL2NvZGUtZWRpdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGlmZkVkaXRvck9wdGlvbnMsIEVkaXRvck9wdGlvbnMsIEpvaW5lZEVkaXRvck9wdGlvbnMsIE56RWRpdG9yTW9kZSB9IGZyb20gJy4vdHlwaW5ncyc7XG5cbi8vIEltcG9ydCB0eXBlcyBmcm9tIG1vbmFjbyBlZGl0b3IuXG50eXBlIElUZXh0TW9kZWwgPSBlZGl0b3IuSVRleHRNb2RlbDtcbnR5cGUgSVN0YW5kYWxvbmVDb2RlRWRpdG9yID0gZWRpdG9yLklTdGFuZGFsb25lQ29kZUVkaXRvcjtcbnR5cGUgSVN0YW5kYWxvbmVEaWZmRWRpdG9yID0gZWRpdG9yLklTdGFuZGFsb25lRGlmZkVkaXRvcjtcblxuZGVjbGFyZSBjb25zdCBtb25hY286IE56U2FmZUFueTtcblxuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzZWxlY3RvcjogJ256LWNvZGUtZWRpdG9yJyxcbiAgZXhwb3J0QXM6ICduekNvZGVFZGl0b3InLFxuICB0ZW1wbGF0ZTogYFxuICAgIEBpZiAobnpMb2FkaW5nKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LWNvZGUtZWRpdG9yLWxvYWRpbmdcIj5cbiAgICAgICAgPG56LXNwaW4gLz5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgICBAaWYgKG56VG9vbGtpdCkge1xuICAgICAgPGRpdiBjbGFzcz1cImFudC1jb2RlLWVkaXRvci10b29sa2l0XCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJuelRvb2xraXRcIiAvPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICBgLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE56Q29kZUVkaXRvckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXSxcbiAgaW1wb3J0czogW05nSWYsIE56U3BpbkNvbXBvbmVudCwgTmdUZW1wbGF0ZU91dGxldF0sXG4gIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgTnpDb2RlRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgQElucHV0KCkgbnpFZGl0b3JNb2RlOiBOekVkaXRvck1vZGUgPSAnbm9ybWFsJztcbiAgQElucHV0KCkgbnpPcmlnaW5hbFRleHQgPSAnJztcbiAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIG56TG9hZGluZyA9IGZhbHNlO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgbnpGdWxsQ29udHJvbCA9IGZhbHNlO1xuICBASW5wdXQoKSBuelRvb2xraXQ/OiBUZW1wbGF0ZVJlZjx2b2lkPjtcblxuICBASW5wdXQoKSBzZXQgbnpFZGl0b3JPcHRpb24odmFsdWU6IEpvaW5lZEVkaXRvck9wdGlvbnMpIHtcbiAgICB0aGlzLmVkaXRvck9wdGlvbiQubmV4dCh2YWx1ZSk7XG4gIH1cblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpFZGl0b3JJbml0aWFsaXplZCA9IG5ldyBFdmVudEVtaXR0ZXI8SVN0YW5kYWxvbmVDb2RlRWRpdG9yIHwgSVN0YW5kYWxvbmVEaWZmRWRpdG9yPigpO1xuXG4gIGVkaXRvck9wdGlvbkNhY2hlZDogSm9pbmVkRWRpdG9yT3B0aW9ucyA9IHt9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZWw6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZXNpemUkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBlZGl0b3JPcHRpb24kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxKb2luZWRFZGl0b3JPcHRpb25zPih7fSk7XG4gIHByaXZhdGUgZWRpdG9ySW5zdGFuY2U6IElTdGFuZGFsb25lQ29kZUVkaXRvciB8IElTdGFuZGFsb25lRGlmZkVkaXRvciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHZhbHVlID0gJyc7XG4gIHByaXZhdGUgbW9kZWxTZXQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBvbkRpZENoYW5nZUNvbnRlbnREaXNwb3NhYmxlOiBJRGlzcG9zYWJsZSB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbnpDb2RlRWRpdG9yU2VydmljZTogTnpDb2RlRWRpdG9yU2VydmljZSxcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBwbGF0Zm9ybTogUGxhdGZvcm1cbiAgKSB7XG4gICAgdGhpcy5lbCA9IGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5hZGQoJ2FudC1jb2RlLWVkaXRvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYSBtb25hY28gZWRpdG9yIGluc3RhbmNlLlxuICAgKi9cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm56Q29kZUVkaXRvclNlcnZpY2VcbiAgICAgIC5yZXF1ZXN0VG9Jbml0KClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUob3B0aW9uID0+IHRoaXMuc2V0dXAob3B0aW9uKSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vbkRpZENoYW5nZUNvbnRlbnREaXNwb3NhYmxlKSB7XG4gICAgICB0aGlzLm9uRGlkQ2hhbmdlQ29udGVudERpc3Bvc2FibGUuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5vbkRpZENoYW5nZUNvbnRlbnREaXNwb3NhYmxlID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5lZGl0b3JJbnN0YW5jZSkge1xuICAgICAgdGhpcy5lZGl0b3JJbnN0YW5jZS5kaXNwb3NlKCk7XG4gICAgICB0aGlzLmVkaXRvckluc3RhbmNlID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5zZXRWYWx1ZSgpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogT25DaGFuZ2VUeXBlKTogTnpTYWZlQW55IHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogT25Ub3VjaGVkVHlwZSk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaCA9IGZuO1xuICB9XG5cbiAgb25DaGFuZ2U6IE9uQ2hhbmdlVHlwZSA9IChfdmFsdWU6IHN0cmluZykgPT4ge307XG5cbiAgb25Ub3VjaDogT25Ub3VjaGVkVHlwZSA9ICgpID0+IHt9O1xuXG4gIGxheW91dCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2l6ZSQubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cChvcHRpb246IEpvaW5lZEVkaXRvck9wdGlvbnMpOiB2b2lkIHtcbiAgICAvLyBUaGUgYHNldHVwKClgIGlzIGludm9rZWQgd2hlbiB0aGUgTW9uYWNvIGVkaXRvciBpcyBsb2FkZWQuIFRoaXMgbWF5IGhhcHBlbiBhc3luY2hyb25vdXNseSBmb3IgdGhlIGZpcnN0XG4gICAgLy8gdGltZSwgYW5kIGl0J2xsIGFsd2F5cyBoYXBwZW4gc3luY2hyb25vdXNseSBhZnRlcndhcmRzLiBUaGUgZmlyc3QgYHNldHVwKClgIGludm9rYXRpb24gaXMgb3V0c2lkZSB0aGUgQW5ndWxhclxuICAgIC8vIHpvbmUsIGJ1dCBmdXJ0aGVyIGludm9rYXRpb25zIHdpbGwgaGFwcGVuIHdpdGhpbiB0aGUgQW5ndWxhciB6b25lLiBXZSBjYWxsIHRoZSBgc2V0TW9kZWwoKWAgb24gdGhlIGVkaXRvclxuICAgIC8vIGluc3RhbmNlLCB3aGljaCB0ZWxscyBNb25hY28gdG8gYWRkIGV2ZW50IGxpc3RlbmVycyBsYXppbHkgaW50ZXJuYWxseSAoYG1vdXNlbW92ZWAsIGBtb3VzZW91dGAsIGV0Yy4pLlxuICAgIC8vIFdlIHNob3VsZCBhdm9pZCBhZGRpbmcgdGhlbSB3aXRoaW4gdGhlIEFuZ3VsYXIgem9uZSBzaW5jZSB0aGlzIHdpbGwgZHJhc3RpY2FsbHkgYWZmZWN0IHRoZSBwZXJmb3JtYW5jZS5cbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PlxuICAgICAgaW5OZXh0VGljaygpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5lZGl0b3JPcHRpb25DYWNoZWQgPSBvcHRpb247XG4gICAgICAgICAgdGhpcy5yZWdpc3Rlck9wdGlvbkNoYW5nZXMoKTtcbiAgICAgICAgICB0aGlzLmluaXRNb25hY29FZGl0b3JJbnN0YW5jZSgpO1xuICAgICAgICAgIHRoaXMucmVnaXN0ZXJSZXNpemVDaGFuZ2UoKTtcbiAgICAgICAgICB0aGlzLnNldFZhbHVlKCk7XG5cbiAgICAgICAgICBpZiAoIXRoaXMubnpGdWxsQ29udHJvbCkge1xuICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZUVtaXR0ZXIoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5uekVkaXRvckluaXRpYWxpemVkLm9ic2VydmVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm56RWRpdG9ySW5pdGlhbGl6ZWQuZW1pdCh0aGlzLmVkaXRvckluc3RhbmNlISkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3Rlck9wdGlvbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgY29tYmluZUxhdGVzdChbdGhpcy5lZGl0b3JPcHRpb24kLCB0aGlzLm56Q29kZUVkaXRvclNlcnZpY2Uub3B0aW9uJF0pXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKChbc2VsZk9wdCwgZGVmYXVsdE9wdF0pID0+IHtcbiAgICAgICAgdGhpcy5lZGl0b3JPcHRpb25DYWNoZWQgPSB7XG4gICAgICAgICAgLi4udGhpcy5lZGl0b3JPcHRpb25DYWNoZWQsXG4gICAgICAgICAgLi4uZGVmYXVsdE9wdCxcbiAgICAgICAgICAuLi5zZWxmT3B0XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudXBkYXRlT3B0aW9uVG9Nb25hY28oKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0TW9uYWNvRWRpdG9ySW5zdGFuY2UoKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgdGhpcy5lZGl0b3JJbnN0YW5jZSA9XG4gICAgICAgIHRoaXMubnpFZGl0b3JNb2RlID09PSAnbm9ybWFsJ1xuICAgICAgICAgID8gbW9uYWNvLmVkaXRvci5jcmVhdGUodGhpcy5lbCwgeyAuLi50aGlzLmVkaXRvck9wdGlvbkNhY2hlZCB9KVxuICAgICAgICAgIDogbW9uYWNvLmVkaXRvci5jcmVhdGVEaWZmRWRpdG9yKHRoaXMuZWwsIHtcbiAgICAgICAgICAgICAgLi4uKHRoaXMuZWRpdG9yT3B0aW9uQ2FjaGVkIGFzIERpZmZFZGl0b3JPcHRpb25zKVxuICAgICAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyUmVzaXplQ2hhbmdlKCk6IHZvaWQge1xuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxuICAgICAgICAucGlwZShkZWJvdW5jZVRpbWUoMzAwKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmxheW91dCgpO1xuICAgICAgICB9KTtcblxuICAgICAgdGhpcy5yZXNpemUkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcbiAgICAgICAgICBmaWx0ZXIoKCkgPT4gISF0aGlzLmVkaXRvckluc3RhbmNlKSxcbiAgICAgICAgICBtYXAoKCkgPT4gKHtcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLmVsLmNsaWVudFdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLmVsLmNsaWVudEhlaWdodFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSwgYikgPT4gYS53aWR0aCA9PT0gYi53aWR0aCAmJiBhLmhlaWdodCA9PT0gYi5oZWlnaHQpLFxuICAgICAgICAgIGRlYm91bmNlVGltZSg1MClcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmVkaXRvckluc3RhbmNlIS5sYXlvdXQoKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldFZhbHVlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0b3JJbnN0YW5jZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm56RnVsbENvbnRyb2wgJiYgdGhpcy52YWx1ZSkge1xuICAgICAgd2Fybihgc2hvdWxkIG5vdCBzZXQgdmFsdWUgd2hlbiB5b3UgYXJlIHVzaW5nIGZ1bGwgY29udHJvbCBtb2RlISBJdCB3b3VsZCByZXN1bHQgaW4gYW1iaWd1b3VzIGRhdGEgZmxvdyFgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5uekVkaXRvck1vZGUgPT09ICdub3JtYWwnKSB7XG4gICAgICBpZiAodGhpcy5tb2RlbFNldCkge1xuICAgICAgICBjb25zdCBtb2RlbCA9IHRoaXMuZWRpdG9ySW5zdGFuY2UuZ2V0TW9kZWwoKSBhcyBJVGV4dE1vZGVsO1xuICAgICAgICB0aGlzLnByZXNlcnZlUG9zaXRpb25BbmRTZWxlY3Rpb25zKCgpID0+IG1vZGVsLnNldFZhbHVlKHRoaXMudmFsdWUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICh0aGlzLmVkaXRvckluc3RhbmNlIGFzIElTdGFuZGFsb25lQ29kZUVkaXRvcikuc2V0TW9kZWwoXG4gICAgICAgICAgbW9uYWNvLmVkaXRvci5jcmVhdGVNb2RlbCh0aGlzLnZhbHVlLCAodGhpcy5lZGl0b3JPcHRpb25DYWNoZWQgYXMgRWRpdG9yT3B0aW9ucykubGFuZ3VhZ2UpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMubW9kZWxTZXQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5tb2RlbFNldCkge1xuICAgICAgICBjb25zdCBtb2RlbCA9ICh0aGlzLmVkaXRvckluc3RhbmNlIGFzIElTdGFuZGFsb25lRGlmZkVkaXRvcikuZ2V0TW9kZWwoKSE7XG4gICAgICAgIHRoaXMucHJlc2VydmVQb3NpdGlvbkFuZFNlbGVjdGlvbnMoKCkgPT4ge1xuICAgICAgICAgIG1vZGVsLm1vZGlmaWVkLnNldFZhbHVlKHRoaXMudmFsdWUpO1xuICAgICAgICAgIG1vZGVsLm9yaWdpbmFsLnNldFZhbHVlKHRoaXMubnpPcmlnaW5hbFRleHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGxhbmd1YWdlID0gKHRoaXMuZWRpdG9yT3B0aW9uQ2FjaGVkIGFzIEVkaXRvck9wdGlvbnMpLmxhbmd1YWdlO1xuICAgICAgICAodGhpcy5lZGl0b3JJbnN0YW5jZSBhcyBJU3RhbmRhbG9uZURpZmZFZGl0b3IpLnNldE1vZGVsKHtcbiAgICAgICAgICBvcmlnaW5hbDogbW9uYWNvLmVkaXRvci5jcmVhdGVNb2RlbCh0aGlzLm56T3JpZ2luYWxUZXh0LCBsYW5ndWFnZSksXG4gICAgICAgICAgbW9kaWZpZWQ6IG1vbmFjby5lZGl0b3IuY3JlYXRlTW9kZWwodGhpcy52YWx1ZSwgbGFuZ3VhZ2UpXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1vZGVsU2V0ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIGVkaXRvci5JQ29kZUVkaXRvcn0jc2V0VmFsdWUgcmVzZXRzIHRoZSBjdXJzb3IgcG9zaXRpb24gdG8gdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudC5cbiAgICogVGhpcyBoZWxwZXIgbWVtb3JpemVzIHRoZSBjdXJzb3IgcG9zaXRpb24gYW5kIHNlbGVjdGlvbnMgYW5kIHJlc3RvcmVzIHRoZW0gYWZ0ZXIgdGhlIGdpdmVuXG4gICAqIGZ1bmN0aW9uIGhhcyBiZWVuIGNhbGxlZC5cbiAgICovXG4gIHByaXZhdGUgcHJlc2VydmVQb3NpdGlvbkFuZFNlbGVjdGlvbnMoZm46ICgpID0+IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9ySW5zdGFuY2UpIHtcbiAgICAgIGZuKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmVkaXRvckluc3RhbmNlLmdldFBvc2l0aW9uKCk7XG4gICAgY29uc3Qgc2VsZWN0aW9ucyA9IHRoaXMuZWRpdG9ySW5zdGFuY2UuZ2V0U2VsZWN0aW9ucygpO1xuXG4gICAgZm4oKTtcblxuICAgIGlmIChwb3NpdGlvbikge1xuICAgICAgdGhpcy5lZGl0b3JJbnN0YW5jZS5zZXRQb3NpdGlvbihwb3NpdGlvbik7XG4gICAgfVxuICAgIGlmIChzZWxlY3Rpb25zKSB7XG4gICAgICB0aGlzLmVkaXRvckluc3RhbmNlLnNldFNlbGVjdGlvbnMoc2VsZWN0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRWYWx1ZUVtaXR0ZXIoKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZWwgPSAoXG4gICAgICB0aGlzLm56RWRpdG9yTW9kZSA9PT0gJ25vcm1hbCdcbiAgICAgICAgPyAodGhpcy5lZGl0b3JJbnN0YW5jZSBhcyBJU3RhbmRhbG9uZUNvZGVFZGl0b3IpLmdldE1vZGVsKClcbiAgICAgICAgOiAodGhpcy5lZGl0b3JJbnN0YW5jZSBhcyBJU3RhbmRhbG9uZURpZmZFZGl0b3IpLmdldE1vZGVsKCkhLm1vZGlmaWVkXG4gICAgKSBhcyBJVGV4dE1vZGVsO1xuXG4gICAgLy8gVGhlIGBvbkRpZENoYW5nZUNvbnRlbnRgIHJldHVybnMgYSBkaXNwb3NhYmxlIG9iamVjdCAoYW4gb2JqZWN0IHdpdGggYGRpc3Bvc2UoKWAgbWV0aG9kKSB3aGljaCB3aWxsIGNsZWFudXBcbiAgICAvLyB0aGUgbGlzdGVuZXIuIFRoZSBjYWxsYmFjaywgdGhhdCB3ZSBwYXNzIHRvIGBvbkRpZENoYW5nZUNvbnRlbnRgLCBjYXB0dXJlcyBgdGhpc2AuIFRoaXMgbGVhZHMgdG8gYSBjaXJjdWxhciByZWZlcmVuY2VcbiAgICAvLyAoYG56LWNvZGUtZWRpdG9yIC0+IG1vbmFjbyAtPiBuei1jb2RlLWVkaXRvcmApIGFuZCBwcmV2ZW50cyB0aGUgYG56LWNvZGUtZWRpdG9yYCBmcm9tIGJlaW5nIEdDJ2QuXG4gICAgdGhpcy5vbkRpZENoYW5nZUNvbnRlbnREaXNwb3NhYmxlID0gbW9kZWwub25EaWRDaGFuZ2VDb250ZW50KCgpID0+IHtcbiAgICAgIHRoaXMuZW1pdFZhbHVlKG1vZGVsLmdldFZhbHVlKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0VmFsdWUodmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgLy8gSWYgdGhlIHZhbHVlIGRpZG4ndCBjaGFuZ2UgdGhlcmUncyBubyByZWFzb24gdG8gc2VuZCBhbiB1cGRhdGUuXG4gICAgICAvLyBTcGVjaWZpY2FsbHkgdGhpcyBtYXkgaGFwcGVuIGR1cmluZyBhbiB1cGRhdGUgZnJvbSB0aGUgbW9kZWwgKHdyaXRlVmFsdWUpIHdoZXJlIHNlbmRpbmcgYW4gdXBkYXRlIHRvIHRoZSBtb2RlbCB3b3VsZCBhY3R1YWxseSBiZSBpbmNvcnJlY3QuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIC8vIFdlJ3JlIHJlLWVudGVyaW5nIHRoZSBBbmd1bGFyIHpvbmUgb25seSBpZiB0aGUgdmFsdWUgaGFzIGJlZW4gY2hhbmdlZCBzaW5jZSB0aGVyZSdzIGEgYHJldHVybmAgZXhwcmVzc2lvbiBwcmV2aW91c2x5LlxuICAgIC8vIFRoaXMgd29uJ3QgY2F1c2UgXCJkZWFkXCIgY2hhbmdlIGRldGVjdGlvbnMgKGJhc2ljYWxseSB3aGVuIHRoZSBgdGljaygpYCBoYXMgYmVlbiBydW4sIGJ1dCB0aGVyZSdzIG5vdGhpbmcgdG8gdXBkYXRlKS5cbiAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgdGhpcy5vbkNoYW5nZSh2YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZU9wdGlvblRvTW9uYWNvKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmVkaXRvckluc3RhbmNlKSB7XG4gICAgICB0aGlzLmVkaXRvckluc3RhbmNlLnVwZGF0ZU9wdGlvbnMoeyAuLi50aGlzLmVkaXRvck9wdGlvbkNhY2hlZCB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==