PluginProbe
Booking Calendar / 11.5
Booking Calendar v11.5
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / includes / page-form-builder / _out / export / builder-exporter.js

builder-exporter.js in Booking Calendar 11.5, at includes/page-form-builder/_out/export/builder-exporter.js

1,149 lines 154.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 /**
4 * @file: ../includes/page-form-builder/_out/export/builder-exporter.js
5 */
6 (function () {
7 "use strict";
8
9 const core = window.WPBC_BFB_Core || {};
10
11 // == Helpers — Shared helper API for field packs ==================================================================
12 // =================================================================================================
13 // == These are generic utilities that packs can call from their own exporters:
14 // == - compute_name(), id_option(), class_options(), size_max_token(), emit_time_select(), etc.
15 // == No field-type branching should live in the core exporter.
16 // =================================================================================================
17
18 /**
19 * Default skip list (can be extended/overridden at runtime).
20 * - Only attribute NAMES here (case-insensitive). Values are removed with them.
21 */
22 const wpbc_export_skip_attrs_default = ['data-colstyles-active'];
23
24 /**
25 * Remove attributes by name from an HTML-like string.
26 * Matches:
27 * - name
28 * - name="..."/name='...'/name=value
29 * with any surrounding whitespace.
30 *
31 * @param {string} html
32 * @param {string[]} attrs_lowercase attribute names (lowercase)
33 * @return {string}
34 */
35 function strip_attributes_from_markup(html, attrs_lowercase) {
36 if (!html || !attrs_lowercase?.length) return html;
37 let out = String(html);
38 for (const rawName of attrs_lowercase) {
39 if (!rawName) continue;
40 const name = String(rawName).toLowerCase().trim();
41 // Escape for regex
42 const esc = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
43 // Match full attribute name only (next char is NOT a valid name char)
44 const re = new RegExp(`\\s${esc}(?![A-Za-z0-9_:\\-])(?:=(?:"[^"]*"|'[^']*'|[^\\s>]*))?`, 'gi');
45 out = out.replace(re, '');
46 }
47 return out;
48 }
49
50 // == Helpers – column styles parsing & CSS vars builder ===========================================================
51
52 // Known keys we treat as real per-column style overrides.
53 function has_non_default_col_styles(obj) {
54 if (!obj || typeof obj !== 'object') {
55 return false;
56 }
57 var keys = ['dir', 'wrap', 'jc', 'ai', 'gap', 'aself', 'ac'];
58 for (var i = 0; i < keys.length; i++) {
59 var k = keys[i];
60 if (obj[k] != null && String(obj[k]).trim() !== '') {
61 return true;
62 }
63 }
64 return false;
65 }
66
67 /**
68 * Parse `col_styles` coming from a Section.
69 * Accepts: JSON string or array of objects.
70 *
71 * @param {string|Array|undefined|null} raw
72 * @returns {Array<Object>} array aligned to columns (may be empty)
73 */
74 function parse_col_styles_json(raw) {
75 if (!raw) return [];
76 if (Array.isArray(raw)) return raw.filter(function (x) {
77 return x && typeof x === 'object';
78 });
79 if (typeof raw === 'string') {
80 try {
81 var arr = JSON.parse(raw);
82 return Array.isArray(arr) ? arr.filter(function (x) {
83 return x && typeof x === 'object';
84 }) : [];
85 } catch (_e) {
86 return [];
87 }
88 }
89 return [];
90 }
91
92 /**
93 * Build CSS variable declarations string for a column style object.
94 * Known keys -> CSS vars:
95 * - dir -> --wpbc-bfb-col-dir
96 * - wrap -> --wpbc-bfb-col-wrap
97 * - jc -> --wpbc-bfb-col-jc
98 * - ai -> --wpbc-bfb-col-ai
99 * - gap -> --wpbc-bfb-col-gap
100 * - ac -> --wpbc-bfb-col-ac
101 * - aself-> --wpbc-bfb-col-aself
102 *
103 * Unknown keys are exported as `--wpbc-bfb-col-${key}`.
104 *
105 * @param {Object|null|undefined} obj
106 * @returns {string} e.g. "--wpbc-bfb-col-dir: row; --wpbc-bfb-col-wrap: wrap;"
107 */
108 function build_col_css_vars(obj) {
109 if (!obj || typeof obj !== 'object') return '';
110 var map = {
111 dir: '--wpbc-bfb-col-dir',
112 wrap: '--wpbc-bfb-col-wrap',
113 jc: '--wpbc-bfb-col-jc',
114 ai: '--wpbc-bfb-col-ai',
115 gap: '--wpbc-bfb-col-gap',
116 ac: '--wpbc-bfb-col-ac',
117 aself: '--wpbc-bfb-col-aself'
118 };
119 var parts = [];
120 for (var k in obj) {
121 if (!Object.prototype.hasOwnProperty.call(obj, k)) continue;
122 var v = obj[k];
123 if (v == null || v === '') continue;
124 var var_name = map[k] || '--wpbc-bfb-col-' + String(k).replace(/[^a-z0-9_-]/gi, '').toLowerCase();
125 parts.push(var_name + ': ' + String(v));
126 }
127
128 // Always include explicit min guard (requested): --wpbc-col-min: 0px;
129 parts.push('--wpbc-col-min: 0px');
130 return parts.join(';') + (parts.length ? ';' : '');
131 }
132
133 /**
134 * Resolve numeric percent from a width token like "48.5%".
135 * Falls back to `fallback_percent` if not in percent format.
136 *
137 * @param {string|number|undefined|null} width_token
138 * @param {number} fallback_percent
139 * @returns {number}
140 */
141 function resolve_flex_basis_percent(width_token, fallback_percent) {
142 if (typeof width_token === 'string') {
143 var s = width_token.trim();
144 if (s.endsWith('%')) {
145 var p = parseFloat(s);
146 if (isFinite(p)) return p;
147 }
148 }
149 if (typeof width_token === 'number' && isFinite(width_token)) {
150 return width_token;
151 }
152 return fallback_percent;
153 }
154
155 /**
156 * Compute effective flex-basis values that respect inter-column gap
157 *
158 * @param columns
159 * @param gap_percent
160 * @returns {*}
161 */
162 function compute_effective_bases(columns, gap_percent = 3) {
163 const n = columns && columns.length ? columns.length : 1;
164 const raw = columns.map(col => {
165 const w = col && col.width != null ? String(col.width).trim() : '';
166 const p = w.endsWith('%') ? parseFloat(w) : w ? parseFloat(w) : NaN;
167 return Number.isFinite(p) ? p : 100 / n;
168 });
169 const sum_raw = raw.reduce((a, b) => a + b, 0) || 100;
170 const gp = Number.isFinite(+gap_percent) ? +gap_percent : 3;
171 const total_gaps = Math.max(0, n - 1) * gp;
172 const available = Math.max(0, 100 - total_gaps);
173 const scale_ratio = available / sum_raw;
174 return raw.map(p => Math.max(0, p * scale_ratio));
175 }
176
177 // == adapter: builder (array-of-pages) > exporter shape { pages: [ { items:[ {kind,data} ] } ] } ==================
178 function adapt_builder_structure_to_exporter(structure) {
179 // if ( !Array.isArray( structure ) ) return { pages: [] };
180
181 // Ensure at least one page exists, even when Builder structure is empty `[]`.
182 // This keeps exported Advanced Form valid (wizard step #1 exists).
183 if (!Array.isArray(structure) || structure.length === 0) {
184 return {
185 pages: [{
186 items: []
187 }]
188 };
189 }
190 const normalize_options = opts => {
191 if (!Array.isArray(opts)) return [];
192 return opts.map(o => {
193 if (typeof o === 'string') return {
194 label: o,
195 value: o,
196 selected: false
197 };
198 if (o && typeof o === 'object') {
199 return {
200 label: String(o.label ?? o.value ?? ''),
201 value: String(o.value ?? o.label ?? ''),
202 selected: !!o.selected
203 };
204 }
205 return {
206 label: String(o),
207 value: String(o),
208 selected: false
209 };
210 });
211 };
212
213 // =================================================================================================
214 // == Adapter – attach parsed per-column `col_styles` from Section into each column
215 // =================================================================================================
216 const walk_section = sec => {
217 const section_col_styles = parse_col_styles_json(sec && sec.col_styles);
218 return {
219 id: sec?.id,
220 html_id: sec?.html_id || '',
221 cssclass: sec?.cssclass || '',
222 columns: (sec?.columns || []).map((col, col_index) => {
223 const items = Array.isArray(col?.items) ? col.items : [...(col?.fields || []).map(f => ({
224 type: 'field',
225 data: f
226 })), ...(col?.sections || []).map(s => ({
227 type: 'section',
228 data: s
229 }))];
230 const fields = items.filter(it => it && it.type === 'field').map(it => ({
231 ...it.data,
232 options: normalize_options(it.data?.options)
233 }));
234 const sections = items.filter(it => it && it.type === 'section').map(it => walk_section(it.data));
235 return {
236 width: col?.width || '100%',
237 style: col?.style || null,
238 col_styles: section_col_styles[col_index] || null,
239 // <- attach style object per column
240 fields,
241 sections
242 };
243 })
244 };
245 };
246 const pages = structure.map(page => {
247 const items = [];
248 (page?.content || []).forEach(item => {
249 if (!item) return;
250 if (item.type === 'section' && item.data) {
251 items.push({
252 kind: 'section',
253 data: walk_section(item.data)
254 });
255 } else if (item.type === 'field' && item.data) {
256 items.push({
257 kind: 'field',
258 data: {
259 ...item.data,
260 options: normalize_options(item.data.options)
261 }
262 });
263 }
264 });
265 return {
266 items
267 };
268 });
269 return {
270 pages
271 };
272 }
273
274 // == Booking From Exporter ========================================================================================
275 class WPBC_BFB_Exporter {
276 /**
277 * Mutable skip-list for attribute names (lowercase).
278 * You can override it via set_skip_attrs() or add with add_skip_attrs().
279 * @type {Set<string>}
280 */
281 static skip_attrs = new Set();
282
283 /**
284 * Replace the entire skip list.
285 * @param {string[]} arr
286 */
287 static set_skip_attrs(arr) {
288 this.skip_attrs = new Set((Array.isArray(arr) ? arr : []).map(n => String(n).toLowerCase().trim()).filter(Boolean));
289 }
290
291 /**
292 * Add one or many attributes to the skip list.
293 * @param {string|string[]} names
294 */
295 static add_skip_attrs(names) {
296 (Array.isArray(names) ? names : [names]).map(n => String(n).toLowerCase().trim()).filter(Boolean).forEach(n => this.skip_attrs.add(n));
297 }
298
299 /**
300 * Remove one attribute from the skip list.
301 * @param {string} name
302 */
303 static remove_skip_attr(name) {
304 if (!name) {
305 return;
306 }
307 this.skip_attrs.delete(String(name).toLowerCase().trim());
308 }
309
310 /**
311 * Apply attribute skipping to a final HTML string.
312 * @param {string} html
313 * @return {string}
314 */
315 static sanitize_export(html) {
316 return strip_attributes_from_markup(html, Array.from(this.skip_attrs));
317 }
318
319 /**
320 * Export adapted structure to advanced form text (with <r>/<c> layout and wizard wrapper).
321 *
322 * @param {Object} adapted
323 * @param {Object} [options]
324 * @param {string} [options.newline="\n"]
325 * @param {boolean} [options.addLabels=true]
326 * @param {number} [options.gapPercent=3]
327 * @returns {string}
328 */
329 static export_form(adapted, options = {}) {
330 // indent: use real TAB by default (can be overridden via options.indent)
331 const cfg = {
332 newline: '\n',
333 addLabels: true,
334 gapPercent: 3,
335 indent: '\t',
336 ...options
337 };
338 const IND = typeof cfg.indent === 'string' ? cfg.indent : '\t';
339 let depth = 0;
340 const lines = [];
341 const push = (s = '') => lines.push(IND.repeat(depth) + String(s));
342 const open = (s = '') => {
343 push(s);
344 depth++;
345 };
346 const close = (s = '') => {
347 depth = Math.max(0, depth - 1);
348 push(s);
349 };
350 const blank = () => {
351 lines.push('');
352 };
353 if (!adapted || !Array.isArray(adapted.pages)) return '';
354
355 // Always export at least one wizard step to keep Advanced Form structure valid.
356 const pages = adapted.pages.length ? adapted.pages : [{
357 items: []
358 }];
359 const ctx = {
360 usedIds: new Set()
361 };
362 open(`<div class="wpbc_bfb_form wpbc_wizard__border_container">`);
363
364 // one-per-form guards (calendar is not gated here)
365 const once = {
366 captcha: 0,
367 country: 0,
368 coupon: 0,
369 cost_corrections: 0,
370 submit: 0
371 };
372 pages.forEach((page, page_index) => {
373 const is_first = page_index === 0;
374 const step_num = page_index + 1;
375 const hidden_class = is_first ? '' : ' wpbc_wizard_step_hidden';
376 const hidden_style = is_first ? '' : ' style="display:none;clear:both;"';
377 open(`<div class="wpbc_wizard_step wpbc__form__div wpbc_wizard_step${step_num}${hidden_class}"${hidden_style}>`);
378 (page.items || []).forEach(item => {
379 if (item.kind === 'section') {
380 WPBC_BFB_Exporter.render_section(item.data, {
381 open,
382 close,
383 push,
384 blank
385 }, cfg, once, ctx);
386 // blank();
387 } else if (item.kind === 'field') {
388 open(`<r>`);
389 open(`<c>`);
390 WPBC_BFB_Exporter.render_field_node(item.data, {
391 open,
392 close,
393 push,
394 blank
395 }, cfg, once, ctx);
396 close(`</c>`);
397 close(`</r>`);
398 // blank();
399 }
400 });
401 close(`</div>`);
402 });
403 close(`</div>`);
404 return WPBC_BFB_Exporter.sanitize_export(lines.join(cfg.newline));
405 }
406
407 /**
408 * High-level helper: export full package from raw Builder structure.
409 *
410 * - Adapts raw Builder structure (pages/sections/columns/items) for exporters.
411 * - Builds:
412 * • advanced_form -> “Advanced Form (export)” text.
413 * • fields_data -> “Content of booking fields data (export)” text.
414 *
415 * @param {Array} structure Raw Builder structure from wpbc_bfb.get_structure().
416 * @param {Object} [options]
417 * @param {number} [options.gapPercent=3] Column gap percent for layout math.
418 *
419 * @returns {{
420 * advanced_form: string,
421 * fields_data: string,
422 * structure: Array,
423 * adapted: Object
424 * }}
425 */
426 static export_all(structure, options = {}) {
427 // 1) Adapt Builder JSON to exporter shape (pages[] -> items[]).
428 const adapted = adapt_builder_structure_to_exporter(structure || []);
429
430 // 2) Advanced Form text (same logic as debug panel).
431 const gap_percent = options && typeof options.gapPercent === 'number' ? options.gapPercent : 3;
432 const advanced_form = WPBC_BFB_Exporter.export_form(adapted, {
433 addLabels: true,
434 gapPercent: gap_percent
435 });
436
437 // 3) Content of booking fields data (if content exporter is available).
438 let fields_data = '';
439 if (window.WPBC_BFB_ContentExporter && typeof window.WPBC_BFB_ContentExporter.export_content === 'function') {
440 fields_data = window.WPBC_BFB_ContentExporter.export_content(adapted, {
441 addLabels: true,
442 sep: ': '
443 });
444 }
445 return {
446 advanced_form: advanced_form || '',
447 fields_data: fields_data || '',
448 structure: structure || [],
449 adapted: adapted
450 };
451 }
452
453 // =================================================================================================
454 // == Exporter – render_section() now injects per-column CSS vars from `col_styles`
455 // =================================================================================================
456 static render_section(section, io, cfg, once, ctx) {
457 once = once || {
458 captcha: 0,
459 country: 0,
460 coupon: 0,
461 cost_corrections: 0,
462 submit: 0
463 };
464 ctx = ctx || {
465 usedIds: new Set()
466 };
467 const {
468 open,
469 close
470 } = io;
471 const cols = Array.isArray(section.columns) && section.columns.length ? section.columns : [{
472 width: '100%',
473 fields: [],
474 sections: []
475 }];
476
477 // Row is active if ANY column carries styles.
478 var row_is_active = cols.some(function (col) {
479 return has_non_default_col_styles(col && col.col_styles);
480 });
481 var row_attr_active = row_is_active ? ' data-colstyles-active="1"' : '';
482 var row_custom_attrs = WPBC_BFB_Exporter.item_wrapper_attrs(section, ctx);
483 open(`<r${row_custom_attrs}${row_attr_active}>`);
484 const bases = compute_effective_bases(cols, cfg.gapPercent);
485 const esc_attr = core.WPBC_BFB_Sanitize.escape_html;
486 cols.forEach((col, idx) => {
487 // (1) Resolve flex-basis.
488 var eff_basis = resolve_flex_basis_percent(col && col.width, Number.isFinite(bases[idx]) ? +bases[idx] : 100);
489
490 // (2) Build inline style.
491 var style_parts = [];
492 if (col && typeof col.style === 'string' && col.style.trim()) {
493 style_parts.push(col.style.trim().replace(/;+\s*$/, ''));
494 }
495 style_parts.push('flex-basis: ' + (Number.isFinite(eff_basis) ? eff_basis.toString() : '100') + '%');
496 var css_vars_str = build_col_css_vars(col && col.col_styles);
497 if (css_vars_str) {
498 style_parts.push(css_vars_str.replace(/^;|;$/g, ''));
499 }
500 var style_attr = ` style="${esc_attr(style_parts.join('; '))}"`;
501
502 // (3) Column-level activation (more precise scoping)
503 var col_is_active = has_non_default_col_styles(col && col.col_styles);
504 var col_attr_active = col_is_active ? ' data-colstyles-active="1"' : '';
505 open(`<c${col_attr_active}${style_attr}>`);
506
507 // Use the shared once/ctx objects so single-per-form guards work across the whole form.
508 (col.fields || []).forEach(node => WPBC_BFB_Exporter.render_field_node(node, io, cfg, once, ctx));
509
510 // Recurse with the same once/ctx as well.
511 (col.sections || []).forEach(nested => WPBC_BFB_Exporter.render_section(nested, io, cfg, once, ctx));
512 close(`</c>`);
513 });
514 close(`</r>`);
515 }
516
517 /**
518 * Build a sanitized custom CSS class and HTML ID attribute string for an exported wrapper.
519 * Used by section row wrappers and fields whose attributes belong on the <item> wrapper.
520 * Also ensures uniqueness of the html_id across the export (uses ctx.usedIds).
521 *
522 * @param {Object} wrapper_data Object containing optional cssclass and html_id properties.
523 * @param {{usedIds:Set<string>}} ctx
524 * @returns {string} e.g. ' class="x y" id="myId"'
525 */
526 static item_wrapper_attrs(wrapper_data, ctx) {
527 if (!wrapper_data) {
528 return '';
529 }
530 const esc_html = core.WPBC_BFB_Sanitize.escape_html;
531 const cls_sanit = core.WPBC_BFB_Sanitize.sanitize_css_classlist;
532 const sid = core.WPBC_BFB_Sanitize.sanitize_html_id;
533 let out = '';
534 const cls_raw = String(wrapper_data.cssclass_extra || wrapper_data.cssclass || wrapper_data.class || '');
535 const cls = cls_sanit(cls_raw);
536 let html_id = wrapper_data.html_id ? sid(String(wrapper_data.html_id)) : '';
537 if (html_id && ctx?.usedIds) {
538 let unique = html_id,
539 i = 2;
540 while (ctx.usedIds.has(unique)) {
541 unique = `${html_id}_${i++}`;
542 }
543 ctx.usedIds.add(unique);
544 html_id = unique;
545 }
546 if (cls) {
547 out += ` class="${esc_html(cls)}"`;
548 }
549 if (html_id) {
550 out += ` id="${esc_html(html_id)}"`;
551 }
552 return out;
553 }
554
555 // =================================================================================================
556 // == Fields – pluggable, pack-driven export
557 // == Wrap every exported field inside <item>…</item> and delegate actual shortcode export
558 // == to per-pack callbacks registered via WPBC_BFB_Exporter.register(type, fn).
559 // =================================================================================================
560 static render_field_node(field, io, cfg, once, ctx) {
561 const {
562 open,
563 close,
564 push
565 } = io;
566 if (!field || !field.type) {
567 return;
568 }
569
570 // Shared context (usedIds, “once-per-form” guards, etc.).
571 once = once || {};
572 ctx = ctx || {
573 usedIds: new Set()
574 };
575 const type = String(field.type).toLowerCase();
576
577 // Optional wrapper attrs for special types (currently only used by captcha).
578 let item_attrs = '';
579 if (type === 'captcha') {
580 item_attrs = WPBC_BFB_Exporter.item_wrapper_attrs(field, ctx);
581 }
582 open(`<item${item_attrs}>`);
583 try {
584 // 1) Let the corresponding field pack handle export.
585 let handled = false;
586 if (WPBC_BFB_Exporter.has_exporter(type)) {
587 handled = WPBC_BFB_Exporter.run_registered_exporter(field, io, cfg, once, ctx);
588 }
589
590 // 2) Fallback: show a clear TODO comment if no exporter is registered.
591 if (!handled) {
592 const name = WPBC_BFB_Exporter.compute_name(type, field);
593 push(`<!-- TODO: map field type "${type}" name="${name}" in a pack exporter -->`);
594 }
595
596 // 3) Append help text consistently (packs shouldn’t duplicate this).
597 if (field.help) {
598 push(`<div class="wpbc_field_description">${core.WPBC_BFB_Sanitize.escape_html(String(field.help))}</div>`);
599 }
600 } finally {
601 // Always close wrapper.
602 close(`</item>`);
603 }
604 }
605
606 // =================================================================================================
607 // == Helpers ==
608 // =================================================================================================
609 static is_required(field) {
610 const v = field && field.required;
611 return v === true || v === 'true' || v === 1 || v === '1' || v === 'required';
612 }
613
614 /**
615 * Shared label emitter used by per-pack exporters.
616 *
617 * Emits optional <l>Label</l> + <br> before the provided body,
618 * respecting cfg.addLabels. Help text is emitted centrally in
619 * render_field_node(), so it is intentionally NOT handled here.
620 *
621 * @param {Object} field
622 * @param {function(string): void} emit
623 * @param {string} body
624 * @param {{addLabels?: boolean}} [cfg]
625 */
626 static emit_label_then(field, emit, body, cfg) {
627 if (typeof emit !== 'function') {
628 return;
629 }
630 cfg = cfg || {};
631 const addLabels = cfg.addLabels !== false;
632 const raw = field && typeof field.label === 'string' ? field.label : '';
633 const label = raw.trim();
634 var is_req = this.is_required(field);
635 var req_mark = is_req ? '*' : '';
636 if (label && addLabels) {
637 const esc_html = core.WPBC_BFB_Sanitize.escape_html;
638 emit('<l>' + esc_html(label) + req_mark + '</l>');
639 emit('<br>' + body);
640 } else {
641 emit(body);
642 }
643 }
644
645 // =================================================================================================
646 // == Helpers ==
647 // =================================================================================================
648
649 // -- Time Select Helpers --------------------------------------------------------------------------------------
650 static is_timeslot_picker_enabled() {
651 try {
652 return !!(window._wpbc && typeof window._wpbc.get_other_param === 'function' && window._wpbc.get_other_param('is_enabled_booking_timeslot_picker'));
653 } catch (_) {
654 return false;
655 }
656 }
657 static time_placeholder_for(name, field) {
658 // Prefer field-specific placeholder; else sensible default per field.
659 if (typeof field.placeholder === 'string' && field.placeholder.trim()) {
660 return field.placeholder.trim();
661 }
662 if (name === 'durationtime') return '--- Select duration ---';
663 return '--- Select time ---';
664 }
665
666 /**
667 * Build tokens/default for a time-like select (start/end/range/duration).
668 * - Adds an empty-value placeholder as the first option only when:
669 * • time picker is OFF, and
670 * • no option is selected by default, and
671 * • there isn't already an empty-value option.
672 */
673 static build_time_select_tokens(field, name) {
674 let tokens_str = this.option_tokens(field);
675 let def_str = this.default_option_suffix(field, tokens_str);
676 if (!this.is_timeslot_picker_enabled()) {
677 const opts = Array.isArray(field.options) ? field.options : [];
678 const has_selected_default = opts.some(o => o && (o.selected === true || o.selected === 'true' || o.selected === 1 || o.selected === '1'));
679 if (!has_selected_default) {
680 const has_empty_value_option = opts.some(o => o && typeof o.value !== 'undefined' && String(o.value).trim() === '');
681 if (!has_empty_value_option) {
682 const phText = this.time_placeholder_for(name, field);
683 const phTokenStr = '"' + core.WPBC_BFB_Sanitize.escape_for_shortcode(phText + '@@') + '"';
684 const other = this.option_tokens(field).trim(); // recompute, trim leading space
685 tokens_str = ' ' + phTokenStr + (other ? ' ' + other : '');
686
687 // Ensure first option (our placeholder) becomes the default implicitly
688 def_str = '';
689 }
690 }
691 }
692 return {
693 tokens_str,
694 def_str
695 };
696 }
697 static emit_time_select(name, field, req_mark, id_opt, cls_opts, emit_label_then) {
698 const {
699 tokens_str,
700 def_str
701 } = this.build_time_select_tokens(field, name);
702 // NOTE: No size/ph tokens here to mirror rangetime behavior exactly.
703 emit_label_then(`[selectbox${req_mark} ${name}${id_opt}${cls_opts}${def_str}${tokens_str}]`);
704 }
705
706 // -- Other Helpers --------------------------------------------------------------------------------------------
707 // Return a field's default value (supports both camelCase and snake_case).
708 static get_default_value(field) {
709 const v = field?.default_value ?? field?.defaultValue ?? '';
710 return v == null ? '' : String(v);
711 }
712
713 // For text-like fields, the default is a final quoted token in the shortcode.
714 static default_text_suffix(field) {
715 const v = this.get_default_value(field);
716 if (!v) return '';
717 return ` "${core.WPBC_BFB_Sanitize.escape_for_shortcode(v)}"`;
718 }
719 static class_options(field) {
720 const raw = field.class || field.className || field.cssclass || '';
721 const cls = core.WPBC_BFB_Sanitize.sanitize_css_classlist(String(raw));
722 if (!cls) return '';
723 return cls.split(/\s+/).filter(Boolean).map(c => ` class:${core.WPBC_BFB_Sanitize.to_token(c)}`).join('');
724 }
725 static id_option(field, ctx) {
726 const raw_id = field.html_id || field.id_attr;
727 if (!raw_id) return '';
728 const base = core.WPBC_BFB_Sanitize.to_token(raw_id);
729 if (!base) return '';
730 let unique = base,
731 i = 2;
732 while (ctx.usedIds.has(unique)) unique = `${base}_${i++}`;
733 ctx.usedIds.add(unique);
734 return ` id:${unique}`;
735 }
736 static ph_attr(v) {
737 if (v == null || v === '') return '';
738 return ` placeholder:"${core.WPBC_BFB_Sanitize.escape_for_attr_quoted(v)}"`;
739 }
740
741 // text-like size/maxlength token: "40/255" (or "40/" or "/255")
742 static size_max_token(f) {
743 const size = parseInt(f.size, 10);
744 const max = parseInt(f.maxlength, 10);
745 if (Number.isFinite(size) && Number.isFinite(max)) return ` ${size}/${max}`;
746 if (Number.isFinite(size)) return ` ${size}/`;
747 if (Number.isFinite(max)) return ` /${max}`;
748 return '';
749 }
750
751 // textarea cols/rows token: "60x4" (or "60x" or "x4")
752 static cols_rows_token(f) {
753 const cols = parseInt(f.cols, 10);
754 const rows = parseInt(f.rows, 10);
755 if (Number.isFinite(cols) && Number.isFinite(rows)) return ` ${cols}x${rows}`;
756 if (Number.isFinite(cols)) return ` ${cols}x`;
757 if (Number.isFinite(rows)) return ` x${rows}`;
758 return '';
759 }
760 static option_tokens(field) {
761 const options = Array.isArray(field.options) ? field.options : [];
762 if (options.length === 0) return '';
763 const parts = options.map(o => {
764 const title = String(o.label ?? o.value ?? '').trim();
765 const value = String(o.value ?? o.label ?? '').trim();
766 return title && value && title !== value ? `"${core.WPBC_BFB_Sanitize.escape_for_shortcode(`${title}@@${value}`)}"` : `"${core.WPBC_BFB_Sanitize.escape_for_shortcode(title || value)}"`;
767 });
768 return ' ' + parts.join(' ');
769 }
770 static default_option_suffix(field, tokens) {
771 const options = Array.isArray(field.options) ? field.options : [];
772 const selected = options.find(o => o.selected);
773 const def_val = selected ? selected.value ?? selected.label : field.default_value ?? field.defaultValue ?? '';
774 if (!def_val) return '';
775 return ` default="${core.WPBC_BFB_Sanitize.escape_value_for_attr(def_val)}"`;
776 }
777
778 /**
779 * SELECTBOX / RADIO - Build the final shortcode for choice-based fields.
780 *
781 * Responsibilities:
782 * - Delegates option/default encoding to:
783 * - WPBC_BFB_Exporter.option_tokens( field )
784 * - WPBC_BFB_Exporter.default_option_suffix( field, tokens )
785 * - For `radio`:
786 * - ALWAYS appends a bare `use_label_element` token.
787 * - For `selectbox`:
788 * - Adds a bare `multiple` token when `field.multiple` is truthy
789 * (true, "true", 1, "1", "multiple") -> `[selectbox services multiple "1" "2"]`.
790 * - When single-select AND there is no `default="..."` attribute AND
791 * a non-empty `field.placeholder` is present, encodes the placeholder
792 * as the FIRST option with empty value via the `@@` syntax:
793 * placeholder "---- Select ----" -> `"---- Select ----@@"`
794 * and clears any default attribute:
795 * [selectbox* services "--- Select ---@@" "Option 1" "Option 2"]
796 * - Respects `field.use_label_element` (adds bare `use_label_element` when true).
797 * - For both kinds:
798 * - Honors `field.label_first` by appending `label_first:"1"` when truthy.
799 * - Keeps the required star, id and cssclass tokens in the canonical order.
800 *
801 * Final shortcode layout (order is important):
802 * [kind req name id cls use_label_element multiple default tokens label_first]
803 *
804 * @jDoc
805 * @param {string} kind
806 * Shortcode kind; typically "radio" or "selectbox".
807 *
808 * @param {string} req_mark
809 * Required marker used by Contact Form 7 style shortcodes:
810 * either "" (not required) or "*" (required).
811 *
812 * @param {string} name
813 * Sanitized field name as exported into the shortcode, e.g. "services".
814 * Must already be computed via WPBC_BFB_Exporter.compute_name().
815 *
816 * @param {Object} field
817 * Normalized field data object as stored in the Builder structure. Common keys:
818 * - type {string} Field type, e.g. "radio" | "select".
819 * - options {Array} Option objects: { label, value, selected }.
820 * - placeholder {string} Placeholder text (single-select only).
821 * - multiple {boolean|string|number} Enables multi-select when truthy.
822 * - use_label_element {boolean} Request bare `use_label_element` token (non-radio).
823 * - label_first {boolean} If true, appends `label_first:"1"` token.
824 * - default_value {string} Optional default value (used by default_option_suffix()).
825 * - html_id / cssclass / class / className {string} Used upstream in id_opt/cls_opts.
826 *
827 * @param {string} id_opt
828 * Optional id token built by WPBC_BFB_Exporter.id_option(field, ctx),
829 * e.g. " id:my_id" or empty string.
830 *
831 * @param {string} cls_opts
832 * Class tokens built by WPBC_BFB_Exporter.class_options(field),
833 * e.g. " class:my_class class:other".
834 *
835 * @returns {string}
836 * Complete shortcode body for the choice field, for example:
837 * "[radio* services use_label_element \"A\" \"B\"]"
838 * "[selectbox services multiple \"1\" \"2\" \"3\"]"
839 * "[selectbox* services \"--- Select ---@@\" \"Option 1\" \"Option 2\"]"
840 */
841 static choice_tag(kind, req_mark, name, field, id_opt, cls_opts) {
842 // Start from the raw options/default as before.
843 let tokens = WPBC_BFB_Exporter.option_tokens(field);
844 let def = WPBC_BFB_Exporter.default_option_suffix(field, tokens);
845
846 // For RADIO we must ALWAYS include a bare `use_label_element` token (no value/quotes).
847 // For other kinds, keep backward compatibility: include only if explicitly set.
848 let ule = '';
849 if (kind === 'radio') {
850 ule = ' use_label_element';
851 } else if (field && field.use_label_element) {
852 ule = ' use_label_element';
853 }
854
855 // SELECTBOX-specific extras:
856 // - "multiple" flag
857 // - placeholder exported as FIRST OPTION when single-select and no default.
858 let multiple_flag = '';
859 if (kind === 'selectbox' && field) {
860 const multiple = field.multiple === true || field.multiple === 'true' || field.multiple === 1 || field.multiple === '1' || field.multiple === 'multiple';
861 if (multiple) {
862 // Export bare "multiple" token as in: [selectbox services multiple "1" "2" "3"].
863 multiple_flag = ' multiple';
864 } else if (!def) {
865 // Single-select + NO default selected:
866 // export placeholder as the FIRST OPTION with empty value:
867 // [selectbox* services "--- Select ---@@" "Option 1" "Option 2"]
868 const rawPh = field.placeholder;
869 const ph = typeof rawPh === 'string' ? rawPh.trim() : '';
870 if (ph) {
871 const S = core.WPBC_BFB_Sanitize;
872 const esc_sc = S && S.escape_for_shortcode ? S.escape_for_shortcode : v => String(v);
873 const phToken = `"${esc_sc(ph + '@@')}"`;
874 if (tokens && tokens.length) {
875 // tokens already starts with a leading space.
876 tokens = ' ' + phToken + tokens;
877 } else {
878 tokens = ' ' + phToken;
879 }
880
881 // Ensure there is still NO default attribute when using placeholder-as-option.
882 def = '';
883 }
884 }
885 }
886
887 // Optional: label_first stays as quoted flag when explicitly requested.
888 const lf = field && field.label_first ? ' label_first:"1"' : '';
889
890 // IMPORTANT ORDER (per request):
891 // [kind req name id cls use_label_element multiple default tokens label_first]
892 // i.e. `use_label_element` (and select extras) come BEFORE default/tokens.
893 return `[${kind}${req_mark} ${name}${id_opt}${cls_opts}${ule}${multiple_flag}${def}${tokens}${lf}]`;
894 }
895 static compute_name(type, field) {
896 // Names are fully validated when the field is added to the canvas.
897 // The exporter must therefore preserve them (apart from idempotent sanitization), otherwise existing forms can break.
898 const Sanit = core.WPBC_BFB_Sanitize;
899 const raw = field && (field.name || field.id) ? String(field.name || field.id) : String(type || 'field');
900
901 // Idempotent sanitization only – no auto-prefixing or renaming.
902 const name = Sanit.sanitize_html_name(raw);
903
904 // In the unlikely case sanitization returns an empty string, fall back to a sanitized type-based token.
905 return name || Sanit.sanitize_html_name(String(type || 'field'));
906 }
907
908 /**
909 * Register a per-field exporter.
910 *
911 * This is the ONLY place where field-specific shortcode markup should live.
912 * Core stays generic; packs provide tiny plugins, for example:
913 *
914 * WPBC_BFB_Exporter.register( 'text', (field, emit, extras) => { ... } );
915 *
916 * @jDoc
917 * @param {string} type Field type key, e.g. 'steps_timeline'
918 * @param {(field:any, emit:(code:string)=>void, extras?:{io?:any,cfg?:any,once?:any,ctx?:any,core?:any})=>void}
919 * fn
920 * @returns {void}
921 */
922 static register(type, fn) {
923 if (!type || typeof fn !== 'function') {
924 return;
925 }
926 if (!this.__registry) {
927 this.__registry = new Map();
928 }
929 this.__registry.set(String(type).toLowerCase(), fn);
930 }
931
932 /**
933 * Unregister a previously registered exporter.
934 *
935 * @jDoc
936 * @param {string} type
937 * @returns {void}
938 */
939 static unregister(type) {
940 if (!this.__registry || !type) {
941 return;
942 }
943 this.__registry.delete(String(type).toLowerCase());
944 }
945
946 /**
947 * Check if an exporter exists for a given field type.
948 *
949 * @jDoc
950 * @param {string} type
951 * @returns {boolean}
952 */
953 static has_exporter(type) {
954 return !!(this.__registry && this.__registry.has(String(type).toLowerCase()));
955 }
956
957 /**
958 * Run a registered exporter for a field, if present.
959 * Returns true if a registered exporter handled it.
960 *
961 * @jDoc
962 * @param {any} field
963 * @param {{open:Function,close:Function,push:Function,blank:Function}} io
964 * @param {any} cfg
965 * @param {any} once
966 * @param {any} ctx
967 * @returns {boolean}
968 */
969 static run_registered_exporter(field, io, cfg, once, ctx) {
970 if (!field || !field.type || !this.__registry) {
971 return false;
972 }
973 const key = String(field.type).toLowerCase();
974 const fn = this.__registry.get(key);
975 if (typeof fn !== 'function') {
976 return false;
977 }
978 try {
979 // Minimal, consistent emit() bridge into our line buffer:
980 const emit = code => {
981 if (typeof code === 'string') {
982 io.push(code);
983 }
984 };
985 fn(field, emit, {
986 io,
987 cfg,
988 once,
989 ctx,
990 core
991 });
992 return true;
993 } catch (e) {
994 _wpbc?.dev?.error?.('WPBC_BFB_Exporter.run_registered_exporter', e);
995 return false;
996 }
997 }
998 }
999
1000 // expose globally for packs (if not already).
1001 window.WPBC_BFB_Exporter = window.WPBC_BFB_Exporter || WPBC_BFB_Exporter;
1002 wpbc_bfb__dispatch_event_safe('wpbc:bfb:exporter-ready', {});
1003
1004 // Initialize default skip list; allow a global override array before export runs.
1005 WPBC_BFB_Exporter.set_skip_attrs(window.WPBC_BFB_EXPORT_SKIP_ATTRS || wpbc_export_skip_attrs_default);
1006
1007 // == "Content of booking fields data" Exporter ====================================================================
1008
1009 // – pack-extensible generator for "Content of booking fields data" ============================================
1010 // == Produces markup like: "<div class=\"standard-content-form\"><b>Title</b>: <f>[shortcode]</f><br> ... </div>"
1011 // == Packs can override per type via: WPBC_BFB_ContentExporter.register('calendar', (field, emit, ctx)=>{...})
1012 // =================================================================================================
1013 class WPBC_BFB_ContentExporter {
1014 static register(type, fn) {
1015 if (!type || typeof fn !== 'function') return;
1016 if (!this.__registry) this.__registry = new Map();
1017 this.__registry.set(String(type).toLowerCase(), fn);
1018 }
1019 static unregister(type) {
1020 if (!this.__registry || !type) return;
1021 this.__registry.delete(String(type).toLowerCase());
1022 }
1023 static has_exporter(type) {
1024 return !!(this.__registry && this.__registry.has(String(type).toLowerCase()));
1025 }
1026 static run_registered_exporter(field, emit, ctx) {
1027 if (!field || !field.type || !this.__registry) return false;
1028 const key = String(field.type).toLowerCase();
1029 const fn = this.__registry.get(key);
1030 if (typeof fn !== 'function') return false;
1031 try {
1032 fn(field, emit, ctx || {});
1033 return true;
1034 } catch (e) {
1035 _wpbc?.dev?.error?.('WPBC_BFB_ContentExporter.run_registered_exporter', e);
1036 return false;
1037 }
1038 }
1039
1040 // === NEW: shared line formatter for "Content of booking fields data" ===
1041 static emit_line_bold_field(emit, label, token, cfg) {
1042 const S = core.WPBC_BFB_Sanitize;
1043 const sep = cfg && typeof cfg.sep === 'string' ? cfg.sep : ': ';
1044 const addLabels = cfg && 'addLabels' in cfg ? !!cfg.addLabels : true;
1045 const title = addLabels && label ? `<b>${S.escape_html(label)}</b>${sep}` : '';
1046 emit(`${title}<f>[${token}]</f><br>`);
1047 }
1048
1049 /**
1050 * Export adapted structure to “content of booking fields data”.
1051 * @param {{pages:Array}} adapted result of adapt_builder_structure_to_exporter()
1052 * @param {{newline?:string, addLabels?:boolean, sep?:string}} options
1053 * @returns {string}
1054 */
1055 static export_content(adapted, options = {}) {
1056 const cfg = {
1057 newline: '\n',
1058 addLabels: true,
1059 sep: ': ',
1060 indent: '\t',
1061 ...options
1062 };
1063 const IND = typeof cfg.indent === 'string' ? cfg.indent : '\t';
1064 let depth = 0;
1065 const lines = [];
1066 const push = (s = '') => lines.push(IND.repeat(depth) + String(s));
1067 const open = (s = '') => {
1068 push(s);
1069 depth++;
1070 };
1071 const close = (s = '') => {
1072 depth = Math.max(0, depth - 1);
1073 push(s);
1074 };
1075 const emit = s => {
1076 if (typeof s !== 'string') {
1077 return;
1078 }
1079 String(s).split(/\r?\n/).forEach(line => push(line));
1080 };
1081 if (!adapted || !Array.isArray(adapted.pages)) return '';
1082 const skipTypes = new Set(['captcha', 'submit', 'divider', 'wizard_nav', 'cost_corrections']);
1083 const fallbackLine = field => {
1084 const type = String(field.type || '').toLowerCase();
1085 const name = WPBC_BFB_Exporter.compute_name(type, field);
1086 const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : name;
1087 if (!name) return;
1088 WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, name, cfg);
1089 };
1090
1091 // Per-type sensible defaults (can be overridden by packs via register())
1092 const defaultContentFor = field => {
1093 const type = String(field.type || '').toLowerCase();
1094 if (skipTypes.has(type)) return;
1095 // Special cases out of the box:
1096 if (type === 'calendar') {
1097 const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : 'Dates';
1098 WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, 'dates', cfg);
1099 return;
1100 }
1101 // time-like reserved names -> keep placeholder token equal to name
1102 const reserved = String(field.name || field.id || '').toLowerCase();
1103 if (['rangetime', 'starttime', 'endtime', 'durationtime'].includes(reserved)) {
1104 const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : reserved;
1105 // Keep your special token for duration time in content: [durationtime_val]
1106 const token = reserved === 'durationtime' ? 'durationtime_val' : reserved;
1107 WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, token, cfg);
1108 return;
1109 }
1110 // Fallback (text/email/tel/number/textarea/select/checkbox/radio etc.)
1111 fallbackLine(field);
1112 };
1113
1114 // Walk pages/sections/columns/fields (same order as form)
1115 const walkSection = sec => {
1116 (sec.columns || []).forEach(col => {
1117 (col.fields || []).forEach(f => processField(f));
1118 (col.sections || []).forEach(s => walkSection(s));
1119 });
1120 };
1121 const processItem = item => {
1122 if (!item) return;
1123 if (item.kind === 'field') processField(item.data);
1124 if (item.kind === 'section') walkSection(item.data);
1125 };
1126 const processField = field => {
1127 if (!field) return;
1128 // allow packs to override:
1129 if (WPBC_BFB_ContentExporter.run_registered_exporter(field, emit, {
1130 cfg,
1131 core
1132 })) return;
1133 defaultContentFor(field);
1134 };
1135
1136 // Wrapper first -> inner lines will be TAB-indented
1137 open(`<div class="standard-content-form">`);
1138 adapted.pages.forEach(page => (page.items || []).forEach(processItem));
1139 close(`</div>`);
1140 return lines.join(cfg.newline);
1141 }
1142 }
1143
1144 // expose + ready event for packs to register their content exporters.
1145 window.WPBC_BFB_ContentExporter = window.WPBC_BFB_ContentExporter || WPBC_BFB_ContentExporter;
1146 wpbc_bfb__dispatch_event_safe('wpbc:bfb:content-exporter-ready', {});
1147 })();
1148 //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvX291dC9leHBvcnQvYnVpbGRlci1leHBvcnRlci5qcyIsIm5hbWVzIjpbImNvcmUiLCJ3aW5kb3ciLCJXUEJDX0JGQl9Db3JlIiwid3BiY19leHBvcnRfc2tpcF9hdHRyc19kZWZhdWx0Iiwic3RyaXBfYXR0cmlidXRlc19mcm9tX21hcmt1cCIsImh0bWwiLCJhdHRyc19sb3dlcmNhc2UiLCJsZW5ndGgiLCJvdXQiLCJTdHJpbmciLCJyYXdOYW1lIiwibmFtZSIsInRvTG93ZXJDYXNlIiwidHJpbSIsImVzYyIsInJlcGxhY2UiLCJyZSIsIlJlZ0V4cCIsImhhc19ub25fZGVmYXVsdF9jb2xfc3R5bGVzIiwib2JqIiwia2V5cyIsImkiLCJrIiwicGFyc2VfY29sX3N0eWxlc19qc29uIiwicmF3IiwiQXJyYXkiLCJpc0FycmF5IiwiZmlsdGVyIiwieCIsImFyciIsIkpTT04iLCJwYXJzZSIsIl9lIiwiYnVpbGRfY29sX2Nzc192YXJzIiwibWFwIiwiZGlyIiwid3JhcCIsImpjIiwiYWkiLCJnYXAiLCJhYyIsImFzZWxmIiwicGFydHMiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ2IiwidmFyX25hbWUiLCJwdXNoIiwiam9pbiIsInJlc29sdmVfZmxleF9iYXNpc19wZXJjZW50Iiwid2lkdGhfdG9rZW4iLCJmYWxsYmFja19wZXJjZW50IiwicyIsImVuZHNXaXRoIiwicCIsInBhcnNlRmxvYXQiLCJpc0Zpbml0ZSIsImNvbXB1dGVfZWZmZWN0aXZlX2Jhc2VzIiwiY29sdW1ucyIsImdhcF9wZXJjZW50IiwibiIsImNvbCIsInciLCJ3aWR0aCIsIk5hTiIsIk51bWJlciIsInN1bV9yYXciLCJyZWR1Y2UiLCJhIiwiYiIsImdwIiwidG90YWxfZ2FwcyIsIk1hdGgiLCJtYXgiLCJhdmFpbGFibGUiLCJzY2FsZV9yYXRpbyIsImFkYXB0X2J1aWxkZXJfc3RydWN0dXJlX3RvX2V4cG9ydGVyIiwic3RydWN0dXJlIiwicGFnZXMiLCJpdGVtcyIsIm5vcm1hbGl6ZV9vcHRpb25zIiwib3B0cyIsIm8iLCJsYWJlbCIsInZhbHVlIiwic2VsZWN0ZWQiLCJ3YWxrX3NlY3Rpb24iLCJzZWMiLCJzZWN0aW9uX2NvbF9zdHlsZXMiLCJjb2xfc3R5bGVzIiwiaWQiLCJodG1sX2lkIiwiY3NzY2xhc3MiLCJjb2xfaW5kZXgiLCJmaWVsZHMiLCJmIiwidHlwZSIsImRhdGEiLCJzZWN0aW9ucyIsIml0Iiwib3B0aW9ucyIsInN0eWxlIiwicGFnZSIsImNvbnRlbnQiLCJmb3JFYWNoIiwiaXRlbSIsImtpbmQiLCJXUEJDX0JGQl9FeHBvcnRlciIsInNraXBfYXR0cnMiLCJTZXQiLCJzZXRfc2tpcF9hdHRycyIsIkJvb2xlYW4iLCJhZGRfc2tpcF9hdHRycyIsIm5hbWVzIiwiYWRkIiwicmVtb3ZlX3NraXBfYXR0ciIsImRlbGV0ZSIsInNhbml0aXplX2V4cG9ydCIsImZyb20iLCJleHBvcnRfZm9ybSIsImFkYXB0ZWQiLCJjZmciLCJuZXdsaW5lIiwiYWRkTGFiZWxzIiwiZ2FwUGVyY2VudCIsImluZGVudCIsIklORCIsImRlcHRoIiwibGluZXMiLCJyZXBlYXQiLCJvcGVuIiwiY2xvc2UiLCJibGFuayIsImN0eCIsInVzZWRJZHMiLCJvbmNlIiwiY2FwdGNoYSIsImNvdW50cnkiLCJjb3Vwb24iLCJjb3N0X2NvcnJlY3Rpb25zIiwic3VibWl0IiwicGFnZV9pbmRleCIsImlzX2ZpcnN0Iiwic3RlcF9udW0iLCJoaWRkZW5fY2xhc3MiLCJoaWRkZW5fc3R5bGUiLCJyZW5kZXJfc2VjdGlvbiIsInJlbmRlcl9maWVsZF9ub2RlIiwiZXhwb3J0X2FsbCIsImFkdmFuY2VkX2Zvcm0iLCJmaWVsZHNfZGF0YSIsIldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlciIsImV4cG9ydF9jb250ZW50Iiwic2VwIiwic2VjdGlvbiIsImlvIiwiY29scyIsInJvd19pc19hY3RpdmUiLCJzb21lIiwicm93X2F0dHJfYWN0aXZlIiwicm93X2N1c3RvbV9hdHRycyIsIml0ZW1fd3JhcHBlcl9hdHRycyIsImJhc2VzIiwiZXNjX2F0dHIiLCJXUEJDX0JGQl9TYW5pdGl6ZSIsImVzY2FwZV9odG1sIiwiaWR4IiwiZWZmX2Jhc2lzIiwic3R5bGVfcGFydHMiLCJ0b1N0cmluZyIsImNzc192YXJzX3N0ciIsInN0eWxlX2F0dHIiLCJjb2xfaXNfYWN0aXZlIiwiY29sX2F0dHJfYWN0aXZlIiwibm9kZSIsIm5lc3RlZCIsIndyYXBwZXJfZGF0YSIsImVzY19odG1sIiwiY2xzX3Nhbml0Iiwic2FuaXRpemVfY3NzX2NsYXNzbGlzdCIsInNpZCIsInNhbml0aXplX2h0bWxfaWQiLCJjbHNfcmF3IiwiY3NzY2xhc3NfZXh0cmEiLCJjbGFzcyIsImNscyIsInVuaXF1ZSIsImhhcyIsImZpZWxkIiwiaXRlbV9hdHRycyIsImhhbmRsZWQiLCJoYXNfZXhwb3J0ZXIiLCJydW5fcmVnaXN0ZXJlZF9leHBvcnRlciIsImNvbXB1dGVfbmFtZSIsImhlbHAiLCJpc19yZXF1aXJlZCIsInJlcXVpcmVkIiwiZW1pdF9sYWJlbF90aGVuIiwiZW1pdCIsImJvZHkiLCJpc19yZXEiLCJyZXFfbWFyayIsImlzX3RpbWVzbG90X3BpY2tlcl9lbmFibGVkIiwiX3dwYmMiLCJnZXRfb3RoZXJfcGFyYW0iLCJfIiwidGltZV9wbGFjZWhvbGRlcl9mb3IiLCJwbGFjZWhvbGRlciIsImJ1aWxkX3RpbWVfc2VsZWN0X3Rva2VucyIsInRva2Vuc19zdHIiLCJvcHRpb25fdG9rZW5zIiwiZGVmX3N0ciIsImRlZmF1bHRfb3B0aW9uX3N1ZmZpeCIsImhhc19zZWxlY3RlZF9kZWZhdWx0IiwiaGFzX2VtcHR5X3ZhbHVlX29wdGlvbiIsInBoVGV4dCIsInBoVG9rZW5TdHIiLCJlc2NhcGVfZm9yX3Nob3J0Y29kZSIsIm90aGVyIiwiZW1pdF90aW1lX3NlbGVjdCIsImlkX29wdCIsImNsc19vcHRzIiwiZ2V0X2RlZmF1bHRfdmFsdWUiLCJkZWZhdWx0X3ZhbHVlIiwiZGVmYXVsdFZhbHVlIiwiZGVmYXVsdF90ZXh0X3N1ZmZpeCIsImNsYXNzX29wdGlvbnMiLCJjbGFzc05hbWUiLCJzcGxpdCIsImMiLCJ0b190b2tlbiIsImlkX29wdGlvbiIsInJhd19pZCIsImlkX2F0dHIiLCJiYXNlIiwicGhfYXR0ciIsImVzY2FwZV9mb3JfYXR0cl9xdW90ZWQiLCJzaXplX21heF90b2tlbiIsInNpemUiLCJwYXJzZUludCIsIm1heGxlbmd0aCIsImNvbHNfcm93c190b2tlbiIsInJvd3MiLCJ0aXRsZSIsInRva2VucyIsImZpbmQiLCJkZWZfdmFsIiwiZXNjYXBlX3ZhbHVlX2Zvcl9hdHRyIiwiY2hvaWNlX3RhZyIsImRlZiIsInVsZSIsInVzZV9sYWJlbF9lbGVtZW50IiwibXVsdGlwbGVfZmxhZyIsIm11bHRpcGxlIiwicmF3UGgiLCJwaCIsIlMiLCJlc2Nfc2MiLCJwaFRva2VuIiwibGYiLCJsYWJlbF9maXJzdCIsIlNhbml0Iiwic2FuaXRpemVfaHRtbF9uYW1lIiwicmVnaXN0ZXIiLCJmbiIsIl9fcmVnaXN0cnkiLCJNYXAiLCJzZXQiLCJ1bnJlZ2lzdGVyIiwia2V5IiwiZ2V0IiwiY29kZSIsImUiLCJkZXYiLCJlcnJvciIsIndwYmNfYmZiX19kaXNwYXRjaF9ldmVudF9zYWZlIiwiV1BCQ19CRkJfRVhQT1JUX1NLSVBfQVRUUlMiLCJlbWl0X2xpbmVfYm9sZF9maWVsZCIsInRva2VuIiwibGluZSIsInNraXBUeXBlcyIsImZhbGxiYWNrTGluZSIsImRlZmF1bHRDb250ZW50Rm9yIiwicmVzZXJ2ZWQiLCJpbmNsdWRlcyIsIndhbGtTZWN0aW9uIiwicHJvY2Vzc0ZpZWxkIiwicHJvY2Vzc0l0ZW0iXSwic291cmNlcyI6WyJpbmNsdWRlcy9wYWdlLWZvcm0tYnVpbGRlci9fc3JjL2V4cG9ydC9idWlsZGVyLWV4cG9ydGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBAZmlsZTogLi4vaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvX291dC9leHBvcnQvYnVpbGRlci1leHBvcnRlci5qc1xyXG4gKi9cclxuKGZ1bmN0aW9uICgpIHtcclxuXHRcInVzZSBzdHJpY3RcIjtcclxuXHJcblx0Y29uc3QgY29yZSA9IHdpbmRvdy5XUEJDX0JGQl9Db3JlIHx8IHt9O1xyXG5cclxuXHQvLyA9PSBIZWxwZXJzIOKAlCBTaGFyZWQgaGVscGVyIEFQSSBmb3IgZmllbGQgcGFja3MgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdC8vID09IFRoZXNlIGFyZSBnZW5lcmljIHV0aWxpdGllcyB0aGF0IHBhY2tzIGNhbiBjYWxsIGZyb20gdGhlaXIgb3duIGV4cG9ydGVyczpcclxuXHQvLyA9PSAgLSBjb21wdXRlX25hbWUoKSwgaWRfb3B0aW9uKCksIGNsYXNzX29wdGlvbnMoKSwgc2l6ZV9tYXhfdG9rZW4oKSwgZW1pdF90aW1lX3NlbGVjdCgpLCBldGMuXHJcblx0Ly8gPT0gTm8gZmllbGQtdHlwZSBicmFuY2hpbmcgc2hvdWxkIGxpdmUgaW4gdGhlIGNvcmUgZXhwb3J0ZXIuXHJcblx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuXHQvKipcclxuXHQgKiBEZWZhdWx0IHNraXAgbGlzdCAoY2FuIGJlIGV4dGVuZGVkL292ZXJyaWRkZW4gYXQgcnVudGltZSkuXHJcblx0ICogLSBPbmx5IGF0dHJpYnV0ZSBOQU1FUyBoZXJlIChjYXNlLWluc2Vuc2l0aXZlKS4gVmFsdWVzIGFyZSByZW1vdmVkIHdpdGggdGhlbS5cclxuXHQgKi9cclxuXHRjb25zdCB3cGJjX2V4cG9ydF9za2lwX2F0dHJzX2RlZmF1bHQgPSBbICdkYXRhLWNvbHN0eWxlcy1hY3RpdmUnIF07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlbW92ZSBhdHRyaWJ1dGVzIGJ5IG5hbWUgZnJvbSBhbiBIVE1MLWxpa2Ugc3RyaW5nLlxyXG5cdCAqIE1hdGNoZXM6XHJcblx0ICogICAtIG5hbWVcclxuXHQgKiAgIC0gbmFtZT1cIi4uLlwiL25hbWU9Jy4uLicvbmFtZT12YWx1ZVxyXG5cdCAqIHdpdGggYW55IHN1cnJvdW5kaW5nIHdoaXRlc3BhY2UuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaHRtbFxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nW119IGF0dHJzX2xvd2VyY2FzZSAgIGF0dHJpYnV0ZSBuYW1lcyAobG93ZXJjYXNlKVxyXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cclxuXHQgKi9cclxuXHRmdW5jdGlvbiBzdHJpcF9hdHRyaWJ1dGVzX2Zyb21fbWFya3VwKGh0bWwsIGF0dHJzX2xvd2VyY2FzZSkge1xyXG5cdFx0aWYgKCFodG1sIHx8ICFhdHRyc19sb3dlcmNhc2U/Lmxlbmd0aCkgcmV0dXJuIGh0bWw7XHJcblx0XHRsZXQgb3V0ID0gU3RyaW5nKGh0bWwpO1xyXG5cdFx0Zm9yIChjb25zdCByYXdOYW1lIG9mIGF0dHJzX2xvd2VyY2FzZSkge1xyXG5cdFx0XHRpZiAoIXJhd05hbWUpIGNvbnRpbnVlO1xyXG5cdFx0XHRjb25zdCBuYW1lID0gU3RyaW5nKHJhd05hbWUpLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xyXG5cdFx0XHQvLyBFc2NhcGUgZm9yIHJlZ2V4XHJcblx0XHRcdGNvbnN0IGVzYyA9IG5hbWUucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTtcclxuXHRcdFx0Ly8gTWF0Y2ggZnVsbCBhdHRyaWJ1dGUgbmFtZSBvbmx5IChuZXh0IGNoYXIgaXMgTk9UIGEgdmFsaWQgbmFtZSBjaGFyKVxyXG5cdFx0XHRjb25zdCByZSA9IG5ldyBSZWdFeHAoXHJcblx0XHRcdFx0YFxcXFxzJHtlc2N9KD8hW0EtWmEtejAtOV86XFxcXC1dKSg/Oj0oPzpcIlteXCJdKlwifCdbXiddKid8W15cXFxccz5dKikpP2AsXHJcblx0XHRcdFx0J2dpJ1xyXG5cdFx0XHQpO1xyXG5cdFx0XHRvdXQgPSBvdXQucmVwbGFjZShyZSwgJycpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG91dDtcclxuXHR9XHJcblxyXG5cdC8vID09IEhlbHBlcnMg4oCTIGNvbHVtbiBzdHlsZXMgcGFyc2luZyAmIENTUyB2YXJzIGJ1aWxkZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcblx0Ly8gS25vd24ga2V5cyB3ZSB0cmVhdCBhcyByZWFsIHBlci1jb2x1bW4gc3R5bGUgb3ZlcnJpZGVzLlxyXG5cdGZ1bmN0aW9uIGhhc19ub25fZGVmYXVsdF9jb2xfc3R5bGVzKG9iaikge1xyXG5cdFx0aWYgKCAhb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnICkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblx0XHR2YXIga2V5cyA9IFsgJ2RpcicsICd3cmFwJywgJ2pjJywgJ2FpJywgJ2dhcCcsICdhc2VsZicsICdhYycgXTtcclxuXHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKysgKSB7XHJcblx0XHRcdHZhciBrID0ga2V5c1tpXTtcclxuXHRcdFx0aWYgKCBvYmpba10gIT0gbnVsbCAmJiBTdHJpbmcoIG9ialtrXSApLnRyaW0oKSAhPT0gJycgKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhcnNlIGBjb2xfc3R5bGVzYCBjb21pbmcgZnJvbSBhIFNlY3Rpb24uXHJcblx0ICogQWNjZXB0czogSlNPTiBzdHJpbmcgb3IgYXJyYXkgb2Ygb2JqZWN0cy5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfEFycmF5fHVuZGVmaW5lZHxudWxsfSByYXdcclxuXHQgKiBAcmV0dXJucyB7QXJyYXk8T2JqZWN0Pn0gYXJyYXkgYWxpZ25lZCB0byBjb2x1bW5zIChtYXkgYmUgZW1wdHkpXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gcGFyc2VfY29sX3N0eWxlc19qc29uKHJhdykge1xyXG5cdFx0aWYgKCAhcmF3ICkgcmV0dXJuIFtdO1xyXG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCByYXcgKSApIHJldHVybiByYXcuZmlsdGVyKCBmdW5jdGlvbiAoeCkge1xyXG5cdFx0XHRyZXR1cm4geCAmJiB0eXBlb2YgeCA9PT0gJ29iamVjdCc7XHJcblx0XHR9ICk7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgcmF3ID09PSAnc3RyaW5nJyApIHtcclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHR2YXIgYXJyID0gSlNPTi5wYXJzZSggcmF3ICk7XHJcblx0XHRcdFx0cmV0dXJuIEFycmF5LmlzQXJyYXkoIGFyciApID8gYXJyLmZpbHRlciggZnVuY3Rpb24gKHgpIHtcclxuXHRcdFx0XHRcdHJldHVybiB4ICYmIHR5cGVvZiB4ID09PSAnb2JqZWN0JztcclxuXHRcdFx0XHR9ICkgOiBbXTtcclxuXHRcdFx0fSBjYXRjaCAoIF9lICkge1xyXG5cdFx0XHRcdHJldHVybiBbXTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIFtdO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQnVpbGQgQ1NTIHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBzdHJpbmcgZm9yIGEgY29sdW1uIHN0eWxlIG9iamVjdC5cclxuXHQgKiBLbm93biBrZXlzIC0+IENTUyB2YXJzOlxyXG5cdCAqICAtIGRpciAgLT4gLS13cGJjLWJmYi1jb2wtZGlyXHJcblx0ICogIC0gd3JhcCAtPiAtLXdwYmMtYmZiLWNvbC13cmFwXHJcblx0ICogIC0gamMgICAtPiAtLXdwYmMtYmZiLWNvbC1qY1xyXG5cdCAqICAtIGFpICAgLT4gLS13cGJjLWJmYi1jb2wtYWlcclxuXHQgKiAgLSBnYXAgIC0+IC0td3BiYy1iZmItY29sLWdhcFxyXG5cdCAqICAtIGFjICAgLT4gLS13cGJjLWJmYi1jb2wtYWNcclxuXHQgKiAgLSBhc2VsZi0+IC0td3BiYy1iZmItY29sLWFzZWxmXHJcblx0ICpcclxuXHQgKiBVbmtub3duIGtleXMgYXJlIGV4cG9ydGVkIGFzIGAtLXdwYmMtYmZiLWNvbC0ke2tleX1gLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R8bnVsbHx1bmRlZmluZWR9IG9ialxyXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9IGUuZy4gXCItLXdwYmMtYmZiLWNvbC1kaXI6IHJvdzsgLS13cGJjLWJmYi1jb2wtd3JhcDogd3JhcDtcIlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIGJ1aWxkX2NvbF9jc3NfdmFycyhvYmopIHtcclxuXHRcdGlmICggIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyApIHJldHVybiAnJztcclxuXHJcblx0XHR2YXIgbWFwID0ge1xyXG5cdFx0XHRkaXIgIDogJy0td3BiYy1iZmItY29sLWRpcicsXHJcblx0XHRcdHdyYXAgOiAnLS13cGJjLWJmYi1jb2wtd3JhcCcsXHJcblx0XHRcdGpjICAgOiAnLS13cGJjLWJmYi1jb2wtamMnLFxyXG5cdFx0XHRhaSAgIDogJy0td3BiYy1iZmItY29sLWFpJyxcclxuXHRcdFx0Z2FwICA6ICctLXdwYmMtYmZiLWNvbC1nYXAnLFxyXG5cdFx0XHRhYyAgIDogJy0td3BiYy1iZmItY29sLWFjJyxcclxuXHRcdFx0YXNlbGY6ICctLXdwYmMtYmZiLWNvbC1hc2VsZidcclxuXHRcdH07XHJcblxyXG5cdFx0dmFyIHBhcnRzID0gW107XHJcblxyXG5cdFx0Zm9yICggdmFyIGsgaW4gb2JqICkge1xyXG5cdFx0XHRpZiAoICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoIG9iaiwgayApICkgY29udGludWU7XHJcblx0XHRcdHZhciB2ID0gb2JqW2tdO1xyXG5cdFx0XHRpZiAoIHYgPT0gbnVsbCB8fCB2ID09PSAnJyApIGNvbnRpbnVlO1xyXG5cclxuXHRcdFx0dmFyIHZhcl9uYW1lID0gbWFwW2tdIHx8ICgnLS13cGJjLWJmYi1jb2wtJyArIFN0cmluZyggayApLnJlcGxhY2UoIC9bXmEtejAtOV8tXS9naSwgJycgKS50b0xvd2VyQ2FzZSgpKTtcclxuXHRcdFx0cGFydHMucHVzaCggdmFyX25hbWUgKyAnOiAnICsgU3RyaW5nKCB2ICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBbHdheXMgaW5jbHVkZSBleHBsaWNpdCBtaW4gZ3VhcmQgKHJlcXVlc3RlZCk6IC0td3BiYy1jb2wtbWluOiAwcHg7XHJcblx0XHRwYXJ0cy5wdXNoKCAnLS13cGJjLWNvbC1taW46IDBweCcgKTtcclxuXHJcblx0XHRyZXR1cm4gcGFydHMuam9pbiggJzsnICkgKyAocGFydHMubGVuZ3RoID8gJzsnIDogJycpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmVzb2x2ZSBudW1lcmljIHBlcmNlbnQgZnJvbSBhIHdpZHRoIHRva2VuIGxpa2UgXCI0OC41JVwiLlxyXG5cdCAqIEZhbGxzIGJhY2sgdG8gYGZhbGxiYWNrX3BlcmNlbnRgIGlmIG5vdCBpbiBwZXJjZW50IGZvcm1hdC5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnx1bmRlZmluZWR8bnVsbH0gd2lkdGhfdG9rZW5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gZmFsbGJhY2tfcGVyY2VudFxyXG5cdCAqIEByZXR1cm5zIHtudW1iZXJ9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gcmVzb2x2ZV9mbGV4X2Jhc2lzX3BlcmNlbnQod2lkdGhfdG9rZW4sIGZhbGxiYWNrX3BlcmNlbnQpIHtcclxuXHRcdGlmICggdHlwZW9mIHdpZHRoX3Rva2VuID09PSAnc3RyaW5nJyApIHtcclxuXHRcdFx0dmFyIHMgPSB3aWR0aF90b2tlbi50cmltKCk7XHJcblx0XHRcdGlmICggcy5lbmRzV2l0aCggJyUnICkgKSB7XHJcblx0XHRcdFx0dmFyIHAgPSBwYXJzZUZsb2F0KCBzICk7XHJcblx0XHRcdFx0aWYgKCBpc0Zpbml0ZSggcCApICkgcmV0dXJuIHA7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGlmICggdHlwZW9mIHdpZHRoX3Rva2VuID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSggd2lkdGhfdG9rZW4gKSApIHtcclxuXHRcdFx0cmV0dXJuIHdpZHRoX3Rva2VuO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGZhbGxiYWNrX3BlcmNlbnQ7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDb21wdXRlIGVmZmVjdGl2ZSBmbGV4LWJhc2lzIHZhbHVlcyB0aGF0IHJlc3BlY3QgaW50ZXItY29sdW1uIGdhcFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGNvbHVtbnNcclxuXHQgKiBAcGFyYW0gZ2FwX3BlcmNlbnRcclxuXHQgKiBAcmV0dXJucyB7Kn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiBjb21wdXRlX2VmZmVjdGl2ZV9iYXNlcyhjb2x1bW5zLCBnYXBfcGVyY2VudCA9IDMpIHtcclxuXHJcblx0XHRjb25zdCBuID0gY29sdW1ucyAmJiBjb2x1bW5zLmxlbmd0aCA/IGNvbHVtbnMubGVuZ3RoIDogMTtcclxuXHJcblx0XHRjb25zdCByYXcgPSBjb2x1bW5zLm1hcCggKGNvbCkgPT4ge1xyXG5cdFx0XHRjb25zdCB3ID0gY29sICYmIGNvbC53aWR0aCAhPSBudWxsID8gU3RyaW5nKCBjb2wud2lkdGggKS50cmltKCkgOiAnJztcclxuXHRcdFx0Y29uc3QgcCA9IHcuZW5kc1dpdGgoICclJyApID8gcGFyc2VGbG9hdCggdyApIDogdyA/IHBhcnNlRmxvYXQoIHcgKSA6IE5hTjtcclxuXHRcdFx0cmV0dXJuIE51bWJlci5pc0Zpbml0ZSggcCApID8gcCA6IDEwMCAvIG47XHJcblx0XHR9ICk7XHJcblxyXG5cdFx0Y29uc3Qgc3VtX3JhdyAgICAgPSByYXcucmVkdWNlKCAoYSwgYikgPT4gYSArIGIsIDAgKSB8fCAxMDA7XHJcblx0XHRjb25zdCBncCAgICAgICAgICA9IE51bWJlci5pc0Zpbml0ZSggK2dhcF9wZXJjZW50ICkgPyArZ2FwX3BlcmNlbnQgOiAzO1xyXG5cdFx0Y29uc3QgdG90YWxfZ2FwcyAgPSBNYXRoLm1heCggMCwgbiAtIDEgKSAqIGdwO1xyXG5cdFx0Y29uc3QgYXZhaWxhYmxlICAgPSBNYXRoLm1heCggMCwgMTAwIC0gdG90YWxfZ2FwcyApO1xyXG5cdFx0Y29uc3Qgc2NhbGVfcmF0aW8gPSBhdmFpbGFibGUgLyBzdW1fcmF3O1xyXG5cclxuXHRcdHJldHVybiByYXcubWFwKCAocCkgPT4gTWF0aC5tYXgoIDAsIHAgKiBzY2FsZV9yYXRpbyApICk7XHJcblx0fVxyXG5cclxuXHQvLyA9PSBhZGFwdGVyOiBidWlsZGVyIChhcnJheS1vZi1wYWdlcykgPiBleHBvcnRlciBzaGFwZSB7IHBhZ2VzOiBbIHsgaXRlbXM6WyB7a2luZCxkYXRhfSBdIH0gXSB9ID09PT09PT09PT09PT09PT09PVxyXG5cdGZ1bmN0aW9uIGFkYXB0X2J1aWxkZXJfc3RydWN0dXJlX3RvX2V4cG9ydGVyKHN0cnVjdHVyZSkge1xyXG5cclxuLy9cdFx0aWYgKCAhQXJyYXkuaXNBcnJheSggc3RydWN0dXJlICkgKSByZXR1cm4geyBwYWdlczogW10gfTtcclxuXHJcblx0XHQvLyBFbnN1cmUgYXQgbGVhc3Qgb25lIHBhZ2UgZXhpc3RzLCBldmVuIHdoZW4gQnVpbGRlciBzdHJ1Y3R1cmUgaXMgZW1wdHkgYFtdYC5cclxuXHRcdC8vIFRoaXMga2VlcHMgZXhwb3J0ZWQgQWR2YW5jZWQgRm9ybSB2YWxpZCAod2l6YXJkIHN0ZXAgIzEgZXhpc3RzKS5cclxuXHRcdGlmICggISBBcnJheS5pc0FycmF5KCBzdHJ1Y3R1cmUgKSB8fCBzdHJ1Y3R1cmUubGVuZ3RoID09PSAwICkge1xyXG5cdFx0XHRyZXR1cm4geyBwYWdlczogWyB7IGl0ZW1zOiBbXSB9IF0gfTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBub3JtYWxpemVfb3B0aW9ucyA9IChvcHRzKSA9PiB7XHJcblx0XHRcdGlmICggIUFycmF5LmlzQXJyYXkoIG9wdHMgKSApIHJldHVybiBbXTtcclxuXHRcdFx0cmV0dXJuIG9wdHMubWFwKCAobykgPT4ge1xyXG5cdFx0XHRcdGlmICggdHlwZW9mIG8gPT09ICdzdHJpbmcnICkgcmV0dXJuIHsgbGFiZWw6IG8sIHZhbHVlOiBvLCBzZWxlY3RlZDogZmFsc2UgfTtcclxuXHRcdFx0XHRpZiAoIG8gJiYgdHlwZW9mIG8gPT09ICdvYmplY3QnICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0bGFiZWwgICA6IFN0cmluZyggby5sYWJlbCA/PyBvLnZhbHVlID8/ICcnICksXHJcblx0XHRcdFx0XHRcdHZhbHVlICAgOiBTdHJpbmcoIG8udmFsdWUgPz8gby5sYWJlbCA/PyAnJyApLFxyXG5cdFx0XHRcdFx0XHRzZWxlY3RlZDogISFvLnNlbGVjdGVkXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4geyBsYWJlbDogU3RyaW5nKCBvICksIHZhbHVlOiBTdHJpbmcoIG8gKSwgc2VsZWN0ZWQ6IGZhbHNlIH07XHJcblx0XHRcdH0gKTtcclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0Ly8gPT0gQWRhcHRlciDigJMgYXR0YWNoIHBhcnNlZCBwZXItY29sdW1uIGBjb2xfc3R5bGVzYCBmcm9tIFNlY3Rpb24gaW50byBlYWNoIGNvbHVtblxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0Y29uc3Qgd2Fsa19zZWN0aW9uID0gKHNlYykgPT4ge1xyXG5cdFx0XHRjb25zdCBzZWN0aW9uX2NvbF9zdHlsZXMgPSBwYXJzZV9jb2xfc3R5bGVzX2pzb24oIHNlYyAmJiBzZWMuY29sX3N0eWxlcyApO1xyXG5cclxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0aWQgICAgICAgOiBzZWM/LmlkLFxuXHRcdFx0XHRodG1sX2lkICA6IHNlYz8uaHRtbF9pZCB8fCAnJyxcblx0XHRcdFx0Y3NzY2xhc3MgOiBzZWM/LmNzc2NsYXNzIHx8ICcnLFxuXHRcdFx0XHRjb2x1bW5zICA6IChzZWM/LmNvbHVtbnMgfHwgW10pLm1hcCggKGNvbCwgY29sX2luZGV4KSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgaXRlbXMgPSBBcnJheS5pc0FycmF5KCBjb2w/Lml0ZW1zIClcclxuXHRcdFx0XHRcdFx0PyBjb2wuaXRlbXNcclxuXHRcdFx0XHRcdFx0OiBbXHJcblx0XHRcdFx0XHRcdFx0Li4uKGNvbD8uZmllbGRzIHx8IFtdKS5tYXAoIChmKSA9PiAoeyB0eXBlOiAnZmllbGQnLCBkYXRhOiBmIH0pICksXHJcblx0XHRcdFx0XHRcdFx0Li4uKGNvbD8uc2VjdGlvbnMgfHwgW10pLm1hcCggKHMpID0+ICh7IHR5cGU6ICdzZWN0aW9uJywgZGF0YTogcyB9KSApXHJcblx0XHRcdFx0XHRcdF07XHJcblxyXG5cdFx0XHRcdFx0Y29uc3QgZmllbGRzID0gaXRlbXNcclxuXHRcdFx0XHRcdFx0LmZpbHRlciggKGl0KSA9PiBpdCAmJiBpdC50eXBlID09PSAnZmllbGQnIClcclxuXHRcdFx0XHRcdFx0Lm1hcCggKGl0KSA9PiAoeyAuLi5pdC5kYXRhLCBvcHRpb25zOiBub3JtYWxpemVfb3B0aW9ucyggaXQuZGF0YT8ub3B0aW9ucyApIH0pICk7XHJcblxyXG5cdFx0XHRcdFx0Y29uc3Qgc2VjdGlvbnMgPSBpdGVtc1xyXG5cdFx0XHRcdFx0XHQuZmlsdGVyKCAoaXQpID0+IGl0ICYmIGl0LnR5cGUgPT09ICdzZWN0aW9uJyApXHJcblx0XHRcdFx0XHRcdC5tYXAoIChpdCkgPT4gd2Fsa19zZWN0aW9uKCBpdC5kYXRhICkgKTtcclxuXHJcblx0XHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0XHR3aWR0aCAgICAgIDogY29sPy53aWR0aCB8fCAnMTAwJScsXHJcblx0XHRcdFx0XHRcdHN0eWxlICAgICAgOiBjb2w/LnN0eWxlIHx8IG51bGwsXHJcblx0XHRcdFx0XHRcdGNvbF9zdHlsZXMgOiBzZWN0aW9uX2NvbF9zdHlsZXNbIGNvbF9pbmRleCBdIHx8IG51bGwsICAgLy8gPC0gYXR0YWNoIHN0eWxlIG9iamVjdCBwZXIgY29sdW1uXHJcblx0XHRcdFx0XHRcdGZpZWxkcyxcclxuXHRcdFx0XHRcdFx0c2VjdGlvbnNcclxuXHRcdFx0XHRcdH07XHJcblx0XHRcdFx0fSApXHJcblx0XHRcdH07XHJcblx0XHR9O1xyXG5cclxuXHJcblx0XHRjb25zdCBwYWdlcyA9IHN0cnVjdHVyZS5tYXAoIChwYWdlKSA9PiB7XHJcblx0XHRcdGNvbnN0IGl0ZW1zID0gW107XHJcblx0XHRcdChwYWdlPy5jb250ZW50IHx8IFtdKS5mb3JFYWNoKCAoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGlmICggIWl0ZW0gKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKCBpdGVtLnR5cGUgPT09ICdzZWN0aW9uJyAmJiBpdGVtLmRhdGEgKSB7XHJcblx0XHRcdFx0XHRpdGVtcy5wdXNoKCB7IGtpbmQ6ICdzZWN0aW9uJywgZGF0YTogd2Fsa19zZWN0aW9uKCBpdGVtLmRhdGEgKSB9ICk7XHJcblx0XHRcdFx0fSBlbHNlIGlmICggaXRlbS50eXBlID09PSAnZmllbGQnICYmIGl0ZW0uZGF0YSApIHtcclxuXHRcdFx0XHRcdGl0ZW1zLnB1c2goIHtcclxuXHRcdFx0XHRcdFx0a2luZDogJ2ZpZWxkJyxcclxuXHRcdFx0XHRcdFx0ZGF0YTogeyAuLi5pdGVtLmRhdGEsIG9wdGlvbnM6IG5vcm1hbGl6ZV9vcHRpb25zKCBpdGVtLmRhdGEub3B0aW9ucyApIH1cclxuXHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gKTtcclxuXHRcdFx0cmV0dXJuIHsgaXRlbXMgfTtcclxuXHRcdH0gKTtcclxuXHJcblx0XHRyZXR1cm4geyBwYWdlcyB9O1xyXG5cdH1cclxuXHJcblxyXG5cdC8vID09IEJvb2tpbmcgRnJvbSBFeHBvcnRlciA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0Y2xhc3MgV1BCQ19CRkJfRXhwb3J0ZXIge1xyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogTXV0YWJsZSBza2lwLWxpc3QgZm9yIGF0dHJpYnV0ZSBuYW1lcyAobG93ZXJjYXNlKS5cclxuXHRcdCAqIFlvdSBjYW4gb3ZlcnJpZGUgaXQgdmlhIHNldF9za2lwX2F0dHJzKCkgb3IgYWRkIHdpdGggYWRkX3NraXBfYXR0cnMoKS5cclxuXHRcdCAqIEB0eXBlIHtTZXQ8c3RyaW5nPn1cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHNraXBfYXR0cnMgPSBuZXcgU2V0KCk7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZXBsYWNlIHRoZSBlbnRpcmUgc2tpcCBsaXN0LlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmdbXX0gYXJyXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBzZXRfc2tpcF9hdHRycyggYXJyICkge1xyXG5cdFx0XHR0aGlzLnNraXBfYXR0cnMgPSBuZXcgU2V0KFxyXG5cdFx0XHRcdChBcnJheS5pc0FycmF5KCBhcnIgKSA/IGFyciA6IFtdKS5tYXAoIChuKSA9PiBTdHJpbmcoIG4gKS50b0xvd2VyQ2FzZSgpLnRyaW0oKSApLmZpbHRlciggQm9vbGVhbiApXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBBZGQgb25lIG9yIG1hbnkgYXR0cmlidXRlcyB0byB0aGUgc2tpcCBsaXN0LlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd8c3RyaW5nW119IG5hbWVzXHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBhZGRfc2tpcF9hdHRycyggbmFtZXMgKSB7XHJcblx0XHRcdCggQXJyYXkuaXNBcnJheSggbmFtZXMgKSA/IG5hbWVzIDogWyBuYW1lcyBdIClcclxuXHRcdFx0XHQubWFwKCAobikgPT4gU3RyaW5nKCBuICkudG9Mb3dlckNhc2UoKS50cmltKCkgKVxyXG5cdFx0XHRcdC5maWx0ZXIoIEJvb2xlYW4gKVxyXG5cdFx0XHRcdC5mb3JFYWNoKCAobikgPT4gdGhpcy5za2lwX2F0dHJzLmFkZCggbiApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZW1vdmUgb25lIGF0dHJpYnV0ZSBmcm9tIHRoZSBza2lwIGxpc3QuXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgcmVtb3ZlX3NraXBfYXR0ciggbmFtZSApIHtcclxuXHRcdFx0aWYgKCAhIG5hbWUgKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLnNraXBfYXR0cnMuZGVsZXRlKCBTdHJpbmcoIG5hbWUgKS50b0xvd2VyQ2FzZSgpLnRyaW0oKSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQXBwbHkgYXR0cmlidXRlIHNraXBwaW5nIHRvIGEgZmluYWwgSFRNTCBzdHJpbmcuXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gaHRtbFxyXG5cdFx0ICogQHJldHVybiB7c3RyaW5nfVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgc2FuaXRpemVfZXhwb3J0KCBodG1sICkge1xyXG5cdFx0XHRyZXR1cm4gc3RyaXBfYXR0cmlidXRlc19mcm9tX21hcmt1cCggaHRtbCwgQXJyYXkuZnJvbSggdGhpcy5za2lwX2F0dHJzICkgKTtcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBFeHBvcnQgYWRhcHRlZCBzdHJ1Y3R1cmUgdG8gYWR2YW5jZWQgZm9ybSB0ZXh0ICh3aXRoIDxyPi88Yz4gbGF5b3V0IGFuZCB3aXphcmQgd3JhcHBlcikuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGFkYXB0ZWRcclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSAgW29wdGlvbnMubmV3bGluZT1cIlxcblwiXVxyXG5cdFx0ICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5hZGRMYWJlbHM9dHJ1ZV1cclxuXHRcdCAqIEBwYXJhbSB7bnVtYmVyfSAgW29wdGlvbnMuZ2FwUGVyY2VudD0zXVxyXG5cdFx0ICogQHJldHVybnMge3N0cmluZ31cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIGV4cG9ydF9mb3JtKGFkYXB0ZWQsIG9wdGlvbnMgPSB7fSkge1xyXG5cdFx0XHQvLyBpbmRlbnQ6IHVzZSByZWFsIFRBQiBieSBkZWZhdWx0IChjYW4gYmUgb3ZlcnJpZGRlbiB2aWEgb3B0aW9ucy5pbmRlbnQpXHJcblx0XHRcdGNvbnN0IGNmZyA9IHsgbmV3bGluZTogJ1xcbicsIGFkZExhYmVsczogdHJ1ZSwgZ2FwUGVyY2VudDogMywgaW5kZW50OiAnXFx0JywgLi4ub3B0aW9ucyB9O1xyXG5cdFx0XHRjb25zdCBJTkQgPSAodHlwZW9mIGNmZy5pbmRlbnQgPT09ICdzdHJpbmcnKSA/IGNmZy5pbmRlbnQgOiAnXFx0JztcclxuXHJcblx0XHRcdGxldCBkZXB0aCAgID0gMDtcclxuXHRcdFx0Y29uc3QgbGluZXMgPSBbXTtcclxuXHRcdFx0Y29uc3QgcHVzaCAgPSAocyA9ICcnKSA9PiBsaW5lcy5wdXNoKCBJTkQucmVwZWF0KCBkZXB0aCApICsgU3RyaW5nKCBzICkgKTtcclxuXHRcdFx0Y29uc3Qgb3BlbiAgPSAocyA9ICcnKSA9PiB7XHJcblx0XHRcdFx0cHVzaCggcyApO1xyXG5cdFx0XHRcdGRlcHRoKys7XHJcblx0XHRcdH07XHJcblx0XHRcdGNvbnN0IGNsb3NlID0gKHMgPSAnJykgPT4ge1xyXG5cdFx0XHRcdGRlcHRoID0gTWF0aC5tYXgoIDAsIGRlcHRoIC0gMSApO1xyXG5cdFx0XHRcdHB1c2goIHMgKTtcclxuXHRcdFx0fTtcclxuXHRcdFx0Y29uc3QgYmxhbmsgPSAoKSA9PiB7XHJcblx0XHRcdFx0bGluZXMucHVzaCggJycgKTtcclxuXHRcdFx0fTtcclxuXHJcblx0XHRcdGlmICggIWFkYXB0ZWQgfHwgIUFycmF5LmlzQXJyYXkoIGFkYXB0ZWQucGFnZXMgKSApIHJldHVybiAnJztcclxuXHJcblx0XHRcdC8vIEFsd2F5cyBleHBvcnQgYXQgbGVhc3Qgb25lIHdpemFyZCBzdGVwIHRvIGtlZXAgQWR2YW5jZWQgRm9ybSBzdHJ1Y3R1cmUgdmFsaWQuXHJcblx0XHRcdGNvbnN0IHBhZ2VzID0gYWRhcHRlZC5wYWdlcy5sZW5ndGggPyBhZGFwdGVkLnBhZ2VzIDogWyB7IGl0ZW1zOiBbXSB9IF07XHJcblxyXG5cdFx0XHRjb25zdCBjdHggPSB7IHVzZWRJZHM6IG5ldyBTZXQoKSB9O1xyXG5cclxuXHRcdFx0b3BlbiggYDxkaXYgY2xhc3M9XCJ3cGJjX2JmYl9mb3JtIHdwYmNfd2l6YXJkX19ib3JkZXJfY29udGFpbmVyXCI+YCApO1xyXG5cclxuXHRcdFx0Ly8gb25lLXBlci1mb3JtIGd1YXJkcyAoY2FsZW5kYXIgaXMgbm90IGdhdGVkIGhlcmUpXHJcblx0XHRcdGNvbnN0IG9uY2UgPSB7IGNhcHRjaGE6IDAsIGNvdW50cnk6IDAsIGNvdXBvbjogMCwgY29zdF9jb3JyZWN0aW9uczogMCwgc3VibWl0OiAwIH07XHJcblxyXG5cdFx0XHRwYWdlcy5mb3JFYWNoKCAocGFnZSwgcGFnZV9pbmRleCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGlzX2ZpcnN0ID0gcGFnZV9pbmRleCA9PT0gMDtcclxuXHRcdFx0XHRjb25zdCBzdGVwX251bSA9IHBhZ2VfaW5kZXggKyAxO1xyXG5cclxuXHRcdFx0XHRjb25zdCBoaWRkZW5fY2xhc3MgPSBpc19maXJzdCA/ICcnIDogJyB3cGJjX3dpemFyZF9zdGVwX2hpZGRlbic7XHJcblx0XHRcdFx0Y29uc3QgaGlkZGVuX3N0eWxlID0gaXNfZmlyc3QgPyAnJyA6ICcgc3R5bGU9XCJkaXNwbGF5Om5vbmU7Y2xlYXI6Ym90aDtcIic7XHJcblx0XHRcdFx0b3BlbiggYDxkaXYgY2xhc3M9XCJ3cGJjX3dpemFyZF9zdGVwIHdwYmNfX2Zvcm1fX2RpdiB3cGJjX3dpemFyZF9zdGVwJHtzdGVwX251bX0ke2hpZGRlbl9jbGFzc31cIiR7aGlkZGVuX3N0eWxlfT5gICk7XHJcblxyXG5cdFx0XHRcdChwYWdlLml0ZW1zIHx8IFtdKS5mb3JFYWNoKCAoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0aWYgKCBpdGVtLmtpbmQgPT09ICdzZWN0aW9uJyApIHtcclxuXHRcdFx0XHRcdFx0V1BCQ19CRkJfRXhwb3J0ZXIucmVuZGVyX3NlY3Rpb24oIGl0ZW0uZGF0YSwgeyBvcGVuLCBjbG9zZSwgcHVzaCwgYmxhbmsgfSwgY2ZnLCBvbmNlLCBjdHggKTtcclxuXHRcdFx0XHRcdFx0Ly8gYmxhbmsoKTtcclxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIGl0ZW0ua2luZCA9PT0gJ2ZpZWxkJyApIHtcclxuXHRcdFx0XHRcdFx0b3BlbiggYDxyPmAgKTtcclxuXHRcdFx0XHRcdFx0b3BlbiggYDxjPmAgKTtcclxuXHRcdFx0XHRcdFx0V1BCQ19CRkJfRXhwb3J0ZXIucmVuZGVyX2ZpZWxkX25vZGUoIGl0ZW0uZGF0YSwgeyBvcGVuLCBjbG9zZSwgcHVzaCwgYmxhbmsgfSwgY2ZnLCBvbmNlLCBjdHggKTtcclxuXHRcdFx0XHRcdFx0Y2xvc2UoIGA8L2M+YCApO1xyXG5cdFx0XHRcdFx0XHRjbG9zZSggYDwvcj5gICk7XHJcblx0XHRcdFx0XHRcdC8vIGJsYW5rKCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSApO1xyXG5cclxuXHRcdFx0XHRjbG9zZSggYDwvZGl2PmAgKTtcclxuXHRcdFx0fSApO1xyXG5cclxuXHRcdFx0Y2xvc2UoIGA8L2Rpdj5gICk7XHJcblx0XHRcdHJldHVybiBXUEJDX0JGQl9FeHBvcnRlci5zYW5pdGl6ZV9leHBvcnQoIGxpbmVzLmpvaW4oIGNmZy5uZXdsaW5lICkgKTtcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBIaWdoLWxldmVsIGhlbHBlcjogZXhwb3J0IGZ1bGwgcGFja2FnZSBmcm9tIHJhdyBCdWlsZGVyIHN0cnVjdHVyZS5cclxuXHRcdCAqXHJcblx0XHQgKiAtIEFkYXB0cyByYXcgQnVpbGRlciBzdHJ1Y3R1cmUgKHBhZ2VzL3NlY3Rpb25zL2NvbHVtbnMvaXRlbXMpIGZvciBleHBvcnRlcnMuXHJcblx0XHQgKiAtIEJ1aWxkczpcclxuXHRcdCAqICAgICAg4oCiIGFkdmFuY2VkX2Zvcm0gIC0+IOKAnEFkdmFuY2VkIEZvcm0gKGV4cG9ydCnigJ0gdGV4dC5cclxuXHRcdCAqICAgICAg4oCiIGZpZWxkc19kYXRhICAgIC0+IOKAnENvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YSAoZXhwb3J0KeKAnSB0ZXh0LlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9ICBzdHJ1Y3R1cmUgIFJhdyBCdWlsZGVyIHN0cnVjdHVyZSBmcm9tIHdwYmNfYmZiLmdldF9zdHJ1Y3R1cmUoKS5cclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cclxuXHRcdCAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5nYXBQZXJjZW50PTNdICBDb2x1bW4gZ2FwIHBlcmNlbnQgZm9yIGxheW91dCBtYXRoLlxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm5zIHt7XHJcblx0XHQgKiAgIGFkdmFuY2VkX2Zvcm06IHN0cmluZyxcclxuXHRcdCAqICAgZmllbGRzX2RhdGE6IHN0cmluZyxcclxuXHRcdCAqICAgc3RydWN0dXJlOiBBcnJheSxcclxuXHRcdCAqICAgYWRhcHRlZDogT2JqZWN0XHJcblx0XHQgKiB9fVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgZXhwb3J0X2FsbCggc3RydWN0dXJlLCBvcHRpb25zID0ge30gKSB7XHJcblxyXG5cdFx0XHQvLyAxKSBBZGFwdCBCdWlsZGVyIEpTT04gdG8gZXhwb3J0ZXIgc2hhcGUgKHBhZ2VzW10gLT4gaXRlbXNbXSkuXHJcblx0XHRcdGNvbnN0IGFkYXB0ZWQgPSBhZGFwdF9idWlsZGVyX3N0cnVjdHVyZV90b19leHBvcnRlciggc3RydWN0dXJlIHx8IFtdICk7XHJcblxyXG5cdFx0XHQvLyAyKSBBZHZhbmNlZCBGb3JtIHRleHQgKHNhbWUgbG9naWMgYXMgZGVidWcgcGFuZWwpLlxyXG5cdFx0XHRjb25zdCBnYXBfcGVyY2VudCAgID0gKCBvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLmdhcFBlcmNlbnQgPT09ICdudW1iZXInICkgPyBvcHRpb25zLmdhcFBlcmNlbnQgOiAzO1xyXG5cdFx0XHRjb25zdCBhZHZhbmNlZF9mb3JtID0gV1BCQ19CRkJfRXhwb3J0ZXIuZXhwb3J0X2Zvcm0oXHJcblx0XHRcdFx0YWRhcHRlZCxcclxuXHRcdFx0XHR7XHJcblx0XHRcdFx0XHRhZGRMYWJlbHMgOiB0cnVlLFxyXG5cdFx0XHRcdFx0Z2FwUGVyY2VudDogZ2FwX3BlcmNlbnRcclxuXHRcdFx0XHR9XHJcblx0XHRcdCk7XHJcblxyXG5cdFx0XHQvLyAzKSBDb250ZW50IG9mIGJvb2tpbmcgZmllbGRzIGRhdGEgKGlmIGNvbnRlbnQgZXhwb3J0ZXIgaXMgYXZhaWxhYmxlKS5cclxuXHRcdFx0bGV0IGZpZWxkc19kYXRhID0gJyc7XHJcblx0XHRcdGlmIChcclxuXHRcdFx0XHR3aW5kb3cuV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyICYmXHJcblx0XHRcdFx0dHlwZW9mIHdpbmRvdy5XUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIuZXhwb3J0X2NvbnRlbnQgPT09ICdmdW5jdGlvbidcclxuXHRcdFx0KSB7XHJcblx0XHRcdFx0ZmllbGRzX2RhdGEgPSB3aW5kb3cuV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLmV4cG9ydF9jb250ZW50KFxyXG5cdFx0XHRcdFx0YWRhcHRlZCxcclxuXHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0YWRkTGFiZWxzOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRzZXAgICAgICA6ICc6ICdcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdGFkdmFuY2VkX2Zvcm06IGFkdmFuY2VkX2Zvcm0gfHwgJycsXHJcblx0XHRcdFx0ZmllbGRzX2RhdGEgIDogZmllbGRzX2RhdGEgfHwgJycsXHJcblx0XHRcdFx0c3RydWN0dXJlICAgIDogc3RydWN0dXJlIHx8IFtdLFxyXG5cdFx0XHRcdGFkYXB0ZWQgICAgICA6IGFkYXB0ZWRcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHQvLyA9PSBFeHBvcnRlciDigJMgcmVuZGVyX3NlY3Rpb24oKSBub3cgaW5qZWN0cyBwZXItY29sdW1uIENTUyB2YXJzIGZyb20gYGNvbF9zdHlsZXNgXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHRzdGF0aWMgcmVuZGVyX3NlY3Rpb24oc2VjdGlvbiwgaW8sIGNmZywgb25jZSwgY3R4KSB7XHJcblxyXG5cdFx0XHRvbmNlID0gb25jZSB8fCB7IGNhcHRjaGE6IDAsIGNvdW50cnk6IDAsIGNvdXBvbjogMCwgY29zdF9jb3JyZWN0aW9uczogMCwgc3VibWl0OiAwIH07XHJcblx0XHRcdGN0eCAgPSBjdHggfHwgeyB1c2VkSWRzOiBuZXcgU2V0KCkgfTtcclxuXHJcblx0XHRcdGNvbnN0IHsgb3BlbiwgY2xvc2UgfSA9IGlvO1xyXG5cclxuXHRcdFx0Y29uc3QgY29scyA9IEFycmF5LmlzQXJyYXkoIHNlY3Rpb24uY29sdW1ucyApICYmIHNlY3Rpb24uY29sdW1ucy5sZW5ndGhcclxuXHRcdFx0XHQ/IHNlY3Rpb24uY29sdW1uc1xyXG5cdFx0XHRcdDogWyB7IHdpZHRoOiAnMTAwJScsIGZpZWxkczogW10sIHNlY3Rpb25zOiBbXSB9IF07XHJcblxyXG5cdFx0XHQvLyBSb3cgaXMgYWN0aXZlIGlmIEFOWSBjb2x1bW4gY2FycmllcyBzdHlsZXMuXHJcblx0XHRcdHZhciByb3dfaXNfYWN0aXZlID0gY29scy5zb21lKCBmdW5jdGlvbiAoY29sKSB7IHJldHVybiBoYXNfbm9uX2RlZmF1bHRfY29sX3N0eWxlcyggY29sICYmIGNvbC5jb2xfc3R5bGVzICk7IH0gKTtcblx0XHRcdHZhciByb3dfYXR0cl9hY3RpdmUgPSByb3dfaXNfYWN0aXZlID8gJyBkYXRhLWNvbHN0eWxlcy1hY3RpdmU9XCIxXCInIDogJyc7XG5cdFx0XHR2YXIgcm93X2N1c3RvbV9hdHRycyA9IFdQQkNfQkZCX0V4cG9ydGVyLml0ZW1fd3JhcHBlcl9hdHRycyggc2VjdGlvbiwgY3R4ICk7XG5cblx0XHRcdG9wZW4oIGA8ciR7cm93X2N1c3RvbV9hdHRyc30ke3Jvd19hdHRyX2FjdGl2ZX0+YCApO1xuXHJcblx0XHRcdGNvbnN0IGJhc2VzICAgID0gY29tcHV0ZV9lZmZlY3RpdmVfYmFzZXMoIGNvbHMsIGNmZy5nYXBQZXJjZW50ICk7XHJcblx0XHRcdGNvbnN0IGVzY19hdHRyID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfaHRtbDtcclxuXHJcblx0XHRcdGNvbHMuZm9yRWFjaCggKGNvbCwgaWR4KSA9PiB7XHJcblx0XHRcdFx0Ly8gKDEpIFJlc29sdmUgZmxleC1iYXNpcy5cclxuXHRcdFx0XHR2YXIgZWZmX2Jhc2lzID0gcmVzb2x2ZV9mbGV4X2Jhc2lzX3BlcmNlbnQoIGNvbCAmJiBjb2wud2lkdGgsIE51bWJlci5pc0Zpbml0ZSggYmFzZXNbaWR4XSApID8gK2Jhc2VzW2lkeF0gOiAxMDAgKTtcclxuXHJcblx0XHRcdFx0Ly8gKDIpIEJ1aWxkIGlubGluZSBzdHlsZS5cclxuXHRcdFx0XHR2YXIgc3R5bGVfcGFydHMgPSBbXTtcclxuXHJcblx0XHRcdFx0aWYgKCBjb2wgJiYgdHlwZW9mIGNvbC5zdHlsZSA9PT0gJ3N0cmluZycgJiYgY29sLnN0eWxlLnRyaW0oKSApIHtcclxuXHRcdFx0XHRcdHN0eWxlX3BhcnRzLnB1c2goIGNvbC5zdHlsZS50cmltKCkucmVwbGFjZSggLzsrXFxzKiQvLCAnJyApICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHN0eWxlX3BhcnRzLnB1c2goICdmbGV4LWJhc2lzOiAnICsgKCBOdW1iZXIuaXNGaW5pdGUoIGVmZl9iYXNpcyApID8gZWZmX2Jhc2lzLnRvU3RyaW5nKCkgOiAnMTAwJyApICsgJyUnICk7XHJcblxyXG5cdFx0XHRcdHZhciBjc3NfdmFyc19zdHIgPSBidWlsZF9jb2xfY3NzX3ZhcnMoIGNvbCAmJiBjb2wuY29sX3N0eWxlcyApO1xyXG5cdFx0XHRcdGlmICggY3NzX3ZhcnNfc3RyICkge1xyXG5cdFx0XHRcdFx0c3R5bGVfcGFydHMucHVzaCggY3NzX3ZhcnNfc3RyLnJlcGxhY2UoIC9eO3w7JC9nLCAnJyApICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR2YXIgc3R5bGVfYXR0ciA9IGAgc3R5bGU9XCIke2VzY19hdHRyKCBzdHlsZV9wYXJ0cy5qb2luKCAnOyAnICkgKX1cImA7XHJcblxyXG5cdFx0XHRcdC8vICgzKSBDb2x1bW4tbGV2ZWwgYWN0aXZhdGlvbiAobW9yZSBwcmVjaXNlIHNjb3BpbmcpXHJcblx0XHRcdFx0dmFyIGNvbF9pc19hY3RpdmUgICA9IGhhc19ub25fZGVmYXVsdF9jb2xfc3R5bGVzKCBjb2wgJiYgY29sLmNvbF9zdHlsZXMgKTtcclxuXHRcdFx0XHR2YXIgY29sX2F0dHJfYWN0aXZlID0gY29sX2lzX2FjdGl2ZSA/ICcgZGF0YS1jb2xzdHlsZXMtYWN0aXZlPVwiMVwiJyA6ICcnO1xyXG5cclxuXHRcdFx0XHRvcGVuKCBgPGMke2NvbF9hdHRyX2FjdGl2ZX0ke3N0eWxlX2F0dHJ9PmAgKTtcclxuXHJcblx0XHRcdFx0Ly8gVXNlIHRoZSBzaGFyZWQgb25jZS9jdHggb2JqZWN0cyBzbyBzaW5nbGUtcGVyLWZvcm0gZ3VhcmRzIHdvcmsgYWNyb3NzIHRoZSB3aG9sZSBmb3JtLlxyXG5cdFx0XHRcdChjb2wuZmllbGRzIHx8IFtdKS5mb3JFYWNoKCAobm9kZSkgPT5cclxuXHRcdFx0XHRcdFdQQkNfQkZCX0V4cG9ydGVyLnJlbmRlcl9maWVsZF9ub2RlKCBub2RlLCBpbywgY2ZnLCBvbmNlLCBjdHggKVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdC8vIFJlY3Vyc2Ugd2l0aCB0aGUgc2FtZSBvbmNlL2N0eCBhcyB3ZWxsLlxyXG5cdFx0XHRcdChjb2wuc2VjdGlvbnMgfHwgW10pLmZvckVhY2goIChuZXN0ZWQpID0+XHJcblx0XHRcdFx0XHRXUEJDX0JGQl9FeHBvcnRlci5yZW5kZXJfc2VjdGlvbiggbmVzdGVkLCBpbywgY2ZnLCBvbmNlLCBjdHggKVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdGNsb3NlKCBgPC9jPmAgKTtcclxuXHRcdFx0fSApO1xyXG5cclxuXHRcdFx0Y2xvc2UoIGA8L3I+YCApO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEJ1aWxkIGEgc2FuaXRpemVkIGN1c3RvbSBDU1MgY2xhc3MgYW5kIEhUTUwgSUQgYXR0cmlidXRlIHN0cmluZyBmb3IgYW4gZXhwb3J0ZWQgd3JhcHBlci5cblx0XHQgKiBVc2VkIGJ5IHNlY3Rpb24gcm93IHdyYXBwZXJzIGFuZCBmaWVsZHMgd2hvc2UgYXR0cmlidXRlcyBiZWxvbmcgb24gdGhlIDxpdGVtPiB3cmFwcGVyLlxuXHRcdCAqIEFsc28gZW5zdXJlcyB1bmlxdWVuZXNzIG9mIHRoZSBodG1sX2lkIGFjcm9zcyB0aGUgZXhwb3J0ICh1c2VzIGN0eC51c2VkSWRzKS5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSB3cmFwcGVyX2RhdGEgT2JqZWN0IGNvbnRhaW5pbmcgb3B0aW9uYWwgY3NzY2xhc3MgYW5kIGh0bWxfaWQgcHJvcGVydGllcy5cblx0XHQgKiBAcGFyYW0ge3t1c2VkSWRzOlNldDxzdHJpbmc+fX0gY3R4XG5cdFx0ICogQHJldHVybnMge3N0cmluZ30gZS5nLiAnIGNsYXNzPVwieCB5XCIgaWQ9XCJteUlkXCInXG5cdFx0ICovXG5cdFx0c3RhdGljIGl0ZW1fd3JhcHBlcl9hdHRycyh3cmFwcGVyX2RhdGEsIGN0eCkge1xuXHRcdFx0aWYgKCAhIHdyYXBwZXJfZGF0YSApIHtcblx0XHRcdFx0cmV0dXJuICcnO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgZXNjX2h0bWwgID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfaHRtbDtcclxuXHRcdFx0Y29uc3QgY2xzX3Nhbml0ID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5zYW5pdGl6ZV9jc3NfY2xhc3NsaXN0O1xyXG5cdFx0XHRjb25zdCBzaWQgICAgICAgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplLnNhbml0aXplX2h0bWxfaWQ7XHJcblxyXG5cdFx0XHRsZXQgb3V0ID0gJyc7XHJcblxyXG5cdFx0XHRjb25zdCBjbHNfcmF3ID0gU3RyaW5nKCB3cmFwcGVyX2RhdGEuY3NzY2xhc3NfZXh0cmEgfHwgd3JhcHBlcl9kYXRhLmNzc2NsYXNzIHx8IHdyYXBwZXJfZGF0YS5jbGFzcyB8fCAnJyApO1xuXHRcdFx0Y29uc3QgY2xzICAgICA9IGNsc19zYW5pdCggY2xzX3JhdyApO1xuXHRcdFx0bGV0IGh0bWxfaWQgICA9IHdyYXBwZXJfZGF0YS5odG1sX2lkID8gc2lkKCBTdHJpbmcoIHdyYXBwZXJfZGF0YS5odG1sX2lkICkgKSA6ICcnO1xuXHRcdFx0aWYgKCBodG1sX2lkICYmIGN0eD8udXNlZElkcyApIHtcclxuXHRcdFx0XHRsZXQgdW5pcXVlID0gaHRtbF9pZCwgaSA9IDI7XHJcblx0XHRcdFx0d2hpbGUgKCBjdHgudXNlZElkcy5oYXMoIHVuaXF1ZSApICkge1xyXG5cdFx0XHRcdFx0dW5pcXVlID0gYCR7aHRtbF9pZH1fJHtpKyt9YDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y3R4LnVzZWRJZHMuYWRkKCB1bmlxdWUgKTtcclxuXHRcdFx0XHRodG1sX2lkID0gdW5pcXVlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICggY2xzICkge1xyXG5cdFx0XHRcdG91dCArPSBgIGNsYXNzPVwiJHtlc2NfaHRtbCggY2xzICl9XCJgO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICggaHRtbF9pZCApIHtcclxuXHRcdFx0XHRvdXQgKz0gYCBpZD1cIiR7ZXNjX2h0bWwoIGh0bWxfaWQgKX1cImA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBvdXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdFx0Ly8gPT0gRmllbGRzIOKAkyBwbHVnZ2FibGUsIHBhY2stZHJpdmVuIGV4cG9ydFxyXG5cdFx0Ly8gPT0gV3JhcCBldmVyeSBleHBvcnRlZCBmaWVsZCBpbnNpZGUgPGl0ZW0+4oCmPC9pdGVtPiBhbmQgZGVsZWdhdGUgYWN0dWFsIHNob3J0Y29kZSBleHBvcnRcclxuXHRcdC8vID09IHRvIHBlci1wYWNrIGNhbGxiYWNrcyByZWdpc3RlcmVkIHZpYSBXUEJDX0JGQl9FeHBvcnRlci5yZWdpc3Rlcih0eXBlLCBmbikuXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHRzdGF0aWMgcmVuZGVyX2ZpZWxkX25vZGUoZmllbGQsIGlvLCBjZmcsIG9uY2UsIGN0eCkge1xyXG5cclxuXHRcdFx0Y29uc3QgeyBvcGVuLCBjbG9zZSwgcHVzaCB9ID0gaW87XHJcblx0XHRcdGlmICggISBmaWVsZCB8fCAhIGZpZWxkLnR5cGUgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTaGFyZWQgY29udGV4dCAodXNlZElkcywg4oCcb25jZS1wZXItZm9ybeKAnSBndWFyZHMsIGV0Yy4pLlxyXG5cdFx0XHRvbmNlID0gb25jZSB8fCB7fTtcclxuXHRcdFx0Y3R4ICA9IGN0eCAgfHwgeyB1c2VkSWRzOiBuZXcgU2V0KCkgfTtcclxuXHJcblx0XHRcdGNvbnN0IHR5cGUgPSBTdHJpbmcoIGZpZWxkLnR5cGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHRcdFx0Ly8gT3B0aW9uYWwgd3JhcHBlciBhdHRycyBmb3Igc3BlY2lhbCB0eXBlcyAoY3VycmVudGx5IG9ubHkgdXNlZCBieSBjYXB0Y2hhKS5cclxuXHRcdFx0bGV0IGl0ZW1fYXR0cnMgPSAnJztcclxuXHRcdFx0aWYgKCB0eXBlID09PSAnY2FwdGNoYScgKSB7XHJcblx0XHRcdFx0aXRlbV9hdHRycyA9IFdQQkNfQkZCX0V4cG9ydGVyLml0ZW1fd3JhcHBlcl9hdHRycyggZmllbGQsIGN0eCApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRvcGVuKCBgPGl0ZW0ke2l0ZW1fYXR0cnN9PmAgKTtcclxuXHJcblx0XHRcdHRyeSB7XHJcblx0XHRcdFx0Ly8gMSkgTGV0IHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkIHBhY2sgaGFuZGxlIGV4cG9ydC5cclxuXHRcdFx0XHRsZXQgaGFuZGxlZCA9IGZhbHNlO1xyXG5cdFx0XHRcdGlmICggV1BCQ19CRkJfRXhwb3J0ZXIuaGFzX2V4cG9ydGVyKCB0eXBlICkgKSB7XHJcblx0XHRcdFx0XHRoYW5kbGVkID0gV1BCQ19CRkJfRXhwb3J0ZXIucnVuX3JlZ2lzdGVyZWRfZXhwb3J0ZXIoIGZpZWxkLCBpbywgY2ZnLCBvbmNlLCBjdHggKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIDIpIEZhbGxiYWNrOiBzaG93IGEgY2xlYXIgVE9ETyBjb21tZW50IGlmIG5vIGV4cG9ydGVyIGlzIHJlZ2lzdGVyZWQuXHJcblx0XHRcdFx0aWYgKCAhIGhhbmRsZWQgKSB7XHJcblx0XHRcdFx0XHRjb25zdCBuYW1lID0gV1BCQ19CRkJfRXhwb3J0ZXIuY29tcHV0ZV9uYW1lKCB0eXBlLCBmaWVsZCApO1xyXG5cdFx0XHRcdFx0cHVzaCggYDwhLS0gVE9ETzogbWFwIGZpZWxkIHR5cGUgXCIke3R5cGV9XCIgbmFtZT1cIiR7bmFtZX1cIiBpbiBhIHBhY2sgZXhwb3J0ZXIgLS0+YCApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gMykgQXBwZW5kIGhlbHAgdGV4dCBjb25zaXN0ZW50bHkgKHBhY2tzIHNob3VsZG7igJl0IGR1cGxpY2F0ZSB0aGlzKS5cclxuXHRcdFx0XHRpZiAoIGZpZWxkLmhlbHAgKSB7XHJcblx0XHRcdFx0XHRwdXNoKFxyXG5cdFx0XHRcdFx0XHRgPGRpdiBjbGFzcz1cIndwYmNfZmllbGRfZGVzY3JpcHRpb25cIj4ke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2h0bWwoXHJcblx0XHRcdFx0XHRcdFx0U3RyaW5nKCBmaWVsZC5oZWxwIClcclxuXHRcdFx0XHRcdFx0KX08L2Rpdj5gXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBmaW5hbGx5IHtcclxuXHRcdFx0XHQvLyBBbHdheXMgY2xvc2Ugd3JhcHBlci5cclxuXHRcdFx0XHRjbG9zZSggYDwvaXRlbT5gICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHQvLyA9PSBIZWxwZXJzID09XHJcblx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0XHRzdGF0aWMgaXNfcmVxdWlyZWQoZmllbGQpIHtcclxuXHRcdFx0Y29uc3QgdiA9IGZpZWxkICYmIGZpZWxkLnJlcXVpcmVkO1xyXG5cdFx0XHRyZXR1cm4gKFxyXG5cdFx0XHRcdHYgPT09IHRydWUgfHxcclxuXHRcdFx0XHR2ID09PSAndHJ1ZScgfHxcclxuXHRcdFx0XHR2ID09PSAxIHx8XHJcblx0XHRcdFx0diA9PT0gJzEnIHx8XHJcblx0XHRcdFx0diA9PT0gJ3JlcXVpcmVkJ1xyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFNoYXJlZCBsYWJlbCBlbWl0dGVyIHVzZWQgYnkgcGVyLXBhY2sgZXhwb3J0ZXJzLlxyXG5cdFx0ICpcclxuXHRcdCAqIEVtaXRzIG9wdGlvbmFsIDxsPkxhYmVsPC9sPiArIDxicj4gYmVmb3JlIHRoZSBwcm92aWRlZCBib2R5LFxyXG5cdFx0ICogcmVzcGVjdGluZyBjZmcuYWRkTGFiZWxzLiBIZWxwIHRleHQgaXMgZW1pdHRlZCBjZW50cmFsbHkgaW5cclxuXHRcdCAqIHJlbmRlcl9maWVsZF9ub2RlKCksIHNvIGl0IGlzIGludGVudGlvbmFsbHkgTk9UIGhhbmRsZWQgaGVyZS5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICAgICBmaWVsZFxyXG5cdFx0ICogQHBhcmFtIHtmdW5jdGlvbihzdHJpbmcpOiB2b2lkfSAgZW1pdFxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9ICAgICAgICAgICAgICAgICAgYm9keVxyXG5cdFx0ICogQHBhcmFtIHt7YWRkTGFiZWxzPzogYm9vbGVhbn19ICBbY2ZnXVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgZW1pdF9sYWJlbF90aGVuKGZpZWxkLCBlbWl0LCBib2R5LCBjZmcpIHtcclxuXHRcdFx0aWYgKCB0eXBlb2YgZW1pdCAhPT0gJ2Z1bmN0aW9uJyApIHsgcmV0dXJuOyB9XHJcblxyXG5cdFx0XHRjZmcgPSBjZmcgfHwge307XHJcblx0XHRcdGNvbnN0IGFkZExhYmVscyA9IGNmZy5hZGRMYWJlbHMgIT09IGZhbHNlO1xyXG5cclxuXHRcdFx0Y29uc3QgcmF3ICAgPSAoZmllbGQgJiYgdHlwZW9mIGZpZWxkLmxhYmVsID09PSAnc3RyaW5nJykgPyBmaWVsZC5sYWJlbCA6ICcnO1xyXG5cdFx0XHRjb25zdCBsYWJlbCA9IHJhdy50cmltKCk7XHJcblxyXG5cdFx0XHR2YXIgaXNfcmVxICAgPSB0aGlzLmlzX3JlcXVpcmVkKCBmaWVsZCApO1xyXG5cdFx0XHR2YXIgcmVxX21hcmsgPSBpc19yZXEgPyAnKicgOiAnJztcclxuXHJcblx0XHRcdGlmICggbGFiZWwgJiYgYWRkTGFiZWxzICkge1xyXG5cdFx0XHRcdGNvbnN0IGVzY19odG1sID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfaHRtbDtcclxuXHRcdFx0XHRlbWl0KCAnPGw+JyArIGVzY19odG1sKCBsYWJlbCApICsgcmVxX21hcmsgKyAnPC9sPicgKTtcclxuXHRcdFx0XHRlbWl0KCAnPGJyPicgKyBib2R5ICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0ZW1pdCggYm9keSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHRcdC8vID09IEhlbHBlcnMgPT1cclxuXHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcblx0XHQvLyAtLSBUaW1lIFNlbGVjdCBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRzdGF0aWMgaXNfdGltZXNsb3RfcGlja2VyX2VuYWJsZWQoKSB7XHJcblx0XHRcdHRyeSB7XHJcblx0XHRcdFx0cmV0dXJuICEhKHdpbmRvdy5fd3BiYyAmJiB0eXBlb2Ygd2luZG93Ll93cGJjLmdldF9vdGhlcl9wYXJhbSA9PT0gJ2Z1bmN0aW9uJ1xyXG5cdFx0XHRcdFx0JiYgd2luZG93Ll93cGJjLmdldF9vdGhlcl9wYXJhbSgnaXNfZW5hYmxlZF9ib29raW5nX3RpbWVzbG90X3BpY2tlcicpKTtcclxuXHRcdFx0fSBjYXRjaCAoXykgeyByZXR1cm4gZmFsc2U7IH1cclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgdGltZV9wbGFjZWhvbGRlcl9mb3IobmFtZSwgZmllbGQpIHtcclxuXHRcdFx0Ly8gUHJlZmVyIGZpZWxkLXNwZWNpZmljIHBsYWNlaG9sZGVyOyBlbHNlIHNlbnNpYmxlIGRlZmF1bHQgcGVyIGZpZWxkLlxyXG5cdFx0XHRpZiAodHlwZW9mIGZpZWxkLnBsYWNlaG9sZGVyID09PSAnc3RyaW5nJyAmJiBmaWVsZC5wbGFjZWhvbGRlci50cmltKCkpIHtcclxuXHRcdFx0XHRyZXR1cm4gZmllbGQucGxhY2Vob2xkZXIudHJpbSgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChuYW1lID09PSAnZHVyYXRpb250aW1lJykgcmV0dXJuICctLS0gU2VsZWN0IGR1cmF0aW9uIC0tLSc7XHJcblx0XHRcdHJldHVybiAnLS0tIFNlbGVjdCB0aW1lIC0tLSc7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBCdWlsZCB0b2tlbnMvZGVmYXVsdCBmb3IgYSB0aW1lLWxpa2Ugc2VsZWN0IChzdGFydC9lbmQvcmFuZ2UvZHVyYXRpb24pLlxyXG5cdFx0ICogLSBBZGRzIGFuIGVtcHR5LXZhbHVlIHBsYWNlaG9sZGVyIGFzIHRoZSBmaXJzdCBvcHRpb24gb25seSB3aGVuOlxyXG5cdFx0ICogICDigKIgdGltZSBwaWNrZXIgaXMgT0ZGLCBhbmRcclxuXHRcdCAqICAg4oCiIG5vIG9wdGlvbiBpcyBzZWxlY3RlZCBieSBkZWZhdWx0LCBhbmRcclxuXHRcdCAqICAg4oCiIHRoZXJlIGlzbid0IGFscmVhZHkgYW4gZW1wdHktdmFsdWUgb3B0aW9uLlxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgYnVpbGRfdGltZV9zZWxlY3RfdG9rZW5zKGZpZWxkLCBuYW1lKSB7XHJcblx0XHRcdGxldCB0b2tlbnNfc3RyID0gdGhpcy5vcHRpb25fdG9rZW5zKGZpZWxkKTtcclxuXHRcdFx0bGV0IGRlZl9zdHIgICAgPSB0aGlzLmRlZmF1bHRfb3B0aW9uX3N1ZmZpeChmaWVsZCwgdG9rZW5zX3N0cik7XHJcblxyXG5cdFx0XHRpZiAoIXRoaXMuaXNfdGltZXNsb3RfcGlja2VyX2VuYWJsZWQoKSkge1xyXG5cdFx0XHRcdGNvbnN0IG9wdHMgPSBBcnJheS5pc0FycmF5KGZpZWxkLm9wdGlvbnMpID8gZmllbGQub3B0aW9ucyA6IFtdO1xyXG5cclxuXHRcdFx0XHRjb25zdCBoYXNfc2VsZWN0ZWRfZGVmYXVsdCA9IG9wdHMuc29tZShvID0+XHJcblx0XHRcdFx0XHRvICYmIChvLnNlbGVjdGVkID09PSB0cnVlIHx8IG8uc2VsZWN0ZWQgPT09ICd0cnVlJyB8fCBvLnNlbGVjdGVkID09PSAxIHx8IG8uc2VsZWN0ZWQgPT09ICcxJylcclxuXHRcdFx0XHQpO1xyXG5cclxuXHRcdFx0XHRpZiAoIWhhc19zZWxlY3RlZF9kZWZhdWx0KSB7XHJcblx0XHRcdFx0XHRjb25zdCBoYXNfZW1wdHlfdmFsdWVfb3B0aW9uID0gb3B0cy5zb21lKG8gPT5cclxuXHRcdFx0XHRcdFx0byAmJiB0eXBlb2Ygby52YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgJiYgU3RyaW5nKG8udmFsdWUpLnRyaW0oKSA9PT0gJydcclxuXHRcdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCFoYXNfZW1wdHlfdmFsdWVfb3B0aW9uKSB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IHBoVGV4dCAgICAgPSB0aGlzLnRpbWVfcGxhY2Vob2xkZXJfZm9yKG5hbWUsIGZpZWxkKTtcclxuXHRcdFx0XHRcdFx0Y29uc3QgcGhUb2tlblN0ciA9ICdcIicgKyBjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9mb3Jfc2hvcnRjb2RlKHBoVGV4dCArICdAQCcpICsgJ1wiJztcclxuXHJcblx0XHRcdFx0XHRcdGNvbnN0IG90aGVyID0gdGhpcy5vcHRpb25fdG9rZW5zKGZpZWxkKS50cmltKCk7IC8vIHJlY29tcHV0ZSwgdHJpbSBsZWFkaW5nIHNwYWNlXHJcblx0XHRcdFx0XHRcdHRva2Vuc19zdHIgID0gJyAnICsgcGhUb2tlblN0ciArIChvdGhlciA/ICgnICcgKyBvdGhlcikgOiAnJyk7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBFbnN1cmUgZmlyc3Qgb3B0aW9uIChvdXIgcGxhY2Vob2xkZXIpIGJlY29tZXMgdGhlIGRlZmF1bHQgaW1wbGljaXRseVxyXG5cdFx0XHRcdFx0XHRkZWZfc3RyID0gJyc7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiB7IHRva2Vuc19zdHIsIGRlZl9zdHIgfTtcclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgZW1pdF90aW1lX3NlbGVjdChuYW1lLCBmaWVsZCwgcmVxX21hcmssIGlkX29wdCwgY2xzX29wdHMsIGVtaXRfbGFiZWxfdGhlbikge1xyXG5cdFx0XHRjb25zdCB7IHRva2Vuc19zdHIsIGRlZl9zdHIgfSA9IHRoaXMuYnVpbGRfdGltZV9zZWxlY3RfdG9rZW5zKGZpZWxkLCBuYW1lKTtcclxuXHRcdFx0Ly8gTk9URTogTm8gc2l6ZS9waCB0b2tlbnMgaGVyZSB0byBtaXJyb3IgcmFuZ2V0aW1lIGJlaGF2aW9yIGV4YWN0bHkuXHJcblx0XHRcdGVtaXRfbGFiZWxfdGhlbihgW3NlbGVjdGJveCR7cmVxX21hcmt9ICR7bmFtZX0ke2lkX29wdH0ke2Nsc19vcHRzfSR7ZGVmX3N0cn0ke3Rva2Vuc19zdHJ9XWApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIC0tIE90aGVyIEhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vIFJldHVybiBhIGZpZWxkJ3MgZGVmYXVsdCB2YWx1ZSAoc3VwcG9ydHMgYm90aCBjYW1lbENhc2UgYW5kIHNuYWtlX2Nhc2UpLlxyXG5cdFx0c3RhdGljIGdldF9kZWZhdWx0X3ZhbHVlKGZpZWxkKSB7XHJcblx0XHRcdGNvbnN0IHYgPSBmaWVsZD8uZGVmYXVsdF92YWx1ZSA/PyBmaWVsZD8uZGVmYXVsdFZhbHVlID8/ICcnO1xyXG5cdFx0XHRyZXR1cm4gKHYgPT0gbnVsbCkgPyAnJyA6IFN0cmluZyggdiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvciB0ZXh0LWxpa2UgZmllbGRzLCB0aGUgZGVmYXVsdCBpcyBhIGZpbmFsIHF1b3RlZCB0b2tlbiBpbiB0aGUgc2hvcnRjb2RlLlxyXG5cdFx0c3RhdGljIGRlZmF1bHRfdGV4dF9zdWZmaXgoZmllbGQpIHtcclxuXHRcdFx0Y29uc3QgdiA9IHRoaXMuZ2V0X2RlZmF1bHRfdmFsdWUoIGZpZWxkICk7XHJcblx0XHRcdGlmICggIXYgKSByZXR1cm4gJyc7XHJcblx0XHRcdHJldHVybiBgIFwiJHtjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9mb3Jfc2hvcnRjb2RlKCB2ICl9XCJgO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBjbGFzc19vcHRpb25zKGZpZWxkKSB7XHJcblx0XHRcdGNvbnN0IHJhdyA9IGZpZWxkLmNsYXNzIHx8IGZpZWxkLmNsYXNzTmFtZSB8fCBmaWVsZC5jc3NjbGFzcyB8fCAnJztcclxuXHRcdFx0Y29uc3QgY2xzID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5zYW5pdGl6ZV9jc3NfY2xhc3NsaXN0KCBTdHJpbmcoIHJhdyApICk7XHJcblx0XHRcdGlmICggIWNscyApIHJldHVybiAnJztcclxuXHRcdFx0cmV0dXJuIGNsc1xyXG5cdFx0XHRcdC5zcGxpdCggL1xccysvIClcclxuXHRcdFx0XHQuZmlsdGVyKCBCb29sZWFuIClcclxuXHRcdFx0XHQubWFwKCAoYykgPT4gYCBjbGFzczoke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUudG9fdG9rZW4oIGMgKX1gIClcclxuXHRcdFx0XHQuam9pbiggJycgKTtcclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgaWRfb3B0aW9uKGZpZWxkLCBjdHgpIHtcclxuXHRcdFx0Y29uc3QgcmF3X2lkID0gZmllbGQuaHRtbF9pZCB8fCBmaWVsZC5pZF9hdHRyO1xyXG5cdFx0XHRpZiAoICFyYXdfaWQgKSByZXR1cm4gJyc7XHJcblx0XHRcdGNvbnN0IGJhc2UgPSBjb3JlLldQQkNfQkZCX1Nhbml0aXplLnRvX3Rva2VuKCByYXdfaWQgKTtcclxuXHRcdFx0aWYgKCAhYmFzZSApIHJldHVybiAnJztcclxuXHRcdFx0bGV0IHVuaXF1ZSA9IGJhc2UsIGkgPSAyO1xyXG5cdFx0XHR3aGlsZSAoIGN0eC51c2VkSWRzLmhhcyggdW5pcXVlICkgKSB1bmlxdWUgPSBgJHtiYXNlfV8ke2krK31gO1xyXG5cdFx0XHRjdHgudXNlZElkcy5hZGQoIHVuaXF1ZSApO1xyXG5cdFx0XHRyZXR1cm4gYCBpZDoke3VuaXF1ZX1gO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBwaF9hdHRyKHYpIHtcclxuXHRcdFx0aWYgKCB2ID09IG51bGwgfHwgdiA9PT0gJycgKSByZXR1cm4gJyc7XHJcblx0XHRcdHJldHVybiBgIHBsYWNlaG9sZGVyOlwiJHtjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV9mb3JfYXR0cl9xdW90ZWQoIHYgKX1cImA7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gdGV4dC1saWtlIHNpemUvbWF4bGVuZ3RoIHRva2VuOiBcIjQwLzI1NVwiIChvciBcIjQwL1wiIG9yIFwiLzI1NVwiKVxyXG5cdFx0c3RhdGljIHNpemVfbWF4X3Rva2VuKGYpIHtcclxuXHRcdFx0Y29uc3Qgc2l6ZSA9IHBhcnNlSW50KCBmLnNpemUsIDEwICk7XHJcblx0XHRcdGNvbnN0IG1heCAgPSBwYXJzZUludCggZi5tYXhsZW5ndGgsIDEwICk7XHJcblx0XHRcdGlmICggTnVtYmVyLmlzRmluaXRlKCBzaXplICkgJiYgTnVtYmVyLmlzRmluaXRlKCBtYXggKSApIHJldHVybiBgICR7c2l6ZX0vJHttYXh9YDtcclxuXHRcdFx0aWYgKCBOdW1iZXIuaXNGaW5pdGUoIHNpemUgKSApIHJldHVybiBgICR7c2l6ZX0vYDtcclxuXHRcdFx0aWYgKCBOdW1iZXIuaXNGaW5pdGUoIG1heCApICkgcmV0dXJuIGAgLyR7bWF4fWA7XHJcblx0XHRcdHJldHVybiAnJztcclxuXHRcdH1cclxuXHJcblx0XHQvLyB0ZXh0YXJlYSBjb2xzL3Jvd3MgdG9rZW46IFwiNjB4NFwiIChvciBcIjYweFwiIG9yIFwieDRcIilcclxuXHRcdHN0YXRpYyBjb2xzX3Jvd3NfdG9rZW4oZikge1xyXG5cdFx0XHRjb25zdCBjb2xzID0gcGFyc2VJbnQoIGYuY29scywgMTAgKTtcclxuXHRcdFx0Y29uc3Qgcm93cyA9IHBhcnNlSW50KCBmLnJvd3MsIDEwICk7XHJcblx0XHRcdGlmICggTnVtYmVyLmlzRmluaXRlKCBjb2xzICkgJiYgTnVtYmVyLmlzRmluaXRlKCByb3dzICkgKSByZXR1cm4gYCAke2NvbHN9eCR7cm93c31gO1xyXG5cdFx0XHRpZiAoIE51bWJlci5pc0Zpbml0ZSggY29scyApICkgcmV0dXJuIGAgJHtjb2xzfXhgO1xyXG5cdFx0XHRpZiAoIE51bWJlci5pc0Zpbml0ZSggcm93cyApICkgcmV0dXJuIGAgeCR7cm93c31gO1xyXG5cdFx0XHRyZXR1cm4gJyc7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIG9wdGlvbl90b2tlbnMoZmllbGQpIHtcclxuXHRcdFx0Y29uc3Qgb3B0aW9ucyA9IEFycmF5LmlzQXJyYXkoIGZpZWxkLm9wdGlvbnMgKSA/IGZpZWxkLm9wdGlvbnMgOiBbXTtcclxuXHRcdFx0aWYgKCBvcHRpb25zLmxlbmd0aCA9PT0gMCApIHJldHVybiAnJztcclxuXHRcdFx0Y29uc3QgcGFydHMgPSBvcHRpb25zLm1hcCggKG8pID0+IHtcclxuXHRcdFx0XHRjb25zdCB0aXRsZSA9IFN0cmluZyggby5sYWJlbCA/PyBvLnZhbHVlID8/ICcnICkudHJpbSgpO1xyXG5cdFx0XHRcdGNvbnN0IHZhbHVlID0gU3RyaW5nKCBvLnZhbHVlID8/IG8ubGFiZWwgPz8gJycgKS50cmltKCk7XHJcblx0XHRcdFx0cmV0dXJuIHRpdGxlICYmIHZhbHVlICYmIHRpdGxlICE9PSB2YWx1ZVxyXG5cdFx0XHRcdFx0PyBgXCIke2NvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2Zvcl9zaG9ydGNvZGUoIGAke3RpdGxlfUBAJHt2YWx1ZX1gICl9XCJgXHJcblx0XHRcdFx0XHQ6IGBcIiR7Y29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfZm9yX3Nob3J0Y29kZSggdGl0bGUgfHwgdmFsdWUgKX1cImA7XHJcblx0XHRcdH0gKTtcclxuXHRcdFx0cmV0dXJuICcgJyArIHBhcnRzLmpvaW4oICcgJyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBkZWZhdWx0X29wdGlvbl9zdWZmaXgoZmllbGQsIHRva2Vucykge1xyXG5cdFx0XHRjb25zdCBvcHRpb25zICA9IEFycmF5LmlzQXJyYXkoIGZpZWxkLm9wdGlvbnMgKSA/IGZpZWxkLm9wdGlvbnMgOiBbXTtcclxuXHRcdFx0Y29uc3Qgc2VsZWN0ZWQgPSBvcHRpb25zLmZpbmQoIChvKSA9PiBvLnNlbGVjdGVkICk7XHJcblx0XHRcdGNvbnN0IGRlZl92YWwgPSBzZWxlY3RlZCA/IChzZWxlY3RlZC52YWx1ZSA/PyBzZWxlY3RlZC5sYWJlbCkgOiAoZmllbGQuZGVmYXVsdF92YWx1ZSA/PyBmaWVsZC5kZWZhdWx0VmFsdWUgPz8gJycpO1xyXG5cdFx0XHRpZiAoICFkZWZfdmFsICkgcmV0dXJuICcnO1xyXG5cdFx0XHRyZXR1cm4gYCBkZWZhdWx0PVwiJHtjb3JlLldQQkNfQkZCX1Nhbml0aXplLmVzY2FwZV92YWx1ZV9mb3JfYXR0ciggZGVmX3ZhbCApfVwiYDtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFNFTEVDVEJPWCAvIFJBRElPIC0gQnVpbGQgdGhlIGZpbmFsIHNob3J0Y29kZSBmb3IgY2hvaWNlLWJhc2VkIGZpZWxkcy5cclxuXHRcdCAqXHJcblx0XHQgKiBSZXNwb25zaWJpbGl0aWVzOlxyXG5cdFx0ICogIC0gRGVsZWdhdGVzIG9wdGlvbi9kZWZhdWx0IGVuY29kaW5nIHRvOlxyXG5cdFx0ICogICAgICAtIFdQQkNfQkZCX0V4cG9ydGVyLm9wdGlvbl90b2tlbnMoIGZpZWxkIClcclxuXHRcdCAqICAgICAgLSBXUEJDX0JGQl9FeHBvcnRlci5kZWZhdWx0X29wdGlvbl9zdWZmaXgoIGZpZWxkLCB0b2tlbnMgKVxyXG5cdFx0ICogIC0gRm9yIGByYWRpb2A6XHJcblx0XHQgKiAgICAgIC0gQUxXQVlTIGFwcGVuZHMgYSBiYXJlIGB1c2VfbGFiZWxfZWxlbWVudGAgdG9rZW4uXHJcblx0XHQgKiAgLSBGb3IgYHNlbGVjdGJveGA6XHJcblx0XHQgKiAgICAgIC0gQWRkcyBhIGJhcmUgYG11bHRpcGxlYCB0b2tlbiB3aGVuIGBmaWVsZC5tdWx0aXBsZWAgaXMgdHJ1dGh5XHJcblx0XHQgKiAgICAgICAgKHRydWUsIFwidHJ1ZVwiLCAxLCBcIjFcIiwgXCJtdWx0aXBsZVwiKSAtPiBgW3NlbGVjdGJveCBzZXJ2aWNlcyBtdWx0aXBsZSBcIjFcIiBcIjJcIl1gLlxyXG5cdFx0ICogICAgICAtIFdoZW4gc2luZ2xlLXNlbGVjdCBBTkQgdGhlcmUgaXMgbm8gYGRlZmF1bHQ9XCIuLi5cImAgYXR0cmlidXRlIEFORFxyXG5cdFx0ICogICAgICAgIGEgbm9uLWVtcHR5IGBmaWVsZC5wbGFjZWhvbGRlcmAgaXMgcHJlc2VudCwgZW5jb2RlcyB0aGUgcGxhY2Vob2xkZXJcclxuXHRcdCAqICAgICAgICBhcyB0aGUgRklSU1Qgb3B0aW9uIHdpdGggZW1wdHkgdmFsdWUgdmlhIHRoZSBgQEBgIHN5bnRheDpcclxuXHRcdCAqICAgICAgICAgICBwbGFjZWhvbGRlciBcIi0tLS0gU2VsZWN0IC0tLS1cIiAgLT4gIGBcIi0tLS0gU2VsZWN0IC0tLS1AQFwiYFxyXG5cdFx0ICogICAgICAgIGFuZCBjbGVhcnMgYW55IGRlZmF1bHQgYXR0cmlidXRlOlxyXG5cdFx0ICogICAgICAgICAgIFtzZWxlY3Rib3gqIHNlcnZpY2VzIFwiLS0tIFNlbGVjdCAtLS1AQFwiIFwiT3B0aW9uIDFcIiBcIk9wdGlvbiAyXCJdXHJcblx0XHQgKiAgICAgIC0gUmVzcGVjdHMgYGZpZWxkLnVzZV9sYWJlbF9lbGVtZW50YCAoYWRkcyBiYXJlIGB1c2VfbGFiZWxfZWxlbWVudGAgd2hlbiB0cnVlKS5cclxuXHRcdCAqICAtIEZvciBib3RoIGtpbmRzOlxyXG5cdFx0ICogICAgICAtIEhvbm9ycyBgZmllbGQubGFiZWxfZmlyc3RgIGJ5IGFwcGVuZGluZyBgbGFiZWxfZmlyc3Q6XCIxXCJgIHdoZW4gdHJ1dGh5LlxyXG5cdFx0ICogICAgICAtIEtlZXBzIHRoZSByZXF1aXJlZCBzdGFyLCBpZCBhbmQgY3NzY2xhc3MgdG9rZW5zIGluIHRoZSBjYW5vbmljYWwgb3JkZXIuXHJcblx0XHQgKlxyXG5cdFx0ICogRmluYWwgc2hvcnRjb2RlIGxheW91dCAob3JkZXIgaXMgaW1wb3J0YW50KTpcclxuXHRcdCAqICAgW2tpbmQgcmVxIG5hbWUgaWQgY2xzIHVzZV9sYWJlbF9lbGVtZW50IG11bHRpcGxlIGRlZmF1bHQgdG9rZW5zIGxhYmVsX2ZpcnN0XVxyXG5cdFx0ICpcclxuXHRcdCAqIEBqRG9jXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30ga2luZFxyXG5cdFx0ICogICBTaG9ydGNvZGUga2luZDsgdHlwaWNhbGx5IFwicmFkaW9cIiBvciBcInNlbGVjdGJveFwiLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSByZXFfbWFya1xyXG5cdFx0ICogICBSZXF1aXJlZCBtYXJrZXIgdXNlZCBieSBDb250YWN0IEZvcm0gNyBzdHlsZSBzaG9ydGNvZGVzOlxyXG5cdFx0ICogICBlaXRoZXIgXCJcIiAobm90IHJlcXVpcmVkKSBvciBcIipcIiAocmVxdWlyZWQpLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXHJcblx0XHQgKiAgIFNhbml0aXplZCBmaWVsZCBuYW1lIGFzIGV4cG9ydGVkIGludG8gdGhlIHNob3J0Y29kZSwgZS5nLiBcInNlcnZpY2VzXCIuXHJcblx0XHQgKiAgIE11c3QgYWxyZWFkeSBiZSBjb21wdXRlZCB2aWEgV1BCQ19CRkJfRXhwb3J0ZXIuY29tcHV0ZV9uYW1lKCkuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGZpZWxkXHJcblx0XHQgKiAgIE5vcm1hbGl6ZWQgZmllbGQgZGF0YSBvYmplY3QgYXMgc3RvcmVkIGluIHRoZSBCdWlsZGVyIHN0cnVjdHVyZS4gQ29tbW9uIGtleXM6XHJcblx0XHQgKiAgICAgLSB0eXBlICAgICAgICAgICB7c3RyaW5nfSAgIEZpZWxkIHR5cGUsIGUuZy4gXCJyYWRpb1wiIHwgXCJzZWxlY3RcIi5cclxuXHRcdCAqICAgICAtIG9wdGlvbnMgICAgICAgIHtBcnJheX0gICAgT3B0aW9uIG9iamVjdHM6IHsgbGFiZWwsIHZhbHVlLCBzZWxlY3RlZCB9LlxyXG5cdFx0ICogICAgIC0gcGxhY2Vob2xkZXIgICAge3N0cmluZ30gICBQbGFjZWhvbGRlciB0ZXh0IChzaW5nbGUtc2VsZWN0IG9ubHkpLlxyXG5cdFx0ICogICAgIC0gbXVsdGlwbGUgICAgICAge2Jvb2xlYW58c3RyaW5nfG51bWJlcn0gIEVuYWJsZXMgbXVsdGktc2VsZWN0IHdoZW4gdHJ1dGh5LlxyXG5cdFx0ICogICAgIC0gdXNlX2xhYmVsX2VsZW1lbnQge2Jvb2xlYW59ICBSZXF1ZXN0IGJhcmUgYHVzZV9sYWJlbF9lbGVtZW50YCB0b2tlbiAobm9uLXJhZGlvKS5cclxuXHRcdCAqICAgICAtIGxhYmVsX2ZpcnN0ICAgIHtib29sZWFufSAgSWYgdHJ1ZSwgYXBwZW5kcyBgbGFiZWxfZmlyc3Q6XCIxXCJgIHRva2VuLlxyXG5cdFx0ICogICAgIC0gZGVmYXVsdF92YWx1ZSAge3N0cmluZ30gICBPcHRpb25hbCBkZWZhdWx0IHZhbHVlICh1c2VkIGJ5IGRlZmF1bHRfb3B0aW9uX3N1ZmZpeCgpKS5cclxuXHRcdCAqICAgICAtIGh0bWxfaWQgLyBjc3NjbGFzcyAvIGNsYXNzIC8gY2xhc3NOYW1lICB7c3RyaW5nfSAgVXNlZCB1cHN0cmVhbSBpbiBpZF9vcHQvY2xzX29wdHMuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGlkX29wdFxyXG5cdFx0ICogICBPcHRpb25hbCBpZCB0b2tlbiBidWlsdCBieSBXUEJDX0JGQl9FeHBvcnRlci5pZF9vcHRpb24oZmllbGQsIGN0eCksXHJcblx0XHQgKiAgIGUuZy4gXCIgaWQ6bXlfaWRcIiBvciBlbXB0eSBzdHJpbmcuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGNsc19vcHRzXHJcblx0XHQgKiAgIENsYXNzIHRva2VucyBidWlsdCBieSBXUEJDX0JGQl9FeHBvcnRlci5jbGFzc19vcHRpb25zKGZpZWxkKSxcclxuXHRcdCAqICAgZS5nLiBcIiBjbGFzczpteV9jbGFzcyBjbGFzczpvdGhlclwiLlxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm5zIHtzdHJpbmd9XHJcblx0XHQgKiAgIENvbXBsZXRlIHNob3J0Y29kZSBib2R5IGZvciB0aGUgY2hvaWNlIGZpZWxkLCBmb3IgZXhhbXBsZTpcclxuXHRcdCAqICAgICBcIltyYWRpbyogc2VydmljZXMgdXNlX2xhYmVsX2VsZW1lbnQgXFxcIkFcXFwiIFxcXCJCXFxcIl1cIlxyXG5cdFx0ICogICAgIFwiW3NlbGVjdGJveCBzZXJ2aWNlcyBtdWx0aXBsZSBcXFwiMVxcXCIgXFxcIjJcXFwiIFxcXCIzXFxcIl1cIlxyXG5cdFx0ICogICAgIFwiW3NlbGVjdGJveCogc2VydmljZXMgXFxcIi0tLSBTZWxlY3QgLS0tQEBcXFwiIFxcXCJPcHRpb24gMVxcXCIgXFxcIk9wdGlvbiAyXFxcIl1cIlxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgY2hvaWNlX3RhZyhraW5kLCByZXFfbWFyaywgbmFtZSwgZmllbGQsIGlkX29wdCwgY2xzX29wdHMpIHtcclxuXHRcdFx0Ly8gU3RhcnQgZnJvbSB0aGUgcmF3IG9wdGlvbnMvZGVmYXVsdCBhcyBiZWZvcmUuXHJcblx0XHRcdGxldCB0b2tlbnMgPSBXUEJDX0JGQl9FeHBvcnRlci5vcHRpb25fdG9rZW5zKCBmaWVsZCApO1xyXG5cdFx0XHRsZXQgZGVmICAgID0gV1BCQ19CRkJfRXhwb3J0ZXIuZGVmYXVsdF9vcHRpb25fc3VmZml4KCBmaWVsZCwgdG9rZW5zICk7XHJcblxyXG5cdFx0XHQvLyBGb3IgUkFESU8gd2UgbXVzdCBBTFdBWVMgaW5jbHVkZSBhIGJhcmUgYHVzZV9sYWJlbF9lbGVtZW50YCB0b2tlbiAobm8gdmFsdWUvcXVvdGVzKS5cclxuXHRcdFx0Ly8gRm9yIG90aGVyIGtpbmRzLCBrZWVwIGJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IGluY2x1ZGUgb25seSBpZiBleHBsaWNpdGx5IHNldC5cclxuXHRcdFx0bGV0IHVsZSA9ICcnO1xyXG5cdFx0XHRpZiAoIGtpbmQgPT09ICdyYWRpbycgKSB7XHJcblx0XHRcdFx0dWxlID0gJyB1c2VfbGFiZWxfZWxlbWVudCc7XHJcblx0XHRcdH0gZWxzZSBpZiAoIGZpZWxkICYmIGZpZWxkLnVzZV9sYWJlbF9lbGVtZW50ICkge1xyXG5cdFx0XHRcdHVsZSA9ICcgdXNlX2xhYmVsX2VsZW1lbnQnO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTRUxFQ1RCT1gtc3BlY2lmaWMgZXh0cmFzOlxyXG5cdFx0XHQvLyAgLSBcIm11bHRpcGxlXCIgZmxhZ1xyXG5cdFx0XHQvLyAgLSBwbGFjZWhvbGRlciBleHBvcnRlZCBhcyBGSVJTVCBPUFRJT04gd2hlbiBzaW5nbGUtc2VsZWN0IGFuZCBubyBkZWZhdWx0LlxyXG5cdFx0XHRsZXQgbXVsdGlwbGVfZmxhZyA9ICcnO1xyXG5cclxuXHRcdFx0aWYgKCBraW5kID09PSAnc2VsZWN0Ym94JyAmJiBmaWVsZCApIHtcclxuXHRcdFx0XHRjb25zdCBtdWx0aXBsZSA9XHJcblx0XHRcdFx0XHRmaWVsZC5tdWx0aXBsZSA9PT0gdHJ1ZSAgIHx8XHJcblx0XHRcdFx0XHRmaWVsZC5tdWx0aXBsZSA9PT0gJ3RydWUnIHx8XHJcblx0XHRcdFx0XHRmaWVsZC5tdWx0aXBsZSA9PT0gMSAgICAgIHx8XHJcblx0XHRcdFx0XHRmaWVsZC5tdWx0aXBsZSA9PT0gJzEnICAgIHx8XHJcblx0XHRcdFx0XHRmaWVsZC5tdWx0aXBsZSA9PT0gJ211bHRpcGxlJztcclxuXHJcblx0XHRcdFx0aWYgKCBtdWx0aXBsZSApIHtcclxuXHRcdFx0XHRcdC8vIEV4cG9ydCBiYXJlIFwibXVsdGlwbGVcIiB0b2tlbiBhcyBpbjogW3NlbGVjdGJveCBzZXJ2aWNlcyBtdWx0aXBsZSBcIjFcIiBcIjJcIiBcIjNcIl0uXHJcblx0XHRcdFx0XHRtdWx0aXBsZV9mbGFnID0gJyBtdWx0aXBsZSc7XHJcblx0XHRcdFx0fSBlbHNlIGlmICggIWRlZiApIHtcclxuXHRcdFx0XHRcdC8vIFNpbmdsZS1zZWxlY3QgKyBOTyBkZWZhdWx0IHNlbGVjdGVkOlxyXG5cdFx0XHRcdFx0Ly8gZXhwb3J0IHBsYWNlaG9sZGVyIGFzIHRoZSBGSVJTVCBPUFRJT04gd2l0aCBlbXB0eSB2YWx1ZTpcclxuXHRcdFx0XHRcdC8vICAgW3NlbGVjdGJveCogc2VydmljZXMgXCItLS0gU2VsZWN0IC0tLUBAXCIgXCJPcHRpb24gMVwiIFwiT3B0aW9uIDJcIl1cclxuXHRcdFx0XHRcdGNvbnN0IHJhd1BoID0gZmllbGQucGxhY2Vob2xkZXI7XHJcblx0XHRcdFx0XHRjb25zdCBwaCAgICA9ICh0eXBlb2YgcmF3UGggPT09ICdzdHJpbmcnKSA/IHJhd1BoLnRyaW0oKSA6ICcnO1xyXG5cclxuXHRcdFx0XHRcdGlmICggcGggKSB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IFMgICAgICA9IGNvcmUuV1BCQ19CRkJfU2FuaXRpemU7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGVzY19zYyA9IChTICYmIFMuZXNjYXBlX2Zvcl9zaG9ydGNvZGUpID8gUy5lc2NhcGVfZm9yX3Nob3J0Y29kZSA6ICh2KSA9PiBTdHJpbmcoIHYgKTtcclxuXHJcblx0XHRcdFx0XHRcdGNvbnN0IHBoVG9rZW4gPSBgXCIke2VzY19zYyggcGggKyAnQEAnICl9XCJgO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCB0b2tlbnMgJiYgdG9rZW5zLmxlbmd0aCApIHtcclxuXHRcdFx0XHRcdFx0XHQvLyB0b2tlbnMgYWxyZWFkeSBzdGFydHMgd2l0aCBhIGxlYWRpbmcgc3BhY2UuXHJcblx0XHRcdFx0XHRcdFx0dG9rZW5zID0gJyAnICsgcGhUb2tlbiArIHRva2VucztcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHR0b2tlbnMgPSAnICcgKyBwaFRva2VuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBFbnN1cmUgdGhlcmUgaXMgc3RpbGwgTk8gZGVmYXVsdCBhdHRyaWJ1dGUgd2hlbiB1c2luZyBwbGFjZWhvbGRlci1hcy1vcHRpb24uXHJcblx0XHRcdFx0XHRcdGRlZiA9ICcnO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gT3B0aW9uYWw6IGxhYmVsX2ZpcnN0IHN0YXlzIGFzIHF1b3RlZCBmbGFnIHdoZW4gZXhwbGljaXRseSByZXF1ZXN0ZWQuXHJcblx0XHRcdGNvbnN0IGxmID0gKGZpZWxkICYmIGZpZWxkLmxhYmVsX2ZpcnN0KSA/ICcgbGFiZWxfZmlyc3Q6XCIxXCInIDogJyc7XHJcblxyXG5cdFx0XHQvLyBJTVBPUlRBTlQgT1JERVIgKHBlciByZXF1ZXN0KTpcclxuXHRcdFx0Ly8gW2tpbmQgcmVxIG5hbWUgaWQgY2xzIHVzZV9sYWJlbF9lbGVtZW50IG11bHRpcGxlIGRlZmF1bHQgdG9rZW5zIGxhYmVsX2ZpcnN0XVxyXG5cdFx0XHQvLyBpLmUuIGB1c2VfbGFiZWxfZWxlbWVudGAgKGFuZCBzZWxlY3QgZXh0cmFzKSBjb21lIEJFRk9SRSBkZWZhdWx0L3Rva2Vucy5cclxuXHRcdFx0cmV0dXJuIGBbJHtraW5kfSR7cmVxX21hcmt9ICR7bmFtZX0ke2lkX29wdH0ke2Nsc19vcHRzfSR7dWxlfSR7bXVsdGlwbGVfZmxhZ30ke2RlZn0ke3Rva2Vuc30ke2xmfV1gO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBjb21wdXRlX25hbWUodHlwZSwgZmllbGQpIHtcclxuXHRcdFx0Ly8gTmFtZXMgYXJlIGZ1bGx5IHZhbGlkYXRlZCB3aGVuIHRoZSBmaWVsZCBpcyBhZGRlZCB0byB0aGUgY2FudmFzLlxyXG5cdFx0XHQvLyBUaGUgZXhwb3J0ZXIgbXVzdCB0aGVyZWZvcmUgcHJlc2VydmUgdGhlbSAoYXBhcnQgZnJvbSBpZGVtcG90ZW50IHNhbml0aXphdGlvbiksIG90aGVyd2lzZSBleGlzdGluZyBmb3JtcyBjYW4gYnJlYWsuXHJcblx0XHRcdGNvbnN0IFNhbml0ID0gY29yZS5XUEJDX0JGQl9TYW5pdGl6ZTtcclxuXHJcblx0XHRcdGNvbnN0IHJhdyA9IChmaWVsZCAmJiAoZmllbGQubmFtZSB8fCBmaWVsZC5pZCkpID8gU3RyaW5nKGZpZWxkLm5hbWUgfHwgZmllbGQuaWQpIDogU3RyaW5nKHR5cGUgfHwgJ2ZpZWxkJyk7XHJcblxyXG5cdFx0XHQvLyBJZGVtcG90ZW50IHNhbml0aXphdGlvbiBvbmx5IOKAkyBubyBhdXRvLXByZWZpeGluZyBvciByZW5hbWluZy5cclxuXHRcdFx0Y29uc3QgbmFtZSA9IFNhbml0LnNhbml0aXplX2h0bWxfbmFtZSggcmF3ICk7XHJcblxyXG5cdFx0XHQvLyBJbiB0aGUgdW5saWtlbHkgY2FzZSBzYW5pdGl6YXRpb24gcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcsIGZhbGwgYmFjayB0byBhIHNhbml0aXplZCB0eXBlLWJhc2VkIHRva2VuLlxyXG5cdFx0XHRyZXR1cm4gbmFtZSB8fCBTYW5pdC5zYW5pdGl6ZV9odG1sX25hbWUoIFN0cmluZyh0eXBlIHx8ICdmaWVsZCcpICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZWdpc3RlciBhIHBlci1maWVsZCBleHBvcnRlci5cclxuXHRcdCAqXHJcblx0XHQgKiBUaGlzIGlzIHRoZSBPTkxZIHBsYWNlIHdoZXJlIGZpZWxkLXNwZWNpZmljIHNob3J0Y29kZSBtYXJrdXAgc2hvdWxkIGxpdmUuXHJcblx0XHQgKiBDb3JlIHN0YXlzIGdlbmVyaWM7IHBhY2tzIHByb3ZpZGUgdGlueSBwbHVnaW5zLCBmb3IgZXhhbXBsZTpcclxuXHRcdCAqXHJcblx0XHQgKiAgIFdQQkNfQkZCX0V4cG9ydGVyLnJlZ2lzdGVyKCAndGV4dCcsIChmaWVsZCwgZW1pdCwgZXh0cmFzKSA9PiB7IC4uLiB9ICk7XHJcblx0XHQgKlxyXG5cdFx0ICogQGpEb2NcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlICBGaWVsZCB0eXBlIGtleSwgZS5nLiAnc3RlcHNfdGltZWxpbmUnXHJcblx0XHQgKiBAcGFyYW0geyhmaWVsZDphbnksIGVtaXQ6KGNvZGU6c3RyaW5nKT0+dm9pZCwgZXh0cmFzPzp7aW8/OmFueSxjZmc/OmFueSxvbmNlPzphbnksY3R4PzphbnksY29yZT86YW55fSk9PnZvaWR9XHJcblx0XHQgKiAgICAgZm5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgcmVnaXN0ZXIodHlwZSwgZm4pIHtcclxuXHRcdFx0aWYgKCAhIHR5cGUgfHwgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nICkgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCAhIHRoaXMuX19yZWdpc3RyeSApIHsgdGhpcy5fX3JlZ2lzdHJ5ID0gbmV3IE1hcCgpOyB9XHJcblx0XHRcdHRoaXMuX19yZWdpc3RyeS5zZXQoIFN0cmluZyggdHlwZSApLnRvTG93ZXJDYXNlKCksIGZuICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBVbnJlZ2lzdGVyIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIGV4cG9ydGVyLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBqRG9jXHJcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxyXG5cdFx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyB1bnJlZ2lzdGVyKHR5cGUpIHtcclxuXHRcdFx0aWYgKCAhIHRoaXMuX19yZWdpc3RyeSB8fCAhIHR5cGUgKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLl9fcmVnaXN0cnkuZGVsZXRlKCBTdHJpbmcoIHR5cGUgKS50b0xvd2VyQ2FzZSgpICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDaGVjayBpZiBhbiBleHBvcnRlciBleGlzdHMgZm9yIGEgZ2l2ZW4gZmllbGQgdHlwZS5cclxuXHRcdCAqXHJcblx0XHQgKiBAakRvY1xyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgaGFzX2V4cG9ydGVyKHR5cGUpIHtcclxuXHRcdFx0cmV0dXJuICEhKCB0aGlzLl9fcmVnaXN0cnkgJiYgdGhpcy5fX3JlZ2lzdHJ5LmhhcyggU3RyaW5nKCB0eXBlICkudG9Mb3dlckNhc2UoKSApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSdW4gYSByZWdpc3RlcmVkIGV4cG9ydGVyIGZvciBhIGZpZWxkLCBpZiBwcmVzZW50LlxyXG5cdFx0ICogUmV0dXJucyB0cnVlIGlmIGEgcmVnaXN0ZXJlZCBleHBvcnRlciBoYW5kbGVkIGl0LlxyXG5cdFx0ICpcclxuXHRcdCAqIEBqRG9jXHJcblx0XHQgKiBAcGFyYW0ge2FueX0gZmllbGRcclxuXHRcdCAqIEBwYXJhbSB7e29wZW46RnVuY3Rpb24sY2xvc2U6RnVuY3Rpb24scHVzaDpGdW5jdGlvbixibGFuazpGdW5jdGlvbn19IGlvXHJcblx0XHQgKiBAcGFyYW0ge2FueX0gY2ZnXHJcblx0XHQgKiBAcGFyYW0ge2FueX0gb25jZVxyXG5cdFx0ICogQHBhcmFtIHthbnl9IGN0eFxyXG5cdFx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBydW5fcmVnaXN0ZXJlZF9leHBvcnRlcihmaWVsZCwgaW8sIGNmZywgb25jZSwgY3R4KSB7XHJcblx0XHRcdGlmICggISBmaWVsZCB8fCAhIGZpZWxkLnR5cGUgfHwgISB0aGlzLl9fcmVnaXN0cnkgKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0XHRjb25zdCBrZXkgPSBTdHJpbmcoIGZpZWxkLnR5cGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRjb25zdCBmbiAgPSB0aGlzLl9fcmVnaXN0cnkuZ2V0KCBrZXkgKTtcclxuXHRcdFx0aWYgKCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicgKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHQvLyBNaW5pbWFsLCBjb25zaXN0ZW50IGVtaXQoKSBicmlkZ2UgaW50byBvdXIgbGluZSBidWZmZXI6XHJcblx0XHRcdFx0Y29uc3QgZW1pdCA9IChjb2RlKSA9PiB7IGlmICggdHlwZW9mIGNvZGUgPT09ICdzdHJpbmcnICkgeyBpby5wdXNoKCBjb2RlICk7IH0gfTtcclxuXHRcdFx0XHRmbiggZmllbGQsIGVtaXQsIHsgaW8sIGNmZywgb25jZSwgY3R4LCBjb3JlIH0gKTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fSBjYXRjaCAoZSkge1xyXG5cdFx0XHRcdF93cGJjPy5kZXY/LmVycm9yPy4oICdXUEJDX0JGQl9FeHBvcnRlci5ydW5fcmVnaXN0ZXJlZF9leHBvcnRlcicsIGUgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHQvLyBleHBvc2UgZ2xvYmFsbHkgZm9yIHBhY2tzIChpZiBub3QgYWxyZWFkeSkuXHJcblx0d2luZG93LldQQkNfQkZCX0V4cG9ydGVyID0gd2luZG93LldQQkNfQkZCX0V4cG9ydGVyIHx8IFdQQkNfQkZCX0V4cG9ydGVyO1xyXG5cdHdwYmNfYmZiX19kaXNwYXRjaF9ldmVudF9zYWZlKCAnd3BiYzpiZmI6ZXhwb3J0ZXItcmVhZHknLCB7fSApO1xyXG5cclxuXHQvLyBJbml0aWFsaXplIGRlZmF1bHQgc2tpcCBsaXN0OyBhbGxvdyBhIGdsb2JhbCBvdmVycmlkZSBhcnJheSBiZWZvcmUgZXhwb3J0IHJ1bnMuXHJcblx0V1BCQ19CRkJfRXhwb3J0ZXIuc2V0X3NraXBfYXR0cnMoIHdpbmRvdy5XUEJDX0JGQl9FWFBPUlRfU0tJUF9BVFRSUyB8fCB3cGJjX2V4cG9ydF9za2lwX2F0dHJzX2RlZmF1bHQgKTtcclxuXHJcblx0Ly8gPT0gXCJDb250ZW50IG9mIGJvb2tpbmcgZmllbGRzIGRhdGFcIiBFeHBvcnRlciA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuXHQvLyDigJMgcGFjay1leHRlbnNpYmxlIGdlbmVyYXRvciBmb3IgXCJDb250ZW50IG9mIGJvb2tpbmcgZmllbGRzIGRhdGFcIiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cdC8vID09IFByb2R1Y2VzIG1hcmt1cCBsaWtlOiAgXCI8ZGl2IGNsYXNzPVxcXCJzdGFuZGFyZC1jb250ZW50LWZvcm1cXFwiPjxiPlRpdGxlPC9iPjogPGY+W3Nob3J0Y29kZV08L2Y+PGJyPiAuLi4gPC9kaXY+XCJcclxuXHQvLyA9PSBQYWNrcyBjYW4gb3ZlcnJpZGUgcGVyIHR5cGUgdmlhOiBXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIucmVnaXN0ZXIoJ2NhbGVuZGFyJywgKGZpZWxkLCBlbWl0LCBjdHgpPT57Li4ufSlcclxuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblx0Y2xhc3MgV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyIHtcclxuXHJcblx0XHRzdGF0aWMgcmVnaXN0ZXIodHlwZSwgZm4pIHtcclxuXHRcdFx0aWYgKCAhdHlwZSB8fCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicgKSByZXR1cm47XHJcblx0XHRcdGlmICggIXRoaXMuX19yZWdpc3RyeSApIHRoaXMuX19yZWdpc3RyeSA9IG5ldyBNYXAoKTtcclxuXHRcdFx0dGhpcy5fX3JlZ2lzdHJ5LnNldCggU3RyaW5nKCB0eXBlICkudG9Mb3dlckNhc2UoKSwgZm4gKTtcclxuXHRcdH1cclxuXHJcblx0XHRzdGF0aWMgdW5yZWdpc3Rlcih0eXBlKSB7XHJcblx0XHRcdGlmICggIXRoaXMuX19yZWdpc3RyeSB8fCAhdHlwZSApIHJldHVybjtcclxuXHRcdFx0dGhpcy5fX3JlZ2lzdHJ5LmRlbGV0ZSggU3RyaW5nKCB0eXBlICkudG9Mb3dlckNhc2UoKSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHN0YXRpYyBoYXNfZXhwb3J0ZXIodHlwZSkge1xyXG5cdFx0XHRyZXR1cm4gISEodGhpcy5fX3JlZ2lzdHJ5ICYmIHRoaXMuX19yZWdpc3RyeS5oYXMoIFN0cmluZyggdHlwZSApLnRvTG93ZXJDYXNlKCkgKSk7XHJcblx0XHR9XHJcblxyXG5cdFx0c3RhdGljIHJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyKGZpZWxkLCBlbWl0LCBjdHgpIHtcclxuXHRcdFx0aWYgKCAhZmllbGQgfHwgIWZpZWxkLnR5cGUgfHwgIXRoaXMuX19yZWdpc3RyeSApIHJldHVybiBmYWxzZTtcclxuXHRcdFx0Y29uc3Qga2V5ID0gU3RyaW5nKCBmaWVsZC50eXBlICkudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0Y29uc3QgZm4gID0gdGhpcy5fX3JlZ2lzdHJ5LmdldCgga2V5ICk7XHJcblx0XHRcdGlmICggdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nICkgcmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdGZuKCBmaWVsZCwgZW1pdCwgY3R4IHx8IHt9ICk7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xyXG5cdFx0XHRcdF93cGJjPy5kZXY/LmVycm9yPy4oICdXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIucnVuX3JlZ2lzdGVyZWRfZXhwb3J0ZXInLCBlICk7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gPT09IE5FVzogc2hhcmVkIGxpbmUgZm9ybWF0dGVyIGZvciBcIkNvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YVwiID09PVxyXG5cdFx0c3RhdGljIGVtaXRfbGluZV9ib2xkX2ZpZWxkKGVtaXQsIGxhYmVsLCB0b2tlbiwgY2ZnKSB7XHJcblx0XHRcdGNvbnN0IFMgICAgICAgICA9IGNvcmUuV1BCQ19CRkJfU2FuaXRpemU7XHJcblx0XHRcdGNvbnN0IHNlcCAgICAgICA9IChjZmcgJiYgdHlwZW9mIGNmZy5zZXAgPT09ICdzdHJpbmcnKSA/IGNmZy5zZXAgOiAnOiAnO1xyXG5cdFx0XHRjb25zdCBhZGRMYWJlbHMgPSAoY2ZnICYmICdhZGRMYWJlbHMnIGluIGNmZykgPyAhIWNmZy5hZGRMYWJlbHMgOiB0cnVlO1xyXG5cclxuXHRcdFx0Y29uc3QgdGl0bGUgPSAoYWRkTGFiZWxzICYmIGxhYmVsKSA/IGA8Yj4ke1MuZXNjYXBlX2h0bWwobGFiZWwpfTwvYj4ke3NlcH1gIDogJyc7XHJcblxyXG5cdFx0XHRlbWl0KGAke3RpdGxlfTxmPlske3Rva2VufV08L2Y+PGJyPmApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogRXhwb3J0IGFkYXB0ZWQgc3RydWN0dXJlIHRvIOKAnGNvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YeKAnS5cclxuXHRcdCAqIEBwYXJhbSB7e3BhZ2VzOkFycmF5fX0gYWRhcHRlZCAgcmVzdWx0IG9mIGFkYXB0X2J1aWxkZXJfc3RydWN0dXJlX3RvX2V4cG9ydGVyKClcclxuXHRcdCAqIEBwYXJhbSB7e25ld2xpbmU/OnN0cmluZywgYWRkTGFiZWxzPzpib29sZWFuLCBzZXA/OnN0cmluZ319IG9wdGlvbnNcclxuXHRcdCAqIEByZXR1cm5zIHtzdHJpbmd9XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBleHBvcnRfY29udGVudChhZGFwdGVkLCBvcHRpb25zID0ge30pIHtcclxuXHJcblx0XHRcdGNvbnN0IGNmZyAgID0geyBuZXdsaW5lOiAnXFxuJywgYWRkTGFiZWxzOiB0cnVlLCBzZXA6ICc6ICcsIGluZGVudDogJ1xcdCcsIC4uLm9wdGlvbnMgfTtcclxuXHRcdFx0Y29uc3QgSU5EICAgPSAodHlwZW9mIGNmZy5pbmRlbnQgPT09ICdzdHJpbmcnKSA/IGNmZy5pbmRlbnQgOiAnXFx0JztcclxuXHRcdFx0bGV0IGRlcHRoICAgPSAwO1xyXG5cdFx0XHRjb25zdCBsaW5lcyA9IFtdO1xyXG5cclxuXHRcdFx0Y29uc3QgcHVzaCAgPSAocyA9ICcnKSA9PiBsaW5lcy5wdXNoKCBJTkQucmVwZWF0KCBkZXB0aCApICsgU3RyaW5nKCBzICkgKTtcclxuXHRcdFx0Y29uc3Qgb3BlbiAgPSAocyA9ICcnKSA9PiB7IHB1c2goIHMgKTsgZGVwdGgrKzsgfTtcclxuXHRcdFx0Y29uc3QgY2xvc2UgPSAocyA9ICcnKSA9PiB7IGRlcHRoID0gTWF0aC5tYXgoIDAsIGRlcHRoIC0gMSApOyBwdXNoKCBzICk7IH07XHJcblxyXG5cdFx0XHRjb25zdCBlbWl0ID0gKHMpID0+IHtcclxuXHRcdFx0XHRpZiAoIHR5cGVvZiBzICE9PSAnc3RyaW5nJyApIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0U3RyaW5nKCBzICkuc3BsaXQoIC9cXHI/XFxuLyApLmZvckVhY2goIChsaW5lKSA9PiBwdXNoKCBsaW5lICkgKTtcclxuXHRcdFx0fTtcclxuXHJcblx0XHRcdGlmICggIWFkYXB0ZWQgfHwgIUFycmF5LmlzQXJyYXkoIGFkYXB0ZWQucGFnZXMgKSApIHJldHVybiAnJztcclxuXHJcblx0XHRcdGNvbnN0IHNraXBUeXBlcyA9IG5ldyBTZXQoIFsgJ2NhcHRjaGEnLCAnc3VibWl0JywgJ2RpdmlkZXInLCAnd2l6YXJkX25hdicsICdjb3N0X2NvcnJlY3Rpb25zJyBdICk7XHJcblxyXG5cdFx0XHRjb25zdCBmYWxsYmFja0xpbmUgPSAoZmllbGQpID0+IHtcclxuXHRcdFx0XHRjb25zdCB0eXBlICA9IFN0cmluZyggZmllbGQudHlwZSB8fCAnJyApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdFx0Y29uc3QgbmFtZSAgPSBXUEJDX0JGQl9FeHBvcnRlci5jb21wdXRlX25hbWUoIHR5cGUsIGZpZWxkICk7XHJcblx0XHRcdFx0Y29uc3QgbGFiZWwgPSAodHlwZW9mIGZpZWxkLmxhYmVsID09PSAnc3RyaW5nJyAmJiBmaWVsZC5sYWJlbC50cmltKCkpID8gZmllbGQubGFiZWwudHJpbSgpIDogbmFtZTtcclxuXHRcdFx0XHRpZiAoICFuYW1lICkgcmV0dXJuO1xyXG5cdFx0XHRcdFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5lbWl0X2xpbmVfYm9sZF9maWVsZCggZW1pdCwgbGFiZWwsIG5hbWUsIGNmZyApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdFx0Ly8gUGVyLXR5cGUgc2Vuc2libGUgZGVmYXVsdHMgKGNhbiBiZSBvdmVycmlkZGVuIGJ5IHBhY2tzIHZpYSByZWdpc3RlcigpKVxyXG5cdFx0XHRjb25zdCBkZWZhdWx0Q29udGVudEZvciA9IChmaWVsZCkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHR5cGUgPSBTdHJpbmcoIGZpZWxkLnR5cGUgfHwgJycgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRcdGlmICggc2tpcFR5cGVzLmhhcyggdHlwZSApICkgcmV0dXJuO1xyXG5cdFx0XHRcdC8vIFNwZWNpYWwgY2FzZXMgb3V0IG9mIHRoZSBib3g6XHJcblx0XHRcdFx0aWYgKCB0eXBlID09PSAnY2FsZW5kYXInICkge1xyXG5cdFx0XHRcdFx0Y29uc3QgbGFiZWwgPSAodHlwZW9mIGZpZWxkLmxhYmVsID09PSAnc3RyaW5nJyAmJiBmaWVsZC5sYWJlbC50cmltKCkpID8gZmllbGQubGFiZWwudHJpbSgpIDogJ0RhdGVzJztcclxuXHRcdFx0XHRcdFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5lbWl0X2xpbmVfYm9sZF9maWVsZCggZW1pdCwgbGFiZWwsICdkYXRlcycsIGNmZyApO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyB0aW1lLWxpa2UgcmVzZXJ2ZWQgbmFtZXMgLT4ga2VlcCBwbGFjZWhvbGRlciB0b2tlbiBlcXVhbCB0byBuYW1lXHJcblx0XHRcdFx0Y29uc3QgcmVzZXJ2ZWQgPSBTdHJpbmcoIGZpZWxkLm5hbWUgfHwgZmllbGQuaWQgfHwgJycgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRcdGlmICggWyAncmFuZ2V0aW1lJywgJ3N0YXJ0dGltZScsICdlbmR0aW1lJywgJ2R1cmF0aW9udGltZScgXS5pbmNsdWRlcyggcmVzZXJ2ZWQgKSApIHtcclxuXHRcdFx0XHRcdGNvbnN0IGxhYmVsID0gKHR5cGVvZiBmaWVsZC5sYWJlbCA9PT0gJ3N0cmluZycgJiYgZmllbGQubGFiZWwudHJpbSgpKSA/IGZpZWxkLmxhYmVsLnRyaW0oKSA6IHJlc2VydmVkO1xyXG5cdFx0XHRcdFx0Ly8gS2VlcCB5b3VyIHNwZWNpYWwgdG9rZW4gZm9yIGR1cmF0aW9uIHRpbWUgaW4gY29udGVudDogW2R1cmF0aW9udGltZV92YWxdXHJcblx0XHRcdFx0XHRjb25zdCB0b2tlbiA9IChyZXNlcnZlZCA9PT0gJ2R1cmF0aW9udGltZScpID8gJ2R1cmF0aW9udGltZV92YWwnIDogcmVzZXJ2ZWQ7XHJcblx0XHRcdFx0XHRXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIuZW1pdF9saW5lX2JvbGRfZmllbGQoIGVtaXQsIGxhYmVsLCB0b2tlbiwgY2ZnICk7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdC8vIEZhbGxiYWNrICh0ZXh0L2VtYWlsL3RlbC9udW1iZXIvdGV4dGFyZWEvc2VsZWN0L2NoZWNrYm94L3JhZGlvIGV0Yy4pXHJcblx0XHRcdFx0ZmFsbGJhY2tMaW5lKCBmaWVsZCApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdFx0Ly8gV2FsayBwYWdlcy9zZWN0aW9ucy9jb2x1bW5zL2ZpZWxkcyAoc2FtZSBvcmRlciBhcyBmb3JtKVxyXG5cdFx0XHRjb25zdCB3YWxrU2VjdGlvbiAgPSAoc2VjKSA9PiB7XHJcblx0XHRcdFx0KHNlYy5jb2x1bW5zIHx8IFtdKS5mb3JFYWNoKCAoY29sKSA9PiB7XHJcblx0XHRcdFx0XHQoY29sLmZpZWxkcyB8fCBbXSkuZm9yRWFjaCggKGYpID0+IHByb2Nlc3NGaWVsZCggZiApICk7XHJcblx0XHRcdFx0XHQoY29sLnNlY3Rpb25zIHx8IFtdKS5mb3JFYWNoKCAocykgPT4gd2Fsa1NlY3Rpb24oIHMgKSApO1xyXG5cdFx0XHRcdH0gKTtcclxuXHRcdFx0fTtcclxuXHRcdFx0Y29uc3QgcHJvY2Vzc0l0ZW0gID0gKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoICFpdGVtICkgcmV0dXJuO1xyXG5cdFx0XHRcdGlmICggaXRlbS5raW5kID09PSAnZmllbGQnICkgcHJvY2Vzc0ZpZWxkKCBpdGVtLmRhdGEgKTtcclxuXHRcdFx0XHRpZiAoIGl0ZW0ua2luZCA9PT0gJ3NlY3Rpb24nICkgd2Fsa1NlY3Rpb24oIGl0ZW0uZGF0YSApO1xyXG5cdFx0XHR9O1xyXG5cdFx0XHRjb25zdCBwcm9jZXNzRmllbGQgPSAoZmllbGQpID0+IHtcclxuXHRcdFx0XHRpZiAoICFmaWVsZCApIHJldHVybjtcclxuXHRcdFx0XHQvLyBhbGxvdyBwYWNrcyB0byBvdmVycmlkZTpcclxuXHRcdFx0XHRpZiAoIFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5ydW5fcmVnaXN0ZXJlZF9leHBvcnRlciggZmllbGQsIGVtaXQsIHsgY2ZnLCBjb3JlIH0gKSApIHJldHVybjtcclxuXHRcdFx0XHRkZWZhdWx0Q29udGVudEZvciggZmllbGQgKTtcclxuXHRcdFx0fTtcclxuXHJcblx0XHRcdC8vIFdyYXBwZXIgZmlyc3QgLT4gaW5uZXIgbGluZXMgd2lsbCBiZSBUQUItaW5kZW50ZWRcclxuXHRcdFx0b3BlbiggYDxkaXYgY2xhc3M9XCJzdGFuZGFyZC1jb250ZW50LWZvcm1cIj5gICk7XHJcblx0XHRcdGFkYXB0ZWQucGFnZXMuZm9yRWFjaCggKHBhZ2UpID0+IChwYWdlLml0ZW1zIHx8IFtdKS5mb3JFYWNoKCBwcm9jZXNzSXRlbSApICk7XHJcblx0XHRcdGNsb3NlKCBgPC9kaXY+YCApO1xyXG5cclxuXHRcdFx0cmV0dXJuIGxpbmVzLmpvaW4oIGNmZy5uZXdsaW5lICk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0Ly8gZXhwb3NlICsgcmVhZHkgZXZlbnQgZm9yIHBhY2tzIHRvIHJlZ2lzdGVyIHRoZWlyIGNvbnRlbnQgZXhwb3J0ZXJzLlxyXG5cdHdpbmRvdy5XUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIgPSB3aW5kb3cuV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyIHx8IFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlcjtcclxuXHR3cGJjX2JmYl9fZGlzcGF0Y2hfZXZlbnRfc2FmZSggJ3dwYmM6YmZiOmNvbnRlbnQtZXhwb3J0ZXItcmVhZHknLCB7fSApO1xyXG59KSgpO1xyXG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxZ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
1149