@firestitch/report 18.6.1 → 18.8.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 (97) hide show
  1. package/app/reports/components/component-chart/component-chart.component.d.ts +6 -7
  2. package/app/reports/components/component-kpi/component-kpi.component.d.ts +17 -9
  3. package/app/reports/components/component-kpi/components/sparkline/sparkline.component.d.ts +8 -0
  4. package/app/reports/components/component-list/component-list.component.d.ts +39 -10
  5. package/app/reports/components/component-note/component-note.component.d.ts +12 -0
  6. package/app/reports/components/report-canvas/report-canvas.component.d.ts +0 -10
  7. package/app/reports/components/report-component/report-component.component.d.ts +5 -12
  8. package/app/reports/data/report.data.d.ts +2 -3
  9. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +34 -2
  10. package/app/reports/dialogs/list-columns/list-columns.component.d.ts +23 -0
  11. package/app/reports/dialogs/report-settings/report-locale-patch.d.ts +5 -0
  12. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +20 -2
  13. package/app/reports/enums/report-change-polarity.enum.d.ts +5 -0
  14. package/app/reports/enums/report-chart-color.enum.d.ts +12 -0
  15. package/app/reports/enums/report-chart-data-labels.enum.d.ts +6 -0
  16. package/app/reports/enums/report-chart-date-label.enum.d.ts +5 -0
  17. package/app/reports/enums/report-chart-line-style.enum.d.ts +5 -0
  18. package/app/reports/enums/report-chart-mark-stat.enum.d.ts +6 -0
  19. package/app/reports/enums/report-kpi-trend.enum.d.ts +5 -0
  20. package/app/reports/enums/report-list-column-format.enum.d.ts +6 -0
  21. package/app/reports/enums/report-number-units.enum.d.ts +6 -0
  22. package/app/reports/enums/report-value-format.enum.d.ts +5 -0
  23. package/app/reports/export/offscreen-chart.d.ts +2 -2
  24. package/app/reports/export/report-export-collector.service.d.ts +37 -8
  25. package/app/reports/export/report-pdf.service.d.ts +6 -0
  26. package/app/reports/export/report-pptx.service.d.ts +24 -0
  27. package/app/reports/format.d.ts +64 -3
  28. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +2 -0
  29. package/app/reports/interfaces/report.interface.d.ts +205 -14
  30. package/app/reports/kpi-card.d.ts +48 -0
  31. package/app/reports/layout.d.ts +0 -9
  32. package/app/reports/list-config.d.ts +16 -0
  33. package/app/reports/option-builder.d.ts +76 -9
  34. package/app/reports/output-notes.d.ts +14 -0
  35. package/app/reports/pipes/report-date.pipe.d.ts +2 -1
  36. package/app/reports/pipes/report-number.pipe.d.ts +8 -0
  37. package/app/reports/pipes/report-output.pipe.d.ts +10 -0
  38. package/app/reports/report-filter-items.d.ts +5 -2
  39. package/app/reports/report-url-state.d.ts +4 -0
  40. package/app/reports/services/report-filter-state.service.d.ts +27 -2
  41. package/app/reports/theme/palette.d.ts +6 -0
  42. package/app/reports/theme/typography.d.ts +2 -0
  43. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +23 -20
  44. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +56 -29
  45. package/esm2022/app/reports/components/component-kpi/components/sparkline/sparkline.component.mjs +19 -0
  46. package/esm2022/app/reports/components/component-list/component-list.component.mjs +218 -32
  47. package/esm2022/app/reports/components/component-note/component-note.component.mjs +30 -0
  48. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +7 -61
  49. package/esm2022/app/reports/components/report-component/report-component.component.mjs +99 -100
  50. package/esm2022/app/reports/data/report.data.mjs +20 -7
  51. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +133 -13
  52. package/esm2022/app/reports/dialogs/list-columns/list-columns.component.mjs +56 -0
  53. package/esm2022/app/reports/dialogs/report-settings/report-locale-patch.mjs +13 -0
  54. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +138 -20
  55. package/esm2022/app/reports/enums/report-change-polarity.enum.mjs +11 -0
  56. package/esm2022/app/reports/enums/report-chart-color.enum.mjs +19 -0
  57. package/esm2022/app/reports/enums/report-chart-data-labels.enum.mjs +13 -0
  58. package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +13 -0
  59. package/esm2022/app/reports/enums/report-chart-line-style.enum.mjs +12 -0
  60. package/esm2022/app/reports/enums/report-chart-mark-stat.enum.mjs +12 -0
  61. package/esm2022/app/reports/enums/report-kpi-trend.enum.mjs +10 -0
  62. package/esm2022/app/reports/enums/report-list-column-format.enum.mjs +14 -0
  63. package/esm2022/app/reports/enums/report-number-units.enum.mjs +14 -0
  64. package/esm2022/app/reports/enums/report-value-format.enum.mjs +13 -0
  65. package/esm2022/app/reports/export/offscreen-chart.mjs +5 -4
  66. package/esm2022/app/reports/export/report-export-collector.service.mjs +186 -40
  67. package/esm2022/app/reports/export/report-pdf.service.mjs +332 -67
  68. package/esm2022/app/reports/export/report-pptx.service.mjs +765 -106
  69. package/esm2022/app/reports/format.mjs +917 -57
  70. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  71. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  72. package/esm2022/app/reports/kpi-card.mjs +174 -0
  73. package/esm2022/app/reports/layout.mjs +1 -46
  74. package/esm2022/app/reports/list-config.mjs +106 -0
  75. package/esm2022/app/reports/option-builder.mjs +1457 -117
  76. package/esm2022/app/reports/output-notes.mjs +158 -0
  77. package/esm2022/app/reports/pipes/report-date.pipe.mjs +7 -6
  78. package/esm2022/app/reports/pipes/report-number.pipe.mjs +25 -0
  79. package/esm2022/app/reports/pipes/report-output.pipe.mjs +28 -0
  80. package/esm2022/app/reports/report-filter-items.mjs +28 -3
  81. package/esm2022/app/reports/report-url-state.mjs +56 -15
  82. package/esm2022/app/reports/services/report-filter-state.service.mjs +274 -22
  83. package/esm2022/app/reports/theme/echarts.mjs +8 -2
  84. package/esm2022/app/reports/theme/palette.mjs +35 -1
  85. package/esm2022/app/reports/theme/typography.mjs +8 -1
  86. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
  87. package/esm2022/app/reports/views/report/report.component.mjs +3 -4
  88. package/esm2022/public_api.mjs +10 -1
  89. package/fesm2022/{firestitch-report-echarts-Djtmaxj1.mjs → firestitch-report-echarts-qCBE3LqM.mjs} +9 -3
  90. package/fesm2022/firestitch-report-echarts-qCBE3LqM.mjs.map +1 -0
  91. package/fesm2022/{firestitch-report-firestitch-report-D3zseBZc.mjs → firestitch-report-firestitch-report-DbsWbE-j.mjs} +5523 -875
  92. package/fesm2022/firestitch-report-firestitch-report-DbsWbE-j.mjs.map +1 -0
  93. package/fesm2022/firestitch-report.mjs +1 -1
  94. package/package.json +1 -1
  95. package/public_api.d.ts +9 -0
  96. package/fesm2022/firestitch-report-echarts-Djtmaxj1.mjs.map +0 -1
  97. package/fesm2022/firestitch-report-firestitch-report-D3zseBZc.mjs.map +0 -1
@@ -1,12 +1,21 @@
1
- import { format, isValid, parseISO } from 'date-fns';
2
- import { formatMeasureValue } from './format';
1
+ import { addDays, addMonths, addQuarters, addWeeks, addYears, endOfMonth, formatISO, isLastDayOfMonth, isValid, max as latestOf, min as earliestOf, parseISO, startOfDay, } from 'date-fns';
2
+ import { ReportChartColor } from './enums/report-chart-color.enum';
3
+ import { ReportChartDataLabels } from './enums/report-chart-data-labels.enum';
4
+ import { ReportChartDateLabel } from './enums/report-chart-date-label.enum';
5
+ import { ReportChartLineStyle } from './enums/report-chart-line-style.enum';
6
+ import { ReportChartMarkStat } from './enums/report-chart-mark-stat.enum';
7
+ import { ReportListColumnFormat } from './enums/report-list-column-format.enum';
8
+ import { ReportNumberUnits } from './enums/report-number-units.enum';
9
+ import { ReportValueFormat } from './enums/report-value-format.enum';
10
+ import { axisNumberFormat, chartValuePeak, comparisonOffsetLabel, DAY_SHORT, dateFormat, formatDayRange, formatDayWindow, formatLocalDate, formatNumber, formatOutputValue, formatPlainNumber, hasNumberFormat, laneOutputAlias, MONTH_DAY, MONTH_LONG, MONTH_YEAR, resolveChartNumberFormat, windowText, } from './format';
3
11
  import { GRANULARITY_OPTIONS, } from './interfaces/report.interface';
4
12
  import { escapeHtml } from './text';
5
- import { REPORT_WATERFALL_COLORS } from './theme/palette';
6
- import { REPORT_AXIS_LABEL_FONT_SIZE, REPORT_CHART_FONT_FAMILY } from './theme/typography';
7
- // Room for the category axis's title. ECharts 5's containLabel keeps the TICK
8
- // labels inside the grid but not the axis name, so without this a vertical
9
- // chart's title runs off the bottom edge or under a bottom legend.
13
+ import { REPORT_CHART_COLOR_BY_NAME, REPORT_CHART_COLORS, REPORT_CHART_COLORS_CSS, REPORT_REFERENCE_COLOR, REPORT_WATERFALL_COLORS, } from './theme/palette';
14
+ import { REPORT_AXIS_LABEL_FONT_SIZE, REPORT_CHART_FONT_FAMILY, REPORT_DATA_LABEL_FONT_SIZE } from './theme/typography';
15
+ // Room for an axis title. ECharts 5's containLabel keeps the TICK labels inside
16
+ // the grid but not the axis name, so without this a vertical chart's category
17
+ // title runs off the bottom edge or under a bottom legend, and its value title
18
+ // above the plot runs off the top or under a top legend.
10
19
  const AXIS_NAME_ROOM = 20;
11
20
  // ECharts' own default gap between the axis line and its tick labels.
12
21
  const AXIS_LABEL_MARGIN = 8;
@@ -22,6 +31,73 @@ const LABEL_ELLIPSIS = '…';
22
31
  // measured in it the way ECharts measures them for containLabel, so a
23
32
  // horizontal chart's title lands exactly beyond the widest label.
24
33
  const AXIS_LABEL_FONT = `${REPORT_AXIS_LABEL_FONT_SIZE}px ${REPORT_CHART_FONT_FAMILY}`;
34
+ // The letter a quarter label starts with, by language subtag. French writes the
35
+ // second quarter 'T2' (trimestre); every other language reads 'Q2'.
36
+ const QUARTER_PREFIXES = new Map([['fr', 'T']]);
37
+ const QUARTER_PREFIX = 'Q';
38
+ // A 100% stacked chart's value axis: whole percentages, a gridline every 25%,
39
+ // up to 100%. Its tooltip gives each share to one decimal.
40
+ const PERCENT_AXIS_FORMAT = { format: ReportValueFormat.Percent, precision: 0 };
41
+ const PERCENT_SHARE_FORMAT = { format: ReportValueFormat.Percent, precision: 1 };
42
+ export const PERCENT_AXIS_MAX = 1;
43
+ export const PERCENT_AXIS_INTERVAL = 0.25;
44
+ // A reference band's fill: the reference slate, faint enough that the series
45
+ // drawn across it stay readable.
46
+ const REFERENCE_BAND_FILL = 'rgba(82, 96, 109, 0.08)';
47
+ // A reference's or statistic line's label sits on a light box, so it stays
48
+ // readable where it crosses a bar or a line.
49
+ const MARK_LABEL_BOX = { backgroundColor: 'rgba(255, 255, 255, 0.85)', padding: [1, 3], borderRadius: 2 };
50
+ // The room an axis stretched to a reference leaves above it, for its label:
51
+ // the bound is the round number at or past the reference plus this share.
52
+ const REFERENCE_HEADROOM = 1.05;
53
+ // How a chart marks what the server says of its numbers (ComponentData's
54
+ // comparison, outputs, windows and partialPeriod). The words are interface
55
+ // text, English in every report locale.
56
+ // - The heading of a period not over yet ('September 2026 (to date)').
57
+ const PARTIAL_PERIOD_TEXT = 'to date';
58
+ // - A compared series' name: its measure's, then its role and lane ('Revenue
59
+ // change (vs previous week)'). A prior keeps the measure's name alone.
60
+ const ROLE_NAME_SUFFIXES = {
61
+ prior: '',
62
+ change: ' change',
63
+ percent_change: ' % change',
64
+ };
65
+ // - A prior series' bars: its current series' color, faded, with a dashed
66
+ // edge. Its line is dashed (PRIOR_LINE_STYLE) unless its measure names one.
67
+ const PRIOR_BAR_OPACITY = 0.45;
68
+ const PRIOR_LINE_STYLE = ReportChartLineStyle.Dashed;
69
+ // - The period not over yet: its bar hatched in light stripes, its point on a
70
+ // line drawn larger with a dashed edge, and, when it is the last one, the
71
+ // line's last segment dashed.
72
+ const PARTIAL_LINE_STYLE = ReportChartLineStyle.Dashed;
73
+ const PARTIAL_BAR_DECAL = {
74
+ symbol: 'none',
75
+ dashArrayX: [1, 0],
76
+ dashArrayY: [3, 5],
77
+ rotation: -Math.PI / 4,
78
+ color: 'rgba(255, 255, 255, 0.6)',
79
+ };
80
+ const PARTIAL_POINT_MARK = { symbol: 'emptyCircle', symbolSize: 9, itemStyle: { borderType: 'dashed' } };
81
+ // - A value axis of ranks only: rank 1 at the top, whole steps, from 1.
82
+ const RANK_AXIS_FORMAT = { format: ReportValueFormat.Number, precision: 0 };
83
+ // (Shared with the PowerPoint export, whose rank axes start there too.)
84
+ export const RANK_AXIS_MIN = 1;
85
+ // - A value axis of 0-1 fractions only (shares, percent changes) is a
86
+ // percent axis, its decimals decided by its peak.
87
+ const FRACTION_AXIS_FORMAT = { format: ReportValueFormat.Percent };
88
+ // - Between a tooltip value and what it covers.
89
+ const TOOLTIP_DETAIL_SEPARATOR = ' · ';
90
+ // - The prior a tooltip value is compared with, when the chart does not plot
91
+ // it ('vs 50% (Sep 1 – 2, 2026)').
92
+ const COMPARED_PRIOR_PREFIX = 'vs';
93
+ // The words a statistic line's label starts with. They are interface text,
94
+ // English in every report locale; only the value after them follows it.
95
+ export const STAT_LABEL = {
96
+ [ReportChartMarkStat.Average]: 'Average',
97
+ [ReportChartMarkStat.Median]: 'Median',
98
+ [ReportChartMarkStat.Min]: 'Minimum',
99
+ [ReportChartMarkStat.Max]: 'Maximum',
100
+ };
25
101
  // colorBy applies only to single-dimension bar charts, and only when splitBy
26
102
  // isn't already driving multiple series: it colors each bar by its category and
27
103
  // shows a legend (one series per category, overlapped to full width).
@@ -36,9 +112,9 @@ const AXIS_LABEL_FONT = `${REPORT_AXIS_LABEL_FONT_SIZE}px ${REPORT_CHART_FONT_FA
36
112
  //
37
113
  // A TIME axis is excluded: consecutive periods are one series moving, not
38
114
  // categories being compared, and coloring each month differently reads as
39
- // unrelated groups. Explicitly opting out — colorBy: {column: ''} or a
40
- // config.legend of 'hidden' — still wins, so a caller that wants one flat color
41
- // can say so.
115
+ // unrelated groups. Explicitly opting out — colorBy: {column: ''}, a color on
116
+ // the measure or a config.legend of 'hidden' — still wins, so a caller that
117
+ // wants one flat color can say so.
42
118
  //
43
119
  // "Bar chart" is the type the lone measure is actually DRAWN as: its own type
44
120
  // when it names one, which can turn a line chart's single series into bars or
@@ -50,6 +126,10 @@ export function isColorBy(config) {
50
126
  if (config.colorBy) {
51
127
  return !!config.colorBy.column;
52
128
  }
129
+ // A measure given its own color asks for one flat color.
130
+ if (measureColorHex(config.measures?.[0])) {
131
+ return false;
132
+ }
53
133
  return (config.xAxis?.kind ?? 'category') === 'category'
54
134
  && !config.xAxis?.granularity
55
135
  && (config.measures?.length ?? 1) <= 1;
@@ -63,15 +143,8 @@ export function colorByColumn(config) {
63
143
  }
64
144
  export function extractChartSeries(component, data) {
65
145
  const config = component.config;
66
- const xColumn = config.xAxis?.column ?? data.columns[0];
67
- const splitColumn = config.splitBy?.column;
68
- // colorBy emits one series per category too (so each bar carries its own
69
- // color + legend entry), but the bars are overlapped to full width in
70
- // buildAxisOption rather than laid side-by-side. splitBy wins if both are set.
71
- const groupColumn = splitColumn || colorByColumn(config);
72
- const measures = config.measures?.length
73
- ? config.measures
74
- : [{ column: data.columns[data.columns.length - 1] }];
146
+ const { xColumn, groupColumn } = chartColumns(config, data);
147
+ const measures = chartMeasures(config, data);
75
148
  const rawCategories = uniqueValues(data.rows, xColumn);
76
149
  const categories = rawCategories.map((category) => String(category ?? '—'));
77
150
  const series = [];
@@ -79,34 +152,221 @@ export function extractChartSeries(component, data) {
79
152
  // One series per group value (splitBy/colorBy), pivoted over the first measure.
80
153
  const measure = measures[0];
81
154
  for (const groupValue of uniqueValues(data.rows, groupColumn)) {
82
- const byCategory = new Map();
83
- for (const row of data.rows) {
84
- if (row[groupColumn] === groupValue) {
85
- byCategory.set(row[xColumn], row[measure.column]);
86
- }
87
- }
88
155
  series.push({
89
156
  name: String(groupValue ?? '—'),
90
- values: rawCategories.map((category) => numeric(byCategory.get(category))),
157
+ values: categoryValues(data.rows, xColumn, rawCategories, measure.column, (row) => row[groupColumn] === groupValue),
91
158
  type: measure.type,
159
+ measure,
160
+ measureIndex: 0,
92
161
  });
93
162
  }
94
163
  }
95
164
  else {
96
- for (const measure of measures) {
97
- const byCategory = new Map();
98
- for (const row of data.rows) {
99
- byCategory.set(row[xColumn], row[measure.column]);
100
- }
165
+ for (const [measureIndex, measure] of measures.entries()) {
101
166
  series.push({
102
- name: measure.label ?? measure.column,
103
- values: rawCategories.map((category) => numeric(byCategory.get(category))),
167
+ name: comparedSeriesName(measure, measures, data) ?? measure.label ?? measure.column,
168
+ values: categoryValues(data.rows, xColumn, rawCategories, measure.column),
104
169
  type: measure.type,
170
+ measure,
171
+ measureIndex,
105
172
  });
106
173
  }
107
174
  }
108
175
  return { categories, series };
109
176
  }
177
+ // The column a chart's categories come from, and the one that splits its
178
+ // first measure into a series per value, if any. colorBy emits one series per
179
+ // category too (so each bar carries its own color + legend entry), but the
180
+ // bars are overlapped to full width in buildAxisOption rather than laid
181
+ // side-by-side. splitBy wins if both are set.
182
+ function chartColumns(config, data) {
183
+ return {
184
+ xColumn: config.xAxis?.column ?? data.columns[0],
185
+ groupColumn: config.splitBy?.column || colorByColumn(config),
186
+ };
187
+ }
188
+ // One column's values by category, from the rows `match` keeps (all of them
189
+ // when it is left out). A category with no row has no value.
190
+ function categoryValues(rows, xColumn, rawCategories, column, match) {
191
+ const byCategory = new Map();
192
+ for (const row of rows) {
193
+ if (!match || match(row)) {
194
+ byCategory.set(row[xColumn], row[column]);
195
+ }
196
+ }
197
+ return rawCategories.map((category) => numeric(byCategory.get(category)));
198
+ }
199
+ // A compared series' name, worded from its lane's offset rather than from its
200
+ // own label, so a chart the viewer regrouped says what it now compares:
201
+ // 'Revenue (vs previous week)', 'Revenue change (vs previous week)', 'Revenue
202
+ // % change (vs previous year)'. The measure is named as its current value's
203
+ // series is. null for any other series, which keeps its own name, and for
204
+ // data without the comparison keys.
205
+ function comparedSeriesName(measure, measures, data) {
206
+ const output = data.outputs?.[measure.column];
207
+ const offset = output?.offset ? data.comparison?.offsets?.[output.offset - 1] : undefined;
208
+ if (!output || !offset || !output.role || output.role === 'current') {
209
+ return null;
210
+ }
211
+ const current = currentOutputAlias(data.outputs, measure.column);
212
+ const label = measures.find((candidate) => candidate.column === current)?.label ?? current;
213
+ return `${label}${ROLE_NAME_SUFFIXES[output.role]} (${comparisonOffsetLabel(offset)})`;
214
+ }
215
+ // The column an output's current value is in: its lane's current output, else
216
+ // for a rank or a share the uncompared one of the same measure, else the
217
+ // measure's own column (a windowed value's source).
218
+ function currentOutputAlias(outputs, alias) {
219
+ const output = outputs[alias];
220
+ const uncompared = output.kind === 'value'
221
+ ? undefined
222
+ : Object.keys(outputs).find((key) => outputs[key].measure === output.measure
223
+ && outputs[key].kind === output.kind
224
+ && outputs[key].role === null);
225
+ return laneOutputAlias(outputs, alias, 'current') ?? uncompared ?? output.measure;
226
+ }
227
+ // A series' own color as CSS hex: its measure's named color, or undefined when
228
+ // it names none (or a name the palette does not know) and the theme colors it
229
+ // by its position.
230
+ export function seriesColor(series) {
231
+ const hex = namedColorHex(series);
232
+ return hex ? `#${hex}` : undefined;
233
+ }
234
+ // A series' color as the bare hex PowerPoint takes: its measure's named color,
235
+ // else the palette color of its position, as the screen's theme picks it.
236
+ export function seriesHex(series, index) {
237
+ return namedColorHex(series) ?? REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length];
238
+ }
239
+ function namedColorHex(series) {
240
+ return measureColorHex(series.measure);
241
+ }
242
+ // A measure's named color as bare hex, or undefined when it names none or a
243
+ // name the palette does not know. The name is read through the enum, so a
244
+ // stored name such as '__proto__' never reaches the lookup object.
245
+ function measureColorHex(measure) {
246
+ const color = Object.values(ReportChartColor).find((name) => name === measure?.color);
247
+ return color ? REPORT_CHART_COLOR_BY_NAME[color] : undefined;
248
+ }
249
+ // A measure's line style when it names one ECharts knows, else undefined and
250
+ // the line is solid.
251
+ export function measureLineStyle(measure) {
252
+ return Object.values(ReportChartLineStyle).find((style) => style === measure?.line);
253
+ }
254
+ // A measure's statistic line when it names one the viewer knows, else
255
+ // undefined and it draws none.
256
+ export function measureMarkStat(measure) {
257
+ return Object.values(ReportChartMarkStat).find((stat) => stat === measure?.markLine);
258
+ }
259
+ // A series' statistic over its points that have a value: their mean, their
260
+ // median (the mean of the two middle values when the count is even), the
261
+ // lowest or the highest. null when no point has a value. Shared with the
262
+ // PowerPoint export so both media draw the line at the same height.
263
+ export function seriesStat(values, stat) {
264
+ const present = values.filter((value) => typeof value === 'number' && Number.isFinite(value));
265
+ if (!present.length) {
266
+ return null;
267
+ }
268
+ switch (stat) {
269
+ case ReportChartMarkStat.Average:
270
+ return present.reduce((sum, value) => sum + value, 0) / present.length;
271
+ case ReportChartMarkStat.Median: {
272
+ const sorted = [...present].sort((a, b) => a - b);
273
+ const middle = Math.floor(sorted.length / 2);
274
+ return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
275
+ }
276
+ case ReportChartMarkStat.Min:
277
+ return Math.min(...present);
278
+ case ReportChartMarkStat.Max:
279
+ return Math.max(...present);
280
+ default:
281
+ return null;
282
+ }
283
+ }
284
+ // Whether a chart draws statistic lines. A horizontal chart's values run
285
+ // along x, and PowerPoint cannot draw a line beside horizontal bars, so
286
+ // neither medium draws one there.
287
+ export function drawsStatLines(config) {
288
+ return config.orientation !== 'horizontal';
289
+ }
290
+ // A colorBy chart's one value per category: series i holds category i's bar.
291
+ // PowerPoint draws these as its one series, and a statistic line is taken
292
+ // over them.
293
+ export function colorByValues(extracted) {
294
+ return extracted.categories.map((_, index) => extracted.series[index]?.values[index] ?? null);
295
+ }
296
+ // The references a chart draws. A vertical axis chart and a waterfall draw
297
+ // them; a pie has no value axis, and a horizontal chart is left without them
298
+ // as PowerPoint cannot draw a line beside horizontal bars. An entry without a
299
+ // finite value is skipped, and one whose `to` is missing or equal to its value
300
+ // is a line. secondary reaches the second value axis only on a chart that has
301
+ // one (twoAxes). Shared with the PowerPoint export.
302
+ export function chartReferences(config, twoAxes) {
303
+ const chartType = config.chartType ?? 'bar';
304
+ const references = Array.isArray(config.references) ? config.references : [];
305
+ if (config.orientation === 'horizontal' || chartType === 'pie' || chartType === 'donut') {
306
+ return [];
307
+ }
308
+ return references.flatMap((reference) => {
309
+ const value = axisNumber(reference?.value);
310
+ if (!reference || value === undefined) {
311
+ return [];
312
+ }
313
+ const to = axisNumber(reference.to);
314
+ const label = typeof reference.label === 'string' ? reference.label : '';
315
+ const axisIndex = twoAxes && reference.secondary === true ? 1 : 0;
316
+ return [to !== undefined && to !== value
317
+ ? { label, low: Math.min(value, to), high: Math.max(value, to), band: true, axisIndex }
318
+ : { label, low: value, high: value, band: false, axisIndex }];
319
+ });
320
+ }
321
+ // Each series as its share of its category's total: per category, the
322
+ // denominator is the sum of every series' absolute value there, so the
323
+ // magnitudes of a category's shares add up to 1. A mixed-sign category's
324
+ // negative values take negative shares, drawn below zero. A missing value
325
+ // stays missing, and a category whose total is zero has no shares. Shared by
326
+ // the screen, the PDF and PowerPoint, so a 100% stack reads the same in each.
327
+ export function percentShares(values) {
328
+ const length = Math.max(0, ...values.map((series) => series.length));
329
+ const totals = Array.from({ length }, (_, index) => values
330
+ .reduce((sum, series) => sum + Math.abs(series[index] ?? 0), 0));
331
+ return values.map((series) => series.map((value, index) => (value === null || !totals[index] ? null : value / totals[index])));
332
+ }
333
+ // The shares a 100% stacked chart draws in place of its values, or null when
334
+ // the chart is not one. The primary axis's bar and area series take them,
335
+ // each type's series sharing among themselves, as each type stacks apart.
336
+ // Lines and secondary-axis series keep their values. A pie, a waterfall and a
337
+ // colorBy chart (one series per category, each of which would be 100%) are
338
+ // never 100% stacked, nor is a chart with no bar or area on its primary axis.
339
+ export function percentStackedShares(extracted, config) {
340
+ const chartType = config.chartType ?? 'bar';
341
+ if (config.percentStacked !== true
342
+ || chartType === 'pie' || chartType === 'donut' || chartType === 'waterfall'
343
+ || isColorBy(config)) {
344
+ return null;
345
+ }
346
+ const types = seriesTypes(extracted, chartType);
347
+ const axisIndexes = seriesAxisIndexes(extracted, config);
348
+ const shares = new Map();
349
+ for (const type of ['bar', 'area']) {
350
+ const indexes = types
351
+ .map((seriesType, index) => (seriesType === type && axisIndexes[index] === 0 ? index : -1))
352
+ .filter((index) => index >= 0);
353
+ const typeShares = percentShares(indexes.map((index) => extracted.series[index].values));
354
+ indexes.forEach((seriesIndex, position) => shares.set(seriesIndex, typeShares[position]));
355
+ }
356
+ return shares.size ? shares : null;
357
+ }
358
+ // Where a 100% stacked chart's value axis starts: at -100% when any share is
359
+ // negative, else at zero.
360
+ export function percentAxisMin(shares) {
361
+ return [...shares.values()].some((series) => series.some((share) => (share ?? 0) < 0)) ? -1 : 0;
362
+ }
363
+ // The measures a chart plots: its configured ones, else the query's last
364
+ // column, unformatted.
365
+ function chartMeasures(config, data) {
366
+ return config.measures?.length
367
+ ? config.measures
368
+ : [{ column: data.columns[data.columns.length - 1] }];
369
+ }
110
370
  // The type each extracted series is drawn as: its measure's own type when it
111
371
  // names one, the chart's chartType otherwise. More than one distinct type is a
112
372
  // combo chart. Shared with the PowerPoint export so both media draw each series
@@ -114,6 +374,17 @@ export function extractChartSeries(component, data) {
114
374
  export function seriesTypes(extracted, chartType) {
115
375
  return extracted.series.map((series) => series.type ?? chartType);
116
376
  }
377
+ // The value axis each extracted series is plotted against: 1 when its measure
378
+ // is secondary, 0 otherwise. A second axis is drawn only on a vertical chart
379
+ // that keeps at least one series on the primary axis, so a combination the
380
+ // server refuses (a horizontal chart, every measure secondary, the one measure
381
+ // of a splitBy or colorBy chart) plots everything on the primary axis. Shared
382
+ // with the PowerPoint export so both media put each series on the same axis.
383
+ export function seriesAxisIndexes(extracted, config) {
384
+ const secondary = extracted.series.map((series) => !!series.measure.secondary);
385
+ const twoAxes = config.orientation !== 'horizontal' && secondary.includes(true) && secondary.includes(false);
386
+ return secondary.map((isSecondary) => (twoAxes && isSecondary ? 1 : 0));
387
+ }
117
388
  export const WATERFALL_TOTAL_LABEL = 'Total';
118
389
  // A waterfall's bars from its one measure: each category's value is how far the
119
390
  // running total moves there, and a last Total bar shows where it ended. A
@@ -136,18 +407,24 @@ export function extractWaterfall(component, data) {
136
407
  // endpoint's rows to an ECharts option. Everything visual that isn't in the
137
408
  // registered 'report' theme is decided here, so report standards have exactly
138
409
  // two homes.
139
- export function buildChartOption(component, data) {
410
+ //
411
+ // Every number and period the chart writes (value-axis ticks, tooltip values,
412
+ // period labels) is in the context's locale, never the browser's. A measure
413
+ // with number-format keys formats its tooltips, and the value axis when every
414
+ // measure on it agrees (axisNumberFormat); without them the axis and tooltips
415
+ // keep the plain locale-grouped number.
416
+ export function buildChartOption(component, data, context) {
140
417
  const config = component.config;
141
418
  const chartType = config.chartType ?? 'bar';
142
419
  if (chartType === 'pie' || chartType === 'donut') {
143
- return buildPieOption(component, data, chartType === 'donut');
420
+ return buildPieOption(component, data, chartType === 'donut', context);
144
421
  }
145
422
  if (chartType === 'waterfall') {
146
- return buildWaterfallOption(component, data);
423
+ return buildWaterfallOption(component, data, context);
147
424
  }
148
- return buildAxisOption(component, data, chartType);
425
+ return buildAxisOption(component, data, chartType, context);
149
426
  }
150
- function buildAxisOption(component, data, chartType) {
427
+ function buildAxisOption(component, data, chartType, context) {
151
428
  const config = component.config;
152
429
  const extracted = extractChartSeries(component, data);
153
430
  const horizontal = config.orientation === 'horizontal';
@@ -161,22 +438,707 @@ function buildAxisOption(component, data, chartType) {
161
438
  //
162
439
  // Stacking sums every series that shares a stack name, whatever its type. In
163
440
  // a combo each type stacks only with its own kind, so a line of a rate never
164
- // sits on top of the bars' total.
165
- const series = extracted.series.map((extractedSeries, index) => buildSeries(extractedSeries.name, extractedSeries.values, types[index], config.stacked ? (combo ? `total-${types[index]}` : 'total') : undefined, colorBy && index === 0, combo));
166
- const categoryAxis = categoryAxisOption(config, data, extracted.categories, horizontal);
167
- const valueAxis = { type: 'value' };
441
+ // sits on top of the bars' total, and on a two-axis chart only with the
442
+ // series on its own axis.
443
+ //
444
+ // A 100% stacked chart (percentStackedShares) plots its primary bars and
445
+ // areas as shares, each type in its own stack, and leaves every other series
446
+ // unstacked on its own values.
447
+ //
448
+ // What the server says of the numbers (chartAnnotations) marks them: a
449
+ // prior series dashed in its current series' color, the period not over yet
450
+ // hatched or dashed, ranks on an inverted axis, fractions on a percent axis,
451
+ // and the tooltip naming each prior's days and each window. Data without
452
+ // those keys draws exactly as before.
453
+ const axisIndexes = seriesAxisIndexes(extracted, config);
454
+ const twoAxes = axisIndexes.includes(1);
455
+ const shares = percentStackedShares(extracted, config);
456
+ const references = chartReferences(config, twoAxes);
457
+ const annotations = chartAnnotations(config, data, extracted, colorBy);
458
+ const axisFormats = valueAxisFormats(config, annotations ? annotatedAxisSeries(extracted, annotations) : extracted, axisIndexes, annotations && !shares ? annotatedAxisContexts(annotations, axisIndexes, context) : [context, context], !!shares, references);
459
+ const rankAxes = annotations && !shares ? rankAxisFlags(annotations.outputs, axisIndexes) : [false, false];
460
+ // A series' statistic line is taken over the points it plots. On a colorBy
461
+ // chart each series holds one bar, so the one line is taken over the bars
462
+ // together and hangs off the first series (colorByStatLine).
463
+ const statLines = drawsStatLines(config) && !colorBy;
464
+ const series = extracted.series.map((extractedSeries, index) => {
465
+ const seriesShares = shares?.get(index);
466
+ let stack;
467
+ if (seriesShares) {
468
+ stack = stackKey(types[index], combo, 0);
469
+ }
470
+ else if (config.stacked && !shares) {
471
+ stack = stackKey(types[index], combo, twoAxes ? axisIndexes[index] : undefined);
472
+ }
473
+ // An output series (a compared, windowed, ranked or shared value) writes
474
+ // its tooltip, data labels and statistic line by what it holds.
475
+ const write = annotations && !seriesShares && annotations.outputs[index]
476
+ ? outputWriter(annotations, index, extractedSeries.measure, context)
477
+ : null;
478
+ const stat = statLines ? measureMarkStat(extractedSeries.measure) : undefined;
479
+ const markLine = stat && statMarkLine(seriesShares ?? extractedSeries.values, stat, seriesShares ? shareWriter(context) : write ?? measureWriter(extractedSeries.measure, context));
480
+ const option = buildSeries(extractedSeries, seriesShares ? shareData(extractedSeries.values, seriesShares) : extractedSeries.values, {
481
+ type: types[index],
482
+ stack,
483
+ overlap: colorBy && index === 0,
484
+ combo,
485
+ tooltip: write ? { valueFormatter: write } : seriesTooltip(extractedSeries.measure, context),
486
+ axisIndex: twoAxes ? axisIndexes[index] : undefined,
487
+ // A colorBy chart's bars take the palette by category, as in
488
+ // PowerPoint, whatever color the measure names.
489
+ color: colorBy ? undefined : annotations?.colors?.[index] ?? seriesColor(extractedSeries),
490
+ labels: dataLabelOption(config.dataLabels, write
491
+ ? outputLabelFormatter(write)
492
+ : dataLabelFormatter(extractedSeries.measure, axisFormats[axisIndexes[index]] ?? null, !!seriesShares, context)),
493
+ });
494
+ const marked = annotations ? markSeries(option, annotations, index, extractedSeries.measure) : option;
495
+ return markLine ? { ...marked, markLine } : marked;
496
+ });
497
+ if (colorBy && drawsStatLines(config) && series.length) {
498
+ series[0] = colorByStatLine(series[0], extracted, context, annotations?.outputs[0]
499
+ ? outputWriter(annotations, 0, extracted.series[0].measure, context)
500
+ : undefined);
501
+ }
502
+ // Drawn after the measure series, so a tooltip reads a series by its index.
503
+ const segments = annotations ? partialSegments(series, annotations) : [];
504
+ const percentMin = shares ? percentAxisMin(shares) : undefined;
505
+ const categoryAxis = categoryAxisOption(config, data, extracted.categories, horizontal, context.locale);
506
+ // An axis of rate changes alone reads in percentage points, as its values do.
507
+ const axisLabels = [0, 1].map((axisIndex) => (annotations && !shares
508
+ ? pointsAxisLabel(annotations, extracted, axisIndexes, axisIndex, context)
509
+ : null) ?? valueAxisLabel(axisFormats[axisIndex] ?? null, context));
510
+ const valueAxis = twoAxes
511
+ ? twoValueAxesOption(config, axisLabels, context, percentMin, references, rankAxes)
512
+ : valueAxisOption(config.valueAxis, horizontal, percentMin === undefined
513
+ ? axisLabels[0]
514
+ : percentAxisLabel(context), { percentMin, reach: referenceReach(references, 0), rank: rankAxes[0] });
168
515
  const legendPosition = resolveLegendPosition(config, series.length, colorBy);
516
+ const valueTitles = [config.valueAxis, twoAxes ? config.secondaryAxis : undefined];
517
+ const granularity = bucketGranularity(data);
169
518
  return {
170
- grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal)),
171
- legend: legendOption(legendPosition),
519
+ grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal), valueTitleSide(valueTitles, horizontal)),
520
+ legend: referenceLegend(legendOption(legendPosition), series, references),
172
521
  // colorBy charts overlap N mostly-null series, so an axis tooltip would list
173
- // every category; an item tooltip shows just the hovered bar.
174
- tooltip: { trigger: colorBy ? 'item' : 'axis' },
522
+ // every category; an item tooltip shows just the hovered bar. A 100%
523
+ // stacked chart's tooltip gives each share and the value it came from. A
524
+ // chart with the server's annotations names what each value covers.
525
+ tooltip: shares
526
+ ? {
527
+ trigger: 'axis',
528
+ formatter: (params) => percentTooltip(params, extracted, shares, granularity, chartDateLabel(config), context),
529
+ }
530
+ : annotatedChartTooltip(annotations && !colorBy ? {
531
+ extracted,
532
+ annotations,
533
+ owners: segments.map((segment) => segment.owner),
534
+ granularity,
535
+ dateLabel: chartDateLabel(config),
536
+ context,
537
+ } : null) ?? { trigger: colorBy ? 'item' : 'axis' },
175
538
  xAxis: horizontal ? valueAxis : categoryAxis,
176
539
  yAxis: horizontal ? categoryAxis : valueAxis,
177
- series,
540
+ series: [...series, ...segments.map((segment) => segment.series), ...referenceCarriers(references, extracted.categories)],
541
+ };
542
+ }
543
+ function chartAnnotations(config, data, extracted, colorBy) {
544
+ if (!data.comparison && !data.outputs && !data.windows && (data.partialPeriod ?? null) === null) {
545
+ return null;
546
+ }
547
+ const columns = extracted.series.map((series) => series.measure.column);
548
+ const outputs = columns.map((column) => data.outputs?.[column] ?? null);
549
+ const currents = columns.map((column, index) => (outputs[index] ? currentOutputAlias(data.outputs, column) : null));
550
+ const measures = chartMeasures(config, data);
551
+ // A prior series' current series, by index; -1 for any other.
552
+ const sources = currents.map((current, index) => (outputs[index]?.role === 'prior' ? columns.indexOf(current) : -1));
553
+ const partialIndex = (data.partialPeriod ?? null) === null ? -1 : extracted.categories.indexOf(String(data.partialPeriod));
554
+ const lanes = lanePriorValues(config, data, extracted, outputs);
555
+ return {
556
+ outputs,
557
+ windows: columns.map((column) => data.windows?.[column] ?? null),
558
+ measureSpecs: currents.map((current) => measures.find((measure) => measure.column === current)),
559
+ priors: lanes.map((lane, index) => (isDeltaRole(outputs[index]?.role) ? lane?.prior.values ?? null : null)),
560
+ lanePriors: lanes.map((lane) => (lane && !columns.includes(lane.alias) ? lane.prior : null)),
561
+ colors: colorBy ? null : annotatedColors(extracted, sources),
562
+ priorSeries: outputs.map((output) => output?.role === 'prior'),
563
+ comparison: data.comparison ?? null,
564
+ partialIndex: partialIndex < 0 ? null : partialIndex,
565
+ };
566
+ }
567
+ // A current, change or percent change series' lane prior, by category: its
568
+ // lane's prior column in the same rows (the same group's on a splitBy chart),
569
+ // and that column's alias.
570
+ function lanePriorValues(config, data, extracted, outputs) {
571
+ const { xColumn, groupColumn } = chartColumns(config, data);
572
+ const rawCategories = uniqueValues(data.rows, xColumn);
573
+ const groups = groupColumn ? uniqueValues(data.rows, groupColumn) : [];
574
+ return extracted.series.map((series, index) => {
575
+ const role = outputs[index]?.role;
576
+ const alias = role === 'current' || isDeltaRole(role)
577
+ ? laneOutputAlias(data.outputs, series.measure.column, 'prior')
578
+ : null;
579
+ const output = alias ? data.outputs?.[alias] : undefined;
580
+ if (!alias || !output) {
581
+ return null;
582
+ }
583
+ const match = groupColumn ? (row) => row[groupColumn] === groups[index] : undefined;
584
+ return {
585
+ alias,
586
+ prior: {
587
+ key: groupColumn ? `${alias}\u0000${index}` : alias,
588
+ output,
589
+ values: categoryValues(data.rows, xColumn, rawCategories, alias, match),
590
+ },
591
+ };
592
+ });
593
+ }
594
+ function isDeltaRole(role) {
595
+ return role === 'change' || role === 'percent_change';
596
+ }
597
+ // Each series' color as the theme would hand it out: its measure's named
598
+ // color, else the next palette color among the series without one. A prior
599
+ // series that names no color takes its current series' color (sources) and
600
+ // no palette color of its own.
601
+ function annotatedColors(extracted, sources) {
602
+ let slot = 0;
603
+ const own = extracted.series.map((series, index) => {
604
+ const named = seriesColor(series);
605
+ if (named || sources[index] >= 0) {
606
+ return named ?? null;
607
+ }
608
+ return REPORT_CHART_COLORS_CSS[slot++ % REPORT_CHART_COLORS_CSS.length];
609
+ });
610
+ return own.map((color, index) => color ?? own[sources[index]]);
611
+ }
612
+ // A series' marks: a prior drawn in its current series' color family, dashed,
613
+ // and the period not over yet hatched (a bar) or ringed (a point).
614
+ function markSeries(option, annotations, index, measure) {
615
+ const prior = annotations.priorSeries[index] ? priorStyle(option, measure, annotations.colors?.[index]) : option;
616
+ return annotations.partialIndex === null ? prior : markPartialPoint(prior, annotations.partialIndex);
617
+ }
618
+ // A prior's bars are faded with a dashed edge; its line is dashed unless its
619
+ // measure names a line style.
620
+ function priorStyle(option, measure, color) {
621
+ const drawn = option;
622
+ if (drawn.type === 'bar') {
623
+ return {
624
+ ...option,
625
+ itemStyle: {
626
+ ...drawn.itemStyle,
627
+ opacity: PRIOR_BAR_OPACITY,
628
+ borderWidth: 1,
629
+ borderType: 'dashed',
630
+ ...(color ? { borderColor: color } : {}),
631
+ },
632
+ };
633
+ }
634
+ return { ...option, lineStyle: { ...drawn.lineStyle, type: measureLineStyle(measure) ?? PRIOR_LINE_STYLE } };
635
+ }
636
+ // The point of the period not over yet, when it has a value.
637
+ function markPartialPoint(option, partialIndex) {
638
+ const drawn = option;
639
+ const data = [...(drawn.data ?? [])];
640
+ const item = data[partialIndex];
641
+ if (item === undefined || pointValue(item) === null) {
642
+ return option;
643
+ }
644
+ const mark = drawn.type === 'bar' ? { itemStyle: { decal: PARTIAL_BAR_DECAL } } : PARTIAL_POINT_MARK;
645
+ data[partialIndex] = (typeof item === 'object' ? { ...item, ...mark } : { value: item, ...mark });
646
+ return { ...option, data };
647
+ }
648
+ // A line or area series whose last period is not over yet draws its last
649
+ // segment dashed: the series stops one point short, and a segment series
650
+ // carries its last two points, dashed, in its color and under its name, so
651
+ // the one legend entry toggles both. A stacked series keeps its line whole (a
652
+ // segment would stack on top of it), and a gap stays a gap. Replaces each
653
+ // such series in `series` and returns the segments.
654
+ function partialSegments(series, annotations) {
655
+ const last = annotations.partialIndex;
656
+ const segments = [];
657
+ series.forEach((option, owner) => {
658
+ const drawn = option;
659
+ const data = drawn.data ?? [];
660
+ const color = annotations.colors?.[owner];
661
+ if (last === null || last < 1 || last !== data.length - 1 || drawn.type !== 'line' || drawn.stack || !color
662
+ || pointValue(data[last - 1]) === null || pointValue(data[last]) === null) {
663
+ return;
664
+ }
665
+ series[owner] = { ...option, data: [...data.slice(0, last), null] };
666
+ segments.push({ owner, series: segmentSeries(option, color, last) });
667
+ });
668
+ return segments;
669
+ }
670
+ // The dashed segment from the point before the last to the last one, which
671
+ // keeps its marks and its data label. The point before it is drawn, and
672
+ // labeled, by the series itself.
673
+ function segmentSeries(option, color, last) {
674
+ const drawn = option;
675
+ const data = drawn.data ?? [];
676
+ return {
677
+ ...option,
678
+ markLine: undefined,
679
+ lineStyle: { ...drawn.lineStyle, color, type: PARTIAL_LINE_STYLE },
680
+ data: data.map((item, index) => {
681
+ if (index === last) {
682
+ return item;
683
+ }
684
+ return index === last - 1 ? { value: pointValue(item), symbol: 'none', label: { show: false } } : null;
685
+ }),
686
+ };
687
+ }
688
+ // A point's plotted value, whether it is a bare number or an object.
689
+ function pointValue(item) {
690
+ if (item === null || item === undefined) {
691
+ return null;
692
+ }
693
+ return typeof item === 'number' ? item : item.value;
694
+ }
695
+ // How an output series writes a value: formatOutputValue's rules (a signed
696
+ // change, points, '—' with the no-baseline title, ranks and shares) with its
697
+ // measure's format and the comparison's floor. Given the point's index (a
698
+ // tooltip, a data label), a change reads its prior there, which tells a
699
+ // missing baseline from a zero one. The title says why a value reads '—' or
700
+ // 'n/a'.
701
+ function outputValue(annotations, index, measure, context) {
702
+ const output = annotations.outputs[index];
703
+ const priors = annotations.priors[index];
704
+ return (value, dataIndex) => formatOutputValue(Array.isArray(value) ? value[0] : value, output, measure, context, {
705
+ measureSpec: annotations.measureSpecs[index],
706
+ floor: annotations.comparison?.floor ?? null,
707
+ ...(priors && dataIndex !== undefined ? { prior: priors[dataIndex] ?? null } : {}),
708
+ });
709
+ }
710
+ // An output value's text alone, for a series' own tooltip and its data labels.
711
+ function outputWriter(annotations, index, measure, context) {
712
+ const write = outputValue(annotations, index, measure, context);
713
+ return (value, dataIndex) => write(value, dataIndex).text;
714
+ }
715
+ function outputLabelFormatter(write) {
716
+ return (params) => write(dataLabelValue(params), params.dataIndex);
717
+ }
718
+ // The chart's series as its value axes read them: an output series whose
719
+ // slot names no format takes its output's (outputAxisMeasure).
720
+ function annotatedAxisSeries(extracted, annotations) {
721
+ return {
722
+ ...extracted,
723
+ series: extracted.series.map((series, index) => ({
724
+ ...series,
725
+ measure: outputAxisMeasure(series.measure, annotations.outputs[index], annotations.measureSpecs[index]),
726
+ })),
727
+ };
728
+ }
729
+ // The format an output's axis reads when its slot names none: a rank's whole
730
+ // numbers, a 0-1 fraction's percent, and a compared or windowed value its
731
+ // measure's format. The slot's own precision and units still apply.
732
+ function outputAxisMeasure(measure, output, measureSpec) {
733
+ if (!output || namesValueFormat(measure)) {
734
+ return measure;
735
+ }
736
+ let base = measureSpec && hasNumberFormat(measureSpec) ? formatKeys(measureSpec) : null;
737
+ if (output.kind === 'rank') {
738
+ base = RANK_AXIS_FORMAT;
739
+ }
740
+ else if (isFractionOutput(output)) {
741
+ base = FRACTION_AXIS_FORMAT;
742
+ }
743
+ return base
744
+ ? { ...measure, ...base, ...formatKeys({ precision: measure.precision, units: measure.units }) }
745
+ : measure;
746
+ }
747
+ function namesValueFormat(spec) {
748
+ return Object.values(ReportValueFormat).some((format) => format === spec.format);
749
+ }
750
+ // A spec's number-format keys that are set.
751
+ function formatKeys(spec) {
752
+ return {
753
+ ...((spec.format ?? null) !== null ? { format: spec.format } : {}),
754
+ ...((spec.precision ?? null) !== null ? { precision: spec.precision } : {}),
755
+ ...((spec.units ?? null) !== null ? { units: spec.units } : {}),
756
+ };
757
+ }
758
+ // Each value axis's context: one that plots only 0-1 fractions reads them as
759
+ // ratios, whatever the report's percentFormat says of its stored values.
760
+ function annotatedAxisContexts(annotations, axisIndexes, context) {
761
+ return [0, 1].map((axisIndex) => (everyOnAxis(annotations.outputs, axisIndexes, axisIndex, isFractionOutput)
762
+ ? { ...context, ratioPercent: true }
763
+ : context));
764
+ }
765
+ // Which value axes, by index, plot nothing but ranks.
766
+ function rankAxisFlags(outputs, axisIndexes) {
767
+ return [0, 1].map((axisIndex) => everyOnAxis(outputs, axisIndexes, axisIndex, isRankPosition));
768
+ }
769
+ // How a chart that plots a prior series colors each series, for the
770
+ // PowerPoint export: every series' color as bare hex, a prior taking its
771
+ // current series' color and no palette color of its own (annotatedColors),
772
+ // and which series are priors, which a line draws dashed. null when the chart
773
+ // plots no prior series, and on a colorBy chart; its series keep seriesHex.
774
+ export function priorSeriesStyles(config, data, extracted) {
775
+ const annotations = chartAnnotations(config, data, extracted, isColorBy(config));
776
+ if (!annotations?.colors || !annotations.priorSeries.some((prior) => prior)) {
777
+ return null;
778
+ }
779
+ return {
780
+ colors: annotations.colors.map((color) => color.replace('#', '')),
781
+ priors: annotations.priorSeries,
782
+ };
783
+ }
784
+ // Which value axes, by index, plot nothing but ranks, which the chart draws
785
+ // inverted with rank 1 at the top. Shared with the PowerPoint export.
786
+ export function rankValueAxes(extracted, data, config) {
787
+ return rankAxisFlags(extracted.series.map((series) => data.outputs?.[series.measure.column] ?? null), seriesAxisIndexes(extracted, config));
788
+ }
789
+ // Whether an axis has series and every one of them passes the test.
790
+ function everyOnAxis(outputs, axisIndexes, axisIndex, test) {
791
+ const onAxis = outputs.filter((_, index) => axisIndexes[index] === axisIndex);
792
+ return onAxis.length > 0 && onAxis.every((output) => !!output && test(output));
793
+ }
794
+ // A share and a percent change are 0-1 fractions, whatever percentFormat says.
795
+ function isFractionOutput(output) {
796
+ return output.kind === 'share' || output.role === 'percent_change';
797
+ }
798
+ // A value axis's tick labels when every series on it is a change of a rate
799
+ // (a share's, or a percent-format value's): signed percentage points, as the
800
+ // series' tooltips and data labels write them ('+5.0 pp'). null for any other
801
+ // axis.
802
+ function pointsAxisLabel(annotations, extracted, axisIndexes, axisIndex, context) {
803
+ const onAxis = extracted.series
804
+ .map((_, index) => index)
805
+ .filter((index) => axisIndexes[index] === axisIndex);
806
+ const points = onAxis.length > 0 && onAxis.every((index) => isPointsChange(annotations.outputs[index], outputAxisMeasure(extracted.series[index].measure, annotations.outputs[index], annotations.measureSpecs[index])));
807
+ if (!points) {
808
+ return null;
809
+ }
810
+ const write = outputWriter(annotations, onAxis[0], extracted.series[onAxis[0]].measure, context);
811
+ return { formatter: (value) => write(value) };
812
+ }
813
+ // A change of a rate, which prints in percentage points: a share's change, or
814
+ // the change of a value whose format (its slot's, else its measure's) is a
815
+ // percent.
816
+ function isPointsChange(output, axisMeasure) {
817
+ return !!output && output.role === 'change' && output.kind !== 'rank'
818
+ && (output.kind === 'share' || axisMeasure.format === ReportValueFormat.Percent);
819
+ }
820
+ // A rank, current or prior; a rank change is a difference, not a position.
821
+ function isRankPosition(output) {
822
+ return output.kind === 'rank' && output.role !== 'change';
823
+ }
824
+ function annotatedChartTooltip(source) {
825
+ return source
826
+ ? {
827
+ trigger: 'axis',
828
+ formatter: (params) => annotatedTooltip(params, source),
829
+ }
830
+ : null;
831
+ }
832
+ // The period, with 'to date' when it is not over yet, then each series shown
833
+ // (a legend can hide some): its value written by what it is, and what it
834
+ // covers. A partial segment speaks for its series. Names and values come from
835
+ // the data and the config, and ECharts sets the tooltip as HTML, so both are
836
+ // escaped.
837
+ function annotatedTooltip(params, source) {
838
+ const items = Array.isArray(params) ? params : [params];
839
+ const dataIndex = items[0]?.dataIndex ?? 0;
840
+ const count = source.extracted.series.length;
841
+ const markers = new Map();
842
+ for (const item of items) {
843
+ const seriesIndex = item.seriesIndex ?? -1;
844
+ const owner = seriesIndex < count ? seriesIndex : source.owners[seriesIndex - count];
845
+ if (owner !== undefined && owner >= 0 && !markers.has(owner)) {
846
+ markers.set(owner, typeof item.marker === 'string' ? item.marker : '');
847
+ }
848
+ }
849
+ const namedPriors = new Set();
850
+ const lines = [...markers.entries()]
851
+ .sort(([first], [second]) => first - second)
852
+ .map(([index, marker]) => annotatedTooltipLine(source, index, dataIndex, marker, namedPriors));
853
+ return [annotatedTooltipHeading(source, dataIndex), ...lines].join('<br/>');
854
+ }
855
+ function annotatedTooltipHeading(source, dataIndex) {
856
+ const category = source.extracted.categories[dataIndex] ?? '';
857
+ const period = source.granularity
858
+ ? formatPeriodLabel(category, source.granularity, true, source.context.locale, source.dateLabel)
859
+ : category;
860
+ return escapeHtml(dataIndex === source.annotations.partialIndex ? `${period} (${PARTIAL_PERIOD_TEXT})` : period);
861
+ }
862
+ // '● Revenue (vs previous month): $813 · Aug 1 – 15, 2026', and why a value
863
+ // reads '—' or 'n/a' when it does ('No baseline: no data before Jun 10, 2026').
864
+ // A value compared with a prior the chart does not plot names that prior
865
+ // once, on the first line shown that is compared with it: 'Rate % change (vs
866
+ // previous month): -10% · vs 50% (Sep 1 – 2, 2026)'. namedPriors holds the
867
+ // priors already named.
868
+ function annotatedTooltipLine(source, index, dataIndex, marker, namedPriors) {
869
+ const series = source.extracted.series[index];
870
+ const value = series.values[dataIndex] ?? null;
871
+ const formatted = source.annotations.outputs[index]
872
+ ? outputValue(source.annotations, index, series.measure, source.context)(value, dataIndex)
873
+ : { text: seriesTooltip(series.measure, source.context).valueFormatter(value), title: null };
874
+ const lanePrior = source.annotations.lanePriors[index];
875
+ const compared = lanePrior && !namedPriors.has(lanePrior.key)
876
+ ? comparedPriorDetail(source, index, lanePrior, dataIndex)
877
+ : '';
878
+ if (lanePrior) {
879
+ namedPriors.add(lanePrior.key);
880
+ }
881
+ const parts = [formatted.text, seriesDetail(source, index, dataIndex), compared, formatted.title ?? ''];
882
+ return `${marker} ${escapeHtml(series.name)}: ${escapeHtml(parts.filter((part) => !!part).join(TOOLTIP_DETAIL_SEPARATOR))}`;
883
+ }
884
+ // The prior a value is compared with, when the chart does not plot it: its
885
+ // value in its measure's format, and its days ('vs 50% (Sep 1 – 2, 2026)').
886
+ // The measure's format is the current series' when the chart plots it, else
887
+ // a change slot's own explicit format (a change is in its measure's units).
888
+ function comparedPriorDetail(source, index, lanePrior, dataIndex) {
889
+ const annotations = source.annotations;
890
+ const measure = source.extracted.series[index].measure;
891
+ const measureSpec = annotations.measureSpecs[index]
892
+ ?? (annotations.outputs[index]?.role !== 'percent_change' && namesValueFormat(measure) ? measure : null);
893
+ const text = formatOutputValue(lanePrior.values[dataIndex] ?? null, lanePrior.output, null, source.context, {
894
+ measureSpec,
895
+ floor: annotations.comparison?.floor ?? null,
896
+ }).text;
897
+ const window = priorDetail(source, lanePrior.output, dataIndex);
898
+ return window ? `${COMPARED_PRIOR_PREFIX} ${text} (${window})` : `${COMPARED_PRIOR_PREFIX} ${text}`;
899
+ }
900
+ // What a series' value covers, when the server says: a prior's days, or a
901
+ // windowed value's window ('Rolling 3-month total'), whose days the note
902
+ // under the chart names.
903
+ function seriesDetail(source, index, dataIndex) {
904
+ const output = source.annotations.outputs[index];
905
+ const window = source.annotations.windows[index];
906
+ if (output?.role === 'prior') {
907
+ return priorDetail(source, output, dataIndex);
908
+ }
909
+ return window ? windowText({ ...window, start: null, end: null }, source.context.locale, source.granularity) : '';
910
+ }
911
+ // A prior value's days. A range comparison compares every point with the
912
+ // same window. A series comparison compares each period with the period its
913
+ // lane's offset back; an as_of comparison reads the value at the end of that
914
+ // period ('on Aug 31, 2026').
915
+ function priorDetail(source, output, dataIndex) {
916
+ const comparison = source.annotations.comparison;
917
+ const lane = (output.offset ?? 1) - 1;
918
+ const offset = comparison?.offsets?.[lane];
919
+ const locale = source.context.locale;
920
+ if (!comparison || !offset) {
921
+ return '';
922
+ }
923
+ if (comparison.mode === 'range' || !source.granularity) {
924
+ const prior = comparison.priors?.[lane];
925
+ return prior ? formatDayWindow(prior, comparison.timezone, locale) : '';
926
+ }
927
+ const partial = dataIndex === source.annotations.partialIndex && comparison.align === 'to_date';
928
+ const today = partial ? zoneToday(comparison.timezone) : null;
929
+ const window = priorPeriodWindow(source.extracted.categories[dataIndex] ?? '', source.granularity, offset, today);
930
+ if (!window) {
931
+ return '';
932
+ }
933
+ return comparison.mode === 'as_of'
934
+ ? `on ${formatDayRange(window.end, window.end, locale)}`
935
+ : formatDayWindow({ ...window, through: partial ? comparison.current?.through ?? null : null }, comparison.timezone, locale);
936
+ }
937
+ // The days one period of the axis is compared with: the period moved back by
938
+ // the lane's offset. A period not over yet, compared to date, runs only to
939
+ // today moved back (priorToDateEnd). null for a category that is not a day,
940
+ // or an offset without a unit (a custom range).
941
+ function priorPeriodWindow(category, granularity, offset, today) {
942
+ const start = parseISO(category);
943
+ const unit = offset.unit;
944
+ const count = offset.count;
945
+ if (!isValid(start) || !unit || !count) {
946
+ return null;
947
+ }
948
+ const back = (date) => addPeriods(date, unit, -count);
949
+ const fullEnd = addDays(back(addPeriods(start, granularity, 1)), -1);
950
+ const end = today ? earliestOf([fullEnd, priorToDateEnd(today, start, back, unit)]) : fullEnd;
951
+ return { start: calendarDay(back(start)), end: calendarDay(latestOf([end, back(start)])) };
952
+ }
953
+ // Today, kept inside the period, moved back by the offset; when today is the
954
+ // last day of its month, the last day of the month it lands in (the
955
+ // server's end-of-month rule: Sep 30 compares with Aug 31, not Aug 30).
956
+ function priorToDateEnd(today, periodStart, back, unit) {
957
+ const day = latestOf([startOfDay(today), periodStart]);
958
+ const moved = back(day);
959
+ return isLastDayOfMonth(day) && unit !== 'day' && unit !== 'week' ? endOfMonth(moved) : moved;
960
+ }
961
+ function addPeriods(date, unit, count) {
962
+ switch (unit) {
963
+ case 'day':
964
+ return addDays(date, count);
965
+ case 'week':
966
+ return addWeeks(date, count);
967
+ case 'quarter':
968
+ return addQuarters(date, count);
969
+ case 'year':
970
+ return addYears(date, count);
971
+ default:
972
+ return addMonths(date, count);
973
+ }
974
+ }
975
+ function calendarDay(date) {
976
+ return formatISO(date, { representation: 'date' });
977
+ }
978
+ // Today's calendar day in the report's zone, as local midnight. The server
979
+ // marks which period holds today (partialPeriod) but not the day itself; the
980
+ // prior of that period is clipped at the same day. An unknown zone reads the
981
+ // browser's own day.
982
+ function zoneToday(timezone) {
983
+ try {
984
+ const parts = dateFormat('en-US', { year: 'numeric', month: 'numeric', day: 'numeric' }, timezone)
985
+ .formatToParts(new Date());
986
+ const part = (type) => Number(parts.find((found) => found.type === type)?.value);
987
+ const today = new Date(part('year'), part('month') - 1, part('day'));
988
+ if (isValid(today)) {
989
+ return today;
990
+ }
991
+ }
992
+ catch {
993
+ // An unknown zone: the browser's day below.
994
+ }
995
+ return startOfDay(new Date());
996
+ }
997
+ // A colorBy chart's statistic line: one line over every bar, hung off the
998
+ // first series and drawn in the reference slate, as no one category's color
999
+ // speaks for the others.
1000
+ function colorByStatLine(first, extracted, context, write) {
1001
+ const measure = extracted.series[0]?.measure;
1002
+ const stat = measureMarkStat(measure);
1003
+ const markLine = stat && statMarkLine(colorByValues(extracted), stat, write ?? measureWriter(measure, context), `#${REPORT_REFERENCE_COLOR}`);
1004
+ return markLine ? { ...first, markLine } : first;
1005
+ }
1006
+ // A series' statistic line across the plot, labeled with the statistic and
1007
+ // its value ('Average: 1,234.5'), or undefined when no point has a value. It
1008
+ // takes the series' color unless it is given one.
1009
+ function statMarkLine(values, stat, write, color) {
1010
+ const value = seriesStat(values, stat);
1011
+ if (value === null) {
1012
+ return undefined;
1013
+ }
1014
+ const text = `${STAT_LABEL[stat]}: ${write(value)}`;
1015
+ return {
1016
+ silent: true,
1017
+ symbol: 'none',
1018
+ lineStyle: { type: 'dashed', width: 1, ...(color ? { color } : {}) },
1019
+ label: { formatter: () => text, position: 'insideEndTop', fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },
1020
+ data: [{ yAxis: value }],
178
1021
  };
179
1022
  }
1023
+ // A statistic's value in its measure's number format, in the report locale.
1024
+ function measureWriter(measure, context) {
1025
+ return (value) => formatNumber(value, measure, context);
1026
+ }
1027
+ // A 100% stacked series' statistic is a share, written as its tooltip writes
1028
+ // one.
1029
+ function shareWriter(context) {
1030
+ const ratioContext = { ...context, ratioPercent: true };
1031
+ return (value) => formatNumber(value, PERCENT_SHARE_FORMAT, ratioContext);
1032
+ }
1033
+ // The series that carry a chart's references, one per value axis that has
1034
+ // any: an empty line (every point null, so it draws nothing and stretches no
1035
+ // axis) whose markLine draws the reference lines and whose markArea fills the
1036
+ // bands. It is silent, left out of the tooltip and, by referenceLegend, out of
1037
+ // the legend. It has no name, so no measure series' legend entry (whatever its
1038
+ // name, '' included) toggles it.
1039
+ //
1040
+ // Labels are functions, as a string formatter is a template that would read
1041
+ // '{b}' or '{c}' in a label as a placeholder. ECharts draws a markArea under
1042
+ // the bars and a markLine over them, so a band's label rides an invisible
1043
+ // markLine on its upper edge, inside its top left corner, where the first bar
1044
+ // would otherwise cover it.
1045
+ function referenceCarriers(references, categories) {
1046
+ const color = `#${REPORT_REFERENCE_COLOR}`;
1047
+ return [0, 1].flatMap((axisIndex) => {
1048
+ const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);
1049
+ const lines = onAxis.filter((reference) => !reference.band);
1050
+ const bands = onAxis.filter((reference) => reference.band);
1051
+ if (!onAxis.length) {
1052
+ return [];
1053
+ }
1054
+ return [{
1055
+ type: 'line',
1056
+ data: categories.map(() => null),
1057
+ yAxisIndex: axisIndex,
1058
+ silent: true,
1059
+ tooltip: { show: false },
1060
+ markLine: {
1061
+ silent: true,
1062
+ symbol: 'none',
1063
+ lineStyle: { color, type: 'dashed', width: 1 },
1064
+ label: { position: 'insideEndTop', color, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },
1065
+ data: [
1066
+ ...lines.map((reference) => ({ yAxis: reference.low, label: { formatter: () => reference.label } })),
1067
+ ...bands.map((reference) => ({
1068
+ yAxis: reference.high,
1069
+ // Zero width, not zero opacity: a markLine's label takes the
1070
+ // line's opacity.
1071
+ lineStyle: { width: 0 },
1072
+ label: { position: 'insideStartBottom', formatter: () => reference.label },
1073
+ })),
1074
+ ],
1075
+ },
1076
+ ...(bands.length ? {
1077
+ markArea: {
1078
+ silent: true,
1079
+ itemStyle: { color: REFERENCE_BAND_FILL },
1080
+ data: bands.map((reference) => [{ yAxis: reference.low }, { yAxis: reference.high }]),
1081
+ },
1082
+ } : {}),
1083
+ }];
1084
+ });
1085
+ }
1086
+ // The largest magnitude a value axis's references reach, which its number
1087
+ // format counts toward its peak, as the axis stretches to them; 0 when it
1088
+ // has none.
1089
+ export function referencePeak(references, axisIndex) {
1090
+ const reach = referenceReach(references, axisIndex);
1091
+ return reach ? Math.max(Math.abs(reach.low), Math.abs(reach.high)) : 0;
1092
+ }
1093
+ // The legend of a chart with references names its measure series alone, so
1094
+ // a carrier never shows as a blank entry. Without references it is left as it
1095
+ // was.
1096
+ function referenceLegend(legend, series, references) {
1097
+ return references.length
1098
+ ? { ...legend, data: series.map((item) => String(item.name ?? '')) }
1099
+ : legend;
1100
+ }
1101
+ // The span of the references on one value axis, or undefined when it has
1102
+ // none.
1103
+ function referenceReach(references, axisIndex) {
1104
+ const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);
1105
+ return onAxis.length
1106
+ ? { low: Math.min(...onAxis.map((reference) => reference.low)), high: Math.max(...onAxis.map((reference) => reference.high)) }
1107
+ : undefined;
1108
+ }
1109
+ // ECharts leaves a markLine or markArea out of an axis's extent, so a
1110
+ // reference beyond the data would fall off the plot. An axis bound the config
1111
+ // does not pin reaches past the furthest reference, to a round number with
1112
+ // room for its label (beyondReference), when the data (and the zero a value
1113
+ // axis always shows) falls short of it, and is left to ECharts otherwise: a
1114
+ // callback returning undefined keeps the bound automatic. Past the data and
1115
+ // zero, a reference beyond the max is above zero and one beyond the min below
1116
+ // it.
1117
+ function reachMin(reach) {
1118
+ return reach
1119
+ ? (extent) => (reach.low < Math.min(extent.min, 0) ? -beyondReference(-reach.low) : undefined)
1120
+ : undefined;
1121
+ }
1122
+ function reachMax(reach) {
1123
+ return reach
1124
+ ? (extent) => (reach.high > Math.max(extent.max, 0) ? beyondReference(reach.high) : undefined)
1125
+ : undefined;
1126
+ }
1127
+ // The bound an axis takes past a reference of this (positive) magnitude: the
1128
+ // smallest round number at or above it plus REFERENCE_HEADROOM. The steps are
1129
+ // finer than ECharts' tick steps, so a reference just past the data does not
1130
+ // double the axis (110 gives 120, not 200). The tolerance keeps a float error
1131
+ // from skipping a round number the value already is.
1132
+ const NICE_STEPS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10];
1133
+ const NICE_TOLERANCE = 1e-9;
1134
+ function beyondReference(magnitude) {
1135
+ const target = magnitude * REFERENCE_HEADROOM;
1136
+ const power = Math.pow(10, Math.floor(Math.log10(target)));
1137
+ const step = NICE_STEPS.find((candidate) => candidate * power >= target * (1 - NICE_TOLERANCE)) ?? 10;
1138
+ // Rounded back to the power's own digits, so 1.2 x 0.1 reads 0.12, not
1139
+ // 0.12000000000000001.
1140
+ return Number((step * power).toPrecision(12));
1141
+ }
180
1142
  // The category axis of an axis chart or a waterfall: the categories in row
181
1143
  // order, labeled as periods when the rows were bucketed by time.
182
1144
  //
@@ -184,30 +1146,46 @@ function buildAxisOption(component, data, chartType) {
184
1146
  // axis is inverted to put the first row (the largest of a top-N, a waterfall's
185
1147
  // first step) at the top. The rotated title sits just beyond the longest label
186
1148
  // rather than at a fixed gap that would put it on top of the labels.
187
- function categoryAxisOption(config, data, categories, horizontal) {
1149
+ //
1150
+ // A bucketed axis also names its period in the axis tooltip's header: ECharts
1151
+ // heads it with the raw category ('2026-01-01') unless the axis pointer's label
1152
+ // has a formatter, so it reads 'January 2026' instead, always with its year.
1153
+ // The axis's dateLabel style writes both its tick labels and that header.
1154
+ function categoryAxisOption(config, data, categories, horizontal, locale) {
188
1155
  const granularity = bucketGranularity(data);
189
- const periodLabel = periodAxisLabel(granularity, categories);
1156
+ const dateLabel = chartDateLabel(config);
1157
+ const periodLabel = periodAxisLabel(granularity, categories, locale, dateLabel);
190
1158
  const axis = {
191
1159
  type: 'category',
192
1160
  data: categories,
193
1161
  inverse: horizontal,
194
1162
  name: config.xAxis?.label,
195
1163
  nameLocation: 'middle',
1164
+ ...(granularity ? {
1165
+ axisPointer: {
1166
+ label: {
1167
+ formatter: (params) => formatPeriodLabel(String(params.value), granularity, true, locale, dateLabel),
1168
+ },
1169
+ },
1170
+ } : {}),
196
1171
  };
197
1172
  if (!horizontal) {
1173
+ // The gap clears the year's second line when the labels print one.
1174
+ const secondLine = granularity && dateLabel === ReportChartDateLabel.Short && spansMultipleYears(categories);
198
1175
  return {
199
1176
  ...axis,
200
- nameGap: granularity && spansMultipleYears(categories) ? 40 : 28,
1177
+ nameGap: secondLine ? 40 : 28,
201
1178
  ...periodLabel,
202
1179
  };
203
1180
  }
204
- // A period label ('May', 'Q2') is always short, so only a plain category is
205
- // cut short. The labels are cut here rather than by ECharts' own truncation,
206
- // so the title's gap is measured on exactly the text the axis draws.
1181
+ // Period labels, short, long or numeric ('May', 'Q2', 'May 2026'), are
1182
+ // bounded in length and never cut; only a plain category is truncated. The labels are cut here rather than by ECharts' own
1183
+ // truncation, so the title's gap is measured on exactly the text the axis
1184
+ // draws.
207
1185
  const shown = granularity
208
1186
  ? null
209
1187
  : new Map(categories.map((category) => [category, truncateAxisLabel(category)]));
210
- const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity);
1188
+ const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity, locale, dateLabel);
211
1189
  return {
212
1190
  ...axis,
213
1191
  nameGap: widestAxisLabel(labels) + AXIS_LABEL_MARGIN + AXIS_NAME_CLEARANCE,
@@ -222,12 +1200,22 @@ function categoryTitleSide(config, horizontal) {
222
1200
  }
223
1201
  return horizontal ? 'left' : 'bottom';
224
1202
  }
1203
+ // The value axes' title side, or null when none of them has a title. A
1204
+ // vertical chart's titles sit above the plot, at the top of each axis line, so
1205
+ // room is made once for both; a horizontal chart's sits below.
1206
+ function valueTitleSide(axes, horizontal) {
1207
+ if (!axes.some((axis) => axis?.label)) {
1208
+ return null;
1209
+ }
1210
+ return horizontal ? 'bottom' : 'top';
1211
+ }
225
1212
  // The tick labels as the axis shows them: a bucket's primary period label
226
- // ('May', 'Q2'), otherwise the category itself. The year a multi-year axis
227
- // prints under a period is left out, as it is never the wider line.
228
- function displayedCategoryLabels(categories, granularity) {
1213
+ // ('May', 'Q2', 'May 2026'), otherwise the category itself. The year a
1214
+ // multi-year axis prints under a short period is left out, as it is never the
1215
+ // wider line.
1216
+ function displayedCategoryLabels(categories, granularity, locale, dateLabel) {
229
1217
  return granularity
230
- ? categories.map((category) => periodLabelParts(category, granularity)?.primary ?? category)
1218
+ ? categories.map((category) => periodLabelParts(category, granularity, locale, dateLabel)?.primary ?? category)
231
1219
  : categories;
232
1220
  }
233
1221
  // The pixel width of the widest label. A label that breaks over several lines
@@ -273,26 +1261,32 @@ function axisLabelWidth(line) {
273
1261
  axisLabelContext.font = AXIS_LABEL_FONT;
274
1262
  return axisLabelContext.measureText(line).width;
275
1263
  }
276
- function buildWaterfallOption(component, data) {
1264
+ function buildWaterfallOption(component, data, context) {
277
1265
  const config = component.config;
278
1266
  const waterfall = extractWaterfall(component, data);
279
1267
  const horizontal = config.orientation === 'horizontal';
280
- const categoryAxis = categoryAxisOption(config, data, waterfall.steps.map((step) => step.category), horizontal);
281
- const valueAxis = { type: 'value' };
1268
+ const categories = waterfall.steps.map((step) => step.category);
1269
+ const categoryAxis = categoryAxisOption(config, data, categories, horizontal, context.locale);
1270
+ // The one measure's format writes the axis and the tooltip. The axis has to
1271
+ // reach the furthest point the running total gets to, on either side of
1272
+ // zero, or the furthest reference.
1273
+ const spec = config.measures?.[0];
1274
+ const references = chartReferences(config, false);
1275
+ const valueAxis = valueAxisOption(config.valueAxis, horizontal, valueAxisLabel(resolveValueAxisFormat(spec && hasNumberFormat(spec) ? spec : null, () => Math.max(referencePeak(references, 0), ...waterfall.steps.map((step) => Math.abs(step.start + (step.change ?? 0)))), context), context), { reach: referenceReach(references, 0) });
282
1276
  // One visible series, so the legend is hidden unless the config pins it.
283
1277
  const legendPosition = resolveLegendPosition(config, 1);
284
1278
  const granularity = bucketGranularity(data);
285
1279
  return {
286
- grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal)),
1280
+ grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal), valueTitleSide([config.valueAxis], horizontal)),
287
1281
  legend: { ...legendOption(legendPosition), data: [waterfall.name] },
288
1282
  // Per bar: the invisible base is silent, so only a step answers the hover.
289
1283
  tooltip: {
290
1284
  trigger: 'item',
291
- formatter: (params) => waterfallTooltip(waterfall, (Array.isArray(params) ? params[0] : params).dataIndex, granularity),
1285
+ formatter: (params) => waterfallTooltip(waterfall, (Array.isArray(params) ? params[0] : params).dataIndex, granularity, chartDateLabel(config), spec, context),
292
1286
  },
293
1287
  xAxis: horizontal ? valueAxis : categoryAxis,
294
1288
  yAxis: horizontal ? categoryAxis : valueAxis,
295
- series: waterfallSeries(waterfall),
1289
+ series: [...waterfallSeries(waterfall), ...referenceCarriers(references, categories)],
296
1290
  };
297
1291
  }
298
1292
  // An invisible base series lifts each visible bar to where its step starts.
@@ -329,17 +1323,22 @@ function waterfallSeries(waterfall) {
329
1323
  // A step's tooltip: its period, how far it moved the running total and where
330
1324
  // that left it. The closing Total shows the total alone. The category and the
331
1325
  // measure name come from the data and the config, and ECharts sets the tooltip
332
- // as HTML, so both are escaped.
333
- function waterfallTooltip(waterfall, index, granularity) {
1326
+ // as HTML, so both are escaped. Periods and amounts are written in the report's
1327
+ // locale, amounts in the measure's number format (a plain number without one);
1328
+ // the words ('Running total') stay English.
1329
+ function waterfallTooltip(waterfall, index, granularity, dateLabel, spec, context) {
334
1330
  const step = waterfall.steps[index];
335
- const category = escapeHtml(granularity ? formatPeriodLabel(step.category, granularity, true) : step.category);
1331
+ const category = escapeHtml(granularity
1332
+ ? formatPeriodLabel(step.category, granularity, true, context.locale, dateLabel)
1333
+ : step.category);
336
1334
  const name = escapeHtml(waterfall.name);
1335
+ const amount = (value) => formatNumber(value, spec ?? {}, context);
337
1336
  if (step.kind === 'total') {
338
- return `${category}<br/>${name}: ${formatMeasureValue(step.change)}`;
1337
+ return `${category}<br/>${name}: ${amount(step.change)}`;
339
1338
  }
340
1339
  const sign = (step.change ?? 0) > 0 ? '+' : '';
341
- return `${category}<br/>${name}: ${sign}${formatMeasureValue(step.change)}`
342
- + `<br/>Running total: ${formatMeasureValue(step.start + (step.change ?? 0))}`;
1340
+ return `${category}<br/>${name}: ${sign}${amount(step.change)}`
1341
+ + `<br/>Running total: ${amount(step.start + (step.change ?? 0))}`;
343
1342
  }
344
1343
  // Default legend placement when the config doesn't pin one: pie charts read
345
1344
  // best with the slice key beside them (right); axis charts only need a legend
@@ -372,18 +1371,10 @@ function legendOption(position) {
372
1371
  }
373
1372
  }
374
1373
  // The plot's grid: room on the legend's side so it never overlaps the
375
- // bars/lines, plus room for the category axis's title on its side, which
376
- // containLabel does not reserve (it covers the tick labels only).
377
- function axisGrid(position, titleSide) {
378
- const grid = legendGrid(position);
379
- switch (titleSide) {
380
- case 'bottom':
381
- return { ...grid, bottom: grid.bottom + AXIS_NAME_ROOM };
382
- case 'left':
383
- return { ...grid, left: grid.left + AXIS_NAME_ROOM };
384
- default:
385
- return grid;
386
- }
1374
+ // bars/lines, plus room for the category and value axes' titles on their
1375
+ // sides, which containLabel does not reserve (it covers the tick labels only).
1376
+ function axisGrid(position, categoryTitle, valueTitle) {
1377
+ return [categoryTitle, valueTitle].reduce((grid, side) => (side ? { ...grid, [side]: grid[side] + AXIS_NAME_ROOM } : grid), legendGrid(position));
387
1378
  }
388
1379
  // Plot-edge room on whichever side the legend occupies; containLabel keeps the
389
1380
  // tick labels inside what is left.
@@ -402,32 +1393,317 @@ function legendGrid(position) {
402
1393
  return { ...base, top: 32 };
403
1394
  }
404
1395
  }
405
- function buildSeries(name, values, type, stack, overlap, combo) {
406
- if (type === 'bar') {
1396
+ // The stack a stacked series joins. On a two-axis chart (axisIndex set) each
1397
+ // type stacks per axis; otherwise a combo stacks per type and a single-type
1398
+ // chart stacks everything together.
1399
+ function stackKey(type, combo, axisIndex) {
1400
+ if (axisIndex !== undefined) {
1401
+ return `total-${type}-${axisIndex}`;
1402
+ }
1403
+ return combo ? `total-${type}` : 'total';
1404
+ }
1405
+ // One series of an axis chart. A measure's display keys only add what they
1406
+ // change, so a series that sets none is drawn by the theme as before: its own
1407
+ // color (the bar, the line, the area under it and its legend key all follow
1408
+ // itemStyle), its line style and its markers, shown on every point unless
1409
+ // markers is false. Data labels come last, on the series or on its latest
1410
+ // point.
1411
+ function buildSeries(series, values, layout) {
1412
+ // On a two-axis chart every series names its value axis.
1413
+ const axis = layout.axisIndex === undefined ? {} : { yAxisIndex: layout.axisIndex };
1414
+ const color = layout.color;
1415
+ const itemStyle = color ? { itemStyle: { color } } : {};
1416
+ if (layout.type === 'bar') {
1417
+ // 'outside' follows each bar's sign: past a positive bar's end and below
1418
+ // (or left of) a negative one's, where 'top' would sit at the zero line.
1419
+ const { series: labels, data } = placeDataLabels(layout.labels, layout.stack ? 'inside' : 'outside', values);
407
1420
  return {
408
- name,
1421
+ name: series.name,
409
1422
  type: 'bar',
410
- data: values,
411
- stack,
1423
+ data,
1424
+ stack: layout.stack,
1425
+ tooltip: layout.tooltip,
1426
+ ...axis,
1427
+ ...itemStyle,
412
1428
  barMaxWidth: 48,
413
1429
  // colorBy: overlap the per-category series so each bar renders full-width.
414
- ...(overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),
1430
+ ...(layout.overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),
1431
+ ...labels,
415
1432
  };
416
1433
  }
1434
+ const lineType = measureLineStyle(series.measure);
1435
+ const lineStyle = color || lineType
1436
+ ? { lineStyle: { ...(color ? { color } : {}), ...(lineType ? { type: lineType } : {}) } }
1437
+ : {};
1438
+ const { series: labels, data } = placeDataLabels(layout.labels, 'top', values);
417
1439
  return {
418
- name,
1440
+ name: series.name,
419
1441
  type: 'line',
420
- data: values,
421
- stack,
1442
+ data,
1443
+ stack: layout.stack,
1444
+ tooltip: layout.tooltip,
1445
+ ...axis,
1446
+ ...itemStyle,
1447
+ ...lineStyle,
1448
+ ...(series.measure.markers === false ? { showSymbol: false } : {}),
422
1449
  smooth: true,
423
1450
  symbolSize: 6,
424
- areaStyle: type === 'area' ? { opacity: 0.25 } : undefined,
1451
+ areaStyle: layout.type === 'area' ? { opacity: 0.25 } : undefined,
425
1452
  // In a combo the line is drawn over the bars whatever order the measures
426
1453
  // come in; at the same z a later bar series would paint across it.
427
- ...(combo ? { z: 3 } : {}),
1454
+ ...(layout.combo ? { z: 3 } : {}),
1455
+ ...labels,
1456
+ };
1457
+ }
1458
+ // A 100% stacked series' points: each share, plotted and stacked, with the
1459
+ // value it came from.
1460
+ function shareData(values, shares) {
1461
+ return values.map((raw, index) => ({ value: shares[index] ?? null, raw }));
1462
+ }
1463
+ // What a series prints beside its points (A2 data labels): every point
1464
+ // ('all'), every point whose label fits without overlapping another ('auto',
1465
+ // LabelLayout's hideOverlap), or only its latest point ('last'). none, an
1466
+ // absent mode or one the viewer does not know prints nothing, and the series
1467
+ // is left as it was. A colorBy chart's series each hold one bar, so 'last'
1468
+ // labels every bar there, as 'all' does.
1469
+ //
1470
+ // Where the label sits depends on what the series draws, so buildSeries
1471
+ // places it (placeDataLabels).
1472
+ export function dataLabelOption(mode, formatter) {
1473
+ const text = { show: true, fontSize: REPORT_DATA_LABEL_FONT_SIZE, formatter };
1474
+ switch (mode) {
1475
+ case ReportChartDataLabels.All:
1476
+ return { text, hideOverlap: false, lastOnly: false };
1477
+ case ReportChartDataLabels.Auto:
1478
+ return { text, hideOverlap: true, lastOnly: false };
1479
+ case ReportChartDataLabels.Last:
1480
+ return { text, hideOverlap: false, lastOnly: true };
1481
+ default:
1482
+ return null;
1483
+ }
1484
+ }
1485
+ // A series' data labels at `position`: on the series ('all', and with the
1486
+ // overlap hiding 'auto'), or on its latest non-empty point alone ('last').
1487
+ // No labels leave the series and its points as they were.
1488
+ function placeDataLabels(labels, position, values) {
1489
+ if (!labels) {
1490
+ return { series: {}, data: values };
1491
+ }
1492
+ const label = { ...labels.text, position };
1493
+ if (labels.lastOnly) {
1494
+ return { series: {}, data: labelLastPoint(values, label) };
1495
+ }
1496
+ return {
1497
+ series: { label, ...(labels.hideOverlap ? { labelLayout: { hideOverlap: true } } : {}) },
1498
+ data: values,
1499
+ };
1500
+ }
1501
+ // A series' points with its latest non-empty point carrying the label. A
1502
+ // series with no value anywhere is left as it was.
1503
+ function labelLastPoint(values, label) {
1504
+ const last = values.reduce((found, item, index) => (pointValue(item) === null ? found : index), -1);
1505
+ return values.map((item, index) => {
1506
+ if (index !== last) {
1507
+ return item;
1508
+ }
1509
+ return isShareDataItem(item) ? { ...item, label } : { value: item, label };
1510
+ });
1511
+ }
1512
+ function isShareDataItem(item) {
1513
+ return item !== null && typeof item === 'object';
1514
+ }
1515
+ // How a series' data labels write a value. A 100% stacked series prints its
1516
+ // share as a whole percentage, as the share axis's ticks do. A series on an
1517
+ // axis with a number format prints its value in its measure's format, at the
1518
+ // units and decimals the axis decided, so a label reads like the ticks beside
1519
+ // it. Any other prints the plain locale-grouped number its tooltip shows. A
1520
+ // share point's raw value is what a label reads when it carries one.
1521
+ function dataLabelFormatter(measure, axisFormat, share, context) {
1522
+ if (share) {
1523
+ const percent = wholePercentFormatter(context);
1524
+ return (params) => percent(params.value);
1525
+ }
1526
+ if (axisFormat) {
1527
+ const options = { units: axisFormat.chart.units, decimals: axisFormat.chart.decimals };
1528
+ return (params) => formatNumber(dataLabelValue(params), measure, context, options);
1529
+ }
1530
+ return (params) => formatPlainNumber(dataLabelValue(params), context.locale);
1531
+ }
1532
+ // The value a data label writes: the raw value its point carries, else the
1533
+ // plotted one.
1534
+ function dataLabelValue(params) {
1535
+ const data = params.data;
1536
+ const raw = data !== null && typeof data === 'object' ? data.raw : undefined;
1537
+ return raw ?? params.value;
1538
+ }
1539
+ // A 100% stacked chart's tooltip: the category, then each series on its own
1540
+ // line, a share as its percentage to one decimal followed by the value it came
1541
+ // from in its measure's format ('25.0% (1)'), and any other series by its own
1542
+ // value. The category and the series names come from the data and the config,
1543
+ // and ECharts sets the tooltip as HTML, so both are escaped.
1544
+ function percentTooltip(params, extracted, shares, granularity, dateLabel, context) {
1545
+ const items = Array.isArray(params) ? params : [params];
1546
+ const dataIndex = items[0]?.dataIndex ?? 0;
1547
+ const category = extracted.categories[dataIndex] ?? '';
1548
+ const heading = escapeHtml(granularity
1549
+ ? formatPeriodLabel(category, granularity, true, context.locale, dateLabel)
1550
+ : category);
1551
+ const ratioContext = { ...context, ratioPercent: true };
1552
+ const lines = items.map((item) => {
1553
+ const series = extracted.series[item.seriesIndex ?? -1];
1554
+ const marker = typeof item.marker === 'string' ? item.marker : '';
1555
+ const label = `${marker} ${escapeHtml(item.seriesName ?? series?.name ?? '')}`;
1556
+ const value = seriesTooltip(series?.measure, context).valueFormatter(series?.values[item.dataIndex] ?? null);
1557
+ const share = shares.get(item.seriesIndex ?? -1)?.[item.dataIndex] ?? null;
1558
+ return share === null
1559
+ ? `${label}: ${value}`
1560
+ : `${label}: ${formatNumber(share, PERCENT_SHARE_FORMAT, ratioContext)} (${value})`;
1561
+ });
1562
+ return [heading, ...lines].join('<br/>');
1563
+ }
1564
+ // A value axis: its title and range from the config, its tick labels from
1565
+ // valueAxisLabel. A vertical chart's title sits above the axis line, reading
1566
+ // away from the plot's edge; a horizontal chart's is centered below the ticks.
1567
+ // A bound or interval that is not a usable number is left to ECharts. A 100%
1568
+ // stacked chart's share axis (extras.percentMin) has its own fixed range.
1569
+ function valueAxisOption(axis, horizontal, axisLabel, extras = {}) {
1570
+ const range = extras.percentMin === undefined
1571
+ ? valueAxisRange(axis)
1572
+ : { min: extras.percentMin, max: PERCENT_AXIS_MAX, interval: PERCENT_AXIS_INTERVAL };
1573
+ return {
1574
+ type: 'value',
1575
+ name: axis?.label || undefined,
1576
+ nameLocation: horizontal ? 'middle' : 'end',
1577
+ nameGap: horizontal ? 28 : 10,
1578
+ nameTextStyle: horizontal ? undefined : { align: extras.index === 1 ? 'right' : 'left' },
1579
+ // A pinned bound wins; one left open reaches the references (reachMin),
1580
+ // or on a rank axis starts at rank 1.
1581
+ min: range.min ?? (extras.rank ? RANK_AXIS_MIN : reachMin(extras.reach)),
1582
+ max: range.max ?? reachMax(extras.reach),
1583
+ interval: range.interval,
1584
+ axisLabel,
1585
+ ...(extras.rank ? { inverse: true, minInterval: 1 } : {}),
1586
+ };
1587
+ }
1588
+ // The part of a value axis's range the config pins. A bound that is not a
1589
+ // finite number, or an interval that is not a positive one, is left out, and
1590
+ // the chart picks it from the data. Shared with the PowerPoint export so both
1591
+ // media draw the same range.
1592
+ export function valueAxisRange(axis) {
1593
+ const interval = axisNumber(axis?.interval);
1594
+ return {
1595
+ min: axisNumber(axis?.min),
1596
+ max: axisNumber(axis?.max),
1597
+ interval: interval !== undefined && interval > 0 ? interval : undefined,
1598
+ };
1599
+ }
1600
+ // A two-axis chart's value axes: the primary on the left, the second on the
1601
+ // right without gridlines of its own. Each axis's ticks take the format of the
1602
+ // measures plotted against it (axisLabels). Without a range on either axis the
1603
+ // second axis aligns its ticks to the primary's gridlines.
1604
+ //
1605
+ // On a 100% stacked chart (percentMin set) the primary axis is the share axis,
1606
+ // whose range is fixed, and the second axis's series are not stacked. An axis
1607
+ // of ranks alone (rankAxes) is inverted, and the axes then keep their own
1608
+ // ticks, so a rank axis steps by whole ranks.
1609
+ function twoValueAxesOption(config, axisLabels, context, percentMin, references, rankAxes) {
1610
+ const percent = percentMin !== undefined;
1611
+ const label = (axisIndex) => axisLabels[axisIndex];
1612
+ return [
1613
+ valueAxisOption(config.valueAxis, false, percent ? percentAxisLabel(context) : label(0), {
1614
+ index: 0,
1615
+ percentMin,
1616
+ reach: referenceReach(references, 0),
1617
+ rank: rankAxes[0],
1618
+ }),
1619
+ {
1620
+ ...valueAxisOption(config.secondaryAxis, false, label(1), {
1621
+ index: 1,
1622
+ reach: referenceReach(references, 1),
1623
+ rank: rankAxes[1],
1624
+ }),
1625
+ position: 'right',
1626
+ splitLine: { show: false },
1627
+ alignTicks: !percent && !rankAxes[0] && !rankAxes[1]
1628
+ && !hasAxisRange(config.valueAxis) && !hasAxisRange(config.secondaryAxis),
1629
+ },
1630
+ ];
1631
+ }
1632
+ // Whether the config pins any of an axis's range: a bound or a tick interval.
1633
+ function hasAxisRange(axis) {
1634
+ return Object.values(valueAxisRange(axis)).some((value) => value !== undefined);
1635
+ }
1636
+ // A configured bound or interval when it is a finite number, else undefined.
1637
+ function axisNumber(value) {
1638
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
1639
+ }
1640
+ // Tick labels written in the locale. ECharts' own ticks are grouped en-US
1641
+ // whatever the page's language.
1642
+ //
1643
+ // With a number format, the units and decimals decided once for the whole
1644
+ // axis (resolveValueAxisFormat) write every tick alike ('1.5K', '2.0K', never
1645
+ // '2K'). Without one, or when it leaves the ticks an unscaled number with no
1646
+ // pinned decimals (format 'number', or precision-less units none), each tick
1647
+ // is a plain locale-grouped number keeping its own decimals, so a 0.0002 tick
1648
+ // never rounds to '0'.
1649
+ function valueAxisLabel(format, context) {
1650
+ if (!format || (format.chart.units === ReportNumberUnits.None && format.chart.decimals === null)) {
1651
+ return { formatter: (value) => formatPlainNumber(value, context.locale) };
1652
+ }
1653
+ const options = { units: format.chart.units, decimals: format.chart.decimals };
1654
+ return {
1655
+ formatter: (value) => formatNumber(value, format.spec, format.context, options),
428
1656
  };
429
1657
  }
430
- function buildPieOption(component, data, donut) {
1658
+ // An axis's format from the spec its measures agree on, with the units and
1659
+ // decimals decided from its peak. Without a spec the axis is plain, and the
1660
+ // peak is never computed.
1661
+ function resolveValueAxisFormat(spec, peak, context) {
1662
+ return spec ? { spec, chart: resolveChartNumberFormat(spec, peak(), context), context } : null;
1663
+ }
1664
+ // Each value axis's format, by axis index. A chart with one value axis takes
1665
+ // the format the plotted series' measures agree on (a splitBy or colorBy chart
1666
+ // plots only its first measure), from the peak of all its series. On a two-axis chart each axis takes the format of the measures
1667
+ // plotted against it, from the peak of its own series, which are never
1668
+ // stacked with a 100% stacked chart's shares. A reference past the data
1669
+ // stretches its axis, so it counts toward the peak (referencePeak); a 100%
1670
+ // stacked chart's references are shares, which the raw values' peak leaves
1671
+ // out. contexts holds each axis's context (annotatedAxisContexts).
1672
+ function valueAxisFormats(config, extracted, axisIndexes, contexts, percent, references) {
1673
+ const reach = (axisIndex) => (percent && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));
1674
+ if (!axisIndexes.includes(1)) {
1675
+ return [resolveValueAxisFormat(axisNumberFormat(extracted.series.map((series) => series.measure)), () => Math.max(chartValuePeak(extracted.series.map((series) => series.values), !!config.stacked), reach(0)), contexts[0])];
1676
+ }
1677
+ return [0, 1].map((axisIndex) => {
1678
+ const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);
1679
+ return resolveValueAxisFormat(axisNumberFormat(onAxis.map((series) => series.measure)), () => Math.max(chartValuePeak(onAxis.map((series) => series.values), !!config.stacked && !percent), reach(axisIndex)), contexts[axisIndex]);
1680
+ });
1681
+ }
1682
+ // A 100% stacked chart's share axis ticks: whole percentages in the locale
1683
+ // ('25%', '25 %' in fr-CA). The shares are ratios whatever the report's
1684
+ // percentFormat says of its stored values.
1685
+ function percentAxisLabel(context) {
1686
+ return { formatter: wholePercentFormatter(context) };
1687
+ }
1688
+ // A share as a whole percentage in the locale, for the share axis's ticks and
1689
+ // its series' data labels.
1690
+ function wholePercentFormatter(context) {
1691
+ const ratioContext = { ...context, ratioPercent: true };
1692
+ return (value) => formatNumber(value, PERCENT_AXIS_FORMAT, ratioContext);
1693
+ }
1694
+ // A series' tooltip value in its measure's number format, per value ('—' when
1695
+ // empty). A measure without one writes it as the plain value axis does. A
1696
+ // value can arrive as an array (a [value, ...] data item), whose first entry
1697
+ // is the value.
1698
+ function seriesTooltip(measure, context) {
1699
+ if (!hasNumberFormat(measure)) {
1700
+ return { valueFormatter: (value) => formatPlainNumber(value, context.locale) };
1701
+ }
1702
+ return {
1703
+ valueFormatter: (value) => formatNumber(Array.isArray(value) ? value[0] : value, measure, context),
1704
+ };
1705
+ }
1706
+ function buildPieOption(component, data, donut, context) {
431
1707
  const config = component.config;
432
1708
  const extracted = extractChartSeries(component, data);
433
1709
  const values = extracted.series[0]?.values ?? [];
@@ -440,6 +1716,7 @@ function buildPieOption(component, data, donut) {
440
1716
  type: 'pie',
441
1717
  radius: donut ? ['45%', '72%'] : '72%',
442
1718
  center: pieCenter(legendPosition),
1719
+ tooltip: seriesTooltip(extracted.series[0]?.measure, context),
443
1720
  label: { show: false },
444
1721
  data: extracted.categories.map((category, index) => ({
445
1722
  name: category,
@@ -503,55 +1780,118 @@ export function spansMultipleYears(categories) {
503
1780
  }
504
1781
  return years.size > 1;
505
1782
  }
506
- // A bucket's period-start split into its primary label and its year. Day/week
507
- // read as "May 1", month as "May", quarter as "Q2", year as "2025". Returns null
508
- // for a value that isn't a parseable date (left as-is by callers).
509
- function periodLabelParts(value, granularity) {
1783
+ // A time axis's date label style when its config names one the viewer knows,
1784
+ // else short.
1785
+ export function chartDateLabel(config) {
1786
+ return Object.values(ReportChartDateLabel).find((style) => style === config?.xAxis?.dateLabel)
1787
+ ?? ReportChartDateLabel.Short;
1788
+ }
1789
+ // A bucket's period-start split into its primary label and its year. A year
1790
+ // reads "2025" in every style. Short, in the locale: day/week read "May 1"
1791
+ // ('1 mai' in fr-CA), month "May" ('mai'), quarter "Q2" ('T2' in French).
1792
+ // Long carries its year, in the locale: "May 1, 2026", "May 2026" ('mai
1793
+ // 2026'), "Q2 2026". Numeric is the same in every locale: "2026-05-01",
1794
+ // "2026-05", "2026-Q2". Returns null for a value that isn't a parseable date
1795
+ // (left as-is by callers).
1796
+ function periodLabelParts(value, granularity, locale, dateLabel = ReportChartDateLabel.Short) {
510
1797
  const date = parseISO(value);
511
1798
  if (!isValid(date)) {
512
1799
  return null;
513
1800
  }
514
1801
  const year = String(date.getFullYear());
1802
+ if (granularity === 'year') {
1803
+ return { primary: year, year };
1804
+ }
1805
+ return { primary: periodPrimaryLabel(date, granularity, locale, dateLabel), year };
1806
+ }
1807
+ // A period's label in the style asked for, the year aside (see
1808
+ // periodLabelParts).
1809
+ function periodPrimaryLabel(date, granularity, locale, dateLabel) {
1810
+ const year = String(date.getFullYear());
1811
+ const quarter = Math.floor(date.getMonth() / 3) + 1;
1812
+ if (dateLabel === ReportChartDateLabel.Numeric) {
1813
+ const month = String(date.getMonth() + 1).padStart(2, '0');
1814
+ const day = String(date.getDate()).padStart(2, '0');
1815
+ switch (granularity) {
1816
+ case 'quarter':
1817
+ return `${year}-Q${quarter}`;
1818
+ case 'month':
1819
+ return `${year}-${month}`;
1820
+ default: // day, week — the bucket start
1821
+ return `${year}-${month}-${day}`;
1822
+ }
1823
+ }
1824
+ const long = dateLabel === ReportChartDateLabel.Long;
515
1825
  switch (granularity) {
516
- case 'year':
517
- return { primary: year, year };
518
1826
  case 'quarter':
519
- return { primary: `Q${Math.floor(date.getMonth() / 3) + 1}`, year };
1827
+ return long
1828
+ ? `${quarterPrefix(locale)}${quarter} ${year}`
1829
+ : `${quarterPrefix(locale)}${quarter}`;
520
1830
  case 'month':
521
- return { primary: format(date, 'MMMM'), year };
522
- default: // day, week — the bucket start as a compact "MMM d"
523
- return { primary: format(date, 'MMM d'), year };
1831
+ return formatLocalDate(date, locale, long ? MONTH_YEAR : MONTH_LONG);
1832
+ default: // day, week — the bucket start as a month and day
1833
+ return formatLocalDate(date, locale, long ? DAY_SHORT : MONTH_DAY);
524
1834
  }
525
1835
  }
526
- // A compact single-line period label (year appended only when the data spans
527
- // years) — for media that can't do a styled second line, e.g. PowerPoint.
528
- export function formatPeriodLabel(value, granularity, multiYear) {
529
- const parts = periodLabelParts(value, granularity);
1836
+ // Whether a period label leaves its year to be added apart: only a short one
1837
+ // does, a long or numeric label already carries it.
1838
+ function periodYearApart(granularity, dateLabel) {
1839
+ return granularity !== 'year' && dateLabel === ReportChartDateLabel.Short;
1840
+ }
1841
+ function quarterPrefix(locale) {
1842
+ return QUARTER_PREFIXES.get(locale.split('-')[0].toLowerCase()) ?? QUARTER_PREFIX;
1843
+ }
1844
+ // A compact single-line period label — for media that can't do a styled
1845
+ // second line, e.g. PowerPoint. A short label has its year appended only when
1846
+ // the data spans years; a long or numeric one always carries it.
1847
+ export function formatPeriodLabel(value, granularity, multiYear, locale, dateLabel = ReportChartDateLabel.Short) {
1848
+ const parts = periodLabelParts(value, granularity, locale, dateLabel);
530
1849
  if (!parts) {
531
1850
  return value;
532
1851
  }
533
- return multiYear && granularity !== 'year' ? `${parts.primary} ${parts.year}` : parts.primary;
1852
+ return multiYear && periodYearApart(granularity, dateLabel) ? `${parts.primary} ${parts.year}` : parts.primary;
534
1853
  }
535
1854
  // A cross-tab's column headings, the one rule the grid and the PDF/PowerPoint
536
1855
  // exports share. The first is the row key and keeps its authored label; the
537
1856
  // rest are pivot VALUES. When the pivot axis is a time dimension the server
538
1857
  // sends the grain it bucketed at, so a period-start like "2026-01-01" reads
539
- // "January 2026", as the chart's x-axis labels it.
540
- export function pivotHeadings(config, data) {
1858
+ // "January 2026" ('janvier 2026' in fr-CA), as the chart's x-axis labels it.
1859
+ export function pivotHeadings(config, data, locale) {
541
1860
  const columns = data.columns ?? [];
542
1861
  const multiYear = spansMultipleYears(columns);
543
1862
  return columns.map((column, index) => {
544
1863
  if (index === 0) {
545
1864
  return config.rowBy?.label || column;
546
1865
  }
547
- return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear) : column;
1866
+ return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear, locale) : column;
548
1867
  });
549
1868
  }
1869
+ // A cross-tab's columns as the grid and the exports draw them: each headed by
1870
+ // pivotHeadings(), and every pivot-value column formatted by the one
1871
+ // config.cellFormat. The row key column stays as it came. `numeric` marks the
1872
+ // columns whose cells are formatted numbers, which are right-aligned.
1873
+ export function pivotColumnSpecs(config, data, locale) {
1874
+ const headings = pivotHeadings(config, data, locale);
1875
+ const cellFormat = config.cellFormat;
1876
+ const numeric = hasNumberFormat(cellFormat);
1877
+ const cells = numeric && cellFormat
1878
+ ? { format: listColumnFormat(cellFormat.format), precision: cellFormat.precision, units: cellFormat.units }
1879
+ : {};
1880
+ return (data.columns ?? []).map((column, index) => index === 0
1881
+ ? { column, label: headings[index], numeric: false }
1882
+ : { column, label: headings[index], ...cells, numeric });
1883
+ }
1884
+ // A number format's style as a list column's format: the two enums share
1885
+ // their number values.
1886
+ function listColumnFormat(format) {
1887
+ return Object.values(ReportListColumnFormat).find((value) => value === format);
1888
+ }
550
1889
  // ECharts category-axis label config for a time bucket: the primary label on
551
1890
  // line one, and — only when the data spans multiple years — the year on a small
552
1891
  // gray second line, centered under the tick (year granularity needs no second
553
- // line, it already is the year). Empty for a non-time axis (labels as-is).
554
- function periodAxisLabel(granularity, categories) {
1892
+ // line, it already is the year, and neither does a long or numeric label,
1893
+ // which carries its year). Empty for a non-time axis (labels as-is).
1894
+ function periodAxisLabel(granularity, categories, locale, dateLabel) {
555
1895
  if (!granularity) {
556
1896
  return {};
557
1897
  }
@@ -559,11 +1899,11 @@ function periodAxisLabel(granularity, categories) {
559
1899
  return {
560
1900
  axisLabel: {
561
1901
  formatter: (value) => {
562
- const parts = periodLabelParts(value, granularity);
1902
+ const parts = periodLabelParts(value, granularity, locale, dateLabel);
563
1903
  if (!parts) {
564
1904
  return value;
565
1905
  }
566
- return multiYear && granularity !== 'year'
1906
+ return multiYear && periodYearApart(granularity, dateLabel)
567
1907
  ? `${parts.primary}\n{yr|${parts.year}}`
568
1908
  : parts.primary;
569
1909
  },
@@ -571,4 +1911,4 @@ function periodAxisLabel(granularity, categories) {
571
1911
  },
572
1912
  };
573
1913
  }
574
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvb3B0aW9uLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXJELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUM5QyxPQUFPLEVBS0wsbUJBQW1CLEdBS3BCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUczRiw4RUFBOEU7QUFDOUUsMkVBQTJFO0FBQzNFLG1FQUFtRTtBQUNuRSxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsc0VBQXNFO0FBQ3RFLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLDRFQUE0RTtBQUM1RSxpQ0FBaUM7QUFDakMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFDOUIsMkVBQTJFO0FBQzNFLDhFQUE4RTtBQUM5RSx5QkFBeUI7QUFDekIsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUM7QUFDckMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLCtFQUErRTtBQUMvRSxzRUFBc0U7QUFDdEUsa0VBQWtFO0FBQ2xFLE1BQU0sZUFBZSxHQUFHLEdBQUcsMkJBQTJCLE1BQU0sd0JBQXdCLEVBQUUsQ0FBQztBQWdCdkYsNkVBQTZFO0FBQzdFLGdGQUFnRjtBQUNoRixzRUFBc0U7QUFDdEUsRUFBRTtBQUNGLGlGQUFpRjtBQUNqRiw4RUFBOEU7QUFDOUUsZ0ZBQWdGO0FBQ2hGLDRF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LFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDakU7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgTGVnZW5kQ29tcG9uZW50T3B0aW9uLCBTZXJpZXNPcHRpb24sIFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcyB9IGZyb20gJ2VjaGFydHMnO1xuXG5pbXBvcnQgeyBmb3JtYXQsIGlzVmFsaWQsIHBhcnNlSVNPIH0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBmb3JtYXRNZWFzdXJlVmFsdWUgfSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBBeGlzQ2hhcnRUeXBlLFxuICBDaGFydENvbmZpZyxcbiAgQ2hhcnRHcmFudWxhcml0eSxcbiAgQ29tcG9uZW50RGF0YSxcbiAgR1JBTlVMQVJJVFlfT1BUSU9OUyxcbiAgTGVnZW5kUG9zaXRpb24sXG4gIExpc3RDb25maWcsXG4gIFJlcG9ydENvbXBvbmVudCxcbiAgV2F0ZXJmYWxsU3RlcEtpbmQsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tICcuL3RleHQnO1xuaW1wb3J0IHsgUkVQT1JUX1dBVEVSRkFMTF9DT0xPUlMgfSBmcm9tICcuL3RoZW1lL3BhbGV0dGUnO1xuaW1wb3J0IHsgUkVQT1JUX0FYSVNfTEFCRUxfRk9OVF9TSVpFLCBSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFkgfSBmcm9tICcuL3RoZW1lL3R5cG9ncmFwaHknO1xuXG5cbi8vIFJvb20gZm9yIHRoZSBjYXRlZ29yeSBheGlzJ3MgdGl0bGUuIEVDaGFydHMgNSdzIGNvbnRhaW5MYWJlbCBrZWVwcyB0aGUgVElDS1xuLy8gbGFiZWxzIGluc2lkZSB0aGUgZ3JpZCBidXQgbm90IHRoZSBheGlzIG5hbWUsIHNvIHdpdGhvdXQgdGhpcyBhIHZlcnRpY2FsXG4vLyBjaGFydCdzIHRpdGxlIHJ1bnMgb2ZmIHRoZSBib3R0b20gZWRnZSBvciB1bmRlciBhIGJvdHRvbSBsZWdlbmQuXG5jb25zdCBBWElTX05BTUVfUk9PTSA9IDIwO1xuLy8gRUNoYXJ0cycgb3duIGRlZmF1bHQgZ2FwIGJldHdlZW4gdGhlIGF4aXMgbGluZSBhbmQgaXRzIHRpY2sgbGFiZWxzLlxuY29uc3QgQVhJU19MQUJFTF9NQVJHSU4gPSA4O1xuLy8gQ2xlYXJhbmNlIGJldHdlZW4gdGhlIGxvbmdlc3QgdGljayBsYWJlbCBhbmQgYSBob3Jpem9udGFsIGNoYXJ0J3Mgcm90YXRlZFxuLy8gdGl0bGUsIHNvIHRoZSB0d28gbmV2ZXIgdG91Y2guXG5jb25zdCBBWElTX05BTUVfQ0xFQVJBTkNFID0gNjtcbi8vIEEgaG9yaXpvbnRhbCBjaGFydCdzIGNhdGVnb3J5IGxhYmVscyBhcmUgY3V0IHNob3J0IHdpdGggYW4gZWxsaXBzaXMgcGFzdFxuLy8gdGhpcyB3aWR0aCAodGhlIHRvb2x0aXAgc3RpbGwgc2hvd3MgdGhlbSBpbiBmdWxsKSwgc28gb25lIGxvbmcgbGFiZWwgY2Fubm90XG4vLyBzcXVlZXplIHRoZSBwbG90IGF3YXkuXG5jb25zdCBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEggPSAxNjA7XG5jb25zdCBMQUJFTF9FTExJUFNJUyA9ICfigKYnO1xuLy8gVGhlIGZvbnQgdGhlIHRoZW1lIGRyYXdzIGF4aXMgbGFiZWxzIGluLCBhcyBhIGNhbnZhcyBmb250IHN0cmluZy4gTGFiZWxzIGFyZVxuLy8gbWVhc3VyZWQgaW4gaXQgdGhlIHdheSBFQ2hhcnRzIG1lYXN1cmVzIHRoZW0gZm9yIGNvbnRhaW5MYWJlbCwgc28gYVxuLy8gaG9yaXpvbnRhbCBjaGFydCdzIHRpdGxlIGxhbmRzIGV4YWN0bHkgYmV5b25kIHRoZSB3aWRlc3QgbGFiZWwuXG5jb25zdCBBWElTX0xBQkVMX0ZPTlQgPSBgJHtSRVBPUlRfQVhJU19MQUJFTF9GT05UX1NJWkV9cHggJHtSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFl9YDtcblxuLy8gV2hpY2ggZWRnZSBvZiB0aGUgcGxvdCB0aGUgY2F0ZWdvcnkgYXhpcydzIHRpdGxlIHNpdHMgb246IGJlbG93IGEgdmVydGljYWxcbi8vIGNoYXJ0LCB0byB0aGUgbGVmdCBvZiBhIGhvcml6b250YWwgb25lLlxudHlwZSBBeGlzVGl0bGVTaWRlID0gJ2JvdHRvbScgfCAnbGVmdCc7XG5cbi8vIFRoZSBwbG90J3MgZGlzdGFuY2UgZnJvbSBlYWNoIGVkZ2Ugb2YgdGhlIGNoYXJ0LCBpbiBwaXhlbHMuXG5pbnRlcmZhY2UgQXhpc0dyaWRSb29tIHtcbiAgbGVmdDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIGNvbnRhaW5MYWJlbDogYm9vbGVhbjtcbn1cblxuXG4vLyBjb2xvckJ5IGFwcGxpZXMgb25seSB0byBzaW5nbGUtZGltZW5zaW9uIGJhciBjaGFydHMsIGFuZCBvbmx5IHdoZW4gc3BsaXRCeVxuLy8gaXNuJ3QgYWxyZWFkeSBkcml2aW5nIG11bHRpcGxlIHNlcmllczogaXQgY29sb3JzIGVhY2ggYmFyIGJ5IGl0cyBjYXRlZ29yeSBhbmRcbi8vIHNob3dzIGEgbGVnZW5kIChvbmUgc2VyaWVzIHBlciBjYXRlZ29yeSwgb3ZlcmxhcHBlZCB0byBmdWxsIHdpZHRoKS5cbi8vXG4vLyBJdCBpcyB0aGUgREVGQVVMVCBmb3IgYSBjYXRlZ29yaWNhbCBiYXIgY2hhcnQgcmF0aGVyIHRoYW4gc29tZXRoaW5nIHRoZSBjb25maWdcbi8vIGhhcyB0byBhc2sgZm9yLiBBIGJhciBjaGFydCB3aG9zZSB4LWF4aXMgaXMgYSBjYXRlZ29yeSDigJQgcmVnaW9ucywgc3RhdHVzZXMsXG4vLyBzdG9yZXMg4oCUIGlzIGNvbXBhcmluZyB0aG9zZSBjYXRlZ29yaWVzIHRvIGVhY2ggb3RoZXIsIGFuZCBvbmUgZmxhdCBjb2xvciB3aXRoXG4vLyBubyBsZWdlbmQgaXMgdGhlIHdyb25nIHJlYWRpbmcgb2YgaXQgaW4gZXNzZW50aWFsbHkgZXZlcnkgY2FzZS4gUmVxdWlyaW5nXG4vLyBjb2xvckJ5IHRvIG9wdCBpbiBtZWFudCBldmVyeSBzdWNoIGNoYXJ0IHJlbmRlcmVkIG1vbm9jaHJvbWUgdW5sZXNzIHdob2V2ZXJcbi8vIHdyb3RlIHRoZSBjb25maWcgcmVtZW1iZXJlZCBhbiBvcHRpb25hbCBwcm9wZXJ0eSwgd2hpY2ggaXMgYSBkZWZhdWx0IHNldCB0aGVcbi8vIHdyb25nIHdheSByb3VuZDogdGhlIGNvbW1vbiBjYXNlIHNob3VsZCBub3QgbmVlZCB0aGUgZmxhZy5cbi8vXG4vLyBBIFRJTUUgYXhpcyBpcyBleGNsdWRlZDogY29uc2VjdXRpdmUgcGVyaW9kcyBhcmUgb25lIHNlcmllcyBtb3ZpbmcsIG5vdFxuLy8gY2F0ZWdvcmllcyBiZWluZyBjb21wYXJlZCwgYW5kIGNvbG9yaW5nIGVhY2ggbW9udGggZGlmZmVyZW50bHkgcmVhZHMgYXNcbi8vIHVucmVsYXRlZCBncm91cHMuIEV4cGxpY2l0bHkgb3B0aW5nIG91dCDigJQgY29sb3JCeToge2NvbHVtbjogJyd9IG9yIGFcbi8vIGNvbmZpZy5sZWdlbmQgb2YgJ2hpZGRlbicg4oCUIHN0aWxsIHdpbnMsIHNvIGEgY2FsbGVyIHRoYXQgd2FudHMgb25lIGZsYXQgY29sb3Jcbi8vIGNhbiBzYXkgc28uXG4vL1xuLy8gXCJCYXIgY2hhcnRcIiBpcyB0aGUgdHlwZSB0aGUgbG9uZSBtZWFzdXJlIGlzIGFjdHVhbGx5IERSQVdOIGFzOiBpdHMgb3duIHR5cGVcbi8vIHdoZW4gaXQgbmFtZXMgb25lLCB3aGljaCBjYW4gdHVybiBhIGxpbmUgY2hhcnQncyBzaW5nbGUgc2VyaWVzIGludG8gYmFycyBvclxuLy8gYSBiYXIgY2hhcnQncyBpbnRvIGEgbGluZS5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yQnkoY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW4ge1xuICBpZiAoY29uZmlnLnNwbGl0Qnk/LmNvbHVtbiB8fCAoY29uZmlnLm1lYXN1cmVzPy5bMF0/LnR5cGUgPz8gY29uZmlnLmNoYXJ0VHlwZSA/PyAnYmFyJykgIT09ICdiYXInKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5jb2xvckJ5KSB7XG4gICAgcmV0dXJuICEhY29uZmlnLmNvbG9yQnkuY29sdW1uO1xuICB9XG5cbiAgcmV0dXJuIChjb25maWcueEF4aXM/LmtpbmQgPz8gJ2NhdGVnb3J5JykgPT09ICdjYXRlZ29yeSdcbiAgICAmJiAhY29uZmlnLnhBeGlzPy5ncmFudWxhcml0eVxuICAgICYmIChjb25maWcubWVhc3VyZXM/Lmxlbmd0aCA/PyAxKSA8PSAxO1xufVxuXG5cbi8vIFRoZSBjb2x1bW4gY29sb3JCeSBncm91cHMgYnkg4oCUIGl0cyBvd24gd2hlbiB0aGUgY29uZmlnIG5hbWVkIG9uZSwgb3RoZXJ3aXNlXG4vLyB0aGUgeC1heGlzIGl0IGRlZmF1bHRzIHRvIGNvbG9yaW5nLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yQnlDb2x1bW4oY29uZmlnOiBDaGFydENvbmZpZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBpc0NvbG9yQnkoY29uZmlnKVxuICAgID8gKGNvbmZpZy5jb2xvckJ5Py5jb2x1bW4gfHwgY29uZmlnLnhBeGlzPy5jb2x1bW4pXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cblxuLy8gQ2F0ZWdvcmllcyArIG5hbWVkIHNlcmllcyBleHRyYWN0ZWQgZnJvbSBhIGNoYXJ0IGNvbXBvbmVudCdzIGNvbmZpZyArIHJvd3Mg4oCUXG4vLyB0aGUgb25lIHBpdm90IChzcGxpdEJ5IOKGkiBzZXJpZXMsIG1lYXN1cmVzIOKGkiBzZXJpZXMpIHNoYXJlZCBieSB0aGUgb24tc2NyZWVuXG4vLyBFQ2hhcnRzIG9wdGlvbiBiZWxvdyBBTkQgdGhlIFBvd2VyUG9pbnQgZXhwb3J0J3MgbmF0aXZlIGNoYXJ0IGRhdGEsIHNvIGJvdGhcbi8vIG1lZGlhIHBsb3QgaWRlbnRpY2FsIG51bWJlcnMuXG4vL1xuLy8gQSBzZXJpZXMnIGB0eXBlYCBpcyB0aGUgdHlwZSBpdHMgbWVhc3VyZSBhc2tzIHRvIGJlIGRyYXduIGFzLCBhbmQgaXMgYWJzZW50XG4vLyB3aGVuIHRoZSBtZWFzdXJlIGxlYXZlcyBpdCB0byB0aGUgY2hhcnQncyBjaGFydFR5cGUgKHNlZSBzZXJpZXNUeXBlcykuXG5leHBvcnQgaW50ZXJmYWNlIEV4dHJhY3RlZENoYXJ0U2VyaWVzIHtcbiAgY2F0ZWdvcmllczogc3RyaW5nW107XG4gIHNlcmllczogeyBuYW1lOiBzdHJpbmc7IHZhbHVlczogKG51bWJlciB8IG51bGwpW107IHR5cGU/OiBBeGlzQ2hhcnRUeXBlIH1bXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RDaGFydFNlcmllcyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgZGF0YTogQ29tcG9uZW50RGF0YSk6IEV4dHJhY3RlZENoYXJ0U2VyaWVzIHtcbiAgY29uc3QgY29uZmlnID0gY29tcG9uZW50LmNvbmZpZyBhcyBDaGFydENvbmZpZztcbiAgY29uc3QgeENvbHVtbiA9IGNvbmZpZy54QXhpcz8uY29sdW1uID8/IGRhdGEuY29sdW1uc1swXTtcbiAgY29uc3Qgc3BsaXRDb2x1bW4gPSBjb25maWcuc3BsaXRCeT8uY29sdW1uO1xuICAvLyBjb2xvckJ5IGVtaXRzIG9uZSBzZXJpZXMgcGVyIGNhdGVnb3J5IHRvbyAoc28gZWFjaCBiYXIgY2FycmllcyBpdHMgb3duXG4gIC8vIGNvbG9yICsgbGVnZW5kIGVudHJ5KSwgYnV0IHRoZSBiYXJzIGFyZSBvdmVybGFwcGVkIHRvIGZ1bGwgd2lkdGggaW5cbiAgLy8gYnVpbGRBeGlzT3B0aW9uIHJhdGhlciB0aGFuIGxhaWQgc2lkZS1ieS1zaWRlLiBzcGxpdEJ5IHdpbnMgaWYgYm90aCBhcmUgc2V0LlxuICBjb25zdCBncm91cENvbHVtbiA9IHNwbGl0Q29sdW1uIHx8IGNvbG9yQnlDb2x1bW4oY29uZmlnKTtcbiAgY29uc3QgbWVhc3VyZXMgPSBjb25maWcubWVhc3VyZXM/Lmxlbmd0aFxuICAgID8gY29uZmlnLm1lYXN1cmVzXG4gICAgOiBbeyBjb2x1bW46IGRhdGEuY29sdW1uc1tkYXRhLmNvbHVtbnMubGVuZ3RoIC0gMV0gfV07XG5cbiAgY29uc3QgcmF3Q2F0ZWdvcmllcyA9IHVuaXF1ZVZhbHVlcyhkYXRhLnJvd3MsIHhDb2x1bW4pO1xuICBjb25zdCBjYXRlZ29yaWVzID0gcmF3Q2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5KSA9PiBTdHJpbmcoY2F0ZWdvcnkgPz8gJ+KAlCcpKTtcbiAgY29uc3Qgc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc1snc2VyaWVzJ10gPSBbXTtcblxuICBpZiAoZ3JvdXBDb2x1bW4pIHtcbiAgICAvLyBPbmUgc2VyaWVzIHBlciBncm91cCB2YWx1ZSAoc3BsaXRCeS9jb2xvckJ5KSwgcGl2b3RlZCBvdmVyIHRoZSBmaXJzdCBtZWFzdXJlLlxuICAgIGNvbnN0IG1lYXN1cmUgPSBtZWFzdXJlc1swXTtcbiAgICBmb3IgKGNvbnN0IGdyb3VwVmFsdWUgb2YgdW5pcXVlVmFsdWVzKGRhdGEucm93cywgZ3JvdXBDb2x1bW4pKSB7XG4gICAgICBjb25zdCBieUNhdGVnb3J5ID0gbmV3IE1hcDx1bmtub3duLCB1bmtub3duPigpO1xuICAgICAgZm9yIChjb25zdCByb3cgb2YgZGF0YS5yb3dzKSB7XG4gICAgICAgIGlmIChyb3dbZ3JvdXBDb2x1bW5dID09PSBncm91cFZhbHVlKSB7XG4gICAgICAgICAgYnlDYXRlZ29yeS5zZXQocm93W3hDb2x1bW5dLCByb3dbbWVhc3VyZS5jb2x1bW5dKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzZXJpZXMucHVzaCh7XG4gICAgICAgIG5hbWU6IFN0cmluZyhncm91cFZhbHVlID8/ICfigJQnKSxcbiAgICAgICAgdmFsdWVzOiByYXdDYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnkpID0+IG51bWVyaWMoYnlDYXRlZ29yeS5nZXQoY2F0ZWdvcnkpKSksXG4gICAgICAgIHR5cGU6IG1lYXN1cmUudHlwZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGNvbnN0IG1lYXN1cmUgb2YgbWVhc3VyZXMpIHtcbiAgICAgIGNvbnN0IGJ5Q2F0ZWdvcnkgPSBuZXcgTWFwPHVua25vd24sIHVua25vd24+KCk7XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhLnJvd3MpIHtcbiAgICAgICAgYnlDYXRlZ29yeS5zZXQocm93W3hDb2x1bW5dLCByb3dbbWVhc3VyZS5jb2x1bW5dKTtcbiAgICAgIH1cblxuICAgICAgc2VyaWVzLnB1c2goe1xuICAgICAgICBuYW1lOiBtZWFzdXJlLmxhYmVsID8/IG1lYXN1cmUuY29sdW1uLFxuICAgICAgICB2YWx1ZXM6IHJhd0NhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gbnVtZXJpYyhieUNhdGVnb3J5LmdldChjYXRlZ29yeSkpKSxcbiAgICAgICAgdHlwZTogbWVhc3VyZS50eXBlLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2F0ZWdvcmllcywgc2VyaWVzIH07XG59XG5cbi8vIFRoZSB0eXBlIGVhY2ggZXh0cmFjdGVkIHNlcmllcyBpcyBkcmF3biBhczogaXRzIG1lYXN1cmUncyBvd24gdHlwZSB3aGVuIGl0XG4vLyBuYW1lcyBvbmUsIHRoZSBjaGFydCdzIGNoYXJ0VHlwZSBvdGhlcndpc2UuIE1vcmUgdGhhbiBvbmUgZGlzdGluY3QgdHlwZSBpcyBhXG4vLyBjb21ibyBjaGFydC4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGggbWVkaWEgZHJhdyBlYWNoIHNlcmllc1xuLy8gdGhlIHNhbWUgd2F5LlxuZXhwb3J0IGZ1bmN0aW9uIHNlcmllc1R5cGVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIGNoYXJ0VHlwZTogQXhpc0NoYXJ0VHlwZSk6IEF4aXNDaGFydFR5cGVbXSB7XG4gIHJldHVybiBleHRyYWN0ZWQuc2VyaWVzLm1hcCgoc2VyaWVzKSA9PiBzZXJpZXMudHlwZSA/PyBjaGFydFR5cGUpO1xufVxuXG4vLyBPbmUgYmFyIG9mIGEgd2F0ZXJmYWxsLiBgc3RhcnRgIGlzIHRoZSBydW5uaW5nIHRvdGFsIGJlZm9yZSBpdCwgd2hlcmUgdGhlIGJhclxuLy8gc3RhcnRzLCBhbmQgYGNoYW5nZWAgaXRzIHNpZ25lZCBoZWlnaHQsIHNvIGl0IGVuZHMgYXQgc3RhcnQgKyBjaGFuZ2UuIFRoZVxuLy8gY2xvc2luZyB0b3RhbCBzdGFydHMgYXQgemVybyBhbmQgaXRzIGNoYW5nZSBpcyB0aGUgd2hvbGUgcnVubmluZyB0b3RhbC5cbmV4cG9ydCBpbnRlcmZhY2UgV2F0ZXJmYWxsU3RlcCB7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIHN0YXJ0OiBudW1iZXI7XG4gIGNoYW5nZTogbnVtYmVyIHwgbnVsbDtcbiAga2luZDogV2F0ZXJmYWxsU3RlcEtpbmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0cmFjdGVkV2F0ZXJmYWxsIHtcbiAgbmFtZTogc3RyaW5nO1xuICBzdGVwczogV2F0ZXJmYWxsU3RlcFtdO1xufVxuXG5leHBvcnQgY29uc3QgV0FURVJGQUxMX1RPVEFMX0xBQkVMID0gJ1RvdGFsJztcblxuLy8gQSB3YXRlcmZhbGwncyBiYXJzIGZyb20gaXRzIG9uZSBtZWFzdXJlOiBlYWNoIGNhdGVnb3J5J3MgdmFsdWUgaXMgaG93IGZhciB0aGVcbi8vIHJ1bm5pbmcgdG90YWwgbW92ZXMgdGhlcmUsIGFuZCBhIGxhc3QgVG90YWwgYmFyIHNob3dzIHdoZXJlIGl0IGVuZGVkLiBBXG4vLyBjYXRlZ29yeSB3aXRoIG5vIHZhbHVlIG1vdmVzIG5vdGhpbmcgYW5kIGRyYXdzIG5vIGJhci4gU2hhcmVkIHdpdGggdGhlXG4vLyBQb3dlclBvaW50IGV4cG9ydCBzbyBib3RoIG1lZGlhIGRyYXcgdGhlIHNhbWUgc3RlcHMuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFdhdGVyZmFsbChjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgZGF0YTogQ29tcG9uZW50RGF0YSk6IEV4dHJhY3RlZFdhdGVyZmFsbCB7XG4gIGNvbnN0IGV4dHJhY3RlZCA9IGV4dHJhY3RDaGFydFNlcmllcyhjb21wb25lbnQsIGRhdGEpO1xuICBjb25zdCB2YWx1ZXMgPSBleHRyYWN0ZWQuc2VyaWVzWzBdPy52YWx1ZXMgPz8gW107XG4gIGNvbnN0IHN0ZXBzOiBXYXRlcmZhbGxTdGVwW10gPSBbXTtcbiAgbGV0IHRvdGFsID0gMDtcblxuICBleHRyYWN0ZWQuY2F0ZWdvcmllcy5mb3JFYWNoKChjYXRlZ29yeSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBjaGFuZ2UgPSB2YWx1ZXNbaW5kZXhdID8/IG51bGw7XG4gICAgc3RlcHMucHVzaCh7IGNhdGVnb3J5LCBzdGFydDogdG90YWwsIGNoYW5nZSwga2luZDogKGNoYW5nZSA/PyAwKSA8IDAgPyAnZmFsbCcgOiAncmlzZScgfSk7XG4gICAgdG90YWwgKz0gY2hhbmdlID8/IDA7XG4gIH0pO1xuXG4gIHN0ZXBzLnB1c2goeyBjYXRlZ29yeTogV0FURVJGQUxMX1RPVEFMX0xBQkVMLCBzdGFydDogMCwgY2hhbmdlOiB0b3RhbCwga2luZDogJ3RvdGFsJyB9KTtcblxuICByZXR1cm4geyBuYW1lOiBleHRyYWN0ZWQuc2VyaWVzWzBdPy5uYW1lID8/ICcnLCBzdGVwcyB9O1xufVxuXG4vLyBUaGUgb25lIHB1cmUgbWFwcGluZyBmcm9tIG91ciBzdGFuZGFyZCBjYW1lbENhc2UgY2hhcnQgY29uZmlnICsgdGhlIGRhdGFcbi8vIGVuZHBvaW50J3Mgcm93cyB0byBhbiBFQ2hhcnRzIG9wdGlvbi4gRXZlcnl0aGluZyB2aXN1YWwgdGhhdCBpc24ndCBpbiB0aGVcbi8vIHJlZ2lzdGVyZWQgJ3JlcG9ydCcgdGhlbWUgaXMgZGVjaWRlZCBoZXJlLCBzbyByZXBvcnQgc3RhbmRhcmRzIGhhdmUgZXhhY3RseVxuLy8gdHdvIGhvbWVzLlxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ2hhcnRPcHRpb24oY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIGRhdGE6IENvbXBvbmVudERhdGEpOiBFQ2hhcnRzT3B0aW9uIHtcbiAgY29uc3QgY29uZmlnID0gY29tcG9uZW50LmNvbmZpZyBhcyBDaGFydENvbmZpZztcbiAgY29uc3QgY2hhcnRUeXBlID0gY29uZmlnLmNoYXJ0VHlwZSA/PyAnYmFyJztcblxuICBpZiAoY2hhcnRUeXBlID09PSAncGllJyB8fCBjaGFydFR5cGUgPT09ICdkb251dCcpIHtcbiAgICByZXR1cm4gYnVpbGRQaWVPcHRpb24oY29tcG9uZW50LCBkYXRhLCBjaGFydFR5cGUgPT09ICdkb251dCcpO1xuICB9XG5cbiAgaWYgKGNoYXJ0VHlwZSA9PT0gJ3dhdGVyZmFsbCcpIHtcbiAgICByZXR1cm4gYnVpbGRXYXRlcmZhbGxPcHRpb24oY29tcG9uZW50LCBkYXRhKTtcbiAgfVxuXG4gIHJldHVybiBidWlsZEF4aXNPcHRpb24oY29tcG9uZW50LCBkYXRhLCBjaGFydFR5cGUpO1xufVxuXG5mdW5jdGlvbiBidWlsZEF4aXNPcHRpb24oXG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBjaGFydFR5cGU6IEF4aXNDaGFydFR5cGUsXG4pOiBFQ2hhcnRzT3B0aW9uIHtcbiAgY29uc3QgY29uZmlnID0gY29tcG9uZW50LmNvbmZpZyBhcyBDaGFydENvbmZpZztcbiAgY29uc3QgZXh0cmFjdGVkID0gZXh0cmFjdENoYXJ0U2VyaWVzKGNvbXBvbmVudCwgZGF0YSk7XG4gIGNvbnN0IGhvcml6b250YWwgPSBjb25maWcub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJztcbiAgY29uc3QgY29sb3JCeSA9IGlzQ29sb3JCeShjb25maWcpO1xuICBjb25zdCB0eXBlcyA9IHNlcmllc1R5cGVzKGV4dHJhY3RlZCwgY2hhcnRUeXBlKTtcbiAgY29uc3QgY29tYm8gPSBuZXcgU2V0KHR5cGVzKS5zaXplID4gMTtcblxuICAvLyBjb2xvckJ5IGVtaXRzIG9uZSBzZXJpZXMgcGVyIGNhdGVnb3J5OyBvdmVybGFwcGluZyB0aGVtIChiYXJHYXAgLTEwMCUpIG1ha2VzXG4gIC8vIGVhY2ggcmVuZGVyIGF0IHRoZSBmdWxsIGNhdGVnb3J5LWJhbmQgd2lkdGgg4oCUIG9uZSBmdWxsLXdpZHRoLCBkaXN0aW5jdGx5XG4gIC8vIGNvbG9yZWQgYmFyIHBlciBjYXRlZ29yeSDigJQgaW5zdGVhZCBvZiBzaWRlLWJ5LXNpZGUgc2xpdmVycy4gVGhlIGxheW91dCBwcm9wc1xuICAvLyBhcmUgcmVhZCBmcm9tIHRoZSBmaXJzdCBzZXJpZXMgb2YgdGhlIGNvb3JkaW5hdGUgc3lzdGVtLlxuICAvL1xuICAvLyBTdGFja2luZyBzdW1zIGV2ZXJ5IHNlcmllcyB0aGF0IHNoYXJlcyBhIHN0YWNrIG5hbWUsIHdoYXRldmVyIGl0cyB0eXBlLiBJblxuICAvLyBhIGNvbWJvIGVhY2ggdHlwZSBzdGFja3Mgb25seSB3aXRoIGl0cyBvd24ga2luZCwgc28gYSBsaW5lIG9mIGEgcmF0ZSBuZXZlclxuICAvLyBzaXRzIG9uIHRvcCBvZiB0aGUgYmFycycgdG90YWwuXG4gIGNvbnN0IHNlcmllczogU2VyaWVzT3B0aW9uW10gPSBleHRyYWN0ZWQuc2VyaWVzLm1hcCgoZXh0cmFjdGVkU2VyaWVzLCBpbmRleCkgPT4gYnVpbGRTZXJpZXMoXG4gICAgZXh0cmFjdGVkU2VyaWVzLm5hbWUsXG4gICAgZXh0cmFjdGVkU2VyaWVzLnZhbHVlcyxcbiAgICB0eXBlc1tpbmRleF0sXG4gICAgY29uZmlnLnN0YWNrZWQgPyAoY29tYm8gPyBgdG90YWwtJHt0eXBlc1tpbmRleF19YCA6ICd0b3RhbCcpIDogdW5kZWZpbmVkLFxuICAgIGNvbG9yQnkgJiYgaW5kZXggPT09IDAsXG4gICAgY29tYm8sXG4gICkpO1xuXG4gIGNvbnN0IGNhdGVnb3J5QXhpcyA9IGNhdGVnb3J5QXhpc09wdGlvbihjb25maWcsIGRhdGEsIGV4dHJhY3RlZC5jYXRlZ29yaWVzLCBob3Jpem9udGFsKTtcbiAgY29uc3QgdmFsdWVBeGlzID0geyB0eXBlOiAndmFsdWUnIGFzIGNvbnN0IH07XG5cbiAgY29uc3QgbGVnZW5kUG9zaXRpb24gPSByZXNvbHZlTGVnZW5kUG9zaXRpb24oY29uZmlnLCBzZXJpZXMubGVuZ3RoLCBjb2xvckJ5KTtcblxuICByZXR1cm4ge1xuICAgIGdyaWQ6IGF4aXNHcmlkKGxlZ2VuZFBvc2l0aW9uLCBjYXRlZ29yeVRpdGxlU2lkZShjb25maWcsIGhvcml6b250YWwpKSxcbiAgICBsZWdlbmQ6IGxlZ2VuZE9wdGlvbihsZWdlbmRQb3NpdGlvbiksXG4gICAgLy8gY29sb3JCeSBjaGFydHMgb3ZlcmxhcCBOIG1vc3RseS1udWxsIHNlcmllcywgc28gYW4gYXhpcyB0b29sdGlwIHdvdWxkIGxpc3RcbiAgICAvLyBldmVyeSBjYXRlZ29yeTsgYW4gaXRlbSB0b29sdGlwIHNob3dzIGp1c3QgdGhlIGhvdmVyZWQgYmFyLlxuICAgIHRvb2x0aXA6IHsgdHJpZ2dlcjogY29sb3JCeSA/ICdpdGVtJyA6ICdheGlzJyB9LFxuICAgIHhBeGlzOiBob3Jpem9udGFsID8gdmFsdWVBeGlzIDogY2F0ZWdvcnlBeGlzLFxuICAgIHlBeGlzOiBob3Jpem9udGFsID8gY2F0ZWdvcnlBeGlzIDogdmFsdWVBeGlzLFxuICAgIHNlcmllcyxcbiAgfTtcbn1cblxuLy8gVGhlIGNhdGVnb3J5IGF4aXMgb2YgYW4gYXhpcyBjaGFydCBvciBhIHdhdGVyZmFsbDogdGhlIGNhdGVnb3JpZXMgaW4gcm93XG4vLyBvcmRlciwgbGFiZWxlZCBhcyBwZXJpb2RzIHdoZW4gdGhlIHJvd3Mgd2VyZSBidWNrZXRlZCBieSB0aW1lLlxuLy9cbi8vIEhvcml6b250YWwgYmFycyByZWFkIHRvcC1kb3duOiBFQ2hhcnRzIGRyYXdzIGNhdGVnb3J5IDAgYXQgdGhlIGJvdHRvbSwgc28gdGhlXG4vLyBheGlzIGlzIGludmVydGVkIHRvIHB1dCB0aGUgZmlyc3Qgcm93ICh0aGUgbGFyZ2VzdCBvZiBhIHRvcC1OLCBhIHdhdGVyZmFsbCdzXG4vLyBmaXJzdCBzdGVwKSBhdCB0aGUgdG9wLiBUaGUgcm90YXRlZCB0aXRsZSBzaXRzIGp1c3QgYmV5b25kIHRoZSBsb25nZXN0IGxhYmVsXG4vLyByYXRoZXIgdGhhbiBhdCBhIGZpeGVkIGdhcCB0aGF0IHdvdWxkIHB1dCBpdCBvbiB0b3Agb2YgdGhlIGxhYmVscy5cbmZ1bmN0aW9uIGNhdGVnb3J5QXhpc09wdGlvbihjb25maWc6IENoYXJ0Q29uZmlnLCBkYXRhOiBDb21wb25lbnREYXRhLCBjYXRlZ29yaWVzOiBzdHJpbmdbXSwgaG9yaXpvbnRhbDogYm9vbGVhbikge1xuICBjb25zdCBncmFudWxhcml0eSA9IGJ1Y2tldEdyYW51bGFyaXR5KGRhdGEpO1xuICBjb25zdCBwZXJpb2RMYWJlbCA9IHBlcmlvZEF4aXNMYWJlbChncmFudWxhcml0eSwgY2F0ZWdvcmllcyk7XG4gIGNvbnN0IGF4aXMgPSB7XG4gICAgdHlwZTogJ2NhdGVnb3J5JyBhcyBjb25zdCxcbiAgICBkYXRhOiBjYXRlZ29yaWVzLFxuICAgIGludmVyc2U6IGhvcml6b250YWwsXG4gICAgbmFtZTogY29uZmlnLnhBeGlzPy5sYWJlbCxcbiAgICBuYW1lTG9jYXRpb246ICdtaWRkbGUnIGFzIGNvbnN0LFxuICB9O1xuXG4gIGlmICghaG9yaXpvbnRhbCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5heGlzLFxuICAgICAgbmFtZUdhcDogZ3JhbnVsYXJpdHkgJiYgc3BhbnNNdWx0aXBsZVllYXJzKGNhdGVnb3JpZXMpID8gNDAgOiAyOCxcbiAgICAgIC4uLnBlcmlvZExhYmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBBIHBlcmlvZCBsYWJlbCAoJ01heScsICdRMicpIGlzIGFsd2F5cyBzaG9ydCwgc28gb25seSBhIHBsYWluIGNhdGVnb3J5IGlzXG4gIC8vIGN1dCBzaG9ydC4gVGhlIGxhYmVscyBhcmUgY3V0IGhlcmUgcmF0aGVyIHRoYW4gYnkgRUNoYXJ0cycgb3duIHRydW5jYXRpb24sXG4gIC8vIHNvIHRoZSB0aXRsZSdzIGdhcCBpcyBtZWFzdXJlZCBvbiBleGFjdGx5IHRoZSB0ZXh0IHRoZSBheGlzIGRyYXdzLlxuICBjb25zdCBzaG93biA9IGdyYW51bGFyaXR5XG4gICAgPyBudWxsXG4gICAgOiBuZXcgTWFwKGNhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gW2NhdGVnb3J5LCB0cnVuY2F0ZUF4aXNMYWJlbChjYXRlZ29yeSldKSk7XG4gIGNvbnN0IGxhYmVscyA9IHNob3duID8gWy4uLnNob3duLnZhbHVlcygpXSA6IGRpc3BsYXllZENhdGVnb3J5TGFiZWxzKGNhdGVnb3JpZXMsIGdyYW51bGFyaXR5KTtcblxuICByZXR1cm4ge1xuICAgIC4uLmF4aXMsXG4gICAgbmFtZUdhcDogd2lkZXN0QXhpc0xhYmVsKGxhYmVscykgKyBBWElTX0xBQkVMX01BUkdJTiArIEFYSVNfTkFNRV9DTEVBUkFOQ0UsXG4gICAgLi4uKHNob3duID8geyBheGlzTGFiZWw6IHsgZm9ybWF0dGVyOiAodmFsdWU6IHN0cmluZykgPT4gc2hvd24uZ2V0KHZhbHVlKSA/PyB2YWx1ZSB9IH0gOiBwZXJpb2RMYWJlbCksXG4gIH07XG59XG5cbi8vIFRoZSBjYXRlZ29yeSBheGlzJ3MgdGl0bGUgc2lkZSwgb3IgbnVsbCB3aGVuIHRoZSBheGlzIGhhcyBubyB0aXRsZSB0byBtYWtlXG4vLyByb29tIGZvci5cbmZ1bmN0aW9uIGNhdGVnb3J5VGl0bGVTaWRlKGNvbmZpZzogQ2hhcnRDb25maWcsIGhvcml6b250YWw6IGJvb2xlYW4pOiBBeGlzVGl0bGVTaWRlIHwgbnVsbCB7XG4gIGlmICghY29uZmlnLnhBeGlzPy5sYWJlbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGhvcml6b250YWwgPyAnbGVmdCcgOiAnYm90dG9tJztcbn1cblxuLy8gVGhlIHRpY2sgbGFiZWxzIGFzIHRoZSBheGlzIHNob3dzIHRoZW06IGEgYnVja2V0J3MgcHJpbWFyeSBwZXJpb2QgbGFiZWxcbi8vICgnTWF5JywgJ1EyJyksIG90aGVyd2lzZSB0aGUgY2F0ZWdvcnkgaXRzZWxmLiBUaGUgeWVhciBhIG11bHRpLXllYXIgYXhpc1xuLy8gcHJpbnRzIHVuZGVyIGEgcGVyaW9kIGlzIGxlZnQgb3V0LCBhcyBpdCBpcyBuZXZlciB0aGUgd2lkZXIgbGluZS5cbmZ1bmN0aW9uIGRpc3BsYXllZENhdGVnb3J5TGFiZWxzKGNhdGVnb3JpZXM6IHN0cmluZ1tdLCBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBncmFudWxhcml0eVxuICAgID8gY2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5KSA9PiBwZXJpb2RMYWJlbFBhcnRzKGNhdGVnb3J5LCBncmFudWxhcml0eSk/LnByaW1hcnkgPz8gY2F0ZWdvcnkpXG4gICAgOiBjYXRlZ29yaWVzO1xufVxuXG4vLyBUaGUgcGl4ZWwgd2lkdGggb2YgdGhlIHdpZGVzdCBsYWJlbC4gQSBsYWJlbCB0aGF0IGJyZWFrcyBvdmVyIHNldmVyYWwgbGluZXNcbi8vIGlzIGFzIHdpZGUgYXMgaXRzIGxvbmdlc3QgbGluZS5cbmZ1bmN0aW9uIHdpZGVzdEF4aXNMYWJlbChsYWJlbHM6IHN0cmluZ1tdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGxhYmVscy5yZWR1Y2UoKHdpZGVzdCwgbGFiZWwpID0+IGxhYmVsLnNwbGl0KCdcXG4nKS5yZWR1Y2UoXG4gICAgKGxpbmVXaWRlc3QsIGxpbmUpID0+IE1hdGgubWF4KGxpbmVXaWRlc3QsIGF4aXNMYWJlbFdpZHRoKGxpbmUpKSxcbiAgICB3aWRlc3QsXG4gICksIDApO1xufVxuXG4vLyBBIGNhdGVnb3J5IGxhYmVsIGN1dCB0byBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEgsIGxpbmUgYnkgbGluZTogdGhlIGxvbmdlc3Rcbi8vIHN0YXJ0IG9mIGVhY2ggbGluZSB0aGF0IHN0aWxsIGZpdHMgd2l0aCB0aGUgZWxsaXBzaXMgYWZ0ZXIgaXQuXG5mdW5jdGlvbiB0cnVuY2F0ZUF4aXNMYWJlbChsYWJlbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGxhYmVsLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmUpID0+IHtcbiAgICBpZiAoYXhpc0xhYmVsV2lkdGgobGluZSkgPD0gQ0FURUdPUllfTEFCRUxfTUFYX1dJRFRIKSB7XG4gICAgICByZXR1cm4gbGluZTtcbiAgICB9XG5cbiAgICAvLyBDb2RlIHBvaW50cywgc28gYW4gZW1vamkgb3Igb3RoZXIgc3Vycm9nYXRlIHBhaXIgaXMgbmV2ZXIgc3BsaXQuXG4gICAgY29uc3QgY2hhcmFjdGVycyA9IEFycmF5LmZyb20obGluZSk7XG4gICAgY29uc3QgY3V0ID0gKGxlbmd0aDogbnVtYmVyKSA9PiBgJHtjaGFyYWN0ZXJzLnNsaWNlKDAsIGxlbmd0aCkuam9pbignJykudHJpbUVuZCgpfSR7TEFCRUxfRUxMSVBTSVN9YDtcbiAgICBsZXQgZml0cyA9IDA7XG4gICAgbGV0IHRvb0xvbmcgPSBjaGFyYWN0ZXJzLmxlbmd0aDtcbiAgICB3aGlsZSAodG9vTG9uZyAtIGZpdHMgPiAxKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBNYXRoLmZsb29yKChmaXRzICsgdG9vTG9uZykgLyAyKTtcbiAgICAgIGlmIChheGlzTGFiZWxXaWR0aChjdXQobGVuZ3RoKSkgPD0gQ0FURUdPUllfTEFCRUxfTUFYX1dJRFRIKSB7XG4gICAgICAgIGZpdHMgPSBsZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0b29Mb25nID0gbGVuZ3RoO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXQoZml0cyk7XG4gIH0pLmpvaW4oJ1xcbicpO1xufVxuXG4vLyBPbmUgbGluZSdzIHdpZHRoIGluIHRoZSBheGlzLWxhYmVsIGZvbnQsIG1lYXN1cmVkIG9uIGEgY2FudmFzIHRoZSB3YXlcbi8vIEVDaGFydHMgbWVhc3VyZXMgaXQgZm9yIGNvbnRhaW5MYWJlbC4gT3V0c2lkZSBhIGJyb3dzZXIgdGhlcmUgaXMgbm8gY2FudmFzXG4vLyB0byBtZWFzdXJlIHdpdGgsIHNvIHRoZSBsaW5lIGNvdW50cyBhcyB6ZXJvIHdpZHRoLlxubGV0IGF4aXNMYWJlbENvbnRleHQ6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCB8IG51bGwgPSBudWxsO1xuXG5mdW5jdGlvbiBheGlzTGFiZWxXaWR0aChsaW5lOiBzdHJpbmcpOiBudW1iZXIge1xuICBpZiAoIWF4aXNMYWJlbENvbnRleHQgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGF4aXNMYWJlbENvbnRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKS5nZXRDb250ZXh0KCcyZCcpO1xuICB9XG5cbiAgaWYgKCFheGlzTGFiZWxDb250ZXh0KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBheGlzTGFiZWxDb250ZXh0LmZvbnQgPSBBWElTX0xBQkVMX0ZPTlQ7XG5cbiAgcmV0dXJuIGF4aXNMYWJlbENvbnRleHQubWVhc3VyZVRleHQobGluZSkud2lkdGg7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkV2F0ZXJmYWxsT3B0aW9uKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCBkYXRhOiBDb21wb25lbnREYXRhKTogRUNoYXJ0c09wdGlvbiB7XG4gIGNvbnN0IGNvbmZpZyA9IGNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWc7XG4gIGNvbnN0IHdhdGVyZmFsbCA9IGV4dHJhY3RXYXRlcmZhbGwoY29tcG9uZW50LCBkYXRhKTtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGNvbmZpZy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnO1xuICBjb25zdCBjYXRlZ29yeUF4aXMgPSBjYXRlZ29yeUF4aXNPcHRpb24oY29uZmlnLCBkYXRhLCB3YXRlcmZhbGwuc3RlcHMubWFwKChzdGVwKSA9PiBzdGVwLmNhdGVnb3J5KSwgaG9yaXpvbnRhbCk7XG4gIGNvbnN0IHZhbHVlQXhpcyA9IHsgdHlwZTogJ3ZhbHVlJyBhcyBjb25zdCB9O1xuICAvLyBPbmUgdmlzaWJsZSBzZXJpZXMsIHNvIHRoZSBsZWdlbmQgaXMgaGlkZGVuIHVubGVzcyB0aGUgY29uZmlnIHBpbnMgaXQuXG4gIGNvbnN0IGxlZ2VuZFBvc2l0aW9uID0gcmVzb2x2ZUxlZ2VuZFBvc2l0aW9uKGNvbmZpZywgMSk7XG4gIGNvbnN0IGdyYW51bGFyaXR5ID0gYnVja2V0R3JhbnVsYXJpdHkoZGF0YSk7XG5cbiAgcmV0dXJuIHtcbiAgICBncmlkOiBheGlzR3JpZChsZWdlbmRQb3NpdGlvbiwgY2F0ZWdvcnlUaXRsZVNpZGUoY29uZmlnLCBob3Jpem9udGFsKSksXG4gICAgbGVnZW5kOiB7IC4uLmxlZ2VuZE9wdGlvbihsZWdlbmRQb3NpdGlvbiksIGRhdGE6IFt3YXRlcmZhbGwubmFtZV0gfSxcbiAgICAvLyBQZXIgYmFyOiB0aGUgaW52aXNpYmxlIGJhc2UgaXMgc2lsZW50LCBzbyBvbmx5IGEgc3RlcCBhbnN3ZXJzIHRoZSBob3Zlci5cbiAgICB0b29sdGlwOiB7XG4gICAgICB0cmlnZ2VyOiAnaXRlbScsXG4gICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcykgPT4gd2F0ZXJmYWxsVG9vbHRpcChcbiAgICAgICAgd2F0ZXJmYWxsLFxuICAgICAgICAoQXJyYXkuaXNBcnJheShwYXJhbXMpID8gcGFyYW1zWzBdIDogcGFyYW1zKS5kYXRhSW5kZXgsXG4gICAgICAgIGdyYW51bGFyaXR5LFxuICAgICAgKSxcbiAgICB9LFxuICAgIHhBeGlzOiBob3Jpem9udGFsID8gdmFsdWVBeGlzIDogY2F0ZWdvcnlBeGlzLFxuICAgIHlBeGlzOiBob3Jpem9udGFsID8gY2F0ZWdvcnlBeGlzIDogdmFsdWVBeGlzLFxuICAgIHNlcmllczogd2F0ZXJmYWxsU2VyaWVzKHdhdGVyZmFsbCksXG4gIH07XG59XG5cbi8vIEFuIGludmlzaWJsZSBiYXNlIHNlcmllcyBsaWZ0cyBlYWNoIHZpc2libGUgYmFyIHRvIHdoZXJlIGl0cyBzdGVwIHN0YXJ0cy5cbi8vIEJvdGggc3RhY2sgd2l0aCB0aGUgJ2FsbCcgc3RyYXRlZ3ksIHdoaWNoIGFkZHMgc2lnbmVkIHZhbHVlcyBpbiBzZXJpZXMgb3JkZXIsXG4vLyBzbyBhIGZhbGwgZHJhd3MgRE9XTiBmcm9tIHRoZSB0b3RhbCBiZWZvcmUgaXQsIGV2ZW4gYWNyb3NzIHplcm8uIFRoZSBkZWZhdWx0XG4vLyBzYW1lLXNpZ24gc3RhY2tpbmcgd291bGQgaGFuZyBhIG5lZ2F0aXZlIGJhciBiZWxvdyB0aGUgYXhpcyBpbnN0ZWFkLlxuZnVuY3Rpb24gd2F0ZXJmYWxsU2VyaWVzKHdhdGVyZmFsbDogRXh0cmFjdGVkV2F0ZXJmYWxsKTogU2VyaWVzT3B0aW9uW10ge1xuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgc3RhY2s6ICd3YXRlcmZhbGwnLFxuICAgICAgc3RhY2tTdHJhdGVneTogJ2FsbCcsXG4gICAgICBkYXRhOiB3YXRlcmZhbGwuc3RlcHMubWFwKChzdGVwKSA9PiBzdGVwLnN0YXJ0KSxcbiAgICAgIGJhck1heFdpZHRoOiA0OCxcbiAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogJ3RyYW5zcGFyZW50JyB9LFxuICAgICAgc2lsZW50OiB0cnVlLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogd2F0ZXJmYWxsLm5hbWUsXG4gICAgICB0eXBlOiAnYmFyJyxcbiAgICAgIHN0YWNrOiAnd2F0ZXJmYWxsJyxcbiAgICAgIHN0YWNrU3RyYXRlZ3k6ICdhbGwnLFxuICAgICAgYmFyTWF4V2lkdGg6IDQ4LFxuICAgICAgLy8gVGhlIHNlcmllcyBjb2xvciBpcyB0aGUgcmlzZSBjb2xvciBzbyBhIHBpbm5lZCBsZWdlbmQgc2hvd3MgaXQ7IGVhY2hcbiAgICAgIC8vIGJhciBpcyB0aGVuIGNvbG9yZWQgYnkgd2hhdCBpdCBkb2VzIHRvIHRoZSB0b3RhbC5cbiAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogYCMke1JFUE9SVF9XQVRFUkZBTExfQ09MT1JTLnJpc2V9YCB9LFxuICAgICAgZGF0YTogd2F0ZXJmYWxsLnN0ZXBzLm1hcCgoc3RlcCkgPT4gKHtcbiAgICAgICAgdmFsdWU6IHN0ZXAuY2hhbmdlLFxuICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGAjJHtSRVBPUlRfV0FURVJGQUxMX0NPTE9SU1tzdGVwLmtpbmRdfWAgfSxcbiAgICAgIH0pKSxcbiAgICB9LFxuICBdO1xufVxuXG4vLyBBIHN0ZXAncyB0b29sdGlwOiBpdHMgcGVyaW9kLCBob3cgZmFyIGl0IG1vdmVkIHRoZSBydW5uaW5nIHRvdGFsIGFuZCB3aGVyZVxuLy8gdGhhdCBsZWZ0IGl0LiBUaGUgY2xvc2luZyBUb3RhbCBzaG93cyB0aGUgdG90YWwgYWxvbmUuIFRoZSBjYXRlZ29yeSBhbmQgdGhlXG4vLyBtZWFzdXJlIG5hbWUgY29tZSBmcm9tIHRoZSBkYXRhIGFuZCB0aGUgY29uZmlnLCBhbmQgRUNoYXJ0cyBzZXRzIHRoZSB0b29sdGlwXG4vLyBhcyBIVE1MLCBzbyBib3RoIGFyZSBlc2NhcGVkLlxuZnVuY3Rpb24gd2F0ZXJmYWxsVG9vbHRpcCh3YXRlcmZhbGw6IEV4dHJhY3RlZFdhdGVyZmFsbCwgaW5kZXg6IG51bWJlciwgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RlcCA9IHdhdGVyZmFsbC5zdGVwc1tpbmRleF07XG4gIGNvbnN0IGNhdGVnb3J5ID0gZXNjYXBlSHRtbChncmFudWxhcml0eSA/IGZvcm1hdFBlcmlvZExhYmVsKHN0ZXAuY2F0ZWdvcnksIGdyYW51bGFyaXR5LCB0cnVlKSA6IHN0ZXAuY2F0ZWdvcnkpO1xuICBjb25zdCBuYW1lID0gZXNjYXBlSHRtbCh3YXRlcmZhbGwubmFtZSk7XG5cbiAgaWYgKHN0ZXAua2luZCA9PT0gJ3RvdGFsJykge1xuICAgIHJldHVybiBgJHtjYXRlZ29yeX08YnIvPiR7bmFtZX06ICR7Zm9ybWF0TWVhc3VyZVZhbHVlKHN0ZXAuY2hhbmdlKX1gO1xuICB9XG5cbiAgY29uc3Qgc2lnbiA9IChzdGVwLmNoYW5nZSA/PyAwKSA+IDAgPyAnKycgOiAnJztcblxuICByZXR1cm4gYCR7Y2F0ZWdvcnl9PGJyLz4ke25hbWV9OiAke3NpZ259JHtmb3JtYXRNZWFzdXJlVmFsdWUoc3RlcC5jaGFuZ2UpfWBcbiAgICArIGA8YnIvPlJ1bm5pbmcgdG90YWw6ICR7Zm9ybWF0TWVhc3VyZVZhbHVlKHN0ZXAuc3RhcnQgKyAoc3RlcC5jaGFuZ2UgPz8gMCkpfWA7XG59XG5cbi8vIERlZmF1bHQgbGVnZW5kIHBsYWNlbWVudCB3aGVuIHRoZSBjb25maWcgZG9lc24ndCBwaW4gb25lOiBwaWUgY2hhcnRzIHJlYWRcbi8vIGJlc3Qgd2l0aCB0aGUgc2xpY2Uga2V5IGJlc2lkZSB0aGVtIChyaWdodCk7IGF4aXMgY2hhcnRzIG9ubHkgbmVlZCBhIGxlZ2VuZFxuLy8gdG8gdGVsbCBtdWx0aXBsZSBzZXJpZXMgYXBhcnQsIHNvIGEgc2luZ2xlLXNlcmllcyBjaGFydCBoaWRlcyBpdC4gQW4gZXhwbGljaXRcbi8vIGNvbmZpZy5sZWdlbmQgKGluY2x1ZGluZyAnaGlkZGVuJykgYWx3YXlzIHdpbnMuIFNoYXJlZCB3aXRoIHRoZSBQb3dlclBvaW50XG4vLyBleHBvcnQgc28gYm90aCBtZWRpYSBwbGFjZSB0aGUgbGVnZW5kIGlkZW50aWNhbGx5LlxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVMZWdlbmRQb3NpdGlvbihjb25maWc6IENoYXJ0Q29uZmlnLCBzZXJpZXNDb3VudDogbnVtYmVyLCBjb2xvckJ5ID0gZmFsc2UpOiBMZWdlbmRQb3NpdGlvbiB7XG4gIGlmIChjb25maWcubGVnZW5kKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5sZWdlbmQ7XG4gIH1cblxuICBjb25zdCBwaWUgPSBjb25maWcuY2hhcnRUeXBlID09PSAncGllJyB8fCBjb25maWcuY2hhcnRUeXBlID09PSAnZG9udXQnO1xuXG4gIC8vIGNvbG9yQnkgbWFwcyBlYWNoIGJhcidzIGNvbG9yIHRvIGl0cyBjYXRlZ29yeSwgc28gaXQgbmVlZHMgYSBsZWdlbmQgZXZlblxuICAvLyB0aG91Z2ggaXQncyBhIHNpbmdsZSBtZWFzdXJlLlxuICByZXR1cm4gcGllIHx8IGNvbG9yQnkgfHwgc2VyaWVzQ291bnQgPiAxID8gKHBpZSA/ICdyaWdodCcgOiAndG9wJykgOiAnaGlkZGVuJztcbn1cblxuZnVuY3Rpb24gbGVnZW5kT3B0aW9uKHBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbik6IExlZ2VuZENvbXBvbmVudE9wdGlvbiB7XG4gIGlmIChwb3NpdGlvbiA9PT0gJ2hpZGRlbicpIHtcbiAgICByZXR1cm4geyBzaG93OiBmYWxzZSB9O1xuICB9XG5cbiAgY29uc3QgYmFzZTogTGVnZW5kQ29tcG9uZW50T3B0aW9uID0geyB0eXBlOiAnc2Nyb2xsJyB9O1xuXG4gIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICBjYXNlICdib3R0b20nOlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgYm90dG9tOiAwIH07XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBvcmllbnQ6ICd2ZXJ0aWNhbCcsIGxlZnQ6IDAsIHRvcDogJ21pZGRsZScgfTtcbiAgICBjYXNlICdyaWdodCc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBvcmllbnQ6ICd2ZXJ0aWNhbCcsIHJpZ2h0OiAwLCB0b3A6ICdtaWRkbGUnIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIHRvcDogMCB9O1xuICB9XG59XG5cbi8vIFRoZSBwbG90J3MgZ3JpZDogcm9vbSBvbiB0aGUgbGVnZW5kJ3Mgc2lkZSBzbyBpdCBuZXZlciBvdmVybGFwcyB0aGVcbi8vIGJhcnMvbGluZXMsIHBsdXMgcm9vbSBmb3IgdGhlIGNhdGVnb3J5IGF4aXMncyB0aXRsZSBvbiBpdHMgc2lkZSwgd2hpY2hcbi8vIGNvbnRhaW5MYWJlbCBkb2VzIG5vdCByZXNlcnZlIChpdCBjb3ZlcnMgdGhlIHRpY2sgbGFiZWxzIG9ubHkpLlxuZnVuY3Rpb24gYXhpc0dyaWQocG9zaXRpb246IExlZ2VuZFBvc2l0aW9uLCB0aXRsZVNpZGU6IEF4aXNUaXRsZVNpZGUgfCBudWxsKTogRUNoYXJ0c09wdGlvblsnZ3JpZCddIHtcbiAgY29uc3QgZ3JpZCA9IGxlZ2VuZEdyaWQocG9zaXRpb24pO1xuXG4gIHN3aXRjaCAodGl0bGVTaWRlKSB7XG4gICAgY2FzZSAnYm90dG9tJzpcbiAgICAgIHJldHVybiB7IC4uLmdyaWQsIGJvdHRvbTogZ3JpZC5ib3R0b20gKyBBWElTX05BTUVfUk9PTSB9O1xuICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgcmV0dXJuIHsgLi4uZ3JpZCwgbGVmdDogZ3JpZC5sZWZ0ICsgQVhJU19OQU1FX1JPT00gfTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGdyaWQ7XG4gIH1cbn1cblxuLy8gUGxvdC1lZGdlIHJvb20gb24gd2hpY2hldmVyIHNpZGUgdGhlIGxlZ2VuZCBvY2N1cGllczsgY29udGFpbkxhYmVsIGtlZXBzIHRoZVxuLy8gdGljayBsYWJlbHMgaW5zaWRlIHdoYXQgaXMgbGVmdC5cbmZ1bmN0aW9uIGxlZ2VuZEdyaWQocG9zaXRpb246IExlZ2VuZFBvc2l0aW9uKTogQXhpc0dyaWRSb29tIHtcbiAgY29uc3QgYmFzZTogQXhpc0dyaWRSb29tID0geyBsZWZ0OiA4LCByaWdodDogMTYsIHRvcDogOCwgYm90dG9tOiA4LCBjb250YWluTGFiZWw6IHRydWUgfTtcblxuICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgY2FzZSAnYm90dG9tJzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIGJvdHRvbTogMzIgfTtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIGxlZnQ6IDk2IH07XG4gICAgY2FzZSAncmlnaHQnOlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgcmlnaHQ6IDk2IH07XG4gICAgY2FzZSAnaGlkZGVuJzpcbiAgICAgIHJldHVybiBiYXNlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCB0b3A6IDMyIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gYnVpbGRTZXJpZXMoXG4gIG5hbWU6IHN0cmluZyxcbiAgdmFsdWVzOiAobnVtYmVyIHwgbnVsbClbXSxcbiAgdHlwZTogQXhpc0NoYXJ0VHlwZSxcbiAgc3RhY2s6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgb3ZlcmxhcDogYm9vbGVhbixcbiAgY29tYm86IGJvb2xlYW4sXG4pOiBTZXJpZXNPcHRpb24ge1xuICBpZiAodHlwZSA9PT0gJ2JhcicpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgZGF0YTogdmFsdWVzLFxuICAgICAgc3RhY2ssXG4gICAgICBiYXJNYXhXaWR0aDogNDgsXG4gICAgICAvLyBjb2xvckJ5OiBvdmVybGFwIHRoZSBwZXItY2F0ZWdvcnkgc2VyaWVzIHNvIGVhY2ggYmFyIHJlbmRlcnMgZnVsbC13aWR0aC5cbiAgICAgIC4uLihvdmVybGFwID8geyBiYXJHYXA6ICctMTAwJScsIGJhckNhdGVnb3J5R2FwOiAnMjAlJyB9IDoge30pLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgdHlwZTogJ2xpbmUnLFxuICAgIGRhdGE6IHZhbHVlcyxcbiAgICBzdGFjayxcbiAgICBzbW9vdGg6IHRydWUsXG4gICAgc3ltYm9sU2l6ZTogNixcbiAgICBhcmVhU3R5bGU6IHR5cGUgPT09ICdhcmVhJyA/IHsgb3BhY2l0eTogMC4yNSB9IDogdW5kZWZpbmVkLFxuICAgIC8vIEluIGEgY29tYm8gdGhlIGxpbmUgaXMgZHJhd24gb3ZlciB0aGUgYmFycyB3aGF0ZXZlciBvcmRlciB0aGUgbWVhc3VyZXNcbiAgICAvLyBjb21lIGluOyBhdCB0aGUgc2FtZSB6IGEgbGF0ZXIgYmFyIHNlcmllcyB3b3VsZCBwYWludCBhY3Jvc3MgaXQuXG4gICAgLi4uKGNvbWJvID8geyB6OiAzIH0gOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkUGllT3B0aW9uKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCBkYXRhOiBDb21wb25lbnREYXRhLCBkb251dDogYm9vbGVhbik6IEVDaGFydHNPcHRpb24ge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCBleHRyYWN0ZWQgPSBleHRyYWN0Q2hhcnRTZXJpZXMoY29tcG9uZW50LCBkYXRhKTtcbiAgY29uc3QgdmFsdWVzID0gZXh0cmFjdGVkLnNlcmllc1swXT8udmFsdWVzID8/IFtdO1xuICBjb25zdCBsZWdlbmRQb3NpdGlvbiA9IHJlc29sdmVMZWdlbmRQb3NpdGlvbihjb25maWcsIGV4dHJhY3RlZC5zZXJpZXMubGVuZ3RoKTtcblxuICByZXR1cm4ge1xuICAgIHRvb2x0aXA6IHsgdHJpZ2dlcjogJ2l0ZW0nIH0sXG4gICAgbGVnZW5kOiBsZWdlbmRPcHRpb24obGVnZW5kUG9zaXRpb24pLFxuICAgIHNlcmllczogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAncGllJyxcbiAgICAgICAgcmFkaXVzOiBkb251dCA/IFsnNDUlJywgJzcyJSddIDogJzcyJScsXG4gICAgICAgIGNlbnRlcjogcGllQ2VudGVyKGxlZ2VuZFBvc2l0aW9uKSxcbiAgICAgICAgbGFiZWw6IHsgc2hvdzogZmFsc2UgfSxcbiAgICAgICAgZGF0YTogZXh0cmFjdGVkLmNhdGVnb3JpZXMubWFwKChjYXRlZ29yeSwgaW5kZXgpID0+ICh7XG4gICAgICAgICAgbmFtZTogY2F0ZWdvcnksXG4gICAgICAgICAgdmFsdWU6IHZhbHVlc1tpbmRleF0gPz8gMCxcbiAgICAgICAgfSkpLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xufVxuXG4vLyBOdWRnZSB0aGUgcGllIG9mZi1jZW50ZXIgdG93YXJkIHRoZSBvcHBvc2l0ZSBlZGdlIGZyb20gaXRzIGxlZ2VuZCBzbyB0aGUgdHdvXG4vLyBkb24ndCBjb2xsaWRlOyBjZW50ZXJlZCB3aGVuIHRoZSBsZWdlbmQgaXMgaGlkZGVuLlxuZnVuY3Rpb24gcGllQ2VudGVyKHBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbik6IFtzdHJpbmcsIHN0cmluZ10ge1xuICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgICByZXR1cm4gWyc2MCUnLCAnNTAlJ107XG4gICAgY2FzZSAncmlnaHQnOlxuICAgICAgcmV0dXJuIFsnNDAlJywgJzUwJSddO1xuICAgIGNhc2UgJ3RvcCc6XG4gICAgICByZXR1cm4gWyc1MCUnLCAnNTglJ107XG4gICAgY2FzZSAnYm90dG9tJzpcbiAgICAgIHJldHVybiBbJzUwJScsICc0NiUnXTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFsnNTAlJywgJzUwJSddO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuaXF1ZVZhbHVlcyhyb3dzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLCBjb2x1bW46IHN0cmluZyk6IHVua25vd25bXSB7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHVua25vd24+KCk7XG4gIGNvbnN0IHZhbHVlczogdW5rbm93bltdID0gW107XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHJvd1tjb2x1bW5dO1xuICAgIGlmICghc2Vlbi5oYXModmFsdWUpKSB7XG4gICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuZnVuY3Rpb24gbnVtZXJpYyh2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IG51bGwge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG5cbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShwYXJzZWQpID8gcGFyc2VkIDogbnVsbDtcbn1cblxuLy8gVGhlIGVmZmVjdGl2ZSB0aW1lIGJ1Y2tldCB0aGUgcm93cyB3ZXJlIGdyb3VwZWQgaW50byAoZnJvbSB0aGUgZGF0YSBlbmRwb2ludCksXG4vLyBvciBudWxsIHdoZW4gdGhlIHgtYXhpcyBpc24ndCBhIHRpbWUgYXhpcyDigJQgZ2F0ZXMgdGhlIGNvbXBhY3QgcGVyaW9kIGxhYmVscy5cbmZ1bmN0aW9uIGJ1Y2tldEdyYW51bGFyaXR5KGRhdGE6IENvbXBvbmVudERhdGEpOiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCB7XG4gIHJldHVybiBkYXRhLmdyYW51bGFyaXR5ICYmIEdSQU5VTEFSSVRZX09QVElPTlMuc29tZSgob3B0aW9uKSA9PiBvcHRpb24udmFsdWUgPT09IGRhdGEuZ3JhbnVsYXJpdHkpXG4gICAgPyBkYXRhLmdyYW51bGFyaXR5XG4gICAgOiBudWxsO1xufVxuXG4vLyBXaGV0aGVyIHRoZSBwZXJpb2Qtc3RhcnQgY2F0ZWdvcmllcyBjcm9zcyBhIHllYXIgYm91bmRhcnkuIFdoZW4gdGhleSBkb24ndCxcbi8vIHRoZSB5ZWFyIGlzIHB1cmUgbm9pc2Ugb24gZXZlcnkgbGFiZWwsIHNvIGl0J3MgZHJvcHBlZCBlbnRpcmVseS5cbmV4cG9ydCBmdW5jdGlvbiBzcGFuc011bHRpcGxlWWVhcnMoY2F0ZWdvcmllczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgY29uc3QgeWVhcnMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yaWVzKSB7XG4gICAgY29uc3QgZGF0ZSA9IHBhcnNlSVNPKGNhdGVnb3J5KTtcbiAgICBpZiAoaXNWYWxpZChkYXRlKSkge1xuICAgICAgeWVhcnMuYWRkKGRhdGUuZ2V0RnVsbFllYXIoKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHllYXJzLnNpemUgPiAxO1xufVxuXG4vLyBBIGJ1Y2tldCdzIHBlcmlvZC1zdGFydCBzcGxpdCBpbnRvIGl0cyBwcmltYXJ5IGxhYmVsIGFuZCBpdHMgeWVhci4gRGF5L3dlZWtcbi8vIHJlYWQgYXMgXCJNYXkgMVwiLCBtb250aCBhcyBcIk1heVwiLCBxdWFydGVyIGFzIFwiUTJcIiwgeWVhciBhcyBcIjIwMjVcIi4gUmV0dXJucyBudWxsXG4vLyBmb3IgYSB2YWx1ZSB0aGF0IGlzbid0IGEgcGFyc2VhYmxlIGRhdGUgKGxlZnQgYXMtaXMgYnkgY2FsbGVycykuXG5mdW5jdGlvbiBwZXJpb2RMYWJlbFBhcnRzKHZhbHVlOiBzdHJpbmcsIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5KTogeyBwcmltYXJ5OiBzdHJpbmc7IHllYXI6IHN0cmluZyB9IHwgbnVsbCB7XG4gIGNvbnN0IGRhdGUgPSBwYXJzZUlTTyh2YWx1ZSk7XG4gIGlmICghaXNWYWxpZChkYXRlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgeWVhciA9IFN0cmluZyhkYXRlLmdldEZ1bGxZZWFyKCkpO1xuICBzd2l0Y2ggKGdyYW51bGFyaXR5KSB7XG4gICAgY2FzZSAneWVhcic6XG4gICAgICByZXR1cm4geyBwcmltYXJ5OiB5ZWFyLCB5ZWFyIH07XG4gICAgY2FzZSAncXVhcnRlcic6XG4gICAgICByZXR1cm4geyBwcmltYXJ5OiBgUSR7TWF0aC5mbG9vcihkYXRlLmdldE1vbnRoKCkgLyAzKSArIDF9YCwgeWVhciB9O1xuICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgIHJldHVybiB7IHByaW1hcnk6IGZvcm1hdChkYXRlLCAnTU1NTScpLCB5ZWFyIH07XG4gICAgZGVmYXVsdDogLy8gZGF5LCB3ZWVrIOKAlCB0aGUgYnVja2V0IHN0YXJ0IGFzIGEgY29tcGFjdCBcIk1NTSBkXCJcbiAgICAgIHJldHVybiB7IHByaW1hcnk6IGZvcm1hdChkYXRlLCAnTU1NIGQnKSwgeWVhciB9O1xuICB9XG59XG5cbi8vIEEgY29tcGFjdCBzaW5nbGUtbGluZSBwZXJpb2QgbGFiZWwgKHllYXIgYXBwZW5kZWQgb25seSB3aGVuIHRoZSBkYXRhIHNwYW5zXG4vLyB5ZWFycykg4oCUIGZvciBtZWRpYSB0aGF0IGNhbid0IGRvIGEgc3R5bGVkIHNlY29uZCBsaW5lLCBlLmcuIFBvd2VyUG9pbnQuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UGVyaW9kTGFiZWwodmFsdWU6IHN0cmluZywgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHksIG11bHRpWWVhcjogYm9vbGVhbik6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnRzID0gcGVyaW9kTGFiZWxQYXJ0cyh2YWx1ZSwgZ3JhbnVsYXJpdHkpO1xuICBpZiAoIXBhcnRzKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG11bHRpWWVhciAmJiBncmFudWxhcml0eSAhPT0gJ3llYXInID8gYCR7cGFydHMucHJpbWFyeX0gJHtwYXJ0cy55ZWFyfWAgOiBwYXJ0cy5wcmltYXJ5O1xufVxuXG4vLyBBIGNyb3NzLXRhYidzIGNvbHVtbiBoZWFkaW5ncywgdGhlIG9uZSBydWxlIHRoZSBncmlkIGFuZCB0aGUgUERGL1Bvd2VyUG9pbnRcbi8vIGV4cG9ydHMgc2hhcmUuIFRoZSBmaXJzdCBpcyB0aGUgcm93IGtleSBhbmQga2VlcHMgaXRzIGF1dGhvcmVkIGxhYmVsOyB0aGVcbi8vIHJlc3QgYXJlIHBpdm90IFZBTFVFUy4gV2hlbiB0aGUgcGl2b3QgYXhpcyBpcyBhIHRpbWUgZGltZW5zaW9uIHRoZSBzZXJ2ZXJcbi8vIHNlbmRzIHRoZSBncmFpbiBpdCBidWNrZXRlZCBhdCwgc28gYSBwZXJpb2Qtc3RhcnQgbGlrZSBcIjIwMjYtMDEtMDFcIiByZWFkc1xuLy8gXCJKYW51YXJ5IDIwMjZcIiwgYXMgdGhlIGNoYXJ0J3MgeC1heGlzIGxhYmVscyBpdC5cbmV4cG9ydCBmdW5jdGlvbiBwaXZvdEhlYWRpbmdzKGNvbmZpZzogTGlzdENvbmZpZywgZGF0YTogQ29tcG9uZW50RGF0YSk6IHN0cmluZ1tdIHtcbiAgY29uc3QgY29sdW1ucyA9IGRhdGEuY29sdW1ucyA/PyBbXTtcbiAgY29uc3QgbXVsdGlZZWFyID0gc3BhbnNNdWx0aXBsZVllYXJzKGNvbHVtbnMpO1xuXG4gIHJldHVybiBjb2x1bW5zLm1hcCgoY29sdW1uLCBpbmRleCkgPT4ge1xuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbmZpZy5yb3dCeT8ubGFiZWwgfHwgY29sdW1uO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhLmdyYW51bGFyaXR5ID8gZm9ybWF0UGVyaW9kTGFiZWwoY29sdW1uLCBkYXRhLmdyYW51bGFyaXR5LCBtdWx0aVllYXIpIDogY29sdW1uO1xuICB9KTtcbn1cblxuLy8gRUNoYXJ0cyBjYXRlZ29yeS1heGlzIGxhYmVsIGNvbmZpZyBmb3IgYSB0aW1lIGJ1Y2tldDogdGhlIHByaW1hcnkgbGFiZWwgb25cbi8vIGxpbmUgb25lLCBhbmQg4oCUIG9ubHkgd2hlbiB0aGUgZGF0YSBzcGFucyBtdWx0aXBsZSB5ZWFycyDigJQgdGhlIHllYXIgb24gYSBzbWFsbFxuLy8gZ3JheSBzZWNvbmQgbGluZSwgY2VudGVyZWQgdW5kZXIgdGhlIHRpY2sgKHllYXIgZ3JhbnVsYXJpdHkgbmVlZHMgbm8gc2Vjb25kXG4vLyBsaW5lLCBpdCBhbHJlYWR5IGlzIHRoZSB5ZWFyKS4gRW1wdHkgZm9yIGEgbm9uLXRpbWUgYXhpcyAobGFiZWxzIGFzLWlzKS5cbmZ1bmN0aW9uIHBlcmlvZEF4aXNMYWJlbChncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwsIGNhdGVnb3JpZXM6IHN0cmluZ1tdKTogeyBheGlzTGFiZWw/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9IHtcbiAgaWYgKCFncmFudWxhcml0eSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IG11bHRpWWVhciA9IHNwYW5zTXVsdGlwbGVZZWFycyhjYXRlZ29yaWVzKTtcblxuICByZXR1cm4ge1xuICAgIGF4aXNMYWJlbDoge1xuICAgICAgZm9ybWF0dGVyOiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IHBlcmlvZExhYmVsUGFydHModmFsdWUsIGdyYW51bGFyaXR5KTtcbiAgICAgICAgaWYgKCFwYXJ0cykge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtdWx0aVllYXIgJiYgZ3JhbnVsYXJpdHkgIT09ICd5ZWFyJ1xuICAgICAgICAgID8gYCR7cGFydHMucHJpbWFyeX1cXG57eXJ8JHtwYXJ0cy55ZWFyfX1gXG4gICAgICAgICAgOiBwYXJ0cy5wcmltYXJ5O1xuICAgICAgfSxcbiAgICAgIHJpY2g6IHsgeXI6IHsgZm9udFNpemU6IDEwLCBjb2xvcjogJyM5YWEwYTYnLCBsaW5lSGVpZ2h0OiAxNCB9IH0sXG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==
1914
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvb3B0aW9uLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUNMLE9BQU8sRUFDUCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFFBQVEsRUFDUixRQUFRLEVBQ1IsVUFBVSxFQUNWLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLEdBQUcsSUFBSSxRQUFRLEVBQ2YsR0FBRyxJQUFJLFVBQVUsRUFDakIsUUFBUSxFQUNSLFVBQVUsR0FDWCxNQUFNLFVBQVUsQ0FBQztBQUVsQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNyRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsZ0JBQWdCLEVBRWhCLGNBQWMsRUFDZCxxQkFBcUIsRUFDckIsU0FBUyxFQUNULFVBQVUsRUFDVixjQUFjLEVBQ2QsZUFBZSxFQUNmLGVBQWUsRUFFZixZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsZUFBZSxFQUNmLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLHdCQUF3QixFQUN4QixVQUFVLEdBQ1gsTUFBTSxV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RCxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFO1NBQ2pFO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEVDaGFydHNPcHRpb24sIExlZ2VuZENvbXBvbmVudE9wdGlvbiwgU2VyaWVzT3B0aW9uLCBUb29sdGlwQ29tcG9uZW50Rm9ybWF0dGVyQ2FsbGJhY2tQYXJhbXMgfSBmcm9tICdlY2hhcnRzJztcblxuaW1wb3J0IHtcbiAgYWRkRGF5cyxcbiAgYWRkTW9udGhzLFxuICBhZGRRdWFydGVycyxcbiAgYWRkV2Vla3MsXG4gIGFkZFllYXJzLFxuICBlbmRPZk1vbnRoLFxuICBmb3JtYXRJU08sXG4gIGlzTGFzdERheU9mTW9udGgsXG4gIGlzVmFsaWQsXG4gIG1heCBhcyBsYXRlc3RPZixcbiAgbWluIGFzIGVhcmxpZXN0T2YsXG4gIHBhcnNlSVNPLFxuICBzdGFydE9mRGF5LFxufSBmcm9tICdkYXRlLWZucyc7XG5cbmltcG9ydCB7IFJlcG9ydENoYXJ0Q29sb3IgfSBmcm9tICcuL2VudW1zL3JlcG9ydC1jaGFydC1jb2xvci5lbnVtJztcbmltcG9ydCB7IFJlcG9ydENoYXJ0RGF0YUxhYmVscyB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWRhdGEtbGFiZWxzLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnREYXRlTGFiZWwgfSBmcm9tICcuL2VudW1zL3JlcG9ydC1jaGFydC1kYXRlLWxhYmVsLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnRMaW5lU3R5bGUgfSBmcm9tICcuL2VudW1zL3JlcG9ydC1jaGFydC1saW5lLXN0eWxlLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnRNYXJrU3RhdCB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LW1hcmstc3RhdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQgfSBmcm9tICcuL2VudW1zL3JlcG9ydC1saXN0LWNvbHVtbi1mb3JtYXQuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnROdW1iZXJVbml0cyB9IGZyb20gJy4vZW51bXMvcmVwb3J0LW51bWJlci11bml0cy5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybWF0IH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtdmFsdWUtZm9ybWF0LmVudW0nO1xuaW1wb3J0IHtcbiAgYXhpc051bWJlckZvcm1hdCxcbiAgQ2hhcnROdW1iZXJGb3JtYXQsXG4gIGNoYXJ0VmFsdWVQZWFrLFxuICBjb21wYXJpc29uT2Zmc2V0TGFiZWwsXG4gIERBWV9TSE9SVCxcbiAgZGF0ZUZvcm1hdCxcbiAgZm9ybWF0RGF5UmFuZ2UsXG4gIGZvcm1hdERheVdpbmRvdyxcbiAgZm9ybWF0TG9jYWxEYXRlLFxuICBGb3JtYXR0ZWRPdXRwdXRWYWx1ZSxcbiAgZm9ybWF0TnVtYmVyLFxuICBmb3JtYXRPdXRwdXRWYWx1ZSxcbiAgZm9ybWF0UGxhaW5OdW1iZXIsXG4gIGhhc051bWJlckZvcm1hdCxcbiAgbGFuZU91dHB1dEFsaWFzLFxuICBNT05USF9EQVksXG4gIE1PTlRIX0xPTkcsXG4gIE1PTlRIX1lFQVIsXG4gIHJlc29sdmVDaGFydE51bWJlckZvcm1hdCxcbiAgd2luZG93VGV4dCxcbn0gZnJvbSAnLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgQXhpc0NoYXJ0VHlwZSxcbiAgQ2hhcnRDb25maWcsXG4gIENoYXJ0R3JhbnVsYXJpdHksXG4gIENoYXJ0TWVhc3VyZSxcbiAgQ2hhcnRSZWZlcmVuY2UsXG4gIENoYXJ0VmFsdWVBeGlzLFxuICBDb21wYXJpc29uT2Zmc2V0LFxuICBDb21wb25lbnRDb21wYXJpc29uLFxuICBDb21wb25lbnREYXRhLFxuICBHUkFOVUxBUklUWV9PUFRJT05TLFxuICBMZWdlbmRQb3NpdGlvbixcbiAgTGlzdENvbHVtbixcbiAgTGlzdENvbmZpZyxcbiAgTnVtYmVyRm9ybWF0U3BlYyxcbiAgT3V0cHV0TWV0YSxcbiAgT3V0cHV0Um9sZSxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGb3JtYXRDb250ZXh0LFxuICBSZXBvcnRMb2NhbGVUYWcsXG4gIFdhdGVyZmFsbFN0ZXBLaW5kLFxuICBXaW5kb3dNZXRhLFxufSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBlc2NhcGVIdG1sIH0gZnJvbSAnLi90ZXh0JztcbmltcG9ydCB7XG4gIFJFUE9SVF9DSEFSVF9DT0xPUl9CWV9OQU1FLFxuICBSRVBPUlRfQ0hBUlRfQ09MT1JTLFxuICBSRVBPUlRfQ0hBUlRfQ09MT1JTX0NTUyxcbiAgUkVQT1JUX1JFRkVSRU5DRV9DT0xPUixcbiAgUkVQT1JUX1dBVEVSRkFMTF9DT0xPUlMsXG59IGZyb20gJy4vdGhlbWUvcGFsZXR0ZSc7XG5pbXBvcnQgeyBSRVBPUlRfQVhJU19MQUJFTF9GT05UX1NJWkUsIFJFUE9SVF9DSEFSVF9GT05UX0ZBTUlMWSwgUkVQT1JUX0RBVEFfTEFCRUxfRk9OVF9TSVpFIH0gZnJvbSAnLi90aGVtZS90eXBvZ3JhcGh5JztcblxuXG4vLyBSb29tIGZvciBhbiBheGlzIHRpdGxlLiBFQ2hhcnRzIDUncyBjb250YWluTGFiZWwga2VlcHMgdGhlIFRJQ0sgbGFiZWxzIGluc2lkZVxuLy8gdGhlIGdyaWQgYnV0IG5vdCB0aGUgYXhpcyBuYW1lLCBzbyB3aXRob3V0IHRoaXMgYSB2ZXJ0aWNhbCBjaGFydCdzIGNhdGVnb3J5XG4vLyB0aXRsZSBydW5zIG9mZiB0aGUgYm90dG9tIGVkZ2Ugb3IgdW5kZXIgYSBib3R0b20gbGVnZW5kLCBhbmQgaXRzIHZhbHVlIHRpdGxlXG4vLyBhYm92ZSB0aGUgcGxvdCBydW5zIG9mZiB0aGUgdG9wIG9yIHVuZGVyIGEgdG9wIGxlZ2VuZC5cbmNvbnN0IEFYSVNfTkFNRV9ST09NID0gMjA7XG4vLyBFQ2hhcnRzJyBvd24gZGVmYXVsdCBnYXAgYmV0d2VlbiB0aGUgYXhpcyBsaW5lIGFuZCBpdHMgdGljayBsYWJlbHMuXG5jb25zdCBBWElTX0xBQkVMX01BUkdJTiA9IDg7XG4vLyBDbGVhcmFuY2UgYmV0d2VlbiB0aGUgbG9uZ2VzdCB0aWNrIGxhYmVsIGFuZCBhIGhvcml6b250YWwgY2hhcnQncyByb3RhdGVkXG4vLyB0aXRsZSwgc28gdGhlIHR3byBuZXZlciB0b3VjaC5cbmNvbnN0IEFYSVNfTkFNRV9DTEVBUkFOQ0UgPSA2O1xuLy8gQSBob3Jpem9udGFsIGNoYXJ0J3MgY2F0ZWdvcnkgbGFiZWxzIGFyZSBjdXQgc2hvcnQgd2l0aCBhbiBlbGxpcHNpcyBwYXN0XG4vLyB0aGlzIHdpZHRoICh0aGUgdG9vbHRpcCBzdGlsbCBzaG93cyB0aGVtIGluIGZ1bGwpLCBzbyBvbmUgbG9uZyBsYWJlbCBjYW5ub3Rcbi8vIHNxdWVlemUgdGhlIHBsb3QgYXdheS5cbmNvbnN0IENBVEVHT1JZX0xBQkVMX01BWF9XSURUSCA9IDE2MDtcbmNvbnN0IExBQkVMX0VMTElQU0lTID0gJ+KApic7XG4vLyBUaGUgZm9udCB0aGUgdGhlbWUgZHJhd3MgYXhpcyBsYWJlbHMgaW4sIGFzIGEgY2FudmFzIGZvbnQgc3RyaW5nLiBMYWJlbHMgYXJlXG4vLyBtZWFzdXJlZCBpbiBpdCB0aGUgd2F5IEVDaGFydHMgbWVhc3VyZXMgdGhlbSBmb3IgY29udGFpbkxhYmVsLCBzbyBhXG4vLyBob3Jpem9udGFsIGNoYXJ0J3MgdGl0bGUgbGFuZHMgZXhhY3RseSBiZXlvbmQgdGhlIHdpZGVzdCBsYWJlbC5cbmNvbnN0IEFYSVNfTEFCRUxfRk9OVCA9IGAke1JFUE9SVF9BWElTX0xBQkVMX0ZPTlRfU0laRX1weCAke1JFUE9SVF9DSEFSVF9GT05UX0ZBTUlMWX1gO1xuLy8gVGhlIGxldHRlciBhIHF1YXJ0ZXIgbGFiZWwgc3RhcnRzIHdpdGgsIGJ5IGxhbmd1YWdlIHN1YnRhZy4gRnJlbmNoIHdyaXRlcyB0aGVcbi8vIHNlY29uZCBxdWFydGVyICdUMicgKHRyaW1lc3RyZSk7IGV2ZXJ5IG90aGVyIGxhbmd1YWdlIHJlYWRzICdRMicuXG5jb25zdCBRVUFSVEVSX1BSRUZJWEVTID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oW1snZnInLCAnVCddXSk7XG5jb25zdCBRVUFSVEVSX1BSRUZJWCA9ICdRJztcbi8vIEEgMTAwJSBzdGFja2VkIGNoYXJ0J3MgdmFsdWUgYXhpczogd2hvbGUgcGVyY2VudGFnZXMsIGEgZ3JpZGxpbmUgZXZlcnkgMjUlLFxuLy8gdXAgdG8gMTAwJS4gSXRzIHRvb2x0aXAgZ2l2ZXMgZWFjaCBzaGFyZSB0byBvbmUgZGVjaW1hbC5cbmNvbnN0IFBFUkNFTlRfQVhJU19GT1JNQVQ6IE51bWJlckZvcm1hdFNwZWMgPSB7IGZvcm1hdDogUmVwb3J0VmFsdWVGb3JtYXQuUGVyY2VudCwgcHJlY2lzaW9uOiAwIH07XG5jb25zdCBQRVJDRU5UX1NIQVJFX0ZPUk1BVDogTnVtYmVyRm9ybWF0U3BlYyA9IHsgZm9ybWF0OiBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50LCBwcmVjaXNpb246IDEgfTtcbmV4cG9ydCBjb25zdCBQRVJDRU5UX0FYSVNfTUFYID0gMTtcbmV4cG9ydCBjb25zdCBQRVJDRU5UX0FYSVNfSU5URVJWQUwgPSAwLjI1O1xuLy8gQSByZWZlcmVuY2UgYmFuZCdzIGZpbGw6IHRoZSByZWZlcmVuY2Ugc2xhdGUsIGZhaW50IGVub3VnaCB0aGF0IHRoZSBzZXJpZXNcbi8vIGRyYXduIGFjcm9zcyBpdCBzdGF5IHJlYWRhYmxlLlxuY29uc3QgUkVGRVJFTkNFX0JBTkRfRklMTCA9ICdyZ2JhKDgyLCA5NiwgMTA5LCAwLjA4KSc7XG4vLyBBIHJlZmVyZW5jZSdzIG9yIHN0YXRpc3RpYyBsaW5lJ3MgbGFiZWwgc2l0cyBvbiBhIGxpZ2h0IGJveCwgc28gaXQgc3RheXNcbi8vIHJlYWRhYmxlIHdoZXJlIGl0IGNyb3NzZXMgYSBiYXIgb3IgYSBsaW5lLlxuY29uc3QgTUFSS19MQUJFTF9CT1ggPSB7IGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMjU1LCAyNTUsIDI1NSwgMC44NSknLCBwYWRkaW5nOiBbMSwgM10sIGJvcmRlclJhZGl1czogMiB9O1xuLy8gVGhlIHJvb20gYW4gYXhpcyBzdHJldGNoZWQgdG8gYSByZWZlcmVuY2UgbGVhdmVzIGFib3ZlIGl0LCBmb3IgaXRzIGxhYmVsOlxuLy8gdGhlIGJvdW5kIGlzIHRoZSByb3VuZCBudW1iZXIgYXQgb3IgcGFzdCB0aGUgcmVmZXJlbmNlIHBsdXMgdGhpcyBzaGFyZS5cbmNvbnN0IFJFRkVSRU5DRV9IRUFEUk9PTSA9IDEuMDU7XG5cbi8vIEhvdyBhIGNoYXJ0IG1hcmtzIHdoYXQgdGhlIHNlcnZlciBzYXlzIG9mIGl0cyBudW1iZXJzIChDb21wb25lbnREYXRhJ3Ncbi8vIGNvbXBhcmlzb24sIG91dHB1dHMsIHdpbmRvd3MgYW5kIHBhcnRpYWxQZXJpb2QpLiBUaGUgd29yZHMgYXJlIGludGVyZmFjZVxuLy8gdGV4dCwgRW5nbGlzaCBpbiBldmVyeSByZXBvcnQgbG9jYWxlLlxuLy8gLSBUaGUgaGVhZGluZyBvZiBhIHBlcmlvZCBub3Qgb3ZlciB5ZXQgKCdTZXB0ZW1iZXIgMjAyNiAodG8gZGF0ZSknKS5cbmNvbnN0IFBBUlRJQUxfUEVSSU9EX1RFWFQgPSAndG8gZGF0ZSc7XG4vLyAtIEEgY29tcGFyZWQgc2VyaWVzJyBuYW1lOiBpdHMgbWVhc3VyZSdzLCB0aGVuIGl0cyByb2xlIGFuZCBsYW5lICgnUmV2ZW51ZVxuLy8gICBjaGFuZ2UgKHZzIHByZXZpb3VzIHdlZWspJykuIEEgcHJpb3Iga2VlcHMgdGhlIG1lYXN1cmUncyBuYW1lIGFsb25lLlxuY29uc3QgUk9MRV9OQU1FX1NVRkZJWEVTOiBSZWNvcmQ8RXhjbHVkZTxPdXRwdXRSb2xlLCAnY3VycmVudCc+LCBzdHJpbmc+ID0ge1xuICBwcmlvcjogJycsXG4gIGNoYW5nZTogJyBjaGFuZ2UnLFxuICBwZXJjZW50X2NoYW5nZTogJyAlIGNoYW5nZScsXG59O1xuLy8gLSBBIHByaW9yIHNlcmllcycgYmFyczogaXRzIGN1cnJlbnQgc2VyaWVzJyBjb2xvciwgZmFkZWQsIHdpdGggYSBkYXNoZWRcbi8vICAgZWRnZS4gSXRzIGxpbmUgaXMgZGFzaGVkIChQUklPUl9MSU5FX1NUWUxFKSB1bmxlc3MgaXRzIG1lYXN1cmUgbmFtZXMgb25lLlxuY29uc3QgUFJJT1JfQkFSX09QQUNJVFkgPSAwLjQ1O1xuY29uc3QgUFJJT1JfTElORV9TVFlMRSA9IFJlcG9ydENoYXJ0TGluZVN0eWxlLkRhc2hlZDtcbi8vIC0gVGhlIHBlcmlvZCBub3Qgb3ZlciB5ZXQ6IGl0cyBiYXIgaGF0Y2hlZCBpbiBsaWdodCBzdHJpcGVzLCBpdHMgcG9pbnQgb24gYVxuLy8gICBsaW5lIGRyYXduIGxhcmdlciB3aXRoIGEgZGFzaGVkIGVkZ2UsIGFuZCwgd2hlbiBpdCBpcyB0aGUgbGFzdCBvbmUsIHRoZVxuLy8gICBsaW5lJ3MgbGFzdCBzZWdtZW50IGRhc2hlZC5cbmNvbnN0IFBBUlRJQUxfTElORV9TVFlMRSA9IFJlcG9ydENoYXJ0TGluZVN0eWxlLkRhc2hlZDtcbmNvbnN0IFBBUlRJQUxfQkFSX0RFQ0FMID0ge1xuICBzeW1ib2w6ICdub25lJyxcbiAgZGFzaEFycmF5WDogWzEsIDBdLFxuICBkYXNoQXJyYXlZOiBbMywgNV0sXG4gIHJvdGF0aW9uOiAtTWF0aC5QSSAvIDQsXG4gIGNvbG9yOiAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjYpJyxcbn07XG5jb25zdCBQQVJUSUFMX1BPSU5UX01BUksgPSB7IHN5bWJvbDogJ2VtcHR5Q2lyY2xlJywgc3ltYm9sU2l6ZTogOSwgaXRlbVN0eWxlOiB7IGJvcmRlclR5cGU6ICdkYXNoZWQnIH0gfTtcbi8vIC0gQSB2YWx1ZSBheGlzIG9mIHJhbmtzIG9ubHk6IHJhbmsgMSBhdCB0aGUgdG9wLCB3aG9sZSBzdGVwcywgZnJvbSAxLlxuY29uc3QgUkFOS19BWElTX0ZPUk1BVDogTnVtYmVyRm9ybWF0U3BlYyA9IHsgZm9ybWF0OiBSZXBvcnRWYWx1ZUZvcm1hdC5OdW1iZXIsIHByZWNpc2lvbjogMCB9O1xuLy8gKFNoYXJlZCB3aXRoIHRoZSBQb3dlclBvaW50IGV4cG9ydCwgd2hvc2UgcmFuayBheGVzIHN0YXJ0IHRoZXJlIHRvby4pXG5leHBvcnQgY29uc3QgUkFOS19BWElTX01JTiA9IDE7XG4vLyAtIEEgdmFsdWUgYXhpcyBvZiAwLTEgZnJhY3Rpb25zIG9ubHkgKHNoYXJlcywgcGVyY2VudCBjaGFuZ2VzKSBpcyBhXG4vLyAgIHBlcmNlbnQgYXhpcywgaXRzIGRlY2ltYWxzIGRlY2lkZWQgYnkgaXRzIHBlYWsuXG5jb25zdCBGUkFDVElPTl9BWElTX0ZPUk1BVDogTnVtYmVyRm9ybWF0U3BlYyA9IHsgZm9ybWF0OiBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50IH07XG4vLyAtIEJldHdlZW4gYSB0b29sdGlwIHZhbHVlIGFuZCB3aGF0IGl0IGNvdmVycy5cbmNvbnN0IFRPT0xUSVBfREVUQUlMX1NFUEFSQVRPUiA9ICcgwrcgJztcbi8vIC0gVGhlIHByaW9yIGEgdG9vbHRpcCB2YWx1ZSBpcyBjb21wYXJlZCB3aXRoLCB3aGVuIHRoZSBjaGFydCBkb2VzIG5vdCBwbG90XG4vLyAgIGl0ICgndnMgNTAlIChTZXAgMSDigJMgMiwgMjAyNiknKS5cbmNvbnN0IENPTVBBUkVEX1BSSU9SX1BSRUZJWCA9ICd2cyc7XG5cbi8vIFRoZSB3b3JkcyBhIHN0YXRpc3RpYyBsaW5lJ3MgbGFiZWwgc3RhcnRzIHdpdGguIFRoZXkgYXJlIGludGVyZmFjZSB0ZXh0LFxuLy8gRW5nbGlzaCBpbiBldmVyeSByZXBvcnQgbG9jYWxlOyBvbmx5IHRoZSB2YWx1ZSBhZnRlciB0aGVtIGZvbGxvd3MgaXQuXG5leHBvcnQgY29uc3QgU1RBVF9MQUJFTDogUmVjb3JkPFJlcG9ydENoYXJ0TWFya1N0YXQsIHN0cmluZz4gPSB7XG4gIFtSZXBvcnRDaGFydE1hcmtTdGF0LkF2ZXJhZ2VdOiAnQXZlcmFnZScsXG4gIFtSZXBvcnRDaGFydE1hcmtTdGF0Lk1lZGlhbl06ICdNZWRpYW4nLFxuICBbUmVwb3J0Q2hhcnRNYXJrU3RhdC5NaW5dOiAnTWluaW11bScsXG4gIFtSZXBvcnRDaGFydE1hcmtTdGF0Lk1heF06ICdNYXhpbXVtJyxcbn07XG5cbi8vIFdoaWNoIGVkZ2Ugb2YgdGhlIHBsb3QgYW4gYXhpcyB0aXRsZSBzaXRzIG9uLiBUaGUgY2F0ZWdvcnkgYXhpcydzIGlzIGJlbG93IGFcbi8vIHZlcnRpY2FsIGNoYXJ0IGFuZCB0byB0aGUgbGVmdCBvZiBhIGhvcml6b250YWwgb25lOyB0aGUgdmFsdWUgYXhpcydzIGlzIGFib3ZlXG4vLyBhIHZlcnRpY2FsIGNoYXJ0IGFuZCBiZWxvdyBhIGhvcml6b250YWwgb25lLlxudHlwZSBBeGlzVGl0bGVTaWRlID0gJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JztcblxuLy8gV2hpY2ggdmFsdWUgYXhpcyBhIHNlcmllcyBpcyBwbG90dGVkIGFnYWluc3Q6IDAgdGhlIHByaW1hcnksIDEgdGhlIHNlY29uZFxuLy8gYXhpcyBvbiB0aGUgcmlnaHQuXG5leHBvcnQgdHlwZSBWYWx1ZUF4aXNJbmRleCA9IDAgfCAxO1xuXG4vLyBXaGF0IHZhbHVlQXhpc09wdGlvbiBhZGRzIGZvciBvbmUgYXhpcy4gYGluZGV4YCBpcyB0aGUgYXhpcyBvZiBhIHR3by1heGlzXG4vLyBjaGFydCBpdCBidWlsZHM6IHRoZSBzZWNvbmQgb25lJ3MgdGl0bGUgaXMgYWxpZ25lZCB0byByZWFkIGxlZnR3YXJkIGZyb20gdGhlXG4vLyByaWdodCBlZGdlLiBgcGVyY2VudE1pbmAgbWFrZXMgaXQgYSAxMDAlIHN0YWNrZWQgY2hhcnQncyBzaGFyZSBheGlzLCBmcm9tXG4vLyB0aGF0IGJvdW5kICgwLCBvciAtMSB3aGVuIGEgc2hhcmUgaXMgbmVnYXRpdmUpIHVwIHRvIDEwMCUsIHdoYXRldmVyIHJhbmdlXG4vLyB0aGUgY29uZmlnIHBpbnMuIGByZWFjaGAgaXMgdGhlIHNwYW4gb2YgdGhlIHJlZmVyZW5jZXMgcGxvdHRlZCBhZ2FpbnN0IGl0LFxuLy8gd2hpY2ggdGhlIGF4aXMgc3RyZXRjaGVzIHRvIHdoZW4gdGhlIGRhdGEgZmFsbHMgc2hvcnQgb2YgdGhlbS4gYHJhbmtgXG4vLyBpbnZlcnRzIGl0LlxuaW50ZXJmYWNlIFZhbHVlQXhpc0V4dHJhcyB7XG4gIGluZGV4PzogVmFsdWVBeGlzSW5kZXg7XG4gIHBlcmNlbnRNaW4/OiBudW1iZXI7XG4gIHJlYWNoPzogUmVmZXJlbmNlUmVhY2g7XG4gIC8vIEV2ZXJ5IHNlcmllcyBvbiB0aGUgYXhpcyBwbG90cyBhIHJhbms6IGl0IHJ1bnMgZnJvbSByYW5rIDEgYXQgdGhlIHRvcCBpblxuICAvLyB3aG9sZSBzdGVwcy5cbiAgcmFuaz86IGJvb2xlYW47XG59XG5cbi8vIEEgcmVmZXJlbmNlIGFzIHRoZSBjaGFydCBkcmF3cyBpdDogaXRzIGxvd2VyIGFuZCB1cHBlciBlZGdlICh0aGUgc2FtZSB2YWx1ZVxuLy8gZm9yIGEgbGluZSksIHdoZXRoZXIgaXQgaXMgYSBiYW5kLCBhbmQgdGhlIHZhbHVlIGF4aXMgaXQgaXMgcGxvdHRlZCBhZ2FpbnN0LlxuLy8gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0LCB3aGljaCBkcmF3cyBlYWNoIGVkZ2UgYXMgYSBjb25zdGFudCBsaW5lLlxuZXhwb3J0IGludGVyZmFjZSBEcmF3blJlZmVyZW5jZSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGxvdzogbnVtYmVyO1xuICBoaWdoOiBudW1iZXI7XG4gIGJhbmQ6IGJvb2xlYW47XG4gIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXg7XG59XG5cbi8vIFRoZSBsb3dlc3QgYW5kIGhpZ2hlc3QgZWRnZSBvZiB0aGUgcmVmZXJlbmNlcyBvbiBvbmUgdmFsdWUgYXhpcy5cbmludGVyZmFjZSBSZWZlcmVuY2VSZWFjaCB7XG4gIGxvdzogbnVtYmVyO1xuICBoaWdoOiBudW1iZXI7XG59XG5cbi8vIFdoYXQgRUNoYXJ0cyBoYW5kcyBhIHZhbHVlIGF4aXMncyBtaW4gYW5kIG1heCBjYWxsYmFja3M6IHRoZSBleHRlbnQgb2YgdGhlXG4vLyBkYXRhIHBsb3R0ZWQgYWdhaW5zdCBpdC5cbmludGVyZmFjZSBBeGlzRXh0ZW50IHtcbiAgbWluOiBudW1iZXI7XG4gIG1heDogbnVtYmVyO1xufVxuXG4vLyBPbmUgcG9pbnQgb2YgYSAxMDAlIHN0YWNrZWQgc2VyaWVzOiBpdHMgc2hhcmUgb2YgdGhlIGNhdGVnb3J5J3MgdG90YWwsXG4vLyB3aGljaCBFQ2hhcnRzIHBsb3RzIGFuZCBzdGFja3MsIGFuZCB0aGUgdmFsdWUgaXQgY2FtZSBmcm9tLlxuaW50ZXJmYWNlIFNoYXJlRGF0YUl0ZW0ge1xuICB2YWx1ZTogbnVtYmVyIHwgbnVsbDtcbiAgcmF3OiBudW1iZXIgfCBudWxsO1xufVxuXG4vLyBBIHBvaW50IHRoYXQgcHJpbnRzIGl0cyBvd24gZGF0YSBsYWJlbDogYSAnbGFzdCcgc2VyaWVzJyBsYXRlc3QgcG9pbnQsXG4vLyBrZWVwaW5nIHRoZSByYXcgdmFsdWUgYSAxMDAlIHN0YWNrZWQgcG9pbnQgY2Fycmllcy5cbmludGVyZmFjZSBMYWJlbGVkRGF0YUl0ZW08UCBleHRlbmRzIERhdGFMYWJlbFBvc2l0aW9uPiB7XG4gIHZhbHVlOiBudW1iZXIgfCBudWxsO1xuICByYXc/OiBudW1iZXIgfCBudWxsO1xuICBsYWJlbDogRGF0YUxhYmVsPFA+O1xufVxuXG50eXBlIFNlcmllc0RhdGFJdGVtPFAgZXh0ZW5kcyBEYXRhTGFiZWxQb3NpdGlvbj4gPSBudW1iZXIgfCBudWxsIHwgU2hhcmVEYXRhSXRlbSB8IExhYmVsZWREYXRhSXRlbTxQPjtcblxuLy8gV2hhdCBhIGRhdGEgbGFiZWwncyBmb3JtYXR0ZXIgaXMgaGFuZGVkOiB0aGUgcG9pbnQncyBwbG90dGVkIHZhbHVlLCBpdHNcbi8vIGRhdGEgaXRlbSBhcyBnaXZlbiAoYSBudW1iZXIsIG9yIGFuIG9iamVjdCBjYXJyeWluZyB0aGUgcmF3IHZhbHVlKSwgYW5kIGl0c1xuLy8gaW5kZXguXG5pbnRlcmZhY2UgRGF0YUxhYmVsUGFyYW1zIHtcbiAgdmFsdWU/OiB1bmtub3duO1xuICBkYXRhPzogdW5rbm93bjtcbiAgZGF0YUluZGV4PzogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBEYXRhTGFiZWxGb3JtYXR0ZXIgPSAocGFyYW1zOiBEYXRhTGFiZWxQYXJhbXMpID0+IHN0cmluZztcblxuLy8gV2hlcmUgYSBkYXRhIGxhYmVsIHNpdHM6ICdvdXRzaWRlJyBwYXN0IGFuIHVuc3RhY2tlZCBiYXIncyBlbmQsIG9uIHRoZSBzaWRlXG4vLyBpdHMgc2lnbiBwb2ludHMgdG87ICdpbnNpZGUnIGEgc3RhY2tlZCBiYXI7ICd0b3AnIGFib3ZlIGEgbGluZSBvciBhcmVhXG4vLyBwb2ludC4gRUNoYXJ0cyB0YWtlcyAnb3V0c2lkZScgb24gYSBiYXIgb25seS5cbmV4cG9ydCB0eXBlIERhdGFMYWJlbFBvc2l0aW9uID0gJ3RvcCcgfCAnaW5zaWRlJyB8ICdvdXRzaWRlJztcblxuLy8gT25lIEVDaGFydHMgbGFiZWwsIGFzIGEgc2VyaWVzIG9yIGEgc2luZ2xlIHBvaW50IHByaW50cyBpdC5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YUxhYmVsPFAgZXh0ZW5kcyBEYXRhTGFiZWxQb3NpdGlvbiA9IERhdGFMYWJlbFBvc2l0aW9uPiB7XG4gIHNob3c6IHRydWU7XG4gIHBvc2l0aW9uOiBQO1xuICBmb250U2l6ZTogbnVtYmVyO1xuICBmb3JtYXR0ZXI6IERhdGFMYWJlbEZvcm1hdHRlcjtcbn1cblxuLy8gQSBzZXJpZXMnIGRhdGEgbGFiZWxzIGFzIGRhdGFMYWJlbE9wdGlvbiBkZWNpZGVzIHRoZW0sIGJlZm9yZSBidWlsZFNlcmllc1xuLy8gcGxhY2VzIHRoZW0gYnkgd2hhdCB0aGUgc2VyaWVzIGRyYXdzOiB0aGUgbGFiZWwncyB0ZXh0IGFuZCBzaXplLCB3aGV0aGVyXG4vLyBsYWJlbHMgdGhhdCB3b3VsZCBvdmVybGFwIGFyZSBoaWRkZW4gKCdhdXRvJyksIGFuZCB3aGV0aGVyIG9ubHkgdGhlIGxhdGVzdFxuLy8gcG9pbnQgcHJpbnRzIG9uZSAoJ2xhc3QnKS5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWVzRGF0YUxhYmVscyB7XG4gIHRleHQ6IE9taXQ8RGF0YUxhYmVsLCAncG9zaXRpb24nPjtcbiAgaGlkZU92ZXJsYXA6IGJvb2xlYW47XG4gIGxhc3RPbmx5OiBib29sZWFuO1xufVxuXG4vLyBBIHNlcmllcycgZGF0YSBsYWJlbHMgcGxhY2VkOiBgc2VyaWVzYCBpcyBzcHJlYWQgb3ZlciB0aGUgc2VyaWVzIChpdHNcbi8vIGxhYmVsLCBhbmQgZm9yICdhdXRvJyB0aGUgb3ZlcmxhcCBoaWRpbmcpLCBhbmQgYGRhdGFgIGlzIGl0cyBwb2ludHMsIHRoZVxuLy8gbGF0ZXN0IG5vbi1lbXB0eSBvbmUgY2FycnlpbmcgdGhlIGxhYmVsIGZvciAnbGFzdCcuXG5pbnRlcmZhY2UgUGxhY2VkRGF0YUxhYmVsczxQIGV4dGVuZHMgRGF0YUxhYmVsUG9zaXRpb24+IHtcbiAgc2VyaWVzOiB7IGxhYmVsPzogRGF0YUxhYmVsPFA+OyBsYWJlbExheW91dD86IHsgaGlkZU92ZXJsYXA6IGJvb2xlYW4gfSB9O1xuICBkYXRhOiBTZXJpZXNEYXRhSXRlbTxQPltdO1xufVxuXG4vLyBBIHZhbHVlIGF4aXMncyBudW1iZXIgZm9ybWF0LCBkZWNpZGVkIG9uY2UgZm9yIHRoZSBheGlzOiB0aGUgZm9ybWF0IHRoZVxuLy8gbWVhc3VyZXMgcGxvdHRlZCBhZ2FpbnN0IGl0IGFncmVlIG9uIChheGlzTnVtYmVyRm9ybWF0KSwgd2l0aCB0aGUgdW5pdHMgYW5kXG4vLyBkZWNpbWFscyBpdHMgcGVhayBjYWxscyBmb3IsIGFuZCB0aGUgY29udGV4dCBpdHMgdGlja3MgYXJlIHdyaXR0ZW4gaW4gKGFuXG4vLyBheGlzIG9mIDAtMSBmcmFjdGlvbnMgcmVhZHMgdGhlbSBhcyByYXRpb3Mgd2hhdGV2ZXIgdGhlIHJlcG9ydCdzXG4vLyBwZXJjZW50Rm9ybWF0KS4gbnVsbCBpcyBhIHBsYWluIGF4aXMuIEl0cyB0aWNrcyBhbmQgaXRzIHNlcmllcycgZGF0YSBsYWJlbHNcbi8vIGJvdGggd3JpdGUgaW4gaXQuXG5pbnRlcmZhY2UgVmFsdWVBeGlzRm9ybWF0IHtcbiAgc3BlYzogTnVtYmVyRm9ybWF0U3BlYztcbiAgY2hhcnQ6IENoYXJ0TnVtYmVyRm9ybWF0O1xuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0O1xufVxuXG4vLyBUaGUgc2hhcmVzIGEgMTAwJSBzdGFja2VkIGNoYXJ0IGRyYXdzLCBieSB0aGUgaW5kZXggb2YgdGhlIGV4dHJhY3RlZCBzZXJpZXNcbi8vIHRoZXkgcmVwbGFjZS5cbmV4cG9ydCB0eXBlIFBlcmNlbnRTaGFyZXMgPSBNYXA8bnVtYmVyLCAobnVtYmVyIHwgbnVsbClbXT47XG5cbi8vIFRoZSBwbG90J3MgZGlzdGFuY2UgZnJvbSBlYWNoIGVkZ2Ugb2YgdGhlIGNoYXJ0LCBpbiBwaXhlbHMuXG5pbnRlcmZhY2UgQXhpc0dyaWRSb29tIHtcbiAgbGVmdDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIGNvbnRhaW5MYWJlbDogYm9vbGVhbjtcbn1cblxuXG4vLyBjb2xvckJ5IGFwcGxpZXMgb25seSB0byBzaW5nbGUtZGltZW5zaW9uIGJhciBjaGFydHMsIGFuZCBvbmx5IHdoZW4gc3BsaXRCeVxuLy8gaXNuJ3QgYWxyZWFkeSBkcml2aW5nIG11bHRpcGxlIHNlcmllczogaXQgY29sb3JzIGVhY2ggYmFyIGJ5IGl0cyBjYXRlZ29yeSBhbmRcbi8vIHNob3dzIGEgbGVnZW5kIChvbmUgc2VyaWVzIHBlciBjYXRlZ29yeSwgb3ZlcmxhcHBlZCB0byBmdWxsIHdpZHRoKS5cbi8vXG4vLyBJdCBpcyB0aGUgREVGQVVMVCBmb3IgYSBjYXRlZ29yaWNhbCBiYXIgY2hhcnQgcmF0aGVyIHRoYW4gc29tZXRoaW5nIHRoZSBjb25maWdcbi8vIGhhcyB0byBhc2sgZm9yLiBBIGJhciBjaGFydCB3aG9zZSB4LWF4aXMgaXMgYSBjYXRlZ29yeSDigJQgcmVnaW9ucywgc3RhdHVzZXMsXG4vLyBzdG9yZXMg4oCUIGlzIGNvbXBhcmluZyB0aG9zZSBjYXRlZ29yaWVzIHRvIGVhY2ggb3RoZXIsIGFuZCBvbmUgZmxhdCBjb2xvciB3aXRoXG4vLyBubyBsZWdlbmQgaXMgdGhlIHdyb25nIHJlYWRpbmcgb2YgaXQgaW4gZXNzZW50aWFsbHkgZXZlcnkgY2FzZS4gUmVxdWlyaW5nXG4vLyBjb2xvckJ5IHRvIG9wdCBpbiBtZWFudCBldmVyeSBzdWNoIGNoYXJ0IHJlbmRlcmVkIG1vbm9jaHJvbWUgdW5sZXNzIHdob2V2ZXJcbi8vIHdyb3RlIHRoZSBjb25maWcgcmVtZW1iZXJlZCBhbiBvcHRpb25hbCBwcm9wZXJ0eSwgd2hpY2ggaXMgYSBkZWZhdWx0IHNldCB0aGVcbi8vIHdyb25nIHdheSByb3VuZDogdGhlIGNvbW1vbiBjYXNlIHNob3VsZCBub3QgbmVlZCB0aGUgZmxhZy5cbi8vXG4vLyBBIFRJTUUgYXhpcyBpcyBleGNsdWRlZDogY29uc2VjdXRpdmUgcGVyaW9kcyBhcmUgb25lIHNlcmllcyBtb3ZpbmcsIG5vdFxuLy8gY2F0ZWdvcmllcyBiZWluZyBjb21wYXJlZCwgYW5kIGNvbG9yaW5nIGVhY2ggbW9udGggZGlmZmVyZW50bHkgcmVhZHMgYXNcbi8vIHVucmVsYXRlZCBncm91cHMuIEV4cGxpY2l0bHkgb3B0aW5nIG91dCDigJQgY29sb3JCeToge2NvbHVtbjogJyd9LCBhIGNvbG9yIG9uXG4vLyB0aGUgbWVhc3VyZSBvciBhIGNvbmZpZy5sZWdlbmQgb2YgJ2hpZGRlbicg4oCUIHN0aWxsIHdpbnMsIHNvIGEgY2FsbGVyIHRoYXRcbi8vIHdhbnRzIG9uZSBmbGF0IGNvbG9yIGNhbiBzYXkgc28uXG4vL1xuLy8gXCJCYXIgY2hhcnRcIiBpcyB0aGUgdHlwZSB0aGUgbG9uZSBtZWFzdXJlIGlzIGFjdHVhbGx5IERSQVdOIGFzOiBpdHMgb3duIHR5cGVcbi8vIHdoZW4gaXQgbmFtZXMgb25lLCB3aGljaCBjYW4gdHVybiBhIGxpbmUgY2hhcnQncyBzaW5nbGUgc2VyaWVzIGludG8gYmFycyBvclxuLy8gYSBiYXIgY2hhcnQncyBpbnRvIGEgbGluZS5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yQnkoY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW4ge1xuICBpZiAoY29uZmlnLnNwbGl0Qnk/LmNvbHVtbiB8fCAoY29uZmlnLm1lYXN1cmVzPy5bMF0/LnR5cGUgPz8gY29uZmlnLmNoYXJ0VHlwZSA/PyAnYmFyJykgIT09ICdiYXInKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5jb2xvckJ5KSB7XG4gICAgcmV0dXJuICEhY29uZmlnLmNvbG9yQnkuY29sdW1uO1xuICB9XG5cbiAgLy8gQSBtZWFzdXJlIGdpdmVuIGl0cyBvd24gY29sb3IgYXNrcyBmb3Igb25lIGZsYXQgY29sb3IuXG4gIGlmIChtZWFzdXJlQ29sb3JIZXgoY29uZmlnLm1lYXN1cmVzPy5bMF0pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIChjb25maWcueEF4aXM/LmtpbmQgPz8gJ2NhdGVnb3J5JykgPT09ICdjYXRlZ29yeSdcbiAgICAmJiAhY29uZmlnLnhBeGlzPy5ncmFudWxhcml0eVxuICAgICYmIChjb25maWcubWVhc3VyZXM/Lmxlbmd0aCA/PyAxKSA8PSAxO1xufVxuXG5cbi8vIFRoZSBjb2x1bW4gY29sb3JCeSBncm91cHMgYnkg4oCUIGl0cyBvd24gd2hlbiB0aGUgY29uZmlnIG5hbWVkIG9uZSwgb3RoZXJ3aXNlXG4vLyB0aGUgeC1heGlzIGl0IGRlZmF1bHRzIHRvIGNvbG9yaW5nLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yQnlDb2x1bW4oY29uZmlnOiBDaGFydENvbmZpZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBpc0NvbG9yQnkoY29uZmlnKVxuICAgID8gKGNvbmZpZy5jb2xvckJ5Py5jb2x1bW4gfHwgY29uZmlnLnhBeGlzPy5jb2x1bW4pXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cblxuLy8gQ2F0ZWdvcmllcyArIG5hbWVkIHNlcmllcyBleHRyYWN0ZWQgZnJvbSBhIGNoYXJ0IGNvbXBvbmVudCdzIGNvbmZpZyArIHJvd3Mg4oCUXG4vLyB0aGUgb25lIHBpdm90IChzcGxpdEJ5IOKGkiBzZXJpZXMsIG1lYXN1cmVzIOKGkiBzZXJpZXMpIHNoYXJlZCBieSB0aGUgb24tc2NyZWVuXG4vLyBFQ2hhcnRzIG9wdGlvbiBiZWxvdyBBTkQgdGhlIFBvd2VyUG9pbnQgZXhwb3J0J3MgbmF0aXZlIGNoYXJ0IGRhdGEsIHNvIGJvdGhcbi8vIG1lZGlhIHBsb3QgaWRlbnRpY2FsIG51bWJlcnMuXG4vL1xuLy8gQSBzZXJpZXMnIGB0eXBlYCBpcyB0aGUgdHlwZSBpdHMgbWVhc3VyZSBhc2tzIHRvIGJlIGRyYXduIGFzLCBhbmQgaXMgYWJzZW50XG4vLyB3aGVuIHRoZSBtZWFzdXJlIGxlYXZlcyBpdCB0byB0aGUgY2hhcnQncyBjaGFydFR5cGUgKHNlZSBzZXJpZXNUeXBlcykuIEl0c1xuLy8gYG1lYXN1cmVgIGlzIHRoZSBvbmUgaXQgcGxvdHMsIHdob3NlIG51bWJlciBmb3JtYXQgaXRzIHRvb2x0aXAgdXNlcyBhbmRcbi8vIHdob3NlIGRpc3BsYXkga2V5cyAoY29sb3IsIGF4aXMpIGl0IGZvbGxvd3MsIGFuZCBgbWVhc3VyZUluZGV4YCB0aGF0XG4vLyBtZWFzdXJlJ3MgcG9zaXRpb246IHRoZSBmaXJzdCBtZWFzdXJlLCAwLCBmb3IgZXZlcnkgc2VyaWVzIG9mIGEgc3BsaXRCeSBvclxuLy8gY29sb3JCeSBjaGFydC5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0cmFjdGVkQ2hhcnRTZXJpZXMge1xuICBjYXRlZ29yaWVzOiBzdHJpbmdbXTtcbiAgc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW1bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlczogKG51bWJlciB8IG51bGwpW107XG4gIHR5cGU/OiBBeGlzQ2hhcnRUeXBlO1xuICBtZWFzdXJlOiBDaGFydE1lYXN1cmU7XG4gIG1lYXN1cmVJbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdENoYXJ0U2VyaWVzKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCBkYXRhOiBDb21wb25lbnREYXRhKTogRXh0cmFjdGVkQ2hhcnRTZXJpZXMge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCB7IHhDb2x1bW4sIGdyb3VwQ29sdW1uIH0gPSBjaGFydENvbHVtbnMoY29uZmlnLCBkYXRhKTtcbiAgY29uc3QgbWVhc3VyZXMgPSBjaGFydE1lYXN1cmVzKGNvbmZpZywgZGF0YSk7XG5cbiAgY29uc3QgcmF3Q2F0ZWdvcmllcyA9IHVuaXF1ZVZhbHVlcyhkYXRhLnJvd3MsIHhDb2x1bW4pO1xuICBjb25zdCBjYXRlZ29yaWVzID0gcmF3Q2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5KSA9PiBTdHJpbmcoY2F0ZWdvcnkgPz8gJ+KAlCcpKTtcbiAgY29uc3Qgc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc1snc2VyaWVzJ10gPSBbXTtcblxuICBpZiAoZ3JvdXBDb2x1bW4pIHtcbiAgICAvLyBPbmUgc2VyaWVzIHBlciBncm91cCB2YWx1ZSAoc3BsaXRCeS9jb2xvckJ5KSwgcGl2b3RlZCBvdmVyIHRoZSBmaXJzdCBtZWFzdXJlLlxuICAgIGNvbnN0IG1lYXN1cmUgPSBtZWFzdXJlc1swXTtcbiAgICBmb3IgKGNvbnN0IGdyb3VwVmFsdWUgb2YgdW5pcXVlVmFsdWVzKGRhdGEucm93cywgZ3JvdXBDb2x1bW4pKSB7XG4gICAgICBzZXJpZXMucHVzaCh7XG4gICAgICAgIG5hbWU6IFN0cmluZyhncm91cFZhbHVlID8/ICfigJQnKSxcbiAgICAgICAgdmFsdWVzOiBjYXRlZ29yeVZhbHVlcyhkYXRhLnJvd3MsIHhDb2x1bW4sIHJhd0NhdGVnb3JpZXMsIG1lYXN1cmUuY29sdW1uLCAocm93KSA9PiByb3dbZ3JvdXBDb2x1bW5dID09PSBncm91cFZhbHVlKSxcbiAgICAgICAgdHlwZTogbWVhc3VyZS50eXBlLFxuICAgICAgICBtZWFzdXJlLFxuICAgICAgICBtZWFzdXJlSW5kZXg6IDAsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBbbWVhc3VyZUluZGV4LCBtZWFzdXJlXSBvZiBtZWFzdXJlcy5lbnRyaWVzKCkpIHtcbiAgICAgIHNlcmllcy5wdXNoKHtcbiAgICAgICAgbmFtZTogY29tcGFyZWRTZXJpZXNOYW1lKG1lYXN1cmUsIG1lYXN1cmVzLCBkYXRhKSA/PyBtZWFzdXJlLmxhYmVsID8/IG1lYXN1cmUuY29sdW1uLFxuICAgICAgICB2YWx1ZXM6IGNhdGVnb3J5VmFsdWVzKGRhdGEucm93cywgeENvbHVtbiwgcmF3Q2F0ZWdvcmllcywgbWVhc3VyZS5jb2x1bW4pLFxuICAgICAgICB0eXBlOiBtZWFzdXJlLnR5cGUsXG4gICAgICAgIG1lYXN1cmUsXG4gICAgICAgIG1lYXN1cmVJbmRleCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGNhdGVnb3JpZXMsIHNlcmllcyB9O1xufVxuXG4vLyBUaGUgY29sdW1uIGEgY2hhcnQncyBjYXRlZ29yaWVzIGNvbWUgZnJvbSwgYW5kIHRoZSBvbmUgdGhhdCBzcGxpdHMgaXRzXG4vLyBmaXJzdCBtZWFzdXJlIGludG8gYSBzZXJpZXMgcGVyIHZhbHVlLCBpZiBhbnkuIGNvbG9yQnkgZW1pdHMgb25lIHNlcmllcyBwZXJcbi8vIGNhdGVnb3J5IHRvbyAoc28gZWFjaCBiYXIgY2FycmllcyBpdHMgb3duIGNvbG9yICsgbGVnZW5kIGVudHJ5KSwgYnV0IHRoZVxuLy8gYmFycyBhcmUgb3ZlcmxhcHBlZCB0byBmdWxsIHdpZHRoIGluIGJ1aWxkQXhpc09wdGlvbiByYXRoZXIgdGhhbiBsYWlkXG4vLyBzaWRlLWJ5LXNpZGUuIHNwbGl0Qnkgd2lucyBpZiBib3RoIGFyZSBzZXQuXG5mdW5jdGlvbiBjaGFydENvbHVtbnMoY29uZmlnOiBDaGFydENvbmZpZywgZGF0YTogQ29tcG9uZW50RGF0YSk6IHsgeENvbHVtbjogc3RyaW5nOyBncm91cENvbHVtbjogc3RyaW5nIHwgdW5kZWZpbmVkIH0ge1xuICByZXR1cm4ge1xuICAgIHhDb2x1bW46IGNvbmZpZy54QXhpcz8uY29sdW1uID8/IGRhdGEuY29sdW1uc1swXSxcbiAgICBncm91cENvbHVtbjogY29uZmlnLnNwbGl0Qnk/LmNvbHVtbiB8fCBjb2xvckJ5Q29sdW1uKGNvbmZpZyksXG4gIH07XG59XG5cbi8vIE9uZSBjb2x1bW4ncyB2YWx1ZXMgYnkgY2F0ZWdvcnksIGZyb20gdGhlIHJvd3MgYG1hdGNoYCBrZWVwcyAoYWxsIG9mIHRoZW1cbi8vIHdoZW4gaXQgaXMgbGVmdCBvdXQpLiBBIGNhdGVnb3J5IHdpdGggbm8gcm93IGhhcyBubyB2YWx1ZS5cbmZ1bmN0aW9uIGNhdGVnb3J5VmFsdWVzKFxuICByb3dzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICB4Q29sdW1uOiBzdHJpbmcsXG4gIHJhd0NhdGVnb3JpZXM6IHVua25vd25bXSxcbiAgY29sdW1uOiBzdHJpbmcsXG4gIG1hdGNoPzogKHJvdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IGJvb2xlYW4sXG4pOiAobnVtYmVyIHwgbnVsbClbXSB7XG4gIGNvbnN0IGJ5Q2F0ZWdvcnkgPSBuZXcgTWFwPHVua25vd24sIHVua25vd24+KCk7XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBpZiAoIW1hdGNoIHx8IG1hdGNoKHJvdykpIHtcbiAgICAgIGJ5Q2F0ZWdvcnkuc2V0KHJvd1t4Q29sdW1uXSwgcm93W2NvbHVtbl0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByYXdDYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnkpID0+IG51bWVyaWMoYnlDYXRlZ29yeS5nZXQoY2F0ZWdvcnkpKSk7XG59XG5cbi8vIEEgY29tcGFyZWQgc2VyaWVzJyBuYW1lLCB3b3JkZWQgZnJvbSBpdHMgbGFuZSdzIG9mZnNldCByYXRoZXIgdGhhbiBmcm9tIGl0c1xuLy8gb3duIGxhYmVsLCBzbyBhIGNoYXJ0IHRoZSB2aWV3ZXIgcmVncm91cGVkIHNheXMgd2hhdCBpdCBub3cgY29tcGFyZXM6XG4vLyAnUmV2ZW51ZSAodnMgcHJldmlvdXMgd2VlayknLCAnUmV2ZW51ZSBjaGFuZ2UgKHZzIHByZXZpb3VzIHdlZWspJywgJ1JldmVudWVcbi8vICUgY2hhbmdlICh2cyBwcmV2aW91cyB5ZWFyKScuIFRoZSBtZWFzdXJlIGlzIG5hbWVkIGFzIGl0cyBjdXJyZW50IHZhbHVlJ3Ncbi8vIHNlcmllcyBpcy4gbnVsbCBmb3IgYW55IG90aGVyIHNlcmllcywgd2hpY2gga2VlcHMgaXRzIG93biBuYW1lLCBhbmQgZm9yXG4vLyBkYXRhIHdpdGhvdXQgdGhlIGNvbXBhcmlzb24ga2V5cy5cbmZ1bmN0aW9uIGNvbXBhcmVkU2VyaWVzTmFtZShtZWFzdXJlOiBDaGFydE1lYXN1cmUsIG1lYXN1cmVzOiBDaGFydE1lYXN1cmVbXSwgZGF0YTogQ29tcG9uZW50RGF0YSk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBvdXRwdXQgPSBkYXRhLm91dHB1dHM/LlttZWFzdXJlLmNvbHVtbl07XG4gIGNvbnN0IG9mZnNldCA9IG91dHB1dD8ub2Zmc2V0ID8gZGF0YS5jb21wYXJpc29uPy5vZmZzZXRzPy5bb3V0cHV0Lm9mZnNldCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gIGlmICghb3V0cHV0IHx8ICFvZmZzZXQgfHwgIW91dHB1dC5yb2xlIHx8IG91dHB1dC5yb2xlID09PSAnY3VycmVudCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnQgPSBjdXJyZW50T3V0cHV0QWxpYXMoZGF0YS5vdXRwdXRzLCBtZWFzdXJlLmNvbHVtbik7XG4gIGNvbnN0IGxhYmVsID0gbWVhc3VyZXMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuY29sdW1uID09PSBjdXJyZW50KT8ubGFiZWwgPz8gY3VycmVudDtcblxuICByZXR1cm4gYCR7bGFiZWx9JHtST0xFX05BTUVfU1VGRklYRVNbb3V0cHV0LnJvbGVdfSAoJHtjb21wYXJpc29uT2Zmc2V0TGFiZWwob2Zmc2V0KX0pYDtcbn1cblxuLy8gVGhlIGNvbHVtbiBhbiBvdXRwdXQncyBjdXJyZW50IHZhbHVlIGlzIGluOiBpdHMgbGFuZSdzIGN1cnJlbnQgb3V0cHV0LCBlbHNlXG4vLyBmb3IgYSByYW5rIG9yIGEgc2hhcmUgdGhlIHVuY29tcGFyZWQgb25lIG9mIHRoZSBzYW1lIG1lYXN1cmUsIGVsc2UgdGhlXG4vLyBtZWFzdXJlJ3Mgb3duIGNvbHVtbiAoYSB3aW5kb3dlZCB2YWx1ZSdzIHNvdXJjZSkuXG5mdW5jdGlvbiBjdXJyZW50T3V0cHV0QWxpYXMob3V0cHV0czogUmVjb3JkPHN0cmluZywgT3V0cHV0TWV0YT4sIGFsaWFzOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBvdXRwdXQgPSBvdXRwdXRzW2FsaWFzXTtcbiAgY29uc3QgdW5jb21wYXJlZCA9IG91dHB1dC5raW5kID09PSAndmFsdWUnXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IE9iamVjdC5rZXlzKG91dHB1dHMpLmZpbmQoKGtleSkgPT4gb3V0cHV0c1trZXldLm1lYXN1cmUgPT09IG91dHB1dC5tZWFzdXJlXG4gICAgICAmJiBvdXRwdXRzW2tleV0ua2luZCA9PT0gb3V0cHV0LmtpbmRcbiAgICAgICYmIG91dHB1dHNba2V5XS5yb2xlID09PSBudWxsKTtcblxuICByZXR1cm4gbGFuZU91dHB1dEFsaWFzKG91dHB1dHMsIGFsaWFzLCAnY3VycmVudCcpID8/IHVuY29tcGFyZWQgPz8gb3V0cHV0Lm1lYXN1cmU7XG59XG5cbi8vIEEgc2VyaWVzJyBvd24gY29sb3IgYXMgQ1NTIGhleDogaXRzIG1lYXN1cmUncyBuYW1lZCBjb2xvciwgb3IgdW5kZWZpbmVkIHdoZW5cbi8vIGl0IG5hbWVzIG5vbmUgKG9yIGEgbmFtZSB0aGUgcGFsZXR0ZSBkb2VzIG5vdCBrbm93KSBhbmQgdGhlIHRoZW1lIGNvbG9ycyBpdFxuLy8gYnkgaXRzIHBvc2l0aW9uLlxuZXhwb3J0IGZ1bmN0aW9uIHNlcmllc0NvbG9yKHNlcmllczogRXh0cmFjdGVkQ2hhcnRTZXJpZXNJdGVtKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgaGV4ID0gbmFtZWRDb2xvckhleChzZXJpZXMpO1xuXG4gIHJldHVybiBoZXggPyBgIyR7aGV4fWAgOiB1bmRlZmluZWQ7XG59XG5cbi8vIEEgc2VyaWVzJyBjb2xvciBhcyB0aGUgYmFyZSBoZXggUG93ZXJQb2ludCB0YWtlczogaXRzIG1lYXN1cmUncyBuYW1lZCBjb2xvcixcbi8vIGVsc2UgdGhlIHBhbGV0dGUgY29sb3Igb2YgaXRzIHBvc2l0aW9uLCBhcyB0aGUgc2NyZWVuJ3MgdGhlbWUgcGlja3MgaXQuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWVzSGV4KHNlcmllczogRXh0cmFjdGVkQ2hhcnRTZXJpZXNJdGVtLCBpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5hbWVkQ29sb3JIZXgoc2VyaWVzKSA/PyBSRVBPUlRfQ0hBUlRfQ09MT1JTW2luZGV4ICUgUkVQT1JUX0NIQVJUX0NPTE9SUy5sZW5ndGhdO1xufVxuXG5mdW5jdGlvbiBuYW1lZENvbG9ySGV4KHNlcmllczogRXh0cmFjdGVkQ2hhcnRTZXJpZXNJdGVtKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIG1lYXN1cmVDb2xvckhleChzZXJpZXMubWVhc3VyZSk7XG59XG5cbi8vIEEgbWVhc3VyZSdzIG5hbWVkIGNvbG9yIGFzIGJhcmUgaGV4LCBvciB1bmRlZmluZWQgd2hlbiBpdCBuYW1lcyBub25lIG9yIGFcbi8vIG5hbWUgdGhlIHBhbGV0dGUgZG9lcyBub3Qga25vdy4gVGhlIG5hbWUgaXMgcmVhZCB0aHJvdWdoIHRoZSBlbnVtLCBzbyBhXG4vLyBzdG9yZWQgbmFtZSBzdWNoIGFzICdfX3Byb3RvX18nIG5ldmVyIHJlYWNoZXMgdGhlIGxvb2t1cCBvYmplY3QuXG5mdW5jdGlvbiBtZWFzdXJlQ29sb3JIZXgobWVhc3VyZTogQ2hhcnRNZWFzdXJlIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgY29sb3IgPSBPYmplY3QudmFsdWVzKFJlcG9ydENoYXJ0Q29sb3IpLmZpbmQoKG5hbWUpID0+IG5hbWUgPT09IG1lYXN1cmU/LmNvbG9yKTtcblxuICByZXR1cm4gY29sb3IgPyBSRVBPUlRfQ0hBUlRfQ09MT1JfQllfTkFNRVtjb2xvcl0gOiB1bmRlZmluZWQ7XG59XG5cbi8vIEEgbWVhc3VyZSdzIGxpbmUgc3R5bGUgd2hlbiBpdCBuYW1lcyBvbmUgRUNoYXJ0cyBrbm93cywgZWxzZSB1bmRlZmluZWQgYW5kXG4vLyB0aGUgbGluZSBpcyBzb2xpZC5cbmV4cG9ydCBmdW5jdGlvbiBtZWFzdXJlTGluZVN0eWxlKG1lYXN1cmU6IENoYXJ0TWVhc3VyZSB8IHVuZGVmaW5lZCk6IFJlcG9ydENoYXJ0TGluZVN0eWxlIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoUmVwb3J0Q2hhcnRMaW5lU3R5bGUpLmZpbmQoKHN0eWxlKSA9PiBzdHlsZSA9PT0gbWVhc3VyZT8ubGluZSk7XG59XG5cbi8vIEEgbWVhc3VyZSdzIHN0YXRpc3RpYyBsaW5lIHdoZW4gaXQgbmFtZXMgb25lIHRoZSB2aWV3ZXIga25vd3MsIGVsc2Vcbi8vIHVuZGVmaW5lZCBhbmQgaXQgZHJhd3Mgbm9uZS5cbmV4cG9ydCBmdW5jdGlvbiBtZWFzdXJlTWFya1N0YXQobWVhc3VyZTogQ2hhcnRNZWFzdXJlIHwgdW5kZWZpbmVkKTogUmVwb3J0Q2hhcnRNYXJrU3RhdCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKFJlcG9ydENoYXJ0TWFya1N0YXQpLmZpbmQoKHN0YXQpID0+IHN0YXQgPT09IG1lYXN1cmU/Lm1hcmtMaW5lKTtcbn1cblxuLy8gQSBzZXJpZXMnIHN0YXRpc3RpYyBvdmVyIGl0cyBwb2ludHMgdGhhdCBoYXZlIGEgdmFsdWU6IHRoZWlyIG1lYW4sIHRoZWlyXG4vLyBtZWRpYW4gKHRoZSBtZWFuIG9mIHRoZSB0d28gbWlkZGxlIHZhbHVlcyB3aGVuIHRoZSBjb3VudCBpcyBldmVuKSwgdGhlXG4vLyBsb3dlc3Qgb3IgdGhlIGhpZ2hlc3QuIG51bGwgd2hlbiBubyBwb2ludCBoYXMgYSB2YWx1ZS4gU2hhcmVkIHdpdGggdGhlXG4vLyBQb3dlclBvaW50IGV4cG9ydCBzbyBib3RoIG1lZGlhIGRyYXcgdGhlIGxpbmUgYXQgdGhlIHNhbWUgaGVpZ2h0LlxuZXhwb3J0IGZ1bmN0aW9uIHNlcmllc1N0YXQodmFsdWVzOiAobnVtYmVyIHwgbnVsbClbXSwgc3RhdDogUmVwb3J0Q2hhcnRNYXJrU3RhdCk6IG51bWJlciB8IG51bGwge1xuICBjb25zdCBwcmVzZW50ID0gdmFsdWVzLmZpbHRlcigodmFsdWUpOiB2YWx1ZSBpcyBudW1iZXIgPT4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpKTtcblxuICBpZiAoIXByZXNlbnQubGVuZ3RoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzd2l0Y2ggKHN0YXQpIHtcbiAgICBjYXNlIFJlcG9ydENoYXJ0TWFya1N0YXQuQXZlcmFnZTpcbiAgICAgIHJldHVybiBwcmVzZW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApIC8gcHJlc2VudC5sZW5ndGg7XG4gICAgY2FzZSBSZXBvcnRDaGFydE1hcmtTdGF0Lk1lZGlhbjoge1xuICAgICAgY29uc3Qgc29ydGVkID0gWy4uLnByZXNlbnRdLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgICAgIGNvbnN0IG1pZGRsZSA9IE1hdGguZmxvb3Ioc29ydGVkLmxlbmd0aCAvIDIpO1xuXG4gICAgICByZXR1cm4gc29ydGVkLmxlbmd0aCAlIDIgPyBzb3J0ZWRbbWlkZGxlXSA6IChzb3J0ZWRbbWlkZGxlIC0gMV0gKyBzb3J0ZWRbbWlkZGxlXSkgLyAyO1xuICAgIH1cbiAgICBjYXNlIFJlcG9ydENoYXJ0TWFya1N0YXQuTWluOlxuICAgICAgcmV0dXJuIE1hdGgubWluKC4uLnByZXNlbnQpO1xuICAgIGNhc2UgUmVwb3J0Q2hhcnRNYXJrU3RhdC5NYXg6XG4gICAgICByZXR1cm4gTWF0aC5tYXgoLi4ucHJlc2VudCk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8vIFdoZXRoZXIgYSBjaGFydCBkcmF3cyBzdGF0aXN0aWMgbGluZXMuIEEgaG9yaXpvbnRhbCBjaGFydCdzIHZhbHVlcyBydW5cbi8vIGFsb25nIHgsIGFuZCBQb3dlclBvaW50IGNhbm5vdCBkcmF3IGEgbGluZSBiZXNpZGUgaG9yaXpvbnRhbCBiYXJzLCBzb1xuLy8gbmVpdGhlciBtZWRpdW0gZHJhd3Mgb25lIHRoZXJlLlxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdzU3RhdExpbmVzKGNvbmZpZzogQ2hhcnRDb25maWcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNvbmZpZy5vcmllbnRhdGlvbiAhPT0gJ2hvcml6b250YWwnO1xufVxuXG4vLyBBIGNvbG9yQnkgY2hhcnQncyBvbmUgdmFsdWUgcGVyIGNhdGVnb3J5OiBzZXJpZXMgaSBob2xkcyBjYXRlZ29yeSBpJ3MgYmFyLlxuLy8gUG93ZXJQb2ludCBkcmF3cyB0aGVzZSBhcyBpdHMgb25lIHNlcmllcywgYW5kIGEgc3RhdGlzdGljIGxpbmUgaXMgdGFrZW5cbi8vIG92ZXIgdGhlbS5cbmV4cG9ydCBmdW5jdGlvbiBjb2xvckJ5VmFsdWVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMpOiAobnVtYmVyIHwgbnVsbClbXSB7XG4gIHJldHVybiBleHRyYWN0ZWQuY2F0ZWdvcmllcy5tYXAoKF8sIGluZGV4KSA9PiBleHRyYWN0ZWQuc2VyaWVzW2luZGV4XT8udmFsdWVzW2luZGV4XSA/PyBudWxsKTtcbn1cblxuLy8gVGhlIHJlZmVyZW5jZXMgYSBjaGFydCBkcmF3cy4gQSB2ZXJ0aWNhbCBheGlzIGNoYXJ0IGFuZCBhIHdhdGVyZmFsbCBkcmF3XG4vLyB0aGVtOyBhIHBpZSBoYXMgbm8gdmFsdWUgYXhpcywgYW5kIGEgaG9yaXpvbnRhbCBjaGFydCBpcyBsZWZ0IHdpdGhvdXQgdGhlbVxuLy8gYXMgUG93ZXJQb2ludCBjYW5ub3QgZHJhdyBhIGxpbmUgYmVzaWRlIGhvcml6b250YWwgYmFycy4gQW4gZW50cnkgd2l0aG91dCBhXG4vLyBmaW5pdGUgdmFsdWUgaXMgc2tpcHBlZCwgYW5kIG9uZSB3aG9zZSBgdG9gIGlzIG1pc3Npbmcgb3IgZXF1YWwgdG8gaXRzIHZhbHVlXG4vLyBpcyBhIGxpbmUuIHNlY29uZGFyeSByZWFjaGVzIHRoZSBzZWNvbmQgdmFsdWUgYXhpcyBvbmx5IG9uIGEgY2hhcnQgdGhhdCBoYXNcbi8vIG9uZSAodHdvQXhlcykuIFNoYXJlZCB3aXRoIHRoZSBQb3dlclBvaW50IGV4cG9ydC5cbmV4cG9ydCBmdW5jdGlvbiBjaGFydFJlZmVyZW5jZXMoY29uZmlnOiBDaGFydENvbmZpZywgdHdvQXhlczogYm9vbGVhbik6IERyYXduUmVmZXJlbmNlW10ge1xuICBjb25zdCBjaGFydFR5cGUgPSBjb25maWcuY2hhcnRUeXBlID8/ICdiYXInO1xuICBjb25zdCByZWZlcmVuY2VzOiAoQ2hhcnRSZWZlcmVuY2UgfCBudWxsIHwgdW5kZWZpbmVkKVtdID0gQXJyYXkuaXNBcnJheShjb25maWcucmVmZXJlbmNlcykgPyBjb25maWcucmVmZXJlbmNlcyA6IFtdO1xuXG4gIGlmIChjb25maWcub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJyB8fCBjaGFydFR5cGUgPT09ICdwaWUnIHx8IGNoYXJ0VHlwZSA9PT0gJ2RvbnV0Jykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiByZWZlcmVuY2VzLmZsYXRNYXAoKHJlZmVyZW5jZSk6IERyYXduUmVmZXJlbmNlW10gPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gYXhpc051bWJlcihyZWZlcmVuY2U/LnZhbHVlKTtcblxuICAgIGlmICghcmVmZXJlbmNlIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCB0byA9IGF4aXNOdW1iZXIocmVmZXJlbmNlLnRvKTtcbiAgICBjb25zdCBsYWJlbCA9IHR5cGVvZiByZWZlcmVuY2UubGFiZWwgPT09ICdzdHJpbmcnID8gcmVmZXJlbmNlLmxhYmVsIDogJyc7XG4gICAgY29uc3QgYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleCA9IHR3b0F4ZXMgJiYgcmVmZXJlbmNlLnNlY29uZGFyeSA9PT0gdHJ1ZSA/IDEgOiAwO1xuXG4gICAgcmV0dXJuIFt0byAhPT0gdW5kZWZpbmVkICYmIHRvICE9PSB2YWx1ZVxuICAgICAgPyB7IGxhYmVsLCBsb3c6IE1hdGgubWluKHZhbHVlLCB0byksIGhpZ2g6IE1hdGgubWF4KHZhbHVlLCB0byksIGJhbmQ6IHRydWUsIGF4aXNJbmRleCB9XG4gICAgICA6IHsgbGFiZWwsIGxvdzogdmFsdWUsIGhpZ2g6IHZhbHVlLCBiYW5kOiBmYWxzZSwgYXhpc0luZGV4IH1dO1xuICB9KTtcbn1cblxuLy8gRWFjaCBzZXJpZXMgYXMgaXRzIHNoYXJlIG9mIGl0cyBjYXRlZ29yeSdzIHRvdGFsOiBwZXIgY2F0ZWdvcnksIHRoZVxuLy8gZGVub21pbmF0b3IgaXMgdGhlIHN1bSBvZiBldmVyeSBzZXJpZXMnIGFic29sdXRlIHZhbHVlIHRoZXJlLCBzbyB0aGVcbi8vIG1hZ25pdHVkZXMgb2YgYSBjYXRlZ29yeSdzIHNoYXJlcyBhZGQgdXAgdG8gMS4gQSBtaXhlZC1zaWduIGNhdGVnb3J5J3Ncbi8vIG5lZ2F0aXZlIHZhbHVlcyB0YWtlIG5lZ2F0aXZlIHNoYXJlcywgZHJhd24gYmVsb3cgemVyby4gQSBtaXNzaW5nIHZhbHVlXG4vLyBzdGF5cyBtaXNzaW5nLCBhbmQgYSBjYXRlZ29yeSB3aG9zZSB0b3RhbCBpcyB6ZXJvIGhhcyBubyBzaGFyZXMuIFNoYXJlZCBieVxuLy8gdGhlIHNjcmVlbiwgdGhlIFBERiBhbmQgUG93ZXJQb2ludCwgc28gYSAxMDAlIHN0YWNrIHJlYWRzIHRoZSBzYW1lIGluIGVhY2guXG5leHBvcnQgZnVuY3Rpb24gcGVyY2VudFNoYXJlcyh2YWx1ZXM6IChudW1iZXIgfCBudWxsKVtdW10pOiAobnVtYmVyIHwgbnVsbClbXVtdIHtcbiAgY29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoMCwgLi4udmFsdWVzLm1hcCgoc2VyaWVzKSA9PiBzZXJpZXMubGVuZ3RoKSk7XG4gIGNvbnN0IHRvdGFscyA9IEFycmF5LmZyb20oeyBsZW5ndGggfSwgKF8sIGluZGV4KSA9PiB2YWx1ZXNcbiAgICAucmVkdWNlKChzdW0sIHNlcmllcykgPT4gc3VtICsgTWF0aC5hYnMoc2VyaWVzW2luZGV4XSA/PyAwKSwgMCkpO1xuXG4gIHJldHVybiB2YWx1ZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy5tYXAoKHZhbHVlLCBpbmRleCkgPT4gKFxuICAgIHZhbHVlID09PSBudWxsIHx8ICF0b3RhbHNbaW5kZXhdID8gbnVsbCA6IHZhbHVlIC8gdG90YWxzW2luZGV4XVxuICApKSk7XG59XG5cbi8vIFRoZSBzaGFyZXMgYSAxMDAlIHN0YWNrZWQgY2hhcnQgZHJhd3MgaW4gcGxhY2Ugb2YgaXRzIHZhbHVlcywgb3IgbnVsbCB3aGVuXG4vLyB0aGUgY2hhcnQgaXMgbm90IG9uZS4gVGhlIHByaW1hcnkgYXhpcydzIGJhciBhbmQgYXJlYSBzZXJpZXMgdGFrZSB0aGVtLFxuLy8gZWFjaCB0eXBlJ3Mgc2VyaWVzIHNoYXJpbmcgYW1vbmcgdGhlbXNlbHZlcywgYXMgZWFjaCB0eXBlIHN0YWNrcyBhcGFydC5cbi8vIExpbmVzIGFuZCBzZWNvbmRhcnktYXhpcyBzZXJpZXMga2VlcCB0aGVpciB2YWx1ZXMuIEEgcGllLCBhIHdhdGVyZmFsbCBhbmQgYVxuLy8gY29sb3JCeSBjaGFydCAob25lIHNlcmllcyBwZXIgY2F0ZWdvcnksIGVhY2ggb2Ygd2hpY2ggd291bGQgYmUgMTAwJSkgYXJlXG4vLyBuZXZlciAxMDAlIHN0YWNrZWQsIG5vciBpcyBhIGNoYXJ0IHdpdGggbm8gYmFyIG9yIGFyZWEgb24gaXRzIHByaW1hcnkgYXhpcy5cbmV4cG9ydCBmdW5jdGlvbiBwZXJjZW50U3RhY2tlZFNoYXJlcyhleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLCBjb25maWc6IENoYXJ0Q29uZmlnKTogUGVyY2VudFNoYXJlcyB8IG51bGwge1xuICBjb25zdCBjaGFydFR5cGUgPSBjb25maWcuY2hhcnRUeXBlID8/ICdiYXInO1xuXG4gIGlmIChjb25maWcucGVyY2VudFN0YWNrZWQgIT09IHRydWVcbiAgICB8fCBjaGFydFR5cGUgPT09ICdwaWUnIHx8IGNoYXJ0VHlwZSA9PT0gJ2RvbnV0JyB8fCBjaGFydFR5cGUgPT09ICd3YXRlcmZhbGwnXG4gICAgfHwgaXNDb2xvckJ5KGNvbmZpZykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHR5cGVzID0gc2VyaWVzVHlwZXMoZXh0cmFjdGVkLCBjaGFydFR5cGUpO1xuICBjb25zdCBheGlzSW5kZXhlcyA9IHNlcmllc0F4aXNJbmRleGVzKGV4dHJhY3RlZCwgY29uZmlnKTtcbiAgY29uc3Qgc2hhcmVzOiBQZXJjZW50U2hhcmVzID0gbmV3IE1hcCgpO1xuXG4gIGZvciAoY29uc3QgdHlwZSBvZiBbJ2JhcicsICdhcmVhJ10gYXMgY29uc3QpIHtcbiAgICBjb25zdCBpbmRleGVzID0gdHlwZXNcbiAgICAgIC5tYXAoKHNlcmllc1R5cGUsIGluZGV4KSA9PiAoc2VyaWVzVHlwZSA9PT0gdHlwZSAmJiBheGlzSW5kZXhlc1tpbmRleF0gPT09IDAgPyBpbmRleCA6IC0xKSlcbiAgICAgIC5maWx0ZXIoKGluZGV4KSA9PiBpbmRleCA+PSAwKTtcbiAgICBjb25zdCB0eXBlU2hhcmVzID0gcGVyY2VudFNoYXJlcyhpbmRleGVzLm1hcCgoaW5kZXgpID0+IGV4dHJhY3RlZC5zZXJpZXNbaW5kZXhdLnZhbHVlcykpO1xuICAgIGluZGV4ZXMuZm9yRWFjaCgoc2VyaWVzSW5kZXgsIHBvc2l0aW9uKSA9PiBzaGFyZXMuc2V0KHNlcmllc0luZGV4LCB0eXBlU2hhcmVzW3Bvc2l0aW9uXSkpO1xuICB9XG5cbiAgcmV0dXJuIHNoYXJlcy5zaXplID8gc2hhcmVzIDogbnVsbDtcbn1cblxuLy8gV2hlcmUgYSAxMDAlIHN0YWNrZWQgY2hhcnQncyB2YWx1ZSBheGlzIHN0YXJ0czogYXQgLTEwMCUgd2hlbiBhbnkgc2hhcmUgaXNcbi8vIG5lZ2F0aXZlLCBlbHNlIGF0IHplcm8uXG5leHBvcnQgZnVuY3Rpb24gcGVyY2VudEF4aXNNaW4oc2hhcmVzOiBQZXJjZW50U2hhcmVzKTogbnVtYmVyIHtcbiAgcmV0dXJuIFsuLi5zaGFyZXMudmFsdWVzKCldLnNvbWUoKHNlcmllcykgPT4gc2VyaWVzLnNvbWUoKHNoYXJlKSA9PiAoc2hhcmUgPz8gMCkgPCAwKSkgPyAtMSA6IDA7XG59XG5cbi8vIFRoZSBtZWFzdXJlcyBhIGNoYXJ0IHBsb3RzOiBpdHMgY29uZmlndXJlZCBvbmVzLCBlbHNlIHRoZSBxdWVyeSdzIGxhc3Rcbi8vIGNvbHVtbiwgdW5mb3JtYXR0ZWQuXG5mdW5jdGlvbiBjaGFydE1lYXN1cmVzKGNvbmZpZzogQ2hhcnRDb25maWcsIGRhdGE6IENvbXBvbmVudERhdGEpOiBDaGFydE1lYXN1cmVbXSB7XG4gIHJldHVybiBjb25maWcubWVhc3VyZXM/Lmxlbmd0aFxuICAgID8gY29uZmlnLm1lYXN1cmVzXG4gICAgOiBbeyBjb2x1bW46IGRhdGEuY29sdW1uc1tkYXRhLmNvbHVtbnMubGVuZ3RoIC0gMV0gfV07XG59XG5cbi8vIFRoZSB0eXBlIGVhY2ggZXh0cmFjdGVkIHNlcmllcyBpcyBkcmF3biBhczogaXRzIG1lYXN1cmUncyBvd24gdHlwZSB3aGVuIGl0XG4vLyBuYW1lcyBvbmUsIHRoZSBjaGFydCdzIGNoYXJ0VHlwZSBvdGhlcndpc2UuIE1vcmUgdGhhbiBvbmUgZGlzdGluY3QgdHlwZSBpcyBhXG4vLyBjb21ibyBjaGFydC4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGggbWVkaWEgZHJhdyBlYWNoIHNlcmllc1xuLy8gdGhlIHNhbWUgd2F5LlxuZXhwb3J0IGZ1bmN0aW9uIHNlcmllc1R5cGVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIGNoYXJ0VHlwZTogQXhpc0NoYXJ0VHlwZSk6IEF4aXNDaGFydFR5cGVbXSB7XG4gIHJldHVybiBleHRyYWN0ZWQuc2VyaWVzLm1hcCgoc2VyaWVzKSA9PiBzZXJpZXMudHlwZSA/PyBjaGFydFR5cGUpO1xufVxuXG4vLyBUaGUgdmFsdWUgYXhpcyBlYWNoIGV4dHJhY3RlZCBzZXJpZXMgaXMgcGxvdHRlZCBhZ2FpbnN0OiAxIHdoZW4gaXRzIG1lYXN1cmVcbi8vIGlzIHNlY29uZGFyeSwgMCBvdGhlcndpc2UuIEEgc2Vjb25kIGF4aXMgaXMgZHJhd24gb25seSBvbiBhIHZlcnRpY2FsIGNoYXJ0XG4vLyB0aGF0IGtlZXBzIGF0IGxlYXN0IG9uZSBzZXJpZXMgb24gdGhlIHByaW1hcnkgYXhpcywgc28gYSBjb21iaW5hdGlvbiB0aGVcbi8vIHNlcnZlciByZWZ1c2VzIChhIGhvcml6b250YWwgY2hhcnQsIGV2ZXJ5IG1lYXN1cmUgc2Vjb25kYXJ5LCB0aGUgb25lIG1lYXN1cmVcbi8vIG9mIGEgc3BsaXRCeSBvciBjb2xvckJ5IGNoYXJ0KSBwbG90cyBldmVyeXRoaW5nIG9uIHRoZSBwcmltYXJ5IGF4aXMuIFNoYXJlZFxuLy8gd2l0aCB0aGUgUG93ZXJQb2ludCBleHBvcnQgc28gYm90aCBtZWRpYSBwdXQgZWFjaCBzZXJpZXMgb24gdGhlIHNhbWUgYXhpcy5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpZXNBeGlzSW5kZXhlcyhleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLCBjb25maWc6IENoYXJ0Q29uZmlnKTogVmFsdWVBeGlzSW5kZXhbXSB7XG4gIGNvbnN0IHNlY29uZGFyeSA9IGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+ICEhc2VyaWVzLm1lYXN1cmUuc2Vjb25kYXJ5KTtcbiAgY29uc3QgdHdvQXhlcyA9IGNvbmZpZy5vcmllbnRhdGlvbiAhPT0gJ2hvcml6b250YWwnICYmIHNlY29uZGFyeS5pbmNsdWRlcyh0cnVlKSAmJiBzZWNvbmRhcnkuaW5jbHVkZXMoZmFsc2UpO1xuXG4gIHJldHVybiBzZWNvbmRhcnkubWFwKChpc1NlY29uZGFyeSkgPT4gKHR3b0F4ZXMgJiYgaXNTZWNvbmRhcnkgPyAxIDogMCkpO1xufVxuXG4vLyBPbmUgYmFyIG9mIGEgd2F0ZXJmYWxsLiBgc3RhcnRgIGlzIHRoZSBydW5uaW5nIHRvdGFsIGJlZm9yZSBpdCwgd2hlcmUgdGhlIGJhclxuLy8gc3RhcnRzLCBhbmQgYGNoYW5nZWAgaXRzIHNpZ25lZCBoZWlnaHQsIHNvIGl0IGVuZHMgYXQgc3RhcnQgKyBjaGFuZ2UuIFRoZVxuLy8gY2xvc2luZyB0b3RhbCBzdGFydHMgYXQgemVybyBhbmQgaXRzIGNoYW5nZSBpcyB0aGUgd2hvbGUgcnVubmluZyB0b3RhbC5cbmV4cG9ydCBpbnRlcmZhY2UgV2F0ZXJmYWxsU3RlcCB7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIHN0YXJ0OiBudW1iZXI7XG4gIGNoYW5nZTogbnVtYmVyIHwgbnVsbDtcbiAga2luZDogV2F0ZXJmYWxsU3RlcEtpbmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0cmFjdGVkV2F0ZXJmYWxsIHtcbiAgbmFtZTogc3RyaW5nO1xuICBzdGVwczogV2F0ZXJmYWxsU3RlcFtdO1xufVxuXG5leHBvcnQgY29uc3QgV0FURVJGQUxMX1RPVEFMX0xBQkVMID0gJ1RvdGFsJztcblxuLy8gQSB3YXRlcmZhbGwncyBiYXJzIGZyb20gaXRzIG9uZSBtZWFzdXJlOiBlYWNoIGNhdGVnb3J5J3MgdmFsdWUgaXMgaG93IGZhciB0aGVcbi8vIHJ1bm5pbmcgdG90YWwgbW92ZXMgdGhlcmUsIGFuZCBhIGxhc3QgVG90YWwgYmFyIHNob3dzIHdoZXJlIGl0IGVuZGVkLiBBXG4vLyBjYXRlZ29yeSB3aXRoIG5vIHZhbHVlIG1vdmVzIG5vdGhpbmcgYW5kIGRyYXdzIG5vIGJhci4gU2hhcmVkIHdpdGggdGhlXG4vLyBQb3dlclBvaW50IGV4cG9ydCBzbyBib3RoIG1lZGlhIGRyYXcgdGhlIHNhbWUgc3RlcHMuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFdhdGVyZmFsbChjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgZGF0YTogQ29tcG9uZW50RGF0YSk6IEV4dHJhY3RlZFdhdGVyZmFsbCB7XG4gIGNvbnN0IGV4dHJhY3RlZCA9IGV4dHJhY3RDaGFydFNlcmllcyhjb21wb25lbnQsIGRhdGEpO1xuICBjb25zdCB2YWx1ZXMgPSBleHRyYWN0ZWQuc2VyaWVzWzBdPy52YWx1ZXMgPz8gW107XG4gIGNvbnN0IHN0ZXBzOiBXYXRlcmZhbGxTdGVwW10gPSBbXTtcbiAgbGV0IHRvdGFsID0gMDtcblxuICBleHRyYWN0ZWQuY2F0ZWdvcmllcy5mb3JFYWNoKChjYXRlZ29yeSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBjaGFuZ2UgPSB2YWx1ZXNbaW5kZXhdID8/IG51bGw7XG4gICAgc3RlcHMucHVzaCh7IGNhdGVnb3J5LCBzdGFydDogdG90YWwsIGNoYW5nZSwga2luZDogKGNoYW5nZSA/PyAwKSA8IDAgPyAnZmFsbCcgOiAncmlzZScgfSk7XG4gICAgdG90YWwgKz0gY2hhbmdlID8/IDA7XG4gIH0pO1xuXG4gIHN0ZXBzLnB1c2goeyBjYXRlZ29yeTogV0FURVJGQUxMX1RPVEFMX0xBQkVMLCBzdGFydDogMCwgY2hhbmdlOiB0b3RhbCwga2luZDogJ3RvdGFsJyB9KTtcblxuICByZXR1cm4geyBuYW1lOiBleHRyYWN0ZWQuc2VyaWVzWzBdPy5uYW1lID8/ICcnLCBzdGVwcyB9O1xufVxuXG4vLyBUaGUgb25lIHB1cmUgbWFwcGluZyBmcm9tIG91ciBzdGFuZGFyZCBjYW1lbENhc2UgY2hhcnQgY29uZmlnICsgdGhlIGRhdGFcbi8vIGVuZHBvaW50J3Mgcm93cyB0byBhbiBFQ2hhcnRzIG9wdGlvbi4gRXZlcnl0aGluZyB2aXN1YWwgdGhhdCBpc24ndCBpbiB0aGVcbi8vIHJlZ2lzdGVyZWQgJ3JlcG9ydCcgdGhlbWUgaXMgZGVjaWRlZCBoZXJlLCBzbyByZXBvcnQgc3RhbmRhcmRzIGhhdmUgZXhhY3RseVxuLy8gdHdvIGhvbWVzLlxuLy9cbi8vIEV2ZXJ5IG51bWJlciBhbmQgcGVyaW9kIHRoZSBjaGFydCB3cml0ZXMgKHZhbHVlLWF4aXMgdGlja3MsIHRvb2x0aXAgdmFsdWVzLFxuLy8gcGVyaW9kIGxhYmVscykgaXMgaW4gdGhlIGNvbnRleHQncyBsb2NhbGUsIG5ldmVyIHRoZSBicm93c2VyJ3MuIEEgbWVhc3VyZVxuLy8gd2l0aCBudW1iZXItZm9ybWF0IGtleXMgZm9ybWF0cyBpdHMgdG9vbHRpcHMsIGFuZCB0aGUgdmFsdWUgYXhpcyB3aGVuIGV2ZXJ5XG4vLyBtZWFzdXJlIG9uIGl0IGFncmVlcyAoYXhpc051bWJlckZvcm1hdCk7IHdpdGhvdXQgdGhlbSB0aGUgYXhpcyBhbmQgdG9vbHRpcHNcbi8vIGtlZXAgdGhlIHBsYWluIGxvY2FsZS1ncm91cGVkIG51bWJlci5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENoYXJ0T3B0aW9uKFxuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6IEVDaGFydHNPcHRpb24ge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCBjaGFydFR5cGUgPSBjb25maWcuY2hhcnRUeXBlID8/ICdiYXInO1xuXG4gIGlmIChjaGFydFR5cGUgPT09ICdwaWUnIHx8IGNoYXJ0VHlwZSA9PT0gJ2RvbnV0Jykge1xuICAgIHJldHVybiBidWlsZFBpZU9wdGlvbihjb21wb25lbnQsIGRhdGEsIGNoYXJ0VHlwZSA9PT0gJ2RvbnV0JywgY29udGV4dCk7XG4gIH1cblxuICBpZiAoY2hhcnRUeXBlID09PSAnd2F0ZXJmYWxsJykge1xuICAgIHJldHVybiBidWlsZFdhdGVyZmFsbE9wdGlvbihjb21wb25lbnQsIGRhdGEsIGNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGJ1aWxkQXhpc09wdGlvbihjb21wb25lbnQsIGRhdGEsIGNoYXJ0VHlwZSwgY29udGV4dCk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkQXhpc09wdGlvbihcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGNoYXJ0VHlwZTogQXhpc0NoYXJ0VHlwZSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6IEVDaGFydHNPcHRpb24ge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCBleHRyYWN0ZWQgPSBleHRyYWN0Q2hhcnRTZXJpZXMoY29tcG9uZW50LCBkYXRhKTtcbiAgY29uc3QgaG9yaXpvbnRhbCA9IGNvbmZpZy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnO1xuICBjb25zdCBjb2xvckJ5ID0gaXNDb2xvckJ5KGNvbmZpZyk7XG4gIGNvbnN0IHR5cGVzID0gc2VyaWVzVHlwZXMoZXh0cmFjdGVkLCBjaGFydFR5cGUpO1xuICBjb25zdCBjb21ibyA9IG5ldyBTZXQodHlwZXMpLnNpemUgPiAxO1xuXG4gIC8vIGNvbG9yQnkgZW1pdHMgb25lIHNlcmllcyBwZXIgY2F0ZWdvcnk7IG92ZXJsYXBwaW5nIHRoZW0gKGJhckdhcCAtMTAwJSkgbWFrZXNcbiAgLy8gZWFjaCByZW5kZXIgYXQgdGhlIGZ1bGwgY2F0ZWdvcnktYmFuZCB3aWR0aCDigJQgb25lIGZ1bGwtd2lkdGgsIGRpc3RpbmN0bHlcbiAgLy8gY29sb3JlZCBiYXIgcGVyIGNhdGVnb3J5IOKAlCBpbnN0ZWFkIG9mIHNpZGUtYnktc2lkZSBzbGl2ZXJzLiBUaGUgbGF5b3V0IHByb3BzXG4gIC8vIGFyZSByZWFkIGZyb20gdGhlIGZpcnN0IHNlcmllcyBvZiB0aGUgY29vcmRpbmF0ZSBzeXN0ZW0uXG4gIC8vXG4gIC8vIFN0YWNraW5nIHN1bXMgZXZlcnkgc2VyaWVzIHRoYXQgc2hhcmVzIGEgc3RhY2sgbmFtZSwgd2hhdGV2ZXIgaXRzIHR5cGUuIEluXG4gIC8vIGEgY29tYm8gZWFjaCB0eXBlIHN0YWNrcyBvbmx5IHdpdGggaXRzIG93biBraW5kLCBzbyBhIGxpbmUgb2YgYSByYXRlIG5ldmVyXG4gIC8vIHNpdHMgb24gdG9wIG9mIHRoZSBiYXJzJyB0b3RhbCwgYW5kIG9uIGEgdHdvLWF4aXMgY2hhcnQgb25seSB3aXRoIHRoZVxuICAvLyBzZXJpZXMgb24gaXRzIG93biBheGlzLlxuICAvL1xuICAvLyBBIDEwMCUgc3RhY2tlZCBjaGFydCAocGVyY2VudFN0YWNrZWRTaGFyZXMpIHBsb3RzIGl0cyBwcmltYXJ5IGJhcnMgYW5kXG4gIC8vIGFyZWFzIGFzIHNoYXJlcywgZWFjaCB0eXBlIGluIGl0cyBvd24gc3RhY2ssIGFuZCBsZWF2ZXMgZXZlcnkgb3RoZXIgc2VyaWVzXG4gIC8vIHVuc3RhY2tlZCBvbiBpdHMgb3duIHZhbHVlcy5cbiAgLy9cbiAgLy8gV2hhdCB0aGUgc2VydmVyIHNheXMgb2YgdGhlIG51bWJlcnMgKGNoYXJ0QW5ub3RhdGlvbnMpIG1hcmtzIHRoZW06IGFcbiAgLy8gcHJpb3Igc2VyaWVzIGRhc2hlZCBpbiBpdHMgY3VycmVudCBzZXJpZXMnIGNvbG9yLCB0aGUgcGVyaW9kIG5vdCBvdmVyIHlldFxuICAvLyBoYXRjaGVkIG9yIGRhc2hlZCwgcmFua3Mgb24gYW4gaW52ZXJ0ZWQgYXhpcywgZnJhY3Rpb25zIG9uIGEgcGVyY2VudCBheGlzLFxuICAvLyBhbmQgdGhlIHRvb2x0aXAgbmFtaW5nIGVhY2ggcHJpb3IncyBkYXlzIGFuZCBlYWNoIHdpbmRvdy4gRGF0YSB3aXRob3V0XG4gIC8vIHRob3NlIGtleXMgZHJhd3MgZXhhY3RseSBhcyBiZWZvcmUuXG4gIGNvbnN0IGF4aXNJbmRleGVzID0gc2VyaWVzQXhpc0luZGV4ZXMoZXh0cmFjdGVkLCBjb25maWcpO1xuICBjb25zdCB0d29BeGVzID0gYXhpc0luZGV4ZXMuaW5jbHVkZXMoMSk7XG4gIGNvbnN0IHNoYXJlcyA9IHBlcmNlbnRTdGFja2VkU2hhcmVzKGV4dHJhY3RlZCwgY29uZmlnKTtcbiAgY29uc3QgcmVmZXJlbmNlcyA9IGNoYXJ0UmVmZXJlbmNlcyhjb25maWcsIHR3b0F4ZXMpO1xuICBjb25zdCBhbm5vdGF0aW9ucyA9IGNoYXJ0QW5ub3RhdGlvbnMoY29uZmlnLCBkYXRhLCBleHRyYWN0ZWQsIGNvbG9yQnkpO1xuICBjb25zdCBheGlzRm9ybWF0cyA9IHZhbHVlQXhpc0Zvcm1hdHMoXG4gICAgY29uZmlnLFxuICAgIGFubm90YXRpb25zID8gYW5ub3RhdGVkQXhpc1NlcmllcyhleHRyYWN0ZWQsIGFubm90YXRpb25zKSA6IGV4dHJhY3RlZCxcbiAgICBheGlzSW5kZXhlcyxcbiAgICBhbm5vdGF0aW9ucyAmJiAhc2hhcmVzID8gYW5ub3RhdGVkQXhpc0NvbnRleHRzKGFubm90YXRpb25zLCBheGlzSW5kZXhlcywgY29udGV4dCkgOiBbY29udGV4dCwgY29udGV4dF0sXG4gICAgISFzaGFyZXMsXG4gICAgcmVmZXJlbmNlcyxcbiAgKTtcbiAgY29uc3QgcmFua0F4ZXMgPSBhbm5vdGF0aW9ucyAmJiAhc2hhcmVzID8gcmFua0F4aXNGbGFncyhhbm5vdGF0aW9ucy5vdXRwdXRzLCBheGlzSW5kZXhlcykgOiBbZmFsc2UsIGZhbHNlXTtcbiAgLy8gQSBzZXJpZXMnIHN0YXRpc3RpYyBsaW5lIGlzIHRha2VuIG92ZXIgdGhlIHBvaW50cyBpdCBwbG90cy4gT24gYSBjb2xvckJ5XG4gIC8vIGNoYXJ0IGVhY2ggc2VyaWVzIGhvbGRzIG9uZSBiYXIsIHNvIHRoZSBvbmUgbGluZSBpcyB0YWtlbiBvdmVyIHRoZSBiYXJzXG4gIC8vIHRvZ2V0aGVyIGFuZCBoYW5ncyBvZmYgdGhlIGZpcnN0IHNlcmllcyAoY29sb3JCeVN0YXRMaW5lKS5cbiAgY29uc3Qgc3RhdExpbmVzID0gZHJhd3NTdGF0TGluZXMoY29uZmlnKSAmJiAhY29sb3JCeTtcbiAgY29uc3Qgc2VyaWVzOiBTZXJpZXNPcHRpb25bXSA9IGV4dHJhY3RlZC5zZXJpZXMubWFwKChleHRyYWN0ZWRTZXJpZXMsIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgc2VyaWVzU2hhcmVzID0gc2hhcmVzPy5nZXQoaW5kZXgpO1xuICAgIGxldCBzdGFjazogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmIChzZXJpZXNTaGFyZXMpIHtcbiAgICAgIHN0YWNrID0gc3RhY2tLZXkodHlwZXNbaW5kZXhdLCBjb21ibywgMCk7XG4gICAgfSBlbHNlIGlmIChjb25maWcuc3RhY2tlZCAmJiAhc2hhcmVzKSB7XG4gICAgICBzdGFjayA9IHN0YWNrS2V5KHR5cGVzW2luZGV4XSwgY29tYm8sIHR3b0F4ZXMgPyBheGlzSW5kZXhlc1tpbmRleF0gOiB1bmRlZmluZWQpO1xuICAgIH1cblxuICAgIC8vIEFuIG91dHB1dCBzZXJpZXMgKGEgY29tcGFyZWQsIHdpbmRvd2VkLCByYW5rZWQgb3Igc2hhcmVkIHZhbHVlKSB3cml0ZXNcbiAgICAvLyBpdHMgdG9vbHRpcCwgZGF0YSBsYWJlbHMgYW5kIHN0YXRpc3RpYyBsaW5lIGJ5IHdoYXQgaXQgaG9sZHMuXG4gICAgY29uc3Qgd3JpdGUgPSBhbm5vdGF0aW9ucyAmJiAhc2VyaWVzU2hhcmVzICYmIGFubm90YXRpb25zLm91dHB1dHNbaW5kZXhdXG4gICAgICA/IG91dHB1dFdyaXRlcihhbm5vdGF0aW9ucywgaW5kZXgsIGV4dHJhY3RlZFNlcmllcy5tZWFzdXJlLCBjb250ZXh0KVxuICAgICAgOiBudWxsO1xuICAgIGNvbnN0IHN0YXQgPSBzdGF0TGluZXMgPyBtZWFzdXJlTWFya1N0YXQoZXh0cmFjdGVkU2VyaWVzLm1lYXN1cmUpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1hcmtMaW5lID0gc3RhdCAmJiBzdGF0TWFya0xpbmUoXG4gICAgICBzZXJpZXNTaGFyZXMgPz8gZXh0cmFjdGVkU2VyaWVzLnZhbHVlcyxcbiAgICAgIHN0YXQsXG4gICAgICBzZXJpZXNTaGFyZXMgPyBzaGFyZVdyaXRlcihjb250ZXh0KSA6IHdyaXRlID8/IG1lYXN1cmVXcml0ZXIoZXh0cmFjdGVkU2VyaWVzLm1lYXN1cmUsIGNvbnRleHQpLFxuICAgICk7XG4gICAgY29uc3Qgb3B0aW9uID0gYnVpbGRTZXJpZXMoXG4gICAgICBleHRyYWN0ZWRTZXJpZXMsXG4gICAgICBzZXJpZXNTaGFyZXMgPyBzaGFyZURhdGEoZXh0cmFjdGVkU2VyaWVzLnZhbHVlcywgc2VyaWVzU2hhcmVzKSA6IGV4dHJhY3RlZFNlcmllcy52YWx1ZXMsXG4gICAgICB7XG4gICAgICAgIHR5cGU6IHR5cGVzW2luZGV4XSxcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIG92ZXJsYXA6IGNvbG9yQnkgJiYgaW5kZXggPT09IDAsXG4gICAgICAgIGNvbWJvLFxuICAgICAgICB0b29sdGlwOiB3cml0ZSA/IHsgdmFsdWVGb3JtYXR0ZXI6IHdyaXRlIH0gOiBzZXJpZXNUb29sdGlwKGV4dHJhY3RlZFNlcmllcy5tZWFzdXJlLCBjb250ZXh0KSxcbiAgICAgICAgYXhpc0luZGV4OiB0d29BeGVzID8gYXhpc0luZGV4ZXNbaW5kZXhdIDogdW5kZWZpbmVkLFxuICAgICAgICAvLyBBIGNvbG9yQnkgY2hhcnQncyBiYXJzIHRha2UgdGhlIHBhbGV0dGUgYnkgY2F0ZWdvcnksIGFzIGluXG4gICAgICAgIC8vIFBvd2VyUG9pbnQsIHdoYXRldmVyIGNvbG9yIHRoZSBtZWFzdXJlIG5hbWVzLlxuICAgICAgICBjb2xvcjogY29sb3JCeSA/IHVuZGVmaW5lZCA6IGFubm90YXRpb25zPy5jb2xvcnM/LltpbmRleF0gPz8gc2VyaWVzQ29sb3IoZXh0cmFjdGVkU2VyaWVzKSxcbiAgICAgICAgbGFiZWxzOiBkYXRhTGFiZWxPcHRpb24oY29uZmlnLmRhdGFMYWJlbHMsIHdyaXRlXG4gICAgICAgICAgPyBvdXRwdXRMYWJlbEZvcm1hdHRlcih3cml0ZSlcbiAgICAgICAgICA6IGRhdGFMYWJlbEZvcm1hdHRlcihcbiAgICAgICAgICAgIGV4dHJhY3RlZFNlcmllcy5tZWFzdXJlLFxuICAgICAgICAgICAgYXhpc0Zvcm1hdHNbYXhpc0luZGV4ZXNbaW5kZXhdXSA/PyBudWxsLFxuICAgICAgICAgICAgISFzZXJpZXNTaGFyZXMsXG4gICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICkpLFxuICAgICAgfSxcbiAgICApO1xuICAgIGNvbnN0IG1hcmtlZCA9IGFubm90YXRpb25zID8gbWFya1NlcmllcyhvcHRpb24sIGFubm90YXRpb25zLCBpbmRleCwgZXh0cmFjdGVkU2VyaWVzLm1lYXN1cmUpIDogb3B0aW9uO1xuXG4gICAgcmV0dXJuIG1hcmtMaW5lID8geyAuLi5tYXJrZWQsIG1hcmtMaW5lIH0gYXMgU2VyaWVzT3B0aW9uIDogbWFya2VkO1xuICB9KTtcblxuICBpZiAoY29sb3JCeSAmJiBkcmF3c1N0YXRMaW5lcyhjb25maWcpICYmIHNlcmllcy5sZW5ndGgpIHtcbiAgICBzZXJpZXNbMF0gPSBjb2xvckJ5U3RhdExpbmUoc2VyaWVzWzBdLCBleHRyYWN0ZWQsIGNvbnRleHQsIGFubm90YXRpb25zPy5vdXRwdXRzWzBdXG4gICAgICA/IG91dHB1dFdyaXRlcihhbm5vdGF0aW9ucywgMCwgZXh0cmFjdGVkLnNlcmllc1swXS5tZWFzdXJlLCBjb250ZXh0KVxuICAgICAgOiB1bmRlZmluZWQpO1xuICB9XG5cbiAgLy8gRHJhd24gYWZ0ZXIgdGhlIG1lYXN1cmUgc2VyaWVzLCBzbyBhIHRvb2x0aXAgcmVhZHMgYSBzZXJpZXMgYnkgaXRzIGluZGV4LlxuICBjb25zdCBzZWdtZW50cyA9IGFubm90YXRpb25zID8gcGFydGlhbFNlZ21lbnRzKHNlcmllcywgYW5ub3RhdGlvbnMpIDogW107XG4gIGNvbnN0IHBlcmNlbnRNaW4gPSBzaGFyZXMgPyBwZXJjZW50QXhpc01pbihzaGFyZXMpIDogdW5kZWZpbmVkO1xuICBjb25zdCBjYXRlZ29yeUF4aXMgPSBjYXRlZ29yeUF4aXNPcHRpb24oY29uZmlnLCBkYXRhLCBleHRyYWN0ZWQuY2F0ZWdvcmllcywgaG9yaXpvbnRhbCwgY29udGV4dC5sb2NhbGUpO1xuICAvLyBBbiBheGlzIG9mIHJhdGUgY2hhbmdlcyBhbG9uZSByZWFkcyBpbiBwZXJjZW50YWdlIHBvaW50cywgYXMgaXRzIHZhbHVlcyBkby5cbiAgY29uc3QgYXhpc0xhYmVscyA9IChbMCwgMV0gYXMgY29uc3QpLm1hcCgoYXhpc0luZGV4KSA9PiAoYW5ub3RhdGlvbnMgJiYgIXNoYXJlc1xuICAgID8gcG9pbnRzQXhpc0xhYmVsKGFubm90YXRpb25zLCBleHRyYWN0ZWQsIGF4aXNJbmRleGVzLCBheGlzSW5kZXgsIGNvbnRleHQpXG4gICAgOiBudWxsKSA/PyB2YWx1ZUF4aXNMYWJlbChheGlzRm9ybWF0c1theGlzSW5kZXhdID8/IG51bGwsIGNvbnRleHQpKTtcbiAgY29uc3QgdmFsdWVBeGlzID0gdHdvQXhlc1xuICAgID8gdHdvVmFsdWVBeGVzT3B0aW9uKGNvbmZpZywgYXhpc0xhYmVscywgY29udGV4dCwgcGVyY2VudE1pbiwgcmVmZXJlbmNlcywgcmFua0F4ZXMpXG4gICAgOiB2YWx1ZUF4aXNPcHRpb24oY29uZmlnLnZhbHVlQXhpcywgaG9yaXpvbnRhbCwgcGVyY2VudE1pbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGF4aXNMYWJlbHNbMF1cbiAgICAgIDogcGVyY2VudEF4aXNMYWJlbChjb250ZXh0KSwgeyBwZXJjZW50TWluLCByZWFjaDogcmVmZXJlbmNlUmVhY2gocmVmZXJlbmNlcywgMCksIHJhbms6IHJhbmtBeGVzWzBdIH0pO1xuXG4gIGNvbnN0IGxlZ2VuZFBvc2l0aW9uID0gcmVzb2x2ZUxlZ2VuZFBvc2l0aW9uKGNvbmZpZywgc2VyaWVzLmxlbmd0aCwgY29sb3JCeSk7XG4gIGNvbnN0IHZhbHVlVGl0bGVzID0gW2NvbmZpZy52YWx1ZUF4aXMsIHR3b0F4ZXMgPyBjb25maWcuc2Vjb25kYXJ5QXhpcyA6IHVuZGVmaW5lZF07XG4gIGNvbnN0IGdyYW51bGFyaXR5ID0gYnVja2V0R3JhbnVsYXJpdHkoZGF0YSk7XG5cbiAgcmV0dXJuIHtcbiAgICBncmlkOiBheGlzR3JpZChsZWdlbmRQb3NpdGlvbiwgY2F0ZWdvcnlUaXRsZVNpZGUoY29uZmlnLCBob3Jpem9udGFsKSwgdmFsdWVUaXRsZVNpZGUodmFsdWVUaXRsZXMsIGhvcml6b250YWwpKSxcbiAgICBsZWdlbmQ6IHJlZmVyZW5jZUxlZ2VuZChsZWdlbmRPcHRpb24obGVnZW5kUG9zaXRpb24pLCBzZXJpZXMsIHJlZmVyZW5jZXMpLFxuICAgIC8vIGNvbG9yQnkgY2hhcnRzIG92ZXJsYXAgTiBtb3N0bHktbnVsbCBzZXJpZXMsIHNvIGFuIGF4aXMgdG9vbHRpcCB3b3VsZCBsaXN0XG4gICAgLy8gZXZlcnkgY2F0ZWdvcnk7IGFuIGl0ZW0gdG9vbHRpcCBzaG93cyBqdXN0IHRoZSBob3ZlcmVkIGJhci4gQSAxMDAlXG4gICAgLy8gc3RhY2tlZCBjaGFydCdzIHRvb2x0aXAgZ2l2ZXMgZWFjaCBzaGFyZSBhbmQgdGhlIHZhbHVlIGl0IGNhbWUgZnJvbS4gQVxuICAgIC8vIGNoYXJ0IHdpdGggdGhlIHNlcnZlcidzIGFubm90YXRpb25zIG5hbWVzIHdoYXQgZWFjaCB2YWx1ZSBjb3ZlcnMuXG4gICAgdG9vbHRpcDogc2hhcmVzXG4gICAgICA/IHtcbiAgICAgICAgdHJpZ2dlcjogJ2F4aXMnLFxuICAgICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcykgPT4gcGVyY2VudFRvb2x0aXAoXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgICBzaGFyZXMsXG4gICAgICAgICAgZ3JhbnVsYXJpdHksXG4gICAgICAgICAgY2hhcnREYXRlTGFiZWwoY29uZmlnKSxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICApLFxuICAgICAgfVxuICAgICAgOiBhbm5vdGF0ZWRDaGFydFRvb2x0aXAoYW5ub3RhdGlvbnMgJiYgIWNvbG9yQnkgPyB7XG4gICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgYW5ub3RhdGlvbnMsXG4gICAgICAgIG93bmVyczogc2VnbWVudHMubWFwKChzZWdtZW50KSA9PiBzZWdtZW50Lm93bmVyKSxcbiAgICAgICAgZ3JhbnVsYXJpdHksXG4gICAgICAgIGRhdGVMYWJlbDogY2hhcnREYXRlTGFiZWwoY29uZmlnKSxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIH0gOiBudWxsKSA/PyB7IHRyaWdnZXI6IGNvbG9yQnkgPyAnaXRlbScgOiAnYXhpcycgfSxcbiAgICB4QXhpczogaG9yaXpvbnRhbCA/IHZhbHVlQXhpcyA6IGNhdGVnb3J5QXhpcyxcbiAgICB5QXhpczogaG9yaXpvbnRhbCA/IGNhdGVnb3J5QXhpcyA6IHZhbHVlQXhpcyxcbiAgICBzZXJpZXM6IFsuLi5zZXJpZXMsIC4uLnNlZ21lbnRzLm1hcCgoc2VnbWVudCkgPT4gc2VnbWVudC5zZXJpZXMpLCAuLi5yZWZlcmVuY2VDYXJyaWVycyhyZWZlcmVuY2VzLCBleHRyYWN0ZWQuY2F0ZWdvcmllcyldLFxuICB9O1xufVxuXG4vLyBXaGF0IHRoZSBzZXJ2ZXIgc2F5cyBvZiB0aGUgc2VyaWVzIGFuIGF4aXMgY2hhcnQgcGxvdHMsIHJlYWQgZnJvbSB0aGVcbi8vIGRhdGEncyBjb21wYXJpc29uLCBvdXRwdXRzLCB3aW5kb3dzIGFuZCBwYXJ0aWFsUGVyaW9kIGJ5IGVhY2ggc2VyaWVzJ1xuLy8gbWVhc3VyZSBjb2x1bW4uIGNoYXJ0QW5ub3RhdGlvbnMgaXMgbnVsbCB3aGVuIHRoZSBkYXRhIGNhcnJpZXMgbm9uZSBvZlxuLy8gdGhvc2Uga2V5cywgYW5kIHRoZSBjaGFydCBkcmF3cyBleGFjdGx5IGFzIGJlZm9yZS5cbmludGVyZmFjZSBDaGFydEFubm90YXRpb25zIHtcbiAgb3V0cHV0czogKE91dHB1dE1ldGEgfCBudWxsKVtdO1xuICB3aW5kb3dzOiAoV2luZG93TWV0YSB8IG51bGwpW107XG4gIC8vIFRoZSBjaGFydCBtZWFzdXJlIGFuIG91dHB1dCB0YWtlcyBpdHMgbWVhc3VyZSdzIGZvcm1hdCBmcm9tOiBpdHMgY3VycmVudFxuICAvLyB2YWx1ZSdzLCB3aGVuIHRoZSBjaGFydCBwbG90cyBpdC5cbiAgbWVhc3VyZVNwZWNzOiAoQ2hhcnRNZWFzdXJlIHwgdW5kZWZpbmVkKVtdO1xuICAvLyBBIGNoYW5nZSBvciBwZXJjZW50IGNoYW5nZSBzZXJpZXMnIHByaW9yIHZhbHVlcyBieSBjYXRlZ29yeSwgd2hpY2ggdGVsbFxuICAvLyBhIG1pc3NpbmcgYmFzZWxpbmUgZnJvbSBhIHplcm8gb25lOyBudWxsIGZvciBhbnkgb3RoZXIgc2VyaWVzLlxuICBwcmlvcnM6ICgobnVtYmVyIHwgbnVsbClbXSB8IG51bGwpW107XG4gIC8vIFRoZSBsYW5lIHByaW9yIGEgY3VycmVudCwgY2hhbmdlIG9yIHBlcmNlbnQgY2hhbmdlIHNlcmllcyBpcyBjb21wYXJlZFxuICAvLyB3aXRoLCB3aGVuIHRoZSBjaGFydCBkb2VzIG5vdCBwbG90IHRoYXQgcHJpb3IgaXRzZWxmOiBpdHMgdG9vbHRpcCBsaW5lXG4gIC8vIG5hbWVzIHRoZSBwcmlvcidzIHZhbHVlIGFuZCBkYXlzLiBudWxsIGZvciBhbnkgb3RoZXIgc2VyaWVzLlxuICBsYW5lUHJpb3JzOiAoTGFuZVByaW9yIHwgbnVsbClbXTtcbiAgLy8gRXZlcnkgc2VyaWVzJyBvd24gQ1NTIGNvbG9yLCBzbyBhIHByaW9yIHNlcmllcyBhbmQgYSBwYXJ0aWFsIHNlZ21lbnQgY2FuXG4gIC8vIHNoYXJlIGFub3RoZXInczsgbnVsbCBvbiBhIGNvbG9yQnkgY2hhcnQsIHdoaWNoIGNvbG9ycyBieSBjYXRlZ29yeS5cbiAgY29sb3JzOiBzdHJpbmdbXSB8IG51bGw7XG4gIHByaW9yU2VyaWVzOiBib29sZWFuW107XG4gIGNvbXBhcmlzb246IENvbXBvbmVudENvbXBhcmlzb24gfCBudWxsO1xuICAvLyBUaGUgY2F0ZWdvcnkgb2YgdGhlIHBlcmlvZCBub3Qgb3ZlciB5ZXQsIG9yIG51bGwuXG4gIHBhcnRpYWxJbmRleDogbnVtYmVyIHwgbnVsbDtcbn1cblxuLy8gQSBzZXJpZXMnIGxhbmUgcHJpb3I6IGl0cyBvdXRwdXQsIGl0cyB2YWx1ZXMgYnkgY2F0ZWdvcnksIGFuZCBhIGtleSB0aGF0XG4vLyBuYW1lcyBpdCBvbmNlIGluIGEgdG9vbHRpcCAodGhlIHByaW9yIGNvbHVtbiwgYW5kIG9uIGEgc3BsaXRCeSBjaGFydCB0aGVcbi8vIGdyb3VwKS5cbmludGVyZmFjZSBMYW5lUHJpb3Ige1xuICBrZXk6IHN0cmluZztcbiAgb3V0cHV0OiBPdXRwdXRNZXRhO1xuICB2YWx1ZXM6IChudW1iZXIgfCBudWxsKVtdO1xufVxuXG4vLyBUaGUga2V5cyBvZiBhIGJ1aWx0IGF4aXMgc2VyaWVzIHRoYXQgdGhlIGFubm90YXRpb25zIHJlYWQgYW5kIHJlcGxhY2UuXG5pbnRlcmZhY2UgRHJhd25TZXJpZXMge1xuICB0eXBlPzogc3RyaW5nO1xuICBzdGFjaz86IHN0cmluZztcbiAgZGF0YT86IFNlcmllc0RhdGFJdGVtPERhdGFMYWJlbFBvc2l0aW9uPltdO1xuICBpdGVtU3R5bGU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgbGluZVN0eWxlPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8vIEEgZGFzaGVkIGxhc3Qgc2VnbWVudCAocGFydGlhbFNlZ21lbnRzKSwgZHJhd24gYWZ0ZXIgdGhlIG1lYXN1cmUgc2VyaWVzLFxuLy8gYW5kIHRoZSBpbmRleCBvZiB0aGUgc2VyaWVzIGl0IGNvbnRpbnVlcy5cbmludGVyZmFjZSBQYXJ0aWFsU2VnbWVudCB7XG4gIHNlcmllczogU2VyaWVzT3B0aW9uO1xuICBvd25lcjogbnVtYmVyO1xufVxuXG4vLyBXaGF0IGFuIGFubm90YXRlZCBjaGFydCdzIGF4aXMgdG9vbHRpcCByZWFkcy4gb3duZXJzIGhvbGRzLCBieSBwb3NpdGlvbixcbi8vIHRoZSBzZXJpZXMgZWFjaCBwYXJ0aWFsIHNlZ21lbnQgY29udGludWVzLlxuaW50ZXJmYWNlIEFubm90YXRlZFRvb2x0aXBTb3VyY2Uge1xuICBleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzO1xuICBhbm5vdGF0aW9uczogQ2hhcnRBbm5vdGF0aW9ucztcbiAgb3duZXJzOiBudW1iZXJbXTtcbiAgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsO1xuICBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsO1xuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0O1xufVxuXG5mdW5jdGlvbiBjaGFydEFubm90YXRpb25zKFxuICBjb25maWc6IENoYXJ0Q29uZmlnLFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLFxuICBjb2xvckJ5OiBib29sZWFuLFxuKTogQ2hhcnRBbm5vdGF0aW9ucyB8IG51bGwge1xuICBpZiAoIWRhdGEuY29tcGFyaXNvbiAmJiAhZGF0YS5vdXRwdXRzICYmICFkYXRhLndpbmRvd3MgJiYgKGRhdGEucGFydGlhbFBlcmlvZCA/PyBudWxsKSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgY29sdW1ucyA9IGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy5tZWFzdXJlLmNvbHVtbik7XG4gIGNvbnN0IG91dHB1dHMgPSBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiBkYXRhLm91dHB1dHM/Lltjb2x1bW5dID8/IG51bGwpO1xuICBjb25zdCBjdXJyZW50cyA9IGNvbHVtbnMubWFwKChjb2x1bW4sIGluZGV4KSA9PiAob3V0cHV0c1tpbmRleF0gPyBjdXJyZW50T3V0cHV0QWxpYXMoZGF0YS5vdXRwdXRzLCBjb2x1bW4pIDogbnVsbCkpO1xuICBjb25zdCBtZWFzdXJlcyA9IGNoYXJ0TWVhc3VyZXMoY29uZmlnLCBkYXRhKTtcbiAgLy8gQSBwcmlvciBzZXJpZXMnIGN1cnJlbnQgc2VyaWVzLCBieSBpbmRleDsgLTEgZm9yIGFueSBvdGhlci5cbiAgY29uc3Qgc291cmNlcyA9IGN1cnJlbnRzLm1hcCgoY3VycmVudCwgaW5kZXgpID0+IChvdXRwdXRzW2luZGV4XT8ucm9sZSA9PT0gJ3ByaW9yJyA/IGNvbHVtbnMuaW5kZXhPZihjdXJyZW50KSA6IC0xKSk7XG4gIGNvbnN0IHBhcnRpYWxJbmRleCA9IChkYXRhLnBhcnRpYWxQZXJpb2QgPz8gbnVsbCkgPT09IG51bGwgPyAtMSA6IGV4dHJhY3RlZC5jYXRlZ29yaWVzLmluZGV4T2YoU3RyaW5nKGRhdGEucGFydGlhbFBlcmlvZCkpO1xuICBjb25zdCBsYW5lcyA9IGxhbmVQcmlvclZhbHVlcyhjb25maWcsIGRhdGEsIGV4dHJhY3RlZCwgb3V0cHV0cyk7XG5cbiAgcmV0dXJuIHtcbiAgICBvdXRwdXRzLFxuICAgIHdpbmRvd3M6IGNvbHVtbnMubWFwKChjb2x1bW4pID0+IGRhdGEud2luZG93cz8uW2NvbHVtbl0gPz8gbnVsbCksXG4gICAgbWVhc3VyZVNwZWNzOiBjdXJyZW50cy5tYXAoKGN1cnJlbnQpID0+IG1lYXN1cmVzLmZpbmQoKG1lYXN1cmUpID0+IG1lYXN1cmUuY29sdW1uID09PSBjdXJyZW50KSksXG4gICAgcHJpb3JzOiBsYW5lcy5tYXAoKGxhbmUsIGluZGV4KSA9PiAoaXNEZWx0YVJvbGUob3V0cHV0c1tpbmRleF0/LnJvbGUpID8gbGFuZT8ucHJpb3IudmFsdWVzID8/IG51bGwgOiBudWxsKSksXG4gICAgbGFuZVByaW9yczogbGFuZXMubWFwKChsYW5lKSA9PiAobGFuZSAmJiAhY29sdW1ucy5pbmNsdWRlcyhsYW5lLmFsaWFzKSA/IGxhbmUucHJpb3IgOiBudWxsKSksXG4gICAgY29sb3JzOiBjb2xvckJ5ID8gbnVsbCA6IGFubm90YXRlZENvbG9ycyhleHRyYWN0ZWQsIHNvdXJjZXMpLFxuICAgIHByaW9yU2VyaWVzOiBvdXRwdXRzLm1hcCgob3V0cHV0KSA9PiBvdXRwdXQ/LnJvbGUgPT09ICdwcmlvcicpLFxuICAgIGNvbXBhcmlzb246IGRhdGEuY29tcGFyaXNvbiA/PyBudWxsLFxuICAgIHBhcnRpYWxJbmRleDogcGFydGlhbEluZGV4IDwgMCA/IG51bGwgOiBwYXJ0aWFsSW5kZXgsXG4gIH07XG59XG5cbi8vIEEgY3VycmVudCwgY2hhbmdlIG9yIHBlcmNlbnQgY2hhbmdlIHNlcmllcycgbGFuZSBwcmlvciwgYnkgY2F0ZWdvcnk6IGl0c1xuLy8gbGFuZSdzIHByaW9yIGNvbHVtbiBpbiB0aGUgc2FtZSByb3dzICh0aGUgc2FtZSBncm91cCdzIG9uIGEgc3BsaXRCeSBjaGFydCksXG4vLyBhbmQgdGhhdCBjb2x1bW4ncyBhbGlhcy5cbmZ1bmN0aW9uIGxhbmVQcmlvclZhbHVlcyhcbiAgY29uZmlnOiBDaGFydENvbmZpZyxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcyxcbiAgb3V0cHV0czogKE91dHB1dE1ldGEgfCBudWxsKVtdLFxuKTogKHsgYWxpYXM6IHN0cmluZzsgcHJpb3I6IExhbmVQcmlvciB9IHwgbnVsbClbXSB7XG4gIGNvbnN0IHsgeENvbHVtbiwgZ3JvdXBDb2x1bW4gfSA9IGNoYXJ0Q29sdW1ucyhjb25maWcsIGRhdGEpO1xuICBjb25zdCByYXdDYXRlZ29yaWVzID0gdW5pcXVlVmFsdWVzKGRhdGEucm93cywgeENvbHVtbik7XG4gIGNvbnN0IGdyb3VwcyA9IGdyb3VwQ29sdW1uID8gdW5pcXVlVmFsdWVzKGRhdGEucm93cywgZ3JvdXBDb2x1bW4pIDogW107XG5cbiAgcmV0dXJuIGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMsIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgcm9sZSA9IG91dHB1dHNbaW5kZXhdPy5yb2xlO1xuICAgIGNvbnN0IGFsaWFzID0gcm9sZSA9PT0gJ2N1cnJlbnQnIHx8IGlzRGVsdGFSb2xlKHJvbGUpXG4gICAgICA/IGxhbmVPdXRwdXRBbGlhcyhkYXRhLm91dHB1dHMsIHNlcmllcy5tZWFzdXJlLmNvbHVtbiwgJ3ByaW9yJylcbiAgICAgIDogbnVsbDtcbiAgICBjb25zdCBvdXRwdXQgPSBhbGlhcyA/IGRhdGEub3V0cHV0cz8uW2FsaWFzXSA6IHVuZGVmaW5lZDtcblxuICAgIGlmICghYWxpYXMgfHwgIW91dHB1dCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgbWF0Y2ggPSBncm91cENvbHVtbiA/IChyb3c6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiByb3dbZ3JvdXBDb2x1bW5dID09PSBncm91cHNbaW5kZXhdIDogdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFsaWFzLFxuICAgICAgcHJpb3I6IHtcbiAgICAgICAga2V5OiBncm91cENvbHVtbiA/IGAke2FsaWFzfVxcdTAwMDAke2luZGV4fWAgOiBhbGlhcyxcbiAgICAgICAgb3V0cHV0LFxuICAgICAgICB2YWx1ZXM6IGNhdGVnb3J5VmFsdWVzKGRhdGEucm93cywgeENvbHVtbiwgcmF3Q2F0ZWdvcmllcywgYWxpYXMsIG1hdGNoKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVsdGFSb2xlKHJvbGU6IE91dHB1dFJvbGUgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiByb2xlID09PSAnY2hhbmdlJyB8fCByb2xlID09PSAncGVyY2VudF9jaGFuZ2UnO1xufVxuXG4vLyBFYWNoIHNlcmllcycgY29sb3IgYXMgdGhlIHRoZW1lIHdvdWxkIGhhbmQgaXQgb3V0OiBpdHMgbWVhc3VyZSdzIG5hbWVkXG4vLyBjb2xvciwgZWxzZSB0aGUgbmV4dCBwYWxldHRlIGNvbG9yIGFtb25nIHRoZSBzZXJpZXMgd2l0aG91dCBvbmUuIEEgcHJpb3Jcbi8vIHNlcmllcyB0aGF0IG5hbWVzIG5vIGNvbG9yIHRha2VzIGl0cyBjdXJyZW50IHNlcmllcycgY29sb3IgKHNvdXJjZXMpIGFuZFxuLy8gbm8gcGFsZXR0ZSBjb2xvciBvZiBpdHMgb3duLlxuZnVuY3Rpb24gYW5ub3RhdGVkQ29sb3JzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIHNvdXJjZXM6IG51bWJlcltdKTogc3RyaW5nW10ge1xuICBsZXQgc2xvdCA9IDA7XG4gIGNvbnN0IG93biA9IGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgbmFtZWQgPSBzZXJpZXNDb2xvcihzZXJpZXMpO1xuXG4gICAgaWYgKG5hbWVkIHx8IHNvdXJjZXNbaW5kZXhdID49IDApIHtcbiAgICAgIHJldHVybiBuYW1lZCA/PyBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBSRVBPUlRfQ0hBUlRfQ09MT1JTX0NTU1tzbG90KysgJSBSRVBPUlRfQ0hBUlRfQ09MT1JTX0NTUy5sZW5ndGhdO1xuICB9KTtcblxuICByZXR1cm4gb3duLm1hcCgoY29sb3IsIGluZGV4KSA9PiBjb2xvciA/PyBvd25bc291cmNlc1tpbmRleF1dIGFzIHN0cmluZyk7XG59XG5cbi8vIEEgc2VyaWVzJyBtYXJrczogYSBwcmlvciBkcmF3biBpbiBpdHMgY3VycmVudCBzZXJpZXMnIGNvbG9yIGZhbWlseSwgZGFzaGVkLFxuLy8gYW5kIHRoZSBwZXJpb2Qgbm90IG92ZXIgeWV0IGhhdGNoZWQgKGEgYmFyKSBvciByaW5nZWQgKGEgcG9pbnQpLlxuZnVuY3Rpb24gbWFya1NlcmllcyhcbiAgb3B0aW9uOiBTZXJpZXNPcHRpb24sXG4gIGFubm90YXRpb25zOiBDaGFydEFubm90YXRpb25zLFxuICBpbmRleDogbnVtYmVyLFxuICBtZWFzdXJlOiBDaGFydE1lYXN1cmUsXG4pOiBTZXJpZXNPcHRpb24ge1xuICBjb25zdCBwcmlvciA9IGFubm90YXRpb25zLnByaW9yU2VyaWVzW2luZGV4XSA/IHByaW9yU3R5bGUob3B0aW9uLCBtZWFzdXJlLCBhbm5vdGF0aW9ucy5jb2xvcnM/LltpbmRleF0pIDogb3B0aW9uO1xuXG4gIHJldHVybiBhbm5vdGF0aW9ucy5wYXJ0aWFsSW5kZXggPT09IG51bGwgPyBwcmlvciA6IG1hcmtQYXJ0aWFsUG9pbnQocHJpb3IsIGFubm90YXRpb25zLnBhcnRpYWxJbmRleCk7XG59XG5cbi8vIEEgcHJpb3IncyBiYXJzIGFyZSBmYWRlZCB3aXRoIGEgZGFzaGVkIGVkZ2U7IGl0cyBsaW5lIGlzIGRhc2hlZCB1bmxlc3MgaXRzXG4vLyBtZWFzdXJlIG5hbWVzIGEgbGluZSBzdHlsZS5cbmZ1bmN0aW9uIHByaW9yU3R5bGUob3B0aW9uOiBTZXJpZXNPcHRpb24sIG1lYXN1cmU6IENoYXJ0TWVhc3VyZSwgY29sb3I6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFNlcmllc09wdGlvbiB7XG4gIGNvbnN0IGRyYXduID0gb3B0aW9uIGFzIERyYXduU2VyaWVzO1xuXG4gIGlmIChkcmF3bi50eXBlID09PSAnYmFyJykge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5vcHRpb24sXG4gICAgICBpdGVtU3R5bGU6IHtcbiAgICAgICAgLi4uZHJhd24uaXRlbVN0eWxlLFxuICAgICAgICBvcGFjaXR5OiBQUklPUl9CQVJfT1BBQ0lUWSxcbiAgICAgICAgYm9yZGVyV2lkdGg6IDEsXG4gICAgICAgIGJvcmRlclR5cGU6ICdkYXNoZWQnLFxuICAgICAgICAuLi4oY29sb3IgPyB7IGJvcmRlckNvbG9yOiBjb2xvciB9IDoge30pLFxuICAgICAgfSxcbiAgICB9IGFzIFNlcmllc09wdGlvbjtcbiAgfVxuXG4gIHJldHVybiB7IC4uLm9wdGlvbiwgbGluZVN0eWxlOiB7IC4uLmRyYXduLmxpbmVTdHlsZSwgdHlwZTogbWVhc3VyZUxpbmVTdHlsZShtZWFzdXJlKSA/PyBQUklPUl9MSU5FX1NUWUxFIH0gfSBhcyBTZXJpZXNPcHRpb247XG59XG5cbi8vIFRoZSBwb2ludCBvZiB0aGUgcGVyaW9kIG5vdCBvdmVyIHlldCwgd2hlbiBpdCBoYXMgYSB2YWx1ZS5cbmZ1bmN0aW9uIG1hcmtQYXJ0aWFsUG9pbnQob3B0aW9uOiBTZXJpZXNPcHRpb24sIHBhcnRpYWxJbmRleDogbnVtYmVyKTogU2VyaWVzT3B0aW9uIHtcbiAgY29uc3QgZHJhd24gPSBvcHRpb24gYXMgRHJhd25TZXJpZXM7XG4gIGNvbnN0IGRhdGEgPSBbLi4uKGRyYXduLmRhdGEgPz8gW10pXTtcbiAgY29uc3QgaXRlbSA9IGRhdGFbcGFydGlhbEluZGV4XTtcblxuICBpZiAoaXRlbSA9PT0gdW5kZWZpbmVkIHx8IHBvaW50VmFsdWUoaXRlbSkgPT09IG51bGwpIHtcbiAgICByZXR1cm4gb3B0aW9uO1xuICB9XG5cbiAgY29uc3QgbWFyayA9IGRyYXduLnR5cGUgPT09ICdiYXInID8geyBpdGVtU3R5bGU6IHsgZGVjYWw6IFBBUlRJQUxfQkFSX0RFQ0FMIH0gfSA6IFBBUlRJQUxfUE9JTlRfTUFSSztcbiAgZGF0YVtwYXJ0aWFsSW5kZXhdID0gKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0JyA/IHsgLi4uaXRlbSwgLi4ubWFyayB9IDogeyB2YWx1ZTogaXRlbSwgLi4ubWFyayB9KSBhcyBTZXJpZXNEYXRhSXRlbTxEYXRhTGFiZWxQb3NpdGlvbj47XG5cbiAgcmV0dXJuIHsgLi4ub3B0aW9uLCBkYXRhIH0gYXMgU2VyaWVzT3B0aW9uO1xufVxuXG4vLyBBIGxpbmUgb3IgYXJlYSBzZXJpZXMgd2hvc2UgbGFzdCBwZXJpb2QgaXMgbm90IG92ZXIgeWV0IGRyYXdzIGl0cyBsYXN0XG4vLyBzZWdtZW50IGRhc2hlZDogdGhlIHNlcmllcyBzdG9wcyBvbmUgcG9pbnQgc2hvcnQsIGFuZCBhIHNlZ21lbnQgc2VyaWVzXG4vLyBjYXJyaWVzIGl0cyBsYXN0IHR3byBwb2ludHMsIGRhc2hlZCwgaW4gaXRzIGNvbG9yIGFuZCB1bmRlciBpdHMgbmFtZSwgc29cbi8vIHRoZSBvbmUgbGVnZW5kIGVudHJ5IHRvZ2dsZXMgYm90aC4gQSBzdGFja2VkIHNlcmllcyBrZWVwcyBpdHMgbGluZSB3aG9sZSAoYVxuLy8gc2VnbWVudCB3b3VsZCBzdGFjayBvbiB0b3Agb2YgaXQpLCBhbmQgYSBnYXAgc3RheXMgYSBnYXAuIFJlcGxhY2VzIGVhY2hcbi8vIHN1Y2ggc2VyaWVzIGluIGBzZXJpZXNgIGFuZCByZXR1cm5zIHRoZSBzZWdtZW50cy5cbmZ1bmN0aW9uIHBhcnRpYWxTZWdtZW50cyhzZXJpZXM6IFNlcmllc09wdGlvbltdLCBhbm5vdGF0aW9uczogQ2hhcnRBbm5vdGF0aW9ucyk6IFBhcnRpYWxTZWdtZW50W10ge1xuICBjb25zdCBsYXN0ID0gYW5ub3RhdGlvbnMucGFydGlhbEluZGV4O1xuICBjb25zdCBzZWdtZW50czogUGFydGlhbFNlZ21lbnRbXSA9IFtdO1xuXG4gIHNlcmllcy5mb3JFYWNoKChvcHRpb24sIG93bmVyKSA9PiB7XG4gICAgY29uc3QgZHJhd24gPSBvcHRpb24gYXMgRHJhd25TZXJpZXM7XG4gICAgY29uc3QgZGF0YSA9IGRyYXduLmRhdGEgPz8gW107XG4gICAgY29uc3QgY29sb3IgPSBhbm5vdGF0aW9ucy5jb2xvcnM/Lltvd25lcl07XG5cbiAgICBpZiAobGFzdCA9PT0gbnVsbCB8fCBsYXN0IDwgMSB8fCBsYXN0ICE9PSBkYXRhLmxlbmd0aCAtIDEgfHwgZHJhd24udHlwZSAhPT0gJ2xpbmUnIHx8IGRyYXduLnN0YWNrIHx8ICFjb2xvclxuICAgICAgfHwgcG9pbnRWYWx1ZShkYXRhW2xhc3QgLSAxXSkgPT09IG51bGwgfHwgcG9pbnRWYWx1ZShkYXRhW2xhc3RdKSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNlcmllc1tvd25lcl0gPSB7IC4uLm9wdGlvbiwgZGF0YTogWy4uLmRhdGEuc2xpY2UoMCwgbGFzdCksIG51bGxdIH0gYXMgU2VyaWVzT3B0aW9uO1xuICAgIHNlZ21lbnRzLnB1c2goeyBvd25lciwgc2VyaWVzOiBzZWdtZW50U2VyaWVzKG9wdGlvbiwgY29sb3IsIGxhc3QpIH0pO1xuICB9KTtcblxuICByZXR1cm4gc2VnbWVudHM7XG59XG5cbi8vIFRoZSBkYXNoZWQgc2VnbWVudCBmcm9tIHRoZSBwb2ludCBiZWZvcmUgdGhlIGxhc3QgdG8gdGhlIGxhc3Qgb25lLCB3aGljaFxuLy8ga2VlcHMgaXRzIG1hcmtzIGFuZCBpdHMgZGF0YSBsYWJlbC4gVGhlIHBvaW50IGJlZm9yZSBpdCBpcyBkcmF3biwgYW5kXG4vLyBsYWJlbGVkLCBieSB0aGUgc2VyaWVzIGl0c2VsZi5cbmZ1bmN0aW9uIHNlZ21lbnRTZXJpZXMob3B0aW9uOiBTZXJpZXNPcHRpb24sIGNvbG9yOiBzdHJpbmcsIGxhc3Q6IG51bWJlcik6IFNlcmllc09wdGlvbiB7XG4gIGNvbnN0IGRyYXduID0gb3B0aW9uIGFzIERyYXduU2VyaWVzO1xuICBjb25zdCBkYXRhID0gZHJhd24uZGF0YSA/PyBbXTtcblxuICByZXR1cm4ge1xuICAgIC4uLm9wdGlvbixcbiAgICBtYXJrTGluZTogdW5kZWZpbmVkLFxuICAgIGxpbmVTdHlsZTogeyAuLi5kcmF3bi5saW5lU3R5bGUsIGNvbG9yLCB0eXBlOiBQQVJUSUFMX0xJTkVfU1RZTEUgfSxcbiAgICBkYXRhOiBkYXRhLm1hcCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChpbmRleCA9PT0gbGFzdCkge1xuICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGluZGV4ID09PSBsYXN0IC0gMSA/IHsgdmFsdWU6IHBvaW50VmFsdWUoaXRlbSksIHN5bWJvbDogJ25vbmUnLCBsYWJlbDogeyBzaG93OiBmYWxzZSB9IH0gOiBudWxsO1xuICAgIH0pLFxuICB9IGFzIFNlcmllc09wdGlvbjtcbn1cblxuLy8gQSBwb2ludCdzIHBsb3R0ZWQgdmFsdWUsIHdoZXRoZXIgaXQgaXMgYSBiYXJlIG51bWJlciBvciBhbiBvYmplY3QuXG5mdW5jdGlvbiBwb2ludFZhbHVlKGl0ZW06IFNlcmllc0RhdGFJdGVtPERhdGFMYWJlbFBvc2l0aW9uPiB8IHVuZGVmaW5lZCk6IG51bWJlciB8IG51bGwge1xuICBpZiAoaXRlbSA9PT0gbnVsbCB8fCBpdGVtID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB0eXBlb2YgaXRlbSA9PT0gJ251bWJlcicgPyBpdGVtIDogaXRlbS52YWx1ZTtcbn1cblxuLy8gSG93IGFuIG91dHB1dCBzZXJpZXMgd3JpdGVzIGEgdmFsdWU6IGZvcm1hdE91dHB1dFZhbHVlJ3MgcnVsZXMgKGEgc2lnbmVkXG4vLyBjaGFuZ2UsIHBvaW50cywgJ+KAlCcgd2l0aCB0aGUgbm8tYmFzZWxpbmUgdGl0bGUsIHJhbmtzIGFuZCBzaGFyZXMpIHdpdGggaXRzXG4vLyBtZWFzdXJlJ3MgZm9ybWF0IGFuZCB0aGUgY29tcGFyaXNvbidzIGZsb29yLiBHaXZlbiB0aGUgcG9pbnQncyBpbmRleCAoYVxuLy8gdG9vbHRpcCwgYSBkYXRhIGxhYmVsKSwgYSBjaGFuZ2UgcmVhZHMgaXRzIHByaW9yIHRoZXJlLCB3aGljaCB0ZWxscyBhXG4vLyBtaXNzaW5nIGJhc2VsaW5lIGZyb20gYSB6ZXJvIG9uZS4gVGhlIHRpdGxlIHNheXMgd2h5IGEgdmFsdWUgcmVhZHMgJ+KAlCcgb3Jcbi8vICduL2EnLlxuZnVuY3Rpb24gb3V0cHV0VmFsdWUoXG4gIGFubm90YXRpb25zOiBDaGFydEFubm90YXRpb25zLFxuICBpbmRleDogbnVtYmVyLFxuICBtZWFzdXJlOiBDaGFydE1lYXN1cmUsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiAodmFsdWU6IHVua25vd24sIGRhdGFJbmRleD86IG51bWJlcikgPT4gRm9ybWF0dGVkT3V0cHV0VmFsdWUge1xuICBjb25zdCBvdXRwdXQgPSBhbm5vdGF0aW9ucy5vdXRwdXRzW2luZGV4XTtcbiAgY29uc3QgcHJpb3JzID0gYW5ub3RhdGlvbnMucHJpb3JzW2luZGV4XTtcblxuICByZXR1cm4gKHZhbHVlLCBkYXRhSW5kZXgpID0+IGZvcm1hdE91dHB1dFZhbHVlKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWVbMF0gOiB2YWx1ZSwgb3V0cHV0LCBtZWFzdXJlLCBjb250ZXh0LCB7XG4gICAgbWVhc3VyZVNwZWM6IGFubm90YXRpb25zLm1lYXN1cmVTcGVjc1tpbmRleF0sXG4gICAgZmxvb3I6IGFubm90YXRpb25zLmNvbXBhcmlzb24/LmZsb29yID8/IG51bGwsXG4gICAgLi4uKHByaW9ycyAmJiBkYXRhSW5kZXggIT09IHVuZGVmaW5lZCA/IHsgcHJpb3I6IHByaW9yc1tkYXRhSW5kZXhdID8/IG51bGwgfSA6IHt9KSxcbiAgfSk7XG59XG5cbi8vIEFuIG91dHB1dCB2YWx1ZSdzIHRleHQgYWxvbmUsIGZvciBhIHNlcmllcycgb3duIHRvb2x0aXAgYW5kIGl0cyBkYXRhIGxhYmVscy5cbmZ1bmN0aW9uIG91dHB1dFdyaXRlcihcbiAgYW5ub3RhdGlvbnM6IENoYXJ0QW5ub3RhdGlvbnMsXG4gIGluZGV4OiBudW1iZXIsXG4gIG1lYXN1cmU6IENoYXJ0TWVhc3VyZSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6ICh2YWx1ZTogdW5rbm93biwgZGF0YUluZGV4PzogbnVtYmVyKSA9PiBzdHJpbmcge1xuICBjb25zdCB3cml0ZSA9IG91dHB1dFZhbHVlKGFubm90YXRpb25zLCBpbmRleCwgbWVhc3VyZSwgY29udGV4dCk7XG5cbiAgcmV0dXJuICh2YWx1ZSwgZGF0YUluZGV4KSA9PiB3cml0ZSh2YWx1ZSwgZGF0YUluZGV4KS50ZXh0O1xufVxuXG5mdW5jdGlvbiBvdXRwdXRMYWJlbEZvcm1hdHRlcih3cml0ZTogKHZhbHVlOiB1bmtub3duLCBkYXRhSW5kZXg/OiBudW1iZXIpID0+IHN0cmluZyk6IERhdGFMYWJlbEZvcm1hdHRlciB7XG4gIHJldHVybiAocGFyYW1zKSA9PiB3cml0ZShkYXRhTGFiZWxWYWx1ZShwYXJhbXMpLCBwYXJhbXMuZGF0YUluZGV4KTtcbn1cblxuLy8gVGhlIGNoYXJ0J3Mgc2VyaWVzIGFzIGl0cyB2YWx1ZSBheGVzIHJlYWQgdGhlbTogYW4gb3V0cHV0IHNlcmllcyB3aG9zZVxuLy8gc2xvdCBuYW1lcyBubyBmb3JtYXQgdGFrZXMgaXRzIG91dHB1dCdzIChvdXRwdXRBeGlzTWVhc3VyZSkuXG5mdW5jdGlvbiBhbm5vdGF0ZWRBeGlzU2VyaWVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIGFubm90YXRpb25zOiBDaGFydEFubm90YXRpb25zKTogRXh0cmFjdGVkQ2hhcnRTZXJpZXMge1xuICByZXR1cm4ge1xuICAgIC4uLmV4dHJhY3RlZCxcbiAgICBzZXJpZXM6IGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMsIGluZGV4KSA9PiAoe1xuICAgICAgLi4uc2VyaWVzLFxuICAgICAgbWVhc3VyZTogb3V0cHV0QXhpc01lYXN1cmUoc2VyaWVzLm1lYXN1cmUsIGFubm90YXRpb25zLm91dHB1dHNbaW5kZXhdLCBhbm5vdGF0aW9ucy5tZWFzdXJlU3BlY3NbaW5kZXhdKSxcbiAgICB9KSksXG4gIH07XG59XG5cbi8vIFRoZSBmb3JtYXQgYW4gb3V0cHV0J3MgYXhpcyByZWFkcyB3aGVuIGl0cyBzbG90IG5hbWVzIG5vbmU6IGEgcmFuaydzIHdob2xlXG4vLyBudW1iZXJzLCBhIDAtMSBmcmFjdGlvbidzIHBlcmNlbnQsIGFuZCBhIGNvbXBhcmVkIG9yIHdpbmRvd2VkIHZhbHVlIGl0c1xuLy8gbWVhc3VyZSdzIGZvcm1hdC4gVGhlIHNsb3QncyBvd24gcHJlY2lzaW9uIGFuZCB1bml0cyBzdGlsbCBhcHBseS5cbmZ1bmN0aW9uIG91dHB1dEF4aXNNZWFzdXJlKFxuICBtZWFzdXJlOiBDaGFydE1lYXN1cmUsXG4gIG91dHB1dDogT3V0cHV0TWV0YSB8IG51bGwsXG4gIG1lYXN1cmVTcGVjOiBDaGFydE1lYXN1cmUgfCB1bmRlZmluZWQsXG4pOiBDaGFydE1lYXN1cmUge1xuICBpZiAoIW91dHB1dCB8fCBuYW1lc1ZhbHVlRm9ybWF0KG1lYXN1cmUpKSB7XG4gICAgcmV0dXJuIG1lYXN1cmU7XG4gIH1cblxuICBsZXQgYmFzZTogTnVtYmVyRm9ybWF0U3BlYyB8IG51bGwgPSBtZWFzdXJlU3BlYyAmJiBoYXNOdW1iZXJGb3JtYXQobWVhc3VyZVNwZWMpID8gZm9ybWF0S2V5cyhtZWFzdXJlU3BlYykgOiBudWxsO1xuICBpZiAob3V0cHV0LmtpbmQgPT09ICdyYW5rJykge1xuICAgIGJhc2UgPSBSQU5LX0FYSVNfRk9STUFUO1xuICB9IGVsc2UgaWYgKGlzRnJhY3Rpb25PdXRwdXQob3V0cHV0KSkge1xuICAgIGJhc2UgPSBGUkFDVElPTl9BWElTX0ZPUk1BVDtcbiAgfVxuXG4gIHJldHVybiBiYXNlXG4gICAgPyB7IC4uLm1lYXN1cmUsIC4uLmJhc2UsIC4uLmZvcm1hdEtleXMoeyBwcmVjaXNpb246IG1lYXN1cmUucHJlY2lzaW9uLCB1bml0czogbWVhc3VyZS51bml0cyB9KSB9IGFzIENoYXJ0TWVhc3VyZVxuICAgIDogbWVhc3VyZTtcbn1cblxuZnVuY3Rpb24gbmFtZXNWYWx1ZUZvcm1hdChzcGVjOiBOdW1iZXJGb3JtYXRTcGVjKTogYm9vbGVhbiB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKFJlcG9ydFZhbHVlRm9ybWF0KS5zb21lKChmb3JtYXQpID0+IGZvcm1hdCA9PT0gc3BlYy5mb3JtYXQpO1xufVxuXG4vLyBBIHNwZWMncyBudW1iZXItZm9ybWF0IGtleXMgdGhhdCBhcmUgc2V0LlxuZnVuY3Rpb24gZm9ybWF0S2V5cyhzcGVjOiBOdW1iZXJGb3JtYXRTcGVjKTogTnVtYmVyRm9ybWF0U3BlYyB7XG4gIHJldHVybiB7XG4gICAgLi4uKChzcGVjLmZvcm1hdCA/PyBudWxsKSAhPT0gbnVsbCA/IHsgZm9ybWF0OiBzcGVjLmZvcm1hdCB9IDoge30pLFxuICAgIC4uLigoc3BlYy5wcmVjaXNpb24gPz8gbnVsbCkgIT09IG51bGwgPyB7IHByZWNpc2lvbjogc3BlYy5wcmVjaXNpb24gfSA6IHt9KSxcbiAgICAuLi4oKHNwZWMudW5pdHMgPz8gbnVsbCkgIT09IG51bGwgPyB7IHVuaXRzOiBzcGVjLnVuaXRzIH0gOiB7fSksXG4gIH07XG59XG5cbi8vIEVhY2ggdmFsdWUgYXhpcydzIGNvbnRleHQ6IG9uZSB0aGF0IHBsb3RzIG9ubHkgMC0xIGZyYWN0aW9ucyByZWFkcyB0aGVtIGFzXG4vLyByYXRpb3MsIHdoYXRldmVyIHRoZSByZXBvcnQncyBwZXJjZW50Rm9ybWF0IHNheXMgb2YgaXRzIHN0b3JlZCB2YWx1ZXMuXG5mdW5jdGlvbiBhbm5vdGF0ZWRBeGlzQ29udGV4dHMoXG4gIGFubm90YXRpb25zOiBDaGFydEFubm90YXRpb25zLFxuICBheGlzSW5kZXhlczogVmFsdWVBeGlzSW5kZXhbXSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6IFJlcG9ydEZvcm1hdENvbnRleHRbXSB7XG4gIHJldHVybiAoWzAsIDFdIGFzIGNvbnN0KS5tYXAoKGF4aXNJbmRleCkgPT4gKGV2ZXJ5T25BeGlzKGFubm90YXRpb25zLm91dHB1dHMsIGF4aXNJbmRleGVzLCBheGlzSW5kZXgsIGlzRnJhY3Rpb25PdXRwdXQpXG4gICAgPyB7IC4uLmNvbnRleHQsIHJhdGlvUGVyY2VudDogdHJ1ZSB9XG4gICAgOiBjb250ZXh0KSk7XG59XG5cbi8vIFdoaWNoIHZhbHVlIGF4ZXMsIGJ5IGluZGV4LCBwbG90IG5vdGhpbmcgYnV0IHJhbmtzLlxuZnVuY3Rpb24gcmFua0F4aXNGbGFncyhvdXRwdXRzOiAoT3V0cHV0TWV0YSB8IG51bGwpW10sIGF4aXNJbmRleGVzOiBWYWx1ZUF4aXNJbmRleFtdKTogYm9vbGVhbltdIHtcbiAgcmV0dXJuIChbMCwgMV0gYXMgY29uc3QpLm1hcCgoYXhpc0luZGV4KSA9PiBldmVyeU9uQXhpcyhvdXRwdXRzLCBheGlzSW5kZXhlcywgYXhpc0luZGV4LCBpc1JhbmtQb3NpdGlvbikpO1xufVxuXG4vLyBIb3cgYSBjaGFydCB0aGF0IHBsb3RzIGEgcHJpb3Igc2VyaWVzIGNvbG9ycyBlYWNoIHNlcmllcywgZm9yIHRoZVxuLy8gUG93ZXJQb2ludCBleHBvcnQ6IGV2ZXJ5IHNlcmllcycgY29sb3IgYXMgYmFyZSBoZXgsIGEgcHJpb3IgdGFraW5nIGl0c1xuLy8gY3VycmVudCBzZXJpZXMnIGNvbG9yIGFuZCBubyBwYWxldHRlIGNvbG9yIG9mIGl0cyBvd24gKGFubm90YXRlZENvbG9ycyksXG4vLyBhbmQgd2hpY2ggc2VyaWVzIGFyZSBwcmlvcnMsIHdoaWNoIGEgbGluZSBkcmF3cyBkYXNoZWQuIG51bGwgd2hlbiB0aGUgY2hhcnRcbi8vIHBsb3RzIG5vIHByaW9yIHNlcmllcywgYW5kIG9uIGEgY29sb3JCeSBjaGFydDsgaXRzIHNlcmllcyBrZWVwIHNlcmllc0hleC5cbmV4cG9ydCBmdW5jdGlvbiBwcmlvclNlcmllc1N0eWxlcyhcbiAgY29uZmlnOiBDaGFydENvbmZpZyxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcyxcbik6IHsgY29sb3JzOiBzdHJpbmdbXTsgcHJpb3JzOiBib29sZWFuW10gfSB8IG51bGwge1xuICBjb25zdCBhbm5vdGF0aW9ucyA9IGNoYXJ0QW5ub3RhdGlvbnMoY29uZmlnLCBkYXRhLCBleHRyYWN0ZWQsIGlzQ29sb3JCeShjb25maWcpKTtcblxuICBpZiAoIWFubm90YXRpb25zPy5jb2xvcnMgfHwgIWFubm90YXRpb25zLnByaW9yU2VyaWVzLnNvbWUoKHByaW9yKSA9PiBwcmlvcikpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29sb3JzOiBhbm5vdGF0aW9ucy5jb2xvcnMubWFwKChjb2xvcikgPT4gY29sb3IucmVwbGFjZSgnIycsICcnKSksXG4gICAgcHJpb3JzOiBhbm5vdGF0aW9ucy5wcmlvclNlcmllcyxcbiAgfTtcbn1cblxuLy8gV2hpY2ggdmFsdWUgYXhlcywgYnkgaW5kZXgsIHBsb3Qgbm90aGluZyBidXQgcmFua3MsIHdoaWNoIHRoZSBjaGFydCBkcmF3c1xuLy8gaW52ZXJ0ZWQgd2l0aCByYW5rIDEgYXQgdGhlIHRvcC4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0LlxuZXhwb3J0IGZ1bmN0aW9uIHJhbmtWYWx1ZUF4ZXMoZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcywgZGF0YTogQ29tcG9uZW50RGF0YSwgY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW5bXSB7XG4gIHJldHVybiByYW5rQXhpc0ZsYWdzKFxuICAgIGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+IGRhdGEub3V0cHV0cz8uW3Nlcmllcy5tZWFzdXJlLmNvbHVtbl0gPz8gbnVsbCksXG4gICAgc2VyaWVzQXhpc0luZGV4ZXMoZXh0cmFjdGVkLCBjb25maWcpLFxuICApO1xufVxuXG4vLyBXaGV0aGVyIGFuIGF4aXMgaGFzIHNlcmllcyBhbmQgZXZlcnkgb25lIG9mIHRoZW0gcGFzc2VzIHRoZSB0ZXN0LlxuZnVuY3Rpb24gZXZlcnlPbkF4aXMoXG4gIG91dHB1dHM6IChPdXRwdXRNZXRhIHwgbnVsbClbXSxcbiAgYXhpc0luZGV4ZXM6IFZhbHVlQXhpc0luZGV4W10sXG4gIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXgsXG4gIHRlc3Q6IChvdXRwdXQ6IE91dHB1dE1ldGEpID0+IGJvb2xlYW4sXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgb25BeGlzID0gb3V0cHV0cy5maWx0ZXIoKF8sIGluZGV4KSA9PiBheGlzSW5kZXhlc1tpbmRleF0gPT09IGF4aXNJbmRleCk7XG5cbiAgcmV0dXJuIG9uQXhpcy5sZW5ndGggPiAwICYmIG9uQXhpcy5ldmVyeSgob3V0cHV0KSA9PiAhIW91dHB1dCAmJiB0ZXN0KG91dHB1dCkpO1xufVxuXG4vLyBBIHNoYXJlIGFuZCBhIHBlcmNlbnQgY2hhbmdlIGFyZSAwLTEgZnJhY3Rpb25zLCB3aGF0ZXZlciBwZXJjZW50Rm9ybWF0IHNheXMuXG5mdW5jdGlvbiBpc0ZyYWN0aW9uT3V0cHV0KG91dHB1dDogT3V0cHV0TWV0YSk6IGJvb2xlYW4ge1xuICByZXR1cm4gb3V0cHV0LmtpbmQgPT09ICdzaGFyZScgfHwgb3V0cHV0LnJvbGUgPT09ICdwZXJjZW50X2NoYW5nZSc7XG59XG5cbi8vIEEgdmFsdWUgYXhpcydzIHRpY2sgbGFiZWxzIHdoZW4gZXZlcnkgc2VyaWVzIG9uIGl0IGlzIGEgY2hhbmdlIG9mIGEgcmF0ZVxuLy8gKGEgc2hhcmUncywgb3IgYSBwZXJjZW50LWZvcm1hdCB2YWx1ZSdzKTogc2lnbmVkIHBlcmNlbnRhZ2UgcG9pbnRzLCBhcyB0aGVcbi8vIHNlcmllcycgdG9vbHRpcHMgYW5kIGRhdGEgbGFiZWxzIHdyaXRlIHRoZW0gKCcrNS4wIHBwJykuIG51bGwgZm9yIGFueSBvdGhlclxuLy8gYXhpcy5cbmZ1bmN0aW9uIHBvaW50c0F4aXNMYWJlbChcbiAgYW5ub3RhdGlvbnM6IENoYXJ0QW5ub3RhdGlvbnMsXG4gIGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsXG4gIGF4aXNJbmRleGVzOiBWYWx1ZUF4aXNJbmRleFtdLFxuICBheGlzSW5kZXg6IFZhbHVlQXhpc0luZGV4LFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogVmFsdWVBeGlzTGFiZWwgfCBudWxsIHtcbiAgY29uc3Qgb25BeGlzID0gZXh0cmFjdGVkLnNlcmllc1xuICAgIC5tYXAoKF8sIGluZGV4KSA9PiBpbmRleClcbiAgICAuZmlsdGVyKChpbmRleCkgPT4gYXhpc0luZGV4ZXNbaW5kZXhdID09PSBheGlzSW5kZXgpO1xuICBjb25zdCBwb2ludHMgPSBvbkF4aXMubGVuZ3RoID4gMCAmJiBvbkF4aXMuZXZlcnkoKGluZGV4KSA9PiBpc1BvaW50c0NoYW5nZShcbiAgICBhbm5vdGF0aW9ucy5vdXRwdXRzW2luZGV4XSxcbiAgICBvdXRwdXRBeGlzTWVhc3VyZShleHRyYWN0ZWQuc2VyaWVzW2luZGV4XS5tZWFzdXJlLCBhbm5vdGF0aW9ucy5vdXRwdXRzW2luZGV4XSwgYW5ub3RhdGlvbnMubWVhc3VyZVNwZWNzW2luZGV4XSksXG4gICkpO1xuXG4gIGlmICghcG9pbnRzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB3cml0ZSA9IG91dHB1dFdyaXRlcihhbm5vdGF0aW9ucywgb25BeGlzWzBdLCBleHRyYWN0ZWQuc2VyaWVzW29uQXhpc1swXV0ubWVhc3VyZSwgY29udGV4dCk7XG5cbiAgcmV0dXJuIHsgZm9ybWF0dGVyOiAodmFsdWU6IG51bWJlcikgPT4gd3JpdGUodmFsdWUpIH07XG59XG5cbi8vIEEgY2hhbmdlIG9mIGEgcmF0ZSwgd2hpY2ggcHJpbnRzIGluIHBlcmNlbnRhZ2UgcG9pbnRzOiBhIHNoYXJlJ3MgY2hhbmdlLCBvclxuLy8gdGhlIGNoYW5nZSBvZiBhIHZhbHVlIHdob3NlIGZvcm1hdCAoaXRzIHNsb3QncywgZWxzZSBpdHMgbWVhc3VyZSdzKSBpcyBhXG4vLyBwZXJjZW50LlxuZnVuY3Rpb24gaXNQb2ludHNDaGFuZ2Uob3V0cHV0OiBPdXRwdXRNZXRhIHwgbnVsbCwgYXhpc01lYXN1cmU6IENoYXJ0TWVhc3VyZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gISFvdXRwdXQgJiYgb3V0cHV0LnJvbGUgPT09ICdjaGFuZ2UnICYmIG91dHB1dC5raW5kICE9PSAncmFuaydcbiAgICAmJiAob3V0cHV0LmtpbmQgPT09ICdzaGFyZScgfHwgYXhpc01lYXN1cmUuZm9ybWF0ID09PSBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50KTtcbn1cblxuLy8gQSByYW5rLCBjdXJyZW50IG9yIHByaW9yOyBhIHJhbmsgY2hhbmdlIGlzIGEgZGlmZmVyZW5jZSwgbm90IGEgcG9zaXRpb24uXG5mdW5jdGlvbiBpc1JhbmtQb3NpdGlvbihvdXRwdXQ6IE91dHB1dE1ldGEpOiBib29sZWFuIHtcbiAgcmV0dXJuIG91dHB1dC5raW5kID09PSAncmFuaycgJiYgb3V0cHV0LnJvbGUgIT09ICdjaGFuZ2UnO1xufVxuXG5mdW5jdGlvbiBhbm5vdGF0ZWRDaGFydFRvb2x0aXAoc291cmNlOiBBbm5vdGF0ZWRUb29sdGlwU291cmNlIHwgbnVsbCkge1xuICByZXR1cm4gc291cmNlXG4gICAgPyB7XG4gICAgICB0cmlnZ2VyOiAnYXhpcycgYXMgY29uc3QsXG4gICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcykgPT4gYW5ub3RhdGVkVG9vbHRpcChwYXJhbXMsIHNvdXJjZSksXG4gICAgfVxuICAgIDogbnVsbDtcbn1cblxuLy8gVGhlIHBlcmlvZCwgd2l0aCAndG8gZGF0ZScgd2hlbiBpdCBpcyBub3Qgb3ZlciB5ZXQsIHRoZW4gZWFjaCBzZXJpZXMgc2hvd25cbi8vIChhIGxlZ2VuZCBjYW4gaGlkZSBzb21lKTogaXRzIHZhbHVlIHdyaXR0ZW4gYnkgd2hhdCBpdCBpcywgYW5kIHdoYXQgaXRcbi8vIGNvdmVycy4gQSBwYXJ0aWFsIHNlZ21lbnQgc3BlYWtzIGZvciBpdHMgc2VyaWVzLiBOYW1lcyBhbmQgdmFsdWVzIGNvbWUgZnJvbVxuLy8gdGhlIGRhdGEgYW5kIHRoZSBjb25maWcsIGFuZCBFQ2hhcnRzIHNldHMgdGhlIHRvb2x0aXAgYXMgSFRNTCwgc28gYm90aCBhcmVcbi8vIGVzY2FwZWQuXG5mdW5jdGlvbiBhbm5vdGF0ZWRUb29sdGlwKHBhcmFtczogVG9vbHRpcENvbXBvbmVudEZvcm1hdHRlckNhbGxiYWNrUGFyYW1zLCBzb3VyY2U6IEFubm90YXRlZFRvb2x0aXBTb3VyY2UpOiBzdHJpbmcge1xuICBjb25zdCBpdGVtcyA9IEFycmF5LmlzQXJyYXkocGFyYW1zKSA/IHBhcmFtcyA6IFtwYXJhbXNdO1xuICBjb25zdCBkYXRhSW5kZXggPSBpdGVtc1swXT8uZGF0YUluZGV4ID8/IDA7XG4gIGNvbnN0IGNvdW50ID0gc291cmNlLmV4dHJhY3RlZC5zZXJpZXMubGVuZ3RoO1xuICBjb25zdCBtYXJrZXJzID0gbmV3IE1hcDxudW1iZXIsIHN0cmluZz4oKTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICBjb25zdCBzZXJpZXNJbmRleCA9IGl0ZW0uc2VyaWVzSW5kZXggPz8gLTE7XG4gICAgY29uc3Qgb3duZXIgPSBzZXJpZXNJbmRleCA8IGNvdW50ID8gc2VyaWVzSW5kZXggOiBzb3VyY2Uub3duZXJzW3Nlcmllc0luZGV4IC0gY291bnRdO1xuXG4gICAgaWYgKG93bmVyICE9PSB1bmRlZmluZWQgJiYgb3duZXIgPj0gMCAmJiAhbWFya2Vycy5oYXMob3duZXIpKSB7XG4gICAgICBtYXJrZXJzLnNldChvd25lciwgdHlwZW9mIGl0ZW0ubWFya2VyID09PSAnc3RyaW5nJyA/IGl0ZW0ubWFya2VyIDogJycpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5hbWVkUHJpb3JzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGxpbmVzID0gWy4uLm1hcmtlcnMuZW50cmllcygpXVxuICAgIC5zb3J0KChbZmlyc3RdLCBbc2Vjb25kXSkgPT4gZmlyc3QgLSBzZWNvbmQpXG4gICAgLm1hcCgoW2luZGV4LCBtYXJrZXJdKSA9PiBhbm5vdGF0ZWRUb29sdGlwTGluZShzb3VyY2UsIGluZGV4LCBkYXRhSW5kZXgsIG1hcmtlciwgbmFtZWRQcmlvcnMpKTtcblxuICByZXR1cm4gW2Fubm90YXRlZFRvb2x0aXBIZWFkaW5nKHNvdXJjZSwgZGF0YUluZGV4KSwgLi4ubGluZXNdLmpvaW4oJzxici8+Jyk7XG59XG5cbmZ1bmN0aW9uIGFubm90YXRlZFRvb2x0aXBIZWFkaW5nKHNvdXJjZTogQW5ub3RhdGVkVG9vbHRpcFNvdXJjZSwgZGF0YUluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCBjYXRlZ29yeSA9IHNvdXJjZS5leHRyYWN0ZWQuY2F0ZWdvcmllc1tkYXRhSW5kZXhdID8/ICcnO1xuICBjb25zdCBwZXJpb2QgPSBzb3VyY2UuZ3JhbnVsYXJpdHlcbiAgICA/IGZvcm1hdFBlcmlvZExhYmVsKGNhdGVnb3J5LCBzb3VyY2UuZ3JhbnVsYXJpdHksIHRydWUsIHNvdXJjZS5jb250ZXh0LmxvY2FsZSwgc291cmNlLmRhdGVMYWJlbClcbiAgICA6IGNhdGVnb3J5O1xuXG4gIHJldHVybiBlc2NhcGVIdG1sKGRhdGFJbmRleCA9PT0gc291cmNlLmFubm90YXRpb25zLnBhcnRpYWxJbmRleCA/IGAke3BlcmlvZH0gKCR7UEFSVElBTF9QRVJJT0RfVEVYVH0pYCA6IHBlcmlvZCk7XG59XG5cbi8vICfil48gUmV2ZW51ZSAodnMgcHJldmlvdXMgbW9udGgpOiAkODEzIMK3IEF1ZyAxIOKAkyAxNSwgMjAyNicsIGFuZCB3aHkgYSB2YWx1ZVxuLy8gcmVhZHMgJ+KAlCcgb3IgJ24vYScgd2hlbiBpdCBkb2VzICgnTm8gYmFzZWxpbmU6IG5vIGRhdGEgYmVmb3JlIEp1biAxMCwgMjAyNicpLlxuLy8gQSB2YWx1ZSBjb21wYXJlZCB3aXRoIGEgcHJpb3IgdGhlIGNoYXJ0IGRvZXMgbm90IHBsb3QgbmFtZXMgdGhhdCBwcmlvclxuLy8gb25jZSwgb24gdGhlIGZpcnN0IGxpbmUgc2hvd24gdGhhdCBpcyBjb21wYXJlZCB3aXRoIGl0OiAnUmF0ZSAlIGNoYW5nZSAodnNcbi8vIHByZXZpb3VzIG1vbnRoKTogLTEwJSDCtyB2cyA1MCUgKFNlcCAxIOKAkyAyLCAyMDI2KScuIG5hbWVkUHJpb3JzIGhvbGRzIHRoZVxuLy8gcHJpb3JzIGFscmVhZHkgbmFtZWQuXG5mdW5jdGlvbiBhbm5vdGF0ZWRUb29sdGlwTGluZShcbiAgc291cmNlOiBBbm5vdGF0ZWRUb29sdGlwU291cmNlLFxuICBpbmRleDogbnVtYmVyLFxuICBkYXRhSW5kZXg6IG51bWJlcixcbiAgbWFya2VyOiBzdHJpbmcsXG4gIG5hbWVkUHJpb3JzOiBTZXQ8c3RyaW5nPixcbik6IHN0cmluZyB7XG4gIGNvbnN0IHNlcmllcyA9IHNvdXJjZS5leHRyYWN0ZWQuc2VyaWVzW2luZGV4XTtcbiAgY29uc3QgdmFsdWUgPSBzZXJpZXMudmFsdWVzW2RhdGFJbmRleF0gPz8gbnVsbDtcbiAgY29uc3QgZm9ybWF0dGVkID0gc291cmNlLmFubm90YXRpb25zLm91dHB1dHNbaW5kZXhdXG4gICAgPyBvdXRwdXRWYWx1ZShzb3VyY2UuYW5ub3RhdGlvbnMsIGluZGV4LCBzZXJpZXMubWVhc3VyZSwgc291cmNlLmNvbnRleHQpKHZhbHVlLCBkYXRhSW5kZXgpXG4gICAgOiB7IHRleHQ6IHNlcmllc1Rvb2x0aXAoc2VyaWVzLm1lYXN1cmUsIHNvdXJjZS5jb250ZXh0KS52YWx1ZUZvcm1hdHRlcih2YWx1ZSksIHRpdGxlOiBudWxsIH07XG4gIGNvbnN0IGxhbmVQcmlvciA9IHNvdXJjZS5hbm5vdGF0aW9ucy5sYW5lUHJpb3JzW2luZGV4XTtcbiAgY29uc3QgY29tcGFyZWQgPSBsYW5lUHJpb3IgJiYgIW5hbWVkUHJpb3JzLmhhcyhsYW5lUHJpb3Iua2V5KVxuICAgID8gY29tcGFyZWRQcmlvckRldGFpbChzb3VyY2UsIGluZGV4LCBsYW5lUHJpb3IsIGRhdGFJbmRleClcbiAgICA6ICcnO1xuICBpZiAobGFuZVByaW9yKSB7XG4gICAgbmFtZWRQcmlvcnMuYWRkKGxhbmVQcmlvci5rZXkpO1xuICB9XG5cbiAgY29uc3QgcGFydHMgPSBbZm9ybWF0dGVkLnRleHQsIHNlcmllc0RldGFpbChzb3VyY2UsIGluZGV4LCBkYXRhSW5kZXgpLCBjb21wYXJlZCwgZm9ybWF0dGVkLnRpdGxlID8/ICcnXTtcblxuICByZXR1cm4gYCR7bWFya2VyfSAke2VzY2FwZUh0bWwoc2VyaWVzLm5hbWUpfTogJHtlc2NhcGVIdG1sKHBhcnRzLmZpbHRlcigocGFydCkgPT4gISFwYXJ0KS5qb2luKFRPT0xUSVBfREVUQUlMX1NFUEFSQVRPUikpfWA7XG59XG5cbi8vIFRoZSBwcmlvciBhIHZhbHVlIGlzIGNvbXBhcmVkIHdpdGgsIHdoZW4gdGhlIGNoYXJ0IGRvZXMgbm90IHBsb3QgaXQ6IGl0c1xuLy8gdmFsdWUgaW4gaXRzIG1lYXN1cmUncyBmb3JtYXQsIGFuZCBpdHMgZGF5cyAoJ3ZzIDUwJSAoU2VwIDEg4oCTIDIsIDIwMjYpJykuXG4vLyBUaGUgbWVhc3VyZSdzIGZvcm1hdCBpcyB0aGUgY3VycmVudCBzZXJpZXMnIHdoZW4gdGhlIGNoYXJ0IHBsb3RzIGl0LCBlbHNlXG4vLyBhIGNoYW5nZSBzbG90J3Mgb3duIGV4cGxpY2l0IGZvcm1hdCAoYSBjaGFuZ2UgaXMgaW4gaXRzIG1lYXN1cmUncyB1bml0cykuXG5mdW5jdGlvbiBjb21wYXJlZFByaW9yRGV0YWlsKFxuICBzb3VyY2U6IEFubm90YXRlZFRvb2x0aXBTb3VyY2UsXG4gIGluZGV4OiBudW1iZXIsXG4gIGxhbmVQcmlvcjogTGFuZVByaW9yLFxuICBkYXRhSW5kZXg6IG51bWJlcixcbik6IHN0cmluZyB7XG4gIGNvbnN0IGFubm90YXRpb25zID0gc291cmNlLmFubm90YXRpb25zO1xuICBjb25zdCBtZWFzdXJlID0gc291cmNlLmV4dHJhY3RlZC5zZXJpZXNbaW5kZXhdLm1lYXN1cmU7XG4gIGNvbnN0IG1lYXN1cmVTcGVjID0gYW5ub3RhdGlvbnMubWVhc3VyZVNwZWNzW2luZGV4XVxuICAgID8/IChhbm5vdGF0aW9ucy5vdXRwdXRzW2luZGV4XT8ucm9sZSAhPT0gJ3BlcmNlbnRfY2hhbmdlJyAmJiBuYW1lc1ZhbHVlRm9ybWF0KG1lYXN1cmUpID8gbWVhc3VyZSA6IG51bGwpO1xuICBjb25zdCB0ZXh0ID0gZm9ybWF0T3V0cHV0VmFsdWUobGFuZVByaW9yLnZhbHVlc1tkYXRhSW5kZXhdID8/IG51bGwsIGxhbmVQcmlvci5vdXRwdXQsIG51bGwsIHNvdXJjZS5jb250ZXh0LCB7XG4gICAgbWVhc3VyZVNwZWMsXG4gICAgZmxvb3I6IGFubm90YXRpb25zLmNvbXBhcmlzb24/LmZsb29yID8/IG51bGwsXG4gIH0pLnRleHQ7XG4gIGNvbnN0IHdpbmRvdyA9IHByaW9yRGV0YWlsKHNvdXJjZSwgbGFuZVByaW9yLm91dHB1dCwgZGF0YUluZGV4KTtcblxuICByZXR1cm4gd2luZG93ID8gYCR7Q09NUEFSRURfUFJJT1JfUFJFRklYfSAke3RleHR9ICgke3dpbmRvd30pYCA6IGAke0NPTVBBUkVEX1BSSU9SX1BSRUZJWH0gJHt0ZXh0fWA7XG59XG5cbi8vIFdoYXQgYSBzZXJpZXMnIHZhbHVlIGNvdmVycywgd2hlbiB0aGUgc2VydmVyIHNheXM6IGEgcHJpb3IncyBkYXlzLCBvciBhXG4vLyB3aW5kb3dlZCB2YWx1ZSdzIHdpbmRvdyAoJ1JvbGxpbmcgMy1tb250aCB0b3RhbCcpLCB3aG9zZSBkYXlzIHRoZSBub3RlXG4vLyB1bmRlciB0aGUgY2hhcnQgbmFtZXMuXG5mdW5jdGlvbiBzZXJpZXNEZXRhaWwoc291cmNlOiBBbm5vdGF0ZWRUb29sdGlwU291cmNlLCBpbmRleDogbnVtYmVyLCBkYXRhSW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IG91dHB1dCA9IHNvdXJjZS5hbm5vdGF0aW9ucy5vdXRwdXRzW2luZGV4XTtcbiAgY29uc3Qgd2luZG93ID0gc291cmNlLmFubm90YXRpb25zLndpbmRvd3NbaW5kZXhdO1xuXG4gIGlmIChvdXRwdXQ/LnJvbGUgPT09ICdwcmlvcicpIHtcbiAgICByZXR1cm4gcHJpb3JEZXRhaWwoc291cmNlLCBvdXRwdXQsIGRhdGFJbmRleCk7XG4gIH1cblxuICByZXR1cm4gd2luZG93ID8gd2luZG93VGV4dCh7IC4uLndpbmRvdywgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCB9LCBzb3VyY2UuY29udGV4dC5sb2NhbGUsIHNvdXJjZS5ncmFudWxhcml0eSkgOiAnJztcbn1cblxuLy8gQSBwcmlvciB2YWx1ZSdzIGRheXMuIEEgcmFuZ2UgY29tcGFyaXNvbiBjb21wYXJlcyBldmVyeSBwb2ludCB3aXRoIHRoZVxuLy8gc2FtZSB3aW5kb3cuIEEgc2VyaWVzIGNvbXBhcmlzb24gY29tcGFyZXMgZWFjaCBwZXJpb2Qgd2l0aCB0aGUgcGVyaW9kIGl0c1xuLy8gbGFuZSdzIG9mZnNldCBiYWNrOyBhbiBhc19vZiBjb21wYXJpc29uIHJlYWRzIHRoZSB2YWx1ZSBhdCB0aGUgZW5kIG9mIHRoYXRcbi8vIHBlcmlvZCAoJ29uIEF1ZyAzMSwgMjAyNicpLlxuZnVuY3Rpb24gcHJpb3JEZXRhaWwoc291cmNlOiBBbm5vdGF0ZWRUb29sdGlwU291cmNlLCBvdXRwdXQ6IE91dHB1dE1ldGEsIGRhdGFJbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgY29tcGFyaXNvbiA9IHNvdXJjZS5hbm5vdGF0aW9ucy5jb21wYXJpc29uO1xuICBjb25zdCBsYW5lID0gKG91dHB1dC5vZmZzZXQgPz8gMSkgLSAxO1xuICBjb25zdCBvZmZzZXQgPSBjb21wYXJpc29uPy5vZmZzZXRzPy5bbGFuZV07XG4gIGNvbnN0IGxvY2FsZSA9IHNvdXJjZS5jb250ZXh0LmxvY2FsZTtcblxuICBpZiAoIWNvbXBhcmlzb24gfHwgIW9mZnNldCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmIChjb21wYXJpc29uLm1vZGUgPT09ICdyYW5nZScgfHwgIXNvdXJjZS5ncmFudWxhcml0eSkge1xuICAgIGNvbnN0IHByaW9yID0gY29tcGFyaXNvbi5wcmlvcnM/LltsYW5lXTtcblxuICAgIHJldHVybiBwcmlvciA/IGZvcm1hdERheVdpbmRvdyhwcmlvciwgY29tcGFyaXNvbi50aW1lem9uZSwgbG9jYWxlKSA6ICcnO1xuICB9XG5cbiAgY29uc3QgcGFydGlhbCA9IGRhdGFJbmRleCA9PT0gc291cmNlLmFubm90YXRpb25zLnBhcnRpYWxJbmRleCAmJiBjb21wYXJpc29uLmFsaWduID09PSAndG9fZGF0ZSc7XG4gIGNvbnN0IHRvZGF5ID0gcGFydGlhbCA/IHpvbmVUb2RheShjb21wYXJpc29uLnRpbWV6b25lKSA6IG51bGw7XG4gIGNvbnN0IHdpbmRvdyA9IHByaW9yUGVyaW9kV2luZG93KHNvdXJjZS5leHRyYWN0ZWQuY2F0ZWdvcmllc1tkYXRhSW5kZXhdID8/ICcnLCBzb3VyY2UuZ3JhbnVsYXJpdHksIG9mZnNldCwgdG9kYXkpO1xuXG4gIGlmICghd2luZG93KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBhcmlzb24ubW9kZSA9PT0gJ2FzX29mJ1xuICAgID8gYG9uICR7Zm9ybWF0RGF5UmFuZ2Uod2luZG93LmVuZCwgd2luZG93LmVuZCwgbG9jYWxlKX1gXG4gICAgOiBmb3JtYXREYXlXaW5kb3coeyAuLi53aW5kb3csIHRocm91Z2g6IHBhcnRpYWwgPyBjb21wYXJpc29uLmN1cnJlbnQ/LnRocm91Z2ggPz8gbnVsbCA6IG51bGwgfSwgY29tcGFyaXNvbi50aW1lem9uZSwgbG9jYWxlKTtcbn1cblxuLy8gVGhlIGRheXMgb25lIHBlcmlvZCBvZiB0aGUgYXhpcyBpcyBjb21wYXJlZCB3aXRoOiB0aGUgcGVyaW9kIG1vdmVkIGJhY2sgYnlcbi8vIHRoZSBsYW5lJ3Mgb2Zmc2V0LiBBIHBlcmlvZCBub3Qgb3ZlciB5ZXQsIGNvbXBhcmVkIHRvIGRhdGUsIHJ1bnMgb25seSB0b1xuLy8gdG9kYXkgbW92ZWQgYmFjayAocHJpb3JUb0RhdGVFbmQpLiBudWxsIGZvciBhIGNhdGVnb3J5IHRoYXQgaXMgbm90IGEgZGF5LFxuLy8gb3IgYW4gb2Zmc2V0IHdpdGhvdXQgYSB1bml0IChhIGN1c3RvbSByYW5nZSkuXG5mdW5jdGlvbiBwcmlvclBlcmlvZFdpbmRvdyhcbiAgY2F0ZWdvcnk6IHN0cmluZyxcbiAgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHksXG4gIG9mZnNldDogQ29tcGFyaXNvbk9mZnNldCxcbiAgdG9kYXk6IERhdGUgfCBudWxsLFxuKTogeyBzdGFydDogc3RyaW5nOyBlbmQ6IHN0cmluZyB9IHwgbnVsbCB7XG4gIGNvbnN0IHN0YXJ0ID0gcGFyc2VJU08oY2F0ZWdvcnkpO1xuICBjb25zdCB1bml0ID0gb2Zmc2V0LnVuaXQ7XG4gIGNvbnN0IGNvdW50ID0gb2Zmc2V0LmNvdW50O1xuXG4gIGlmICghaXNWYWxpZChzdGFydCkgfHwgIXVuaXQgfHwgIWNvdW50KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBiYWNrID0gKGRhdGU6IERhdGUpID0+IGFkZFBlcmlvZHMoZGF0ZSwgdW5pdCwgLWNvdW50KTtcbiAgY29uc3QgZnVsbEVuZCA9IGFkZERheXMoYmFjayhhZGRQZXJpb2RzKHN0YXJ0LCBncmFudWxhcml0eSwgMSkpLCAtMSk7XG4gIGNvbnN0IGVuZCA9IHRvZGF5ID8gZWFybGllc3RPZihbZnVsbEVuZCwgcHJpb3JUb0RhdGVFbmQodG9kYXksIHN0YXJ0LCBiYWNrLCB1bml0KV0pIDogZnVsbEVuZDtcblxuICByZXR1cm4geyBzdGFydDogY2FsZW5kYXJEYXkoYmFjayhzdGFydCkpLCBlbmQ6IGNhbGVuZGFyRGF5KGxhdGVzdE9mKFtlbmQsIGJhY2soc3RhcnQpXSkpIH07XG59XG5cbi8vIFRvZGF5LCBrZXB0IGluc2lkZSB0aGUgcGVyaW9kLCBtb3ZlZCBiYWNrIGJ5IHRoZSBvZmZzZXQ7IHdoZW4gdG9kYXkgaXMgdGhlXG4vLyBsYXN0IGRheSBvZiBpdHMgbW9udGgsIHRoZSBsYXN0IGRheSBvZiB0aGUgbW9udGggaXQgbGFuZHMgaW4gKHRoZVxuLy8gc2VydmVyJ3MgZW5kLW9mLW1vbnRoIHJ1bGU6IFNlcCAzMCBjb21wYXJlcyB3aXRoIEF1ZyAzMSwgbm90IEF1ZyAzMCkuXG5mdW5jdGlvbiBwcmlvclRvRGF0ZUVuZChcbiAgdG9kYXk6IERhdGUsXG4gIHBlcmlvZFN0YXJ0OiBEYXRlLFxuICBiYWNrOiAoZGF0ZTogRGF0ZSkgPT4gRGF0ZSxcbiAgdW5pdDogQ2hhcnRHcmFudWxhcml0eSxcbik6IERhdGUge1xuICBjb25zdCBkYXkgPSBsYXRlc3RPZihbc3RhcnRPZkRheSh0b2RheSksIHBlcmlvZFN0YXJ0XSk7XG4gIGNvbnN0IG1vdmVkID0gYmFjayhkYXkpO1xuXG4gIHJldHVybiBpc0xhc3REYXlPZk1vbnRoKGRheSkgJiYgdW5pdCAhPT0gJ2RheScgJiYgdW5pdCAhPT0gJ3dlZWsnID8gZW5kT2ZNb250aChtb3ZlZCkgOiBtb3ZlZDtcbn1cblxuZnVuY3Rpb24gYWRkUGVyaW9kcyhkYXRlOiBEYXRlLCB1bml0OiBDaGFydEdyYW51bGFyaXR5LCBjb3VudDogbnVtYmVyKTogRGF0ZSB7XG4gIHN3aXRjaCAodW5pdCkge1xuICAgIGNhc2UgJ2RheSc6XG4gICAgICByZXR1cm4gYWRkRGF5cyhkYXRlLCBjb3VudCk7XG4gICAgY2FzZSAnd2Vlayc6XG4gICAgICByZXR1cm4gYWRkV2Vla3MoZGF0ZSwgY291bnQpO1xuICAgIGNhc2UgJ3F1YXJ0ZXInOlxuICAgICAgcmV0dXJuIGFkZFF1YXJ0ZXJzKGRhdGUsIGNvdW50KTtcbiAgICBjYXNlICd5ZWFyJzpcbiAgICAgIHJldHVybiBhZGRZZWFycyhkYXRlLCBjb3VudCk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBhZGRNb250aHMoZGF0ZSwgY291bnQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGVuZGFyRGF5KGRhdGU6IERhdGUpOiBzdHJpbmcge1xuICByZXR1cm4gZm9ybWF0SVNPKGRhdGUsIHsgcmVwcmVzZW50YXRpb246ICdkYXRlJyB9KTtcbn1cblxuLy8gVG9kYXkncyBjYWxlbmRhciBkYXkgaW4gdGhlIHJlcG9ydCdzIHpvbmUsIGFzIGxvY2FsIG1pZG5pZ2h0LiBUaGUgc2VydmVyXG4vLyBtYXJrcyB3aGljaCBwZXJpb2QgaG9sZHMgdG9kYXkgKHBhcnRpYWxQZXJpb2QpIGJ1dCBub3QgdGhlIGRheSBpdHNlbGY7IHRoZVxuLy8gcHJpb3Igb2YgdGhhdCBwZXJpb2QgaXMgY2xpcHBlZCBhdCB0aGUgc2FtZSBkYXkuIEFuIHVua25vd24gem9uZSByZWFkcyB0aGVcbi8vIGJyb3dzZXIncyBvd24gZGF5LlxuZnVuY3Rpb24gem9uZVRvZGF5KHRpbWV6b25lOiBzdHJpbmcpOiBEYXRlIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJ0cyA9IGRhdGVGb3JtYXQoJ2VuLVVTJywgeyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnbnVtZXJpYycsIGRheTogJ251bWVyaWMnIH0sIHRpbWV6b25lKVxuICAgICAgLmZvcm1hdFRvUGFydHMobmV3IERhdGUoKSk7XG4gICAgY29uc3QgcGFydCA9ICh0eXBlOiBJbnRsLkRhdGVUaW1lRm9ybWF0UGFydFR5cGVzKSA9PiBOdW1iZXIocGFydHMuZmluZCgoZm91bmQpID0+IGZvdW5kLnR5cGUgPT09IHR5cGUpPy52YWx1ZSk7XG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZShwYXJ0KCd5ZWFyJyksIHBhcnQoJ21vbnRoJykgLSAxLCBwYXJ0KCdkYXknKSk7XG5cbiAgICBpZiAoaXNWYWxpZCh0b2RheSkpIHtcbiAgICAgIHJldHVybiB0b2RheTtcbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIC8vIEFuIHVua25vd24gem9uZTogdGhlIGJyb3dzZXIncyBkYXkgYmVsb3cuXG4gIH1cblxuICByZXR1cm4gc3RhcnRPZkRheShuZXcgRGF0ZSgpKTtcbn1cblxuLy8gQSBjb2xvckJ5IGNoYXJ0J3Mgc3RhdGlzdGljIGxpbmU6IG9uZSBsaW5lIG92ZXIgZXZlcnkgYmFyLCBodW5nIG9mZiB0aGVcbi8vIGZpcnN0IHNlcmllcyBhbmQgZHJhd24gaW4gdGhlIHJlZmVyZW5jZSBzbGF0ZSwgYXMgbm8gb25lIGNhdGVnb3J5J3MgY29sb3Jcbi8vIHNwZWFrcyBmb3IgdGhlIG90aGVycy5cbmZ1bmN0aW9uIGNvbG9yQnlTdGF0TGluZShcbiAgZmlyc3Q6IFNlcmllc09wdGlvbixcbiAgZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcyxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgd3JpdGU/OiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nLFxuKTogU2VyaWVzT3B0aW9uIHtcbiAgY29uc3QgbWVhc3VyZSA9IGV4dHJhY3RlZC5zZXJpZXNbMF0/Lm1lYXN1cmU7XG4gIGNvbnN0IHN0YXQgPSBtZWFzdXJlTWFya1N0YXQobWVhc3VyZSk7XG4gIGNvbnN0IG1hcmtMaW5lID0gc3RhdCAmJiBzdGF0TWFya0xpbmUoXG4gICAgY29sb3JCeVZhbHVlcyhleHRyYWN0ZWQpLFxuICAgIHN0YXQsXG4gICAgd3JpdGUgPz8gbWVhc3VyZVdyaXRlcihtZWFzdXJlLCBjb250ZXh0KSxcbiAgICBgIyR7UkVQT1JUX1JFRkVSRU5DRV9DT0xPUn1gLFxuICApO1xuXG4gIHJldHVybiBtYXJrTGluZSA/IHsgLi4uZmlyc3QsIG1hcmtMaW5lIH0gYXMgU2VyaWVzT3B0aW9uIDogZmlyc3Q7XG59XG5cbi8vIEEgc2VyaWVzJyBzdGF0aXN0aWMgbGluZSBhY3Jvc3MgdGhlIHBsb3QsIGxhYmVsZWQgd2l0aCB0aGUgc3RhdGlzdGljIGFuZFxuLy8gaXRzIHZhbHVlICgnQXZlcmFnZTogMSwyMzQuNScpLCBvciB1bmRlZmluZWQgd2hlbiBubyBwb2ludCBoYXMgYSB2YWx1ZS4gSXRcbi8vIHRha2VzIHRoZSBzZXJpZXMnIGNvbG9yIHVubGVzcyBpdCBpcyBnaXZlbiBvbmUuXG5mdW5jdGlvbiBzdGF0TWFya0xpbmUoXG4gIHZhbHVlczogKG51bWJlciB8IG51bGwpW10sXG4gIHN0YXQ6IFJlcG9ydENoYXJ0TWFya1N0YXQsXG4gIHdyaXRlOiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nLFxuICBjb2xvcj86IHN0cmluZyxcbikge1xuICBjb25zdCB2YWx1ZSA9IHNlcmllc1N0YXQodmFsdWVzLCBzdGF0KTtcblxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgdGV4dCA9IGAke1NUQVRfTEFCRUxbc3RhdF19OiAke3dyaXRlKHZhbHVlKX1gO1xuXG4gIHJldHVybiB7XG4gICAgc2lsZW50OiB0cnVlLFxuICAgIHN5bWJvbDogJ25vbmUnLFxuICAgIGxpbmVTdHlsZTogeyB0eXBlOiAnZGFzaGVkJyBhcyBjb25zdCwgd2lkdGg6IDEsIC4uLihjb2xvciA/IHsgY29sb3IgfSA6IHt9KSB9LFxuICAgIGxhYmVsOiB7IGZvcm1hdHRlcjogKCkgPT4gdGV4dCwgcG9zaXRpb246ICdpbnNpZGVFbmRUb3AnIGFzIGNvbnN0LCBmb250U2l6ZTogUkVQT1JUX0RBVEFfTEFCRUxfRk9OVF9TSVpFLCAuLi5NQVJLX0xBQkVMX0JPWCB9LFxuICAgIGRhdGE6IFt7IHlBeGlzOiB2YWx1ZSB9XSxcbiAgfTtcbn1cblxuLy8gQSBzdGF0aXN0aWMncyB2YWx1ZSBpbiBpdHMgbWVhc3VyZSdzIG51bWJlciBmb3JtYXQsIGluIHRoZSByZXBvcnQgbG9jYWxlLlxuZnVuY3Rpb24gbWVhc3VyZVdyaXRlcihtZWFzdXJlOiBDaGFydE1lYXN1cmUgfCB1bmRlZmluZWQsIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nIHtcbiAgcmV0dXJuICh2YWx1ZSkgPT4gZm9ybWF0TnVtYmVyKHZhbHVlLCBtZWFzdXJlLCBjb250ZXh0KTtcbn1cblxuLy8gQSAxMDAlIHN0YWNrZWQgc2VyaWVzJyBzdGF0aXN0aWMgaXMgYSBzaGFyZSwgd3JpdHRlbiBhcyBpdHMgdG9vbHRpcCB3cml0ZXNcbi8vIG9uZS5cbmZ1bmN0aW9uIHNoYXJlV3JpdGVyKGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nIHtcbiAgY29uc3QgcmF0aW9Db250ZXh0ID0geyAuLi5jb250ZXh0LCByYXRpb1BlcmNlbnQ6IHRydWUgfTtcblxuICByZXR1cm4gKHZhbHVlKSA9PiBmb3JtYXROdW1iZXIodmFsdWUsIFBFUkNFTlRfU0hBUkVfRk9STUFULCByYXRpb0NvbnRleHQpO1xufVxuXG4vLyBUaGUgc2VyaWVzIHRoYXQgY2FycnkgYSBjaGFydCdzIHJlZmVyZW5jZXMsIG9uZSBwZXIgdmFsdWUgYXhpcyB0aGF0IGhhc1xuLy8gYW55OiBhbiBlbXB0eSBsaW5lIChldmVyeSBwb2ludCBudWxsLCBzbyBpdCBkcmF3cyBub3RoaW5nIGFuZCBzdHJldGNoZXMgbm9cbi8vIGF4aXMpIHdob3NlIG1hcmtMaW5lIGRyYXdzIHRoZSByZWZlcmVuY2UgbGluZXMgYW5kIHdob3NlIG1hcmtBcmVhIGZpbGxzIHRoZVxuLy8gYmFuZHMuIEl0IGlzIHNpbGVudCwgbGVmdCBvdXQgb2YgdGhlIHRvb2x0aXAgYW5kLCBieSByZWZlcmVuY2VMZWdlbmQsIG91dCBvZlxuLy8gdGhlIGxlZ2VuZC4gSXQgaGFzIG5vIG5hbWUsIHNvIG5vIG1lYXN1cmUgc2VyaWVzJyBsZWdlbmQgZW50cnkgKHdoYXRldmVyIGl0c1xuLy8gbmFtZSwgJycgaW5jbHVkZWQpIHRvZ2dsZXMgaXQuXG4vL1xuLy8gTGFiZWxzIGFyZSBmdW5jdGlvbnMsIGFzIGEgc3RyaW5nIGZvcm1hdHRlciBpcyBhIHRlbXBsYXRlIHRoYXQgd291bGQgcmVhZFxuLy8gJ3tifScgb3IgJ3tjfScgaW4gYSBsYWJlbCBhcyBhIHBsYWNlaG9sZGVyLiBFQ2hhcnRzIGRyYXdzIGEgbWFya0FyZWEgdW5kZXJcbi8vIHRoZSBiYXJzIGFuZCBhIG1hcmtMaW5lIG92ZXIgdGhlbSwgc28gYSBiYW5kJ3MgbGFiZWwgcmlkZXMgYW4gaW52aXNpYmxlXG4vLyBtYXJrTGluZSBvbiBpdHMgdXBwZXIgZWRnZSwgaW5zaWRlIGl0cyB0b3AgbGVmdCBjb3JuZXIsIHdoZXJlIHRoZSBmaXJzdCBiYXJcbi8vIHdvdWxkIG90aGVyd2lzZSBjb3ZlciBpdC5cbmZ1bmN0aW9uIHJlZmVyZW5jZUNhcnJpZXJzKHJlZmVyZW5jZXM6IERyYXduUmVmZXJlbmNlW10sIGNhdGVnb3JpZXM6IHN0cmluZ1tdKTogU2VyaWVzT3B0aW9uW10ge1xuICBjb25zdCBjb2xvciA9IGAjJHtSRVBPUlRfUkVGRVJFTkNFX0NPTE9SfWA7XG5cbiAgcmV0dXJuIChbMCwgMV0gYXMgY29uc3QpLmZsYXRNYXAoKGF4aXNJbmRleCk6IFNlcmllc09wdGlvbltdID0+IHtcbiAgICBjb25zdCBvbkF4aXMgPSByZWZlcmVuY2VzLmZpbHRlcigocmVmZXJlbmNlKSA9PiByZWZlcmVuY2UuYXhpc0luZGV4ID09PSBheGlzSW5kZXgpO1xuICAgIGNvbnN0IGxpbmVzID0gb25BeGlzLmZpbHRlcigocmVmZXJlbmNlKSA9PiAhcmVmZXJlbmNlLmJhbmQpO1xuICAgIGNvbnN0IGJhbmRzID0gb25BeGlzLmZpbHRlcigocmVmZXJlbmNlKSA9PiByZWZlcmVuY2UuYmFuZCk7XG5cbiAgICBpZiAoIW9uQXhpcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3tcbiAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgIGRhdGE6IGNhdGVnb3JpZXMubWFwKCgpID0+IG51bGwpLFxuICAgICAgeUF4aXNJbmRleDogYXhpc0luZGV4LFxuICAgICAgc2lsZW50OiB0cnVlLFxuICAgICAgdG9vbHRpcDogeyBzaG93OiBmYWxzZSB9LFxuICAgICAgbWFya0xpbmU6IHtcbiAgICAgICAgc2lsZW50OiB0cnVlLFxuICAgICAgICBzeW1ib2w6ICdub25lJyxcbiAgICAgICAgbGluZVN0eWxlOiB7IGNvbG9yLCB0eXBlOiAnZGFzaGVkJywgd2lkdGg6IDEgfSxcbiAgICAgICAgbGFiZWw6IHsgcG9zaXRpb246ICdpbnNpZGVFbmRUb3AnLCBjb2xvciwgZm9udFNpemU6IFJFUE9SVF9EQVRBX0xBQkVMX0ZPTlRfU0laRSwgLi4uTUFSS19MQUJFTF9CT1ggfSxcbiAgICAgICAgZGF0YTogW1xuICAgICAgICAgIC4uLmxpbmVzLm1hcCgocmVmZXJlbmNlKSA9PiAoeyB5QXhpczogcmVmZXJlbmNlLmxvdywgbGFiZWw6IHsgZm9ybWF0dGVyOiAoKSA9PiByZWZlcmVuY2UubGFiZWwgfSB9KSksXG4gICAgICAgICAgLi4uYmFuZHMubWFwKChyZWZlcmVuY2UpID0+ICh7XG4gICAgICAgICAgICB5QXhpczogcmVmZXJlbmNlLmhpZ2gsXG4gICAgICAgICAgICAvLyBaZXJvIHdpZHRoLCBub3QgemVybyBvcGFjaXR5OiBhIG1hcmtMaW5lJ3MgbGFiZWwgdGFrZXMgdGhlXG4gICAgICAgICAgICAvLyBsaW5lJ3Mgb3BhY2l0eS5cbiAgICAgICAgICAgIGxpbmVTdHlsZTogeyB3aWR0aDogMCB9LFxuICAgICAgICAgICAgbGFiZWw6IHsgcG9zaXRpb246ICdpbnNpZGVTdGFydEJvdHRvbScsIGZvcm1hdHRlcjogKCkgPT4gcmVmZXJlbmNlLmxhYmVsIH0sXG4gICAgICAgICAgfSkpLFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICAgIC4uLihiYW5kcy5sZW5ndGggPyB7XG4gICAgICAgIG1hcmtBcmVhOiB7XG4gICAgICAgICAgc2lsZW50OiB0cnVlLFxuICAgICAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogUkVGRVJFTkNFX0JBTkRfRklMTCB9LFxuICAgICAgICAgIGRhdGE6IGJhbmRzLm1hcCgocmVmZXJlbmNlKSA9PiBbeyB5QXhpczogcmVmZXJlbmNlLmxvdyB9LCB7IHlBeGlzOiByZWZlcmVuY2UuaGlnaCB9XSksXG4gICAgICAgIH0sXG4gICAgICB9IDoge30pLFxuICAgIH0gYXMgU2VyaWVzT3B0aW9uXTtcbiAgfSk7XG59XG5cbi8vIFRoZSBsYXJnZXN0IG1hZ25pdHVkZSBhIHZhbHVlIGF4aXMncyByZWZlcmVuY2VzIHJlYWNoLCB3aGljaCBpdHMgbnVtYmVyXG4vLyBmb3JtYXQgY291bnRzIHRvd2FyZCBpdHMgcGVhaywgYXMgdGhlIGF4aXMgc3RyZXRjaGVzIHRvIHRoZW07IDAgd2hlbiBpdFxuLy8gaGFzIG5vbmUuXG5leHBvcnQgZnVuY3Rpb24gcmVmZXJlbmNlUGVhayhyZWZlcmVuY2VzOiBEcmF3blJlZmVyZW5jZVtdLCBheGlzSW5kZXg6IFZhbHVlQXhpc0luZGV4KTogbnVtYmVyIHtcbiAgY29uc3QgcmVhY2ggPSByZWZlcmVuY2VSZWFjaChyZWZlcmVuY2VzLCBheGlzSW5kZXgpO1xuXG4gIHJldHVybiByZWFjaCA/IE1hdGgubWF4KE1hdGguYWJzKHJlYWNoLmxvdyksIE1hdGguYWJzKHJlYWNoLmhpZ2gpKSA6IDA7XG59XG5cbi8vIFRoZSBsZWdlbmQgb2YgYSBjaGFydCB3aXRoIHJlZmVyZW5jZXMgbmFtZXMgaXRzIG1lYXN1cmUgc2VyaWVzIGFsb25lLCBzb1xuLy8gYSBjYXJyaWVyIG5ldmVyIHNob3dzIGFzIGEgYmxhbmsgZW50cnkuIFdpdGhvdXQgcmVmZXJlbmNlcyBpdCBpcyBsZWZ0IGFzIGl0XG4vLyB3YXMuXG5mdW5jdGlvbiByZWZlcmVuY2VMZWdlbmQoXG4gIGxlZ2VuZDogTGVnZW5kQ29tcG9uZW50T3B0aW9uLFxuICBzZXJpZXM6IFNlcmllc09wdGlvbltdLFxuICByZWZlcmVuY2VzOiBEcmF3blJlZmVyZW5jZVtdLFxuKTogTGVnZW5kQ29tcG9uZW50T3B0aW9uIHtcbiAgcmV0dXJuIHJlZmVyZW5jZXMubGVuZ3RoXG4gICAgPyB7IC4uLmxlZ2VuZCwgZGF0YTogc2VyaWVzLm1hcCgoaXRlbSkgPT4gU3RyaW5nKGl0ZW0ubmFtZSA/PyAnJykpIH1cbiAgICA6IGxlZ2VuZDtcbn1cblxuLy8gVGhlIHNwYW4gb2YgdGhlIHJlZmVyZW5jZXMgb24gb25lIHZhbHVlIGF4aXMsIG9yIHVuZGVmaW5lZCB3aGVuIGl0IGhhc1xuLy8gbm9uZS5cbmZ1bmN0aW9uIHJlZmVyZW5jZVJlYWNoKHJlZmVyZW5jZXM6IERyYXduUmVmZXJlbmNlW10sIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXgpOiBSZWZlcmVuY2VSZWFjaCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG9uQXhpcyA9IHJlZmVyZW5jZXMuZmlsdGVyKChyZWZlcmVuY2UpID0+IHJlZmVyZW5jZS5heGlzSW5kZXggPT09IGF4aXNJbmRleCk7XG5cbiAgcmV0dXJuIG9uQXhpcy5sZW5ndGhcbiAgICA/IHsgbG93OiBNYXRoLm1pbiguLi5vbkF4aXMubWFwKChyZWZlcmVuY2UpID0+IHJlZmVyZW5jZS5sb3cpKSwgaGlnaDogTWF0aC5tYXgoLi4ub25BeGlzLm1hcCgocmVmZXJlbmNlKSA9PiByZWZlcmVuY2UuaGlnaCkpIH1cbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuLy8gRUNoYXJ0cyBsZWF2ZXMgYSBtYXJrTGluZSBvciBtYXJrQXJlYSBvdXQgb2YgYW4gYXhpcydzIGV4dGVudCwgc28gYVxuLy8gcmVmZXJlbmNlIGJleW9uZCB0aGUgZGF0YSB3b3VsZCBmYWxsIG9mZiB0aGUgcGxvdC4gQW4gYXhpcyBib3VuZCB0aGUgY29uZmlnXG4vLyBkb2VzIG5vdCBwaW4gcmVhY2hlcyBwYXN0IHRoZSBmdXJ0aGVzdCByZWZlcmVuY2UsIHRvIGEgcm91bmQgbnVtYmVyIHdpdGhcbi8vIHJvb20gZm9yIGl0cyBsYWJlbCAoYmV5b25kUmVmZXJlbmNlKSwgd2hlbiB0aGUgZGF0YSAoYW5kIHRoZSB6ZXJvIGEgdmFsdWVcbi8vIGF4aXMgYWx3YXlzIHNob3dzKSBmYWxscyBzaG9ydCBvZiBpdCwgYW5kIGlzIGxlZnQgdG8gRUNoYXJ0cyBvdGhlcndpc2U6IGFcbi8vIGNhbGxiYWNrIHJldHVybmluZyB1bmRlZmluZWQga2VlcHMgdGhlIGJvdW5kIGF1dG9tYXRpYy4gUGFzdCB0aGUgZGF0YSBhbmRcbi8vIHplcm8sIGEgcmVmZXJlbmNlIGJleW9uZCB0aGUgbWF4IGlzIGFib3ZlIHplcm8gYW5kIG9uZSBiZXlvbmQgdGhlIG1pbiBiZWxvd1xuLy8gaXQuXG5mdW5jdGlvbiByZWFjaE1pbihyZWFjaDogUmVmZXJlbmNlUmVhY2ggfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIHJlYWNoXG4gICAgPyAoZXh0ZW50OiBBeGlzRXh0ZW50KSA9PiAocmVhY2gubG93IDwgTWF0aC5taW4oZXh0ZW50Lm1pbiwgMCkgPyAtYmV5b25kUmVmZXJlbmNlKC1yZWFjaC5sb3cpIDogdW5kZWZpbmVkKVxuICAgIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiByZWFjaE1heChyZWFjaDogUmVmZXJlbmNlUmVhY2ggfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIHJlYWNoXG4gICAgPyAoZXh0ZW50OiBBeGlzRXh0ZW50KSA9PiAocmVhY2guaGlnaCA+IE1hdGgubWF4KGV4dGVudC5tYXgsIDApID8gYmV5b25kUmVmZXJlbmNlKHJlYWNoLmhpZ2gpIDogdW5kZWZpbmVkKVxuICAgIDogdW5kZWZpbmVkO1xufVxuXG4vLyBUaGUgYm91bmQgYW4gYXhpcyB0YWtlcyBwYXN0IGEgcmVmZXJlbmNlIG9mIHRoaXMgKHBvc2l0aXZlKSBtYWduaXR1ZGU6IHRoZVxuLy8gc21hbGxlc3Qgcm91bmQgbnVtYmVyIGF0IG9yIGFib3ZlIGl0IHBsdXMgUkVGRVJFTkNFX0hFQURST09NLiBUaGUgc3RlcHMgYXJlXG4vLyBmaW5lciB0aGFuIEVDaGFydHMnIHRpY2sgc3RlcHMsIHNvIGEgcmVmZXJlbmNlIGp1c3QgcGFzdCB0aGUgZGF0YSBkb2VzIG5vdFxuLy8gZG91YmxlIHRoZSBheGlzICgxMTAgZ2l2ZXMgMTIwLCBub3QgMjAwKS4gVGhlIHRvbGVyYW5jZSBrZWVwcyBhIGZsb2F0IGVycm9yXG4vLyBmcm9tIHNraXBwaW5nIGEgcm91bmQgbnVtYmVyIHRoZSB2YWx1ZSBhbHJlYWR5IGlzLlxuY29uc3QgTklDRV9TVEVQUyA9IFsxLCAxLjIsIDEuNSwgMiwgMi41LCAzLCA0LCA1LCA2LCA4LCAxMF07XG5jb25zdCBOSUNFX1RPTEVSQU5DRSA9IDFlLTk7XG5cbmZ1bmN0aW9uIGJleW9uZFJlZmVyZW5jZShtYWduaXR1ZGU6IG51bWJlcik6IG51bWJlciB7XG4gIGNvbnN0IHRhcmdldCA9IG1hZ25pdHVkZSAqIFJFRkVSRU5DRV9IRUFEUk9PTTtcbiAgY29uc3QgcG93ZXIgPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihNYXRoLmxvZzEwKHRhcmdldCkpKTtcbiAgY29uc3Qgc3RlcCA9IE5JQ0VfU1RFUFMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUgKiBwb3dlciA+PSB0YXJnZXQgKiAoMSAtIE5JQ0VfVE9MRVJBTkNFKSkgPz8gMTA7XG5cbiAgLy8gUm91bmRlZCBiYWNrIHRvIHRoZSBwb3dlcidzIG93biBkaWdpdHMsIHNvIDEuMiB4IDAuMSByZWFkcyAwLjEyLCBub3RcbiAgLy8gMC4xMjAwMDAwMDAwMDAwMDAwMS5cbiAgcmV0dXJuIE51bWJlcigoc3RlcCAqIHBvd2VyKS50b1ByZWNpc2lvbigxMikpO1xufVxuXG4vLyBUaGUgY2F0ZWdvcnkgYXhpcyBvZiBhbiBheGlzIGNoYXJ0IG9yIGEgd2F0ZXJmYWxsOiB0aGUgY2F0ZWdvcmllcyBpbiByb3dcbi8vIG9yZGVyLCBsYWJlbGVkIGFzIHBlcmlvZHMgd2hlbiB0aGUgcm93cyB3ZXJlIGJ1Y2tldGVkIGJ5IHRpbWUuXG4vL1xuLy8gSG9yaXpvbnRhbCBiYXJzIHJlYWQgdG9wLWRvd246IEVDaGFydHMgZHJhd3MgY2F0ZWdvcnkgMCBhdCB0aGUgYm90dG9tLCBzbyB0aGVcbi8vIGF4aXMgaXMgaW52ZXJ0ZWQgdG8gcHV0IHRoZSBmaXJzdCByb3cgKHRoZSBsYXJnZXN0IG9mIGEgdG9wLU4sIGEgd2F0ZXJmYWxsJ3Ncbi8vIGZpcnN0IHN0ZXApIGF0IHRoZSB0b3AuIFRoZSByb3RhdGVkIHRpdGxlIHNpdHMganVzdCBiZXlvbmQgdGhlIGxvbmdlc3QgbGFiZWxcbi8vIHJhdGhlciB0aGFuIGF0IGEgZml4ZWQgZ2FwIHRoYXQgd291bGQgcHV0IGl0IG9uIHRvcCBvZiB0aGUgbGFiZWxzLlxuLy9cbi8vIEEgYnVja2V0ZWQgYXhpcyBhbHNvIG5hbWVzIGl0cyBwZXJpb2QgaW4gdGhlIGF4aXMgdG9vbHRpcCdzIGhlYWRlcjogRUNoYXJ0c1xuLy8gaGVhZHMgaXQgd2l0aCB0aGUgcmF3IGNhdGVnb3J5ICgnMjAyNi0wMS0wMScpIHVubGVzcyB0aGUgYXhpcyBwb2ludGVyJ3MgbGFiZWxcbi8vIGhhcyBhIGZvcm1hdHRlciwgc28gaXQgcmVhZHMgJ0phbnVhcnkgMjAyNicgaW5zdGVhZCwgYWx3YXlzIHdpdGggaXRzIHllYXIuXG4vLyBUaGUgYXhpcydzIGRhdGVMYWJlbCBzdHlsZSB3cml0ZXMgYm90aCBpdHMgdGljayBsYWJlbHMgYW5kIHRoYXQgaGVhZGVyLlxuZnVuY3Rpb24gY2F0ZWdvcnlBeGlzT3B0aW9uKFxuICBjb25maWc6IENoYXJ0Q29uZmlnLFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBjYXRlZ29yaWVzOiBzdHJpbmdbXSxcbiAgaG9yaXpvbnRhbDogYm9vbGVhbixcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4pIHtcbiAgY29uc3QgZ3JhbnVsYXJpdHkgPSBidWNrZXRHcmFudWxhcml0eShkYXRhKTtcbiAgY29uc3QgZGF0ZUxhYmVsID0gY2hhcnREYXRlTGFiZWwoY29uZmlnKTtcbiAgY29uc3QgcGVyaW9kTGFiZWwgPSBwZXJpb2RBeGlzTGFiZWwoZ3JhbnVsYXJpdHksIGNhdGVnb3JpZXMsIGxvY2FsZSwgZGF0ZUxhYmVsKTtcbiAgY29uc3QgYXhpcyA9IHtcbiAgICB0eXBlOiAnY2F0ZWdvcnknIGFzIGNvbnN0LFxuICAgIGRhdGE6IGNhdGVnb3JpZXMsXG4gICAgaW52ZXJzZTogaG9yaXpvbnRhbCxcbiAgICBuYW1lOiBjb25maWcueEF4aXM/LmxhYmVsLFxuICAgIG5hbWVMb2NhdGlvbjogJ21pZGRsZScgYXMgY29uc3QsXG4gICAgLi4uKGdyYW51bGFyaXR5ID8ge1xuICAgICAgYXhpc1BvaW50ZXI6IHtcbiAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IHsgdmFsdWU6IHVua25vd24gfSkgPT4gZm9ybWF0UGVyaW9kTGFiZWwoXG4gICAgICAgICAgICBTdHJpbmcocGFyYW1zLnZhbHVlKSxcbiAgICAgICAgICAgIGdyYW51bGFyaXR5LFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICAgIGRhdGVMYWJlbCxcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9IDoge30pLFxuICB9O1xuXG4gIGlmICghaG9yaXpvbnRhbCkge1xuICAgIC8vIFRoZSBnYXAgY2xlYXJzIHRoZSB5ZWFyJ3Mgc2Vjb25kIGxpbmUgd2hlbiB0aGUgbGFiZWxzIHByaW50IG9uZS5cbiAgICBjb25zdCBzZWNvbmRMaW5lID0gZ3JhbnVsYXJpdHkgJiYgZGF0ZUxhYmVsID09PSBSZXBvcnRDaGFydERhdGVMYWJlbC5TaG9ydCAmJiBzcGFuc011bHRpcGxlWWVhcnMoY2F0ZWdvcmllcyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uYXhpcyxcbiAgICAgIG5hbWVHYXA6IHNlY29uZExpbmUgPyA0MCA6IDI4LFxuICAgICAgLi4ucGVyaW9kTGFiZWwsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFBlcmlvZCBsYWJlbHMsIHNob3J0LCBsb25nIG9yIG51bWVyaWMgKCdNYXknLCAnUTInLCAnTWF5IDIwMjYnKSwgYXJlXG4gIC8vIGJvdW5kZWQgaW4gbGVuZ3RoIGFuZCBuZXZlciBjdXQ7IG9ubHkgYSBwbGFpbiBjYXRlZ29yeSBpcyB0cnVuY2F0ZWQuIFRoZSBsYWJlbHMgYXJlIGN1dCBoZXJlIHJhdGhlciB0aGFuIGJ5IEVDaGFydHMnIG93blxuICAvLyB0cnVuY2F0aW9uLCBzbyB0aGUgdGl0bGUncyBnYXAgaXMgbWVhc3VyZWQgb24gZXhhY3RseSB0aGUgdGV4dCB0aGUgYXhpc1xuICAvLyBkcmF3cy5cbiAgY29uc3Qgc2hvd24gPSBncmFudWxhcml0eVxuICAgID8gbnVsbFxuICAgIDogbmV3IE1hcChjYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnkpID0+IFtjYXRlZ29yeSwgdHJ1bmNhdGVBeGlzTGFiZWwoY2F0ZWdvcnkpXSkpO1xuICBjb25zdCBsYWJlbHMgPSBzaG93biA/IFsuLi5zaG93bi52YWx1ZXMoKV0gOiBkaXNwbGF5ZWRDYXRlZ29yeUxhYmVscyhjYXRlZ29yaWVzLCBncmFudWxhcml0eSwgbG9jYWxlLCBkYXRlTGFiZWwpO1xuXG4gIHJldHVybiB7XG4gICAgLi4uYXhpcyxcbiAgICBuYW1lR2FwOiB3aWRlc3RBeGlzTGFiZWwobGFiZWxzKSArIEFYSVNfTEFCRUxfTUFSR0lOICsgQVhJU19OQU1FX0NMRUFSQU5DRSxcbiAgICAuLi4oc2hvd24gPyB7IGF4aXNMYWJlbDogeyBmb3JtYXR0ZXI6ICh2YWx1ZTogc3RyaW5nKSA9PiBzaG93bi5nZXQodmFsdWUpID8/IHZhbHVlIH0gfSA6IHBlcmlvZExhYmVsKSxcbiAgfTtcbn1cblxuLy8gVGhlIGNhdGVnb3J5IGF4aXMncyB0aXRsZSBzaWRlLCBvciBudWxsIHdoZW4gdGhlIGF4aXMgaGFzIG5vIHRpdGxlIHRvIG1ha2Vcbi8vIHJvb20gZm9yLlxuZnVuY3Rpb24gY2F0ZWdvcnlUaXRsZVNpZGUoY29uZmlnOiBDaGFydENvbmZpZywgaG9yaXpvbnRhbDogYm9vbGVhbik6IEF4aXNUaXRsZVNpZGUgfCBudWxsIHtcbiAgaWYgKCFjb25maWcueEF4aXM/LmxhYmVsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9yaXpvbnRhbCA/ICdsZWZ0JyA6ICdib3R0b20nO1xufVxuXG4vLyBUaGUgdmFsdWUgYXhlcycgdGl0bGUgc2lkZSwgb3IgbnVsbCB3aGVuIG5vbmUgb2YgdGhlbSBoYXMgYSB0aXRsZS4gQVxuLy8gdmVydGljYWwgY2hhcnQncyB0aXRsZXMgc2l0IGFib3ZlIHRoZSBwbG90LCBhdCB0aGUgdG9wIG9mIGVhY2ggYXhpcyBsaW5lLCBzb1xuLy8gcm9vbSBpcyBtYWRlIG9uY2UgZm9yIGJvdGg7IGEgaG9yaXpvbnRhbCBjaGFydCdzIHNpdHMgYmVsb3cuXG5mdW5jdGlvbiB2YWx1ZVRpdGxlU2lkZShheGVzOiAoQ2hhcnRWYWx1ZUF4aXMgfCB1bmRlZmluZWQpW10sIGhvcml6b250YWw6IGJvb2xlYW4pOiBBeGlzVGl0bGVTaWRlIHwgbnVsbCB7XG4gIGlmICghYXhlcy5zb21lKChheGlzKSA9PiBheGlzPy5sYWJlbCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBob3Jpem9udGFsID8gJ2JvdHRvbScgOiAndG9wJztcbn1cblxuLy8gVGhlIHRpY2sgbGFiZWxzIGFzIHRoZSBheGlzIHNob3dzIHRoZW06IGEgYnVja2V0J3MgcHJpbWFyeSBwZXJpb2QgbGFiZWxcbi8vICgnTWF5JywgJ1EyJywgJ01heSAyMDI2JyksIG90aGVyd2lzZSB0aGUgY2F0ZWdvcnkgaXRzZWxmLiBUaGUgeWVhciBhXG4vLyBtdWx0aS15ZWFyIGF4aXMgcHJpbnRzIHVuZGVyIGEgc2hvcnQgcGVyaW9kIGlzIGxlZnQgb3V0LCBhcyBpdCBpcyBuZXZlciB0aGVcbi8vIHdpZGVyIGxpbmUuXG5mdW5jdGlvbiBkaXNwbGF5ZWRDYXRlZ29yeUxhYmVscyhcbiAgY2F0ZWdvcmllczogc3RyaW5nW10sXG4gIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4gIGRhdGVMYWJlbDogUmVwb3J0Q2hhcnREYXRlTGFiZWwsXG4pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBncmFudWxhcml0eVxuICAgID8gY2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5KSA9PiBwZXJpb2RMYWJlbFBhcnRzKGNhdGVnb3J5LCBncmFudWxhcml0eSwgbG9jYWxlLCBkYXRlTGFiZWwpPy5wcmltYXJ5ID8/IGNhdGVnb3J5KVxuICAgIDogY2F0ZWdvcmllcztcbn1cblxuLy8gVGhlIHBpeGVsIHdpZHRoIG9mIHRoZSB3aWRlc3QgbGFiZWwuIEEgbGFiZWwgdGhhdCBicmVha3Mgb3ZlciBzZXZlcmFsIGxpbmVzXG4vLyBpcyBhcyB3aWRlIGFzIGl0cyBsb25nZXN0IGxpbmUuXG5mdW5jdGlvbiB3aWRlc3RBeGlzTGFiZWwobGFiZWxzOiBzdHJpbmdbXSk6IG51bWJlciB7XG4gIHJldHVybiBsYWJlbHMucmVkdWNlKCh3aWRlc3QsIGxhYmVsKSA9PiBsYWJlbC5zcGxpdCgnXFxuJykucmVkdWNlKFxuICAgIChsaW5lV2lkZXN0LCBsaW5lKSA9PiBNYXRoLm1heChsaW5lV2lkZXN0LCBheGlzTGFiZWxXaWR0aChsaW5lKSksXG4gICAgd2lkZXN0LFxuICApLCAwKTtcbn1cblxuLy8gQSBjYXRlZ29yeSBsYWJlbCBjdXQgdG8gQ0FURUdPUllfTEFCRUxfTUFYX1dJRFRILCBsaW5lIGJ5IGxpbmU6IHRoZSBsb25nZXN0XG4vLyBzdGFydCBvZiBlYWNoIGxpbmUgdGhhdCBzdGlsbCBmaXRzIHdpdGggdGhlIGVsbGlwc2lzIGFmdGVyIGl0LlxuZnVuY3Rpb24gdHJ1bmNhdGVBeGlzTGFiZWwobGFiZWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBsYWJlbC5zcGxpdCgnXFxuJykubWFwKChsaW5lKSA9PiB7XG4gICAgaWYgKGF4aXNMYWJlbFdpZHRoKGxpbmUpIDw9IENBVEVHT1JZX0xBQkVMX01BWF9XSURUSCkge1xuICAgICAgcmV0dXJuIGxpbmU7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBwb2ludHMsIHNvIGFuIGVtb2ppIG9yIG90aGVyIHN1cnJvZ2F0ZSBwYWlyIGlzIG5ldmVyIHNwbGl0LlxuICAgIGNvbnN0IGNoYXJhY3RlcnMgPSBBcnJheS5mcm9tKGxpbmUpO1xuICAgIGNvbnN0IGN1dCA9IChsZW5ndGg6IG51bWJlcikgPT4gYCR7Y2hhcmFjdGVycy5zbGljZSgwLCBsZW5ndGgpLmpvaW4oJycpLnRyaW1FbmQoKX0ke0xBQkVMX0VMTElQU0lTfWA7XG4gICAgbGV0IGZpdHMgPSAwO1xuICAgIGxldCB0b29Mb25nID0gY2hhcmFjdGVycy5sZW5ndGg7XG4gICAgd2hpbGUgKHRvb0xvbmcgLSBmaXRzID4gMSkge1xuICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5mbG9vcigoZml0cyArIHRvb0xvbmcpIC8gMik7XG4gICAgICBpZiAoYXhpc0xhYmVsV2lkdGgoY3V0KGxlbmd0aCkpIDw9IENBVEVHT1JZX0xBQkVMX01BWF9XSURUSCkge1xuICAgICAgICBmaXRzID0gbGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9vTG9uZyA9IGxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3V0KGZpdHMpO1xuICB9KS5qb2luKCdcXG4nKTtcbn1cblxuLy8gT25lIGxpbmUncyB3aWR0aCBpbiB0aGUgYXhpcy1sYWJlbCBmb250LCBtZWFzdXJlZCBvbiBhIGNhbnZhcyB0aGUgd2F5XG4vLyBFQ2hhcnRzIG1lYXN1cmVzIGl0IGZvciBjb250YWluTGFiZWwuIE91dHNpZGUgYSBicm93c2VyIHRoZXJlIGlzIG5vIGNhbnZhc1xuLy8gdG8gbWVhc3VyZSB3aXRoLCBzbyB0aGUgbGluZSBjb3VudHMgYXMgemVybyB3aWR0aC5cbmxldCBheGlzTGFiZWxDb250ZXh0OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgfCBudWxsID0gbnVsbDtcblxuZnVuY3Rpb24gYXhpc0xhYmVsV2lkdGgobGluZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgaWYgKCFheGlzTGFiZWxDb250ZXh0ICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBheGlzTGFiZWxDb250ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcbiAgfVxuXG4gIGlmICghYXhpc0xhYmVsQ29udGV4dCkge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgYXhpc0xhYmVsQ29udGV4dC5mb250ID0gQVhJU19MQUJFTF9GT05UO1xuXG4gIHJldHVybiBheGlzTGFiZWxDb250ZXh0Lm1lYXN1cmVUZXh0KGxpbmUpLndpZHRoO1xufVxuXG5mdW5jdGlvbiBidWlsZFdhdGVyZmFsbE9wdGlvbihcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBFQ2hhcnRzT3B0aW9uIHtcbiAgY29uc3QgY29uZmlnID0gY29tcG9uZW50LmNvbmZpZyBhcyBDaGFydENvbmZpZztcbiAgY29uc3Qgd2F0ZXJmYWxsID0gZXh0cmFjdFdhdGVyZmFsbChjb21wb25lbnQsIGRhdGEpO1xuICBjb25zdCBob3Jpem9udGFsID0gY29uZmlnLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCc7XG4gIGNvbnN0IGNhdGVnb3JpZXMgPSB3YXRlcmZhbGwuc3RlcHMubWFwKChzdGVwKSA9PiBzdGVwLmNhdGVnb3J5KTtcbiAgY29uc3QgY2F0ZWdvcnlBeGlzID0gY2F0ZWdvcnlBeGlzT3B0aW9uKGNvbmZpZywgZGF0YSwgY2F0ZWdvcmllcywgaG9yaXpvbnRhbCwgY29udGV4dC5sb2NhbGUpO1xuICAvLyBUaGUgb25lIG1lYXN1cmUncyBmb3JtYXQgd3JpdGVzIHRoZSBheGlzIGFuZCB0aGUgdG9vbHRpcC4gVGhlIGF4aXMgaGFzIHRvXG4gIC8vIHJlYWNoIHRoZSBmdXJ0aGVzdCBwb2ludCB0aGUgcnVubmluZyB0b3RhbCBnZXRzIHRvLCBvbiBlaXRoZXIgc2lkZSBvZlxuICAvLyB6ZXJvLCBvciB0aGUgZnVydGhlc3QgcmVmZXJlbmNlLlxuICBjb25zdCBzcGVjID0gY29uZmlnLm1lYXN1cmVzPy5bMF07XG4gIGNvbnN0IHJlZmVyZW5jZXMgPSBjaGFydFJlZmVyZW5jZXMoY29uZmlnLCBmYWxzZSk7XG4gIGNvbnN0IHZhbHVlQXhpcyA9IHZhbHVlQXhpc09wdGlvbihjb25maWcudmFsdWVBeGlzLCBob3Jpem9udGFsLCB2YWx1ZUF4aXNMYWJlbChyZXNvbHZlVmFsdWVBeGlzRm9ybWF0KFxuICAgIHNwZWMgJiYgaGFzTnVtYmVyRm9ybWF0KHNwZWMpID8gc3BlYyA6IG51bGwsXG4gICAgKCkgPT4gTWF0aC5tYXgocmVmZXJlbmNlUGVhayhyZWZlcmVuY2VzLCAwKSwgLi4ud2F0ZXJmYWxsLnN0ZXBzLm1hcCgoc3RlcCkgPT4gTWF0aC5hYnMoc3RlcC5zdGFydCArIChzdGVwLmNoYW5nZSA/PyAwKSkpKSxcbiAgICBjb250ZXh0LFxuICApLCBjb250ZXh0KSwgeyByZWFjaDogcmVmZXJlbmNlUmVhY2gocmVmZXJlbmNlcywgMCkgfSk7XG4gIC8vIE9uZSB2aXNpYmxlIHNlcmllcywgc28gdGhlIGxlZ2VuZCBpcyBoaWRkZW4gdW5sZXNzIHRoZSBjb25maWcgcGlucyBpdC5cbiAgY29uc3QgbGVnZW5kUG9zaXRpb24gPSByZXNvbHZlTGVnZW5kUG9zaXRpb24oY29uZmlnLCAxKTtcbiAgY29uc3QgZ3JhbnVsYXJpdHkgPSBidWNrZXRHcmFudWxhcml0eShkYXRhKTtcblxuICByZXR1cm4ge1xuICAgIGdyaWQ6IGF4aXNHcmlkKFxuICAgICAgbGVnZW5kUG9zaXRpb24sXG4gICAgICBjYXRlZ29yeVRpdGxlU2lkZShjb25maWcsIGhvcml6b250YWwpLFxuICAgICAgdmFsdWVUaXRsZVNpZGUoW2NvbmZpZy52YWx1ZUF4aXNdLCBob3Jpem9udGFsKSxcbiAgICApLFxuICAgIGxlZ2VuZDogeyAuLi5sZWdlbmRPcHRpb24obGVnZW5kUG9zaXRpb24pLCBkYXRhOiBbd2F0ZXJmYWxsLm5hbWVdIH0sXG4gICAgLy8gUGVyIGJhcjogdGhlIGludmlzaWJsZSBiYXNlIGlzIHNpbGVudCwgc28gb25seSBhIHN0ZXAgYW5zd2VycyB0aGUgaG92ZXIuXG4gICAgdG9vbHRpcDoge1xuICAgICAgdHJpZ2dlcjogJ2l0ZW0nLFxuICAgICAgZm9ybWF0dGVyOiAocGFyYW1zOiBUb29sdGlwQ29tcG9uZW50Rm9ybWF0dGVyQ2FsbGJhY2tQYXJhbXMpID0+IHdhdGVyZmFsbFRvb2x0aXAoXG4gICAgICAgIHdhdGVyZmFsbCxcbiAgICAgICAgKEFycmF5LmlzQXJyYXkocGFyYW1zKSA/IHBhcmFtc1swXSA6IHBhcmFtcykuZGF0YUluZGV4LFxuICAgICAgICBncmFudWxhcml0eSxcbiAgICAgICAgY2hhcnREYXRlTGFiZWwoY29uZmlnKSxcbiAgICAgICAgc3BlYyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICksXG4gICAgfSxcbiAgICB4QXhpczogaG9yaXpvbnRhbCA/IHZhbHVlQXhpcyA6IGNhdGVnb3J5QXhpcyxcbiAgICB5QXhpczogaG9yaXpvbnRhbCA/IGNhdGVnb3J5QXhpcyA6IHZhbHVlQXhpcyxcbiAgICBzZXJpZXM6IFsuLi53YXRlcmZhbGxTZXJpZXMod2F0ZXJmYWxsKSwgLi4ucmVmZXJlbmNlQ2FycmllcnMocmVmZXJlbmNlcywgY2F0ZWdvcmllcyldLFxuICB9O1xufVxuXG4vLyBBbiBpbnZpc2libGUgYmFzZSBzZXJpZXMgbGlmdHMgZWFjaCB2aXNpYmxlIGJhciB0byB3aGVyZSBpdHMgc3RlcCBzdGFydHMuXG4vLyBCb3RoIHN0YWNrIHdpdGggdGhlICdhbGwnIHN0cmF0ZWd5LCB3aGljaCBhZGRzIHNpZ25lZCB2YWx1ZXMgaW4gc2VyaWVzIG9yZGVyLFxuLy8gc28gYSBmYWxsIGRyYXdzIERPV04gZnJvbSB0aGUgdG90YWwgYmVmb3JlIGl0LCBldmVuIGFjcm9zcyB6ZXJvLiBUaGUgZGVmYXVsdFxuLy8gc2FtZS1zaWduIHN0YWNraW5nIHdvdWxkIGhhbmcgYSBuZWdhdGl2ZSBiYXIgYmVsb3cgdGhlIGF4aXMgaW5zdGVhZC5cbmZ1bmN0aW9uIHdhdGVyZmFsbFNlcmllcyh3YXRlcmZhbGw6IEV4dHJhY3RlZFdhdGVyZmFsbCk6IFNlcmllc09wdGlvbltdIHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0eXBlOiAnYmFyJyxcbiAgICAgIHN0YWNrOiAnd2F0ZXJmYWxsJyxcbiAgICAgIHN0YWNrU3RyYXRlZ3k6ICdhbGwnLFxuICAgICAgZGF0YTogd2F0ZXJmYWxsLnN0ZXBzLm1hcCgoc3RlcCkgPT4gc3RlcC5zdGFydCksXG4gICAgICBiYXJNYXhXaWR0aDogNDgsXG4gICAgICBpdGVtU3R5bGU6IHsgY29sb3I6ICd0cmFuc3BhcmVudCcgfSxcbiAgICAgIHNpbGVudDogdHJ1ZSxcbiAgICB9LFxuICAgIHtcbiAgICAgIG5hbWU6IHdhdGVyZmFsbC5uYW1lLFxuICAgICAgdHlwZTogJ2JhcicsXG4gICAgICBzdGFjazogJ3dhdGVyZmFsbCcsXG4gICAgICBzdGFja1N0cmF0ZWd5OiAnYWxsJyxcbiAgICAgIGJhck1heFdpZHRoOiA0OCxcbiAgICAgIC8vIFRoZSBzZXJpZXMgY29sb3IgaXMgdGhlIHJpc2UgY29sb3Igc28gYSBwaW5uZWQgbGVnZW5kIHNob3dzIGl0OyBlYWNoXG4gICAgICAvLyBiYXIgaXMgdGhlbiBjb2xvcmVkIGJ5IHdoYXQgaXQgZG9lcyB0byB0aGUgdG90YWwuXG4gICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGAjJHtSRVBPUlRfV0FURVJGQUxMX0NPTE9SUy5yaXNlfWAgfSxcbiAgICAgIGRhdGE6IHdhdGVyZmFsbC5zdGVwcy5tYXAoKHN0ZXApID0+ICh7XG4gICAgICAgIHZhbHVlOiBzdGVwLmNoYW5nZSxcbiAgICAgICAgaXRlbVN0eWxlOiB7IGNvbG9yOiBgIyR7UkVQT1JUX1dBVEVSRkFMTF9DT0xPUlNbc3RlcC5raW5kXX1gIH0sXG4gICAgICB9KSksXG4gICAgfSxcbiAgXTtcbn1cblxuLy8gQSBzdGVwJ3MgdG9vbHRpcDogaXRzIHBlcmlvZCwgaG93IGZhciBpdCBtb3ZlZCB0aGUgcnVubmluZyB0b3RhbCBhbmQgd2hlcmVcbi8vIHRoYXQgbGVmdCBpdC4gVGhlIGNsb3NpbmcgVG90YWwgc2hvd3MgdGhlIHRvdGFsIGFsb25lLiBUaGUgY2F0ZWdvcnkgYW5kIHRoZVxuLy8gbWVhc3VyZSBuYW1lIGNvbWUgZnJvbSB0aGUgZGF0YSBhbmQgdGhlIGNvbmZpZywgYW5kIEVDaGFydHMgc2V0cyB0aGUgdG9vbHRpcFxuLy8gYXMgSFRNTCwgc28gYm90aCBhcmUgZXNjYXBlZC4gUGVyaW9kcyBhbmQgYW1vdW50cyBhcmUgd3JpdHRlbiBpbiB0aGUgcmVwb3J0J3Ncbi8vIGxvY2FsZSwgYW1vdW50cyBpbiB0aGUgbWVhc3VyZSdzIG51bWJlciBmb3JtYXQgKGEgcGxhaW4gbnVtYmVyIHdpdGhvdXQgb25lKTtcbi8vIHRoZSB3b3JkcyAoJ1J1bm5pbmcgdG90YWwnKSBzdGF5IEVuZ2xpc2guXG5mdW5jdGlvbiB3YXRlcmZhbGxUb29sdGlwKFxuICB3YXRlcmZhbGw6IEV4dHJhY3RlZFdhdGVyZmFsbCxcbiAgaW5kZXg6IG51bWJlcixcbiAgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsLFxuICBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLFxuICBzcGVjOiBOdW1iZXJGb3JtYXRTcGVjIHwgdW5kZWZpbmVkLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RlcCA9IHdhdGVyZmFsbC5zdGVwc1tpbmRleF07XG4gIGNvbnN0IGNhdGVnb3J5ID0gZXNjYXBlSHRtbChncmFudWxhcml0eVxuICAgID8gZm9ybWF0UGVyaW9kTGFiZWwoc3RlcC5jYXRlZ29yeSwgZ3JhbnVsYXJpdHksIHRydWUsIGNvbnRleHQubG9jYWxlLCBkYXRlTGFiZWwpXG4gICAgOiBzdGVwLmNhdGVnb3J5KTtcbiAgY29uc3QgbmFtZSA9IGVzY2FwZUh0bWwod2F0ZXJmYWxsLm5hbWUpO1xuICBjb25zdCBhbW91bnQgPSAodmFsdWU6IG51bWJlciB8IG51bGwpID0+IGZvcm1hdE51bWJlcih2YWx1ZSwgc3BlYyA/PyB7fSwgY29udGV4dCk7XG5cbiAgaWYgKHN0ZXAua2luZCA9PT0gJ3RvdGFsJykge1xuICAgIHJldHVybiBgJHtjYXRlZ29yeX08YnIvPiR7bmFtZX06ICR7YW1vdW50KHN0ZXAuY2hhbmdlKX1gO1xuICB9XG5cbiAgY29uc3Qgc2lnbiA9IChzdGVwLmNoYW5nZSA/PyAwKSA+IDAgPyAnKycgOiAnJztcblxuICByZXR1cm4gYCR7Y2F0ZWdvcnl9PGJyLz4ke25hbWV9OiAke3NpZ259JHthbW91bnQoc3RlcC5jaGFuZ2UpfWBcbiAgICArIGA8YnIvPlJ1bm5pbmcgdG90YWw6ICR7YW1vdW50KHN0ZXAuc3RhcnQgKyAoc3RlcC5jaGFuZ2UgPz8gMCkpfWA7XG59XG5cbi8vIERlZmF1bHQgbGVnZW5kIHBsYWNlbWVudCB3aGVuIHRoZSBjb25maWcgZG9lc24ndCBwaW4gb25lOiBwaWUgY2hhcnRzIHJlYWRcbi8vIGJlc3Qgd2l0aCB0aGUgc2xpY2Uga2V5IGJlc2lkZSB0aGVtIChyaWdodCk7IGF4aXMgY2hhcnRzIG9ubHkgbmVlZCBhIGxlZ2VuZFxuLy8gdG8gdGVsbCBtdWx0aXBsZSBzZXJpZXMgYXBhcnQsIHNvIGEgc2luZ2xlLXNlcmllcyBjaGFydCBoaWRlcyBpdC4gQW4gZXhwbGljaXRcbi8vIGNvbmZpZy5sZWdlbmQgKGluY2x1ZGluZyAnaGlkZGVuJykgYWx3YXlzIHdpbnMuIFNoYXJlZCB3aXRoIHRoZSBQb3dlclBvaW50XG4vLyBleHBvcnQgc28gYm90aCBtZWRpYSBwbGFjZSB0aGUgbGVnZW5kIGlkZW50aWNhbGx5LlxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVMZWdlbmRQb3NpdGlvbihjb25maWc6IENoYXJ0Q29uZmlnLCBzZXJpZXNDb3VudDogbnVtYmVyLCBjb2xvckJ5ID0gZmFsc2UpOiBMZWdlbmRQb3NpdGlvbiB7XG4gIGlmIChjb25maWcubGVnZW5kKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5sZWdlbmQ7XG4gIH1cblxuICBjb25zdCBwaWUgPSBjb25maWcuY2hhcnRUeXBlID09PSAncGllJyB8fCBjb25maWcuY2hhcnRUeXBlID09PSAnZG9udXQnO1xuXG4gIC8vIGNvbG9yQnkgbWFwcyBlYWNoIGJhcidzIGNvbG9yIHRvIGl0cyBjYXRlZ29yeSwgc28gaXQgbmVlZHMgYSBsZWdlbmQgZXZlblxuICAvLyB0aG91Z2ggaXQncyBhIHNpbmdsZSBtZWFzdXJlLlxuICByZXR1cm4gcGllIHx8IGNvbG9yQnkgfHwgc2VyaWVzQ291bnQgPiAxID8gKHBpZSA/ICdyaWdodCcgOiAndG9wJykgOiAnaGlkZGVuJztcbn1cblxuZnVuY3Rpb24gbGVnZW5kT3B0aW9uKHBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbik6IExlZ2VuZENvbXBvbmVudE9wdGlvbiB7XG4gIGlmIChwb3NpdGlvbiA9PT0gJ2hpZGRlbicpIHtcbiAgICByZXR1cm4geyBzaG93OiBmYWxzZSB9O1xuICB9XG5cbiAgY29uc3QgYmFzZTogTGVnZW5kQ29tcG9uZW50T3B0aW9uID0geyB0eXBlOiAnc2Nyb2xsJyB9O1xuXG4gIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICBjYXNlICdib3R0b20nOlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgYm90dG9tOiAwIH07XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBvcmllbnQ6ICd2ZXJ0aWNhbCcsIGxlZnQ6IDAsIHRvcDogJ21pZGRsZScgfTtcbiAgICBjYXNlICdyaWdodCc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBvcmllbnQ6ICd2ZXJ0aWNhbCcsIHJpZ2h0OiAwLCB0b3A6ICdtaWRkbGUnIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIHRvcDogMCB9O1xuICB9XG59XG5cbi8vIFRoZSBwbG90J3MgZ3JpZDogcm9vbSBvbiB0aGUgbGVnZW5kJ3Mgc2lkZSBzbyBpdCBuZXZlciBvdmVybGFwcyB0aGVcbi8vIGJhcnMvbGluZXMsIHBsdXMgcm9vbSBmb3IgdGhlIGNhdGVnb3J5IGFuZCB2YWx1ZSBheGVzJyB0aXRsZXMgb24gdGhlaXJcbi8vIHNpZGVzLCB3aGljaCBjb250YWluTGFiZWwgZG9lcyBub3QgcmVzZXJ2ZSAoaXQgY292ZXJzIHRoZSB0aWNrIGxhYmVscyBvbmx5KS5cbmZ1bmN0aW9uIGF4aXNHcmlkKFxuICBwb3NpdGlvbjogTGVnZW5kUG9zaXRpb24sXG4gIGNhdGVnb3J5VGl0bGU6IEF4aXNUaXRsZVNpZGUgfCBudWxsLFxuICB2YWx1ZVRpdGxlOiBBeGlzVGl0bGVTaWRlIHwgbnVsbCxcbik6IEVDaGFydHNPcHRpb25bJ2dyaWQnXSB7XG4gIHJldHVybiBbY2F0ZWdvcnlUaXRsZSwgdmFsdWVUaXRsZV0ucmVkdWNlPEF4aXNHcmlkUm9vbT4oXG4gICAgKGdyaWQsIHNpZGUpID0+IChzaWRlID8geyAuLi5ncmlkLCBbc2lkZV06IGdyaWRbc2lkZV0gKyBBWElTX05BTUVfUk9PTSB9IDogZ3JpZCksXG4gICAgbGVnZW5kR3JpZChwb3NpdGlvbiksXG4gICk7XG59XG5cbi8vIFBsb3QtZWRnZSByb29tIG9uIHdoaWNoZXZlciBzaWRlIHRoZSBsZWdlbmQgb2NjdXBpZXM7IGNvbnRhaW5MYWJlbCBrZWVwcyB0aGVcbi8vIHRpY2sgbGFiZWxzIGluc2lkZSB3aGF0IGlzIGxlZnQuXG5mdW5jdGlvbiBsZWdlbmRHcmlkKHBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbik6IEF4aXNHcmlkUm9vbSB7XG4gIGNvbnN0IGJhc2U6IEF4aXNHcmlkUm9vbSA9IHsgbGVmdDogOCwgcmlnaHQ6IDE2LCB0b3A6IDgsIGJvdHRvbTogOCwgY29udGFpbkxhYmVsOiB0cnVlIH07XG5cbiAgc3dpdGNoIChwb3NpdGlvbikge1xuICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBib3R0b206IDMyIH07XG4gICAgY2FzZSAnbGVmdCc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBsZWZ0OiA5NiB9O1xuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIHJpZ2h0OiA5NiB9O1xuICAgIGNhc2UgJ2hpZGRlbic6XG4gICAgICByZXR1cm4gYmFzZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgdG9wOiAzMiB9O1xuICB9XG59XG5cbi8vIFRoZSBzdGFjayBhIHN0YWNrZWQgc2VyaWVzIGpvaW5zLiBPbiBhIHR3by1heGlzIGNoYXJ0IChheGlzSW5kZXggc2V0KSBlYWNoXG4vLyB0eXBlIHN0YWNrcyBwZXIgYXhpczsgb3RoZXJ3aXNlIGEgY29tYm8gc3RhY2tzIHBlciB0eXBlIGFuZCBhIHNpbmdsZS10eXBlXG4vLyBjaGFydCBzdGFja3MgZXZlcnl0aGluZyB0b2dldGhlci5cbmZ1bmN0aW9uIHN0YWNrS2V5KHR5cGU6IEF4aXNDaGFydFR5cGUsIGNvbWJvOiBib29sZWFuLCBheGlzSW5kZXg6IFZhbHVlQXhpc0luZGV4IHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgaWYgKGF4aXNJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGB0b3RhbC0ke3R5cGV9LSR7YXhpc0luZGV4fWA7XG4gIH1cblxuICByZXR1cm4gY29tYm8gPyBgdG90YWwtJHt0eXBlfWAgOiAndG90YWwnO1xufVxuXG4vLyBIb3cgYnVpbGRTZXJpZXMgZHJhd3Mgb25lIHNlcmllczogaXRzIGRyYXduIHR5cGUsIHRoZSBzdGFjayBpdCBqb2lucywgd2hldGhlclxuLy8gaXQgbGF5cyB0aGUgY29sb3JCeSBvdmVybGFwLCB3aGV0aGVyIHRoZSBjaGFydCBpcyBhIGNvbWJvLCBpdHMgdG9vbHRpcCwgaXRzXG4vLyB2YWx1ZSBheGlzIG9uIGEgdHdvLWF4aXMgY2hhcnQsIGl0cyBvd24gQ1NTIGNvbG9yICh1bmRlZmluZWQgbGVhdmVzIGl0IHRvXG4vLyB0aGUgdGhlbWUncyBwYWxldHRlIGJ5IHBvc2l0aW9uKSwgYW5kIGl0cyBkYXRhIGxhYmVscyAobnVsbCBwcmludHMgbm9uZSkuXG5pbnRlcmZhY2UgU2VyaWVzTGF5b3V0IHtcbiAgdHlwZTogQXhpc0NoYXJ0VHlwZTtcbiAgc3RhY2s6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgb3ZlcmxhcDogYm9vbGVhbjtcbiAgY29tYm86IGJvb2xlYW47XG4gIHRvb2x0aXA6IFNlcmllc1Rvb2x0aXA7XG4gIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXggfCB1bmRlZmluZWQ7XG4gIGNvbG9yOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxhYmVsczogU2VyaWVzRGF0YUxhYmVscyB8IG51bGw7XG59XG5cbi8vIE9uZSBzZXJpZXMgb2YgYW4gYXhpcyBjaGFydC4gQSBtZWFzdXJlJ3MgZGlzcGxheSBrZXlzIG9ubHkgYWRkIHdoYXQgdGhleVxuLy8gY2hhbmdlLCBzbyBhIHNlcmllcyB0aGF0IHNldHMgbm9uZSBpcyBkcmF3biBieSB0aGUgdGhlbWUgYXMgYmVmb3JlOiBpdHMgb3duXG4vLyBjb2xvciAodGhlIGJhciwgdGhlIGxpbmUsIHRoZSBhcmVhIHVuZGVyIGl0IGFuZCBpdHMgbGVnZW5kIGtleSBhbGwgZm9sbG93XG4vLyBpdGVtU3R5bGUpLCBpdHMgbGluZSBzdHlsZSBhbmQgaXRzIG1hcmtlcnMsIHNob3duIG9uIGV2ZXJ5IHBvaW50IHVubGVzc1xuLy8gbWFya2VycyBpcyBmYWxzZS4gRGF0YSBsYWJlbHMgY29tZSBsYXN0LCBvbiB0aGUgc2VyaWVzIG9yIG9uIGl0cyBsYXRlc3Rcbi8vIHBvaW50LlxuZnVuY3Rpb24gYnVpbGRTZXJpZXMoXG4gIHNlcmllczogRXh0cmFjdGVkQ2hhcnRTZXJpZXNJdGVtLFxuICB2YWx1ZXM6IChudW1iZXIgfCBudWxsIHwgU2hhcmVEYXRhSXRlbSlbXSxcbiAgbGF5b3V0OiBTZXJpZXNMYXlvdXQsXG4pOiBTZXJpZXNPcHRpb24ge1xuICAvLyBPbiBhIHR3by1heGlzIGNoYXJ0IGV2ZXJ5IHNlcmllcyBuYW1lcyBpdHMgdmFsdWUgYXhpcy5cbiAgY29uc3QgYXhpcyA9IGxheW91dC5heGlzSW5kZXggPT09IHVuZGVmaW5lZCA/IHt9IDogeyB5QXhpc0luZGV4OiBsYXlvdXQuYXhpc0luZGV4IH07XG4gIGNvbnN0IGNvbG9yID0gbGF5b3V0LmNvbG9yO1xuICBjb25zdCBpdGVtU3R5bGUgPSBjb2xvciA/IHsgaXRlbVN0eWxlOiB7IGNvbG9yIH0gfSA6IHt9O1xuXG4gIGlmIChsYXlvdXQudHlwZSA9PT0gJ2JhcicpIHtcbiAgICAvLyAnb3V0c2lkZScgZm9sbG93cyBlYWNoIGJhcidzIHNpZ246IHBhc3QgYSBwb3NpdGl2ZSBiYXIncyBlbmQgYW5kIGJlbG93XG4gICAgLy8gKG9yIGxlZnQgb2YpIGEgbmVnYXRpdmUgb25lJ3MsIHdoZXJlICd0b3AnIHdvdWxkIHNpdCBhdCB0aGUgemVybyBsaW5lLlxuICAgIGNvbnN0IHsgc2VyaWVzOiBsYWJlbHMsIGRhdGEgfSA9IHBsYWNlRGF0YUxhYmVscyhsYXlvdXQubGFiZWxzLCBsYXlvdXQuc3RhY2sgPyAnaW5zaWRlJyA6ICdvdXRzaWRlJywgdmFsdWVzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBzZXJpZXMubmFtZSxcbiAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgZGF0YSxcbiAgICAgIHN0YWNrOiBsYXlvdXQuc3RhY2ssXG4gICAgICB0b29sdGlwOiBsYXlvdXQudG9vbHRpcCxcbiAgICAgIC4uLmF4aXMsXG4gICAgICAuLi5pdGVtU3R5bGUsXG4gICAgICBiYXJNYXhXaWR0aDogNDgsXG4gICAgICAvLyBjb2xvckJ5OiBvdmVybGFwIHRoZSBwZXItY2F0ZWdvcnkgc2VyaWVzIHNvIGVhY2ggYmFyIHJlbmRlcnMgZnVsbC13aWR0aC5cbiAgICAgIC4uLihsYXlvdXQub3ZlcmxhcCA/IHsgYmFyR2FwOiAnLTEwMCUnLCBiYXJDYXRlZ29yeUdhcDogJzIwJScgfSA6IHt9KSxcbiAgICAgIC4uLmxhYmVscyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgbGluZVR5cGUgPSBtZWFzdXJlTGluZVN0eWxlKHNlcmllcy5tZWFzdXJlKTtcbiAgY29uc3QgbGluZVN0eWxlID0gY29sb3IgfHwgbGluZVR5cGVcbiAgICA/IHsgbGluZVN0eWxlOiB7IC4uLihjb2xvciA/IHsgY29sb3IgfSA6IHt9KSwgLi4uKGxpbmVUeXBlID8geyB0eXBlOiBsaW5lVHlwZSB9IDoge30pIH0gfVxuICAgIDoge307XG4gIGNvbnN0IHsgc2VyaWVzOiBsYWJlbHMsIGRhdGEgfSA9IHBsYWNlRGF0YUxhYmVscyhsYXlvdXQubGFiZWxzLCAndG9wJywgdmFsdWVzKTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6IHNlcmllcy5uYW1lLFxuICAgIHR5cGU6ICdsaW5lJyxcbiAgICBkYXRhLFxuICAgIHN0YWNrOiBsYXlvdXQuc3RhY2ssXG4gICAgdG9vbHRpcDogbGF5b3V0LnRvb2x0aXAsXG4gICAgLi4uYXhpcyxcbiAgICAuLi5pdGVtU3R5bGUsXG4gICAgLi4ubGluZVN0eWxlLFxuICAgIC4uLihzZXJpZXMubWVhc3VyZS5tYXJrZXJzID09PSBmYWxzZSA/IHsgc2hvd1N5bWJvbDogZmFsc2UgfSA6IHt9KSxcbiAgICBzbW9vdGg6IHRydWUsXG4gICAgc3ltYm9sU2l6ZTogNixcbiAgICBhcmVhU3R5bGU6IGxheW91dC50eXBlID09PSAnYXJlYScgPyB7IG9wYWNpdHk6IDAuMjUgfSA6IHVuZGVmaW5lZCxcbiAgICAvLyBJbiBhIGNvbWJvIHRoZSBsaW5lIGlzIGRyYXduIG92ZXIgdGhlIGJhcnMgd2hhdGV2ZXIgb3JkZXIgdGhlIG1lYXN1cmVzXG4gICAgLy8gY29tZSBpbjsgYXQgdGhlIHNhbWUgeiBhIGxhdGVyIGJhciBzZXJpZXMgd291bGQgcGFpbnQgYWNyb3NzIGl0LlxuICAgIC4uLihsYXlvdXQuY29tYm8gPyB7IHo6IDMgfSA6IHt9KSxcbiAgICAuLi5sYWJlbHMsXG4gIH07XG59XG5cbi8vIEEgMTAwJSBzdGFja2VkIHNlcmllcycgcG9pbnRzOiBlYWNoIHNoYXJlLCBwbG90dGVkIGFuZCBzdGFja2VkLCB3aXRoIHRoZVxuLy8gdmFsdWUgaXQgY2FtZSBmcm9tLlxuZnVuY3Rpb24gc2hhcmVEYXRhKHZhbHVlczogKG51bWJlciB8IG51bGwpW10sIHNoYXJlczogKG51bWJlciB8IG51bGwpW10pOiBTaGFyZURhdGFJdGVtW10ge1xuICByZXR1cm4gdmFsdWVzLm1hcCgocmF3LCBpbmRleCkgPT4gKHsgdmFsdWU6IHNoYXJlc1tpbmRleF0gPz8gbnVsbCwgcmF3IH0pKTtcbn1cblxuLy8gV2hhdCBhIHNlcmllcyBwcmludHMgYmVzaWRlIGl0cyBwb2ludHMgKEEyIGRhdGEgbGFiZWxzKTogZXZlcnkgcG9pbnRcbi8vICgnYWxsJyksIGV2ZXJ5IHBvaW50IHdob3NlIGxhYmVsIGZpdHMgd2l0aG91dCBvdmVybGFwcGluZyBhbm90aGVyICgnYXV0bycsXG4vLyBMYWJlbExheW91dCdzIGhpZGVPdmVybGFwKSwgb3Igb25seSBpdHMgbGF0ZXN0IHBvaW50ICgnbGFzdCcpLiBub25lLCBhblxuLy8gYWJzZW50IG1vZGUgb3Igb25lIHRoZSB2aWV3ZXIgZG9lcyBub3Qga25vdyBwcmludHMgbm90aGluZywgYW5kIHRoZSBzZXJpZXNcbi8vIGlzIGxlZnQgYXMgaXQgd2FzLiBBIGNvbG9yQnkgY2hhcnQncyBzZXJpZXMgZWFjaCBob2xkIG9uZSBiYXIsIHNvICdsYXN0J1xuLy8gbGFiZWxzIGV2ZXJ5IGJhciB0aGVyZSwgYXMgJ2FsbCcgZG9lcy5cbi8vXG4vLyBXaGVyZSB0aGUgbGFiZWwgc2l0cyBkZXBlbmRzIG9uIHdoYXQgdGhlIHNlcmllcyBkcmF3cywgc28gYnVpbGRTZXJpZXNcbi8vIHBsYWNlcyBpdCAocGxhY2VEYXRhTGFiZWxzKS5cbmV4cG9ydCBmdW5jdGlvbiBkYXRhTGFiZWxPcHRpb24oXG4gIG1vZGU6IFJlcG9ydENoYXJ0RGF0YUxhYmVscyB8IHVuZGVmaW5lZCxcbiAgZm9ybWF0dGVyOiBEYXRhTGFiZWxGb3JtYXR0ZXIsXG4pOiBTZXJpZXNEYXRhTGFiZWxzIHwgbnVsbCB7XG4gIGNvbnN0IHRleHQgPSB7IHNob3c6IHRydWUgYXMgY29uc3QsIGZvbnRTaXplOiBSRVBPUlRfREFUQV9MQUJFTF9GT05UX1NJWkUsIGZvcm1hdHRlciB9O1xuXG4gIHN3aXRjaCAobW9kZSkge1xuICAgIGNhc2UgUmVwb3J0Q2hhcnREYXRhTGFiZWxzLkFsbDpcbiAgICAgIHJldHVybiB7IHRleHQsIGhpZGVPdmVybGFwOiBmYWxzZSwgbGFzdE9ubHk6IGZhbHNlIH07XG4gICAgY2FzZSBSZXBvcnRDaGFydERhdGFMYWJlbHMuQXV0bzpcbiAgICAgIHJldHVybiB7IHRleHQsIGhpZGVPdmVybGFwOiB0cnVlLCBsYXN0T25seTogZmFsc2UgfTtcbiAgICBjYXNlIFJlcG9ydENoYXJ0RGF0YUxhYmVscy5MYXN0OlxuICAgICAgcmV0dXJuIHsgdGV4dCwgaGlkZU92ZXJsYXA6IGZhbHNlLCBsYXN0T25seTogdHJ1ZSB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vLyBBIHNlcmllcycgZGF0YSBsYWJlbHMgYXQgYHBvc2l0aW9uYDogb24gdGhlIHNlcmllcyAoJ2FsbCcsIGFuZCB3aXRoIHRoZVxuLy8gb3ZlcmxhcCBoaWRpbmcgJ2F1dG8nKSwgb3Igb24gaXRzIGxhdGVzdCBub24tZW1wdHkgcG9pbnQgYWxvbmUgKCdsYXN0JykuXG4vLyBObyBsYWJlbHMgbGVhdmUgdGhlIHNlcmllcyBhbmQgaXRzIHBvaW50cyBhcyB0aGV5IHdlcmUuXG5mdW5jdGlvbiBwbGFjZURhdGFMYWJlbHM8UCBleHRlbmRzIERhdGFMYWJlbFBvc2l0aW9uPihcbiAgbGFiZWxzOiBTZXJpZXNEYXRhTGFiZWxzIHwgbnVsbCxcbiAgcG9zaXRpb246IFAsXG4gIHZhbHVlczogKG51bWJlciB8IG51bGwgfCBTaGFyZURhdGFJdGVtKVtdLFxuKTogUGxhY2VkRGF0YUxhYmVsczxQPiB7XG4gIGlmICghbGFiZWxzKSB7XG4gICAgcmV0dXJuIHsgc2VyaWVzOiB7fSwgZGF0YTogdmFsdWVzIH07XG4gIH1cblxuICBjb25zdCBsYWJlbDogRGF0YUxhYmVsPFA+ID0geyAuLi5sYWJlbHMudGV4dCwgcG9zaXRpb24gfTtcblxuICBpZiAobGFiZWxzLmxhc3RPbmx5KSB7XG4gICAgcmV0dXJuIHsgc2VyaWVzOiB7fSwgZGF0YTogbGFiZWxMYXN0UG9pbnQodmFsdWVzLCBsYWJlbCkgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc2VyaWVzOiB7IGxhYmVsLCAuLi4obGFiZWxzLmhpZGVPdmVybGFwID8geyBsYWJlbExheW91dDogeyBoaWRlT3ZlcmxhcDogdHJ1ZSB9IH0gOiB7fSkgfSxcbiAgICBkYXRhOiB2YWx1ZXMsXG4gIH07XG59XG5cbi8vIEEgc2VyaWVzJyBwb2ludHMgd2l0aCBpdHMgbGF0ZXN0IG5vbi1lbXB0eSBwb2ludCBjYXJyeWluZyB0aGUgbGFiZWwuIEFcbi8vIHNlcmllcyB3aXRoIG5vIHZhbHVlIGFueXdoZXJlIGlzIGxlZnQgYXMgaXQgd2FzLlxuZnVuY3Rpb24gbGFiZWxMYXN0UG9pbnQ8UCBleHRlbmRzIERhdGFMYWJlbFBvc2l0aW9uPihcbiAgdmFsdWVzOiAobnVtYmVyIHwgbnVsbCB8IFNoYXJlRGF0YUl0ZW0pW10sXG4gIGxhYmVsOiBEYXRhTGFiZWw8UD4sXG4pOiBTZXJpZXNEYXRhSXRlbTxQPltdIHtcbiAgY29uc3QgbGFzdCA9IHZhbHVlcy5yZWR1Y2U8bnVtYmVyPigoZm91bmQsIGl0ZW0sIGluZGV4KSA9PiAocG9pbnRWYWx1ZShpdGVtKSA9PT0gbnVsbCA/IGZvdW5kIDogaW5kZXgpLCAtMSk7XG5cbiAgcmV0dXJuIHZhbHVlcy5tYXAoKGl0ZW0sIGluZGV4KTogU2VyaWVzRGF0YUl0ZW08UD4gPT4ge1xuICAgIGlmIChpbmRleCAhPT0gbGFzdCkge1xuICAgICAgcmV0dXJuIGl0ZW07XG4gICAgfVxuXG4gICAgcmV0dXJuIGlzU2hhcmVEYXRhSXRlbShpdGVtKSA/IHsgLi4uaXRlbSwgbGFiZWwgfSA6IHsgdmFsdWU6IGl0ZW0sIGxhYmVsIH07XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc1NoYXJlRGF0YUl0ZW0oaXRlbTogbnVtYmVyIHwgbnVsbCB8IFNoYXJlRGF0YUl0ZW0pOiBpdGVtIGlzIFNoYXJlRGF0YUl0ZW0ge1xuICByZXR1cm4gaXRlbSAhPT0gbnVsbCAmJiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCc7XG59XG5cbi8vIEhvdyBhIHNlcmllcycgZGF0YSBsYWJlbHMgd3JpdGUgYSB2YWx1ZS4gQSAxMDAlIHN0YWNrZWQgc2VyaWVzIHByaW50cyBpdHNcbi8vIHNoYXJlIGFzIGEgd2hvbGUgcGVyY2VudGFnZSwgYXMgdGhlIHNoYXJlIGF4aXMncyB0aWNrcyBkby4gQSBzZXJpZXMgb24gYW5cbi8vIGF4aXMgd2l0aCBhIG51bWJlciBmb3JtYXQgcHJpbnRzIGl0cyB2YWx1ZSBpbiBpdHMgbWVhc3VyZSdzIGZvcm1hdCwgYXQgdGhlXG4vLyB1bml0cyBhbmQgZGVjaW1hbHMgdGhlIGF4aXMgZGVjaWRlZCwgc28gYSBsYWJlbCByZWFkcyBsaWtlIHRoZSB0aWNrcyBiZXNpZGVcbi8vIGl0LiBBbnkgb3RoZXIgcHJpbnRzIHRoZSBwbGFpbiBsb2NhbGUtZ3JvdXBlZCBudW1iZXIgaXRzIHRvb2x0aXAgc2hvd3MuIEFcbi8vIHNoYXJlIHBvaW50J3MgcmF3IHZhbHVlIGlzIHdoYXQgYSBsYWJlbCByZWFkcyB3aGVuIGl0IGNhcnJpZXMgb25lLlxuZnVuY3Rpb24gZGF0YUxhYmVsRm9ybWF0dGVyKFxuICBtZWFzdXJlOiBDaGFydE1lYXN1cmUsXG4gIGF4aXNGb3JtYXQ6IFZhbHVlQXhpc0Zvcm1hdCB8IG51bGwsXG4gIHNoYXJlOiBib29sZWFuLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogRGF0YUxhYmVsRm9ybWF0dGVyIHtcbiAgaWYgKHNoYXJlKSB7XG4gICAgY29uc3QgcGVyY2VudCA9IHdob2xlUGVyY2VudEZvcm1hdHRlcihjb250ZXh0KTtcblxuICAgIHJldHVybiAocGFyYW1zKSA9PiBwZXJjZW50KHBhcmFtcy52YWx1ZSk7XG4gIH1cblxuICBpZiAoYXhpc0Zvcm1hdCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7IHVuaXRzOiBheGlzRm9ybWF0LmNoYXJ0LnVuaXRzLCBkZWNpbWFsczogYXhpc0Zvcm1hdC5jaGFydC5kZWNpbWFscyB9O1xuXG4gICAgcmV0dXJuIChwYXJhbXMpID0+IGZvcm1hdE51bWJlcihkYXRhTGFiZWxWYWx1ZShwYXJhbXMpLCBtZWFzdXJlLCBjb250ZXh0LCBvcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAocGFyYW1zKSA9PiBmb3JtYXRQbGFpbk51bWJlcihkYXRhTGFiZWxWYWx1ZShwYXJhbXMpLCBjb250ZXh0LmxvY2FsZSk7XG59XG5cbi8vIFRoZSB2YWx1ZSBhIGRhdGEgbGFiZWwgd3JpdGVzOiB0aGUgcmF3IHZhbHVlIGl0cyBwb2ludCBjYXJyaWVzLCBlbHNlIHRoZVxuLy8gcGxvdHRlZCBvbmUuXG5mdW5jdGlvbiBkYXRhTGFiZWxWYWx1ZShwYXJhbXM6IERhdGFMYWJlbFBhcmFtcyk6IHVua25vd24ge1xuICBjb25zdCBkYXRhID0gcGFyYW1zLmRhdGE7XG4gIGNvbnN0IHJhdyA9IGRhdGEgIT09IG51bGwgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnID8gKGRhdGEgYXMgeyByYXc/OiB1bmtub3duIH0pLnJhdyA6IHVuZGVmaW5lZDtcblxuICByZXR1cm4gcmF3ID8/IHBhcmFtcy52YWx1ZTtcbn1cblxuLy8gQSAxMDAlIHN0YWNrZWQgY2hhcnQncyB0b29sdGlwOiB0aGUgY2F0ZWdvcnksIHRoZW4gZWFjaCBzZXJpZXMgb24gaXRzIG93blxuLy8gbGluZSwgYSBzaGFyZSBhcyBpdHMgcGVyY2VudGFnZSB0byBvbmUgZGVjaW1hbCBmb2xsb3dlZCBieSB0aGUgdmFsdWUgaXQgY2FtZVxuLy8gZnJvbSBpbiBpdHMgbWVhc3VyZSdzIGZvcm1hdCAoJzI1LjAlICgxKScpLCBhbmQgYW55IG90aGVyIHNlcmllcyBieSBpdHMgb3duXG4vLyB2YWx1ZS4gVGhlIGNhdGVnb3J5IGFuZCB0aGUgc2VyaWVzIG5hbWVzIGNvbWUgZnJvbSB0aGUgZGF0YSBhbmQgdGhlIGNvbmZpZyxcbi8vIGFuZCBFQ2hhcnRzIHNldHMgdGhlIHRvb2x0aXAgYXMgSFRNTCwgc28gYm90aCBhcmUgZXNjYXBlZC5cbmZ1bmN0aW9uIHBlcmNlbnRUb29sdGlwKFxuICBwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcyxcbiAgZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcyxcbiAgc2hhcmVzOiBQZXJjZW50U2hhcmVzLFxuICBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwsXG4gIGRhdGVMYWJlbDogUmVwb3J0Q2hhcnREYXRlTGFiZWwsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBzdHJpbmcge1xuICBjb25zdCBpdGVtcyA9IEFycmF5LmlzQXJyYXkocGFyYW1zKSA/IHBhcmFtcyA6IFtwYXJhbXNdO1xuICBjb25zdCBkYXRhSW5kZXggPSBpdGVtc1swXT8uZGF0YUluZGV4ID8/IDA7XG4gIGNvbnN0IGNhdGVnb3J5ID0gZXh0cmFjdGVkLmNhdGVnb3JpZXNbZGF0YUluZGV4XSA/PyAnJztcbiAgY29uc3QgaGVhZGluZyA9IGVzY2FwZUh0bWwoZ3JhbnVsYXJpdHlcbiAgICA/IGZvcm1hdFBlcmlvZExhYmVsKGNhdGVnb3J5LCBncmFudWxhcml0eSwgdHJ1ZSwgY29udGV4dC5sb2NhbGUsIGRhdGVMYWJlbClcbiAgICA6IGNhdGVnb3J5KTtcbiAgY29uc3QgcmF0aW9Db250ZXh0ID0geyAuLi5jb250ZXh0LCByYXRpb1BlcmNlbnQ6IHRydWUgfTtcblxuICBjb25zdCBsaW5lcyA9IGl0ZW1zLm1hcCgoaXRlbSkgPT4ge1xuICAgIGNvbnN0IHNlcmllcyA9IGV4dHJhY3RlZC5zZXJpZXNbaXRlbS5zZXJpZXNJbmRleCA/PyAtMV07XG4gICAgY29uc3QgbWFya2VyID0gdHlwZW9mIGl0ZW0ubWFya2VyID09PSAnc3RyaW5nJyA/IGl0ZW0ubWFya2VyIDogJyc7XG4gICAgY29uc3QgbGFiZWwgPSBgJHttYXJrZXJ9ICR7ZXNjYXBlSHRtbChpdGVtLnNlcmllc05hbWUgPz8gc2VyaWVzPy5uYW1lID8/ICcnKX1gO1xuICAgIGNvbnN0IHZhbHVlID0gc2VyaWVzVG9vbHRpcChzZXJpZXM/Lm1lYXN1cmUsIGNvbnRleHQpLnZhbHVlRm9ybWF0dGVyKHNlcmllcz8udmFsdWVzW2l0ZW0uZGF0YUluZGV4XSA/PyBudWxsKTtcbiAgICBjb25zdCBzaGFyZSA9IHNoYXJlcy5nZXQoaXRlbS5zZXJpZXNJbmRleCA/PyAtMSk/LltpdGVtLmRhdGFJbmRleF0gPz8gbnVsbDtcblxuICAgIHJldHVybiBzaGFyZSA9PT0gbnVsbFxuICAgICAgPyBgJHtsYWJlbH06ICR7dmFsdWV9YFxuICAgICAgOiBgJHtsYWJlbH06ICR7Zm9ybWF0TnVtYmVyKHNoYXJlLCBQRVJDRU5UX1NIQVJFX0ZPUk1BVCwgcmF0aW9Db250ZXh0KX0gKCR7dmFsdWV9KWA7XG4gIH0pO1xuXG4gIHJldHVybiBbaGVhZGluZywgLi4ubGluZXNdLmpvaW4oJzxici8+Jyk7XG59XG5cbi8vIEEgdmFsdWUgYXhpczogaXRzIHRpdGxlIGFuZCByYW5nZSBmcm9tIHRoZSBjb25maWcsIGl0cyB0aWNrIGxhYmVscyBmcm9tXG4vLyB2YWx1ZUF4aXNMYWJlbC4gQSB2ZXJ0aWNhbCBjaGFydCdzIHRpdGxlIHNpdHMgYWJvdmUgdGhlIGF4aXMgbGluZSwgcmVhZGluZ1xuLy8gYXdheSBmcm9tIHRoZSBwbG90J3MgZWRnZTsgYSBob3Jpem9udGFsIGNoYXJ0J3MgaXMgY2VudGVyZWQgYmVsb3cgdGhlIHRpY2tzLlxuLy8gQSBib3VuZCBvciBpbnRlcnZhbCB0aGF0IGlzIG5vdCBhIHVzYWJsZSBudW1iZXIgaXMgbGVmdCB0byBFQ2hhcnRzLiBBIDEwMCVcbi8vIHN0YWNrZWQgY2hhcnQncyBzaGFyZSBheGlzIChleHRyYXMucGVyY2VudE1pbikgaGFzIGl0cyBvd24gZml4ZWQgcmFuZ2UuXG5mdW5jdGlvbiB2YWx1ZUF4aXNPcHRpb24oXG4gIGF4aXM6IENoYXJ0VmFsdWVBeGlzIHwgdW5kZWZpbmVkLFxuICBob3Jpem9udGFsOiBib29sZWFuLFxuICBheGlzTGFiZWw6IFZhbHVlQXhpc0xhYmVsLFxuICBleHRyYXM6IFZhbHVlQXhpc0V4dHJhcyA9IHt9LFxuKSB7XG4gIGNvbnN0IHJhbmdlID0gZXh0cmFzLnBlcmNlbnRNaW4gPT09IHVuZGVmaW5lZFxuICAgID8gdmFsdWVBeGlzUmFuZ2UoYXhpcylcbiAgICA6IHsgbWluOiBleHRyYXMucGVyY2VudE1pbiwgbWF4OiBQRVJDRU5UX0FYSVNfTUFYLCBpbnRlcnZhbDogUEVSQ0VOVF9BWElTX0lOVEVSVkFMIH07XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAndmFsdWUnIGFzIGNvbnN0LFxuICAgIG5hbWU6IGF4aXM/LmxhYmVsIHx8IHVuZGVmaW5lZCxcbiAgICBuYW1lTG9jYXRpb246IGhvcml6b250YWwgPyAnbWlkZGxlJyBhcyBjb25zdCA6ICdlbmQnIGFzIGNvbnN0LFxuICAgIG5hbWVHYXA6IGhvcml6b250YWwgPyAyOCA6IDEwLFxuICAgIG5hbWVUZXh0U3R5bGU6IGhvcml6b250YWwgPyB1bmRlZmluZWQgOiB7IGFsaWduOiBleHRyYXMuaW5kZXggPT09IDEgPyAncmlnaHQnIGFzIGNvbnN0IDogJ2xlZnQnIGFzIGNvbnN0IH0sXG4gICAgLy8gQSBwaW5uZWQgYm91bmQgd2luczsgb25lIGxlZnQgb3BlbiByZWFjaGVzIHRoZSByZWZlcmVuY2VzIChyZWFjaE1pbiksXG4gICAgLy8gb3Igb24gYSByYW5rIGF4aXMgc3RhcnRzIGF0IHJhbmsgMS5cbiAgICBtaW46IHJhbmdlLm1pbiA/PyAoZXh0cmFzLnJhbmsgPyBSQU5LX0FYSVNfTUlOIDogcmVhY2hNaW4oZXh0cmFzLnJlYWNoKSksXG4gICAgbWF4OiByYW5nZS5tYXggPz8gcmVhY2hNYXgoZXh0cmFzLnJlYWNoKSxcbiAgICBpbnRlcnZhbDogcmFuZ2UuaW50ZXJ2YWwsXG4gICAgYXhpc0xhYmVsLFxuICAgIC4uLihleHRyYXMucmFuayA/IHsgaW52ZXJzZTogdHJ1ZSwgbWluSW50ZXJ2YWw6IDEgfSA6IHt9KSxcbiAgfTtcbn1cblxuLy8gVGhlIHBhcnQgb2YgYSB2YWx1ZSBheGlzJ3MgcmFuZ2UgdGhlIGNvbmZpZyBwaW5zLiBBIGJvdW5kIHRoYXQgaXMgbm90IGFcbi8vIGZpbml0ZSBudW1iZXIsIG9yIGFuIGludGVydmFsIHRoYXQgaXMgbm90IGEgcG9zaXRpdmUgb25lLCBpcyBsZWZ0IG91dCwgYW5kXG4vLyB0aGUgY2hhcnQgcGlja3MgaXQgZnJvbSB0aGUgZGF0YS4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGhcbi8vIG1lZGlhIGRyYXcgdGhlIHNhbWUgcmFuZ2UuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVBeGlzUmFuZ2UoYXhpczogQ2hhcnRWYWx1ZUF4aXMgfCB1bmRlZmluZWQpOiB7IG1pbj86IG51bWJlcjsgbWF4PzogbnVtYmVyOyBpbnRlcnZhbD86IG51bWJlciB9IHtcbiAgY29uc3QgaW50ZXJ2YWwgPSBheGlzTnVtYmVyKGF4aXM/LmludGVydmFsKTtcblxuICByZXR1cm4ge1xuICAgIG1pbjogYXhpc051bWJlcihheGlzPy5taW4pLFxuICAgIG1heDogYXhpc051bWJlcihheGlzPy5tYXgpLFxuICAgIGludGVydmFsOiBpbnRlcnZhbCAhPT0gdW5kZWZpbmVkICYmIGludGVydmFsID4gMCA/IGludGVydmFsIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vLyBBIHR3by1heGlzIGNoYXJ0J3MgdmFsdWUgYXhlczogdGhlIHByaW1hcnkgb24gdGhlIGxlZnQsIHRoZSBzZWNvbmQgb24gdGhlXG4vLyByaWdodCB3aXRob3V0IGdyaWRsaW5lcyBvZiBpdHMgb3duLiBFYWNoIGF4aXMncyB0aWNrcyB0YWtlIHRoZSBmb3JtYXQgb2YgdGhlXG4vLyBtZWFzdXJlcyBwbG90dGVkIGFnYWluc3QgaXQgKGF4aXNMYWJlbHMpLiBXaXRob3V0IGEgcmFuZ2Ugb24gZWl0aGVyIGF4aXMgdGhlXG4vLyBzZWNvbmQgYXhpcyBhbGlnbnMgaXRzIHRpY2tzIHRvIHRoZSBwcmltYXJ5J3MgZ3JpZGxpbmVzLlxuLy9cbi8vIE9uIGEgMTAwJSBzdGFja2VkIGNoYXJ0IChwZXJjZW50TWluIHNldCkgdGhlIHByaW1hcnkgYXhpcyBpcyB0aGUgc2hhcmUgYXhpcyxcbi8vIHdob3NlIHJhbmdlIGlzIGZpeGVkLCBhbmQgdGhlIHNlY29uZCBheGlzJ3Mgc2VyaWVzIGFyZSBub3Qgc3RhY2tlZC4gQW4gYXhpc1xuLy8gb2YgcmFua3MgYWxvbmUgKHJhbmtBeGVzKSBpcyBpbnZlcnRlZCwgYW5kIHRoZSBheGVzIHRoZW4ga2VlcCB0aGVpciBvd25cbi8vIHRpY2tzLCBzbyBhIHJhbmsgYXhpcyBzdGVwcyBieSB3aG9sZSByYW5rcy5cbmZ1bmN0aW9uIHR3b1ZhbHVlQXhlc09wdGlvbihcbiAgY29uZmlnOiBDaGFydENvbmZpZyxcbiAgYXhpc0xhYmVsczogVmFsdWVBeGlzTGFiZWxbXSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgcGVyY2VudE1pbjogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICByZWZlcmVuY2VzOiBEcmF3blJlZmVyZW5jZVtdLFxuICByYW5rQXhlczogYm9vbGVhbltdLFxuKSB7XG4gIGNvbnN0IHBlcmNlbnQgPSBwZXJjZW50TWluICE9PSB1bmRlZmluZWQ7XG4gIGNvbnN0IGxhYmVsID0gKGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXgpID0+IGF4aXNMYWJlbHNbYXhpc0luZGV4XTtcblxuICByZXR1cm4gW1xuICAgIHZhbHVlQXhpc09wdGlvbihjb25maWcudmFsdWVBeGlzLCBmYWxzZSwgcGVyY2VudCA/IHBlcmNlbnRBeGlzTGFiZWwoY29udGV4dCkgOiBsYWJlbCgwKSwge1xuICAgICAgaW5kZXg6IDAsXG4gICAgICBwZXJjZW50TWluLFxuICAgICAgcmVhY2g6IHJlZmVyZW5jZVJlYWNoKHJlZmVyZW5jZXMsIDApLFxuICAgICAgcmFuazogcmFua0F4ZXNbMF0sXG4gICAgfSksXG4gICAge1xuICAgICAgLi4udmFsdWVBeGlzT3B0aW9uKGNvbmZpZy5zZWNvbmRhcnlBeGlzLCBmYWxzZSwgbGFiZWwoMSksIHtcbiAgICAgICAgaW5kZXg6IDEsXG4gICAgICAgIHJlYWNoOiByZWZlcmVuY2VSZWFjaChyZWZlcmVuY2VzLCAxKSxcbiAgICAgICAgcmFuazogcmFua0F4ZXNbMV0sXG4gICAgICB9KSxcbiAgICAgIHBvc2l0aW9uOiAncmlnaHQnIGFzIGNvbnN0LFxuICAgICAgc3BsaXRMaW5lOiB7IHNob3c6IGZhbHNlIH0sXG4gICAgICBhbGlnblRpY2tzOiAhcGVyY2VudCAmJiAhcmFua0F4ZXNbMF0gJiYgIXJhbmtBeGVzWzFdXG4gICAgICAgICYmICFoYXNBeGlzUmFuZ2UoY29uZmlnLnZhbHVlQXhpcykgJiYgIWhhc0F4aXNSYW5nZShjb25maWcuc2Vjb25kYXJ5QXhpcyksXG4gICAgfSxcbiAgXTtcbn1cblxuLy8gV2hldGhlciB0aGUgY29uZmlnIHBpbnMgYW55IG9mIGFuIGF4aXMncyByYW5nZTogYSBib3VuZCBvciBhIHRpY2sgaW50ZXJ2YWwuXG5mdW5jdGlvbiBoYXNBeGlzUmFuZ2UoYXhpczogQ2hhcnRWYWx1ZUF4aXMgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXModmFsdWVBeGlzUmFuZ2UoYXhpcykpLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkKTtcbn1cblxuLy8gQSBjb25maWd1cmVkIGJvdW5kIG9yIGludGVydmFsIHdoZW4gaXQgaXMgYSBmaW5pdGUgbnVtYmVyLCBlbHNlIHVuZGVmaW5lZC5cbmZ1bmN0aW9uIGF4aXNOdW1iZXIodmFsdWU6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbi8vIEEgdmFsdWUgYXhpcydzIHRpY2sgbGFiZWxzLlxuaW50ZXJmYWNlIFZhbHVlQXhpc0xhYmVsIHtcbiAgZm9ybWF0dGVyOiAodmFsdWU6IG51bWJlcikgPT4gc3RyaW5nO1xufVxuXG4vLyBUaWNrIGxhYmVscyB3cml0dGVuIGluIHRoZSBsb2NhbGUuIEVDaGFydHMnIG93biB0aWNrcyBhcmUgZ3JvdXBlZCBlbi1VU1xuLy8gd2hhdGV2ZXIgdGhlIHBhZ2UncyBsYW5ndWFnZS5cbi8vXG4vLyBXaXRoIGEgbnVtYmVyIGZvcm1hdCwgdGhlIHVuaXRzIGFuZCBkZWNpbWFscyBkZWNpZGVkIG9uY2UgZm9yIHRoZSB3aG9sZVxuLy8gYXhpcyAocmVzb2x2ZVZhbHVlQXhpc0Zvcm1hdCkgd3JpdGUgZXZlcnkgdGljayBhbGlrZSAoJzEuNUsnLCAnMi4wSycsIG5ldmVyXG4vLyAnMksnKS4gV2l0aG91dCBvbmUsIG9yIHdoZW4gaXQgbGVhdmVzIHRoZSB0aWNrcyBhbiB1bnNjYWxlZCBudW1iZXIgd2l0aCBub1xuLy8gcGlubmVkIGRlY2ltYWxzIChmb3JtYXQgJ251bWJlcicsIG9yIHByZWNpc2lvbi1sZXNzIHVuaXRzIG5vbmUpLCBlYWNoIHRpY2tcbi8vIGlzIGEgcGxhaW4gbG9jYWxlLWdyb3VwZWQgbnVtYmVyIGtlZXBpbmcgaXRzIG93biBkZWNpbWFscywgc28gYSAwLjAwMDIgdGlja1xuLy8gbmV2ZXIgcm91bmRzIHRvICcwJy5cbmZ1bmN0aW9uIHZhbHVlQXhpc0xhYmVsKGZvcm1hdDogVmFsdWVBeGlzRm9ybWF0IHwgbnVsbCwgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCk6IFZhbHVlQXhpc0xhYmVsIHtcbiAgaWYgKCFmb3JtYXQgfHwgKGZvcm1hdC5jaGFydC51bml0cyA9PT0gUmVwb3J0TnVtYmVyVW5pdHMuTm9uZSAmJiBmb3JtYXQuY2hhcnQuZGVjaW1hbHMgPT09IG51bGwpKSB7XG4gICAgcmV0dXJuIHsgZm9ybWF0dGVyOiAodmFsdWU6IG51bWJlcikgPT4gZm9ybWF0UGxhaW5OdW1iZXIodmFsdWUsIGNvbnRleHQubG9jYWxlKSB9O1xuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHsgdW5pdHM6IGZvcm1hdC5jaGFydC51bml0cywgZGVjaW1hbHM6IGZvcm1hdC5jaGFydC5kZWNpbWFscyB9O1xuXG4gIHJldHVybiB7XG4gICAgZm9ybWF0dGVyOiAodmFsdWU6IG51bWJlcikgPT4gZm9ybWF0TnVtYmVyKHZhbHVlLCBmb3JtYXQuc3BlYywgZm9ybWF0LmNvbnRleHQsIG9wdGlvbnMpLFxuICB9O1xufVxuXG4vLyBBbiBheGlzJ3MgZm9ybWF0IGZyb20gdGhlIHNwZWMgaXRzIG1lYXN1cmVzIGFncmVlIG9uLCB3aXRoIHRoZSB1bml0cyBhbmRcbi8vIGRlY2ltYWxzIGRlY2lkZWQgZnJvbSBpdHMgcGVhay4gV2l0aG91dCBhIHNwZWMgdGhlIGF4aXMgaXMgcGxhaW4sIGFuZCB0aGVcbi8vIHBlYWsgaXMgbmV2ZXIgY29tcHV0ZWQuXG5mdW5jdGlvbiByZXNvbHZlVmFsdWVBeGlzRm9ybWF0KFxuICBzcGVjOiBOdW1iZXJGb3JtYXRTcGVjIHwgbnVsbCxcbiAgcGVhazogKCkgPT4gbnVtYmVyLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogVmFsdWVBeGlzRm9ybWF0IHwgbnVsbCB7XG4gIHJldHVybiBzcGVjID8geyBzcGVjLCBjaGFydDogcmVzb2x2ZUNoYXJ0TnVtYmVyRm9ybWF0KHNwZWMsIHBlYWsoKSwgY29udGV4dCksIGNvbnRleHQgfSA6IG51bGw7XG59XG5cbi8vIEVhY2ggdmFsdWUgYXhpcydzIGZvcm1hdCwgYnkgYXhpcyBpbmRleC4gQSBjaGFydCB3aXRoIG9uZSB2YWx1ZSBheGlzIHRha2VzXG4vLyB0aGUgZm9ybWF0IHRoZSBwbG90dGVkIHNlcmllcycgbWVhc3VyZXMgYWdyZWUgb24gKGEgc3BsaXRCeSBvciBjb2xvckJ5IGNoYXJ0XG4vLyBwbG90cyBvbmx5IGl0cyBmaXJzdCBtZWFzdXJlKSwgZnJvbSB0aGUgcGVhayBvZiBhbGwgaXRzIHNlcmllcy4gT24gYSB0d28tYXhpcyBjaGFydCBlYWNoIGF4aXMgdGFrZXMgdGhlIGZvcm1hdCBvZiB0aGUgbWVhc3VyZXNcbi8vIHBsb3R0ZWQgYWdhaW5zdCBpdCwgZnJvbSB0aGUgcGVhayBvZiBpdHMgb3duIHNlcmllcywgd2hpY2ggYXJlIG5ldmVyXG4vLyBzdGFja2VkIHdpdGggYSAxMDAlIHN0YWNrZWQgY2hhcnQncyBzaGFyZXMuIEEgcmVmZXJlbmNlIHBhc3QgdGhlIGRhdGFcbi8vIHN0cmV0Y2hlcyBpdHMgYXhpcywgc28gaXQgY291bnRzIHRvd2FyZCB0aGUgcGVhayAocmVmZXJlbmNlUGVhayk7IGEgMTAwJVxuLy8gc3RhY2tlZCBjaGFydCdzIHJlZmVyZW5jZXMgYXJlIHNoYXJlcywgd2hpY2ggdGhlIHJhdyB2YWx1ZXMnIHBlYWsgbGVhdmVzXG4vLyBvdXQuIGNvbnRleHRzIGhvbGRzIGVhY2ggYXhpcydzIGNvbnRleHQgKGFubm90YXRlZEF4aXNDb250ZXh0cykuXG5mdW5jdGlvbiB2YWx1ZUF4aXNGb3JtYXRzKFxuICBjb25maWc6IENoYXJ0Q29uZmlnLFxuICBleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLFxuICBheGlzSW5kZXhlczogVmFsdWVBeGlzSW5kZXhbXSxcbiAgY29udGV4dHM6IFJlcG9ydEZvcm1hdENvbnRleHRbXSxcbiAgcGVyY2VudDogYm9vbGVhbixcbiAgcmVmZXJlbmNlczogRHJhd25SZWZlcmVuY2VbXSxcbik6IChWYWx1ZUF4aXNGb3JtYXQgfCBudWxsKVtdIHtcbiAgY29uc3QgcmVhY2ggPSAoYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleCkgPT4gKHBlcmNlbnQgJiYgYXhpc0luZGV4ID09PSAwID8gMCA6IHJlZmVyZW5jZVBlYWsocmVmZXJlbmNlcywgYXhpc0luZGV4KSk7XG5cbiAgaWYgKCFheGlzSW5kZXhlcy5pbmNsdWRlcygxKSkge1xuICAgIHJldHVybiBbcmVzb2x2ZVZhbHVlQXhpc0Zvcm1hdChcbiAgICAgIGF4aXNOdW1iZXJGb3JtYXQoZXh0cmFjdGVkLnNlcmllcy5tYXAoKHNlcmllcykgPT4gc2VyaWVzLm1lYXN1cmUpKSxcbiAgICAgICgpID0+IE1hdGgubWF4KGNoYXJ0VmFsdWVQZWFrKGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy52YWx1ZXMpLCAhIWNvbmZpZy5zdGFja2VkKSwgcmVhY2goMCkpLFxuICAgICAgY29udGV4dHNbMF0sXG4gICAgKV07XG4gIH1cblxuICByZXR1cm4gKFswLCAxXSBhcyBjb25zdCkubWFwKChheGlzSW5kZXgpID0+IHtcbiAgICBjb25zdCBvbkF4aXMgPSBleHRyYWN0ZWQuc2VyaWVzLmZpbHRlcigoXywgaW5kZXgpID0+IGF4aXNJbmRleGVzW2luZGV4XSA9PT0gYXhpc0luZGV4KTtcblxuICAgIHJldHVybiByZXNvbHZlVmFsdWVBeGlzRm9ybWF0KFxuICAgICAgYXhpc051bWJlckZvcm1hdChvbkF4aXMubWFwKChzZXJpZXMpID0+IHNlcmllcy5tZWFzdXJlKSksXG4gICAgICAoKSA9PiBNYXRoLm1heChjaGFydFZhbHVlUGVhayhvbkF4aXMubWFwKChzZXJpZXMpID0+IHNlcmllcy52YWx1ZXMpLCAhIWNvbmZpZy5zdGFja2VkICYmICFwZXJjZW50KSwgcmVhY2goYXhpc0luZGV4KSksXG4gICAgICBjb250ZXh0c1theGlzSW5kZXhdLFxuICAgICk7XG4gIH0pO1xufVxuXG4vLyBBIDEwMCUgc3RhY2tlZCBjaGFydCdzIHNoYXJlIGF4aXMgdGlja3M6IHdob2xlIHBlcmNlbnRhZ2VzIGluIHRoZSBsb2NhbGVcbi8vICgnMjUlJywgJzI1ICUnIGluIGZyLUNBKS4gVGhlIHNoYXJlcyBhcmUgcmF0aW9zIHdoYXRldmVyIHRoZSByZXBvcnQnc1xuLy8gcGVyY2VudEZvcm1hdCBzYXlzIG9mIGl0cyBzdG9yZWQgdmFsdWVzLlxuZnVuY3Rpb24gcGVyY2VudEF4aXNMYWJlbChjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0KTogVmFsdWVBeGlzTGFiZWwge1xuICByZXR1cm4geyBmb3JtYXR0ZXI6IHdob2xlUGVyY2VudEZvcm1hdHRlcihjb250ZXh0KSB9O1xufVxuXG4vLyBBIHNoYXJlIGFzIGEgd2hvbGUgcGVyY2VudGFnZSBpbiB0aGUgbG9jYWxlLCBmb3IgdGhlIHNoYXJlIGF4aXMncyB0aWNrcyBhbmRcbi8vIGl0cyBzZXJpZXMnIGRhdGEgbGFiZWxzLlxuZnVuY3Rpb24gd2hvbGVQZXJjZW50Rm9ybWF0dGVyKGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiAodmFsdWU6IHVua25vd24pID0+IHN0cmluZyB7XG4gIGNvbnN0IHJhdGlvQ29udGV4dCA9IHsgLi4uY29udGV4dCwgcmF0aW9QZXJjZW50OiB0cnVlIH07XG5cbiAgcmV0dXJuICh2YWx1ZTogdW5rbm93bikgPT4gZm9ybWF0TnVtYmVyKHZhbHVlLCBQRVJDRU5UX0FYSVNfRk9STUFULCByYXRpb0NvbnRleHQpO1xufVxuXG4vLyBXaGF0IGEgc2VyaWVzJyB0b29sdGlwIHdyaXRlcyBiZXNpZGUgaXRzIG5hbWUuXG5pbnRlcmZhY2UgU2VyaWVzVG9vbHRpcCB7XG4gIHZhbHVlRm9ybWF0dGVyOiAodmFsdWU6IHVua25vd24pID0+IHN0cmluZztcbn1cblxuLy8gQSBzZXJpZXMnIHRvb2x0aXAgdmFsdWUgaW4gaXRzIG1lYXN1cmUncyBudW1iZXIgZm9ybWF0LCBwZXIgdmFsdWUgKCfigJQnIHdoZW5cbi8vIGVtcHR5KS4gQSBtZWFzdXJlIHdpdGhvdXQgb25lIHdyaXRlcyBpdCBhcyB0aGUgcGxhaW4gdmFsdWUgYXhpcyBkb2VzLiBBXG4vLyB2YWx1ZSBjYW4gYXJyaXZlIGFzIGFuIGFycmF5IChhIFt2YWx1ZSwgLi4uXSBkYXRhIGl0ZW0pLCB3aG9zZSBmaXJzdCBlbnRyeVxuLy8gaXMgdGhlIHZhbHVlLlxuZnVuY3Rpb24gc2VyaWVzVG9vbHRpcChtZWFzdXJlOiBDaGFydE1lYXN1cmUgfCB1bmRlZmluZWQsIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiBTZXJpZXNUb29sdGlwIHtcbiAgaWYgKCFoYXNOdW1iZXJGb3JtYXQobWVhc3VyZSkpIHtcbiAgICByZXR1cm4geyB2YWx1ZUZvcm1hdHRlcjogKHZhbHVlOiB1bmtub3duKSA9PiBmb3JtYXRQbGFpbk51bWJlcih2YWx1ZSwgY29udGV4dC5sb2NhbGUpIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHZhbHVlRm9ybWF0dGVyOiAodmFsdWU6IHVua25vd24pID0+IGZvcm1hdE51bWJlcihBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlWzBdIDogdmFsdWUsIG1lYXN1cmUsIGNvbnRleHQpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBidWlsZFBpZU9wdGlvbihcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGRvbnV0OiBib29sZWFuLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogRUNoYXJ0c09wdGlvbiB7XG4gIGNvbnN0IGNvbmZpZyA9IGNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWc7XG4gIGNvbnN0IGV4dHJhY3RlZCA9IGV4dHJhY3RDaGFydFNlcmllcyhjb21wb25lbnQsIGRhdGEpO1xuICBjb25zdCB2YWx1ZXMgPSBleHRyYWN0ZWQuc2VyaWVzWzBdPy52YWx1ZXMgPz8gW107XG4gIGNvbnN0IGxlZ2VuZFBvc2l0aW9uID0gcmVzb2x2ZUxlZ2VuZFBvc2l0aW9uKGNvbmZpZywgZXh0cmFjdGVkLnNlcmllcy5sZW5ndGgpO1xuXG4gIHJldHVybiB7XG4gICAgdG9vbHRpcDogeyB0cmlnZ2VyOiAnaXRlbScgfSxcbiAgICBsZWdlbmQ6IGxlZ2VuZE9wdGlvbihsZWdlbmRQb3NpdGlvbiksXG4gICAgc2VyaWVzOiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdwaWUnLFxuICAgICAgICByYWRpdXM6IGRvbnV0ID8gWyc0NSUnLCAnNzIlJ10gOiAnNzIlJyxcbiAgICAgICAgY2VudGVyOiBwaWVDZW50ZXIobGVnZW5kUG9zaXRpb24pLFxuICAgICAgICB0b29sdGlwOiBzZXJpZXNUb29sdGlwKGV4dHJhY3RlZC5zZXJpZXNbMF0/Lm1lYXN1cmUsIGNvbnRleHQpLFxuICAgICAgICBsYWJlbDogeyBzaG93OiBmYWxzZSB9LFxuICAgICAgICBkYXRhOiBleHRyYWN0ZWQuY2F0ZWdvcmllcy5tYXAoKGNhdGVnb3J5LCBpbmRleCkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBjYXRlZ29yeSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVzW2luZGV4XSA/PyAwLFxuICAgICAgICB9KSksXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG5cbi8vIE51ZGdlIHRoZSBwaWUgb2ZmLWNlbnRlciB0b3dhcmQgdGhlIG9wcG9zaXRlIGVkZ2UgZnJvbSBpdHMgbGVnZW5kIHNvIHRoZSB0d29cbi8vIGRvbid0IGNvbGxpZGU7IGNlbnRlcmVkIHdoZW4gdGhlIGxlZ2VuZCBpcyBoaWRkZW4uXG5mdW5jdGlvbiBwaWVDZW50ZXIocG9zaXRpb246IExlZ2VuZFBvc2l0aW9uKTogW3N0cmluZywgc3RyaW5nXSB7XG4gIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHJldHVybiBbJzYwJScsICc1MCUnXTtcbiAgICBjYXNlICdyaWdodCc6XG4gICAgICByZXR1cm4gWyc0MCUnLCAnNTAlJ107XG4gICAgY2FzZSAndG9wJzpcbiAgICAgIHJldHVybiBbJzUwJScsICc1OCUnXTtcbiAgICBjYXNlICdib3R0b20nOlxuICAgICAgcmV0dXJuIFsnNTAlJywgJzQ2JSddO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gWyc1MCUnLCAnNTAlJ107XG4gIH1cbn1cblxuZnVuY3Rpb24gdW5pcXVlVmFsdWVzKHJvd3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sIGNvbHVtbjogc3RyaW5nKTogdW5rbm93bltdIHtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgY29uc3QgdmFsdWVzOiB1bmtub3duW10gPSBbXTtcbiAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgIGNvbnN0IHZhbHVlID0gcm93W2NvbHVtbl07XG4gICAgaWYgKCFzZWVuLmhhcyh2YWx1ZSkpIHtcbiAgICAgIHNlZW4uYWRkKHZhbHVlKTtcbiAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsdWVzO1xufVxuXG5mdW5jdGlvbiBudW1lcmljKHZhbHVlOiB1bmtub3duKTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHZhbHVlKTtcblxuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHBhcnNlZCkgPyBwYXJzZWQgOiBudWxsO1xufVxuXG4vLyBUaGUgZWZmZWN0aXZlIHRpbWUgYnVja2V0IHRoZSByb3dzIHdlcmUgZ3JvdXBlZCBpbnRvIChmcm9tIHRoZSBkYXRhIGVuZHBvaW50KSxcbi8vIG9yIG51bGwgd2hlbiB0aGUgeC1heGlzIGlzbid0IGEgdGltZSBheGlzIOKAlCBnYXRlcyB0aGUgY29tcGFjdCBwZXJpb2QgbGFiZWxzLlxuZnVuY3Rpb24gYnVja2V0R3JhbnVsYXJpdHkoZGF0YTogQ29tcG9uZW50RGF0YSk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsIHtcbiAgcmV0dXJuIGRhdGEuZ3JhbnVsYXJpdHkgJiYgR1JBTlVMQVJJVFlfT1BUSU9OUy5zb21lKChvcHRpb24pID0+IG9wdGlvbi52YWx1ZSA9PT0gZGF0YS5ncmFudWxhcml0eSlcbiAgICA/IGRhdGEuZ3JhbnVsYXJpdHlcbiAgICA6IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhlIHBlcmlvZC1zdGFydCBjYXRlZ29yaWVzIGNyb3NzIGEgeWVhciBib3VuZGFyeS4gV2hlbiB0aGV5IGRvbid0LFxuLy8gdGhlIHllYXIgaXMgcHVyZSBub2lzZSBvbiBldmVyeSBsYWJlbCwgc28gaXQncyBkcm9wcGVkIGVudGlyZWx5LlxuZXhwb3J0IGZ1bmN0aW9uIHNwYW5zTXVsdGlwbGVZZWFycyhjYXRlZ29yaWVzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICBjb25zdCB5ZWFycyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBmb3IgKGNvbnN0IGNhdGVnb3J5IG9mIGNhdGVnb3JpZXMpIHtcbiAgICBjb25zdCBkYXRlID0gcGFyc2VJU08oY2F0ZWdvcnkpO1xuICAgIGlmIChpc1ZhbGlkKGRhdGUpKSB7XG4gICAgICB5ZWFycy5hZGQoZGF0ZS5nZXRGdWxsWWVhcigpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geWVhcnMuc2l6ZSA+IDE7XG59XG5cbi8vIEEgdGltZSBheGlzJ3MgZGF0ZSBsYWJlbCBzdHlsZSB3aGVuIGl0cyBjb25maWcgbmFtZXMgb25lIHRoZSB2aWV3ZXIga25vd3MsXG4vLyBlbHNlIHNob3J0LlxuZXhwb3J0IGZ1bmN0aW9uIGNoYXJ0RGF0ZUxhYmVsKGNvbmZpZzogQ2hhcnRDb25maWcgfCB1bmRlZmluZWQpOiBSZXBvcnRDaGFydERhdGVMYWJlbCB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKFJlcG9ydENoYXJ0RGF0ZUxhYmVsKS5maW5kKChzdHlsZSkgPT4gc3R5bGUgPT09IGNvbmZpZz8ueEF4aXM/LmRhdGVMYWJlbClcbiAgICA/PyBSZXBvcnRDaGFydERhdGVMYWJlbC5TaG9ydDtcbn1cblxuLy8gQSBidWNrZXQncyBwZXJpb2Qtc3RhcnQgc3BsaXQgaW50byBpdHMgcHJpbWFyeSBsYWJlbCBhbmQgaXRzIHllYXIuIEEgeWVhclxuLy8gcmVhZHMgXCIyMDI1XCIgaW4gZXZlcnkgc3R5bGUuIFNob3J0LCBpbiB0aGUgbG9jYWxlOiBkYXkvd2VlayByZWFkIFwiTWF5IDFcIlxuLy8gKCcxIG1haScgaW4gZnItQ0EpLCBtb250aCBcIk1heVwiICgnbWFpJyksIHF1YXJ0ZXIgXCJRMlwiICgnVDInIGluIEZyZW5jaCkuXG4vLyBMb25nIGNhcnJpZXMgaXRzIHllYXIsIGluIHRoZSBsb2NhbGU6IFwiTWF5IDEsIDIwMjZcIiwgXCJNYXkgMjAyNlwiICgnbWFpXG4vLyAyMDI2JyksIFwiUTIgMjAyNlwiLiBOdW1lcmljIGlzIHRoZSBzYW1lIGluIGV2ZXJ5IGxvY2FsZTogXCIyMDI2LTA1LTAxXCIsXG4vLyBcIjIwMjYtMDVcIiwgXCIyMDI2LVEyXCIuIFJldHVybnMgbnVsbCBmb3IgYSB2YWx1ZSB0aGF0IGlzbid0IGEgcGFyc2VhYmxlIGRhdGVcbi8vIChsZWZ0IGFzLWlzIGJ5IGNhbGxlcnMpLlxuZnVuY3Rpb24gcGVyaW9kTGFiZWxQYXJ0cyhcbiAgdmFsdWU6IHN0cmluZyxcbiAgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHksXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuICBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsID0gUmVwb3J0Q2hhcnREYXRlTGFiZWwuU2hvcnQsXG4pOiB7IHByaW1hcnk6IHN0cmluZzsgeWVhcjogc3RyaW5nIH0gfCBudWxsIHtcbiAgY29uc3QgZGF0ZSA9IHBhcnNlSVNPKHZhbHVlKTtcbiAgaWYgKCFpc1ZhbGlkKGRhdGUpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB5ZWFyID0gU3RyaW5nKGRhdGUuZ2V0RnVsbFllYXIoKSk7XG4gIGlmIChncmFudWxhcml0eSA9PT0gJ3llYXInKSB7XG4gICAgcmV0dXJuIHsgcHJpbWFyeTogeWVhciwgeWVhciB9O1xuICB9XG5cbiAgcmV0dXJuIHsgcHJpbWFyeTogcGVyaW9kUHJpbWFyeUxhYmVsKGRhdGUsIGdyYW51bGFyaXR5LCBsb2NhbGUsIGRhdGVMYWJlbCksIHllYXIgfTtcbn1cblxuLy8gQSBwZXJpb2QncyBsYWJlbCBpbiB0aGUgc3R5bGUgYXNrZWQgZm9yLCB0aGUgeWVhciBhc2lkZSAoc2VlXG4vLyBwZXJpb2RMYWJlbFBhcnRzKS5cbmZ1bmN0aW9uIHBlcmlvZFByaW1hcnlMYWJlbChcbiAgZGF0ZTogRGF0ZSxcbiAgZ3JhbnVsYXJpdHk6IEV4Y2x1ZGU8Q2hhcnRHcmFudWxhcml0eSwgJ3llYXInPixcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4gIGRhdGVMYWJlbDogUmVwb3J0Q2hhcnREYXRlTGFiZWwsXG4pOiBzdHJpbmcge1xuICBjb25zdCB5ZWFyID0gU3RyaW5nKGRhdGUuZ2V0RnVsbFllYXIoKSk7XG4gIGNvbnN0IHF1YXJ0ZXIgPSBNYXRoLmZsb29yKGRhdGUuZ2V0TW9udGgoKSAvIDMpICsgMTtcblxuICBpZiAoZGF0ZUxhYmVsID09PSBSZXBvcnRDaGFydERhdGVMYWJlbC5OdW1lcmljKSB7XG4gICAgY29uc3QgbW9udGggPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkYXkgPSBTdHJpbmcoZGF0ZS5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgc3dpdGNoIChncmFudWxhcml0eSkge1xuICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgIHJldHVybiBgJHt5ZWFyfS1RJHtxdWFydGVyfWA7XG4gICAgICBjYXNlICdtb250aCc6XG4gICAgICAgIHJldHVybiBgJHt5ZWFyfS0ke21vbnRofWA7XG4gICAgICBkZWZhdWx0OiAvLyBkYXksIHdlZWsg4oCUIHRoZSBidWNrZXQgc3RhcnRcbiAgICAgICAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9LSR7ZGF5fWA7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbG9uZyA9IGRhdGVMYWJlbCA9PT0gUmVwb3J0Q2hhcnREYXRlTGFiZWwuTG9uZztcbiAgc3dpdGNoIChncmFudWxhcml0eSkge1xuICAgIGNhc2UgJ3F1YXJ0ZXInOlxuICAgICAgcmV0dXJuIGxvbmdcbiAgICAgICAgPyBgJHtxdWFydGVyUHJlZml4KGxvY2FsZSl9JHtxdWFydGVyfSAke3llYXJ9YFxuICAgICAgICA6IGAke3F1YXJ0ZXJQcmVmaXgobG9jYWxlKX0ke3F1YXJ0ZXJ9YDtcbiAgICBjYXNlICdtb250aCc6XG4gICAgICByZXR1cm4gZm9ybWF0TG9jYWxEYXRlKGRhdGUsIGxvY2FsZSwgbG9uZyA/IE1PTlRIX1lFQVIgOiBNT05USF9MT05HKTtcbiAgICBkZWZhdWx0OiAvLyBkYXksIHdlZWsg4oCUIHRoZSBidWNrZXQgc3RhcnQgYXMgYSBtb250aCBhbmQgZGF5XG4gICAgICByZXR1cm4gZm9ybWF0TG9jYWxEYXRlKGRhdGUsIGxvY2FsZSwgbG9uZyA/IERBWV9TSE9SVCA6IE1PTlRIX0RBWSk7XG4gIH1cbn1cblxuLy8gV2hldGhlciBhIHBlcmlvZCBsYWJlbCBsZWF2ZXMgaXRzIHllYXIgdG8gYmUgYWRkZWQgYXBhcnQ6IG9ubHkgYSBzaG9ydCBvbmVcbi8vIGRvZXMsIGEgbG9uZyBvciBudW1lcmljIGxhYmVsIGFscmVhZHkgY2FycmllcyBpdC5cbmZ1bmN0aW9uIHBlcmlvZFllYXJBcGFydChncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSwgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZ3JhbnVsYXJpdHkgIT09ICd5ZWFyJyAmJiBkYXRlTGFiZWwgPT09IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0O1xufVxuXG5mdW5jdGlvbiBxdWFydGVyUHJlZml4KGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnKTogc3RyaW5nIHtcbiAgcmV0dXJuIFFVQVJURVJfUFJFRklYRVMuZ2V0KGxvY2FsZS5zcGxpdCgnLScpWzBdLnRvTG93ZXJDYXNlKCkpID8/IFFVQVJURVJfUFJFRklYO1xufVxuXG4vLyBBIGNvbXBhY3Qgc2luZ2xlLWxpbmUgcGVyaW9kIGxhYmVsIOKAlCBmb3IgbWVkaWEgdGhhdCBjYW4ndCBkbyBhIHN0eWxlZFxuLy8gc2Vjb25kIGxpbmUsIGUuZy4gUG93ZXJQb2ludC4gQSBzaG9ydCBsYWJlbCBoYXMgaXRzIHllYXIgYXBwZW5kZWQgb25seSB3aGVuXG4vLyB0aGUgZGF0YSBzcGFucyB5ZWFyczsgYSBsb25nIG9yIG51bWVyaWMgb25lIGFsd2F5cyBjYXJyaWVzIGl0LlxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFBlcmlvZExhYmVsKFxuICB2YWx1ZTogc3RyaW5nLFxuICBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSxcbiAgbXVsdGlZZWFyOiBib29sZWFuLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCA9IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgcGFydHMgPSBwZXJpb2RMYWJlbFBhcnRzKHZhbHVlLCBncmFudWxhcml0eSwgbG9jYWxlLCBkYXRlTGFiZWwpO1xuICBpZiAoIXBhcnRzKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG11bHRpWWVhciAmJiBwZXJpb2RZZWFyQXBhcnQoZ3JhbnVsYXJpdHksIGRhdGVMYWJlbCkgPyBgJHtwYXJ0cy5wcmltYXJ5fSAke3BhcnRzLnllYXJ9YCA6IHBhcnRzLnByaW1hcnk7XG59XG5cbi8vIEEgY3Jvc3MtdGFiJ3MgY29sdW1uIGhlYWRpbmdzLCB0aGUgb25lIHJ1bGUgdGhlIGdyaWQgYW5kIHRoZSBQREYvUG93ZXJQb2ludFxuLy8gZXhwb3J0cyBzaGFyZS4gVGhlIGZpcnN0IGlzIHRoZSByb3cga2V5IGFuZCBrZWVwcyBpdHMgYXV0aG9yZWQgbGFiZWw7IHRoZVxuLy8gcmVzdCBhcmUgcGl2b3QgVkFMVUVTLiBXaGVuIHRoZSBwaXZvdCBheGlzIGlzIGEgdGltZSBkaW1lbnNpb24gdGhlIHNlcnZlclxuLy8gc2VuZHMgdGhlIGdyYWluIGl0IGJ1Y2tldGVkIGF0LCBzbyBhIHBlcmlvZC1zdGFydCBsaWtlIFwiMjAyNi0wMS0wMVwiIHJlYWRzXG4vLyBcIkphbnVhcnkgMjAyNlwiICgnamFudmllciAyMDI2JyBpbiBmci1DQSksIGFzIHRoZSBjaGFydCdzIHgtYXhpcyBsYWJlbHMgaXQuXG5leHBvcnQgZnVuY3Rpb24gcGl2b3RIZWFkaW5ncyhcbiAgY29uZmlnOiBMaXN0Q29uZmlnLFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgY29sdW1ucyA9IGRhdGEuY29sdW1ucyA/PyBbXTtcbiAgY29uc3QgbXVsdGlZZWFyID0gc3BhbnNNdWx0aXBsZVllYXJzKGNvbHVtbnMpO1xuXG4gIHJldHVybiBjb2x1bW5zLm1hcCgoY29sdW1uLCBpbmRleCkgPT4ge1xuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbmZpZy5yb3dCeT8ubGFiZWwgfHwgY29sdW1uO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhLmdyYW51bGFyaXR5ID8gZm9ybWF0UGVyaW9kTGFiZWwoY29sdW1uLCBkYXRhLmdyYW51bGFyaXR5LCBtdWx0aVllYXIsIGxvY2FsZSkgOiBjb2x1bW47XG4gIH0pO1xufVxuXG4vLyBBIGNyb3NzLXRhYidzIGNvbHVtbnMgYXMgdGhlIGdyaWQgYW5kIHRoZSBleHBvcnRzIGRyYXcgdGhlbTogZWFjaCBoZWFkZWQgYnlcbi8vIHBpdm90SGVhZGluZ3MoKSwgYW5kIGV2ZXJ5IHBpdm90LXZhbHVlIGNvbHVtbiBmb3JtYXR0ZWQgYnkgdGhlIG9uZVxuLy8gY29uZmlnLmNlbGxGb3JtYXQuIFRoZSByb3cga2V5IGNvbHVtbiBzdGF5cyBhcyBpdCBjYW1lLiBgbnVtZXJpY2AgbWFya3MgdGhlXG4vLyBjb2x1bW5zIHdob3NlIGNlbGxzIGFyZSBmb3JtYXR0ZWQgbnVtYmVycywgd2hpY2ggYXJlIHJpZ2h0LWFsaWduZWQuXG5leHBvcnQgZnVuY3Rpb24gcGl2b3RDb2x1bW5TcGVjcyhcbiAgY29uZmlnOiBMaXN0Q29uZmlnLFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbik6IChMaXN0Q29sdW1uICYgeyBudW1lcmljOiBib29sZWFuIH0pW10ge1xuICBjb25zdCBoZWFkaW5ncyA9IHBpdm90SGVhZGluZ3MoY29uZmlnLCBkYXRhLCBsb2NhbGUpO1xuICBjb25zdCBjZWxsRm9ybWF0ID0gY29uZmlnLmNlbGxGb3JtYXQ7XG4gIGNvbnN0IG51bWVyaWMgPSBoYXNOdW1iZXJGb3JtYXQoY2VsbEZvcm1hdCk7XG4gIGNvbnN0IGNlbGxzOiBQaWNrPExpc3RDb2x1bW4sICdmb3JtYXQnIHwgJ3ByZWNpc2lvbicgfCAndW5pdHMnPiA9IG51bWVyaWMgJiYgY2VsbEZvcm1hdFxuICAgID8geyBmb3JtYXQ6IGxpc3RDb2x1bW5Gb3JtYXQoY2VsbEZvcm1hdC5mb3JtYXQpLCBwcmVjaXNpb246IGNlbGxGb3JtYXQucHJlY2lzaW9uLCB1bml0czogY2VsbEZvcm1hdC51bml0cyB9XG4gICAgOiB7fTtcblxuICByZXR1cm4gKGRhdGEuY29sdW1ucyA/PyBbXSkubWFwKChjb2x1bW4sIGluZGV4KSA9PiBpbmRleCA9PT0gMFxuICAgID8geyBjb2x1bW4sIGxhYmVsOiBoZWFkaW5nc1tpbmRleF0sIG51bWVyaWM6IGZhbHNlIH1cbiAgICA6IHsgY29sdW1uLCBsYWJlbDogaGVhZGluZ3NbaW5kZXhdLCAuLi5jZWxscywgbnVtZXJpYyB9KTtcbn1cblxuLy8gQSBudW1iZXIgZm9ybWF0J3Mgc3R5bGUgYXMgYSBsaXN0IGNvbHVtbidzIGZvcm1hdDogdGhlIHR3byBlbnVtcyBzaGFyZVxuLy8gdGhlaXIgbnVtYmVyIHZhbHVlcy5cbmZ1bmN0aW9uIGxpc3RDb2x1bW5Gb3JtYXQoZm9ybWF0OiBOdW1iZXJGb3JtYXRTcGVjWydmb3JtYXQnXSk6IFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQgfCB1bmRlZmluZWQge1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhSZXBvcnRMaXN0Q29sdW1uRm9ybWF0KS5maW5kKCh2YWx1ZSkgPT4gdmFsdWUgPT09IGZvcm1hdCk7XG59XG5cbi8vIEVDaGFydHMgY2F0ZWdvcnktYXhpcyBsYWJlbCBjb25maWcgZm9yIGEgdGltZSBidWNrZXQ6IHRoZSBwcmltYXJ5IGxhYmVsIG9uXG4vLyBsaW5lIG9uZSwgYW5kIOKAlCBvbmx5IHdoZW4gdGhlIGRhdGEgc3BhbnMgbXVsdGlwbGUgeWVhcnMg4oCUIHRoZSB5ZWFyIG9uIGEgc21hbGxcbi8vIGdyYXkgc2Vjb25kIGxpbmUsIGNlbnRlcmVkIHVuZGVyIHRoZSB0aWNrICh5ZWFyIGdyYW51bGFyaXR5IG5lZWRzIG5vIHNlY29uZFxuLy8gbGluZSwgaXQgYWxyZWFkeSBpcyB0aGUgeWVhciwgYW5kIG5laXRoZXIgZG9lcyBhIGxvbmcgb3IgbnVtZXJpYyBsYWJlbCxcbi8vIHdoaWNoIGNhcnJpZXMgaXRzIHllYXIpLiBFbXB0eSBmb3IgYSBub24tdGltZSBheGlzIChsYWJlbHMgYXMtaXMpLlxuZnVuY3Rpb24gcGVyaW9kQXhpc0xhYmVsKFxuICBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwsXG4gIGNhdGVnb3JpZXM6IHN0cmluZ1tdLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCxcbik6IHsgYXhpc0xhYmVsPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfSB7XG4gIGlmICghZ3JhbnVsYXJpdHkpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCBtdWx0aVllYXIgPSBzcGFuc011bHRpcGxlWWVhcnMoY2F0ZWdvcmllcyk7XG5cbiAgcmV0dXJuIHtcbiAgICBheGlzTGFiZWw6IHtcbiAgICAgIGZvcm1hdHRlcjogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgcGFydHMgPSBwZXJpb2RMYWJlbFBhcnRzKHZhbHVlLCBncmFudWxhcml0eSwgbG9jYWxlLCBkYXRlTGFiZWwpO1xuICAgICAgICBpZiAoIXBhcnRzKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG11bHRpWWVhciAmJiBwZXJpb2RZZWFyQXBhcnQoZ3JhbnVsYXJpdHksIGRhdGVMYWJlbClcbiAgICAgICAgICA/IGAke3BhcnRzLnByaW1hcnl9XFxue3lyfCR7cGFydHMueWVhcn19YFxuICAgICAgICAgIDogcGFydHMucHJpbWFyeTtcbiAgICAgIH0sXG4gICAgICByaWNoOiB7IHlyOiB7IGZvbnRTaXplOiAxMCwgY29sb3I6ICcjOWFhMGE2JywgbGluZUhlaWdodDogMTQgfSB9LFxuICAgIH0sXG4gIH07XG59XG4iXX0=