@firestitch/report 18.8.0 → 18.9.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-text/component-text.component.d.ts +47 -2
- package/app/reports/components/component-text/value-embed.plugin.d.ts +67 -0
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +34 -9
- package/app/reports/components/report-component/report-component.component.d.ts +10 -1
- package/app/reports/data/report.data.d.ts +2 -1
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +8 -0
- package/app/reports/enums/report-value-formula.enum.d.ts +6 -0
- package/app/reports/export/report-export-collector.service.d.ts +24 -0
- package/app/reports/export/report-export.service.d.ts +3 -1
- package/app/reports/export/report-pdf.service.d.ts +18 -2
- package/app/reports/export/report-pptx.service.d.ts +15 -2
- package/app/reports/export/report-text-layout.service.d.ts +35 -0
- package/app/reports/format.d.ts +5 -1
- package/app/reports/interfaces/report.interface.d.ts +22 -3
- package/app/reports/layout.d.ts +2 -0
- package/app/reports/services/report-filter-state.service.d.ts +1 -1
- package/app/reports/text.d.ts +50 -0
- package/app/reports/theme/palette.d.ts +2 -0
- package/app/reports/values.d.ts +17 -0
- package/esm2022/app/reports/components/component-text/component-text.component.mjs +213 -16
- package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +484 -0
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +260 -34
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +65 -19
- package/esm2022/app/reports/data/report.data.mjs +19 -1
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +134 -23
- package/esm2022/app/reports/enums/report-value-formula.enum.mjs +14 -0
- package/esm2022/app/reports/export/report-export-collector.service.mjs +170 -44
- package/esm2022/app/reports/export/report-export.service.mjs +57 -19
- package/esm2022/app/reports/export/report-pdf.service.mjs +339 -96
- package/esm2022/app/reports/export/report-pptx.service.mjs +316 -88
- package/esm2022/app/reports/export/report-text-layout.service.mjs +241 -0
- package/esm2022/app/reports/format.mjs +41 -10
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/kpi-card.mjs +19 -6
- package/esm2022/app/reports/layout.mjs +11 -1
- package/esm2022/app/reports/option-builder.mjs +18 -5
- package/esm2022/app/reports/output-notes.mjs +57 -11
- package/esm2022/app/reports/services/report-filter-state.service.mjs +19 -10
- package/esm2022/app/reports/text.mjs +293 -85
- package/esm2022/app/reports/theme/palette.mjs +7 -2
- package/esm2022/app/reports/values.mjs +183 -0
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +4 -1
- package/esm2022/app/reports/views/report/report.component.mjs +4 -1
- package/esm2022/public_api.mjs +2 -1
- package/fesm2022/{firestitch-report-echarts-qCBE3LqM.mjs → firestitch-report-echarts-DBMOHmBF.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-qCBE3LqM.mjs.map → firestitch-report-echarts-DBMOHmBF.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-DbsWbE-j.mjs → firestitch-report-firestitch-report-CqbXT1gh.mjs} +3492 -1028
- package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +1 -0
- package/fesm2022/firestitch-report-firestitch-report-DbsWbE-j.mjs.map +0 -1
|
@@ -4,12 +4,49 @@
|
|
|
4
4
|
// A block's html arrives already rebuilt server-side from a small allowlist
|
|
5
5
|
// (ReportTextHtml): p, h1-h3, strong, em, u, s, ul/ol/li, br, a, and span with
|
|
6
6
|
// color / background-color / font-size / font-weight / font-family, plus
|
|
7
|
-
// text-align on a block.
|
|
7
|
+
// text-align on a block. A table may sit at the top level of a block: table,
|
|
8
|
+
// thead, tbody, tfoot, tr, th and td, a width on the table, and on a cell
|
|
9
|
+
// text-align, vertical-align, background-color, a width and a colspan or
|
|
10
|
+
// rowspan. Its grid lines, padding and margin are never stored: every renderer
|
|
11
|
+
// draws them from the TEXT_TABLE_* constants below. Transparent, currentcolor
|
|
12
|
+
// and the CSS-wide keywords (inherit, initial, …) are not colors, so the
|
|
13
|
+
// server drops them and hexColor reads them as no color. Everything here only
|
|
14
|
+
// has to understand that set.
|
|
8
15
|
// Body text size, points, and the heading sizes — the same numbers the canvas
|
|
9
16
|
// stylesheet uses, so an unstyled paragraph is one size everywhere.
|
|
10
17
|
export const DEFAULT_TEXT_SIZE = 12;
|
|
11
18
|
export const HEADING_TEXT_SIZES = { 1: 24, 2: 18, 3: 14 };
|
|
12
19
|
export const DEFAULT_TEXT_COLOR = '#1f2933';
|
|
20
|
+
// A table's grid lines: their color, and their width in points (0.75pt is one
|
|
21
|
+
// pixel on the canvas). The html never stores borders or padding
|
|
22
|
+
// (ReportTextHtml drops them), so the canvas, the editor and both exports all
|
|
23
|
+
// draw this one look.
|
|
24
|
+
export const TEXT_TABLE_BORDER_COLOR = '#cbd2d9';
|
|
25
|
+
export const TEXT_TABLE_BORDER_WIDTH = 0.75;
|
|
26
|
+
// The space between a cell's grid lines and its words, in points.
|
|
27
|
+
export const TEXT_TABLE_CELL_PADDING = { vertical: 2, horizontal: 4 };
|
|
28
|
+
// The space above and below a table, between it and the words around it, in
|
|
29
|
+
// points.
|
|
30
|
+
export const TEXT_TABLE_MARGIN = 4;
|
|
31
|
+
// A value token: {{value.total_visits}}. Keys are lowercase letters, digits and
|
|
32
|
+
// underscores, starting with a letter.
|
|
33
|
+
export const VALUE_TOKEN_PATTERN = /\{\{\s*value\.([a-z][a-z0-9_]*)\s*\}\}/gi;
|
|
34
|
+
// What a value with no number reads as — it failed, it is not on this page, or
|
|
35
|
+
// its query found nothing — so a block never prints a raw token.
|
|
36
|
+
export const VALUE_EMPTY_TEXT = '—';
|
|
37
|
+
// What a value reads as while its number is on its way (on screen only: an
|
|
38
|
+
// export waits for every number).
|
|
39
|
+
export const VALUE_LOADING_TEXT = '…';
|
|
40
|
+
export function valueToken(key) {
|
|
41
|
+
return `{{value.${key}}}`;
|
|
42
|
+
}
|
|
43
|
+
// What a value reads as in a block, viewed or edited: its formatted number,
|
|
44
|
+
// the ellipsis while that loads, else the em dash.
|
|
45
|
+
export function valueText(value) {
|
|
46
|
+
return value?.text ?? (value?.loading ? VALUE_LOADING_TEXT : VALUE_EMPTY_TEXT);
|
|
47
|
+
}
|
|
48
|
+
// What a table's cells are joined by where it reads as lines of text.
|
|
49
|
+
const TABLE_CELL_SEPARATOR = ' · ';
|
|
13
50
|
// The tokens a block may carry, with what fills each. {{page.number}} is the
|
|
14
51
|
// page's position among the report's pages (1-based), which is what makes a
|
|
15
52
|
// shared footer number every page correctly.
|
|
@@ -19,23 +56,46 @@ const TOKENS = {
|
|
|
19
56
|
'report.name': (context) => context.reportName,
|
|
20
57
|
};
|
|
21
58
|
// Replace every {{token}} in the html. Values are html-escaped: a page named
|
|
22
|
-
// "R&D <draft>" must read as that, not as markup.
|
|
59
|
+
// "R&D <draft>" must read as that, not as markup. A {{value.<key>}} token reads
|
|
60
|
+
// as its formatted number, the ellipsis while that loads, else the em dash.
|
|
23
61
|
export function fillTextTokens(html, context) {
|
|
24
|
-
return html
|
|
62
|
+
return html
|
|
63
|
+
.replace(VALUE_TOKEN_PATTERN, (match, key) => escapeHtml(valueText(context.values?.[key.toLowerCase()])))
|
|
64
|
+
.replace(/\{\{\s*([a-z.]+)\s*\}\}/gi, (match, token) => {
|
|
25
65
|
const fill = TOKENS[token.toLowerCase()];
|
|
26
66
|
return fill ? escapeHtml(fill(context)) : match;
|
|
27
67
|
});
|
|
28
68
|
}
|
|
29
|
-
// Walk a block's html into
|
|
30
|
-
//
|
|
31
|
-
|
|
69
|
+
// Walk a block's html into what the exports draw: the words between its tables
|
|
70
|
+
// as paragraphs of styled runs, and each table as a grid of cells. Tokens are
|
|
71
|
+
// filled first so a page number is just text by then. There is a text part for
|
|
72
|
+
// every run of nodes splitAtTables finds, even one that holds no words, so the
|
|
73
|
+
// nth text part is the nth run the export's DOM measure finds.
|
|
74
|
+
export function textBlocks(html, context) {
|
|
32
75
|
const document = new DOMParser().parseFromString(`<body>${fillTextTokens(html, context)}</body>`, 'text/html');
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
76
|
+
const blocks = splitAtTables(document.body).map((part) => {
|
|
77
|
+
if (!Array.isArray(part)) {
|
|
78
|
+
return { kind: 'table', table: parseTable(part) };
|
|
79
|
+
}
|
|
80
|
+
const fragment = document.createDocumentFragment();
|
|
81
|
+
const paragraphs = [];
|
|
82
|
+
fragment.append(...part);
|
|
83
|
+
walkBlocks(fragment, paragraphs, null);
|
|
84
|
+
return { kind: 'text', paragraphs };
|
|
85
|
+
});
|
|
86
|
+
trimBlankEnd(blocks);
|
|
87
|
+
return blocks;
|
|
88
|
+
}
|
|
89
|
+
// The block as paragraphs alone, for anything that draws no grid: a table reads
|
|
90
|
+
// as a line per row, its cells' words joined by ' · '.
|
|
91
|
+
export function textParagraphs(html, context) {
|
|
92
|
+
return blockParagraphs(textBlocks(html, context));
|
|
93
|
+
}
|
|
94
|
+
// Blocks textBlocks already walked, as textParagraphs reads them.
|
|
95
|
+
export function blockParagraphs(blocks) {
|
|
96
|
+
return blocks.flatMap((block) => block.kind === 'text'
|
|
97
|
+
? block.paragraphs
|
|
98
|
+
: block.table.rows.map(rowParagraph));
|
|
39
99
|
}
|
|
40
100
|
// The html as plain text — what a block says, for anything that cannot style it.
|
|
41
101
|
export function textPlain(html, context) {
|
|
@@ -43,85 +103,218 @@ export function textPlain(html, context) {
|
|
|
43
103
|
.map((paragraph) => paragraph.runs.map((run) => run.text).join(''))
|
|
44
104
|
.join('\n');
|
|
45
105
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
106
|
+
// A block's top-level nodes split at each table: each table on its own, and
|
|
107
|
+
// each run of the nodes between them as a list. A table sits only at the top
|
|
108
|
+
// level (ReportTextHtml flattens any other), so this is the whole split.
|
|
109
|
+
// textBlocks and the export's measure of the rendered block both split here.
|
|
110
|
+
export function splitAtTables(parent) {
|
|
111
|
+
const parts = [];
|
|
112
|
+
let run = null;
|
|
113
|
+
parent.childNodes.forEach((node) => {
|
|
114
|
+
if (node.nodeName === 'TABLE') {
|
|
115
|
+
parts.push(node);
|
|
116
|
+
run = null;
|
|
117
|
+
}
|
|
118
|
+
else if (run) {
|
|
119
|
+
run.push(node);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
run = [node];
|
|
123
|
+
parts.push(run);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return parts;
|
|
127
|
+
}
|
|
128
|
+
// A table as a grid of cells, each holding its words as paragraphs. Rows come
|
|
129
|
+
// as a browser draws them, the head first and the foot last, whatever order the
|
|
130
|
+
// html writes its sections in.
|
|
131
|
+
export function parseTable(element) {
|
|
132
|
+
const rows = Array.from(element.rows, (row) => ({
|
|
133
|
+
section: tableSection(row),
|
|
134
|
+
cells: Array.from(row.cells, tableCell),
|
|
135
|
+
}));
|
|
136
|
+
return tableGrid({ rows, columns: 0 });
|
|
137
|
+
}
|
|
138
|
+
// Where each cell sits, by the HTML table algorithm: a cell takes the first
|
|
139
|
+
// column of its row that no cell spanning down from a row above holds. A rowspan
|
|
140
|
+
// stops at the last row of its section, as a browser draws it, and the grid is
|
|
141
|
+
// as wide as the widest right edge of any cell.
|
|
142
|
+
export function tableGrid(table) {
|
|
143
|
+
const taken = table.rows.map(() => []);
|
|
144
|
+
let columns = 0;
|
|
145
|
+
const rows = table.rows.map((row, index) => {
|
|
146
|
+
const sectionEnd = rowSectionEnd(table.rows, index);
|
|
147
|
+
let column = 0;
|
|
148
|
+
const cells = row.cells.map((cell) => {
|
|
149
|
+
while (taken[index][column]) {
|
|
150
|
+
column++;
|
|
151
|
+
}
|
|
152
|
+
const placed = { ...cell, row: index, column, rowSpan: Math.min(cell.rowSpan, sectionEnd - index) };
|
|
153
|
+
occupy(taken, placed);
|
|
154
|
+
column += placed.colSpan;
|
|
155
|
+
columns = Math.max(columns, column);
|
|
156
|
+
return placed;
|
|
157
|
+
});
|
|
158
|
+
return { ...row, cells };
|
|
159
|
+
});
|
|
160
|
+
return { rows, columns };
|
|
161
|
+
}
|
|
162
|
+
function tableSection(row) {
|
|
163
|
+
const section = row.parentElement?.nodeName;
|
|
164
|
+
return section === 'THEAD' ? 'head' : section === 'TFOOT' ? 'foot' : 'body';
|
|
165
|
+
}
|
|
166
|
+
// One th or td. A header cell's runs are bold, and every paragraph takes the
|
|
167
|
+
// cell's text-align unless it has its own: the default look centers a header
|
|
168
|
+
// cell and puts any other on the left.
|
|
169
|
+
function tableCell(cell) {
|
|
170
|
+
const header = cell.nodeName === 'TH';
|
|
171
|
+
const align = cellAlign(cell.style.textAlign) ?? (header ? 'center' : 'left');
|
|
172
|
+
const valign = cell.style.verticalAlign;
|
|
173
|
+
const paragraphs = [];
|
|
174
|
+
walkBlocks(cell, paragraphs, null, header ? { bold: true } : {});
|
|
175
|
+
return {
|
|
176
|
+
paragraphs: paragraphs.map((paragraph) => ({ ...paragraph, align: paragraph.align ?? align })),
|
|
177
|
+
colSpan: Math.max(1, cell.colSpan),
|
|
178
|
+
rowSpan: Math.max(1, cell.rowSpan),
|
|
179
|
+
row: 0,
|
|
180
|
+
column: 0,
|
|
181
|
+
align,
|
|
182
|
+
valign: valign === 'top' || valign === 'middle' || valign === 'bottom' ? valign : undefined,
|
|
183
|
+
fill: cell.style.backgroundColor ? hexColor(cell.style.backgroundColor) : undefined,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function cellAlign(value) {
|
|
187
|
+
return value === 'left' || value === 'center' || value === 'right' || value === 'justify' ? value : undefined;
|
|
188
|
+
}
|
|
189
|
+
// The index just past the last row of the section the row at index sits in.
|
|
190
|
+
function rowSectionEnd(rows, index) {
|
|
191
|
+
let end = index + 1;
|
|
192
|
+
while (end < rows.length && rows[end].section === rows[index].section) {
|
|
193
|
+
end++;
|
|
194
|
+
}
|
|
195
|
+
return end;
|
|
196
|
+
}
|
|
197
|
+
// Mark the grid slots a placed cell covers.
|
|
198
|
+
function occupy(taken, cell) {
|
|
199
|
+
for (let row = cell.row; row < cell.row + cell.rowSpan; row++) {
|
|
200
|
+
for (let column = cell.column; column < cell.column + cell.colSpan; column++) {
|
|
201
|
+
taken[row][column] = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// A table row as one line of text: its cells in order, a cell's own lines
|
|
206
|
+
// joined by a space.
|
|
207
|
+
function rowParagraph(row) {
|
|
208
|
+
return {
|
|
209
|
+
runs: row.cells.flatMap((cell, index) => [
|
|
210
|
+
...(index ? [{ text: TABLE_CELL_SEPARATOR }] : []),
|
|
211
|
+
...cell.paragraphs.flatMap((paragraph, line) => [...(line ? [{ text: ' ' }] : []), ...paragraph.runs]),
|
|
212
|
+
]),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// An empty paragraph is a blank line the canvas draws (<p><br></p>, or an empty
|
|
216
|
+
// <p>), so one at the start of the block keeps the words below it where the
|
|
217
|
+
// canvas puts them. At the end of the whole block it draws nothing, and is
|
|
218
|
+
// dropped so it never counts as running past the box. An empty paragraph
|
|
219
|
+
// before a table is not at the end.
|
|
220
|
+
function trimBlankEnd(blocks) {
|
|
221
|
+
const last = blocks[blocks.length - 1];
|
|
222
|
+
while (last?.kind === 'text' && last.paragraphs.length && !last.paragraphs[last.paragraphs.length - 1].runs.length) {
|
|
223
|
+
last.paragraphs.pop();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// base is the style every run starts from: bold for a header cell's words.
|
|
227
|
+
function walkBlocks(parent, paragraphs, list, base = {}) {
|
|
228
|
+
// Loose inline content between blocks (text straight under the block, an
|
|
229
|
+
// <li> or a cell) is gathered into a paragraph of its own.
|
|
49
230
|
let loose = null;
|
|
50
231
|
const flush = () => {
|
|
51
|
-
if (loose) {
|
|
232
|
+
if (loose && isShown(loose)) {
|
|
52
233
|
paragraphs.push(loose);
|
|
53
|
-
loose = null;
|
|
54
234
|
}
|
|
235
|
+
loose = null;
|
|
55
236
|
};
|
|
56
237
|
parent.childNodes.forEach((node) => {
|
|
57
238
|
const name = node.nodeName.toLowerCase();
|
|
58
|
-
if (name === 'ul' || name === 'ol') {
|
|
59
|
-
flush();
|
|
60
|
-
walkBlocks(node, paragraphs, name === 'ul' ? 'bullet' : 'number');
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (name === 'li') {
|
|
239
|
+
if (name === 'ul' || name === 'ol' || name === 'li' || name === 'p' || /^h[1-3]$/.test(name)) {
|
|
64
240
|
flush();
|
|
65
|
-
|
|
66
|
-
const nested = [];
|
|
67
|
-
// A list item's first paragraph IS the item; anything after it is its own
|
|
68
|
-
// line under the same bullet.
|
|
69
|
-
walkBlocks(node, nested, list);
|
|
70
|
-
const [first, ...rest] = nested.length ? nested : [item];
|
|
71
|
-
paragraphs.push({ ...first, bullet: list ?? 'bullet' }, ...rest);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (name === 'p' || /^h[1-3]$/.test(name)) {
|
|
75
|
-
flush();
|
|
76
|
-
const element = node;
|
|
77
|
-
const heading = name.startsWith('h') ? Number(name[1]) : undefined;
|
|
78
|
-
const paragraph = {
|
|
79
|
-
runs: [],
|
|
80
|
-
align: blockAlign(element),
|
|
81
|
-
bullet: undefined,
|
|
82
|
-
heading,
|
|
83
|
-
};
|
|
84
|
-
const base = heading
|
|
85
|
-
? { bold: true, fontSize: HEADING_TEXT_SIZES[heading] }
|
|
86
|
-
: {};
|
|
87
|
-
walkInline(node, base, paragraph, paragraphs);
|
|
88
|
-
paragraphs.push(paragraph);
|
|
241
|
+
walkBlock(node, paragraphs, list, base);
|
|
89
242
|
return;
|
|
90
243
|
}
|
|
91
244
|
loose = loose ?? { runs: [] };
|
|
92
|
-
walkInline(node,
|
|
245
|
+
walkInline(node, base, loose, paragraphs, true);
|
|
93
246
|
});
|
|
94
247
|
flush();
|
|
95
248
|
}
|
|
249
|
+
// Whether loose content's last line shows anything. Whitespace alone between
|
|
250
|
+
// blocks is not drawn, and a line a <br> ended was pushed when it ended, so a
|
|
251
|
+
// trailing <br> adds no empty line after it.
|
|
252
|
+
function isShown(loose) {
|
|
253
|
+
return loose.runs.some((run) => /[^ \t\n\r\f]/.test(run.text));
|
|
254
|
+
}
|
|
255
|
+
function walkBlock(element, paragraphs, list, base) {
|
|
256
|
+
const name = element.nodeName.toLowerCase();
|
|
257
|
+
if (name === 'ul' || name === 'ol') {
|
|
258
|
+
walkBlocks(element, paragraphs, name === 'ul' ? 'bullet' : 'number', base);
|
|
259
|
+
}
|
|
260
|
+
else if (name === 'li') {
|
|
261
|
+
const item = { runs: [], bullet: list ?? 'bullet' };
|
|
262
|
+
const nested = [];
|
|
263
|
+
// A list item's first paragraph IS the item; anything after it is its own
|
|
264
|
+
// line under the same bullet.
|
|
265
|
+
walkBlocks(element, nested, list, base);
|
|
266
|
+
const [first, ...rest] = nested.length ? nested : [item];
|
|
267
|
+
paragraphs.push({ ...first, bullet: list ?? 'bullet' }, ...rest);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
walkParagraph(element, paragraphs, base);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
// A p or a heading. A <br> ends a line, so its last line is pushed only when it
|
|
274
|
+
// holds words or no <br> came before it: <p><br></p> is one blank line,
|
|
275
|
+
// <p>a<br></p> one line and <p>a<br>b</p> two, as a browser draws them.
|
|
276
|
+
function walkParagraph(element, paragraphs, base) {
|
|
277
|
+
const name = element.nodeName.toLowerCase();
|
|
278
|
+
const heading = name.startsWith('h') ? Number(name[1]) : undefined;
|
|
279
|
+
const paragraph = {
|
|
280
|
+
runs: [],
|
|
281
|
+
align: blockAlign(element),
|
|
282
|
+
bullet: undefined,
|
|
283
|
+
heading,
|
|
284
|
+
};
|
|
285
|
+
const style = heading
|
|
286
|
+
? { ...base, bold: true, fontSize: HEADING_TEXT_SIZES[heading] }
|
|
287
|
+
: base;
|
|
288
|
+
const breaks = walkInline(element, style, paragraph, paragraphs);
|
|
289
|
+
if (paragraph.runs.length || !breaks) {
|
|
290
|
+
paragraphs.push(paragraph);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
96
293
|
// Accumulate inline styles down the tree. A <br> ends the current line: the
|
|
97
294
|
// runs after it start a new paragraph with the same alignment and bullet.
|
|
295
|
+
// Returns how many lines a <br> ended.
|
|
98
296
|
function walkInline(node, style, paragraph, paragraphs, isSelf = false) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (child.nodeType !== Node.ELEMENT_NODE) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const element = child;
|
|
111
|
-
const name = element.nodeName.toLowerCase();
|
|
112
|
-
if (name === 'br') {
|
|
113
|
-
paragraphs.push({ ...paragraph, runs: [...paragraph.runs] });
|
|
114
|
-
paragraph.runs.length = 0;
|
|
115
|
-
return;
|
|
297
|
+
const nodes = isSelf ? [node] : Array.from(node.childNodes);
|
|
298
|
+
return nodes.reduce((breaks, child) => breaks + walkInlineNode(child, style, paragraph, paragraphs), 0);
|
|
299
|
+
}
|
|
300
|
+
function walkInlineNode(node, style, paragraph, paragraphs) {
|
|
301
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
302
|
+
const text = node.textContent ?? '';
|
|
303
|
+
if (text) {
|
|
304
|
+
paragraph.runs.push({ ...style, text });
|
|
116
305
|
}
|
|
117
|
-
|
|
118
|
-
};
|
|
119
|
-
if (isSelf) {
|
|
120
|
-
visit(node);
|
|
306
|
+
return 0;
|
|
121
307
|
}
|
|
122
|
-
|
|
123
|
-
|
|
308
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
309
|
+
return 0;
|
|
310
|
+
}
|
|
311
|
+
const element = node;
|
|
312
|
+
if (element.nodeName.toLowerCase() === 'br') {
|
|
313
|
+
paragraphs.push({ ...paragraph, runs: [...paragraph.runs] });
|
|
314
|
+
paragraph.runs.length = 0;
|
|
315
|
+
return 1;
|
|
124
316
|
}
|
|
317
|
+
return walkInline(element, { ...style, ...inlineStyle(element) }, paragraph, paragraphs);
|
|
125
318
|
}
|
|
126
319
|
function inlineStyle(element) {
|
|
127
320
|
const name = element.nodeName.toLowerCase();
|
|
@@ -142,12 +335,15 @@ function inlineStyle(element) {
|
|
|
142
335
|
style.link = element.getAttribute('href') ?? undefined;
|
|
143
336
|
style.underline = true;
|
|
144
337
|
}
|
|
338
|
+
// What is no color leaves the color the run inherits.
|
|
145
339
|
const css = element.style;
|
|
146
|
-
|
|
147
|
-
|
|
340
|
+
const color = css.color ? hexColor(css.color) : undefined;
|
|
341
|
+
const highlight = css.backgroundColor ? hexColor(css.backgroundColor) : undefined;
|
|
342
|
+
if (color) {
|
|
343
|
+
style.color = color;
|
|
148
344
|
}
|
|
149
|
-
if (
|
|
150
|
-
style.highlight =
|
|
345
|
+
if (highlight) {
|
|
346
|
+
style.highlight = highlight;
|
|
151
347
|
}
|
|
152
348
|
if (css.fontSize) {
|
|
153
349
|
style.fontSize = points(css.fontSize);
|
|
@@ -192,24 +388,36 @@ function points(value) {
|
|
|
192
388
|
}
|
|
193
389
|
// Any CSS color the allowlist lets through (hex, rgb(), a name) as #rrggbb —
|
|
194
390
|
// the one form both exports accept. The browser resolves it, so a named color
|
|
195
|
-
// comes out exactly as the canvas painted it.
|
|
391
|
+
// comes out exactly as the canvas painted it. A value that is no color of its
|
|
392
|
+
// own (inherit, currentcolor, a typo) or paints nothing (transparent, an alpha
|
|
393
|
+
// of 0) is undefined, so an export never paints it black.
|
|
196
394
|
let colorContext = null;
|
|
197
395
|
function hexColor(value) {
|
|
198
396
|
colorContext = colorContext ?? document.createElement('canvas').getContext('2d');
|
|
199
|
-
if (!colorContext) {
|
|
397
|
+
if (!colorContext || /^\s*currentcolor\s*$/i.test(value)) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
// A value the canvas cannot read leaves the color set before it, so it reads
|
|
401
|
+
// back one way over black and another over white. (currentcolor reads as
|
|
402
|
+
// black over both, hence the check above.)
|
|
403
|
+
const resolved = resolveColor(colorContext, '#000000', value);
|
|
404
|
+
if (resolved !== resolveColor(colorContext, '#ffffff', value)) {
|
|
200
405
|
return undefined;
|
|
201
406
|
}
|
|
202
|
-
colorContext.fillStyle = '#000000';
|
|
203
|
-
colorContext.fillStyle = value;
|
|
204
|
-
const resolved = String(colorContext.fillStyle);
|
|
205
407
|
if (resolved.startsWith('#')) {
|
|
206
408
|
return resolved;
|
|
207
409
|
}
|
|
208
410
|
// rgba(...) for a translucent color — drop the alpha, keep the hue.
|
|
209
|
-
const
|
|
210
|
-
return
|
|
211
|
-
?
|
|
212
|
-
:
|
|
411
|
+
const [red, green, blue, alpha] = resolved.match(/[\d.]+/g)?.map(Number) ?? [];
|
|
412
|
+
return blue === undefined || alpha === 0
|
|
413
|
+
? undefined
|
|
414
|
+
: `#${[red, green, blue].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`;
|
|
415
|
+
}
|
|
416
|
+
// What the canvas reads value as, set over seed.
|
|
417
|
+
function resolveColor(context, seed, value) {
|
|
418
|
+
context.fillStyle = seed;
|
|
419
|
+
context.fillStyle = value;
|
|
420
|
+
return String(context.fillStyle);
|
|
213
421
|
}
|
|
214
422
|
export function escapeHtml(value) {
|
|
215
423
|
return value
|
|
@@ -218,4 +426,4 @@ export function escapeHtml(value) {
|
|
|
218
426
|
.replace(/>/g, '>')
|
|
219
427
|
.replace(/"/g, '"');
|
|
220
428
|
}
|
|
221
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy90ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRFQUE0RTtBQUM1RSw4Q0FBOEM7QUFDOUMsRUFBRTtBQUNGLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UseUVBQXlFO0FBQ3pFLDBFQUEwRTtBQUcxRSw4RUFBOEU7QUFDOUUsb0VBQW9FO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztBQUNwQyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBMkIsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztBQWlDNUMsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSw2Q0FBNkM7QUFDN0MsTUFBTSxNQUFNLEdBQTBEO0lBQ3BFLGFBQWEsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7SUFDdEQsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUTtJQUMxQyxhQUFhLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVO0NBQy9DLENBQUM7QUFFRiw2RUFBNkU7QUFDN0Usa0RBQWtEO0FBQ2xELE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBWSxFQUFFLE9BQXlCO0lBQ3BFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywyQkFBMkIsRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFhLEVBQUUsRUFBRTtRQUN4RSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFFekMsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSw0RUFBNEU7QUFDNUUsTUFBTSxVQUFVLGNBQWMsQ0FBQyxJQUFZLEVBQUUsT0FBeUI7SUFDcEUsTUFBTSxRQUFRLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQyxlQUFlLENBQUMsU0FBUyxjQUFjLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDL0csTUFBTSxVQUFVLEdBQW9CLEVBQUUsQ0FBQztJQUV2QyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFNUMsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFO0lBQzVDLDRFQUE0RTtJQUM1RSx1Q0FBdUM7SUFDdkMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVELGlGQUFpRjtBQUNqRixNQUFNLFVBQVUsU0FBUyxDQUFDLElBQVksRUFBRSxPQUF5QjtJQUMvRCxPQUFPLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO1NBQ2pDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDbEUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2hCLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FDakIsTUFBWSxFQUNaLFVBQTJCLEVBQzNCLElBQWdDO0lBRWhDLDJFQUEyRTtJQUMzRSwyQ0FBMkM7SUFDM0MsSUFBSSxLQUFLLEdBQXlCLElBQUksQ0FBQztJQUN2QyxNQUFNLEtBQUssR0FBRyxHQUFHLEVBQUU7UUFDakIsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ2pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFekMsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuQyxLQUFLLEVBQUUsQ0FBQztZQUNSLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFbEUsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNsQixLQUFLLEVBQUUsQ0FBQztZQUNSLE1BQU0sSUFBSSxHQUFrQixFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNuRSxNQUFNLE1BQU0sR0FBb0IsRUFBRSxDQUFDO1lBQ25DLDBFQUEwRTtZQUMxRSw4QkFBOEI7WUFDOUIsVUFBVSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0IsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6RCxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxRQUFRLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBRWpFLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxQyxLQUFLLEVBQUUsQ0FBQztZQUNSLE1BQU0sT0FBTyxHQUFHLElBQW1CLENBQUM7WUFDcEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDbkUsTUFBTSxTQUFTLEdBQWtCO2dCQUMvQixJQUFJLEVBQUUsRUFBRTtnQkFDUixLQUFLLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFDMUIsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLE9BQU87YUFDUixDQUFDO1lBQ0YsTUFBTSxJQUFJLEdBQXFCLE9BQU87Z0JBQ3BDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUN2RCxDQUFDLENBQUMsRUFBRSxDQUFDO1lBRVAsVUFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzlDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFM0IsT0FBTztRQUNULENBQUM7UUFFRCxLQUFLLEdBQUcsS0FBSyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQzlCLFVBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLEVBQUUsQ0FBQztBQUNWLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsMEVBQTBFO0FBQzFFLFNBQVMsVUFBVSxDQUNqQixJQUFVLEVBQ1YsS0FBdUIsRUFDdkIsU0FBd0IsRUFDeEIsVUFBMkIsRUFDM0IsTUFBTSxHQUFHLEtBQUs7SUFFZCxNQUFNLEtBQUssR0FBRyxDQUFDLEtBQVcsRUFBRSxFQUFFO1FBQzVCLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7WUFDckMsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDVCxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUVELE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLEtBQW9CLENBQUM7UUFDckMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUU1QyxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNsQixVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzdELFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUUxQixPQUFPO1FBQ1QsQ0FBQztRQUVELFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLEtBQUssRUFBRSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNwRixDQUFDLENBQUM7SUFFRixJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2QsQ0FBQztTQUFNLENBQUM7UUFDTixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLE9BQW9CO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDNUMsTUFBTSxLQUFLLEdBQXFCLEVBQUUsQ0FBQztJQUVuQyxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QixLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNwQixDQUFDO0lBQ0QsSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDbEIsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDdEIsQ0FBQztJQUNELElBQUksSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxJQUFJLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNqQixLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztJQUN0QixDQUFDO0lBQ0QsSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDakIsS0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFNBQVMsQ0FBQztRQUN2RCxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN6QixDQUFDO0lBRUQsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUMxQixJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkLEtBQUssQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBQ0QsSUFBSSxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsS0FBSyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxJQUFJLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNqQixLQUFLLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUNELElBQUksR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ25CLEtBQUssQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsS0FBSyxNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxHQUFHLENBQUM7SUFDMUUsQ0FBQztJQUNELElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2xCLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFNBQVMsS0FBSyxRQUFRLENBQUM7SUFDNUMsQ0FBQztJQUNELElBQUksR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0QsS0FBSyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBQ0QsSUFBSSxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbkIsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzVFLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxPQUFvQjtJQUN0QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUV0QyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLE9BQU8sSUFBSSxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM1RixDQUFDO0FBRUQsNEVBQTRFO0FBQzVFLDBEQUEwRDtBQUMxRCxTQUFTLE1BQU0sQ0FBQyxLQUFhO0lBQzNCLE1BQU0sS0FBSyxHQUFHLDRCQUE0QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM5RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlCLFFBQVEsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDakIsS0FBSyxJQUFJO1lBQ1AsT0FBTyxJQUFJLENBQUM7UUFDZCxLQUFLLElBQUk7WUFDUCxPQUFPLElBQUksR0FBRyxJQUFJLENBQUM7UUFDckIsS0FBSyxHQUFHO1lBQ04sT0FBTyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztRQUMxQztZQUNFLE9BQU8sSUFBSSxHQUFHLGlCQUFpQixDQUFDO0lBQ3BDLENBQUM7QUFDSCxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLDhFQUE4RTtBQUM5RSw4Q0FBOEM7QUFDOUMsSUFBSSxZQUFZLEdBQW9DLElBQUksQ0FBQztBQUV6RCxTQUFTLFFBQVEsQ0FBQyxLQUFhO0lBQzdCLFlBQVksR0FBRyxZQUFZLElBQUksUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakYsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxZQUFZLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUNuQyxZQUFZLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRWhELElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxvRUFBb0U7SUFDcEUsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFMUUsT0FBTyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUM7UUFDMUIsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRTtRQUM3RixDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2hCLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFDLEtBQWE7SUFDdEMsT0FBTyxLQUFLO1NBQ1QsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7U0FDdEIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVGV4dCBibG9ja3Mg4oCUIHNoYXJlZCBieSB0aGUgY2FudmFzIGFuZCBib3RoIGV4cG9ydHMsIHNvIGEgYmxvY2sgcmVhZHMgdGhlXG4vLyBzYW1lIG9uIHNjcmVlbiwgaW4gdGhlIGRlY2sgYW5kIGluIHRoZSBQREYuXG4vL1xuLy8gQSBibG9jaydzIGh0bWwgYXJyaXZlcyBhbHJlYWR5IHJlYnVpbHQgc2VydmVyLXNpZGUgZnJvbSBhIHNtYWxsIGFsbG93bGlzdFxuLy8gKFJlcG9ydFRleHRIdG1sKTogcCwgaDEtaDMsIHN0cm9uZywgZW0sIHUsIHMsIHVsL29sL2xpLCBiciwgYSwgYW5kIHNwYW4gd2l0aFxuLy8gY29sb3IgLyBiYWNrZ3JvdW5kLWNvbG9yIC8gZm9udC1zaXplIC8gZm9udC13ZWlnaHQgLyBmb250LWZhbWlseSwgcGx1c1xuLy8gdGV4dC1hbGlnbiBvbiBhIGJsb2NrLiBFdmVyeXRoaW5nIGhlcmUgb25seSBoYXMgdG8gdW5kZXJzdGFuZCB0aGF0IHNldC5cblxuXG4vLyBCb2R5IHRleHQgc2l6ZSwgcG9pbnRzLCBhbmQgdGhlIGhlYWRpbmcgc2l6ZXMg4oCUIHRoZSBzYW1lIG51bWJlcnMgdGhlIGNhbnZhc1xuLy8gc3R5bGVzaGVldCB1c2VzLCBzbyBhbiB1bnN0eWxlZCBwYXJhZ3JhcGggaXMgb25lIHNpemUgZXZlcnl3aGVyZS5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RFWFRfU0laRSA9IDEyO1xuZXhwb3J0IGNvbnN0IEhFQURJTkdfVEVYVF9TSVpFUzogUmVjb3JkPG51bWJlciwgbnVtYmVyPiA9IHsgMTogMjQsIDI6IDE4LCAzOiAxNCB9O1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEVYVF9DT0xPUiA9ICcjMWYyOTMzJztcblxuLy8gV2hhdCB0aGUgdG9rZW5zIGluIGEgYmxvY2sncyBodG1sIGFyZSBmaWxsZWQgd2l0aCwgcGVyIHBhZ2UuXG5leHBvcnQgaW50ZXJmYWNlIFRleHRUb2tlbkNvbnRleHQge1xuICBwYWdlTnVtYmVyOiBudW1iZXI7XG4gIHBhZ2VOYW1lOiBzdHJpbmc7XG4gIHJlcG9ydE5hbWU6IHN0cmluZztcbn1cblxuLy8gT25lIHN0eWxlZCBzdHJldGNoIG9mIHRleHQuXG5leHBvcnQgaW50ZXJmYWNlIFRleHRSdW4ge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGJvbGQ/OiBib29sZWFuO1xuICBpdGFsaWM/OiBib29sZWFuO1xuICB1bmRlcmxpbmU/OiBib29sZWFuO1xuICBzdHJpa2U/OiBib29sZWFuO1xuICAvLyAjcnJnZ2JiXG4gIGNvbG9yPzogc3RyaW5nO1xuICBoaWdobGlnaHQ/OiBzdHJpbmc7XG4gIC8vIHBvaW50c1xuICBmb250U2l6ZT86IG51bWJlcjtcbiAgZm9udEZhY2U/OiBzdHJpbmc7XG4gIGxpbms/OiBzdHJpbmc7XG59XG5cbi8vIE9uZSBsaW5lLXN0YXJ0aW5nIGJsb2NrOiBhIHBhcmFncmFwaCwgYSBoZWFkaW5nIG9yIGEgbGlzdCBpdGVtLlxuZXhwb3J0IGludGVyZmFjZSBUZXh0UGFyYWdyYXBoIHtcbiAgcnVuczogVGV4dFJ1bltdO1xuICBhbGlnbj86ICdsZWZ0JyB8ICdjZW50ZXInIHwgJ3JpZ2h0JyB8ICdqdXN0aWZ5JztcbiAgYnVsbGV0PzogJ2J1bGxldCcgfCAnbnVtYmVyJztcbiAgaGVhZGluZz86IG51bWJlcjtcbn1cblxuLy8gVGhlIHRva2VucyBhIGJsb2NrIG1heSBjYXJyeSwgd2l0aCB3aGF0IGZpbGxzIGVhY2guIHt7cGFnZS5udW1iZXJ9fSBpcyB0aGVcbi8vIHBhZ2UncyBwb3NpdGlvbiBhbW9uZyB0aGUgcmVwb3J0J3MgcGFnZXMgKDEtYmFzZWQpLCB3aGljaCBpcyB3aGF0IG1ha2VzIGFcbi8vIHNoYXJlZCBmb290ZXIgbnVtYmVyIGV2ZXJ5IHBhZ2UgY29ycmVjdGx5LlxuY29uc3QgVE9LRU5TOiBSZWNvcmQ8c3RyaW5nLCAoY29udGV4dDogVGV4dFRva2VuQ29udGV4dCkgPT4gc3RyaW5nPiA9IHtcbiAgJ3BhZ2UubnVtYmVyJzogKGNvbnRleHQpID0+IFN0cmluZyhjb250ZXh0LnBhZ2VOdW1iZXIpLFxuICAncGFnZS5uYW1lJzogKGNvbnRleHQpID0+IGNvbnRleHQucGFnZU5hbWUsXG4gICdyZXBvcnQubmFtZSc6IChjb250ZXh0KSA9PiBjb250ZXh0LnJlcG9ydE5hbWUsXG59O1xuXG4vLyBSZXBsYWNlIGV2ZXJ5IHt7dG9rZW59fSBpbiB0aGUgaHRtbC4gVmFsdWVzIGFyZSBodG1sLWVzY2FwZWQ6IGEgcGFnZSBuYW1lZFxuLy8gXCJSJkQgPGRyYWZ0PlwiIG11c3QgcmVhZCBhcyB0aGF0LCBub3QgYXMgbWFya3VwLlxuZXhwb3J0IGZ1bmN0aW9uIGZpbGxUZXh0VG9rZW5zKGh0bWw6IHN0cmluZywgY29udGV4dDogVGV4dFRva2VuQ29udGV4dCk6IHN0cmluZyB7XG4gIHJldHVybiBodG1sLnJlcGxhY2UoL1xce1xce1xccyooW2Etei5dKylcXHMqXFx9XFx9L2dpLCAobWF0Y2gsIHRva2VuOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBmaWxsID0gVE9LRU5TW3Rva2VuLnRvTG93ZXJDYXNlKCldO1xuXG4gICAgcmV0dXJuIGZpbGwgPyBlc2NhcGVIdG1sKGZpbGwoY29udGV4dCkpIDogbWF0Y2g7XG4gIH0pO1xufVxuXG4vLyBXYWxrIGEgYmxvY2sncyBodG1sIGludG8gcGFyYWdyYXBocyBvZiBzdHlsZWQgcnVucyDigJQgdGhlIHNoYXBlIGJvdGggZXhwb3J0c1xuLy8gZHJhdyBmcm9tLiBUb2tlbnMgYXJlIGZpbGxlZCBmaXJzdCBzbyBhIHBhZ2UgbnVtYmVyIGlzIGp1c3QgdGV4dCBieSB0aGVuLlxuZXhwb3J0IGZ1bmN0aW9uIHRleHRQYXJhZ3JhcGhzKGh0bWw6IHN0cmluZywgY29udGV4dDogVGV4dFRva2VuQ29udGV4dCk6IFRleHRQYXJhZ3JhcGhbXSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhgPGJvZHk+JHtmaWxsVGV4dFRva2VucyhodG1sLCBjb250ZXh0KX08L2JvZHk+YCwgJ3RleHQvaHRtbCcpO1xuICBjb25zdCBwYXJhZ3JhcGhzOiBUZXh0UGFyYWdyYXBoW10gPSBbXTtcblxuICB3YWxrQmxvY2tzKGRvY3VtZW50LmJvZHksIHBhcmFncmFwaHMsIG51bGwpO1xuXG4gIHJldHVybiBwYXJhZ3JhcGhzLmZpbHRlcigocGFyYWdyYXBoLCBpbmRleCkgPT5cbiAgICAvLyBLZWVwIGFuIGVtcHR5IHBhcmFncmFwaCBiZXR3ZWVuIHR3byBvdGhlcnMgKGEgZGVsaWJlcmF0ZSBibGFuayBsaW5lKSwgYnV0XG4gICAgLy8gbm90IG9uZSBsZWZ0IGRhbmdsaW5nIGF0IGVpdGhlciBlbmQuXG4gICAgcGFyYWdyYXBoLnJ1bnMubGVuZ3RoIHx8IChpbmRleCA+IDAgJiYgaW5kZXggPCBwYXJhZ3JhcGhzLmxlbmd0aCAtIDEpKTtcbn1cblxuLy8gVGhlIGh0bWwgYXMgcGxhaW4gdGV4dCDigJQgd2hhdCBhIGJsb2NrIHNheXMsIGZvciBhbnl0aGluZyB0aGF0IGNhbm5vdCBzdHlsZSBpdC5cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0UGxhaW4oaHRtbDogc3RyaW5nLCBjb250ZXh0OiBUZXh0VG9rZW5Db250ZXh0KTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHRQYXJhZ3JhcGhzKGh0bWwsIGNvbnRleHQpXG4gICAgLm1hcCgocGFyYWdyYXBoKSA9PiBwYXJhZ3JhcGgucnVucy5tYXAoKHJ1bikgPT4gcnVuLnRleHQpLmpvaW4oJycpKVxuICAgIC5qb2luKCdcXG4nKTtcbn1cblxuZnVuY3Rpb24gd2Fsa0Jsb2NrcyhcbiAgcGFyZW50OiBOb2RlLFxuICBwYXJhZ3JhcGhzOiBUZXh0UGFyYWdyYXBoW10sXG4gIGxpc3Q6ICdidWxsZXQnIHwgJ251bWJlcicgfCBudWxsLFxuKTogdm9pZCB7XG4gIC8vIExvb3NlIGlubGluZSBjb250ZW50IGJldHdlZW4gYmxvY2tzICh0ZXh0IHN0cmFpZ2h0IHVuZGVyIDxib2R5PiBvciA8bGk+KVxuICAvLyBpcyBnYXRoZXJlZCBpbnRvIGEgcGFyYWdyYXBoIG9mIGl0cyBvd24uXG4gIGxldCBsb29zZTogVGV4dFBhcmFncmFwaCB8IG51bGwgPSBudWxsO1xuICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICBpZiAobG9vc2UpIHtcbiAgICAgIHBhcmFncmFwaHMucHVzaChsb29zZSk7XG4gICAgICBsb29zZSA9IG51bGw7XG4gICAgfVxuICB9O1xuXG4gIHBhcmVudC5jaGlsZE5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICBjb25zdCBuYW1lID0gbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgaWYgKG5hbWUgPT09ICd1bCcgfHwgbmFtZSA9PT0gJ29sJykge1xuICAgICAgZmx1c2goKTtcbiAgICAgIHdhbGtCbG9ja3Mobm9kZSwgcGFyYWdyYXBocywgbmFtZSA9PT0gJ3VsJyA/ICdidWxsZXQnIDogJ251bWJlcicpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgPT09ICdsaScpIHtcbiAgICAgIGZsdXNoKCk7XG4gICAgICBjb25zdCBpdGVtOiBUZXh0UGFyYWdyYXBoID0geyBydW5zOiBbXSwgYnVsbGV0OiBsaXN0ID8/ICdidWxsZXQnIH07XG4gICAgICBjb25zdCBuZXN0ZWQ6IFRleHRQYXJhZ3JhcGhbXSA9IFtdO1xuICAgICAgLy8gQSBsaXN0IGl0ZW0ncyBmaXJzdCBwYXJhZ3JhcGggSVMgdGhlIGl0ZW07IGFueXRoaW5nIGFmdGVyIGl0IGlzIGl0cyBvd25cbiAgICAgIC8vIGxpbmUgdW5kZXIgdGhlIHNhbWUgYnVsbGV0LlxuICAgICAgd2Fsa0Jsb2Nrcyhub2RlLCBuZXN0ZWQsIGxpc3QpO1xuICAgICAgY29uc3QgW2ZpcnN0LCAuLi5yZXN0XSA9IG5lc3RlZC5sZW5ndGggPyBuZXN0ZWQgOiBbaXRlbV07XG4gICAgICBwYXJhZ3JhcGhzLnB1c2goeyAuLi5maXJzdCwgYnVsbGV0OiBsaXN0ID8/ICdidWxsZXQnIH0sIC4uLnJlc3QpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgPT09ICdwJyB8fCAvXmhbMS0zXSQvLnRlc3QobmFtZSkpIHtcbiAgICAgIGZsdXNoKCk7XG4gICAgICBjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGNvbnN0IGhlYWRpbmcgPSBuYW1lLnN0YXJ0c1dpdGgoJ2gnKSA/IE51bWJlcihuYW1lWzFdKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHBhcmFncmFwaDogVGV4dFBhcmFncmFwaCA9IHtcbiAgICAgICAgcnVuczogW10sXG4gICAgICAgIGFsaWduOiBibG9ja0FsaWduKGVsZW1lbnQpLFxuICAgICAgICBidWxsZXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGluZyxcbiAgICAgIH07XG4gICAgICBjb25zdCBiYXNlOiBQYXJ0aWFsPFRleHRSdW4+ID0gaGVhZGluZ1xuICAgICAgICA/IHsgYm9sZDogdHJ1ZSwgZm9udFNpemU6IEhFQURJTkdfVEVYVF9TSVpFU1toZWFkaW5nXSB9XG4gICAgICAgIDoge307XG5cbiAgICAgIHdhbGtJbmxpbmUobm9kZSwgYmFzZSwgcGFyYWdyYXBoLCBwYXJhZ3JhcGhzKTtcbiAgICAgIHBhcmFncmFwaHMucHVzaChwYXJhZ3JhcGgpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9vc2UgPSBsb29zZSA/PyB7IHJ1bnM6IFtdIH07XG4gICAgd2Fsa0lubGluZShub2RlLCB7fSwgbG9vc2UsIHBhcmFncmFwaHMsIHRydWUpO1xuICB9KTtcblxuICBmbHVzaCgpO1xufVxuXG4vLyBBY2N1bXVsYXRlIGlubGluZSBzdHlsZXMgZG93biB0aGUgdHJlZS4gQSA8YnI+IGVuZHMgdGhlIGN1cnJlbnQgbGluZTogdGhlXG4vLyBydW5zIGFmdGVyIGl0IHN0YXJ0IGEgbmV3IHBhcmFncmFwaCB3aXRoIHRoZSBzYW1lIGFsaWdubWVudCBhbmQgYnVsbGV0LlxuZnVuY3Rpb24gd2Fsa0lubGluZShcbiAgbm9kZTogTm9kZSxcbiAgc3R5bGU6IFBhcnRpYWw8VGV4dFJ1bj4sXG4gIHBhcmFncmFwaDogVGV4dFBhcmFncmFwaCxcbiAgcGFyYWdyYXBoczogVGV4dFBhcmFncmFwaFtdLFxuICBpc1NlbGYgPSBmYWxzZSxcbik6IHZvaWQge1xuICBjb25zdCB2aXNpdCA9IChjaGlsZDogTm9kZSkgPT4ge1xuICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgIGNvbnN0IHRleHQgPSBjaGlsZC50ZXh0Q29udGVudCA/PyAnJztcbiAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgIHBhcmFncmFwaC5ydW5zLnB1c2goeyAuLi5zdHlsZSwgdGV4dCB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjaGlsZC5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gY2hpbGQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgbmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChuYW1lID09PSAnYnInKSB7XG4gICAgICBwYXJhZ3JhcGhzLnB1c2goeyAuLi5wYXJhZ3JhcGgsIHJ1bnM6IFsuLi5wYXJhZ3JhcGgucnVuc10gfSk7XG4gICAgICBwYXJhZ3JhcGgucnVucy5sZW5ndGggPSAwO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2Fsa0lubGluZShlbGVtZW50LCB7IC4uLnN0eWxlLCAuLi5pbmxpbmVTdHlsZShlbGVtZW50KSB9LCBwYXJhZ3JhcGgsIHBhcmFncmFwaHMpO1xuICB9O1xuXG4gIGlmIChpc1NlbGYpIHtcbiAgICB2aXNpdChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICBub2RlLmNoaWxkTm9kZXMuZm9yRWFjaCh2aXNpdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5saW5lU3R5bGUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBQYXJ0aWFsPFRleHRSdW4+IHtcbiAgY29uc3QgbmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgY29uc3Qgc3R5bGU6IFBhcnRpYWw8VGV4dFJ1bj4gPSB7fTtcblxuICBpZiAobmFtZSA9PT0gJ3N0cm9uZycpIHtcbiAgICBzdHlsZS5ib2xkID0gdHJ1ZTtcbiAgfVxuICBpZiAobmFtZSA9PT0gJ2VtJykge1xuICAgIHN0eWxlLml0YWxpYyA9IHRydWU7XG4gIH1cbiAgaWYgKG5hbWUgPT09ICd1Jykge1xuICAgIHN0eWxlLnVuZGVybGluZSA9IHRydWU7XG4gIH1cbiAgaWYgKG5hbWUgPT09ICdzJykge1xuICAgIHN0eWxlLnN0cmlrZSA9IHRydWU7XG4gIH1cbiAgaWYgKG5hbWUgPT09ICdhJykge1xuICAgIHN0eWxlLmxpbmsgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpID8/IHVuZGVmaW5lZDtcbiAgICBzdHlsZS51bmRlcmxpbmUgPSB0cnVlO1xuICB9XG5cbiAgY29uc3QgY3NzID0gZWxlbWVudC5zdHlsZTtcbiAgaWYgKGNzcy5jb2xvcikge1xuICAgIHN0eWxlLmNvbG9yID0gaGV4Q29sb3IoY3NzLmNvbG9yKTtcbiAgfVxuICBpZiAoY3NzLmJhY2tncm91bmRDb2xvcikge1xuICAgIHN0eWxlLmhpZ2hsaWdodCA9IGhleENvbG9yKGNzcy5iYWNrZ3JvdW5kQ29sb3IpO1xuICB9XG4gIGlmIChjc3MuZm9udFNpemUpIHtcbiAgICBzdHlsZS5mb250U2l6ZSA9IHBvaW50cyhjc3MuZm9udFNpemUpO1xuICB9XG4gIGlmIChjc3MuZm9udFdlaWdodCkge1xuICAgIHN0eWxlLmJvbGQgPSBjc3MuZm9udFdlaWdodCA9PT0gJ2JvbGQnIHx8IE51bWJlcihjc3MuZm9udFdlaWdodCkgPj0gNjAwO1xuICB9XG4gIGlmIChjc3MuZm9udFN0eWxlKSB7XG4gICAgc3R5bGUuaXRhbGljID0gY3NzLmZvbnRTdHlsZSA9PT0gJ2l0YWxpYyc7XG4gIH1cbiAgaWYgKGNzcy50ZXh0RGVjb3JhdGlvbikge1xuICAgIHN0eWxlLnVuZGVybGluZSA9IGNzcy50ZXh0RGVjb3JhdGlvbi5pbmNsdWRlcygndW5kZXJsaW5lJyk7XG4gICAgc3R5bGUuc3RyaWtlID0gY3NzLnRleHREZWNvcmF0aW9uLmluY2x1ZGVzKCdsaW5lLXRocm91Z2gnKTtcbiAgfVxuICBpZiAoY3NzLmZvbnRGYW1pbHkpIHtcbiAgICBzdHlsZS5mb250RmFjZSA9IGNzcy5mb250RmFtaWx5LnNwbGl0KCcsJylbMF0ucmVwbGFjZSgvW1wiJ10vZywgJycpLnRyaW0oKTtcbiAgfVxuXG4gIHJldHVybiBzdHlsZTtcbn1cblxuZnVuY3Rpb24gYmxvY2tBbGlnbihlbGVtZW50OiBIVE1MRWxlbWVudCk6IFRleHRQYXJhZ3JhcGhbJ2FsaWduJ10ge1xuICBjb25zdCBhbGlnbiA9IGVsZW1lbnQuc3R5bGUudGV4dEFsaWduO1xuXG4gIHJldHVybiBhbGlnbiA9PT0gJ2NlbnRlcicgfHwgYWxpZ24gPT09ICdyaWdodCcgfHwgYWxpZ24gPT09ICdqdXN0aWZ5JyA/IGFsaWduIDogdW5kZWZpbmVkO1xufVxuXG4vLyBBIENTUyBmb250LXNpemUgaW4gcG9pbnRzLiBUaGUgY2FudmFzIHJlbmRlcnMgYXQgOTZweCBwZXIgaW5jaCwgc28gMXB4IGlzXG4vLyBleGFjdGx5IDAuNzVwdDsgZW0vcmVtLyUgYXJlIHJlbGF0aXZlIHRvIHRoZSBib2R5IHNpemUuXG5mdW5jdGlvbiBwb2ludHModmFsdWU6IHN0cmluZyk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG1hdGNoID0gL14oW1xcZC5dKykocHR8cHh8ZW18cmVtfCUpJC8uZXhlYyh2YWx1ZS50cmltKCkpO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHNpemUgPSBOdW1iZXIobWF0Y2hbMV0pO1xuICBzd2l0Y2ggKG1hdGNoWzJdKSB7XG4gICAgY2FzZSAncHQnOlxuICAgICAgcmV0dXJuIHNpemU7XG4gICAgY2FzZSAncHgnOlxuICAgICAgcmV0dXJuIHNpemUgKiAwLjc1O1xuICAgIGNhc2UgJyUnOlxuICAgICAgcmV0dXJuIChzaXplIC8gMTAwKSAqIERFRkFVTFRfVEVYVF9TSVpFO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc2l6ZSAqIERFRkFVTFRfVEVYVF9TSVpFO1xuICB9XG59XG5cbi8vIEFueSBDU1MgY29sb3IgdGhlIGFsbG93bGlzdCBsZXRzIHRocm91Z2ggKGhleCwgcmdiKCksIGEgbmFtZSkgYXMgI3JyZ2diYiDigJRcbi8vIHRoZSBvbmUgZm9ybSBib3RoIGV4cG9ydHMgYWNjZXB0LiBUaGUgYnJvd3NlciByZXNvbHZlcyBpdCwgc28gYSBuYW1lZCBjb2xvclxuLy8gY29tZXMgb3V0IGV4YWN0bHkgYXMgdGhlIGNhbnZhcyBwYWludGVkIGl0LlxubGV0IGNvbG9yQ29udGV4dDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCA9IG51bGw7XG5cbmZ1bmN0aW9uIGhleENvbG9yKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb2xvckNvbnRleHQgPSBjb2xvckNvbnRleHQgPz8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcbiAgaWYgKCFjb2xvckNvbnRleHQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29sb3JDb250ZXh0LmZpbGxTdHlsZSA9ICcjMDAwMDAwJztcbiAgY29sb3JDb250ZXh0LmZpbGxTdHlsZSA9IHZhbHVlO1xuICBjb25zdCByZXNvbHZlZCA9IFN0cmluZyhjb2xvckNvbnRleHQuZmlsbFN0eWxlKTtcblxuICBpZiAocmVzb2x2ZWQuc3RhcnRzV2l0aCgnIycpKSB7XG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgLy8gcmdiYSguLi4pIGZvciBhIHRyYW5zbHVjZW50IGNvbG9yIOKAlCBkcm9wIHRoZSBhbHBoYSwga2VlcCB0aGUgaHVlLlxuICBjb25zdCBjaGFubmVscyA9IHJlc29sdmVkLm1hdGNoKC9bXFxkLl0rL2cpPy5zbGljZSgwLCAzKS5tYXAoTnVtYmVyKSA/PyBbXTtcblxuICByZXR1cm4gY2hhbm5lbHMubGVuZ3RoID09PSAzXG4gICAgPyBgIyR7Y2hhbm5lbHMubWFwKChjaGFubmVsKSA9PiBNYXRoLnJvdW5kKGNoYW5uZWwpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpKS5qb2luKCcnKX1gXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVIdG1sKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWVcbiAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpXG4gICAgLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKTtcbn1cbiJdfQ==
|
|
429
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy90ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRFQUE0RTtBQUM1RSw4Q0FBOEM7QUFDOUMsRUFBRTtBQUNGLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UseUVBQXlFO0FBQ3pFLDZFQUE2RTtBQUM3RSwwRUFBMEU7QUFDMUUseUVBQXlFO0FBQ3pFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUseUVBQXlFO0FBQ3pFLDhFQUE4RTtBQUM5RSw4QkFBOEI7QUFHOUIsOEVBQThFO0FBQzlFLG9FQUFvRTtBQUNwRSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUM7QUFDcEMsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQTJCLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUNsRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUM7QUFFNUMsOEVBQThFO0FBQzlFLGlFQUFpRTtBQUNqRSw4RUFBOEU7QUFDOUUsc0JBQXNCO0FBQ3RCLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLFNBQVMsQ0FBQztBQUNqRCxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLENBQUM7QUFDNUMsa0VBQWtFO0FBQ2xFLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDdEUsNEVBQTRFO0FBQzVFLFVBQVU7QUFDVixNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7QUE4Qm5DLGdGQUFnRjtBQUNoRix1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsMENBQTBDLENBQUM7QUFFOUUsK0VBQStFO0FB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QVM7UUFDWCxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDNUcsQ0FBQztBQUVELGlEQUFpRDtBQUNqRCxTQUFTLFlBQVksQ0FBQyxPQUFpQyxFQUFFLElBQVksRUFBRSxLQUFhO0lBQ2xGLE9BQU8sQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLE9BQU8sQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBRTFCLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxLQUFhO0lBQ3RDLE9BQU8sS0FBSztTQUNULE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO1NBQ3RCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO1NBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO1NBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRleHQgYmxvY2tzIOKAlCBzaGFyZWQgYnkgdGhlIGNhbnZhcyBhbmQgYm90aCBleHBvcnRzLCBzbyBhIGJsb2NrIHJlYWRzIHRoZVxuLy8gc2FtZSBvbiBzY3JlZW4sIGluIHRoZSBkZWNrIGFuZCBpbiB0aGUgUERGLlxuLy9cbi8vIEEgYmxvY2sncyBodG1sIGFycml2ZXMgYWxyZWFkeSByZWJ1aWx0IHNlcnZlci1zaWRlIGZyb20gYSBzbWFsbCBhbGxvd2xpc3Rcbi8vIChSZXBvcnRUZXh0SHRtbCk6IHAsIGgxLWgzLCBzdHJvbmcsIGVtLCB1LCBzLCB1bC9vbC9saSwgYnIsIGEsIGFuZCBzcGFuIHdpdGhcbi8vIGNvbG9yIC8gYmFja2dyb3VuZC1jb2xvciAvIGZvbnQtc2l6ZSAvIGZvbnQtd2VpZ2h0IC8gZm9udC1mYW1pbHksIHBsdXNcbi8vIHRleHQtYWxpZ24gb24gYSBibG9jay4gQSB0YWJsZSBtYXkgc2l0IGF0IHRoZSB0b3AgbGV2ZWwgb2YgYSBibG9jazogdGFibGUsXG4vLyB0aGVhZCwgdGJvZHksIHRmb290LCB0ciwgdGggYW5kIHRkLCBhIHdpZHRoIG9uIHRoZSB0YWJsZSwgYW5kIG9uIGEgY2VsbFxuLy8gdGV4dC1hbGlnbiwgdmVydGljYWwtYWxpZ24sIGJhY2tncm91bmQtY29sb3IsIGEgd2lkdGggYW5kIGEgY29sc3BhbiBvclxuLy8gcm93c3Bhbi4gSXRzIGdyaWQgbGluZXMsIHBhZGRpbmcgYW5kIG1hcmdpbiBhcmUgbmV2ZXIgc3RvcmVkOiBldmVyeSByZW5kZXJlclxuLy8gZHJhd3MgdGhlbSBmcm9tIHRoZSBURVhUX1RBQkxFXyogY29uc3RhbnRzIGJlbG93LiBUcmFuc3BhcmVudCwgY3VycmVudGNvbG9yXG4vLyBhbmQgdGhlIENTUy13aWRlIGtleXdvcmRzIChpbmhlcml0LCBpbml0aWFsLCDigKYpIGFyZSBub3QgY29sb3JzLCBzbyB0aGVcbi8vIHNlcnZlciBkcm9wcyB0aGVtIGFuZCBoZXhDb2xvciByZWFkcyB0aGVtIGFzIG5vIGNvbG9yLiBFdmVyeXRoaW5nIGhlcmUgb25seVxuLy8gaGFzIHRvIHVuZGVyc3RhbmQgdGhhdCBzZXQuXG5cblxuLy8gQm9keSB0ZXh0IHNpemUsIHBvaW50cywgYW5kIHRoZSBoZWFkaW5nIHNpemVzIOKAlCB0aGUgc2FtZSBudW1iZXJzIHRoZSBjYW52YXNcbi8vIHN0eWxlc2hlZXQgdXNlcywgc28gYW4gdW5zdHlsZWQgcGFyYWdyYXBoIGlzIG9uZSBzaXplIGV2ZXJ5d2hlcmUuXG5leHBvcnQgY29uc3QgREVGQVVMVF9URVhUX1NJWkUgPSAxMjtcbmV4cG9ydCBjb25zdCBIRUFESU5HX1RFWFRfU0laRVM6IFJlY29yZDxudW1iZXIsIG51bWJlcj4gPSB7IDE6IDI0LCAyOiAxOCwgMzogMTQgfTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX1RFWFRfQ09MT1IgPSAnIzFmMjkzMyc7XG5cbi8vIEEgdGFibGUncyBncmlkIGxpbmVzOiB0aGVpciBjb2xvciwgYW5kIHRoZWlyIHdpZHRoIGluIHBvaW50cyAoMC43NXB0IGlzIG9uZVxuLy8gcGl4ZWwgb24gdGhlIGNhbnZhcykuIFRoZSBodG1sIG5ldmVyIHN0b3JlcyBib3JkZXJzIG9yIHBhZGRpbmdcbi8vIChSZXBvcnRUZXh0SHRtbCBkcm9wcyB0aGVtKSwgc28gdGhlIGNhbnZhcywgdGhlIGVkaXRvciBhbmQgYm90aCBleHBvcnRzIGFsbFxuLy8gZHJhdyB0aGlzIG9uZSBsb29rLlxuZXhwb3J0IGNvbnN0IFRFWFRfVEFCTEVfQk9SREVSX0NPTE9SID0gJyNjYmQyZDknO1xuZXhwb3J0IGNvbnN0IFRFWFRfVEFCTEVfQk9SREVSX1dJRFRIID0gMC43NTtcbi8vIFRoZSBzcGFjZSBiZXR3ZWVuIGEgY2VsbCdzIGdyaWQgbGluZXMgYW5kIGl0cyB3b3JkcywgaW4gcG9pbnRzLlxuZXhwb3J0IGNvbnN0IFRFWFRfVEFCTEVfQ0VMTF9QQURESU5HID0geyB2ZXJ0aWNhbDogMiwgaG9yaXpvbnRhbDogNCB9O1xuLy8gVGhlIHNwYWNlIGFib3ZlIGFuZCBiZWxvdyBhIHRhYmxlLCBiZXR3ZWVuIGl0IGFuZCB0aGUgd29yZHMgYXJvdW5kIGl0LCBpblxuLy8gcG9pbnRzLlxuZXhwb3J0IGNvbnN0IFRFWFRfVEFCTEVfTUFSR0lOID0gNDtcblxuLy8gQSBsaXZlIHZhbHVlIGEgYmxvY2sgc2hvd3MgaW5saW5lLCB3cml0dGVuIHt7dmFsdWUuPGtleT59fSBpbiBpdHMgaHRtbDogd2hhdFxuLy8gdGhlIHZhbHVlIGlzLCBhbmQgaXRzIGZvcm1hdHRlZCB0ZXh0IG9uY2UgbG9hZGVkLiBWYWx1ZXMgYmVsb25nIHRvIHRoZSBwYWdlXG4vLyB0aGUgYmxvY2sgc2l0cyBvbiAodGhlIG1hc3RlciBmb3IgYSBoZWFkZXIgb3IgZm9vdGVyIGJsb2NrKSwgc28gdGhlIGtleSBpc1xuLy8gdW5pcXVlIHdpdGhpbiB0aGF0IHBhZ2UuXG5leHBvcnQgaW50ZXJmYWNlIFRleHRWYWx1ZSB7XG4gIG5hbWU6IHN0cmluZztcbiAgLy8gQWJzZW50IHdoaWxlIGxvYWRpbmcsIGFuZCB3aGVuIHRoZSB2YWx1ZSdzIHF1ZXJ5IGZhaWxlZC5cbiAgdGV4dD86IHN0cmluZztcbiAgLy8gSXRzIG51bWJlciBoYXMgYmVlbiBhc2tlZCBmb3IgYW5kIGhhcyBub3QgYXJyaXZlZCB5ZXQuXG4gIGxvYWRpbmc/OiBib29sZWFuO1xuICAvLyBBIGZvcm11bGEncyBvcGVyYW5kIGtleXMsIGxvd2VyY2FzZTogdGhlIHZhbHVlcyBpdCByZWFkcywgd2hpY2ggdGhlIHBhZ2VcbiAgLy8gcmVhZHMgdG9vIHdoaWxlIHRoZSBmb3JtdWxhIGlzIHNob3duLlxuICByZWFkcz86IHN0cmluZ1tdO1xufVxuXG4vLyBXaGF0IHRoZSB0b2tlbnMgaW4gYSBibG9jaydzIGh0bWwgYXJlIGZpbGxlZCB3aXRoLCBwZXIgcGFnZS5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dFRva2VuQ29udGV4dCB7XG4gIHBhZ2VOdW1iZXI6IG51bWJlcjtcbiAgcGFnZU5hbWU6IHN0cmluZztcbiAgcmVwb3J0TmFtZTogc3RyaW5nO1xuICAvLyBUaGUgcGFnZSdzIHZhbHVlcywgYnkgbG93ZXJjYXNlIGtleS5cbiAgdmFsdWVzPzogUmVjb3JkPHN0cmluZywgVGV4dFZhbHVlPjtcbiAgLy8gVGhlIHJlcG9ydCBwYWdlIHdob3NlIHZhbHVlcyB0aGUgYmxvY2sgc2hvd3M6IHRoZSBwYWdlIGl0IHNpdHMgb24sIG9yIHRoZVxuICAvLyBtYXN0ZXIgZm9yIGEgaGVhZGVyIG9yIGZvb3RlciBibG9jay4gSXQgaXMgYWxzbyB0aGUgZWRpdG9yJ3MgY2xpcGJvYXJkXG4gIC8vIHNjb3BlLCBzbyBhIGNvcGllZCBjaGlwIHBhc3RlcyBiYWNrIGFzIGEgY2hpcCBvbmx5IG9uIHRoYXQgcGFnZS5cbiAgdmFsdWVQYWdlSWQ/OiBudW1iZXIgfCBudWxsO1xufVxuXG4vLyBBIHZhbHVlIHRva2VuOiB7e3ZhbHVlLnRvdGFsX3Zpc2l0c319LiBLZXlzIGFyZSBsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzIGFuZFxuLy8gdW5kZXJzY29yZXMsIHN0YXJ0aW5nIHdpdGggYSBsZXR0ZXIuXG5leHBvcnQgY29uc3QgVkFMVUVfVE9LRU5fUEFUVEVSTiA9IC9cXHtcXHtcXHMqdmFsdWVcXC4oW2Etel1bYS16MC05X10qKVxccypcXH1cXH0vZ2k7XG5cbi8vIFdoYXQgYSB2YWx1ZSB3aXRoIG5vIG51bWJlciByZWFkcyBhcyDigJQgaXQgZmFpbGVkLCBpdCBpcyBub3Qgb24gdGhpcyBwYWdlLCBvclxuLy8gaXRzIHF1ZXJ5IGZvdW5kIG5vdGhpbmcg4oCUIHNvIGEgYmxvY2sgbmV2ZXIgcHJpbnRzIGEgcmF3IHRva2VuLlxuZXhwb3J0IGNvbnN0IFZBTFVFX0VNUFRZX1RFWFQgPSAn4oCUJztcblxuLy8gV2hhdCBhIHZhbHVlIHJlYWRzIGFzIHdoaWxlIGl0cyBudW1iZXIgaXMgb24gaXRzIHdheSAob24gc2NyZWVuIG9ubHk6IGFuXG4vLyBleHBvcnQgd2FpdHMgZm9yIGV2ZXJ5IG51bWJlcikuXG5leHBvcnQgY29uc3QgVkFMVUVfTE9BRElOR19URVhUID0gJ+KApic7XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZVRva2VuKGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGB7e3ZhbHVlLiR7a2V5fX19YDtcbn1cblxuLy8gV2hhdCBhIHZhbHVlIHJlYWRzIGFzIGluIGEgYmxvY2ssIHZpZXdlZCBvciBlZGl0ZWQ6IGl0cyBmb3JtYXR0ZWQgbnVtYmVyLFxuLy8gdGhlIGVsbGlwc2lzIHdoaWxlIHRoYXQgbG9hZHMsIGVsc2UgdGhlIGVtIGRhc2guXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVUZXh0KHZhbHVlOiBUZXh0VmFsdWUgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWU/LnRleHQgPz8gKHZhbHVlPy5sb2FkaW5nID8gVkFMVUVfTE9BRElOR19URVhUIDogVkFMVUVfRU1QVFlfVEVYVCk7XG59XG5cbi8vIE9uZSBzdHlsZWQgc3RyZXRjaCBvZiB0ZXh0LlxuZXhwb3J0IGludGVyZmFjZSBUZXh0UnVuIHtcbiAgdGV4dDogc3RyaW5nO1xuICBib2xkPzogYm9vbGVhbjtcbiAgaXRhbGljPzogYm9vbGVhbjtcbiAgdW5kZXJsaW5lPzogYm9vbGVhbjtcbiAgc3RyaWtlPzogYm9vbGVhbjtcbiAgLy8gI3JyZ2diYlxuICBjb2xvcj86IHN0cmluZztcbiAgaGlnaGxpZ2h0Pzogc3RyaW5nO1xuICAvLyBwb2ludHNcbiAgZm9udFNpemU/OiBudW1iZXI7XG4gIGZvbnRGYWNlPzogc3RyaW5nO1xuICBsaW5rPzogc3RyaW5nO1xufVxuXG4vLyBPbmUgbGluZS1zdGFydGluZyBibG9jazogYSBwYXJhZ3JhcGgsIGEgaGVhZGluZyBvciBhIGxpc3QgaXRlbS5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dFBhcmFncmFwaCB7XG4gIHJ1bnM6IFRleHRSdW5bXTtcbiAgYWxpZ24/OiAnbGVmdCcgfCAnY2VudGVyJyB8ICdyaWdodCcgfCAnanVzdGlmeSc7XG4gIGJ1bGxldD86ICdidWxsZXQnIHwgJ251bWJlcic7XG4gIGhlYWRpbmc/OiBudW1iZXI7XG59XG5cbi8vIE9uZSBjZWxsIG9mIGEgdGFibGUgaW4gYSBibG9jay4gSXRzIHdvcmRzIGFyZSBwYXJhZ3JhcGhzIGxpa2UgYW55IG90aGVyczogYVxuLy8gPGJyPiBpbiBhIGNlbGwgc3RhcnRzIGEgbmV3IG9uZSwgYW5kIGEgaGVhZGVyIGNlbGwncyBydW5zIGFyZSBib2xkLiBFYWNoXG4vLyBwYXJhZ3JhcGggY2FycmllcyB0aGUgY2VsbCdzIGFsaWdubWVudCB1bmxlc3MgaXQgaGFzIGl0cyBvd24sIHNvIGV2ZXJ5XG4vLyByZW5kZXJlciByZWFkcyBhbGlnbm1lbnQgYW5kIHdlaWdodCBmcm9tIHRoZSBwYXJhZ3JhcGhzLlxuZXhwb3J0IGludGVyZmFjZSBUZXh0VGFibGVDZWxsIHtcbiAgcGFyYWdyYXBoczogVGV4dFBhcmFncmFwaFtdO1xuICBjb2xTcGFuOiBudW1iZXI7XG4gIC8vIEN1dCBhdCB0aGUgbGFzdCByb3cgb2YgdGhlIGNlbGwncyBzZWN0aW9uLCBhcyBhIGJyb3dzZXIgZHJhd3MgaXQuXG4gIHJvd1NwYW46IG51bWJlcjtcbiAgLy8gV2hlcmUgdGhlIGNlbGwgc2l0cyBpbiB0aGUgZ3JpZCAodGFibGVHcmlkKSwgMC1iYXNlZDogaXRzIHRvcCByb3cgYW5kIGl0c1xuICAvLyBsZWZ0IGNvbHVtbi5cbiAgcm93OiBudW1iZXI7XG4gIGNvbHVtbjogbnVtYmVyO1xuICAvLyBJdHMgdGV4dC1hbGlnbiwgZWxzZSBjZW50ZXJlZCBmb3IgYSBoZWFkZXIgY2VsbCBhbmQgbGVmdCBmb3IgYW55IG90aGVyLlxuICBhbGlnbjogJ2xlZnQnIHwgJ2NlbnRlcicgfCAncmlnaHQnIHwgJ2p1c3RpZnknO1xuICB2YWxpZ24/OiAndG9wJyB8ICdtaWRkbGUnIHwgJ2JvdHRvbSc7XG4gIC8vIEl0cyBiYWNrZ3JvdW5kLCAjcnJnZ2JiLlxuICBmaWxsPzogc3RyaW5nO1xufVxuXG4vLyBBIHRhYmxlJ3Mgcm93LiBSb3dzIGNvbWUgaW4gdGhlIG9yZGVyIGEgYnJvd3NlciBkcmF3cyB0aGVtOiB0aGUgaGVhZCwgdGhlXG4vLyBib2R5LCB0aGVuIHRoZSBmb290LlxuZXhwb3J0IGludGVyZmFjZSBUZXh0VGFibGVSb3cge1xuICBzZWN0aW9uOiAnaGVhZCcgfCAnYm9keScgfCAnZm9vdCc7XG4gIGNlbGxzOiBUZXh0VGFibGVDZWxsW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dFRhYmxlIHtcbiAgcm93czogVGV4dFRhYmxlUm93W107XG4gIC8vIEhvdyBtYW55IGNvbHVtbnMgdGhlIGdyaWQgaGFzOiB0aGUgd2lkZXN0IHJpZ2h0IGVkZ2Ugb2YgYW55IGNlbGwuXG4gIGNvbHVtbnM6IG51bWJlcjtcbn1cblxuLy8gQSBibG9jayBhcyB0aGUgZXhwb3J0cyBkcmF3IGl0OiBpdHMgd29yZHMsIHNwbGl0IGF0IGVhY2ggdGFibGUgaXQgaG9sZHMuXG5leHBvcnQgdHlwZSBUZXh0QmxvY2sgPVxuICB8IHsga2luZDogJ3RleHQnOyBwYXJhZ3JhcGhzOiBUZXh0UGFyYWdyYXBoW10gfVxuICB8IHsga2luZDogJ3RhYmxlJzsgdGFibGU6IFRleHRUYWJsZSB9O1xuXG4vLyBXaGF0IGEgdGFibGUncyBjZWxscyBhcmUgam9pbmVkIGJ5IHdoZXJlIGl0IHJlYWRzIGFzIGxpbmVzIG9mIHRleHQuXG5jb25zdCBUQUJMRV9DRUxMX1NFUEFSQVRPUiA9ICcgwrcgJztcblxuLy8gVGhlIHRva2VucyBhIGJsb2NrIG1heSBjYXJyeSwgd2l0aCB3aGF0IGZpbGxzIGVhY2guIHt7cGFnZS5udW1iZXJ9fSBpcyB0aGVcbi8vIHBhZ2UncyBwb3NpdGlvbiBhbW9uZyB0aGUgcmVwb3J0J3MgcGFnZXMgKDEtYmFzZWQpLCB3aGljaCBpcyB3aGF0IG1ha2VzIGFcbi8vIHNoYXJlZCBmb290ZXIgbnVtYmVyIGV2ZXJ5IHBhZ2UgY29ycmVjdGx5LlxuY29uc3QgVE9LRU5TOiBSZWNvcmQ8c3RyaW5nLCAoY29udGV4dDogVGV4dFRva2VuQ29udGV4dCkgPT4gc3RyaW5nPiA9IHtcbiAgJ3BhZ2UubnVtYmVyJzogKGNvbnRleHQpID0+IFN0cmluZyhjb250ZXh0LnBhZ2VOdW1iZXIpLFxuICAncGFnZS5uYW1lJzogKGNvbnRleHQpID0+IGNvbnRleHQucGFnZU5hbWUsXG4gICdyZXBvcnQubmFtZSc6IChjb250ZXh0KSA9PiBjb250ZXh0LnJlcG9ydE5hbWUsXG59O1xuXG4vLyBSZXBsYWNlIGV2ZXJ5IHt7dG9rZW59fSBpbiB0aGUgaHRtbC4gVmFsdWVzIGFyZSBodG1sLWVzY2FwZWQ6IGEgcGFnZSBuYW1lZFxuLy8gXCJSJkQgPGRyYWZ0PlwiIG11c3QgcmVhZCBhcyB0aGF0LCBub3QgYXMgbWFya3VwLiBBIHt7dmFsdWUuPGtleT59fSB0b2tlbiByZWFkc1xuLy8gYXMgaXRzIGZvcm1hdHRlZCBudW1iZXIsIHRoZSBlbGxpcHNpcyB3aGlsZSB0aGF0IGxvYWRzLCBlbHNlIHRoZSBlbSBkYXNoLlxuZXhwb3J0IGZ1bmN0aW9uIGZpbGxUZXh0VG9rZW5zKGh0bWw6IHN0cmluZywgY29udGV4dDogVGV4dFRva2VuQ29udGV4dCk6IHN0cmluZyB7XG4gIHJldHVybiBodG1sXG4gICAgLnJlcGxhY2UoVkFMVUVfVE9LRU5fUEFUVEVSTiwgKG1hdGNoLCBrZXk6IHN0cmluZykgPT4gZXNjYXBlSHRtbChcbiAgICAgIHZhbHVlVGV4dChjb250ZXh0LnZhbHVlcz8uW2tleS50b0xvd2VyQ2FzZSgpXSksXG4gICAgKSlcbiAgICAucmVwbGFjZSgvXFx7XFx7XFxzKihbYS16Ll0rKVxccypcXH1cXH0vZ2ksIChtYXRjaCwgdG9rZW46IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgZmlsbCA9IFRPS0VOU1t0b2tlbi50b0xvd2VyQ2FzZSgpXTtcblxuICAgICAgcmV0dXJuIGZpbGwgPyBlc2NhcGVIdG1sKGZpbGwoY29udGV4dCkpIDogbWF0Y2g7XG4gICAgfSk7XG59XG5cbi8vIFdhbGsgYSBibG9jaydzIGh0bWwgaW50byB3aGF0IHRoZSBleHBvcnRzIGRyYXc6IHRoZSB3b3JkcyBiZXR3ZWVuIGl0cyB0YWJsZXNcbi8vIGFzIHBhcmFncmFwaHMgb2Ygc3R5bGVkIHJ1bnMsIGFuZCBlYWNoIHRhYmxlIGFzIGEgZ3JpZCBvZiBjZWxscy4gVG9rZW5zIGFyZVxuLy8gZmlsbGVkIGZpcnN0IHNvIGEgcGFnZSBudW1iZXIgaXMganVzdCB0ZXh0IGJ5IHRoZW4uIFRoZXJlIGlzIGEgdGV4dCBwYXJ0IGZvclxuLy8gZXZlcnkgcnVuIG9mIG5vZGVzIHNwbGl0QXRUYWJsZXMgZmluZHMsIGV2ZW4gb25lIHRoYXQgaG9sZHMgbm8gd29yZHMsIHNvIHRoZVxuLy8gbnRoIHRleHQgcGFydCBpcyB0aGUgbnRoIHJ1biB0aGUgZXhwb3J0J3MgRE9NIG1lYXN1cmUgZmluZHMuXG5leHBvcnQgZnVuY3Rpb24gdGV4dEJsb2NrcyhodG1sOiBzdHJpbmcsIGNvbnRleHQ6IFRleHRUb2tlbkNvbnRleHQpOiBUZXh0QmxvY2tbXSB7XG4gIGNvbnN0IGRvY3VtZW50ID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhgPGJvZHk+JHtmaWxsVGV4dFRva2VucyhodG1sLCBjb250ZXh0KX08L2JvZHk+YCwgJ3RleHQvaHRtbCcpO1xuICBjb25zdCBibG9ja3MgPSBzcGxpdEF0VGFibGVzKGRvY3VtZW50LmJvZHkpLm1hcCgocGFydCk6IFRleHRCbG9jayA9PiB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHBhcnQpKSB7XG4gICAgICByZXR1cm4geyBraW5kOiAndGFibGUnLCB0YWJsZTogcGFyc2VUYWJsZShwYXJ0KSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIGNvbnN0IHBhcmFncmFwaHM6IFRleHRQYXJhZ3JhcGhbXSA9IFtdO1xuICAgIGZyYWdtZW50LmFwcGVuZCguLi5wYXJ0KTtcbiAgICB3YWxrQmxvY2tzKGZyYWdtZW50LCBwYXJhZ3JhcGhzLCBudWxsKTtcblxuICAgIHJldHVybiB7IGtpbmQ6ICd0ZXh0JywgcGFyYWdyYXBocyB9O1xuICB9KTtcblxuICB0cmltQmxhbmtFbmQoYmxvY2tzKTtcblxuICByZXR1cm4gYmxvY2tzO1xufVxuXG4vLyBUaGUgYmxvY2sgYXMgcGFyYWdyYXBocyBhbG9uZSwgZm9yIGFueXRoaW5nIHRoYXQgZHJhd3Mgbm8gZ3JpZDogYSB0YWJsZSByZWFkc1xuLy8gYXMgYSBsaW5lIHBlciByb3csIGl0cyBjZWxscycgd29yZHMgam9pbmVkIGJ5ICcgwrcgJy5cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0UGFyYWdyYXBocyhodG1sOiBzdHJpbmcsIGNvbnRleHQ6IFRleHRUb2tlbkNvbnRleHQpOiBUZXh0UGFyYWdyYXBoW10ge1xuICByZXR1cm4gYmxvY2tQYXJhZ3JhcGhzKHRleHRCbG9ja3MoaHRtbCwgY29udGV4dCkpO1xufVxuXG4vLyBCbG9ja3MgdGV4dEJsb2NrcyBhbHJlYWR5IHdhbGtlZCwgYXMgdGV4dFBhcmFncmFwaHMgcmVhZHMgdGhlbS5cbmV4cG9ydCBmdW5jdGlvbiBibG9ja1BhcmFncmFwaHMoYmxvY2tzOiBUZXh0QmxvY2tbXSk6IFRleHRQYXJhZ3JhcGhbXSB7XG4gIHJldHVybiBibG9ja3MuZmxhdE1hcCgoYmxvY2spID0+IGJsb2NrLmtpbmQgPT09ICd0ZXh0J1xuICAgID8gYmxvY2sucGFyYWdyYXBoc1xuICAgIDogYmxvY2sudGFibGUucm93cy5tYXAocm93UGFyYWdyYXBoKSk7XG59XG5cbi8vIFRoZSBodG1sIGFzIHBsYWluIHRleHQg4oCUIHdoYXQgYSBibG9jayBzYXlzLCBmb3IgYW55dGhpbmcgdGhhdCBjYW5ub3Qgc3R5bGUgaXQuXG5leHBvcnQgZnVuY3Rpb24gdGV4dFBsYWluKGh0bWw6IHN0cmluZywgY29udGV4dDogVGV4dFRva2VuQ29udGV4dCk6IHN0cmluZyB7XG4gIHJldHVybiB0ZXh0UGFyYWdyYXBocyhodG1sLCBjb250ZXh0KVxuICAgIC5tYXAoKHBhcmFncmFwaCkgPT4gcGFyYWdyYXBoLnJ1bnMubWFwKChydW4pID0+IHJ1bi50ZXh0KS5qb2luKCcnKSlcbiAgICAuam9pbignXFxuJyk7XG59XG5cbi8vIEEgYmxvY2sncyB0b3AtbGV2ZWwgbm9kZXMgc3BsaXQgYXQgZWFjaCB0YWJsZTogZWFjaCB0YWJsZSBvbiBpdHMgb3duLCBhbmRcbi8vIGVhY2ggcnVuIG9mIHRoZSBub2RlcyBiZXR3ZWVuIHRoZW0gYXMgYSBsaXN0LiBBIHRhYmxlIHNpdHMgb25seSBhdCB0aGUgdG9wXG4vLyBsZXZlbCAoUmVwb3J0VGV4dEh0bWwgZmxhdHRlbnMgYW55IG90aGVyKSwgc28gdGhpcyBpcyB0aGUgd2hvbGUgc3BsaXQuXG4vLyB0ZXh0QmxvY2tzIGFuZCB0aGUgZXhwb3J0J3MgbWVhc3VyZSBvZiB0aGUgcmVuZGVyZWQgYmxvY2sgYm90aCBzcGxpdCBoZXJlLlxuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0QXRUYWJsZXMocGFyZW50OiBOb2RlKTogKE5vZGVbXSB8IEhUTUxUYWJsZUVsZW1lbnQpW10ge1xuICBjb25zdCBwYXJ0czogKE5vZGVbXSB8IEhUTUxUYWJsZUVsZW1lbnQpW10gPSBbXTtcbiAgbGV0IHJ1bjogTm9kZVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgcGFyZW50LmNoaWxkTm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLm5vZGVOYW1lID09PSAnVEFCTEUnKSB7XG4gICAgICBwYXJ0cy5wdXNoKG5vZGUgYXMgSFRNTFRhYmxlRWxlbWVudCk7XG4gICAgICBydW4gPSBudWxsO1xuICAgIH0gZWxzZSBpZiAocnVuKSB7XG4gICAgICBydW4ucHVzaChub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcnVuID0gW25vZGVdO1xuICAgICAgcGFydHMucHVzaChydW4pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHBhcnRzO1xufVxuXG4vLyBBIHRhYmxlIGFzIGEgZ3JpZCBvZiBjZWxscywgZWFjaCBob2xkaW5nIGl0cyB3b3JkcyBhcyBwYXJhZ3JhcGhzLiBSb3dzIGNvbWVcbi8vIGFzIGEgYnJvd3NlciBkcmF3cyB0aGVtLCB0aGUgaGVhZCBmaXJzdCBhbmQgdGhlIGZvb3QgbGFzdCwgd2hhdGV2ZXIgb3JkZXIgdGhlXG4vLyBodG1sIHdyaXRlcyBpdHMgc2VjdGlvbnMgaW4uXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUYWJsZShlbGVtZW50OiBIVE1MVGFibGVFbGVtZW50KTogVGV4dFRhYmxlIHtcbiAgY29uc3Qgcm93cyA9IEFycmF5LmZyb20oZWxlbWVudC5yb3dzLCAocm93KTogVGV4dFRhYmxlUm93ID0+ICh7XG4gICAgc2VjdGlvbjogdGFibGVTZWN0aW9uKHJvdyksXG4gICAgY2VsbHM6IEFycmF5LmZyb20ocm93LmNlbGxzLCB0YWJsZUNlbGwpLFxuICB9KSk7XG5cbiAgcmV0dXJuIHRhYmxlR3JpZCh7IHJvd3MsIGNvbHVtbnM6IDAgfSk7XG59XG5cbi8vIFdoZXJlIGVhY2ggY2VsbCBzaXRzLCBieSB0aGUgSFRNTCB0YWJsZSBhbGdvcml0aG06IGEgY2VsbCB0YWtlcyB0aGUgZmlyc3Rcbi8vIGNvbHVtbiBvZiBpdHMgcm93IHRoYXQgbm8gY2VsbCBzcGFubmluZyBkb3duIGZyb20gYSByb3cgYWJvdmUgaG9sZHMuIEEgcm93c3BhblxuLy8gc3RvcHMgYXQgdGhlIGxhc3Qgcm93IG9mIGl0cyBzZWN0aW9uLCBhcyBhIGJyb3dzZXIgZHJhd3MgaXQsIGFuZCB0aGUgZ3JpZCBpc1xuLy8gYXMgd2lkZSBhcyB0aGUgd2lkZXN0IHJpZ2h0IGVkZ2Ugb2YgYW55IGNlbGwuXG5leHBvcnQgZnVuY3Rpb24gdGFibGVHcmlkKHRhYmxlOiBUZXh0VGFibGUpOiBUZXh0VGFibGUge1xuICBjb25zdCB0YWtlbjogYm9vbGVhbltdW10gPSB0YWJsZS5yb3dzLm1hcCgoKSA9PiBbXSk7XG4gIGxldCBjb2x1bW5zID0gMDtcblxuICBjb25zdCByb3dzID0gdGFibGUucm93cy5tYXAoKHJvdywgaW5kZXgpOiBUZXh0VGFibGVSb3cgPT4ge1xuICAgIGNvbnN0IHNlY3Rpb25FbmQgPSByb3dTZWN0aW9uRW5kKHRhYmxlLnJvd3MsIGluZGV4KTtcbiAgICBsZXQgY29sdW1uID0gMDtcblxuICAgIGNvbnN0IGNlbGxzID0gcm93LmNlbGxzLm1hcCgoY2VsbCk6IFRleHRUYWJsZUNlbGwgPT4ge1xuICAgICAgd2hpbGUgKHRha2VuW2luZGV4XVtjb2x1bW5dKSB7XG4gICAgICAgIGNvbHVtbisrO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwbGFjZWQgPSB7IC4uLmNlbGwsIHJvdzogaW5kZXgsIGNvbHVtbiwgcm93U3BhbjogTWF0aC5taW4oY2VsbC5yb3dTcGFuLCBzZWN0aW9uRW5kIC0gaW5kZXgpIH07XG4gICAgICBvY2N1cHkodGFrZW4sIHBsYWNlZCk7XG4gICAgICBjb2x1bW4gKz0gcGxhY2VkLmNvbFNwYW47XG4gICAgICBjb2x1bW5zID0gTWF0aC5tYXgoY29sdW1ucywgY29sdW1uKTtcblxuICAgICAgcmV0dXJuIHBsYWNlZDtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IC4uLnJvdywgY2VsbHMgfTtcbiAgfSk7XG5cbiAgcmV0dXJuIHsgcm93cywgY29sdW1ucyB9O1xufVxuXG5mdW5jdGlvbiB0YWJsZVNlY3Rpb24ocm93OiBIVE1MVGFibGVSb3dFbGVtZW50KTogVGV4dFRhYmxlUm93WydzZWN0aW9uJ10ge1xuICBjb25zdCBzZWN0aW9uID0gcm93LnBhcmVudEVsZW1lbnQ/Lm5vZGVOYW1lO1xuXG4gIHJldHVybiBzZWN0aW9uID09PSAnVEhFQUQnID8gJ2hlYWQnIDogc2VjdGlvbiA9PT0gJ1RGT09UJyA/ICdmb290JyA6ICdib2R5Jztcbn1cblxuLy8gT25lIHRoIG9yIHRkLiBBIGhlYWRlciBjZWxsJ3MgcnVucyBhcmUgYm9sZCwgYW5kIGV2ZXJ5IHBhcmFncmFwaCB0YWtlcyB0aGVcbi8vIGNlbGwncyB0ZXh0LWFsaWduIHVubGVzcyBpdCBoYXMgaXRzIG93bjogdGhlIGRlZmF1bHQgbG9vayBjZW50ZXJzIGEgaGVhZGVyXG4vLyBjZWxsIGFuZCBwdXRzIGFueSBvdGhlciBvbiB0aGUgbGVmdC5cbmZ1bmN0aW9uIHRhYmxlQ2VsbChjZWxsOiBIVE1MVGFibGVDZWxsRWxlbWVudCk6IFRleHRUYWJsZUNlbGwge1xuICBjb25zdCBoZWFkZXIgPSBjZWxsLm5vZGVOYW1lID09PSAnVEgnO1xuICBjb25zdCBhbGlnbiA9IGNlbGxBbGlnbihjZWxsLnN0eWxlLnRleHRBbGlnbikgPz8gKGhlYWRlciA/ICdjZW50ZXInIDogJ2xlZnQnKTtcbiAgY29uc3QgdmFsaWduID0gY2VsbC5zdHlsZS52ZXJ0aWNhbEFsaWduO1xuICBjb25zdCBwYXJhZ3JhcGhzOiBUZXh0UGFyYWdyYXBoW10gPSBbXTtcblxuICB3YWxrQmxvY2tzKGNlbGwsIHBhcmFncmFwaHMsIG51bGwsIGhlYWRlciA/IHsgYm9sZDogdHJ1ZSB9IDoge30pO1xuXG4gIHJldHVybiB7XG4gICAgcGFyYWdyYXBoczogcGFyYWdyYXBocy5tYXAoKHBhcmFncmFwaCkgPT4gKHsgLi4ucGFyYWdyYXBoLCBhbGlnbjogcGFyYWdyYXBoLmFsaWduID8/IGFsaWduIH0pKSxcbiAgICBjb2xTcGFuOiBNYXRoLm1heCgxLCBjZWxsLmNvbFNwYW4pLFxuICAgIHJvd1NwYW46IE1hdGgubWF4KDEsIGNlbGwucm93U3BhbiksXG4gICAgcm93OiAwLFxuICAgIGNvbHVtbjogMCxcbiAgICBhbGlnbixcbiAgICB2YWxpZ246IHZhbGlnbiA9PT0gJ3RvcCcgfHwgdmFsaWduID09PSAnbWlkZGxlJyB8fCB2YWxpZ24gPT09ICdib3R0b20nID8gdmFsaWduIDogdW5kZWZpbmVkLFxuICAgIGZpbGw6IGNlbGwuc3R5bGUuYmFja2dyb3VuZENvbG9yID8gaGV4Q29sb3IoY2VsbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IpIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjZWxsQWxpZ24odmFsdWU6IHN0cmluZyk6IFRleHRUYWJsZUNlbGxbJ2FsaWduJ10gfCB1bmRlZmluZWQge1xuICByZXR1cm4gdmFsdWUgPT09ICdsZWZ0JyB8fCB2YWx1ZSA9PT0gJ2NlbnRlcicgfHwgdmFsdWUgPT09ICdyaWdodCcgfHwgdmFsdWUgPT09ICdqdXN0aWZ5JyA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG4vLyBUaGUgaW5kZXgganVzdCBwYXN0IHRoZSBsYXN0IHJvdyBvZiB0aGUgc2VjdGlvbiB0aGUgcm93IGF0IGluZGV4IHNpdHMgaW4uXG5mdW5jdGlvbiByb3dTZWN0aW9uRW5kKHJvd3M6IFRleHRUYWJsZVJvd1tdLCBpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgbGV0IGVuZCA9IGluZGV4ICsgMTtcbiAgd2hpbGUgKGVuZCA8IHJvd3MubGVuZ3RoICYmIHJvd3NbZW5kXS5zZWN0aW9uID09PSByb3dzW2luZGV4XS5zZWN0aW9uKSB7XG4gICAgZW5kKys7XG4gIH1cblxuICByZXR1cm4gZW5kO1xufVxuXG4vLyBNYXJrIHRoZSBncmlkIHNsb3RzIGEgcGxhY2VkIGNlbGwgY292ZXJzLlxuZnVuY3Rpb24gb2NjdXB5KHRha2VuOiBib29sZWFuW11bXSwgY2VsbDogVGV4dFRhYmxlQ2VsbCk6IHZvaWQge1xuICBmb3IgKGxldCByb3cgPSBjZWxsLnJvdzsgcm93IDwgY2VsbC5yb3cgKyBjZWxsLnJvd1NwYW47IHJvdysrKSB7XG4gICAgZm9yIChsZXQgY29sdW1uID0gY2VsbC5jb2x1bW47IGNvbHVtbiA8IGNlbGwuY29sdW1uICsgY2VsbC5jb2xTcGFuOyBjb2x1bW4rKykge1xuICAgICAgdGFrZW5bcm93XVtjb2x1bW5dID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn1cblxuLy8gQSB0YWJsZSByb3cgYXMgb25lIGxpbmUgb2YgdGV4dDogaXRzIGNlbGxzIGluIG9yZGVyLCBhIGNlbGwncyBvd24gbGluZXNcbi8vIGpvaW5lZCBieSBhIHNwYWNlLlxuZnVuY3Rpb24gcm93UGFyYWdyYXBoKHJvdzogVGV4dFRhYmxlUm93KTogVGV4dFBhcmFncmFwaCB7XG4gIHJldHVybiB7XG4gICAgcnVuczogcm93LmNlbGxzLmZsYXRNYXAoKGNlbGwsIGluZGV4KSA9PiBbXG4gICAgICAuLi4oaW5kZXggPyBbeyB0ZXh0OiBUQUJMRV9DRUxMX1NFUEFSQVRPUiB9XSA6IFtdKSxcbiAgICAgIC4uLmNlbGwucGFyYWdyYXBocy5mbGF0TWFwKChwYXJhZ3JhcGgsIGxpbmUpID0+IFsuLi4obGluZSA/IFt7IHRleHQ6ICcgJyB9XSA6IFtdKSwgLi4ucGFyYWdyYXBoLnJ1bnNdKSxcbiAgICBdKSxcbiAgfTtcbn1cblxuLy8gQW4gZW1wdHkgcGFyYWdyYXBoIGlzIGEgYmxhbmsgbGluZSB0aGUgY2FudmFzIGRyYXdzICg8cD48YnI+PC9wPiwgb3IgYW4gZW1wdHlcbi8vIDxwPiksIHNvIG9uZSBhdCB0aGUgc3RhcnQgb2YgdGhlIGJsb2NrIGtlZXBzIHRoZSB3b3JkcyBiZWxvdyBpdCB3aGVyZSB0aGVcbi8vIGNhbnZhcyBwdXRzIHRoZW0uIEF0IHRoZSBlbmQgb2YgdGhlIHdob2xlIGJsb2NrIGl0IGRyYXdzIG5vdGhpbmcsIGFuZCBpc1xuLy8gZHJvcHBlZCBzbyBpdCBuZXZlciBjb3VudHMgYXMgcnVubmluZyBwYXN0IHRoZSBib3guIEFuIGVtcHR5IHBhcmFncmFwaFxuLy8gYmVmb3JlIGEgdGFibGUgaXMgbm90IGF0IHRoZSBlbmQuXG5mdW5jdGlvbiB0cmltQmxhbmtFbmQoYmxvY2tzOiBUZXh0QmxvY2tbXSk6IHZvaWQge1xuICBjb25zdCBsYXN0ID0gYmxvY2tzW2Jsb2Nrcy5sZW5ndGggLSAxXTtcblxuICB3aGlsZSAobGFzdD8ua2luZCA9PT0gJ3RleHQnICYmIGxhc3QucGFyYWdyYXBocy5sZW5ndGggJiYgIWxhc3QucGFyYWdyYXBoc1tsYXN0LnBhcmFncmFwaHMubGVuZ3RoIC0gMV0ucnVucy5sZW5ndGgpIHtcbiAgICBsYXN0LnBhcmFncmFwaHMucG9wKCk7XG4gIH1cbn1cblxuLy8gYmFzZSBpcyB0aGUgc3R5bGUgZXZlcnkgcnVuIHN0YXJ0cyBmcm9tOiBib2xkIGZvciBhIGhlYWRlciBjZWxsJ3Mgd29yZHMuXG5mdW5jdGlvbiB3YWxrQmxvY2tzKFxuICBwYXJlbnQ6IE5vZGUsXG4gIHBhcmFncmFwaHM6IFRleHRQYXJhZ3JhcGhbXSxcbiAgbGlzdDogJ2J1bGxldCcgfCAnbnVtYmVyJyB8IG51bGwsXG4gIGJhc2U6IFBhcnRpYWw8VGV4dFJ1bj4gPSB7fSxcbik6IHZvaWQge1xuICAvLyBMb29zZSBpbmxpbmUgY29udGVudCBiZXR3ZWVuIGJsb2NrcyAodGV4dCBzdHJhaWdodCB1bmRlciB0aGUgYmxvY2ssIGFuXG4gIC8vIDxsaT4gb3IgYSBjZWxsKSBpcyBnYXRoZXJlZCBpbnRvIGEgcGFyYWdyYXBoIG9mIGl0cyBvd24uXG4gIGxldCBsb29zZTogVGV4dFBhcmFncmFwaCB8IG51bGwgPSBudWxsO1xuICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICBpZiAobG9vc2UgJiYgaXNTaG93bihsb29zZSkpIHtcbiAgICAgIHBhcmFncmFwaHMucHVzaChsb29zZSk7XG4gICAgfVxuICAgIGxvb3NlID0gbnVsbDtcbiAgfTtcblxuICBwYXJlbnQuY2hpbGROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChuYW1lID09PSAndWwnIHx8IG5hbWUgPT09ICdvbCcgfHwgbmFtZSA9PT0gJ2xpJyB8fCBuYW1lID09PSAncCcgfHwgL15oWzEtM10kLy50ZXN0KG5hbWUpKSB7XG4gICAgICBmbHVzaCgpO1xuICAgICAgd2Fsa0Jsb2NrKG5vZGUgYXMgSFRNTEVsZW1lbnQsIHBhcmFncmFwaHMsIGxpc3QsIGJhc2UpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9vc2UgPSBsb29zZSA/PyB7IHJ1bnM6IFtdIH07XG4gICAgd2Fsa0lubGluZShub2RlLCBiYXNlLCBsb29zZSwgcGFyYWdyYXBocywgdHJ1ZSk7XG4gIH0pO1xuXG4gIGZsdXNoKCk7XG59XG5cbi8vIFdoZXRoZXIgbG9vc2UgY29udGVudCdzIGxhc3QgbGluZSBzaG93cyBhbnl0aGluZy4gV2hpdGVzcGFjZSBhbG9uZSBiZXR3ZWVuXG4vLyBibG9ja3MgaXMgbm90IGRyYXduLCBhbmQgYSBsaW5lIGEgPGJyPiBlbmRlZCB3YXMgcHVzaGVkIHdoZW4gaXQgZW5kZWQsIHNvIGFcbi8vIHRyYWlsaW5nIDxicj4gYWRkcyBubyBlbXB0eSBsaW5lIGFmdGVyIGl0LlxuZnVuY3Rpb24gaXNTaG93bihsb29zZTogVGV4dFBhcmFncmFwaCk6IGJvb2xlYW4ge1xuICByZXR1cm4gbG9vc2UucnVucy5zb21lKChydW4pID0+IC9bXiBcXHRcXG5cXHJcXGZdLy50ZXN0KHJ1bi50ZXh0KSk7XG59XG5cbmZ1bmN0aW9uIHdhbGtCbG9jayhcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gIHBhcmFncmFwaHM6IFRleHRQYXJhZ3JhcGhbXSxcbiAgbGlzdDogJ2J1bGxldCcgfCAnbnVtYmVyJyB8IG51bGwsXG4gIGJhc2U6IFBhcnRpYWw8VGV4dFJ1bj4sXG4pOiB2b2lkIHtcbiAgY29uc3QgbmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuICBpZiAobmFtZSA9PT0gJ3VsJyB8fCBuYW1lID09PSAnb2wnKSB7XG4gICAgd2Fsa0Jsb2NrcyhlbGVtZW50LCBwYXJhZ3JhcGhzLCBuYW1lID09PSAndWwnID8gJ2J1bGxldCcgOiAnbnVtYmVyJywgYmFzZSk7XG4gIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2xpJykge1xuICAgIGNvbnN0IGl0ZW06IFRleHRQYXJhZ3JhcGggPSB7IHJ1bnM6IFtdLCBidWxsZXQ6IGxpc3QgPz8gJ2J1bGxldCcgfTtcbiAgICBjb25zdCBuZXN0ZWQ6IFRleHRQYXJhZ3JhcGhbXSA9IFtdO1xuICAgIC8vIEEgbGlzdCBpdGVtJ3MgZmlyc3QgcGFyYWdyYXBoIElTIHRoZSBpdGVtOyBhbnl0aGluZyBhZnRlciBpdCBpcyBpdHMgb3duXG4gICAgLy8gbGluZSB1bmRlciB0aGUgc2FtZSBidWxsZXQuXG4gICAgd2Fsa0Jsb2NrcyhlbGVtZW50LCBuZXN0ZWQsIGxpc3QsIGJhc2UpO1xuICAgIGNvbnN0IFtmaXJzdCwgLi4ucmVzdF0gPSBuZXN0ZWQubGVuZ3RoID8gbmVzdGVkIDogW2l0ZW1dO1xuICAgIHBhcmFncmFwaHMucHVzaCh7IC4uLmZpcnN0LCBidWxsZXQ6IGxpc3QgPz8gJ2J1bGxldCcgfSwgLi4ucmVzdCk7XG4gIH0gZWxzZSB7XG4gICAgd2Fsa1BhcmFncmFwaChlbGVtZW50LCBwYXJhZ3JhcGhzLCBiYXNlKTtcbiAgfVxufVxuXG4vLyBBIHAgb3IgYSBoZWFkaW5nLiBBIDxicj4gZW5kcyBhIGxpbmUsIHNvIGl0cyBsYXN0IGxpbmUgaXMgcHVzaGVkIG9ubHkgd2hlbiBpdFxuLy8gaG9sZHMgd29yZHMgb3Igbm8gPGJyPiBjYW1lIGJlZm9yZSBpdDogPHA+PGJyPjwvcD4gaXMgb25lIGJsYW5rIGxpbmUsXG4vLyA8cD5hPGJyPjwvcD4gb25lIGxpbmUgYW5kIDxwPmE8YnI+YjwvcD4gdHdvLCBhcyBhIGJyb3dzZXIgZHJhd3MgdGhlbS5cbmZ1bmN0aW9uIHdhbGtQYXJhZ3JhcGgoZWxlbWVudDogSFRNTEVsZW1lbnQsIHBhcmFncmFwaHM6IFRleHRQYXJhZ3JhcGhbXSwgYmFzZTogUGFydGlhbDxUZXh0UnVuPik6IHZvaWQge1xuICBjb25zdCBuYW1lID0gZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBoZWFkaW5nID0gbmFtZS5zdGFydHNXaXRoKCdoJykgPyBOdW1iZXIobmFtZVsxXSkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHBhcmFncmFwaDogVGV4dFBhcmFncmFwaCA9IHtcbiAgICBydW5zOiBbXSxcbiAgICBhbGlnbjogYmxvY2tBbGlnbihlbGVtZW50KSxcbiAgICBidWxsZXQ6IHVuZGVmaW5lZCxcbiAgICBoZWFkaW5nLFxuICB9O1xuICBjb25zdCBzdHlsZTogUGFydGlhbDxUZXh0UnVuPiA9IGhlYWRpbmdcbiAgICA/IHsgLi4uYmFzZSwgYm9sZDogdHJ1ZSwgZm9udFNpemU6IEhFQURJTkdfVEVYVF9TSVpFU1toZWFkaW5nXSB9XG4gICAgOiBiYXNlO1xuXG4gIGNvbnN0IGJyZWFrcyA9IHdhbGtJbmxpbmUoZWxlbWVudCwgc3R5bGUsIHBhcmFncmFwaCwgcGFyYWdyYXBocyk7XG4gIGlmIChwYXJhZ3JhcGgucnVucy5sZW5ndGggfHwgIWJyZWFrcykge1xuICAgIHBhcmFncmFwaHMucHVzaChwYXJhZ3JhcGgpO1xuICB9XG59XG5cbi8vIEFjY3VtdWxhdGUgaW5saW5lIHN0eWxlcyBkb3duIHRoZSB0cmVlLiBBIDxicj4gZW5kcyB0aGUgY3VycmVudCBsaW5lOiB0aGVcbi8vIHJ1bnMgYWZ0ZXIgaXQgc3RhcnQgYSBuZXcgcGFyYWdyYXBoIHdpdGggdGhlIHNhbWUgYWxpZ25tZW50IGFuZCBidWxsZXQuXG4vLyBSZXR1cm5zIGhvdyBtYW55IGxpbmVzIGEgPGJyPiBlbmRlZC5cbmZ1bmN0aW9uIHdhbGtJbmxpbmUoXG4gIG5vZGU6IE5vZGUsXG4gIHN0eWxlOiBQYXJ0aWFsPFRleHRSdW4+LFxuICBwYXJhZ3JhcGg6IFRleHRQYXJhZ3JhcGgsXG4gIHBhcmFncmFwaHM6IFRleHRQYXJhZ3JhcGhbXSxcbiAgaXNTZWxmID0gZmFsc2UsXG4pOiBudW1iZXIge1xuICBjb25zdCBub2RlcyA9IGlzU2VsZiA/IFtub2RlXSA6IEFycmF5LmZyb20obm9kZS5jaGlsZE5vZGVzKTtcblxuICByZXR1cm4gbm9kZXMucmVkdWNlKChicmVha3MsIGNoaWxkKSA9PiBicmVha3MgKyB3YWxrSW5saW5lTm9kZShjaGlsZCwgc3R5bGUsIHBhcmFncmFwaCwgcGFyYWdyYXBocyksIDApO1xufVxuXG5mdW5jdGlvbiB3YWxrSW5saW5lTm9kZShcbiAgbm9kZTogTm9kZSxcbiAgc3R5bGU6IFBhcnRpYWw8VGV4dFJ1bj4sXG4gIHBhcmFncmFwaDogVGV4dFBhcmFncmFwaCxcbiAgcGFyYWdyYXBoczogVGV4dFBhcmFncmFwaFtdLFxuKTogbnVtYmVyIHtcbiAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgY29uc3QgdGV4dCA9IG5vZGUudGV4dENvbnRlbnQgPz8gJyc7XG4gICAgaWYgKHRleHQpIHtcbiAgICAgIHBhcmFncmFwaC5ydW5zLnB1c2goeyAuLi5zdHlsZSwgdGV4dCB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgY29uc3QgZWxlbWVudCA9IG5vZGUgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgaWYgKGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2JyJykge1xuICAgIHBhcmFncmFwaHMucHVzaCh7IC4uLnBhcmFncmFwaCwgcnVuczogWy4uLnBhcmFncmFwaC5ydW5zXSB9KTtcbiAgICBwYXJhZ3JhcGgucnVucy5sZW5ndGggPSAwO1xuXG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICByZXR1cm4gd2Fsa0lubGluZShlbGVtZW50LCB7IC4uLnN0eWxlLCAuLi5pbmxpbmVTdHlsZShlbGVtZW50KSB9LCBwYXJhZ3JhcGgsIHBhcmFncmFwaHMpO1xufVxuXG5mdW5jdGlvbiBpbmxpbmVTdHlsZShlbGVtZW50OiBIVE1MRWxlbWVudCk6IFBhcnRpYWw8VGV4dFJ1bj4ge1xuICBjb25zdCBuYW1lID0gZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBzdHlsZTogUGFydGlhbDxUZXh0UnVuPiA9IHt9O1xuXG4gIGlmIChuYW1lID09PSAnc3Ryb25nJykge1xuICAgIHN0eWxlLmJvbGQgPSB0cnVlO1xuICB9XG4gIGlmIChuYW1lID09PSAnZW0nKSB7XG4gICAgc3R5bGUuaXRhbGljID0gdHJ1ZTtcbiAgfVxuICBpZiAobmFtZSA9PT0gJ3UnKSB7XG4gICAgc3R5bGUudW5kZXJsaW5lID0gdHJ1ZTtcbiAgfVxuICBpZiAobmFtZSA9PT0gJ3MnKSB7XG4gICAgc3R5bGUuc3RyaWtlID0gdHJ1ZTtcbiAgfVxuICBpZiAobmFtZSA9PT0gJ2EnKSB7XG4gICAgc3R5bGUubGluayA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdocmVmJykgPz8gdW5kZWZpbmVkO1xuICAgIHN0eWxlLnVuZGVybGluZSA9IHRydWU7XG4gIH1cblxuICAvLyBXaGF0IGlzIG5vIGNvbG9yIGxlYXZlcyB0aGUgY29sb3IgdGhlIHJ1biBpbmhlcml0cy5cbiAgY29uc3QgY3NzID0gZWxlbWVudC5zdHlsZTtcbiAgY29uc3QgY29sb3IgPSBjc3MuY29sb3IgPyBoZXhDb2xvcihjc3MuY29sb3IpIDogdW5kZWZpbmVkO1xuICBjb25zdCBoaWdobGlnaHQgPSBjc3MuYmFja2dyb3VuZENvbG9yID8gaGV4Q29sb3IoY3NzLmJhY2tncm91bmRDb2xvcikgOiB1bmRlZmluZWQ7XG4gIGlmIChjb2xvcikge1xuICAgIHN0eWxlLmNvbG9yID0gY29sb3I7XG4gIH1cbiAgaWYgKGhpZ2hsaWdodCkge1xuICAgIHN0eWxlLmhpZ2hsaWdodCA9IGhpZ2hsaWdodDtcbiAgfVxuICBpZiAoY3NzLmZvbnRTaXplKSB7XG4gICAgc3R5bGUuZm9udFNpemUgPSBwb2ludHMoY3NzLmZvbnRTaXplKTtcbiAgfVxuICBpZiAoY3NzLmZvbnRXZWlnaHQpIHtcbiAgICBzdHlsZS5ib2xkID0gY3NzLmZvbnRXZWlnaHQgPT09ICdib2xkJyB8fCBOdW1iZXIoY3NzLmZvbnRXZWlnaHQpID49IDYwMDtcbiAgfVxuICBpZiAoY3NzLmZvbnRTdHlsZSkge1xuICAgIHN0eWxlLml0YWxpYyA9IGNzcy5mb250U3R5bGUgPT09ICdpdGFsaWMnO1xuICB9XG4gIGlmIChjc3MudGV4dERlY29yYXRpb24pIHtcbiAgICBzdHlsZS51bmRlcmxpbmUgPSBjc3MudGV4dERlY29yYXRpb24uaW5jbHVkZXMoJ3VuZGVybGluZScpO1xuICAgIHN0eWxlLnN0cmlrZSA9IGNzcy50ZXh0RGVjb3JhdGlvbi5pbmNsdWRlcygnbGluZS10aHJvdWdoJyk7XG4gIH1cbiAgaWYgKGNzcy5mb250RmFtaWx5KSB7XG4gICAgc3R5bGUuZm9udEZhY2UgPSBjc3MuZm9udEZhbWlseS5zcGxpdCgnLCcpWzBdLnJlcGxhY2UoL1tcIiddL2csICcnKS50cmltKCk7XG4gIH1cblxuICByZXR1cm4gc3R5bGU7XG59XG5cbmZ1bmN0aW9uIGJsb2NrQWxpZ24oZWxlbWVudDogSFRNTEVsZW1lbnQpOiBUZXh0UGFyYWdyYXBoWydhbGlnbiddIHtcbiAgY29uc3QgYWxpZ24gPSBlbGVtZW50LnN0eWxlLnRleHRBbGlnbjtcblxuICByZXR1cm4gYWxpZ24gPT09ICdjZW50ZXInIHx8IGFsaWduID09PSAncmlnaHQnIHx8IGFsaWduID09PSAnanVzdGlmeScgPyBhbGlnbiA6IHVuZGVmaW5lZDtcbn1cblxuLy8gQSBDU1MgZm9udC1zaXplIGluIHBvaW50cy4gVGhlIGNhbnZhcyByZW5kZXJzIGF0IDk2cHggcGVyIGluY2gsIHNvIDFweCBpc1xuLy8gZXhhY3RseSAwLjc1cHQ7IGVtL3JlbS8lIGFyZSByZWxhdGl2ZSB0byB0aGUgYm9keSBzaXplLlxuZnVuY3Rpb24gcG9pbnRzKHZhbHVlOiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBtYXRjaCA9IC9eKFtcXGQuXSspKHB0fHB4fGVtfHJlbXwlKSQvLmV4ZWModmFsdWUudHJpbSgpKTtcbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBzaXplID0gTnVtYmVyKG1hdGNoWzFdKTtcbiAgc3dpdGNoIChtYXRjaFsyXSkge1xuICAgIGNhc2UgJ3B0JzpcbiAgICAgIHJldHVybiBzaXplO1xuICAgIGNhc2UgJ3B4JzpcbiAgICAgIHJldHVybiBzaXplICogMC43NTtcbiAgICBjYXNlICclJzpcbiAgICAgIHJldHVybiAoc2l6ZSAvIDEwMCkgKiBERUZBVUxUX1RFWFRfU0laRTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHNpemUgKiBERUZBVUxUX1RFWFRfU0laRTtcbiAgfVxufVxuXG4vLyBBbnkgQ1NTIGNvbG9yIHRoZSBhbGxvd2xpc3QgbGV0cyB0aHJvdWdoIChoZXgsIHJnYigpLCBhIG5hbWUpIGFzICNycmdnYmIg4oCUXG4vLyB0aGUgb25lIGZvcm0gYm90aCBleHBvcnRzIGFjY2VwdC4gVGhlIGJyb3dzZXIgcmVzb2x2ZXMgaXQsIHNvIGEgbmFtZWQgY29sb3Jcbi8vIGNvbWVzIG91dCBleGFjdGx5IGFzIHRoZSBjYW52YXMgcGFpbnRlZCBpdC4gQSB2YWx1ZSB0aGF0IGlzIG5vIGNvbG9yIG9mIGl0c1xuLy8gb3duIChpbmhlcml0LCBjdXJyZW50Y29sb3IsIGEgdHlwbykgb3IgcGFpbnRzIG5vdGhpbmcgKHRyYW5zcGFyZW50LCBhbiBhbHBoYVxuLy8gb2YgMCkgaXMgdW5kZWZpbmVkLCBzbyBhbiBleHBvcnQgbmV2ZXIgcGFpbnRzIGl0IGJsYWNrLlxubGV0IGNvbG9yQ29udGV4dDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIHwgbnVsbCA9IG51bGw7XG5cbmZ1bmN0aW9uIGhleENvbG9yKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb2xvckNvbnRleHQgPSBjb2xvckNvbnRleHQgPz8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcbiAgaWYgKCFjb2xvckNvbnRleHQgfHwgL15cXHMqY3VycmVudGNvbG9yXFxzKiQvaS50ZXN0KHZhbHVlKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBBIHZhbHVlIHRoZSBjYW52YXMgY2Fubm90IHJlYWQgbGVhdmVzIHRoZSBjb2xvciBzZXQgYmVmb3JlIGl0LCBzbyBpdCByZWFkc1xuICAvLyBiYWNrIG9uZSB3YXkgb3ZlciBibGFjayBhbmQgYW5vdGhlciBvdmVyIHdoaXRlLiAoY3VycmVudGNvbG9yIHJlYWRzIGFzXG4gIC8vIGJsYWNrIG92ZXIgYm90aCwgaGVuY2UgdGhlIGNoZWNrIGFib3ZlLilcbiAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlQ29sb3IoY29sb3JDb250ZXh0LCAnIzAwMDAwMCcsIHZhbHVlKTtcbiAgaWYgKHJlc29sdmVkICE9PSByZXNvbHZlQ29sb3IoY29sb3JDb250ZXh0LCAnI2ZmZmZmZicsIHZhbHVlKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAocmVzb2x2ZWQuc3RhcnRzV2l0aCgnIycpKSB7XG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgLy8gcmdiYSguLi4pIGZvciBhIHRyYW5zbHVjZW50IGNvbG9yIOKAlCBkcm9wIHRoZSBhbHBoYSwga2VlcCB0aGUgaHVlLlxuICBjb25zdCBbcmVkLCBncmVlbiwgYmx1ZSwgYWxwaGFdID0gcmVzb2x2ZWQubWF0Y2goL1tcXGQuXSsvZyk/Lm1hcChOdW1iZXIpID8/IFtdO1xuXG4gIHJldHVybiBibHVlID09PSB1bmRlZmluZWQgfHwgYWxwaGEgPT09IDBcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogYCMke1tyZWQsIGdyZWVuLCBibHVlXS5tYXAoKGNoYW5uZWwpID0+IE1hdGgucm91bmQoY2hhbm5lbCkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJykpLmpvaW4oJycpfWA7XG59XG5cbi8vIFdoYXQgdGhlIGNhbnZhcyByZWFkcyB2YWx1ZSBhcywgc2V0IG92ZXIgc2VlZC5cbmZ1bmN0aW9uIHJlc29sdmVDb2xvcihjb250ZXh0OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsIHNlZWQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnRleHQuZmlsbFN0eWxlID0gc2VlZDtcbiAgY29udGV4dC5maWxsU3R5bGUgPSB2YWx1ZTtcblxuICByZXR1cm4gU3RyaW5nKGNvbnRleHQuZmlsbFN0eWxlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUh0bWwodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiB2YWx1ZVxuICAgIC5yZXBsYWNlKC8mL2csICcmYW1wOycpXG4gICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpO1xufVxuIl19
|