@tetacom/svg-charts 1.4.21 → 1.4.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chart/base/series-base.component.d.ts +1 -1
- package/chart/chart/chart.component.d.ts +1 -1
- package/chart/chart-container/annotation/annotation.component.d.ts +1 -1
- package/chart/chart-container/chart-container.component.d.ts +1 -1
- package/chart/chart-container/crosshair/crosshair.component.d.ts +1 -1
- package/chart/chart-container/gridlines/gridlines.component.d.ts +1 -1
- package/chart/chart-container/plotband/plot-band.component.d.ts +1 -1
- package/chart/chart-container/plotline/plotline.component.d.ts +1 -1
- package/chart/chart-container/series/area-series/area-series.component.d.ts +1 -1
- package/chart/chart-container/series/bar/bar-series.component.d.ts +1 -1
- package/chart/chart-container/series/block-area-series/block-area-series.component.d.ts +1 -1
- package/chart/chart-container/series/block-series/block-series.component.d.ts +1 -1
- package/chart/chart-container/series/line/line-series.component.d.ts +1 -1
- package/chart/chart-container/series/linear-series-base.d.ts +1 -1
- package/chart/chart-container/series/scatter-series/scatter-series.component.d.ts +1 -1
- package/chart/chart-container/series-host/series-host.component.d.ts +1 -1
- package/chart/chart-container/tooltip/tooltip.component.d.ts +1 -1
- package/chart/chart-container/x-axis/x-axis.component.d.ts +1 -1
- package/chart/chart-container/y-axis/y-axis.component.d.ts +1 -1
- package/chart/directives/brushable.directive.d.ts +1 -1
- package/chart/directives/draggable-point.directive.d.ts +1 -1
- package/chart/directives/zoomable.directive.d.ts +1 -1
- package/chart/legend/legend.component.d.ts +1 -1
- package/chart/model/i-broadcast-message.d.ts +2 -2
- package/chart/stories/bandseries/bandseries.component.d.ts +1 -1
- package/esm2022/chart/base/series-base.component.mjs +50 -0
- package/esm2022/chart/chart/chart.component.mjs +175 -0
- package/esm2022/chart/chart-container/annotation/annotation.component.mjs +108 -0
- package/esm2022/chart/chart-container/chart-container.component.mjs +194 -0
- package/esm2022/chart/chart-container/crosshair/crosshair.component.mjs +39 -0
- package/esm2022/chart/chart-container/gridlines/gridlines.component.mjs +45 -0
- package/esm2022/chart/chart-container/plotband/plot-band.component.mjs +174 -0
- package/esm2022/chart/chart-container/plotline/plotline.component.mjs +98 -0
- package/esm2022/chart/chart-container/series/area-series/area-series.component.mjs +74 -0
- package/esm2022/chart/chart-container/series/bar/bar-series.component.mjs +68 -0
- package/esm2022/chart/chart-container/series/block-area-series/block-area-series.component.mjs +69 -0
- package/esm2022/chart/chart-container/series/block-series/block-series.component.mjs +69 -0
- package/{esm2020 → esm2022}/chart/chart-container/series/line/line-series.component.mjs +37 -30
- package/esm2022/chart/chart-container/series/linear-series-base.mjs +210 -0
- package/esm2022/chart/chart-container/series/scatter-series/scatter-series.component.mjs +53 -0
- package/esm2022/chart/chart-container/series-host/series-host.component.mjs +50 -0
- package/{esm2020 → esm2022}/chart/chart-container/tooltip/tooltip.component.mjs +18 -5
- package/esm2022/chart/chart-container/x-axis/x-axis.component.mjs +54 -0
- package/esm2022/chart/chart-container/y-axis/y-axis.component.mjs +40 -0
- package/{esm2020 → esm2022}/chart/chart.module.mjs +36 -36
- package/esm2022/chart/core/axis/axis.mjs +135 -0
- package/esm2022/chart/core/axis/builders/axis-size-builder.mjs +31 -0
- package/esm2022/chart/core/axis/builders/extremes-builder.mjs +33 -0
- package/esm2022/chart/directives/brushable.directive.mjs +162 -0
- package/esm2022/chart/directives/draggable-point.directive.mjs +147 -0
- package/esm2022/chart/directives/zoomable.directive.mjs +263 -0
- package/esm2022/chart/legend/legend.component.mjs +38 -0
- package/{esm2020 → esm2022}/chart/model/chart-bounds.mjs +5 -5
- package/esm2022/chart/model/i-broadcast-message.mjs +27 -0
- package/esm2022/chart/model/plot-band.mjs +28 -0
- package/esm2022/chart/model/plot-line.mjs +21 -0
- package/esm2022/chart/service/broadcast.service.mjs +24 -0
- package/esm2022/chart/service/brush.service.mjs +22 -0
- package/esm2022/chart/service/chart.service.mjs +244 -0
- package/esm2022/chart/service/scale.service.mjs +206 -0
- package/esm2022/chart/service/zoom.service.mjs +85 -0
- package/esm2022/chart/stories/bandseries/bandseries.component.mjs +36 -0
- package/{fesm2020 → fesm2022}/tetacom-svg-charts.mjs +584 -338
- package/fesm2022/tetacom-svg-charts.mjs.map +1 -0
- package/package.json +8 -14
- package/esm2020/chart/base/series-base.component.mjs +0 -42
- package/esm2020/chart/chart/chart.component.mjs +0 -172
- package/esm2020/chart/chart-container/annotation/annotation.component.mjs +0 -99
- package/esm2020/chart/chart-container/chart-container.component.mjs +0 -182
- package/esm2020/chart/chart-container/crosshair/crosshair.component.mjs +0 -34
- package/esm2020/chart/chart-container/gridlines/gridlines.component.mjs +0 -37
- package/esm2020/chart/chart-container/plotband/plot-band.component.mjs +0 -163
- package/esm2020/chart/chart-container/plotline/plotline.component.mjs +0 -87
- package/esm2020/chart/chart-container/series/area-series/area-series.component.mjs +0 -67
- package/esm2020/chart/chart-container/series/bar/bar-series.component.mjs +0 -59
- package/esm2020/chart/chart-container/series/block-area-series/block-area-series.component.mjs +0 -60
- package/esm2020/chart/chart-container/series/block-series/block-series.component.mjs +0 -60
- package/esm2020/chart/chart-container/series/linear-series-base.mjs +0 -198
- package/esm2020/chart/chart-container/series/scatter-series/scatter-series.component.mjs +0 -43
- package/esm2020/chart/chart-container/series-host/series-host.component.mjs +0 -46
- package/esm2020/chart/chart-container/x-axis/x-axis.component.mjs +0 -48
- package/esm2020/chart/chart-container/y-axis/y-axis.component.mjs +0 -36
- package/esm2020/chart/core/axis/axis.mjs +0 -128
- package/esm2020/chart/core/axis/builders/axis-size-builder.mjs +0 -33
- package/esm2020/chart/core/axis/builders/extremes-builder.mjs +0 -35
- package/esm2020/chart/directives/brushable.directive.mjs +0 -153
- package/esm2020/chart/directives/draggable-point.directive.mjs +0 -141
- package/esm2020/chart/directives/zoomable.directive.mjs +0 -254
- package/esm2020/chart/legend/legend.component.mjs +0 -36
- package/esm2020/chart/model/i-broadcast-message.mjs +0 -18
- package/esm2020/chart/model/plot-band.mjs +0 -17
- package/esm2020/chart/model/plot-line.mjs +0 -13
- package/esm2020/chart/service/broadcast.service.mjs +0 -23
- package/esm2020/chart/service/brush.service.mjs +0 -21
- package/esm2020/chart/service/chart.service.mjs +0 -229
- package/esm2020/chart/service/scale.service.mjs +0 -203
- package/esm2020/chart/service/zoom.service.mjs +0 -80
- package/esm2020/chart/stories/bandseries/bandseries.component.mjs +0 -29
- package/fesm2015/tetacom-svg-charts.mjs +0 -3095
- package/fesm2015/tetacom-svg-charts.mjs.map +0 -1
- package/fesm2020/tetacom-svg-charts.mjs.map +0 -1
- /package/{esm2020 → esm2022}/chart/chart-container/series/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/core/axis/builders/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/core/utils/generate-ticks.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/core/utils/get-text-width.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/core/utils/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/default/default-axis-config.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/default/default-chart-config.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/default/default-series-config.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/default/defaultSeriesTypeMapping.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/annotation.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/axis-options.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/base-point.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/axis-orientation.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/brush-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/clip-points-direction.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/drag-point-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/fill-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/scale-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/series-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/tooltip-tracking.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/zoom-behavior-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/enum/zoom-type.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-builder.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-chart-config.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-chart-event.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-display-tooltip.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-point-move.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/i-scales-map.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/marker-options.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/series.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/svg-attributes.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/model/tooltip-options.mjs +0 -0
- /package/{esm2020 → esm2022}/chart/service/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/tetacom-svg-charts.mjs +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, HostListener, Input, ViewChild, } from '@angular/core';
|
|
2
|
+
import * as d3 from 'd3';
|
|
3
|
+
import { lastValueFrom, map, take } from 'rxjs';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../../service/scale.service";
|
|
6
|
+
import * as i2 from "../../service/chart.service";
|
|
7
|
+
import * as i3 from "@angular/common";
|
|
8
|
+
export class AnnotationComponent {
|
|
9
|
+
scaleService;
|
|
10
|
+
cdr;
|
|
11
|
+
chartService;
|
|
12
|
+
visibleRect;
|
|
13
|
+
set annotation(annotation) {
|
|
14
|
+
this._annotation = annotation;
|
|
15
|
+
}
|
|
16
|
+
get annotation() {
|
|
17
|
+
return this._annotation;
|
|
18
|
+
}
|
|
19
|
+
set node(node) {
|
|
20
|
+
this._node = node;
|
|
21
|
+
this.init();
|
|
22
|
+
this.cdr.detectChanges();
|
|
23
|
+
}
|
|
24
|
+
get node() {
|
|
25
|
+
return this._node;
|
|
26
|
+
}
|
|
27
|
+
x;
|
|
28
|
+
y;
|
|
29
|
+
drag;
|
|
30
|
+
_annotation;
|
|
31
|
+
_node;
|
|
32
|
+
constructor(scaleService, cdr, chartService) {
|
|
33
|
+
this.scaleService = scaleService;
|
|
34
|
+
this.cdr = cdr;
|
|
35
|
+
this.chartService = chartService;
|
|
36
|
+
this.x = this.scaleService.scales.pipe(map((_) => _.x.get(this.annotation.xAxisIndex ?? 0)?.scale));
|
|
37
|
+
this.y = this.scaleService.scales.pipe(map((_) => _.y.get(this.annotation.yAxisIndex ?? 0)?.scale));
|
|
38
|
+
this.drag = d3.drag();
|
|
39
|
+
}
|
|
40
|
+
click(event) {
|
|
41
|
+
this.chartService.emitAnnotation({
|
|
42
|
+
event,
|
|
43
|
+
target: this.annotation
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
contextMenu(event) {
|
|
47
|
+
this.chartService.emitAnnotation({
|
|
48
|
+
event,
|
|
49
|
+
target: this.annotation
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
ngOnDestroy() {
|
|
53
|
+
this.drag.on('drag end', null);
|
|
54
|
+
}
|
|
55
|
+
init() {
|
|
56
|
+
d3.select(this.node.nativeElement).datum(this.annotation);
|
|
57
|
+
const offsetPx = 10;
|
|
58
|
+
const nodeRect = this.node.nativeElement.getBoundingClientRect();
|
|
59
|
+
if (this.annotation.draggable) {
|
|
60
|
+
this.drag.on('drag end', async (event, d) => {
|
|
61
|
+
const x = await lastValueFrom(this.x.pipe(take(1)));
|
|
62
|
+
const y = await lastValueFrom(this.y.pipe(take(1)));
|
|
63
|
+
d.dx += event.dx;
|
|
64
|
+
d.dy += event.dy;
|
|
65
|
+
// x constraint
|
|
66
|
+
if ((d.dx + x(d.point.x) - offsetPx) <= 0) {
|
|
67
|
+
d.dx = -x(d.point.x) + offsetPx;
|
|
68
|
+
}
|
|
69
|
+
if (d.dx + x(d.point.x) + nodeRect.width - offsetPx >= this.visibleRect.width) {
|
|
70
|
+
d.dx = this.visibleRect.width - x(d.point.x) - nodeRect.width + offsetPx;
|
|
71
|
+
}
|
|
72
|
+
// y constraint
|
|
73
|
+
if ((d.dy + y(d.point.y) - offsetPx) <= 0) {
|
|
74
|
+
d.dy = -y(d.point.y) + offsetPx;
|
|
75
|
+
}
|
|
76
|
+
if (d.dy + y(d.point.y) + nodeRect.height - offsetPx >= this.visibleRect.height) {
|
|
77
|
+
d.dy = Math.abs(y(d.point.y) - this.visibleRect.height) - nodeRect.height + offsetPx;
|
|
78
|
+
}
|
|
79
|
+
this.cdr.detectChanges();
|
|
80
|
+
this.chartService.emitMoveAnnotation({
|
|
81
|
+
event,
|
|
82
|
+
target: d
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
d3.select(this.node.nativeElement).call(this.drag);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: AnnotationComponent, deps: [{ token: i1.ScaleService }, { token: i0.ChangeDetectorRef }, { token: i2.ChartService }], target: i0.ɵɵFactoryTarget.Component });
|
|
89
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.4", type: AnnotationComponent, selector: "[teta-annotation]", inputs: { visibleRect: "visibleRect", annotation: "annotation" }, host: { listeners: { "click": "click($event)", "contextmenu": "contextMenu($event)" } }, viewQueries: [{ propertyName: "node", first: true, predicate: ["annotationNode"], descendants: true }], ngImport: i0, template: "<ng-container *ngIf=\"{\n x: x | async,\n y: y | async\n } as data\">\n <ng-container *ngIf=\"data.x && data.y\">\n\n\n <svg:circle\n [attr.r]=\"annotation.style?.radius ?? 5\"\n [attr.cx]=\"data.x(annotation.point.x)\"\n [attr.fill]=\"annotation?.style?.fill ?? 'var(--color-text-90)'\"\n [attr.cy]=\"data.y(annotation.point.y)\">\n </svg:circle>\n <svg:line\n [attr.x1]=\"data.x(annotation.point.x)\"\n [attr.y1]=\"data.y(annotation.point.y)\"\n [attr.x2]=\"data.x(annotation.point.x) + (annotation.dx ?? 0)\"\n [attr.y2]=\"data.y(annotation.point.y) + (annotation.dy ?? 0)\"\n [attr.stroke]=\"annotation.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"annotation.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"annotation.style?.strokeDasharray ?? null\"\n >\n </svg:line>\n <svg:foreignObject\n class=\"position-absolute\"\n [attr.width]=\"node?.nativeElement.offsetWidth ?? 0\"\n [attr.height]=\"node?.nativeElement.offsetHeight ?? 0\"\n [attr.x]=\"data.x(annotation.point.x) + (annotation.dx ?? 0) - 10\"\n [attr.y]=\"data.y(annotation.point.y) + (annotation.dy ?? 0) - 10\">\n <div\n #annotationNode\n [style.background-color]=\"annotation.style?.fill ?? 'var(--color-global-bgmain)'\"\n [style.cursor]=\"annotation?.draggable ? 'move' : 'default'\"\n [className]=\"'padding-h-2 ' + annotation.className ?? ''\"\n style=\"border-radius: 2px; display: inline-block;\">\n <ng-container *ngIf=\"annotation.template;else default\">\n <ng-container *ngTemplateOutlet=\"annotation.template;context: {$implicit: annotation}\"></ng-container>\n </ng-container>\n </div>\n </svg:foreignObject>\n </ng-container>\n</ng-container>\n<ng-template #default>\n {{ annotation.note?.label}}\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
90
|
+
}
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: AnnotationComponent, decorators: [{
|
|
92
|
+
type: Component,
|
|
93
|
+
args: [{ selector: '[teta-annotation]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n x: x | async,\n y: y | async\n } as data\">\n <ng-container *ngIf=\"data.x && data.y\">\n\n\n <svg:circle\n [attr.r]=\"annotation.style?.radius ?? 5\"\n [attr.cx]=\"data.x(annotation.point.x)\"\n [attr.fill]=\"annotation?.style?.fill ?? 'var(--color-text-90)'\"\n [attr.cy]=\"data.y(annotation.point.y)\">\n </svg:circle>\n <svg:line\n [attr.x1]=\"data.x(annotation.point.x)\"\n [attr.y1]=\"data.y(annotation.point.y)\"\n [attr.x2]=\"data.x(annotation.point.x) + (annotation.dx ?? 0)\"\n [attr.y2]=\"data.y(annotation.point.y) + (annotation.dy ?? 0)\"\n [attr.stroke]=\"annotation.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"annotation.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"annotation.style?.strokeDasharray ?? null\"\n >\n </svg:line>\n <svg:foreignObject\n class=\"position-absolute\"\n [attr.width]=\"node?.nativeElement.offsetWidth ?? 0\"\n [attr.height]=\"node?.nativeElement.offsetHeight ?? 0\"\n [attr.x]=\"data.x(annotation.point.x) + (annotation.dx ?? 0) - 10\"\n [attr.y]=\"data.y(annotation.point.y) + (annotation.dy ?? 0) - 10\">\n <div\n #annotationNode\n [style.background-color]=\"annotation.style?.fill ?? 'var(--color-global-bgmain)'\"\n [style.cursor]=\"annotation?.draggable ? 'move' : 'default'\"\n [className]=\"'padding-h-2 ' + annotation.className ?? ''\"\n style=\"border-radius: 2px; display: inline-block;\">\n <ng-container *ngIf=\"annotation.template;else default\">\n <ng-container *ngTemplateOutlet=\"annotation.template;context: {$implicit: annotation}\"></ng-container>\n </ng-container>\n </div>\n </svg:foreignObject>\n </ng-container>\n</ng-container>\n<ng-template #default>\n {{ annotation.note?.label}}\n</ng-template>\n" }]
|
|
94
|
+
}], ctorParameters: function () { return [{ type: i1.ScaleService }, { type: i0.ChangeDetectorRef }, { type: i2.ChartService }]; }, propDecorators: { visibleRect: [{
|
|
95
|
+
type: Input
|
|
96
|
+
}], annotation: [{
|
|
97
|
+
type: Input
|
|
98
|
+
}], node: [{
|
|
99
|
+
type: ViewChild,
|
|
100
|
+
args: ['annotationNode', { static: false }]
|
|
101
|
+
}], click: [{
|
|
102
|
+
type: HostListener,
|
|
103
|
+
args: ['click', ['$event']]
|
|
104
|
+
}], contextMenu: [{
|
|
105
|
+
type: HostListener,
|
|
106
|
+
args: ['contextmenu', ['$event']]
|
|
107
|
+
}] } });
|
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ub3RhdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY2hhcnQvY2hhcnQtY29udGFpbmVyL2Fubm90YXRpb24vYW5ub3RhdGlvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvY2hhcnQvY2hhcnQtY29udGFpbmVyL2Fubm90YXRpb24vYW5ub3RhdGlvbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDRyxZQUFZLEVBQ3hCLEtBQUssRUFDTCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxFQUFDLGFBQWEsRUFBRSxHQUFHLEVBQWMsSUFBSSxFQUFDLE1BQU0sTUFBTSxDQUFDOzs7OztBQVUxRCxNQUFNLE9BQU8sbUJBQW1CO0lBOEJwQjtJQUNBO0lBQ0E7SUEvQkQsV0FBVyxDQUFVO0lBRTlCLElBQWEsVUFBVSxDQUFDLFVBQXNCO1FBQzVDLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQ0ksSUFBSSxDQUFDLElBQWdCO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNaLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsQ0FBQyxDQUFrQjtJQUNuQixDQUFDLENBQWtCO0lBRVgsSUFBSSxDQUFpQztJQUNyQyxXQUFXLENBQWE7SUFDeEIsS0FB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TUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNwRDtJQUNILENBQUM7dUdBcEdVLG1CQUFtQjsyRkFBbkIsbUJBQW1CLDRUQ25CaEMscTNEQTZDQTs7MkZEMUJhLG1CQUFtQjtrQkFOL0IsU0FBUzsrQkFDRSxtQkFBbUIsbUJBR1osdUJBQXVCLENBQUMsTUFBTTs4SkFHdEMsV0FBVztzQkFBbkIsS0FBSztnQkFFTyxVQUFVO3NCQUF0QixLQUFLO2dCQVNGLElBQUk7c0JBRFAsU0FBUzt1QkFBQyxnQkFBZ0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUM7Z0JBMkJULEtBQUs7c0JBQXZDLFlBQVk7dUJBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQU9RLFdBQVc7c0JBQW5ELFlBQVk7dUJBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsIE9uRGVzdHJveSxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QW5ub3RhdGlvbn0gZnJvbSAnLi4vLi4vbW9kZWwvYW5ub3RhdGlvbic7XG5pbXBvcnQgKiBhcyBkMyBmcm9tICdkMyc7XG5pbXBvcnQge2xhc3RWYWx1ZUZyb20sIG1hcCwgT2JzZXJ2YWJsZSwgdGFrZX0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1NjYWxlU2VydmljZX0gZnJvbSAnLi4vLi4vc2VydmljZS9zY2FsZS5zZXJ2aWNlJztcbmltcG9ydCB7Q2hhcnRTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlL2NoYXJ0LnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdbdGV0YS1hbm5vdGF0aW9uXScsXG4gIHRlbXBsYXRlVXJsOiAnLi9hbm5vdGF0aW9uLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYW5ub3RhdGlvbi5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBBbm5vdGF0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgQElucHV0KCkgdmlzaWJsZVJlY3Q6IERPTVJlY3Q7XG5cbiAgQElucHV0KCkgc2V0IGFubm90YXRpb24oYW5ub3RhdGlvbjogQW5ub3RhdGlvbikge1xuICAgIHRoaXMuX2Fubm90YXRpb24gPSBhbm5vdGF0aW9uO1xuICB9XG5cbiAgZ2V0IGFubm90YXRpb24oKTogQW5ub3RhdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Fubm90YXRpb247XG4gIH1cblxuICBAVmlld0NoaWxkKCdhbm5vdGF0aW9uTm9kZScsIHtzdGF0aWM6IGZhbHNlfSlcbiAgc2V0IG5vZGUobm9kZTogRWxlbWVudFJlZikge1xuICAgIHRoaXMuX25vZGUgPSBub2RlO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIGdldCBub2RlKCkge1xuICAgIHJldHVybiB0aGlzLl9ub2RlO1xuICB9XG5cbiAgeDogT2JzZXJ2YWJsZTxhbnk+O1xuICB5OiBPYnNlcnZhYmxlPGFueT47XG5cbiAgcHJpdmF0ZSBkcmFnOiBkMy5EcmFnQmVoYXZpb3I8YW55LCBhbnksIGFueT47XG4gIHByaXZhdGUgX2Fubm90YXRpb246IEFubm90YXRpb247XG4gIHByaXZhdGUgX25vZGU6IEVsZW1lbnRSZWY7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzY2FsZVNlcnZpY2U6IFNjYWxlU2VydmljZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBjaGFydFNlcnZpY2U6IENoYXJ0U2VydmljZSkge1xuICAgIHRoaXMueCA9IHRoaXMuc2NhbGVTZXJ2aWNlLnNjYWxlcy5waXBlKG1hcCgoXykgPT4gXy54LmdldCh0aGlzLmFubm90YXRpb24ueEF4aXNJbmRleCA/PyAwKT8uc2NhbGUpKTtcbiAgICB0aGlzLnkgPSB0aGlzLnNjYWxlU2VydmljZS5zY2FsZXMucGlwZShtYXAoKF8pID0+IF8ueS5nZXQodGhpcy5hbm5vdGF0aW9uLnlBeGlzSW5kZXggPz8gMCk/LnNjYWxlKSk7XG4gICAgdGhpcy5kcmFnID0gZDMuZHJhZygpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snLCBbJyRldmVudCddKSBjbGljayhldmVudDogTW91c2VFdmVudCkge1xuICAgIHRoaXMuY2hhcnRTZXJ2aWNlLmVtaXRBbm5vdGF0aW9uKHtcbiAgICAgIGV2ZW50LFxuICAgICAgdGFyZ2V0OiB0aGlzLmFubm90YXRpb25cbiAgICB9KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgWyckZXZlbnQnXSkgY29udGV4dE1lbnUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLmNoYXJ0U2VydmljZS5lbWl0QW5ub3RhdGlvbih7XG4gICAgICBldmVudCxcbiAgICAgIHRhcmdldDogdGhpcy5hbm5vdGF0aW9uXG4gICAgfSk7XG4gIH1cblxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZHJhZy5vbignZHJhZyBlbmQnLCBudWxsKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdCgpIHtcblxuICAgIGQzLnNlbGVjdCh0aGlzLm5vZGUubmF0aXZlRWxlbWVudCkuZGF0dW0odGhpcy5hbm5vdGF0aW9uKTtcblxuICAgIGNvbnN0IG9mZnNldFB4ID0gMTA7XG4gICAgY29uc3Qgbm9kZVJlY3QgPSB0aGlzLm5vZGUubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGlmICh0aGlzLmFubm90YXRpb24uZHJhZ2dhYmxlKSB7XG4gICAgICB0aGlzLmRyYWcub24oJ2RyYWcgZW5kJywgYXN5bmMgKGV2ZW50LCBkOiBBbm5vdGF0aW9uKSA9PiB7XG5cbiAgICAgICAgY29uc3QgeCA9IGF3YWl0IGxhc3RWYWx1ZUZyb20odGhpcy54LnBpcGUodGFrZSgxKSkpO1xuICAgICAgICBjb25zdCB5ID0gYXdhaXQgbGFzdFZhbHVlRnJvbSh0aGlzLnkucGlwZSh0YWtlKDEpKSk7XG5cbiAgICAgICAgZC5keCArPSBldmVudC5keDtcbiAgICAgICAgZC5keSArPSBldmVudC5keTtcblxuICAgICAgICAvLyB4IGNvbnN0cmFpbnRcbiAgICAgICAgaWYgKChkLmR4ICsgeChkLnBvaW50LngpIC0gb2Zmc2V0UHgpIDw9IDApIHtcbiAgICAgICAgICBkLmR4ID0gLXgoZC5wb2ludC54KSArIG9mZnNldFB4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGQuZHggKyB4KGQucG9pbnQueCkgKyBub2RlUmVjdC53aWR0aCAtIG9mZnNldFB4ID49IHRoaXMudmlzaWJsZVJlY3Qud2lkdGgpIHtcbiAgICAgICAgICBkLmR4ID0gdGhpcy52aXNpYmxlUmVjdC53aWR0aCAtIHgoZC5wb2ludC54KSAtIG5vZGVSZWN0LndpZHRoICsgb2Zmc2V0UHg7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB5IGNvbnN0cmFpbnRcbiAgICAgICAgaWYgKChkLmR5ICsgeShkLnBvaW50LnkpIC0gb2Zmc2V0UHgpIDw9IDApIHtcbiAgICAgICAgICBkLmR5ID0gLXkoZC5wb2ludC55KSArIG9mZnNldFB4O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGQuZHkgKyB5KGQucG9pbnQueSkgKyBub2RlUmVjdC5oZWlnaHQgLSBvZmZzZXRQeCA+PSB0aGlzLnZpc2libGVSZWN0LmhlaWdodCkge1xuICAgICAgICAgIGQuZHkgPSBNYXRoLmFicyh5KGQucG9pbnQueSkgLSB0aGlzLnZpc2libGVSZWN0LmhlaWdodCkgLSBub2RlUmVjdC5oZWlnaHQgK29mZnNldFB4O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB0aGlzLmNoYXJ0U2VydmljZS5lbWl0TW92ZUFubm90YXRpb24oe1xuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIHRhcmdldDogZFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkMy5zZWxlY3QodGhpcy5ub2RlLm5hdGl2ZUVsZW1lbnQpLmNhbGwodGhpcy5kcmFnKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCJ7XG4gICAgICB4OiB4IHwgYXN5bmMsXG4gICAgICB5OiB5IHwgYXN5bmNcbiAgICB9IGFzIGRhdGFcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGEueCAmJiBkYXRhLnlcIj5cblxuXG4gICAgPHN2ZzpjaXJjbGVcbiAgICAgIFthdHRyLnJdPVwiYW5ub3RhdGlvbi5zdHlsZT8ucmFkaXVzID8/IDVcIlxuICAgICAgW2F0dHIuY3hdPVwiZGF0YS54KGFubm90YXRpb24ucG9pbnQueClcIlxuICAgICAgW2F0dHIuZmlsbF09XCJhbm5vdGF0aW9uPy5zdHlsZT8uZmlsbCA/PyAndmFyKC0tY29sb3ItdGV4dC05MCknXCJcbiAgICAgIFthdHRyLmN5XT1cImRhdGEueShhbm5vdGF0aW9uLnBvaW50LnkpXCI+XG4gICAgPC9zdmc6Y2lyY2xlPlxuICAgIDxzdmc6bGluZVxuICAgICAgW2F0dHIueDFdPVwiZGF0YS54KGFubm90YXRpb24ucG9pbnQueClcIlxuICAgICAgW2F0dHIueTFdPVwiZGF0YS55KGFubm90YXRpb24ucG9pbnQueSlcIlxuICAgICAgW2F0dHIueDJdPVwiZGF0YS54KGFubm90YXRpb24ucG9pbnQueCkgKyAoYW5ub3RhdGlvbi5keCA/PyAwKVwiXG4gICAgICBbYXR0ci55Ml09XCJkYXRhLnkoYW5ub3RhdGlvbi5wb2ludC55KSArIChhbm5vdGF0aW9uLmR5ID8/IDApXCJcbiAgICAgIFthdHRyLnN0cm9rZV09XCJhbm5vdGF0aW9uLnN0eWxlPy5zdHJva2UgPz8gJ3ZhcigtLWNvbG9yLXRleHQtOTApJ1wiXG4gICAgICBbYXR0ci5zdHJva2Utd2lkdGhdPVwiYW5ub3RhdGlvbi5zdHlsZT8uc3Ryb2tlV2lkdGggPz8gMVwiXG4gICAgICBbYXR0ci5zdHJva2UtZGFzaGFycmF5XT1cImFubm90YXRpb24uc3R5bGU/LnN0cm9rZURhc2hhcnJheSA/PyBudWxsXCJcbiAgICA+XG4gICAgPC9zdmc6bGluZT5cbiAgICA8c3ZnOmZvcmVpZ25PYmplY3RcbiAgICAgIGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGVcIlxuICAgICAgW2F0dHIud2lkdGhdPVwibm9kZT8ubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCA/PyAwXCJcbiAgICAgIFthdHRyLmhlaWdodF09XCJub2RlPy5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodCA/PyAwXCJcbiAgICAgIFthdHRyLnhdPVwiZGF0YS54KGFubm90YXRpb24ucG9pbnQueCkgKyAoYW5ub3RhdGlvbi5keCA/PyAwKSAtIDEwXCJcbiAgICAgIFthdHRyLnldPVwiZGF0YS55KGFubm90YXRpb24ucG9pbnQueSkgKyAoYW5ub3RhdGlvbi5keSA/PyAwKSAtIDEwXCI+XG4gICAgICA8ZGl2XG4gICAgICAgICNhbm5vdGF0aW9uTm9kZVxuICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJhbm5vdGF0aW9uLnN0eWxlPy5maWxsID8/ICd2YXIoLS1jb2xvci1nbG9iYWwtYmdtYWluKSdcIlxuICAgICAgICBbc3R5bGUuY3Vyc29yXT1cImFubm90YXRpb24/LmRyYWdnYWJsZSA/ICdtb3ZlJyA6ICdkZWZhdWx0J1wiXG4gICAgICAgIFtjbGFzc05hbWVdPVwiJ3BhZGRpbmctaC0yICcgKyBhbm5vdGF0aW9uLmNsYXNzTmFtZSA/PyAnJ1wiXG4gICAgICAgIHN0eWxlPVwiYm9yZGVyLXJhZGl1czogMnB4OyBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhbm5vdGF0aW9uLnRlbXBsYXRlO2Vsc2UgZGVmYXVsdFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJhbm5vdGF0aW9uLnRlbXBsYXRlO2NvbnRleHQ6IHskaW1wbGljaXQ6IGFubm90YXRpb259XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9zdmc6Zm9yZWlnbk9iamVjdD5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbjxuZy10ZW1wbGF0ZSAjZGVmYXVsdD5cbiAge3sgYW5ub3RhdGlvbi5ub3RlPy5sYWJlbH19XG48L25nLXRlbXBsYXRlPlxuIl19
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, } from '@angular/core';
|
|
2
|
+
import { animationFrameScheduler, combineLatest, map, observeOn, shareReplay, withLatestFrom, } from 'rxjs';
|
|
3
|
+
import { AxisOrientation } from '../model/enum/axis-orientation';
|
|
4
|
+
import { BrushType } from '../model/enum/brush-type';
|
|
5
|
+
import { ZoomType } from '../model/enum/zoom-type';
|
|
6
|
+
import { tetaZoneFull } from '@tetacom/ng-components';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "../service/chart.service";
|
|
9
|
+
import * as i2 from "../service/scale.service";
|
|
10
|
+
import * as i3 from "../service/zoom.service";
|
|
11
|
+
import * as i4 from "@angular/common";
|
|
12
|
+
import * as i5 from "./series-host/series-host.component";
|
|
13
|
+
import * as i6 from "./gridlines/gridlines.component";
|
|
14
|
+
import * as i7 from "./x-axis/x-axis.component";
|
|
15
|
+
import * as i8 from "./y-axis/y-axis.component";
|
|
16
|
+
import * as i9 from "./plotline/plotline.component";
|
|
17
|
+
import * as i10 from "./plotband/plot-band.component";
|
|
18
|
+
import * as i11 from "./tooltip/tooltip.component";
|
|
19
|
+
import * as i12 from "../directives/zoomable.directive";
|
|
20
|
+
import * as i13 from "../directives/brushable.directive";
|
|
21
|
+
import * as i14 from "./annotation/annotation.component";
|
|
22
|
+
import * as i15 from "./crosshair/crosshair.component";
|
|
23
|
+
export class ChartContainerComponent {
|
|
24
|
+
_svc;
|
|
25
|
+
_cdr;
|
|
26
|
+
_scaleService;
|
|
27
|
+
_zoomService;
|
|
28
|
+
_elementRef;
|
|
29
|
+
_zone;
|
|
30
|
+
config;
|
|
31
|
+
scales;
|
|
32
|
+
size;
|
|
33
|
+
visibleRect;
|
|
34
|
+
brushScale;
|
|
35
|
+
zoomType = ZoomType;
|
|
36
|
+
_observer;
|
|
37
|
+
filterPositionMap = new Map()
|
|
38
|
+
.set(true, (axis) => (_) => _.options.opposite && _.options.visible && axis.index <= _.index)
|
|
39
|
+
.set(false, (axis) => (_) => _.options.opposite !== true &&
|
|
40
|
+
_.options.visible &&
|
|
41
|
+
_.index <= axis.index);
|
|
42
|
+
constructor(_svc, _cdr, _scaleService, _zoomService, _elementRef, _zone) {
|
|
43
|
+
this._svc = _svc;
|
|
44
|
+
this._cdr = _cdr;
|
|
45
|
+
this._scaleService = _scaleService;
|
|
46
|
+
this._zoomService = _zoomService;
|
|
47
|
+
this._elementRef = _elementRef;
|
|
48
|
+
this._zone = _zone;
|
|
49
|
+
this.config = this._svc.config;
|
|
50
|
+
this.size = this._svc.size;
|
|
51
|
+
this.scales = this._scaleService.scales.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
|
|
52
|
+
bufferSize: 1,
|
|
53
|
+
refCount: true,
|
|
54
|
+
}));
|
|
55
|
+
this.brushScale = this._scaleService.scales.pipe(withLatestFrom(this.config), map((data) => {
|
|
56
|
+
const [{ x, y }, config] = data;
|
|
57
|
+
return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0)?.scale : y.get(0)?.scale;
|
|
58
|
+
}), shareReplay({
|
|
59
|
+
bufferSize: 1,
|
|
60
|
+
refCount: true,
|
|
61
|
+
}));
|
|
62
|
+
this.visibleRect = combineLatest([this.size, this.scales, this.config])
|
|
63
|
+
.pipe(map((data) => {
|
|
64
|
+
const [size, { x, y }, config] = data;
|
|
65
|
+
const yAxesArray = Array.from(y.values());
|
|
66
|
+
const xAxesArray = Array.from(x.values());
|
|
67
|
+
const left = yAxesArray
|
|
68
|
+
.filter((_) => _.options.opposite !== true && _.options.visible)
|
|
69
|
+
.reduce(this.sumSize, 0);
|
|
70
|
+
const right = yAxesArray
|
|
71
|
+
.filter((_) => _.options.opposite && _.options.visible)
|
|
72
|
+
.reduce(this.sumSize, 0);
|
|
73
|
+
const bottom = xAxesArray
|
|
74
|
+
.filter((_) => _.options.opposite !== true && _.options.visible)
|
|
75
|
+
.reduce(this.sumSize, 0);
|
|
76
|
+
const top = xAxesArray
|
|
77
|
+
.filter((_) => _.options.opposite && _.options.visible)
|
|
78
|
+
.reduce(this.sumSize, 0);
|
|
79
|
+
return {
|
|
80
|
+
x: left + config.bounds?.left,
|
|
81
|
+
y: top + config.bounds?.top,
|
|
82
|
+
width: size.width -
|
|
83
|
+
left -
|
|
84
|
+
right -
|
|
85
|
+
config.bounds?.left -
|
|
86
|
+
config.bounds?.right,
|
|
87
|
+
height: size.height -
|
|
88
|
+
top -
|
|
89
|
+
bottom -
|
|
90
|
+
config.bounds?.top -
|
|
91
|
+
config.bounds?.bottom,
|
|
92
|
+
};
|
|
93
|
+
}), tetaZoneFull(this._zone), shareReplay({
|
|
94
|
+
bufferSize: 1,
|
|
95
|
+
refCount: true,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
ngOnInit() {
|
|
99
|
+
}
|
|
100
|
+
ngAfterViewInit() {
|
|
101
|
+
this._observer = new ResizeObserver((entries) => {
|
|
102
|
+
requestAnimationFrame(() => {
|
|
103
|
+
if (!Array.isArray(entries) ||
|
|
104
|
+
!entries.length ||
|
|
105
|
+
entries[0].contentRect.width <= 0 ||
|
|
106
|
+
entries[0].contentRect.height <= 0) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this._svc.setSize(entries[0].contentRect);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
this._observer.observe(this._elementRef.nativeElement);
|
|
113
|
+
}
|
|
114
|
+
ngOnDestroy() {
|
|
115
|
+
this._observer.unobserve(this._elementRef.nativeElement);
|
|
116
|
+
this._observer.disconnect();
|
|
117
|
+
}
|
|
118
|
+
sumSize = (acc, curr) => acc + curr.selfSize;
|
|
119
|
+
getTranslate(axis, size) {
|
|
120
|
+
return this.scales.pipe(withLatestFrom(this.config), map((data) => {
|
|
121
|
+
const [{ x, y }, config] = data;
|
|
122
|
+
const xAxesArray = Array.from(x.values());
|
|
123
|
+
const yAxesArray = Array.from(y.values());
|
|
124
|
+
const oppositeFilter = this.filterPositionMap.get(true);
|
|
125
|
+
const nonOppositeFilter = this.filterPositionMap.get(false);
|
|
126
|
+
const oppositeOffsetY = yAxesArray.filter(oppositeFilter(axis));
|
|
127
|
+
const nonOppositeOffsetY = yAxesArray.filter(nonOppositeFilter(axis));
|
|
128
|
+
const oppositeOffsetX = xAxesArray.filter(oppositeFilter(axis));
|
|
129
|
+
const nonOppositeOffsetX = xAxesArray.filter(nonOppositeFilter(axis));
|
|
130
|
+
const oppositeTranslateY = oppositeOffsetY.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.right);
|
|
131
|
+
const nonOppisteTranslateY = nonOppositeOffsetY.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.left);
|
|
132
|
+
const oppositeTranslateX = oppositeOffsetX.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.top);
|
|
133
|
+
const nonOppisteTranslateX = nonOppositeOffsetX.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.bottom);
|
|
134
|
+
const left = yAxesArray
|
|
135
|
+
.filter((_) => _.options.visible && _.options.opposite !== true)
|
|
136
|
+
.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.left);
|
|
137
|
+
const top = xAxesArray
|
|
138
|
+
.filter((_) => _.options.visible && _.options.opposite === true)
|
|
139
|
+
.reduce((acc, curr) => acc + curr.selfSize, config.bounds?.top);
|
|
140
|
+
if (axis.orientation === AxisOrientation.x) {
|
|
141
|
+
return `translate(${left}, ${axis.options.opposite
|
|
142
|
+
? oppositeTranslateX
|
|
143
|
+
: size.height - nonOppisteTranslateX})`;
|
|
144
|
+
}
|
|
145
|
+
if (axis.orientation === AxisOrientation.y) {
|
|
146
|
+
return `translate(${axis.options.opposite
|
|
147
|
+
? size.width - oppositeTranslateY
|
|
148
|
+
: nonOppisteTranslateY}, ${top})`;
|
|
149
|
+
}
|
|
150
|
+
return 'translate(0, 0)';
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
identify(index, item) {
|
|
154
|
+
return item.value.index;
|
|
155
|
+
}
|
|
156
|
+
click(event, xScales, yScales) {
|
|
157
|
+
const x = xScales.get(0)?.scale;
|
|
158
|
+
const y = yScales.get(0)?.scale;
|
|
159
|
+
this._svc.emitChartClick({
|
|
160
|
+
event: event,
|
|
161
|
+
target: {
|
|
162
|
+
x: x.invert(event.offsetX),
|
|
163
|
+
y: y.invert(event.offsetY),
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
contextMenu(event, xScales, yScales) {
|
|
168
|
+
const x = xScales.get(0)?.scale;
|
|
169
|
+
const y = yScales.get(0)?.scale;
|
|
170
|
+
this._svc.emitChartContextMenu({
|
|
171
|
+
event: event,
|
|
172
|
+
target: {
|
|
173
|
+
x: x.invert(event.offsetX),
|
|
174
|
+
y: y.invert(event.offsetY),
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
mouseMove(event) {
|
|
179
|
+
this._svc.setPointerMove(event);
|
|
180
|
+
}
|
|
181
|
+
mouseLeave(event) {
|
|
182
|
+
this._svc.setPointerMove(event);
|
|
183
|
+
}
|
|
184
|
+
trackSerie(index, item) {
|
|
185
|
+
return item.name?.length ? item.name : index;
|
|
186
|
+
}
|
|
187
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: ChartContainerComponent, deps: [{ token: i1.ChartService }, { token: i0.ChangeDetectorRef }, { token: i2.ScaleService }, { token: i3.ZoomService }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
188
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.4", type: ChartContainerComponent, selector: "teta-chart-container", ngImport: i0, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n scales: scales | async,\n visibleRect: visibleRect | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.size?.height > 0\n && data.size?.width > 0\n && data.visibleRect?.height > 0\n && data.visibleRect?.width > 0\n && data.scales?.x.size === data.config.xAxis.length\n && data.scales?.y.size === data.config.yAxis.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.y | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.selfSize > 0\n && item.value.options.visible\n && data.scales.x.size > 0\n && data.scales.y.size > 0\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.x | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x.size > 0 && data.scales.y.size > 0\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container\n *ngIf=\"data.size?.height > 0\n && data.size?.width > 0\n && data.visibleRect?.height > 0\n && data.visibleRect?.width > 0\n && data.scales?.x.size === data.config.xAxis.length\n && data.scales?.y.size === data.config.yAxis.length\">\n <svg\n tetaZoomable\n tetaBrushable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.scales.x.get(0) : data.scales.y.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.scales.x, data.scales.y)\"\n (click)=\"click($event, data.scales.x, data.scales.y)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.scales.x.get(i).scale\"\n [size]=\"data.visibleRect\"\n [axis]=\"data.scales.x.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.scales.y.get(i).scale\"\n [size]=\"data.visibleRect\"\n [axis]=\"data.scales.y.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.y.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series;\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n [visibleRect]=\"data.visibleRect\"\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i5.SeriesHostComponent, selector: "[teta-series-host]", inputs: ["config", "series"] }, { kind: "component", type: i6.GridlinesComponent, selector: "[teta-gridlines]", inputs: ["size"] }, { kind: "component", type: i7.XAxisComponent, selector: "[teta-x-axis]", inputs: ["axis", "size"] }, { kind: "component", type: i8.YAxisComponent, selector: "[teta-y-axis]", inputs: ["axis", "size"] }, { kind: "component", type: i9.PlotlineComponent, selector: "[teta-plot-line]", inputs: ["plotLine", "size", "axis", "scale"] }, { kind: "component", type: i10.PlotBandComponent, selector: "[teta-plot-band]", inputs: ["plotBand", "axis", "scale", "size"] }, { kind: "component", type: i11.TooltipComponent, selector: "teta-tooltip", inputs: ["size", "config"] }, { kind: "directive", type: i12.ZoomableDirective, selector: "[tetaZoomable]", inputs: ["config", "axis", "size"] }, { kind: "directive", type: i13.BrushableDirective, selector: "[tetaBrushable]", inputs: ["config", "axis"] }, { kind: "component", type: i14.AnnotationComponent, selector: "[teta-annotation]", inputs: ["visibleRect", "annotation"] }, { kind: "component", type: i15.CrosshairComponent, selector: "[teta-crosshair]", inputs: ["size"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
189
|
+
}
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: ChartContainerComponent, decorators: [{
|
|
191
|
+
type: Component,
|
|
192
|
+
args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n scales: scales | async,\n visibleRect: visibleRect | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.size?.height > 0\n && data.size?.width > 0\n && data.visibleRect?.height > 0\n && data.visibleRect?.width > 0\n && data.scales?.x.size === data.config.xAxis.length\n && data.scales?.y.size === data.config.yAxis.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.y | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.selfSize > 0\n && item.value.options.visible\n && data.scales.x.size > 0\n && data.scales.y.size > 0\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.x | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x.size > 0 && data.scales.y.size > 0\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container\n *ngIf=\"data.size?.height > 0\n && data.size?.width > 0\n && data.visibleRect?.height > 0\n && data.visibleRect?.width > 0\n && data.scales?.x.size === data.config.xAxis.length\n && data.scales?.y.size === data.config.yAxis.length\">\n <svg\n tetaZoomable\n tetaBrushable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.scales.x.get(0) : data.scales.y.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.scales.x, data.scales.y)\"\n (click)=\"click($event, data.scales.x, data.scales.y)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.scales.x.get(i).scale\"\n [size]=\"data.visibleRect\"\n [axis]=\"data.scales.x.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.scales.y.get(i).scale\"\n [size]=\"data.visibleRect\"\n [axis]=\"data.scales.y.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.y.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series;\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n [visibleRect]=\"data.visibleRect\"\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"] }]
|
|
193
|
+
}], ctorParameters: function () { return [{ type: i1.ChartService }, { type: i0.ChangeDetectorRef }, { type: i2.ScaleService }, { type: i3.ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
|
|
194
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQtY29udGFpbmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jaGFydC9jaGFydC1jb250YWluZXIvY2hhcnQtY29udGFpbmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3NyYy9jaGFydC9jaGFydC1jb250YWluZXIvY2hhcnQtY29udGFpbmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxHQUtWLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsYUFBYSxFQUNiLEdBQUcsRUFDUyxTQUFTLEVBQ3JCLFdBQVcsRUFDWCxjQUFjLEdBQ2YsTUFBTSxNQUFNLENBQUM7QUFFZCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFHL0QsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBYXBELE1BQU0sT0FBTyx1QkFBdUI7SUF5QnhCO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQTdCVixNQUFNLENBQTJCO0lBQ2pDLE1BQU0sQ0FBeUI7SUFDL0IsSUFBSSxDQUFzQjtJQUMxQixXQUFXLENBQWtCO0lBQzdCLFVBQVUsQ0FBa0I7SUFDNUIsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUVaLFNBQVMsQ0FBaUI7SUFDMUIsaUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQ007U0FDdEMsR0FBRyxDQUNGLElBQUksRUFDSixDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFPLEVBQUUsRUFBRSxDQUNwQixDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxD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QkFBdUI7a0JBTm5DLFNBQVM7K0JBQ0Usc0JBQXNCLG1CQUdmLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0lDaGFydENvbmZpZ30gZnJvbSAnLi4vbW9kZWwvaS1jaGFydC1jb25maWcnO1xuaW1wb3J0IHtDaGFydFNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2UvY2hhcnQuc2VydmljZSc7XG5pbXBvcnQge1xuICBhbmltYXRpb25GcmFtZVNjaGVkdWxlcixcbiAgY29tYmluZUxhdGVzdCxcbiAgbWFwLFxuICBPYnNlcnZhYmxlLCBvYnNlcnZlT24sXG4gIHNoYXJlUmVwbGF5LFxuICB3aXRoTGF0ZXN0RnJvbSxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0F4aXN9IGZyb20gJy4uL2NvcmUvYXhpcy9heGlzJztcbmltcG9ydCB7QXhpc09yaWVudGF0aW9ufSBmcm9tICcuLi9tb2RlbC9lbnVtL2F4aXMtb3JpZW50YXRpb24nO1xuaW1wb3J0IHtTY2FsZVNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2Uvc2NhbGUuc2VydmljZSc7XG5pbXBvcnQge1pvb21TZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlL3pvb20uc2VydmljZSc7XG5pbXBvcnQge0JydXNoVHlwZX0gZnJvbSAnLi4vbW9kZWwvZW51bS9icnVzaC10eXBlJztcbmltcG9ydCB7Wm9vbVR5cGV9IGZyb20gJy4uL21vZGVsL2VudW0vem9vbS10eXBlJztcbmltcG9ydCB7dGV0YVpvbmVGdWxsfSBmcm9tICdAdGV0YWNvbS9uZy1jb21wb25lbnRzJztcbmltcG9ydCB7SVNjYWxlc01hcH0gZnJvbSAnLi4vbW9kZWwvaS1zY2FsZXMtbWFwJztcbmltcG9ydCB7U2VyaWVzfSBmcm9tIFwiLi4vbW9kZWwvc2VyaWVzXCI7XG5pbXBvcnQge0Jhc2VQb2ludH0gZnJvbSBcIi4uL21vZGVsL2Jhc2UtcG9pbnRcIjtcblxudHlwZSBPcHBvc2l0ZSA9IGJvb2xlYW47XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RldGEtY2hhcnQtY29udGFpbmVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NoYXJ0LWNvbnRhaW5lci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXJ0LWNvbnRhaW5lci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQ2hhcnRDb250YWluZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGNvbmZpZzogT2JzZXJ2YWJsZTxJQ2hhcnRDb25maWc+O1xuICBzY2FsZXM6IE9ic2VydmFibGU8SVNjYWxlc01hcD47XG4gIHNpemU6IE9ic2VydmFibGU8RE9NUmVjdD47XG4gIHZpc2libGVSZWN0OiBPYnNlcnZhYmxlPGFueT47XG4gIGJydXNoU2NhbGU6IE9ic2VydmFibGU8YW55PjtcbiAgem9vbVR5cGUgPSBab29tVHlwZTtcblxuICBwcml2YXRlIF9vYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXI7XG4gIHByaXZhdGUgZmlsdGVyUG9zaXRpb25NYXAgPSBuZXcgTWFwPE9wcG9zaXRlLFxuICAgIChheGlzOiBBeGlzKSA9PiAoXzogQXhpcykgPT4gYm9vbGVhbj4oKVxuICAgIC5zZXQoXG4gICAgICB0cnVlLFxuICAgICAgKGF4aXMpID0+IChfOiBBeGlzKSA9PlxuICAgICAgICBfLm9wdGlvbnMub3Bwb3NpdGUgJiYgXy5vcHRpb25zLnZpc2libGUgJiYgYXhpcy5pbmRleCA8PSBfLmluZGV4XG4gICAgKVxuICAgIC5zZXQoXG4gICAgICBmYWxzZSxcbiAgICAgIChheGlzKSA9PiAoXzogQXhpcykgPT5cbiAgICAgICAgXy5vcHRpb25zLm9wcG9zaXRlICE9PSB0cnVlICYmXG4gICAgICAgIF8ub3B0aW9ucy52aXNpYmxlICYmXG4gICAgICAgIF8uaW5kZXggPD0gYXhpcy5pbmRleFxuICAgICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfc3ZjOiBDaGFydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIF9zY2FsZVNlcnZpY2U6IFNjYWxlU2VydmljZSxcbiAgICBwcml2YXRlIF96b29tU2VydmljZTogWm9vbVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIF96b25lOiBOZ1pvbmVcbiAgKSB7XG4gICAgdGhpcy5jb25maWcgPSB0aGlzLl9zdmMuY29uZmlnO1xuICAgIHRoaXMuc2l6ZSA9IHRoaXMuX3N2Yy5zaXplO1xuXG4gICAgdGhpcy5zY2FsZXMgPSB0aGlzLl9zY2FsZVNlcnZpY2Uuc2NhbGVzLnBpcGUoXG4gICAgICBvYnNlcnZlT24oYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIpLFxuICAgICAgdGV0YVpvbmVGdWxsKHRoaXMuX3pvbmUpLFxuICAgICAgc2hhcmVSZXBsYXkoe1xuICAgICAgICBidWZmZXJTaXplOiAxLFxuICAgICAgICByZWZDb3VudDogdHJ1ZSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuYnJ1c2hTY2FsZSA9IHRoaXMuX3NjYWxlU2VydmljZS5zY2FsZXMucGlwZShcbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuY29uZmlnKSxcbiAgICAgIG1hcCgoZGF0YTogW0lTY2FsZXNNYXAsIElDaGFydENvbmZpZ10pID0+IHtcbiAgICAgICAgY29uc3QgW3t4LCB5fSwgY29uZmlnXSA9IGRhdGE7XG5cbiAgICAgICAgcmV0dXJuIGNvbmZpZy5icnVzaD8udHlwZSA9PT0gQnJ1c2hUeXBlLnggfHwgY29uZmlnPy56b29tPy50eXBlID09PSBab29tVHlwZS54ID8geC5nZXQoMCk/LnNjYWxlIDogeS5nZXQoMCk/LnNjYWxlO1xuICAgICAgfSksXG4gICAgICBzaGFyZVJlcGxheSh7XG4gICAgICAgIGJ1ZmZlclNpemU6IDEsXG4gICAgICAgIHJlZkNvdW50OiB0cnVlLFxuICAgICAgfSlcbiAgICApO1xuXG5cbiAgICB0aGlzLnZpc2libGVSZWN0ID0gY29tYmluZUxhdGVzdChbdGhpcy5zaXplLCB0aGlzLnNjYWxlcywgdGhpcy5jb25maWddKVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcChcbiAgICAgICAgICAoXG4gICAgICAgICAgICBkYXRhOiBbRE9NUmVjdCwgSVNjYWxlc01hcCwgSUNoYXJ0Q29uZmlnXVxuICAgICAgICAgICkgPT4ge1xuICAgICAgICAgICAgY29uc3QgW3NpemUsIHt4LCB5fSwgY29uZmlnXSA9IGRhdGE7XG4gICAgICAgICAgICBjb25zdCB5QXhlc0FycmF5ID0gQXJyYXkuZnJvbSh5LnZhbHVlcygpKTtcbiAgICAgICAgICAgIGNvbnN0IHhBeGVzQXJyYXkgPSBBcnJheS5mcm9tKHgudmFsdWVzKCkpO1xuICAgICAgICAgICAgY29uc3QgbGVmdCA9IHlBeGVzQXJyYXlcbiAgICAgICAgICAgICAgLmZpbHRlcigoXykgPT4gXy5vcHRpb25zLm9wcG9zaXRlICE9PSB0cnVlICYmIF8ub3B0aW9ucy52aXNpYmxlKVxuICAgICAgICAgICAgICAucmVkdWNlKHRoaXMuc3VtU2l6ZSwgMCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0ID0geUF4ZXNBcnJheVxuICAgICAgICAgICAgICAuZmlsdGVyKChfKSA9PiBfLm9wdGlvbnMub3Bwb3NpdGUgJiYgXy5vcHRpb25zLnZpc2libGUpXG4gICAgICAgICAgICAgIC5yZWR1Y2UodGhpcy5zdW1TaXplLCAwKTtcblxuICAgICAgICAgICAgY29uc3QgYm90dG9tID0geEF4ZXNBcnJheVxuICAgICAgICAgICAgICAuZmlsdGVyKChfKSA9PiBfLm9wdGlvbnMub3Bwb3NpdGUgIT09IHRydWUgJiYgXy5vcHRpb25zLnZpc2libGUpXG4gICAgICAgICAgICAgIC5yZWR1Y2UodGhpcy5zdW1TaXplLCAwKTtcblxuICAgICAgICAgICAgY29uc3QgdG9wID0geEF4ZXNBcnJheVxuICAgICAgICAgICAgICAuZmlsdGVyKChfKSA9PiBfLm9wdGlvbnMub3Bwb3NpdGUgJiYgXy5vcHRpb25zLnZpc2libGUpXG4gICAgICAgICAgICAgIC5yZWR1Y2UodGhpcy5zdW1TaXplLCAwKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHg6IGxlZnQgKyBjb25maWcuYm91bmRzPy5sZWZ0LFxuICAgICAgICAgICAgICB5OiB0b3AgKyBjb25maWcuYm91bmRzPy50b3AsXG4gICAgICAgICAgICAgIHdpZHRoOlxuICAgICAgICAgICAgICAgIHNpemUud2lkdGggLVxuICAgICAgICAgICAgICAgIGxlZnQgLVxuICAgICAgICAgICAgICAgIHJpZ2h0IC1cbiAgICAgICAgICAgICAgICBjb25maWcuYm91bmRzPy5sZWZ0IC1cbiAgICAgICAgICAgICAgICBjb25maWcuYm91bmRzPy5yaWdodCxcbiAgICAgICAgICAgICAgaGVpZ2h0OlxuICAgICAgICAgICAgICAgIHNpemUuaGVpZ2h0IC1cbiAgICAgICAgICAgICAgICB0b3AgLVxuICAgICAgICAgICAgICAgIGJvdHRvbSAtXG4gICAgICAgICAgICAgICAgY29uZmlnLmJvdW5kcz8udG9wIC1cbiAgICAgICAgICAgICAgICBjb25maWcuYm91bmRzPy5ib3R0b20sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgKSxcbiAgICAgICAgdGV0YVpvbmVGdWxsKHRoaXMuX3pvbmUpLFxuICAgICAgICBzaGFyZVJlcGxheSh7XG4gICAgICAgICAgYnVmZmVyU2l6ZTogMSxcbiAgICAgICAgICByZWZDb3VudDogdHJ1ZSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9vYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoZW50cmllczogUmVzaXplT2JzZXJ2ZXJFbnRyeVtdKSA9PiB7XG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIUFycmF5LmlzQXJyYXkoZW50cmllcykgfHxcbiAgICAgICAgICAhZW50cmllcy5sZW5ndGggfHxcbiAgICAgICAgICBlbnRyaWVzWzBdLmNvbnRlbnRSZWN0LndpZHRoIDw9IDAgfHxcbiAgICAgICAgICBlbnRyaWVzWzBdLmNvbnRlbnRSZWN0LmhlaWdodCA8PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdmMuc2V0U2l6ZShlbnRyaWVzWzBdLmNvbnRlbnRSZWN0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMuX29ic2VydmVyLm9ic2VydmUodGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX29ic2VydmVyLnVub2JzZXJ2ZSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHRoaXMuX29ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgfVxuXG4gIHByaXZhdGUgc3VtU2l6ZSA9IChhY2MsIGN1cnIpID0+IGFjYyArIGN1cnIuc2VsZlNpemU7XG5cbiAgZ2V0VHJhbnNsYXRlKGF4aXM/OiBBeGlzLCBzaXplPzogRE9NUmVjdCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuc2NhbGVzLnBpcGUoXG4gICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmNvbmZpZyksXG4gICAgICBtYXAoKGRhdGE6IFtJU2NhbGVzTWFwLCBJQ2hhcnRDb25maWddKSA9PiB7XG4gICAgICAgIGNvbnN0IFt7eCwgeX0sIGNvbmZpZ10gPSBkYXRhO1xuICAgICAgICBjb25zdCB4QXhlc0FycmF5ID0gQXJyYXkuZnJvbSh4LnZhbHVlcygpKTtcbiAgICAgICAgY29uc3QgeUF4ZXNBcnJheSA9IEFycmF5LmZyb20oeS52YWx1ZXMoKSk7XG5cbiAgICAgICAgY29uc3Qgb3Bwb3NpdGVGaWx0ZXIgPSB0aGlzLmZpbHRlclBvc2l0aW9uTWFwLmdldCh0cnVlKTtcbiAgICAgICAgY29uc3Qgbm9uT3Bwb3NpdGVGaWx0ZXIgPSB0aGlzLmZpbHRlclBvc2l0aW9uTWFwLmdldChmYWxzZSk7XG5cbiAgICAgICAgY29uc3Qgb3Bwb3NpdGVPZmZzZXRZID0geUF4ZXNBcnJheS5maWx0ZXIob3Bwb3NpdGVGaWx0ZXIoYXhpcykpO1xuICAgICAgICBjb25zdCBub25PcHBvc2l0ZU9mZnNldFkgPSB5QXhlc0FycmF5LmZpbHRlcihub25PcHBvc2l0ZUZpbHRlcihheGlzKSk7XG5cbiAgICAgICAgY29uc3Qgb3Bwb3NpdGVPZmZzZXRYID0geEF4ZXNBcnJheS5maWx0ZXIob3Bwb3NpdGVGaWx0ZXIoYXhpcykpO1xuICAgICAgICBjb25zdCBub25PcHBvc2l0ZU9mZnNldFggPSB4QXhlc0FycmF5LmZpbHRlcihub25PcHBvc2l0ZUZpbHRlcihheGlzKSk7XG5cbiAgICAgICAgY29uc3Qgb3Bwb3NpdGVUcmFuc2xhdGVZID0gb3Bwb3NpdGVPZmZzZXRZLnJlZHVjZShcbiAgICAgICAgICAoYWNjLCBjdXJyKSA9PiBhY2MgKyBjdXJyLnNlbGZTaXplLFxuICAgICAgICAgIGNvbmZpZy5ib3VuZHM/LnJpZ2h0XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IG5vbk9wcGlzdGVUcmFuc2xhdGVZID0gbm9uT3Bwb3NpdGVPZmZzZXRZLnJlZHVjZShcbiAgICAgICAgICAoYWNjLCBjdXJyKSA9PiBhY2MgKyBjdXJyLnNlbGZTaXplLFxuICAgICAgICAgIGNvbmZpZy5ib3VuZHM/LmxlZnRcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBvcHBvc2l0ZVRyYW5zbGF0ZVggPSBvcHBvc2l0ZU9mZnNldFgucmVkdWNlKFxuICAgICAgICAgIChhY2MsIGN1cnIpID0+IGFjYyArIGN1cnIuc2VsZlNpemUsXG4gICAgICAgICAgY29uZmlnLmJvdW5kcz8udG9wXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3Qgbm9uT3BwaXN0ZVRyYW5zbGF0ZVggPSBub25PcHBvc2l0ZU9mZnNldFgucmVkdWNlKFxuICAgICAgICAgIChhY2MsIGN1cnIpID0+IGFjYyArIGN1cnIuc2VsZlNpemUsXG4gICAgICAgICAgY29uZmlnLmJvdW5kcz8uYm90dG9tXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgbGVmdCA9IHlBeGVzQXJyYXlcbiAgICAgICAgICAuZmlsdGVyKChfKSA9PiBfLm9wdGlvbnMudmlzaWJsZSAmJiBfLm9wdGlvbnMub3Bwb3NpdGUgIT09IHRydWUpXG4gICAgICAgICAgLnJlZHVjZSgoYWNjLCBjdXJyKSA9PiBhY2MgKyBjdXJyLnNlbGZTaXplLCBjb25maWcuYm91bmRzPy5sZWZ0KTtcblxuICAgICAgICBjb25zdCB0b3AgPSB4QXhlc0FycmF5XG4gICAgICAgICAgLmZpbHRlcigoXykgPT4gXy5vcHRpb25zLnZpc2libGUgJiYgXy5vcHRpb25zLm9wcG9zaXRlID09PSB0cnVlKVxuICAgICAgICAgIC5yZWR1Y2UoKGFjYywgY3VycikgPT4gYWNjICsgY3Vyci5zZWxmU2l6ZSwgY29uZmlnLmJvdW5kcz8udG9wKTtcblxuICAgICAgICBpZiAoYXhpcy5vcmllbnRhdGlvbiA9PT0gQXhpc09yaWVudGF0aW9uLngpIHtcbiAgICAgICAgICByZXR1cm4gYHRyYW5zbGF0ZSgke2xlZnR9LCAke1xuICAgICAgICAgICAgYXhpcy5vcHRpb25zLm9wcG9zaXRlXG4gICAgICAgICAgICAgID8gb3Bwb3NpdGVUcmFuc2xhdGVYXG4gICAgICAgICAgICAgIDogc2l6ZS5oZWlnaHQgLSBub25PcHBpc3RlVHJhbnNsYXRlWFxuICAgICAgICAgIH0pYDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChheGlzLm9yaWVudGF0aW9uID09PSBBeGlzT3JpZW50YXRpb24ueSkge1xuICAgICAgICAgIHJldHVybiBgdHJhbnNsYXRlKCR7XG4gICAgICAgICAgICBheGlzLm9wdGlvbnMub3Bwb3NpdGVcbiAgICAgICAgICAgICAgPyBzaXplLndpZHRoIC0gb3Bwb3NpdGVUcmFuc2xhdGVZXG4gICAgICAgICAgICAgIDogbm9uT3BwaXN0ZVRyYW5zbGF0ZVlcbiAgICAgICAgICB9LCAke3RvcH0pYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAndHJhbnNsYXRlKDAsIDApJztcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGlkZW50aWZ5KGluZGV4LCBpdGVtKSB7XG4gICAgcmV0dXJuIGl0ZW0udmFsdWUuaW5kZXg7XG4gIH1cblxuICBjbGljayhcbiAgICBldmVudDogTW91c2VFdmVudCxcbiAgICB4U2NhbGVzOiBNYXA8bnVtYmVyLCBBeGlzPixcbiAgICB5U2NhbGVzOiBNYXA8bnVtYmVyLCBBeGlzPlxuICApIHtcbiAgICBjb25zdCB4ID0geFNjYWxlcy5nZXQoMCk/LnNjYWxlO1xuICAgIGNvbnN0IHkgPSB5U2NhbGVzLmdldCgwKT8uc2NhbGU7XG4gICAgdGhpcy5fc3ZjLmVtaXRDaGFydENsaWNrKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIHRhcmdldDoge1xuICAgICAgICB4OiB4LmludmVydChldmVudC5vZmZzZXRYKSxcbiAgICAgICAgeTogeS5pbnZlcnQoZXZlbnQub2Zmc2V0WSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29udGV4dE1lbnUoXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gICAgeFNjYWxlczogTWFwPG51bWJlciwgQXhpcz4sXG4gICAgeVNjYWxlczogTWFwPG51bWJlciwgQXhpcz5cbiAgKSB7XG4gICAgY29uc3QgeCA9IHhTY2FsZXMuZ2V0KDApPy5zY2FsZTtcbiAgICBjb25zdCB5ID0geVNjYWxlcy5nZXQoMCk/LnNjYWxlO1xuICAgIHRoaXMuX3N2Yy5lbWl0Q2hhcnRDb250ZXh0TWVudSh7XG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICB0YXJnZXQ6IHtcbiAgICAgICAgeDogeC5pbnZlcnQoZXZlbnQub2Zmc2V0WCksXG4gICAgICAgIHk6IHkuaW52ZXJ0KGV2ZW50Lm9mZnNldFkpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIG1vdXNlTW92ZShldmVudCkge1xuICAgIHRoaXMuX3N2Yy5zZXRQb2ludGVyTW92ZShldmVudCk7XG4gIH1cblxuICBtb3VzZUxlYXZlKGV2ZW50KSB7XG4gICAgdGhpcy5fc3ZjLnNldFBvaW50ZXJNb3ZlKGV2ZW50KTtcbiAgfVxuXG4gIHRyYWNrU2VyaWUoaW5kZXgsIGl0ZW06IFNlcmllczxCYXNlUG9pbnQ+KSB7XG4gICAgcmV0dXJuIGl0ZW0ubmFtZT8ubGVuZ3RoID8gaXRlbS5uYW1lIDogaW5kZXhcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cIntcbiAgc2l6ZTogc2l6ZSB8IGFzeW5jLFxuICBjb25maWc6IGNvbmZpZyB8IGFzeW5jLFxuICBzY2FsZXM6IHNjYWxlcyB8IGFzeW5jLFxuICB2aXNpYmxlUmVjdDogdmlzaWJsZVJlY3QgfCBhc3luY1xufSBhcyBkYXRhXCIgeG1sbnM6c3ZnPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS9odG1sXCI+XG4gIDx0ZXRhLXRvb2x0aXAgKm5nSWY9XCJkYXRhLmNvbmZpZz8udG9vbHRpcD8uZW5hYmxlXCJcbiAgICAgICAgICAgICAgICBbc2l6ZV09XCJkYXRhLnNpemVcIlxuICAgICAgICAgICAgICAgIFtjb25maWddPVwiZGF0YS5jb25maWdcIj48L3RldGEtdG9vbHRpcD5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGEuc2l6ZT8uaGVpZ2h0ID4gMFxuICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEuc2l6ZT8ud2lkdGggPiAwXG4gICAgICAgICAgICAgICAgICAgICAgJiYgZGF0YS52aXNpYmxlUmVjdD8uaGVpZ2h0ID4gMFxuICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEudmlzaWJsZVJlY3Q/LndpZHRoID4gMFxuICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEuc2NhbGVzPy54LnNpemUgPT09IGRhdGEuY29uZmlnLnhBeGlzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICYmIGRhdGEuc2NhbGVzPy55LnNpemUgPT09IGRhdGEuY29uZmlnLnlBeGlzLmxlbmd0aFwiPlxuICAgIDxzdmcgaGVpZ2h0PVwiMTAwJVwiIHdpZHRoPVwiMTAwJVwiIGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGVcIj5cbiAgICAgIDxnIGNsYXNzPVwieS1heGlzLWNvbnRhaW5lclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGRhdGEuc2NhbGVzLnkgfCBrZXl2YWx1ZTsgdHJhY2tCeTogaWRlbnRpZnlcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS52YWx1ZS5zZWxmU2l6ZSA+IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgaXRlbS52YWx1ZS5vcHRpb25zLnZpc2libGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZGF0YS5zY2FsZXMueC5zaXplID4gMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBkYXRhLnNjYWxlcy55LnNpemUgPiAwXCI+XG4gICAgICAgICAgICA8Z1xuICAgICAgICAgICAgICB0ZXRhLXktYXhpc1xuICAgICAgICAgICAgICBbYXhpc109XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgW3NpemVdPVwiZGF0YS52aXNpYmxlUmVjdFwiXG4gICAgICAgICAgICAgIFthdHRyLnRyYW5zZm9ybV09XCJnZXRUcmFuc2xhdGUoaXRlbS52YWx1ZSwgZGF0YS5zaXplKSB8IGFzeW5jXCI+PC9nPlxuICAgICAgICAgICAgPHJlY3RcbiAgICAgICAgICAgICAgdGV0YVpvb21hYmxlXG4gICAgICAgICAgICAgIGZpbGwtb3BhY2l0eT1cIjBcIlxuICAgICAgICAgICAgICBbYXhpc109XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJkYXRhLmNvbmZpZ1wiXG4gICAgICAgICAgICAgIFtzaXplXT1cImRhdGEudmlzaWJsZVJlY3RcIlxuICAgICAgICAgICAgICBbYXR0ci54XT1cIml0ZW0udmFsdWUub3B0aW9ucy5vcHBvc2l0ZSA/IDAgOiAtaXRlbS52YWx1ZS5zZWxmU2l6ZVwiXG4gICAgICAgICAgICAgIFthdHRyLnldPVwiMFwiXG4gICAgICAgICAgICAgIFthdHRyLmhlaWdodF09XCJkYXRhLnZpc2libGVSZWN0LmhlaWdodFwiXG4gICAgICAgICAgICAgIFthdHRyLndpZHRoXT1cIml0ZW0udmFsdWUuc2VsZlNpemVcIlxuICAgICAgICAgICAgICBbYXR0ci50cmFuc2Zvcm1dPVwiZ2V0VHJhbnNsYXRlKGl0ZW0udmFsdWUsIGRhdGEuc2l6ZSkgfCBhc3luY1wiPjwvcmVjdD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZz5cbiAgICAgIDxnIGNsYXNzPVwieC1heGlzLWNvbnRhaW5lclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGRhdGEuc2NhbGVzLnggfCBrZXl2YWx1ZTsgdHJhY2tCeTogaWRlbnRpZnlcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS52YWx1ZS5vcHRpb25zLnZpc2libGUgJiYgZGF0YS5zY2FsZXMueC5zaXplID4gMCAmJiBkYXRhLnNjYWxlcy55LnNpemUgPiAwXCI+XG4gICAgICAgICAgICA8Z1xuICAgICAgICAgICAgICB0ZXRhLXgtYXhpc1xuICAgICAgICAgICAgICBbYXhpc109XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgW3NpemVdPVwiZGF0YS52aXNpYmxlUmVjdFwiXG4gICAgICAgICAgICAgIFthdHRyLnRyYW5zZm9ybV09XCJnZXRUcmFuc2xhdGUoaXRlbS52YWx1ZSwgZGF0YS5zaXplKSB8IGFzeW5jXCI+PC9nPlxuICAgICAgICAgICAgPHJlY3RcbiAgICAgICAgICAgICAgdGV0YVpvb21hYmxlXG4gICAgICAgICAgICAgIGZpbGwtb3BhY2l0eT1cIjBcIlxuICAgICAgICAgICAgICBbYXhpc109XCJpdGVtLnZhbHVlXCJcbiAgICAgICAgICAgICAgW2NvbmZpZ109XCJkYXRhLmNvbmZpZ1wiXG4gICAgICAgICAgICAgIFtzaXplXT1cImRhdGEudmlzaWJsZVJlY3RcIlxuICAgICAgICAgICAgICBbYXR0ci54XT1cIjBcIlxuICAgICAgICAgICAgICBbYXR0ci55XT1cIml0ZW0udmFsdWUub3B0aW9ucy5vcHBvc2l0ZSA/IC1pdGVtLnZhbHVlLnNlbGZTaXplIDogMFwiXG4gICAgICAgICAgICAgIFthdHRyLndpZHRoXT1cImRhdGEudmlzaWJsZVJlY3Qud2lkdGhcIlxuICAgICAgICAgICAgICBbYXR0ci5oZWlnaHRdPVwiaXRlbS52YWx1ZS5zZWxmU2l6ZVwiXG4gICAgICAgICAgICAgIFthdHRyLnRyYW5zZm9ybV09XCJnZXRUcmFuc2xhdGUoaXRlbS52YWx1ZSwgZGF0YS5zaXplKSB8IGFzeW5jXCI+PC9yZWN0PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZz5cbiAgICA8L3N2Zz5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdJZj1cImRhdGEuc2l6ZT8uaGVpZ2h0ID4gMFxuICAgICAgICAgICYmIGRhdGEuc2l6ZT8ud2lkdGggPiAwXG4gICAgICAgICAgJiYgZGF0YS52aXNpYmxlUmVjdD8uaGVpZ2h0ID4gMFxuICAgICAgICAgICYmIGRhdGEudmlzaWJsZVJlY3Q/LndpZHRoID4gMFxuICAgICAgICAgICYmIGRhdGEuc2NhbGVzPy54LnNpemUgPT09IGRhdGEuY29uZmlnLnhBeGlzLmxlbmd0aFxuICAgICAgICAgICYmIGRhdGEuc2NhbGVzPy55LnNpemUgPT09IGRhdGEuY29uZmlnLnlBeGlzLmxlbmd0aFwiPlxuICAgIDxzdmdcbiAgICAgIHRldGFab29tYWJsZVxuICAgICAgdGV0YUJydXNoYWJsZVxuICAgICAgY2xhc3M9XCJwb3NpdGlvbi1hYnNvbHV0ZVwiXG4gICAgICBbc2l6ZV09XCJkYXRhLnZpc2libGVSZWN0XCJcbiAgICAgIFtjb25maWddPVwiZGF0YS5jb25maWdcIlxuICAgICAgW2F4aXNdPVwiZGF0YS5jb25maWc/Lnpvb20/LnR5cGUgPT09IHpvb21UeXBlLnggPyBkYXRhLnNjYWxlcy54LmdldCgwKSA6IGRhdGEuc2NhbGVzLnkuZ2V0KDApXCJcbiAgICAgIFthdHRyLndpZHRoXT1cImRhdGEudmlzaWJsZVJlY3Qud2lkdGhcIlxuICAgICAgW2F0dHIuaGVpZ2h0XT1cImRhdGEudmlzaWJsZVJlY3QuaGVpZ2h0XCJcbiAgICAgIFthdHRyLnZpZXdCb3hdPVwiJzAgMCAnICsgZGF0YS52aXNpYmxlUmVjdC53aWR0aCArICcgJyArIGRhdGEudmlzaWJsZVJlY3QuaGVpZ2h0XCJcbiAgICAgIFtzdHlsZS50cmFuc2Zvcm1dPVwiJ3RyYW5zbGF0ZSgnKyBkYXRhLnZpc2libGVSZWN0LnggKydweCwgJysgZGF0YS52aXNpYmxlUmVjdC55ICsncHgpJ1wiXG4gICAgICAoY29udGV4dG1lbnUpPVwiY29udGV4dE1lbnUoJGV2ZW50LCBkYXRhLnNjYWxlcy54LCBkYXRhLnNjYWxlcy55KVwiXG4gICAgICAoY2xpY2spPVwiY2xpY2soJGV2ZW50LCBkYXRhLnNjYWxlcy54LCBkYXRhLnNjYWxlcy55KVwiXG4gICAgICAobW91c2VsZWF2ZSk9XCJtb3VzZUxlYXZlKCRldmVudClcIlxuICAgICAgKG1vdXNlbW92ZSk9XCJtb3VzZU1vdmUoJGV2ZW50KVwiPlxuXG4gICAgICA8ZyBjbGFzcz1cImdyaWRsaW5lc1wiXG4gICAgICAgICB0ZXRhLWdyaWRsaW5lc1xuICAgICAgICAgKm5nSWY9XCJkYXRhLmNvbmZpZy5ncmlkTGluZXM/LmVuYWJsZSAhPT0gZmFsc2VcIlxuICAgICAgICAgW3NpemVdPVwiZGF0YS5zaXplXCI+PC9nPlxuXG4gICAgICA8ZyBjbGFzcz1cIngtYXhpcy1wbG90YmFuZC1jb250YWluZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYXhpcyBvZiBkYXRhLmNvbmZpZy54QXhpczsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgIDxnIHRldGEtcGxvdC1iYW5kICpuZ0Zvcj1cImxldCBwbG90QmFuZCBvZiBheGlzLnBsb3RCYW5kc1wiXG4gICAgICAgICAgICAgW3Bsb3RCYW5kXT1cInBsb3RCYW5kXCJcbiAgICAgICAgICAgICBbc2NhbGVdPVwiZGF0YS5zY2FsZXMueC5nZXQoaSkuc2NhbGVcIlxuICAgICAgICAgICAgIFtzaXplXT1cImRhdGEudmlzaWJsZVJlY3RcIlxuICAgICAgICAgICAgIFtheGlzXT1cImRhdGEuc2NhbGVzLnguZ2V0KGkpXCI+PC9nPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZz5cbiAgICAgIDxnIGNsYXNzPVwieS1heGlzLXBsb3RiYW5kLWNvbnRhaW5lclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBheGlzIG9mIGRhdGEuY29uZmlnLnlBeGlzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgPGcgdGV0YS1wbG90LWJhbmQgKm5nRm9yPVwibGV0IHBsb3RCYW5kIG9mIGF4aXMucGxvdEJhbmRzXCJcbiAgICAgICAgICAgICBbcGxvdEJhbmRdPVwicGxvdEJhbmRcIlxuICAgICAgICAgICAgIFtzY2FsZV09XCJkYXRhLnNjYWxlcy55LmdldChpKS5zY2FsZVwiXG4gICAgICAgICAgICAgW3NpemVdPVwiZGF0YS52aXNpYmxlUmVjdFwiXG4gICAgICAgICAgICAgW2F4aXNdPVwiZGF0YS5zY2FsZXMueS5nZXQoaSlcIj48L2c+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9nPlxuICAgICAgPGcgY2xhc3M9XCJ4LWF4aXMtcGxvdGxpbmUtY29udGFpbmVyXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGF4aXMgb2YgZGF0YS5jb25maWcueEF4aXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICA8ZyB0ZXRhLXBsb3QtbGluZSAqbmdGb3I9XCJsZXQgcGxvdExpbmUgb2YgYXhpcy5wbG90TGluZXNcIlxuICAgICAgICAgICAgIFtwbG90TGluZV09XCJwbG90TGluZVwiXG4gICAgICAgICAgICAgW3NjYWxlXT1cImRhdGEuc2NhbGVzLnguZ2V0KGkpLnNjYWxlXCJcbiAgICAgICAgICAgICBbc2l6ZV09XCJkYXRhLnNpemVcIlxuICAgICAgICAgICAgIFtheGlzXT1cImRhdGEuc2NhbGVzLnguZ2V0KGkpXCI+PC9nPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZz5cbiAgICAgIDxnIGNsYXNzPVwieS1heGlzLXBsb3RsaW5lLWNvbnRhaW5lclwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBheGlzIG9mIGRhdGEuY29uZmlnLnlBeGlzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgPGcgdGV0YS1wbG90LWxpbmUgKm5nRm9yPVwibGV0IHBsb3RMaW5lIG9mIGF4aXMucGxvdExpbmVzXCJcbiAgICAgICAgICAgICBbcGxvdExpbmVdPVwicGxvdExpbmVcIlxuICAgICAgICAgICAgIFtzY2FsZV09XCJkYXRhLnNjYWxlcy55LmdldChpKS5zY2FsZVwiXG4gICAgICAgICAgICAgW3NpemVdPVwiZGF0YS5zaXplXCJcbiAgICAgICAgICAgICBbYXhpc109XCJkYXRhLnNjYWxlcy55LmdldChpKVwiPjwvZz5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2c+XG4gICAgICA8ZyBjbGFzcz1cInNlcmllcy1jb250YWluZXJcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc2VyaWVzIG9mIGRhdGEuY29uZmlnLnNlcmllcztcIj5cbiAgICAgICAgICA8ZyB0ZXRhLXNlcmllcy1ob3N0XG4gICAgICAgICAgICAgKm5nSWY9XCJzZXJpZXMudmlzaWJsZVwiXG4gICAgICAgICAgICAgW2NvbmZpZ109XCJkYXRhLmNvbmZpZ1wiXG4gICAgICAgICAgICAgW3Nlcmllc109XCJzZXJpZXNcIj48L2c+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9nPlxuICAgICAgPGcgY2xhc3M9XCJhbm5vdGF0aW9uc1wiPlxuICAgICAgICA8ZyB0ZXRhLWFubm90YXRpb25cbiAgICAgICAgICAgW3Zpc2libGVSZWN0XT1cImRhdGEudmlzaWJsZVJlY3RcIlxuICAgICAgICAgICAqbmdGb3I9XCJsZXQgYW5ub3RhdGlvbiBvZiBkYXRhLmNvbmZpZy5hbm5vdGF0aW9uc1wiXG4gICAgICAgICAgIFthbm5vdGF0aW9uXT1cImFubm90YXRpb25cIj48L2c+XG4gICAgICA8L2c+XG4gICAgICA8ZyBjbGFzcz1cImNyb3NzaGFpclwiICpuZ0lmPVwiZGF0YS5jb25maWcudG9vbHRpcD8uc2hvd0Nyb3NzaGFpclwiPlxuICAgICAgICA8ZyB0ZXRhLWNyb3NzaGFpciBbc2l6ZV09XCJkYXRhLnZpc2libGVSZWN0XCI+PC9nPlxuICAgICAgPC9nPlxuICAgIDwvc3ZnPlxuXG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy1jb250YWluZXI+XG4iXX0=
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { map, tap } from "rxjs";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "../../service/scale.service";
|
|
5
|
+
import * as i2 from "../../service/chart.service";
|
|
6
|
+
import * as i3 from "@angular/common";
|
|
7
|
+
export class CrosshairComponent {
|
|
8
|
+
scaleService;
|
|
9
|
+
chartService;
|
|
10
|
+
cdr;
|
|
11
|
+
size;
|
|
12
|
+
transform;
|
|
13
|
+
constructor(scaleService, chartService, cdr) {
|
|
14
|
+
this.scaleService = scaleService;
|
|
15
|
+
this.chartService = chartService;
|
|
16
|
+
this.cdr = cdr;
|
|
17
|
+
}
|
|
18
|
+
ngOnInit() {
|
|
19
|
+
this.transform = this.chartService.pointerMove.pipe(map((event) => {
|
|
20
|
+
return {
|
|
21
|
+
x: event.type === 'mouseleave' ? -9999 : event.offsetX,
|
|
22
|
+
y: event.type === 'mouseleave' ? -9999 : event.offsetY
|
|
23
|
+
};
|
|
24
|
+
}), tap(() => {
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
this.cdr.detectChanges();
|
|
27
|
+
});
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: CrosshairComponent, deps: [{ token: i1.ScaleService }, { token: i2.ChartService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.4", type: CrosshairComponent, selector: "[teta-crosshair]", inputs: { size: "size" }, ngImport: i0, template: "<ng-container *ngIf=\"transform | async as t\">\n <svg:line [attr.x1]=\"t.x\" y1=\"0\" [attr.x2]=\"t.x\" [attr.y2]=\"size.height\" stroke=\"var(--color-text-90)\" stroke-width=\"0.5\"></svg:line>\n <svg:line x1=\"0\" [attr.y1]=\"t.y\" [attr.x2]=\"size.width\" [attr.y2]=\"t.y\" stroke=\"var(--color-text-90)\" stroke-width=\"0.5\"></svg:line>\n</ng-container>\n", styles: [":host{shape-rendering:crispEdges;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] });
|
|
32
|
+
}
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: CrosshairComponent, decorators: [{
|
|
34
|
+
type: Component,
|
|
35
|
+
args: [{ selector: '[teta-crosshair]', template: "<ng-container *ngIf=\"transform | async as t\">\n <svg:line [attr.x1]=\"t.x\" y1=\"0\" [attr.x2]=\"t.x\" [attr.y2]=\"size.height\" stroke=\"var(--color-text-90)\" stroke-width=\"0.5\"></svg:line>\n <svg:line x1=\"0\" [attr.y1]=\"t.y\" [attr.x2]=\"size.width\" [attr.y2]=\"t.y\" stroke=\"var(--color-text-90)\" stroke-width=\"0.5\"></svg:line>\n</ng-container>\n", styles: [":host{shape-rendering:crispEdges;pointer-events:none}\n"] }]
|
|
36
|
+
}], ctorParameters: function () { return [{ type: i1.ScaleService }, { type: i2.ChartService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { size: [{
|
|
37
|
+
type: Input
|
|
38
|
+
}] } });
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3NoYWlyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jaGFydC9jaGFydC1jb250YWluZXIvY3Jvc3NoYWlyL2Nyb3NzaGFpci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvY2hhcnQvY2hhcnQtY29udGFpbmVyL2Nyb3NzaGFpci9jcm9zc2hhaXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQUUsS0FBSyxFQUFTLE1BQU0sZUFBZSxDQUFDO0FBRTFFLE9BQU8sRUFBQyxHQUFHLEVBQWMsR0FBRyxFQUFDLE1BQU0sTUFBTSxDQUFDOzs7OztBQVExQyxNQUFNLE9BQU8sa0JBQWtCO0lBS1Q7SUFBb0M7SUFBb0M7SUFIbkYsSUFBSSxDQUFVO0lBQ3ZCLFNBQVMsQ0FBa0I7SUFFM0IsWUFBb0IsWUFBMEIsRUFBVSxZQUEwQixFQUFVLEdBQXNCO1FBQTlGLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQVUsaUJBQVksR0FBWixZQUFZLENBQWM7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtJQUNsSCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUNqRCxHQUFHLENBQUMsQ0FBQyxLQUFtQixFQUFFLEVBQUU7WUFDMUIsT0FBTztnQkFDTCxDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTztnQkFDdEQsQ0FBQyxFQUFFLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU87YUFDdkQsQ0FBQTtRQUNILENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUE7UUFFSixDQUFDLENBQUMsQ0FDSCxDQUFBO0lBRUgsQ0FBQzt1R0F4QlUsa0JBQWtCOzJGQUFsQixrQkFBa0Isa0ZDVi9CLDZXQUlBOzsyRkRNYSxrQkFBa0I7a0JBTDlCLFNBQVM7K0JBQ0Usa0JBQWtCOzhKQU1uQixJQUFJO3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIElucHV0LCBPbkluaXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtTY2FsZVNlcnZpY2V9IGZyb20gXCIuLi8uLi9zZXJ2aWNlL3NjYWxlLnNlcnZpY2VcIjtcbmltcG9ydCB7bWFwLCBPYnNlcnZhYmxlLCB0YXB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQge0NoYXJ0U2VydmljZX0gZnJvbSBcIi4uLy4uL3NlcnZpY2UvY2hhcnQuc2VydmljZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdbdGV0YS1jcm9zc2hhaXJdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2Nyb3NzaGFpci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2Nyb3NzaGFpci5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIENyb3NzaGFpckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgQElucHV0KCkgc2l6ZTogRE9NUmVjdDtcbiAgdHJhbnNmb3JtOiBPYnNlcnZhYmxlPGFueT47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzY2FsZVNlcnZpY2U6IFNjYWxlU2VydmljZSwgcHJpdmF0ZSBjaGFydFNlcnZpY2U6IENoYXJ0U2VydmljZSwgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHRoaXMuY2hhcnRTZXJ2aWNlLnBvaW50ZXJNb3ZlLnBpcGUoXG4gICAgICBtYXAoKGV2ZW50OiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB4OiBldmVudC50eXBlID09PSAnbW91c2VsZWF2ZScgPyAtOTk5OSA6IGV2ZW50Lm9mZnNldFgsXG4gICAgICAgICAgeTogZXZlbnQudHlwZSA9PT0gJ21vdXNlbGVhdmUnID8gLTk5OTkgOiBldmVudC5vZmZzZXRZXG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9KVxuXG4gICAgICB9KVxuICAgIClcblxuICB9XG5cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCJ0cmFuc2Zvcm0gfCBhc3luYyBhcyB0XCI+XG4gIDxzdmc6bGluZSBbYXR0ci54MV09XCJ0LnhcIiB5MT1cIjBcIiBbYXR0ci54Ml09XCJ0LnhcIiBbYXR0ci55Ml09XCJzaXplLmhlaWdodFwiIHN0cm9rZT1cInZhcigtLWNvbG9yLXRleHQtOTApXCIgc3Ryb2tlLXdpZHRoPVwiMC41XCI+PC9zdmc6bGluZT5cbiAgPHN2ZzpsaW5lIHgxPVwiMFwiIFthdHRyLnkxXT1cInQueVwiIFthdHRyLngyXT1cInNpemUud2lkdGhcIiBbYXR0ci55Ml09XCJ0LnlcIiBzdHJva2U9XCJ2YXIoLS1jb2xvci10ZXh0LTkwKVwiIHN0cm9rZS13aWR0aD1cIjAuNVwiPjwvc3ZnOmxpbmU+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, Input, } from '@angular/core';
|
|
2
|
+
import { map, withLatestFrom } from "rxjs";
|
|
3
|
+
import { generateTicks } from "../../core/utils/generate-ticks";
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../../service/scale.service";
|
|
6
|
+
import * as i2 from "../../service/chart.service";
|
|
7
|
+
import * as i3 from "@angular/common";
|
|
8
|
+
export class GridlinesComponent {
|
|
9
|
+
svc;
|
|
10
|
+
chartService;
|
|
11
|
+
size;
|
|
12
|
+
config;
|
|
13
|
+
tickYValues;
|
|
14
|
+
tickXValues;
|
|
15
|
+
x;
|
|
16
|
+
y;
|
|
17
|
+
constructor(svc, chartService) {
|
|
18
|
+
this.svc = svc;
|
|
19
|
+
this.chartService = chartService;
|
|
20
|
+
this.config = this.chartService.config;
|
|
21
|
+
this.tickYValues = this.svc.scales.pipe(withLatestFrom(this.config), map((_) => {
|
|
22
|
+
const [scales, config] = _;
|
|
23
|
+
const ratio = this.size.height / 40;
|
|
24
|
+
return config.gridLines?.y?.ticksCount != null ? generateTicks(scales.y.get(0).scale.domain(), config.gridLines?.y?.ticksCount) : scales.y.get(0)?.scale.ticks(ratio);
|
|
25
|
+
}));
|
|
26
|
+
this.tickXValues = this.svc.scales.pipe(withLatestFrom(this.config), map((_) => {
|
|
27
|
+
const [scales, config] = _;
|
|
28
|
+
const ratio = this.size.width / 40;
|
|
29
|
+
return config.gridLines?.x?.ticksCount != null ? generateTicks(scales.x.get(0).originDomain, config.gridLines?.x?.ticksCount) : scales.x.get(0)?.scale.ticks(ratio);
|
|
30
|
+
}));
|
|
31
|
+
this.y = this.svc.scales.pipe(map((_) => _.y.get(0)?.scale));
|
|
32
|
+
this.x = this.svc.scales.pipe(map((_) => _.x.get(0)?.scale));
|
|
33
|
+
}
|
|
34
|
+
ngAfterViewInit() {
|
|
35
|
+
}
|
|
36
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: GridlinesComponent, deps: [{ token: i1.ScaleService }, { token: i2.ChartService }], target: i0.ɵɵFactoryTarget.Component });
|
|
37
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.4", type: GridlinesComponent, selector: "[teta-gridlines]", inputs: { size: "size" }, ngImport: i0, template: "<ng-container *ngIf=\"{\n xValues: tickXValues | async,\n yValues: tickYValues | async,\n x: x | async,\n y: y | async,\n config: config | async\n} as data\">\n <ng-container *ngIf=\"data.y && data.config.gridLines?.showY !== false\">\n <ng-container *ngFor=\"let tick of data.yValues\">\n <svg:line [attr.x1]=\"0\"\n [attr.y1]=\"data.y(tick) || 1\"\n [attr.x2]=\"size?.width\"\n [attr.y2]=\"data.y(tick) || 1\"></svg:line>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"data.x && data.config.gridLines?.showX !== false\">\n <ng-container *ngFor=\"let tick of data.xValues\">\n <svg:line [attr.x1]=\"data.x(tick) || 1\"\n [attr.y1]=\"0\"\n [attr.x2]=\"data.x(tick) || 1\"\n [attr.y2]=\"size?.height\"></svg:line>\n </ng-container>\n </ng-container>\n\n</ng-container>\n\n\n", styles: [":host{shape-rendering:crispEdges}:host line{stroke:var(--color-text-5)}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
38
|
+
}
|
|
39
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.4", ngImport: i0, type: GridlinesComponent, decorators: [{
|
|
40
|
+
type: Component,
|
|
41
|
+
args: [{ selector: '[teta-gridlines]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n xValues: tickXValues | async,\n yValues: tickYValues | async,\n x: x | async,\n y: y | async,\n config: config | async\n} as data\">\n <ng-container *ngIf=\"data.y && data.config.gridLines?.showY !== false\">\n <ng-container *ngFor=\"let tick of data.yValues\">\n <svg:line [attr.x1]=\"0\"\n [attr.y1]=\"data.y(tick) || 1\"\n [attr.x2]=\"size?.width\"\n [attr.y2]=\"data.y(tick) || 1\"></svg:line>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"data.x && data.config.gridLines?.showX !== false\">\n <ng-container *ngFor=\"let tick of data.xValues\">\n <svg:line [attr.x1]=\"data.x(tick) || 1\"\n [attr.y1]=\"0\"\n [attr.x2]=\"data.x(tick) || 1\"\n [attr.y2]=\"size?.height\"></svg:line>\n </ng-container>\n </ng-container>\n\n</ng-container>\n\n\n", styles: [":host{shape-rendering:crispEdges}:host line{stroke:var(--color-text-5)}\n"] }]
|
|
42
|
+
}], ctorParameters: function () { return [{ type: i1.ScaleService }, { type: i2.ChartService }]; }, propDecorators: { size: [{
|
|
43
|
+
type: Input
|
|
44
|
+
}] } });
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZGxpbmVzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jaGFydC9jaGFydC1jb250YWluZXIvZ3JpZGxpbmVzL2dyaWRsaW5lcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9zcmMvY2hhcnQvY2hhcnQtY29udGFpbmVyL2dyaWRsaW5lcy9ncmlkbGluZXMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBQUUsS0FBSyxHQUNqQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUMsR0FBRyxFQUFjLGNBQWMsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUdyRCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0saUNBQWlDLENBQUM7Ozs7O0FBUzlELE1BQU0sT0FBTyxrQkFBa0I7SUFVVDtJQUEyQjtJQVJ0QyxJQUFJLENBQVU7SUFFdkIsTUFBTSxDQUEyQjtJQUNqQyxXQUFXLENBQXVCO0lBQ2xDLFdBQVcsQ0FBdUI7SUFDbEMsQ0FBQyxDQUFrQjtJQUNuQixDQUFDLENBQWtCO0lBRW5CLFlBQW9CLEdBQWlCLEVBQVUsWUFBMEI7UUFBckQsUUFBRyxHQUFILEdBQUcsQ0FBYztRQUFVLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQ3ZFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUM7UUFFdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3JDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQzNCLEdBQUcsQ0FBQyxDQUFDLENBQTZCLEVBQUUsRUFBRTtZQUNwQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDcEMsT0FBTyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxVQUFVLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFTixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDckMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFDM0IsR0FBRyxDQUFDLENBQUMsQ0FBNkIsRUFBRSxFQUFFO1lBQ3BDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNuQyxPQUFPLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLFVBQVUsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVOLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELGVBQWU7SUFFZixDQUFDO3VHQW5DVSxrQkFBa0I7MkZBQWxCLGtCQUFrQixrRkNuQi9CLCs0QkE0QkE7OzJGRFRhLGtCQUFrQjtrQkFOOUIsU0FBUzsrQkFDRSxrQkFBa0IsbUJBR1gsdUJBQXVCLENBQUMsTUFBTTs4SEFJdEMsSUFBSTtzQkFBWixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCwgSW5wdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge1NjYWxlU2VydmljZX0gZnJvbSBcIi4uLy4uL3NlcnZpY2Uvc2NhbGUuc2VydmljZVwiO1xuaW1wb3J0IHttYXAsIE9ic2VydmFibGUsIHdpdGhMYXRlc3RGcm9tfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHtJQ2hhcnRDb25maWd9IGZyb20gXCIuLi8uLi9tb2RlbC9pLWNoYXJ0LWNvbmZpZ1wiO1xuaW1wb3J0IHtDaGFydFNlcnZpY2V9IGZyb20gXCIuLi8uLi9zZXJ2aWNlL2NoYXJ0LnNlcnZpY2VcIjtcbmltcG9ydCB7Z2VuZXJhdGVUaWNrc30gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbHMvZ2VuZXJhdGUtdGlja3NcIjtcbmltcG9ydCB7SVNjYWxlc01hcH0gZnJvbSBcIi4uLy4uL21vZGVsL2ktc2NhbGVzLW1hcFwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdbdGV0YS1ncmlkbGluZXNdJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2dyaWRsaW5lcy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2dyaWRsaW5lcy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgR3JpZGxpbmVzQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgQElucHV0KCkgc2l6ZTogRE9NUmVjdDtcblxuICBjb25maWc6IE9ic2VydmFibGU8SUNoYXJ0Q29uZmlnPjtcbiAgdGlja1lWYWx1ZXM6IE9ic2VydmFibGU8bnVtYmVyW10+O1xuICB0aWNrWFZhbHVlczogT2JzZXJ2YWJsZTxudW1iZXJbXT47XG4gIHg6IE9ic2VydmFibGU8YW55PjtcbiAgeTogT2JzZXJ2YWJsZTxhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3ZjOiBTY2FsZVNlcnZpY2UsIHByaXZhdGUgY2hhcnRTZXJ2aWNlOiBDaGFydFNlcnZpY2UpIHtcbiAgICB0aGlzLmNvbmZpZyA9IHRoaXMuY2hhcnRTZXJ2aWNlLmNvbmZpZztcblxuICAgIHRoaXMudGlja1lWYWx1ZXMgPSB0aGlzLnN2Yy5zY2FsZXMucGlwZShcbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuY29uZmlnKSxcbiAgICAgIG1hcCgoXzogW0lTY2FsZXNNYXAsIElDaGFydENvbmZpZ10pID0+IHtcbiAgICAgICAgY29uc3QgW3NjYWxlcywgY29uZmlnXSA9IF87XG4gICAgICAgIGNvbnN0IHJhdGlvID0gdGhpcy5zaXplLmhlaWdodCAvIDQwO1xuICAgICAgICByZXR1cm4gY29uZmlnLmdyaWRMaW5lcz8ueT8udGlja3NDb3VudCAhPSBudWxsID8gZ2VuZXJhdGVUaWNrcyhzY2FsZXMueS5nZXQoMCkuc2NhbGUuZG9tYWluKCksIGNvbmZpZy5ncmlkTGluZXM/Lnk/LnRpY2tzQ291bnQpIDogc2NhbGVzLnkuZ2V0KDApPy5zY2FsZS50aWNrcyhyYXRpbyk7XG4gICAgICB9KSk7XG5cbiAgICB0aGlzLnRpY2tYVmFsdWVzID0gdGhpcy5zdmMuc2NhbGVzLnBpcGUoXG4gICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmNvbmZpZyksXG4gICAgICBtYXAoKF86IFtJU2NhbGVzTWFwLCBJQ2hhcnRDb25maWddKSA9PiB7XG4gICAgICAgIGNvbnN0IFtzY2FsZXMsIGNvbmZpZ10gPSBfO1xuICAgICAgICBjb25zdCByYXRpbyA9IHRoaXMuc2l6ZS53aWR0aCAvIDQwO1xuICAgICAgICByZXR1cm4gY29uZmlnLmdyaWRMaW5lcz8ueD8udGlja3NDb3VudCAhPSBudWxsID8gZ2VuZXJhdGVUaWNrcyhzY2FsZXMueC5nZXQoMCkub3JpZ2luRG9tYWluLCBjb25maWcuZ3JpZExpbmVzPy54Py50aWNrc0NvdW50KSA6IHNjYWxlcy54LmdldCgwKT8uc2NhbGUudGlja3MocmF0aW8pO1xuICAgICAgfSkpO1xuXG4gICAgdGhpcy55ID0gdGhpcy5zdmMuc2NhbGVzLnBpcGUobWFwKChfKSA9PiBfLnkuZ2V0KDApPy5zY2FsZSkpO1xuICAgIHRoaXMueCA9IHRoaXMuc3ZjLnNjYWxlcy5waXBlKG1hcCgoXykgPT4gXy54LmdldCgwKT8uc2NhbGUpKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcblxuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwie1xuICB4VmFsdWVzOiB0aWNrWFZhbHVlcyB8IGFzeW5jLFxuICB5VmFsdWVzOiB0aWNrWVZhbHVlcyB8IGFzeW5jLFxuICB4OiB4IHwgYXN5bmMsXG4gIHk6IHkgfCBhc3luYyxcbiAgY29uZmlnOiBjb25maWcgfCBhc3luY1xufSBhcyBkYXRhXCI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJkYXRhLnkgJiYgZGF0YS5jb25maWcuZ3JpZExpbmVzPy5zaG93WSAhPT0gZmFsc2VcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0aWNrIG9mIGRhdGEueVZhbHVlc1wiPlxuICAgICAgPHN2ZzpsaW5lIFthdHRyLngxXT1cIjBcIlxuICAgICAgICAgICAgICAgIFthdHRyLnkxXT1cImRhdGEueSh0aWNrKSB8fCAxXCJcbiAgICAgICAgICAgICAgICBbYXR0ci54Ml09XCJzaXplPy53aWR0aFwiXG4gICAgICAgICAgICAgICAgW2F0dHIueTJdPVwiZGF0YS55KHRpY2spIHx8IDFcIj48L3N2ZzpsaW5lPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGF0YS54ICYmIGRhdGEuY29uZmlnLmdyaWRMaW5lcz8uc2hvd1ggIT09IGZhbHNlXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdGljayBvZiBkYXRhLnhWYWx1ZXNcIj5cbiAgICAgIDxzdmc6bGluZSBbYXR0ci54MV09XCJkYXRhLngodGljaykgfHwgMVwiXG4gICAgICAgICAgICAgICAgW2F0dHIueTFdPVwiMFwiXG4gICAgICAgICAgICAgICAgW2F0dHIueDJdPVwiZGF0YS54KHRpY2spIHx8IDFcIlxuICAgICAgICAgICAgICAgIFthdHRyLnkyXT1cInNpemU/LmhlaWdodFwiPjwvc3ZnOmxpbmU+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuXG48L25nLWNvbnRhaW5lcj5cblxuXG4iXX0=
|