@visuno/angular 0.0.0-stage → 0.1.0

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.
Files changed (175) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +56 -2
  3. package/account-table/account-table.component.d.ts +72 -0
  4. package/action-log/action-log.component.d.ts +41 -0
  5. package/activity-heatmap/activity-heatmap.component.d.ts +67 -0
  6. package/agent-inbox/agent-inbox.component.d.ts +75 -0
  7. package/agent-lanes/agent-lanes.component.d.ts +152 -0
  8. package/agent-phases/agent-phases.component.d.ts +62 -0
  9. package/agent-run-timeline/agent-run-timeline.component.d.ts +113 -0
  10. package/agent-tree/agent-tree.component.d.ts +80 -0
  11. package/answer-action-bar/answer-action-bar.component.d.ts +110 -0
  12. package/artifact-card/artifact-card.component.d.ts +145 -0
  13. package/attachment-tray/attachment-tray.component.d.ts +84 -0
  14. package/badge/badge.component.d.ts +25 -0
  15. package/bar-chart/bar-chart.component.d.ts +87 -0
  16. package/browser-session/browser-session.component.d.ts +70 -0
  17. package/buttons/buttons.component.d.ts +63 -0
  18. package/card/card.component.d.ts +21 -0
  19. package/change-review/change-review.component.d.ts +97 -0
  20. package/citation-hover-card/citation-hover-card.component.d.ts +95 -0
  21. package/code-viewer/code-viewer.component.d.ts +86 -0
  22. package/composer/composer.component.d.ts +114 -0
  23. package/context-meter/context-meter.component.d.ts +60 -0
  24. package/core/icon.component.d.ts +10 -0
  25. package/core/reduced-motion.service.d.ts +15 -0
  26. package/decision-prompt/decision-prompt.component.d.ts +56 -0
  27. package/design-review/design-review.component.d.ts +108 -0
  28. package/design-tuner/design-tuner.component.d.ts +75 -0
  29. package/details-panel/details-panel.component.d.ts +150 -0
  30. package/donut-chart/donut-chart.component.d.ts +63 -0
  31. package/draft-review/draft-review.component.d.ts +128 -0
  32. package/error-recovery/error-recovery.component.d.ts +59 -0
  33. package/esm2022/account-table/account-table.component.mjs +399 -0
  34. package/esm2022/action-log/action-log.component.mjs +177 -0
  35. package/esm2022/activity-heatmap/activity-heatmap.component.mjs +285 -0
  36. package/esm2022/agent-inbox/agent-inbox.component.mjs +284 -0
  37. package/esm2022/agent-lanes/agent-lanes.component.mjs +600 -0
  38. package/esm2022/agent-phases/agent-phases.component.mjs +300 -0
  39. package/esm2022/agent-run-timeline/agent-run-timeline.component.mjs +412 -0
  40. package/esm2022/agent-tree/agent-tree.component.mjs +393 -0
  41. package/esm2022/answer-action-bar/answer-action-bar.component.mjs +636 -0
  42. package/esm2022/artifact-card/artifact-card.component.mjs +916 -0
  43. package/esm2022/attachment-tray/attachment-tray.component.mjs +402 -0
  44. package/esm2022/badge/badge.component.mjs +97 -0
  45. package/esm2022/bar-chart/bar-chart.component.mjs +300 -0
  46. package/esm2022/browser-session/browser-session.component.mjs +352 -0
  47. package/esm2022/buttons/buttons.component.mjs +215 -0
  48. package/esm2022/card/card.component.mjs +107 -0
  49. package/esm2022/change-review/change-review.component.mjs +398 -0
  50. package/esm2022/citation-hover-card/citation-hover-card.component.mjs +360 -0
  51. package/esm2022/code-viewer/code-viewer.component.mjs +291 -0
  52. package/esm2022/composer/composer.component.mjs +743 -0
  53. package/esm2022/context-meter/context-meter.component.mjs +275 -0
  54. package/esm2022/core/icon.component.mjs +111 -0
  55. package/esm2022/core/reduced-motion.service.mjs +34 -0
  56. package/esm2022/decision-prompt/decision-prompt.component.mjs +259 -0
  57. package/esm2022/design-review/design-review.component.mjs +428 -0
  58. package/esm2022/design-tuner/design-tuner.component.mjs +341 -0
  59. package/esm2022/details-panel/details-panel.component.mjs +537 -0
  60. package/esm2022/donut-chart/donut-chart.component.mjs +240 -0
  61. package/esm2022/draft-review/draft-review.component.mjs +549 -0
  62. package/esm2022/error-recovery/error-recovery.component.mjs +231 -0
  63. package/esm2022/eval-results/eval-results.component.mjs +368 -0
  64. package/esm2022/feedback-sheet/feedback-sheet.component.mjs +411 -0
  65. package/esm2022/field-extraction/field-extraction.component.mjs +368 -0
  66. package/esm2022/funnel-chart/funnel-chart.component.mjs +258 -0
  67. package/esm2022/grid/grid.component.mjs +66 -0
  68. package/esm2022/health-score/health-score.component.mjs +420 -0
  69. package/esm2022/human-handoff/human-handoff.component.mjs +676 -0
  70. package/esm2022/image-generation/image-generation.component.mjs +1028 -0
  71. package/esm2022/inline-text-diff/inline-text-diff.component.mjs +390 -0
  72. package/esm2022/launch-checklist/launch-checklist.component.mjs +229 -0
  73. package/esm2022/line-chart/line-chart.component.mjs +417 -0
  74. package/esm2022/live-answer/live-answer.component.mjs +411 -0
  75. package/esm2022/metric-insight/metric-insight.component.mjs +511 -0
  76. package/esm2022/modal/modal.component.mjs +202 -0
  77. package/esm2022/model-picker/model-picker.component.mjs +491 -0
  78. package/esm2022/permission-gate/permission-gate.component.mjs +498 -0
  79. package/esm2022/plan-review/plan-review.component.mjs +432 -0
  80. package/esm2022/progress/progress.component.mjs +503 -0
  81. package/esm2022/prompt-library/prompt-library.component.mjs +453 -0
  82. package/esm2022/prompt-starters/prompt-starters.component.mjs +272 -0
  83. package/esm2022/proposal-card/proposal-card.component.mjs +402 -0
  84. package/esm2022/public-api.mjs +88 -0
  85. package/esm2022/radar-chart/radar-chart.component.mjs +500 -0
  86. package/esm2022/radial-goals/radial-goals.component.mjs +418 -0
  87. package/esm2022/reasoning-trail/reasoning-trail.component.mjs +284 -0
  88. package/esm2022/response-versions/response-versions.component.mjs +288 -0
  89. package/esm2022/rewrite-toolbar/rewrite-toolbar.component.mjs +397 -0
  90. package/esm2022/rich-text-editor/rich-text-editor.component.mjs +1755 -0
  91. package/esm2022/run-cost/run-cost.component.mjs +215 -0
  92. package/esm2022/run-queue/run-queue.component.mjs +481 -0
  93. package/esm2022/run-summary/run-summary.component.mjs +331 -0
  94. package/esm2022/scatter-chart/scatter-chart.component.mjs +705 -0
  95. package/esm2022/score-breakdown/score-breakdown.component.mjs +460 -0
  96. package/esm2022/segmented-control/segmented-control.component.mjs +180 -0
  97. package/esm2022/source-stack/source-stack.component.mjs +245 -0
  98. package/esm2022/stat-cards/stat-cards.component.mjs +258 -0
  99. package/esm2022/status-pill/status-pill.component.mjs +305 -0
  100. package/esm2022/steering/steering.component.mjs +343 -0
  101. package/esm2022/step-loader/step-loader.component.mjs +209 -0
  102. package/esm2022/task-table/task-table.component.mjs +534 -0
  103. package/esm2022/terminal-stream/terminal-stream.component.mjs +583 -0
  104. package/esm2022/thinking/thinking.component.mjs +276 -0
  105. package/esm2022/thinking-states/thinking-states.component.mjs +333 -0
  106. package/esm2022/thread-panel/thread-panel.component.mjs +271 -0
  107. package/esm2022/toast/toast.component.mjs +195 -0
  108. package/esm2022/toast-stack/toast-stack.component.mjs +301 -0
  109. package/esm2022/tool-call/tool-call.component.mjs +273 -0
  110. package/esm2022/tooltip/tooltip.component.mjs +417 -0
  111. package/esm2022/top-pages/top-pages.component.mjs +240 -0
  112. package/esm2022/trace-view/trace-view.component.mjs +440 -0
  113. package/esm2022/visuno-angular.mjs +5 -0
  114. package/esm2022/voice-capture/voice-capture.component.mjs +650 -0
  115. package/esm2022/voice-orb/voice-orb.component.mjs +538 -0
  116. package/esm2022/web-search/web-search.component.mjs +374 -0
  117. package/eval-results/eval-results.component.d.ts +67 -0
  118. package/feedback-sheet/feedback-sheet.component.d.ts +74 -0
  119. package/fesm2022/visuno-angular.mjs +31992 -0
  120. package/fesm2022/visuno-angular.mjs.map +1 -0
  121. package/field-extraction/field-extraction.component.d.ts +82 -0
  122. package/funnel-chart/funnel-chart.component.d.ts +70 -0
  123. package/grid/grid.component.d.ts +22 -0
  124. package/health-score/health-score.component.d.ts +87 -0
  125. package/human-handoff/human-handoff.component.d.ts +125 -0
  126. package/image-generation/image-generation.component.d.ts +253 -0
  127. package/index.d.ts +5 -0
  128. package/inline-text-diff/inline-text-diff.component.d.ts +76 -0
  129. package/launch-checklist/launch-checklist.component.d.ts +46 -0
  130. package/line-chart/line-chart.component.d.ts +89 -0
  131. package/live-answer/live-answer.component.d.ts +110 -0
  132. package/metric-insight/metric-insight.component.d.ts +110 -0
  133. package/modal/modal.component.d.ts +37 -0
  134. package/model-picker/model-picker.component.d.ts +97 -0
  135. package/package.json +51 -4
  136. package/permission-gate/permission-gate.component.d.ts +100 -0
  137. package/plan-review/plan-review.component.d.ts +86 -0
  138. package/progress/progress.component.d.ts +91 -0
  139. package/prompt-library/prompt-library.component.d.ts +121 -0
  140. package/prompt-starters/prompt-starters.component.d.ts +65 -0
  141. package/proposal-card/proposal-card.component.d.ts +101 -0
  142. package/public-api.d.ts +82 -0
  143. package/radar-chart/radar-chart.component.d.ts +110 -0
  144. package/radial-goals/radial-goals.component.d.ts +90 -0
  145. package/reasoning-trail/reasoning-trail.component.d.ts +73 -0
  146. package/response-versions/response-versions.component.d.ts +54 -0
  147. package/rewrite-toolbar/rewrite-toolbar.component.d.ts +92 -0
  148. package/rich-text-editor/rich-text-editor.component.d.ts +180 -0
  149. package/run-cost/run-cost.component.d.ts +43 -0
  150. package/run-queue/run-queue.component.d.ts +93 -0
  151. package/run-summary/run-summary.component.d.ts +81 -0
  152. package/scatter-chart/scatter-chart.component.d.ts +139 -0
  153. package/score-breakdown/score-breakdown.component.d.ts +107 -0
  154. package/segmented-control/segmented-control.component.d.ts +44 -0
  155. package/source-stack/source-stack.component.d.ts +60 -0
  156. package/stat-cards/stat-cards.component.d.ts +86 -0
  157. package/status-pill/status-pill.component.d.ts +64 -0
  158. package/steering/steering.component.d.ts +75 -0
  159. package/step-loader/step-loader.component.d.ts +40 -0
  160. package/styles.css +424 -0
  161. package/task-table/task-table.component.d.ts +114 -0
  162. package/terminal-stream/terminal-stream.component.d.ts +110 -0
  163. package/thinking/thinking.component.d.ts +63 -0
  164. package/thinking-states/thinking-states.component.d.ts +51 -0
  165. package/thread-panel/thread-panel.component.d.ts +75 -0
  166. package/toast/toast.component.d.ts +56 -0
  167. package/toast-stack/toast-stack.component.d.ts +72 -0
  168. package/tokens.css +424 -0
  169. package/tool-call/tool-call.component.d.ts +61 -0
  170. package/tooltip/tooltip.component.d.ts +89 -0
  171. package/top-pages/top-pages.component.d.ts +75 -0
  172. package/trace-view/trace-view.component.d.ts +95 -0
  173. package/voice-capture/voice-capture.component.d.ts +103 -0
  174. package/voice-orb/voice-orb.component.d.ts +78 -0
  175. package/web-search/web-search.component.d.ts +77 -0
@@ -0,0 +1,705 @@
1
+ // framework/angular/scatter-chart/scatter-chart.component.ts
2
+ //
3
+ // Native Angular port of framework/react/scatter-chart/ScatterChart.tsx.
4
+ // Every run is a dot by cost (along) and eval score (up), sized by tokens, with
5
+ // a colour and a shape per series. Dashed median lines cut the plot into four
6
+ // named quadrants; pointing snaps to the nearest run and a drag draws a box that
7
+ // selects the runs in it. Inputs mirror the React props; React callbacks become
8
+ // @Output EventEmitters. The plot measures itself with a ResizeObserver set up
9
+ // in ngAfterViewInit and torn down in ngOnDestroy, mirroring the vanilla JS
10
+ // (scatter-chart.js). Styling flows only through the --vo-* tokens.
11
+ //
12
+ // Icons: only the "spark" glyph is used (the note and the "Ask the agent why"
13
+ // button), via VoIconComponent — the same glyph the React/Vanilla originals use.
14
+ import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject, } from '@angular/core';
15
+ import { VoIconComponent } from '../core/icon.component';
16
+ import { ReducedMotionService } from '../core/reduced-motion.service';
17
+ import * as i0 from "@angular/core";
18
+ const PAL = [
19
+ 'var(--vo-c1)',
20
+ 'var(--vo-c2)',
21
+ 'var(--vo-c3)',
22
+ 'var(--vo-c4)',
23
+ 'var(--vo-c5)',
24
+ 'var(--vo-c6)',
25
+ ];
26
+ const SHAPES = ['circle', 'square', 'triangle'];
27
+ const median = (a) => {
28
+ if (!a.length)
29
+ return 0;
30
+ const s = [...a].sort((p, q) => p - q);
31
+ const m = s.length >> 1;
32
+ return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
33
+ };
34
+ export class ScatterChartComponent {
35
+ constructor() {
36
+ this.runs = [];
37
+ this.series = [];
38
+ this.className = '';
39
+ this.title = 'Cost vs quality';
40
+ /** [min, max] of each axis. */
41
+ this.xDomain = [0, 0.6];
42
+ this.yDomain = [60, 100];
43
+ /** Where the labels go along the bottom. A narrow chart keeps the two ends and the middle. */
44
+ this.xTicks = [0, 0.2, 0.4, 0.6];
45
+ /** Where the gridlines and their labels go up the side. A narrow chart keeps the two ends and the middle. */
46
+ this.yTicks = [60, 80, 100];
47
+ this.xTitle = 'Cost per run (USD)';
48
+ this.yTitle = 'Eval score (%)';
49
+ this.formatX = (x) => '$' + x.toFixed(2);
50
+ this.formatY = (y) => Math.round(y) + '%';
51
+ this.formatSize = (s) => Math.round(s) + 'k tokens';
52
+ /** The four quadrants the medians make, from the top left, clockwise. A narrow chart keeps the median lines and leaves the names out. */
53
+ this.quadrants = [
54
+ 'Cheap, good',
55
+ 'Costly, good',
56
+ 'Costly, weaker',
57
+ 'Cheap, weaker',
58
+ ];
59
+ /** Runs to ring, like outliers the agent found. */
60
+ this.ringed = [];
61
+ this.selectedChange = new EventEmitter();
62
+ /** Adds "Ask the agent why" to a selection. Return the answer and it streams in. */
63
+ this.ask = new EventEmitter();
64
+ this.reduced = inject(ReducedMotionService);
65
+ this.cdr = inject(ChangeDetectorRef);
66
+ // measured geometry
67
+ this.W = 0;
68
+ this.H = 0;
69
+ this.narrow = false;
70
+ this.l = 44;
71
+ this.b = 40;
72
+ this.t = 6;
73
+ this.rr = 8;
74
+ // render state
75
+ this.dots = [];
76
+ this.ringDots = [];
77
+ this.xt = [];
78
+ this.yt = [];
79
+ this.mx = 0;
80
+ this.my = 0;
81
+ this.hot = -1;
82
+ this.hr = null;
83
+ this.box = null;
84
+ this.ttX = 0;
85
+ this.ttY = 0;
86
+ this.focused = false;
87
+ this.order = [];
88
+ this.selectedRuns = [];
89
+ this.avgX = 0;
90
+ this.avgY = 0;
91
+ this.answer = null;
92
+ this.off = [];
93
+ this.sel = [];
94
+ this.controlled = false;
95
+ this.ready = false;
96
+ this.asked = 0;
97
+ this.drag = null;
98
+ this.timers = [];
99
+ // template helpers
100
+ this.min = Math.min;
101
+ this.abs = Math.abs;
102
+ this.pendingAsk = 0;
103
+ }
104
+ /** The selected runs, by id. Leave it out to let the chart hold the selection. */
105
+ set selected(value) {
106
+ this.controlled = value !== undefined;
107
+ if (value !== undefined) {
108
+ this.sel = value;
109
+ this.asked++;
110
+ this.answer = null;
111
+ if (this.ready)
112
+ this.draw();
113
+ }
114
+ }
115
+ get defaultNote() {
116
+ return `Medians split the runs: ${this.formatX(this.mx)} and ${this.formatY(this.my)}. Drag across the chart to select runs.`;
117
+ }
118
+ ngAfterViewInit() {
119
+ const el = this.plotRef.nativeElement;
120
+ this.ro = new ResizeObserver(() => {
121
+ this.W = el.clientWidth;
122
+ this.H = el.clientHeight;
123
+ this.draw();
124
+ });
125
+ this.ro.observe(el);
126
+ this.ready = true;
127
+ this.W = el.clientWidth;
128
+ this.H = el.clientHeight;
129
+ this.draw();
130
+ this.cdr.detectChanges();
131
+ }
132
+ // ----- series look-ups -----
133
+ si(key) {
134
+ return Math.max(0, this.series.findIndex((s) => s.key === key));
135
+ }
136
+ colorOf(key) {
137
+ return this.series[this.si(key)]?.color ?? PAL[this.si(key) % PAL.length];
138
+ }
139
+ shapeOf(key) {
140
+ return this.series[this.si(key)]?.shape ?? SHAPES[this.si(key) % SHAPES.length];
141
+ }
142
+ labelOf(key) {
143
+ return this.series[this.si(key)]?.label ?? '';
144
+ }
145
+ /** The triangle mark's path, so a dot reads without colour too. */
146
+ triPath(x, y, s) {
147
+ return `M${x} ${y - s * 1.15}L${x + s * 1.05} ${y + s * 0.75}L${x - s * 1.05} ${y + s * 0.75}Z`;
148
+ }
149
+ // ----- geometry -----
150
+ X(v) {
151
+ return this.l + ((v - this.xDomain[0]) / (this.xDomain[1] - this.xDomain[0])) * (this.W - this.l - this.rr);
152
+ }
153
+ Y(v) {
154
+ return this.t + (1 - (v - this.yDomain[0]) / (this.yDomain[1] - this.yDomain[0])) * (this.H - this.t - this.b);
155
+ }
156
+ R(run) {
157
+ const sMin = Math.min(...this.runs.map((r) => r.size));
158
+ const sMax = Math.max(...this.runs.map((r) => r.size));
159
+ return (3 + ((run.size - sMin) / Math.max(1, sMax - sMin)) * 4.5) * (this.narrow ? 0.85 : 1);
160
+ }
161
+ shownIdx() {
162
+ return this.runs.map((_, i) => i).filter((i) => !this.off.includes(this.runs[i].series));
163
+ }
164
+ // ----- draw: recompute every view model, mirroring the React render -----
165
+ draw() {
166
+ if (!this.ready || this.W <= 0) {
167
+ this.cdr.markForCheck();
168
+ return;
169
+ }
170
+ this.narrow = this.W > 0 && this.W <= 340;
171
+ this.l = this.narrow ? 38 : 44;
172
+ const ends = (a, d) => this.narrow && a.length > 3 ? [a[0], (d[0] + d[1]) / 2, a[a.length - 1]] : a;
173
+ this.xt = ends(this.xTicks, this.xDomain);
174
+ this.yt = ends(this.yTicks, this.yDomain);
175
+ const shown = this.shownIdx();
176
+ this.mx = median(shown.map((i) => this.runs[i].x));
177
+ this.my = median(shown.map((i) => this.runs[i].y));
178
+ const sel = this.sel;
179
+ this.dots = this.runs.map((run, i) => {
180
+ const off = this.off.includes(run.series);
181
+ const dim = this.hr != null && this.hr.series !== run.series && !off;
182
+ const cls = ['vo-d', off ? 'vo-off' : '', dim ? 'vo-dim' : '', i === this.hot ? 'vo-on' : '', sel.includes(run.id) ? 'vo-sel' : '']
183
+ .filter(Boolean)
184
+ .join(' ');
185
+ return {
186
+ run,
187
+ index: i,
188
+ cls,
189
+ fill: this.colorOf(run.series),
190
+ shape: this.shapeOf(run.series),
191
+ cx: +this.X(run.x).toFixed(1),
192
+ cy: +this.Y(run.y).toFixed(1),
193
+ r: +this.R(run).toFixed(1),
194
+ };
195
+ });
196
+ this.ringDots = this.runs
197
+ .filter((run) => this.ringed.includes(run.id) && !this.off.includes(run.series))
198
+ .map((run) => ({
199
+ run,
200
+ index: this.runs.indexOf(run),
201
+ cls: '',
202
+ fill: this.colorOf(run.series),
203
+ shape: this.shapeOf(run.series),
204
+ cx: this.X(run.x),
205
+ cy: this.Y(run.y),
206
+ r: this.R(run),
207
+ }));
208
+ this.order = [...shown].sort((a, c) => this.runs[a].x - this.runs[c].x || this.runs[c].y - this.runs[a].y);
209
+ this.hr = this.hot >= 0 ? this.runs[this.hot] : null;
210
+ if (this.hr && this.tipRef) {
211
+ const w = this.tipRef.nativeElement.offsetWidth;
212
+ this.ttX = Math.max(w / 2, Math.min(this.W - w / 2, this.X(this.hr.x)));
213
+ this.ttY = this.Y(this.hr.y) - this.R(this.hr);
214
+ }
215
+ this.selectedRuns = this.runs.filter((r) => sel.includes(r.id));
216
+ if (this.selectedRuns.length) {
217
+ this.avgX = this.selectedRuns.reduce((a, r) => a + r.x, 0) / this.selectedRuns.length;
218
+ this.avgY = this.selectedRuns.reduce((a, r) => a + r.y, 0) / this.selectedRuns.length;
219
+ }
220
+ this.cdr.markForCheck();
221
+ }
222
+ // ----- legend -----
223
+ toggle(key) {
224
+ if (!this.off.includes(key) && this.off.length === this.series.length - 1)
225
+ return;
226
+ this.hot = -1;
227
+ this.off = this.off.includes(key) ? this.off.filter((k) => k !== key) : [...this.off, key];
228
+ this.draw();
229
+ }
230
+ // ----- pointer / selection -----
231
+ local(e) {
232
+ const r = this.plotRef.nativeElement.getBoundingClientRect();
233
+ return [e.clientX - r.left, e.clientY - r.top];
234
+ }
235
+ near(px, py) {
236
+ let best = -1;
237
+ let bd = 26 * 26;
238
+ for (const i of this.shownIdx()) {
239
+ const dx = this.X(this.runs[i].x) - px;
240
+ const dy = this.Y(this.runs[i].y) - py;
241
+ const d = dx * dx + dy * dy;
242
+ if (d < bd) {
243
+ bd = d;
244
+ best = i;
245
+ }
246
+ }
247
+ return best;
248
+ }
249
+ setSel(ids) {
250
+ if (!this.controlled) {
251
+ this.sel = ids;
252
+ this.asked++;
253
+ this.answer = null;
254
+ }
255
+ this.selectedChange.emit(ids);
256
+ this.draw();
257
+ }
258
+ onPointerDown(e) {
259
+ if (e.button)
260
+ return;
261
+ const [x, y] = this.local(e);
262
+ this.drag = { x, y, id: e.pointerId, moved: false };
263
+ }
264
+ onPointerMove(e) {
265
+ const [x, y] = this.local(e);
266
+ const d = this.drag;
267
+ if (d && (d.moved || Math.abs(x - d.x) + Math.abs(y - d.y) > 5)) {
268
+ if (!d.moved) {
269
+ d.moved = true;
270
+ this.plotRef.nativeElement.setPointerCapture(d.id);
271
+ this.hot = -1;
272
+ }
273
+ this.box = [
274
+ d.x,
275
+ d.y,
276
+ Math.max(this.l, Math.min(this.W - this.rr, x)),
277
+ Math.max(this.t, Math.min(this.H - this.b, y)),
278
+ ];
279
+ this.draw();
280
+ return;
281
+ }
282
+ if (e.pointerType !== 'touch') {
283
+ const i = this.near(x, y);
284
+ if (i !== this.hot) {
285
+ this.hot = i;
286
+ this.draw();
287
+ }
288
+ }
289
+ }
290
+ onPointerUp() {
291
+ const d = this.drag;
292
+ this.drag = null;
293
+ if (!d)
294
+ return;
295
+ if (d.moved && this.box) {
296
+ const [a, b2, x2, y2] = this.box;
297
+ const lo = Math.min(a, x2);
298
+ const hi = Math.max(a, x2);
299
+ const top = Math.min(b2, y2);
300
+ const bot = Math.max(b2, y2);
301
+ const ids = this.shownIdx()
302
+ .filter((i) => this.X(this.runs[i].x) >= lo &&
303
+ this.X(this.runs[i].x) <= hi &&
304
+ this.Y(this.runs[i].y) >= top &&
305
+ this.Y(this.runs[i].y) <= bot)
306
+ .map((i) => this.runs[i].id);
307
+ this.box = null;
308
+ this.setSel(ids);
309
+ }
310
+ else if (this.hot < 0 && this.sel.length) {
311
+ this.box = null;
312
+ this.setSel([]);
313
+ }
314
+ }
315
+ onPointerCancel() {
316
+ this.drag = null;
317
+ this.box = null;
318
+ this.draw();
319
+ }
320
+ onPointerLeave() {
321
+ if (!this.drag && document.activeElement !== this.plotRef.nativeElement && this.hot >= 0) {
322
+ this.hot = -1;
323
+ this.draw();
324
+ }
325
+ }
326
+ onBlur() {
327
+ this.focused = false;
328
+ if (this.hot >= 0) {
329
+ this.hot = -1;
330
+ this.draw();
331
+ }
332
+ }
333
+ onKeyDown(e) {
334
+ this.focused = true;
335
+ const o = this.order;
336
+ let k = o.indexOf(this.hot);
337
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown')
338
+ k = Math.min(o.length - 1, k + 1);
339
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp')
340
+ k = Math.max(0, k < 0 ? 0 : k - 1);
341
+ else if (e.key === 'Home')
342
+ k = 0;
343
+ else if (e.key === 'End')
344
+ k = o.length - 1;
345
+ else if (e.key === 'Escape' && this.sel.length) {
346
+ this.box = null;
347
+ this.setSel([]);
348
+ return;
349
+ }
350
+ else
351
+ return;
352
+ e.preventDefault();
353
+ this.hot = o[k];
354
+ this.draw();
355
+ }
356
+ // ----- ask the agent -----
357
+ runAsk() {
358
+ if (!this.ask.observed)
359
+ return;
360
+ this.asked++;
361
+ const id = this.asked;
362
+ this.answer = { text: '', busy: true };
363
+ this.ask.emit(this.selectedRuns);
364
+ this.cdr.markForCheck();
365
+ // the host answers via streamAnswer(); until then the shimmer shows
366
+ this.pendingAsk = id;
367
+ }
368
+ /** The host calls this with the answer; it streams in word by word. */
369
+ streamAnswer(text) {
370
+ const id = this.pendingAsk;
371
+ if (id !== this.asked)
372
+ return;
373
+ const ws = text.split(' ');
374
+ const step = (i) => {
375
+ if (id !== this.asked)
376
+ return;
377
+ this.answer = { text: ws.slice(0, i).join(' '), busy: false };
378
+ this.cdr.markForCheck();
379
+ if (i < ws.length) {
380
+ this.timers.push(setTimeout(() => step(i + 1), this.reduced.reduce() ? 0 : 45));
381
+ }
382
+ };
383
+ step(1);
384
+ }
385
+ ngOnDestroy() {
386
+ this.ro?.disconnect();
387
+ this.timers.forEach(clearTimeout);
388
+ this.timers = [];
389
+ }
390
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScatterChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
391
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScatterChartComponent, isStandalone: true, selector: "vo-scatter-chart", inputs: { runs: "runs", series: "series", className: "className", title: "title", subtitle: "subtitle", xDomain: "xDomain", yDomain: "yDomain", xTicks: "xTicks", yTicks: "yTicks", xTitle: "xTitle", yTitle: "yTitle", formatX: "formatX", formatY: "formatY", formatSize: "formatSize", quadrants: "quadrants", ringed: "ringed", note: "note", selected: "selected" }, outputs: { selectedChange: "selectedChange", ask: "ask" }, viewQueries: [{ propertyName: "plotRef", first: true, predicate: ["plot"], descendants: true }, { propertyName: "tipRef", first: true, predicate: ["tip"], descendants: true }], ngImport: i0, template: `
392
+ <div data-vo="" class="vo-cvq vo-panel" [class]="className">
393
+ <div class="vo-cvq-h">
394
+ <div class="vo-cvq-t">
395
+ <b>{{ title }}</b>
396
+ @if (subtitle) {
397
+ <span class="vo-muted">{{ subtitle }}</span>
398
+ }
399
+ </div>
400
+ <div class="vo-cvq-lg">
401
+ @for (s of series; track s.key) {
402
+ <button
403
+ type="button"
404
+ class="vo-cvq-k"
405
+ [attr.aria-pressed]="!off.includes(s.key)"
406
+ (click)="toggle(s.key)"
407
+ >
408
+ <svg viewBox="-6 -6 12 12" [style.fill]="colorOf(s.key)" aria-hidden="true">
409
+ @switch (shapeOf(s.key)) {
410
+ @case ('circle') { <circle [attr.cx]="0" [attr.cy]="0" [attr.r]="4.5" /> }
411
+ @case ('square') { <rect [attr.x]="-4.05" [attr.y]="-4.05" [attr.width]="8.1" [attr.height]="8.1" [attr.rx]="1.125" /> }
412
+ @default { <path [attr.d]="triPath(0, 0, 4.5)" /> }
413
+ }
414
+ </svg>{{ s.label }}
415
+ </button>
416
+ }
417
+ </div>
418
+ </div>
419
+
420
+ <div
421
+ #plot
422
+ class="vo-cvq-pl"
423
+ tabindex="0"
424
+ role="group"
425
+ aria-roledescription="scatter chart"
426
+ [attr.aria-label]="title + '. Arrow keys step through the runs'"
427
+ (pointerdown)="onPointerDown($event)"
428
+ (pointermove)="onPointerMove($event)"
429
+ (pointerup)="onPointerUp()"
430
+ (pointercancel)="onPointerCancel()"
431
+ (pointerleave)="onPointerLeave()"
432
+ (blur)="onBlur()"
433
+ (keydown)="onKeyDown($event)"
434
+ >
435
+ @if (W > 0) {
436
+ <svg class="vo-cvq-svg" [attr.viewBox]="'0 0 ' + W + ' ' + H" aria-hidden="true">
437
+ <!-- a few light gridlines and quiet tick labels; the axis titles sit well clear of the ticks -->
438
+ @for (v of yt; track v) {
439
+ <g>
440
+ <line class="vo-gl" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="Y(v)" [attr.y2]="Y(v)" />
441
+ <text [attr.x]="l - 6" [attr.y]="Y(v) + 3.5" text-anchor="end">{{ v }}</text>
442
+ </g>
443
+ }
444
+ @for (v of xt; track $index) {
445
+ <text
446
+ [attr.x]="X(v)"
447
+ [attr.y]="H - b + 15"
448
+ [attr.text-anchor]="$index === 0 ? 'start' : $index === xt.length - 1 ? 'end' : 'middle'"
449
+ >{{ formatX(v) }}</text>
450
+ }
451
+ <line class="vo-ax" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="H - b" [attr.y2]="H - b" />
452
+ <text class="vo-at" [attr.x]="W - rr" [attr.y]="H - 1" text-anchor="end">{{ xTitle }}</text>
453
+ <text class="vo-at" [attr.x]="-t" [attr.y]="9" transform="rotate(-90)" text-anchor="end">{{ yTitle }}</text>
454
+ <line class="vo-md" [attr.x1]="X(mx)" [attr.x2]="X(mx)" [attr.y1]="t" [attr.y2]="H - b" />
455
+ <line class="vo-md" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="Y(my)" [attr.y2]="Y(my)" />
456
+ @if (!narrow) {
457
+ <text class="vo-q" [attr.x]="l + 6" [attr.y]="t + 11">{{ quadrants[0] }}</text>
458
+ <text class="vo-q" [attr.x]="W - rr - 4" [attr.y]="t + 11" text-anchor="end">{{ quadrants[1] }}</text>
459
+ <text class="vo-q" [attr.x]="W - rr - 4" [attr.y]="H - b - 6" text-anchor="end">{{ quadrants[2] }}</text>
460
+ <text class="vo-q" [attr.x]="l + 6" [attr.y]="H - b - 6">{{ quadrants[3] }}</text>
461
+ }
462
+ @for (d of dots; track d.run.id) {
463
+ <g [class]="d.cls" [style.fill]="d.fill">
464
+ @switch (d.shape) {
465
+ @case ('circle') { <circle [attr.cx]="d.cx" [attr.cy]="d.cy" [attr.r]="d.r" /> }
466
+ @case ('square') { <rect [attr.x]="d.cx - d.r * 0.9" [attr.y]="d.cy - d.r * 0.9" [attr.width]="d.r * 1.8" [attr.height]="d.r * 1.8" [attr.rx]="d.r * 0.25" /> }
467
+ @default { <path [attr.d]="triPath(d.cx, d.cy, d.r)" /> }
468
+ }
469
+ </g>
470
+ }
471
+ @for (d of ringDots; track d.run.id) {
472
+ <circle class="vo-ring" [attr.cx]="d.cx" [attr.cy]="d.cy" [attr.r]="d.r + 6" />
473
+ }
474
+ @if (box) {
475
+ <rect
476
+ class="vo-box"
477
+ [attr.x]="min(box[0], box[2])"
478
+ [attr.y]="min(box[1], box[3])"
479
+ [attr.width]="abs(box[2] - box[0])"
480
+ [attr.height]="abs(box[3] - box[1])"
481
+ [attr.rx]="3"
482
+ />
483
+ }
484
+ </svg>
485
+ }
486
+ <div #tip class="vo-cvq-tt" [class.vo-on]="hr" [style.left.px]="ttX" [style.top.px]="ttY">
487
+ @if (hr) {
488
+ <b class="vo-num">{{ formatX(hr.x) }} · {{ formatY(hr.y) }}</b>
489
+ <span>Run {{ hr.id }}, {{ labelOf(hr.series) }}, {{ formatSize(hr.size) }}</span>
490
+ }
491
+ </div>
492
+ </div>
493
+
494
+ <div class="vo-cvq-ft" aria-live="polite">
495
+ @if (hr && focused) {
496
+ <span class="vo-cvq-msg">
497
+ <span><b>Run {{ hr.id }}</b>, {{ labelOf(hr.series) }}: {{ formatX(hr.x) }}, {{ formatY(hr.y) }}, {{ formatSize(hr.size) }}. {{ order.indexOf(hot) + 1 }} of {{ order.length }}</span>
498
+ </span>
499
+ } @else if (answer) {
500
+ <span class="vo-cvq-msg">
501
+ <vo-icon class="vo-i" name="spark" size="xs"></vo-icon>
502
+ <span [class.vo-shim]="answer.busy">{{ answer.busy ? 'Looking at ' + selectedRuns.length + ' runs' : answer.text }}</span>
503
+ </span>
504
+ } @else if (selectedRuns.length) {
505
+ <span class="vo-cvq-msg">
506
+ <span><b>{{ selectedRuns.length }} runs selected</b>, {{ formatX(avgX) }} and {{ formatY(avgY) }} on average</span>
507
+ </span>
508
+ @if (ask.observed) {
509
+ <button type="button" class="vo-pill vo-soft vo-sm" (click)="runAsk()">
510
+ <vo-icon name="spark" size="xs"></vo-icon>Ask the agent why
511
+ </button>
512
+ }
513
+ } @else {
514
+ <span class="vo-cvq-msg">
515
+ <vo-icon class="vo-i" name="spark" size="xs"></vo-icon>
516
+ <span>{{ note ?? defaultNote }}</span>
517
+ </span>
518
+ }
519
+ </div>
520
+ </div>
521
+ `, isInline: true, styles: [".vo-cvq{padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-cvq-h{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;flex-wrap:wrap}.vo-cvq-t{display:flex;flex-direction:column;font-size:13.5px;line-height:1.4}.vo-cvq-t b{font-weight:500}.vo-cvq-t .vo-muted{font-size:12px}.vo-cvq-lg{display:flex;gap:2px}.vo-cvq-k{display:flex;align-items:center;gap:6px;height:26px;padding:0 8px;border-radius:var(--vo-r-pill);font-size:12px;color:var(--vo-muted);transition:color .2s,background .2s}@media (hover:hover) and (pointer:fine){.vo-cvq-k:hover{background:var(--vo-row)}}.vo-cvq-k[aria-pressed=true]{color:var(--vo-fg)}.vo-cvq-k svg{width:10px;height:10px;overflow:visible;transition:opacity .3s,transform .3s var(--vo-ease)}.vo-cvq-k[aria-pressed=false] svg{opacity:.3;transform:scale(.7)}.vo-cvq-pl{position:relative;height:244px;touch-action:pan-y;cursor:crosshair;user-select:none;-webkit-user-select:none;border-radius:var(--vo-r-sm)}.vo-cvq-pl:focus-visible{outline-offset:4px}.vo-cvq-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.vo-cvq-svg .vo-gl{stroke:color-mix(in srgb,var(--vo-line) 40%,transparent);stroke-width:1}.vo-cvq-svg .vo-ax{stroke:color-mix(in srgb,var(--vo-line) 80%,transparent);stroke-width:1}.vo-cvq-svg .vo-md{stroke:color-mix(in srgb,var(--vo-faint) 75%,transparent);stroke-width:1;stroke-dasharray:3 3}.vo-cvq-svg text{font-size:10.5px;fill:var(--vo-muted);font-family:var(--vo-sans)}.vo-cvq-svg text.vo-q{font-size:10px}.vo-cvq-svg text.vo-at{font-size:10.5px}.vo-cvq-svg .vo-d{stroke:var(--vo-surface);stroke-width:1;fill-opacity:.85;transition:opacity .25s,fill-opacity .25s}.vo-cvq-svg .vo-d.vo-dim{opacity:.18}.vo-cvq-svg .vo-d.vo-off{opacity:0}.vo-cvq-svg .vo-d.vo-sel{fill-opacity:1;stroke:var(--vo-fg);stroke-width:1.2}.vo-cvq-svg .vo-d.vo-on{fill-opacity:1;stroke:var(--vo-fg);stroke-width:1.5}.vo-cvq-svg .vo-ring{fill:none;stroke:var(--vo-fg2);stroke-width:1.2;stroke-dasharray:3 2.5}.vo-cvq-svg .vo-box{fill:color-mix(in srgb,var(--vo-fg) 5%,transparent);stroke:var(--vo-fg2);stroke-width:1;stroke-dasharray:4 3}.vo-cvq-tt{position:absolute;left:0;top:0;padding:6px 9px;border-radius:calc(10px * var(--vo-rk));background:var(--vo-ink);color:var(--vo-on-ink);font-size:11.5px;display:flex;flex-direction:column;opacity:0;transform:translate(-50%,-100%) translateY(-6px);transition:opacity .15s;pointer-events:none;white-space:nowrap;z-index:2}.vo-cvq-tt span{opacity:.75}.vo-cvq-tt.vo-on{opacity:1}.vo-cvq-ft{min-height:72px;display:flex;align-items:center;gap:var(--vo-s-2);padding:var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-row);font-size:12.5px;color:var(--vo-fg2)}.vo-cvq-msg{flex:1;min-width:0;display:flex;align-items:center;gap:var(--vo-s-2)}.vo-cvq-msg .vo-i{flex:none;color:var(--vo-accent-fg,var(--vo-accent))}.vo-cvq-msg b{font-weight:500;color:var(--vo-fg)}.vo-cvq-ft .vo-pill{flex:none}.vo-cvq-ft .vo-ib{flex:none;width:26px;height:26px}.vo-cvq-ft{flex-wrap:wrap}.vo-cvq-msg{flex:1 1 180px}.vo-cvq{container-type:inline-size}@container (max-width:340px){.vo-cvq-pl{height:228px}.vo-cvq-ft{flex-direction:column;align-items:stretch;justify-content:center;gap:10px}.vo-cvq-msg{flex:none}.vo-cvq-msg:has(>.vo-pill){flex-direction:column;align-items:stretch;gap:10px}.vo-cvq-ft .vo-pill{justify-content:center}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-soft{background:var(--vo-chip);color:var(--vo-fg2)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-soft:hover{background:var(--vo-row,var(--vo-hover));color:var(--vo-fg)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-shim{background:linear-gradient(90deg,var(--vo-muted) 25%,var(--vo-fg) 50%,var(--vo-muted) 75%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:vo-shim 1.4s linear infinite}@keyframes vo-shim{to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.vo-shim{color:var(--vo-fg);background:none}}\n"], dependencies: [{ kind: "component", type: VoIconComponent, selector: "vo-icon", inputs: ["name", "size"] }], encapsulation: i0.ViewEncapsulation.None }); }
522
+ }
523
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScatterChartComponent, decorators: [{
524
+ type: Component,
525
+ args: [{ selector: 'vo-scatter-chart', standalone: true, encapsulation: ViewEncapsulation.None, imports: [VoIconComponent], template: `
526
+ <div data-vo="" class="vo-cvq vo-panel" [class]="className">
527
+ <div class="vo-cvq-h">
528
+ <div class="vo-cvq-t">
529
+ <b>{{ title }}</b>
530
+ @if (subtitle) {
531
+ <span class="vo-muted">{{ subtitle }}</span>
532
+ }
533
+ </div>
534
+ <div class="vo-cvq-lg">
535
+ @for (s of series; track s.key) {
536
+ <button
537
+ type="button"
538
+ class="vo-cvq-k"
539
+ [attr.aria-pressed]="!off.includes(s.key)"
540
+ (click)="toggle(s.key)"
541
+ >
542
+ <svg viewBox="-6 -6 12 12" [style.fill]="colorOf(s.key)" aria-hidden="true">
543
+ @switch (shapeOf(s.key)) {
544
+ @case ('circle') { <circle [attr.cx]="0" [attr.cy]="0" [attr.r]="4.5" /> }
545
+ @case ('square') { <rect [attr.x]="-4.05" [attr.y]="-4.05" [attr.width]="8.1" [attr.height]="8.1" [attr.rx]="1.125" /> }
546
+ @default { <path [attr.d]="triPath(0, 0, 4.5)" /> }
547
+ }
548
+ </svg>{{ s.label }}
549
+ </button>
550
+ }
551
+ </div>
552
+ </div>
553
+
554
+ <div
555
+ #plot
556
+ class="vo-cvq-pl"
557
+ tabindex="0"
558
+ role="group"
559
+ aria-roledescription="scatter chart"
560
+ [attr.aria-label]="title + '. Arrow keys step through the runs'"
561
+ (pointerdown)="onPointerDown($event)"
562
+ (pointermove)="onPointerMove($event)"
563
+ (pointerup)="onPointerUp()"
564
+ (pointercancel)="onPointerCancel()"
565
+ (pointerleave)="onPointerLeave()"
566
+ (blur)="onBlur()"
567
+ (keydown)="onKeyDown($event)"
568
+ >
569
+ @if (W > 0) {
570
+ <svg class="vo-cvq-svg" [attr.viewBox]="'0 0 ' + W + ' ' + H" aria-hidden="true">
571
+ <!-- a few light gridlines and quiet tick labels; the axis titles sit well clear of the ticks -->
572
+ @for (v of yt; track v) {
573
+ <g>
574
+ <line class="vo-gl" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="Y(v)" [attr.y2]="Y(v)" />
575
+ <text [attr.x]="l - 6" [attr.y]="Y(v) + 3.5" text-anchor="end">{{ v }}</text>
576
+ </g>
577
+ }
578
+ @for (v of xt; track $index) {
579
+ <text
580
+ [attr.x]="X(v)"
581
+ [attr.y]="H - b + 15"
582
+ [attr.text-anchor]="$index === 0 ? 'start' : $index === xt.length - 1 ? 'end' : 'middle'"
583
+ >{{ formatX(v) }}</text>
584
+ }
585
+ <line class="vo-ax" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="H - b" [attr.y2]="H - b" />
586
+ <text class="vo-at" [attr.x]="W - rr" [attr.y]="H - 1" text-anchor="end">{{ xTitle }}</text>
587
+ <text class="vo-at" [attr.x]="-t" [attr.y]="9" transform="rotate(-90)" text-anchor="end">{{ yTitle }}</text>
588
+ <line class="vo-md" [attr.x1]="X(mx)" [attr.x2]="X(mx)" [attr.y1]="t" [attr.y2]="H - b" />
589
+ <line class="vo-md" [attr.x1]="l" [attr.x2]="W - rr" [attr.y1]="Y(my)" [attr.y2]="Y(my)" />
590
+ @if (!narrow) {
591
+ <text class="vo-q" [attr.x]="l + 6" [attr.y]="t + 11">{{ quadrants[0] }}</text>
592
+ <text class="vo-q" [attr.x]="W - rr - 4" [attr.y]="t + 11" text-anchor="end">{{ quadrants[1] }}</text>
593
+ <text class="vo-q" [attr.x]="W - rr - 4" [attr.y]="H - b - 6" text-anchor="end">{{ quadrants[2] }}</text>
594
+ <text class="vo-q" [attr.x]="l + 6" [attr.y]="H - b - 6">{{ quadrants[3] }}</text>
595
+ }
596
+ @for (d of dots; track d.run.id) {
597
+ <g [class]="d.cls" [style.fill]="d.fill">
598
+ @switch (d.shape) {
599
+ @case ('circle') { <circle [attr.cx]="d.cx" [attr.cy]="d.cy" [attr.r]="d.r" /> }
600
+ @case ('square') { <rect [attr.x]="d.cx - d.r * 0.9" [attr.y]="d.cy - d.r * 0.9" [attr.width]="d.r * 1.8" [attr.height]="d.r * 1.8" [attr.rx]="d.r * 0.25" /> }
601
+ @default { <path [attr.d]="triPath(d.cx, d.cy, d.r)" /> }
602
+ }
603
+ </g>
604
+ }
605
+ @for (d of ringDots; track d.run.id) {
606
+ <circle class="vo-ring" [attr.cx]="d.cx" [attr.cy]="d.cy" [attr.r]="d.r + 6" />
607
+ }
608
+ @if (box) {
609
+ <rect
610
+ class="vo-box"
611
+ [attr.x]="min(box[0], box[2])"
612
+ [attr.y]="min(box[1], box[3])"
613
+ [attr.width]="abs(box[2] - box[0])"
614
+ [attr.height]="abs(box[3] - box[1])"
615
+ [attr.rx]="3"
616
+ />
617
+ }
618
+ </svg>
619
+ }
620
+ <div #tip class="vo-cvq-tt" [class.vo-on]="hr" [style.left.px]="ttX" [style.top.px]="ttY">
621
+ @if (hr) {
622
+ <b class="vo-num">{{ formatX(hr.x) }} · {{ formatY(hr.y) }}</b>
623
+ <span>Run {{ hr.id }}, {{ labelOf(hr.series) }}, {{ formatSize(hr.size) }}</span>
624
+ }
625
+ </div>
626
+ </div>
627
+
628
+ <div class="vo-cvq-ft" aria-live="polite">
629
+ @if (hr && focused) {
630
+ <span class="vo-cvq-msg">
631
+ <span><b>Run {{ hr.id }}</b>, {{ labelOf(hr.series) }}: {{ formatX(hr.x) }}, {{ formatY(hr.y) }}, {{ formatSize(hr.size) }}. {{ order.indexOf(hot) + 1 }} of {{ order.length }}</span>
632
+ </span>
633
+ } @else if (answer) {
634
+ <span class="vo-cvq-msg">
635
+ <vo-icon class="vo-i" name="spark" size="xs"></vo-icon>
636
+ <span [class.vo-shim]="answer.busy">{{ answer.busy ? 'Looking at ' + selectedRuns.length + ' runs' : answer.text }}</span>
637
+ </span>
638
+ } @else if (selectedRuns.length) {
639
+ <span class="vo-cvq-msg">
640
+ <span><b>{{ selectedRuns.length }} runs selected</b>, {{ formatX(avgX) }} and {{ formatY(avgY) }} on average</span>
641
+ </span>
642
+ @if (ask.observed) {
643
+ <button type="button" class="vo-pill vo-soft vo-sm" (click)="runAsk()">
644
+ <vo-icon name="spark" size="xs"></vo-icon>Ask the agent why
645
+ </button>
646
+ }
647
+ } @else {
648
+ <span class="vo-cvq-msg">
649
+ <vo-icon class="vo-i" name="spark" size="xs"></vo-icon>
650
+ <span>{{ note ?? defaultNote }}</span>
651
+ </span>
652
+ }
653
+ </div>
654
+ </div>
655
+ `, styles: [".vo-cvq{padding:var(--vo-s-4);display:flex;flex-direction:column;gap:var(--vo-s-3)}.vo-cvq-h{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;flex-wrap:wrap}.vo-cvq-t{display:flex;flex-direction:column;font-size:13.5px;line-height:1.4}.vo-cvq-t b{font-weight:500}.vo-cvq-t .vo-muted{font-size:12px}.vo-cvq-lg{display:flex;gap:2px}.vo-cvq-k{display:flex;align-items:center;gap:6px;height:26px;padding:0 8px;border-radius:var(--vo-r-pill);font-size:12px;color:var(--vo-muted);transition:color .2s,background .2s}@media (hover:hover) and (pointer:fine){.vo-cvq-k:hover{background:var(--vo-row)}}.vo-cvq-k[aria-pressed=true]{color:var(--vo-fg)}.vo-cvq-k svg{width:10px;height:10px;overflow:visible;transition:opacity .3s,transform .3s var(--vo-ease)}.vo-cvq-k[aria-pressed=false] svg{opacity:.3;transform:scale(.7)}.vo-cvq-pl{position:relative;height:244px;touch-action:pan-y;cursor:crosshair;user-select:none;-webkit-user-select:none;border-radius:var(--vo-r-sm)}.vo-cvq-pl:focus-visible{outline-offset:4px}.vo-cvq-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}.vo-cvq-svg .vo-gl{stroke:color-mix(in srgb,var(--vo-line) 40%,transparent);stroke-width:1}.vo-cvq-svg .vo-ax{stroke:color-mix(in srgb,var(--vo-line) 80%,transparent);stroke-width:1}.vo-cvq-svg .vo-md{stroke:color-mix(in srgb,var(--vo-faint) 75%,transparent);stroke-width:1;stroke-dasharray:3 3}.vo-cvq-svg text{font-size:10.5px;fill:var(--vo-muted);font-family:var(--vo-sans)}.vo-cvq-svg text.vo-q{font-size:10px}.vo-cvq-svg text.vo-at{font-size:10.5px}.vo-cvq-svg .vo-d{stroke:var(--vo-surface);stroke-width:1;fill-opacity:.85;transition:opacity .25s,fill-opacity .25s}.vo-cvq-svg .vo-d.vo-dim{opacity:.18}.vo-cvq-svg .vo-d.vo-off{opacity:0}.vo-cvq-svg .vo-d.vo-sel{fill-opacity:1;stroke:var(--vo-fg);stroke-width:1.2}.vo-cvq-svg .vo-d.vo-on{fill-opacity:1;stroke:var(--vo-fg);stroke-width:1.5}.vo-cvq-svg .vo-ring{fill:none;stroke:var(--vo-fg2);stroke-width:1.2;stroke-dasharray:3 2.5}.vo-cvq-svg .vo-box{fill:color-mix(in srgb,var(--vo-fg) 5%,transparent);stroke:var(--vo-fg2);stroke-width:1;stroke-dasharray:4 3}.vo-cvq-tt{position:absolute;left:0;top:0;padding:6px 9px;border-radius:calc(10px * var(--vo-rk));background:var(--vo-ink);color:var(--vo-on-ink);font-size:11.5px;display:flex;flex-direction:column;opacity:0;transform:translate(-50%,-100%) translateY(-6px);transition:opacity .15s;pointer-events:none;white-space:nowrap;z-index:2}.vo-cvq-tt span{opacity:.75}.vo-cvq-tt.vo-on{opacity:1}.vo-cvq-ft{min-height:72px;display:flex;align-items:center;gap:var(--vo-s-2);padding:var(--vo-s-2) var(--vo-s-3);border-radius:var(--vo-r-in);background:var(--vo-row);font-size:12.5px;color:var(--vo-fg2)}.vo-cvq-msg{flex:1;min-width:0;display:flex;align-items:center;gap:var(--vo-s-2)}.vo-cvq-msg .vo-i{flex:none;color:var(--vo-accent-fg,var(--vo-accent))}.vo-cvq-msg b{font-weight:500;color:var(--vo-fg)}.vo-cvq-ft .vo-pill{flex:none}.vo-cvq-ft .vo-ib{flex:none;width:26px;height:26px}.vo-cvq-ft{flex-wrap:wrap}.vo-cvq-msg{flex:1 1 180px}.vo-cvq{container-type:inline-size}@container (max-width:340px){.vo-cvq-pl{height:228px}.vo-cvq-ft{flex-direction:column;align-items:stretch;justify-content:center;gap:10px}.vo-cvq-msg{flex:none}.vo-cvq-msg:has(>.vo-pill){flex-direction:column;align-items:stretch;gap:10px}.vo-cvq-ft .vo-pill{justify-content:center}}.vo-pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:32px;padding:0 14px;border-radius:var(--vo-r-pill);font-size:13px;font-weight:500;white-space:nowrap;cursor:pointer;transition:background var(--vo-t-fast),color var(--vo-t-fast),opacity var(--vo-t-fast),transform .15s}.vo-pill:active{transform:scale(.97)}.vo-pill.vo-soft{background:var(--vo-chip);color:var(--vo-fg2)}@media (hover:hover) and (pointer:fine){.vo-pill.vo-soft:hover{background:var(--vo-row,var(--vo-hover));color:var(--vo-fg)}}.vo-pill.vo-sm{height:28px;padding:0 11px;font-size:12.5px}.vo-shim{background:linear-gradient(90deg,var(--vo-muted) 25%,var(--vo-fg) 50%,var(--vo-muted) 75%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:vo-shim 1.4s linear infinite}@keyframes vo-shim{to{background-position:-200% 0}}@media (prefers-reduced-motion:reduce){.vo-shim{color:var(--vo-fg);background:none}}\n"] }]
656
+ }], propDecorators: { runs: [{
657
+ type: Input,
658
+ args: [{ required: true }]
659
+ }], series: [{
660
+ type: Input,
661
+ args: [{ required: true }]
662
+ }], className: [{
663
+ type: Input
664
+ }], title: [{
665
+ type: Input
666
+ }], subtitle: [{
667
+ type: Input
668
+ }], xDomain: [{
669
+ type: Input
670
+ }], yDomain: [{
671
+ type: Input
672
+ }], xTicks: [{
673
+ type: Input
674
+ }], yTicks: [{
675
+ type: Input
676
+ }], xTitle: [{
677
+ type: Input
678
+ }], yTitle: [{
679
+ type: Input
680
+ }], formatX: [{
681
+ type: Input
682
+ }], formatY: [{
683
+ type: Input
684
+ }], formatSize: [{
685
+ type: Input
686
+ }], quadrants: [{
687
+ type: Input
688
+ }], ringed: [{
689
+ type: Input
690
+ }], note: [{
691
+ type: Input
692
+ }], selected: [{
693
+ type: Input
694
+ }], selectedChange: [{
695
+ type: Output
696
+ }], ask: [{
697
+ type: Output
698
+ }], plotRef: [{
699
+ type: ViewChild,
700
+ args: ['plot']
701
+ }], tipRef: [{
702
+ type: ViewChild,
703
+ args: ['tip']
704
+ }] } });
705
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhdHRlci1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zY2F0dGVyLWNoYXJ0L3NjYXR0ZXItY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDZEQUE2RDtBQUM3RCxFQUFFO0FBQ0YseUVBQXlFO0FBQ3pFLGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsaUZBQWlGO0FBQ2pGLGdGQUFnRjtBQUNoRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG9FQUFvRTtBQUNwRSxFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLGlGQUFpRjtBQUVqRixPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7O0FBd0N0RSxNQUFNLEdBQUcsR0FBRztJQUNWLGNBQWM7SUFDZCxjQUFjO0lBQ2QsY0FBYztJQUNkLGNBQWM7SUFDZCxjQUFjO0lBQ2QsY0FBYztDQUNmLENBQUM7QUFDRixNQUFNLE1BQU0sR0FBbUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBRWhFLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBVyxFQUFVLEVBQUU7SUFDckMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNO1FBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2QyxNQUFNLENBQUMsR0FB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S0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUM7UUFDMUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUUvQixNQUFNLElBQUksR0FBRyxDQUFDLENBQVcsRUFBRSxDQUFtQixFQUFZLEVBQUUsQ0FDMUQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUxQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMs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QUMsQ0FBQyxDQUFDO1lBQ2pCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztTQUNmLENBQUMsQ0FBQyxDQUFDO1FBRU4sSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzRyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3JELElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1lBQ2hELElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEUsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJ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QUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBT0csTUFBTTtzQkFBZCxLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFTyxRQUFRO3NCQUFwQixLQUFLO2dCQVVJLGNBQWM7c0JBQXZCLE1BQU07Z0JBRUcsR0FBRztzQkFBWixNQUFNO2dCQUVZLE9BQU87c0JBQXpCLFNBQVM7dUJBQUMsTUFBTTtnQkFDQyxNQUFNO3NCQUF2QixTQUFTO3VCQUFDLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBmcmFtZXdvcmsvYW5ndWxhci9zY2F0dGVyLWNoYXJ0L3NjYXR0ZXItY2hhcnQuY29tcG9uZW50LnRzXG4vL1xuLy8gTmF0aXZlIEFuZ3VsYXIgcG9ydCBvZiBmcmFtZXdvcmsvcmVhY3Qvc2NhdHRlci1jaGFydC9TY2F0dGVyQ2hhcnQudHN4LlxuLy8gRXZlcnkgcnVuIGlzIGEgZG90IGJ5IGNvc3QgKGFsb25nKSBhbmQgZXZhbCBzY29yZSAodXApLCBzaXplZCBieSB0b2tlbnMsIHdpdGhcbi8vIGEgY29sb3VyIGFuZCBhIHNoYXBlIHBlciBzZXJpZXMuIERhc2hlZCBtZWRpYW4gbGluZXMgY3V0IHRoZSBwbG90IGludG8gZm91clxuLy8gbmFtZWQgcXVhZHJhbnRzOyBwb2ludGluZyBzbmFwcyB0byB0aGUgbmVhcmVzdCBydW4gYW5kIGEgZHJhZyBkcmF3cyBhIGJveCB0aGF0XG4vLyBzZWxlY3RzIHRoZSBydW5zIGluIGl0LiBJbnB1dHMgbWlycm9yIHRoZSBSZWFjdCBwcm9wczsgUmVhY3QgY2FsbGJhY2tzIGJlY29tZVxuLy8gQE91dHB1dCBFdmVudEVtaXR0ZXJzLiBUaGUgcGxvdCBtZWFzdXJlcyBpdHNlbGYgd2l0aCBhIFJlc2l6ZU9ic2VydmVyIHNldCB1cFxuLy8gaW4gbmdBZnRlclZpZXdJbml0IGFuZCB0b3JuIGRvd24gaW4gbmdPbkRlc3Ryb3ksIG1pcnJvcmluZyB0aGUgdmFuaWxsYSBKU1xuLy8gKHNjYXR0ZXItY2hhcnQuanMpLiBTdHlsaW5nIGZsb3dzIG9ubHkgdGhyb3VnaCB0aGUgLS12by0qIHRva2Vucy5cbi8vXG4vLyBJY29uczogb25seSB0aGUgXCJzcGFya1wiIGdseXBoIGlzIHVzZWQgKHRoZSBub3RlIGFuZCB0aGUgXCJBc2sgdGhlIGFnZW50IHdoeVwiXG4vLyBidXR0b24pLCB2aWEgVm9JY29uQ29tcG9uZW50IOKAlCB0aGUgc2FtZSBnbHlwaCB0aGUgUmVhY3QvVmFuaWxsYSBvcmlnaW5hbHMgdXNlLlxuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZvSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uL2NvcmUvaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVkdWNlZE1vdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL3JlZHVjZWQtbW90aW9uLnNlcnZpY2UnO1xuXG4vKiogQSBzaGFwZSBmb3IgYSBzZXJpZXMsIHNvIGl0IHJlYWRzIHdpdGhvdXQgY29sb3VyIHRvby4gKi9cbmV4cG9ydCB0eXBlIFNjYXR0ZXJTaGFwZSA9ICdjaXJjbGUnIHwgJ3NxdWFyZScgfCAndHJpYW5nbGUnO1xuXG4vKiogT25lIHJ1bjogYSBkb3Qgb24gdGhlIGNoYXJ0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY2F0dGVyUnVuIHtcbiAgaWQ6IHN0cmluZyB8IG51bWJlcjtcbiAgLyoqIFdoaWNoIHNlcmllcyBpdCBiZWxvbmdzIHRvLCBieSBrZXkuICovXG4gIHNlcmllczogc3RyaW5nO1xuICAvKiogQWxvbmcgdGhlIGJvdHRvbSwgbGlrZSBjb3N0IHBlciBydW4gaW4gZG9sbGFycy4gKi9cbiAgeDogbnVtYmVyO1xuICAvKiogVXAgdGhlIHNpZGUsIGxpa2UgYW4gZXZhbCBzY29yZSBpbiAlLiAqL1xuICB5OiBudW1iZXI7XG4gIC8qKiBJdHMgZG90J3Mgc2l6ZSwgbGlrZSB0aG91c2FuZHMgb2YgdG9rZW5zLiAqL1xuICBzaXplOiBudW1iZXI7XG59XG5cbi8qKiBPbmUgc2VyaWVzOiBhIGNvbG91ciBhbmQgYSBzaGFwZSwgd2l0aCBhIGxlZ2VuZCBsYWJlbC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NhdHRlclNlcmllcyB7XG4gIGtleTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICAvKiogRGVmYXVsdHMgdG8gdGhlIGNoYXJ0IHBhbGV0dGUgaW4gb3JkZXI6IC0tdm8tYzEsIC0tdm8tYzIsIC0tdm8tYzMuICovXG4gIGNvbG9yPzogc3RyaW5nO1xuICAvKiogRWFjaCBzZXJpZXMgaGFzIGEgc2hhcGUgYXMgd2VsbCBhcyBhIGNvbG91ciwgc28gaXQgcmVhZHMgd2l0aG91dCBjb2xvdXIgdG9vLiAqL1xuICBzaGFwZT86IFNjYXR0ZXJTaGFwZTtcbn1cblxuLyoqIEludGVybmFsIHBlci1kb3QgcmVuZGVyIGRhdGEuICovXG5pbnRlcmZhY2UgRG90VmlldyB7XG4gIHJ1bjogU2NhdHRlclJ1bjtcbiAgaW5kZXg6IG51bWJlcjtcbiAgY2xzOiBzdHJpbmc7XG4gIGZpbGw6IHN0cmluZztcbiAgc2hhcGU6IFNjYXR0ZXJTaGFwZTtcbiAgY3g6IG51bWJlcjtcbiAgY3k6IG51bWJlcjtcbiAgcjogbnVtYmVyO1xufVxuXG5jb25zdCBQQUwgPSBbXG4gICd2YXIoLS12by1jMSknLFxuICAndmFyKC0tdm8tYzIpJyxcbiAgJ3ZhcigtLXZvLWMzKScsXG4gICd2YXIoLS12by1jNCknLFxuICAndmFyKC0tdm8tYzUpJyxcbiAgJ3ZhcigtLXZvLWM2KScsXG5dO1xuY29uc3QgU0hBUEVTOiBTY2F0dGVyU2hhcGVbXSA9IFsnY2lyY2xlJywgJ3NxdWFyZScsICd0cmlhbmdsZSddO1xuXG5jb25zdCBtZWRpYW4gPSAoYTogbnVtYmVyW10pOiBudW1iZXIgPT4ge1xuICBpZiAoIWEubGVuZ3RoKSByZXR1cm4gMDtcbiAgY29uc3QgcyA9IFsuLi5hXS5zb3J0KChwLCBxKSA9PiBwIC0gcSk7XG4gIGNvbnN0IG0gPSBzLmxlbmd0aCA+PiAxO1xuICByZXR1cm4gcy5sZW5ndGggJSAyID8gc1ttXSA6IChzW20gLSAxXSArIHNbbV0pIC8gMjtcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZvLXNjYXR0ZXItY2hhcnQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBpbXBvcnRzOiBbVm9JY29uQ29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGRhdGEtdm89XCJcIiBjbGFzcz1cInZvLWN2cSB2by1wYW5lbFwiIFtjbGFzc109XCJjbGFzc05hbWVcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2by1jdnEtaFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidm8tY3ZxLXRcIj5cbiAgICAgICAgICA8Yj57eyB0aXRsZSB9fTwvYj5cbiAgICAgICAgICBAaWYgKHN1YnRpdGxlKSB7XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZvLW11dGVkXCI+e3sgc3VidGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInZvLWN2cS1sZ1wiPlxuICAgICAgICAgIEBmb3IgKHMgb2Ygc2VyaWVzOyB0cmFjayBzLmtleSkge1xuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJ2by1jdnEta1wiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCIhb2ZmLmluY2x1ZGVzKHMua2V5KVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGUocy5rZXkpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHN2ZyB2aWV3Qm94PVwiLTYgLTYgMTIgMTJcIiBbc3R5bGUuZmlsbF09XCJjb2xvck9mKHMua2V5KVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgIEBzd2l0Y2ggKHNoYXBlT2Yocy5rZXkpKSB7XG4gICAgICAgICAgICAgICAgICBAY2FzZSAoJ2NpcmNsZScpIHsgPGNpcmNsZSBbYXR0ci5jeF09XCIwXCIgW2F0dHIuY3ldPVwiMFwiIFthdHRyLnJdPVwiNC41XCIgLz4gfVxuICAgICAgICAgICAgICAgICAgQGNhc2UgKCdzcXVhcmUnKSB7IDxyZWN0IFthdHRyLnhdPVwiLTQuMDVcIiBbYXR0ci55XT1cIi00LjA1XCIgW2F0dHIud2lkdGhdPVwiOC4xXCIgW2F0dHIuaGVpZ2h0XT1cIjguMVwiIFthdHRyLnJ4XT1cIjEuMTI1XCIgLz4gfVxuICAgICAgICAgICAgICAgICAgQGRlZmF1bHQgeyA8cGF0aCBbYXR0ci5kXT1cInRyaVBhdGgoMCwgMCwgNC41KVwiIC8+IH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvc3ZnPnt7IHMubGFiZWwgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdlxuICAgICAgICAjcGxvdFxuICAgICAgICBjbGFzcz1cInZvLWN2cS1wbFwiXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIHJvbGU9XCJncm91cFwiXG4gICAgICAgIGFyaWEtcm9sZWRlc2NyaXB0aW9uPVwic2NhdHRlciBjaGFydFwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwidGl0bGUgKyAnLiBBcnJvdyBrZXlzIHN0ZXAgdGhyb3VnaCB0aGUgcnVucydcIlxuICAgICAgICAocG9pbnRlcmRvd24pPVwib25Qb2ludGVyRG93bigkZXZlbnQpXCJcbiAgICAgICAgKHBvaW50ZXJtb3ZlKT1cIm9uUG9pbnRlck1vdmUoJGV2ZW50KVwiXG4gICAgICAgIChwb2ludGVydXApPVwib25Qb2ludGVyVXAoKVwiXG4gICAgICAgIChwb2ludGVyY2FuY2VsKT1cIm9uUG9pbnRlckNhbmNlbCgpXCJcbiAgICAgICAgKHBvaW50ZXJsZWF2ZSk9XCJvblBvaW50ZXJMZWF2ZSgpXCJcbiAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIEBpZiAoVyA+IDApIHtcbiAgICAgICAgICA8c3ZnIGNsYXNzPVwidm8tY3ZxLXN2Z1wiIFthdHRyLnZpZXdCb3hdPVwiJzAgMCAnICsgVyArICcgJyArIEhcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgIDwhLS0gYSBmZXcgbGlnaHQgZ3JpZGxpbmVzIGFuZCBxdWlldCB0aWNrIGxhYmVsczsgdGhlIGF4aXMgdGl0bGVzIHNpdCB3ZWxsIGNsZWFyIG9mIHRoZSB0aWNrcyAtLT5cbiAgICAgICAgICAgIEBmb3IgKHYgb2YgeXQ7IHRyYWNrIHYpIHtcbiAgICAgICAgICAgICAgPGc+XG4gICAgICAgICAgICAgICAgPGxpbmUgY2xhc3M9XCJ2by1nbFwiIFthdHRyLngxXT1cImxcIiBbYXR0ci54Ml09XCJXIC0gcnJcIiBbYXR0ci55MV09XCJZKHYpXCIgW2F0dHIueTJdPVwiWSh2KVwiIC8+XG4gICAgICAgICAgICAgICAgPHRleHQgW2F0dHIueF09XCJsIC0gNlwiIFthdHRyLnldPVwiWSh2KSArIDMuNVwiIHRleHQtYW5jaG9yPVwiZW5kXCI+e3sgdiB9fTwvdGV4dD5cbiAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGZvciAodiBvZiB4dDsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDx0ZXh0XG4gICAgICAgICAgICAgICAgW2F0dHIueF09XCJYKHYpXCJcbiAgICAgICAgICAgICAgICBbYXR0ci55XT1cIkggLSBiICsgMTVcIlxuICAgICAgICAgICAgICAgIFthdHRyLnRleHQtYW5jaG9yXT1cIiRpbmRleCA9PT0gMCA/ICdzdGFydCcgOiAkaW5kZXggPT09IHh0Lmxlbmd0aCAtIDEgPyAnZW5kJyA6ICdtaWRkbGUnXCJcbiAgICAgICAgICAgICAgPnt7IGZvcm1hdFgodikgfX08L3RleHQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bGluZSBjbGFzcz1cInZvLWF4XCIgW2F0dHIueDFdPVwibFwiIFthdHRyLngyXT1cIlcgLSByclwiIFthdHRyLnkxXT1cIkggLSBiXCIgW2F0dHIueTJdPVwiSCAtIGJcIiAvPlxuICAgICAgICAgICAgPHRleHQgY2xhc3M9XCJ2by1hdFwiIFthdHRyLnhdPVwiVyAtIHJyXCIgW2F0dHIueV09XCJIIC0gMVwiIHRleHQtYW5jaG9yPVwiZW5kXCI+e3sgeFRpdGxlIH19PC90ZXh0PlxuICAgICAgICAgICAgPHRleHQgY2xhc3M9XCJ2by1hdFwiIFthdHRyLnhdPVwiLXRcIiBbYXR0ci55XT1cIjlcIiB0cmFuc2Zvcm09XCJyb3RhdGUoLTkwKVwiIHRleHQtYW5jaG9yPVwiZW5kXCI+e3sgeVRpdGxlIH19PC90ZXh0PlxuICAgICAgICAgICAgPGxpbmUgY2xhc3M9XCJ2by1tZFwiIFthdHRyLngxXT1cIlgobXgpXCIgW2F0dHIueDJdPVwiWChteClcIiBbYXR0ci55MV09XCJ0XCIgW2F0dHIueTJdPVwiSCAtIGJcIiAvPlxuICAgICAgICAgICAgPGxpbmUgY2xhc3M9XCJ2by1tZFwiIFthdHRyLngxXT1cImxcIiBbYXR0ci54Ml09XCJXIC0gcnJcIiBbYXR0ci55MV09XCJZKG15KVwiIFthdHRyLnkyXT1cIlkobXkpXCIgLz5cbiAgICAgICAgICAgIEBpZiAoIW5hcnJvdykge1xuICAgICAgICAgICAgICA8dGV4dCBjbGFzcz1cInZvLXFcIiBbYXR0ci54XT1cImwgKyA2XCIgW2F0dHIueV09XCJ0ICsgMTFcIj57eyBxdWFkcmFudHNbMF0gfX08L3RleHQ+XG4gICAgICAgICAgICAgIDx0ZXh0IGNsYXNzPVwidm8tcVwiIFthdHRyLnhdPVwiVyAtIHJyIC0gNFwiIFthdHRyLnldPVwidCArIDExXCIgdGV4dC1hbmNob3I9XCJlbmRcIj57eyBxdWFkcmFudHNbMV0gfX08L3RleHQ+XG4gICAgICAgICAgICAgIDx0ZXh0IGNsYXNzPVwidm8tcVwiIFthdHRyLnhdPVwiVyAtIHJyIC0gNFwiIFthdHRyLnldPVwiSCAtIGIgLSA2XCIgdGV4dC1hbmNob3I9XCJlbmRcIj57eyBxdWFkcmFudHNbMl0gfX08L3RleHQ+XG4gICAgICAgICAgICAgIDx0ZXh0IGNsYXNzPVwidm8tcVwiIFthdHRyLnhdPVwibCArIDZcIiBbYXR0ci55XT1cIkggLSBiIC0gNlwiPnt7IHF1YWRyYW50c1szXSB9fTwvdGV4dD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBmb3IgKGQgb2YgZG90czsgdHJhY2sgZC5ydW4uaWQpIHtcbiAgICAgICAgICAgICAgPGcgW2NsYXNzXT1cImQuY2xzXCIgW3N0eWxlLmZpbGxdPVwiZC5maWxsXCI+XG4gICAgICAgICAgICAgICAgQHN3aXRjaCAoZC5zaGFwZSkge1xuICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaXJjbGUnKSB7IDxjaXJjbGUgW2F0dHIuY3hdPVwiZC5jeFwiIFthdHRyLmN5XT1cImQuY3lcIiBbYXR0ci5yXT1cImQuclwiIC8+IH1cbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnc3F1YXJlJykgeyA8cmVjdCBbYXR0ci54XT1cImQuY3ggLSBkLnIgKiAwLjlcIiBbYXR0ci55XT1cImQuY3kgLSBkLnIgKiAwLjlcIiBbYXR0ci53aWR0aF09XCJkLnIgKiAxLjhcIiBbYXR0ci5oZWlnaHRdPVwiZC5yICogMS44XCIgW2F0dHIucnhdPVwiZC5yICogMC4yNVwiIC8+IH1cbiAgICAgICAgICAgICAgICAgIEBkZWZhdWx0IHsgPHBhdGggW2F0dHIuZF09XCJ0cmlQYXRoKGQuY3gsIGQuY3ksIGQucilcIiAvPiB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChkIG9mIHJpbmdEb3RzOyB0cmFjayBkLnJ1bi5pZCkge1xuICAgICAgICAgICAgICA8Y2lyY2xlIGNsYXNzPVwidm8tcmluZ1wiIFthdHRyLmN4XT1cImQuY3hcIiBbYXR0ci5jeV09XCJkLmN5XCIgW2F0dHIucl09XCJkLnIgKyA2XCIgLz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoYm94KSB7XG4gICAgICAgICAgICAgIDxyZWN0XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ2by1ib3hcIlxuICAgICAgICAgICAgICAgIFthdHRyLnhdPVwibWluKGJveFswXSwgYm94WzJdKVwiXG4gICAgICAgICAgICAgICAgW2F0dHIueV09XCJtaW4oYm94WzFdLCBib3hbM10pXCJcbiAgICAgICAgICAgICAgICBbYXR0ci53aWR0aF09XCJhYnMoYm94WzJdIC0gYm94WzBdKVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuaGVpZ2h0XT1cImFicyhib3hbM10gLSBib3hbMV0pXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5yeF09XCIzXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgfVxuICAgICAgICA8ZGl2ICN0aXAgY2xhc3M9XCJ2by1jdnEtdHRcIiBbY2xhc3Mudm8tb25dPVwiaHJcIiBbc3R5bGUubGVmdC5weF09XCJ0dFhcIiBbc3R5bGUudG9wLnB4XT1cInR0WVwiPlxuICAgICAgICAgIEBpZiAoaHIpIHtcbiAgICAgICAgICAgIDxiIGNsYXNzPVwidm8tbnVtXCI+e3sgZm9ybWF0WChoci54KSB9fSDCtyB7eyBmb3JtYXRZKGhyLnkpIH19PC9iPlxuICAgICAgICAgICAgPHNwYW4+UnVuIHt7IGhyLmlkIH19LCB7eyBsYWJlbE9mKGhyLnNlcmllcykgfX0sIHt7IGZvcm1hdFNpemUoaHIuc2l6ZSkgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwidm8tY3ZxLWZ0XCIgYXJpYS1saXZlPVwicG9saXRlXCI+XG4gICAgICAgIEBpZiAoaHIgJiYgZm9jdXNlZCkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tY3ZxLW1zZ1wiPlxuICAgICAgICAgICAgPHNwYW4+PGI+UnVuIHt7IGhyLmlkIH19PC9iPiwge3sgbGFiZWxPZihoci5zZXJpZXMpIH19OiB7eyBmb3JtYXRYKGhyLngpIH19LCB7eyBmb3JtYXRZKGhyLnkpIH19LCB7eyBmb3JtYXRTaXplKGhyLnNpemUpIH19LiB7eyBvcmRlci5pbmRleE9mKGhvdCkgKyAxIH19IG9mIHt7IG9yZGVyLmxlbmd0aCB9fTwvc3Bhbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH0gQGVsc2UgaWYgKGFuc3dlcikge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tY3ZxLW1zZ1wiPlxuICAgICAgICAgICAgPHZvLWljb24gY2xhc3M9XCJ2by1pXCIgbmFtZT1cInNwYXJrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPlxuICAgICAgICAgICAgPHNwYW4gW2NsYXNzLnZvLXNoaW1dPVwiYW5zd2VyLmJ1c3lcIj57eyBhbnN3ZXIuYnVzeSA/ICdMb29raW5nIGF0ICcgKyBzZWxlY3RlZFJ1bnMubGVuZ3RoICsgJyBydW5zJyA6IGFuc3dlci50ZXh0IH19PC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgfSBAZWxzZSBpZiAoc2VsZWN0ZWRSdW5zLmxlbmd0aCkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tY3ZxLW1zZ1wiPlxuICAgICAgICAgICAgPHNwYW4+PGI+e3sgc2VsZWN0ZWRSdW5zLmxlbmd0aCB9fSBydW5zIHNlbGVjdGVkPC9iPiwge3sgZm9ybWF0WChhdmdYKSB9fSBhbmQge3sgZm9ybWF0WShhdmdZKSB9fSBvbiBhdmVyYWdlPC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICBAaWYgKGFzay5vYnNlcnZlZCkge1xuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ2by1waWxsIHZvLXNvZnQgdm8tc21cIiAoY2xpY2spPVwicnVuQXNrKClcIj5cbiAgICAgICAgICAgICAgPHZvLWljb24gbmFtZT1cInNwYXJrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPkFzayB0aGUgYWdlbnQgd2h5XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidm8tY3ZxLW1zZ1wiPlxuICAgICAgICAgICAgPHZvLWljb24gY2xhc3M9XCJ2by1pXCIgbmFtZT1cInNwYXJrXCIgc2l6ZT1cInhzXCI+PC92by1pY29uPlxuICAgICAgICAgICAgPHNwYW4+e3sgbm90ZSA/PyBkZWZhdWx0Tm90ZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZVVybDogJy4vc2NhdHRlci1jaGFydC5jc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBTY2F0dGVyQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBydW5zOiBTY2F0dGVyUnVuW10gPSBbXTtcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgc2VyaWVzOiBTY2F0dGVyU2VyaWVzW10gPSBbXTtcbiAgQElucHV0KCkgY2xhc3NOYW1lID0gJyc7XG4gIEBJbnB1dCgpIHRpdGxlID0gJ0Nvc3QgdnMgcXVhbGl0eSc7XG4gIEBJbnB1dCgpIHN1YnRpdGxlPzogc3RyaW5nO1xuICAvKiogW21pbiwgbWF4XSBvZiBlYWNoIGF4aXMuICovXG4gIEBJbnB1dCgpIHhEb21haW46IFtudW1iZXIsIG51bWJlcl0gPSBbMCwgMC42XTtcbiAgQElucHV0KCkgeURvbWFpbjogW251bWJlciwgbnVtYmVyXSA9IFs2MCwgMTAwXTtcbiAgLyoqIFdoZXJlIHRoZSBsYWJlbHMgZ28gYWxvbmcgdGhlIGJvdHRvbS4gQSBuYXJyb3cgY2hhcnQga2VlcHMgdGhlIHR3byBlbmRzIGFuZCB0aGUgbWlkZGxlLiAqL1xuICBASW5wdXQoKSB4VGlja3M6IG51bWJlcltdID0gWzAsIDAuMiwgMC40LCAwLjZdO1xuICAvKiogV2hlcmUgdGhlIGdyaWRsaW5lcyBhbmQgdGhlaXIgbGFiZWxzIGdvIHVwIHRoZSBzaWRlLiBBIG5hcnJvdyBjaGFydCBrZWVwcyB0aGUgdHdvIGVuZHMgYW5kIHRoZSBtaWRkbGUuICovXG4gIEBJbnB1dCgpIHlUaWNrczogbnVtYmVyW10gPSBbNjAsIDgwLCAxMDBdO1xuICBASW5wdXQoKSB4VGl0bGUgPSAnQ29zdCBwZXIgcnVuIChVU0QpJztcbiAgQElucHV0KCkgeVRpdGxlID0gJ0V2YWwgc2NvcmUgKCUpJztcbiAgQElucHV0KCkgZm9ybWF0WDogKHg6IG51bWJlcikgPT4gc3RyaW5nID0gKHgpID0+ICckJyArIHgudG9GaXhlZCgyKTtcbiAgQElucHV0KCkgZm9ybWF0WTogKHk6IG51bWJlcikgPT4gc3RyaW5nID0gKHkpID0+IE1hdGgucm91bmQoeSkgKyAnJSc7XG4gIEBJbnB1dCgpIGZvcm1hdFNpemU6IChzOiBudW1iZXIpID0+IHN0cmluZyA9IChzKSA9PiBNYXRoLnJvdW5kKHMpICsgJ2sgdG9rZW5zJztcbiAgLyoqIFRoZSBmb3VyIHF1YWRyYW50cyB0aGUgbWVkaWFucyBtYWtlLCBmcm9tIHRoZSB0b3AgbGVmdCwgY2xvY2t3aXNlLiBBIG5hcnJvdyBjaGFydCBrZWVwcyB0aGUgbWVkaWFuIGxpbmVzIGFuZCBsZWF2ZXMgdGhlIG5hbWVzIG91dC4gKi9cbiAgQElucHV0KCkgcXVhZHJhbnRzOiBbc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nXSA9IFtcbiAgICAnQ2hlYXAsIGdvb2QnLFxuICAgICdDb3N0bHksIGdvb2QnLFxuICAgICdDb3N0bHksIHdlYWtlcicsXG4gICAgJ0NoZWFwLCB3ZWFrZXInLFxuICBdO1xuICAvKiogUnVucyB0byByaW5nLCBsaWtlIG91dGxpZXJzIHRoZSBhZ2VudCBmb3VuZC4gKi9cbiAgQElucHV0KCkgcmluZ2VkOiAoc3RyaW5nIHwgbnVtYmVyKVtdID0gW107XG4gIC8qKiBUaGUgbGluZSB1bmRlciB0aGUgY2hhcnQgd2hpbGUgbm90aGluZyBpcyBzZWxlY3RlZCBvciBpbiBmb2N1cy4gKi9cbiAgQElucHV0KCkgbm90ZT86IHN0cmluZztcbiAgLyoqIFRoZSBzZWxlY3RlZCBydW5zLCBieSBpZC4gTGVhdmUgaXQgb3V0IHRvIGxldCB0aGUgY2hhcnQgaG9sZCB0aGUgc2VsZWN0aW9uLiAqL1xuICBASW5wdXQoKSBzZXQgc2VsZWN0ZWQodmFsdWU6IChzdHJpbmcgfCBudW1iZXIpW10gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLmNvbnRyb2xsZWQgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNlbCA9IHZhbHVlO1xuICAgICAgdGhpcy5hc2tlZCsrO1xuICAgICAgdGhpcy5hbnN3ZXIgPSBudWxsO1xuICAgICAgaWYgKHRoaXMucmVhZHkpIHRoaXMuZHJhdygpO1xuICAgIH1cbiAgfVxuXG4gIEBPdXRwdXQoKSBzZWxlY3RlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8KHN0cmluZyB8IG51bWJlcilbXT4oKTtcbiAgLyoqIEFkZHMgXCJBc2sgdGhlIGFnZW50IHdoeVwiIHRvIGEgc2VsZWN0aW9uLiBSZXR1cm4gdGhlIGFuc3dlciBhbmQgaXQgc3RyZWFtcyBpbi4gKi9cbiAgQE91dHB1dCgpIGFzayA9IG5ldyBFdmVudEVtaXR0ZXI8U2NhdHRlclJ1bltdPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ3Bsb3QnKSBwbG90UmVmITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3RpcCcpIHRpcFJlZiE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVkdWNlZCA9IGluamVjdChSZWR1Y2VkTW90aW9uU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICAvLyBtZWFzdXJlZCBnZW9tZXRyeVxuICBXID0gMDtcbiAgSCA9IDA7XG4gIG5hcnJvdyA9IGZhbHNlO1xuICBsID0gNDQ7XG4gIGIgPSA0MDtcbiAgdCA9IDY7XG4gIHJyID0gODtcblxuICAvLyByZW5kZXIgc3RhdGVcbiAgZG90czogRG90Vmlld1tdID0gW107XG4gIHJpbmdEb3RzOiBEb3RWaWV3W10gPSBbXTtcbiAgeHQ6IG51bWJlcltdID0gW107XG4gIHl0OiBudW1iZXJbXSA9IFtdO1xuICBteCA9IDA7XG4gIG15ID0gMDtcbiAgaG90ID0gLTE7XG4gIGhyOiBTY2F0dGVyUnVuIHwgbnVsbCA9IG51bGw7XG4gIGJveDogbnVtYmVyW10gfCBudWxsID0gbnVsbDtcbiAgdHRYID0gMDtcbiAgdHRZID0gMDtcbiAgZm9jdXNlZCA9IGZhbHNlO1xuICBvcmRlcjogbnVtYmVyW10gPSBbXTtcbiAgc2VsZWN0ZWRSdW5zOiBTY2F0dGVyUnVuW10gPSBbXTtcbiAgYXZnWCA9IDA7XG4gIGF2Z1kgPSAwO1xuICBhbnN3ZXI6IHsgdGV4dDogc3RyaW5nOyBidXN5OiBib29sZWFuIH0gfCBudWxsID0gbnVsbDtcblxuICBvZmY6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgc2VsOiAoc3RyaW5nIHwgbnVtYmVyKVtdID0gW107XG4gIHByaXZhdGUgY29udHJvbGxlZCA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWR5ID0gZmFsc2U7XG4gIHByaXZhdGUgYXNrZWQgPSAwO1xuICBwcml2YXRlIGRyYWc6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGlkOiBudW1iZXI7IG1vdmVkOiBib29sZWFuIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBybz86IFJlc2l6ZU9ic2VydmVyO1xuICBwcml2YXRlIHRpbWVyczogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD5bXSA9IFtdO1xuXG4gIC8vIHRlbXBsYXRlIGhlbHBlcnNcbiAgcmVhZG9ubHkgbWluID0gTWF0aC5taW47XG4gIHJlYWRvbmx5IGFicyA9IE1hdGguYWJzO1xuXG4gIGdldCBkZWZhdWx0Tm90ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgTWVkaWFucyBzcGxpdCB0aGUgcnVuczogJHt0aGlzLmZvcm1hdFgodGhpcy5teCl9IGFuZCAke3RoaXMuZm9ybWF0WSh0aGlzLm15KX0uIERyYWcgYWNyb3NzIHRoZSBjaGFydCB0byBzZWxlY3QgcnVucy5gO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IGVsID0gdGhpcy5wbG90UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5ybyA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICB0aGlzLlcgPSBlbC5jbGllbnRXaWR0aDtcbiAgICAgIHRoaXMuSCA9IGVsLmNsaWVudEhlaWdodDtcbiAgICAgIHRoaXMuZHJhdygpO1xuICAgIH0pO1xuICAgIHRoaXMucm8ub2JzZXJ2ZShlbCk7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgdGhpcy5XID0gZWwuY2xpZW50V2lkdGg7XG4gICAgdGhpcy5IID0gZWwuY2xpZW50SGVpZ2h0O1xuICAgIHRoaXMuZHJhdygpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8vIC0tLS0tIHNlcmllcyBsb29rLXVwcyAtLS0tLVxuICBwcml2YXRlIHNpKGtleTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5zZXJpZXMuZmluZEluZGV4KChzKSA9PiBzLmtleSA9PT0ga2V5KSk7XG4gIH1cbiAgY29sb3JPZihrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VyaWVzW3RoaXMuc2koa2V5KV0/LmNvbG9yID8/IFBBTFt0aGlzLnNpKGtleSkgJSBQQUwubGVuZ3RoXTtcbiAgfVxuICBzaGFwZU9mKGtleTogc3RyaW5nKTogU2NhdHRlclNoYXBlIHtcbiAgICByZXR1cm4gdGhpcy5zZXJpZXNbdGhpcy5zaShrZXkpXT8uc2hhcGUgPz8gU0hBUEVTW3RoaXMuc2koa2V5KSAlIFNIQVBFUy5sZW5ndGhdO1xuICB9XG4gIGxhYmVsT2Yoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNlcmllc1t0aGlzLnNpKGtleSldPy5sYWJlbCA/PyAnJztcbiAgfVxuXG4gIC8qKiBUaGUgdHJpYW5nbGUgbWFyaydzIHBhdGgsIHNvIGEgZG90IHJlYWRzIHdpdGhvdXQgY29sb3VyIHRvby4gKi9cbiAgdHJpUGF0aCh4OiBudW1iZXIsIHk6IG51bWJlciwgczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYE0ke3h9ICR7eSAtIHMgKiAxLjE1fUwke3ggKyBzICogMS4wNX0gJHt5ICsgcyAqIDAuNzV9TCR7eCAtIHMgKiAxLjA1fSAke3kgKyBzICogMC43NX1aYDtcbiAgfVxuXG4gIC8vIC0tLS0tIGdlb21ldHJ5IC0tLS0tXG4gIFgodjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5sICsgKCh2IC0gdGhpcy54RG9tYWluWzBdKSAvICh0aGlzLnhEb21haW5bMV0gLSB0aGlzLnhEb21haW5bMF0pKSAqICh0aGlzLlcgLSB0aGlzLmwgLSB0aGlzLnJyKTtcbiAgfVxuICBZKHY6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudCArICgxIC0gKHYgLSB0aGlzLnlEb21haW5bMF0pIC8gKHRoaXMueURvbWFpblsxXSAtIHRoaXMueURvbWFpblswXSkpICogKHRoaXMuSCAtIHRoaXMudCAtIHRoaXMuYik7XG4gIH1cbiAgcHJpdmF0ZSBSKHJ1bjogU2NhdHRlclJ1bik6IG51bWJlciB7XG4gICAgY29uc3Qgc01pbiA9IE1hdGgubWluKC4uLnRoaXMucnVucy5tYXAoKHIpID0+IHIuc2l6ZSkpO1xuICAgIGNvbnN0IHNNYXggPSBNYXRoLm1heCguLi50aGlzLnJ1bnMubWFwKChyKSA9PiByLnNpemUpKTtcbiAgICByZXR1cm4gKDMgKyAoKHJ1bi5zaXplIC0gc01pbikgLyBNYXRoLm1heCgxLCBzTWF4IC0gc01pbikpICogNC41KSAqICh0aGlzLm5hcnJvdyA/IDAuODUgOiAxKTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd25JZHgoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnJ1bnMubWFwKChfLCBpKSA9PiBpKS5maWx0ZXIoKGkpID0+ICF0aGlzLm9mZi5pbmNsdWRlcyh0aGlzLnJ1bnNbaV0uc2VyaWVzKSk7XG4gIH1cblxuICAvLyAtLS0tLSBkcmF3OiByZWNvbXB1dGUgZXZlcnkgdmlldyBtb2RlbCwgbWlycm9yaW5nIHRoZSBSZWFjdCByZW5kZXIgLS0tLS1cbiAgZHJhdygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVhZHkgfHwgdGhpcy5XIDw9IDApIHtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm5hcnJvdyA9IHRoaXMuVyA+IDAgJiYgdGhpcy5XIDw9IDM0MDtcbiAgICB0aGlzLmwgPSB0aGlzLm5hcnJvdyA/IDM4IDogNDQ7XG5cbiAgICBjb25zdCBlbmRzID0gKGE6IG51bWJlcltdLCBkOiBbbnVtYmVyLCBudW1iZXJdKTogbnVtYmVyW10gPT5cbiAgICAgIHRoaXMubmFycm93ICYmIGEubGVuZ3RoID4gMyA/IFthWzBdLCAoZFswXSArIGRbMV0pIC8gMiwgYVthLmxlbmd0aCAtIDFdXSA6IGE7XG4gICAgdGhpcy54dCA9IGVuZHModGhpcy54VGlja3MsIHRoaXMueERvbWFpbik7XG4gICAgdGhpcy55dCA9IGVuZHModGhpcy55VGlja3MsIHRoaXMueURvbWFpbik7XG5cbiAgICBjb25zdCBzaG93biA9IHRoaXMuc2hvd25JZHgoKTtcbiAgICB0aGlzLm14ID0gbWVkaWFuKHNob3duLm1hcCgoaSkgPT4gdGhpcy5ydW5zW2ldLngpKTtcbiAgICB0aGlzLm15ID0gbWVkaWFuKHNob3duLm1hcCgoaSkgPT4gdGhpcy5ydW5zW2ldLnkpKTtcblxuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsO1xuICAgIHRoaXMuZG90cyA9IHRoaXMucnVucy5tYXAoKHJ1biwgaSkgPT4ge1xuICAgICAgY29uc3Qgb2ZmID0gdGhpcy5vZmYuaW5jbHVkZXMocnVuLnNlcmllcyk7XG4gICAgICBjb25zdCBkaW0gPSB0aGlzLmhyICE9IG51bGwgJiYgdGhpcy5oci5zZXJpZXMgIT09IHJ1bi5zZXJpZXMgJiYgIW9mZjtcbiAgICAgIGNvbnN0IGNscyA9IFsndm8tZCcsIG9mZiA/ICd2by1vZmYnIDogJycsIGRpbSA/ICd2by1kaW0nIDogJycsIGkgPT09IHRoaXMuaG90ID8gJ3ZvLW9uJyA6ICcnLCBzZWwuaW5jbHVkZXMocnVuLmlkKSA/ICd2by1zZWwnIDogJyddXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgLmpvaW4oJyAnKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJ1bixcbiAgICAgICAgaW5kZXg6IGksXG4gICAgICAgIGNscyxcbiAgICAgICAgZmlsbDogdGhpcy5jb2xvck9mKHJ1bi5zZXJpZXMpLFxuICAgICAgICBzaGFwZTogdGhpcy5zaGFwZU9mKHJ1bi5zZXJpZXMpLFxuICAgICAgICBjeDogK3RoaXMuWChydW4ueCkudG9GaXhlZCgxKSxcbiAgICAgICAgY3k6ICt0aGlzLlkocnVuLnkpLnRvRml4ZWQoMSksXG4gICAgICAgIHI6ICt0aGlzLlIocnVuKS50b0ZpeGVkKDEpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHRoaXMucmluZ0RvdHMgPSB0aGlzLnJ1bnNcbiAgICAgIC5maWx0ZXIoKHJ1bikgPT4gdGhpcy5yaW5nZWQuaW5jbHVkZXMocnVuLmlkKSAmJiAhdGhpcy5vZmYuaW5jbHVkZXMocnVuLnNlcmllcykpXG4gICAgICAubWFwKChydW4pID0+ICh7XG4gICAgICAgIHJ1bixcbiAgICAgICAgaW5kZXg6IHRoaXMucnVucy5pbmRleE9mKHJ1biksXG4gICAgICAgIGNsczogJycsXG4gICAgICAgIGZpbGw6IHRoaXMuY29sb3JPZihydW4uc2VyaWVzKSxcbiAgICAgICAgc2hhcGU6IHRoaXMuc2hhcGVPZihydW4uc2VyaWVzKSxcbiAgICAgICAgY3g6IHRoaXMuWChydW4ueCksXG4gICAgICAgIGN5OiB0aGlzLlkocnVuLnkpLFxuICAgICAgICByOiB0aGlzLlIocnVuKSxcbiAgICAgIH0pKTtcblxuICAgIHRoaXMub3JkZXIgPSBbLi4uc2hvd25dLnNvcnQoKGEsIGMpID0+IHRoaXMucnVuc1thXS54IC0gdGhpcy5ydW5zW2NdLnggfHwgdGhpcy5ydW5zW2NdLnkgLSB0aGlzLnJ1bnNbYV0ueSk7XG5cbiAgICB0aGlzLmhyID0gdGhpcy5ob3QgPj0gMCA/IHRoaXMucnVuc1t0aGlzLmhvdF0gOiBudWxsO1xuICAgIGlmICh0aGlzLmhyICYmIHRoaXMudGlwUmVmKSB7XG4gICAgICBjb25zdCB3ID0gdGhpcy50aXBSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgIHRoaXMudHRYID0gTWF0aC5tYXgodyAvIDIsIE1hdGgubWluKHRoaXMuVyAtIHcgLyAyLCB0aGlzLlgodGhpcy5oci54KSkpO1xuICAgICAgdGhpcy50dFkgPSB0aGlzLlkodGhpcy5oci55KSAtIHRoaXMuUih0aGlzLmhyKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkUnVucyA9IHRoaXMucnVucy5maWx0ZXIoKHIpID0+IHNlbC5pbmNsdWRlcyhyLmlkKSk7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRSdW5zLmxlbmd0aCkge1xuICAgICAgdGhpcy5hdmdYID0gdGhpcy5zZWxlY3RlZFJ1bnMucmVkdWNlKChhLCByKSA9PiBhICsgci54LCAwKSAvIHRoaXMuc2VsZWN0ZWRSdW5zLmxlbmd0aDtcbiAgICAgIHRoaXMuYXZnWSA9IHRoaXMuc2VsZWN0ZWRSdW5zLnJlZHVjZSgoYSwgcikgPT4gYSArIHIueSwgMCkgLyB0aGlzLnNlbGVjdGVkUnVucy5sZW5ndGg7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLy8gLS0tLS0gbGVnZW5kIC0tLS0tXG4gIHRvZ2dsZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5vZmYuaW5jbHVkZXMoa2V5KSAmJiB0aGlzLm9mZi5sZW5ndGggPT09IHRoaXMuc2VyaWVzLmxlbmd0aCAtIDEpIHJldHVybjtcbiAgICB0aGlzLmhvdCA9IC0xO1xuICAgIHRoaXMub2ZmID0gdGhpcy5vZmYuaW5jbHVkZXMoa2V5KSA/IHRoaXMub2ZmLmZpbHRlcigoaykgPT4gayAhPT0ga2V5KSA6IFsuLi50aGlzLm9mZiwga2V5XTtcbiAgICB0aGlzLmRyYXcoKTtcbiAgfVxuXG4gIC8vIC0tLS0tIHBvaW50ZXIgLyBzZWxlY3Rpb24gLS0tLS1cbiAgcHJpdmF0ZSBsb2NhbChlOiBQb2ludGVyRXZlbnQpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCByID0gdGhpcy5wbG90UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIFtlLmNsaWVudFggLSByLmxlZnQsIGUuY2xpZW50WSAtIHIudG9wXTtcbiAgfVxuICBwcml2YXRlIG5lYXIocHg6IG51bWJlciwgcHk6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IGJlc3QgPSAtMTtcbiAgICBsZXQgYmQgPSAyNiAqIDI2O1xuICAgIGZvciAoY29uc3QgaSBvZiB0aGlzLnNob3duSWR4KCkpIHtcbiAgICAgIGNvbnN0IGR4ID0gdGhpcy5YKHRoaXMucnVuc1tpXS54KSAtIHB4O1xuICAgICAgY29uc3QgZHkgPSB0aGlzLlkodGhpcy5ydW5zW2ldLnkpIC0gcHk7XG4gICAgICBjb25zdCBkID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgICBpZiAoZCA8IGJkKSB7XG4gICAgICAgIGJkID0gZDtcbiAgICAgICAgYmVzdCA9IGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTZWwoaWRzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xsZWQpIHtcbiAgICAgIHRoaXMuc2VsID0gaWRzO1xuICAgICAgdGhpcy5hc2tlZCsrO1xuICAgICAgdGhpcy5hbnN3ZXIgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkQ2hhbmdlLmVtaXQoaWRzKTtcbiAgICB0aGlzLmRyYXcoKTtcbiAgfVxuXG4gIG9uUG9pbnRlckRvd24oZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGUuYnV0dG9uKSByZXR1cm47XG4gICAgY29uc3QgW3gsIHldID0gdGhpcy5sb2NhbChlKTtcbiAgICB0aGlzLmRyYWcgPSB7IHgsIHksIGlkOiBlLnBvaW50ZXJJZCwgbW92ZWQ6IGZhbHNlIH07XG4gIH1cblxuICBvblBvaW50ZXJNb3ZlKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IFt4LCB5XSA9IHRoaXMubG9jYWwoZSk7XG4gICAgY29uc3QgZCA9IHRoaXMuZHJhZztcbiAgICBpZiAoZCAmJiAoZC5tb3ZlZCB8fCBNYXRoLmFicyh4IC0gZC54KSArIE1hdGguYWJzKHkgLSBkLnkpID4gNSkpIHtcbiAgICAgIGlmICghZC5tb3ZlZCkge1xuICAgICAgICBkLm1vdmVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wbG90UmVmLm5hdGl2ZUVsZW1lbnQuc2V0UG9pbnRlckNhcHR1cmUoZC5pZCk7XG4gICAgICAgIHRoaXMuaG90ID0gLTE7XG4gICAgICB9XG4gICAgICB0aGlzLmJveCA9IFtcbiAgICAgICAgZC54LFxuICAgICAgICBkLnksXG4gICAgICAgIE1hdGgubWF4KHRoaXMubCwgTWF0aC5taW4odGhpcy5XIC0gdGhpcy5yciwgeCkpLFxuICAgICAgICBNYXRoLm1heCh0aGlzLnQsIE1hdGgubWluKHRoaXMuSCAtIHRoaXMuYiwgeSkpLFxuICAgICAgXTtcbiAgICAgIHRoaXMuZHJhdygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZS5wb2ludGVyVHlwZSAhPT0gJ3RvdWNoJykge1xuICAgICAgY29uc3QgaSA9IHRoaXMubmVhcih4LCB5KTtcbiAgICAgIGlmIChpICE9PSB0aGlzLmhvdCkge1xuICAgICAgICB0aGlzLmhvdCA9IGk7XG4gICAgICAgIHRoaXMuZHJhdygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uUG9pbnRlclVwKCk6IHZvaWQge1xuICAgIGNvbnN0IGQgPSB0aGlzLmRyYWc7XG4gICAgdGhpcy5kcmFnID0gbnVsbDtcbiAgICBpZiAoIWQpIHJldHVybjtcbiAgICBpZiAoZC5tb3ZlZCAmJiB0aGlzLmJveCkge1xuICAgICAgY29uc3QgW2EsIGIyLCB4MiwgeTJdID0gdGhpcy5ib3g7XG4gICAgICBjb25zdCBsbyA9IE1hdGgubWluKGEsIHgyKTtcbiAgICAgIGNvbnN0IGhpID0gTWF0aC5tYXgoYSwgeDIpO1xuICAgICAgY29uc3QgdG9wID0gTWF0aC5taW4oYjIsIHkyKTtcbiAgICAgIGNvbnN0IGJvdCA9IE1hdGgubWF4KGIyLCB5Mik7XG4gICAgICBjb25zdCBpZHMgPSB0aGlzLnNob3duSWR4KClcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAoaSkgPT5cbiAgICAgICAgICAgIHRoaXMuWCh0aGlzLnJ1bnNbaV0ueCkgPj0gbG8gJiZcbiAgICAgICAgICAgIHRoaXMuWCh0aGlzLnJ1bnNbaV0ueCkgPD0gaGkgJiZcbiAgICAgICAgICAgIHRoaXMuWSh0aGlzLnJ1bnNbaV0ueSkgPj0gdG9wICYmXG4gICAgICAgICAgICB0aGlzLlkodGhpcy5ydW5zW2ldLnkpIDw9IGJvdCxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChpKSA9PiB0aGlzLnJ1bnNbaV0uaWQpO1xuICAgICAgdGhpcy5ib3ggPSBudWxsO1xuICAgICAgdGhpcy5zZXRTZWwoaWRzKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaG90IDwgMCAmJiB0aGlzLnNlbC5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYm94ID0gbnVsbDtcbiAgICAgIHRoaXMuc2V0U2VsKFtdKTtcbiAgICB9XG4gIH1cblxuICBvblBvaW50ZXJDYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5kcmFnID0gbnVsbDtcbiAgICB0aGlzLmJveCA9IG51bGw7XG4gICAgdGhpcy5kcmF3KCk7XG4gIH1cblxuICBvblBvaW50ZXJMZWF2ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZyAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0aGlzLnBsb3RSZWYubmF0aXZlRWxlbWVudCAmJiB0aGlzLmhvdCA+PSAwKSB7XG4gICAgICB0aGlzLmhvdCA9IC0xO1xuICAgICAgdGhpcy5kcmF3KCk7XG4gICAgfVxuICB9XG5cbiAgb25CbHVyKCk6IHZvaWQge1xuICAgIHRoaXMuZm9jdXNlZCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmhvdCA+PSAwKSB7XG4gICAgICB0aGlzLmhvdCA9IC0xO1xuICAgICAgdGhpcy5kcmF3KCk7XG4gICAgfVxuICB9XG5cbiAgb25LZXlEb3duKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzZWQgPSB0cnVlO1xuICAgIGNvbnN0IG8gPSB0aGlzLm9yZGVyO1xuICAgIGxldCBrID0gby5pbmRleE9mKHRoaXMuaG90KTtcbiAgICBpZiAoZS5rZXkgPT09ICdBcnJvd1JpZ2h0JyB8fCBlLmtleSA9PT0gJ0Fycm93RG93bicpIGsgPSBNYXRoLm1pbihvLmxlbmd0aCAtIDEsIGsgKyAxKTtcbiAgICBlbHNlIGlmIChlLmtleSA9PT0gJ0Fycm93TGVmdCcgfHwgZS5rZXkgPT09ICdBcnJvd1VwJykgayA9IE1hdGgubWF4KDAsIGsgPCAwID8gMCA6IGsgLSAxKTtcbiAgICBlbHNlIGlmIChlLmtleSA9PT0gJ0hvbWUnKSBrID0gMDtcbiAgICBlbHNlIGlmIChlLmtleSA9PT0gJ0VuZCcpIGsgPSBvLmxlbmd0aCAtIDE7XG4gICAgZWxzZSBpZiAoZS5rZXkgPT09ICdFc2NhcGUnICYmIHRoaXMuc2VsLmxlbmd0aCkge1xuICAgICAgdGhpcy5ib3ggPSBudWxsO1xuICAgICAgdGhpcy5zZXRTZWwoW10pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSByZXR1cm47XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuaG90ID0gb1trXTtcbiAgICB0aGlzLmRyYXcoKTtcbiAgfVxuXG4gIC8vIC0tLS0tIGFzayB0aGUgYWdlbnQgLS0tLS1cbiAgcnVuQXNrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5hc2sub2JzZXJ2ZWQpIHJldHVybjtcbiAgICB0aGlzLmFza2VkKys7XG4gICAgY29uc3QgaWQgPSB0aGlzLmFza2VkO1xuICAgIHRoaXMuYW5zd2VyID0geyB0ZXh0OiAnJywgYnVzeTogdHJ1ZSB9O1xuICAgIHRoaXMuYXNrLmVtaXQodGhpcy5zZWxlY3RlZFJ1bnMpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIC8vIHRoZSBob3N0IGFuc3dlcnMgdmlhIHN0cmVhbUFuc3dlcigpOyB1bnRpbCB0aGVuIHRoZSBzaGltbWVyIHNob3dzXG4gICAgdGhpcy5wZW5kaW5nQXNrID0gaWQ7XG4gIH1cblxuICBwcml2YXRlIHBlbmRpbmdBc2sgPSAwO1xuXG4gIC8qKiBUaGUgaG9zdCBjYWxscyB0aGlzIHdpdGggdGhlIGFuc3dlcjsgaXQgc3RyZWFtcyBpbiB3b3JkIGJ5IHdvcmQuICovXG4gIHN0cmVhbUFuc3dlcih0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHRoaXMucGVuZGluZ0FzaztcbiAgICBpZiAoaWQgIT09IHRoaXMuYXNrZWQpIHJldHVybjtcbiAgICBjb25zdCB3cyA9IHRleHQuc3BsaXQoJyAnKTtcbiAgICBjb25zdCBzdGVwID0gKGk6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgaWYgKGlkICE9PSB0aGlzLmFza2VkKSByZXR1cm47XG4gICAgICB0aGlzLmFuc3dlciA9IHsgdGV4dDogd3Muc2xpY2UoMCwgaSkuam9pbignICcpLCBidXN5OiBmYWxzZSB9O1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICBpZiAoaSA8IHdzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnRpbWVycy5wdXNoKHNldFRpbWVvdXQoKCkgPT4gc3RlcChpICsgMSksIHRoaXMucmVkdWNlZC5yZWR1Y2UoKSA/IDAgOiA0NSkpO1xuICAgICAgfVxuICAgIH07XG4gICAgc3RlcCgxKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMucm8/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLnRpbWVycy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG4gICAgdGhpcy50aW1lcnMgPSBbXTtcbiAgfVxufVxuIl19