@firestitch/report 18.6.1 → 18.7.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 (76) 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 +8 -9
  3. package/app/reports/components/component-list/component-list.component.d.ts +33 -10
  4. package/app/reports/components/report-canvas/report-canvas.component.d.ts +0 -1
  5. package/app/reports/components/report-component/report-component.component.d.ts +4 -2
  6. package/app/reports/data/report.data.d.ts +2 -1
  7. package/app/reports/dialogs/list-columns/list-columns.component.d.ts +23 -0
  8. package/app/reports/dialogs/report-settings/report-locale-patch.d.ts +5 -0
  9. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +20 -1
  10. package/app/reports/enums/report-chart-color.enum.d.ts +12 -0
  11. package/app/reports/enums/report-chart-data-labels.enum.d.ts +6 -0
  12. package/app/reports/enums/report-chart-date-label.enum.d.ts +5 -0
  13. package/app/reports/enums/report-chart-line-style.enum.d.ts +5 -0
  14. package/app/reports/enums/report-chart-mark-stat.enum.d.ts +6 -0
  15. package/app/reports/enums/report-list-column-format.enum.d.ts +6 -0
  16. package/app/reports/enums/report-number-units.enum.d.ts +6 -0
  17. package/app/reports/enums/report-value-format.enum.d.ts +5 -0
  18. package/app/reports/export/offscreen-chart.d.ts +2 -2
  19. package/app/reports/export/report-export-collector.service.d.ts +12 -9
  20. package/app/reports/export/report-pdf.service.d.ts +1 -0
  21. package/app/reports/export/report-pptx.service.d.ts +17 -0
  22. package/app/reports/format.d.ts +38 -3
  23. package/app/reports/interfaces/report.interface.d.ts +81 -10
  24. package/app/reports/list-config.d.ts +9 -0
  25. package/app/reports/option-builder.d.ts +69 -9
  26. package/app/reports/pipes/report-date.pipe.d.ts +2 -1
  27. package/app/reports/pipes/report-number.pipe.d.ts +8 -0
  28. package/app/reports/report-filter-items.d.ts +5 -2
  29. package/app/reports/report-url-state.d.ts +4 -0
  30. package/app/reports/services/report-filter-state.service.d.ts +26 -2
  31. package/app/reports/theme/palette.d.ts +3 -0
  32. package/app/reports/theme/typography.d.ts +1 -0
  33. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +19 -20
  34. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +23 -29
  35. package/esm2022/app/reports/components/component-list/component-list.component.mjs +158 -32
  36. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +3 -8
  37. package/esm2022/app/reports/components/report-component/report-component.component.mjs +81 -21
  38. package/esm2022/app/reports/data/report.data.mjs +17 -4
  39. package/esm2022/app/reports/dialogs/list-columns/list-columns.component.mjs +56 -0
  40. package/esm2022/app/reports/dialogs/report-settings/report-locale-patch.mjs +13 -0
  41. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +137 -15
  42. package/esm2022/app/reports/enums/report-chart-color.enum.mjs +19 -0
  43. package/esm2022/app/reports/enums/report-chart-data-labels.enum.mjs +13 -0
  44. package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +13 -0
  45. package/esm2022/app/reports/enums/report-chart-line-style.enum.mjs +12 -0
  46. package/esm2022/app/reports/enums/report-chart-mark-stat.enum.mjs +12 -0
  47. package/esm2022/app/reports/enums/report-list-column-format.enum.mjs +14 -0
  48. package/esm2022/app/reports/enums/report-number-units.enum.mjs +14 -0
  49. package/esm2022/app/reports/enums/report-value-format.enum.mjs +13 -0
  50. package/esm2022/app/reports/export/offscreen-chart.mjs +5 -4
  51. package/esm2022/app/reports/export/report-export-collector.service.mjs +95 -40
  52. package/esm2022/app/reports/export/report-pdf.service.mjs +92 -36
  53. package/esm2022/app/reports/export/report-pptx.service.mjs +482 -86
  54. package/esm2022/app/reports/format.mjs +497 -58
  55. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  56. package/esm2022/app/reports/list-config.mjs +74 -0
  57. package/esm2022/app/reports/option-builder.mjs +868 -98
  58. package/esm2022/app/reports/pipes/report-date.pipe.mjs +7 -6
  59. package/esm2022/app/reports/pipes/report-number.pipe.mjs +25 -0
  60. package/esm2022/app/reports/report-filter-items.mjs +28 -3
  61. package/esm2022/app/reports/report-url-state.mjs +56 -15
  62. package/esm2022/app/reports/services/report-filter-state.service.mjs +235 -20
  63. package/esm2022/app/reports/theme/echarts.mjs +8 -2
  64. package/esm2022/app/reports/theme/palette.mjs +19 -1
  65. package/esm2022/app/reports/theme/typography.mjs +4 -1
  66. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +1 -1
  67. package/esm2022/public_api.mjs +9 -1
  68. package/fesm2022/{firestitch-report-echarts-Djtmaxj1.mjs → firestitch-report-echarts-u5ImuZT5.mjs} +9 -3
  69. package/fesm2022/firestitch-report-echarts-u5ImuZT5.mjs.map +1 -0
  70. package/fesm2022/{firestitch-report-firestitch-report-D3zseBZc.mjs → firestitch-report-firestitch-report-Cz-kA_id.mjs} +3221 -660
  71. package/fesm2022/firestitch-report-firestitch-report-Cz-kA_id.mjs.map +1 -0
  72. package/fesm2022/firestitch-report.mjs +1 -1
  73. package/package.json +1 -1
  74. package/public_api.d.ts +8 -0
  75. package/fesm2022/firestitch-report-echarts-Djtmaxj1.mjs.map +0 -1
  76. 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 { isValid, parseISO } 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, DAY_SHORT, formatLocalDate, formatNumber, formatPlainNumber, hasNumberFormat, MONTH_DAY, MONTH_LONG, MONTH_YEAR, resolveChartNumberFormat, } 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_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,33 @@ 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
+ // The words a statistic line's label starts with. They are interface text,
54
+ // English in every report locale; only the value after them follows it.
55
+ export const STAT_LABEL = {
56
+ [ReportChartMarkStat.Average]: 'Average',
57
+ [ReportChartMarkStat.Median]: 'Median',
58
+ [ReportChartMarkStat.Min]: 'Minimum',
59
+ [ReportChartMarkStat.Max]: 'Maximum',
60
+ };
25
61
  // colorBy applies only to single-dimension bar charts, and only when splitBy
26
62
  // isn't already driving multiple series: it colors each bar by its category and
27
63
  // shows a legend (one series per category, overlapped to full width).
@@ -36,9 +72,9 @@ const AXIS_LABEL_FONT = `${REPORT_AXIS_LABEL_FONT_SIZE}px ${REPORT_CHART_FONT_FA
36
72
  //
37
73
  // A TIME axis is excluded: consecutive periods are one series moving, not
38
74
  // 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.
75
+ // unrelated groups. Explicitly opting out — colorBy: {column: ''}, a color on
76
+ // the measure or a config.legend of 'hidden' — still wins, so a caller that
77
+ // wants one flat color can say so.
42
78
  //
43
79
  // "Bar chart" is the type the lone measure is actually DRAWN as: its own type
44
80
  // when it names one, which can turn a line chart's single series into bars or
@@ -50,6 +86,10 @@ export function isColorBy(config) {
50
86
  if (config.colorBy) {
51
87
  return !!config.colorBy.column;
52
88
  }
89
+ // A measure given its own color asks for one flat color.
90
+ if (measureColorHex(config.measures?.[0])) {
91
+ return false;
92
+ }
53
93
  return (config.xAxis?.kind ?? 'category') === 'category'
54
94
  && !config.xAxis?.granularity
55
95
  && (config.measures?.length ?? 1) <= 1;
@@ -69,9 +109,7 @@ export function extractChartSeries(component, data) {
69
109
  // color + legend entry), but the bars are overlapped to full width in
70
110
  // buildAxisOption rather than laid side-by-side. splitBy wins if both are set.
71
111
  const groupColumn = splitColumn || colorByColumn(config);
72
- const measures = config.measures?.length
73
- ? config.measures
74
- : [{ column: data.columns[data.columns.length - 1] }];
112
+ const measures = chartMeasures(config, data);
75
113
  const rawCategories = uniqueValues(data.rows, xColumn);
76
114
  const categories = rawCategories.map((category) => String(category ?? '—'));
77
115
  const series = [];
@@ -89,11 +127,13 @@ export function extractChartSeries(component, data) {
89
127
  name: String(groupValue ?? '—'),
90
128
  values: rawCategories.map((category) => numeric(byCategory.get(category))),
91
129
  type: measure.type,
130
+ measure,
131
+ measureIndex: 0,
92
132
  });
93
133
  }
94
134
  }
95
135
  else {
96
- for (const measure of measures) {
136
+ for (const [measureIndex, measure] of measures.entries()) {
97
137
  const byCategory = new Map();
98
138
  for (const row of data.rows) {
99
139
  byCategory.set(row[xColumn], row[measure.column]);
@@ -102,11 +142,156 @@ export function extractChartSeries(component, data) {
102
142
  name: measure.label ?? measure.column,
103
143
  values: rawCategories.map((category) => numeric(byCategory.get(category))),
104
144
  type: measure.type,
145
+ measure,
146
+ measureIndex,
105
147
  });
106
148
  }
107
149
  }
108
150
  return { categories, series };
109
151
  }
152
+ // A series' own color as CSS hex: its measure's named color, or undefined when
153
+ // it names none (or a name the palette does not know) and the theme colors it
154
+ // by its position.
155
+ export function seriesColor(series) {
156
+ const hex = namedColorHex(series);
157
+ return hex ? `#${hex}` : undefined;
158
+ }
159
+ // A series' color as the bare hex PowerPoint takes: its measure's named color,
160
+ // else the palette color of its position, as the screen's theme picks it.
161
+ export function seriesHex(series, index) {
162
+ return namedColorHex(series) ?? REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length];
163
+ }
164
+ function namedColorHex(series) {
165
+ return measureColorHex(series.measure);
166
+ }
167
+ // A measure's named color as bare hex, or undefined when it names none or a
168
+ // name the palette does not know. The name is read through the enum, so a
169
+ // stored name such as '__proto__' never reaches the lookup object.
170
+ function measureColorHex(measure) {
171
+ const color = Object.values(ReportChartColor).find((name) => name === measure?.color);
172
+ return color ? REPORT_CHART_COLOR_BY_NAME[color] : undefined;
173
+ }
174
+ // A measure's line style when it names one ECharts knows, else undefined and
175
+ // the line is solid.
176
+ export function measureLineStyle(measure) {
177
+ return Object.values(ReportChartLineStyle).find((style) => style === measure?.line);
178
+ }
179
+ // A measure's statistic line when it names one the viewer knows, else
180
+ // undefined and it draws none.
181
+ export function measureMarkStat(measure) {
182
+ return Object.values(ReportChartMarkStat).find((stat) => stat === measure?.markLine);
183
+ }
184
+ // A series' statistic over its points that have a value: their mean, their
185
+ // median (the mean of the two middle values when the count is even), the
186
+ // lowest or the highest. null when no point has a value. Shared with the
187
+ // PowerPoint export so both media draw the line at the same height.
188
+ export function seriesStat(values, stat) {
189
+ const present = values.filter((value) => typeof value === 'number' && Number.isFinite(value));
190
+ if (!present.length) {
191
+ return null;
192
+ }
193
+ switch (stat) {
194
+ case ReportChartMarkStat.Average:
195
+ return present.reduce((sum, value) => sum + value, 0) / present.length;
196
+ case ReportChartMarkStat.Median: {
197
+ const sorted = [...present].sort((a, b) => a - b);
198
+ const middle = Math.floor(sorted.length / 2);
199
+ return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;
200
+ }
201
+ case ReportChartMarkStat.Min:
202
+ return Math.min(...present);
203
+ case ReportChartMarkStat.Max:
204
+ return Math.max(...present);
205
+ default:
206
+ return null;
207
+ }
208
+ }
209
+ // Whether a chart draws statistic lines. A horizontal chart's values run
210
+ // along x, and PowerPoint cannot draw a line beside horizontal bars, so
211
+ // neither medium draws one there.
212
+ export function drawsStatLines(config) {
213
+ return config.orientation !== 'horizontal';
214
+ }
215
+ // A colorBy chart's one value per category: series i holds category i's bar.
216
+ // PowerPoint draws these as its one series, and a statistic line is taken
217
+ // over them.
218
+ export function colorByValues(extracted) {
219
+ return extracted.categories.map((_, index) => extracted.series[index]?.values[index] ?? null);
220
+ }
221
+ // The references a chart draws. A vertical axis chart and a waterfall draw
222
+ // them; a pie has no value axis, and a horizontal chart is left without them
223
+ // as PowerPoint cannot draw a line beside horizontal bars. An entry without a
224
+ // finite value is skipped, and one whose `to` is missing or equal to its value
225
+ // is a line. secondary reaches the second value axis only on a chart that has
226
+ // one (twoAxes). Shared with the PowerPoint export.
227
+ export function chartReferences(config, twoAxes) {
228
+ const chartType = config.chartType ?? 'bar';
229
+ const references = Array.isArray(config.references) ? config.references : [];
230
+ if (config.orientation === 'horizontal' || chartType === 'pie' || chartType === 'donut') {
231
+ return [];
232
+ }
233
+ return references.flatMap((reference) => {
234
+ const value = axisNumber(reference?.value);
235
+ if (!reference || value === undefined) {
236
+ return [];
237
+ }
238
+ const to = axisNumber(reference.to);
239
+ const label = typeof reference.label === 'string' ? reference.label : '';
240
+ const axisIndex = twoAxes && reference.secondary === true ? 1 : 0;
241
+ return [to !== undefined && to !== value
242
+ ? { label, low: Math.min(value, to), high: Math.max(value, to), band: true, axisIndex }
243
+ : { label, low: value, high: value, band: false, axisIndex }];
244
+ });
245
+ }
246
+ // Each series as its share of its category's total: per category, the
247
+ // denominator is the sum of every series' absolute value there, so the
248
+ // magnitudes of a category's shares add up to 1. A mixed-sign category's
249
+ // negative values take negative shares, drawn below zero. A missing value
250
+ // stays missing, and a category whose total is zero has no shares. Shared by
251
+ // the screen, the PDF and PowerPoint, so a 100% stack reads the same in each.
252
+ export function percentShares(values) {
253
+ const length = Math.max(0, ...values.map((series) => series.length));
254
+ const totals = Array.from({ length }, (_, index) => values
255
+ .reduce((sum, series) => sum + Math.abs(series[index] ?? 0), 0));
256
+ return values.map((series) => series.map((value, index) => (value === null || !totals[index] ? null : value / totals[index])));
257
+ }
258
+ // The shares a 100% stacked chart draws in place of its values, or null when
259
+ // the chart is not one. The primary axis's bar and area series take them,
260
+ // each type's series sharing among themselves, as each type stacks apart.
261
+ // Lines and secondary-axis series keep their values. A pie, a waterfall and a
262
+ // colorBy chart (one series per category, each of which would be 100%) are
263
+ // never 100% stacked, nor is a chart with no bar or area on its primary axis.
264
+ export function percentStackedShares(extracted, config) {
265
+ const chartType = config.chartType ?? 'bar';
266
+ if (config.percentStacked !== true
267
+ || chartType === 'pie' || chartType === 'donut' || chartType === 'waterfall'
268
+ || isColorBy(config)) {
269
+ return null;
270
+ }
271
+ const types = seriesTypes(extracted, chartType);
272
+ const axisIndexes = seriesAxisIndexes(extracted, config);
273
+ const shares = new Map();
274
+ for (const type of ['bar', 'area']) {
275
+ const indexes = types
276
+ .map((seriesType, index) => (seriesType === type && axisIndexes[index] === 0 ? index : -1))
277
+ .filter((index) => index >= 0);
278
+ const typeShares = percentShares(indexes.map((index) => extracted.series[index].values));
279
+ indexes.forEach((seriesIndex, position) => shares.set(seriesIndex, typeShares[position]));
280
+ }
281
+ return shares.size ? shares : null;
282
+ }
283
+ // Where a 100% stacked chart's value axis starts: at -100% when any share is
284
+ // negative, else at zero.
285
+ export function percentAxisMin(shares) {
286
+ return [...shares.values()].some((series) => series.some((share) => (share ?? 0) < 0)) ? -1 : 0;
287
+ }
288
+ // The measures a chart plots: its configured ones, else the query's last
289
+ // column, unformatted.
290
+ function chartMeasures(config, data) {
291
+ return config.measures?.length
292
+ ? config.measures
293
+ : [{ column: data.columns[data.columns.length - 1] }];
294
+ }
110
295
  // The type each extracted series is drawn as: its measure's own type when it
111
296
  // names one, the chart's chartType otherwise. More than one distinct type is a
112
297
  // combo chart. Shared with the PowerPoint export so both media draw each series
@@ -114,6 +299,17 @@ export function extractChartSeries(component, data) {
114
299
  export function seriesTypes(extracted, chartType) {
115
300
  return extracted.series.map((series) => series.type ?? chartType);
116
301
  }
302
+ // The value axis each extracted series is plotted against: 1 when its measure
303
+ // is secondary, 0 otherwise. A second axis is drawn only on a vertical chart
304
+ // that keeps at least one series on the primary axis, so a combination the
305
+ // server refuses (a horizontal chart, every measure secondary, the one measure
306
+ // of a splitBy or colorBy chart) plots everything on the primary axis. Shared
307
+ // with the PowerPoint export so both media put each series on the same axis.
308
+ export function seriesAxisIndexes(extracted, config) {
309
+ const secondary = extracted.series.map((series) => !!series.measure.secondary);
310
+ const twoAxes = config.orientation !== 'horizontal' && secondary.includes(true) && secondary.includes(false);
311
+ return secondary.map((isSecondary) => (twoAxes && isSecondary ? 1 : 0));
312
+ }
117
313
  export const WATERFALL_TOTAL_LABEL = 'Total';
118
314
  // A waterfall's bars from its one measure: each category's value is how far the
119
315
  // running total moves there, and a last Total bar shows where it ended. A
@@ -136,18 +332,24 @@ export function extractWaterfall(component, data) {
136
332
  // endpoint's rows to an ECharts option. Everything visual that isn't in the
137
333
  // registered 'report' theme is decided here, so report standards have exactly
138
334
  // two homes.
139
- export function buildChartOption(component, data) {
335
+ //
336
+ // Every number and period the chart writes (value-axis ticks, tooltip values,
337
+ // period labels) is in the context's locale, never the browser's. A measure
338
+ // with number-format keys formats its tooltips, and the value axis when every
339
+ // measure on it agrees (axisNumberFormat); without them the axis and tooltips
340
+ // keep the plain locale-grouped number.
341
+ export function buildChartOption(component, data, context) {
140
342
  const config = component.config;
141
343
  const chartType = config.chartType ?? 'bar';
142
344
  if (chartType === 'pie' || chartType === 'donut') {
143
- return buildPieOption(component, data, chartType === 'donut');
345
+ return buildPieOption(component, data, chartType === 'donut', context);
144
346
  }
145
347
  if (chartType === 'waterfall') {
146
- return buildWaterfallOption(component, data);
348
+ return buildWaterfallOption(component, data, context);
147
349
  }
148
- return buildAxisOption(component, data, chartType);
350
+ return buildAxisOption(component, data, chartType, context);
149
351
  }
150
- function buildAxisOption(component, data, chartType) {
352
+ function buildAxisOption(component, data, chartType, context) {
151
353
  const config = component.config;
152
354
  const extracted = extractChartSeries(component, data);
153
355
  const horizontal = config.orientation === 'horizontal';
@@ -161,22 +363,221 @@ function buildAxisOption(component, data, chartType) {
161
363
  //
162
364
  // Stacking sums every series that shares a stack name, whatever its type. In
163
365
  // 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' };
366
+ // sits on top of the bars' total, and on a two-axis chart only with the
367
+ // series on its own axis.
368
+ //
369
+ // A 100% stacked chart (percentStackedShares) plots its primary bars and
370
+ // areas as shares, each type in its own stack, and leaves every other series
371
+ // unstacked on its own values.
372
+ const axisIndexes = seriesAxisIndexes(extracted, config);
373
+ const twoAxes = axisIndexes.includes(1);
374
+ const shares = percentStackedShares(extracted, config);
375
+ const references = chartReferences(config, twoAxes);
376
+ const axisFormats = valueAxisFormats(config, extracted, axisIndexes, context, !!shares, references);
377
+ // A series' statistic line is taken over the points it plots. On a colorBy
378
+ // chart each series holds one bar, so the one line is taken over the bars
379
+ // together and hangs off the first series (colorByStatLine).
380
+ const statLines = drawsStatLines(config) && !colorBy;
381
+ const series = extracted.series.map((extractedSeries, index) => {
382
+ const seriesShares = shares?.get(index);
383
+ let stack;
384
+ if (seriesShares) {
385
+ stack = stackKey(types[index], combo, 0);
386
+ }
387
+ else if (config.stacked && !shares) {
388
+ stack = stackKey(types[index], combo, twoAxes ? axisIndexes[index] : undefined);
389
+ }
390
+ const stat = statLines ? measureMarkStat(extractedSeries.measure) : undefined;
391
+ const markLine = stat && statMarkLine(seriesShares ?? extractedSeries.values, stat, seriesShares ? shareWriter(context) : measureWriter(extractedSeries.measure, context));
392
+ const option = buildSeries(extractedSeries, seriesShares ? shareData(extractedSeries.values, seriesShares) : extractedSeries.values, {
393
+ type: types[index],
394
+ stack,
395
+ overlap: colorBy && index === 0,
396
+ combo,
397
+ tooltip: seriesTooltip(extractedSeries.measure, context),
398
+ axisIndex: twoAxes ? axisIndexes[index] : undefined,
399
+ // A colorBy chart's bars take the palette by category, as in
400
+ // PowerPoint, whatever color the measure names.
401
+ color: colorBy ? undefined : seriesColor(extractedSeries),
402
+ labels: dataLabelOption(config.dataLabels, dataLabelFormatter(extractedSeries.measure, axisFormats[axisIndexes[index]] ?? null, !!seriesShares, context)),
403
+ });
404
+ return markLine ? { ...option, markLine } : option;
405
+ });
406
+ if (colorBy && drawsStatLines(config) && series.length) {
407
+ series[0] = colorByStatLine(series[0], extracted, context);
408
+ }
409
+ const percentMin = shares ? percentAxisMin(shares) : undefined;
410
+ const categoryAxis = categoryAxisOption(config, data, extracted.categories, horizontal, context.locale);
411
+ const valueAxis = twoAxes
412
+ ? twoValueAxesOption(config, axisFormats, context, percentMin, references)
413
+ : valueAxisOption(config.valueAxis, horizontal, percentMin === undefined
414
+ ? valueAxisLabel(axisFormats[0], context)
415
+ : percentAxisLabel(context), { percentMin, reach: referenceReach(references, 0) });
168
416
  const legendPosition = resolveLegendPosition(config, series.length, colorBy);
417
+ const valueTitles = [config.valueAxis, twoAxes ? config.secondaryAxis : undefined];
418
+ const granularity = bucketGranularity(data);
169
419
  return {
170
- grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal)),
171
- legend: legendOption(legendPosition),
420
+ grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal), valueTitleSide(valueTitles, horizontal)),
421
+ legend: referenceLegend(legendOption(legendPosition), series, references),
172
422
  // 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' },
423
+ // every category; an item tooltip shows just the hovered bar. A 100%
424
+ // stacked chart's tooltip gives each share and the value it came from.
425
+ tooltip: shares
426
+ ? {
427
+ trigger: 'axis',
428
+ formatter: (params) => percentTooltip(params, extracted, shares, granularity, chartDateLabel(config), context),
429
+ }
430
+ : { trigger: colorBy ? 'item' : 'axis' },
175
431
  xAxis: horizontal ? valueAxis : categoryAxis,
176
432
  yAxis: horizontal ? categoryAxis : valueAxis,
177
- series,
433
+ series: [...series, ...referenceCarriers(references, extracted.categories)],
178
434
  };
179
435
  }
436
+ // A colorBy chart's statistic line: one line over every bar, hung off the
437
+ // first series and drawn in the reference slate, as no one category's color
438
+ // speaks for the others.
439
+ function colorByStatLine(first, extracted, context) {
440
+ const measure = extracted.series[0]?.measure;
441
+ const stat = measureMarkStat(measure);
442
+ const markLine = stat && statMarkLine(colorByValues(extracted), stat, measureWriter(measure, context), `#${REPORT_REFERENCE_COLOR}`);
443
+ return markLine ? { ...first, markLine } : first;
444
+ }
445
+ // A series' statistic line across the plot, labeled with the statistic and
446
+ // its value ('Average: 1,234.5'), or undefined when no point has a value. It
447
+ // takes the series' color unless it is given one.
448
+ function statMarkLine(values, stat, write, color) {
449
+ const value = seriesStat(values, stat);
450
+ if (value === null) {
451
+ return undefined;
452
+ }
453
+ const text = `${STAT_LABEL[stat]}: ${write(value)}`;
454
+ return {
455
+ silent: true,
456
+ symbol: 'none',
457
+ lineStyle: { type: 'dashed', width: 1, ...(color ? { color } : {}) },
458
+ label: { formatter: () => text, position: 'insideEndTop', fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },
459
+ data: [{ yAxis: value }],
460
+ };
461
+ }
462
+ // A statistic's value in its measure's number format, in the report locale.
463
+ function measureWriter(measure, context) {
464
+ return (value) => formatNumber(value, measure, context);
465
+ }
466
+ // A 100% stacked series' statistic is a share, written as its tooltip writes
467
+ // one.
468
+ function shareWriter(context) {
469
+ const ratioContext = { ...context, ratioPercent: true };
470
+ return (value) => formatNumber(value, PERCENT_SHARE_FORMAT, ratioContext);
471
+ }
472
+ // The series that carry a chart's references, one per value axis that has
473
+ // any: an empty line (every point null, so it draws nothing and stretches no
474
+ // axis) whose markLine draws the reference lines and whose markArea fills the
475
+ // bands. It is silent, left out of the tooltip and, by referenceLegend, out of
476
+ // the legend. It has no name, so no measure series' legend entry (whatever its
477
+ // name, '' included) toggles it.
478
+ //
479
+ // Labels are functions, as a string formatter is a template that would read
480
+ // '{b}' or '{c}' in a label as a placeholder. ECharts draws a markArea under
481
+ // the bars and a markLine over them, so a band's label rides an invisible
482
+ // markLine on its upper edge, inside its top left corner, where the first bar
483
+ // would otherwise cover it.
484
+ function referenceCarriers(references, categories) {
485
+ const color = `#${REPORT_REFERENCE_COLOR}`;
486
+ return [0, 1].flatMap((axisIndex) => {
487
+ const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);
488
+ const lines = onAxis.filter((reference) => !reference.band);
489
+ const bands = onAxis.filter((reference) => reference.band);
490
+ if (!onAxis.length) {
491
+ return [];
492
+ }
493
+ return [{
494
+ type: 'line',
495
+ data: categories.map(() => null),
496
+ yAxisIndex: axisIndex,
497
+ silent: true,
498
+ tooltip: { show: false },
499
+ markLine: {
500
+ silent: true,
501
+ symbol: 'none',
502
+ lineStyle: { color, type: 'dashed', width: 1 },
503
+ label: { position: 'insideEndTop', color, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },
504
+ data: [
505
+ ...lines.map((reference) => ({ yAxis: reference.low, label: { formatter: () => reference.label } })),
506
+ ...bands.map((reference) => ({
507
+ yAxis: reference.high,
508
+ // Zero width, not zero opacity: a markLine's label takes the
509
+ // line's opacity.
510
+ lineStyle: { width: 0 },
511
+ label: { position: 'insideStartBottom', formatter: () => reference.label },
512
+ })),
513
+ ],
514
+ },
515
+ ...(bands.length ? {
516
+ markArea: {
517
+ silent: true,
518
+ itemStyle: { color: REFERENCE_BAND_FILL },
519
+ data: bands.map((reference) => [{ yAxis: reference.low }, { yAxis: reference.high }]),
520
+ },
521
+ } : {}),
522
+ }];
523
+ });
524
+ }
525
+ // The largest magnitude a value axis's references reach, which its number
526
+ // format counts toward its peak, as the axis stretches to them; 0 when it
527
+ // has none.
528
+ export function referencePeak(references, axisIndex) {
529
+ const reach = referenceReach(references, axisIndex);
530
+ return reach ? Math.max(Math.abs(reach.low), Math.abs(reach.high)) : 0;
531
+ }
532
+ // The legend of a chart with references names its measure series alone, so
533
+ // a carrier never shows as a blank entry. Without references it is left as it
534
+ // was.
535
+ function referenceLegend(legend, series, references) {
536
+ return references.length
537
+ ? { ...legend, data: series.map((item) => String(item.name ?? '')) }
538
+ : legend;
539
+ }
540
+ // The span of the references on one value axis, or undefined when it has
541
+ // none.
542
+ function referenceReach(references, axisIndex) {
543
+ const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);
544
+ return onAxis.length
545
+ ? { low: Math.min(...onAxis.map((reference) => reference.low)), high: Math.max(...onAxis.map((reference) => reference.high)) }
546
+ : undefined;
547
+ }
548
+ // ECharts leaves a markLine or markArea out of an axis's extent, so a
549
+ // reference beyond the data would fall off the plot. An axis bound the config
550
+ // does not pin reaches past the furthest reference, to a round number with
551
+ // room for its label (beyondReference), when the data (and the zero a value
552
+ // axis always shows) falls short of it, and is left to ECharts otherwise: a
553
+ // callback returning undefined keeps the bound automatic. Past the data and
554
+ // zero, a reference beyond the max is above zero and one beyond the min below
555
+ // it.
556
+ function reachMin(reach) {
557
+ return reach
558
+ ? (extent) => (reach.low < Math.min(extent.min, 0) ? -beyondReference(-reach.low) : undefined)
559
+ : undefined;
560
+ }
561
+ function reachMax(reach) {
562
+ return reach
563
+ ? (extent) => (reach.high > Math.max(extent.max, 0) ? beyondReference(reach.high) : undefined)
564
+ : undefined;
565
+ }
566
+ // The bound an axis takes past a reference of this (positive) magnitude: the
567
+ // smallest round number at or above it plus REFERENCE_HEADROOM. The steps are
568
+ // finer than ECharts' tick steps, so a reference just past the data does not
569
+ // double the axis (110 gives 120, not 200). The tolerance keeps a float error
570
+ // from skipping a round number the value already is.
571
+ const NICE_STEPS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10];
572
+ const NICE_TOLERANCE = 1e-9;
573
+ function beyondReference(magnitude) {
574
+ const target = magnitude * REFERENCE_HEADROOM;
575
+ const power = Math.pow(10, Math.floor(Math.log10(target)));
576
+ const step = NICE_STEPS.find((candidate) => candidate * power >= target * (1 - NICE_TOLERANCE)) ?? 10;
577
+ // Rounded back to the power's own digits, so 1.2 x 0.1 reads 0.12, not
578
+ // 0.12000000000000001.
579
+ return Number((step * power).toPrecision(12));
580
+ }
180
581
  // The category axis of an axis chart or a waterfall: the categories in row
181
582
  // order, labeled as periods when the rows were bucketed by time.
182
583
  //
@@ -184,30 +585,46 @@ function buildAxisOption(component, data, chartType) {
184
585
  // axis is inverted to put the first row (the largest of a top-N, a waterfall's
185
586
  // first step) at the top. The rotated title sits just beyond the longest label
186
587
  // rather than at a fixed gap that would put it on top of the labels.
187
- function categoryAxisOption(config, data, categories, horizontal) {
588
+ //
589
+ // A bucketed axis also names its period in the axis tooltip's header: ECharts
590
+ // heads it with the raw category ('2026-01-01') unless the axis pointer's label
591
+ // has a formatter, so it reads 'January 2026' instead, always with its year.
592
+ // The axis's dateLabel style writes both its tick labels and that header.
593
+ function categoryAxisOption(config, data, categories, horizontal, locale) {
188
594
  const granularity = bucketGranularity(data);
189
- const periodLabel = periodAxisLabel(granularity, categories);
595
+ const dateLabel = chartDateLabel(config);
596
+ const periodLabel = periodAxisLabel(granularity, categories, locale, dateLabel);
190
597
  const axis = {
191
598
  type: 'category',
192
599
  data: categories,
193
600
  inverse: horizontal,
194
601
  name: config.xAxis?.label,
195
602
  nameLocation: 'middle',
603
+ ...(granularity ? {
604
+ axisPointer: {
605
+ label: {
606
+ formatter: (params) => formatPeriodLabel(String(params.value), granularity, true, locale, dateLabel),
607
+ },
608
+ },
609
+ } : {}),
196
610
  };
197
611
  if (!horizontal) {
612
+ // The gap clears the year's second line when the labels print one.
613
+ const secondLine = granularity && dateLabel === ReportChartDateLabel.Short && spansMultipleYears(categories);
198
614
  return {
199
615
  ...axis,
200
- nameGap: granularity && spansMultipleYears(categories) ? 40 : 28,
616
+ nameGap: secondLine ? 40 : 28,
201
617
  ...periodLabel,
202
618
  };
203
619
  }
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.
620
+ // Period labels, short, long or numeric ('May', 'Q2', 'May 2026'), are
621
+ // bounded in length and never cut; only a plain category is truncated. The labels are cut here rather than by ECharts' own
622
+ // truncation, so the title's gap is measured on exactly the text the axis
623
+ // draws.
207
624
  const shown = granularity
208
625
  ? null
209
626
  : new Map(categories.map((category) => [category, truncateAxisLabel(category)]));
210
- const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity);
627
+ const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity, locale, dateLabel);
211
628
  return {
212
629
  ...axis,
213
630
  nameGap: widestAxisLabel(labels) + AXIS_LABEL_MARGIN + AXIS_NAME_CLEARANCE,
@@ -222,12 +639,22 @@ function categoryTitleSide(config, horizontal) {
222
639
  }
223
640
  return horizontal ? 'left' : 'bottom';
224
641
  }
642
+ // The value axes' title side, or null when none of them has a title. A
643
+ // vertical chart's titles sit above the plot, at the top of each axis line, so
644
+ // room is made once for both; a horizontal chart's sits below.
645
+ function valueTitleSide(axes, horizontal) {
646
+ if (!axes.some((axis) => axis?.label)) {
647
+ return null;
648
+ }
649
+ return horizontal ? 'bottom' : 'top';
650
+ }
225
651
  // 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) {
652
+ // ('May', 'Q2', 'May 2026'), otherwise the category itself. The year a
653
+ // multi-year axis prints under a short period is left out, as it is never the
654
+ // wider line.
655
+ function displayedCategoryLabels(categories, granularity, locale, dateLabel) {
229
656
  return granularity
230
- ? categories.map((category) => periodLabelParts(category, granularity)?.primary ?? category)
657
+ ? categories.map((category) => periodLabelParts(category, granularity, locale, dateLabel)?.primary ?? category)
231
658
  : categories;
232
659
  }
233
660
  // The pixel width of the widest label. A label that breaks over several lines
@@ -273,26 +700,32 @@ function axisLabelWidth(line) {
273
700
  axisLabelContext.font = AXIS_LABEL_FONT;
274
701
  return axisLabelContext.measureText(line).width;
275
702
  }
276
- function buildWaterfallOption(component, data) {
703
+ function buildWaterfallOption(component, data, context) {
277
704
  const config = component.config;
278
705
  const waterfall = extractWaterfall(component, data);
279
706
  const horizontal = config.orientation === 'horizontal';
280
- const categoryAxis = categoryAxisOption(config, data, waterfall.steps.map((step) => step.category), horizontal);
281
- const valueAxis = { type: 'value' };
707
+ const categories = waterfall.steps.map((step) => step.category);
708
+ const categoryAxis = categoryAxisOption(config, data, categories, horizontal, context.locale);
709
+ // The one measure's format writes the axis and the tooltip. The axis has to
710
+ // reach the furthest point the running total gets to, on either side of
711
+ // zero, or the furthest reference.
712
+ const spec = config.measures?.[0];
713
+ const references = chartReferences(config, false);
714
+ 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
715
  // One visible series, so the legend is hidden unless the config pins it.
283
716
  const legendPosition = resolveLegendPosition(config, 1);
284
717
  const granularity = bucketGranularity(data);
285
718
  return {
286
- grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal)),
719
+ grid: axisGrid(legendPosition, categoryTitleSide(config, horizontal), valueTitleSide([config.valueAxis], horizontal)),
287
720
  legend: { ...legendOption(legendPosition), data: [waterfall.name] },
288
721
  // Per bar: the invisible base is silent, so only a step answers the hover.
289
722
  tooltip: {
290
723
  trigger: 'item',
291
- formatter: (params) => waterfallTooltip(waterfall, (Array.isArray(params) ? params[0] : params).dataIndex, granularity),
724
+ formatter: (params) => waterfallTooltip(waterfall, (Array.isArray(params) ? params[0] : params).dataIndex, granularity, chartDateLabel(config), spec, context),
292
725
  },
293
726
  xAxis: horizontal ? valueAxis : categoryAxis,
294
727
  yAxis: horizontal ? categoryAxis : valueAxis,
295
- series: waterfallSeries(waterfall),
728
+ series: [...waterfallSeries(waterfall), ...referenceCarriers(references, categories)],
296
729
  };
297
730
  }
298
731
  // An invisible base series lifts each visible bar to where its step starts.
@@ -329,17 +762,22 @@ function waterfallSeries(waterfall) {
329
762
  // A step's tooltip: its period, how far it moved the running total and where
330
763
  // that left it. The closing Total shows the total alone. The category and the
331
764
  // 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) {
765
+ // as HTML, so both are escaped. Periods and amounts are written in the report's
766
+ // locale, amounts in the measure's number format (a plain number without one);
767
+ // the words ('Running total') stay English.
768
+ function waterfallTooltip(waterfall, index, granularity, dateLabel, spec, context) {
334
769
  const step = waterfall.steps[index];
335
- const category = escapeHtml(granularity ? formatPeriodLabel(step.category, granularity, true) : step.category);
770
+ const category = escapeHtml(granularity
771
+ ? formatPeriodLabel(step.category, granularity, true, context.locale, dateLabel)
772
+ : step.category);
336
773
  const name = escapeHtml(waterfall.name);
774
+ const amount = (value) => formatNumber(value, spec ?? {}, context);
337
775
  if (step.kind === 'total') {
338
- return `${category}<br/>${name}: ${formatMeasureValue(step.change)}`;
776
+ return `${category}<br/>${name}: ${amount(step.change)}`;
339
777
  }
340
778
  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))}`;
779
+ return `${category}<br/>${name}: ${sign}${amount(step.change)}`
780
+ + `<br/>Running total: ${amount(step.start + (step.change ?? 0))}`;
343
781
  }
344
782
  // Default legend placement when the config doesn't pin one: pie charts read
345
783
  // best with the slice key beside them (right); axis charts only need a legend
@@ -372,18 +810,10 @@ function legendOption(position) {
372
810
  }
373
811
  }
374
812
  // 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
- }
813
+ // bars/lines, plus room for the category and value axes' titles on their
814
+ // sides, which containLabel does not reserve (it covers the tick labels only).
815
+ function axisGrid(position, categoryTitle, valueTitle) {
816
+ return [categoryTitle, valueTitle].reduce((grid, side) => (side ? { ...grid, [side]: grid[side] + AXIS_NAME_ROOM } : grid), legendGrid(position));
387
817
  }
388
818
  // Plot-edge room on whichever side the legend occupies; containLabel keeps the
389
819
  // tick labels inside what is left.
@@ -402,32 +832,308 @@ function legendGrid(position) {
402
832
  return { ...base, top: 32 };
403
833
  }
404
834
  }
405
- function buildSeries(name, values, type, stack, overlap, combo) {
406
- if (type === 'bar') {
835
+ // The stack a stacked series joins. On a two-axis chart (axisIndex set) each
836
+ // type stacks per axis; otherwise a combo stacks per type and a single-type
837
+ // chart stacks everything together.
838
+ function stackKey(type, combo, axisIndex) {
839
+ if (axisIndex !== undefined) {
840
+ return `total-${type}-${axisIndex}`;
841
+ }
842
+ return combo ? `total-${type}` : 'total';
843
+ }
844
+ // One series of an axis chart. A measure's display keys only add what they
845
+ // change, so a series that sets none is drawn by the theme as before: its own
846
+ // color (the bar, the line, the area under it and its legend key all follow
847
+ // itemStyle), its line style and its markers, shown on every point unless
848
+ // markers is false. Data labels come last, on the series or on its latest
849
+ // point.
850
+ function buildSeries(series, values, layout) {
851
+ // On a two-axis chart every series names its value axis.
852
+ const axis = layout.axisIndex === undefined ? {} : { yAxisIndex: layout.axisIndex };
853
+ const color = layout.color;
854
+ const itemStyle = color ? { itemStyle: { color } } : {};
855
+ if (layout.type === 'bar') {
856
+ // 'outside' follows each bar's sign: past a positive bar's end and below
857
+ // (or left of) a negative one's, where 'top' would sit at the zero line.
858
+ const { series: labels, data } = placeDataLabels(layout.labels, layout.stack ? 'inside' : 'outside', values);
407
859
  return {
408
- name,
860
+ name: series.name,
409
861
  type: 'bar',
410
- data: values,
411
- stack,
862
+ data,
863
+ stack: layout.stack,
864
+ tooltip: layout.tooltip,
865
+ ...axis,
866
+ ...itemStyle,
412
867
  barMaxWidth: 48,
413
868
  // colorBy: overlap the per-category series so each bar renders full-width.
414
- ...(overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),
869
+ ...(layout.overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),
870
+ ...labels,
415
871
  };
416
872
  }
873
+ const lineType = measureLineStyle(series.measure);
874
+ const lineStyle = color || lineType
875
+ ? { lineStyle: { ...(color ? { color } : {}), ...(lineType ? { type: lineType } : {}) } }
876
+ : {};
877
+ const { series: labels, data } = placeDataLabels(layout.labels, 'top', values);
417
878
  return {
418
- name,
879
+ name: series.name,
419
880
  type: 'line',
420
- data: values,
421
- stack,
881
+ data,
882
+ stack: layout.stack,
883
+ tooltip: layout.tooltip,
884
+ ...axis,
885
+ ...itemStyle,
886
+ ...lineStyle,
887
+ ...(series.measure.markers === false ? { showSymbol: false } : {}),
422
888
  smooth: true,
423
889
  symbolSize: 6,
424
- areaStyle: type === 'area' ? { opacity: 0.25 } : undefined,
890
+ areaStyle: layout.type === 'area' ? { opacity: 0.25 } : undefined,
425
891
  // In a combo the line is drawn over the bars whatever order the measures
426
892
  // come in; at the same z a later bar series would paint across it.
427
- ...(combo ? { z: 3 } : {}),
893
+ ...(layout.combo ? { z: 3 } : {}),
894
+ ...labels,
895
+ };
896
+ }
897
+ // A 100% stacked series' points: each share, plotted and stacked, with the
898
+ // value it came from.
899
+ function shareData(values, shares) {
900
+ return values.map((raw, index) => ({ value: shares[index] ?? null, raw }));
901
+ }
902
+ // What a series prints beside its points (A2 data labels): every point
903
+ // ('all'), every point whose label fits without overlapping another ('auto',
904
+ // LabelLayout's hideOverlap), or only its latest point ('last'). none, an
905
+ // absent mode or one the viewer does not know prints nothing, and the series
906
+ // is left as it was. A colorBy chart's series each hold one bar, so 'last'
907
+ // labels every bar there, as 'all' does.
908
+ //
909
+ // Where the label sits depends on what the series draws, so buildSeries
910
+ // places it (placeDataLabels).
911
+ export function dataLabelOption(mode, formatter) {
912
+ const text = { show: true, fontSize: REPORT_DATA_LABEL_FONT_SIZE, formatter };
913
+ switch (mode) {
914
+ case ReportChartDataLabels.All:
915
+ return { text, hideOverlap: false, lastOnly: false };
916
+ case ReportChartDataLabels.Auto:
917
+ return { text, hideOverlap: true, lastOnly: false };
918
+ case ReportChartDataLabels.Last:
919
+ return { text, hideOverlap: false, lastOnly: true };
920
+ default:
921
+ return null;
922
+ }
923
+ }
924
+ // A series' data labels at `position`: on the series ('all', and with the
925
+ // overlap hiding 'auto'), or on its latest non-empty point alone ('last').
926
+ // No labels leave the series and its points as they were.
927
+ function placeDataLabels(labels, position, values) {
928
+ if (!labels) {
929
+ return { series: {}, data: values };
930
+ }
931
+ const label = { ...labels.text, position };
932
+ if (labels.lastOnly) {
933
+ return { series: {}, data: labelLastPoint(values, label) };
934
+ }
935
+ return {
936
+ series: { label, ...(labels.hideOverlap ? { labelLayout: { hideOverlap: true } } : {}) },
937
+ data: values,
938
+ };
939
+ }
940
+ // A series' points with its latest non-empty point carrying the label. A
941
+ // series with no value anywhere is left as it was.
942
+ function labelLastPoint(values, label) {
943
+ const pointValue = (item) => (isShareDataItem(item) ? item.value : item);
944
+ const last = values.reduce((found, item, index) => (pointValue(item) === null ? found : index), -1);
945
+ return values.map((item, index) => {
946
+ if (index !== last) {
947
+ return item;
948
+ }
949
+ return isShareDataItem(item) ? { ...item, label } : { value: item, label };
950
+ });
951
+ }
952
+ function isShareDataItem(item) {
953
+ return item !== null && typeof item === 'object';
954
+ }
955
+ // How a series' data labels write a value. A 100% stacked series prints its
956
+ // share as a whole percentage, as the share axis's ticks do. A series on an
957
+ // axis with a number format prints its value in its measure's format, at the
958
+ // units and decimals the axis decided, so a label reads like the ticks beside
959
+ // it. Any other prints the plain locale-grouped number its tooltip shows. A
960
+ // share point's raw value is what a label reads when it carries one.
961
+ function dataLabelFormatter(measure, axisFormat, share, context) {
962
+ if (share) {
963
+ const percent = wholePercentFormatter(context);
964
+ return (params) => percent(params.value);
965
+ }
966
+ if (axisFormat) {
967
+ const options = { units: axisFormat.chart.units, decimals: axisFormat.chart.decimals };
968
+ return (params) => formatNumber(dataLabelValue(params), measure, context, options);
969
+ }
970
+ return (params) => formatPlainNumber(dataLabelValue(params), context.locale);
971
+ }
972
+ // The value a data label writes: the raw value its point carries, else the
973
+ // plotted one.
974
+ function dataLabelValue(params) {
975
+ const data = params.data;
976
+ const raw = data !== null && typeof data === 'object' ? data.raw : undefined;
977
+ return raw ?? params.value;
978
+ }
979
+ // A 100% stacked chart's tooltip: the category, then each series on its own
980
+ // line, a share as its percentage to one decimal followed by the value it came
981
+ // from in its measure's format ('25.0% (1)'), and any other series by its own
982
+ // value. The category and the series names come from the data and the config,
983
+ // and ECharts sets the tooltip as HTML, so both are escaped.
984
+ function percentTooltip(params, extracted, shares, granularity, dateLabel, context) {
985
+ const items = Array.isArray(params) ? params : [params];
986
+ const dataIndex = items[0]?.dataIndex ?? 0;
987
+ const category = extracted.categories[dataIndex] ?? '';
988
+ const heading = escapeHtml(granularity
989
+ ? formatPeriodLabel(category, granularity, true, context.locale, dateLabel)
990
+ : category);
991
+ const ratioContext = { ...context, ratioPercent: true };
992
+ const lines = items.map((item) => {
993
+ const series = extracted.series[item.seriesIndex ?? -1];
994
+ const marker = typeof item.marker === 'string' ? item.marker : '';
995
+ const label = `${marker} ${escapeHtml(item.seriesName ?? series?.name ?? '')}`;
996
+ const value = seriesTooltip(series?.measure, context).valueFormatter(series?.values[item.dataIndex] ?? null);
997
+ const share = shares.get(item.seriesIndex ?? -1)?.[item.dataIndex] ?? null;
998
+ return share === null
999
+ ? `${label}: ${value}`
1000
+ : `${label}: ${formatNumber(share, PERCENT_SHARE_FORMAT, ratioContext)} (${value})`;
1001
+ });
1002
+ return [heading, ...lines].join('<br/>');
1003
+ }
1004
+ // A value axis: its title and range from the config, its tick labels from
1005
+ // valueAxisLabel. A vertical chart's title sits above the axis line, reading
1006
+ // away from the plot's edge; a horizontal chart's is centered below the ticks.
1007
+ // A bound or interval that is not a usable number is left to ECharts. A 100%
1008
+ // stacked chart's share axis (extras.percentMin) has its own fixed range.
1009
+ function valueAxisOption(axis, horizontal, axisLabel, extras = {}) {
1010
+ const range = extras.percentMin === undefined
1011
+ ? valueAxisRange(axis)
1012
+ : { min: extras.percentMin, max: PERCENT_AXIS_MAX, interval: PERCENT_AXIS_INTERVAL };
1013
+ return {
1014
+ type: 'value',
1015
+ name: axis?.label || undefined,
1016
+ nameLocation: horizontal ? 'middle' : 'end',
1017
+ nameGap: horizontal ? 28 : 10,
1018
+ nameTextStyle: horizontal ? undefined : { align: extras.index === 1 ? 'right' : 'left' },
1019
+ // A pinned bound wins; one left open reaches the references (reachMin).
1020
+ min: range.min ?? reachMin(extras.reach),
1021
+ max: range.max ?? reachMax(extras.reach),
1022
+ interval: range.interval,
1023
+ axisLabel,
1024
+ };
1025
+ }
1026
+ // The part of a value axis's range the config pins. A bound that is not a
1027
+ // finite number, or an interval that is not a positive one, is left out, and
1028
+ // the chart picks it from the data. Shared with the PowerPoint export so both
1029
+ // media draw the same range.
1030
+ export function valueAxisRange(axis) {
1031
+ const interval = axisNumber(axis?.interval);
1032
+ return {
1033
+ min: axisNumber(axis?.min),
1034
+ max: axisNumber(axis?.max),
1035
+ interval: interval !== undefined && interval > 0 ? interval : undefined,
1036
+ };
1037
+ }
1038
+ // A two-axis chart's value axes: the primary on the left, the second on the
1039
+ // right without gridlines of its own. Each axis's ticks take the format of the
1040
+ // measures plotted against it. Without a range on either axis the second axis
1041
+ // aligns its ticks to the primary's gridlines.
1042
+ //
1043
+ // On a 100% stacked chart (percentMin set) the primary axis is the share axis,
1044
+ // whose range is fixed, and the second axis's series are not stacked.
1045
+ function twoValueAxesOption(config, axisFormats, context, percentMin, references) {
1046
+ const percent = percentMin !== undefined;
1047
+ const label = (axisIndex) => valueAxisLabel(axisFormats[axisIndex] ?? null, context);
1048
+ return [
1049
+ valueAxisOption(config.valueAxis, false, percent ? percentAxisLabel(context) : label(0), {
1050
+ index: 0,
1051
+ percentMin,
1052
+ reach: referenceReach(references, 0),
1053
+ }),
1054
+ {
1055
+ ...valueAxisOption(config.secondaryAxis, false, label(1), { index: 1, reach: referenceReach(references, 1) }),
1056
+ position: 'right',
1057
+ splitLine: { show: false },
1058
+ alignTicks: !percent && !hasAxisRange(config.valueAxis) && !hasAxisRange(config.secondaryAxis),
1059
+ },
1060
+ ];
1061
+ }
1062
+ // Whether the config pins any of an axis's range: a bound or a tick interval.
1063
+ function hasAxisRange(axis) {
1064
+ return Object.values(valueAxisRange(axis)).some((value) => value !== undefined);
1065
+ }
1066
+ // A configured bound or interval when it is a finite number, else undefined.
1067
+ function axisNumber(value) {
1068
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
1069
+ }
1070
+ // Tick labels written in the locale. ECharts' own ticks are grouped en-US
1071
+ // whatever the page's language.
1072
+ //
1073
+ // With a number format, the units and decimals decided once for the whole
1074
+ // axis (resolveValueAxisFormat) write every tick alike ('1.5K', '2.0K', never
1075
+ // '2K'). Without one, or when it leaves the ticks an unscaled number with no
1076
+ // pinned decimals (format 'number', or precision-less units none), each tick
1077
+ // is a plain locale-grouped number keeping its own decimals, so a 0.0002 tick
1078
+ // never rounds to '0'.
1079
+ function valueAxisLabel(format, context) {
1080
+ if (!format || (format.chart.units === ReportNumberUnits.None && format.chart.decimals === null)) {
1081
+ return { formatter: (value) => formatPlainNumber(value, context.locale) };
1082
+ }
1083
+ const options = { units: format.chart.units, decimals: format.chart.decimals };
1084
+ return {
1085
+ formatter: (value) => formatNumber(value, format.spec, context, options),
428
1086
  };
429
1087
  }
430
- function buildPieOption(component, data, donut) {
1088
+ // An axis's format from the spec its measures agree on, with the units and
1089
+ // decimals decided from its peak. Without a spec the axis is plain, and the
1090
+ // peak is never computed.
1091
+ function resolveValueAxisFormat(spec, peak, context) {
1092
+ return spec ? { spec, chart: resolveChartNumberFormat(spec, peak(), context) } : null;
1093
+ }
1094
+ // Each value axis's format, by axis index. A chart with one value axis takes
1095
+ // the format the plotted series' measures agree on (a splitBy or colorBy chart
1096
+ // 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
1097
+ // plotted against it, from the peak of its own series, which are never
1098
+ // stacked with a 100% stacked chart's shares. A reference past the data
1099
+ // stretches its axis, so it counts toward the peak (referencePeak); a 100%
1100
+ // stacked chart's references are shares, which the raw values' peak leaves
1101
+ // out.
1102
+ function valueAxisFormats(config, extracted, axisIndexes, context, percent, references) {
1103
+ const reach = (axisIndex) => (percent && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));
1104
+ if (!axisIndexes.includes(1)) {
1105
+ return [resolveValueAxisFormat(axisNumberFormat(extracted.series.map((series) => series.measure)), () => Math.max(chartValuePeak(extracted.series.map((series) => series.values), !!config.stacked), reach(0)), context)];
1106
+ }
1107
+ return [0, 1].map((axisIndex) => {
1108
+ const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);
1109
+ return resolveValueAxisFormat(axisNumberFormat(onAxis.map((series) => series.measure)), () => Math.max(chartValuePeak(onAxis.map((series) => series.values), !!config.stacked && !percent), reach(axisIndex)), context);
1110
+ });
1111
+ }
1112
+ // A 100% stacked chart's share axis ticks: whole percentages in the locale
1113
+ // ('25%', '25 %' in fr-CA). The shares are ratios whatever the report's
1114
+ // percentFormat says of its stored values.
1115
+ function percentAxisLabel(context) {
1116
+ return { formatter: wholePercentFormatter(context) };
1117
+ }
1118
+ // A share as a whole percentage in the locale, for the share axis's ticks and
1119
+ // its series' data labels.
1120
+ function wholePercentFormatter(context) {
1121
+ const ratioContext = { ...context, ratioPercent: true };
1122
+ return (value) => formatNumber(value, PERCENT_AXIS_FORMAT, ratioContext);
1123
+ }
1124
+ // A series' tooltip value in its measure's number format, per value ('—' when
1125
+ // empty). A measure without one writes it as the plain value axis does. A
1126
+ // value can arrive as an array (a [value, ...] data item), whose first entry
1127
+ // is the value.
1128
+ function seriesTooltip(measure, context) {
1129
+ if (!hasNumberFormat(measure)) {
1130
+ return { valueFormatter: (value) => formatPlainNumber(value, context.locale) };
1131
+ }
1132
+ return {
1133
+ valueFormatter: (value) => formatNumber(Array.isArray(value) ? value[0] : value, measure, context),
1134
+ };
1135
+ }
1136
+ function buildPieOption(component, data, donut, context) {
431
1137
  const config = component.config;
432
1138
  const extracted = extractChartSeries(component, data);
433
1139
  const values = extracted.series[0]?.values ?? [];
@@ -440,6 +1146,7 @@ function buildPieOption(component, data, donut) {
440
1146
  type: 'pie',
441
1147
  radius: donut ? ['45%', '72%'] : '72%',
442
1148
  center: pieCenter(legendPosition),
1149
+ tooltip: seriesTooltip(extracted.series[0]?.measure, context),
443
1150
  label: { show: false },
444
1151
  data: extracted.categories.map((category, index) => ({
445
1152
  name: category,
@@ -503,55 +1210,118 @@ export function spansMultipleYears(categories) {
503
1210
  }
504
1211
  return years.size > 1;
505
1212
  }
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) {
1213
+ // A time axis's date label style when its config names one the viewer knows,
1214
+ // else short.
1215
+ export function chartDateLabel(config) {
1216
+ return Object.values(ReportChartDateLabel).find((style) => style === config?.xAxis?.dateLabel)
1217
+ ?? ReportChartDateLabel.Short;
1218
+ }
1219
+ // A bucket's period-start split into its primary label and its year. A year
1220
+ // reads "2025" in every style. Short, in the locale: day/week read "May 1"
1221
+ // ('1 mai' in fr-CA), month "May" ('mai'), quarter "Q2" ('T2' in French).
1222
+ // Long carries its year, in the locale: "May 1, 2026", "May 2026" ('mai
1223
+ // 2026'), "Q2 2026". Numeric is the same in every locale: "2026-05-01",
1224
+ // "2026-05", "2026-Q2". Returns null for a value that isn't a parseable date
1225
+ // (left as-is by callers).
1226
+ function periodLabelParts(value, granularity, locale, dateLabel = ReportChartDateLabel.Short) {
510
1227
  const date = parseISO(value);
511
1228
  if (!isValid(date)) {
512
1229
  return null;
513
1230
  }
514
1231
  const year = String(date.getFullYear());
1232
+ if (granularity === 'year') {
1233
+ return { primary: year, year };
1234
+ }
1235
+ return { primary: periodPrimaryLabel(date, granularity, locale, dateLabel), year };
1236
+ }
1237
+ // A period's label in the style asked for, the year aside (see
1238
+ // periodLabelParts).
1239
+ function periodPrimaryLabel(date, granularity, locale, dateLabel) {
1240
+ const year = String(date.getFullYear());
1241
+ const quarter = Math.floor(date.getMonth() / 3) + 1;
1242
+ if (dateLabel === ReportChartDateLabel.Numeric) {
1243
+ const month = String(date.getMonth() + 1).padStart(2, '0');
1244
+ const day = String(date.getDate()).padStart(2, '0');
1245
+ switch (granularity) {
1246
+ case 'quarter':
1247
+ return `${year}-Q${quarter}`;
1248
+ case 'month':
1249
+ return `${year}-${month}`;
1250
+ default: // day, week — the bucket start
1251
+ return `${year}-${month}-${day}`;
1252
+ }
1253
+ }
1254
+ const long = dateLabel === ReportChartDateLabel.Long;
515
1255
  switch (granularity) {
516
- case 'year':
517
- return { primary: year, year };
518
1256
  case 'quarter':
519
- return { primary: `Q${Math.floor(date.getMonth() / 3) + 1}`, year };
1257
+ return long
1258
+ ? `${quarterPrefix(locale)}${quarter} ${year}`
1259
+ : `${quarterPrefix(locale)}${quarter}`;
520
1260
  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 };
1261
+ return formatLocalDate(date, locale, long ? MONTH_YEAR : MONTH_LONG);
1262
+ default: // day, week — the bucket start as a month and day
1263
+ return formatLocalDate(date, locale, long ? DAY_SHORT : MONTH_DAY);
524
1264
  }
525
1265
  }
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);
1266
+ // Whether a period label leaves its year to be added apart: only a short one
1267
+ // does, a long or numeric label already carries it.
1268
+ function periodYearApart(granularity, dateLabel) {
1269
+ return granularity !== 'year' && dateLabel === ReportChartDateLabel.Short;
1270
+ }
1271
+ function quarterPrefix(locale) {
1272
+ return QUARTER_PREFIXES.get(locale.split('-')[0].toLowerCase()) ?? QUARTER_PREFIX;
1273
+ }
1274
+ // A compact single-line period label — for media that can't do a styled
1275
+ // second line, e.g. PowerPoint. A short label has its year appended only when
1276
+ // the data spans years; a long or numeric one always carries it.
1277
+ export function formatPeriodLabel(value, granularity, multiYear, locale, dateLabel = ReportChartDateLabel.Short) {
1278
+ const parts = periodLabelParts(value, granularity, locale, dateLabel);
530
1279
  if (!parts) {
531
1280
  return value;
532
1281
  }
533
- return multiYear && granularity !== 'year' ? `${parts.primary} ${parts.year}` : parts.primary;
1282
+ return multiYear && periodYearApart(granularity, dateLabel) ? `${parts.primary} ${parts.year}` : parts.primary;
534
1283
  }
535
1284
  // A cross-tab's column headings, the one rule the grid and the PDF/PowerPoint
536
1285
  // exports share. The first is the row key and keeps its authored label; the
537
1286
  // rest are pivot VALUES. When the pivot axis is a time dimension the server
538
1287
  // 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) {
1288
+ // "January 2026" ('janvier 2026' in fr-CA), as the chart's x-axis labels it.
1289
+ export function pivotHeadings(config, data, locale) {
541
1290
  const columns = data.columns ?? [];
542
1291
  const multiYear = spansMultipleYears(columns);
543
1292
  return columns.map((column, index) => {
544
1293
  if (index === 0) {
545
1294
  return config.rowBy?.label || column;
546
1295
  }
547
- return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear) : column;
1296
+ return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear, locale) : column;
548
1297
  });
549
1298
  }
1299
+ // A cross-tab's columns as the grid and the exports draw them: each headed by
1300
+ // pivotHeadings(), and every pivot-value column formatted by the one
1301
+ // config.cellFormat. The row key column stays as it came. `numeric` marks the
1302
+ // columns whose cells are formatted numbers, which are right-aligned.
1303
+ export function pivotColumnSpecs(config, data, locale) {
1304
+ const headings = pivotHeadings(config, data, locale);
1305
+ const cellFormat = config.cellFormat;
1306
+ const numeric = hasNumberFormat(cellFormat);
1307
+ const cells = numeric && cellFormat
1308
+ ? { format: listColumnFormat(cellFormat.format), precision: cellFormat.precision, units: cellFormat.units }
1309
+ : {};
1310
+ return (data.columns ?? []).map((column, index) => index === 0
1311
+ ? { column, label: headings[index], numeric: false }
1312
+ : { column, label: headings[index], ...cells, numeric });
1313
+ }
1314
+ // A number format's style as a list column's format: the two enums share
1315
+ // their number values.
1316
+ function listColumnFormat(format) {
1317
+ return Object.values(ReportListColumnFormat).find((value) => value === format);
1318
+ }
550
1319
  // ECharts category-axis label config for a time bucket: the primary label on
551
1320
  // line one, and — only when the data spans multiple years — the year on a small
552
1321
  // 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) {
1322
+ // line, it already is the year, and neither does a long or numeric label,
1323
+ // which carries its year). Empty for a non-time axis (labels as-is).
1324
+ function periodAxisLabel(granularity, categories, locale, dateLabel) {
555
1325
  if (!granularity) {
556
1326
  return {};
557
1327
  }
@@ -559,11 +1329,11 @@ function periodAxisLabel(granularity, categories) {
559
1329
  return {
560
1330
  axisLabel: {
561
1331
  formatter: (value) => {
562
- const parts = periodLabelParts(value, granularity);
1332
+ const parts = periodLabelParts(value, granularity, locale, dateLabel);
563
1333
  if (!parts) {
564
1334
  return value;
565
1335
  }
566
- return multiYear && granularity !== 'year'
1336
+ return multiYear && periodYearApart(granularity, dateLabel)
567
1337
  ? `${parts.primary}\n{yr|${parts.year}}`
568
1338
  : parts.primary;
569
1339
  },
@@ -571,4 +1341,4 @@ function periodAxisLabel(granularity, categories) {
571
1341
  },
572
1342
  };
573
1343
  }
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==
1344
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvb3B0aW9uLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFN0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDNUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDNUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDaEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUNMLGdCQUFnQixFQUVoQixjQUFjLEVBQ2QsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixTQUFTLEVBQ1QsVUFBVSxFQUNWLFVBQVUsRUFDVix3QkFBd0IsR0FDekIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQVFMLG1CQUFtQixHQVNwQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLHVCQUF1QixHQUN4QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSx3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QXFFO0FBQ3JFLFNBQVMsZUFBZSxDQUN0QixXQUFvQyxFQUNwQyxVQUFvQixFQUNwQixNQUF1QixFQUN2QixTQUErQjtJQUUvQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakIsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFakQsT0FBTztRQUNMLFNBQVMsRUFBRTtZQUNULFNBQVMsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFO2dCQUMzQixNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNYLE9BQU8sS0FBSyxDQUFDO2dCQUNmLENBQUM7Z0JBRUQsT0FBTyxTQUFTLElBQUksZUFBZSxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUM7b0JBQ3pELENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLFNBQVMsS0FBSyxDQUFDLElBQUksR0FBRztvQkFDeEMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDcEIsQ0FBQztZQUNELElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDakU7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgTGVnZW5kQ29tcG9uZW50T3B0aW9uLCBTZXJpZXNPcHRpb24sIFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcyB9IGZyb20gJ2VjaGFydHMnO1xuXG5pbXBvcnQgeyBpc1ZhbGlkLCBwYXJzZUlTTyB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgUmVwb3J0Q2hhcnRDb2xvciB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWNvbG9yLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnREYXRhTGFiZWxzIH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtY2hhcnQtZGF0YS1sYWJlbHMuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydERhdGVMYWJlbCB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWRhdGUtbGFiZWwuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydExpbmVTdHlsZSB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWxpbmUtc3R5bGUuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydE1hcmtTdGF0IH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtY2hhcnQtbWFyay1zdGF0LmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0TGlzdENvbHVtbkZvcm1hdCB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWxpc3QtY29sdW1uLWZvcm1hdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydE51bWJlclVuaXRzIH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtbnVtYmVyLXVuaXRzLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0VmFsdWVGb3JtYXQgfSBmcm9tICcuL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtYXQuZW51bSc7XG5pbXBvcnQge1xuICBheGlzTnVtYmVyRm9ybWF0LFxuICBDaGFydE51bWJlckZvcm1hdCxcbiAgY2hhcnRWYWx1ZVBlYWssXG4gIERBWV9TSE9SVCxcbiAgZm9ybWF0TG9jYWxEYXRlLFxuICBmb3JtYXROdW1iZXIsXG4gIGZvcm1hdFBsYWluTnVtYmVyLFxuICBoYXNOdW1iZXJGb3JtYXQsXG4gIE1PTlRIX0RBWSxcbiAgTU9OVEhfTE9ORyxcbiAgTU9OVEhfWUVBUixcbiAgcmVzb2x2ZUNoYXJ0TnVtYmVyRm9ybWF0LFxufSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBBeGlzQ2hhcnRUeXBlLFxuICBDaGFydENvbmZpZyxcbiAgQ2hhcnRHcmFudWxhcml0eSxcbiAgQ2hhcnRNZWFzdXJlLFxuICBDaGFydFJlZmVyZW5jZSxcbiAgQ2hhcnRWYWx1ZUF4aXMsXG4gIENvbXBvbmVudERhdGEsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIExlZ2VuZFBvc2l0aW9uLFxuICBMaXN0Q29sdW1uLFxuICBMaXN0Q29uZmlnLFxuICBOdW1iZXJGb3JtYXRTcGVjLFxuICBSZXBvcnRDb21wb25lbnQsXG4gIFJlcG9ydEZvcm1hdENvbnRleHQsXG4gIFJlcG9ydExvY2FsZVRhZyxcbiAgV2F0ZXJmYWxsU3RlcEtpbmQsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tICcuL3RleHQnO1xuaW1wb3J0IHtcbiAgUkVQT1JUX0NIQVJUX0NPTE9SX0JZX05BTUUsXG4gIFJFUE9SVF9DSEFSVF9DT0xPUlMsXG4gIFJFUE9SVF9SRUZFUkVOQ0VfQ09MT1IsXG4gIFJFUE9SVF9XQVRFUkZBTExfQ09MT1JTLFxufSBmcm9tICcuL3RoZW1lL3BhbGV0dGUnO1xuaW1wb3J0IHsgUkVQT1JUX0FYSVNfTEFCRUxfRk9OVF9TSVpFLCBSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFksIFJFUE9SVF9EQVRBX0xBQkVMX0ZPTlRfU0laRSB9IGZyb20gJy4vdGhlbWUvdHlwb2dyYXBoeSc7XG5cblxuLy8gUm9vbSBmb3IgYW4gYXhpcyB0aXRsZS4gRUNoYXJ0cyA1J3MgY29udGFpbkxhYmVsIGtlZXBzIHRoZSBUSUNLIGxhYmVscyBpbnNpZGVcbi8vIHRoZSBncmlkIGJ1dCBub3QgdGhlIGF4aXMgbmFtZSwgc28gd2l0aG91dCB0aGlzIGEgdmVydGljYWwgY2hhcnQncyBjYXRlZ29yeVxuLy8gdGl0bGUgcnVucyBvZmYgdGhlIGJvdHRvbSBlZGdlIG9yIHVuZGVyIGEgYm90dG9tIGxlZ2VuZCwgYW5kIGl0cyB2YWx1ZSB0aXRsZVxuLy8gYWJvdmUgdGhlIHBsb3QgcnVucyBvZmYgdGhlIHRvcCBvciB1bmRlciBhIHRvcCBsZWdlbmQuXG5jb25zdCBBWElTX05BTUVfUk9PTSA9IDIwO1xuLy8gRUNoYXJ0cycgb3duIGRlZmF1bHQgZ2FwIGJldHdlZW4gdGhlIGF4aXMgbGluZSBhbmQgaXRzIHRpY2sgbGFiZWxzLlxuY29uc3QgQVhJU19MQUJFTF9NQVJHSU4gPSA4O1xuLy8gQ2xlYXJhbmNlIGJldHdlZW4gdGhlIGxvbmdlc3QgdGljayBsYWJlbCBhbmQgYSBob3Jpem9udGFsIGNoYXJ0J3Mgcm90YXRlZFxuLy8gdGl0bGUsIHNvIHRoZSB0d28gbmV2ZXIgdG91Y2guXG5jb25zdCBBWElTX05BTUVfQ0xFQVJBTkNFID0gNjtcbi8vIEEgaG9yaXpvbnRhbCBjaGFydCdzIGNhdGVnb3J5IGxhYmVscyBhcmUgY3V0IHNob3J0IHdpdGggYW4gZWxsaXBzaXMgcGFzdFxuLy8gdGhpcyB3aWR0aCAodGhlIHRvb2x0aXAgc3RpbGwgc2hvd3MgdGhlbSBpbiBmdWxsKSwgc28gb25lIGxvbmcgbGFiZWwgY2Fubm90XG4vLyBzcXVlZXplIHRoZSBwbG90IGF3YXkuXG5jb25zdCBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEggPSAxNjA7XG5jb25zdCBMQUJFTF9FTExJUFNJUyA9ICfigKYnO1xuLy8gVGhlIGZvbnQgdGhlIHRoZW1lIGRyYXdzIGF4aXMgbGFiZWxzIGluLCBhcyBhIGNhbnZhcyBmb250IHN0cmluZy4gTGFiZWxzIGFyZVxuLy8gbWVhc3VyZWQgaW4gaXQgdGhlIHdheSBFQ2hhcnRzIG1lYXN1cmVzIHRoZW0gZm9yIGNvbnRhaW5MYWJlbCwgc28gYVxuLy8gaG9yaXpvbnRhbCBjaGFydCdzIHRpdGxlIGxhbmRzIGV4YWN0bHkgYmV5b25kIHRoZSB3aWRlc3QgbGFiZWwuXG5jb25zdCBBWElTX0xBQkVMX0ZPTlQgPSBgJHtSRVBPUlRfQVhJU19MQUJFTF9GT05UX1NJWkV9cHggJHtSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFl9YDtcbi8vIFRoZSBsZXR0ZXIgYSBxdWFydGVyIGxhYmVsIHN0YXJ0cyB3aXRoLCBieSBsYW5ndWFnZSBzdWJ0YWcuIEZyZW5jaCB3cml0ZXMgdGhlXG4vLyBzZWNvbmQgcXVhcnRlciAnVDInICh0cmltZXN0cmUpOyBldmVyeSBvdGhlciBsYW5ndWFnZSByZWFkcyAnUTInLlxuY29uc3QgUVVBUlRFUl9QUkVGSVhFUyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFtbJ2ZyJywgJ1QnXV0pO1xuY29uc3QgUVVBUlRFUl9QUkVGSVggPSAnUSc7XG4vLyBBIDEwMCUgc3RhY2tlZCBjaGFydCdzIHZhbHVlIGF4aXM6IHdob2xlIHBlcmNlbnRhZ2VzLCBhIGdyaWRsaW5lIGV2ZXJ5IDI1JSxcbi8vIHVwIHRvIDEwMCUuIEl0cyB0b29sdGlwIGdpdmVzIGVhY2ggc2hhcmUgdG8gb25lIGRlY2ltYWwuXG5jb25zdCBQRVJDRU5UX0FYSVNfRk9STUFUOiBOdW1iZXJGb3JtYXRTcGVjID0geyBmb3JtYXQ6IFJlcG9ydFZhbHVlRm9ybWF0LlBlcmNlbnQsIHByZWNpc2lvbjogMCB9O1xuY29uc3QgUEVSQ0VOVF9TSEFSRV9GT1JNQVQ6IE51bWJlckZvcm1hdFNwZWMgPSB7IGZvcm1hdDogUmVwb3J0VmFsdWVGb3JtYXQuUGVyY2VudCwgcHJlY2lzaW9uOiAxIH07XG5leHBvcnQgY29uc3QgUEVSQ0VOVF9BWElTX01BWCA9IDE7XG5leHBvcnQgY29uc3QgUEVSQ0VOVF9BWElTX0lOVEVSVkFMID0gMC4yNTtcbi8vIEEgcmVmZXJlbmNlIGJhbmQncyBmaWxsOiB0aGUgcmVmZXJlbmNlIHNsYXRlLCBmYWludCBlbm91Z2ggdGhhdCB0aGUgc2VyaWVzXG4vLyBkcmF3biBhY3Jvc3MgaXQgc3RheSByZWFkYWJsZS5cbmNvbnN0IFJFRkVSRU5DRV9CQU5EX0ZJTEwgPSAncmdiYSg4MiwgOTYsIDEwOSwgMC4wOCknO1xuLy8gQSByZWZlcmVuY2UncyBvciBzdGF0aXN0aWMgbGluZSdzIGxhYmVsIHNpdHMgb24gYSBsaWdodCBib3gsIHNvIGl0IHN0YXlzXG4vLyByZWFkYWJsZSB3aGVyZSBpdCBjcm9zc2VzIGEgYmFyIG9yIGEgbGluZS5cbmNvbnN0IE1BUktfTEFCRUxfQk9YID0geyBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuODUpJywgcGFkZGluZzogWzEsIDNdLCBib3JkZXJSYWRpdXM6IDIgfTtcbi8vIFRoZSByb29tIGFuIGF4aXMgc3RyZXRjaGVkIHRvIGEgcmVmZXJlbmNlIGxlYXZlcyBhYm92ZSBpdCwgZm9yIGl0cyBsYWJlbDpcbi8vIHRoZSBib3VuZCBpcyB0aGUgcm91bmQgbnVtYmVyIGF0IG9yIHBhc3QgdGhlIHJlZmVyZW5jZSBwbHVzIHRoaXMgc2hhcmUuXG5jb25zdCBSRUZFUkVOQ0VfSEVBRFJPT00gPSAxLjA1O1xuXG4vLyBUaGUgd29yZHMgYSBzdGF0aXN0aWMgbGluZSdzIGxhYmVsIHN0YXJ0cyB3aXRoLiBUaGV5IGFyZSBpbnRlcmZhY2UgdGV4dCxcbi8vIEVuZ2xpc2ggaW4gZXZlcnkgcmVwb3J0IGxvY2FsZTsgb25seSB0aGUgdmFsdWUgYWZ0ZXIgdGhlbSBmb2xsb3dzIGl0LlxuZXhwb3J0IGNvbnN0IFNUQVRfTEFCRUw6IFJlY29yZDxSZXBvcnRDaGFydE1hcmtTdGF0LCBzdHJpbmc+ID0ge1xuICBbUmVwb3J0Q2hhcnRNYXJrU3RhdC5BdmVyYWdlXTogJ0F2ZXJhZ2UnLFxuICBbUmVwb3J0Q2hhcnRNYXJrU3RhdC5NZWRpYW5dOiAnTWVkaWFuJyxcbiAgW1JlcG9ydENoYXJ0TWFya1N0YXQuTWluXTogJ01pbmltdW0nLFxuICBbUmVwb3J0Q2hhcnRNYXJrU3RhdC5NYXhdOiAnTWF4aW11bScsXG59O1xuXG4vLyBXaGljaCBlZGdlIG9mIHRoZSBwbG90IGFuIGF4aXMgdGl0bGUgc2l0cyBvbi4gVGhlIGNhdGVnb3J5IGF4aXMncyBpcyBiZWxvdyBhXG4vLyB2ZXJ0aWNhbCBjaGFydCBhbmQgdG8gdGhlIGxlZnQgb2YgYSBob3Jpem9udGFsIG9uZTsgdGhlIHZhbHVlIGF4aXMncyBpcyBhYm92ZVxuLy8gYSB2ZXJ0aWNhbCBjaGFydCBhbmQgYmVsb3cgYSBob3Jpem9udGFsIG9uZS5cbnR5cGUgQXhpc1RpdGxlU2lkZSA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCc7XG5cbi8vIFdoaWNoIHZhbHVlIGF4aXMgYSBzZXJpZXMgaXMgcGxvdHRlZCBhZ2FpbnN0OiAwIHRoZSBwcmltYXJ5LCAxIHRoZSBzZWNvbmRcbi8vIGF4aXMgb24gdGhlIHJpZ2h0LlxuZXhwb3J0IHR5cGUgVmFsdWVBeGlzSW5kZXggPSAwIHwgMTtcblxuLy8gV2hhdCB2YWx1ZUF4aXNPcHRpb24gYWRkcyBmb3Igb25lIGF4aXMuIGBpbmRleGAgaXMgdGhlIGF4aXMgb2YgYSB0d28tYXhpc1xuLy8gY2hhcnQgaXQgYnVpbGRzOiB0aGUgc2Vjb25kIG9uZSdzIHRpdGxlIGlzIGFsaWduZWQgdG8gcmVhZCBsZWZ0d2FyZCBmcm9tIHRoZVxuLy8gcmlnaHQgZWRnZS4gYHBlcmNlbnRNaW5gIG1ha2VzIGl0IGEgMTAwJSBzdGFja2VkIGNoYXJ0J3Mgc2hhcmUgYXhpcywgZnJvbVxuLy8gdGhhdCBib3VuZCAoMCwgb3IgLTEgd2hlbiBhIHNoYXJlIGlzIG5lZ2F0aXZlKSB1cCB0byAxMDAlLCB3aGF0ZXZlciByYW5nZVxuLy8gdGhlIGNvbmZpZyBwaW5zLiBgcmVhY2hgIGlzIHRoZSBzcGFuIG9mIHRoZSByZWZlcmVuY2VzIHBsb3R0ZWQgYWdhaW5zdCBpdCxcbi8vIHdoaWNoIHRoZSBheGlzIHN0cmV0Y2hlcyB0byB3aGVuIHRoZSBkYXRhIGZhbGxzIHNob3J0IG9mIHRoZW0uXG5pbnRlcmZhY2UgVmFsdWVBeGlzRXh0cmFzIHtcbiAgaW5kZXg/OiBWYWx1ZUF4aXNJbmRleDtcbiAgcGVyY2VudE1pbj86IG51bWJlcjtcbiAgcmVhY2g/OiBSZWZlcmVuY2VSZWFjaDtcbn1cblxuLy8gQSByZWZlcmVuY2UgYXMgdGhlIGNoYXJ0IGRyYXdzIGl0OiBpdHMgbG93ZXIgYW5kIHVwcGVyIGVkZ2UgKHRoZSBzYW1lIHZhbHVlXG4vLyBmb3IgYSBsaW5lKSwgd2hldGhlciBpdCBpcyBhIGJhbmQsIGFuZCB0aGUgdmFsdWUgYXhpcyBpdCBpcyBwbG90dGVkIGFnYWluc3QuXG4vLyBTaGFyZWQgd2l0aCB0aGUgUG93ZXJQb2ludCBleHBvcnQsIHdoaWNoIGRyYXdzIGVhY2ggZWRnZSBhcyBhIGNvbnN0YW50IGxpbmUuXG5leHBvcnQgaW50ZXJmYWNlIERyYXduUmVmZXJlbmNlIHtcbiAgbGFiZWw6IHN0cmluZztcbiAgbG93OiBudW1iZXI7XG4gIGhpZ2g6IG51bWJlcjtcbiAgYmFuZDogYm9vbGVhbjtcbiAgYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleDtcbn1cblxuLy8gVGhlIGxvd2VzdCBhbmQgaGlnaGVzdCBlZGdlIG9mIHRoZSByZWZlcmVuY2VzIG9uIG9uZSB2YWx1ZSBheGlzLlxuaW50ZXJmYWNlIFJlZmVyZW5jZVJlYWNoIHtcbiAgbG93OiBudW1iZXI7XG4gIGhpZ2g6IG51bWJlcjtcbn1cblxuLy8gV2hhdCBFQ2hhcnRzIGhhbmRzIGEgdmFsdWUgYXhpcydzIG1pbiBhbmQgbWF4IGNhbGxiYWNrczogdGhlIGV4dGVudCBvZiB0aGVcbi8vIGRhdGEgcGxvdHRlZCBhZ2FpbnN0IGl0LlxuaW50ZXJmYWNlIEF4aXNFeHRlbnQge1xuICBtaW46IG51bWJlcjtcbiAgbWF4OiBudW1iZXI7XG59XG5cbi8vIE9uZSBwb2ludCBvZiBhIDEwMCUgc3RhY2tlZCBzZXJpZXM6IGl0cyBzaGFyZSBvZiB0aGUgY2F0ZWdvcnkncyB0b3RhbCxcbi8vIHdoaWNoIEVDaGFydHMgcGxvdHMgYW5kIHN0YWNrcywgYW5kIHRoZSB2YWx1ZSBpdCBjYW1lIGZyb20uXG5pbnRlcmZhY2UgU2hhcmVEYXRhSXRlbSB7XG4gIHZhbHVlOiBudW1iZXIgfCBudWxsO1xuICByYXc6IG51bWJlciB8IG51bGw7XG59XG5cbi8vIEEgcG9pbnQgdGhhdCBwcmludHMgaXRzIG93biBkYXRhIGxhYmVsOiBhICdsYXN0JyBzZXJpZXMnIGxhdGVzdCBwb2ludCxcbi8vIGtlZXBpbmcgdGhlIHJhdyB2YWx1ZSBhIDEwMCUgc3RhY2tlZCBwb2ludCBjYXJyaWVzLlxuaW50ZXJmYWNlIExhYmVsZWREYXRhSXRlbTxQIGV4dGVuZHMgRGF0YUxhYmVsUG9zaXRpb24+IHtcbiAgdmFsdWU6IG51bWJlciB8IG51bGw7XG4gIHJhdz86IG51bWJlciB8IG51bGw7XG4gIGxhYmVsOiBEYXRhTGFiZWw8UD47XG59XG5cbnR5cGUgU2VyaWVzRGF0YUl0ZW08UCBleHRlbmRzIERhdGFMYWJlbFBvc2l0aW9uPiA9IG51bWJlciB8IG51bGwgfCBTaGFyZURhdGFJdGVtIHwgTGFiZWxlZERhdGFJdGVtPFA+O1xuXG4vLyBXaGF0IGEgZGF0YSBsYWJlbCdzIGZvcm1hdHRlciBpcyBoYW5kZWQ6IHRoZSBwb2ludCdzIHBsb3R0ZWQgdmFsdWUgYW5kIGl0c1xuLy8gZGF0YSBpdGVtIGFzIGdpdmVuIChhIG51bWJlciwgb3IgYW4gb2JqZWN0IGNhcnJ5aW5nIHRoZSByYXcgdmFsdWUpLlxuaW50ZXJmYWNlIERhdGFMYWJlbFBhcmFtcyB7XG4gIHZhbHVlPzogdW5rbm93bjtcbiAgZGF0YT86IHVua25vd247XG59XG5cbmV4cG9ydCB0eXBlIERhdGFMYWJlbEZvcm1hdHRlciA9IChwYXJhbXM6IERhdGFMYWJlbFBhcmFtcykgPT4gc3RyaW5nO1xuXG4vLyBXaGVyZSBhIGRhdGEgbGFiZWwgc2l0czogJ291dHNpZGUnIHBhc3QgYW4gdW5zdGFja2VkIGJhcidzIGVuZCwgb24gdGhlIHNpZGVcbi8vIGl0cyBzaWduIHBvaW50cyB0bzsgJ2luc2lkZScgYSBzdGFja2VkIGJhcjsgJ3RvcCcgYWJvdmUgYSBsaW5lIG9yIGFyZWFcbi8vIHBvaW50LiBFQ2hhcnRzIHRha2VzICdvdXRzaWRlJyBvbiBhIGJhciBvbmx5LlxuZXhwb3J0IHR5cGUgRGF0YUxhYmVsUG9zaXRpb24gPSAndG9wJyB8ICdpbnNpZGUnIHwgJ291dHNpZGUnO1xuXG4vLyBPbmUgRUNoYXJ0cyBsYWJlbCwgYXMgYSBzZXJpZXMgb3IgYSBzaW5nbGUgcG9pbnQgcHJpbnRzIGl0LlxuZXhwb3J0IGludGVyZmFjZSBEYXRhTGFiZWw8UCBleHRlbmRzIERhdGFMYWJlbFBvc2l0aW9uID0gRGF0YUxhYmVsUG9zaXRpb24+IHtcbiAgc2hvdzogdHJ1ZTtcbiAgcG9zaXRpb246IFA7XG4gIGZvbnRTaXplOiBudW1iZXI7XG4gIGZvcm1hdHRlcjogRGF0YUxhYmVsRm9ybWF0dGVyO1xufVxuXG4vLyBBIHNlcmllcycgZGF0YSBsYWJlbHMgYXMgZGF0YUxhYmVsT3B0aW9uIGRlY2lkZXMgdGhlbSwgYmVmb3JlIGJ1aWxkU2VyaWVzXG4vLyBwbGFjZXMgdGhlbSBieSB3aGF0IHRoZSBzZXJpZXMgZHJhd3M6IHRoZSBsYWJlbCdzIHRleHQgYW5kIHNpemUsIHdoZXRoZXJcbi8vIGxhYmVscyB0aGF0IHdvdWxkIG92ZXJsYXAgYXJlIGhpZGRlbiAoJ2F1dG8nKSwgYW5kIHdoZXRoZXIgb25seSB0aGUgbGF0ZXN0XG4vLyBwb2ludCBwcmludHMgb25lICgnbGFzdCcpLlxuZXhwb3J0IGludGVyZmFjZSBTZXJpZXNEYXRhTGFiZWxzIHtcbiAgdGV4dDogT21pdDxEYXRhTGFiZWwsICdwb3NpdGlvbic+O1xuICBoaWRlT3ZlcmxhcDogYm9vbGVhbjtcbiAgbGFzdE9ubHk6IGJvb2xlYW47XG59XG5cbi8vIEEgc2VyaWVzJyBkYXRhIGxhYmVscyBwbGFjZWQ6IGBzZXJpZXNgIGlzIHNwcmVhZCBvdmVyIHRoZSBzZXJpZXMgKGl0c1xuLy8gbGFiZWwsIGFuZCBmb3IgJ2F1dG8nIHRoZSBvdmVybGFwIGhpZGluZyksIGFuZCBgZGF0YWAgaXMgaXRzIHBvaW50cywgdGhlXG4vLyBsYXRlc3Qgbm9uLWVtcHR5IG9uZSBjYXJyeWluZyB0aGUgbGFiZWwgZm9yICdsYXN0Jy5cbmludGVyZmFjZSBQbGFjZWREYXRhTGFiZWxzPFAgZXh0ZW5kcyBEYXRhTGFiZWxQb3NpdGlvbj4ge1xuICBzZXJpZXM6IHsgbGFiZWw/OiBEYXRhTGFiZWw8UD47IGxhYmVsTGF5b3V0PzogeyBoaWRlT3ZlcmxhcDogYm9vbGVhbiB9IH07XG4gIGRhdGE6IFNlcmllc0RhdGFJdGVtPFA+W107XG59XG5cbi8vIEEgdmFsdWUgYXhpcydzIG51bWJlciBmb3JtYXQsIGRlY2lkZWQgb25jZSBmb3IgdGhlIGF4aXM6IHRoZSBmb3JtYXQgdGhlXG4vLyBtZWFzdXJlcyBwbG90dGVkIGFnYWluc3QgaXQgYWdyZWUgb24gKGF4aXNOdW1iZXJGb3JtYXQpLCB3aXRoIHRoZSB1bml0cyBhbmRcbi8vIGRlY2ltYWxzIGl0cyBwZWFrIGNhbGxzIGZvci4gbnVsbCBpcyBhIHBsYWluIGF4aXMuIEl0cyB0aWNrcyBhbmQgaXRzIHNlcmllcydcbi8vIGRhdGEgbGFiZWxzIGJvdGggd3JpdGUgaW4gaXQuXG5pbnRlcmZhY2UgVmFsdWVBeGlzRm9ybWF0IHtcbiAgc3BlYzogTnVtYmVyRm9ybWF0U3BlYztcbiAgY2hhcnQ6IENoYXJ0TnVtYmVyRm9ybWF0O1xufVxuXG4vLyBUaGUgc2hhcmVzIGEgMTAwJSBzdGFja2VkIGNoYXJ0IGRyYXdzLCBieSB0aGUgaW5kZXggb2YgdGhlIGV4dHJhY3RlZCBzZXJpZXNcbi8vIHRoZXkgcmVwbGFjZS5cbmV4cG9ydCB0eXBlIFBlcmNlbnRTaGFyZXMgPSBNYXA8bnVtYmVyLCAobnVtYmVyIHwgbnVsbClbXT47XG5cbi8vIFRoZSBwbG90J3MgZGlzdGFuY2UgZnJvbSBlYWNoIGVkZ2Ugb2YgdGhlIGNoYXJ0LCBpbiBwaXhlbHMuXG5pbnRlcmZhY2UgQXhpc0dyaWRSb29tIHtcbiAgbGVmdDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIGNvbnRhaW5MYWJlbDogYm9vbGVhbjtcbn1cblxuXG4vLyBjb2xvckJ5IGFwcGxpZXMgb25seSB0byBzaW5nbGUtZGltZW5zaW9uIGJhciBjaGFydHMsIGFuZCBvbmx5IHdoZW4gc3BsaXRCeVxuLy8gaXNuJ3QgYWxyZWFkeSBkcml2aW5nIG11bHRpcGxlIHNlcmllczogaXQgY29sb3JzIGVhY2ggYmFyIGJ5IGl0cyBjYXRlZ29yeSBhbmRcbi8vIHNob3dzIGEgbGVnZW5kIChvbmUgc2VyaWVzIHBlciBjYXRlZ29yeSwgb3ZlcmxhcHBlZCB0byBmdWxsIHdpZHRoKS5cbi8vXG4vLyBJdCBpcyB0aGUgREVGQVVMVCBmb3IgYSBjYXRlZ29yaWNhbCBiYXIgY2hhcnQgcmF0aGVyIHRoYW4gc29tZXRoaW5nIHRoZSBjb25maWdcbi8vIGhhcyB0byBhc2sgZm9yLiBBIGJhciBjaGFydCB3aG9zZSB4LWF4aXMgaXMgYSBjYXRlZ29yeSDigJQgcmVnaW9ucywgc3RhdHVzZXMsXG4vLyBzdG9yZXMg4oCUIGlzIGNvbXBhcmluZyB0aG9zZSBjYXRlZ29yaWVzIHRvIGVhY2ggb3RoZXIsIGFuZCBvbmUgZmxhdCBjb2xvciB3aXRoXG4vLyBubyBsZWdlbmQgaXMgdGhlIHdyb25nIHJlYWRpbmcgb2YgaXQgaW4gZXNzZW50aWFsbHkgZXZlcnkgY2FzZS4gUmVxdWlyaW5nXG4vLyBjb2xvckJ5IHRvIG9wdCBpbiBtZWFudCBldmVyeSBzdWNoIGNoYXJ0IHJlbmRlcmVkIG1vbm9jaHJvbWUgdW5sZXNzIHdob2V2ZXJcbi8vIHdyb3RlIHRoZSBjb25maWcgcmVtZW1iZXJlZCBhbiBvcHRpb25hbCBwcm9wZXJ0eSwgd2hpY2ggaXMgYSBkZWZhdWx0IHNldCB0aGVcbi8vIHdyb25nIHdheSByb3VuZDogdGhlIGNvbW1vbiBjYXNlIHNob3VsZCBub3QgbmVlZCB0aGUgZmxhZy5cbi8vXG4vLyBBIFRJTUUgYXhpcyBpcyBleGNsdWRlZDogY29uc2VjdXRpdmUgcGVyaW9kcyBhcmUgb25lIHNlcmllcyBtb3ZpbmcsIG5vdFxuLy8gY2F0ZWdvcmllcyBiZWluZyBjb21wYXJlZCwgYW5kIGNvbG9yaW5nIGVhY2ggbW9udGggZGlmZmVyZW50bHkgcmVhZHMgYXNcbi8vIHVucmVsYXRlZCBncm91cHMuIEV4cGxpY2l0bHkgb3B0aW5nIG91dCDigJQgY29sb3JCeToge2NvbHVtbjogJyd9LCBhIGNvbG9yIG9uXG4vLyB0aGUgbWVhc3VyZSBvciBhIGNvbmZpZy5sZWdlbmQgb2YgJ2hpZGRlbicg4oCUIHN0aWxsIHdpbnMsIHNvIGEgY2FsbGVyIHRoYXRcbi8vIHdhbnRzIG9uZSBmbGF0IGNvbG9yIGNhbiBzYXkgc28uXG4vL1xuLy8gXCJCYXIgY2hhcnRcIiBpcyB0aGUgdHlwZSB0aGUgbG9uZSBtZWFzdXJlIGlzIGFjdHVhbGx5IERSQVdOIGFzOiBpdHMgb3duIHR5cGVcbi8vIHdoZW4gaXQgbmFtZXMgb25lLCB3aGljaCBjYW4gdHVybiBhIGxpbmUgY2hhcnQncyBzaW5nbGUgc2VyaWVzIGludG8gYmFycyBvclxuLy8gYSBiYXIgY2hhcnQncyBpbnRvIGEgbGluZS5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yQnkoY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW4ge1xuICBpZiAoY29uZmlnLnNwbGl0Qnk/LmNvbHVtbiB8fCAoY29uZmlnLm1lYXN1cmVzPy5bMF0/LnR5cGUgPz8gY29uZmlnLmNoYXJ0VHlwZSA/PyAnYmFyJykgIT09ICdiYXInKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5jb2xvckJ5KSB7XG4gICAgcmV0dXJuICEhY29uZmlnLmNvbG9yQnkuY29sdW1uO1xuICB9XG5cbiAgLy8gQSBtZWFzdXJlIGdpdmVuIGl0cyBvd24gY29sb3IgYXNrcyBmb3Igb25lIGZsYXQgY29sb3IuXG4gIGlmIChtZWFzdXJlQ29sb3JIZXgoY29uZmlnLm1lYXN1cmVzPy5bMF0pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIChjb25maWcueEF4aXM/LmtpbmQgPz8gJ2NhdGVnb3J5JykgPT09ICdjYXRlZ29yeSdcbiAgICAmJiAhY29uZmlnLnhBeGlzPy5ncmFudWxhcml0eVxuICAgICYmIChjb25maWcubWVhc3VyZXM/Lmxlbmd0aCA/PyAxKSA8PSAxO1xufVxuXG5cbi8vIFRoZSBjb2x1bW4gY29sb3JCeSBncm91cHMgYnkg4oCUIGl0cyBvd24gd2hlbiB0aGUgY29uZmlnIG5hbWVkIG9uZSwgb3RoZXJ3aXNlXG4vLyB0aGUgeC1heGlzIGl0IGRlZmF1bHRzIHRvIGNvbG9yaW5nLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yQnlDb2x1bW4oY29uZmlnOiBDaGFydENvbmZpZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBpc0NvbG9yQnkoY29uZmlnKVxuICAgID8gKGNvbmZpZy5jb2xvckJ5Py5jb2x1bW4gfHwgY29uZmlnLnhBeGlzPy5jb2x1bW4pXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cblxuLy8gQ2F0ZWdvcmllcyArIG5hbWVkIHNlcmllcyBleHRyYWN0ZWQgZnJvbSBhIGNoYXJ0IGNvbXBvbmVudCdzIGNvbmZpZyArIHJvd3Mg4oCUXG4vLyB0aGUgb25lIHBpdm90IChzcGxpdEJ5IOKGkiBzZXJpZXMsIG1lYXN1cmVzIOKGkiBzZXJpZXMpIHNoYXJlZCBieSB0aGUgb24tc2NyZWVuXG4vLyBFQ2hhcnRzIG9wdGlvbiBiZWxvdyBBTkQgdGhlIFBvd2VyUG9pbnQgZXhwb3J0J3MgbmF0aXZlIGNoYXJ0IGRhdGEsIHNvIGJvdGhcbi8vIG1lZGlhIHBsb3QgaWRlbnRpY2FsIG51bWJlcnMuXG4vL1xuLy8gQSBzZXJpZXMnIGB0eXBlYCBpcyB0aGUgdHlwZSBpdHMgbWVhc3VyZSBhc2tzIHRvIGJlIGRyYXduIGFzLCBhbmQgaXMgYWJzZW50XG4vLyB3aGVuIHRoZSBtZWFzdXJlIGxlYXZlcyBpdCB0byB0aGUgY2hhcnQncyBjaGFydFR5cGUgKHNlZSBzZXJpZXNUeXBlcykuIEl0c1xuLy8gYG1lYXN1cmVgIGlzIHRoZSBvbmUgaXQgcGxvdHMsIHdob3NlIG51bWJlciBmb3JtYXQgaXRzIHRvb2x0aXAgdXNlcyBhbmRcbi8vIHdob3NlIGRpc3BsYXkga2V5cyAoY29sb3IsIGF4aXMpIGl0IGZvbGxvd3MsIGFuZCBgbWVhc3VyZUluZGV4YCB0aGF0XG4vLyBtZWFzdXJlJ3MgcG9zaXRpb246IHRoZSBmaXJzdCBtZWFzdXJlLCAwLCBmb3IgZXZlcnkgc2VyaWVzIG9mIGEgc3BsaXRCeSBvclxuLy8gY29sb3JCeSBjaGFydC5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0cmFjdGVkQ2hhcnRTZXJpZXMge1xuICBjYXRlZ29yaWVzOiBzdHJpbmdbXTtcbiAgc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW1bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZhbHVlczogKG51bWJlciB8IG51bGwpW107XG4gIHR5cGU/OiBBeGlzQ2hhcnRUeXBlO1xuICBtZWFzdXJlOiBDaGFydE1lYXN1cmU7XG4gIG1lYXN1cmVJbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdENoYXJ0U2VyaWVzKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCBkYXRhOiBDb21wb25lbnREYXRhKTogRXh0cmFjdGVkQ2hhcnRTZXJpZXMge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCB4Q29sdW1uID0gY29uZmlnLnhBeGlzPy5jb2x1bW4gPz8gZGF0YS5jb2x1bW5zWzBdO1xuICBjb25zdCBzcGxpdENvbHVtbiA9IGNvbmZpZy5zcGxpdEJ5Py5jb2x1bW47XG4gIC8vIGNvbG9yQnkgZW1pdHMgb25lIHNlcmllcyBwZXIgY2F0ZWdvcnkgdG9vIChzbyBlYWNoIGJhciBjYXJyaWVzIGl0cyBvd25cbiAgLy8gY29sb3IgKyBsZWdlbmQgZW50cnkpLCBidXQgdGhlIGJhcnMgYXJlIG92ZXJsYXBwZWQgdG8gZnVsbCB3aWR0aCBpblxuICAvLyBidWlsZEF4aXNPcHRpb24gcmF0aGVyIHRoYW4gbGFpZCBzaWRlLWJ5LXNpZGUuIHNwbGl0Qnkgd2lucyBpZiBib3RoIGFyZSBzZXQuXG4gIGNvbnN0IGdyb3VwQ29sdW1uID0gc3BsaXRDb2x1bW4gfHwgY29sb3JCeUNvbHVtbihjb25maWcpO1xuICBjb25zdCBtZWFzdXJlcyA9IGNoYXJ0TWVhc3VyZXMoY29uZmlnLCBkYXRhKTtcblxuICBjb25zdCByYXdDYXRlZ29yaWVzID0gdW5pcXVlVmFsdWVzKGRhdGEucm93cywgeENvbHVtbik7XG4gIGNvbnN0IGNhdGVnb3JpZXMgPSByYXdDYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnkpID0+IFN0cmluZyhjYXRlZ29yeSA/PyAn4oCUJykpO1xuICBjb25zdCBzZXJpZXM6IEV4dHJhY3RlZENoYXJ0U2VyaWVzWydzZXJpZXMnXSA9IFtdO1xuXG4gIGlmIChncm91cENvbHVtbikge1xuICAgIC8vIE9uZSBzZXJpZXMgcGVyIGdyb3VwIHZhbHVlIChzcGxpdEJ5L2NvbG9yQnkpLCBwaXZvdGVkIG92ZXIgdGhlIGZpcnN0IG1lYXN1cmUuXG4gICAgY29uc3QgbWVhc3VyZSA9IG1lYXN1cmVzWzBdO1xuICAgIGZvciAoY29uc3QgZ3JvdXBWYWx1ZSBvZiB1bmlxdWVWYWx1ZXMoZGF0YS5yb3dzLCBncm91cENvbHVtbikpIHtcbiAgICAgIGNvbnN0IGJ5Q2F0ZWdvcnkgPSBuZXcgTWFwPHVua25vd24sIHVua25vd24+KCk7XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhLnJvd3MpIHtcbiAgICAgICAgaWYgKHJvd1tncm91cENvbHVtbl0gPT09IGdyb3VwVmFsdWUpIHtcbiAgICAgICAgICBieUNhdGVnb3J5LnNldChyb3dbeENvbHVtbl0sIHJvd1ttZWFzdXJlLmNvbHVtbl0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHNlcmllcy5wdXNoKHtcbiAgICAgICAgbmFtZTogU3RyaW5nKGdyb3VwVmFsdWUgPz8gJ+KAlCcpLFxuICAgICAgICB2YWx1ZXM6IHJhd0NhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gbnVtZXJpYyhieUNhdGVnb3J5LmdldChjYXRlZ29yeSkpKSxcbiAgICAgICAgdHlwZTogbWVhc3VyZS50eXBlLFxuICAgICAgICBtZWFzdXJlLFxuICAgICAgICBtZWFzdXJlSW5kZXg6IDAsXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBbbWVhc3VyZUluZGV4LCBtZWFzdXJlXSBvZiBtZWFzdXJlcy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IGJ5Q2F0ZWdvcnkgPSBuZXcgTWFwPHVua25vd24sIHVua25vd24+KCk7XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhLnJvd3MpIHtcbiAgICAgICAgYnlDYXRlZ29yeS5zZXQocm93W3hDb2x1bW5dLCByb3dbbWVhc3VyZS5jb2x1bW5dKTtcbiAgICAgIH1cblxuICAgICAgc2VyaWVzLnB1c2goe1xuICAgICAgICBuYW1lOiBtZWFzdXJlLmxhYmVsID8/IG1lYXN1cmUuY29sdW1uLFxuICAgICAgICB2YWx1ZXM6IHJhd0NhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gbnVtZXJpYyhieUNhdGVnb3J5LmdldChjYXRlZ29yeSkpKSxcbiAgICAgICAgdHlwZTogbWVhc3VyZS50eXBlLFxuICAgICAgICBtZWFzdXJlLFxuICAgICAgICBtZWFzdXJlSW5kZXgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBjYXRlZ29yaWVzLCBzZXJpZXMgfTtcbn1cblxuLy8gQSBzZXJpZXMnIG93biBjb2xvciBhcyBDU1MgaGV4OiBpdHMgbWVhc3VyZSdzIG5hbWVkIGNvbG9yLCBvciB1bmRlZmluZWQgd2hlblxuLy8gaXQgbmFtZXMgbm9uZSAob3IgYSBuYW1lIHRoZSBwYWxldHRlIGRvZXMgbm90IGtub3cpIGFuZCB0aGUgdGhlbWUgY29sb3JzIGl0XG4vLyBieSBpdHMgcG9zaXRpb24uXG5leHBvcnQgZnVuY3Rpb24gc2VyaWVzQ29sb3Ioc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBoZXggPSBuYW1lZENvbG9ySGV4KHNlcmllcyk7XG5cbiAgcmV0dXJuIGhleCA/IGAjJHtoZXh9YCA6IHVuZGVmaW5lZDtcbn1cblxuLy8gQSBzZXJpZXMnIGNvbG9yIGFzIHRoZSBiYXJlIGhleCBQb3dlclBvaW50IHRha2VzOiBpdHMgbWVhc3VyZSdzIG5hbWVkIGNvbG9yLFxuLy8gZWxzZSB0aGUgcGFsZXR0ZSBjb2xvciBvZiBpdHMgcG9zaXRpb24sIGFzIHRoZSBzY3JlZW4ncyB0aGVtZSBwaWNrcyBpdC5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpZXNIZXgoc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0sIGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbmFtZWRDb2xvckhleChzZXJpZXMpID8/IFJFUE9SVF9DSEFSVF9DT0xPUlNbaW5kZXggJSBSRVBPUlRfQ0hBUlRfQ09MT1JTLmxlbmd0aF07XG59XG5cbmZ1bmN0aW9uIG5hbWVkQ29sb3JIZXgoc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gbWVhc3VyZUNvbG9ySGV4KHNlcmllcy5tZWFzdXJlKTtcbn1cblxuLy8gQSBtZWFzdXJlJ3MgbmFtZWQgY29sb3IgYXMgYmFyZSBoZXgsIG9yIHVuZGVmaW5lZCB3aGVuIGl0IG5hbWVzIG5vbmUgb3IgYVxuLy8gbmFtZSB0aGUgcGFsZXR0ZSBkb2VzIG5vdCBrbm93LiBUaGUgbmFtZSBpcyByZWFkIHRocm91Z2ggdGhlIGVudW0sIHNvIGFcbi8vIHN0b3JlZCBuYW1lIHN1Y2ggYXMgJ19fcHJvdG9fXycgbmV2ZXIgcmVhY2hlcyB0aGUgbG9va3VwIG9iamVjdC5cbmZ1bmN0aW9uIG1lYXN1cmVDb2xvckhleChtZWFzdXJlOiBDaGFydE1lYXN1cmUgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBjb2xvciA9IE9iamVjdC52YWx1ZXMoUmVwb3J0Q2hhcnRDb2xvcikuZmluZCgobmFtZSkgPT4gbmFtZSA9PT0gbWVhc3VyZT8uY29sb3IpO1xuXG4gIHJldHVybiBjb2xvciA/IFJFUE9SVF9DSEFSVF9DT0xPUl9CWV9OQU1FW2NvbG9yXSA6IHVuZGVmaW5lZDtcbn1cblxuLy8gQSBtZWFzdXJlJ3MgbGluZSBzdHlsZSB3aGVuIGl0IG5hbWVzIG9uZSBFQ2hhcnRzIGtub3dzLCBlbHNlIHVuZGVmaW5lZCBhbmRcbi8vIHRoZSBsaW5lIGlzIHNvbGlkLlxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVMaW5lU3R5bGUobWVhc3VyZTogQ2hhcnRNZWFzdXJlIHwgdW5kZWZpbmVkKTogUmVwb3J0Q2hhcnRMaW5lU3R5bGUgfCB1bmRlZmluZWQge1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhSZXBvcnRDaGFydExpbmVTdHlsZSkuZmluZCgoc3R5bGUpID0+IHN0eWxlID09PSBtZWFzdXJlPy5saW5lKTtcbn1cblxuLy8gQSBtZWFzdXJlJ3Mgc3RhdGlzdGljIGxpbmUgd2hlbiBpdCBuYW1lcyBvbmUgdGhlIHZpZXdlciBrbm93cywgZWxzZVxuLy8gdW5kZWZpbmVkIGFuZCBpdCBkcmF3cyBub25lLlxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVNYXJrU3RhdChtZWFzdXJlOiBDaGFydE1lYXN1cmUgfCB1bmRlZmluZWQpOiBSZXBvcnRDaGFydE1hcmtTdGF0IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoUmVwb3J0Q2hhcnRNYXJrU3RhdCkuZmluZCgoc3RhdCkgPT4gc3RhdCA9PT0gbWVhc3VyZT8ubWFya0xpbmUpO1xufVxuXG4vLyBBIHNlcmllcycgc3RhdGlzdGljIG92ZXIgaXRzIHBvaW50cyB0aGF0IGhhdmUgYSB2YWx1ZTogdGhlaXIgbWVhbiwgdGhlaXJcbi8vIG1lZGlhbiAodGhlIG1lYW4gb2YgdGhlIHR3byBtaWRkbGUgdmFsdWVzIHdoZW4gdGhlIGNvdW50IGlzIGV2ZW4pLCB0aGVcbi8vIGxvd2VzdCBvciB0aGUgaGlnaGVzdC4gbnVsbCB3aGVuIG5vIHBvaW50IGhhcyBhIHZhbHVlLiBTaGFyZWQgd2l0aCB0aGVcbi8vIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGggbWVkaWEgZHJhdyB0aGUgbGluZSBhdCB0aGUgc2FtZSBoZWlnaHQuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWVzU3RhdCh2YWx1ZXM6IChudW1iZXIgfCBudWxsKVtdLCBzdGF0OiBSZXBvcnRDaGFydE1hcmtTdGF0KTogbnVtYmVyIHwgbnVsbCB7XG4gIGNvbnN0IHByZXNlbnQgPSB2YWx1ZXMuZmlsdGVyKCh2YWx1ZSk6IHZhbHVlIGlzIG51bWJlciA9PiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpO1xuXG4gIGlmICghcHJlc2VudC5sZW5ndGgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN3aXRjaCAoc3RhdCkge1xuICAgIGNhc2UgUmVwb3J0Q2hhcnRNYXJrU3RhdC5BdmVyYWdlOlxuICAgICAgcmV0dXJuIHByZXNlbnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCkgLyBwcmVzZW50Lmxlbmd0aDtcbiAgICBjYXNlIFJlcG9ydENoYXJ0TWFya1N0YXQuTWVkaWFuOiB7XG4gICAgICBjb25zdCBzb3J0ZWQgPSBbLi4ucHJlc2VudF0uc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICAgICAgY29uc3QgbWlkZGxlID0gTWF0aC5mbG9vcihzb3J0ZWQubGVuZ3RoIC8gMik7XG5cbiAgICAgIHJldHVybiBzb3J0ZWQubGVuZ3RoICUgMiA/IHNvcnRlZFttaWRkbGVdIDogKHNvcnRlZFttaWRkbGUgLSAxXSArIHNvcnRlZFttaWRkbGVdKSAvIDI7XG4gICAgfVxuICAgIGNhc2UgUmVwb3J0Q2hhcnRNYXJrU3RhdC5NaW46XG4gICAgICByZXR1cm4gTWF0aC5taW4oLi4ucHJlc2VudCk7XG4gICAgY2FzZSBSZXBvcnRDaGFydE1hcmtTdGF0Lk1heDpcbiAgICAgIHJldHVybiBNYXRoLm1heCguLi5wcmVzZW50KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLy8gV2hldGhlciBhIGNoYXJ0IGRyYXdzIHN0YXRpc3RpYyBsaW5lcy4gQSBob3Jpem9udGFsIGNoYXJ0J3MgdmFsdWVzIHJ1blxuLy8gYWxvbmcgeCwgYW5kIFBvd2VyUG9pbnQgY2Fubm90IGRyYXcgYSBsaW5lIGJlc2lkZSBob3Jpem9udGFsIGJhcnMsIHNvXG4vLyBuZWl0aGVyIG1lZGl1bSBkcmF3cyBvbmUgdGhlcmUuXG5leHBvcnQgZnVuY3Rpb24gZHJhd3NTdGF0TGluZXMoY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gY29uZmlnLm9yaWVudGF0aW9uICE9PSAnaG9yaXpvbnRhbCc7XG59XG5cbi8vIEEgY29sb3JCeSBjaGFydCdzIG9uZSB2YWx1ZSBwZXIgY2F0ZWdvcnk6IHNlcmllcyBpIGhvbGRzIGNhdGVnb3J5IGkncyBiYXIuXG4vLyBQb3dlclBvaW50IGRyYXdzIHRoZXNlIGFzIGl0cyBvbmUgc2VyaWVzLCBhbmQgYSBzdGF0aXN0aWMgbGluZSBpcyB0YWtlblxuLy8gb3ZlciB0aGVtLlxuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yQnlWYWx1ZXMoZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcyk6IChudW1iZXIgfCBudWxsKVtdIHtcbiAgcmV0dXJuIGV4dHJhY3RlZC5jYXRlZ29yaWVzLm1hcCgoXywgaW5kZXgpID0+IGV4dHJhY3RlZC5zZXJpZXNbaW5kZXhdPy52YWx1ZXNbaW5kZXhdID8/IG51bGwpO1xufVxuXG4vLyBUaGUgcmVmZXJlbmNlcyBhIGNoYXJ0IGRyYXdzLiBBIHZlcnRpY2FsIGF4aXMgY2hhcnQgYW5kIGEgd2F0ZXJmYWxsIGRyYXdcbi8vIHRoZW07IGEgcGllIGhhcyBubyB2YWx1ZSBheGlzLCBhbmQgYSBob3Jpem9udGFsIGNoYXJ0IGlzIGxlZnQgd2l0aG91dCB0aGVtXG4vLyBhcyBQb3dlclBvaW50IGNhbm5vdCBkcmF3IGEgbGluZSBiZXNpZGUgaG9yaXpvbnRhbCBiYXJzLiBBbiBlbnRyeSB3aXRob3V0IGFcbi8vIGZpbml0ZSB2YWx1ZSBpcyBza2lwcGVkLCBhbmQgb25lIHdob3NlIGB0b2AgaXMgbWlzc2luZyBvciBlcXVhbCB0byBpdHMgdmFsdWVcbi8vIGlzIGEgbGluZS4gc2Vjb25kYXJ5IHJlYWNoZXMgdGhlIHNlY29uZCB2YWx1ZSBheGlzIG9ubHkgb24gYSBjaGFydCB0aGF0IGhhc1xuLy8gb25lICh0d29BeGVzKS4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0LlxuZXhwb3J0IGZ1bmN0aW9uIGNoYXJ0UmVmZXJlbmNlcyhjb25maWc6IENoYXJ0Q29uZmlnLCB0d29BeGVzOiBib29sZWFuKTogRHJhd25SZWZlcmVuY2VbXSB7XG4gIGNvbnN0IGNoYXJ0VHlwZSA9IGNvbmZpZy5jaGFydFR5cGUgPz8gJ2Jhcic7XG4gIGNvbnN0IHJlZmVyZW5jZXM6IChDaGFydFJlZmVyZW5jZSB8IG51bGwgfCB1bmRlZmluZWQpW10gPSBBcnJheS5pc0FycmF5KGNvbmZpZy5yZWZlcmVuY2VzKSA/IGNvbmZpZy5yZWZlcmVuY2VzIDogW107XG5cbiAgaWYgKGNvbmZpZy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnIHx8IGNoYXJ0VHlwZSA9PT0gJ3BpZScgfHwgY2hhcnRUeXBlID09PSAnZG9udXQnKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcmV0dXJuIHJlZmVyZW5jZXMuZmxhdE1hcCgocmVmZXJlbmNlKTogRHJhd25SZWZlcmVuY2VbXSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBheGlzTnVtYmVyKHJlZmVyZW5jZT8udmFsdWUpO1xuXG4gICAgaWYgKCFyZWZlcmVuY2UgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IHRvID0gYXhpc051bWJlcihyZWZlcmVuY2UudG8pO1xuICAgIGNvbnN0IGxhYmVsID0gdHlwZW9mIHJlZmVyZW5jZS5sYWJlbCA9PT0gJ3N0cmluZycgPyByZWZlcmVuY2UubGFiZWwgOiAnJztcbiAgICBjb25zdCBheGlzSW5kZXg6IFZhbHVlQXhpc0luZGV4ID0gdHdvQXhlcyAmJiByZWZlcmVuY2Uuc2Vjb25kYXJ5ID09PSB0cnVlID8gMSA6IDA7XG5cbiAgICByZXR1cm4gW3RvICE9PSB1bmRlZmluZWQgJiYgdG8gIT09IHZhbHVlXG4gICAgICA/IHsgbGFiZWwsIGxvdzogTWF0aC5taW4odmFsdWUsIHRvKSwgaGlnaDogTWF0aC5tYXgodmFsdWUsIHRvKSwgYmFuZDogdHJ1ZSwgYXhpc0luZGV4IH1cbiAgICAgIDogeyBsYWJlbCwgbG93OiB2YWx1ZSwgaGlnaDogdmFsdWUsIGJhbmQ6IGZhbHNlLCBheGlzSW5kZXggfV07XG4gIH0pO1xufVxuXG4vLyBFYWNoIHNlcmllcyBhcyBpdHMgc2hhcmUgb2YgaXRzIGNhdGVnb3J5J3MgdG90YWw6IHBlciBjYXRlZ29yeSwgdGhlXG4vLyBkZW5vbWluYXRvciBpcyB0aGUgc3VtIG9mIGV2ZXJ5IHNlcmllcycgYWJzb2x1dGUgdmFsdWUgdGhlcmUsIHNvIHRoZVxuLy8gbWFnbml0dWRlcyBvZiBhIGNhdGVnb3J5J3Mgc2hhcmVzIGFkZCB1cCB0byAxLiBBIG1peGVkLXNpZ24gY2F0ZWdvcnknc1xuLy8gbmVnYXRpdmUgdmFsdWVzIHRha2UgbmVnYXRpdmUgc2hhcmVzLCBkcmF3biBiZWxvdyB6ZXJvLiBBIG1pc3NpbmcgdmFsdWVcbi8vIHN0YXlzIG1pc3NpbmcsIGFuZCBhIGNhdGVnb3J5IHdob3NlIHRvdGFsIGlzIHplcm8gaGFzIG5vIHNoYXJlcy4gU2hhcmVkIGJ5XG4vLyB0aGUgc2NyZWVuLCB0aGUgUERGIGFuZCBQb3dlclBvaW50LCBzbyBhIDEwMCUgc3RhY2sgcmVhZHMgdGhlIHNhbWUgaW4gZWFjaC5cbmV4cG9ydCBmdW5jdGlvbiBwZXJjZW50U2hhcmVzKHZhbHVlczogKG51bWJlciB8IG51bGwpW11bXSk6IChudW1iZXIgfCBudWxsKVtdW10ge1xuICBjb25zdCBsZW5ndGggPSBNYXRoLm1heCgwLCAuLi52YWx1ZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy5sZW5ndGgpKTtcbiAgY29uc3QgdG90YWxzID0gQXJyYXkuZnJvbSh7IGxlbmd0aCB9LCAoXywgaW5kZXgpID0+IHZhbHVlc1xuICAgIC5yZWR1Y2UoKHN1bSwgc2VyaWVzKSA9PiBzdW0gKyBNYXRoLmFicyhzZXJpZXNbaW5kZXhdID8/IDApLCAwKSk7XG5cbiAgcmV0dXJuIHZhbHVlcy5tYXAoKHNlcmllcykgPT4gc2VyaWVzLm1hcCgodmFsdWUsIGluZGV4KSA9PiAoXG4gICAgdmFsdWUgPT09IG51bGwgfHwgIXRvdGFsc1tpbmRleF0gPyBudWxsIDogdmFsdWUgLyB0b3RhbHNbaW5kZXhdXG4gICkpKTtcbn1cblxuLy8gVGhlIHNoYXJlcyBhIDEwMCUgc3RhY2tlZCBjaGFydCBkcmF3cyBpbiBwbGFjZSBvZiBpdHMgdmFsdWVzLCBvciBudWxsIHdoZW5cbi8vIHRoZSBjaGFydCBpcyBub3Qgb25lLiBUaGUgcHJpbWFyeSBheGlzJ3MgYmFyIGFuZCBhcmVhIHNlcmllcyB0YWtlIHRoZW0sXG4vLyBlYWNoIHR5cGUncyBzZXJpZXMgc2hhcmluZyBhbW9uZyB0aGVtc2VsdmVzLCBhcyBlYWNoIHR5cGUgc3RhY2tzIGFwYXJ0LlxuLy8gTGluZXMgYW5kIHNlY29uZGFyeS1heGlzIHNlcmllcyBrZWVwIHRoZWlyIHZhbHVlcy4gQSBwaWUsIGEgd2F0ZXJmYWxsIGFuZCBhXG4vLyBjb2xvckJ5IGNoYXJ0IChvbmUgc2VyaWVzIHBlciBjYXRlZ29yeSwgZWFjaCBvZiB3aGljaCB3b3VsZCBiZSAxMDAlKSBhcmVcbi8vIG5ldmVyIDEwMCUgc3RhY2tlZCwgbm9yIGlzIGEgY2hhcnQgd2l0aCBubyBiYXIgb3IgYXJlYSBvbiBpdHMgcHJpbWFyeSBheGlzLlxuZXhwb3J0IGZ1bmN0aW9uIHBlcmNlbnRTdGFja2VkU2hhcmVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIGNvbmZpZzogQ2hhcnRDb25maWcpOiBQZXJjZW50U2hhcmVzIHwgbnVsbCB7XG4gIGNvbnN0IGNoYXJ0VHlwZSA9IGNvbmZpZy5jaGFydFR5cGUgPz8gJ2Jhcic7XG5cbiAgaWYgKGNvbmZpZy5wZXJjZW50U3RhY2tlZCAhPT0gdHJ1ZVxuICAgIHx8IGNoYXJ0VHlwZSA9PT0gJ3BpZScgfHwgY2hhcnRUeXBlID09PSAnZG9udXQnIHx8IGNoYXJ0VHlwZSA9PT0gJ3dhdGVyZmFsbCdcbiAgICB8fCBpc0NvbG9yQnkoY29uZmlnKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdHlwZXMgPSBzZXJpZXNUeXBlcyhleHRyYWN0ZWQsIGNoYXJ0VHlwZSk7XG4gIGNvbnN0IGF4aXNJbmRleGVzID0gc2VyaWVzQXhpc0luZGV4ZXMoZXh0cmFjdGVkLCBjb25maWcpO1xuICBjb25zdCBzaGFyZXM6IFBlcmNlbnRTaGFyZXMgPSBuZXcgTWFwKCk7XG5cbiAgZm9yIChjb25zdCB0eXBlIG9mIFsnYmFyJywgJ2FyZWEnXSBhcyBjb25zdCkge1xuICAgIGNvbnN0IGluZGV4ZXMgPSB0eXBlc1xuICAgICAgLm1hcCgoc2VyaWVzVHlwZSwgaW5kZXgpID0+IChzZXJpZXNUeXBlID09PSB0eXBlICYmIGF4aXNJbmRleGVzW2luZGV4XSA9PT0gMCA/IGluZGV4IDogLTEpKVxuICAgICAgLmZpbHRlcigoaW5kZXgpID0+IGluZGV4ID49IDApO1xuICAgIGNvbnN0IHR5cGVTaGFyZXMgPSBwZXJjZW50U2hhcmVzKGluZGV4ZXMubWFwKChpbmRleCkgPT4gZXh0cmFjdGVkLnNlcmllc1tpbmRleF0udmFsdWVzKSk7XG4gICAgaW5kZXhlcy5mb3JFYWNoKChzZXJpZXNJbmRleCwgcG9zaXRpb24pID0+IHNoYXJlcy5zZXQoc2VyaWVzSW5kZXgsIHR5cGVTaGFyZXNbcG9zaXRpb25dKSk7XG4gIH1cblxuICByZXR1cm4gc2hhcmVzLnNpemUgPyBzaGFyZXMgOiBudWxsO1xufVxuXG4vLyBXaGVyZSBhIDEwMCUgc3RhY2tlZCBjaGFydCdzIHZhbHVlIGF4aXMgc3RhcnRzOiBhdCAtMTAwJSB3aGVuIGFueSBzaGFyZSBpc1xuLy8gbmVnYXRpdmUsIGVsc2UgYXQgemVyby5cbmV4cG9ydCBmdW5jdGlvbiBwZXJjZW50QXhpc01pbihzaGFyZXM6IFBlcmNlbnRTaGFyZXMpOiBudW1iZXIge1xuICByZXR1cm4gWy4uLnNoYXJlcy52YWx1ZXMoKV0uc29tZSgoc2VyaWVzKSA9PiBzZXJpZXMuc29tZSgoc2hhcmUpID0+IChzaGFyZSA/PyAwKSA8IDApKSA/IC0xIDogMDtcbn1cblxuLy8gVGhlIG1lYXN1cmVzIGEgY2hhcnQgcGxvdHM6IGl0cyBjb25maWd1cmVkIG9uZXMsIGVsc2UgdGhlIHF1ZXJ5J3MgbGFzdFxuLy8gY29sdW1uLCB1bmZvcm1hdHRlZC5cbmZ1bmN0aW9uIGNoYXJ0TWVhc3VyZXMoY29uZmlnOiBDaGFydENvbmZpZywgZGF0YTogQ29tcG9uZW50RGF0YSk6IENoYXJ0TWVhc3VyZVtdIHtcbiAgcmV0dXJuIGNvbmZpZy5tZWFzdXJlcz8ubGVuZ3RoXG4gICAgPyBjb25maWcubWVhc3VyZXNcbiAgICA6IFt7IGNvbHVtbjogZGF0YS5jb2x1bW5zW2RhdGEuY29sdW1ucy5sZW5ndGggLSAxXSB9XTtcbn1cblxuLy8gVGhlIHR5cGUgZWFjaCBleHRyYWN0ZWQgc2VyaWVzIGlzIGRyYXduIGFzOiBpdHMgbWVhc3VyZSdzIG93biB0eXBlIHdoZW4gaXRcbi8vIG5hbWVzIG9uZSwgdGhlIGNoYXJ0J3MgY2hhcnRUeXBlIG90aGVyd2lzZS4gTW9yZSB0aGFuIG9uZSBkaXN0aW5jdCB0eXBlIGlzIGFcbi8vIGNvbWJvIGNoYXJ0LiBTaGFyZWQgd2l0aCB0aGUgUG93ZXJQb2ludCBleHBvcnQgc28gYm90aCBtZWRpYSBkcmF3IGVhY2ggc2VyaWVzXG4vLyB0aGUgc2FtZSB3YXkuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWVzVHlwZXMoZXh0cmFjdGVkOiBFeHRyYWN0ZWRDaGFydFNlcmllcywgY2hhcnRUeXBlOiBBeGlzQ2hhcnRUeXBlKTogQXhpc0NoYXJ0VHlwZVtdIHtcbiAgcmV0dXJuIGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy50eXBlID8/IGNoYXJ0VHlwZSk7XG59XG5cbi8vIFRoZSB2YWx1ZSBheGlzIGVhY2ggZXh0cmFjdGVkIHNlcmllcyBpcyBwbG90dGVkIGFnYWluc3Q6IDEgd2hlbiBpdHMgbWVhc3VyZVxuLy8gaXMgc2Vjb25kYXJ5LCAwIG90aGVyd2lzZS4gQSBzZWNvbmQgYXhpcyBpcyBkcmF3biBvbmx5IG9uIGEgdmVydGljYWwgY2hhcnRcbi8vIHRoYXQga2VlcHMgYXQgbGVhc3Qgb25lIHNlcmllcyBvbiB0aGUgcHJpbWFyeSBheGlzLCBzbyBhIGNvbWJpbmF0aW9uIHRoZVxuLy8gc2VydmVyIHJlZnVzZXMgKGEgaG9yaXpvbnRhbCBjaGFydCwgZXZlcnkgbWVhc3VyZSBzZWNvbmRhcnksIHRoZSBvbmUgbWVhc3VyZVxuLy8gb2YgYSBzcGxpdEJ5IG9yIGNvbG9yQnkgY2hhcnQpIHBsb3RzIGV2ZXJ5dGhpbmcgb24gdGhlIHByaW1hcnkgYXhpcy4gU2hhcmVkXG4vLyB3aXRoIHRoZSBQb3dlclBvaW50IGV4cG9ydCBzbyBib3RoIG1lZGlhIHB1dCBlYWNoIHNlcmllcyBvbiB0aGUgc2FtZSBheGlzLlxuZXhwb3J0IGZ1bmN0aW9uIHNlcmllc0F4aXNJbmRleGVzKGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsIGNvbmZpZzogQ2hhcnRDb25maWcpOiBWYWx1ZUF4aXNJbmRleFtdIHtcbiAgY29uc3Qgc2Vjb25kYXJ5ID0gZXh0cmFjdGVkLnNlcmllcy5tYXAoKHNlcmllcykgPT4gISFzZXJpZXMubWVhc3VyZS5zZWNvbmRhcnkpO1xuICBjb25zdCB0d29BeGVzID0gY29uZmlnLm9yaWVudGF0aW9uICE9PSAnaG9yaXpvbnRhbCcgJiYgc2Vjb25kYXJ5LmluY2x1ZGVzKHRydWUpICYmIHNlY29uZGFyeS5pbmNsdWRlcyhmYWxzZSk7XG5cbiAgcmV0dXJuIHNlY29uZGFyeS5tYXAoKGlzU2Vjb25kYXJ5KSA9PiAodHdvQXhlcyAmJiBpc1NlY29uZGFyeSA/IDEgOiAwKSk7XG59XG5cbi8vIE9uZSBiYXIgb2YgYSB3YXRlcmZhbGwuIGBzdGFydGAgaXMgdGhlIHJ1bm5pbmcgdG90YWwgYmVmb3JlIGl0LCB3aGVyZSB0aGUgYmFyXG4vLyBzdGFydHMsIGFuZCBgY2hhbmdlYCBpdHMgc2lnbmVkIGhlaWdodCwgc28gaXQgZW5kcyBhdCBzdGFydCArIGNoYW5nZS4gVGhlXG4vLyBjbG9zaW5nIHRvdGFsIHN0YXJ0cyBhdCB6ZXJvIGFuZCBpdHMgY2hhbmdlIGlzIHRoZSB3aG9sZSBydW5uaW5nIHRvdGFsLlxuZXhwb3J0IGludGVyZmFjZSBXYXRlcmZhbGxTdGVwIHtcbiAgY2F0ZWdvcnk6IHN0cmluZztcbiAgc3RhcnQ6IG51bWJlcjtcbiAgY2hhbmdlOiBudW1iZXIgfCBudWxsO1xuICBraW5kOiBXYXRlcmZhbGxTdGVwS2luZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHRyYWN0ZWRXYXRlcmZhbGwge1xuICBuYW1lOiBzdHJpbmc7XG4gIHN0ZXBzOiBXYXRlcmZhbGxTdGVwW107XG59XG5cbmV4cG9ydCBjb25zdCBXQVRFUkZBTExfVE9UQUxfTEFCRUwgPSAnVG90YWwnO1xuXG4vLyBBIHdhdGVyZmFsbCdzIGJhcnMgZnJvbSBpdHMgb25lIG1lYXN1cmU6IGVhY2ggY2F0ZWdvcnkncyB2YWx1ZSBpcyBob3cgZmFyIHRoZVxuLy8gcnVubmluZyB0b3RhbCBtb3ZlcyB0aGVyZSwgYW5kIGEgbGFzdCBUb3RhbCBiYXIgc2hvd3Mgd2hlcmUgaXQgZW5kZWQuIEFcbi8vIGNhdGVnb3J5IHdpdGggbm8gdmFsdWUgbW92ZXMgbm90aGluZyBhbmQgZHJhd3Mgbm8gYmFyLiBTaGFyZWQgd2l0aCB0aGVcbi8vIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGggbWVkaWEgZHJhdyB0aGUgc2FtZSBzdGVwcy5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0V2F0ZXJmYWxsKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCBkYXRhOiBDb21wb25lbnREYXRhKTogRXh0cmFjdGVkV2F0ZXJmYWxsIHtcbiAgY29uc3QgZXh0cmFjdGVkID0gZXh0cmFjdENoYXJ0U2VyaWVzKGNvbXBvbmVudCwgZGF0YSk7XG4gIGNvbnN0IHZhbHVlcyA9IGV4dHJhY3RlZC5zZXJpZXNbMF0/LnZhbHVlcyA/PyBbXTtcbiAgY29uc3Qgc3RlcHM6IFdhdGVyZmFsbFN0ZXBbXSA9IFtdO1xuICBsZXQgdG90YWwgPSAwO1xuXG4gIGV4dHJhY3RlZC5jYXRlZ29yaWVzLmZvckVhY2goKGNhdGVnb3J5LCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGNoYW5nZSA9IHZhbHVlc1tpbmRleF0gPz8gbnVsbDtcbiAgICBzdGVwcy5wdXNoKHsgY2F0ZWdvcnksIHN0YXJ0OiB0b3RhbCwgY2hhbmdlLCBraW5kOiAoY2hhbmdlID8/IDApIDwgMCA/ICdmYWxsJyA6ICdyaXNlJyB9KTtcbiAgICB0b3RhbCArPSBjaGFuZ2UgPz8gMDtcbiAgfSk7XG5cbiAgc3RlcHMucHVzaCh7IGNhdGVnb3J5OiBXQVRFUkZBTExfVE9UQUxfTEFCRUwsIHN0YXJ0OiAwLCBjaGFuZ2U6IHRvdGFsLCBraW5kOiAndG90YWwnIH0pO1xuXG4gIHJldHVybiB7IG5hbWU6IGV4dHJhY3RlZC5zZXJpZXNbMF0/Lm5hbWUgPz8gJycsIHN0ZXBzIH07XG59XG5cbi8vIFRoZSBvbmUgcHVyZSBtYXBwaW5nIGZyb20gb3VyIHN0YW5kYXJkIGNhbWVsQ2FzZSBjaGFydCBjb25maWcgKyB0aGUgZGF0YVxuLy8gZW5kcG9pbnQncyByb3dzIHRvIGFuIEVDaGFydHMgb3B0aW9uLiBFdmVyeXRoaW5nIHZpc3VhbCB0aGF0IGlzbid0IGluIHRoZVxuLy8gcmVnaXN0ZXJlZCAncmVwb3J0JyB0aGVtZSBpcyBkZWNpZGVkIGhlcmUsIHNvIHJlcG9ydCBzdGFuZGFyZHMgaGF2ZSBleGFjdGx5XG4vLyB0d28gaG9tZXMuXG4vL1xuLy8gRXZlcnkgbnVtYmVyIGFuZCBwZXJpb2QgdGhlIGNoYXJ0IHdyaXRlcyAodmFsdWUtYXhpcyB0aWNrcywgdG9vbHRpcCB2YWx1ZXMsXG4vLyBwZXJpb2QgbGFiZWxzKSBpcyBpbiB0aGUgY29udGV4dCdzIGxvY2FsZSwgbmV2ZXIgdGhlIGJyb3dzZXIncy4gQSBtZWFzdXJlXG4vLyB3aXRoIG51bWJlci1mb3JtYXQga2V5cyBmb3JtYXRzIGl0cyB0b29sdGlwcywgYW5kIHRoZSB2YWx1ZSBheGlzIHdoZW4gZXZlcnlcbi8vIG1lYXN1cmUgb24gaXQgYWdyZWVzIChheGlzTnVtYmVyRm9ybWF0KTsgd2l0aG91dCB0aGVtIHRoZSBheGlzIGFuZCB0b29sdGlwc1xuLy8ga2VlcCB0aGUgcGxhaW4gbG9jYWxlLWdyb3VwZWQgbnVtYmVyLlxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ2hhcnRPcHRpb24oXG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LFxuICBkYXRhOiBDb21wb25lbnREYXRhLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogRUNoYXJ0c09wdGlvbiB7XG4gIGNvbnN0IGNvbmZpZyA9IGNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWc7XG4gIGNvbnN0IGNoYXJ0VHlwZSA9IGNvbmZpZy5jaGFydFR5cGUgPz8gJ2Jhcic7XG5cbiAgaWYgKGNoYXJ0VHlwZSA9PT0gJ3BpZScgfHwgY2hhcnRUeXBlID09PSAnZG9udXQnKSB7XG4gICAgcmV0dXJuIGJ1aWxkUGllT3B0aW9uKGNvbXBvbmVudCwgZGF0YSwgY2hhcnRUeXBlID09PSAnZG9udXQnLCBjb250ZXh0KTtcbiAgfVxuXG4gIGlmIChjaGFydFR5cGUgPT09ICd3YXRlcmZhbGwnKSB7XG4gICAgcmV0dXJuIGJ1aWxkV2F0ZXJmYWxsT3B0aW9uKGNvbXBvbmVudCwgZGF0YSwgY29udGV4dCk7XG4gIH1cblxuICByZXR1cm4gYnVpbGRBeGlzT3B0aW9uKGNvbXBvbmVudCwgZGF0YSwgY2hhcnRUeXBlLCBjb250ZXh0KTtcbn1cblxuZnVuY3Rpb24gYnVpbGRBeGlzT3B0aW9uKFxuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgY2hhcnRUeXBlOiBBeGlzQ2hhcnRUeXBlLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogRUNoYXJ0c09wdGlvbiB7XG4gIGNvbnN0IGNvbmZpZyA9IGNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWc7XG4gIGNvbnN0IGV4dHJhY3RlZCA9IGV4dHJhY3RDaGFydFNlcmllcyhjb21wb25lbnQsIGRhdGEpO1xuICBjb25zdCBob3Jpem9udGFsID0gY29uZmlnLm9yaWVudGF0aW9uID09PSAnaG9yaXpvbnRhbCc7XG4gIGNvbnN0IGNvbG9yQnkgPSBpc0NvbG9yQnkoY29uZmlnKTtcbiAgY29uc3QgdHlwZXMgPSBzZXJpZXNUeXBlcyhleHRyYWN0ZWQsIGNoYXJ0VHlwZSk7XG4gIGNvbnN0IGNvbWJvID0gbmV3IFNldCh0eXBlcykuc2l6ZSA+IDE7XG5cbiAgLy8gY29sb3JCeSBlbWl0cyBvbmUgc2VyaWVzIHBlciBjYXRlZ29yeTsgb3ZlcmxhcHBpbmcgdGhlbSAoYmFyR2FwIC0xMDAlKSBtYWtlc1xuICAvLyBlYWNoIHJlbmRlciBhdCB0aGUgZnVsbCBjYXRlZ29yeS1iYW5kIHdpZHRoIOKAlCBvbmUgZnVsbC13aWR0aCwgZGlzdGluY3RseVxuICAvLyBjb2xvcmVkIGJhciBwZXIgY2F0ZWdvcnkg4oCUIGluc3RlYWQgb2Ygc2lkZS1ieS1zaWRlIHNsaXZlcnMuIFRoZSBsYXlvdXQgcHJvcHNcbiAgLy8gYXJlIHJlYWQgZnJvbSB0aGUgZmlyc3Qgc2VyaWVzIG9mIHRoZSBjb29yZGluYXRlIHN5c3RlbS5cbiAgLy9cbiAgLy8gU3RhY2tpbmcgc3VtcyBldmVyeSBzZXJpZXMgdGhhdCBzaGFyZXMgYSBzdGFjayBuYW1lLCB3aGF0ZXZlciBpdHMgdHlwZS4gSW5cbiAgLy8gYSBjb21ibyBlYWNoIHR5cGUgc3RhY2tzIG9ubHkgd2l0aCBpdHMgb3duIGtpbmQsIHNvIGEgbGluZSBvZiBhIHJhdGUgbmV2ZXJcbiAgLy8gc2l0cyBvbiB0b3Agb2YgdGhlIGJhcnMnIHRvdGFsLCBhbmQgb24gYSB0d28tYXhpcyBjaGFydCBvbmx5IHdpdGggdGhlXG4gIC8vIHNlcmllcyBvbiBpdHMgb3duIGF4aXMuXG4gIC8vXG4gIC8vIEEgMTAwJSBzdGFja2VkIGNoYXJ0IChwZXJjZW50U3RhY2tlZFNoYXJlcykgcGxvdHMgaXRzIHByaW1hcnkgYmFycyBhbmRcbiAgLy8gYXJlYXMgYXMgc2hhcmVzLCBlYWNoIHR5cGUgaW4gaXRzIG93biBzdGFjaywgYW5kIGxlYXZlcyBldmVyeSBvdGhlciBzZXJpZXNcbiAgLy8gdW5zdGFja2VkIG9uIGl0cyBvd24gdmFsdWVzLlxuICBjb25zdCBheGlzSW5kZXhlcyA9IHNlcmllc0F4aXNJbmRleGVzKGV4dHJhY3RlZCwgY29uZmlnKTtcbiAgY29uc3QgdHdvQXhlcyA9IGF4aXNJbmRleGVzLmluY2x1ZGVzKDEpO1xuICBjb25zdCBzaGFyZXMgPSBwZXJjZW50U3RhY2tlZFNoYXJlcyhleHRyYWN0ZWQsIGNvbmZpZyk7XG4gIGNvbnN0IHJlZmVyZW5jZXMgPSBjaGFydFJlZmVyZW5jZXMoY29uZmlnLCB0d29BeGVzKTtcbiAgY29uc3QgYXhpc0Zvcm1hdHMgPSB2YWx1ZUF4aXNGb3JtYXRzKGNvbmZpZywgZXh0cmFjdGVkLCBheGlzSW5kZXhlcywgY29udGV4dCwgISFzaGFyZXMsIHJlZmVyZW5jZXMpO1xuICAvLyBBIHNlcmllcycgc3RhdGlzdGljIGxpbmUgaXMgdGFrZW4gb3ZlciB0aGUgcG9pbnRzIGl0IHBsb3RzLiBPbiBhIGNvbG9yQnlcbiAgLy8gY2hhcnQgZWFjaCBzZXJpZXMgaG9sZHMgb25lIGJhciwgc28gdGhlIG9uZSBsaW5lIGlzIHRha2VuIG92ZXIgdGhlIGJhcnNcbiAgLy8gdG9nZXRoZXIgYW5kIGhhbmdzIG9mZiB0aGUgZmlyc3Qgc2VyaWVzIChjb2xvckJ5U3RhdExpbmUpLlxuICBjb25zdCBzdGF0TGluZXMgPSBkcmF3c1N0YXRMaW5lcyhjb25maWcpICYmICFjb2xvckJ5O1xuICBjb25zdCBzZXJpZXM6IFNlcmllc09wdGlvbltdID0gZXh0cmFjdGVkLnNlcmllcy5tYXAoKGV4dHJhY3RlZFNlcmllcywgaW5kZXgpID0+IHtcbiAgICBjb25zdCBzZXJpZXNTaGFyZXMgPSBzaGFyZXM/LmdldChpbmRleCk7XG4gICAgbGV0IHN0YWNrOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHNlcmllc1NoYXJlcykge1xuICAgICAgc3RhY2sgPSBzdGFja0tleSh0eXBlc1tpbmRleF0sIGNvbWJvLCAwKTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5zdGFja2VkICYmICFzaGFyZXMpIHtcbiAgICAgIHN0YWNrID0gc3RhY2tLZXkodHlwZXNbaW5kZXhdLCBjb21ibywgdHdvQXhlcyA/IGF4aXNJbmRleGVzW2luZGV4XSA6IHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdCA9IHN0YXRMaW5lcyA/IG1lYXN1cmVNYXJrU3RhdChleHRyYWN0ZWRTZXJpZXMubWVhc3VyZSkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbWFya0xpbmUgPSBzdGF0ICYmIHN0YXRNYXJrTGluZShcbiAgICAgIHNlcmllc1NoYXJlcyA/PyBleHRyYWN0ZWRTZXJpZXMudmFsdWVzLFxuICAgICAgc3RhdCxcbiAgICAgIHNlcmllc1NoYXJlcyA/IHNoYXJlV3JpdGVyKGNvbnRleHQpIDogbWVhc3VyZVdyaXRlcihleHRyYWN0ZWRTZXJpZXMubWVhc3VyZSwgY29udGV4dCksXG4gICAgKTtcbiAgICBjb25zdCBvcHRpb24gPSBidWlsZFNlcmllcyhcbiAgICAgIGV4dHJhY3RlZFNlcmllcyxcbiAgICAgIHNlcmllc1NoYXJlcyA/IHNoYXJlRGF0YShleHRyYWN0ZWRTZXJpZXMudmFsdWVzLCBzZXJpZXNTaGFyZXMpIDogZXh0cmFjdGVkU2VyaWVzLnZhbHVlcyxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogdHlwZXNbaW5kZXhdLFxuICAgICAgICBzdGFjayxcbiAgICAgICAgb3ZlcmxhcDogY29sb3JCeSAmJiBpbmRleCA9PT0gMCxcbiAgICAgICAgY29tYm8sXG4gICAgICAgIHRvb2x0aXA6IHNlcmllc1Rvb2x0aXAoZXh0cmFjdGVkU2VyaWVzLm1lYXN1cmUsIGNvbnRleHQpLFxuICAgICAgICBheGlzSW5kZXg6IHR3b0F4ZXMgPyBheGlzSW5kZXhlc1tpbmRleF0gOiB1bmRlZmluZWQsXG4gICAgICAgIC8vIEEgY29sb3JCeSBjaGFydCdzIGJhcnMgdGFrZSB0aGUgcGFsZXR0ZSBieSBjYXRlZ29yeSwgYXMgaW5cbiAgICAgICAgLy8gUG93ZXJQb2ludCwgd2hhdGV2ZXIgY29sb3IgdGhlIG1lYXN1cmUgbmFtZXMuXG4gICAgICAgIGNvbG9yOiBjb2xvckJ5ID8gdW5kZWZpbmVkIDogc2VyaWVzQ29sb3IoZXh0cmFjdGVkU2VyaWVzKSxcbiAgICAgICAgbGFiZWxzOiBkYXRhTGFiZWxPcHRpb24oY29uZmlnLmRhdGFMYWJlbHMsIGRhdGFMYWJlbEZvcm1hdHRlcihcbiAgICAgICAgICBleHRyYWN0ZWRTZXJpZXMubWVhc3VyZSxcbiAgICAgICAgICBheGlzRm9ybWF0c1theGlzSW5kZXhlc1tpbmRleF1dID8/IG51bGwsXG4gICAgICAgICAgISFzZXJpZXNTaGFyZXMsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKSksXG4gICAgICB9LFxuICAgICk7XG5cbiAgICByZXR1cm4gbWFya0xpbmUgPyB7IC4uLm9wdGlvbiwgbWFya0xpbmUgfSBhcyBTZXJpZXNPcHRpb24gOiBvcHRpb247XG4gIH0pO1xuXG4gIGlmIChjb2xvckJ5ICYmIGRyYXdzU3RhdExpbmVzKGNvbmZpZykgJiYgc2VyaWVzLmxlbmd0aCkge1xuICAgIHNlcmllc1swXSA9IGNvbG9yQnlTdGF0TGluZShzZXJpZXNbMF0sIGV4dHJhY3RlZCwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCBwZXJjZW50TWluID0gc2hhcmVzID8gcGVyY2VudEF4aXNNaW4oc2hhcmVzKSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgY2F0ZWdvcnlBeGlzID0gY2F0ZWdvcnlBeGlzT3B0aW9uKGNvbmZpZywgZGF0YSwgZXh0cmFjdGVkLmNhdGVnb3JpZXMsIGhvcml6b250YWwsIGNvbnRleHQubG9jYWxlKTtcbiAgY29uc3QgdmFsdWVBeGlzID0gdHdvQXhlc1xuICAgID8gdHdvVmFsdWVBeGVzT3B0aW9uKGNvbmZpZywgYXhpc0Zvcm1hdHMsIGNvbnRleHQsIHBlcmNlbnRNaW4sIHJlZmVyZW5jZXMpXG4gICAgOiB2YWx1ZUF4aXNPcHRpb24oY29uZmlnLnZhbHVlQXhpcywgaG9yaXpvbnRhbCwgcGVyY2VudE1pbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/IHZhbHVlQXhpc0xhYmVsKGF4aXNGb3JtYXRzWzBdLCBjb250ZXh0KVxuICAgICAgOiBwZXJjZW50QXhpc0xhYmVsKGNvbnRleHQpLCB7IHBlcmNlbnRNaW4sIHJlYWNoOiByZWZlcmVuY2VSZWFjaChyZWZlcmVuY2VzLCAwKSB9KTtcblxuICBjb25zdCBsZWdlbmRQb3NpdGlvbiA9IHJlc29sdmVMZWdlbmRQb3NpdGlvbihjb25maWcsIHNlcmllcy5sZW5ndGgsIGNvbG9yQnkpO1xuICBjb25zdCB2YWx1ZVRpdGxlcyA9IFtjb25maWcudmFsdWVBeGlzLCB0d29BeGVzID8gY29uZmlnLnNlY29uZGFyeUF4aXMgOiB1bmRlZmluZWRdO1xuICBjb25zdCBncmFudWxhcml0eSA9IGJ1Y2tldEdyYW51bGFyaXR5KGRhdGEpO1xuXG4gIHJldHVybiB7XG4gICAgZ3JpZDogYXhpc0dyaWQobGVnZW5kUG9zaXRpb24sIGNhdGVnb3J5VGl0bGVTaWRlKGNvbmZpZywgaG9yaXpvbnRhbCksIHZhbHVlVGl0bGVTaWRlKHZhbHVlVGl0bGVzLCBob3Jpem9udGFsKSksXG4gICAgbGVnZW5kOiByZWZlcmVuY2VMZWdlbmQobGVnZW5kT3B0aW9uKGxlZ2VuZFBvc2l0aW9uKSwgc2VyaWVzLCByZWZlcmVuY2VzKSxcbiAgICAvLyBjb2xvckJ5IGNoYXJ0cyBvdmVybGFwIE4gbW9zdGx5LW51bGwgc2VyaWVzLCBzbyBhbiBheGlzIHRvb2x0aXAgd291bGQgbGlzdFxuICAgIC8vIGV2ZXJ5IGNhdGVnb3J5OyBhbiBpdGVtIHRvb2x0aXAgc2hvd3MganVzdCB0aGUgaG92ZXJlZCBiYXIuIEEgMTAwJVxuICAgIC8vIHN0YWNrZWQgY2hhcnQncyB0b29sdGlwIGdpdmVzIGVhY2ggc2hhcmUgYW5kIHRoZSB2YWx1ZSBpdCBjYW1lIGZyb20uXG4gICAgdG9vbHRpcDogc2hhcmVzXG4gICAgICA/IHtcbiAgICAgICAgdHJpZ2dlcjogJ2F4aXMnLFxuICAgICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcykgPT4gcGVyY2VudFRvb2x0aXAoXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGV4dHJhY3RlZCxcbiAgICAgICAgICBzaGFyZXMsXG4gICAgICAgICAgZ3JhbnVsYXJpdHksXG4gICAgICAgICAgY2hhcnREYXRlTGFiZWwoY29uZmlnKSxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICApLFxuICAgICAgfVxuICAgICAgOiB7IHRyaWdnZXI6IGNvbG9yQnkgPyAnaXRlbScgOiAnYXhpcycgfSxcbiAgICB4QXhpczogaG9yaXpvbnRhbCA/IHZhbHVlQXhpcyA6IGNhdGVnb3J5QXhpcyxcbiAgICB5QXhpczogaG9yaXpvbnRhbCA/IGNhdGVnb3J5QXhpcyA6IHZhbHVlQXhpcyxcbiAgICBzZXJpZXM6IFsuLi5zZXJpZXMsIC4uLnJlZmVyZW5jZUNhcnJpZXJzKHJlZmVyZW5jZXMsIGV4dHJhY3RlZC5jYXRlZ29yaWVzKV0sXG4gIH07XG59XG5cbi8vIEEgY29sb3JCeSBjaGFydCdzIHN0YXRpc3RpYyBsaW5lOiBvbmUgbGluZSBvdmVyIGV2ZXJ5IGJhciwgaHVuZyBvZmYgdGhlXG4vLyBmaXJzdCBzZXJpZXMgYW5kIGRyYXduIGluIHRoZSByZWZlcmVuY2Ugc2xhdGUsIGFzIG5vIG9uZSBjYXRlZ29yeSdzIGNvbG9yXG4vLyBzcGVha3MgZm9yIHRoZSBvdGhlcnMuXG5mdW5jdGlvbiBjb2xvckJ5U3RhdExpbmUoXG4gIGZpcnN0OiBTZXJpZXNPcHRpb24sXG4gIGV4dHJhY3RlZDogRXh0cmFjdGVkQ2hhcnRTZXJpZXMsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBTZXJpZXNPcHRpb24ge1xuICBjb25zdCBtZWFzdXJlID0gZXh0cmFjdGVkLnNlcmllc1swXT8ubWVhc3VyZTtcbiAgY29uc3Qgc3RhdCA9IG1lYXN1cmVNYXJrU3RhdChtZWFzdXJlKTtcbiAgY29uc3QgbWFya0xpbmUgPSBzdGF0ICYmIHN0YXRNYXJrTGluZShcbiAgICBjb2xvckJ5VmFsdWVzKGV4dHJhY3RlZCksXG4gICAgc3RhdCxcbiAgICBtZWFzdXJlV3JpdGVyKG1lYXN1cmUsIGNvbnRleHQpLFxuICAgIGAjJHtSRVBPUlRfUkVGRVJFTkNFX0NPTE9SfWAsXG4gICk7XG5cbiAgcmV0dXJuIG1hcmtMaW5lID8geyAuLi5maXJzdCwgbWFya0xpbmUgfSBhcyBTZXJpZXNPcHRpb24gOiBmaXJzdDtcbn1cblxuLy8gQSBzZXJpZXMnIHN0YXRpc3RpYyBsaW5lIGFjcm9zcyB0aGUgcGxvdCwgbGFiZWxlZCB3aXRoIHRoZSBzdGF0aXN0aWMgYW5kXG4vLyBpdHMgdmFsdWUgKCdBdmVyYWdlOiAxLDIzNC41JyksIG9yIHVuZGVmaW5lZCB3aGVuIG5vIHBvaW50IGhhcyBhIHZhbHVlLiBJdFxuLy8gdGFrZXMgdGhlIHNlcmllcycgY29sb3IgdW5sZXNzIGl0IGlzIGdpdmVuIG9uZS5cbmZ1bmN0aW9uIHN0YXRNYXJrTGluZShcbiAgdmFsdWVzOiAobnVtYmVyIHwgbnVsbClbXSxcbiAgc3RhdDogUmVwb3J0Q2hhcnRNYXJrU3RhdCxcbiAgd3JpdGU6ICh2YWx1ZTogbnVtYmVyKSA9PiBzdHJpbmcsXG4gIGNvbG9yPzogc3RyaW5nLFxuKSB7XG4gIGNvbnN0IHZhbHVlID0gc2VyaWVzU3RhdCh2YWx1ZXMsIHN0YXQpO1xuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCB0ZXh0ID0gYCR7U1RBVF9MQUJFTFtzdGF0XX06ICR7d3JpdGUodmFsdWUpfWA7XG5cbiAgcmV0dXJuIHtcbiAgICBzaWxlbnQ6IHRydWUsXG4gICAgc3ltYm9sOiAnbm9uZScsXG4gICAgbGluZVN0eWxlOiB7IHR5cGU6ICdkYXNoZWQnIGFzIGNvbnN0LCB3aWR0aDogMSwgLi4uKGNvbG9yID8geyBjb2xvciB9IDoge30pIH0sXG4gICAgbGFiZWw6IHsgZm9ybWF0dGVyOiAoKSA9PiB0ZXh0LCBwb3NpdGlvbjogJ2luc2lkZUVuZFRvcCcgYXMgY29uc3QsIGZvbnRTaXplOiBSRVBPUlRfREFUQV9MQUJFTF9GT05UX1NJWkUsIC4uLk1BUktfTEFCRUxfQk9YIH0sXG4gICAgZGF0YTogW3sgeUF4aXM6IHZhbHVlIH1dLFxuICB9O1xufVxuXG4vLyBBIHN0YXRpc3RpYydzIHZhbHVlIGluIGl0cyBtZWFzdXJlJ3MgbnVtYmVyIGZvcm1hdCwgaW4gdGhlIHJlcG9ydCBsb2NhbGUuXG5mdW5jdGlvbiBtZWFzdXJlV3JpdGVyKG1lYXN1cmU6IENoYXJ0TWVhc3VyZSB8IHVuZGVmaW5lZCwgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCk6ICh2YWx1ZTogbnVtYmVyKSA9PiBzdHJpbmcge1xuICByZXR1cm4gKHZhbHVlKSA9PiBmb3JtYXROdW1iZXIodmFsdWUsIG1lYXN1cmUsIGNvbnRleHQpO1xufVxuXG4vLyBBIDEwMCUgc3RhY2tlZCBzZXJpZXMnIHN0YXRpc3RpYyBpcyBhIHNoYXJlLCB3cml0dGVuIGFzIGl0cyB0b29sdGlwIHdyaXRlc1xuLy8gb25lLlxuZnVuY3Rpb24gc2hhcmVXcml0ZXIoY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCk6ICh2YWx1ZTogbnVtYmVyKSA9PiBzdHJpbmcge1xuICBjb25zdCByYXRpb0NvbnRleHQgPSB7IC4uLmNvbnRleHQsIHJhdGlvUGVyY2VudDogdHJ1ZSB9O1xuXG4gIHJldHVybiAodmFsdWUpID0+IGZvcm1hdE51bWJlcih2YWx1ZSwgUEVSQ0VOVF9TSEFSRV9GT1JNQVQsIHJhdGlvQ29udGV4dCk7XG59XG5cbi8vIFRoZSBzZXJpZXMgdGhhdCBjYXJyeSBhIGNoYXJ0J3MgcmVmZXJlbmNlcywgb25lIHBlciB2YWx1ZSBheGlzIHRoYXQgaGFzXG4vLyBhbnk6IGFuIGVtcHR5IGxpbmUgKGV2ZXJ5IHBvaW50IG51bGwsIHNvIGl0IGRyYXdzIG5vdGhpbmcgYW5kIHN0cmV0Y2hlcyBub1xuLy8gYXhpcykgd2hvc2UgbWFya0xpbmUgZHJhd3MgdGhlIHJlZmVyZW5jZSBsaW5lcyBhbmQgd2hvc2UgbWFya0FyZWEgZmlsbHMgdGhlXG4vLyBiYW5kcy4gSXQgaXMgc2lsZW50LCBsZWZ0IG91dCBvZiB0aGUgdG9vbHRpcCBhbmQsIGJ5IHJlZmVyZW5jZUxlZ2VuZCwgb3V0IG9mXG4vLyB0aGUgbGVnZW5kLiBJdCBoYXMgbm8gbmFtZSwgc28gbm8gbWVhc3VyZSBzZXJpZXMnIGxlZ2VuZCBlbnRyeSAod2hhdGV2ZXIgaXRzXG4vLyBuYW1lLCAnJyBpbmNsdWRlZCkgdG9nZ2xlcyBpdC5cbi8vXG4vLyBMYWJlbHMgYXJlIGZ1bmN0aW9ucywgYXMgYSBzdHJpbmcgZm9ybWF0dGVyIGlzIGEgdGVtcGxhdGUgdGhhdCB3b3VsZCByZWFkXG4vLyAne2J9JyBvciAne2N9JyBpbiBhIGxhYmVsIGFzIGEgcGxhY2Vob2xkZXIuIEVDaGFydHMgZHJhd3MgYSBtYXJrQXJlYSB1bmRlclxuLy8gdGhlIGJhcnMgYW5kIGEgbWFya0xpbmUgb3ZlciB0aGVtLCBzbyBhIGJhbmQncyBsYWJlbCByaWRlcyBhbiBpbnZpc2libGVcbi8vIG1hcmtMaW5lIG9uIGl0cyB1cHBlciBlZGdlLCBpbnNpZGUgaXRzIHRvcCBsZWZ0IGNvcm5lciwgd2hlcmUgdGhlIGZpcnN0IGJhclxuLy8gd291bGQgb3RoZXJ3aXNlIGNvdmVyIGl0LlxuZnVuY3Rpb24gcmVmZXJlbmNlQ2FycmllcnMocmVmZXJlbmNlczogRHJhd25SZWZlcmVuY2VbXSwgY2F0ZWdvcmllczogc3RyaW5nW10pOiBTZXJpZXNPcHRpb25bXSB7XG4gIGNvbnN0IGNvbG9yID0gYCMke1JFUE9SVF9SRUZFUkVOQ0VfQ09MT1J9YDtcblxuICByZXR1cm4gKFswLCAxXSBhcyBjb25zdCkuZmxhdE1hcCgoYXhpc0luZGV4KTogU2VyaWVzT3B0aW9uW10gPT4ge1xuICAgIGNvbnN0IG9uQXhpcyA9IHJlZmVyZW5jZXMuZmlsdGVyKChyZWZlcmVuY2UpID0+IHJlZmVyZW5jZS5heGlzSW5kZXggPT09IGF4aXNJbmRleCk7XG4gICAgY29uc3QgbGluZXMgPSBvbkF4aXMuZmlsdGVyKChyZWZlcmVuY2UpID0+ICFyZWZlcmVuY2UuYmFuZCk7XG4gICAgY29uc3QgYmFuZHMgPSBvbkF4aXMuZmlsdGVyKChyZWZlcmVuY2UpID0+IHJlZmVyZW5jZS5iYW5kKTtcblxuICAgIGlmICghb25BeGlzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBbe1xuICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgZGF0YTogY2F0ZWdvcmllcy5tYXAoKCkgPT4gbnVsbCksXG4gICAgICB5QXhpc0luZGV4OiBheGlzSW5kZXgsXG4gICAgICBzaWxlbnQ6IHRydWUsXG4gICAgICB0b29sdGlwOiB7IHNob3c6IGZhbHNlIH0sXG4gICAgICBtYXJrTGluZToge1xuICAgICAgICBzaWxlbnQ6IHRydWUsXG4gICAgICAgIHN5bWJvbDogJ25vbmUnLFxuICAgICAgICBsaW5lU3R5bGU6IHsgY29sb3IsIHR5cGU6ICdkYXNoZWQnLCB3aWR0aDogMSB9LFxuICAgICAgICBsYWJlbDogeyBwb3NpdGlvbjogJ2luc2lkZUVuZFRvcCcsIGNvbG9yLCBmb250U2l6ZTogUkVQT1JUX0RBVEFfTEFCRUxfRk9OVF9TSVpFLCAuLi5NQVJLX0xBQkVMX0JPWCB9LFxuICAgICAgICBkYXRhOiBbXG4gICAgICAgICAgLi4ubGluZXMubWFwKChyZWZlcmVuY2UpID0+ICh7IHlBeGlzOiByZWZlcmVuY2UubG93LCBsYWJlbDogeyBmb3JtYXR0ZXI6ICgpID0+IHJlZmVyZW5jZS5sYWJlbCB9IH0pKSxcbiAgICAgICAgICAuLi5iYW5kcy5tYXAoKHJlZmVyZW5jZSkgPT4gKHtcbiAgICAgICAgICAgIHlBeGlzOiByZWZlcmVuY2UuaGlnaCxcbiAgICAgICAgICAgIC8vIFplcm8gd2lkdGgsIG5vdCB6ZXJvIG9wYWNpdHk6IGEgbWFya0xpbmUncyBsYWJlbCB0YWtlcyB0aGVcbiAgICAgICAgICAgIC8vIGxpbmUncyBvcGFjaXR5LlxuICAgICAgICAgICAgbGluZVN0eWxlOiB7IHdpZHRoOiAwIH0sXG4gICAgICAgICAgICBsYWJlbDogeyBwb3NpdGlvbjogJ2luc2lkZVN0YXJ0Qm90dG9tJywgZm9ybWF0dGVyOiAoKSA9PiByZWZlcmVuY2UubGFiZWwgfSxcbiAgICAgICAgICB9KSksXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAgLi4uKGJhbmRzLmxlbmd0aCA/IHtcbiAgICAgICAgbWFya0FyZWE6IHtcbiAgICAgICAgICBzaWxlbnQ6IHRydWUsXG4gICAgICAgICAgaXRlbVN0eWxlOiB7IGNvbG9yOiBSRUZFUkVOQ0VfQkFORF9GSUxMIH0sXG4gICAgICAgICAgZGF0YTogYmFuZHMubWFwKChyZWZlcmVuY2UpID0+IFt7IHlBeGlzOiByZWZlcmVuY2UubG93IH0sIHsgeUF4aXM6IHJlZmVyZW5jZS5oaWdoIH1dKSxcbiAgICAgICAgfSxcbiAgICAgIH0gOiB7fSksXG4gICAgfSBhcyBTZXJpZXNPcHRpb25dO1xuICB9KTtcbn1cblxuLy8gVGhlIGxhcmdlc3QgbWFnbml0dWRlIGEgdmFsdWUgYXhpcydzIHJlZmVyZW5jZXMgcmVhY2gsIHdoaWNoIGl0cyBudW1iZXJcbi8vIGZvcm1hdCBjb3VudHMgdG93YXJkIGl0cyBwZWFrLCBhcyB0aGUgYXhpcyBzdHJldGNoZXMgdG8gdGhlbTsgMCB3aGVuIGl0XG4vLyBoYXMgbm9uZS5cbmV4cG9ydCBmdW5jdGlvbiByZWZlcmVuY2VQZWFrKHJlZmVyZW5jZXM6IERyYXduUmVmZXJlbmNlW10sIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXgpOiBudW1iZXIge1xuICBjb25zdCByZWFjaCA9IHJlZmVyZW5jZVJlYWNoKHJlZmVyZW5jZXMsIGF4aXNJbmRleCk7XG5cbiAgcmV0dXJuIHJlYWNoID8gTWF0aC5tYXgoTWF0aC5hYnMocmVhY2gubG93KSwgTWF0aC5hYnMocmVhY2guaGlnaCkpIDogMDtcbn1cblxuLy8gVGhlIGxlZ2VuZCBvZiBhIGNoYXJ0IHdpdGggcmVmZXJlbmNlcyBuYW1lcyBpdHMgbWVhc3VyZSBzZXJpZXMgYWxvbmUsIHNvXG4vLyBhIGNhcnJpZXIgbmV2ZXIgc2hvd3MgYXMgYSBibGFuayBlbnRyeS4gV2l0aG91dCByZWZlcmVuY2VzIGl0IGlzIGxlZnQgYXMgaXRcbi8vIHdhcy5cbmZ1bmN0aW9uIHJlZmVyZW5jZUxlZ2VuZChcbiAgbGVnZW5kOiBMZWdlbmRDb21wb25lbnRPcHRpb24sXG4gIHNlcmllczogU2VyaWVzT3B0aW9uW10sXG4gIHJlZmVyZW5jZXM6IERyYXduUmVmZXJlbmNlW10sXG4pOiBMZWdlbmRDb21wb25lbnRPcHRpb24ge1xuICByZXR1cm4gcmVmZXJlbmNlcy5sZW5ndGhcbiAgICA/IHsgLi4ubGVnZW5kLCBkYXRhOiBzZXJpZXMubWFwKChpdGVtKSA9PiBTdHJpbmcoaXRlbS5uYW1lID8/ICcnKSkgfVxuICAgIDogbGVnZW5kO1xufVxuXG4vLyBUaGUgc3BhbiBvZiB0aGUgcmVmZXJlbmNlcyBvbiBvbmUgdmFsdWUgYXhpcywgb3IgdW5kZWZpbmVkIHdoZW4gaXQgaGFzXG4vLyBub25lLlxuZnVuY3Rpb24gcmVmZXJlbmNlUmVhY2gocmVmZXJlbmNlczogRHJhd25SZWZlcmVuY2VbXSwgYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleCk6IFJlZmVyZW5jZVJlYWNoIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgb25BeGlzID0gcmVmZXJlbmNlcy5maWx0ZXIoKHJlZmVyZW5jZSkgPT4gcmVmZXJlbmNlLmF4aXNJbmRleCA9PT0gYXhpc0luZGV4KTtcblxuICByZXR1cm4gb25BeGlzLmxlbmd0aFxuICAgID8geyBsb3c6IE1hdGgubWluKC4uLm9uQXhpcy5tYXAoKHJlZmVyZW5jZSkgPT4gcmVmZXJlbmNlLmxvdykpLCBoaWdoOiBNYXRoLm1heCguLi5vbkF4aXMubWFwKChyZWZlcmVuY2UpID0+IHJlZmVyZW5jZS5oaWdoKSkgfVxuICAgIDogdW5kZWZpbmVkO1xufVxuXG4vLyBFQ2hhcnRzIGxlYXZlcyBhIG1hcmtMaW5lIG9yIG1hcmtBcmVhIG91dCBvZiBhbiBheGlzJ3MgZXh0ZW50LCBzbyBhXG4vLyByZWZlcmVuY2UgYmV5b25kIHRoZSBkYXRhIHdvdWxkIGZhbGwgb2ZmIHRoZSBwbG90LiBBbiBheGlzIGJvdW5kIHRoZSBjb25maWdcbi8vIGRvZXMgbm90IHBpbiByZWFjaGVzIHBhc3QgdGhlIGZ1cnRoZXN0IHJlZmVyZW5jZSwgdG8gYSByb3VuZCBudW1iZXIgd2l0aFxuLy8gcm9vbSBmb3IgaXRzIGxhYmVsIChiZXlvbmRSZWZlcmVuY2UpLCB3aGVuIHRoZSBkYXRhIChhbmQgdGhlIHplcm8gYSB2YWx1ZVxuLy8gYXhpcyBhbHdheXMgc2hvd3MpIGZhbGxzIHNob3J0IG9mIGl0LCBhbmQgaXMgbGVmdCB0byBFQ2hhcnRzIG90aGVyd2lzZTogYVxuLy8gY2FsbGJhY2sgcmV0dXJuaW5nIHVuZGVmaW5lZCBrZWVwcyB0aGUgYm91bmQgYXV0b21hdGljLiBQYXN0IHRoZSBkYXRhIGFuZFxuLy8gemVybywgYSByZWZlcmVuY2UgYmV5b25kIHRoZSBtYXggaXMgYWJvdmUgemVybyBhbmQgb25lIGJleW9uZCB0aGUgbWluIGJlbG93XG4vLyBpdC5cbmZ1bmN0aW9uIHJlYWNoTWluKHJlYWNoOiBSZWZlcmVuY2VSZWFjaCB8IHVuZGVmaW5lZCkge1xuICByZXR1cm4gcmVhY2hcbiAgICA/IChleHRlbnQ6IEF4aXNFeHRlbnQpID0+IChyZWFjaC5sb3cgPCBNYXRoLm1pbihleHRlbnQubWluLCAwKSA/IC1iZXlvbmRSZWZlcmVuY2UoLXJlYWNoLmxvdykgOiB1bmRlZmluZWQpXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHJlYWNoTWF4KHJlYWNoOiBSZWZlcmVuY2VSZWFjaCB8IHVuZGVmaW5lZCkge1xuICByZXR1cm4gcmVhY2hcbiAgICA/IChleHRlbnQ6IEF4aXNFeHRlbnQpID0+IChyZWFjaC5oaWdoID4gTWF0aC5tYXgoZXh0ZW50Lm1heCwgMCkgPyBiZXlvbmRSZWZlcmVuY2UocmVhY2guaGlnaCkgOiB1bmRlZmluZWQpXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbi8vIFRoZSBib3VuZCBhbiBheGlzIHRha2VzIHBhc3QgYSByZWZlcmVuY2Ugb2YgdGhpcyAocG9zaXRpdmUpIG1hZ25pdHVkZTogdGhlXG4vLyBzbWFsbGVzdCByb3VuZCBudW1iZXIgYXQgb3IgYWJvdmUgaXQgcGx1cyBSRUZFUkVOQ0VfSEVBRFJPT00uIFRoZSBzdGVwcyBhcmVcbi8vIGZpbmVyIHRoYW4gRUNoYXJ0cycgdGljayBzdGVwcywgc28gYSByZWZlcmVuY2UganVzdCBwYXN0IHRoZSBkYXRhIGRvZXMgbm90XG4vLyBkb3VibGUgdGhlIGF4aXMgKDExMCBnaXZlcyAxMjAsIG5vdCAyMDApLiBUaGUgdG9sZXJhbmNlIGtlZXBzIGEgZmxvYXQgZXJyb3Jcbi8vIGZyb20gc2tpcHBpbmcgYSByb3VuZCBudW1iZXIgdGhlIHZhbHVlIGFscmVhZHkgaXMuXG5jb25zdCBOSUNFX1NURVBTID0gWzEsIDEuMiwgMS41LCAyLCAyLjUsIDMsIDQsIDUsIDYsIDgsIDEwXTtcbmNvbnN0IE5JQ0VfVE9MRVJBTkNFID0gMWUtOTtcblxuZnVuY3Rpb24gYmV5b25kUmVmZXJlbmNlKG1hZ25pdHVkZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgdGFyZ2V0ID0gbWFnbml0dWRlICogUkVGRVJFTkNFX0hFQURST09NO1xuICBjb25zdCBwb3dlciA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKE1hdGgubG9nMTAodGFyZ2V0KSkpO1xuICBjb25zdCBzdGVwID0gTklDRV9TVEVQUy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZSAqIHBvd2VyID49IHRhcmdldCAqICgxIC0gTklDRV9UT0xFUkFOQ0UpKSA/PyAxMDtcblxuICAvLyBSb3VuZGVkIGJhY2sgdG8gdGhlIHBvd2VyJ3Mgb3duIGRpZ2l0cywgc28gMS4yIHggMC4xIHJlYWRzIDAuMTIsIG5vdFxuICAvLyAwLjEyMDAwMDAwMDAwMDAwMDAxLlxuICByZXR1cm4gTnVtYmVyKChzdGVwICogcG93ZXIpLnRvUHJlY2lzaW9uKDEyKSk7XG59XG5cbi8vIFRoZSBjYXRlZ29yeSBheGlzIG9mIGFuIGF4aXMgY2hhcnQgb3IgYSB3YXRlcmZhbGw6IHRoZSBjYXRlZ29yaWVzIGluIHJvd1xuLy8gb3JkZXIsIGxhYmVsZWQgYXMgcGVyaW9kcyB3aGVuIHRoZSByb3dzIHdlcmUgYnVja2V0ZWQgYnkgdGltZS5cbi8vXG4vLyBIb3Jpem9udGFsIGJhcnMgcmVhZCB0b3AtZG93bjogRUNoYXJ0cyBkcmF3cyBjYXRlZ29yeSAwIGF0IHRoZSBib3R0b20sIHNvIHRoZVxuLy8gYXhpcyBpcyBpbnZlcnRlZCB0byBwdXQgdGhlIGZpcnN0IHJvdyAodGhlIGxhcmdlc3Qgb2YgYSB0b3AtTiwgYSB3YXRlcmZhbGwnc1xuLy8gZmlyc3Qgc3RlcCkgYXQgdGhlIHRvcC4gVGhlIHJvdGF0ZWQgdGl0bGUgc2l0cyBqdXN0IGJleW9uZCB0aGUgbG9uZ2VzdCBsYWJlbFxuLy8gcmF0aGVyIHRoYW4gYXQgYSBmaXhlZCBnYXAgdGhhdCB3b3VsZCBwdXQgaXQgb24gdG9wIG9mIHRoZSBsYWJlbHMuXG4vL1xuLy8gQSBidWNrZXRlZCBheGlzIGFsc28gbmFtZXMgaXRzIHBlcmlvZCBpbiB0aGUgYXhpcyB0b29sdGlwJ3MgaGVhZGVyOiBFQ2hhcnRzXG4vLyBoZWFkcyBpdCB3aXRoIHRoZSByYXcgY2F0ZWdvcnkgKCcyMDI2LTAxLTAxJykgdW5sZXNzIHRoZSBheGlzIHBvaW50ZXIncyBsYWJlbFxuLy8gaGFzIGEgZm9ybWF0dGVyLCBzbyBpdCByZWFkcyAnSmFudWFyeSAyMDI2JyBpbnN0ZWFkLCBhbHdheXMgd2l0aCBpdHMgeWVhci5cbi8vIFRoZSBheGlzJ3MgZGF0ZUxhYmVsIHN0eWxlIHdyaXRlcyBib3RoIGl0cyB0aWNrIGxhYmVscyBhbmQgdGhhdCBoZWFkZXIuXG5mdW5jdGlvbiBjYXRlZ29yeUF4aXNPcHRpb24oXG4gIGNvbmZpZzogQ2hhcnRDb25maWcsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGNhdGVnb3JpZXM6IHN0cmluZ1tdLFxuICBob3Jpem9udGFsOiBib29sZWFuLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbikge1xuICBjb25zdCBncmFudWxhcml0eSA9IGJ1Y2tldEdyYW51bGFyaXR5KGRhdGEpO1xuICBjb25zdCBkYXRlTGFiZWwgPSBjaGFydERhdGVMYWJlbChjb25maWcpO1xuICBjb25zdCBwZXJpb2RMYWJlbCA9IHBlcmlvZEF4aXNMYWJlbChncmFudWxhcml0eSwgY2F0ZWdvcmllcywgbG9jYWxlLCBkYXRlTGFiZWwpO1xuICBjb25zdCBheGlzID0ge1xuICAgIHR5cGU6ICdjYXRlZ29yeScgYXMgY29uc3QsXG4gICAgZGF0YTogY2F0ZWdvcmllcyxcbiAgICBpbnZlcnNlOiBob3Jpem9udGFsLFxuICAgIG5hbWU6IGNvbmZpZy54QXhpcz8ubGFiZWwsXG4gICAgbmFtZUxvY2F0aW9uOiAnbWlkZGxlJyBhcyBjb25zdCxcbiAgICAuLi4oZ3JhbnVsYXJpdHkgPyB7XG4gICAgICBheGlzUG9pbnRlcjoge1xuICAgICAgICBsYWJlbDoge1xuICAgICAgICAgIGZvcm1hdHRlcjogKHBhcmFtczogeyB2YWx1ZTogdW5rbm93biB9KSA9PiBmb3JtYXRQZXJpb2RMYWJlbChcbiAgICAgICAgICAgIFN0cmluZyhwYXJhbXMudmFsdWUpLFxuICAgICAgICAgICAgZ3JhbnVsYXJpdHksXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgICAgZGF0ZUxhYmVsLFxuICAgICAgICAgICksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0gOiB7fSksXG4gIH07XG5cbiAgaWYgKCFob3Jpem9udGFsKSB7XG4gICAgLy8gVGhlIGdhcCBjbGVhcnMgdGhlIHllYXIncyBzZWNvbmQgbGluZSB3aGVuIHRoZSBsYWJlbHMgcHJpbnQgb25lLlxuICAgIGNvbnN0IHNlY29uZExpbmUgPSBncmFudWxhcml0eSAmJiBkYXRlTGFiZWwgPT09IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0ICYmIHNwYW5zTXVsdGlwbGVZZWFycyhjYXRlZ29yaWVzKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5heGlzLFxuICAgICAgbmFtZUdhcDogc2Vjb25kTGluZSA/IDQwIDogMjgsXG4gICAgICAuLi5wZXJpb2RMYWJlbCxcbiAgICB9O1xuICB9XG5cbiAgLy8gUGVyaW9kIGxhYmVscywgc2hvcnQsIGxvbmcgb3IgbnVtZXJpYyAoJ01heScsICdRMicsICdNYXkgMjAyNicpLCBhcmVcbiAgLy8gYm91bmRlZCBpbiBsZW5ndGggYW5kIG5ldmVyIGN1dDsgb25seSBhIHBsYWluIGNhdGVnb3J5IGlzIHRydW5jYXRlZC4gVGhlIGxhYmVscyBhcmUgY3V0IGhlcmUgcmF0aGVyIHRoYW4gYnkgRUNoYXJ0cycgb3duXG4gIC8vIHRydW5jYXRpb24sIHNvIHRoZSB0aXRsZSdzIGdhcCBpcyBtZWFzdXJlZCBvbiBleGFjdGx5IHRoZSB0ZXh0IHRoZSBheGlzXG4gIC8vIGRyYXdzLlxuICBjb25zdCBzaG93biA9IGdyYW51bGFyaXR5XG4gICAgPyBudWxsXG4gICAgOiBuZXcgTWFwKGNhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gW2NhdGVnb3J5LCB0cnVuY2F0ZUF4aXNMYWJlbChjYXRlZ29yeSldKSk7XG4gIGNvbnN0IGxhYmVscyA9IHNob3duID8gWy4uLnNob3duLnZhbHVlcygpXSA6IGRpc3BsYXllZENhdGVnb3J5TGFiZWxzKGNhdGVnb3JpZXMsIGdyYW51bGFyaXR5LCBsb2NhbGUsIGRhdGVMYWJlbCk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5heGlzLFxuICAgIG5hbWVHYXA6IHdpZGVzdEF4aXNMYWJlbChsYWJlbHMpICsgQVhJU19MQUJFTF9NQVJHSU4gKyBBWElTX05BTUVfQ0xFQVJBTkNFLFxuICAgIC4uLihzaG93biA/IHsgYXhpc0xhYmVsOiB7IGZvcm1hdHRlcjogKHZhbHVlOiBzdHJpbmcpID0+IHNob3duLmdldCh2YWx1ZSkgPz8gdmFsdWUgfSB9IDogcGVyaW9kTGFiZWwpLFxuICB9O1xufVxuXG4vLyBUaGUgY2F0ZWdvcnkgYXhpcydzIHRpdGxlIHNpZGUsIG9yIG51bGwgd2hlbiB0aGUgYXhpcyBoYXMgbm8gdGl0bGUgdG8gbWFrZVxuLy8gcm9vbSBmb3IuXG5mdW5jdGlvbiBjYXRlZ29yeVRpdGxlU2lkZShjb25maWc6IENoYXJ0Q29uZmlnLCBob3Jpem9udGFsOiBib29sZWFuKTogQXhpc1RpdGxlU2lkZSB8IG51bGwge1xuICBpZiAoIWNvbmZpZy54QXhpcz8ubGFiZWwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBob3Jpem9udGFsID8gJ2xlZnQnIDogJ2JvdHRvbSc7XG59XG5cbi8vIFRoZSB2YWx1ZSBheGVzJyB0aXRsZSBzaWRlLCBvciBudWxsIHdoZW4gbm9uZSBvZiB0aGVtIGhhcyBhIHRpdGxlLiBBXG4vLyB2ZXJ0aWNhbCBjaGFydCdzIHRpdGxlcyBzaXQgYWJvdmUgdGhlIHBsb3QsIGF0IHRoZSB0b3Agb2YgZWFjaCBheGlzIGxpbmUsIHNvXG4vLyByb29tIGlzIG1hZGUgb25jZSBmb3IgYm90aDsgYSBob3Jpem9udGFsIGNoYXJ0J3Mgc2l0cyBiZWxvdy5cbmZ1bmN0aW9uIHZhbHVlVGl0bGVTaWRlKGF4ZXM6IChDaGFydFZhbHVlQXhpcyB8IHVuZGVmaW5lZClbXSwgaG9yaXpvbnRhbDogYm9vbGVhbik6IEF4aXNUaXRsZVNpZGUgfCBudWxsIHtcbiAgaWYgKCFheGVzLnNvbWUoKGF4aXMpID0+IGF4aXM/LmxhYmVsKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGhvcml6b250YWwgPyAnYm90dG9tJyA6ICd0b3AnO1xufVxuXG4vLyBUaGUgdGljayBsYWJlbHMgYXMgdGhlIGF4aXMgc2hvd3MgdGhlbTogYSBidWNrZXQncyBwcmltYXJ5IHBlcmlvZCBsYWJlbFxuLy8gKCdNYXknLCAnUTInLCAnTWF5IDIwMjYnKSwgb3RoZXJ3aXNlIHRoZSBjYXRlZ29yeSBpdHNlbGYuIFRoZSB5ZWFyIGFcbi8vIG11bHRpLXllYXIgYXhpcyBwcmludHMgdW5kZXIgYSBzaG9ydCBwZXJpb2QgaXMgbGVmdCBvdXQsIGFzIGl0IGlzIG5ldmVyIHRoZVxuLy8gd2lkZXIgbGluZS5cbmZ1bmN0aW9uIGRpc3BsYXllZENhdGVnb3J5TGFiZWxzKFxuICBjYXRlZ29yaWVzOiBzdHJpbmdbXSxcbiAgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsLFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCxcbik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGdyYW51bGFyaXR5XG4gICAgPyBjYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnkpID0+IHBlcmlvZExhYmVsUGFydHMoY2F0ZWdvcnksIGdyYW51bGFyaXR5LCBsb2NhbGUsIGRhdGVMYWJlbCk/LnByaW1hcnkgPz8gY2F0ZWdvcnkpXG4gICAgOiBjYXRlZ29yaWVzO1xufVxuXG4vLyBUaGUgcGl4ZWwgd2lkdGggb2YgdGhlIHdpZGVzdCBsYWJlbC4gQSBsYWJlbCB0aGF0IGJyZWFrcyBvdmVyIHNldmVyYWwgbGluZXNcbi8vIGlzIGFzIHdpZGUgYXMgaXRzIGxvbmdlc3QgbGluZS5cbmZ1bmN0aW9uIHdpZGVzdEF4aXNMYWJlbChsYWJlbHM6IHN0cmluZ1tdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGxhYmVscy5yZWR1Y2UoKHdpZGVzdCwgbGFiZWwpID0+IGxhYmVsLnNwbGl0KCdcXG4nKS5yZWR1Y2UoXG4gICAgKGxpbmVXaWRlc3QsIGxpbmUpID0+IE1hdGgubWF4KGxpbmVXaWRlc3QsIGF4aXNMYWJlbFdpZHRoKGxpbmUpKSxcbiAgICB3aWRlc3QsXG4gICksIDApO1xufVxuXG4vLyBBIGNhdGVnb3J5IGxhYmVsIGN1dCB0byBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEgsIGxpbmUgYnkgbGluZTogdGhlIGxvbmdlc3Rcbi8vIHN0YXJ0IG9mIGVhY2ggbGluZSB0aGF0IHN0aWxsIGZpdHMgd2l0aCB0aGUgZWxsaXBzaXMgYWZ0ZXIgaXQuXG5mdW5jdGlvbiB0cnVuY2F0ZUF4aXNMYWJlbChsYWJlbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGxhYmVsLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmUpID0+IHtcbiAgICBpZiAoYXhpc0xhYmVsV2lkdGgobGluZSkgPD0gQ0FURUdPUllfTEFCRUxfTUFYX1dJRFRIKSB7XG4gICAgICByZXR1cm4gbGluZTtcbiAgICB9XG5cbiAgICAvLyBDb2RlIHBvaW50cywgc28gYW4gZW1vamkgb3Igb3RoZXIgc3Vycm9nYXRlIHBhaXIgaXMgbmV2ZXIgc3BsaXQuXG4gICAgY29uc3QgY2hhcmFjdGVycyA9IEFycmF5LmZyb20obGluZSk7XG4gICAgY29uc3QgY3V0ID0gKGxlbmd0aDogbnVtYmVyKSA9PiBgJHtjaGFyYWN0ZXJzLnNsaWNlKDAsIGxlbmd0aCkuam9pbignJykudHJpbUVuZCgpfSR7TEFCRUxfRUxMSVBTSVN9YDtcbiAgICBsZXQgZml0cyA9IDA7XG4gICAgbGV0IHRvb0xvbmcgPSBjaGFyYWN0ZXJzLmxlbmd0aDtcbiAgICB3aGlsZSAodG9vTG9uZyAtIGZpdHMgPiAxKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSBNYXRoLmZsb29yKChmaXRzICsgdG9vTG9uZykgLyAyKTtcbiAgICAgIGlmIChheGlzTGFiZWxXaWR0aChjdXQobGVuZ3RoKSkgPD0gQ0FURUdPUllfTEFCRUxfTUFYX1dJRFRIKSB7XG4gICAgICAgIGZpdHMgPSBsZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0b29Mb25nID0gbGVuZ3RoO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXQoZml0cyk7XG4gIH0pLmpvaW4oJ1xcbicpO1xufVxuXG4vLyBPbmUgbGluZSdzIHdpZHRoIGluIHRoZSBheGlzLWxhYmVsIGZvbnQsIG1lYXN1cmVkIG9uIGEgY2FudmFzIHRoZSB3YXlcbi8vIEVDaGFydHMgbWVhc3VyZXMgaXQgZm9yIGNvbnRhaW5MYWJlbC4gT3V0c2lkZSBhIGJyb3dzZXIgdGhlcmUgaXMgbm8gY2FudmFzXG4vLyB0byBtZWFzdXJlIHdpdGgsIHNvIHRoZSBsaW5lIGNvdW50cyBhcyB6ZXJvIHdpZHRoLlxubGV0IGF4aXNMYWJlbENvbnRleHQ6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCB8IG51bGwgPSBudWxsO1xuXG5mdW5jdGlvbiBheGlzTGFiZWxXaWR0aChsaW5lOiBzdHJpbmcpOiBudW1iZXIge1xuICBpZiAoIWF4aXNMYWJlbENvbnRleHQgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGF4aXNMYWJlbENvbnRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKS5nZXRDb250ZXh0KCcyZCcpO1xuICB9XG5cbiAgaWYgKCFheGlzTGFiZWxDb250ZXh0KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBheGlzTGFiZWxDb250ZXh0LmZvbnQgPSBBWElTX0xBQkVMX0ZPTlQ7XG5cbiAgcmV0dXJuIGF4aXNMYWJlbENvbnRleHQubWVhc3VyZVRleHQobGluZSkud2lkdGg7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkV2F0ZXJmYWxsT3B0aW9uKFxuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6IEVDaGFydHNPcHRpb24ge1xuICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnIGFzIENoYXJ0Q29uZmlnO1xuICBjb25zdCB3YXRlcmZhbGwgPSBleHRyYWN0V2F0ZXJmYWxsKGNvbXBvbmVudCwgZGF0YSk7XG4gIGNvbnN0IGhvcml6b250YWwgPSBjb25maWcub3JpZW50YXRpb24gPT09ICdob3Jpem9udGFsJztcbiAgY29uc3QgY2F0ZWdvcmllcyA9IHdhdGVyZmFsbC5zdGVwcy5tYXAoKHN0ZXApID0+IHN0ZXAuY2F0ZWdvcnkpO1xuICBjb25zdCBjYXRlZ29yeUF4aXMgPSBjYXRlZ29yeUF4aXNPcHRpb24oY29uZmlnLCBkYXRhLCBjYXRlZ29yaWVzLCBob3Jpem9udGFsLCBjb250ZXh0LmxvY2FsZSk7XG4gIC8vIFRoZSBvbmUgbWVhc3VyZSdzIGZvcm1hdCB3cml0ZXMgdGhlIGF4aXMgYW5kIHRoZSB0b29sdGlwLiBUaGUgYXhpcyBoYXMgdG9cbiAgLy8gcmVhY2ggdGhlIGZ1cnRoZXN0IHBvaW50IHRoZSBydW5uaW5nIHRvdGFsIGdldHMgdG8sIG9uIGVpdGhlciBzaWRlIG9mXG4gIC8vIHplcm8sIG9yIHRoZSBmdXJ0aGVzdCByZWZlcmVuY2UuXG4gIGNvbnN0IHNwZWMgPSBjb25maWcubWVhc3VyZXM/LlswXTtcbiAgY29uc3QgcmVmZXJlbmNlcyA9IGNoYXJ0UmVmZXJlbmNlcyhjb25maWcsIGZhbHNlKTtcbiAgY29uc3QgdmFsdWVBeGlzID0gdmFsdWVBeGlzT3B0aW9uKGNvbmZpZy52YWx1ZUF4aXMsIGhvcml6b250YWwsIHZhbHVlQXhpc0xhYmVsKHJlc29sdmVWYWx1ZUF4aXNGb3JtYXQoXG4gICAgc3BlYyAmJiBoYXNOdW1iZXJGb3JtYXQoc3BlYykgPyBzcGVjIDogbnVsbCxcbiAgICAoKSA9PiBNYXRoLm1heChyZWZlcmVuY2VQZWFrKHJlZmVyZW5jZXMsIDApLCAuLi53YXRlcmZhbGwuc3RlcHMubWFwKChzdGVwKSA9PiBNYXRoLmFicyhzdGVwLnN0YXJ0ICsgKHN0ZXAuY2hhbmdlID8/IDApKSkpLFxuICAgIGNvbnRleHQsXG4gICksIGNvbnRleHQpLCB7IHJlYWNoOiByZWZlcmVuY2VSZWFjaChyZWZlcmVuY2VzLCAwKSB9KTtcbiAgLy8gT25lIHZpc2libGUgc2VyaWVzLCBzbyB0aGUgbGVnZW5kIGlzIGhpZGRlbiB1bmxlc3MgdGhlIGNvbmZpZyBwaW5zIGl0LlxuICBjb25zdCBsZWdlbmRQb3NpdGlvbiA9IHJlc29sdmVMZWdlbmRQb3NpdGlvbihjb25maWcsIDEpO1xuICBjb25zdCBncmFudWxhcml0eSA9IGJ1Y2tldEdyYW51bGFyaXR5KGRhdGEpO1xuXG4gIHJldHVybiB7XG4gICAgZ3JpZDogYXhpc0dyaWQoXG4gICAgICBsZWdlbmRQb3NpdGlvbixcbiAgICAgIGNhdGVnb3J5VGl0bGVTaWRlKGNvbmZpZywgaG9yaXpvbnRhbCksXG4gICAgICB2YWx1ZVRpdGxlU2lkZShbY29uZmlnLnZhbHVlQXhpc10sIGhvcml6b250YWwpLFxuICAgICksXG4gICAgbGVnZW5kOiB7IC4uLmxlZ2VuZE9wdGlvbihsZWdlbmRQb3NpdGlvbiksIGRhdGE6IFt3YXRlcmZhbGwubmFtZV0gfSxcbiAgICAvLyBQZXIgYmFyOiB0aGUgaW52aXNpYmxlIGJhc2UgaXMgc2lsZW50LCBzbyBvbmx5IGEgc3RlcCBhbnN3ZXJzIHRoZSBob3Zlci5cbiAgICB0b29sdGlwOiB7XG4gICAgICB0cmlnZ2VyOiAnaXRlbScsXG4gICAgICBmb3JtYXR0ZXI6IChwYXJhbXM6IFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcykgPT4gd2F0ZXJmYWxsVG9vbHRpcChcbiAgICAgICAgd2F0ZXJmYWxsLFxuICAgICAgICAoQXJyYXkuaXNBcnJheShwYXJhbXMpID8gcGFyYW1zWzBdIDogcGFyYW1zKS5kYXRhSW5kZXgsXG4gICAgICAgIGdyYW51bGFyaXR5LFxuICAgICAgICBjaGFydERhdGVMYWJlbChjb25maWcpLFxuICAgICAgICBzcGVjLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKSxcbiAgICB9LFxuICAgIHhBeGlzOiBob3Jpem9udGFsID8gdmFsdWVBeGlzIDogY2F0ZWdvcnlBeGlzLFxuICAgIHlBeGlzOiBob3Jpem9udGFsID8gY2F0ZWdvcnlBeGlzIDogdmFsdWVBeGlzLFxuICAgIHNlcmllczogWy4uLndhdGVyZmFsbFNlcmllcyh3YXRlcmZhbGwpLCAuLi5yZWZlcmVuY2VDYXJyaWVycyhyZWZlcmVuY2VzLCBjYXRlZ29yaWVzKV0sXG4gIH07XG59XG5cbi8vIEFuIGludmlzaWJsZSBiYXNlIHNlcmllcyBsaWZ0cyBlYWNoIHZpc2libGUgYmFyIHRvIHdoZXJlIGl0cyBzdGVwIHN0YXJ0cy5cbi8vIEJvdGggc3RhY2sgd2l0aCB0aGUgJ2FsbCcgc3RyYXRlZ3ksIHdoaWNoIGFkZHMgc2lnbmVkIHZhbHVlcyBpbiBzZXJpZXMgb3JkZXIsXG4vLyBzbyBhIGZhbGwgZHJhd3MgRE9XTiBmcm9tIHRoZSB0b3RhbCBiZWZvcmUgaXQsIGV2ZW4gYWNyb3NzIHplcm8uIFRoZSBkZWZhdWx0XG4vLyBzYW1lLXNpZ24gc3RhY2tpbmcgd291bGQgaGFuZyBhIG5lZ2F0aXZlIGJhciBiZWxvdyB0aGUgYXhpcyBpbnN0ZWFkLlxuZnVuY3Rpb24gd2F0ZXJmYWxsU2VyaWVzKHdhdGVyZmFsbDogRXh0cmFjdGVkV2F0ZXJmYWxsKTogU2VyaWVzT3B0aW9uW10ge1xuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHR5cGU6ICdiYXInLFxuICAgICAgc3RhY2s6ICd3YXRlcmZhbGwnLFxuICAgICAgc3RhY2tTdHJhdGVneTogJ2FsbCcsXG4gICAgICBkYXRhOiB3YXRlcmZhbGwuc3RlcHMubWFwKChzdGVwKSA9PiBzdGVwLnN0YXJ0KSxcbiAgICAgIGJhck1heFdpZHRoOiA0OCxcbiAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogJ3RyYW5zcGFyZW50JyB9LFxuICAgICAgc2lsZW50OiB0cnVlLFxuICAgIH0sXG4gICAge1xuICAgICAgbmFtZTogd2F0ZXJmYWxsLm5hbWUsXG4gICAgICB0eXBlOiAnYmFyJyxcbiAgICAgIHN0YWNrOiAnd2F0ZXJmYWxsJyxcbiAgICAgIHN0YWNrU3RyYXRlZ3k6ICdhbGwnLFxuICAgICAgYmFyTWF4V2lkdGg6IDQ4LFxuICAgICAgLy8gVGhlIHNlcmllcyBjb2xvciBpcyB0aGUgcmlzZSBjb2xvciBzbyBhIHBpbm5lZCBsZWdlbmQgc2hvd3MgaXQ7IGVhY2hcbiAgICAgIC8vIGJhciBpcyB0aGVuIGNvbG9yZWQgYnkgd2hhdCBpdCBkb2VzIHRvIHRoZSB0b3RhbC5cbiAgICAgIGl0ZW1TdHlsZTogeyBjb2xvcjogYCMke1JFUE9SVF9XQVRFUkZBTExfQ09MT1JTLnJpc2V9YCB9LFxuICAgICAgZGF0YTogd2F0ZXJmYWxsLnN0ZXBzLm1hcCgoc3RlcCkgPT4gKHtcbiAgICAgICAgdmFsdWU6IHN0ZXAuY2hhbmdlLFxuICAgICAgICBpdGVtU3R5bGU6IHsgY29sb3I6IGAjJHtSRVBPUlRfV0FURVJGQUxMX0NPTE9SU1tzdGVwLmtpbmRdfWAgfSxcbiAgICAgIH0pKSxcbiAgICB9LFxuICBdO1xufVxuXG4vLyBBIHN0ZXAncyB0b29sdGlwOiBpdHMgcGVyaW9kLCBob3cgZmFyIGl0IG1vdmVkIHRoZSBydW5uaW5nIHRvdGFsIGFuZCB3aGVyZVxuLy8gdGhhdCBsZWZ0IGl0LiBUaGUgY2xvc2luZyBUb3RhbCBzaG93cyB0aGUgdG90YWwgYWxvbmUuIFRoZSBjYXRlZ29yeSBhbmQgdGhlXG4vLyBtZWFzdXJlIG5hbWUgY29tZSBmcm9tIHRoZSBkYXRhIGFuZCB0aGUgY29uZmlnLCBhbmQgRUNoYXJ0cyBzZXRzIHRoZSB0b29sdGlwXG4vLyBhcyBIVE1MLCBzbyBib3RoIGFyZSBlc2NhcGVkLiBQZXJpb2RzIGFuZCBhbW91bnRzIGFyZSB3cml0dGVuIGluIHRoZSByZXBvcnQnc1xuLy8gbG9jYWxlLCBhbW91bnRzIGluIHRoZSBtZWFzdXJlJ3MgbnVtYmVyIGZvcm1hdCAoYSBwbGFpbiBudW1iZXIgd2l0aG91dCBvbmUpO1xuLy8gdGhlIHdvcmRzICgnUnVubmluZyB0b3RhbCcpIHN0YXkgRW5nbGlzaC5cbmZ1bmN0aW9uIHdhdGVyZmFsbFRvb2x0aXAoXG4gIHdhdGVyZmFsbDogRXh0cmFjdGVkV2F0ZXJmYWxsLFxuICBpbmRleDogbnVtYmVyLFxuICBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwsXG4gIGRhdGVMYWJlbDogUmVwb3J0Q2hhcnREYXRlTGFiZWwsXG4gIHNwZWM6IE51bWJlckZvcm1hdFNwZWMgfCB1bmRlZmluZWQsXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBzdHJpbmcge1xuICBjb25zdCBzdGVwID0gd2F0ZXJmYWxsLnN0ZXBzW2luZGV4XTtcbiAgY29uc3QgY2F0ZWdvcnkgPSBlc2NhcGVIdG1sKGdyYW51bGFyaXR5XG4gICAgPyBmb3JtYXRQZXJpb2RMYWJlbChzdGVwLmNhdGVnb3J5LCBncmFudWxhcml0eSwgdHJ1ZSwgY29udGV4dC5sb2NhbGUsIGRhdGVMYWJlbClcbiAgICA6IHN0ZXAuY2F0ZWdvcnkpO1xuICBjb25zdCBuYW1lID0gZXNjYXBlSHRtbCh3YXRlcmZhbGwubmFtZSk7XG4gIGNvbnN0IGFtb3VudCA9ICh2YWx1ZTogbnVtYmVyIHwgbnVsbCkgPT4gZm9ybWF0TnVtYmVyKHZhbHVlLCBzcGVjID8/IHt9LCBjb250ZXh0KTtcblxuICBpZiAoc3RlcC5raW5kID09PSAndG90YWwnKSB7XG4gICAgcmV0dXJuIGAke2NhdGVnb3J5fTxici8+JHtuYW1lfTogJHthbW91bnQoc3RlcC5jaGFuZ2UpfWA7XG4gIH1cblxuICBjb25zdCBzaWduID0gKHN0ZXAuY2hhbmdlID8/IDApID4gMCA/ICcrJyA6ICcnO1xuXG4gIHJldHVybiBgJHtjYXRlZ29yeX08YnIvPiR7bmFtZX06ICR7c2lnbn0ke2Ftb3VudChzdGVwLmNoYW5nZSl9YFxuICAgICsgYDxici8+UnVubmluZyB0b3RhbDogJHthbW91bnQoc3RlcC5zdGFydCArIChzdGVwLmNoYW5nZSA/PyAwKSl9YDtcbn1cblxuLy8gRGVmYXVsdCBsZWdlbmQgcGxhY2VtZW50IHdoZW4gdGhlIGNvbmZpZyBkb2Vzbid0IHBpbiBvbmU6IHBpZSBjaGFydHMgcmVhZFxuLy8gYmVzdCB3aXRoIHRoZSBzbGljZSBrZXkgYmVzaWRlIHRoZW0gKHJpZ2h0KTsgYXhpcyBjaGFydHMgb25seSBuZWVkIGEgbGVnZW5kXG4vLyB0byB0ZWxsIG11bHRpcGxlIHNlcmllcyBhcGFydCwgc28gYSBzaW5nbGUtc2VyaWVzIGNoYXJ0IGhpZGVzIGl0LiBBbiBleHBsaWNpdFxuLy8gY29uZmlnLmxlZ2VuZCAoaW5jbHVkaW5nICdoaWRkZW4nKSBhbHdheXMgd2lucy4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnRcbi8vIGV4cG9ydCBzbyBib3RoIG1lZGlhIHBsYWNlIHRoZSBsZWdlbmQgaWRlbnRpY2FsbHkuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUxlZ2VuZFBvc2l0aW9uKGNvbmZpZzogQ2hhcnRDb25maWcsIHNlcmllc0NvdW50OiBudW1iZXIsIGNvbG9yQnkgPSBmYWxzZSk6IExlZ2VuZFBvc2l0aW9uIHtcbiAgaWYgKGNvbmZpZy5sZWdlbmQpIHtcbiAgICByZXR1cm4gY29uZmlnLmxlZ2VuZDtcbiAgfVxuXG4gIGNvbnN0IHBpZSA9IGNvbmZpZy5jaGFydFR5cGUgPT09ICdwaWUnIHx8IGNvbmZpZy5jaGFydFR5cGUgPT09ICdkb251dCc7XG5cbiAgLy8gY29sb3JCeSBtYXBzIGVhY2ggYmFyJ3MgY29sb3IgdG8gaXRzIGNhdGVnb3J5LCBzbyBpdCBuZWVkcyBhIGxlZ2VuZCBldmVuXG4gIC8vIHRob3VnaCBpdCdzIGEgc2luZ2xlIG1lYXN1cmUuXG4gIHJldHVybiBwaWUgfHwgY29sb3JCeSB8fCBzZXJpZXNDb3VudCA+IDEgPyAocGllID8gJ3JpZ2h0JyA6ICd0b3AnKSA6ICdoaWRkZW4nO1xufVxuXG5mdW5jdGlvbiBsZWdlbmRPcHRpb24ocG9zaXRpb246IExlZ2VuZFBvc2l0aW9uKTogTGVnZW5kQ29tcG9uZW50T3B0aW9uIHtcbiAgaWYgKHBvc2l0aW9uID09PSAnaGlkZGVuJykge1xuICAgIHJldHVybiB7IHNob3c6IGZhbHNlIH07XG4gIH1cblxuICBjb25zdCBiYXNlOiBMZWdlbmRDb21wb25lbnRPcHRpb24gPSB7IHR5cGU6ICdzY3JvbGwnIH07XG5cbiAgc3dpdGNoIChwb3NpdGlvbikge1xuICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBib3R0b206IDAgfTtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIG9yaWVudDogJ3ZlcnRpY2FsJywgbGVmdDogMCwgdG9wOiAnbWlkZGxlJyB9O1xuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIG9yaWVudDogJ3ZlcnRpY2FsJywgcmlnaHQ6IDAsIHRvcDogJ21pZGRsZScgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgdG9wOiAwIH07XG4gIH1cbn1cblxuLy8gVGhlIHBsb3QncyBncmlkOiByb29tIG9uIHRoZSBsZWdlbmQncyBzaWRlIHNvIGl0IG5ldmVyIG92ZXJsYXBzIHRoZVxuLy8gYmFycy9saW5lcywgcGx1cyByb29tIGZvciB0aGUgY2F0ZWdvcnkgYW5kIHZhbHVlIGF4ZXMnIHRpdGxlcyBvbiB0aGVpclxuLy8gc2lkZXMsIHdoaWNoIGNvbnRhaW5MYWJlbCBkb2VzIG5vdCByZXNlcnZlIChpdCBjb3ZlcnMgdGhlIHRpY2sgbGFiZWxzIG9ubHkpLlxuZnVuY3Rpb24gYXhpc0dyaWQoXG4gIHBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbixcbiAgY2F0ZWdvcnlUaXRsZTogQXhpc1RpdGxlU2lkZSB8IG51bGwsXG4gIHZhbHVlVGl0bGU6IEF4aXNUaXRsZVNpZGUgfCBudWxsLFxuKTogRUNoYXJ0c09wdGlvblsnZ3JpZCddIHtcbiAgcmV0dXJuIFtjYXRlZ29yeVRpdGxlLCB2YWx1ZVRpdGxlXS5yZWR1Y2U8QXhpc0dyaWRSb29tPihcbiAgICAoZ3JpZCwgc2lkZSkgPT4gKHNpZGUgPyB7IC4uLmdyaWQsIFtzaWRlXTogZ3JpZFtzaWRlXSArIEFYSVNfTkFNRV9ST09NIH0gOiBncmlkKSxcbiAgICBsZWdlbmRHcmlkKHBvc2l0aW9uKSxcbiAgKTtcbn1cblxuLy8gUGxvdC1lZGdlIHJvb20gb24gd2hpY2hldmVyIHNpZGUgdGhlIGxlZ2VuZCBvY2N1cGllczsgY29udGFpbkxhYmVsIGtlZXBzIHRoZVxuLy8gdGljayBsYWJlbHMgaW5zaWRlIHdoYXQgaXMgbGVmdC5cbmZ1bmN0aW9uIGxlZ2VuZEdyaWQocG9zaXRpb246IExlZ2VuZFBvc2l0aW9uKTogQXhpc0dyaWRSb29tIHtcbiAgY29uc3QgYmFzZTogQXhpc0dyaWRSb29tID0geyBsZWZ0OiA4LCByaWdodDogMTYsIHRvcDogOCwgYm90dG9tOiA4LCBjb250YWluTGFiZWw6IHRydWUgfTtcblxuICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgY2FzZSAnYm90dG9tJzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIGJvdHRvbTogMzIgfTtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIGxlZnQ6IDk2IH07XG4gICAgY2FzZSAncmlnaHQnOlxuICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgcmlnaHQ6IDk2IH07XG4gICAgY2FzZSAnaGlkZGVuJzpcbiAgICAgIHJldHVybiBiYXNlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCB0b3A6IDMyIH07XG4gIH1cbn1cblxuLy8gVGhlIHN0YWNrIGEgc3RhY2tlZCBzZXJpZXMgam9pbnMuIE9uIGEgdHdvLWF4aXMgY2hhcnQgKGF4aXNJbmRleCBzZXQpIGVhY2hcbi8vIHR5cGUgc3RhY2tzIHBlciBheGlzOyBvdGhlcndpc2UgYSBjb21ibyBzdGFja3MgcGVyIHR5cGUgYW5kIGEgc2luZ2xlLXR5cGVcbi8vIGNoYXJ0IHN0YWNrcyBldmVyeXRoaW5nIHRvZ2V0aGVyLlxuZnVuY3Rpb24gc3RhY2tLZXkodHlwZTogQXhpc0NoYXJ0VHlwZSwgY29tYm86IGJvb2xlYW4sIGF4aXNJbmRleDogVmFsdWVBeGlzSW5kZXggfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBpZiAoYXhpc0luZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYHRvdGFsLSR7dHlwZX0tJHtheGlzSW5kZXh9YDtcbiAgfVxuXG4gIHJldHVybiBjb21ibyA/IGB0b3RhbC0ke3R5cGV9YCA6ICd0b3RhbCc7XG59XG5cbi8vIEhvdyBidWlsZFNlcmllcyBkcmF3cyBvbmUgc2VyaWVzOiBpdHMgZHJhd24gdHlwZSwgdGhlIHN0YWNrIGl0IGpvaW5zLCB3aGV0aGVyXG4vLyBpdCBsYXlzIHRoZSBjb2xvckJ5IG92ZXJsYXAsIHdoZXRoZXIgdGhlIGNoYXJ0IGlzIGEgY29tYm8sIGl0cyB0b29sdGlwLCBpdHNcbi8vIHZhbHVlIGF4aXMgb24gYSB0d28tYXhpcyBjaGFydCwgaXRzIG93biBDU1MgY29sb3IgKHVuZGVmaW5lZCBsZWF2ZXMgaXQgdG9cbi8vIHRoZSB0aGVtZSdzIHBhbGV0dGUgYnkgcG9zaXRpb24pLCBhbmQgaXRzIGRhdGEgbGFiZWxzIChudWxsIHByaW50cyBub25lKS5cbmludGVyZmFjZSBTZXJpZXNMYXlvdXQge1xuICB0eXBlOiBBeGlzQ2hhcnRUeXBlO1xuICBzdGFjazogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBvdmVybGFwOiBib29sZWFuO1xuICBjb21ibzogYm9vbGVhbjtcbiAgdG9vbHRpcDogU2VyaWVzVG9vbHRpcDtcbiAgYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleCB8IHVuZGVmaW5lZDtcbiAgY29sb3I6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgbGFiZWxzOiBTZXJpZXNEYXRhTGFiZWxzIHwgbnVsbDtcbn1cblxuLy8gT25lIHNlcmllcyBvZiBhbiBheGlzIGNoYXJ0LiBBIG1lYXN1cmUncyBkaXNwbGF5IGtleXMgb25seSBhZGQgd2hhdCB0aGV5XG4vLyBjaGFuZ2UsIHNvIGEgc2VyaWVzIHRoYXQgc2V0cyBub25lIGlzIGRyYXduIGJ5IHRoZSB0aGVtZSBhcyBiZWZvcmU6IGl0cyBvd25cbi8vIGNvbG9yICh0aGUgYmFyLCB0aGUgbGluZSwgdGhlIGFyZWEgdW5kZXIgaXQgYW5kIGl0cyBsZWdlbmQga2V5IGFsbCBmb2xsb3dcbi8vIGl0ZW1TdHlsZSksIGl0cyBsaW5lIHN0eWxlIGFuZCBpdHMgbWFya2Vycywgc2hvd24gb24gZXZlcnkgcG9pbnQgdW5sZXNzXG4vLyBtYXJrZXJzIGlzIGZhbHNlLiBEYXRhIGxhYmVscyBjb21lIGxhc3QsIG9uIHRoZSBzZXJpZXMgb3Igb24gaXRzIGxhdGVzdFxuLy8gcG9pbnQuXG5mdW5jdGlvbiBidWlsZFNlcmllcyhcbiAgc2VyaWVzOiBFeHRyYWN0ZWRDaGFydFNlcmllc0l0ZW0sXG4gIHZhbHVlczogKG51bWJlciB8IG51bGwgfCBTaGFyZURhdGFJdGVtKVtdLFxuICBsYXlvdXQ6IFNlcmllc0xheW91dCxcbik6IFNlcmllc09wdGlvbiB7XG4gIC8vIE9uIGEgdHdvLWF4aXMgY2hhcnQgZXZlcnkgc2VyaWVzIG5hbWVzIGl0cyB2YWx1ZSBheGlzLlxuICBjb25zdCBheGlzID0gbGF5b3V0LmF4aXNJbmRleCA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHlBeGlzSW5kZXg6IGxheW91dC5heGlzSW5kZXggfTtcbiAgY29uc3QgY29sb3IgPSBsYXlvdXQuY29sb3I7XG4gIGNvbnN0IGl0ZW1TdHlsZSA9IGNvbG9yID8geyBpdGVtU3R5bGU6IHsgY29sb3IgfSB9IDoge307XG5cbiAgaWYgKGxheW91dC50eXBlID09PSAnYmFyJykge1xuICAgIC8vICdvdXRzaWRlJyBmb2xsb3dzIGVhY2ggYmFyJ3Mgc2lnbjogcGFzdCBhIHBvc2l0aXZlIGJhcidzIGVuZCBhbmQgYmVsb3dcbiAgICAvLyAob3IgbGVmdCBvZikgYSBuZWdhdGl2ZSBvbmUncywgd2hlcmUgJ3RvcCcgd291bGQgc2l0IGF0IHRoZSB6ZXJvIGxpbmUuXG4gICAgY29uc3QgeyBzZXJpZXM6IGxhYmVscywgZGF0YSB9ID0gcGxhY2VEYXRhTGFiZWxzKGxheW91dC5sYWJlbHMsIGxheW91dC5zdGFjayA/ICdpbnNpZGUnIDogJ291dHNpZGUnLCB2YWx1ZXMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHNlcmllcy5uYW1lLFxuICAgICAgdHlwZTogJ2JhcicsXG4gICAgICBkYXRhLFxuICAgICAgc3RhY2s6IGxheW91dC5zdGFjayxcbiAgICAgIHRvb2x0aXA6IGxheW91dC50b29sdGlwLFxuICAgICAgLi4uYXhpcyxcbiAgICAgIC4uLml0ZW1TdHlsZSxcbiAgICAgIGJhck1heFdpZHRoOiA0OCxcbiAgICAgIC8vIGNvbG9yQnk6IG92ZXJsYXAgdGhlIHBlci1jYXRlZ29yeSBzZXJpZXMgc28gZWFjaCBiYXIgcmVuZGVycyBmdWxsLXdpZHRoLlxuICAgICAgLi4uKGxheW91dC5vdmVybGFwID8geyBiYXJHYXA6ICctMTAwJScsIGJhckNhdGVnb3J5R2FwOiAnMjAlJyB9IDoge30pLFxuICAgICAgLi4ubGFiZWxzLFxuICAgIH07XG4gIH1cblxuICBjb25zdCBsaW5lVHlwZSA9IG1lYXN1cmVMaW5lU3R5bGUoc2VyaWVzLm1lYXN1cmUpO1xuICBjb25zdCBsaW5lU3R5bGUgPSBjb2xvciB8fCBsaW5lVHlwZVxuICAgID8geyBsaW5lU3R5bGU6IHsgLi4uKGNvbG9yID8geyBjb2xvciB9IDoge30pLCAuLi4obGluZVR5cGUgPyB7IHR5cGU6IGxpbmVUeXBlIH0gOiB7fSkgfSB9XG4gICAgOiB7fTtcbiAgY29uc3QgeyBzZXJpZXM6IGxhYmVscywgZGF0YSB9ID0gcGxhY2VEYXRhTGFiZWxzKGxheW91dC5sYWJlbHMsICd0b3AnLCB2YWx1ZXMpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogc2VyaWVzLm5hbWUsXG4gICAgdHlwZTogJ2xpbmUnLFxuICAgIGRhdGEsXG4gICAgc3RhY2s6IGxheW91dC5zdGFjayxcbiAgICB0b29sdGlwOiBsYXlvdXQudG9vbHRpcCxcbiAgICAuLi5heGlzLFxuICAgIC4uLml0ZW1TdHlsZSxcbiAgICAuLi5saW5lU3R5bGUsXG4gICAgLi4uKHNlcmllcy5tZWFzdXJlLm1hcmtlcnMgPT09IGZhbHNlID8geyBzaG93U3ltYm9sOiBmYWxzZSB9IDoge30pLFxuICAgIHNtb290aDogdHJ1ZSxcbiAgICBzeW1ib2xTaXplOiA2LFxuICAgIGFyZWFTdHlsZTogbGF5b3V0LnR5cGUgPT09ICdhcmVhJyA/IHsgb3BhY2l0eTogMC4yNSB9IDogdW5kZWZpbmVkLFxuICAgIC8vIEluIGEgY29tYm8gdGhlIGxpbmUgaXMgZHJhd24gb3ZlciB0aGUgYmFycyB3aGF0ZXZlciBvcmRlciB0aGUgbWVhc3VyZXNcbiAgICAvLyBjb21lIGluOyBhdCB0aGUgc2FtZSB6IGEgbGF0ZXIgYmFyIHNlcmllcyB3b3VsZCBwYWludCBhY3Jvc3MgaXQuXG4gICAgLi4uKGxheW91dC5jb21ibyA/IHsgejogMyB9IDoge30pLFxuICAgIC4uLmxhYmVscyxcbiAgfTtcbn1cblxuLy8gQSAxMDAlIHN0YWNrZWQgc2VyaWVzJyBwb2ludHM6IGVhY2ggc2hhcmUsIHBsb3R0ZWQgYW5kIHN0YWNrZWQsIHdpdGggdGhlXG4vLyB2YWx1ZSBpdCBjYW1lIGZyb20uXG5mdW5jdGlvbiBzaGFyZURhdGEodmFsdWVzOiAobnVtYmVyIHwgbnVsbClbXSwgc2hhcmVzOiAobnVtYmVyIHwgbnVsbClbXSk6IFNoYXJlRGF0YUl0ZW1bXSB7XG4gIHJldHVybiB2YWx1ZXMubWFwKChyYXcsIGluZGV4KSA9PiAoeyB2YWx1ZTogc2hhcmVzW2luZGV4XSA/PyBudWxsLCByYXcgfSkpO1xufVxuXG4vLyBXaGF0IGEgc2VyaWVzIHByaW50cyBiZXNpZGUgaXRzIHBvaW50cyAoQTIgZGF0YSBsYWJlbHMpOiBldmVyeSBwb2ludFxuLy8gKCdhbGwnKSwgZXZlcnkgcG9pbnQgd2hvc2UgbGFiZWwgZml0cyB3aXRob3V0IG92ZXJsYXBwaW5nIGFub3RoZXIgKCdhdXRvJyxcbi8vIExhYmVsTGF5b3V0J3MgaGlkZU92ZXJsYXApLCBvciBvbmx5IGl0cyBsYXRlc3QgcG9pbnQgKCdsYXN0JykuIG5vbmUsIGFuXG4vLyBhYnNlbnQgbW9kZSBvciBvbmUgdGhlIHZpZXdlciBkb2VzIG5vdCBrbm93IHByaW50cyBub3RoaW5nLCBhbmQgdGhlIHNlcmllc1xuLy8gaXMgbGVmdCBhcyBpdCB3YXMuIEEgY29sb3JCeSBjaGFydCdzIHNlcmllcyBlYWNoIGhvbGQgb25lIGJhciwgc28gJ2xhc3QnXG4vLyBsYWJlbHMgZXZlcnkgYmFyIHRoZXJlLCBhcyAnYWxsJyBkb2VzLlxuLy9cbi8vIFdoZXJlIHRoZSBsYWJlbCBzaXRzIGRlcGVuZHMgb24gd2hhdCB0aGUgc2VyaWVzIGRyYXdzLCBzbyBidWlsZFNlcmllc1xuLy8gcGxhY2VzIGl0IChwbGFjZURhdGFMYWJlbHMpLlxuZXhwb3J0IGZ1bmN0aW9uIGRhdGFMYWJlbE9wdGlvbihcbiAgbW9kZTogUmVwb3J0Q2hhcnREYXRhTGFiZWxzIHwgdW5kZWZpbmVkLFxuICBmb3JtYXR0ZXI6IERhdGFMYWJlbEZvcm1hdHRlcixcbik6IFNlcmllc0RhdGFMYWJlbHMgfCBudWxsIHtcbiAgY29uc3QgdGV4dCA9IHsgc2hvdzogdHJ1ZSBhcyBjb25zdCwgZm9udFNpemU6IFJFUE9SVF9EQVRBX0xBQkVMX0ZPTlRfU0laRSwgZm9ybWF0dGVyIH07XG5cbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBSZXBvcnRDaGFydERhdGFMYWJlbHMuQWxsOlxuICAgICAgcmV0dXJuIHsgdGV4dCwgaGlkZU92ZXJsYXA6IGZhbHNlLCBsYXN0T25seTogZmFsc2UgfTtcbiAgICBjYXNlIFJlcG9ydENoYXJ0RGF0YUxhYmVscy5BdXRvOlxuICAgICAgcmV0dXJuIHsgdGV4dCwgaGlkZU92ZXJsYXA6IHRydWUsIGxhc3RPbmx5OiBmYWxzZSB9O1xuICAgIGNhc2UgUmVwb3J0Q2hhcnREYXRhTGFiZWxzLkxhc3Q6XG4gICAgICByZXR1cm4geyB0ZXh0LCBoaWRlT3ZlcmxhcDogZmFsc2UsIGxhc3RPbmx5OiB0cnVlIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8vIEEgc2VyaWVzJyBkYXRhIGxhYmVscyBhdCBgcG9zaXRpb25gOiBvbiB0aGUgc2VyaWVzICgnYWxsJywgYW5kIHdpdGggdGhlXG4vLyBvdmVybGFwIGhpZGluZyAnYXV0bycpLCBvciBvbiBpdHMgbGF0ZXN0IG5vbi1lbXB0eSBwb2ludCBhbG9uZSAoJ2xhc3QnKS5cbi8vIE5vIGxhYmVscyBsZWF2ZSB0aGUgc2VyaWVzIGFuZCBpdHMgcG9pbnRzIGFzIHRoZXkgd2VyZS5cbmZ1bmN0aW9uIHBsYWNlRGF0YUxhYmVsczxQIGV4dGVuZHMgRGF0YUxhYmVsUG9zaXRpb24+KFxuICBsYWJlbHM6IFNlcmllc0RhdGFMYWJlbHMgfCBudWxsLFxuICBwb3NpdGlvbjogUCxcbiAgdmFsdWVzOiAobnVtYmVyIHwgbnVsbCB8IFNoYXJlRGF0YUl0ZW0pW10sXG4pOiBQbGFjZWREYXRhTGFiZWxzPFA+IHtcbiAgaWYgKCFsYWJlbHMpIHtcbiAgICByZXR1cm4geyBzZXJpZXM6IHt9LCBkYXRhOiB2YWx1ZXMgfTtcbiAgfVxuXG4gIGNvbnN0IGxhYmVsOiBEYXRhTGFiZWw8UD4gPSB7IC4uLmxhYmVscy50ZXh0LCBwb3NpdGlvbiB9O1xuXG4gIGlmIChsYWJlbHMubGFzdE9ubHkpIHtcbiAgICByZXR1cm4geyBzZXJpZXM6IHt9LCBkYXRhOiBsYWJlbExhc3RQb2ludCh2YWx1ZXMsIGxhYmVsKSB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzZXJpZXM6IHsgbGFiZWwsIC4uLihsYWJlbHMuaGlkZU92ZXJsYXAgPyB7IGxhYmVsTGF5b3V0OiB7IGhpZGVPdmVybGFwOiB0cnVlIH0gfSA6IHt9KSB9LFxuICAgIGRhdGE6IHZhbHVlcyxcbiAgfTtcbn1cblxuLy8gQSBzZXJpZXMnIHBvaW50cyB3aXRoIGl0cyBsYXRlc3Qgbm9uLWVtcHR5IHBvaW50IGNhcnJ5aW5nIHRoZSBsYWJlbC4gQVxuLy8gc2VyaWVzIHdpdGggbm8gdmFsdWUgYW55d2hlcmUgaXMgbGVmdCBhcyBpdCB3YXMuXG5mdW5jdGlvbiBsYWJlbExhc3RQb2ludDxQIGV4dGVuZHMgRGF0YUxhYmVsUG9zaXRpb24+KFxuICB2YWx1ZXM6IChudW1iZXIgfCBudWxsIHwgU2hhcmVEYXRhSXRlbSlbXSxcbiAgbGFiZWw6IERhdGFMYWJlbDxQPixcbik6IFNlcmllc0RhdGFJdGVtPFA+W10ge1xuICBjb25zdCBwb2ludFZhbHVlID0gKGl0ZW06IG51bWJlciB8IG51bGwgfCBTaGFyZURhdGFJdGVtKSA9PiAoaXNTaGFyZURhdGFJdGVtKGl0ZW0pID8gaXRlbS52YWx1ZSA6IGl0ZW0pO1xuICBjb25zdCBsYXN0ID0gdmFsdWVzLnJlZHVjZTxudW1iZXI+KChmb3VuZCwgaXRlbSwgaW5kZXgpID0+IChwb2ludFZhbHVlKGl0ZW0pID09PSBudWxsID8gZm91bmQgOiBpbmRleCksIC0xKTtcblxuICByZXR1cm4gdmFsdWVzLm1hcCgoaXRlbSwgaW5kZXgpOiBTZXJpZXNEYXRhSXRlbTxQPiA9PiB7XG4gICAgaWYgKGluZGV4ICE9PSBsYXN0KSB7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXNTaGFyZURhdGFJdGVtKGl0ZW0pID8geyAuLi5pdGVtLCBsYWJlbCB9IDogeyB2YWx1ZTogaXRlbSwgbGFiZWwgfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzU2hhcmVEYXRhSXRlbShpdGVtOiBudW1iZXIgfCBudWxsIHwgU2hhcmVEYXRhSXRlbSk6IGl0ZW0gaXMgU2hhcmVEYXRhSXRlbSB7XG4gIHJldHVybiBpdGVtICE9PSBudWxsICYmIHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jztcbn1cblxuLy8gSG93IGEgc2VyaWVzJyBkYXRhIGxhYmVscyB3cml0ZSBhIHZhbHVlLiBBIDEwMCUgc3RhY2tlZCBzZXJpZXMgcHJpbnRzIGl0c1xuLy8gc2hhcmUgYXMgYSB3aG9sZSBwZXJjZW50YWdlLCBhcyB0aGUgc2hhcmUgYXhpcydzIHRpY2tzIGRvLiBBIHNlcmllcyBvbiBhblxuLy8gYXhpcyB3aXRoIGEgbnVtYmVyIGZvcm1hdCBwcmludHMgaXRzIHZhbHVlIGluIGl0cyBtZWFzdXJlJ3MgZm9ybWF0LCBhdCB0aGVcbi8vIHVuaXRzIGFuZCBkZWNpbWFscyB0aGUgYXhpcyBkZWNpZGVkLCBzbyBhIGxhYmVsIHJlYWRzIGxpa2UgdGhlIHRpY2tzIGJlc2lkZVxuLy8gaXQuIEFueSBvdGhlciBwcmludHMgdGhlIHBsYWluIGxvY2FsZS1ncm91cGVkIG51bWJlciBpdHMgdG9vbHRpcCBzaG93cy4gQVxuLy8gc2hhcmUgcG9pbnQncyByYXcgdmFsdWUgaXMgd2hhdCBhIGxhYmVsIHJlYWRzIHdoZW4gaXQgY2FycmllcyBvbmUuXG5mdW5jdGlvbiBkYXRhTGFiZWxGb3JtYXR0ZXIoXG4gIG1lYXN1cmU6IENoYXJ0TWVhc3VyZSxcbiAgYXhpc0Zvcm1hdDogVmFsdWVBeGlzRm9ybWF0IHwgbnVsbCxcbiAgc2hhcmU6IGJvb2xlYW4sXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBEYXRhTGFiZWxGb3JtYXR0ZXIge1xuICBpZiAoc2hhcmUpIHtcbiAgICBjb25zdCBwZXJjZW50ID0gd2hvbGVQZXJjZW50Rm9ybWF0dGVyKGNvbnRleHQpO1xuXG4gICAgcmV0dXJuIChwYXJhbXMpID0+IHBlcmNlbnQocGFyYW1zLnZhbHVlKTtcbiAgfVxuXG4gIGlmIChheGlzRm9ybWF0KSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgdW5pdHM6IGF4aXNGb3JtYXQuY2hhcnQudW5pdHMsIGRlY2ltYWxzOiBheGlzRm9ybWF0LmNoYXJ0LmRlY2ltYWxzIH07XG5cbiAgICByZXR1cm4gKHBhcmFtcykgPT4gZm9ybWF0TnVtYmVyKGRhdGFMYWJlbFZhbHVlKHBhcmFtcyksIG1lYXN1cmUsIGNvbnRleHQsIG9wdGlvbnMpO1xuICB9XG5cbiAgcmV0dXJuIChwYXJhbXMpID0+IGZvcm1hdFBsYWluTnVtYmVyKGRhdGFMYWJlbFZhbHVlKHBhcmFtcyksIGNvbnRleHQubG9jYWxlKTtcbn1cblxuLy8gVGhlIHZhbHVlIGEgZGF0YSBsYWJlbCB3cml0ZXM6IHRoZSByYXcgdmFsdWUgaXRzIHBvaW50IGNhcnJpZXMsIGVsc2UgdGhlXG4vLyBwbG90dGVkIG9uZS5cbmZ1bmN0aW9uIGRhdGFMYWJlbFZhbHVlKHBhcmFtczogRGF0YUxhYmVsUGFyYW1zKTogdW5rbm93biB7XG4gIGNvbnN0IGRhdGEgPSBwYXJhbXMuZGF0YTtcbiAgY29uc3QgcmF3ID0gZGF0YSAhPT0gbnVsbCAmJiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgPyAoZGF0YSBhcyB7IHJhdz86IHVua25vd24gfSkucmF3IDogdW5kZWZpbmVkO1xuXG4gIHJldHVybiByYXcgPz8gcGFyYW1zLnZhbHVlO1xufVxuXG4vLyBBIDEwMCUgc3RhY2tlZCBjaGFydCdzIHRvb2x0aXA6IHRoZSBjYXRlZ29yeSwgdGhlbiBlYWNoIHNlcmllcyBvbiBpdHMgb3duXG4vLyBsaW5lLCBhIHNoYXJlIGFzIGl0cyBwZXJjZW50YWdlIHRvIG9uZSBkZWNpbWFsIGZvbGxvd2VkIGJ5IHRoZSB2YWx1ZSBpdCBjYW1lXG4vLyBmcm9tIGluIGl0cyBtZWFzdXJlJ3MgZm9ybWF0ICgnMjUuMCUgKDEpJyksIGFuZCBhbnkgb3RoZXIgc2VyaWVzIGJ5IGl0cyBvd25cbi8vIHZhbHVlLiBUaGUgY2F0ZWdvcnkgYW5kIHRoZSBzZXJpZXMgbmFtZXMgY29tZSBmcm9tIHRoZSBkYXRhIGFuZCB0aGUgY29uZmlnLFxuLy8gYW5kIEVDaGFydHMgc2V0cyB0aGUgdG9vbHRpcCBhcyBIVE1MLCBzbyBib3RoIGFyZSBlc2NhcGVkLlxuZnVuY3Rpb24gcGVyY2VudFRvb2x0aXAoXG4gIHBhcmFtczogVG9vbHRpcENvbXBvbmVudEZvcm1hdHRlckNhbGxiYWNrUGFyYW1zLFxuICBleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLFxuICBzaGFyZXM6IFBlcmNlbnRTaGFyZXMsXG4gIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCxcbiAgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IGl0ZW1zID0gQXJyYXkuaXNBcnJheShwYXJhbXMpID8gcGFyYW1zIDogW3BhcmFtc107XG4gIGNvbnN0IGRhdGFJbmRleCA9IGl0ZW1zWzBdPy5kYXRhSW5kZXggPz8gMDtcbiAgY29uc3QgY2F0ZWdvcnkgPSBleHRyYWN0ZWQuY2F0ZWdvcmllc1tkYXRhSW5kZXhdID8/ICcnO1xuICBjb25zdCBoZWFkaW5nID0gZXNjYXBlSHRtbChncmFudWxhcml0eVxuICAgID8gZm9ybWF0UGVyaW9kTGFiZWwoY2F0ZWdvcnksIGdyYW51bGFyaXR5LCB0cnVlLCBjb250ZXh0LmxvY2FsZSwgZGF0ZUxhYmVsKVxuICAgIDogY2F0ZWdvcnkpO1xuICBjb25zdCByYXRpb0NvbnRleHQgPSB7IC4uLmNvbnRleHQsIHJhdGlvUGVyY2VudDogdHJ1ZSB9O1xuXG4gIGNvbnN0IGxpbmVzID0gaXRlbXMubWFwKChpdGVtKSA9PiB7XG4gICAgY29uc3Qgc2VyaWVzID0gZXh0cmFjdGVkLnNlcmllc1tpdGVtLnNlcmllc0luZGV4ID8/IC0xXTtcbiAgICBjb25zdCBtYXJrZXIgPSB0eXBlb2YgaXRlbS5tYXJrZXIgPT09ICdzdHJpbmcnID8gaXRlbS5tYXJrZXIgOiAnJztcbiAgICBjb25zdCBsYWJlbCA9IGAke21hcmtlcn0gJHtlc2NhcGVIdG1sKGl0ZW0uc2VyaWVzTmFtZSA/PyBzZXJpZXM/Lm5hbWUgPz8gJycpfWA7XG4gICAgY29uc3QgdmFsdWUgPSBzZXJpZXNUb29sdGlwKHNlcmllcz8ubWVhc3VyZSwgY29udGV4dCkudmFsdWVGb3JtYXR0ZXIoc2VyaWVzPy52YWx1ZXNbaXRlbS5kYXRhSW5kZXhdID8/IG51bGwpO1xuICAgIGNvbnN0IHNoYXJlID0gc2hhcmVzLmdldChpdGVtLnNlcmllc0luZGV4ID8/IC0xKT8uW2l0ZW0uZGF0YUluZGV4XSA/PyBudWxsO1xuXG4gICAgcmV0dXJuIHNoYXJlID09PSBudWxsXG4gICAgICA/IGAke2xhYmVsfTogJHt2YWx1ZX1gXG4gICAgICA6IGAke2xhYmVsfTogJHtmb3JtYXROdW1iZXIoc2hhcmUsIFBFUkNFTlRfU0hBUkVfRk9STUFULCByYXRpb0NvbnRleHQpfSAoJHt2YWx1ZX0pYDtcbiAgfSk7XG5cbiAgcmV0dXJuIFtoZWFkaW5nLCAuLi5saW5lc10uam9pbignPGJyLz4nKTtcbn1cblxuLy8gQSB2YWx1ZSBheGlzOiBpdHMgdGl0bGUgYW5kIHJhbmdlIGZyb20gdGhlIGNvbmZpZywgaXRzIHRpY2sgbGFiZWxzIGZyb21cbi8vIHZhbHVlQXhpc0xhYmVsLiBBIHZlcnRpY2FsIGNoYXJ0J3MgdGl0bGUgc2l0cyBhYm92ZSB0aGUgYXhpcyBsaW5lLCByZWFkaW5nXG4vLyBhd2F5IGZyb20gdGhlIHBsb3QncyBlZGdlOyBhIGhvcml6b250YWwgY2hhcnQncyBpcyBjZW50ZXJlZCBiZWxvdyB0aGUgdGlja3MuXG4vLyBBIGJvdW5kIG9yIGludGVydmFsIHRoYXQgaXMgbm90IGEgdXNhYmxlIG51bWJlciBpcyBsZWZ0IHRvIEVDaGFydHMuIEEgMTAwJVxuLy8gc3RhY2tlZCBjaGFydCdzIHNoYXJlIGF4aXMgKGV4dHJhcy5wZXJjZW50TWluKSBoYXMgaXRzIG93biBmaXhlZCByYW5nZS5cbmZ1bmN0aW9uIHZhbHVlQXhpc09wdGlvbihcbiAgYXhpczogQ2hhcnRWYWx1ZUF4aXMgfCB1bmRlZmluZWQsXG4gIGhvcml6b250YWw6IGJvb2xlYW4sXG4gIGF4aXNMYWJlbDogVmFsdWVBeGlzTGFiZWwsXG4gIGV4dHJhczogVmFsdWVBeGlzRXh0cmFzID0ge30sXG4pIHtcbiAgY29uc3QgcmFuZ2UgPSBleHRyYXMucGVyY2VudE1pbiA9PT0gdW5kZWZpbmVkXG4gICAgPyB2YWx1ZUF4aXNSYW5nZShheGlzKVxuICAgIDogeyBtaW46IGV4dHJhcy5wZXJjZW50TWluLCBtYXg6IFBFUkNFTlRfQVhJU19NQVgsIGludGVydmFsOiBQRVJDRU5UX0FYSVNfSU5URVJWQUwgfTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICd2YWx1ZScgYXMgY29uc3QsXG4gICAgbmFtZTogYXhpcz8ubGFiZWwgfHwgdW5kZWZpbmVkLFxuICAgIG5hbWVMb2NhdGlvbjogaG9yaXpvbnRhbCA/ICdtaWRkbGUnIGFzIGNvbnN0IDogJ2VuZCcgYXMgY29uc3QsXG4gICAgbmFtZUdhcDogaG9yaXpvbnRhbCA/IDI4IDogMTAsXG4gICAgbmFtZVRleHRTdHlsZTogaG9yaXpvbnRhbCA/IHVuZGVmaW5lZCA6IHsgYWxpZ246IGV4dHJhcy5pbmRleCA9PT0gMSA/ICdyaWdodCcgYXMgY29uc3QgOiAnbGVmdCcgYXMgY29uc3QgfSxcbiAgICAvLyBBIHBpbm5lZCBib3VuZCB3aW5zOyBvbmUgbGVmdCBvcGVuIHJlYWNoZXMgdGhlIHJlZmVyZW5jZXMgKHJlYWNoTWluKS5cbiAgICBtaW46IHJhbmdlLm1pbiA/PyByZWFjaE1pbihleHRyYXMucmVhY2gpLFxuICAgIG1heDogcmFuZ2UubWF4ID8/IHJlYWNoTWF4KGV4dHJhcy5yZWFjaCksXG4gICAgaW50ZXJ2YWw6IHJhbmdlLmludGVydmFsLFxuICAgIGF4aXNMYWJlbCxcbiAgfTtcbn1cblxuLy8gVGhlIHBhcnQgb2YgYSB2YWx1ZSBheGlzJ3MgcmFuZ2UgdGhlIGNvbmZpZyBwaW5zLiBBIGJvdW5kIHRoYXQgaXMgbm90IGFcbi8vIGZpbml0ZSBudW1iZXIsIG9yIGFuIGludGVydmFsIHRoYXQgaXMgbm90IGEgcG9zaXRpdmUgb25lLCBpcyBsZWZ0IG91dCwgYW5kXG4vLyB0aGUgY2hhcnQgcGlja3MgaXQgZnJvbSB0aGUgZGF0YS4gU2hhcmVkIHdpdGggdGhlIFBvd2VyUG9pbnQgZXhwb3J0IHNvIGJvdGhcbi8vIG1lZGlhIGRyYXcgdGhlIHNhbWUgcmFuZ2UuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVBeGlzUmFuZ2UoYXhpczogQ2hhcnRWYWx1ZUF4aXMgfCB1bmRlZmluZWQpOiB7IG1pbj86IG51bWJlcjsgbWF4PzogbnVtYmVyOyBpbnRlcnZhbD86IG51bWJlciB9IHtcbiAgY29uc3QgaW50ZXJ2YWwgPSBheGlzTnVtYmVyKGF4aXM/LmludGVydmFsKTtcblxuICByZXR1cm4ge1xuICAgIG1pbjogYXhpc051bWJlcihheGlzPy5taW4pLFxuICAgIG1heDogYXhpc051bWJlcihheGlzPy5tYXgpLFxuICAgIGludGVydmFsOiBpbnRlcnZhbCAhPT0gdW5kZWZpbmVkICYmIGludGVydmFsID4gMCA/IGludGVydmFsIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vLyBBIHR3by1heGlzIGNoYXJ0J3MgdmFsdWUgYXhlczogdGhlIHByaW1hcnkgb24gdGhlIGxlZnQsIHRoZSBzZWNvbmQgb24gdGhlXG4vLyByaWdodCB3aXRob3V0IGdyaWRsaW5lcyBvZiBpdHMgb3duLiBFYWNoIGF4aXMncyB0aWNrcyB0YWtlIHRoZSBmb3JtYXQgb2YgdGhlXG4vLyBtZWFzdXJlcyBwbG90dGVkIGFnYWluc3QgaXQuIFdpdGhvdXQgYSByYW5nZSBvbiBlaXRoZXIgYXhpcyB0aGUgc2Vjb25kIGF4aXNcbi8vIGFsaWducyBpdHMgdGlja3MgdG8gdGhlIHByaW1hcnkncyBncmlkbGluZXMuXG4vL1xuLy8gT24gYSAxMDAlIHN0YWNrZWQgY2hhcnQgKHBlcmNlbnRNaW4gc2V0KSB0aGUgcHJpbWFyeSBheGlzIGlzIHRoZSBzaGFyZSBheGlzLFxuLy8gd2hvc2UgcmFuZ2UgaXMgZml4ZWQsIGFuZCB0aGUgc2Vjb25kIGF4aXMncyBzZXJpZXMgYXJlIG5vdCBzdGFja2VkLlxuZnVuY3Rpb24gdHdvVmFsdWVBeGVzT3B0aW9uKFxuICBjb25maWc6IENoYXJ0Q29uZmlnLFxuICBheGlzRm9ybWF0czogKFZhbHVlQXhpc0Zvcm1hdCB8IG51bGwpW10sXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4gIHBlcmNlbnRNaW46IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgcmVmZXJlbmNlczogRHJhd25SZWZlcmVuY2VbXSxcbikge1xuICBjb25zdCBwZXJjZW50ID0gcGVyY2VudE1pbiAhPT0gdW5kZWZpbmVkO1xuICBjb25zdCBsYWJlbCA9IChheGlzSW5kZXg6IFZhbHVlQXhpc0luZGV4KSA9PiB2YWx1ZUF4aXNMYWJlbChheGlzRm9ybWF0c1theGlzSW5kZXhdID8/IG51bGwsIGNvbnRleHQpO1xuXG4gIHJldHVybiBbXG4gICAgdmFsdWVBeGlzT3B0aW9uKGNvbmZpZy52YWx1ZUF4aXMsIGZhbHNlLCBwZXJjZW50ID8gcGVyY2VudEF4aXNMYWJlbChjb250ZXh0KSA6IGxhYmVsKDApLCB7XG4gICAgICBpbmRleDogMCxcbiAgICAgIHBlcmNlbnRNaW4sXG4gICAgICByZWFjaDogcmVmZXJlbmNlUmVhY2gocmVmZXJlbmNlcywgMCksXG4gICAgfSksXG4gICAge1xuICAgICAgLi4udmFsdWVBeGlzT3B0aW9uKGNvbmZpZy5zZWNvbmRhcnlBeGlzLCBmYWxzZSwgbGFiZWwoMSksIHsgaW5kZXg6IDEsIHJlYWNoOiByZWZlcmVuY2VSZWFjaChyZWZlcmVuY2VzLCAxKSB9KSxcbiAgICAgIHBvc2l0aW9uOiAncmlnaHQnIGFzIGNvbnN0LFxuICAgICAgc3BsaXRMaW5lOiB7IHNob3c6IGZhbHNlIH0sXG4gICAgICBhbGlnblRpY2tzOiAhcGVyY2VudCAmJiAhaGFzQXhpc1JhbmdlKGNvbmZpZy52YWx1ZUF4aXMpICYmICFoYXNBeGlzUmFuZ2UoY29uZmlnLnNlY29uZGFyeUF4aXMpLFxuICAgIH0sXG4gIF07XG59XG5cbi8vIFdoZXRoZXIgdGhlIGNvbmZpZyBwaW5zIGFueSBvZiBhbiBheGlzJ3MgcmFuZ2U6IGEgYm91bmQgb3IgYSB0aWNrIGludGVydmFsLlxuZnVuY3Rpb24gaGFzQXhpc1JhbmdlKGF4aXM6IENoYXJ0VmFsdWVBeGlzIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKHZhbHVlQXhpc1JhbmdlKGF4aXMpKS5zb21lKCh2YWx1ZSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCk7XG59XG5cbi8vIEEgY29uZmlndXJlZCBib3VuZCBvciBpbnRlcnZhbCB3aGVuIGl0IGlzIGEgZmluaXRlIG51bWJlciwgZWxzZSB1bmRlZmluZWQuXG5mdW5jdGlvbiBheGlzTnVtYmVyKHZhbHVlOiB1bmtub3duKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG4vLyBBIHZhbHVlIGF4aXMncyB0aWNrIGxhYmVscy5cbmludGVyZmFjZSBWYWx1ZUF4aXNMYWJlbCB7XG4gIGZvcm1hdHRlcjogKHZhbHVlOiBudW1iZXIpID0+IHN0cmluZztcbn1cblxuLy8gVGljayBsYWJlbHMgd3JpdHRlbiBpbiB0aGUgbG9jYWxlLiBFQ2hhcnRzJyBvd24gdGlja3MgYXJlIGdyb3VwZWQgZW4tVVNcbi8vIHdoYXRldmVyIHRoZSBwYWdlJ3MgbGFuZ3VhZ2UuXG4vL1xuLy8gV2l0aCBhIG51bWJlciBmb3JtYXQsIHRoZSB1bml0cyBhbmQgZGVjaW1hbHMgZGVjaWRlZCBvbmNlIGZvciB0aGUgd2hvbGVcbi8vIGF4aXMgKHJlc29sdmVWYWx1ZUF4aXNGb3JtYXQpIHdyaXRlIGV2ZXJ5IHRpY2sgYWxpa2UgKCcxLjVLJywgJzIuMEsnLCBuZXZlclxuLy8gJzJLJykuIFdpdGhvdXQgb25lLCBvciB3aGVuIGl0IGxlYXZlcyB0aGUgdGlja3MgYW4gdW5zY2FsZWQgbnVtYmVyIHdpdGggbm9cbi8vIHBpbm5lZCBkZWNpbWFscyAoZm9ybWF0ICdudW1iZXInLCBvciBwcmVjaXNpb24tbGVzcyB1bml0cyBub25lKSwgZWFjaCB0aWNrXG4vLyBpcyBhIHBsYWluIGxvY2FsZS1ncm91cGVkIG51bWJlciBrZWVwaW5nIGl0cyBvd24gZGVjaW1hbHMsIHNvIGEgMC4wMDAyIHRpY2tcbi8vIG5ldmVyIHJvdW5kcyB0byAnMCcuXG5mdW5jdGlvbiB2YWx1ZUF4aXNMYWJlbChmb3JtYXQ6IFZhbHVlQXhpc0Zvcm1hdCB8IG51bGwsIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiBWYWx1ZUF4aXNMYWJlbCB7XG4gIGlmICghZm9ybWF0IHx8IChmb3JtYXQuY2hhcnQudW5pdHMgPT09IFJlcG9ydE51bWJlclVuaXRzLk5vbmUgJiYgZm9ybWF0LmNoYXJ0LmRlY2ltYWxzID09PSBudWxsKSkge1xuICAgIHJldHVybiB7IGZvcm1hdHRlcjogKHZhbHVlOiBudW1iZXIpID0+IGZvcm1hdFBsYWluTnVtYmVyKHZhbHVlLCBjb250ZXh0LmxvY2FsZSkgfTtcbiAgfVxuXG4gIGNvbnN0IG9wdGlvbnMgPSB7IHVuaXRzOiBmb3JtYXQuY2hhcnQudW5pdHMsIGRlY2ltYWxzOiBmb3JtYXQuY2hhcnQuZGVjaW1hbHMgfTtcblxuICByZXR1cm4ge1xuICAgIGZvcm1hdHRlcjogKHZhbHVlOiBudW1iZXIpID0+IGZvcm1hdE51bWJlcih2YWx1ZSwgZm9ybWF0LnNwZWMsIGNvbnRleHQsIG9wdGlvbnMpLFxuICB9O1xufVxuXG4vLyBBbiBheGlzJ3MgZm9ybWF0IGZyb20gdGhlIHNwZWMgaXRzIG1lYXN1cmVzIGFncmVlIG9uLCB3aXRoIHRoZSB1bml0cyBhbmRcbi8vIGRlY2ltYWxzIGRlY2lkZWQgZnJvbSBpdHMgcGVhay4gV2l0aG91dCBhIHNwZWMgdGhlIGF4aXMgaXMgcGxhaW4sIGFuZCB0aGVcbi8vIHBlYWsgaXMgbmV2ZXIgY29tcHV0ZWQuXG5mdW5jdGlvbiByZXNvbHZlVmFsdWVBeGlzRm9ybWF0KFxuICBzcGVjOiBOdW1iZXJGb3JtYXRTcGVjIHwgbnVsbCxcbiAgcGVhazogKCkgPT4gbnVtYmVyLFxuICBjb250ZXh0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuKTogVmFsdWVBeGlzRm9ybWF0IHwgbnVsbCB7XG4gIHJldHVybiBzcGVjID8geyBzcGVjLCBjaGFydDogcmVzb2x2ZUNoYXJ0TnVtYmVyRm9ybWF0KHNwZWMsIHBlYWsoKSwgY29udGV4dCkgfSA6IG51bGw7XG59XG5cbi8vIEVhY2ggdmFsdWUgYXhpcydzIGZvcm1hdCwgYnkgYXhpcyBpbmRleC4gQSBjaGFydCB3aXRoIG9uZSB2YWx1ZSBheGlzIHRha2VzXG4vLyB0aGUgZm9ybWF0IHRoZSBwbG90dGVkIHNlcmllcycgbWVhc3VyZXMgYWdyZWUgb24gKGEgc3BsaXRCeSBvciBjb2xvckJ5IGNoYXJ0XG4vLyBwbG90cyBvbmx5IGl0cyBmaXJzdCBtZWFzdXJlKSwgZnJvbSB0aGUgcGVhayBvZiBhbGwgaXRzIHNlcmllcy4gT24gYSB0d28tYXhpcyBjaGFydCBlYWNoIGF4aXMgdGFrZXMgdGhlIGZvcm1hdCBvZiB0aGUgbWVhc3VyZXNcbi8vIHBsb3R0ZWQgYWdhaW5zdCBpdCwgZnJvbSB0aGUgcGVhayBvZiBpdHMgb3duIHNlcmllcywgd2hpY2ggYXJlIG5ldmVyXG4vLyBzdGFja2VkIHdpdGggYSAxMDAlIHN0YWNrZWQgY2hhcnQncyBzaGFyZXMuIEEgcmVmZXJlbmNlIHBhc3QgdGhlIGRhdGFcbi8vIHN0cmV0Y2hlcyBpdHMgYXhpcywgc28gaXQgY291bnRzIHRvd2FyZCB0aGUgcGVhayAocmVmZXJlbmNlUGVhayk7IGEgMTAwJVxuLy8gc3RhY2tlZCBjaGFydCdzIHJlZmVyZW5jZXMgYXJlIHNoYXJlcywgd2hpY2ggdGhlIHJhdyB2YWx1ZXMnIHBlYWsgbGVhdmVzXG4vLyBvdXQuXG5mdW5jdGlvbiB2YWx1ZUF4aXNGb3JtYXRzKFxuICBjb25maWc6IENoYXJ0Q29uZmlnLFxuICBleHRyYWN0ZWQ6IEV4dHJhY3RlZENoYXJ0U2VyaWVzLFxuICBheGlzSW5kZXhlczogVmFsdWVBeGlzSW5kZXhbXSxcbiAgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgcGVyY2VudDogYm9vbGVhbixcbiAgcmVmZXJlbmNlczogRHJhd25SZWZlcmVuY2VbXSxcbik6IChWYWx1ZUF4aXNGb3JtYXQgfCBudWxsKVtdIHtcbiAgY29uc3QgcmVhY2ggPSAoYXhpc0luZGV4OiBWYWx1ZUF4aXNJbmRleCkgPT4gKHBlcmNlbnQgJiYgYXhpc0luZGV4ID09PSAwID8gMCA6IHJlZmVyZW5jZVBlYWsocmVmZXJlbmNlcywgYXhpc0luZGV4KSk7XG5cbiAgaWYgKCFheGlzSW5kZXhlcy5pbmNsdWRlcygxKSkge1xuICAgIHJldHVybiBbcmVzb2x2ZVZhbHVlQXhpc0Zvcm1hdChcbiAgICAgIGF4aXNOdW1iZXJGb3JtYXQoZXh0cmFjdGVkLnNlcmllcy5tYXAoKHNlcmllcykgPT4gc2VyaWVzLm1lYXN1cmUpKSxcbiAgICAgICgpID0+IE1hdGgubWF4KGNoYXJ0VmFsdWVQZWFrKGV4dHJhY3RlZC5zZXJpZXMubWFwKChzZXJpZXMpID0+IHNlcmllcy52YWx1ZXMpLCAhIWNvbmZpZy5zdGFja2VkKSwgcmVhY2goMCkpLFxuICAgICAgY29udGV4dCxcbiAgICApXTtcbiAgfVxuXG4gIHJldHVybiAoWzAsIDFdIGFzIGNvbnN0KS5tYXAoKGF4aXNJbmRleCkgPT4ge1xuICAgIGNvbnN0IG9uQXhpcyA9IGV4dHJhY3RlZC5zZXJpZXMuZmlsdGVyKChfLCBpbmRleCkgPT4gYXhpc0luZGV4ZXNbaW5kZXhdID09PSBheGlzSW5kZXgpO1xuXG4gICAgcmV0dXJuIHJlc29sdmVWYWx1ZUF4aXNGb3JtYXQoXG4gICAgICBheGlzTnVtYmVyRm9ybWF0KG9uQXhpcy5tYXAoKHNlcmllcykgPT4gc2VyaWVzLm1lYXN1cmUpKSxcbiAgICAgICgpID0+IE1hdGgubWF4KGNoYXJ0VmFsdWVQZWFrKG9uQXhpcy5tYXAoKHNlcmllcykgPT4gc2VyaWVzLnZhbHVlcyksICEhY29uZmlnLnN0YWNrZWQgJiYgIXBlcmNlbnQpLCByZWFjaChheGlzSW5kZXgpKSxcbiAgICAgIGNvbnRleHQsXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIEEgMTAwJSBzdGFja2VkIGNoYXJ0J3Mgc2hhcmUgYXhpcyB0aWNrczogd2hvbGUgcGVyY2VudGFnZXMgaW4gdGhlIGxvY2FsZVxuLy8gKCcyNSUnLCAnMjUgJScgaW4gZnItQ0EpLiBUaGUgc2hhcmVzIGFyZSByYXRpb3Mgd2hhdGV2ZXIgdGhlIHJlcG9ydCdzXG4vLyBwZXJjZW50Rm9ybWF0IHNheXMgb2YgaXRzIHN0b3JlZCB2YWx1ZXMuXG5mdW5jdGlvbiBwZXJjZW50QXhpc0xhYmVsKGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQpOiBWYWx1ZUF4aXNMYWJlbCB7XG4gIHJldHVybiB7IGZvcm1hdHRlcjogd2hvbGVQZXJjZW50Rm9ybWF0dGVyKGNvbnRleHQpIH07XG59XG5cbi8vIEEgc2hhcmUgYXMgYSB3aG9sZSBwZXJjZW50YWdlIGluIHRoZSBsb2NhbGUsIGZvciB0aGUgc2hhcmUgYXhpcydzIHRpY2tzIGFuZFxuLy8gaXRzIHNlcmllcycgZGF0YSBsYWJlbHMuXG5mdW5jdGlvbiB3aG9sZVBlcmNlbnRGb3JtYXR0ZXIoY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCk6ICh2YWx1ZTogdW5rbm93bikgPT4gc3RyaW5nIHtcbiAgY29uc3QgcmF0aW9Db250ZXh0ID0geyAuLi5jb250ZXh0LCByYXRpb1BlcmNlbnQ6IHRydWUgfTtcblxuICByZXR1cm4gKHZhbHVlOiB1bmtub3duKSA9PiBmb3JtYXROdW1iZXIodmFsdWUsIFBFUkNFTlRfQVhJU19GT1JNQVQsIHJhdGlvQ29udGV4dCk7XG59XG5cbi8vIFdoYXQgYSBzZXJpZXMnIHRvb2x0aXAgd3JpdGVzIGJlc2lkZSBpdHMgbmFtZS5cbmludGVyZmFjZSBTZXJpZXNUb29sdGlwIHtcbiAgdmFsdWVGb3JtYXR0ZXI6ICh2YWx1ZTogdW5rbm93bikgPT4gc3RyaW5nO1xufVxuXG4vLyBBIHNlcmllcycgdG9vbHRpcCB2YWx1ZSBpbiBpdHMgbWVhc3VyZSdzIG51bWJlciBmb3JtYXQsIHBlciB2YWx1ZSAoJ+KAlCcgd2hlblxuLy8gZW1wdHkpLiBBIG1lYXN1cmUgd2l0aG91dCBvbmUgd3JpdGVzIGl0IGFzIHRoZSBwbGFpbiB2YWx1ZSBheGlzIGRvZXMuIEFcbi8vIHZhbHVlIGNhbiBhcnJpdmUgYXMgYW4gYXJyYXkgKGEgW3ZhbHVlLCAuLi5dIGRhdGEgaXRlbSksIHdob3NlIGZpcnN0IGVudHJ5XG4vLyBpcyB0aGUgdmFsdWUuXG5mdW5jdGlvbiBzZXJpZXNUb29sdGlwKG1lYXN1cmU6IENoYXJ0TWVhc3VyZSB8IHVuZGVmaW5lZCwgY29udGV4dDogUmVwb3J0Rm9ybWF0Q29udGV4dCk6IFNlcmllc1Rvb2x0aXAge1xuICBpZiAoIWhhc051bWJlckZvcm1hdChtZWFzdXJlKSkge1xuICAgIHJldHVybiB7IHZhbHVlRm9ybWF0dGVyOiAodmFsdWU6IHVua25vd24pID0+IGZvcm1hdFBsYWluTnVtYmVyKHZhbHVlLCBjb250ZXh0LmxvY2FsZSkgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmFsdWVGb3JtYXR0ZXI6ICh2YWx1ZTogdW5rbm93bikgPT4gZm9ybWF0TnVtYmVyKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWVbMF0gOiB2YWx1ZSwgbWVhc3VyZSwgY29udGV4dCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkUGllT3B0aW9uKFxuICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgZGF0YTogQ29tcG9uZW50RGF0YSxcbiAgZG9udXQ6IGJvb2xlYW4sXG4gIGNvbnRleHQ6IFJlcG9ydEZvcm1hdENvbnRleHQsXG4pOiBFQ2hhcnRzT3B0aW9uIHtcbiAgY29uc3QgY29uZmlnID0gY29tcG9uZW50LmNvbmZpZyBhcyBDaGFydENvbmZpZztcbiAgY29uc3QgZXh0cmFjdGVkID0gZXh0cmFjdENoYXJ0U2VyaWVzKGNvbXBvbmVudCwgZGF0YSk7XG4gIGNvbnN0IHZhbHVlcyA9IGV4dHJhY3RlZC5zZXJpZXNbMF0/LnZhbHVlcyA/PyBbXTtcbiAgY29uc3QgbGVnZW5kUG9zaXRpb24gPSByZXNvbHZlTGVnZW5kUG9zaXRpb24oY29uZmlnLCBleHRyYWN0ZWQuc2VyaWVzLmxlbmd0aCk7XG5cbiAgcmV0dXJuIHtcbiAgICB0b29sdGlwOiB7IHRyaWdnZXI6ICdpdGVtJyB9LFxuICAgIGxlZ2VuZDogbGVnZW5kT3B0aW9uKGxlZ2VuZFBvc2l0aW9uKSxcbiAgICBzZXJpZXM6IFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ3BpZScsXG4gICAgICAgIHJhZGl1czogZG9udXQgPyBbJzQ1JScsICc3MiUnXSA6ICc3MiUnLFxuICAgICAgICBjZW50ZXI6IHBpZUNlbnRlcihsZWdlbmRQb3NpdGlvbiksXG4gICAgICAgIHRvb2x0aXA6IHNlcmllc1Rvb2x0aXAoZXh0cmFjdGVkLnNlcmllc1swXT8ubWVhc3VyZSwgY29udGV4dCksXG4gICAgICAgIGxhYmVsOiB7IHNob3c6IGZhbHNlIH0sXG4gICAgICAgIGRhdGE6IGV4dHJhY3RlZC5jYXRlZ29yaWVzLm1hcCgoY2F0ZWdvcnksIGluZGV4KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IGNhdGVnb3J5LFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZXNbaW5kZXhdID8/IDAsXG4gICAgICAgIH0pKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbn1cblxuLy8gTnVkZ2UgdGhlIHBpZSBvZmYtY2VudGVyIHRvd2FyZCB0aGUgb3Bwb3NpdGUgZWRnZSBmcm9tIGl0cyBsZWdlbmQgc28gdGhlIHR3b1xuLy8gZG9uJ3QgY29sbGlkZTsgY2VudGVyZWQgd2hlbiB0aGUgbGVnZW5kIGlzIGhpZGRlbi5cbmZ1bmN0aW9uIHBpZUNlbnRlcihwb3NpdGlvbjogTGVnZW5kUG9zaXRpb24pOiBbc3RyaW5nLCBzdHJpbmddIHtcbiAgc3dpdGNoIChwb3NpdGlvbikge1xuICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgcmV0dXJuIFsnNjAlJywgJzUwJSddO1xuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgIHJldHVybiBbJzQwJScsICc1MCUnXTtcbiAgICBjYXNlICd0b3AnOlxuICAgICAgcmV0dXJuIFsnNTAlJywgJzU4JSddO1xuICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICByZXR1cm4gWyc1MCUnLCAnNDYlJ107XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBbJzUwJScsICc1MCUnXTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bmlxdWVWYWx1ZXMocm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgY29sdW1uOiBzdHJpbmcpOiB1bmtub3duW10ge1xuICBjb25zdCBzZWVuID0gbmV3IFNldDx1bmtub3duPigpO1xuICBjb25zdCB2YWx1ZXM6IHVua25vd25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgY29uc3QgdmFsdWUgPSByb3dbY29sdW1uXTtcbiAgICBpZiAoIXNlZW4uaGFzKHZhbHVlKSkge1xuICAgICAgc2Vlbi5hZGQodmFsdWUpO1xuICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbmZ1bmN0aW9uIG51bWVyaWModmFsdWU6IHVua25vd24pOiBudW1iZXIgfCBudWxsIHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09ICcnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIodmFsdWUpO1xuXG4gIHJldHVybiBOdW1iZXIuaXNGaW5pdGUocGFyc2VkKSA/IHBhcnNlZCA6IG51bGw7XG59XG5cbi8vIFRoZSBlZmZlY3RpdmUgdGltZSBidWNrZXQgdGhlIHJvd3Mgd2VyZSBncm91cGVkIGludG8gKGZyb20gdGhlIGRhdGEgZW5kcG9pbnQpLFxuLy8gb3IgbnVsbCB3aGVuIHRoZSB4LWF4aXMgaXNuJ3QgYSB0aW1lIGF4aXMg4oCUIGdhdGVzIHRoZSBjb21wYWN0IHBlcmlvZCBsYWJlbHMuXG5mdW5jdGlvbiBidWNrZXRHcmFudWxhcml0eShkYXRhOiBDb21wb25lbnREYXRhKTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwge1xuICByZXR1cm4gZGF0YS5ncmFudWxhcml0eSAmJiBHUkFOVUxBUklUWV9PUFRJT05TLnNvbWUoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlID09PSBkYXRhLmdyYW51bGFyaXR5KVxuICAgID8gZGF0YS5ncmFudWxhcml0eVxuICAgIDogbnVsbDtcbn1cblxuLy8gV2hldGhlciB0aGUgcGVyaW9kLXN0YXJ0IGNhdGVnb3JpZXMgY3Jvc3MgYSB5ZWFyIGJvdW5kYXJ5LiBXaGVuIHRoZXkgZG9uJ3QsXG4vLyB0aGUgeWVhciBpcyBwdXJlIG5vaXNlIG9uIGV2ZXJ5IGxhYmVsLCBzbyBpdCdzIGRyb3BwZWQgZW50aXJlbHkuXG5leHBvcnQgZnVuY3Rpb24gc3BhbnNNdWx0aXBsZVllYXJzKGNhdGVnb3JpZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gIGNvbnN0IHllYXJzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgY2F0ZWdvcmllcykge1xuICAgIGNvbnN0IGRhdGUgPSBwYXJzZUlTTyhjYXRlZ29yeSk7XG4gICAgaWYgKGlzVmFsaWQoZGF0ZSkpIHtcbiAgICAgIHllYXJzLmFkZChkYXRlLmdldEZ1bGxZZWFyKCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB5ZWFycy5zaXplID4gMTtcbn1cblxuLy8gQSB0aW1lIGF4aXMncyBkYXRlIGxhYmVsIHN0eWxlIHdoZW4gaXRzIGNvbmZpZyBuYW1lcyBvbmUgdGhlIHZpZXdlciBrbm93cyxcbi8vIGVsc2Ugc2hvcnQuXG5leHBvcnQgZnVuY3Rpb24gY2hhcnREYXRlTGFiZWwoY29uZmlnOiBDaGFydENvbmZpZyB8IHVuZGVmaW5lZCk6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoUmVwb3J0Q2hhcnREYXRlTGFiZWwpLmZpbmQoKHN0eWxlKSA9PiBzdHlsZSA9PT0gY29uZmlnPy54QXhpcz8uZGF0ZUxhYmVsKVxuICAgID8/IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0O1xufVxuXG4vLyBBIGJ1Y2tldCdzIHBlcmlvZC1zdGFydCBzcGxpdCBpbnRvIGl0cyBwcmltYXJ5IGxhYmVsIGFuZCBpdHMgeWVhci4gQSB5ZWFyXG4vLyByZWFkcyBcIjIwMjVcIiBpbiBldmVyeSBzdHlsZS4gU2hvcnQsIGluIHRoZSBsb2NhbGU6IGRheS93ZWVrIHJlYWQgXCJNYXkgMVwiXG4vLyAoJzEgbWFpJyBpbiBmci1DQSksIG1vbnRoIFwiTWF5XCIgKCdtYWknKSwgcXVhcnRlciBcIlEyXCIgKCdUMicgaW4gRnJlbmNoKS5cbi8vIExvbmcgY2FycmllcyBpdHMgeWVhciwgaW4gdGhlIGxvY2FsZTogXCJNYXkgMSwgMjAyNlwiLCBcIk1heSAyMDI2XCIgKCdtYWlcbi8vIDIwMjYnKSwgXCJRMiAyMDI2XCIuIE51bWVyaWMgaXMgdGhlIHNhbWUgaW4gZXZlcnkgbG9jYWxlOiBcIjIwMjYtMDUtMDFcIixcbi8vIFwiMjAyNi0wNVwiLCBcIjIwMjYtUTJcIi4gUmV0dXJucyBudWxsIGZvciBhIHZhbHVlIHRoYXQgaXNuJ3QgYSBwYXJzZWFibGUgZGF0ZVxuLy8gKGxlZnQgYXMtaXMgYnkgY2FsbGVycykuXG5mdW5jdGlvbiBwZXJpb2RMYWJlbFBhcnRzKFxuICB2YWx1ZTogc3RyaW5nLFxuICBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSxcbiAgbG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcsXG4gIGRhdGVMYWJlbDogUmVwb3J0Q2hhcnREYXRlTGFiZWwgPSBSZXBvcnRDaGFydERhdGVMYWJlbC5TaG9ydCxcbik6IHsgcHJpbWFyeTogc3RyaW5nOyB5ZWFyOiBzdHJpbmcgfSB8IG51bGwge1xuICBjb25zdCBkYXRlID0gcGFyc2VJU08odmFsdWUpO1xuICBpZiAoIWlzVmFsaWQoZGF0ZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHllYXIgPSBTdHJpbmcoZGF0ZS5nZXRGdWxsWWVhcigpKTtcbiAgaWYgKGdyYW51bGFyaXR5ID09PSAneWVhcicpIHtcbiAgICByZXR1cm4geyBwcmltYXJ5OiB5ZWFyLCB5ZWFyIH07XG4gIH1cblxuICByZXR1cm4geyBwcmltYXJ5OiBwZXJpb2RQcmltYXJ5TGFiZWwoZGF0ZSwgZ3JhbnVsYXJpdHksIGxvY2FsZSwgZGF0ZUxhYmVsKSwgeWVhciB9O1xufVxuXG4vLyBBIHBlcmlvZCdzIGxhYmVsIGluIHRoZSBzdHlsZSBhc2tlZCBmb3IsIHRoZSB5ZWFyIGFzaWRlIChzZWVcbi8vIHBlcmlvZExhYmVsUGFydHMpLlxuZnVuY3Rpb24gcGVyaW9kUHJpbWFyeUxhYmVsKFxuICBkYXRlOiBEYXRlLFxuICBncmFudWxhcml0eTogRXhjbHVkZTxDaGFydEdyYW51bGFyaXR5LCAneWVhcic+LFxuICBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyxcbiAgZGF0ZUxhYmVsOiBSZXBvcnRDaGFydERhdGVMYWJlbCxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHllYXIgPSBTdHJpbmcoZGF0ZS5nZXRGdWxsWWVhcigpKTtcbiAgY29uc3QgcXVhcnRlciA9IE1hdGguZmxvb3IoZGF0ZS5nZXRNb250aCgpIC8gMykgKyAxO1xuXG4gIGlmIChkYXRlTGFiZWwgPT09IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLk51bWVyaWMpIHtcbiAgICBjb25zdCBtb250aCA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRheSA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBzd2l0Y2ggKGdyYW51bGFyaXR5KSB7XG4gICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgcmV0dXJuIGAke3llYXJ9LVEke3F1YXJ0ZXJ9YDtcbiAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgcmV0dXJuIGAke3llYXJ9LSR7bW9udGh9YDtcbiAgICAgIGRlZmF1bHQ6IC8vIGRheSwgd2VlayDigJQgdGhlIGJ1Y2tldCBzdGFydFxuICAgICAgICByZXR1cm4gYCR7eWVhcn0tJHttb250aH0tJHtkYXl9YDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBsb25nID0gZGF0ZUxhYmVsID09PSBSZXBvcnRDaGFydERhdGVMYWJlbC5Mb25nO1xuICBzd2l0Y2ggKGdyYW51bGFyaXR5KSB7XG4gICAgY2FzZSAncXVhcnRlcic6XG4gICAgICByZXR1cm4gbG9uZ1xuICAgICAgICA/IGAke3F1YXJ0ZXJQcmVmaXgobG9jYWxlKX0ke3F1YXJ0ZXJ9ICR7eWVhcn1gXG4gICAgICAgIDogYCR7cXVhcnRlclByZWZpeChsb2NhbGUpfSR7cXVhcnRlcn1gO1xuICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgIHJldHVybiBmb3JtYXRMb2NhbERhdGUoZGF0ZSwgbG9jYWxlLCBsb25nID8gTU9OVEhfWUVBUiA6IE1PTlRIX0xPTkcpO1xuICAgIGRlZmF1bHQ6IC8vIGRheSwgd2VlayDigJQgdGhlIGJ1Y2tldCBzdGFydCBhcyBhIG1vbnRoIGFuZCBkYXlcbiAgICAgIHJldHVybiBmb3JtYXRMb2NhbERhdGUoZGF0ZSwgbG9jYWxlLCBsb25nID8gREFZX1NIT1JUIDogTU9OVEhfREFZKTtcbiAgfVxufVxuXG4vLyBXaGV0aGVyIGEgcGVyaW9kIGxhYmVsIGxlYXZlcyBpdHMgeWVhciB0byBiZSBhZGRlZCBhcGFydDogb25seSBhIHNob3J0IG9uZVxuLy8gZG9lcywgYSBsb25nIG9yIG51bWVyaWMgbGFiZWwgYWxyZWFkeSBjYXJyaWVzIGl0LlxuZnVuY3Rpb24gcGVyaW9kWWVhckFwYXJ0KGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5LCBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsKTogYm9vbGVhbiB7XG4gIHJldHVybiBncmFudWxhcml0eSAhPT0gJ3llYXInICYmIGRhdGVMYWJlbCA9PT0gUmVwb3J0Q2hhcnREYXRlTGFiZWwuU2hvcnQ7XG59XG5cbmZ1bmN0aW9uIHF1YXJ0ZXJQcmVmaXgobG9jYWxlOiBSZXBvcnRMb2NhbGVUYWcpOiBzdHJpbmcge1xuICByZXR1cm4gUVVBUlRFUl9QUkVGSVhFUy5nZXQobG9jYWxlLnNwbGl0KCctJylbMF0udG9Mb3dlckNhc2UoKSkgPz8gUVVBUlRFUl9QUkVGSVg7XG59XG5cbi8vIEEgY29tcGFjdCBzaW5nbGUtbGluZSBwZXJpb2QgbGFiZWwg4oCUIGZvciBtZWRpYSB0aGF0IGNhbid0IGRvIGEgc3R5bGVkXG4vLyBzZWNvbmQgbGluZSwgZS5nLiBQb3dlclBvaW50LiBBIHNob3J0IGxhYmVsIGhhcyBpdHMgeWVhciBhcHBlbmRlZCBvbmx5IHdoZW5cbi8vIHRoZSBkYXRhIHNwYW5zIHllYXJzOyBhIGxvbmcgb3IgbnVtZXJpYyBvbmUgYWx3YXlzIGNhcnJpZXMgaXQuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UGVyaW9kTGFiZWwoXG4gIHZhbHVlOiBzdHJpbmcsXG4gIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5LFxuICBtdWx0aVllYXI6IGJvb2xlYW4sXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuICBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsID0gUmVwb3J0Q2hhcnREYXRlTGFiZWwuU2hvcnQsXG4pOiBzdHJpbmcge1xuICBjb25zdCBwYXJ0cyA9IHBlcmlvZExhYmVsUGFydHModmFsdWUsIGdyYW51bGFyaXR5LCBsb2NhbGUsIGRhdGVMYWJlbCk7XG4gIGlmICghcGFydHMpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gbXVsdGlZZWFyICYmIHBlcmlvZFllYXJBcGFydChncmFudWxhcml0eSwgZGF0ZUxhYmVsKSA/IGAke3BhcnRzLnByaW1hcnl9ICR7cGFydHMueWVhcn1gIDogcGFydHMucHJpbWFyeTtcbn1cblxuLy8gQSBjcm9zcy10YWIncyBjb2x1bW4gaGVhZGluZ3MsIHRoZSBvbmUgcnVsZSB0aGUgZ3JpZCBhbmQgdGhlIFBERi9Qb3dlclBvaW50XG4vLyBleHBvcnRzIHNoYXJlLiBUaGUgZmlyc3QgaXMgdGhlIHJvdyBrZXkgYW5kIGtlZXBzIGl0cyBhdXRob3JlZCBsYWJlbDsgdGhlXG4vLyByZXN0IGFyZSBwaXZvdCBWQUxVRVMuIFdoZW4gdGhlIHBpdm90IGF4aXMgaXMgYSB0aW1lIGRpbWVuc2lvbiB0aGUgc2VydmVyXG4vLyBzZW5kcyB0aGUgZ3JhaW4gaXQgYnVja2V0ZWQgYXQsIHNvIGEgcGVyaW9kLXN0YXJ0IGxpa2UgXCIyMDI2LTAxLTAxXCIgcmVhZHNcbi8vIFwiSmFudWFyeSAyMDI2XCIgKCdqYW52aWVyIDIwMjYnIGluIGZyLUNBKSwgYXMgdGhlIGNoYXJ0J3MgeC1heGlzIGxhYmVscyBpdC5cbmV4cG9ydCBmdW5jdGlvbiBwaXZvdEhlYWRpbmdzKFxuICBjb25maWc6IExpc3RDb25maWcsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuKTogc3RyaW5nW10ge1xuICBjb25zdCBjb2x1bW5zID0gZGF0YS5jb2x1bW5zID8/IFtdO1xuICBjb25zdCBtdWx0aVllYXIgPSBzcGFuc011bHRpcGxlWWVhcnMoY29sdW1ucyk7XG5cbiAgcmV0dXJuIGNvbHVtbnMubWFwKChjb2x1bW4sIGluZGV4KSA9PiB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gY29uZmlnLnJvd0J5Py5sYWJlbCB8fCBjb2x1bW47XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGEuZ3JhbnVsYXJpdHkgPyBmb3JtYXRQZXJpb2RMYWJlbChjb2x1bW4sIGRhdGEuZ3JhbnVsYXJpdHksIG11bHRpWWVhciwgbG9jYWxlKSA6IGNvbHVtbjtcbiAgfSk7XG59XG5cbi8vIEEgY3Jvc3MtdGFiJ3MgY29sdW1ucyBhcyB0aGUgZ3JpZCBhbmQgdGhlIGV4cG9ydHMgZHJhdyB0aGVtOiBlYWNoIGhlYWRlZCBieVxuLy8gcGl2b3RIZWFkaW5ncygpLCBhbmQgZXZlcnkgcGl2b3QtdmFsdWUgY29sdW1uIGZvcm1hdHRlZCBieSB0aGUgb25lXG4vLyBjb25maWcuY2VsbEZvcm1hdC4gVGhlIHJvdyBrZXkgY29sdW1uIHN0YXlzIGFzIGl0IGNhbWUuIGBudW1lcmljYCBtYXJrcyB0aGVcbi8vIGNvbHVtbnMgd2hvc2UgY2VsbHMgYXJlIGZvcm1hdHRlZCBudW1iZXJzLCB3aGljaCBhcmUgcmlnaHQtYWxpZ25lZC5cbmV4cG9ydCBmdW5jdGlvbiBwaXZvdENvbHVtblNwZWNzKFxuICBjb25maWc6IExpc3RDb25maWcsXG4gIGRhdGE6IENvbXBvbmVudERhdGEsXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuKTogKExpc3RDb2x1bW4gJiB7IG51bWVyaWM6IGJvb2xlYW4gfSlbXSB7XG4gIGNvbnN0IGhlYWRpbmdzID0gcGl2b3RIZWFkaW5ncyhjb25maWcsIGRhdGEsIGxvY2FsZSk7XG4gIGNvbnN0IGNlbGxGb3JtYXQgPSBjb25maWcuY2VsbEZvcm1hdDtcbiAgY29uc3QgbnVtZXJpYyA9IGhhc051bWJlckZvcm1hdChjZWxsRm9ybWF0KTtcbiAgY29uc3QgY2VsbHM6IFBpY2s8TGlzdENvbHVtbiwgJ2Zvcm1hdCcgfCAncHJlY2lzaW9uJyB8ICd1bml0cyc+ID0gbnVtZXJpYyAmJiBjZWxsRm9ybWF0XG4gICAgPyB7IGZvcm1hdDogbGlzdENvbHVtbkZvcm1hdChjZWxsRm9ybWF0LmZvcm1hdCksIHByZWNpc2lvbjogY2VsbEZvcm1hdC5wcmVjaXNpb24sIHVuaXRzOiBjZWxsRm9ybWF0LnVuaXRzIH1cbiAgICA6IHt9O1xuXG4gIHJldHVybiAoZGF0YS5jb2x1bW5zID8/IFtdKS5tYXAoKGNvbHVtbiwgaW5kZXgpID0+IGluZGV4ID09PSAwXG4gICAgPyB7IGNvbHVtbiwgbGFiZWw6IGhlYWRpbmdzW2luZGV4XSwgbnVtZXJpYzogZmFsc2UgfVxuICAgIDogeyBjb2x1bW4sIGxhYmVsOiBoZWFkaW5nc1tpbmRleF0sIC4uLmNlbGxzLCBudW1lcmljIH0pO1xufVxuXG4vLyBBIG51bWJlciBmb3JtYXQncyBzdHlsZSBhcyBhIGxpc3QgY29sdW1uJ3MgZm9ybWF0OiB0aGUgdHdvIGVudW1zIHNoYXJlXG4vLyB0aGVpciBudW1iZXIgdmFsdWVzLlxuZnVuY3Rpb24gbGlzdENvbHVtbkZvcm1hdChmb3JtYXQ6IE51bWJlckZvcm1hdFNwZWNbJ2Zvcm1hdCddKTogUmVwb3J0TGlzdENvbHVtbkZvcm1hdCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKFJlcG9ydExpc3RDb2x1bW5Gb3JtYXQpLmZpbmQoKHZhbHVlKSA9PiB2YWx1ZSA9PT0gZm9ybWF0KTtcbn1cblxuLy8gRUNoYXJ0cyBjYXRlZ29yeS1heGlzIGxhYmVsIGNvbmZpZyBmb3IgYSB0aW1lIGJ1Y2tldDogdGhlIHByaW1hcnkgbGFiZWwgb25cbi8vIGxpbmUgb25lLCBhbmQg4oCUIG9ubHkgd2hlbiB0aGUgZGF0YSBzcGFucyBtdWx0aXBsZSB5ZWFycyDigJQgdGhlIHllYXIgb24gYSBzbWFsbFxuLy8gZ3JheSBzZWNvbmQgbGluZSwgY2VudGVyZWQgdW5kZXIgdGhlIHRpY2sgKHllYXIgZ3JhbnVsYXJpdHkgbmVlZHMgbm8gc2Vjb25kXG4vLyBsaW5lLCBpdCBhbHJlYWR5IGlzIHRoZSB5ZWFyLCBhbmQgbmVpdGhlciBkb2VzIGEgbG9uZyBvciBudW1lcmljIGxhYmVsLFxuLy8gd2hpY2ggY2FycmllcyBpdHMgeWVhcikuIEVtcHR5IGZvciBhIG5vbi10aW1lIGF4aXMgKGxhYmVscyBhcy1pcykuXG5mdW5jdGlvbiBwZXJpb2RBeGlzTGFiZWwoXG4gIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCxcbiAgY2F0ZWdvcmllczogc3RyaW5nW10sXG4gIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnLFxuICBkYXRlTGFiZWw6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLFxuKTogeyBheGlzTGFiZWw/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9IHtcbiAgaWYgKCFncmFudWxhcml0eSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IG11bHRpWWVhciA9IHNwYW5zTXVsdGlwbGVZZWFycyhjYXRlZ29yaWVzKTtcblxuICByZXR1cm4ge1xuICAgIGF4aXNMYWJlbDoge1xuICAgICAgZm9ybWF0dGVyOiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IHBlcmlvZExhYmVsUGFydHModmFsdWUsIGdyYW51bGFyaXR5LCBsb2NhbGUsIGRhdGVMYWJlbCk7XG4gICAgICAgIGlmICghcGFydHMpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbXVsdGlZZWFyICYmIHBlcmlvZFllYXJBcGFydChncmFudWxhcml0eSwgZGF0ZUxhYmVsKVxuICAgICAgICAgID8gYCR7cGFydHMucHJpbWFyeX1cXG57eXJ8JHtwYXJ0cy55ZWFyfX1gXG4gICAgICAgICAgOiBwYXJ0cy5wcmltYXJ5O1xuICAgICAgfSxcbiAgICAgIHJpY2g6IHsgeXI6IHsgZm9udFNpemU6IDEwLCBjb2xvcjogJyM5YWEwYTYnLCBsaW5lSGVpZ2h0OiAxNCB9IH0sXG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==