UNPKG

@swimlane/ngx-charts

Version:

Declarative Charting Framework for Angular

305 lines 31.8 kB
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, PLATFORM_ID, Inject } from '@angular/core'; import { trigger, style, animate, transition } from '@angular/animations'; import { formatLabel, escapeLabel } from '../common/label.helper'; import { PlacementTypes } from '../common/tooltip/position'; import { StyleTypes } from '../common/tooltip/style.type'; import { ScaleType } from '../common/types/scale-type.enum'; import { isPlatformServer } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "../common/circle.component"; import * as i2 from "@angular/common"; import * as i3 from "../common/tooltip/tooltip.directive"; export class BubbleSeriesComponent { constructor(platformId) { this.platformId = platformId; this.tooltipDisabled = false; this.select = new EventEmitter(); this.activate = new EventEmitter(); this.deactivate = new EventEmitter(); this.placementTypes = PlacementTypes; this.styleTypes = StyleTypes; this.isSSR = false; } ngOnInit() { if (isPlatformServer(this.platformId)) { this.isSSR = true; } } ngOnChanges(changes) { this.update(); } update() { this.circles = this.getCircles(); } getCircles() { const seriesName = this.data.name; return this.data.series .map((d, i) => { if (typeof d.y !== 'undefined' && typeof d.x !== 'undefined') { const y = d.y; const x = d.x; const r = d.r; const radius = this.rScale(r || 1); const tooltipLabel = formatLabel(d.name); const cx = this.xScaleType === ScaleType.Linear ? this.xScale(Number(x)) : this.xScale(x); const cy = this.yScaleType === ScaleType.Linear ? this.yScale(Number(y)) : this.yScale(y); const color = this.colors.scaleType === ScaleType.Linear ? this.colors.getColor(r) : this.colors.getColor(seriesName); const isActive = !this.activeEntries.length ? true : this.isActive({ name: seriesName }); const opacity = isActive ? 1 : 0.3; const data = Object.assign({}, d, { series: seriesName, name: d.name, value: d.y, x: d.x, radius: d.r }); return { data, x, y, r, classNames: [`circle-data-${i}`], value: y, label: x, cx, cy, radius, tooltipLabel, color, opacity, seriesName, isActive, transform: `translate(${cx},${cy})` }; } }) .filter(circle => circle !== undefined); } getTooltipText(circle) { const hasRadius = typeof circle.r !== 'undefined'; const hasTooltipLabel = circle.tooltipLabel && circle.tooltipLabel.length; const hasSeriesName = circle.seriesName && circle.seriesName.length; const radiusValue = hasRadius ? formatLabel(circle.r) : ''; const xAxisLabel = this.xAxisLabel && this.xAxisLabel !== '' ? `${this.xAxisLabel}:` : ''; const yAxisLabel = this.yAxisLabel && this.yAxisLabel !== '' ? `${this.yAxisLabel}:` : ''; const x = formatLabel(circle.x); const y = formatLabel(circle.y); const name = hasSeriesName && hasTooltipLabel ? `${circle.seriesName} • ${circle.tooltipLabel}` : circle.seriesName + circle.tooltipLabel; const tooltipTitle = hasSeriesName || hasTooltipLabel ? `<span class="tooltip-label">${escapeLabel(name)}</span>` : ''; return ` ${tooltipTitle} <span class="tooltip-label"> <label>${escapeLabel(xAxisLabel)}</label> ${escapeLabel(x)}<br /> <label>${escapeLabel(yAxisLabel)}</label> ${escapeLabel(y)} </span> <span class="tooltip-val"> ${escapeLabel(radiusValue)} </span> `; } onClick(data) { this.select.emit(data); } isActive(entry) { if (!this.activeEntries) return false; const item = this.activeEntries.find(d => { return entry.name === d.name; }); return item !== undefined; } isVisible(circle) { if (this.activeEntries.length > 0) { return this.isActive({ name: circle.seriesName }); } return circle.opacity !== 0; } activateCircle(circle) { circle.barVisible = true; this.activate.emit({ name: this.data.name }); } deactivateCircle(circle) { circle.barVisible = false; this.deactivate.emit({ name: this.data.name }); } trackBy(index, circle) { return `${circle.data.series} ${circle.data.name}`; } } BubbleSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BubbleSeriesComponent, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); BubbleSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.0", type: BubbleSeriesComponent, selector: "g[ngx-charts-bubble-series]", inputs: { data: "data", xScale: "xScale", yScale: "yScale", rScale: "rScale", xScaleType: "xScaleType", yScaleType: "yScaleType", colors: "colors", visibleValue: "visibleValue", activeEntries: "activeEntries", xAxisLabel: "xAxisLabel", yAxisLabel: "yAxisLabel", tooltipDisabled: "tooltipDisabled", tooltipTemplate: "tooltipTemplate" }, outputs: { select: "select", activate: "activate", deactivate: "deactivate" }, usesOnChanges: true, ngImport: i0, template: ` <svg:g *ngFor="let circle of circles; trackBy: trackBy"> <svg:g [attr.transform]="circle.transform"> <svg:g *ngIf="!isSSR" ngx-charts-circle [@animationState]="'active'" class="circle" [cx]="0" [cy]="0" [r]="circle.radius" [fill]="circle.color" [style.opacity]="circle.opacity" [class.active]="circle.isActive" [pointerEvents]="'all'" [data]="circle.value" [classNames]="circle.classNames" (select)="onClick(circle.data)" (activate)="activateCircle(circle)" (deactivate)="deactivateCircle(circle)" ngx-tooltip [tooltipDisabled]="tooltipDisabled" [tooltipPlacement]="placementTypes.Top" [tooltipType]="styleTypes.tooltip" [tooltipTitle]="tooltipTemplate ? undefined : getTooltipText(circle)" [tooltipTemplate]="tooltipTemplate" [tooltipContext]="circle.data" /> <svg:g *ngIf="isSSR" ngx-charts-circle class="circle" [cx]="0" [cy]="0" [r]="circle.radius" [fill]="circle.color" [style.opacity]="circle.opacity" [class.active]="circle.isActive" [pointerEvents]="'all'" [data]="circle.value" [classNames]="circle.classNames" (select)="onClick(circle.data)" (activate)="activateCircle(circle)" (deactivate)="deactivateCircle(circle)" ngx-tooltip [tooltipDisabled]="tooltipDisabled" [tooltipPlacement]="placementTypes.Top" [tooltipType]="styleTypes.tooltip" [tooltipTitle]="tooltipTemplate ? undefined : getTooltipText(circle)" [tooltipTemplate]="tooltipTemplate" [tooltipContext]="circle.data" /> </svg:g> </svg:g> `, isInline: true, components: [{ type: i1.CircleComponent, selector: "g[ngx-charts-circle]", inputs: ["cx", "cy", "r", "fill", "stroke", "data", "classNames", "circleOpacity", "pointerEvents"], outputs: ["select", "activate", "deactivate"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.TooltipDirective, selector: "[ngx-tooltip]", inputs: ["tooltipCssClass", "tooltipTitle", "tooltipAppendToBody", "tooltipSpacing", "tooltipDisabled", "tooltipShowCaret", "tooltipPlacement", "tooltipAlignment", "tooltipType", "tooltipCloseOnClickOutside", "tooltipCloseOnMouseLeave", "tooltipHideTimeout", "tooltipShowTimeout", "tooltipTemplate", "tooltipShowEvent", "tooltipContext", "tooltipImmediateExit"], outputs: ["show", "hide"] }], animations: [ trigger('animationState', [ transition(':enter', [ style({ opacity: 0, transform: 'scale(0)' }), animate(250, style({ opacity: 1, transform: 'scale(1)' })) ]) ]) ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.0", ngImport: i0, type: BubbleSeriesComponent, decorators: [{ type: Component, args: [{ selector: 'g[ngx-charts-bubble-series]', template: ` <svg:g *ngFor="let circle of circles; trackBy: trackBy"> <svg:g [attr.transform]="circle.transform"> <svg:g *ngIf="!isSSR" ngx-charts-circle [@animationState]="'active'" class="circle" [cx]="0" [cy]="0" [r]="circle.radius" [fill]="circle.color" [style.opacity]="circle.opacity" [class.active]="circle.isActive" [pointerEvents]="'all'" [data]="circle.value" [classNames]="circle.classNames" (select)="onClick(circle.data)" (activate)="activateCircle(circle)" (deactivate)="deactivateCircle(circle)" ngx-tooltip [tooltipDisabled]="tooltipDisabled" [tooltipPlacement]="placementTypes.Top" [tooltipType]="styleTypes.tooltip" [tooltipTitle]="tooltipTemplate ? undefined : getTooltipText(circle)" [tooltipTemplate]="tooltipTemplate" [tooltipContext]="circle.data" /> <svg:g *ngIf="isSSR" ngx-charts-circle class="circle" [cx]="0" [cy]="0" [r]="circle.radius" [fill]="circle.color" [style.opacity]="circle.opacity" [class.active]="circle.isActive" [pointerEvents]="'all'" [data]="circle.value" [classNames]="circle.classNames" (select)="onClick(circle.data)" (activate)="activateCircle(circle)" (deactivate)="deactivateCircle(circle)" ngx-tooltip [tooltipDisabled]="tooltipDisabled" [tooltipPlacement]="placementTypes.Top" [tooltipType]="styleTypes.tooltip" [tooltipTitle]="tooltipTemplate ? undefined : getTooltipText(circle)" [tooltipTemplate]="tooltipTemplate" [tooltipContext]="circle.data" /> </svg:g> </svg:g> `, changeDetection: ChangeDetectionStrategy.OnPush, animations: [ trigger('animationState', [ transition(':enter', [ style({ opacity: 0, transform: 'scale(0)' }), animate(250, style({ opacity: 1, transform: 'scale(1)' })) ]) ]) ] }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }]; }, propDecorators: { data: [{ type: Input }], xScale: [{ type: Input }], yScale: [{ type: Input }], rScale: [{ type: Input }], xScaleType: [{ type: Input }], yScaleType: [{ type: Input }], colors: [{ type: Input }], visibleValue: [{ type: Input }], activeEntries: [{ type: Input }], xAxisLabel: [{ type: Input }], yAxisLabel: [{ type: Input }], tooltipDisabled: [{ type: Input }], tooltipTemplate: [{ type: Input }], select: [{ type: Output }], activate: [{ type: Output }], deactivate: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnViYmxlLXNlcmllcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zd2ltbGFuZS9uZ3gtY2hhcnRzL3NyYy9saWIvYnViYmxlLWNoYXJ0L2J1YmJsZS1zZXJpZXMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFFTixZQUFZLEVBRVosdUJBQXVCLEVBRXZCLFdBQVcsRUFDWCxNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzVELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDNUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7O0FBd0VuRCxNQUFNLE9BQU8scUJBQXFCO0lBMkJoQyxZQUF5QyxVQUFlO1FBQWYsZUFBVSxHQUFWLFVBQVUsQ0FBSztRQWYvQyxvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUdoQyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM1QixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM5QixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUsxQyxtQkFBYyxHQUFHLGNBQWMsQ0FBQztRQUNoQyxlQUFVLEdBQUcsVUFBVSxDQUFDO1FBRXhCLFVBQUssR0FBRyxLQUFLLENBQUM7SUFFNkMsQ0FBQztJQUU1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cUI7a0JBdEVqQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSw2QkFBNkI7b0JBQ3ZDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0RUO29CQUNELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxVQUFVLEVBQUU7d0JBQ1YsT0FBTyxDQUFDLGdCQUFnQixFQUFFOzRCQUN4QixVQUFVLENBQUMsUUFBUSxFQUFFO2dDQUNuQixLQUFLLENBQUM7b0NBQ0osT0FBTyxFQUFFLENBQUM7b0NBQ1YsU0FBUyxFQUFFLFVBQVU7aUNBQ3RCLENBQUM7Z0NBQ0YsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDOzZCQUMzRCxDQUFDO3lCQUNILENBQUM7cUJBQ0g7aUJBQ0Y7OzBCQTRCYyxNQUFNOzJCQUFDLFdBQVc7NENBMUJ0QixJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFFSSxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBFdmVudEVtaXR0ZXIsXG4gIE9uQ2hhbmdlcyxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIFRlbXBsYXRlUmVmLFxuICBQTEFURk9STV9JRCxcbiAgSW5qZWN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdHJpZ2dlciwgc3R5bGUsIGFuaW1hdGUsIHRyYW5zaXRpb24gfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7IGZvcm1hdExhYmVsLCBlc2NhcGVMYWJlbCB9IGZyb20gJy4uL2NvbW1vbi9sYWJlbC5oZWxwZXInO1xuaW1wb3J0IHsgQ29sb3JIZWxwZXIgfSBmcm9tICcuLi9jb21tb24vY29sb3IuaGVscGVyJztcbmltcG9ydCB7IEJ1YmJsZUNoYXJ0U2VyaWVzIH0gZnJvbSAnLi4vbW9kZWxzL2NoYXJ0LWRhdGEubW9kZWwnO1xuaW1wb3J0IHsgUGxhY2VtZW50VHlwZXMgfSBmcm9tICcuLi9jb21tb24vdG9vbHRpcC9wb3NpdGlvbic7XG5pbXBvcnQgeyBTdHlsZVR5cGVzIH0gZnJvbSAnLi4vY29tbW9uL3Rvb2x0aXAvc3R5bGUudHlwZSc7XG5pbXBvcnQgeyBTY2FsZVR5cGUgfSBmcm9tICcuLi9jb21tb24vdHlwZXMvc2NhbGUtdHlwZS5lbnVtJztcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdnW25neC1jaGFydHMtYnViYmxlLXNlcmllc10nLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxzdmc6ZyAqbmdGb3I9XCJsZXQgY2lyY2xlIG9mIGNpcmNsZXM7IHRyYWNrQnk6IHRyYWNrQnlcIj5cbiAgICAgIDxzdmc6ZyBbYXR0ci50cmFuc2Zvcm1dPVwiY2lyY2xlLnRyYW5zZm9ybVwiPlxuICAgICAgICA8c3ZnOmdcbiAgICAgICAgICAqbmdJZj1cIiFpc1NTUlwiXG4gICAgICAgICAgbmd4LWNoYXJ0cy1jaXJjbGVcbiAgICAgICAgICBbQGFuaW1hdGlvblN0YXRlXT1cIidhY3RpdmUnXCJcbiAgICAgICAgICBjbGFzcz1cImNpcmNsZVwiXG4gICAgICAgICAgW2N4XT1cIjBcIlxuICAgICAgICAgIFtjeV09XCIwXCJcbiAgICAgICAgICBbcl09XCJjaXJjbGUucmFkaXVzXCJcbiAgICAgICAgICBbZmlsbF09XCJjaXJjbGUuY29sb3JcIlxuICAgICAgICAgIFtzdHlsZS5vcGFjaXR5XT1cImNpcmNsZS5vcGFjaXR5XCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImNpcmNsZS5pc0FjdGl2ZVwiXG4gICAgICAgICAgW3BvaW50ZXJFdmVudHNdPVwiJ2FsbCdcIlxuICAgICAgICAgIFtkYXRhXT1cImNpcmNsZS52YWx1ZVwiXG4gICAgICAgICAgW2NsYXNzTmFtZXNdPVwiY2lyY2xlLmNsYXNzTmFtZXNcIlxuICAgICAgICAgIChzZWxlY3QpPVwib25DbGljayhjaXJjbGUuZGF0YSlcIlxuICAgICAgICAgIChhY3RpdmF0ZSk9XCJhY3RpdmF0ZUNpcmNsZShjaXJjbGUpXCJcbiAgICAgICAgICAoZGVhY3RpdmF0ZSk9XCJkZWFjdGl2YXRlQ2lyY2xlKGNpcmNsZSlcIlxuICAgICAgICAgIG5neC10b29sdGlwXG4gICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWRcIlxuICAgICAgICAgIFt0b29sdGlwUGxhY2VtZW50XT1cInBsYWNlbWVudFR5cGVzLlRvcFwiXG4gICAgICAgICAgW3Rvb2x0aXBUeXBlXT1cInN0eWxlVHlwZXMudG9vbHRpcFwiXG4gICAgICAgICAgW3Rvb2x0aXBUaXRsZV09XCJ0b29sdGlwVGVtcGxhdGUgPyB1bmRlZmluZWQgOiBnZXRUb29sdGlwVGV4dChjaXJjbGUpXCJcbiAgICAgICAgICBbdG9vbHRpcFRlbXBsYXRlXT1cInRvb2x0aXBUZW1wbGF0ZVwiXG4gICAgICAgICAgW3Rvb2x0aXBDb250ZXh0XT1cImNpcmNsZS5kYXRhXCJcbiAgICAgICAgLz5cbiAgICAgICAgPHN2ZzpnXG4gICAgICAgICAgKm5nSWY9XCJpc1NTUlwiXG4gICAgICAgICAgbmd4LWNoYXJ0cy1jaXJjbGVcbiAgICAgICAgICBjbGFzcz1cImNpcmNsZVwiXG4gICAgICAgICAgW2N4XT1cIjBcIlxuICAgICAgICAgIFtjeV09XCIwXCJcbiAgICAgICAgICBbcl09XCJjaXJjbGUucmFkaXVzXCJcbiAgICAgICAgICBbZmlsbF09XCJjaXJjbGUuY29sb3JcIlxuICAgICAgICAgIFtzdHlsZS5vcGFjaXR5XT1cImNpcmNsZS5vcGFjaXR5XCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImNpcmNsZS5pc0FjdGl2ZVwiXG4gICAgICAgICAgW3BvaW50ZXJFdmVudHNdPVwiJ2FsbCdcIlxuICAgICAgICAgIFtkYXRhXT1cImNpcmNsZS52YWx1ZVwiXG4gICAgICAgICAgW2NsYXNzTmFtZXNdPVwiY2lyY2xlLmNsYXNzTmFtZXNcIlxuICAgICAgICAgIChzZWxlY3QpPVwib25DbGljayhjaXJjbGUuZGF0YSlcIlxuICAgICAgICAgIChhY3RpdmF0ZSk9XCJhY3RpdmF0ZUNpcmNsZShjaXJjbGUpXCJcbiAgICAgICAgICAoZGVhY3RpdmF0ZSk9XCJkZWFjdGl2YXRlQ2lyY2xlKGNpcmNsZSlcIlxuICAgICAgICAgIG5neC10b29sdGlwXG4gICAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWRcIlxuICAgICAgICAgIFt0b29sdGlwUGxhY2VtZW50XT1cInBsYWNlbWVudFR5cGVzLlRvcFwiXG4gICAgICAgICAgW3Rvb2x0aXBUeXBlXT1cInN0eWxlVHlwZXMudG9vbHRpcFwiXG4gICAgICAgICAgW3Rvb2x0aXBUaXRsZV09XCJ0b29sdGlwVGVtcGxhdGUgPyB1bmRlZmluZWQgOiBnZXRUb29sdGlwVGV4dChjaXJjbGUpXCJcbiAgICAgICAgICBbdG9vbHRpcFRlbXBsYXRlXT1cInRvb2x0aXBUZW1wbGF0ZVwiXG4gICAgICAgICAgW3Rvb2x0aXBDb250ZXh0XT1cImNpcmNsZS5kYXRhXCJcbiAgICAgICAgLz5cbiAgICAgIDwvc3ZnOmc+XG4gICAgPC9zdmc6Zz5cbiAgYCxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGFuaW1hdGlvbnM6IFtcbiAgICB0cmlnZ2VyKCdhbmltYXRpb25TdGF0ZScsIFtcbiAgICAgIHRyYW5zaXRpb24oJzplbnRlcicsIFtcbiAgICAgICAgc3R5bGUoe1xuICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgdHJhbnNmb3JtOiAnc2NhbGUoMCknXG4gICAgICAgIH0pLFxuICAgICAgICBhbmltYXRlKDI1MCwgc3R5bGUoeyBvcGFjaXR5OiAxLCB0cmFuc2Zvcm06ICdzY2FsZSgxKScgfSkpXG4gICAgICBdKVxuICAgIF0pXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgQnViYmxlU2VyaWVzQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgZGF0YTogQnViYmxlQ2hhcnRTZXJpZXM7XG4gIEBJbnB1dCgpIHhTY2FsZTtcbiAgQElucHV0KCkgeVNjYWxlO1xuICBASW5wdXQoKSByU2NhbGU7XG4gIEBJbnB1dCgpIHhTY2FsZVR5cGU6IFNjYWxlVHlwZTtcbiAgQElucHV0KCkgeVNjYWxlVHlwZTogU2NhbGVUeXBlO1xuICBASW5wdXQoKSBjb2xvcnM6IENvbG9ySGVscGVyO1xuICBASW5wdXQoKSB2aXNpYmxlVmFsdWU7XG4gIEBJbnB1dCgpIGFjdGl2ZUVudHJpZXM6IGFueVtdO1xuICBASW5wdXQoKSB4QXhpc0xhYmVsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHlBeGlzTGFiZWw6IHN0cmluZztcbiAgQElucHV0KCkgdG9vbHRpcERpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHRvb2x0aXBUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBAT3V0cHV0KCkgc2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgYWN0aXZhdGUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWFjdGl2YXRlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIGFyZWFQYXRoOiBhbnk7XG4gIGNpcmNsZXM6IGFueVtdOyAvLyBUT0RPIHR5cGUgdGhpc1xuXG4gIHBsYWNlbWVudFR5cGVzID0gUGxhY2VtZW50VHlwZXM7XG4gIHN0eWxlVHlwZXMgPSBTdHlsZVR5cGVzO1xuXG4gIGlzU1NSID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBhbnkpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgdGhpcy5pc1NTUiA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICB1cGRhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5jaXJjbGVzID0gdGhpcy5nZXRDaXJjbGVzKCk7XG4gIH1cblxuICBnZXRDaXJjbGVzKCk6IGFueVtdIHtcbiAgICBjb25zdCBzZXJpZXNOYW1lID0gdGhpcy5kYXRhLm5hbWU7XG5cbiAgICByZXR1cm4gdGhpcy5kYXRhLnNlcmllc1xuICAgICAgLm1hcCgoZCwgaSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGQueSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGQueCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCB5ID0gZC55O1xuICAgICAgICAgIGNvbnN0IHggPSBkLng7XG4gICAgICAgICAgY29uc3QgciA9IGQucjtcblxuICAgICAgICAgIGNvbnN0IHJhZGl1cyA9IHRoaXMuclNjYWxlKHIgfHwgMSk7XG4gICAgICAgICAgY29uc3QgdG9vbHRpcExhYmVsID0gZm9ybWF0TGFiZWwoZC5uYW1lKTtcblxuICAgICAgICAgIGNvbnN0IGN4ID0gdGhpcy54U2NhbGVUeXBlID09PSBTY2FsZVR5cGUuTGluZWFyID8gdGhpcy54U2NhbGUoTnVtYmVyKHgpKSA6IHRoaXMueFNjYWxlKHgpO1xuICAgICAgICAgIGNvbnN0IGN5ID0gdGhpcy55U2NhbGVUeXBlID09PSBTY2FsZVR5cGUuTGluZWFyID8gdGhpcy55U2NhbGUoTnVtYmVyKHkpKSA6IHRoaXMueVNjYWxlKHkpO1xuXG4gICAgICAgICAgY29uc3QgY29sb3IgPVxuICAgICAgICAgICAgdGhpcy5jb2xvcnMuc2NhbGVUeXBlID09PSBTY2FsZVR5cGUuTGluZWFyID8gdGhpcy5jb2xvcnMuZ2V0Q29sb3IocikgOiB0aGlzLmNvbG9ycy5nZXRDb2xvcihzZXJpZXNOYW1lKTtcblxuICAgICAgICAgIGNvbnN0IGlzQWN0aXZlID0gIXRoaXMuYWN0aXZlRW50cmllcy5sZW5ndGggPyB0cnVlIDogdGhpcy5pc0FjdGl2ZSh7IG5hbWU6IHNlcmllc05hbWUgfSk7XG4gICAgICAgICAgY29uc3Qgb3BhY2l0eSA9IGlzQWN0aXZlID8gMSA6IDAuMztcblxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBPYmplY3QuYXNzaWduKHt9LCBkLCB7XG4gICAgICAgICAgICBzZXJpZXM6IHNlcmllc05hbWUsXG4gICAgICAgICAgICBuYW1lOiBkLm5hbWUsXG4gICAgICAgICAgICB2YWx1ZTogZC55LFxuICAgICAgICAgICAgeDogZC54LFxuICAgICAgICAgICAgcmFkaXVzOiBkLnJcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgeCxcbiAgICAgICAgICAgIHksXG4gICAgICAgICAgICByLFxuICAgICAgICAgICAgY2xhc3NOYW1lczogW2BjaXJjbGUtZGF0YS0ke2l9YF0sXG4gICAgICAgICAgICB2YWx1ZTogeSxcbiAgICAgICAgICAgIGxhYmVsOiB4LFxuICAgICAgICAgICAgY3gsXG4gICAgICAgICAgICBjeSxcbiAgICAgICAgICAgIHJhZGl1cyxcbiAgICAgICAgICAgIHRvb2x0aXBMYWJlbCxcbiAgICAgICAgICAgIGNvbG9yLFxuICAgICAgICAgICAgb3BhY2l0eSxcbiAgICAgICAgICAgIHNlcmllc05hbWUsXG4gICAgICAgICAgICBpc0FjdGl2ZSxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgke2N4fSwke2N5fSlgXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoY2lyY2xlID0+IGNpcmNsZSAhPT0gdW5kZWZpbmVkKTtcbiAgfVxuXG4gIGdldFRvb2x0aXBUZXh0KGNpcmNsZSk6IHN0cmluZyB7XG4gICAgY29uc3QgaGFzUmFkaXVzID0gdHlwZW9mIGNpcmNsZS5yICE9PSAndW5kZWZpbmVkJztcbiAgICBjb25zdCBoYXNUb29sdGlwTGFiZWwgPSBjaXJjbGUudG9vbHRpcExhYmVsICYmIGNpcmNsZS50b29sdGlwTGFiZWwubGVuZ3RoO1xuICAgIGNvbnN0IGhhc1Nlcmllc05hbWUgPSBjaXJjbGUuc2VyaWVzTmFtZSAmJiBjaXJjbGUuc2VyaWVzTmFtZS5sZW5ndGg7XG5cbiAgICBjb25zdCByYWRpdXNWYWx1ZSA9IGhhc1JhZGl1cyA/IGZvcm1hdExhYmVsKGNpcmNsZS5yKSA6ICcnO1xuICAgIGNvbnN0IHhBeGlzTGFiZWwgPSB0aGlzLnhBeGlzTGFiZWwgJiYgdGhpcy54QXhpc0xhYmVsICE9PSAnJyA/IGAke3RoaXMueEF4aXNMYWJlbH06YCA6ICcnO1xuICAgIGNvbnN0IHlBeGlzTGFiZWwgPSB0aGlzLnlBeGlzTGFiZWwgJiYgdGhpcy55QXhpc0xhYmVsICE9PSAnJyA/IGAke3RoaXMueUF4aXNMYWJlbH06YCA6ICcnO1xuICAgIGNvbnN0IHggPSBmb3JtYXRMYWJlbChjaXJjbGUueCk7XG4gICAgY29uc3QgeSA9IGZvcm1hdExhYmVsKGNpcmNsZS55KTtcbiAgICBjb25zdCBuYW1lID1cbiAgICAgIGhhc1Nlcmllc05hbWUgJiYgaGFzVG9vbHRpcExhYmVsXG4gICAgICAgID8gYCR7Y2lyY2xlLnNlcmllc05hbWV9IOKAoiAke2NpcmNsZS50b29sdGlwTGFiZWx9YFxuICAgICAgICA6IGNpcmNsZS5zZXJpZXNOYW1lICsgY2lyY2xlLnRvb2x0aXBMYWJlbDtcbiAgICBjb25zdCB0b29sdGlwVGl0bGUgPVxuICAgICAgaGFzU2VyaWVzTmFtZSB8fCBoYXNUb29sdGlwTGFiZWwgPyBgPHNwYW4gY2xhc3M9XCJ0b29sdGlwLWxhYmVsXCI+JHtlc2NhcGVMYWJlbChuYW1lKX08L3NwYW4+YCA6ICcnO1xuXG4gICAgcmV0dXJuIGBcbiAgICAgICR7dG9vbHRpcFRpdGxlfVxuICAgICAgPHNwYW4gY2xhc3M9XCJ0b29sdGlwLWxhYmVsXCI+XG4gICAgICAgIDxsYWJlbD4ke2VzY2FwZUxhYmVsKHhBeGlzTGFiZWwpfTwvbGFiZWw+ICR7ZXNjYXBlTGFiZWwoeCl9PGJyIC8+XG4gICAgICAgIDxsYWJlbD4ke2VzY2FwZUxhYmVsKHlBeGlzTGFiZWwpfTwvbGFiZWw+ICR7ZXNjYXBlTGFiZWwoeSl9XG4gICAgICA8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInRvb2x0aXAtdmFsXCI+XG4gICAgICAgICR7ZXNjYXBlTGFiZWwocmFkaXVzVmFsdWUpfVxuICAgICAgPC9zcGFuPlxuICAgIGA7XG4gIH1cblxuICBvbkNsaWNrKGRhdGEpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdC5lbWl0KGRhdGEpO1xuICB9XG5cbiAgaXNBY3RpdmUoZW50cnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlRW50cmllcykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmFjdGl2ZUVudHJpZXMuZmluZChkID0+IHtcbiAgICAgIHJldHVybiBlbnRyeS5uYW1lID09PSBkLm5hbWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIGl0ZW0gIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlzVmlzaWJsZShjaXJjbGUpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5hY3RpdmVFbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmlzQWN0aXZlKHsgbmFtZTogY2lyY2xlLnNlcmllc05hbWUgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNpcmNsZS5vcGFjaXR5ICE9PSAwO1xuICB9XG5cbiAgYWN0aXZhdGVDaXJjbGUoY2lyY2xlKTogdm9pZCB7XG4gICAgY2lyY2xlLmJhclZpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuYWN0aXZhdGUuZW1pdCh7IG5hbWU6IHRoaXMuZGF0YS5uYW1lIH0pO1xuICB9XG5cbiAgZGVhY3RpdmF0ZUNpcmNsZShjaXJjbGUpOiB2b2lkIHtcbiAgICBjaXJjbGUuYmFyVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuZGVhY3RpdmF0ZS5lbWl0KHsgbmFtZTogdGhpcy5kYXRhLm5hbWUgfSk7XG4gIH1cblxuICB0cmFja0J5KGluZGV4LCBjaXJjbGUpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtjaXJjbGUuZGF0YS5zZXJpZXN9ICR7Y2lyY2xlLmRhdGEubmFtZX1gO1xuICB9XG59XG4iXX0=