@tolle_/tolle-ui 18.2.29 → 18.2.30

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 (279) hide show
  1. package/esm2022/lib/accordion-item.component.mjs +5 -11
  2. package/esm2022/lib/accordion.component.mjs +4 -9
  3. package/esm2022/lib/alert-dialog-dynamic.component.mjs +5 -10
  4. package/esm2022/lib/alert-dialog.component.mjs +44 -59
  5. package/esm2022/lib/alert.component.mjs +5 -11
  6. package/esm2022/lib/aspect-ratio.component.mjs +119 -0
  7. package/esm2022/lib/attachment.component.mjs +334 -0
  8. package/esm2022/lib/avatar-fallback.component.mjs +3 -3
  9. package/esm2022/lib/avatar.component.mjs +4 -9
  10. package/esm2022/lib/badge.component.mjs +4 -9
  11. package/esm2022/lib/breadcrumb-item.component.mjs +3 -3
  12. package/esm2022/lib/breadcrumb-link.component.mjs +3 -3
  13. package/esm2022/lib/breadcrumb-separator.component.mjs +3 -3
  14. package/esm2022/lib/breadcrumb.component.mjs +3 -3
  15. package/esm2022/lib/bubble.component.mjs +301 -0
  16. package/esm2022/lib/button.component.mjs +5 -11
  17. package/esm2022/lib/calendar.component.mjs +5 -11
  18. package/esm2022/lib/card.component.mjs +14 -43
  19. package/esm2022/lib/carousel/carousel.component.mjs +5 -12
  20. package/esm2022/lib/chain-of-thought.component.mjs +380 -0
  21. package/esm2022/lib/chart-pie.component.mjs +386 -0
  22. package/esm2022/lib/chart.component.mjs +1146 -0
  23. package/esm2022/lib/chart.service.mjs +555 -0
  24. package/esm2022/lib/checkbox.component.mjs +5 -11
  25. package/esm2022/lib/checkpoint.component.mjs +134 -0
  26. package/esm2022/lib/collapsible.component.mjs +4 -11
  27. package/esm2022/lib/combobox.component.mjs +372 -0
  28. package/esm2022/lib/command-dialog.component.mjs +164 -0
  29. package/esm2022/lib/command.component.mjs +514 -0
  30. package/esm2022/lib/command.service.mjs +130 -0
  31. package/esm2022/lib/confirmation.component.mjs +219 -0
  32. package/esm2022/lib/context-menu-trigger.directive.mjs +36 -0
  33. package/esm2022/lib/context-menu.component.mjs +460 -0
  34. package/esm2022/lib/context-menu.service.mjs +121 -0
  35. package/esm2022/lib/context.component.mjs +377 -0
  36. package/esm2022/lib/conversation.component.mjs +442 -0
  37. package/esm2022/lib/country-selector.component.mjs +5 -11
  38. package/esm2022/lib/data-table.component.mjs +59 -12
  39. package/esm2022/lib/date-picker.component.mjs +251 -198
  40. package/esm2022/lib/date-range-picker.component.mjs +224 -116
  41. package/esm2022/lib/date-time-picker.component.mjs +506 -0
  42. package/esm2022/lib/direction.component.mjs +79 -0
  43. package/esm2022/lib/dropdown-item.component.mjs +3 -3
  44. package/esm2022/lib/dropdown-label.component.mjs +3 -3
  45. package/esm2022/lib/dropdown-menu.component.mjs +3 -3
  46. package/esm2022/lib/dropdown-separator.component.mjs +3 -3
  47. package/esm2022/lib/dropdown-trigger.directive.mjs +6 -4
  48. package/esm2022/lib/empty-state.component.mjs +4 -9
  49. package/esm2022/lib/field.component.mjs +394 -0
  50. package/esm2022/lib/hover-card.component.mjs +6 -16
  51. package/esm2022/lib/inline-citation.component.mjs +263 -0
  52. package/esm2022/lib/input-group.component.mjs +418 -0
  53. package/esm2022/lib/input.component.mjs +5 -11
  54. package/esm2022/lib/item.component.mjs +243 -0
  55. package/esm2022/lib/kbd.component.mjs +82 -0
  56. package/esm2022/lib/label.component.mjs +4 -9
  57. package/esm2022/lib/marker.component.mjs +135 -0
  58. package/esm2022/lib/masked-input.component.mjs +5 -11
  59. package/esm2022/lib/menubar.component.mjs +683 -0
  60. package/esm2022/lib/message-scroller.component.mjs +353 -0
  61. package/esm2022/lib/message-scroller.service.mjs +157 -0
  62. package/esm2022/lib/message.component.mjs +228 -0
  63. package/esm2022/lib/model-selector.component.mjs +310 -0
  64. package/esm2022/lib/multi-select.component.mjs +155 -72
  65. package/esm2022/lib/native-select.component.mjs +201 -0
  66. package/esm2022/lib/navigation-menu.component.mjs +642 -0
  67. package/esm2022/lib/otp-group.component.mjs +3 -3
  68. package/esm2022/lib/otp-slot.component.mjs +4 -9
  69. package/esm2022/lib/otp.component.mjs +5 -11
  70. package/esm2022/lib/pagination.component.mjs +7 -10
  71. package/esm2022/lib/plan.component.mjs +335 -0
  72. package/esm2022/lib/popover-content.component.mjs +4 -9
  73. package/esm2022/lib/popover.component.mjs +15 -13
  74. package/esm2022/lib/progress.component.mjs +4 -9
  75. package/esm2022/lib/prompt-input.component.mjs +526 -0
  76. package/esm2022/lib/queue.component.mjs +280 -0
  77. package/esm2022/lib/radio-group.component.mjs +6 -13
  78. package/esm2022/lib/radio-item.component.mjs +4 -9
  79. package/esm2022/lib/range-calendar.component.mjs +5 -11
  80. package/esm2022/lib/reasoning.component.mjs +335 -0
  81. package/esm2022/lib/resizable.component.mjs +219 -0
  82. package/esm2022/lib/segment.component.mjs +17 -7
  83. package/esm2022/lib/select-group.component.mjs +4 -8
  84. package/esm2022/lib/select-item.component.mjs +4 -9
  85. package/esm2022/lib/select-separator.component.mjs +4 -8
  86. package/esm2022/lib/select.component.mjs +133 -49
  87. package/esm2022/lib/separator.component.mjs +4 -9
  88. package/esm2022/lib/sheet.component.mjs +38 -56
  89. package/esm2022/lib/shimmer.component.mjs +84 -0
  90. package/esm2022/lib/sidebar.component.mjs +11 -1
  91. package/esm2022/lib/skeleton.component.mjs +4 -9
  92. package/esm2022/lib/sources.component.mjs +452 -0
  93. package/esm2022/lib/spinner.component.mjs +68 -0
  94. package/esm2022/lib/suggestion.component.mjs +207 -0
  95. package/esm2022/lib/switch.component.mjs +5 -11
  96. package/esm2022/lib/table.component.mjs +213 -0
  97. package/esm2022/lib/tabs.component.mjs +4 -11
  98. package/esm2022/lib/tag-input.component.mjs +5 -11
  99. package/esm2022/lib/task.component.mjs +359 -0
  100. package/esm2022/lib/textarea.component.mjs +5 -11
  101. package/esm2022/lib/theme.service.mjs +17 -6
  102. package/esm2022/lib/time-picker.component.mjs +923 -0
  103. package/esm2022/lib/toast.service.mjs +3 -2
  104. package/esm2022/lib/toaster.component.mjs +76 -39
  105. package/esm2022/lib/toggle-group.component.mjs +4 -9
  106. package/esm2022/lib/toggle.component.mjs +5 -11
  107. package/esm2022/lib/tool.component.mjs +462 -0
  108. package/esm2022/lib/typography.component.mjs +83 -0
  109. package/esm2022/lib/utils/color.mjs +140 -19
  110. package/esm2022/public-api.mjs +61 -1
  111. package/fesm2022/tolle-ui.mjs +16453 -1024
  112. package/fesm2022/tolle-ui.mjs.map +1 -1
  113. package/lib/alert-dialog.component.d.ts +10 -2
  114. package/lib/aspect-ratio.component.d.ts +20 -0
  115. package/lib/attachment.component.d.ts +101 -0
  116. package/lib/bubble.component.d.ts +112 -0
  117. package/lib/chain-of-thought.component.d.ts +166 -0
  118. package/lib/chart-pie.component.d.ts +108 -0
  119. package/lib/chart.component.d.ts +369 -0
  120. package/lib/chart.service.d.ts +222 -0
  121. package/lib/checkpoint.component.d.ts +51 -0
  122. package/lib/combobox.component.d.ts +90 -0
  123. package/lib/command-dialog.component.d.ts +53 -0
  124. package/lib/command.component.d.ts +189 -0
  125. package/lib/command.service.d.ts +67 -0
  126. package/lib/confirmation.component.d.ts +70 -0
  127. package/lib/context-menu-trigger.directive.d.ts +12 -0
  128. package/lib/context-menu.component.d.ts +41 -0
  129. package/lib/context-menu.service.d.ts +38 -0
  130. package/lib/context.component.d.ts +134 -0
  131. package/lib/conversation.component.d.ts +165 -0
  132. package/lib/data-table.component.d.ts +26 -1
  133. package/lib/date-picker.component.d.ts +72 -11
  134. package/lib/date-range-picker.component.d.ts +63 -6
  135. package/lib/date-time-picker.component.d.ts +119 -0
  136. package/lib/direction.component.d.ts +45 -0
  137. package/lib/field.component.d.ts +201 -0
  138. package/lib/inline-citation.component.d.ts +103 -0
  139. package/lib/input-group.component.d.ts +150 -0
  140. package/lib/item.component.d.ts +154 -0
  141. package/lib/kbd.component.d.ts +50 -0
  142. package/lib/marker.component.d.ts +58 -0
  143. package/lib/menubar.component.d.ts +247 -0
  144. package/lib/message-scroller.component.d.ts +159 -0
  145. package/lib/message-scroller.service.d.ts +73 -0
  146. package/lib/message.component.d.ts +128 -0
  147. package/lib/model-selector.component.d.ts +103 -0
  148. package/lib/multi-select.component.d.ts +66 -14
  149. package/lib/native-select.component.d.ts +57 -0
  150. package/lib/navigation-menu.component.d.ts +230 -0
  151. package/lib/plan.component.d.ts +120 -0
  152. package/lib/popover.component.d.ts +1 -0
  153. package/lib/prompt-input.component.d.ts +194 -0
  154. package/lib/queue.component.d.ts +106 -0
  155. package/lib/reasoning.component.d.ts +127 -0
  156. package/lib/resizable.component.d.ts +43 -0
  157. package/lib/segment.component.d.ts +13 -3
  158. package/lib/select.component.d.ts +37 -5
  159. package/lib/sheet.component.d.ts +3 -0
  160. package/lib/shimmer.component.d.ts +38 -0
  161. package/lib/sidebar.component.d.ts +2 -0
  162. package/lib/sources.component.d.ts +156 -0
  163. package/lib/spinner.component.d.ts +29 -0
  164. package/lib/suggestion.component.d.ts +96 -0
  165. package/lib/table.component.d.ts +106 -0
  166. package/lib/task.component.d.ts +151 -0
  167. package/lib/theme.service.d.ts +9 -0
  168. package/lib/time-picker.component.d.ts +243 -0
  169. package/lib/toast.service.d.ts +3 -1
  170. package/lib/toaster.component.d.ts +26 -9
  171. package/lib/tool.component.d.ts +158 -0
  172. package/lib/typography.component.d.ts +32 -0
  173. package/lib/utils/color.d.ts +19 -5
  174. package/package.json +1 -1
  175. package/public-api.d.ts +50 -0
  176. package/registry/docs-content.json +8480 -1542
  177. package/registry/llms-full.txt +2679 -319
  178. package/registry/llms.txt +43 -4
  179. package/registry/manifest.json +9090 -1742
  180. package/registry/r/accordion-item.json +1 -1
  181. package/registry/r/accordion.json +1 -1
  182. package/registry/r/alert-dialog-dynamic.json +1 -1
  183. package/registry/r/alert-dialog.json +1 -1
  184. package/registry/r/alert.json +1 -1
  185. package/registry/r/attachment.json +23 -0
  186. package/registry/r/avatar-fallback.json +1 -1
  187. package/registry/r/avatar.json +1 -1
  188. package/registry/r/badge.json +1 -1
  189. package/registry/r/breadcrumb-item.json +1 -1
  190. package/registry/r/breadcrumb-link.json +1 -1
  191. package/registry/r/breadcrumb-separator.json +1 -1
  192. package/registry/r/breadcrumb.json +1 -1
  193. package/registry/r/bubble.json +23 -0
  194. package/registry/r/button.json +1 -1
  195. package/registry/r/calendar.json +1 -1
  196. package/registry/r/card.json +1 -1
  197. package/registry/r/carousel.json +1 -1
  198. package/registry/r/chain-of-thought.json +23 -0
  199. package/registry/r/chart-pie.json +30 -0
  200. package/registry/r/chart.json +28 -0
  201. package/registry/r/checkbox.json +1 -1
  202. package/registry/r/checkpoint.json +23 -0
  203. package/registry/r/collapsible.json +1 -1
  204. package/registry/r/combobox.json +31 -0
  205. package/registry/r/command-dialog.json +21 -0
  206. package/registry/r/command.json +26 -0
  207. package/registry/r/confirmation.json +23 -0
  208. package/registry/r/context.json +26 -0
  209. package/registry/r/conversation.json +23 -0
  210. package/registry/r/country-selector.json +1 -1
  211. package/registry/r/data-table.json +1 -1
  212. package/registry/r/date-picker.json +4 -4
  213. package/registry/r/date-range-picker.json +3 -3
  214. package/registry/r/date-time-picker.json +28 -0
  215. package/registry/r/direction.json +16 -0
  216. package/registry/r/dropdown-item.json +1 -1
  217. package/registry/r/dropdown-label.json +1 -1
  218. package/registry/r/dropdown-menu.json +1 -1
  219. package/registry/r/dropdown-separator.json +1 -1
  220. package/registry/r/dropdown-trigger.json +1 -1
  221. package/registry/r/empty-state.json +1 -1
  222. package/registry/r/field.json +23 -0
  223. package/registry/r/hover-card.json +1 -1
  224. package/registry/r/inline-citation.json +26 -0
  225. package/registry/r/input-group.json +23 -0
  226. package/registry/r/input.json +1 -1
  227. package/registry/r/item.json +23 -0
  228. package/registry/r/kbd.json +23 -0
  229. package/registry/r/label.json +1 -1
  230. package/registry/r/marker.json +23 -0
  231. package/registry/r/masked-input.json +1 -1
  232. package/registry/r/menubar.json +24 -0
  233. package/registry/r/message-scroller.json +26 -0
  234. package/registry/r/message.json +23 -0
  235. package/registry/r/model-selector.json +32 -0
  236. package/registry/r/multi-select.json +2 -2
  237. package/registry/r/native-select.json +23 -0
  238. package/registry/r/navigation-menu.json +24 -0
  239. package/registry/r/otp-group.json +1 -1
  240. package/registry/r/otp-slot.json +1 -1
  241. package/registry/r/otp.json +1 -1
  242. package/registry/r/pagination.json +3 -2
  243. package/registry/r/plan.json +23 -0
  244. package/registry/r/popover-content.json +1 -1
  245. package/registry/r/popover.json +1 -1
  246. package/registry/r/progress.json +1 -1
  247. package/registry/r/prompt-input.json +23 -0
  248. package/registry/r/queue.json +23 -0
  249. package/registry/r/radio-group.json +1 -1
  250. package/registry/r/radio-item.json +1 -1
  251. package/registry/r/range-calendar.json +1 -1
  252. package/registry/r/reasoning.json +23 -0
  253. package/registry/r/segment.json +1 -1
  254. package/registry/r/select-group.json +1 -1
  255. package/registry/r/select-item.json +1 -1
  256. package/registry/r/select-separator.json +1 -1
  257. package/registry/r/select.json +4 -3
  258. package/registry/r/separator.json +1 -1
  259. package/registry/r/sheet.json +1 -1
  260. package/registry/r/shimmer.json +23 -0
  261. package/registry/r/sidebar.json +1 -1
  262. package/registry/r/skeleton.json +1 -1
  263. package/registry/r/sources.json +23 -0
  264. package/registry/r/spinner.json +23 -0
  265. package/registry/r/suggestion.json +23 -0
  266. package/registry/r/switch.json +1 -1
  267. package/registry/r/table.json +21 -0
  268. package/registry/r/tabs.json +1 -1
  269. package/registry/r/tag-input.json +1 -1
  270. package/registry/r/task.json +23 -0
  271. package/registry/r/textarea.json +1 -1
  272. package/registry/r/time-picker.json +24 -0
  273. package/registry/r/toaster.json +2 -2
  274. package/registry/r/toggle-group.json +1 -1
  275. package/registry/r/toggle.json +1 -1
  276. package/registry/r/tool.json +23 -0
  277. package/registry/r/typography.json +23 -0
  278. package/registry/registry.json +915 -22
  279. package/theme.css +109 -8
@@ -0,0 +1,386 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from './utils/cn';
5
+ import { ChartService, ChartColorScale } from './chart.service';
6
+ import { ChartTableComponent } from './chart.component';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ let chartPieId = 0;
10
+ /** Converts an angle measured clockwise from 12 o'clock into svg coordinates. */
11
+ export function polarPoint(cx, cy, r, angle) {
12
+ return [cx + r * Math.sin(angle), cy - r * Math.cos(angle)];
13
+ }
14
+ /**
15
+ * Builds one slice. `innerRadius` above zero produces a donut segment; a span
16
+ * covering the full circle is drawn as two half arcs, because an SVG arc whose
17
+ * start and end points coincide renders nothing at all.
18
+ */
19
+ export function arcPath(cx, cy, outer, inner, start, end) {
20
+ const span = end - start;
21
+ if (span <= 0)
22
+ return '';
23
+ if (span >= Math.PI * 2 - 1e-6) {
24
+ const mid = start + Math.PI;
25
+ return arcPath(cx, cy, outer, inner, start, mid) + ' ' + arcPath(cx, cy, outer, inner, mid, end);
26
+ }
27
+ const large = span > Math.PI ? 1 : 0;
28
+ const [ox0, oy0] = polarPoint(cx, cy, outer, start);
29
+ const [ox1, oy1] = polarPoint(cx, cy, outer, end);
30
+ if (inner > 0) {
31
+ const [ix1, iy1] = polarPoint(cx, cy, inner, end);
32
+ const [ix0, iy0] = polarPoint(cx, cy, inner, start);
33
+ return ('M ' + ox0 + ' ' + oy0 +
34
+ ' A ' + outer + ' ' + outer + ' 0 ' + large + ' 1 ' + ox1 + ' ' + oy1 +
35
+ ' L ' + ix1 + ' ' + iy1 +
36
+ ' A ' + inner + ' ' + inner + ' 0 ' + large + ' 0 ' + ix0 + ' ' + iy0 +
37
+ ' Z');
38
+ }
39
+ return ('M ' + cx + ' ' + cy +
40
+ ' L ' + ox0 + ' ' + oy0 +
41
+ ' A ' + outer + ' ' + outer + ' 0 ' + large + ' 1 ' + ox1 + ' ' + oy1 +
42
+ ' Z');
43
+ }
44
+ const chartPieVariants = cva('relative w-full', {
45
+ variants: {
46
+ variant: {
47
+ default: '',
48
+ card: 'rounded-lg border border-border bg-background p-4',
49
+ },
50
+ },
51
+ defaultVariants: { variant: 'default' },
52
+ });
53
+ /**
54
+ * A pie or donut drawn from hand-written SVG arcs.
55
+ *
56
+ * Slices are separated by a real 2px angular gap rather than a stroke, so what
57
+ * divides them is surface rather than added ink. Colour is assigned by slice
58
+ * label, so re-sorting or filtering the data never repaints a slice, and a
59
+ * sixth slice falls back to a neutral rather than reusing `--chart-1`.
60
+ *
61
+ * Renders its own legend at two or more slices, a per-slice hover tooltip, and
62
+ * the same accessible `tolle-chart-table` fallback as `tolle-chart`.
63
+ * @new
64
+ */
65
+ export class ChartPieComponent {
66
+ /** Rows to plot, one slice each. @default [] */
67
+ data = [];
68
+ /** Row key holding each slice's numeric value. @default 'value' */
69
+ valueKey = 'value';
70
+ /** Row key holding each slice's label. @default 'label' */
71
+ labelKey = 'label';
72
+ /** Cuts a hole in the middle, making it a donut. @default false */
73
+ donut = false;
74
+ /** Hole size as a fraction of the outer radius, used when `donut` is set. @default 0.6 */
75
+ innerRadius = 0.6;
76
+ /** Width and height of the square plot in px. @default 240 */
77
+ size = 240;
78
+ /** Angular gap between slices, expressed in px of arc at the outer edge. @default 2 */
79
+ gap = 2;
80
+ /** Accessible name for the chart, used as the svg `<title>`. @default '' */
81
+ ariaLabel = '';
82
+ /** Longer summary used as the svg `<desc>`. Falls back to `ariaLabel`. @default '' */
83
+ description = '';
84
+ /** Shows the data table instead of leaving it visually hidden. @default false */
85
+ showTable = false;
86
+ /** Column header the table fallback gives the label column. @default 'Category' */
87
+ labelHeader = 'Category';
88
+ /** Column header the table fallback gives the value column. @default 'Value' */
89
+ valueHeader = 'Value';
90
+ /** Visual treatment of the chart frame. @default 'default' */
91
+ variant = 'default';
92
+ /** Extra Tailwind classes merged onto the chart via `cn()` (last-wins). */
93
+ class = '';
94
+ /** Emitted with the hovered slice index, or null when the pointer leaves. */
95
+ activeIndexChange = new EventEmitter();
96
+ cdr = inject(ChangeDetectorRef);
97
+ /** Only used to feed the shared table fallback; the pie owns its own colours. */
98
+ tableSource = inject(ChartService);
99
+ colors = new ChartColorScale();
100
+ /** Id of the table fallback, referenced by the svg's `aria-describedby`. */
101
+ tableId = 'chart-pie-table-' + chartPieId++;
102
+ /** Index of the hovered slice, or null. */
103
+ activeIndex = null;
104
+ ngOnChanges() {
105
+ // Reserve palette slots in data order, so a slice keeps its colour when the
106
+ // data is later re-sorted or filtered.
107
+ this.colors.register(this.labels);
108
+ this.tableSource.configure({
109
+ data: this.data ?? [],
110
+ xKey: this.labelKey,
111
+ series: [{ key: this.valueKey, label: this.valueHeader }],
112
+ });
113
+ this._slices = this.computeSlices();
114
+ // A bound `class` input is written through Angular's styling path,
115
+ // which does not mark an OnPush view dirty on its own.
116
+ this.cdr.markForCheck();
117
+ }
118
+ get labels() {
119
+ return (this.data ?? []).map((row) => {
120
+ const raw = row?.[this.labelKey];
121
+ return raw == null ? '' : String(raw);
122
+ });
123
+ }
124
+ get viewBox() {
125
+ return '0 0 ' + this.size + ' ' + this.size;
126
+ }
127
+ get outerRadius() {
128
+ return this.size / 2;
129
+ }
130
+ /**
131
+ * Resolved slices in data order, each already padded for the surface gap.
132
+ *
133
+ * Computed once per input change, NOT per read. Three template bindings read
134
+ * this each pass; when it rebuilt the array every time, `*ngFor` saw fresh
135
+ * identities and tore down every `<path>` on every change-detection run.
136
+ * Destroying the node under the pointer re-fires `pointerenter`, which calls
137
+ * `markForCheck`, which schedules another pass — the chart locked the page up.
138
+ */
139
+ get slices() {
140
+ return this._slices;
141
+ }
142
+ _slices = [];
143
+ /** Identity for `*ngFor`, so a redraw patches attributes instead of replacing nodes. */
144
+ trackSlice = (_, slice) => slice.label;
145
+ computeSlices() {
146
+ const rows = this.data ?? [];
147
+ const values = rows.map((row) => {
148
+ const num = Number(row?.[this.valueKey]);
149
+ // A pie divides a whole; a negative share has no meaning in one.
150
+ return Number.isFinite(num) && num > 0 ? num : 0;
151
+ });
152
+ const total = values.reduce((sum, v) => sum + v, 0);
153
+ if (total <= 0)
154
+ return [];
155
+ const cx = this.size / 2;
156
+ const cy = this.size / 2;
157
+ const outer = this.outerRadius;
158
+ const inner = this.donut ? outer * Math.min(0.95, Math.max(0, this.innerRadius)) : 0;
159
+ // Turn a px gap at the rim into the angle that subtends it.
160
+ const pad = outer > 0 ? this.gap / outer : 0;
161
+ const out = [];
162
+ let cursor = 0;
163
+ for (let i = 0; i < rows.length; i++) {
164
+ const value = values[i];
165
+ if (value <= 0)
166
+ continue;
167
+ const span = (value / total) * Math.PI * 2;
168
+ const start = cursor;
169
+ const end = cursor + span;
170
+ cursor = end;
171
+ // Never let the gap eat a slice: a sliver keeps a hairline of itself.
172
+ const usable = Math.max(span * 0.2, span - pad);
173
+ const inset = (span - usable) / 2;
174
+ const label = this.labels[i];
175
+ const mid = start + span / 2;
176
+ const [anchorX, anchorY] = polarPoint(cx, cy, (outer + inner) / 2, mid);
177
+ out.push({
178
+ label,
179
+ value,
180
+ percent: value / total,
181
+ color: this.colors.colorFor(label),
182
+ d: arcPath(cx, cy, outer, inner, start + inset, end - inset),
183
+ anchorX,
184
+ anchorY,
185
+ });
186
+ }
187
+ return out;
188
+ }
189
+ get activeSlice() {
190
+ if (this.activeIndex === null)
191
+ return null;
192
+ return this.slices[this.activeIndex] ?? null;
193
+ }
194
+ get tooltipLeft() {
195
+ const slice = this.activeSlice;
196
+ if (!slice)
197
+ return 0;
198
+ // Flip toward the centre rather than let the readout leave the frame.
199
+ return slice.anchorX > this.size / 2
200
+ ? Math.max(0, slice.anchorX - 140)
201
+ : Math.min(this.size, slice.anchorX + 8);
202
+ }
203
+ get tooltipTop() {
204
+ return this.activeSlice ? this.activeSlice.anchorY : 0;
205
+ }
206
+ formatValue(value) {
207
+ return value.toLocaleString('en-US');
208
+ }
209
+ formatPercent(percent) {
210
+ return (percent * 100).toFixed(1) + '%';
211
+ }
212
+ onEnter(index) {
213
+ if (this.activeIndex === index)
214
+ return;
215
+ this.activeIndex = index;
216
+ this.activeIndexChange.emit(index);
217
+ this.cdr.markForCheck();
218
+ }
219
+ onLeave() {
220
+ if (this.activeIndex === null)
221
+ return;
222
+ this.activeIndex = null;
223
+ this.activeIndexChange.emit(null);
224
+ this.cdr.markForCheck();
225
+ }
226
+ get computedClass() {
227
+ return cn(chartPieVariants({ variant: this.variant }), this.class);
228
+ }
229
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartPieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
230
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChartPieComponent, isStandalone: true, selector: "tolle-chart-pie", inputs: { data: "data", valueKey: "valueKey", labelKey: "labelKey", donut: "donut", innerRadius: "innerRadius", size: "size", gap: "gap", ariaLabel: "ariaLabel", description: "description", showTable: "showTable", labelHeader: "labelHeader", valueHeader: "valueHeader", variant: "variant", class: "class" }, outputs: { activeIndexChange: "activeIndexChange" }, providers: [ChartService], usesOnChanges: true, ngImport: i0, template: `
231
+ <div [class]="computedClass">
232
+ <div class="relative w-full">
233
+ <svg
234
+ role="img"
235
+ width="100%"
236
+ [attr.height]="size"
237
+ [attr.viewBox]="viewBox"
238
+ [attr.aria-label]="ariaLabel || null"
239
+ [attr.aria-describedby]="tableId"
240
+ class="block w-full"
241
+ (pointerleave)="onLeave()"
242
+ >
243
+ <title>{{ ariaLabel }}</title>
244
+ <desc>{{ description || ariaLabel }}</desc>
245
+
246
+ <svg:path
247
+ *ngFor="let slice of slices; let i = index; trackBy: trackSlice"
248
+ [attr.d]="slice.d"
249
+ [attr.fill]="slice.color"
250
+ [attr.fill-opacity]="activeIndex === i ? 1 : 0.85"
251
+ (pointerenter)="onEnter(i)"
252
+ ></svg:path>
253
+ </svg>
254
+
255
+ <div
256
+ *ngIf="activeSlice"
257
+ role="status"
258
+ aria-live="polite"
259
+ class="pointer-events-none absolute z-10 min-w-[8rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md"
260
+ [style.left.px]="tooltipLeft"
261
+ [style.top.px]="tooltipTop"
262
+ >
263
+ <div class="flex items-center gap-2 text-xs">
264
+ <span class="h-2 w-2 shrink-0 rounded-[2px]" [style.background]="activeSlice.color"></span>
265
+ <span class="text-muted-foreground">{{ activeSlice.label }}</span>
266
+ <span class="ml-auto font-medium tabular-nums text-foreground">
267
+ {{ formatValue(activeSlice.value) }}
268
+ </span>
269
+ </div>
270
+ <p class="mt-0.5 text-right text-xs text-muted-foreground tabular-nums">
271
+ {{ formatPercent(activeSlice.percent) }}
272
+ </p>
273
+ </div>
274
+ </div>
275
+
276
+ <ul *ngIf="slices.length > 1" class="flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-2 text-xs">
277
+ <li *ngFor="let slice of slices; trackBy: trackSlice" class="flex items-center gap-1.5">
278
+ <span class="h-2 w-2 shrink-0 rounded-[2px]" [style.background]="slice.color"></span>
279
+ <span class="text-muted-foreground">{{ slice.label }}</span>
280
+ </li>
281
+ </ul>
282
+
283
+ <tolle-chart-table
284
+ [tableId]="tableId"
285
+ [visible]="showTable"
286
+ [xHeader]="labelHeader"
287
+ [caption]="ariaLabel || 'Chart data'"
288
+ ></tolle-chart-table>
289
+ </div>
290
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartTableComponent, selector: "tolle-chart-table", inputs: ["visible", "tableId", "xHeader", "caption", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
291
+ }
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartPieComponent, decorators: [{
293
+ type: Component,
294
+ args: [{ selector: 'tolle-chart-pie', standalone: true, imports: [CommonModule, ChartTableComponent], providers: [ChartService], changeDetection: ChangeDetectionStrategy.OnPush, template: `
295
+ <div [class]="computedClass">
296
+ <div class="relative w-full">
297
+ <svg
298
+ role="img"
299
+ width="100%"
300
+ [attr.height]="size"
301
+ [attr.viewBox]="viewBox"
302
+ [attr.aria-label]="ariaLabel || null"
303
+ [attr.aria-describedby]="tableId"
304
+ class="block w-full"
305
+ (pointerleave)="onLeave()"
306
+ >
307
+ <title>{{ ariaLabel }}</title>
308
+ <desc>{{ description || ariaLabel }}</desc>
309
+
310
+ <svg:path
311
+ *ngFor="let slice of slices; let i = index; trackBy: trackSlice"
312
+ [attr.d]="slice.d"
313
+ [attr.fill]="slice.color"
314
+ [attr.fill-opacity]="activeIndex === i ? 1 : 0.85"
315
+ (pointerenter)="onEnter(i)"
316
+ ></svg:path>
317
+ </svg>
318
+
319
+ <div
320
+ *ngIf="activeSlice"
321
+ role="status"
322
+ aria-live="polite"
323
+ class="pointer-events-none absolute z-10 min-w-[8rem] rounded-md border border-border bg-popover p-2 text-popover-foreground shadow-md"
324
+ [style.left.px]="tooltipLeft"
325
+ [style.top.px]="tooltipTop"
326
+ >
327
+ <div class="flex items-center gap-2 text-xs">
328
+ <span class="h-2 w-2 shrink-0 rounded-[2px]" [style.background]="activeSlice.color"></span>
329
+ <span class="text-muted-foreground">{{ activeSlice.label }}</span>
330
+ <span class="ml-auto font-medium tabular-nums text-foreground">
331
+ {{ formatValue(activeSlice.value) }}
332
+ </span>
333
+ </div>
334
+ <p class="mt-0.5 text-right text-xs text-muted-foreground tabular-nums">
335
+ {{ formatPercent(activeSlice.percent) }}
336
+ </p>
337
+ </div>
338
+ </div>
339
+
340
+ <ul *ngIf="slices.length > 1" class="flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-2 text-xs">
341
+ <li *ngFor="let slice of slices; trackBy: trackSlice" class="flex items-center gap-1.5">
342
+ <span class="h-2 w-2 shrink-0 rounded-[2px]" [style.background]="slice.color"></span>
343
+ <span class="text-muted-foreground">{{ slice.label }}</span>
344
+ </li>
345
+ </ul>
346
+
347
+ <tolle-chart-table
348
+ [tableId]="tableId"
349
+ [visible]="showTable"
350
+ [xHeader]="labelHeader"
351
+ [caption]="ariaLabel || 'Chart data'"
352
+ ></tolle-chart-table>
353
+ </div>
354
+ `, styles: [":host{display:block}\n"] }]
355
+ }], propDecorators: { data: [{
356
+ type: Input
357
+ }], valueKey: [{
358
+ type: Input
359
+ }], labelKey: [{
360
+ type: Input
361
+ }], donut: [{
362
+ type: Input
363
+ }], innerRadius: [{
364
+ type: Input
365
+ }], size: [{
366
+ type: Input
367
+ }], gap: [{
368
+ type: Input
369
+ }], ariaLabel: [{
370
+ type: Input
371
+ }], description: [{
372
+ type: Input
373
+ }], showTable: [{
374
+ type: Input
375
+ }], labelHeader: [{
376
+ type: Input
377
+ }], valueHeader: [{
378
+ type: Input
379
+ }], variant: [{
380
+ type: Input
381
+ }], class: [{
382
+ type: Input
383
+ }], activeIndexChange: [{
384
+ type: Output
385
+ }] } });
386
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQtcGllLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvY2hhcnQtcGllLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFhLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0SSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7OztBQUV4RCxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFlbkIsaUZBQWlGO0FBQ2pGLE1BQU0sVUFBVSxVQUFVLENBQUMsRUFBVSxFQUFFLEVBQVUsRUFBRSxDQUFTLEVBQUUsS0FBYTtJQUN6RSxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLE9BQU8sQ0FDckIsRUFBVSxFQUNWLEVBQVUsRUFDVixLQUFhLEVBQ2IsS0FBYSxFQUNiLEtBQWEsRUFDYixHQUFXO0lBRVgsTUFBTSxJQUFJLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQztJQUN6QixJQUFJLElBQUksSUFBSSxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFFekIsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDNUIsT0FBTyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNwRCxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztJQUVsRCxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNkLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BELE9BQU8sQ0FDTCxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHO1lBQ3RCLEtBQUssR0FBRyxLQUFLLEdBQUcs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OzhCQUlRLElBQUk7c0JBQVosS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsT0FBTztzQkFBZixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFHSSxpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBPbkNoYW5nZXMsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGN2YSwgdHlwZSBWYXJpYW50UHJvcHMgfSBmcm9tICdjbGFzcy12YXJpYW5jZS1hdXRob3JpdHknO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJztcbmltcG9ydCB7IENoYXJ0U2VydmljZSwgQ2hhcnRDb2xvclNjYWxlIH0gZnJvbSAnLi9jaGFydC5zZXJ2aWNlJztcbmltcG9ydCB7IENoYXJ0VGFibGVDb21wb25lbnQgfSBmcm9tICcuL2NoYXJ0LmNvbXBvbmVudCc7XG5cbmxldCBjaGFydFBpZUlkID0gMDtcblxuLyoqIE9uZSByZXNvbHZlZCBzbGljZTogaXRzIGdlb21ldHJ5LCBpdHMgcGFpbnQsIGFuZCB0aGUgbnVtYmVycyBiZWhpbmQgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYXJ0UGllU2xpY2Uge1xuICBsYWJlbDogc3RyaW5nO1xuICB2YWx1ZTogbnVtYmVyO1xuICBwZXJjZW50OiBudW1iZXI7XG4gIGNvbG9yOiBzdHJpbmc7XG4gIC8qKiBUaGUgYXJjIHBhdGgsIGFscmVhZHkgcGFkZGVkIGZvciB0aGUgc3VyZmFjZSBnYXAuICovXG4gIGQ6IHN0cmluZztcbiAgLyoqIE1pZC1hbmdsZSBwb2ludCBvbiB0aGUgb3V0ZXIgZWRnZSwgdXNlZCB0byBwbGFjZSB0aGUgdG9vbHRpcC4gKi9cbiAgYW5jaG9yWDogbnVtYmVyO1xuICBhbmNob3JZOiBudW1iZXI7XG59XG5cbi8qKiBDb252ZXJ0cyBhbiBhbmdsZSBtZWFzdXJlZCBjbG9ja3dpc2UgZnJvbSAxMiBvJ2Nsb2NrIGludG8gc3ZnIGNvb3JkaW5hdGVzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvbGFyUG9pbnQoY3g6IG51bWJlciwgY3k6IG51bWJlciwgcjogbnVtYmVyLCBhbmdsZTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIHJldHVybiBbY3ggKyByICogTWF0aC5zaW4oYW5nbGUpLCBjeSAtIHIgKiBNYXRoLmNvcyhhbmdsZSldO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBvbmUgc2xpY2UuIGBpbm5lclJhZGl1c2AgYWJvdmUgemVybyBwcm9kdWNlcyBhIGRvbnV0IHNlZ21lbnQ7IGEgc3BhblxuICogY292ZXJpbmcgdGhlIGZ1bGwgY2lyY2xlIGlzIGRyYXduIGFzIHR3byBoYWxmIGFyY3MsIGJlY2F1c2UgYW4gU1ZHIGFyYyB3aG9zZVxuICogc3RhcnQgYW5kIGVuZCBwb2ludHMgY29pbmNpZGUgcmVuZGVycyBub3RoaW5nIGF0IGFsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFyY1BhdGgoXG4gIGN4OiBudW1iZXIsXG4gIGN5OiBudW1iZXIsXG4gIG91dGVyOiBudW1iZXIsXG4gIGlubmVyOiBudW1iZXIsXG4gIHN0YXJ0OiBudW1iZXIsXG4gIGVuZDogbnVtYmVyXG4pOiBzdHJpbmcge1xuICBjb25zdCBzcGFuID0gZW5kIC0gc3RhcnQ7XG4gIGlmIChzcGFuIDw9IDApIHJldHVybiAnJztcblxuICBpZiAoc3BhbiA+PSBNYXRoLlBJICogMiAtIDFlLTYpIHtcbiAgICBjb25zdCBtaWQgPSBzdGFydCArIE1hdGguUEk7XG4gICAgcmV0dXJuIGFyY1BhdGgoY3gsIGN5LCBvdXRlciwgaW5uZXIsIHN0YXJ0LCBtaWQpICsgJyAnICsgYXJjUGF0aChjeCwgY3ksIG91dGVyLCBpbm5lciwgbWlkLCBlbmQpO1xuICB9XG5cbiAgY29uc3QgbGFyZ2UgPSBzcGFuID4gTWF0aC5QSSA/IDEgOiAwO1xuICBjb25zdCBbb3gwLCBveTBdID0gcG9sYXJQb2ludChjeCwgY3ksIG91dGVyLCBzdGFydCk7XG4gIGNvbnN0IFtveDEsIG95MV0gPSBwb2xhclBvaW50KGN4LCBjeSwgb3V0ZXIsIGVuZCk7XG5cbiAgaWYgKGlubmVyID4gMCkge1xuICAgIGNvbnN0IFtpeDEsIGl5MV0gPSBwb2xhclBvaW50KGN4LCBjeSwgaW5uZXIsIGVuZCk7XG4gICAgY29uc3QgW2l4MCwgaXkwXSA9IHBvbGFyUG9pbnQoY3gsIGN5LCBpbm5lciwgc3RhcnQpO1xuICAgIHJldHVybiAoXG4gICAgICAnTSAnICsgb3gwICsgJyAnICsgb3kwICtcbiAgICAgICcgQSAnICsgb3V0ZXIgKyAnICcgKyBvdXRlciArICcgMCAnICsgbGFyZ2UgKyAnIDEgJyArIG94MSArICcgJyArIG95MSArXG4gICAgICAnIEwgJyArIGl4MSArICcgJyArIGl5MSArXG4gICAgICAnIEEgJyArIGlubmVyICsgJyAnICsgaW5uZXIgKyAnIDAgJyArIGxhcmdlICsgJyAwICcgKyBpeDAgKyAnICcgKyBpeTAgK1xuICAgICAgJyBaJ1xuICAgICk7XG4gIH1cblxuICByZXR1cm4gKFxuICAgICdNICcgKyBjeCArICcgJyArIGN5ICtcbiAgICAnIEwgJyArIG94MCArICcgJyArIG95MCArXG4gICAgJyBBICcgKyBvdXRlciArICcgJyArIG91dGVyICsgJyAwICcgKyBsYXJnZSArICcgMSAnICsgb3gxICsgJyAnICsgb3kxICtcbiAgICAnIFonXG4gICk7XG59XG5cbmNvbnN0IGNoYXJ0UGllVmFyaWFudHMgPSBjdmEoJ3JlbGF0aXZlIHctZnVsbCcsIHtcbiAgdmFyaWFudHM6IHtcbiAgICB2YXJpYW50OiB7XG4gICAgICBkZWZhdWx0OiAnJyxcbiAgICAgIGNhcmQ6ICdyb3VuZGVkLWxnIGJvcmRlciBib3JkZXItYm9yZGVyIGJnLWJhY2tncm91bmQgcC00JyxcbiAgICB9LFxuICB9LFxuICBkZWZhdWx0VmFyaWFudHM6IHsgdmFyaWFudDogJ2RlZmF1bHQnIH0sXG59KTtcblxuZXhwb3J0IHR5cGUgQ2hhcnRQaWVQcm9wcyA9IFZhcmlhbnRQcm9wczx0eXBlb2YgY2hhcnRQaWVWYXJpYW50cz47XG5cbi8qKlxuICogQSBwaWUgb3IgZG9udXQgZHJhd24gZnJvbSBoYW5kLXdyaXR0ZW4gU1ZHIGFyY3MuXG4gKlxuICogU2xpY2VzIGFyZSBzZXBhcmF0ZWQgYnkgYSByZWFsIDJweCBhbmd1bGFyIGdhcCByYXRoZXIgdGhhbiBhIHN0cm9rZSwgc28gd2hhdFxuICogZGl2aWRlcyB0aGVtIGlzIHN1cmZhY2UgcmF0aGVyIHRoYW4gYWRkZWQgaW5rLiBDb2xvdXIgaXMgYXNzaWduZWQgYnkgc2xpY2VcbiAqIGxhYmVsLCBzbyByZS1zb3J0aW5nIG9yIGZpbHRlcmluZyB0aGUgZGF0YSBuZXZlciByZXBhaW50cyBhIHNsaWNlLCBhbmQgYVxuICogc2l4dGggc2xpY2UgZmFsbHMgYmFjayB0byBhIG5ldXRyYWwgcmF0aGVyIHRoYW4gcmV1c2luZyBgLS1jaGFydC0xYC5cbiAqXG4gKiBSZW5kZXJzIGl0cyBvd24gbGVnZW5kIGF0IHR3byBvciBtb3JlIHNsaWNlcywgYSBwZXItc2xpY2UgaG92ZXIgdG9vbHRpcCwgYW5kXG4gKiB0aGUgc2FtZSBhY2Nlc3NpYmxlIGB0b2xsZS1jaGFydC10YWJsZWAgZmFsbGJhY2sgYXMgYHRvbGxlLWNoYXJ0YC5cbiAqIEBuZXdcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtY2hhcnQtcGllJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgQ2hhcnRUYWJsZUNvbXBvbmVudF0sXG4gIHByb3ZpZGVyczogW0NoYXJ0U2VydmljZV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNvbXB1dGVkQ2xhc3NcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSB3LWZ1bGxcIj5cbiAgICAgICAgPHN2Z1xuICAgICAgICAgIHJvbGU9XCJpbWdcIlxuICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXG4gICAgICAgICAgW2F0dHIuaGVpZ2h0XT1cInNpemVcIlxuICAgICAgICAgIFthdHRyLnZpZXdCb3hdPVwidmlld0JveFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTGFiZWwgfHwgbnVsbFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJ0YWJsZUlkXCJcbiAgICAgICAgICBjbGFzcz1cImJsb2NrIHctZnVsbFwiXG4gICAgICAgICAgKHBvaW50ZXJsZWF2ZSk9XCJvbkxlYXZlKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPHRpdGxlPnt7IGFyaWFMYWJlbCB9fTwvdGl0bGU+XG4gICAgICAgICAgPGRlc2M+e3sgZGVzY3JpcHRpb24gfHwgYXJpYUxhYmVsIH19PC9kZXNjPlxuXG4gICAgICAgICAgPHN2ZzpwYXRoXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc2xpY2Ugb2Ygc2xpY2VzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja1NsaWNlXCJcbiAgICAgICAgICAgIFthdHRyLmRdPVwic2xpY2UuZFwiXG4gICAgICAgICAgICBbYXR0ci5maWxsXT1cInNsaWNlLmNvbG9yXCJcbiAgICAgICAgICAgIFthdHRyLmZpbGwtb3BhY2l0eV09XCJhY3RpdmVJbmRleCA9PT0gaSA/IDEgOiAwLjg1XCJcbiAgICAgICAgICAgIChwb2ludGVyZW50ZXIpPVwib25FbnRlcihpKVwiXG4gICAgICAgICAgPjwvc3ZnOnBhdGg+XG4gICAgICAgIDwvc3ZnPlxuXG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdJZj1cImFjdGl2ZVNsaWNlXCJcbiAgICAgICAgICByb2xlPVwic3RhdHVzXCJcbiAgICAgICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgICAgIGNsYXNzPVwicG9pbnRlci1ldmVudHMtbm9uZSBhYnNvbHV0ZSB6LTEwIG1pbi13LVs4cmVtXSByb3VuZGVkLW1kIGJvcmRlciBib3JkZXItYm9yZGVyIGJnLXBvcG92ZXIgcC0yIHRleHQtcG9wb3Zlci1mb3JlZ3JvdW5kIHNoYWRvdy1tZFwiXG4gICAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwidG9vbHRpcExlZnRcIlxuICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwidG9vbHRpcFRvcFwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTIgdGV4dC14c1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoLTIgdy0yIHNocmluay0wIHJvdW5kZWQtWzJweF1cIiBbc3R5bGUuYmFja2dyb3VuZF09XCJhY3RpdmVTbGljZS5jb2xvclwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCI+e3sgYWN0aXZlU2xpY2UubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1sLWF1dG8gZm9udC1tZWRpdW0gdGFidWxhci1udW1zIHRleHQtZm9yZWdyb3VuZFwiPlxuICAgICAgICAgICAgICB7eyBmb3JtYXRWYWx1ZShhY3RpdmVTbGljZS52YWx1ZSkgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8cCBjbGFzcz1cIm10LTAuNSB0ZXh0LXJpZ2h0IHRleHQteHMgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kIHRhYnVsYXItbnVtc1wiPlxuICAgICAgICAgICAge3sgZm9ybWF0UGVyY2VudChhY3RpdmVTbGljZS5wZXJjZW50KSB9fVxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPHVsICpuZ0lmPVwic2xpY2VzLmxlbmd0aCA+IDFcIiBjbGFzcz1cImZsZXggZmxleC13cmFwIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBnYXAteC00IGdhcC15LTEgcHQtMiB0ZXh0LXhzXCI+XG4gICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgc2xpY2Ugb2Ygc2xpY2VzOyB0cmFja0J5OiB0cmFja1NsaWNlXCIgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMS41XCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJoLTIgdy0yIHNocmluay0wIHJvdW5kZWQtWzJweF1cIiBbc3R5bGUuYmFja2dyb3VuZF09XCJzbGljZS5jb2xvclwiPjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWQtZm9yZWdyb3VuZFwiPnt7IHNsaWNlLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cblxuICAgICAgPHRvbGxlLWNoYXJ0LXRhYmxlXG4gICAgICAgIFt0YWJsZUlkXT1cInRhYmxlSWRcIlxuICAgICAgICBbdmlzaWJsZV09XCJzaG93VGFibGVcIlxuICAgICAgICBbeEhlYWRlcl09XCJsYWJlbEhlYWRlclwiXG4gICAgICAgIFtjYXB0aW9uXT1cImFyaWFMYWJlbCB8fCAnQ2hhcnQgZGF0YSdcIlxuICAgICAgPjwvdG9sbGUtY2hhcnQtdGFibGU+XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENoYXJ0UGllQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqIFJvd3MgdG8gcGxvdCwgb25lIHNsaWNlIGVhY2guIEBkZWZhdWx0IFtdICovXG4gIEBJbnB1dCgpIGRhdGE6IFJlY29yZDxzdHJpbmcsIGFueT5bXSA9IFtdO1xuICAvKiogUm93IGtleSBob2xkaW5nIGVhY2ggc2xpY2UncyBudW1lcmljIHZhbHVlLiBAZGVmYXVsdCAndmFsdWUnICovXG4gIEBJbnB1dCgpIHZhbHVlS2V5ID0gJ3ZhbHVlJztcbiAgLyoqIFJvdyBrZXkgaG9sZGluZyBlYWNoIHNsaWNlJ3MgbGFiZWwuIEBkZWZhdWx0ICdsYWJlbCcgKi9cbiAgQElucHV0KCkgbGFiZWxLZXkgPSAnbGFiZWwnO1xuICAvKiogQ3V0cyBhIGhvbGUgaW4gdGhlIG1pZGRsZSwgbWFraW5nIGl0IGEgZG9udXQuIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIGRvbnV0ID0gZmFsc2U7XG4gIC8qKiBIb2xlIHNpemUgYXMgYSBmcmFjdGlvbiBvZiB0aGUgb3V0ZXIgcmFkaXVzLCB1c2VkIHdoZW4gYGRvbnV0YCBpcyBzZXQuIEBkZWZhdWx0IDAuNiAqL1xuICBASW5wdXQoKSBpbm5lclJhZGl1cyA9IDAuNjtcbiAgLyoqIFdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHNxdWFyZSBwbG90IGluIHB4LiBAZGVmYXVsdCAyNDAgKi9cbiAgQElucHV0KCkgc2l6ZSA9IDI0MDtcbiAgLyoqIEFuZ3VsYXIgZ2FwIGJldHdlZW4gc2xpY2VzLCBleHByZXNzZWQgaW4gcHggb2YgYXJjIGF0IHRoZSBvdXRlciBlZGdlLiBAZGVmYXVsdCAyICovXG4gIEBJbnB1dCgpIGdhcCA9IDI7XG4gIC8qKiBBY2Nlc3NpYmxlIG5hbWUgZm9yIHRoZSBjaGFydCwgdXNlZCBhcyB0aGUgc3ZnIGA8dGl0bGU+YC4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsID0gJyc7XG4gIC8qKiBMb25nZXIgc3VtbWFyeSB1c2VkIGFzIHRoZSBzdmcgYDxkZXNjPmAuIEZhbGxzIGJhY2sgdG8gYGFyaWFMYWJlbGAuIEBkZWZhdWx0ICcnICovXG4gIEBJbnB1dCgpIGRlc2NyaXB0aW9uID0gJyc7XG4gIC8qKiBTaG93cyB0aGUgZGF0YSB0YWJsZSBpbnN0ZWFkIG9mIGxlYXZpbmcgaXQgdmlzdWFsbHkgaGlkZGVuLiBAZGVmYXVsdCBmYWxzZSAqL1xuICBASW5wdXQoKSBzaG93VGFibGUgPSBmYWxzZTtcbiAgLyoqIENvbHVtbiBoZWFkZXIgdGhlIHRhYmxlIGZhbGxiYWNrIGdpdmVzIHRoZSBsYWJlbCBjb2x1bW4uIEBkZWZhdWx0ICdDYXRlZ29yeScgKi9cbiAgQElucHV0KCkgbGFiZWxIZWFkZXIgPSAnQ2F0ZWdvcnknO1xuICAvKiogQ29sdW1uIGhlYWRlciB0aGUgdGFibGUgZmFsbGJhY2sgZ2l2ZXMgdGhlIHZhbHVlIGNvbHVtbi4gQGRlZmF1bHQgJ1ZhbHVlJyAqL1xuICBASW5wdXQoKSB2YWx1ZUhlYWRlciA9ICdWYWx1ZSc7XG4gIC8qKiBWaXN1YWwgdHJlYXRtZW50IG9mIHRoZSBjaGFydCBmcmFtZS4gQGRlZmF1bHQgJ2RlZmF1bHQnICovXG4gIEBJbnB1dCgpIHZhcmlhbnQ6IENoYXJ0UGllUHJvcHNbJ3ZhcmlhbnQnXSA9ICdkZWZhdWx0JztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIGNoYXJ0IHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgLyoqIEVtaXR0ZWQgd2l0aCB0aGUgaG92ZXJlZCBzbGljZSBpbmRleCwgb3IgbnVsbCB3aGVuIHRoZSBwb2ludGVyIGxlYXZlcy4gKi9cbiAgQE91dHB1dCgpIGFjdGl2ZUluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCBudWxsPigpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgLyoqIE9ubHkgdXNlZCB0byBmZWVkIHRoZSBzaGFyZWQgdGFibGUgZmFsbGJhY2s7IHRoZSBwaWUgb3ducyBpdHMgb3duIGNvbG91cnMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdGFibGVTb3VyY2UgPSBpbmplY3QoQ2hhcnRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb2xvcnMgPSBuZXcgQ2hhcnRDb2xvclNjYWxlKCk7XG5cbiAgLyoqIElkIG9mIHRoZSB0YWJsZSBmYWxsYmFjaywgcmVmZXJlbmNlZCBieSB0aGUgc3ZnJ3MgYGFyaWEtZGVzY3JpYmVkYnlgLiAqL1xuICByZWFkb25seSB0YWJsZUlkID0gJ2NoYXJ0LXBpZS10YWJsZS0nICsgY2hhcnRQaWVJZCsrO1xuXG4gIC8qKiBJbmRleCBvZiB0aGUgaG92ZXJlZCBzbGljZSwgb3IgbnVsbC4gKi9cbiAgYWN0aXZlSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIC8vIFJlc2VydmUgcGFsZXR0ZSBzbG90cyBpbiBkYXRhIG9yZGVyLCBzbyBhIHNsaWNlIGtlZXBzIGl0cyBjb2xvdXIgd2hlbiB0aGVcbiAgICAvLyBkYXRhIGlzIGxhdGVyIHJlLXNvcnRlZCBvciBmaWx0ZXJlZC5cbiAgICB0aGlzLmNvbG9ycy5yZWdpc3Rlcih0aGlzLmxhYmVscyk7XG4gICAgdGhpcy50YWJsZVNvdXJjZS5jb25maWd1cmUoe1xuICAgICAgZGF0YTogdGhpcy5kYXRhID8/IFtdLFxuICAgICAgeEtleTogdGhpcy5sYWJlbEtleSxcbiAgICAgIHNlcmllczogW3sga2V5OiB0aGlzLnZhbHVlS2V5LCBsYWJlbDogdGhpcy52YWx1ZUhlYWRlciB9XSxcbiAgICB9KTtcbiAgICB0aGlzLl9zbGljZXMgPSB0aGlzLmNvbXB1dGVTbGljZXMoKTtcbiAgXG4gICAgLy8gQSBib3VuZCBgY2xhc3NgIGlucHV0IGlzIHdyaXR0ZW4gdGhyb3VnaCBBbmd1bGFyJ3Mgc3R5bGluZyBwYXRoLFxuICAgIC8vIHdoaWNoIGRvZXMgbm90IG1hcmsgYW4gT25QdXNoIHZpZXcgZGlydHkgb24gaXRzIG93bi5cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGxhYmVscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuICh0aGlzLmRhdGEgPz8gW10pLm1hcCgocm93KSA9PiB7XG4gICAgICBjb25zdCByYXcgPSByb3c/Llt0aGlzLmxhYmVsS2V5XTtcbiAgICAgIHJldHVybiByYXcgPT0gbnVsbCA/ICcnIDogU3RyaW5nKHJhdyk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgdmlld0JveCgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnMCAwICcgKyB0aGlzLnNpemUgKyAnICcgKyB0aGlzLnNpemU7XG4gIH1cblxuICBwcml2YXRlIGdldCBvdXRlclJhZGl1cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnNpemUgLyAyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVkIHNsaWNlcyBpbiBkYXRhIG9yZGVyLCBlYWNoIGFscmVhZHkgcGFkZGVkIGZvciB0aGUgc3VyZmFjZSBnYXAuXG4gICAqXG4gICAqIENvbXB1dGVkIG9uY2UgcGVyIGlucHV0IGNoYW5nZSwgTk9UIHBlciByZWFkLiBUaHJlZSB0ZW1wbGF0ZSBiaW5kaW5ncyByZWFkXG4gICAqIHRoaXMgZWFjaCBwYXNzOyB3aGVuIGl0IHJlYnVpbHQgdGhlIGFycmF5IGV2ZXJ5IHRpbWUsIGAqbmdGb3JgIHNhdyBmcmVzaFxuICAgKiBpZGVudGl0aWVzIGFuZCB0b3JlIGRvd24gZXZlcnkgYDxwYXRoPmAgb24gZXZlcnkgY2hhbmdlLWRldGVjdGlvbiBydW4uXG4gICAqIERlc3Ryb3lpbmcgdGhlIG5vZGUgdW5kZXIgdGhlIHBvaW50ZXIgcmUtZmlyZXMgYHBvaW50ZXJlbnRlcmAsIHdoaWNoIGNhbGxzXG4gICAqIGBtYXJrRm9yQ2hlY2tgLCB3aGljaCBzY2hlZHVsZXMgYW5vdGhlciBwYXNzIOKAlCB0aGUgY2hhcnQgbG9ja2VkIHRoZSBwYWdlIHVwLlxuICAgKi9cbiAgZ2V0IHNsaWNlcygpOiBDaGFydFBpZVNsaWNlW10ge1xuICAgIHJldHVybiB0aGlzLl9zbGljZXM7XG4gIH1cblxuICBwcml2YXRlIF9zbGljZXM6IENoYXJ0UGllU2xpY2VbXSA9IFtdO1xuXG4gIC8qKiBJZGVudGl0eSBmb3IgYCpuZ0ZvcmAsIHNvIGEgcmVkcmF3IHBhdGNoZXMgYXR0cmlidXRlcyBpbnN0ZWFkIG9mIHJlcGxhY2luZyBub2Rlcy4gKi9cbiAgdHJhY2tTbGljZSA9IChfOiBudW1iZXIsIHNsaWNlOiBDaGFydFBpZVNsaWNlKTogc3RyaW5nID0+IHNsaWNlLmxhYmVsO1xuXG4gIHByaXZhdGUgY29tcHV0ZVNsaWNlcygpOiBDaGFydFBpZVNsaWNlW10ge1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLmRhdGEgPz8gW107XG4gICAgY29uc3QgdmFsdWVzID0gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgY29uc3QgbnVtID0gTnVtYmVyKHJvdz8uW3RoaXMudmFsdWVLZXldKTtcbiAgICAgIC8vIEEgcGllIGRpdmlkZXMgYSB3aG9sZTsgYSBuZWdhdGl2ZSBzaGFyZSBoYXMgbm8gbWVhbmluZyBpbiBvbmUuXG4gICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bSkgJiYgbnVtID4gMCA/IG51bSA6IDA7XG4gICAgfSk7XG4gICAgY29uc3QgdG90YWwgPSB2YWx1ZXMucmVkdWNlKChzdW0sIHYpID0+IHN1bSArIHYsIDApO1xuICAgIGlmICh0b3RhbCA8PSAwKSByZXR1cm4gW107XG5cbiAgICBjb25zdCBjeCA9IHRoaXMuc2l6ZSAvIDI7XG4gICAgY29uc3QgY3kgPSB0aGlzLnNpemUgLyAyO1xuICAgIGNvbnN0IG91dGVyID0gdGhpcy5vdXRlclJhZGl1cztcbiAgICBjb25zdCBpbm5lciA9IHRoaXMuZG9udXQgPyBvdXRlciAqIE1hdGgubWluKDAuOTUsIE1hdGgubWF4KDAsIHRoaXMuaW5uZXJSYWRpdXMpKSA6IDA7XG4gICAgLy8gVHVybiBhIHB4IGdhcCBhdCB0aGUgcmltIGludG8gdGhlIGFuZ2xlIHRoYXQgc3VidGVuZHMgaXQuXG4gICAgY29uc3QgcGFkID0gb3V0ZXIgPiAwID8gdGhpcy5nYXAgLyBvdXRlciA6IDA7XG5cbiAgICBjb25zdCBvdXQ6IENoYXJ0UGllU2xpY2VbXSA9IFtdO1xuICAgIGxldCBjdXJzb3IgPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgIGlmICh2YWx1ZSA8PSAwKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgc3BhbiA9ICh2YWx1ZSAvIHRvdGFsKSAqIE1hdGguUEkgKiAyO1xuICAgICAgY29uc3Qgc3RhcnQgPSBjdXJzb3I7XG4gICAgICBjb25zdCBlbmQgPSBjdXJzb3IgKyBzcGFuO1xuICAgICAgY3Vyc29yID0gZW5kO1xuXG4gICAgICAvLyBOZXZlciBsZXQgdGhlIGdhcCBlYXQgYSBzbGljZTogYSBzbGl2ZXIga2VlcHMgYSBoYWlybGluZSBvZiBpdHNlbGYuXG4gICAgICBjb25zdCB1c2FibGUgPSBNYXRoLm1heChzcGFuICogMC4yLCBzcGFuIC0gcGFkKTtcbiAgICAgIGNvbnN0IGluc2V0ID0gKHNwYW4gLSB1c2FibGUpIC8gMjtcbiAgICAgIGNvbnN0IGxhYmVsID0gdGhpcy5sYWJlbHNbaV07XG4gICAgICBjb25zdCBtaWQgPSBzdGFydCArIHNwYW4gLyAyO1xuICAgICAgY29uc3QgW2FuY2hvclgsIGFuY2hvclldID0gcG9sYXJQb2ludChjeCwgY3ksIChvdXRlciArIGlubmVyKSAvIDIsIG1pZCk7XG5cbiAgICAgIG91dC5wdXNoKHtcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBwZXJjZW50OiB2YWx1ZSAvIHRvdGFsLFxuICAgICAgICBjb2xvcjogdGhpcy5jb2xvcnMuY29sb3JGb3IobGFiZWwpLFxuICAgICAgICBkOiBhcmNQYXRoKGN4LCBjeSwgb3V0ZXIsIGlubmVyLCBzdGFydCArIGluc2V0LCBlbmQgLSBpbnNldCksXG4gICAgICAgIGFuY2hvclgsXG4gICAgICAgIGFuY2hvclksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgZ2V0IGFjdGl2ZVNsaWNlKCk6IENoYXJ0UGllU2xpY2UgfCBudWxsIHtcbiAgICBpZiAodGhpcy5hY3RpdmVJbmRleCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMuc2xpY2VzW3RoaXMuYWN0aXZlSW5kZXhdID8/IG51bGw7XG4gIH1cblxuICBnZXQgdG9vbHRpcExlZnQoKTogbnVtYmVyIHtcbiAgICBjb25zdCBzbGljZSA9IHRoaXMuYWN0aXZlU2xpY2U7XG4gICAgaWYgKCFzbGljZSkgcmV0dXJuIDA7XG4gICAgLy8gRmxpcCB0b3dhcmQgdGhlIGNlbnRyZSByYXRoZXIgdGhhbiBsZXQgdGhlIHJlYWRvdXQgbGVhdmUgdGhlIGZyYW1lLlxuICAgIHJldHVybiBzbGljZS5hbmNob3JYID4gdGhpcy5zaXplIC8gMlxuICAgICAgPyBNYXRoLm1heCgwLCBzbGljZS5hbmNob3JYIC0gMTQwKVxuICAgICAgOiBNYXRoLm1pbih0aGlzLnNpemUsIHNsaWNlLmFuY2hvclggKyA4KTtcbiAgfVxuXG4gIGdldCB0b29sdGlwVG9wKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlU2xpY2UgPyB0aGlzLmFjdGl2ZVNsaWNlLmFuY2hvclkgOiAwO1xuICB9XG5cbiAgZm9ybWF0VmFsdWUodmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHZhbHVlLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycpO1xuICB9XG5cbiAgZm9ybWF0UGVyY2VudChwZXJjZW50OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiAocGVyY2VudCAqIDEwMCkudG9GaXhlZCgxKSArICclJztcbiAgfVxuXG4gIG9uRW50ZXIoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2ZUluZGV4ID09PSBpbmRleCkgcmV0dXJuO1xuICAgIHRoaXMuYWN0aXZlSW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmFjdGl2ZUluZGV4Q2hhbmdlLmVtaXQoaW5kZXgpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25MZWF2ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hY3RpdmVJbmRleCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgIHRoaXMuYWN0aXZlSW5kZXggPSBudWxsO1xuICAgIHRoaXMuYWN0aXZlSW5kZXhDaGFuZ2UuZW1pdChudWxsKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihjaGFydFBpZVZhcmlhbnRzKHsgdmFyaWFudDogdGhpcy52YXJpYW50IH0pLCB0aGlzLmNsYXNzKTtcbiAgfVxufVxuIl19