UNPKG

26.2 kBJavaScriptView Raw
1import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, PLATFORM_ID, Inject } from '@angular/core';
2import { trigger, style, animate, transition } from '@angular/animations';
3import { createMouseEvent } from '../events';
4import { isPlatformBrowser } from '@angular/common';
5import { PlacementTypes } from './tooltip/position';
6import { StyleTypes } from './tooltip/style.type';
7import { ScaleType } from './types/scale-type.enum';
8export class TooltipArea {
9 constructor(platformId) {
10 this.platformId = platformId;
11 this.anchorOpacity = 0;
12 this.anchorPos = -1;
13 this.anchorValues = [];
14 this.placementTypes = PlacementTypes;
15 this.styleTypes = StyleTypes;
16 this.showPercentage = false;
17 this.tooltipDisabled = false;
18 this.hover = new EventEmitter();
19 }
20 getValues(xVal) {
21 const results = [];
22 for (const group of this.results) {
23 const item = group.series.find(d => d.name.toString() === xVal.toString());
24 let groupName = group.name;
25 if (groupName instanceof Date) {
26 groupName = groupName.toLocaleDateString();
27 }
28 if (item) {
29 const label = item.name;
30 let val = item.value;
31 if (this.showPercentage) {
32 val = (item.d1 - item.d0).toFixed(2) + '%';
33 }
34 let color;
35 if (this.colors.scaleType === ScaleType.Linear) {
36 let v = val;
37 if (item.d1) {
38 v = item.d1;
39 }
40 color = this.colors.getColor(v);
41 }
42 else {
43 color = this.colors.getColor(group.name);
44 }
45 const data = Object.assign({}, item, {
46 value: val,
47 name: label,
48 series: groupName,
49 min: item.min,
50 max: item.max,
51 color
52 });
53 results.push(data);
54 }
55 }
56 return results;
57 }
58 mouseMove(event) {
59 if (!isPlatformBrowser(this.platformId)) {
60 return;
61 }
62 const xPos = event.pageX - event.target.getBoundingClientRect().left;
63 const closestIndex = this.findClosestPointIndex(xPos);
64 const closestPoint = this.xSet[closestIndex];
65 this.anchorPos = this.xScale(closestPoint);
66 this.anchorPos = Math.max(0, this.anchorPos);
67 this.anchorPos = Math.min(this.dims.width, this.anchorPos);
68 this.anchorValues = this.getValues(closestPoint);
69 if (this.anchorPos !== this.lastAnchorPos) {
70 const ev = createMouseEvent('mouseleave');
71 this.tooltipAnchor.nativeElement.dispatchEvent(ev);
72 this.anchorOpacity = 0.7;
73 this.hover.emit({
74 value: closestPoint
75 });
76 this.showTooltip();
77 this.lastAnchorPos = this.anchorPos;
78 }
79 }
80 findClosestPointIndex(xPos) {
81 let minIndex = 0;
82 let maxIndex = this.xSet.length - 1;
83 let minDiff = Number.MAX_VALUE;
84 let closestIndex = 0;
85 while (minIndex <= maxIndex) {
86 const currentIndex = ((minIndex + maxIndex) / 2) | 0;
87 const currentElement = this.xScale(this.xSet[currentIndex]);
88 const curDiff = Math.abs(currentElement - xPos);
89 if (curDiff < minDiff) {
90 minDiff = curDiff;
91 closestIndex = currentIndex;
92 }
93 if (currentElement < xPos) {
94 minIndex = currentIndex + 1;
95 }
96 else if (currentElement > xPos) {
97 maxIndex = currentIndex - 1;
98 }
99 else {
100 minDiff = 0;
101 closestIndex = currentIndex;
102 break;
103 }
104 }
105 return closestIndex;
106 }
107 showTooltip() {
108 const event = createMouseEvent('mouseenter');
109 this.tooltipAnchor.nativeElement.dispatchEvent(event);
110 }
111 hideTooltip() {
112 const event = createMouseEvent('mouseleave');
113 this.tooltipAnchor.nativeElement.dispatchEvent(event);
114 this.anchorOpacity = 0;
115 this.lastAnchorPos = -1;
116 }
117 getToolTipText(tooltipItem) {
118 let result = '';
119 if (tooltipItem.series !== undefined) {
120 result += tooltipItem.series;
121 }
122 else {
123 result += '???';
124 }
125 result += ': ';
126 if (tooltipItem.value !== undefined) {
127 result += tooltipItem.value.toLocaleString();
128 }
129 if (tooltipItem.min !== undefined || tooltipItem.max !== undefined) {
130 result += ' (';
131 if (tooltipItem.min !== undefined) {
132 if (tooltipItem.max === undefined) {
133 result += '≥';
134 }
135 result += tooltipItem.min.toLocaleString();
136 if (tooltipItem.max !== undefined) {
137 result += ' - ';
138 }
139 }
140 else if (tooltipItem.max !== undefined) {
141 result += '≤';
142 }
143 if (tooltipItem.max !== undefined) {
144 result += tooltipItem.max.toLocaleString();
145 }
146 result += ')';
147 }
148 return result;
149 }
150}
151TooltipArea.decorators = [
152 { type: Component, args: [{
153 selector: 'g[ngx-charts-tooltip-area]',
154 template: `
155 <svg:g>
156 <svg:rect
157 class="tooltip-area"
158 [attr.x]="0"
159 y="0"
160 [attr.width]="dims.width"
161 [attr.height]="dims.height"
162 style="opacity: 0; cursor: 'auto';"
163 (mousemove)="mouseMove($event)"
164 (mouseleave)="hideTooltip()"
165 />
166 <ng-template #defaultTooltipTemplate let-model="model">
167 <xhtml:div class="area-tooltip-container">
168 <xhtml:div *ngFor="let tooltipItem of model" class="tooltip-item">
169 <xhtml:span class="tooltip-item-color" [style.background-color]="tooltipItem.color"></xhtml:span>
170 {{ getToolTipText(tooltipItem) }}
171 </xhtml:div>
172 </xhtml:div>
173 </ng-template>
174 <svg:rect
175 #tooltipAnchor
176 [@animationState]="anchorOpacity !== 0 ? 'active' : 'inactive'"
177 class="tooltip-anchor"
178 [attr.x]="anchorPos"
179 y="0"
180 [attr.width]="1"
181 [attr.height]="dims.height"
182 [style.opacity]="anchorOpacity"
183 [style.pointer-events]="'none'"
184 ngx-tooltip
185 [tooltipDisabled]="tooltipDisabled"
186 [tooltipPlacement]="placementTypes.Right"
187 [tooltipType]="styleTypes.tooltip"
188 [tooltipSpacing]="15"
189 [tooltipTemplate]="tooltipTemplate ? tooltipTemplate : defaultTooltipTemplate"
190 [tooltipContext]="anchorValues"
191 [tooltipImmediateExit]="true"
192 />
193 </svg:g>
194 `,
195 changeDetection: ChangeDetectionStrategy.OnPush,
196 animations: [
197 trigger('animationState', [
198 transition('inactive => active', [
199 style({
200 opacity: 0
201 }),
202 animate(250, style({ opacity: 0.7 }))
203 ]),
204 transition('active => inactive', [
205 style({
206 opacity: 0.7
207 }),
208 animate(250, style({ opacity: 0 }))
209 ])
210 ])
211 ]
212 },] }
213];
214TooltipArea.ctorParameters = () => [
215 { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }
216];
217TooltipArea.propDecorators = {
218 dims: [{ type: Input }],
219 xSet: [{ type: Input }],
220 xScale: [{ type: Input }],
221 yScale: [{ type: Input }],
222 results: [{ type: Input }],
223 colors: [{ type: Input }],
224 showPercentage: [{ type: Input }],
225 tooltipDisabled: [{ type: Input }],
226 tooltipTemplate: [{ type: Input }],
227 hover: [{ type: Output }],
228 tooltipAnchor: [{ type: ViewChild, args: ['tooltipAnchor', { static: false },] }]
229};
230//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC1hcmVhLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N3aW1sYW5lL25neC1jaGFydHMvc3JjL2xpYi9jb21tb24vdG9vbHRpcC1hcmVhLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFNBQVMsRUFDVCx1QkFBdUIsRUFFdkIsV0FBVyxFQUNYLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXBELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBMEVwRCxNQUFNLE9BQU8sV0FBVztJQXVCdEIsWUFBeUMsVUFBZTtRQUFmLGVBQVUsR0FBVixVQUFVLENBQUs7UUF0QnhELGtCQUFhLEdBQVcsQ0FBQyxDQUFDO1FBQzFCLGNBQVMsR0FBVyxDQUFDLENBQUMsQ0FBQztRQUN2QixpQkFBWSxHQUFjLEVBQUUsQ0FBQztRQUc3QixtQkFBYyxHQUFHLGNBQWMsQ0FBQztRQUNoQyxlQUFVLEdBQUcsVUFBVSxDQUFDO1FBUWYsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFDaEMsb0JBQWUsR0FBWSxLQUFLLENBQUM7UUFHaEMsVUFBSyxHQUFpQyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBSVIsQ0FBQztJQUU1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QUUsQ0FBQyxDQUFDO3lCQUN0QyxDQUFDO3dCQUNGLFVBQVUsQ0FBQyxvQkFBb0IsRUFBRTs0QkFDL0IsS0FBSyxDQUFDO2dDQUNKLE9BQU8sRUFBRSxHQUFHOzZCQUNiLENBQUM7NEJBQ0YsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQzt5QkFDcEMsQ0FBQztxQkFDSCxDQUFDO2lCQUNIO2FBQ0Y7Ozs0Q0F3QmMsTUFBTSxTQUFDLFdBQVc7OzttQkFkOUIsS0FBSzttQkFDTCxLQUFLO3FCQUNMLEtBQUs7cUJBQ0wsS0FBSztzQkFDTCxLQUFLO3FCQUNMLEtBQUs7NkJBQ0wsS0FBSzs4QkFDTCxLQUFLOzhCQUNMLEtBQUs7b0JBRUwsTUFBTTs0QkFFTixTQUFTLFNBQUMsZUFBZSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyLFxuICBWaWV3Q2hpbGQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBUZW1wbGF0ZVJlZixcbiAgUExBVEZPUk1fSUQsXG4gIEluamVjdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRyaWdnZXIsIHN0eWxlLCBhbmltYXRlLCB0cmFuc2l0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVNb3VzZUV2ZW50IH0gZnJvbSAnLi4vZXZlbnRzJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbG9ySGVscGVyIH0gZnJvbSAnLi4vY29tbW9uL2NvbG9yLmhlbHBlcic7XG5pbXBvcnQgeyBQbGFjZW1lbnRUeXBlcyB9IGZyb20gJy4vdG9vbHRpcC9wb3NpdGlvbic7XG5pbXBvcnQgeyBTdHlsZVR5cGVzIH0gZnJvbSAnLi90b29sdGlwL3N0eWxlLnR5cGUnO1xuaW1wb3J0IHsgVmlld0RpbWVuc2lvbnMgfSBmcm9tICcuL3R5cGVzL3ZpZXctZGltZW5zaW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBTY2FsZVR5cGUgfSBmcm9tICcuL3R5cGVzL3NjYWxlLXR5cGUuZW51bSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVG9vbHRpcCB7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIGQwOiBudW1iZXI7XG4gIGQxOiBudW1iZXI7XG4gIG1heDogbnVtYmVyO1xuICBtaW46IG51bWJlcjtcbiAgbmFtZTogYW55O1xuICBzZXJpZXM6IGFueTtcbiAgdmFsdWU6IGFueTtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZ1tuZ3gtY2hhcnRzLXRvb2x0aXAtYXJlYV0nLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxzdmc6Zz5cbiAgICAgIDxzdmc6cmVjdFxuICAgICAgICBjbGFzcz1cInRvb2x0aXAtYXJlYVwiXG4gICAgICAgIFthdHRyLnhdPVwiMFwiXG4gICAgICAgIHk9XCIwXCJcbiAgICAgICAgW2F0dHIud2lkdGhdPVwiZGltcy53aWR0aFwiXG4gICAgICAgIFthdHRyLmhlaWdodF09XCJkaW1zLmhlaWdodFwiXG4gICAgICAgIHN0eWxlPVwib3BhY2l0eTogMDsgY3Vyc29yOiAnYXV0byc7XCJcbiAgICAgICAgKG1vdXNlbW92ZSk9XCJtb3VzZU1vdmUoJGV2ZW50KVwiXG4gICAgICAgIChtb3VzZWxlYXZlKT1cImhpZGVUb29sdGlwKClcIlxuICAgICAgLz5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFRvb2x0aXBUZW1wbGF0ZSBsZXQtbW9kZWw9XCJtb2RlbFwiPlxuICAgICAgICA8eGh0bWw6ZGl2IGNsYXNzPVwiYXJlYS10b29sdGlwLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDx4aHRtbDpkaXYgKm5nRm9yPVwibGV0IHRvb2x0aXBJdGVtIG9mIG1vZGVsXCIgY2xhc3M9XCJ0b29sdGlwLWl0ZW1cIj5cbiAgICAgICAgICAgIDx4aHRtbDpzcGFuIGNsYXNzPVwidG9vbHRpcC1pdGVtLWNvbG9yXCIgW3N0eWxlLmJhY2tncm91bmQtY29sb3JdPVwidG9vbHRpcEl0ZW0uY29sb3JcIj48L3hodG1sOnNwYW4+XG4gICAgICAgICAgICB7eyBnZXRUb29sVGlwVGV4dCh0b29sdGlwSXRlbSkgfX1cbiAgICAgICAgICA8L3hodG1sOmRpdj5cbiAgICAgICAgPC94aHRtbDpkaXY+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPHN2ZzpyZWN0XG4gICAgICAgICN0b29sdGlwQW5jaG9yXG4gICAgICAgIFtAYW5pbWF0aW9uU3RhdGVdPVwiYW5jaG9yT3BhY2l0eSAhPT0gMCA/ICdhY3RpdmUnIDogJ2luYWN0aXZlJ1wiXG4gICAgICAgIGNsYXNzPVwidG9vbHRpcC1hbmNob3JcIlxuICAgICAgICBbYXR0ci54XT1cImFuY2hvclBvc1wiXG4gICAgICAgIHk9XCIwXCJcbiAgICAgICAgW2F0dHIud2lkdGhdPVwiMVwiXG4gICAgICAgIFthdHRyLmhlaWdodF09XCJkaW1zLmhlaWdodFwiXG4gICAgICAgIFtzdHlsZS5vcGFjaXR5XT1cImFuY2hvck9wYWNpdHlcIlxuICAgICAgICBbc3R5bGUucG9pbnRlci1ldmVudHNdPVwiJ25vbmUnXCJcbiAgICAgICAgbmd4LXRvb2x0aXBcbiAgICAgICAgW3Rvb2x0aXBEaXNhYmxlZF09XCJ0b29sdGlwRGlzYWJsZWRcIlxuICAgICAgICBbdG9vbHRpcFBsYWNlbWVudF09XCJwbGFjZW1lbnRUeXBlcy5SaWdodFwiXG4gICAgICAgIFt0b29sdGlwVHlwZV09XCJzdHlsZVR5cGVzLnRvb2x0aXBcIlxuICAgICAgICBbdG9vbHRpcFNwYWNpbmddPVwiMTVcIlxuICAgICAgICBbdG9vbHRpcFRlbXBsYXRlXT1cInRvb2x0aXBUZW1wbGF0ZSA/IHRvb2x0aXBUZW1wbGF0ZSA6IGRlZmF1bHRUb29sdGlwVGVtcGxhdGVcIlxuICAgICAgICBbdG9vbHRpcENvbnRleHRdPVwiYW5jaG9yVmFsdWVzXCJcbiAgICAgICAgW3Rvb2x0aXBJbW1lZGlhdGVFeGl0XT1cInRydWVcIlxuICAgICAgLz5cbiAgICA8L3N2ZzpnPlxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ2FuaW1hdGlvblN0YXRlJywgW1xuICAgICAgdHJhbnNpdGlvbignaW5hY3RpdmUgPT4gYWN0aXZlJywgW1xuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgb3BhY2l0eTogMFxuICAgICAgICB9KSxcbiAgICAgICAgYW5pbWF0ZSgyNTAsIHN0eWxlKHsgb3BhY2l0eTogMC43IH0pKVxuICAgICAgXSksXG4gICAgICB0cmFuc2l0aW9uKCdhY3RpdmUgPT4gaW5hY3RpdmUnLCBbXG4gICAgICAgIHN0eWxlKHtcbiAgICAgICAgICBvcGFjaXR5OiAwLjdcbiAgICAgICAgfSksXG4gICAgICAgIGFuaW1hdGUoMjUwLCBzdHlsZSh7IG9wYWNpdHk6IDAgfSkpXG4gICAgICBdKVxuICAgIF0pXG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgVG9vbHRpcEFyZWEge1xuICBhbmNob3JPcGFjaXR5OiBudW1iZXIgPSAwO1xuICBhbmNob3JQb3M6IG51bWJlciA9IC0xO1xuICBhbmNob3JWYWx1ZXM6IFRvb2x0aXBbXSA9IFtdO1xuICBsYXN0QW5jaG9yUG9zOiBudW1iZXI7XG5cbiAgcGxhY2VtZW50VHlwZXMgPSBQbGFjZW1lbnRUeXBlcztcbiAgc3R5bGVUeXBlcyA9IFN0eWxlVHlwZXM7XG5cbiAgQElucHV0KCkgZGltczogVmlld0RpbWVuc2lvbnM7XG4gIEBJbnB1dCgpIHhTZXQ6IGFueVtdO1xuICBASW5wdXQoKSB4U2NhbGU7XG4gIEBJbnB1dCgpIHlTY2FsZTtcbiAgQElucHV0KCkgcmVzdWx0czogYW55W107XG4gIEBJbnB1dCgpIGNvbG9yczogQ29sb3JIZWxwZXI7XG4gIEBJbnB1dCgpIHNob3dQZXJjZW50YWdlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHRvb2x0aXBEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSB0b29sdGlwVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgQE91dHB1dCgpIGhvdmVyOiBFdmVudEVtaXR0ZXI8eyB2YWx1ZTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3Rvb2x0aXBBbmNob3InLCB7IHN0YXRpYzogZmFsc2UgfSkgdG9vbHRpcEFuY2hvcjtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IGFueSkge31cblxuICBnZXRWYWx1ZXMoeFZhbCk6IFRvb2x0aXBbXSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLnJlc3VsdHMpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBncm91cC5zZXJpZXMuZmluZChkID0+IGQubmFtZS50b1N0cmluZygpID09PSB4VmFsLnRvU3RyaW5nKCkpO1xuICAgICAgbGV0IGdyb3VwTmFtZSA9IGdyb3VwLm5hbWU7XG4gICAgICBpZiAoZ3JvdXBOYW1lIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBncm91cE5hbWUgPSBncm91cE5hbWUudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpdGVtKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsID0gaXRlbS5uYW1lO1xuICAgICAgICBsZXQgdmFsID0gaXRlbS52YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMuc2hvd1BlcmNlbnRhZ2UpIHtcbiAgICAgICAgICB2YWwgPSAoaXRlbS5kMSAtIGl0ZW0uZDApLnRvRml4ZWQoMikgKyAnJSc7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNvbG9yO1xuICAgICAgICBpZiAodGhpcy5jb2xvcnMuc2NhbGVUeXBlID09PSBTY2FsZVR5cGUuTGluZWFyKSB7XG4gICAgICAgICAgbGV0IHYgPSB2YWw7XG4gICAgICAgICAgaWYgKGl0ZW0uZDEpIHtcbiAgICAgICAgICAgIHYgPSBpdGVtLmQxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb2xvciA9IHRoaXMuY29sb3JzLmdldENvbG9yKHYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbG9yID0gdGhpcy5jb2xvcnMuZ2V0Q29sb3IoZ3JvdXAubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhID0gT2JqZWN0LmFzc2lnbih7fSwgaXRlbSwge1xuICAgICAgICAgIHZhbHVlOiB2YWwsXG4gICAgICAgICAgbmFtZTogbGFiZWwsXG4gICAgICAgICAgc2VyaWVzOiBncm91cE5hbWUsXG4gICAgICAgICAgbWluOiBpdGVtLm1pbixcbiAgICAgICAgICBtYXg6IGl0ZW0ubWF4LFxuICAgICAgICAgIGNvbG9yXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3VsdHMucHVzaChkYXRhKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIG1vdXNlTW92ZShldmVudCkge1xuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHhQb3MgPSBldmVudC5wYWdlWCAtIGV2ZW50LnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0O1xuXG4gICAgY29uc3QgY2xvc2VzdEluZGV4ID0gdGhpcy5maW5kQ2xvc2VzdFBvaW50SW5kZXgoeFBvcyk7XG4gICAgY29uc3QgY2xvc2VzdFBvaW50ID0gdGhpcy54U2V0W2Nsb3Nlc3RJbmRleF07XG4gICAgdGhpcy5hbmNob3JQb3MgPSB0aGlzLnhTY2FsZShjbG9zZXN0UG9pbnQpO1xuICAgIHRoaXMuYW5jaG9yUG9zID0gTWF0aC5tYXgoMCwgdGhpcy5hbmNob3JQb3MpO1xuICAgIHRoaXMuYW5jaG9yUG9zID0gTWF0aC5taW4odGhpcy5kaW1zLndpZHRoLCB0aGlzLmFuY2hvclBvcyk7XG5cbiAgICB0aGlzLmFuY2hvclZhbHVlcyA9IHRoaXMuZ2V0VmFsdWVzKGNsb3Nlc3RQb2ludCk7XG4gICAgaWYgKHRoaXMuYW5jaG9yUG9zICE9PSB0aGlzLmxhc3RBbmNob3JQb3MpIHtcbiAgICAgIGNvbnN0IGV2ID0gY3JlYXRlTW91c2VFdmVudCgnbW91c2VsZWF2ZScpO1xuICAgICAgdGhpcy50b29sdGlwQW5jaG9yLm5hdGl2ZUVsZW1lbnQuZGlzcGF0Y2hFdmVudChldik7XG4gICAgICB0aGlzLmFuY2hvck9wYWNpdHkgPSAwLjc7XG4gICAgICB0aGlzLmhvdmVyLmVtaXQoe1xuICAgICAgICB2YWx1ZTogY2xvc2VzdFBvaW50XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2hvd1Rvb2x0aXAoKTtcblxuICAgICAgdGhpcy5sYXN0QW5jaG9yUG9zID0gdGhpcy5hbmNob3JQb3M7XG4gICAgfVxuICB9XG5cbiAgZmluZENsb3Nlc3RQb2ludEluZGV4KHhQb3M6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IG1pbkluZGV4ID0gMDtcbiAgICBsZXQgbWF4SW5kZXggPSB0aGlzLnhTZXQubGVuZ3RoIC0gMTtcbiAgICBsZXQgbWluRGlmZiA9IE51bWJlci5NQVhfVkFMVUU7XG4gICAgbGV0IGNsb3Nlc3RJbmRleCA9IDA7XG5cbiAgICB3aGlsZSAobWluSW5kZXggPD0gbWF4SW5kZXgpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9ICgobWluSW5kZXggKyBtYXhJbmRleCkgLyAyKSB8IDA7XG4gICAgICBjb25zdCBjdXJyZW50RWxlbWVudCA9IHRoaXMueFNjYWxlKHRoaXMueFNldFtjdXJyZW50SW5kZXhdKTtcblxuICAgICAgY29uc3QgY3VyRGlmZiA9IE1hdGguYWJzKGN1cnJlbnRFbGVtZW50IC0geFBvcyk7XG5cbiAgICAgIGlmIChjdXJEaWZmIDwgbWluRGlmZikge1xuICAgICAgICBtaW5EaWZmID0gY3VyRGlmZjtcbiAgICAgICAgY2xvc2VzdEluZGV4ID0gY3VycmVudEluZGV4O1xuICAgICAgfVxuXG4gICAgICBpZiAoY3VycmVudEVsZW1lbnQgPCB4UG9zKSB7XG4gICAgICAgIG1pbkluZGV4ID0gY3VycmVudEluZGV4ICsgMTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudEVsZW1lbnQgPiB4UG9zKSB7XG4gICAgICAgIG1heEluZGV4ID0gY3VycmVudEluZGV4IC0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pbkRpZmYgPSAwO1xuICAgICAgICBjbG9zZXN0SW5kZXggPSBjdXJyZW50SW5kZXg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjbG9zZXN0SW5kZXg7XG4gIH1cblxuICBzaG93VG9vbHRpcCgpOiB2b2lkIHtcbiAgICBjb25zdCBldmVudCA9IGNyZWF0ZU1vdXNlRXZlbnQoJ21vdXNlZW50ZXInKTtcbiAgICB0aGlzLnRvb2x0aXBBbmNob3IubmF0aXZlRWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgfVxuXG4gIGhpZGVUb29sdGlwKCk6IHZvaWQge1xuICAgIGNvbnN0IGV2ZW50ID0gY3JlYXRlTW91c2VFdmVudCgnbW91c2VsZWF2ZScpO1xuICAgIHRoaXMudG9vbHRpcEFuY2hvci5uYXRpdmVFbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuYW5jaG9yT3BhY2l0eSA9IDA7XG4gICAgdGhpcy5sYXN0QW5jaG9yUG9zID0gLTE7XG4gIH1cblxuICBnZXRUb29sVGlwVGV4dCh0b29sdGlwSXRlbTogVG9vbHRpcCk6IHN0cmluZyB7XG4gICAgbGV0IHJlc3VsdDogc3RyaW5nID0gJyc7XG4gICAgaWYgKHRvb2x0aXBJdGVtLnNlcmllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgKz0gdG9vbHRpcEl0ZW0uc2VyaWVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgKz0gJz8/Pyc7XG4gICAgfVxuICAgIHJlc3VsdCArPSAnOiAnO1xuICAgIGlmICh0b29sdGlwSXRlbS52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgKz0gdG9vbHRpcEl0ZW0udmFsdWUudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHRvb2x0aXBJdGVtLm1pbiAhPT0gdW5kZWZpbmVkIHx8IHRvb2x0aXBJdGVtLm1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgKz0gJyAoJztcbiAgICAgIGlmICh0b29sdGlwSXRlbS5taW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodG9vbHRpcEl0ZW0ubWF4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgKz0gJ+KJpSc7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ICs9IHRvb2x0aXBJdGVtLm1pbi50b0xvY2FsZVN0cmluZygpO1xuICAgICAgICBpZiAodG9vbHRpcEl0ZW0ubWF4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgKz0gJyAtICc7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodG9vbHRpcEl0ZW0ubWF4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVzdWx0ICs9ICfiiaQnO1xuICAgICAgfVxuICAgICAgaWYgKHRvb2x0aXBJdGVtLm1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlc3VsdCArPSB0b29sdGlwSXRlbS5tYXgudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCArPSAnKSc7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiJdfQ==
\No newline at end of file