ngx-echarts
Version:
<!-- Badges section here. -->
281 lines • 36.2 kB
JavaScript
import { Directive, EventEmitter, Inject, InjectionToken, Input, Output, } from '@angular/core';
import { Observable, Subject, asyncScheduler } from 'rxjs';
import { switchMap, throttleTime } from 'rxjs/operators';
import { ChangeFilter } from './change-filter';
import * as i0 from "@angular/core";
export const NGX_ECHARTS_CONFIG = new InjectionToken('NGX_ECHARTS_CONFIG');
export class NgxEchartsDirective {
constructor(config, el, ngZone) {
this.el = el;
this.ngZone = ngZone;
this.autoResize = true;
this.loadingType = 'default';
// ngx-echarts events
this.chartInit = new EventEmitter();
this.optionsError = new EventEmitter();
// echarts mouse events
this.chartClick = this.createLazyEvent('click');
this.chartDblClick = this.createLazyEvent('dblclick');
this.chartMouseDown = this.createLazyEvent('mousedown');
this.chartMouseMove = this.createLazyEvent('mousemove');
this.chartMouseUp = this.createLazyEvent('mouseup');
this.chartMouseOver = this.createLazyEvent('mouseover');
this.chartMouseOut = this.createLazyEvent('mouseout');
this.chartGlobalOut = this.createLazyEvent('globalout');
this.chartContextMenu = this.createLazyEvent('contextmenu');
// echarts mouse events
this.chartLegendSelectChanged = this.createLazyEvent('legendselectchanged');
this.chartLegendSelected = this.createLazyEvent('legendselected');
this.chartLegendUnselected = this.createLazyEvent('legendunselected');
this.chartLegendScroll = this.createLazyEvent('legendscroll');
this.chartDataZoom = this.createLazyEvent('datazoom');
this.chartDataRangeSelected = this.createLazyEvent('datarangeselected');
this.chartTimelineChanged = this.createLazyEvent('timelinechanged');
this.chartTimelinePlayChanged = this.createLazyEvent('timelineplaychanged');
this.chartRestore = this.createLazyEvent('restore');
this.chartDataViewChanged = this.createLazyEvent('dataviewchanged');
this.chartMagicTypeChanged = this.createLazyEvent('magictypechanged');
this.chartPieSelectChanged = this.createLazyEvent('pieselectchanged');
this.chartPieSelected = this.createLazyEvent('pieselected');
this.chartPieUnselected = this.createLazyEvent('pieunselected');
this.chartMapSelectChanged = this.createLazyEvent('mapselectchanged');
this.chartMapSelected = this.createLazyEvent('mapselected');
this.chartMapUnselected = this.createLazyEvent('mapunselected');
this.chartAxisAreaSelected = this.createLazyEvent('axisareaselected');
this.chartFocusNodeAdjacency = this.createLazyEvent('focusnodeadjacency');
this.chartUnfocusNodeAdjacency = this.createLazyEvent('unfocusnodeadjacency');
this.chartBrush = this.createLazyEvent('brush');
this.chartBrushEnd = this.createLazyEvent('brushend');
this.chartBrushSelected = this.createLazyEvent('brushselected');
this.chartRendered = this.createLazyEvent('rendered');
this.chartFinished = this.createLazyEvent('finished');
this.animationFrameID = null;
this.resize$ = new Subject();
this.echarts = config.echarts;
}
ngOnChanges(changes) {
const filter = ChangeFilter.of(changes);
filter.notFirstAndEmpty('options').subscribe((opt) => this.onOptionsChange(opt));
filter.notFirstAndEmpty('merge').subscribe((opt) => this.setOption(opt));
filter.has('loading').subscribe((v) => this.toggleLoading(!!v));
filter.notFirst('theme').subscribe(() => this.refreshChart());
}
ngOnInit() {
if (!window.ResizeObserver) {
throw new Error('please install a polyfill for ResizeObserver');
}
this.resizeSub = this.resize$.pipe(throttleTime(100, asyncScheduler, { leading: false, trailing: true })).subscribe(() => this.resize());
if (this.autoResize) {
this.resizeOb = this.ngZone.runOutsideAngular(() => new window.ResizeObserver(() => {
this.animationFrameID = window.requestAnimationFrame(() => this.resize$.next());
}));
this.resizeOb.observe(this.el.nativeElement);
}
}
ngOnDestroy() {
window.clearTimeout(this.initChartTimer);
if (this.resizeSub) {
this.resizeSub.unsubscribe();
}
if (this.animationFrameID) {
window.cancelAnimationFrame(this.animationFrameID);
}
if (this.resizeOb) {
this.resizeOb.unobserve(this.el.nativeElement);
}
this.dispose();
}
ngAfterViewInit() {
this.initChartTimer = window.setTimeout(() => this.initChart());
}
dispose() {
if (this.chart) {
if (!this.chart.isDisposed()) {
this.chart.dispose();
}
this.chart = null;
}
}
/**
* resize chart
*/
resize() {
if (this.chart) {
this.chart.resize();
}
}
toggleLoading(loading) {
if (this.chart) {
loading
? this.chart.showLoading(this.loadingType, this.loadingOpts)
: this.chart.hideLoading();
}
}
setOption(option, opts) {
if (this.chart) {
try {
this.chart.setOption(option, opts);
}
catch (e) {
console.error(e);
this.optionsError.emit(e);
}
}
}
/**
* dispose old chart and create a new one.
*/
async refreshChart() {
this.dispose();
await this.initChart();
}
createChart() {
const dom = this.el.nativeElement;
if (window && window.getComputedStyle) {
const prop = window.getComputedStyle(dom, null).getPropertyValue('height');
if ((!prop || prop === '0px') && (!dom.style.height || dom.style.height === '0px')) {
dom.style.height = '400px';
}
}
// here a bit tricky: we check if the echarts module is provided as function returning native import('...') then use the promise
// otherwise create the function that imitates behaviour above with a provided as is module
return this.ngZone.runOutsideAngular(() => {
const load = typeof this.echarts === 'function' ? this.echarts : () => Promise.resolve(this.echarts);
return load().then(({ init }) => init(dom, this.theme, this.initOpts));
});
}
async initChart() {
await this.onOptionsChange(this.options);
if (this.merge && this.chart) {
this.setOption(this.merge);
}
}
async onOptionsChange(opt) {
if (!opt) {
return;
}
if (this.chart) {
this.setOption(this.options, true);
}
else {
this.chart = await this.createChart();
this.chartInit.emit(this.chart);
this.setOption(this.options, true);
}
}
// allows to lazily bind to only those events that are requested through the `@Output` by parent components
// see https://stackoverflow.com/questions/51787972/optimal-reentering-the-ngzone-from-eventemitter-event for more info
createLazyEvent(eventName) {
return this.chartInit.pipe(switchMap((chart) => new Observable((observer) => {
chart.on(eventName, (data) => this.ngZone.run(() => observer.next(data)));
return () => {
if (this.chart) {
if (!this.chart.isDisposed()) {
chart.off(eventName);
}
}
};
})));
}
}
NgxEchartsDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, deps: [{ token: NGX_ECHARTS_CONFIG }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
NgxEchartsDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: { options: "options", theme: "theme", loading: "loading", initOpts: "initOpts", merge: "merge", autoResize: "autoResize", loadingType: "loadingType", loadingOpts: "loadingOpts" }, outputs: { chartInit: "chartInit", optionsError: "optionsError", chartClick: "chartClick", chartDblClick: "chartDblClick", chartMouseDown: "chartMouseDown", chartMouseMove: "chartMouseMove", chartMouseUp: "chartMouseUp", chartMouseOver: "chartMouseOver", chartMouseOut: "chartMouseOut", chartGlobalOut: "chartGlobalOut", chartContextMenu: "chartContextMenu", chartLegendSelectChanged: "chartLegendSelectChanged", chartLegendSelected: "chartLegendSelected", chartLegendUnselected: "chartLegendUnselected", chartLegendScroll: "chartLegendScroll", chartDataZoom: "chartDataZoom", chartDataRangeSelected: "chartDataRangeSelected", chartTimelineChanged: "chartTimelineChanged", chartTimelinePlayChanged: "chartTimelinePlayChanged", chartRestore: "chartRestore", chartDataViewChanged: "chartDataViewChanged", chartMagicTypeChanged: "chartMagicTypeChanged", chartPieSelectChanged: "chartPieSelectChanged", chartPieSelected: "chartPieSelected", chartPieUnselected: "chartPieUnselected", chartMapSelectChanged: "chartMapSelectChanged", chartMapSelected: "chartMapSelected", chartMapUnselected: "chartMapUnselected", chartAxisAreaSelected: "chartAxisAreaSelected", chartFocusNodeAdjacency: "chartFocusNodeAdjacency", chartUnfocusNodeAdjacency: "chartUnfocusNodeAdjacency", chartBrush: "chartBrush", chartBrushEnd: "chartBrushEnd", chartBrushSelected: "chartBrushSelected", chartRendered: "chartRendered", chartFinished: "chartFinished" }, exportAs: ["echarts"], usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, decorators: [{
type: Directive,
args: [{
selector: 'echarts, [echarts]',
exportAs: 'echarts',
}]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [NGX_ECHARTS_CONFIG]
}] }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { options: [{
type: Input
}], theme: [{
type: Input
}], loading: [{
type: Input
}], initOpts: [{
type: Input
}], merge: [{
type: Input
}], autoResize: [{
type: Input
}], loadingType: [{
type: Input
}], loadingOpts: [{
type: Input
}], chartInit: [{
type: Output
}], optionsError: [{
type: Output
}], chartClick: [{
type: Output
}], chartDblClick: [{
type: Output
}], chartMouseDown: [{
type: Output
}], chartMouseMove: [{
type: Output
}], chartMouseUp: [{
type: Output
}], chartMouseOver: [{
type: Output
}], chartMouseOut: [{
type: Output
}], chartGlobalOut: [{
type: Output
}], chartContextMenu: [{
type: Output
}], chartLegendSelectChanged: [{
type: Output
}], chartLegendSelected: [{
type: Output
}], chartLegendUnselected: [{
type: Output
}], chartLegendScroll: [{
type: Output
}], chartDataZoom: [{
type: Output
}], chartDataRangeSelected: [{
type: Output
}], chartTimelineChanged: [{
type: Output
}], chartTimelinePlayChanged: [{
type: Output
}], chartRestore: [{
type: Output
}], chartDataViewChanged: [{
type: Output
}], chartMagicTypeChanged: [{
type: Output
}], chartPieSelectChanged: [{
type: Output
}], chartPieSelected: [{
type: Output
}], chartPieUnselected: [{
type: Output
}], chartMapSelectChanged: [{
type: Output
}], chartMapSelected: [{
type: Output
}], chartMapUnselected: [{
type: Output
}], chartAxisAreaSelected: [{
type: Output
}], chartFocusNodeAdjacency: [{
type: Output
}], chartUnfocusNodeAdjacency: [{
type: Output
}], chartBrush: [{
type: Output
}], chartBrushEnd: [{
type: Output
}], chartBrushSelected: [{
type: Output
}], chartRendered: [{
type: Output
}], chartFinished: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWVjaGFydHMuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVjaGFydHMvc3JjL2xpYi9uZ3gtZWNoYXJ0cy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLGNBQWMsRUFDZCxLQUFLLEVBS0wsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFnQixjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekUsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBUy9DLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUFtQixvQkFBb0IsQ0FBQyxDQUFDO0FBTTdGLE1BQU0sT0FBTyxtQkFBbUI7SUFrRTlCLFlBQzhCLE1BQXdCLEVBQzVDLEVBQWMsRUFDZCxNQUFjO1FBRGQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLFdBQU0sR0FBTixNQUFNLENBQVE7UUF6RGYsZUFBVSxHQUFHLElBQUksQ0FBQztRQUNsQixnQkFBVyxHQUFHLFNBQVMsQ0FBQztRQUdqQyxxQkFBcUI7UUFDWCxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNwQyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7UUFFbkQsdUJBQXVCO1FBQ2IsZUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0Msa0JBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELG1CQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztR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Q0cscUJBQXFCO3NCQUE5QixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0cscUJBQXFCO3NCQUE5QixNQUFNO2dCQUNHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFDRyx5QkFBeUI7c0JBQWxDLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgYXN5bmNTY2hlZHVsZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGhyb3R0bGVUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ2hhbmdlRmlsdGVyIH0gZnJvbSAnLi9jaGFuZ2UtZmlsdGVyJztcbmltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgRUNoYXJ0cyB9IGZyb20gJ2VjaGFydHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5neEVjaGFydHNDb25maWcge1xuICBlY2hhcnRzOiBhbnkgfCAoKCkgPT4gUHJvbWlzZTxhbnk+KTtcbn1cblxuZXhwb3J0IHR5cGUgVGhlbWVPcHRpb24gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG5leHBvcnQgY29uc3QgTkdYX0VDSEFSVFNfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPE5neEVjaGFydHNDb25maWc+KCdOR1hfRUNIQVJUU19DT05GSUcnKTtcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnZWNoYXJ0cywgW2VjaGFydHNdJyxcbiAgZXhwb3J0QXM6ICdlY2hhcnRzJyxcbn0pXG5leHBvcnQgY2xhc3MgTmd4RWNoYXJ0c0RpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBvcHRpb25zOiBFQ2hhcnRzT3B0aW9uO1xuICBASW5wdXQoKSB0aGVtZTogc3RyaW5nIHwgVGhlbWVPcHRpb247XG4gIEBJbnB1dCgpIGxvYWRpbmc6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGluaXRPcHRzOiB7XG4gICAgZGV2aWNlUGl4ZWxSYXRpbz86IG51bWJlcjtcbiAgICByZW5kZXJlcj86IHN0cmluZztcbiAgICB3aWR0aD86IG51bWJlciB8IHN0cmluZztcbiAgICBoZWlnaHQ/OiBudW1iZXIgfCBzdHJpbmc7XG4gICAgbG9jYWxlPzogc3RyaW5nO1xuICB9O1xuICBASW5wdXQoKSBtZXJnZTogRUNoYXJ0c09wdGlvbjtcbiAgQElucHV0KCkgYXV0b1Jlc2l6ZSA9IHRydWU7XG4gIEBJbnB1dCgpIGxvYWRpbmdUeXBlID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBsb2FkaW5nT3B0czogb2JqZWN0O1xuXG4gIC8vIG5neC1lY2hhcnRzIGV2ZW50c1xuICBAT3V0cHV0KCkgY2hhcnRJbml0ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvcHRpb25zRXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEVycm9yPigpO1xuXG4gIC8vIGVjaGFydHMgbW91c2UgZXZlbnRzXG4gIEBPdXRwdXQoKSBjaGFydENsaWNrID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NsaWNrJyk7XG4gIEBPdXRwdXQoKSBjaGFydERibENsaWNrID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RibGNsaWNrJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1vdXNlRG93biA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtb3VzZWRvd24nKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VNb3ZlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNlbW92ZScpO1xuICBAT3V0cHV0KCkgY2hhcnRNb3VzZVVwID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNldXAnKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VPdmVyID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNlb3ZlcicpO1xuICBAT3V0cHV0KCkgY2hhcnRNb3VzZU91dCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtb3VzZW91dCcpO1xuICBAT3V0cHV0KCkgY2hhcnRHbG9iYWxPdXQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnZ2xvYmFsb3V0Jyk7XG4gIEBPdXRwdXQoKSBjaGFydENvbnRleHRNZW51ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NvbnRleHRtZW51Jyk7XG5cbiAgLy8gZWNoYXJ0cyBtb3VzZSBldmVudHNcbiAgQE91dHB1dCgpIGNoYXJ0TGVnZW5kU2VsZWN0Q2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdsZWdlbmRzZWxlY3RjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2xlZ2VuZHNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFVuc2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbGVnZW5kdW5zZWxlY3RlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRMZWdlbmRTY3JvbGwgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbGVnZW5kc2Nyb2xsJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFab29tID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RhdGF6b29tJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFSYW5nZVNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RhdGFyYW5nZXNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFRpbWVsaW5lQ2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCd0aW1lbGluZWNoYW5nZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0VGltZWxpbmVQbGF5Q2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCd0aW1lbGluZXBsYXljaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlc3RvcmUgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgncmVzdG9yZScpO1xuICBAT3V0cHV0KCkgY2hhcnREYXRhVmlld0NoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnZGF0YXZpZXdjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1hZ2ljVHlwZUNoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbWFnaWN0eXBlY2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRQaWVTZWxlY3RDaGFuZ2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3BpZXNlbGVjdGNoYW5nZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0UGllU2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgncGllc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0UGllVW5zZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdwaWV1bnNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1hcFNlbGVjdENoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbWFwc2VsZWN0Y2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRNYXBTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtYXBzZWxlY3RlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRNYXBVbnNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21hcHVuc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QXhpc0FyZWFTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdheGlzYXJlYXNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEZvY3VzTm9kZUFkamFjZW5jeSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdmb2N1c25vZGVhZGphY2VuY3knKTtcbiAgQE91dHB1dCgpIGNoYXJ0VW5mb2N1c05vZGVBZGphY2VuY3kgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgndW5mb2N1c25vZGVhZGphY2VuY3knKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2ggPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnYnJ1c2gnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2hFbmQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnYnJ1c2hlbmQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2hTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdicnVzaHNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlbmRlcmVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3JlbmRlcmVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEZpbmlzaGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2ZpbmlzaGVkJyk7XG5cbiAgcHVibGljIGFuaW1hdGlvbkZyYW1lSUQgPSBudWxsO1xuICBwcml2YXRlIGNoYXJ0OiBFQ2hhcnRzO1xuICBwcml2YXRlIGVjaGFydHM6IGFueTtcbiAgcHJpdmF0ZSByZXNpemVPYjogUmVzaXplT2JzZXJ2ZXI7XG4gIHByaXZhdGUgcmVzaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVzaXplU3ViOiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgaW5pdENoYXJ0VGltZXI/OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChOR1hfRUNIQVJUU19DT05GSUcpIGNvbmZpZzogTmd4RWNoYXJ0c0NvbmZpZyxcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICkge1xuICAgIHRoaXMuZWNoYXJ0cyA9IGNvbmZpZy5lY2hhcnRzO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGNvbnN0IGZpbHRlciA9IENoYW5nZUZpbHRlci5vZihjaGFuZ2VzKTtcbiAgICBmaWx0ZXIubm90Rmlyc3RBbmRFbXB0eTxhbnk+KCdvcHRpb25zJykuc3Vic2NyaWJlKChvcHQpID0+IHRoaXMub25PcHRpb25zQ2hhbmdlKG9wdCkpO1xuICAgIGZpbHRlci5ub3RGaXJzdEFuZEVtcHR5PGFueT4oJ21lcmdlJykuc3Vic2NyaWJlKChvcHQpID0+IHRoaXMuc2V0T3B0aW9uKG9wdCkpO1xuICAgIGZpbHRlci5oYXM8Ym9vbGVhbj4oJ2xvYWRpbmcnKS5zdWJzY3JpYmUoKHYpID0+IHRoaXMudG9nZ2xlTG9hZGluZyghIXYpKTtcbiAgICBmaWx0ZXIubm90Rmlyc3Q8c3RyaW5nIHwgVGhlbWVPcHRpb24+KCd0aGVtZScpLnN1YnNjcmliZSgoKSA9PiB0aGlzLnJlZnJlc2hDaGFydCgpKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICghd2luZG93LlJlc2l6ZU9ic2VydmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BsZWFzZSBpbnN0YWxsIGEgcG9seWZpbGwgZm9yIFJlc2l6ZU9ic2VydmVyJyk7XG4gICAgfVxuICAgIHRoaXMucmVzaXplU3ViID0gdGhpcy5yZXNpemUkLnBpcGUoXG4gICAgICB0aHJvdHRsZVRpbWUoMTAwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiBmYWxzZSwgdHJhaWxpbmc6IHRydWUgfSlcbiAgICApLnN1YnNjcmliZSgoKSA9PiB0aGlzLnJlc2l6ZSgpKVxuXG4gICAgaWYgKHRoaXMuYXV0b1Jlc2l6ZSkge1xuICAgICAgdGhpcy5yZXNpemVPYiA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IG5ldyB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSUQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHRoaXMucmVzaXplJC5uZXh0KCkpXG4gICAgICB9KSlcbiAgICAgIHRoaXMucmVzaXplT2Iub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5pbml0Q2hhcnRUaW1lcik7XG4gICAgaWYgKHRoaXMucmVzaXplU3ViKSB7XG4gICAgICB0aGlzLnJlc2l6ZVN1Yi51bnN1YnNjcmliZSgpXG4gICAgfVxuICAgIGlmICh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpIHtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXNpemVPYikge1xuICAgICAgdGhpcy5yZXNpemVPYi51bm9ic2VydmUodGhpcy5lbC5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gICAgdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5pbml0Q2hhcnRUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pdENoYXJ0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkaXNwb3NlKCkge1xuICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICBpZiAoIXRoaXMuY2hhcnQuaXNEaXNwb3NlZCgpKSB7XG4gICAgICAgIHRoaXMuY2hhcnQuZGlzcG9zZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGFydCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHJlc2l6ZSBjaGFydFxuICAgKi9cbiAgcmVzaXplKCkge1xuICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLmNoYXJ0LnJlc2l6ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdG9nZ2xlTG9hZGluZyhsb2FkaW5nOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIGxvYWRpbmdcbiAgICAgICAgPyB0aGlzLmNoYXJ0LnNob3dMb2FkaW5nKHRoaXMubG9hZGluZ1R5cGUsIHRoaXMubG9hZGluZ09wdHMpXG4gICAgICAgIDogdGhpcy5jaGFydC5oaWRlTG9hZGluZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0T3B0aW9uKG9wdGlvbjogYW55LCBvcHRzPzogYW55KSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY2hhcnQuc2V0T3B0aW9uKG9wdGlvbiwgb3B0cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIHRoaXMub3B0aW9uc0Vycm9yLmVtaXQoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2Ugb2xkIGNoYXJ0IGFuZCBjcmVhdGUgYSBuZXcgb25lLlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaENoYXJ0KCkge1xuICAgIHRoaXMuZGlzcG9zZSgpO1xuICAgIGF3YWl0IHRoaXMuaW5pdENoYXJ0KCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNoYXJ0KCkge1xuICAgIGNvbnN0IGRvbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICh3aW5kb3cgJiYgd2luZG93LmdldENvbXB1dGVkU3R5bGUpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb20sIG51bGwpLmdldFByb3BlcnR5VmFsdWUoJ2hlaWdodCcpO1xuICAgICAgaWYgKCghcHJvcCB8fCBwcm9wID09PSAnMHB4JykgJiYgKCFkb20uc3R5bGUuaGVpZ2h0IHx8IGRvbS5zdHlsZS5oZWlnaHQgPT09ICcwcHgnKSkge1xuICAgICAgICBkb20uc3R5bGUuaGVpZ2h0ID0gJzQwMHB4JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBoZXJlIGEgYml0IHRyaWNreTogd2UgY2hlY2sgaWYgdGhlIGVjaGFydHMgbW9kdWxlIGlzIHByb3ZpZGVkIGFzIGZ1bmN0aW9uIHJldHVybmluZyBuYXRpdmUgaW1wb3J0KCcuLi4nKSB0aGVuIHVzZSB0aGUgcHJvbWlzZVxuICAgIC8vIG90aGVyd2lzZSBjcmVhdGUgdGhlIGZ1bmN0aW9uIHRoYXQgaW1pdGF0ZXMgYmVoYXZpb3VyIGFib3ZlIHdpdGggYSBwcm92aWRlZCBhcyBpcyBtb2R1bGVcbiAgICByZXR1cm4gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgbG9hZCA9XG4gICAgICAgIHR5cGVvZiB0aGlzLmVjaGFydHMgPT09ICdmdW5jdGlvbicgPyB0aGlzLmVjaGFydHMgOiAoKSA9PiBQcm9taXNlLnJlc29sdmUodGhpcy5lY2hhcnRzKTtcblxuICAgICAgcmV0dXJuIGxvYWQoKS50aGVuKCh7IGluaXQgfSkgPT4gaW5pdChkb20sIHRoaXMudGhlbWUsIHRoaXMuaW5pdE9wdHMpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdENoYXJ0KCkge1xuICAgIGF3YWl0IHRoaXMub25PcHRpb25zQ2hhbmdlKHRoaXMub3B0aW9ucyk7XG5cbiAgICBpZiAodGhpcy5tZXJnZSAmJiB0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLnNldE9wdGlvbih0aGlzLm1lcmdlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9uT3B0aW9uc0NoYW5nZShvcHQ6IGFueSkge1xuICAgIGlmICghb3B0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRoaXMuc2V0T3B0aW9uKHRoaXMub3B0aW9ucywgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhcnQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNoYXJ0KCk7XG4gICAgICB0aGlzLmNoYXJ0SW5pdC5lbWl0KHRoaXMuY2hhcnQpO1xuICAgICAgdGhpcy5zZXRPcHRpb24odGhpcy5vcHRpb25zLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhbGxvd3MgdG8gbGF6aWx5IGJpbmQgdG8gb25seSB0aG9zZSBldmVudHMgdGhhdCBhcmUgcmVxdWVzdGVkIHRocm91Z2ggdGhlIGBAT3V0cHV0YCBieSBwYXJlbnQgY29tcG9uZW50c1xuICAvLyBzZWUgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTE3ODc5NzIvb3B0aW1hbC1yZWVudGVyaW5nLXRoZS1uZ3pvbmUtZnJvbS1ldmVudGVtaXR0ZXItZXZlbnQgZm9yIG1vcmUgaW5mb1xuICBwcml2YXRlIGNyZWF0ZUxhenlFdmVudDxUPihldmVudE5hbWU6IHN0cmluZyk6IEV2ZW50RW1pdHRlcjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnRJbml0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoXG4gICAgICAgIChjaGFydDogYW55KSA9PlxuICAgICAgICAgIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgY2hhcnQub24oZXZlbnROYW1lLCAoZGF0YTogVCkgPT4gdGhpcy5uZ1pvbmUucnVuKCgpID0+IG9ic2VydmVyLm5leHQoZGF0YSkpKTtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNoYXJ0LmlzRGlzcG9zZWQoKSkge1xuICAgICAgICAgICAgICAgICAgY2hhcnQub2ZmKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApIGFzIEV2ZW50RW1pdHRlcjxUPjtcbiAgfVxufVxuIl19