@firestitch/report 18.6.0 → 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.
- package/app/reports/components/component-chart/component-chart.component.d.ts +6 -7
- package/app/reports/components/component-kpi/component-kpi.component.d.ts +8 -8
- package/app/reports/components/component-list/component-list.component.d.ts +33 -11
- package/app/reports/components/report-component/report-component.component.d.ts +3 -0
- package/app/reports/data/report.data.d.ts +2 -1
- package/app/reports/dialogs/list-columns/list-columns.component.d.ts +23 -0
- package/app/reports/dialogs/report-settings/report-locale-patch.d.ts +5 -0
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +20 -1
- package/app/reports/enums/report-chart-color.enum.d.ts +12 -0
- package/app/reports/enums/report-chart-data-labels.enum.d.ts +6 -0
- package/app/reports/enums/report-chart-date-label.enum.d.ts +5 -0
- package/app/reports/enums/report-chart-line-style.enum.d.ts +5 -0
- package/app/reports/enums/report-chart-mark-stat.enum.d.ts +6 -0
- package/app/reports/enums/report-list-column-format.enum.d.ts +6 -0
- package/app/reports/enums/report-number-units.enum.d.ts +6 -0
- package/app/reports/enums/report-value-format.enum.d.ts +5 -0
- package/app/reports/export/offscreen-chart.d.ts +2 -2
- package/app/reports/export/report-export-collector.service.d.ts +12 -9
- package/app/reports/export/report-pdf.service.d.ts +1 -0
- package/app/reports/export/report-pptx.service.d.ts +17 -0
- package/app/reports/format.d.ts +39 -4
- package/app/reports/interfaces/report.interface.d.ts +82 -10
- package/app/reports/list-config.d.ts +9 -0
- package/app/reports/option-builder.d.ts +69 -8
- package/app/reports/pipes/report-date.pipe.d.ts +2 -1
- package/app/reports/pipes/report-number.pipe.d.ts +8 -0
- package/app/reports/report-filter-items.d.ts +5 -2
- package/app/reports/report-url-state.d.ts +5 -0
- package/app/reports/services/report-filter-state.service.d.ts +29 -2
- package/app/reports/theme/palette.d.ts +3 -0
- package/app/reports/theme/typography.d.ts +1 -0
- package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +19 -20
- package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +23 -26
- package/esm2022/app/reports/components/component-list/component-list.component.mjs +157 -53
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +81 -19
- package/esm2022/app/reports/data/report.data.mjs +17 -4
- package/esm2022/app/reports/dialogs/global-settings/global-settings.component.mjs +2 -2
- package/esm2022/app/reports/dialogs/list-columns/list-columns.component.mjs +56 -0
- package/esm2022/app/reports/dialogs/report-settings/report-locale-patch.mjs +13 -0
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +137 -15
- package/esm2022/app/reports/enums/report-chart-color.enum.mjs +19 -0
- package/esm2022/app/reports/enums/report-chart-data-labels.enum.mjs +13 -0
- package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +13 -0
- package/esm2022/app/reports/enums/report-chart-line-style.enum.mjs +12 -0
- package/esm2022/app/reports/enums/report-chart-mark-stat.enum.mjs +12 -0
- package/esm2022/app/reports/enums/report-list-column-format.enum.mjs +14 -0
- package/esm2022/app/reports/enums/report-number-units.enum.mjs +14 -0
- package/esm2022/app/reports/enums/report-value-format.enum.mjs +13 -0
- package/esm2022/app/reports/export/offscreen-chart.mjs +5 -4
- package/esm2022/app/reports/export/report-export-collector.service.mjs +96 -39
- package/esm2022/app/reports/export/report-pdf.service.mjs +94 -37
- package/esm2022/app/reports/export/report-pptx.service.mjs +482 -85
- package/esm2022/app/reports/format.mjs +502 -57
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/list-config.mjs +74 -0
- package/esm2022/app/reports/option-builder.mjs +880 -95
- package/esm2022/app/reports/pipes/report-date.pipe.mjs +7 -6
- package/esm2022/app/reports/pipes/report-number.pipe.mjs +25 -0
- package/esm2022/app/reports/report-filter-items.mjs +28 -3
- package/esm2022/app/reports/report-url-state.mjs +60 -15
- package/esm2022/app/reports/services/report-filter-state.service.mjs +275 -29
- package/esm2022/app/reports/theme/echarts.mjs +8 -2
- package/esm2022/app/reports/theme/palette.mjs +19 -1
- package/esm2022/app/reports/theme/typography.mjs +4 -1
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +11 -4
- package/esm2022/app/reports/views/report/report.component.mjs +6 -2
- package/esm2022/public_api.mjs +9 -1
- package/fesm2022/{firestitch-report-echarts-B9nl9XKM.mjs → firestitch-report-echarts-u5ImuZT5.mjs} +9 -3
- package/fesm2022/firestitch-report-echarts-u5ImuZT5.mjs.map +1 -0
- package/fesm2022/{firestitch-report-firestitch-report-Bb65HEYB.mjs → firestitch-report-firestitch-report-Cz-kA_id.mjs} +3213 -613
- package/fesm2022/firestitch-report-firestitch-report-Cz-kA_id.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +8 -0
- package/fesm2022/firestitch-report-echarts-B9nl9XKM.mjs.map +0 -1
- package/fesm2022/firestitch-report-firestitch-report-Bb65HEYB.mjs.map +0 -1
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
|
|
8
|
-
//
|
|
9
|
-
//
|
|
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: ''}
|
|
40
|
-
// config.legend of 'hidden' — still wins, so a caller that
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
616
|
+
nameGap: secondLine ? 40 : 28,
|
|
201
617
|
...periodLabel,
|
|
202
618
|
};
|
|
203
619
|
}
|
|
204
|
-
//
|
|
205
|
-
// cut
|
|
206
|
-
// so the title's gap is measured on exactly the text the axis
|
|
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
|
|
227
|
-
// prints under a period is left out, as it is never the
|
|
228
|
-
|
|
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
|
|
281
|
-
const
|
|
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
|
-
|
|
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
|
|
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}: ${
|
|
776
|
+
return `${category}<br/>${name}: ${amount(step.change)}`;
|
|
339
777
|
}
|
|
340
778
|
const sign = (step.change ?? 0) > 0 ? '+' : '';
|
|
341
|
-
return `${category}<br/>${name}: ${sign}${
|
|
342
|
-
+ `<br/>Running total: ${
|
|
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
|
|
376
|
-
// containLabel does not reserve (it covers the tick labels only).
|
|
377
|
-
function axisGrid(position,
|
|
378
|
-
|
|
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
|
-
|
|
406
|
-
|
|
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
|
|
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
|
|
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,
|
|
428
1024
|
};
|
|
429
1025
|
}
|
|
430
|
-
|
|
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),
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
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,40 +1210,118 @@ export function spansMultipleYears(categories) {
|
|
|
503
1210
|
}
|
|
504
1211
|
return years.size > 1;
|
|
505
1212
|
}
|
|
506
|
-
// A
|
|
507
|
-
//
|
|
508
|
-
|
|
509
|
-
|
|
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
|
|
1257
|
+
return long
|
|
1258
|
+
? `${quarterPrefix(locale)}${quarter} ${year}`
|
|
1259
|
+
: `${quarterPrefix(locale)}${quarter}`;
|
|
520
1260
|
case 'month':
|
|
521
|
-
return
|
|
522
|
-
default: // day, week — the bucket start as a
|
|
523
|
-
return
|
|
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
|
-
//
|
|
527
|
-
//
|
|
528
|
-
|
|
529
|
-
|
|
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
|
|
1282
|
+
return multiYear && periodYearApart(granularity, dateLabel) ? `${parts.primary} ${parts.year}` : parts.primary;
|
|
1283
|
+
}
|
|
1284
|
+
// A cross-tab's column headings, the one rule the grid and the PDF/PowerPoint
|
|
1285
|
+
// exports share. The first is the row key and keeps its authored label; the
|
|
1286
|
+
// rest are pivot VALUES. When the pivot axis is a time dimension the server
|
|
1287
|
+
// sends the grain it bucketed at, so a period-start like "2026-01-01" reads
|
|
1288
|
+
// "January 2026" ('janvier 2026' in fr-CA), as the chart's x-axis labels it.
|
|
1289
|
+
export function pivotHeadings(config, data, locale) {
|
|
1290
|
+
const columns = data.columns ?? [];
|
|
1291
|
+
const multiYear = spansMultipleYears(columns);
|
|
1292
|
+
return columns.map((column, index) => {
|
|
1293
|
+
if (index === 0) {
|
|
1294
|
+
return config.rowBy?.label || column;
|
|
1295
|
+
}
|
|
1296
|
+
return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear, locale) : column;
|
|
1297
|
+
});
|
|
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);
|
|
534
1318
|
}
|
|
535
1319
|
// ECharts category-axis label config for a time bucket: the primary label on
|
|
536
1320
|
// line one, and — only when the data spans multiple years — the year on a small
|
|
537
1321
|
// gray second line, centered under the tick (year granularity needs no second
|
|
538
|
-
// line, it already is the year
|
|
539
|
-
|
|
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) {
|
|
540
1325
|
if (!granularity) {
|
|
541
1326
|
return {};
|
|
542
1327
|
}
|
|
@@ -544,11 +1329,11 @@ function periodAxisLabel(granularity, categories) {
|
|
|
544
1329
|
return {
|
|
545
1330
|
axisLabel: {
|
|
546
1331
|
formatter: (value) => {
|
|
547
|
-
const parts = periodLabelParts(value, granularity);
|
|
1332
|
+
const parts = periodLabelParts(value, granularity, locale, dateLabel);
|
|
548
1333
|
if (!parts) {
|
|
549
1334
|
return value;
|
|
550
1335
|
}
|
|
551
|
-
return multiYear && granularity
|
|
1336
|
+
return multiYear && periodYearApart(granularity, dateLabel)
|
|
552
1337
|
? `${parts.primary}\n{yr|${parts.year}}`
|
|
553
1338
|
: parts.primary;
|
|
554
1339
|
},
|
|
@@ -556,4 +1341,4 @@ function periodAxisLabel(granularity, categories) {
|
|
|
556
1341
|
},
|
|
557
1342
|
};
|
|
558
1343
|
}
|
|
559
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvb3B0aW9uLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXJELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUM5QyxPQUFPLEVBS0wsbUJBQW1CLEdBSXBCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUczRiw4RUFBOEU7QUFDOUUsMkVBQTJFO0FBQzNFLG1FQUFtRTtBQUNuRSxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsc0VBQXNFO0FBQ3RFLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLDRFQUE0RTtBQUM1RSxpQ0FBaUM7QUFDakMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFDOUIsMkVBQTJFO0FBQzNFLDhFQUE4RTtBQUM5RSx5QkFBeUI7QUFDekIsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUM7QUFDckMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLCtFQUErRTtBQUMvRSxzRUFBc0U7QUFDdEUsa0VBQWtFO0FBQ2xFLE1BQU0sZUFBZSxHQUFHLEdBQUcsMkJBQTJCLE1BQU0sd0JBQXdCLEVBQUUsQ0FBQztBQWdCdkYsNkVBQTZFO0FBQzdFLGdGQUFnRjtBQUNoRixzRUFBc0U7QUFDdEUsRUFBRTtBQUNGLGlGQUFpRjtBQUNqRiw4RUFBOEU7QUFDOUUsZ0ZBQWdGO0FBQ2hGLDRF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a0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVqRCxPQUFPO1FBQ0wsU0FBUyxFQUFFO1lBQ1QsU0FBUyxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUU7Z0JBQzNCLE1BQU0sS0FBSyxHQUFHLGdCQUFnQixDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNYLE9BQU8sS0FBSyxDQUFDO2dCQUNmLENBQUM7Z0JBRUQsT0FBTyxTQUFTLElBQUksV0FBVyxLQUFLLE1BQU07b0JBQ3hDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLFNBQVMsS0FBSyxDQUFDLElBQUksR0FBRztvQkFDeEMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDcEIsQ0FBQztZQUNELElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDakU7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgTGVnZW5kQ29tcG9uZW50T3B0aW9uLCBTZXJpZXNPcHRpb24sIFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcyB9IGZyb20gJ2VjaGFydHMnO1xuXG5pbXBvcnQgeyBmb3JtYXQsIGlzVmFsaWQsIHBhcnNlSVNPIH0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBmb3JtYXRNZWFzdXJlVmFsdWUgfSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBBeGlzQ2hhcnRUeXBlLFxuICBDaGFydENvbmZpZyxcbiAgQ2hhcnRHcmFudWxhcml0eSxcbiAgQ29tcG9uZW50RGF0YSxcbiAgR1JBTlVMQVJJVFlfT1BUSU9OUyxcbiAgTGVnZW5kUG9zaXRpb24sXG4gIFJlcG9ydENvbXBvbmVudCxcbiAgV2F0ZXJmYWxsU3RlcEtpbmQsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tICcuL3RleHQnO1xuaW1wb3J0IHsgUkVQT1JUX1dBVEVSRkFMTF9DT0xPUlMgfSBmcm9tICcuL3RoZW1lL3BhbGV0dGUnO1xuaW1wb3J0IHsgUkVQT1JUX0FYSVNfTEFCRUxfRk9OVF9TSVpFLCBSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFkgfSBmcm9tICcuL3RoZW1lL3R5cG9ncmFwaHknO1xuXG5cbi8vIFJvb20gZm9yIHRoZSBjYXRlZ29yeSBheGlzJ3MgdGl0bGUuIEVDaGFydHMgNSdzIGNvbnRhaW5MYWJlbCBrZWVwcyB0aGUgVElDS1xuLy8gbGFiZWxzIGluc2lkZSB0aGUgZ3JpZCBidXQgbm90IHRoZSBheGlzIG5hbWUsIHNvIHdpdGhvdXQgdGhpcyBhIHZlcnRpY2FsXG4vLyBjaGFydCdzIHRpdGxlIHJ1bnMgb2ZmIHRoZSBib3R0b20gZWRnZSBvciB1bmRlciBhIGJvdHRvbSBsZWdlbmQuXG5jb25zdCBBWElTX05BTUVfUk9PTSA9IDIwO1xuLy8gRUNoYXJ0cycgb3duIGRlZmF1bHQgZ2FwIGJldHdlZW4gdGhlIGF4aXMgbGluZSBhbmQgaXRzIHRpY2sgbGFiZWxzLlxuY29uc3QgQVhJU19MQUJFTF9NQVJHSU4gPSA4O1xuLy8gQ2xlYXJhbmNlIGJldHdlZW4gdGhlIGxvbmdlc3QgdGljayBsYWJlbCBhbmQgYSBob3Jpem9udGFsIGNoYXJ0J3Mgcm90YXRlZFxuLy8gdGl0bGUsIHNvIHRoZSB0d28gbmV2ZXIgdG91Y2guXG5jb25zdCBBWElTX05BTUVfQ0xFQVJBTkNFID0gNjtcbi8vIEEgaG9yaXpvbnRhbCBjaGFydCdzIGNhdGVnb3J5IGxhYmVscyBhcmUgY3V0IHNob3J0IHdpdGggYW4gZWxsaXBzaXMgcGFzdFxuLy8gdGhpcyB3aWR0aCAodGhlIHRvb2x0aXAgc3RpbGwgc2hvd3MgdGhlbSBpbiBmdWxsKSwgc28gb25lIGxvbmcgbGFiZWwgY2Fubm90XG4vLyBzcXVlZXplIHRoZSBwbG90IGF3YXkuXG5jb25zdCBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEggPSAxNjA7XG5jb25zdCBMQUJFTF9FTExJUFNJUyA9ICfigKYnO1xuLy8gVGhlIGZvbnQgdGhlIHRoZW1lIGRyYXdzIGF4aXMgbGFiZWxzIGluLCBhcyBhIGNhbnZhcyBmb250IHN0cmluZy4gTGFiZWxzIGFyZVxuLy8gbWVhc3VyZWQgaW4gaXQgdGhlIHdheSBFQ2hhcnRzIG1lYXN1cmVzIHRoZW0gZm9yIGNvbnRhaW5MYWJlbCwgc28gYVxuLy8gaG9yaXpvbnRhbCBjaGFydCdzIHRpdGxlIGxhbmRzIGV4YWN0bHkgYmV5b25kIHRoZSB3aWRlc3QgbGFiZWwuXG5jb25zdCBBWElTX0xBQkVMX0ZPTlQgPSBgJHtSRVBPUlRfQVhJU19MQUJFTF9GT05UX1NJWkV9cHggJHtSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFl9YDtcblxuLy8gV2hpY2ggZWRnZSBvZiB0aGUgcGxvdCB0aGUgY2F0ZWdvcnkgYXhpcydzIHRpdGxlIHNpdHMgb246IGJlbG93IGEgdmVydGljYWxcbi8vIGNoYXJ0LCB0byB0aGUgbGVmdCBvZiBhIGhvcml6b250YWwgb25lLlxudHlwZSBBeGlzVGl0bGVTaWRlID0gJ2JvdHRvbScgfCAnbGVmdCc7XG5cbi8vIFRoZSBwbG90J3MgZGlzdGFuY2UgZnJvbSBlYWNoIGVkZ2Ugb2YgdGhlIGNoYXJ0LCBpbiBwaXhlbHMuXG5pbnRlcmZhY2UgQXhpc0dyaWRSb29tIHtcbiAgbGVmdDogbnVtYmVyO1xuICByaWdodDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIGNvbnRhaW5MYWJlbDogYm9vbGVhbjtcbn1cblxuXG4vLyBjb2xvckJ5IGFwcGxpZXMgb25seSB0byBzaW5nbGUtZGltZW5zaW9uIGJhciBjaGFydHMsIGFuZCBvbmx5IHdoZW4gc3BsaXRCeVxuLy8gaXNuJ3QgYWxyZWFkeSBkcml2aW5nIG11bHRpcGxlIHNlcmllczogaXQgY29sb3JzIGVhY2ggYmFyIGJ5IGl0cyBjYXRlZ29yeSBhbmRcbi8vIHNob3dzIGEgbGVnZW5kIChvbmUgc2VyaWVzIHBlciBjYXRlZ29yeSwgb3ZlcmxhcHBlZCB0byBmdWxsIHdpZHRoKS5cbi8vXG4vLyBJdCBpcyB0aGUgREVGQVVMVCBmb3IgYSBjYXRlZ29yaWNhbCBiYXIgY2hhcnQgcmF0aGVyIHRoYW4gc29tZXRoaW5nIHRoZSBjb25maWdcbi8vIGhhcyB0byBhc2sgZm9yLiBBIGJhciBjaGFydCB3aG9zZSB4LWF4aXMgaXMgYSBjYXRlZ29yeSDigJQgcmVnaW9ucywgc3RhdHVzZXMsXG4vLyBzdG9yZXMg4oCUIGlzIGNvbXBhcmluZyB0aG9zZSBjYXRlZ29yaWVzIHRvIGVhY2ggb3RoZXIsIGFuZCBvbmUgZmxhdCBjb2xvciB3aXRoXG4vLyBubyBsZWdlbmQgaXMgdGhlIHdyb25nIHJlYWRpbmcgb2YgaXQgaW4gZXNzZW50aWFsbHkgZXZlcnkgY2FzZS4gUmVxdWlyaW5nXG4vLyBjb2xvckJ5IHRvIG9wdCBpbiBtZWFudCBldmVyeSBzdWNoIGNoYXJ0IHJlbmRlcmVkIG1vbm9jaHJvbWUgdW5sZXNzIHdob2V2ZXJcbi8vIHdyb3RlIHRoZSBjb25maWcgcmVtZW1iZXJlZCBhbiBvcHRpb25hbCBwcm9wZXJ0eSwgd2hpY2ggaXMgYSBkZWZhdWx0IHNldCB0aGVcbi8vIHdyb25nIHdheSByb3VuZDogdGhlIGNvbW1vbiBjYXNlIHNob3VsZCBub3QgbmVlZCB0aGUgZmxhZy5cbi8vXG4vLyBBIFRJTUUgYXhpcyBpcyBleGNsdWRlZDogY29uc2VjdXRpdmUgcGVyaW9kcyBhcmUgb25lIHNlcmllcyBtb3ZpbmcsIG5vdFxuLy8gY2F0ZWdvcmllcyBiZWluZyBjb21wYXJlZCwgYW5kIGNvbG9yaW5nIGVhY2ggbW9udGggZGlmZmVyZW50bHkgcmVhZHMgYXNcbi8vIHVucmVsYXRlZCBncm91cHMuIEV4cGxpY2l0bHkgb3B0aW5nIG91dCDigJQgY29sb3JCeToge2NvbHVtbjogJyd9IG9yIGFcbi8vIGNvbmZpZy5sZWdlbmQgb2YgJ2hpZGRlbicg4oCUIHN0aWxsIHdpbnMsIHNvIGEgY2FsbGVyIHRoYXQgd2FudHMgb25lIGZsYXQgY29sb3Jcbi8vIGNhbiBzYXkgc28uXG4vL1xuLy8gXCJCYXIgY2hhcnRcIiBpcyB0aGUgdHlwZSB0aGUgbG9uZSBtZWFzdXJlIGlzIGFjdHVhbGx5IERSQVdOIGFzOiBpdHMgb3duIHR5cGVcbi8vIHdoZW4gaXQgbmFtZXMgb25lLCB3aGljaCBjYW4gdHVybiBhIGxpbmUgY2hhcnQncyBzaW5nbGUgc2VyaWVzIGludG8gYmFycyBvclxuLy8gYSBiYXIgY2hhcnQncyBpbnRvIGEgbGluZS5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yQnkoY29uZmlnOiBDaGFydENvbmZpZyk6IGJvb2xlYW4ge1xuICBpZiAoY29uZmlnLnNwbGl0Qnk/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+KCk7XG4gIGNvbnN0IHZhbHVlczogdW5rbm93bltdID0gW107XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHJvd1tjb2x1bW5dO1xuICAgIGlmICghc2Vlbi5oYXModmFsdWUpKSB7XG4gICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuZnVuY3Rpb24gbnVtZXJpYyh2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IG51bGwge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG5cbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShwYXJzZWQpID8gcGFyc2VkIDogbnVsbDtcbn1cblxuLy8gVGhlIGVmZmVjdGl2ZSB0aW1lIGJ1Y2tldCB0aGUgcm93cyB3ZXJlIGdyb3VwZWQgaW50byAoZnJvbSB0aGUgZGF0YSBlbmRwb2ludCksXG4vLyBvciBudWxsIHdoZW4gdGhlIHgtYXhpcyBpc24ndCBhIHRpbWUgYXhpcyDigJQgZ2F0ZXMgdGhlIGNvbXBhY3QgcGVyaW9kIGxhYmVscy5cbmZ1bmN0aW9uIGJ1Y2tldEdyYW51bGFyaXR5KGRhdGE6IENvbXBvbmVudERhdGEpOiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCB7XG4gIHJldHVybiBkYXRhLmdyYW51bGFyaXR5ICYmIEdSQU5VTEFSSVRZX09QVElPTlMuc29tZSgob3B0aW9uKSA9PiBvcHRpb24udmFsdWUgPT09IGRhdGEuZ3JhbnVsYXJpdHkpXG4gICAgPyBkYXRhLmdyYW51bGFyaXR5XG4gICAgOiBudWxsO1xufVxuXG4vLyBXaGV0aGVyIHRoZSBwZXJpb2Qtc3RhcnQgY2F0ZWdvcmllcyBjcm9zcyBhIHllYXIgYm91bmRhcnkuIFdoZW4gdGhleSBkb24ndCxcbi8vIHRoZSB5ZWFyIGlzIHB1cmUgbm9pc2Ugb24gZXZlcnkgbGFiZWwsIHNvIGl0J3MgZHJvcHBlZCBlbnRpcmVseS5cbmV4cG9ydCBmdW5jdGlvbiBzcGFuc011bHRpcGxlWWVhcnMoY2F0ZWdvcmllczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgY29uc3QgeWVhcnMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBjYXRlZ29yaWVzKSB7XG4gICAgY29uc3QgZGF0ZSA9IHBhcnNlSVNPKGNhdGVnb3J5KTtcbiAgICBpZiAoaXNWYWxpZChkYXRlKSkge1xuICAgICAgeWVhcnMuYWRkKGRhdGUuZ2V0RnVsbFllYXIoKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHllYXJzLnNpemUgPiAxO1xufVxuXG4vLyBBIGJ1Y2tldCdzIHBlcmlvZC1zdGFydCBzcGxpdCBpbnRvIGl0cyBwcmltYXJ5IGxhYmVsIGFuZCBpdHMgeWVhci4gRGF5L3dlZWtcbi8vIHJlYWQgYXMgXCJNYXkgMVwiLCBtb250aCBhcyBcIk1heVwiLCBxdWFydGVyIGFzIFwiUTJcIiwgeWVhciBhcyBcIjIwMjVcIi4gUmV0dXJucyBudWxsXG4vLyBmb3IgYSB2YWx1ZSB0aGF0IGlzbid0IGEgcGFyc2VhYmxlIGRhdGUgKGxlZnQgYXMtaXMgYnkgY2FsbGVycykuXG5mdW5jdGlvbiBwZXJpb2RMYWJlbFBhcnRzKHZhbHVlOiBzdHJpbmcsIGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5KTogeyBwcmltYXJ5OiBzdHJpbmc7IHllYXI6IHN0cmluZyB9IHwgbnVsbCB7XG4gIGNvbnN0IGRhdGUgPSBwYXJzZUlTTyh2YWx1ZSk7XG4gIGlmICghaXNWYWxpZChkYXRlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgeWVhciA9IFN0cmluZyhkYXRlLmdldEZ1bGxZZWFyKCkpO1xuICBzd2l0Y2ggKGdyYW51bGFyaXR5KSB7XG4gICAgY2FzZSAneWVhcic6XG4gICAgICByZXR1cm4geyBwcmltYXJ5OiB5ZWFyLCB5ZWFyIH07XG4gICAgY2FzZSAncXVhcnRlcic6XG4gICAgICByZXR1cm4geyBwcmltYXJ5OiBgUSR7TWF0aC5mbG9vcihkYXRlLmdldE1vbnRoKCkgLyAzKSArIDF9YCwgeWVhciB9O1xuICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgIHJldHVybiB7IHByaW1hcnk6IGZvcm1hdChkYXRlLCAnTU1NTScpLCB5ZWFyIH07XG4gICAgZGVmYXVsdDogLy8gZGF5LCB3ZWVrIOKAlCB0aGUgYnVja2V0IHN0YXJ0IGFzIGEgY29tcGFjdCBcIk1NTSBkXCJcbiAgICAgIHJldHVybiB7IHByaW1hcnk6IGZvcm1hdChkYXRlLCAnTU1NIGQnKSwgeWVhciB9O1xuICB9XG59XG5cbi8vIEEgY29tcGFjdCBzaW5nbGUtbGluZSBwZXJpb2QgbGFiZWwgKHllYXIgYXBwZW5kZWQgb25seSB3aGVuIHRoZSBkYXRhIHNwYW5zXG4vLyB5ZWFycykg4oCUIGZvciBtZWRpYSB0aGF0IGNhbid0IGRvIGEgc3R5bGVkIHNlY29uZCBsaW5lLCBlLmcuIFBvd2VyUG9pbnQuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UGVyaW9kTGFiZWwodmFsdWU6IHN0cmluZywgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHksIG11bHRpWWVhcjogYm9vbGVhbik6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnRzID0gcGVyaW9kTGFiZWxQYXJ0cyh2YWx1ZSwgZ3JhbnVsYXJpdHkpO1xuICBpZiAoIXBhcnRzKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG11bHRpWWVhciAmJiBncmFudWxhcml0eSAhPT0gJ3llYXInID8gYCR7cGFydHMucHJpbWFyeX0gJHtwYXJ0cy55ZWFyfWAgOiBwYXJ0cy5wcmltYXJ5O1xufVxuXG4vLyBFQ2hhcnRzIGNhdGVnb3J5LWF4aXMgbGFiZWwgY29uZmlnIGZvciBhIHRpbWUgYnVja2V0OiB0aGUgcHJpbWFyeSBsYWJlbCBvblxuLy8gbGluZSBvbmUsIGFuZCDigJQgb25seSB3aGVuIHRoZSBkYXRhIHNwYW5zIG11bHRpcGxlIHllYXJzIOKAlCB0aGUgeWVhciBvbiBhIHNtYWxsXG4vLyBncmF5IHNlY29uZCBsaW5lLCBjZW50ZXJlZCB1bmRlciB0aGUgdGljayAoeWVhciBncmFudWxhcml0eSBuZWVkcyBubyBzZWNvbmRcbi8vIGxpbmUsIGl0IGFscmVhZHkgaXMgdGhlIHllYXIpLiBFbXB0eSBmb3IgYSBub24tdGltZSBheGlzIChsYWJlbHMgYXMtaXMpLlxuZnVuY3Rpb24gcGVyaW9kQXhpc0xhYmVsKGdyYW51bGFyaXR5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCwgY2F0ZWdvcmllczogc3RyaW5nW10pOiB7IGF4aXNMYWJlbD86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0ge1xuICBpZiAoIWdyYW51bGFyaXR5KSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgbXVsdGlZZWFyID0gc3BhbnNNdWx0aXBsZVllYXJzKGNhdGVnb3JpZXMpO1xuXG4gIHJldHVybiB7XG4gICAgYXhpc0xhYmVsOiB7XG4gICAgICBmb3JtYXR0ZXI6ICh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcnRzID0gcGVyaW9kTGFiZWxQYXJ0cyh2YWx1ZSwgZ3JhbnVsYXJpdHkpO1xuICAgICAgICBpZiAoIXBhcnRzKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG11bHRpWWVhciAmJiBncmFudWxhcml0eSAhPT0gJ3llYXInXG4gICAgICAgICAgPyBgJHtwYXJ0cy5wcmltYXJ5fVxcbnt5cnwke3BhcnRzLnllYXJ9fWBcbiAgICAgICAgICA6IHBhcnRzLnByaW1hcnk7XG4gICAgICB9LFxuICAgICAgcmljaDogeyB5cjogeyBmb250U2l6ZTogMTAsIGNvbG9yOiAnIzlhYTBhNicsIGxpbmVIZWlnaHQ6IDE0IH0gfSxcbiAgICB9LFxuICB9O1xufVxuIl19
|
|
1344
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvb3B0aW9uLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFN0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDNUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDNUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDaEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUNMLGdCQUFnQixFQUVoQixjQUFjLEVBQ2QsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixTQUFTLEVBQ1QsVUFBVSxFQUNWLFVBQVUsRUFDVix3QkFBd0IsR0FDekIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQVFMLG1CQUFtQixHQVNwQixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLHVCQUF1QixHQUN4QixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSx3QkFBd0IsRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3hILGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLHlEQUF5RDtBQUN6RCxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsc0VBQXNFO0FBQ3RFLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLDRFQUE0RTtBQUM1RSxpQ0FBaUM7QUFDakMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFDOUIsMkVBQTJFO0FBQzNFLDhFQUE4RTtBQUM5RSx5QkFBeUI7QUFDekIsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUM7QUFDckMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUFDO0FBQzNCLCtFQUErRTtBQUMvRSxzRUFBc0U7QUFDdEUsa0VBQWtFO0FBQ2xFLE1BQU0sZUFBZSxHQUFHLEdBQUcsMkJBQTJCLE1BQU0sd0JBQXdCLEVBQUUsQ0FBQztBQUN2RixnRkFBZ0Y7QUFDaEYsb0VBQW9FO0FBQ3BFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQWlCLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hFLE1BQU0sY0FBYyxHQUFHLEdBQUcsQ0FBQztBQUMzQiw4RUFBOEU7QUFDOUUsMkRBQTJEO0FBQzNELE1BQU0sbUJBQW1CLEdBQXFCLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDbEcsTUFBTSxvQkFBb0IsR0FBcUIsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNuRyxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDbEMsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDO0FBQzFDLDZFQUE2RTtBQUM3RSxpQ0FBaUM7QUFDakMsTUFBTSxtQkFBbUIsR0FBRyx5QkFBeUIsQ0FBQztBQUN0RCwyRUFBMkU7QUFDM0UsNkNBQTZDO0FBQzdDLE1BQU0sY0FBYyxHQUFHLEVBQUUsZUFBZSxFQUFFLDJCQUEyQixFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDMUcsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQztBQUVoQywyRUFBMkU7QUFDM0Usd0VBQXdFO0FBQ3hFLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBd0M7SUFDN0QsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxTQUFTO0lBQ3hDLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUTtJQUN0QyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxFQUFFLFNBQVM7SUFDcEMsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxTQUFTO0NBQ3JDLENBQUM7QUErSEYsNkVBQTZFO0FBQzdFLGdGQUFnRjtBQUNoRixzRUFBc0U7QUFDdEUsRUFBRTtBQUNGLGlGQUFpRjtBQUNqRiw4RUFBOEU7QUFDOUUsZ0ZBQWdGO0FBQ2hGLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDZEQUE2RDtBQUM3RCxFQUFFO0FBQ0YsMEVBQTBFO0FBQzFFLDBFQUEwRTtBQUMxRSw4RUFBOEU7QUFDOUUsNEVBQTRFO0FBQzVFLG1DQUFtQztBQUNuQyxFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLDhFQUE4RTtBQUM5RSw2QkFBNkI7QUFDN0IsTUFBTSxVQUFVLFNBQVMsQ0FBQyxNQUFtQjtJQUMzQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxNQUFNLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQ2xHLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25CLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQ2pDLENBQUM7SUFFRCx5REFBeUQ7SUFDekQsSUFBSSxlQUFlLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMxQyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLElBQUksVUFBVSxDQUFDLEtBQUssVUFBVTtXQUNuRCxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVztXQUMxQixDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBR0QsOEVBQThFO0FBQzlFLHNDQUFzQztBQUN0QyxNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQW1CO0lBQy9DLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUN0QixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQztRQUNsRCxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2hCLENBQUM7QUEyQkQsTUFBTSxVQUFVLGtCQUFrQixDQUFDLFNBQTBCLEVBQUUsSUFBbUI7SUFDaEYsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQXFCLENBQUM7SUFDL0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4RCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQztJQUMzQyx5RUFBeUU7SUFDekUsc0VBQXNFO0lBQ3RFLCtFQUErRTtJQUMvRSxNQUFNLFdBQVcsR0FBRyxXQUFXLElBQUksYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pELE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFN0MsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkQsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sTUFBTSxHQUFtQyxFQUFFLENBQUM7SUFFbEQsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixnRkFBZ0Y7UUFDaEYsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLEtBQUssTUFBTSxVQUFVLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUM5RCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztZQUMvQyxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ3BDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDcEQsQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNWLElBQUksRUFBRSxNQUFNLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQztnQkFDL0IsTUFBTSxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQzFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsT0FBTztnQkFDUCxZQUFZLEVBQUUsQ0FBQzthQUNoQixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixLQUFLLE1BQU0sQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDekQsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7WUFDL0MsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzVCLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDVixJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsTUFBTTtnQkFDckMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQzFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsT0FBTztnQkFDUCxZQUFZO2FBQ2IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBQ2hDLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLG1CQUFtQjtBQUNuQixNQUFNLFVBQVUsV0FBVyxDQUFDLE1BQWdDO0lBQzFELE1BQU0sR0FBRyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVsQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3JDLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLE1BQU0sVUFBVSxTQUFTLENBQUMsTUFBZ0MsRUFBRSxLQUFhO0lBQ3ZFLE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLG1CQUFtQixDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMxRixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsTUFBZ0M7SUFDckQsT0FBTyxlQUFlLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsMEVBQTBFO0FBQzFFLG1FQUFtRTtBQUNuRSxTQUFTLGVBQWUsQ0FBQyxPQUFpQztJQUN4RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRXRGLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQy9ELENBQUM7QUFFRCw2RUFBNkU7QUFDN0UscUJBQXFCO0FBQ3JCLE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUFpQztJQUNoRSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdEYsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSwrQkFBK0I7QUFDL0IsTUFBTSxVQUFVLGVBQWUsQ0FBQyxPQUFpQztJQUMvRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDdkYsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSx5RUFBeUU7QUFDekUseUVBQXlFO0FBQ3pFLG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsVUFBVSxDQUFDLE1BQXlCLEVBQUUsSUFBeUI7SUFDN0UsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBbUIsRUFBRSxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFL0csSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ2IsS0FBSyxtQkFBbUIsQ0FBQyxPQUFPO1lBQzlCLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUN6RSxLQUFLLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDaEMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFN0MsT0FBTyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3hGLENBQUM7UUFDRCxLQUFLLG1CQUFtQixDQUFDLEdBQUc7WUFDMUIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDOUIsS0FBSyxtQkFBbUIsQ0FBQyxHQUFHO1lBQzFCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBQzlCO1lBQ0UsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztBQUNILENBQUM7QUFFRCx5RUFBeUU7QUFDekUsd0VBQXdFO0FBQ3hFLGtDQUFrQztBQUNsQyxNQUFNLFVBQVUsY0FBYyxDQUFDLE1BQW1CO0lBQ2hELE9BQU8sTUFBTSxDQUFDLFdBQVcsS0FBSyxZQUFZLENBQUM7QUFDN0MsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSwwRUFBMEU7QUFDMUUsYUFBYTtBQUNiLE1BQU0sVUFBVSxhQUFhLENBQUMsU0FBK0I7SUFDM0QsT0FBTyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQ2hHLENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLG9EQUFvRDtBQUNwRCxNQUFNLFVBQVUsZUFBZSxDQUFDLE1BQW1CLEVBQUUsT0FBZ0I7SUFDbkUsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7SUFDNUMsTUFBTSxVQUFVLEdBQTBDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFcEgsSUFBSSxNQUFNLENBQUMsV0FBVyxLQUFLLFlBQVksSUFBSSxTQUFTLEtBQUssS0FBSyxJQUFJLFNBQVMsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUN4RixPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQW9CLEVBQUU7UUFDeEQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUUzQyxJQUFJLENBQUMsU0FBUyxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0QyxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sS0FBSyxHQUFHLE9BQU8sU0FBUyxDQUFDLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN6RSxNQUFNLFNBQVMsR0FBbUIsT0FBTyxJQUFJLFNBQVMsQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVsRixPQUFPLENBQUMsRUFBRSxLQUFLLFNBQVMsSUFBSSxFQUFFLEtBQUssS0FBSztnQkFDdEMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7Z0JBQ3ZGLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELHNFQUFzRTtBQUN0RSx1RUFBdUU7QUFDdkUseUVBQXlFO0FBQ3pFLDBFQUEwRTtBQUMxRSw2RUFBNkU7QUFDN0UsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBMkI7SUFDdkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNyRSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxNQUFNO1NBQ3ZELE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRW5FLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQ3pELEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FDaEUsQ0FBQyxDQUFDLENBQUM7QUFDTixDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDBFQUEwRTtBQUMxRSwwRUFBMEU7QUFDMUUsOEVBQThFO0FBQzlFLDJFQUEyRTtBQUMzRSw4RUFBOEU7QUFDOUUsTUFBTSxVQUFVLG9CQUFvQixDQUFDLFNBQStCLEVBQUUsTUFBbUI7SUFDdkYsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7SUFFNUMsSUFBSSxNQUFNLENBQUMsY0FBYyxLQUFLLElBQUk7V0FDN0IsU0FBUyxLQUFLLEtBQUssSUFBSSxTQUFTLEtBQUssT0FBTyxJQUFJLFNBQVMsS0FBSyxXQUFXO1dBQ3pFLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDaEQsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3pELE1BQU0sTUFBTSxHQUFrQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXhDLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFVLEVBQUUsQ0FBQztRQUM1QyxNQUFNLE9BQU8sR0FBRyxLQUFLO2FBQ2xCLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsVUFBVSxLQUFLLElBQUksSUFBSSxXQUFXLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDMUYsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDakMsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN6RixPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1RixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNyQyxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDBCQUEwQjtBQUMxQixNQUFNLFVBQVUsY0FBYyxDQUFDLE1BQXFCO0lBQ2xELE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsRyxDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLHVCQUF1QjtBQUN2QixTQUFTLGFBQWEsQ0FBQyxNQUFtQixFQUFFLElBQW1CO0lBQzdELE9BQU8sTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNO1FBQzVCLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUTtRQUNqQixDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLCtFQUErRTtBQUMvRSxnRkFBZ0Y7QUFDaEYsZ0JBQWdCO0FBQ2hCLE1BQU0sVUFBVSxXQUFXLENBQUMsU0FBK0IsRUFBRSxTQUF3QjtJQUNuRixPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDJFQUEyRTtBQUMzRSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDZFQUE2RTtBQUM3RSxNQUFNLFVBQVUsaUJBQWlCLENBQUMsU0FBK0IsRUFBRSxNQUFtQjtJQUNwRixNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0UsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFdBQVcsS0FBSyxZQUFZLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRTdHLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQWlCRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxPQUFPLENBQUM7QUFFN0MsZ0ZBQWdGO0FBQ2hGLDBFQUEwRTtBQUMxRSx5RUFBeUU7QUFDekUsdURBQXVEO0FBQ3ZELE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxTQUEwQixFQUFFLElBQW1CO0lBQzlFLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN0RCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFDakQsTUFBTSxLQUFLLEdBQW9CLEVBQUUsQ0FBQztJQUNsQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFFZCxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsRUFBRTtRQUMvQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDO1FBQ3JDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLEtBQUssSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRSxxQkFBcUIsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFFeEYsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDMUQsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLGFBQWE7QUFDYixFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsOEVBQThFO0FBQzlFLHdDQUF3QztBQUN4QyxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLFNBQTBCLEVBQzFCLElBQW1CLEVBQ25CLE9BQTRCO0lBRTVCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFxQixDQUFDO0lBQy9DLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDO0lBRTVDLElBQUksU0FBUyxLQUFLLEtBQUssSUFBSSxTQUFTLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDakQsT0FBTyxjQUFjLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEtBQUssT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxJQUFJLFNBQVMsS0FBSyxXQUFXLEVBQUUsQ0FBQztRQUM5QixPQUFPLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELE9BQU8sZUFBZSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FDdEIsU0FBMEIsRUFDMUIsSUFBbUIsRUFDbkIsU0FBd0IsRUFDeEIsT0FBNEI7SUFFNUIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQXFCLENBQUM7SUFDL0MsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxXQUFXLEtBQUssWUFBWSxDQUFDO0lBQ3ZELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQyxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7SUFFdEMsK0VBQStFO0lBQy9FLDJFQUEyRTtJQUMzRSwrRUFBK0U7SUFDL0UsMkRBQTJEO0lBQzNELEVBQUU7SUFDRiw2RUFBNkU7SUFDN0UsNkVBQTZFO0lBQzdFLHdFQUF3RTtJQUN4RSwwQkFBMEI7SUFDMUIsRUFBRTtJQUNGLHlFQUF5RTtJQUN6RSw2RUFBNkU7SUFDN0UsK0JBQStCO0lBQy9CLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6RCxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN2RCxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3BELE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3BHLDJFQUEyRTtJQUMzRSwwRUFBMEU7SUFDMUUsNkRBQTZEO0lBQzdELE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUNyRCxNQUFNLE1BQU0sR0FBbUIsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxlQUFlLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDN0UsTUFBTSxZQUFZLEdBQUcsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4QyxJQUFJLEtBQXlCLENBQUM7UUFDOUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0MsQ0FBQzthQUFNLElBQUksTUFBTSxDQUFDLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3JDLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEYsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzlFLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxZQUFZLENBQ25DLFlBQVksSUFBSSxlQUFlLENBQUMsTUFBTSxFQUN0QyxJQUFJLEVBQ0osWUFBWSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUN0RixDQUFDO1FBQ0YsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUN4QixlQUFlLEVBQ2YsWUFBWSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFDdkY7WUFDRSxJQUFJLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQztZQUNsQixLQUFLO1lBQ0wsT0FBTyxFQUFFLE9BQU8sSUFBSSxLQUFLLEtBQUssQ0FBQztZQUMvQixLQUFLO1lBQ0wsT0FBTyxFQUFFLGFBQWEsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztZQUN4RCxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDbkQsNkRBQTZEO1lBQzdELGdEQUFnRDtZQUNoRCxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUM7WUFDekQsTUFBTSxFQUFFLGVBQWUsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLGtCQUFrQixDQUMzRCxlQUFlLENBQUMsT0FBTyxFQUN2QixXQUFXLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxFQUN2QyxDQUFDLENBQUMsWUFBWSxFQUNkLE9BQU8sQ0FDUixDQUFDO1NBQ0gsQ0FDRixDQUFDO1FBRUYsT0FBTyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsUUFBUSxFQUFrQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDckUsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLE9BQU8sSUFBSSxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3ZELE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMvRCxNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4RyxNQUFNLFNBQVMsR0FBRyxPQUFPO1FBQ3ZCLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDO1FBQzFFLENBQUMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxLQUFLLFNBQVM7WUFDdEUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFdkYsTUFBTSxjQUFjLEdBQUcscUJBQXFCLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0UsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkYsTUFBTSxXQUFXLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFNUMsT0FBTztRQUNMLElBQUksRUFBRSxRQUFRLENBQUMsY0FBYyxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxjQUFjLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzlHLE1BQU0sRUFBRSxlQUFlLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUM7UUFDekUsNkVBQTZFO1FBQzdFLHFFQUFxRTtRQUNyRSx1RUFBdUU7UUFDdkUsT0FBTyxFQUFFLE1BQU07WUFDYixDQUFDLENBQUM7Z0JBQ0EsT0FBTyxFQUFFLE1BQU07Z0JBQ2YsU0FBUyxFQUFFLENBQUMsTUFBK0MsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUM1RSxNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sRUFDTixXQUFXLEVBQ1gsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUN0QixPQUFPLENBQ1I7YUFDRjtZQUNELENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFO1FBQzFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWTtRQUM1QyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDNUMsTUFBTSxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQzVFLENBQUM7QUFDSixDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLDRFQUE0RTtBQUM1RSx5QkFBeUI7QUFDekIsU0FBUyxlQUFlLENBQ3RCLEtBQW1CLEVBQ25CLFNBQStCLEVBQy9CLE9BQTRCO0lBRTVCLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDO0lBQzdDLE1BQU0sSUFBSSxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLElBQUksWUFBWSxDQUNuQyxhQUFhLENBQUMsU0FBUyxDQUFDLEVBQ3hCLElBQUksRUFDSixhQUFhLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUMvQixJQUFJLHNCQUFzQixFQUFFLENBQzdCLENBQUM7SUFFRixPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxRQUFRLEVBQWtCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztBQUNuRSxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLDZFQUE2RTtBQUM3RSxrREFBa0Q7QUFDbEQsU0FBUyxZQUFZLENBQ25CLE1BQXlCLEVBQ3pCLElBQXlCLEVBQ3pCLEtBQWdDLEVBQ2hDLEtBQWM7SUFFZCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRXZDLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ25CLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztJQUVwRCxPQUFPO1FBQ0wsTUFBTSxFQUFFLElBQUk7UUFDWixNQUFNLEVBQUUsTUFBTTtRQUNkLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFpQixFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7UUFDN0UsS0FBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsY0FBdUIsRUFBRSxRQUFRLEVBQUUsMkJBQTJCLEVBQUUsR0FBRyxjQUFjLEVBQUU7UUFDN0gsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7S0FDekIsQ0FBQztBQUNKLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsU0FBUyxhQUFhLENBQUMsT0FBaUMsRUFBRSxPQUE0QjtJQUNwRixPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLE9BQU87QUFDUCxTQUFTLFdBQVcsQ0FBQyxPQUE0QjtJQUMvQyxNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsT0FBTyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUV4RCxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLG9CQUFvQixFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzVFLENBQUM7QUFFRCwwRUFBMEU7QUFDMUUsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsK0VBQStFO0FBQy9FLGlDQUFpQztBQUNqQyxFQUFFO0FBQ0YsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3RSwwRUFBMEU7QUFDMUUsOEVBQThFO0FBQzlFLDRCQUE0QjtBQUM1QixTQUFTLGlCQUFpQixDQUFDLFVBQTRCLEVBQUUsVUFBb0I7SUFDM0UsTUFBTSxLQUFLLEdBQUcsSUFBSSxzQkFBc0IsRUFBRSxDQUFDO0lBRTNDLE9BQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFrQixFQUFFO1FBQzdELE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDbkYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbkIsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsT0FBTyxDQUFDO2dCQUNOLElBQUksRUFBRSxNQUFNO2dCQUNaLElBQUksRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDaEMsVUFBVSxFQUFFLFNBQVM7Z0JBQ3JCLE1BQU0sRUFBRSxJQUFJO2dCQUNaLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7Z0JBQ3hCLFFBQVEsRUFBRTtvQkFDUixNQUFNLEVBQUUsSUFBSTtvQkFDWixNQUFNLEVBQUUsTUFBTTtvQkFDZCxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFO29CQUM5QyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsMkJBQTJCLEVBQUUsR0FBRyxjQUFjLEVBQUU7b0JBQ3BHLElBQUksRUFBRTt3QkFDSixHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDcEcsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDOzRCQUMzQixLQUFLLEVBQUUsU0FBUyxDQUFDLElBQUk7NEJBQ3JCLDZEQUE2RDs0QkFDN0Qsa0JBQWtCOzRCQUNsQixTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFOzRCQUN2QixLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7eUJBQzNFLENBQUMsQ0FBQztxQkFDSjtpQkFDRjtnQkFDRCxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7b0JBQ2pCLFFBQVEsRUFBRTt3QkFDUixNQUFNLEVBQUUsSUFBSTt3QkFDWixTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsbUJBQW1CLEVBQUU7d0JBQ3pDLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDdEY7aUJBQ0YsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQ1EsQ0FBQyxDQUFDO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELDBFQUEwRTtBQUMxRSwwRUFBMEU7QUFDMUUsWUFBWTtBQUNaLE1BQU0sVUFBVSxhQUFhLENBQUMsVUFBNEIsRUFBRSxTQUF5QjtJQUNuRixNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBRXBELE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RSxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLDhFQUE4RTtBQUM5RSxPQUFPO0FBQ1AsU0FBUyxlQUFlLENBQ3RCLE1BQTZCLEVBQzdCLE1BQXNCLEVBQ3RCLFVBQTRCO0lBRTVCLE9BQU8sVUFBVSxDQUFDLE1BQU07UUFDdEIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUU7UUFDcEUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNiLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsUUFBUTtBQUNSLFNBQVMsY0FBYyxDQUFDLFVBQTRCLEVBQUUsU0FBeUI7SUFDN0UsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUVuRixPQUFPLE1BQU0sQ0FBQyxNQUFNO1FBQ2xCLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRTtRQUM5SCxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2hCLENBQUM7QUFFRCxzRUFBc0U7QUFDdEUsOEVBQThFO0FBQzlFLDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsTUFBTTtBQUNOLFNBQVMsUUFBUSxDQUFDLEtBQWlDO0lBQ2pELE9BQU8sS0FBSztRQUNWLENBQUMsQ0FBQyxDQUFDLE1BQWtCLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDMUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsS0FBaUM7SUFDakQsT0FBTyxLQUFLO1FBQ1YsQ0FBQyxDQUFDLENBQUMsTUFBa0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzFHLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDaEIsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSxxREFBcUQ7QUFDckQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDNUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO0FBRTVCLFNBQVMsZUFBZSxDQUFDLFNBQWlCO0lBQ3hDLE1BQU0sTUFBTSxHQUFHLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQztJQUM5QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsR0FBRyxLQUFLLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRXRHLHVFQUF1RTtJQUN2RSx1QkFBdUI7SUFDdkIsT0FBTyxNQUFNLENBQUMsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSxpRUFBaUU7QUFDakUsRUFBRTtBQUNGLGdGQUFnRjtBQUNoRiwrRUFBK0U7QUFDL0UsK0VBQStFO0FBQy9FLHFFQUFxRTtBQUNyRSxFQUFFO0FBQ0YsOEVBQThFO0FBQzlFLGdGQUFnRjtBQUNoRiw2RUFBNkU7QUFDN0UsMEVBQTBFO0FBQzFFLFNBQVMsa0JBQWtCLENBQ3pCLE1BQW1CLEVBQ25CLElBQW1CLEVBQ25CLFVBQW9CLEVBQ3BCLFVBQW1CLEVBQ25CLE1BQXVCO0lBRXZCLE1BQU0sV0FBVyxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVDLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6QyxNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDaEYsTUFBTSxJQUFJLEdBQUc7UUFDWCxJQUFJLEVBQUUsVUFBbUI7UUFDekIsSUFBSSxFQUFFLFVBQVU7UUFDaEIsT0FBTyxFQUFFLFVBQVU7UUFDbkIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSztRQUN6QixZQUFZLEVBQUUsUUFBaUI7UUFDL0IsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDaEIsV0FBVyxFQUFFO2dCQUNYLEtBQUssRUFBRTtvQkFDTCxTQUFTLEVBQUUsQ0FBQyxNQUEwQixFQUFFLEVBQUUsQ0FBQyxpQkFBaUIsQ0FDMUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFDcEIsV0FBVyxFQUNYLElBQUksRUFDSixNQUFNLEVBQ04sU0FBUyxDQUNWO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDUixDQUFDO0lBRUYsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLG1FQUFtRTtRQUNuRSxNQUFNLFVBQVUsR0FBRyxXQUFXLElBQUksU0FBUyxLQUFLLG9CQUFvQixDQUFDLEtBQUssSUFBSSxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU3RyxPQUFPO1lBQ0wsR0FBRyxJQUFJO1lBQ1AsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQzdCLEdBQUcsV0FBVztTQUNmLENBQUM7SUFDSixDQUFDO0lBRUQsdUVBQXVFO0lBQ3ZFLDJIQUEySDtJQUMzSCwwRUFBMEU7SUFDMUUsU0FBUztJQUNULE1BQU0sS0FBSyxHQUFHLFdBQVc7UUFDdkIsQ0FBQyxDQUFDLElBQUk7UUFDTixDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkYsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBRWpILE9BQU87UUFDTCxHQUFHLElBQUk7UUFDUCxPQUFPLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxHQUFHLGlCQUFpQixHQUFHLG1CQUFtQjtRQUMxRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7S0FDdEcsQ0FBQztBQUNKLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsWUFBWTtBQUNaLFNBQVMsaUJBQWlCLENBQUMsTUFBbUIsRUFBRSxVQUFtQjtJQUNqRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUN6QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7QUFDeEMsQ0FBQztBQUVELHVFQUF1RTtBQUN2RSwrRUFBK0U7QUFDL0UsK0RBQStEO0FBQy9ELFNBQVMsY0FBYyxDQUFDLElBQW9DLEVBQUUsVUFBbUI7SUFDL0UsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztBQUN2QyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLHVFQUF1RTtBQUN2RSw4RUFBOEU7QUFDOUUsY0FBYztBQUNkLFNBQVMsdUJBQXVCLENBQzlCLFVBQW9CLEVBQ3BCLFdBQW9DLEVBQ3BDLE1BQXVCLEVBQ3ZCLFNBQStCO0lBRS9CLE9BQU8sV0FBVztRQUNoQixDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLEVBQUUsT0FBTyxJQUFJLFFBQVEsQ0FBQztRQUMvRyxDQUFDLENBQUMsVUFBVSxDQUFDO0FBQ2pCLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsa0NBQWtDO0FBQ2xDLFNBQVMsZUFBZSxDQUFDLE1BQWdCO0lBQ3ZDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUM5RCxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUNoRSxNQUFNLENBQ1AsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNSLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsaUVBQWlFO0FBQ2pFLFNBQVMsaUJBQWlCLENBQUMsS0FBYTtJQUN0QyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDcEMsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksd0JBQXdCLEVBQUUsQ0FBQztZQUNyRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxtRUFBbUU7UUFDbkUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsY0FBYyxFQUFFLENBQUM7UUFDckcsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsSUFBSSxPQUFPLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUNoQyxPQUFPLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNoRCxJQUFJLGNBQWMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO2dCQUM1RCxJQUFJLEdBQUcsTUFBTSxDQUFDO1lBQ2hCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ25CLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hCLENBQUM7QUFFRCx3RUFBd0U7QUFDeEUsNkVBQTZFO0FBQzdFLHFEQUFxRDtBQUNyRCxJQUFJLGdCQUFnQixHQUFvQyxJQUFJLENBQUM7QUFFN0QsU0FBUyxjQUFjLENBQUMsSUFBWTtJQUNsQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDekQsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVELGdCQUFnQixDQUFDLElBQUksR0FBRyxlQUFlLENBQUM7SUFFeEMsT0FBTyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQ2xELENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUMzQixTQUEwQixFQUMxQixJQUFtQixFQUNuQixPQUE0QjtJQUU1QixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBcUIsQ0FBQztJQUMvQyxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFdBQVcsS0FBSyxZQUFZLENBQUM7SUFDdkQsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNoRSxNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlGLDRFQUE0RTtJQUM1RSx3RUFBd0U7SUFDeEUsbUNBQW1DO0lBQ25DLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2xELE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxjQUFjLENBQUMsc0JBQXNCLENBQ25HLElBQUksSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUMzQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDekgsT0FBTyxDQUNSLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkQseUVBQXlFO0lBQ3pFLE1BQU0sY0FBYyxHQUFHLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN4RCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUU1QyxPQUFPO1FBQ0wsSUFBSSxFQUFFLFFBQVEsQ0FDWixjQUFjLEVBQ2QsaUJBQWlCLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxFQUNyQyxjQUFjLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQy9DO1FBQ0QsTUFBTSxFQUFFLEVBQUUsR0FBRyxZQUFZLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ25FLDJFQUEyRTtRQUMzRSxPQUFPLEVBQUU7WUFDUCxPQUFPLEVBQUUsTUFBTTtZQUNmLFNBQVMsRUFBRSxDQUFDLE1BQStDLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUM5RSxTQUFTLEVBQ1QsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFDdEQsV0FBVyxFQUNYLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFDdEIsSUFBSSxFQUNKLE9BQU8sQ0FDUjtTQUNGO1FBQ0QsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxZQUFZO1FBQzVDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUztRQUM1QyxNQUFNLEVBQUUsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztLQUN0RixDQUFDO0FBQ0osQ0FBQztBQUVELDRFQUE0RTtBQUM1RSxnRkFBZ0Y7QUFDaEYsK0VBQStFO0FBQy9FLHVFQUF1RTtBQUN2RSxTQUFTLGVBQWUsQ0FBQyxTQUE2QjtJQUNwRCxPQUFPO1FBQ0w7WUFDRSxJQUFJLEVBQUUsS0FBSztZQUNYLEtBQUssRUFBRSxXQUFXO1lBQ2xCLGFBQWEsRUFBRSxLQUFLO1lBQ3BCLElBQUksRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUMvQyxXQUFXLEVBQUUsRUFBRTtZQUNmLFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7WUFDbkMsTUFBTSxFQUFFLElBQUk7U0FDYjtRQUNEO1lBQ0UsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1lBQ3BCLElBQUksRUFBRSxLQUFLO1lBQ1gsS0FBSyxFQUFFLFdBQVc7WUFDbEIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsV0FBVyxFQUFFLEVBQUU7WUFDZix1RUFBdUU7WUFDdkUsb0RBQW9EO1lBQ3BELFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLHVCQUF1QixDQUFDLElBQUksRUFBRSxFQUFFO1lBQ3hELElBQUksRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbkMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNsQixTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTthQUMvRCxDQUFDLENBQUM7U0FDSjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLCtFQUErRTtBQUMvRSw0Q0FBNEM7QUFDNUMsU0FBUyxnQkFBZ0IsQ0FDdkIsU0FBNkIsRUFDN0IsS0FBYSxFQUNiLFdBQW9DLEVBQ3BDLFNBQStCLEVBQy9CLElBQWtDLEVBQ2xDLE9BQTRCO0lBRTVCLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFdBQVc7UUFDckMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQztRQUNoRixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25CLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFvQixFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFbEYsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQzFCLE9BQU8sR0FBRyxRQUFRLFFBQVEsSUFBSSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFL0MsT0FBTyxHQUFHLFFBQVEsUUFBUSxJQUFJLEtBQUssSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7VUFDM0QsdUJBQXVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDdkUsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsZ0ZBQWdGO0FBQ2hGLDZFQUE2RTtBQUM3RSxxREFBcUQ7QUFDckQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLE1BQW1CLEVBQUUsV0FBbUIsRUFBRSxPQUFPLEdBQUcsS0FBSztJQUM3RixJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNsQixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEtBQUssT0FBTyxDQUFDO0lBRXZFLDJFQUEyRTtJQUMzRSxnQ0FBZ0M7SUFDaEMsT0FBTyxHQUFHLElBQUksT0FBTyxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUM7QUFDaEYsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLFFBQXdCO0lBQzVDLElBQUksUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUEwQixFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUV2RCxRQUFRLFFBQVEsRUFBRSxDQUFDO1FBQ2pCLEtBQUssUUFBUTtZQUNYLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDaEMsS0FBSyxNQUFNO1lBQ1QsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDakUsS0FBSyxPQUFPO1lBQ1YsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDbEU7WUFDRSxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQy9CLENBQUM7QUFDSCxDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLHlFQUF5RTtBQUN6RSwrRUFBK0U7QUFDL0UsU0FBUyxRQUFRLENBQ2YsUUFBd0IsRUFDeEIsYUFBbUMsRUFDbkMsVUFBZ0M7SUFFaEMsT0FBTyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQ3ZDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUNoRixVQUFVLENBQUMsUUFBUSxDQUFDLENBQ3JCLENBQUM7QUFDSixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLG1DQUFtQztBQUNuQyxTQUFTLFVBQVUsQ0FBQyxRQUF3QjtJQUMxQyxNQUFNLElBQUksR0FBaUIsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUV6RixRQUFRLFFBQVEsRUFBRSxDQUFDO1FBQ2pCLEtBQUssUUFBUTtZQUNYLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDakMsS0FBSyxNQUFNO1lBQ1QsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUMvQixLQUFLLE9BQU87WUFDVixPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLEtBQUssUUFBUTtZQUNYLE9BQU8sSUFBSSxDQUFDO1FBQ2Q7WUFDRSxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQ2hDLENBQUM7QUFDSCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSxvQ0FBb0M7QUFDcEMsU0FBUyxRQUFRLENBQUMsSUFBbUIsRUFBRSxLQUFjLEVBQUUsU0FBcUM7SUFDMUYsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUIsT0FBTyxTQUFTLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUMzQyxDQUFDO0FBaUJELDJFQUEyRTtBQUMzRSw4RUFBOEU7QUFDOUUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSwwRUFBMEU7QUFDMUUsU0FBUztBQUNULFNBQVMsV0FBVyxDQUNsQixNQUFnQyxFQUNoQyxNQUF5QyxFQUN6QyxNQUFvQjtJQUVwQix5REFBeUQ7SUFDekQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3BGLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDM0IsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUV4RCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDMUIseUVBQXlFO1FBQ3pFLHlFQUF5RTtRQUN6RSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUU3RyxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ2pCLElBQUksRUFBRSxLQUFLO1lBQ1gsSUFBSTtZQUNKLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztZQUNuQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDdkIsR0FBRyxJQUFJO1lBQ1AsR0FBRyxTQUFTO1lBQ1osV0FBVyxFQUFFLEVBQUU7WUFDZiwyRUFBMkU7WUFDM0UsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNyRSxHQUFHLE1BQU07U0FDVixDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsRCxNQUFNLFNBQVMsR0FBRyxLQUFLLElBQUksUUFBUTtRQUNqQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN6RixDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ1AsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRS9FLE9BQU87UUFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7UUFDakIsSUFBSSxFQUFFLE1BQU07UUFDWixJQUFJO1FBQ0osS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO1FBQ25CLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztRQUN2QixHQUFHLElBQUk7UUFDUCxHQUFHLFNBQVM7UUFDWixHQUFHLFNBQVM7UUFDWixHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2xFLE1BQU0sRUFBRSxJQUFJO1FBQ1osVUFBVSxFQUFFLENBQUM7UUFDYixTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ2pFLHlFQUF5RTtRQUN6RSxtRUFBbUU7UUFDbkUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDakMsR0FBRyxNQUFNO0tBQ1YsQ0FBQztBQUNKLENBQUM7QUFFRCwyRUFBMkU7QUFDM0Usc0JBQXNCO0FBQ3RCLFNBQVMsU0FBUyxDQUFDLE1BQXlCLEVBQUUsTUFBeUI7SUFDckUsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRUQsdUVBQXVFO0FBQ3ZFLDZFQUE2RTtBQUM3RSwwRUFBMEU7QUFDMUUsNkVBQTZFO0FBQzdFLDJFQUEyRTtBQUMzRSx5Q0FBeUM7QUFDekMsRUFBRTtBQUNGLHdFQUF3RTtBQUN4RSwrQkFBK0I7QUFDL0IsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsSUFBdUMsRUFDdkMsU0FBNkI7SUFFN0IsTUFBTSxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBYSxFQUFFLFFBQVEsRUFBRSwyQkFBMkIsRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUV2RixRQUFRLElBQUksRUFBRSxDQUFDO1FBQ2IsS0FBSyxxQkFBcUIsQ0FBQyxHQUFHO1lBQzVCLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdkQsS0FBSyxxQkFBcUIsQ0FBQyxJQUFJO1lBQzdCLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdEQsS0FBSyxxQkFBcUIsQ0FBQyxJQUFJO1lBQzdCLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDdEQ7WUFDRSxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0FBQ0gsQ0FBQztBQUVELDBFQUEwRTtBQUMxRSwyRUFBMkU7QUFDM0UsMERBQTBEO0FBQzFELFNBQVMsZUFBZSxDQUN0QixNQUErQixFQUMvQixRQUFXLEVBQ1gsTUFBeUM7SUFFekMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBaUIsRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFFekQsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDcEIsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQsT0FBTztRQUNMLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7UUFDeEYsSUFBSSxFQUFFLE1BQU07S0FDYixDQUFDO0FBQ0osQ0FBQztBQUVELHlFQUF5RTtBQUN6RSxtREFBbUQ7QUFDbkQsU0FBUyxjQUFjLENBQ3JCLE1BQXlDLEVBQ3pDLEtBQW1CO0lBRW5CLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBbUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hHLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQVMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFNUcsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBcUIsRUFBRTtRQUNuRCxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQzdFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLElBQW1DO0lBQzFELE9BQU8sSUFBSSxLQUFLLElBQUksSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLENBQUM7QUFDbkQsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSw0RUFBNEU7QUFDNUUscUVBQXFFO0FBQ3JFLFNBQVMsa0JBQWtCLENBQ3pCLE9BQXFCLEVBQ3JCLFVBQWtDLEVBQ2xDLEtBQWMsRUFDZCxPQUE0QjtJQUU1QixJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFL0MsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNmLE1BQU0sT0FBTyxHQUFHLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXZGLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsaUJBQWlCLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUMvRSxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLGVBQWU7QUFDZixTQUFTLGNBQWMsQ0FBQyxNQUF1QjtJQUM3QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ3pCLE1BQU0sR0FBRyxHQUFHLElBQUksS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBRSxJQUEwQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRXBHLE9BQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDN0IsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDhFQUE4RTtBQUM5RSw2REFBNkQ7QUFDN0QsU0FBUyxjQUFjLENBQ3JCLE1BQStDLEVBQy9DLFNBQStCLEVBQy9CLE1BQXFCLEVBQ3JCLFdBQW9DLEVBQ3BDLFNBQStCLEVBQy9CLE9BQTRCO0lBRTVCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4RCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxJQUFJLENBQUMsQ0FBQztJQUMzQyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN2RCxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsV0FBVztRQUNwQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUM7UUFDM0UsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2QsTUFBTSxZQUFZLEdBQUcsRUFBRSxHQUFHLE9BQU8sRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFFeEQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQy9CLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sTUFBTSxHQUFHLE9BQU8sSUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNsRSxNQUFNLEtBQUssR0FBRyxHQUFHLE1BQU0sSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxNQUFNLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDL0UsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQzdHLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQztRQUUzRSxPQUFPLEtBQUssS0FBSyxJQUFJO1lBQ25CLENBQUMsQ0FBQyxHQUFHLEtBQUssS0FBSyxLQUFLLEVBQUU7WUFDdEIsQ0FBQyxDQUFDLEdBQUcsS0FBSyxLQUFLLFlBQVksQ0FBQyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxDQUFDLEtBQUssS0FBSyxHQUFHLENBQUM7SUFDeEYsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLENBQUMsT0FBTyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRCwwRUFBMEU7QUFDMUUsNkVBQTZFO0FBQzdFLCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UsMEVBQTBFO0FBQzFFLFNBQVMsZUFBZSxDQUN0QixJQUFnQyxFQUNoQyxVQUFtQixFQUNuQixTQUF5QixFQUN6QixTQUEwQixFQUFFO0lBRTVCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEtBQUssU0FBUztRQUMzQyxDQUFDLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQztRQUN0QixDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLHFCQUFxQixFQUFFLENBQUM7SUFFdkYsT0FBTztRQUNMLElBQUksRUFBRSxPQUFnQjtRQUN0QixJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSSxTQUFTO1FBQzlCLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQWlCLENBQUMsQ0FBQyxDQUFDLEtBQWM7UUFDN0QsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQzdCLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQWdCLENBQUMsQ0FBQyxDQUFDLE1BQWUsRUFBRTtRQUMxRyx3RUFBd0U7UUFDeEUsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDeEMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDeEMsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1FBQ3hCLFNBQVM7S0FDVixDQUFDO0FBQ0osQ0FBQztBQUVELDBFQUEwRTtBQUMxRSw2RUFBNkU7QUFDN0UsOEVBQThFO0FBQzlFLDZCQUE2QjtBQUM3QixNQUFNLFVBQVUsY0FBYyxDQUFDLElBQWdDO0lBQzdELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFNUMsT0FBTztRQUNMLEdBQUcsRUFBRSxVQUFVLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQztRQUMxQixHQUFHLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUM7UUFDMUIsUUFBUSxFQUFFLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTO0tBQ3hFLENBQUM7QUFDSixDQUFDO0FBRUQsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsK0NBQStDO0FBQy9DLEVBQUU7QUFDRiwrRUFBK0U7QUFDL0Usc0VBQXNFO0FBQ3RFLFNBQVMsa0JBQWtCLENBQ3pCLE1BQW1CLEVBQ25CLFdBQXVDLEVBQ3ZDLE9BQTRCLEVBQzVCLFVBQThCLEVBQzlCLFVBQTRCO0lBRTVCLE1BQU0sT0FBTyxHQUFHLFVBQVUsS0FBSyxTQUFTLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxTQUF5QixFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVyRyxPQUFPO1FBQ0wsZUFBZSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUN2RixLQUFLLEVBQUUsQ0FBQztZQUNSLFVBQVU7WUFDVixLQUFLLEVBQUUsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7U0FDckMsQ0FBQztRQUNGO1lBQ0UsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdHLFFBQVEsRUFBRSxPQUFnQjtZQUMxQixTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO1lBQzFCLFVBQVUsRUFBRSxDQUFDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztTQUMvRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsOEVBQThFO0FBQzlFLFNBQVMsWUFBWSxDQUFDLElBQWdDO0lBQ3BELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQztBQUNsRixDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLFNBQVMsVUFBVSxDQUFDLEtBQWM7SUFDaEMsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDakYsQ0FBQztBQU9ELDBFQUEwRTtBQUMxRSxnQ0FBZ0M7QUFDaEMsRUFBRTtBQUNGLDBFQUEwRTtBQUMxRSw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDZFQUE2RTtBQUM3RSw4RUFBOEU7QUFDOUUsdUJBQXVCO0FBQ3ZCLFNBQVMsY0FBYyxDQUFDLE1BQThCLEVBQUUsT0FBNEI7SUFDbEYsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLGlCQUFpQixDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2pHLE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztJQUNwRixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7SUFFL0UsT0FBTztRQUNMLFNBQVMsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUM7S0FDakYsQ0FBQztBQUNKLENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsNEVBQTRFO0FBQzVFLDBCQUEwQjtBQUMxQixTQUFTLHNCQUFzQixDQUM3QixJQUE2QixFQUM3QixJQUFrQixFQUNsQixPQUE0QjtJQUU1QixPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLHdCQUF3QixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDeEYsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsaUlBQWlJO0FBQ2pJLHVFQUF1RTtBQUN2RSx3RUFBd0U7QUFDeEUsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxPQUFPO0FBQ1AsU0FBUyxnQkFBZ0IsQ0FDdkIsTUFBbUIsRUFDbkIsU0FBK0IsRUFDL0IsV0FBNkIsRUFDN0IsT0FBNEIsRUFDNUIsT0FBZ0IsRUFDaEIsVUFBNEI7SUFFNUIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxTQUF5QixFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxTQUFTLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUVySCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sQ0FBQyxzQkFBc0IsQ0FDNUIsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUNsRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQzNHLE9BQU8sQ0FDUixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtRQUN6QyxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQztRQUV2RixPQUFPLHNCQUFzQixDQUMzQixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsRUFDeEQsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQ3JILE9BQU8sQ0FDUixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLHdFQUF3RTtBQUN4RSwyQ0FBMkM7QUFDM0MsU0FBUyxnQkFBZ0IsQ0FBQyxPQUE0QjtJQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7QUFDdkQsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSwyQkFBMkI7QUFDM0IsU0FBUyxxQkFBcUIsQ0FBQyxPQUE0QjtJQUN6RCxNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsT0FBTyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUV4RCxPQUFPLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLG1CQUFtQixFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQ3BGLENBQUM7QUFPRCw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBQzFFLDZFQUE2RTtBQUM3RSxnQkFBZ0I7QUFDaEIsU0FBUyxhQUFhLENBQUMsT0FBaUMsRUFBRSxPQUE0QjtJQUNwRixJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQzFGLENBQUM7SUFFRCxPQUFPO1FBQ0wsY0FBYyxFQUFFLENBQUMsS0FBYyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQztLQUM1RyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsY0FBYyxDQUNyQixTQUEwQixFQUMxQixJQUFtQixFQUNuQixLQUFjLEVBQ2QsT0FBNEI7SUFFNUIsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQXFCLENBQUM7SUFDL0MsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxJQUFJLEVBQUUsQ0FBQztJQUNqRCxNQUFNLGNBQWMsR0FBRyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUU5RSxPQUFPO1FBQ0wsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRTtRQUM1QixNQUFNLEVBQUUsWUFBWSxDQUFDLGNBQWMsQ0FBQztRQUNwQyxNQUFNLEVBQUU7WUFDTjtnQkFDRSxJQUFJLEVBQUUsS0FBSztnQkFDWCxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSztnQkFDdEMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUM7Z0JBQ2pDLE9BQU8sRUFBRSxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDO2dCQUM3RCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO2dCQUN0QixJQUFJLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUNuRCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7aUJBQzFCLENBQUMsQ0FBQzthQUNKO1NBQ0Y7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELCtFQUErRTtBQUMvRSxxREFBcUQ7QUFDckQsU0FBUyxTQUFTLENBQUMsUUFBd0I7SUFDekMsUUFBUSxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLE1BQU07WUFDVCxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLEtBQUssT0FBTztZQUNWLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEIsS0FBSyxLQUFLO1lBQ1IsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QixLQUFLLFFBQVE7WUFDWCxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hCO1lBQ0UsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLElBQStCLEVBQUUsTUFBYztJQUNuRSxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBVyxDQUFDO0lBQ2hDLE1BQU0sTUFBTSxHQUFjLEVBQUUsQ0FBQztJQUM3QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxLQUFjO0lBQzdCLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUMxRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFN0IsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNqRCxDQUFDO0FBRUQsaUZBQWlGO0FBQ2pGLCtFQUErRTtBQUMvRSxTQUFTLGlCQUFpQixDQUFDLElBQW1CO0lBQzVDLE9BQU8sSUFBSSxDQUFDLFdBQVcsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNoRyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVc7UUFDbEIsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUNYLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsbUVBQW1FO0FBQ25FLE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxVQUFvQjtJQUNyRCxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ2hDLEtBQUssTUFBTSxRQUFRLElBQUksVUFBVSxFQUFFLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7QUFDeEIsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSxjQUFjO0FBQ2QsTUFBTSxVQUFVLGNBQWMsQ0FBQyxNQUErQjtJQUM1RCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQztXQUN6RixvQkFBb0IsQ0FBQyxLQUFLLENBQUM7QUFDbEMsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSwyRUFBMkU7QUFDM0UsMEVBQTBFO0FBQzFFLHdFQUF3RTtBQUN4RSx3RUFBd0U7QUFDeEUsNkVBQTZFO0FBQzdFLDJCQUEyQjtBQUMzQixTQUFTLGdCQUFnQixDQUN2QixLQUFhLEVBQ2IsV0FBNkIsRUFDN0IsTUFBdUIsRUFDdkIsWUFBa0Msb0JBQW9CLENBQUMsS0FBSztJQUU1RCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ25CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN4QyxJQUFJLFdBQVcsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUMzQixPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUNyRixDQUFDO0FBRUQsK0RBQStEO0FBQy9ELHFCQUFxQjtBQUNyQixTQUFTLGtCQUFrQixDQUN6QixJQUFVLEVBQ1YsV0FBOEMsRUFDOUMsTUFBdUIsRUFDdkIsU0FBK0I7SUFFL0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVwRCxJQUFJLFNBQVMsS0FBSyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMvQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDcEQsUUFBUSxXQUFXLEVBQUUsQ0FBQztZQUNwQixLQUFLLFNBQVM7Z0JBQ1osT0FBTyxHQUFHLElBQUksS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUMvQixLQUFLLE9BQU87Z0JBQ1YsT0FBTyxHQUFHLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUM1QixTQUFTLCtCQUErQjtnQkFDdEMsT0FBTyxHQUFHLElBQUksSUFBSSxLQUFLLElBQUksR0FBRyxFQUFFLENBQUM7UUFDckMsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxTQUFTLEtBQUssb0JBQW9CLENBQUMsSUFBSSxDQUFDO0lBQ3JELFFBQVEsV0FBVyxFQUFFLENBQUM7UUFDcEIsS0FBSyxTQUFTO1lBQ1osT0FBTyxJQUFJO2dCQUNULENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxPQUFPLElBQUksSUFBSSxFQUFFO2dCQUM5QyxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7UUFDM0MsS0FBSyxPQUFPO1lBQ1YsT0FBTyxlQUFlLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkUsU0FBUyxrREFBa0Q7WUFDekQsT0FBTyxlQUFlLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdkUsQ0FBQztBQUNILENBQUM7QUFFRCw2RUFBNkU7QUFDN0Usb0RBQW9EO0FBQ3BELFNBQVMsZUFBZSxDQUFDLFdBQTZCLEVBQUUsU0FBK0I7SUFDckYsT0FBTyxXQUFXLEtBQUssTUFBTSxJQUFJLFNBQVMsS0FBSyxvQkFBb0IsQ0FBQyxLQUFLLENBQUM7QUFDNUUsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLE1BQXVCO0lBQzVDLE9BQU8sZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxjQUFjLENBQUM7QUFDcEYsQ0FBQztBQUVELHdFQUF3RTtBQUN4RSw4RUFBOEU7QUFDOUUsaUVBQWlFO0FBQ2pFLE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsS0FBYSxFQUNiLFdBQTZCLEVBQzdCLFNBQWtCLEVBQ2xCLE1BQXVCLEVBQ3ZCLFlBQWtDLG9CQUFvQixDQUFDLEtBQUs7SUFFNUQsTUFBTSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDdEUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTyxTQUFTLElBQUksZUFBZSxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztBQUNqSCxDQUFDO0FBRUQsOEVBQThFO0FBQzlFLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3RSxNQUFNLFVBQVUsYUFBYSxDQUMzQixNQUFrQixFQUNsQixJQUFtQixFQUNuQixNQUF1QjtJQUV2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUNuQyxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUU5QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDbkMsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEIsT0FBTyxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssSUFBSSxNQUFNLENBQUM7UUFDdkMsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDcEcsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSw4RUFBOEU7QUFDOUUsc0VBQXNFO0FBQ3RFLE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsTUFBa0IsRUFDbEIsSUFBbUIsRUFDbkIsTUFBdUI7SUFFdkIsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztJQUNyQyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUMsTUFBTSxLQUFLLEdBQXVELE9BQU8sSUFBSSxVQUFVO1FBQ3JGLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUU7UUFDM0csQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUVQLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxDQUFDO1FBQzVELENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDcEQsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLHVCQUF1QjtBQUN2QixTQUFTLGdCQUFnQixDQUFDLE1BQWtDO0lBQzFELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBQ2pGLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsZ0ZBQWdGO0FBQ2hGLDhFQUE4RTtBQUM5RSwwRUFBMEU7QUFDMUUscUVBQXFFO0FBQ3JFLFNBQVMsZUFBZSxDQUN0QixXQUFvQyxFQUNwQyxVQUFvQixFQUNwQixNQUF1QixFQUN2QixTQUErQjtJQUUvQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakIsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFakQsT0FBTztRQUNMLFNBQVMsRUFBRTtZQUNULFNBQVMsRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFO2dCQUMzQixNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNYLE9BQU8sS0FBSyxDQUFDO2dCQUNmLENBQUM7Z0JBRUQsT0FBTyxTQUFTLElBQUksZUFBZSxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUM7b0JBQ3pELENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLFNBQVMsS0FBSyxDQUFDLElBQUksR0FBRztvQkFDeEMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7WUFDcEIsQ0FBQztZQUNELElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDakU7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgTGVnZW5kQ29tcG9uZW50T3B0aW9uLCBTZXJpZXNPcHRpb24sIFRvb2x0aXBDb21wb25lbnRGb3JtYXR0ZXJDYWxsYmFja1BhcmFtcyB9IGZyb20gJ2VjaGFydHMnO1xuXG5pbXBvcnQgeyBpc1ZhbGlkLCBwYXJzZUlTTyB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgUmVwb3J0Q2hhcnRDb2xvciB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWNvbG9yLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnREYXRhTGFiZWxzIH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtY2hhcnQtZGF0YS1sYWJlbHMuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydERhdGVMYWJlbCB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWRhdGUtbGFiZWwuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydExpbmVTdHlsZSB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWNoYXJ0LWxpbmUtc3R5bGUuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydE1hcmtTdGF0IH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtY2hhcnQtbWFyay1zdGF0LmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0TGlzdENvbHVtbkZvcm1hdCB9IGZyb20gJy4vZW51bXMvcmVwb3J0LWxpc3QtY29sdW1uLWZvcm1hdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydE51bWJlclVuaXRzIH0gZnJvbSAnLi9lbnVtcy9yZXBvcnQtbnVtYmVyLXVuaXRzLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0VmFsdWVGb3JtYXQgfSBmcm9tICcuL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtYXQuZW51bSc7XG5pbXBvcnQge1xuICBheGlzTnVtYmVyRm9ybWF0LFxuICBDaGFydE51bWJlckZvcm1hdCxcbiAgY2hhcnRWYWx1ZVBlYWssXG4gIERBWV9TSE9SVCxcbiAgZm9ybWF0TG9jYWxEYXRlLFxuICBmb3JtYXROdW1iZXIsXG4gIGZvcm1hdFBsYWluTnVtYmVyLFxuICBoYXNOdW1iZXJGb3JtYXQsXG4gIE1PTlRIX0RBWSxcbiAgTU9OVEhfTE9ORyxcbiAgTU9OVEhfWUVBUixcbiAgcmVzb2x2ZUNoYXJ0TnVtYmVyRm9ybWF0LFxufSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBBeGlzQ2hhcnRUeXBlLFxuICBDaGFydENvbmZpZyxcbiAgQ2hhcnRHcmFudWxhcml0eSxcbiAgQ2hhcnRNZWFzdXJlLFxuICBDaGFydFJlZmVyZW5jZSxcbiAgQ2hhcnRWYWx1ZUF4aXMsXG4gIENvbXBvbmVudERhdGEsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIExlZ2VuZFBvc2l0aW9uLFxuICBMaXN0Q29sdW1uLFxuICBMaXN0Q29uZmlnLFxuICBOdW1iZXJGb3JtYXRTcGVjLFxuICBSZXBvcnRDb21wb25lbnQsXG4gIFJlcG9ydEZvcm1hdENvbnRleHQsXG4gIFJlcG9ydExvY2FsZVRhZyxcbiAgV2F0ZXJmYWxsU3RlcEtpbmQsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tICcuL3RleHQnO1xuaW1wb3J0IHtcbiAgUkVQT1JUX0NIQVJUX0NPTE9SX0JZX05BTUUsXG4gIFJFUE9SVF9DSEFSVF9DT0xPUlMsXG4gIFJFUE9SVF9SRUZFUkVOQ0VfQ09MT1IsXG4gIFJFUE9SVF9XQVRFUkZBTExfQ09MT1JTLFxufSBmcm9tICcuL3RoZW1lL3BhbGV0dGUnO1xuaW1wb3J0IHsgUkVQT1JUX0FYSVNfTEFCRUxfRk9OVF9TSVpFLCBSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFksIFJFUE9SVF9EQVRBX0xBQkVMX0ZPTlRfU0laRSB9IGZyb20gJy4vdGhlbWUvdHlwb2dyYXBoeSc7XG5cblxuLy8gUm9vbSBmb3IgYW4gYXhpcyB0aXRsZS4gRUNoYXJ0cyA1J3MgY29udGFpbkxhYmVsIGtlZXBzIHRoZSBUSUNLIGxhYmVscyBpbnNpZGVcbi8vIHRoZSBncmlkIGJ1dCBub3QgdGhlIGF4aXMgbmFtZSwgc28gd2l0aG91dCB0aGlzIGEgdmVydGljYWwgY2hhcnQncyBjYXRlZ29yeVxuLy8gdGl0bGUgcnVucyBvZmYgdGhlIGJvdHRvbSBlZGdlIG9yIHVuZGVyIGEgYm90dG9tIGxlZ2VuZCwgYW5kIGl0cyB2YWx1ZSB0aXRsZVxuLy8gYWJvdmUgdGhlIHBsb3QgcnVucyBvZmYgdGhlIHRvcCBvciB1bmRlciBhIHRvcCBsZWdlbmQuXG5jb25zdCBBWElTX05BTUVfUk9PTSA9IDIwO1xuLy8gRUNoYXJ0cycgb3duIGRlZmF1bHQgZ2FwIGJldHdlZW4gdGhlIGF4aXMgbGluZSBhbmQgaXRzIHRpY2sgbGFiZWxzLlxuY29uc3QgQVhJU19MQUJFTF9NQVJHSU4gPSA4O1xuLy8gQ2xlYXJhbmNlIGJldHdlZW4gdGhlIGxvbmdlc3QgdGljayBsYWJlbCBhbmQgYSBob3Jpem9udGFsIGNoYXJ0J3Mgcm90YXRlZFxuLy8gdGl0bGUsIHNvIHRoZSB0d28gbmV2ZXIgdG91Y2guXG5jb25zdCBBWElTX05BTUVfQ0xFQVJBTkNFID0gNjtcbi8vIEEgaG9yaXpvbnRhbCBjaGFydCdzIGNhdGVnb3J5IGxhYmVscyBhcmUgY3V0IHNob3J0IHdpdGggYW4gZWxsaXBzaXMgcGFzdFxuLy8gdGhpcyB3aWR0aCAodGhlIHRvb2x0aXAgc3RpbGwgc2hvd3MgdGhlbSBpbiBmdWxsKSwgc28gb25lIGxvbmcgbGFiZWwgY2Fubm90XG4vLyBzcXVlZXplIHRoZSBwbG90IGF3YXkuXG5jb25zdCBDQVRFR09SWV9MQUJFTF9NQVhfV0lEVEggPSAxNjA7XG5jb25zdCBMQUJFTF9FTExJUFNJUyA9ICfigKYnO1xuLy8gVGhlIGZvbnQgdGhlIHRoZW1lIGRyYXdzIGF4aXMgbGFiZWxzIGluLCBhcyBhIGNhbnZhcyBmb250IHN0cmluZy4gTGFiZWxzIGFyZVxuLy8gbWVhc3VyZWQgaW4gaXQgdGhlIHdheSBFQ2hhcnRzIG1lYXN1cmVzIHRoZW0gZm9yIGNvbnRhaW5MYWJlbCwgc28gYVxuLy8gaG9yaXpvbnRhbCBjaGFydCdzIHRpdGxlIGxhbmRzIGV4YWN0bHkgYmV5b25kIHRoZSB3aWRlc3QgbGFiZWwuXG5jb25zdCBBWElTX0xBQkVMX0ZPTlQgPSBgJHtSRVBPUlRfQVhJU19MQUJFTF9GT05UX1NJWkV9cHggJHtSRVBPUlRfQ0hBUlRfRk9OVF9GQU1JTFl9YDtcbi8vIFRoZSBsZXR0ZXIgYSBxdWFydGVyIGxhYmVsIHN0YXJ0cyB3aXRoLCBieSBsYW5ndWFnZSBzdWJ0YWcuIEZyZW5jaCB3cml0ZXMgdGhlXG4vLyBzZWNvbmQgcXVhcnRlciAnVDInICh0cmltZXN0cmUpOyBldmVyeSBvdGhlciBsYW5ndWFnZSByZWFkcyAnUTInLlxuY29uc3QgUVVBUlRFUl9QUkVGSVhFUyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+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==
|