| 1 |
"use strict"; |
| 2 |
|
| 3 |
/** |
| 4 |
* WPBC BFB: Field Renderer for "text" (Schema-driven Reference, template-literal render) |
| 5 |
* ============================================================================================== |
| 6 |
* Purpose: |
| 7 |
* - Uses template literals (no wp.template) |
| 8 |
* - Inspector is rendered by Factory (PHP schema) |
| 9 |
* - Uses WPBC_BFB_Sanitize (from core) with method names as in bfb-core.js |
| 10 |
* |
| 11 |
* Contracts: |
| 12 |
* - Registry: WPBC_BFB_Field_Renderer_Registry.register( 'text', Class ) |
| 13 |
* - Class API: static get_defaults(), static render(el, data, ctx), static on_field_drop(data, el, ctx?) [optional] |
| 14 |
* |
| 15 |
* Notes: |
| 16 |
* - Keep defaults aligned with PHP schema->props->default. |
| 17 |
* - Use Overlay.ensure(...) so field controls (handle, settings, etc.) appear. |
| 18 |
* |
| 19 |
* File: ../includes/page-form-builder/field-packs/text/_out/field-text.js |
| 20 |
* |
| 21 |
* @since 11.0.0 |
| 22 |
* @modified 2025-09-06 14:08 |
| 23 |
* @version 1.0.1 |
| 24 |
* |
| 25 |
*/ |
| 26 |
(function (w) { |
| 27 |
'use strict'; |
| 28 |
|
| 29 |
var Core = w.WPBC_BFB_Core || {}; |
| 30 |
var registry = Core.WPBC_BFB_Field_Renderer_Registry; |
| 31 |
var Base = Core.WPBC_BFB_Field_Base; |
| 32 |
if (!registry || typeof registry.register !== 'function' || !Base) { |
| 33 |
_wpbc?.dev?.error?.('WPBC_BFB_Field_Text', 'Core registry/base missing'); |
| 34 |
return; |
| 35 |
} |
| 36 |
class WPBC_BFB_Field_Text extends Base { |
| 37 |
/** |
| 38 |
* Return default props for "text" field. |
| 39 |
* Must stay in sync with PHP schema defaults. |
| 40 |
* |
| 41 |
* @returns {Object} |
| 42 |
*/ |
| 43 |
static get_defaults() { |
| 44 |
return { |
| 45 |
type: 'text', |
| 46 |
label: 'Text', |
| 47 |
name: '', |
| 48 |
html_id: '', |
| 49 |
placeholder: '', |
| 50 |
required: false, |
| 51 |
minlength: null, |
| 52 |
maxlength: null, |
| 53 |
pattern: '', |
| 54 |
cssclass: '', |
| 55 |
help: '', |
| 56 |
default_value: '' |
| 57 |
}; |
| 58 |
} |
| 59 |
|
| 60 |
/** |
| 61 |
* Render the preview markup into the field element. |
| 62 |
* |
| 63 |
* @param {HTMLElement} el Field root element inside the canvas. |
| 64 |
* @param {Object} d Field props (already normalized by schema). |
| 65 |
* @param {Object} ctx Context: { builder, sanit, ... } |
| 66 |
*/ |
| 67 |
static render(el, data, ctx) { |
| 68 |
if (!el) { |
| 69 |
return; |
| 70 |
} |
| 71 |
|
| 72 |
// Normalize against defaults first. |
| 73 |
const d = this.normalize_data(data); |
| 74 |
|
| 75 |
// ----- Core sanitize helpers (static) ----- |
| 76 |
const eh = v => Core.WPBC_BFB_Sanitize.escape_html(v); |
| 77 |
const sid = v => Core.WPBC_BFB_Sanitize.sanitize_html_id(v); |
| 78 |
const sname = v => Core.WPBC_BFB_Sanitize.sanitize_html_name(v); |
| 79 |
const sclass = v => Core.WPBC_BFB_Sanitize.sanitize_css_classlist(v); |
| 80 |
const truthy = v => Core.WPBC_BFB_Sanitize.is_truthy(v); |
| 81 |
|
| 82 |
// Sanitize public id/name for the control itself. |
| 83 |
const html_id = d.html_id ? sid(String(d.html_id)) : ''; |
| 84 |
const name_val = sname(String(d.name || d.id || 'field')); |
| 85 |
const cssNext = sclass(String(d.cssclass || '')); |
| 86 |
|
| 87 |
// Keep wrapper classes in sync with dataset.cssclass ONLY (don’t touch core classes). |
| 88 |
// if ( 'cssclass' in d ) { |
| 89 |
// const prev = el.dataset.cssclass || ''; |
| 90 |
// if ( prev !== cssNext ) { |
| 91 |
// prev.split( /\s+/ ).filter( Boolean ).forEach( (c) => el.classList.remove( c ) ); |
| 92 |
// cssNext.split( /\s+/ ).filter( Boolean ).forEach( (c) => el.classList.add( c ) ); |
| 93 |
// el.dataset.cssclass = cssNext; |
| 94 |
// } |
| 95 |
// } |
| 96 |
// NEW: store only; do NOT modify wrapper classes. |
| 97 |
if ('cssclass' in d) { |
| 98 |
if (el.dataset.cssclass !== cssNext) { |
| 99 |
el.dataset.cssclass = cssNext; |
| 100 |
} |
| 101 |
} |
| 102 |
// Keep wrapper's stored html_id (dataset) updated. |
| 103 |
if ('html_id' in d) { |
| 104 |
if (el.dataset.html_id !== html_id) { |
| 105 |
el.dataset.html_id = html_id; |
| 106 |
} |
| 107 |
} |
| 108 |
|
| 109 |
// Flags / numeric constraints. |
| 110 |
const is_required = truthy(d.required); |
| 111 |
const has_minlength = d.minlength != null && d.minlength !== '' && Number.isFinite(+d.minlength); |
| 112 |
const has_maxlength = d.maxlength != null && d.maxlength !== '' && Number.isFinite(+d.maxlength); |
| 113 |
const has_pattern = !!d.pattern; |
| 114 |
const minlength_num = has_minlength ? Number(d.minlength) : null; |
| 115 |
const maxlength_num = has_maxlength ? Number(d.maxlength) : null; |
| 116 |
|
| 117 |
// Attribute fragments (using escape_html for safe innerHTML attribute context). |
| 118 |
const id_attr = html_id ? ` id="${eh(html_id)}"` : ''; |
| 119 |
const name_attr = ` name="${eh(name_val)}"`; |
| 120 |
// const cls_attr = ` class="wpbc_bfb__preview-input ${eh( cssNext )}"`; |
| 121 |
const cls_attr = ` class="wpbc_bfb__preview-input ${cssNext ? ' ' + eh(cssNext) : ''}"`; |
| 122 |
const ph_attr = d.placeholder ? ` placeholder="${eh(d.placeholder)}"` : ''; |
| 123 |
const req_attr = is_required ? ' required aria-required="true"' : ''; |
| 124 |
const minlength_attr = has_minlength ? ` minlength="${minlength_num}"` : ''; |
| 125 |
const maxlength_attr = has_maxlength ? ` maxlength="${maxlength_num}"` : ''; |
| 126 |
const pattern_attr = has_pattern ? ` pattern="${eh(d.pattern)}"` : ''; |
| 127 |
const value_attr = d.default_value != null && d.default_value !== '' ? ` value="${eh(String(d.default_value))}"` : ''; |
| 128 |
// Optional fragments. |
| 129 |
const label_html = d.label != null && d.label !== '' ? `<label class="wpbc_bfb__field-label"${html_id ? ` for="${eh(html_id)}"` : ''}>${eh(d.label)}${is_required ? '<span aria-hidden="true">*</span>' : ''}</label>` : ''; |
| 130 |
const help_html = d.help ? `<div class="wpbc_bfb__help">${eh(d.help)}</div>` : ''; |
| 131 |
|
| 132 |
// Render preview HTML. |
| 133 |
el.innerHTML = ` |
| 134 |
<span class="wpbc_bfb__noaction wpbc_bfb__no-drag-zone" inert=""> |
| 135 |
${label_html} |
| 136 |
<span class="wpbc_wrap_text wpdev-form-control-wrap"> |
| 137 |
<input type="text"${cls_attr}${ph_attr}${name_attr} autocomplete="off" tabindex="-1" aria-disabled="true"${id_attr}${value_attr}${req_attr}${minlength_attr}${maxlength_attr}${pattern_attr} /> |
| 138 |
|
| 139 |
</span> |
| 140 |
${help_html} |
| 141 |
</span> |
| 142 |
`; |
| 143 |
|
| 144 |
// Overlay (handles/toolbars). |
| 145 |
Core.UI?.WPBC_BFB_Overlay?.ensure?.(ctx?.builder, el); |
| 146 |
} |
| 147 |
|
| 148 |
/** |
| 149 |
* Optional hook executed after field is dropped from the palette. |
| 150 |
* Example recipe placeholder for future: try { if ( !data.name ) { data.name = core.WPBC_BFB_IdService?.next_name?.( 'text' ) || 'text'; } } catch ( e ) { } |
| 151 |
* |
| 152 |
* @param {Object} data Palette/field data. |
| 153 |
* @param {HTMLElement} el Newly created field element. |
| 154 |
* @param {Object} ctx Context { builder, sanit, context: 'drop' | 'load' | 'preview' } |
| 155 |
* @returns {void} |
| 156 |
*/ |
| 157 |
static on_field_drop(data, el, ctx) { |
| 158 |
super.on_field_drop?.(data, el, ctx); // Required for correctly auto-names from Labels ! |
| 159 |
// (your extra pack-specific logic if ever needed) |
| 160 |
} |
| 161 |
} |
| 162 |
try { |
| 163 |
registry.register('text', WPBC_BFB_Field_Text); |
| 164 |
} catch (e) { |
| 165 |
_wpbc?.dev?.error?.('WPBC_BFB_Field_Text.register', e); |
| 166 |
} |
| 167 |
|
| 168 |
// Optional global alias (debugging / dev tools). |
| 169 |
w.WPBC_BFB_Field_Text = w.WPBC_BFB_Field_Text || WPBC_BFB_Field_Text; |
| 170 |
|
| 171 |
// ----------------------------------------------------------------------------------------------------------------- |
| 172 |
// Export for "Booking Form" (Advanced Form shortcode) |
| 173 |
// ----------------------------------------------------------------------------------------------------------------- |
| 174 |
/** |
| 175 |
* Booking Form exporter callback (Advanced Form shortcode). |
| 176 |
* |
| 177 |
* This callback is registered per field type via: |
| 178 |
* WPBC_BFB_Exporter.register( 'text', callback ) |
| 179 |
* |
| 180 |
* Core call site (builder-exporter.js): |
| 181 |
* WPBC_BFB_Exporter.run_registered_exporter( field, io, cfg, once, ctx ) |
| 182 |
* -> callback( field, emit, { io, cfg, once, ctx, core } ); |
| 183 |
* |
| 184 |
* @callback WPBC_BFB_ExporterCallback |
| 185 |
* @param {Object} field |
| 186 |
* Normalized field data coming from the Builder structure. |
| 187 |
* - field.type {string} Field type, e.g. "text". |
| 188 |
* - field.name {string} Name as stored on the canvas (already validated). |
| 189 |
* - field.id / html_id {string} Optional HTML id / user-visible id. |
| 190 |
* - field.label {string} Visible label in the form (may be empty). |
| 191 |
* - field.placeholder {string} Placeholder text (may be empty). |
| 192 |
* - field.required {boolean|number|string} "truthy" if required. |
| 193 |
* - field.cssclass {string} Extra CSS classes entered in Inspector. |
| 194 |
* - field.default_value {string} Default text value. |
| 195 |
* - field.options {Array} Only for option-based fields (select, checkbox, etc.). |
| 196 |
* - ... (Any other pack-specific props are also present.) |
| 197 |
* |
| 198 |
* @param {function(string):void} emit |
| 199 |
* Emits one line/fragment into the export buffer. |
| 200 |
* - Each call corresponds to one `push()` in the core exporter. |
| 201 |
* - For multi-line output (e.g. label + shortcode), call `emit()` multiple times: |
| 202 |
* emit('<l>Label</l>'); |
| 203 |
* emit('<br>[text* name ...]'); |
| 204 |
* |
| 205 |
* @param {Object} [extras] |
| 206 |
* Extra context passed by the core exporter. |
| 207 |
* |
| 208 |
* @param {Object} [extras.io] |
| 209 |
* Low-level writer used internally by the core. |
| 210 |
* Normally you do NOT need it in packs — prefer `emit()`. |
| 211 |
* - extras.io.open(str) -> open a nested block (increments indentation). |
| 212 |
* - extras.io.close(str) -> close a block (decrements indentation). |
| 213 |
* - extras.io.push(str) -> push raw line (used by `emit()`). |
| 214 |
* - extras.io.blank() -> push an empty line. |
| 215 |
* |
| 216 |
* @param {Object} [extras.cfg] |
| 217 |
* Export configuration (same object passed to WPBC_BFB_Exporter.export_form()). |
| 218 |
* Useful flags for field packs: |
| 219 |
* - extras.cfg.addLabels {boolean} Default: true. |
| 220 |
* If false, packs should NOT emit <l>Label</l> lines. |
| 221 |
* - extras.cfg.newline {string} Newline separator (usually "\n"). |
| 222 |
* - extras.cfg.gapPercent{number} Layout gap (used only by section/column logic). |
| 223 |
* |
| 224 |
* @param {Object} [extras.once] |
| 225 |
* Shared "once-per-form" guards across all fields. |
| 226 |
* Counters are incremented by some field types (captcha, coupon, etc.). |
| 227 |
* Typical shape: |
| 228 |
* - extras.once.captcha {number} |
| 229 |
* - extras.once.country {number} |
| 230 |
* - extras.once.coupon {number} |
| 231 |
* - extras.once.cost_corrections {number} |
| 232 |
* - extras.once.submit {number} |
| 233 |
* |
| 234 |
* Text field usually does not touch this object, but other packs can use it |
| 235 |
* to skip duplicates (e.g. only the first [coupon] per form is exported). |
| 236 |
* |
| 237 |
* @param {Object} [extras.ctx] |
| 238 |
* Shared export context for the entire form. |
| 239 |
* Currently: |
| 240 |
* - extras.ctx.usedIds {Set<string>} |
| 241 |
* Set of HTML/shortcode IDs already used in this export. |
| 242 |
* Helpers like Exp.id_option(field, ctx) use it to ensure uniqueness. |
| 243 |
* |
| 244 |
* Packs normally just pass `ctx` into helpers (id_option, etc.) without |
| 245 |
* mutating it directly. |
| 246 |
* |
| 247 |
* @param {Object} [extras.core] |
| 248 |
* Reference to WPBC_BFB_Core passed from builder-exporter.js. |
| 249 |
* Primarily used to access sanitizers: |
| 250 |
* - extras.core.WPBC_BFB_Sanitize.escape_html(...) |
| 251 |
* - extras.core.WPBC_BFB_Sanitize.escape_for_shortcode(...) |
| 252 |
* - extras.core.WPBC_BFB_Sanitize.sanitize_html_name(...) |
| 253 |
* - etc. |
| 254 |
*/ |
| 255 |
function register_text_booking_form_exporter() { |
| 256 |
const Exp = w.WPBC_BFB_Exporter; |
| 257 |
if (!Exp || typeof Exp.register !== 'function') { |
| 258 |
return; |
| 259 |
} |
| 260 |
if (typeof Exp.has_exporter === 'function' && Exp.has_exporter('text')) { |
| 261 |
return; |
| 262 |
} |
| 263 |
const S = Core.WPBC_BFB_Sanitize; |
| 264 |
Exp.register('text', (field, emit, extras = {}) => { |
| 265 |
const cfg = extras.cfg || {}; |
| 266 |
const ctx = extras.ctx; // no local fallback needed. |
| 267 |
const addLabels = cfg.addLabels !== false; |
| 268 |
|
| 269 |
// Required marker logic (same as before). |
| 270 |
const is_req = Exp.is_required(field); |
| 271 |
const req_mark = is_req ? '*' : ''; |
| 272 |
|
| 273 |
// Reuse helpers from WPBC_BFB_Exporter. |
| 274 |
const name = Exp.compute_name('text', field); |
| 275 |
const id_opt = Exp.id_option(field, ctx); |
| 276 |
const cls_opts = Exp.class_options(field); |
| 277 |
const ph_attr = Exp.ph_attr(field.placeholder); |
| 278 |
const size_max = Exp.size_max_token(field); |
| 279 |
const def_value = Exp.default_text_suffix(field); |
| 280 |
|
| 281 |
// Build body shortcode. |
| 282 |
const body = `[text${req_mark} ${name}${size_max}${id_opt}${cls_opts}${ph_attr}${def_value}]`; |
| 283 |
|
| 284 |
// Label behavior identical to legacy emit_label_then(). |
| 285 |
const label = (field.label ?? '').toString().trim(); |
| 286 |
if (label && addLabels) { |
| 287 |
emit(`<l>${S.escape_html(label)}${req_mark}</l>`); |
| 288 |
emit(`<br>${body}`); |
| 289 |
} else { |
| 290 |
emit(body); |
| 291 |
} |
| 292 |
// Help text is appended centrally by WPBC_BFB_Exporter.render_field_node(). |
| 293 |
}); |
| 294 |
} |
| 295 |
|
| 296 |
// Try immediate registration; if core isn’t ready, wait for the event. |
| 297 |
if (w.WPBC_BFB_Exporter && typeof w.WPBC_BFB_Exporter.register === 'function') { |
| 298 |
register_text_booking_form_exporter(); |
| 299 |
} else { |
| 300 |
document.addEventListener('wpbc:bfb:exporter-ready', register_text_booking_form_exporter, { |
| 301 |
once: true |
| 302 |
}); |
| 303 |
} |
| 304 |
|
| 305 |
// ----------------------------------------------------------------------------------------------------------------- |
| 306 |
// Export for "Booking Data" (Content of booking fields data) |
| 307 |
// ----------------------------------------------------------------------------------------------------------------- |
| 308 |
/** |
| 309 |
* Booking Data exporter callback ("Content of booking fields data"). Default output: <b>Label</b>: <f>[field_name]</f><br> |
| 310 |
* |
| 311 |
* Registered per field type via: |
| 312 |
* WPBC_BFB_ContentExporter.register( 'text', callback ) |
| 313 |
* |
| 314 |
* Core call site (builder-exporter.js): |
| 315 |
* WPBC_BFB_ContentExporter.run_registered_exporter( field, emit, { cfg, core } ); |
| 316 |
* |
| 317 |
* @callback WPBC_BFB_ContentExporterCallback |
| 318 |
* @param {Object} field |
| 319 |
* Normalized field data (same shape as in the main exporter). |
| 320 |
* Important properties for content templates: |
| 321 |
* - field.type {string} Field type, e.g. "text". |
| 322 |
* - field.name {string} Field name used as placeholder token. |
| 323 |
* - field.label {string} Human-readable label (may be empty). |
| 324 |
* - field.options {Array} For option-based fields (select, checkbox, radio, etc.). |
| 325 |
* - Other pack-specific props if needed. |
| 326 |
* |
| 327 |
* @param {function(string):void} emit |
| 328 |
* Emits a raw HTML fragment into the "Content of booking fields data" template. |
| 329 |
* Core will wrap everything once into: |
| 330 |
* <div class="standard-content-form"> |
| 331 |
* ... emitted fragments ... |
| 332 |
* </div> |
| 333 |
* |
| 334 |
* Typical usage pattern: |
| 335 |
* emit('<b>Label</b>: <f>[field_name]</f><br>'); |
| 336 |
* |
| 337 |
* In most cases, packs call the shared helper: |
| 338 |
* WPBC_BFB_ContentExporter.emit_line_bold_field(emit, label, token, cfg); |
| 339 |
* |
| 340 |
* @param {Object} [extras] |
| 341 |
* Additional context passed from run_registered_exporter(). |
| 342 |
* |
| 343 |
* @param {Object} [extras.cfg] |
| 344 |
* Content exporter configuration: |
| 345 |
* - extras.cfg.addLabels {boolean} Default: true. |
| 346 |
* If false, helper may omit the bold label part. |
| 347 |
* - extras.cfg.sep {string} Label separator, default ": ". |
| 348 |
* Example: "<b>Label</b>: " vs "<b>Label</b> – ". |
| 349 |
* - extras.cfg.newline {string} Newline separator when joining lines (usually "\n"). |
| 350 |
* |
| 351 |
* @param {Object} [extras.core] |
| 352 |
* Reference to WPBC_BFB_Core (same as in main exporter). |
| 353 |
* Usually not needed here, because: |
| 354 |
* - Sanitization and consistent rendering are already done via |
| 355 |
* WPBC_BFB_ContentExporter.emit_line_bold_field( ... ). |
| 356 |
*/ |
| 357 |
function register_text_booking_data_exporter() { |
| 358 |
const C = w.WPBC_BFB_ContentExporter; |
| 359 |
if (!C || typeof C.register !== 'function') { |
| 360 |
return; |
| 361 |
} |
| 362 |
if (typeof C.has_exporter === 'function' && C.has_exporter('text')) { |
| 363 |
return; |
| 364 |
} |
| 365 |
C.register('text', function (field, emit, extras) { |
| 366 |
extras = extras || {}; |
| 367 |
const cfg = extras.cfg || {}; |
| 368 |
const Exp = w.WPBC_BFB_Exporter; |
| 369 |
if (!Exp || typeof Exp.compute_name !== 'function') { |
| 370 |
return; |
| 371 |
} |
| 372 |
const name = Exp.compute_name('text', field); |
| 373 |
if (!name) { |
| 374 |
return; |
| 375 |
} |
| 376 |
const label = typeof field.label === 'string' && field.label.trim() ? field.label.trim() : name; |
| 377 |
|
| 378 |
// Shared formatter keeps all packs consistent:. |
| 379 |
C.emit_line_bold_field(emit, label, name, cfg); |
| 380 |
}); |
| 381 |
} |
| 382 |
if (w.WPBC_BFB_ContentExporter && typeof w.WPBC_BFB_ContentExporter.register === 'function') { |
| 383 |
register_text_booking_data_exporter(); |
| 384 |
} else { |
| 385 |
document.addEventListener('wpbc:bfb:content-exporter-ready', register_text_booking_data_exporter, { |
| 386 |
once: true |
| 387 |
}); |
| 388 |
} |
| 389 |
})(window); |
| 390 |
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvZmllbGQtcGFja3MvdGV4dC9fb3V0L2ZpZWxkLXRleHQuanMiLCJuYW1lcyI6WyJ3IiwiQ29yZSIsIldQQkNfQkZCX0NvcmUiLCJyZWdpc3RyeSIsIldQQkNfQkZCX0ZpZWxkX1JlbmRlcmVyX1JlZ2lzdHJ5IiwiQmFzZSIsIldQQkNfQkZCX0ZpZWxkX0Jhc2UiLCJyZWdpc3RlciIsIl93cGJjIiwiZGV2IiwiZXJyb3IiLCJXUEJDX0JGQl9GaWVsZF9UZXh0IiwiZ2V0X2RlZmF1bHRzIiwidHlwZSIsImxhYmVsIiwibmFtZSIsImh0bWxfaWQiLCJwbGFjZWhvbGRlciIsInJlcXVpcmVkIiwibWlubGVuZ3RoIiwibWF4bGVuZ3RoIiwicGF0dGVybiIsImNzc2NsYXNzIiwiaGVscCIsImRlZmF1bHRfdmFsdWUiLCJyZW5kZXIiLCJlbCIsImRhdGEiLCJjdHgiLCJkIiwibm9ybWFsaXplX2RhdGEiLCJlaCIsInYiLCJXUEJDX0JGQl9TYW5pdGl6ZSIsImVzY2FwZV9odG1sIiwic2lkIiwic2FuaXRpemVfaHRtbF9pZCIsInNuYW1lIiwic2FuaXRpemVfaHRtbF9uYW1lIiwic2NsYXNzIiwic2FuaXRpemVfY3NzX2NsYXNzbGlzdCIsInRydXRoeSIsImlzX3RydXRoeSIsIlN0cmluZyIsIm5hbWVfdmFsIiwiaWQiLCJjc3NOZXh0IiwiZGF0YXNldCIsImlzX3JlcXVpcmVkIiwiaGFzX21pbmxlbmd0aCIsIk51bWJlciIsImlzRmluaXRlIiwiaGFzX21heGxlbmd0aCIsImhhc19wYXR0ZXJuIiwibWlubGVuZ3RoX251bSIsIm1heGxlbmd0aF9udW0iLCJpZF9hdHRyIiwibmFtZV9hdHRyIiwiY2xzX2F0dHIiLCJwaF9hdHRyIiwicmVxX2F0dHIiLCJtaW5sZW5ndGhfYXR0ciIsIm1heGxlbmd0aF9hdHRyIiwicGF0dGVybl9hdHRyIiwidmFsdWVfYXR0ciIsImxhYmVsX2h0bWwiLCJoZWxwX2h0bWwiLCJpbm5lckhUTUwiLCJVSSIsIldQQkNfQkZCX092ZXJsYXkiLCJlbnN1cmUiLCJidWlsZGVyIiwib25fZmllbGRfZHJvcCIsImUiLCJyZWdpc3Rlcl90ZXh0X2Jvb2tpbmdfZm9ybV9leHBvcnRlciIsIkV4cCIsIldQQkNfQkZCX0V4cG9ydGVyIiwiaGFzX2V4cG9ydGVyIiwiUyIsImZpZWxkIiwiZW1pdCIsImV4dHJhcyIsImNmZyIsImFkZExhYmVscyIsImlzX3JlcSIsInJlcV9tYXJrIiwiY29tcHV0ZV9uYW1lIiwiaWRfb3B0IiwiaWRfb3B0aW9uIiwiY2xzX29wdHMiLCJjbGFzc19vcHRpb25zIiwic2l6ZV9tYXgiLCJzaXplX21heF90b2tlbiIsImRlZl92YWx1ZSIsImRlZmF1bHRfdGV4dF9zdWZmaXgiLCJib2R5IiwidG9TdHJpbmciLCJ0cmltIiwiZG9jdW1lbnQiLCJhZGRFdmVudExpc3RlbmVyIiwib25jZSIsInJlZ2lzdGVyX3RleHRfYm9va2luZ19kYXRhX2V4cG9ydGVyIiwiQyIsIldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlciIsImVtaXRfbGluZV9ib2xkX2ZpZWxkIiwid2luZG93Il0sInNvdXJjZXMiOlsiaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvZmllbGQtcGFja3MvdGV4dC9fc3JjL2ZpZWxkLXRleHQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIFdQQkMgQkZCOiBGaWVsZCBSZW5kZXJlciBmb3IgXCJ0ZXh0XCIgKFNjaGVtYS1kcml2ZW4gUmVmZXJlbmNlLCB0ZW1wbGF0ZS1saXRlcmFsIHJlbmRlcilcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKiBQdXJwb3NlOlxyXG4gKiAtIFVzZXMgdGVtcGxhdGUgbGl0ZXJhbHMgKG5vIHdwLnRlbXBsYXRlKVxyXG4gKiAtIEluc3BlY3RvciBpcyByZW5kZXJlZCBieSBGYWN0b3J5IChQSFAgc2NoZW1hKVxyXG4gKiAtIFVzZXMgV1BCQ19CRkJfU2FuaXRpemUgKGZyb20gY29yZSkgd2l0aCBtZXRob2QgbmFtZXMgYXMgaW4gYmZiLWNvcmUuanNcclxuICpcclxuICogQ29udHJhY3RzOlxyXG4gKiAtIFJlZ2lzdHJ5OiAgV1BCQ19CRkJfRmllbGRfUmVuZGVyZXJfUmVnaXN0cnkucmVnaXN0ZXIoICd0ZXh0JywgQ2xhc3MgKVxyXG4gKiAtIENsYXNzIEFQSTogc3RhdGljIGdldF9kZWZhdWx0cygpLCBzdGF0aWMgcmVuZGVyKGVsLCBkYXRhLCBjdHgpLCBzdGF0aWMgb25fZmllbGRfZHJvcChkYXRhLCBlbCwgY3R4PykgW29wdGlvbmFsXVxyXG4gKlxyXG4gKiBOb3RlczpcclxuICogLSBLZWVwIGRlZmF1bHRzIGFsaWduZWQgd2l0aCBQSFAgc2NoZW1hLT5wcm9wcy0+ZGVmYXVsdC5cclxuICogLSBVc2UgT3ZlcmxheS5lbnN1cmUoLi4uKSBzbyBmaWVsZCBjb250cm9scyAoaGFuZGxlLCBzZXR0aW5ncywgZXRjLikgYXBwZWFyLlxyXG4gKlxyXG4gKiBGaWxlOiAgLi4vaW5jbHVkZXMvcGFnZS1mb3JtLWJ1aWxkZXIvZmllbGQtcGFja3MvdGV4dC9fb3V0L2ZpZWxkLXRleHQuanNcclxuICpcclxuICogQHNpbmNlICAgIDExLjAuMFxyXG4gKiBAbW9kaWZpZWQgIDIwMjUtMDktMDYgMTQ6MDhcclxuICogQHZlcnNpb24gIDEuMC4xXHJcbiAqXHJcbiAqL1xyXG4oZnVuY3Rpb24gKHcpIHtcclxuXHQndXNlIHN0cmljdCc7XHJcblxyXG5cdHZhciBDb3JlICAgICA9IHcuV1BCQ19CRkJfQ29yZSB8fCB7fTtcclxuXHR2YXIgcmVnaXN0cnkgPSBDb3JlLldQQkNfQkZCX0ZpZWxkX1JlbmRlcmVyX1JlZ2lzdHJ5O1xyXG5cdHZhciBCYXNlICAgICA9IENvcmUuV1BCQ19CRkJfRmllbGRfQmFzZTtcclxuXHJcblx0aWYgKCAhIHJlZ2lzdHJ5IHx8IHR5cGVvZiByZWdpc3RyeS5yZWdpc3RlciAhPT0gJ2Z1bmN0aW9uJyB8fCAhIEJhc2UgKSB7XHJcblx0XHRfd3BiYz8uZGV2Py5lcnJvcj8uKCAnV1BCQ19CRkJfRmllbGRfVGV4dCcsICdDb3JlIHJlZ2lzdHJ5L2Jhc2UgbWlzc2luZycgKTtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdGNsYXNzIFdQQkNfQkZCX0ZpZWxkX1RleHQgZXh0ZW5kcyBCYXNlIHtcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJldHVybiBkZWZhdWx0IHByb3BzIGZvciBcInRleHRcIiBmaWVsZC5cclxuXHRcdCAqIE11c3Qgc3RheSBpbiBzeW5jIHdpdGggUEhQIHNjaGVtYSBkZWZhdWx0cy5cclxuXHRcdCAqXHJcblx0XHQgKiBAcmV0dXJucyB7T2JqZWN0fVxyXG5cdFx0ICovXHJcblx0XHRzdGF0aWMgZ2V0X2RlZmF1bHRzKCkge1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdHR5cGUgICAgICAgICA6ICd0ZXh0JyxcclxuXHRcdFx0XHRsYWJlbCAgICAgICAgOiAnVGV4dCcsXHJcblx0XHRcdFx0bmFtZSAgICAgICAgIDogJycsXHJcblx0XHRcdFx0aHRtbF9pZCAgICAgIDogJycsXHJcblx0XHRcdFx0cGxhY2Vob2xkZXIgIDogJycsXHJcblx0XHRcdFx0cmVxdWlyZWQgICAgIDogZmFsc2UsXHJcblx0XHRcdFx0bWlubGVuZ3RoICAgIDogbnVsbCxcclxuXHRcdFx0XHRtYXhsZW5ndGggICAgOiBudWxsLFxyXG5cdFx0XHRcdHBhdHRlcm4gICAgICA6ICcnLFxyXG5cdFx0XHRcdGNzc2NsYXNzICAgICA6ICcnLFxyXG5cdFx0XHRcdGhlbHAgICAgICAgICA6ICcnLFxyXG5cdFx0XHRcdGRlZmF1bHRfdmFsdWU6ICcnXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBSZW5kZXIgdGhlIHByZXZpZXcgbWFya3VwIGludG8gdGhlIGZpZWxkIGVsZW1lbnQuXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWwgICBGaWVsZCByb290IGVsZW1lbnQgaW5zaWRlIHRoZSBjYW52YXMuXHJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gICAgICBkICAgIEZpZWxkIHByb3BzIChhbHJlYWR5IG5vcm1hbGl6ZWQgYnkgc2NoZW1hKS5cclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSAgICAgIGN0eCAgQ29udGV4dDogeyBidWlsZGVyLCBzYW5pdCwgLi4uIH1cclxuXHRcdCAqL1xyXG5cdFx0c3RhdGljIHJlbmRlcihlbCwgZGF0YSwgY3R4KSB7XHJcblxyXG5cdFx0XHRpZiAoICEgZWwgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBOb3JtYWxpemUgYWdhaW5zdCBkZWZhdWx0cyBmaXJzdC5cclxuXHRcdFx0Y29uc3QgZCA9IHRoaXMubm9ybWFsaXplX2RhdGEoIGRhdGEgKTtcclxuXHJcblx0XHRcdC8vIC0tLS0tIENvcmUgc2FuaXRpemUgaGVscGVycyAoc3RhdGljKSAtLS0tLVxyXG5cdFx0XHRjb25zdCBlaCAgICAgPSAodikgPT4gQ29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfaHRtbCggdiApO1xyXG5cdFx0XHRjb25zdCBzaWQgICAgPSAodikgPT4gQ29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5zYW5pdGl6ZV9odG1sX2lkKCB2ICk7XHJcblx0XHRcdGNvbnN0IHNuYW1lICA9ICh2KSA9PiBDb3JlLldQQkNfQkZCX1Nhbml0aXplLnNhbml0aXplX2h0bWxfbmFtZSggdiApO1xyXG5cdFx0XHRjb25zdCBzY2xhc3MgPSAodikgPT4gQ29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5zYW5pdGl6ZV9jc3NfY2xhc3NsaXN0KCB2ICk7XHJcblx0XHRcdGNvbnN0IHRydXRoeSA9ICh2KSA9PiBDb3JlLldQQkNfQkZCX1Nhbml0aXplLmlzX3RydXRoeSggdiApO1xyXG5cclxuXHRcdFx0Ly8gU2FuaXRpemUgcHVibGljIGlkL25hbWUgZm9yIHRoZSBjb250cm9sIGl0c2VsZi5cclxuXHRcdFx0Y29uc3QgaHRtbF9pZCAgPSBkLmh0bWxfaWQgPyBzaWQoIFN0cmluZyggZC5odG1sX2lkICkgKSA6ICcnO1xyXG5cdFx0XHRjb25zdCBuYW1lX3ZhbCA9IHNuYW1lKCBTdHJpbmcoIGQubmFtZSB8fCBkLmlkIHx8ICdmaWVsZCcgKSApO1xyXG5cdFx0XHRjb25zdCBjc3NOZXh0ICA9IHNjbGFzcyggU3RyaW5nKCBkLmNzc2NsYXNzIHx8ICcnICkgKTtcclxuXHJcblx0XHRcdC8vIEtlZXAgd3JhcHBlciBjbGFzc2VzIGluIHN5bmMgd2l0aCBkYXRhc2V0LmNzc2NsYXNzIE9OTFkgKGRvbuKAmXQgdG91Y2ggY29yZSBjbGFzc2VzKS5cclxuXHRcdFx0Ly8gaWYgKCAnY3NzY2xhc3MnIGluIGQgKSB7XHJcblx0XHRcdC8vIFx0Y29uc3QgcHJldiA9IGVsLmRhdGFzZXQuY3NzY2xhc3MgfHwgJyc7XHJcblx0XHRcdC8vIFx0aWYgKCBwcmV2ICE9PSBjc3NOZXh0ICkge1xyXG5cdFx0XHQvLyBcdFx0cHJldi5zcGxpdCggL1xccysvICkuZmlsdGVyKCBCb29sZWFuICkuZm9yRWFjaCggKGMpID0+IGVsLmNsYXNzTGlzdC5yZW1vdmUoIGMgKSApO1xyXG5cdFx0XHQvLyBcdFx0Y3NzTmV4dC5zcGxpdCggL1xccysvICkuZmlsdGVyKCBCb29sZWFuICkuZm9yRWFjaCggKGMpID0+IGVsLmNsYXNzTGlzdC5hZGQoIGMgKSApO1xyXG5cdFx0XHQvLyBcdFx0ZWwuZGF0YXNldC5jc3NjbGFzcyA9IGNzc05leHQ7XHJcblx0XHRcdC8vIFx0fVxyXG5cdFx0XHQvLyB9XHJcblx0XHRcdC8vIE5FVzogc3RvcmUgb25seTsgZG8gTk9UIG1vZGlmeSB3cmFwcGVyIGNsYXNzZXMuXHJcblx0XHRcdGlmICggJ2Nzc2NsYXNzJyBpbiBkICkge1xyXG5cdFx0XHRcdGlmICggZWwuZGF0YXNldC5jc3NjbGFzcyAhPT0gY3NzTmV4dCApIHtcclxuXHRcdFx0XHRcdGVsLmRhdGFzZXQuY3NzY2xhc3MgPSBjc3NOZXh0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBLZWVwIHdyYXBwZXIncyBzdG9yZWQgaHRtbF9pZCAoZGF0YXNldCkgdXBkYXRlZC5cclxuXHRcdFx0aWYgKCAnaHRtbF9pZCcgaW4gZCApIHtcclxuXHRcdFx0XHRpZiAoIGVsLmRhdGFzZXQuaHRtbF9pZCAhPT0gaHRtbF9pZCApIHtcclxuXHRcdFx0XHRcdGVsLmRhdGFzZXQuaHRtbF9pZCA9IGh0bWxfaWQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBGbGFncyAvIG51bWVyaWMgY29uc3RyYWludHMuXHJcblx0XHRcdGNvbnN0IGlzX3JlcXVpcmVkICAgPSB0cnV0aHkoIGQucmVxdWlyZWQgKTtcclxuXHRcdFx0Y29uc3QgaGFzX21pbmxlbmd0aCA9IChkLm1pbmxlbmd0aCAhPSBudWxsICYmIGQubWlubGVuZ3RoICE9PSAnJyAmJiBOdW1iZXIuaXNGaW5pdGUoICtkLm1pbmxlbmd0aCApKTtcclxuXHRcdFx0Y29uc3QgaGFzX21heGxlbmd0aCA9IChkLm1heGxlbmd0aCAhPSBudWxsICYmIGQubWF4bGVuZ3RoICE9PSAnJyAmJiBOdW1iZXIuaXNGaW5pdGUoICtkLm1heGxlbmd0aCApKTtcclxuXHRcdFx0Y29uc3QgaGFzX3BhdHRlcm4gICA9ICEhZC5wYXR0ZXJuO1xyXG5cclxuXHRcdFx0Y29uc3QgbWlubGVuZ3RoX251bSA9IGhhc19taW5sZW5ndGggPyBOdW1iZXIoIGQubWlubGVuZ3RoICkgOiBudWxsO1xyXG5cdFx0XHRjb25zdCBtYXhsZW5ndGhfbnVtID0gaGFzX21heGxlbmd0aCA/IE51bWJlciggZC5tYXhsZW5ndGggKSA6IG51bGw7XHJcblxyXG5cdFx0XHQvLyBBdHRyaWJ1dGUgZnJhZ21lbnRzICh1c2luZyBlc2NhcGVfaHRtbCBmb3Igc2FmZSBpbm5lckhUTUwgYXR0cmlidXRlIGNvbnRleHQpLlxyXG5cdFx0XHRjb25zdCBpZF9hdHRyICAgICAgICA9IGh0bWxfaWQgPyBgIGlkPVwiJHtlaCggaHRtbF9pZCApfVwiYCA6ICcnO1xyXG5cdFx0XHRjb25zdCBuYW1lX2F0dHIgICAgICA9IGAgbmFtZT1cIiR7ZWgoIG5hbWVfdmFsICl9XCJgO1xyXG5cdFx0XHQvLyBjb25zdCBjbHNfYXR0ciAgICAgICA9IGAgY2xhc3M9XCJ3cGJjX2JmYl9fcHJldmlldy1pbnB1dCAke2VoKCBjc3NOZXh0ICl9XCJgO1xyXG5cdFx0XHRjb25zdCBjbHNfYXR0ciA9IGAgY2xhc3M9XCJ3cGJjX2JmYl9fcHJldmlldy1pbnB1dCAke2Nzc05leHQgPyAnICcgKyBlaChjc3NOZXh0KSA6ICcnfVwiYDtcclxuXHRcdFx0Y29uc3QgcGhfYXR0ciAgICAgICAgPSBkLnBsYWNlaG9sZGVyID8gYCBwbGFjZWhvbGRlcj1cIiR7ZWgoIGQucGxhY2Vob2xkZXIgKX1cImAgOiAnJztcclxuXHRcdFx0Y29uc3QgcmVxX2F0dHIgICAgICAgPSBpc19yZXF1aXJlZCA/ICcgcmVxdWlyZWQgYXJpYS1yZXF1aXJlZD1cInRydWVcIicgOiAnJztcclxuXHRcdFx0Y29uc3QgbWlubGVuZ3RoX2F0dHIgPSBoYXNfbWlubGVuZ3RoID8gYCBtaW5sZW5ndGg9XCIke21pbmxlbmd0aF9udW19XCJgIDogJyc7XHJcblx0XHRcdGNvbnN0IG1heGxlbmd0aF9hdHRyID0gaGFzX21heGxlbmd0aCA/IGAgbWF4bGVuZ3RoPVwiJHttYXhsZW5ndGhfbnVtfVwiYCA6ICcnO1xyXG5cdFx0XHRjb25zdCBwYXR0ZXJuX2F0dHIgICA9IGhhc19wYXR0ZXJuID8gYCBwYXR0ZXJuPVwiJHtlaCggZC5wYXR0ZXJuICl9XCJgIDogJyc7XHJcblx0XHRcdGNvbnN0IHZhbHVlX2F0dHIgPSAoZC5kZWZhdWx0X3ZhbHVlICE9IG51bGwgJiYgZC5kZWZhdWx0X3ZhbHVlICE9PSAnJylcclxuXHRcdFx0XHQ/IGAgdmFsdWU9XCIke2VoKCBTdHJpbmcoIGQuZGVmYXVsdF92YWx1ZSApICl9XCJgXHJcblx0XHRcdFx0OiAnJztcclxuXHRcdFx0Ly8gT3B0aW9uYWwgZnJhZ21lbnRzLlxyXG5cdFx0XHRjb25zdCBsYWJlbF9odG1sID0gKGQubGFiZWwgIT0gbnVsbCAmJiBkLmxhYmVsICE9PSAnJylcclxuXHRcdFx0XHQ/IGA8bGFiZWwgY2xhc3M9XCJ3cGJjX2JmYl9fZmllbGQtbGFiZWxcIiR7aHRtbF9pZCA/IGAgZm9yPVwiJHtlaCggaHRtbF9pZCApfVwiYCA6ICcnfT4ke2VoKCBkLmxhYmVsICl9JHtpc19yZXF1aXJlZCA/ICc8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4qPC9zcGFuPicgOiAnJ308L2xhYmVsPmBcclxuXHRcdFx0XHQ6ICcnO1xyXG5cclxuXHRcdFx0Y29uc3QgaGVscF9odG1sID0gZC5oZWxwID8gYDxkaXYgY2xhc3M9XCJ3cGJjX2JmYl9faGVscFwiPiR7ZWgoIGQuaGVscCApfTwvZGl2PmAgOiAnJztcclxuXHJcblx0XHRcdC8vIFJlbmRlciBwcmV2aWV3IEhUTUwuXHJcblx0XHRcdGVsLmlubmVySFRNTCA9IGBcclxuXHRcdFx0XHQ8c3BhbiBjbGFzcz1cIndwYmNfYmZiX19ub2FjdGlvbiB3cGJjX2JmYl9fbm8tZHJhZy16b25lXCIgaW5lcnQ9XCJcIj5cclxuXHRcdFx0XHRcdCR7bGFiZWxfaHRtbH1cclxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwid3BiY193cmFwX3RleHQgd3BkZXYtZm9ybS1jb250cm9sLXdyYXBcIj5cclxuXHRcdFx0XHRcdFx0PGlucHV0IHR5cGU9XCJ0ZXh0XCIke2Nsc19hdHRyfSR7cGhfYXR0cn0ke25hbWVfYXR0cn0gYXV0b2NvbXBsZXRlPVwib2ZmXCIgdGFiaW5kZXg9XCItMVwiIGFyaWEtZGlzYWJsZWQ9XCJ0cnVlXCIke2lkX2F0dHJ9JHt2YWx1ZV9hdHRyfSR7cmVxX2F0dHJ9JHttaW5sZW5ndGhfYXR0cn0ke21heGxlbmd0aF9hdHRyfSR7cGF0dGVybl9hdHRyfSAvPlxyXG5cclxuXHRcdFx0XHRcdDwvc3Bhbj5cclxuXHRcdFx0XHRcdCR7aGVscF9odG1sfVxyXG5cdFx0XHRcdDwvc3Bhbj5cclxuXHRcdFx0YDtcclxuXHJcblx0XHRcdC8vIE92ZXJsYXkgKGhhbmRsZXMvdG9vbGJhcnMpLlxyXG5cdFx0XHRDb3JlLlVJPy5XUEJDX0JGQl9PdmVybGF5Py5lbnN1cmU/LiggY3R4Py5idWlsZGVyLCBlbCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogT3B0aW9uYWwgaG9vayBleGVjdXRlZCBhZnRlciBmaWVsZCBpcyBkcm9wcGVkIGZyb20gdGhlIHBhbGV0dGUuXHJcblx0XHQgKiBFeGFtcGxlIHJlY2lwZSBwbGFjZWhvbGRlciBmb3IgZnV0dXJlOiAgIHRyeSB7IGlmICggIWRhdGEubmFtZSApIHsgZGF0YS5uYW1lID0gY29yZS5XUEJDX0JGQl9JZFNlcnZpY2U/Lm5leHRfbmFtZT8uKCAndGV4dCcgKSB8fCAndGV4dCc7IH0gIH0gY2F0Y2ggKCBlICkgeyB9XHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9ICAgICAgZGF0YSAgUGFsZXR0ZS9maWVsZCBkYXRhLlxyXG5cdFx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWwgICAgTmV3bHkgY3JlYXRlZCBmaWVsZCBlbGVtZW50LlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9ICAgICAgY3R4ICAgQ29udGV4dCB7IGJ1aWxkZXIsIHNhbml0LCBjb250ZXh0OiAnZHJvcCcgfCAnbG9hZCcgfCAncHJldmlldycgfVxyXG5cdFx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0XHQgKi9cclxuXHRcdHN0YXRpYyBvbl9maWVsZF9kcm9wKGRhdGEsIGVsLCBjdHgpIHtcclxuXHRcdFx0c3VwZXIub25fZmllbGRfZHJvcD8uKCBkYXRhLCBlbCwgY3R4ICk7ICAvLyBSZXF1aXJlZCBmb3IgY29ycmVjdGx5IGF1dG8tbmFtZXMgZnJvbSAgTGFiZWxzICFcclxuXHRcdFx0Ly8gKHlvdXIgZXh0cmEgcGFjay1zcGVjaWZpYyBsb2dpYyBpZiBldmVyIG5lZWRlZClcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHRyeSB7XHJcblx0XHRyZWdpc3RyeS5yZWdpc3RlciggJ3RleHQnLCBXUEJDX0JGQl9GaWVsZF9UZXh0ICk7XHJcblx0fSBjYXRjaCAoIGUgKSB7XHJcblx0XHRfd3BiYz8uZGV2Py5lcnJvcj8uKCAnV1BCQ19CRkJfRmllbGRfVGV4dC5yZWdpc3RlcicsIGUgKTtcclxuXHR9XHJcblxyXG5cdC8vIE9wdGlvbmFsIGdsb2JhbCBhbGlhcyAoZGVidWdnaW5nIC8gZGV2IHRvb2xzKS5cclxuXHR3LldQQkNfQkZCX0ZpZWxkX1RleHQgPSB3LldQQkNfQkZCX0ZpZWxkX1RleHQgfHwgV1BCQ19CRkJfRmllbGRfVGV4dDtcclxuXHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gRXhwb3J0IGZvciBcIkJvb2tpbmcgRm9ybVwiIChBZHZhbmNlZCBGb3JtIHNob3J0Y29kZSlcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8qKlxyXG5cdCAqIEJvb2tpbmcgRm9ybSBleHBvcnRlciBjYWxsYmFjayAoQWR2YW5jZWQgRm9ybSBzaG9ydGNvZGUpLlxyXG5cdCAqXHJcblx0ICogVGhpcyBjYWxsYmFjayBpcyByZWdpc3RlcmVkIHBlciBmaWVsZCB0eXBlIHZpYTpcclxuXHQgKiAgIFdQQkNfQkZCX0V4cG9ydGVyLnJlZ2lzdGVyKCAndGV4dCcsIGNhbGxiYWNrIClcclxuXHQgKlxyXG5cdCAqIENvcmUgY2FsbCBzaXRlIChidWlsZGVyLWV4cG9ydGVyLmpzKTpcclxuXHQgKiAgIFdQQkNfQkZCX0V4cG9ydGVyLnJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyKCBmaWVsZCwgaW8sIGNmZywgb25jZSwgY3R4IClcclxuXHQgKiAgICAgLT4gY2FsbGJhY2soIGZpZWxkLCBlbWl0LCB7IGlvLCBjZmcsIG9uY2UsIGN0eCwgY29yZSB9ICk7XHJcblx0ICpcclxuXHQgKiBAY2FsbGJhY2sgV1BCQ19CRkJfRXhwb3J0ZXJDYWxsYmFja1xyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSAgZmllbGRcclxuXHQgKiAgIE5vcm1hbGl6ZWQgZmllbGQgZGF0YSBjb21pbmcgZnJvbSB0aGUgQnVpbGRlciBzdHJ1Y3R1cmUuXHJcblx0ICogICAtIGZpZWxkLnR5cGUgICAgICAgICAge3N0cmluZ30gICBGaWVsZCB0eXBlLCBlLmcuIFwidGV4dFwiLlxyXG5cdCAqICAgLSBmaWVsZC5uYW1lICAgICAgICAgIHtzdHJpbmd9ICAgTmFtZSBhcyBzdG9yZWQgb24gdGhlIGNhbnZhcyAoYWxyZWFkeSB2YWxpZGF0ZWQpLlxyXG5cdCAqICAgLSBmaWVsZC5pZCAvIGh0bWxfaWQgIHtzdHJpbmd9ICAgT3B0aW9uYWwgSFRNTCBpZCAvIHVzZXItdmlzaWJsZSBpZC5cclxuXHQgKiAgIC0gZmllbGQubGFiZWwgICAgICAgICB7c3RyaW5nfSAgIFZpc2libGUgbGFiZWwgaW4gdGhlIGZvcm0gKG1heSBiZSBlbXB0eSkuXHJcblx0ICogICAtIGZpZWxkLnBsYWNlaG9sZGVyICAge3N0cmluZ30gICBQbGFjZWhvbGRlciB0ZXh0IChtYXkgYmUgZW1wdHkpLlxyXG5cdCAqICAgLSBmaWVsZC5yZXF1aXJlZCAgICAgIHtib29sZWFufG51bWJlcnxzdHJpbmd9IFwidHJ1dGh5XCIgaWYgcmVxdWlyZWQuXHJcblx0ICogICAtIGZpZWxkLmNzc2NsYXNzICAgICAge3N0cmluZ30gICBFeHRyYSBDU1MgY2xhc3NlcyBlbnRlcmVkIGluIEluc3BlY3Rvci5cclxuXHQgKiAgIC0gZmllbGQuZGVmYXVsdF92YWx1ZSB7c3RyaW5nfSAgIERlZmF1bHQgdGV4dCB2YWx1ZS5cclxuXHQgKiAgIC0gZmllbGQub3B0aW9ucyAgICAgICB7QXJyYXl9ICAgIE9ubHkgZm9yIG9wdGlvbi1iYXNlZCBmaWVsZHMgKHNlbGVjdCwgY2hlY2tib3gsIGV0Yy4pLlxyXG5cdCAqICAgLSAuLi4gICAgICAgICAgICAgICAgIChBbnkgb3RoZXIgcGFjay1zcGVjaWZpYyBwcm9wcyBhcmUgYWxzbyBwcmVzZW50LilcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nKTp2b2lkfSBlbWl0XHJcblx0ICogICBFbWl0cyBvbmUgbGluZS9mcmFnbWVudCBpbnRvIHRoZSBleHBvcnQgYnVmZmVyLlxyXG5cdCAqICAgLSBFYWNoIGNhbGwgY29ycmVzcG9uZHMgdG8gb25lIGBwdXNoKClgIGluIHRoZSBjb3JlIGV4cG9ydGVyLlxyXG5cdCAqICAgLSBGb3IgbXVsdGktbGluZSBvdXRwdXQgKGUuZy4gbGFiZWwgKyBzaG9ydGNvZGUpLCBjYWxsIGBlbWl0KClgIG11bHRpcGxlIHRpbWVzOlxyXG5cdCAqICAgICAgIGVtaXQoJzxsPkxhYmVsPC9sPicpO1xyXG5cdCAqICAgICAgIGVtaXQoJzxicj5bdGV4dCogbmFtZSAuLi5dJyk7XHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge09iamVjdH0gW2V4dHJhc11cclxuXHQgKiAgIEV4dHJhIGNvbnRleHQgcGFzc2VkIGJ5IHRoZSBjb3JlIGV4cG9ydGVyLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMuaW9dXHJcblx0ICogICBMb3ctbGV2ZWwgd3JpdGVyIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgY29yZS5cclxuXHQgKiAgIE5vcm1hbGx5IHlvdSBkbyBOT1QgbmVlZCBpdCBpbiBwYWNrcyDigJQgcHJlZmVyIGBlbWl0KClgLlxyXG5cdCAqICAgLSBleHRyYXMuaW8ub3BlbihzdHIpICAgLT4gb3BlbiBhIG5lc3RlZCBibG9jayAoaW5jcmVtZW50cyBpbmRlbnRhdGlvbikuXHJcblx0ICogICAtIGV4dHJhcy5pby5jbG9zZShzdHIpICAtPiBjbG9zZSBhIGJsb2NrIChkZWNyZW1lbnRzIGluZGVudGF0aW9uKS5cclxuXHQgKiAgIC0gZXh0cmFzLmlvLnB1c2goc3RyKSAgIC0+IHB1c2ggcmF3IGxpbmUgKHVzZWQgYnkgYGVtaXQoKWApLlxyXG5cdCAqICAgLSBleHRyYXMuaW8uYmxhbmsoKSAgICAgLT4gcHVzaCBhbiBlbXB0eSBsaW5lLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMuY2ZnXVxyXG5cdCAqICAgRXhwb3J0IGNvbmZpZ3VyYXRpb24gKHNhbWUgb2JqZWN0IHBhc3NlZCB0byBXUEJDX0JGQl9FeHBvcnRlci5leHBvcnRfZm9ybSgpKS5cclxuXHQgKiAgIFVzZWZ1bCBmbGFncyBmb3IgZmllbGQgcGFja3M6XHJcblx0ICogICAtIGV4dHJhcy5jZmcuYWRkTGFiZWxzIHtib29sZWFufSAgRGVmYXVsdDogdHJ1ZS5cclxuXHQgKiAgICAgICBJZiBmYWxzZSwgcGFja3Mgc2hvdWxkIE5PVCBlbWl0IDxsPkxhYmVsPC9sPiBsaW5lcy5cclxuXHQgKiAgIC0gZXh0cmFzLmNmZy5uZXdsaW5lICAge3N0cmluZ30gICBOZXdsaW5lIHNlcGFyYXRvciAodXN1YWxseSBcIlxcblwiKS5cclxuXHQgKiAgIC0gZXh0cmFzLmNmZy5nYXBQZXJjZW50e251bWJlcn0gICBMYXlvdXQgZ2FwICh1c2VkIG9ubHkgYnkgc2VjdGlvbi9jb2x1bW4gbG9naWMpLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMub25jZV1cclxuXHQgKiAgIFNoYXJlZCBcIm9uY2UtcGVyLWZvcm1cIiBndWFyZHMgYWNyb3NzIGFsbCBmaWVsZHMuXHJcblx0ICogICBDb3VudGVycyBhcmUgaW5jcmVtZW50ZWQgYnkgc29tZSBmaWVsZCB0eXBlcyAoY2FwdGNoYSwgY291cG9uLCBldGMuKS5cclxuXHQgKiAgIFR5cGljYWwgc2hhcGU6XHJcblx0ICogICAtIGV4dHJhcy5vbmNlLmNhcHRjaGEgICAgICAgICAge251bWJlcn1cclxuXHQgKiAgIC0gZXh0cmFzLm9uY2UuY291bnRyeSAgICAgICAgICB7bnVtYmVyfVxyXG5cdCAqICAgLSBleHRyYXMub25jZS5jb3Vwb24gICAgICAgICAgIHtudW1iZXJ9XHJcblx0ICogICAtIGV4dHJhcy5vbmNlLmNvc3RfY29ycmVjdGlvbnMge251bWJlcn1cclxuXHQgKiAgIC0gZXh0cmFzLm9uY2Uuc3VibWl0ICAgICAgICAgICB7bnVtYmVyfVxyXG5cdCAqXHJcblx0ICogICBUZXh0IGZpZWxkIHVzdWFsbHkgZG9lcyBub3QgdG91Y2ggdGhpcyBvYmplY3QsIGJ1dCBvdGhlciBwYWNrcyBjYW4gdXNlIGl0XHJcblx0ICogICB0byBza2lwIGR1cGxpY2F0ZXMgKGUuZy4gb25seSB0aGUgZmlyc3QgW2NvdXBvbl0gcGVyIGZvcm0gaXMgZXhwb3J0ZWQpLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMuY3R4XVxyXG5cdCAqICAgU2hhcmVkIGV4cG9ydCBjb250ZXh0IGZvciB0aGUgZW50aXJlIGZvcm0uXHJcblx0ICogICBDdXJyZW50bHk6XHJcblx0ICogICAtIGV4dHJhcy5jdHgudXNlZElkcyB7U2V0PHN0cmluZz59XHJcblx0ICogICAgICAgU2V0IG9mIEhUTUwvc2hvcnRjb2RlIElEcyBhbHJlYWR5IHVzZWQgaW4gdGhpcyBleHBvcnQuXHJcblx0ICogICAgICAgSGVscGVycyBsaWtlIEV4cC5pZF9vcHRpb24oZmllbGQsIGN0eCkgdXNlIGl0IHRvIGVuc3VyZSB1bmlxdWVuZXNzLlxyXG5cdCAqXHJcblx0ICogICBQYWNrcyBub3JtYWxseSBqdXN0IHBhc3MgYGN0eGAgaW50byBoZWxwZXJzIChpZF9vcHRpb24sIGV0Yy4pIHdpdGhvdXRcclxuXHQgKiAgIG11dGF0aW5nIGl0IGRpcmVjdGx5LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMuY29yZV1cclxuXHQgKiAgIFJlZmVyZW5jZSB0byBXUEJDX0JGQl9Db3JlIHBhc3NlZCBmcm9tIGJ1aWxkZXItZXhwb3J0ZXIuanMuXHJcblx0ICogICBQcmltYXJpbHkgdXNlZCB0byBhY2Nlc3Mgc2FuaXRpemVyczpcclxuXHQgKiAgIC0gZXh0cmFzLmNvcmUuV1BCQ19CRkJfU2FuaXRpemUuZXNjYXBlX2h0bWwoLi4uKVxyXG5cdCAqICAgLSBleHRyYXMuY29yZS5XUEJDX0JGQl9TYW5pdGl6ZS5lc2NhcGVfZm9yX3Nob3J0Y29kZSguLi4pXHJcblx0ICogICAtIGV4dHJhcy5jb3JlLldQQkNfQkZCX1Nhbml0aXplLnNhbml0aXplX2h0bWxfbmFtZSguLi4pXHJcblx0ICogICAtIGV0Yy5cclxuXHQgKi9cclxuXHRmdW5jdGlvbiByZWdpc3Rlcl90ZXh0X2Jvb2tpbmdfZm9ybV9leHBvcnRlcigpIHtcclxuXHJcblx0XHRjb25zdCBFeHAgPSB3LldQQkNfQkZCX0V4cG9ydGVyO1xyXG5cdFx0aWYgKCAhIEV4cCB8fCB0eXBlb2YgRXhwLnJlZ2lzdGVyICE9PSAnZnVuY3Rpb24nICkgeyByZXR1cm47IH1cclxuXHRcdGlmICggdHlwZW9mIEV4cC5oYXNfZXhwb3J0ZXIgPT09ICdmdW5jdGlvbicgJiYgRXhwLmhhc19leHBvcnRlciggJ3RleHQnICkgKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdGNvbnN0IFMgPSBDb3JlLldQQkNfQkZCX1Nhbml0aXplO1xyXG5cclxuXHRcdEV4cC5yZWdpc3RlciggJ3RleHQnLCAoZmllbGQsIGVtaXQsIGV4dHJhcyA9IHt9KSA9PiB7XHJcblxyXG5cdFx0XHRjb25zdCBjZmcgICAgICAgPSBleHRyYXMuY2ZnIHx8IHt9O1xyXG5cdFx0XHRjb25zdCBjdHggICAgICAgPSBleHRyYXMuY3R4OyAgICAgICAgICAvLyBubyBsb2NhbCBmYWxsYmFjayBuZWVkZWQuXHJcblx0XHRcdGNvbnN0IGFkZExhYmVscyA9IGNmZy5hZGRMYWJlbHMgIT09IGZhbHNlO1xyXG5cclxuXHRcdFx0Ly8gUmVxdWlyZWQgbWFya2VyIGxvZ2ljIChzYW1lIGFzIGJlZm9yZSkuXHJcblx0XHRcdGNvbnN0IGlzX3JlcSAgID0gRXhwLmlzX3JlcXVpcmVkKCBmaWVsZCApO1xyXG5cdFx0XHRjb25zdCByZXFfbWFyayA9IGlzX3JlcSA/ICcqJyA6ICcnO1xyXG5cclxuXHRcdFx0Ly8gUmV1c2UgaGVscGVycyBmcm9tIFdQQkNfQkZCX0V4cG9ydGVyLlxyXG5cdFx0XHRjb25zdCBuYW1lICAgICAgPSBFeHAuY29tcHV0ZV9uYW1lKCAndGV4dCcsIGZpZWxkICk7XHJcblx0XHRcdGNvbnN0IGlkX29wdCAgICA9IEV4cC5pZF9vcHRpb24oIGZpZWxkLCBjdHggKTtcclxuXHRcdFx0Y29uc3QgY2xzX29wdHMgID0gRXhwLmNsYXNzX29wdGlvbnMoIGZpZWxkICk7XHJcblx0XHRcdGNvbnN0IHBoX2F0dHIgICA9IEV4cC5waF9hdHRyKCBmaWVsZC5wbGFjZWhvbGRlciApO1xyXG5cdFx0XHRjb25zdCBzaXplX21heCAgPSBFeHAuc2l6ZV9tYXhfdG9rZW4oIGZpZWxkICk7XHJcblx0XHRcdGNvbnN0IGRlZl92YWx1ZSA9IEV4cC5kZWZhdWx0X3RleHRfc3VmZml4KCBmaWVsZCApO1xyXG5cclxuXHRcdFx0Ly8gQnVpbGQgYm9keSBzaG9ydGNvZGUuXHJcblx0XHRcdGNvbnN0IGJvZHkgPSBgW3RleHQke3JlcV9tYXJrfSAke25hbWV9JHtzaXplX21heH0ke2lkX29wdH0ke2Nsc19vcHRzfSR7cGhfYXR0cn0ke2RlZl92YWx1ZX1dYDtcclxuXHJcblx0XHRcdC8vIExhYmVsIGJlaGF2aW9yIGlkZW50aWNhbCB0byBsZWdhY3kgZW1pdF9sYWJlbF90aGVuKCkuXHJcblx0XHRcdGNvbnN0IGxhYmVsID0gKGZpZWxkLmxhYmVsID8/ICcnKS50b1N0cmluZygpLnRyaW0oKTtcclxuXHRcdFx0aWYgKCBsYWJlbCAmJiBhZGRMYWJlbHMgKSB7XHJcblx0XHRcdFx0ZW1pdCggYDxsPiR7Uy5lc2NhcGVfaHRtbCggbGFiZWwgKX0ke3JlcV9tYXJrfTwvbD5gICk7XHJcblx0XHRcdFx0ZW1pdCggYDxicj4ke2JvZHl9YCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGVtaXQoIGJvZHkgKTtcclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBIZWxwIHRleHQgaXMgYXBwZW5kZWQgY2VudHJhbGx5IGJ5IFdQQkNfQkZCX0V4cG9ydGVyLnJlbmRlcl9maWVsZF9ub2RlKCkuXHJcblx0XHR9ICk7XHJcblx0fVxyXG5cclxuXHQvLyBUcnkgaW1tZWRpYXRlIHJlZ2lzdHJhdGlvbjsgaWYgY29yZSBpc27igJl0IHJlYWR5LCB3YWl0IGZvciB0aGUgZXZlbnQuXHJcblx0aWYgKCB3LldQQkNfQkZCX0V4cG9ydGVyICYmIHR5cGVvZiB3LldQQkNfQkZCX0V4cG9ydGVyLnJlZ2lzdGVyID09PSAnZnVuY3Rpb24nICkge1xyXG5cdFx0cmVnaXN0ZXJfdGV4dF9ib29raW5nX2Zvcm1fZXhwb3J0ZXIoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggJ3dwYmM6YmZiOmV4cG9ydGVyLXJlYWR5JywgcmVnaXN0ZXJfdGV4dF9ib29raW5nX2Zvcm1fZXhwb3J0ZXIsIHsgb25jZTogdHJ1ZSB9ICk7XHJcblx0fVxyXG5cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBFeHBvcnQgZm9yIFwiQm9va2luZyBEYXRhXCIgKENvbnRlbnQgb2YgYm9va2luZyBmaWVsZHMgZGF0YSlcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8qKlxyXG5cdCAqIEJvb2tpbmcgRGF0YSBleHBvcnRlciBjYWxsYmFjayAoXCJDb250ZW50IG9mIGJvb2tpbmcgZmllbGRzIGRhdGFcIikuICBEZWZhdWx0IG91dHB1dDogPGI+TGFiZWw8L2I+OiA8Zj5bZmllbGRfbmFtZV08L2Y+PGJyPlxyXG5cdCAqXHJcblx0ICogUmVnaXN0ZXJlZCBwZXIgZmllbGQgdHlwZSB2aWE6XHJcblx0ICogICBXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIucmVnaXN0ZXIoICd0ZXh0JywgY2FsbGJhY2sgKVxyXG5cdCAqXHJcblx0ICogQ29yZSBjYWxsIHNpdGUgKGJ1aWxkZXItZXhwb3J0ZXIuanMpOlxyXG5cdCAqICAgV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLnJ1bl9yZWdpc3RlcmVkX2V4cG9ydGVyKCBmaWVsZCwgZW1pdCwgeyBjZmcsIGNvcmUgfSApO1xyXG5cdCAqXHJcblx0ICogQGNhbGxiYWNrIFdQQkNfQkZCX0NvbnRlbnRFeHBvcnRlckNhbGxiYWNrXHJcblx0ICogQHBhcmFtIHtPYmplY3R9ICBmaWVsZFxyXG5cdCAqICAgTm9ybWFsaXplZCBmaWVsZCBkYXRhIChzYW1lIHNoYXBlIGFzIGluIHRoZSBtYWluIGV4cG9ydGVyKS5cclxuXHQgKiAgIEltcG9ydGFudCBwcm9wZXJ0aWVzIGZvciBjb250ZW50IHRlbXBsYXRlczpcclxuXHQgKiAgIC0gZmllbGQudHlwZSAgICAgIHtzdHJpbmd9ICBGaWVsZCB0eXBlLCBlLmcuIFwidGV4dFwiLlxyXG5cdCAqICAgLSBmaWVsZC5uYW1lICAgICAge3N0cmluZ30gIEZpZWxkIG5hbWUgdXNlZCBhcyBwbGFjZWhvbGRlciB0b2tlbi5cclxuXHQgKiAgIC0gZmllbGQubGFiZWwgICAgIHtzdHJpbmd9ICBIdW1hbi1yZWFkYWJsZSBsYWJlbCAobWF5IGJlIGVtcHR5KS5cclxuXHQgKiAgIC0gZmllbGQub3B0aW9ucyAgIHtBcnJheX0gICBGb3Igb3B0aW9uLWJhc2VkIGZpZWxkcyAoc2VsZWN0LCBjaGVja2JveCwgcmFkaW8sIGV0Yy4pLlxyXG5cdCAqICAgLSBPdGhlciBwYWNrLXNwZWNpZmljIHByb3BzIGlmIG5lZWRlZC5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nKTp2b2lkfSBlbWl0XHJcblx0ICogICBFbWl0cyBhIHJhdyBIVE1MIGZyYWdtZW50IGludG8gdGhlIFwiQ29udGVudCBvZiBib29raW5nIGZpZWxkcyBkYXRhXCIgdGVtcGxhdGUuXHJcblx0ICogICBDb3JlIHdpbGwgd3JhcCBldmVyeXRoaW5nIG9uY2UgaW50bzpcclxuXHQgKiAgICAgPGRpdiBjbGFzcz1cInN0YW5kYXJkLWNvbnRlbnQtZm9ybVwiPlxyXG5cdCAqICAgICAgIC4uLiBlbWl0dGVkIGZyYWdtZW50cyAuLi5cclxuXHQgKiAgICAgPC9kaXY+XHJcblx0ICpcclxuXHQgKiAgIFR5cGljYWwgdXNhZ2UgcGF0dGVybjpcclxuXHQgKiAgICAgZW1pdCgnPGI+TGFiZWw8L2I+OiA8Zj5bZmllbGRfbmFtZV08L2Y+PGJyPicpO1xyXG5cdCAqXHJcblx0ICogICBJbiBtb3N0IGNhc2VzLCBwYWNrcyBjYWxsIHRoZSBzaGFyZWQgaGVscGVyOlxyXG5cdCAqICAgICBXUEJDX0JGQl9Db250ZW50RXhwb3J0ZXIuZW1pdF9saW5lX2JvbGRfZmllbGQoZW1pdCwgbGFiZWwsIHRva2VuLCBjZmcpO1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXNdXHJcblx0ICogICBBZGRpdGlvbmFsIGNvbnRleHQgcGFzc2VkIGZyb20gcnVuX3JlZ2lzdGVyZWRfZXhwb3J0ZXIoKS5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbZXh0cmFzLmNmZ11cclxuXHQgKiAgIENvbnRlbnQgZXhwb3J0ZXIgY29uZmlndXJhdGlvbjpcclxuXHQgKiAgIC0gZXh0cmFzLmNmZy5hZGRMYWJlbHMge2Jvb2xlYW59IERlZmF1bHQ6IHRydWUuXHJcblx0ICogICAgICAgSWYgZmFsc2UsIGhlbHBlciBtYXkgb21pdCB0aGUgYm9sZCBsYWJlbCBwYXJ0LlxyXG5cdCAqICAgLSBleHRyYXMuY2ZnLnNlcCAgICAgICB7c3RyaW5nfSAgTGFiZWwgc2VwYXJhdG9yLCBkZWZhdWx0IFwiOiBcIi5cclxuXHQgKiAgICAgICBFeGFtcGxlOiBcIjxiPkxhYmVsPC9iPjogXCIgdnMgXCI8Yj5MYWJlbDwvYj4g4oCTIFwiLlxyXG5cdCAqICAgLSBleHRyYXMuY2ZnLm5ld2xpbmUgICB7c3RyaW5nfSAgTmV3bGluZSBzZXBhcmF0b3Igd2hlbiBqb2luaW5nIGxpbmVzICh1c3VhbGx5IFwiXFxuXCIpLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtPYmplY3R9IFtleHRyYXMuY29yZV1cclxuXHQgKiAgIFJlZmVyZW5jZSB0byBXUEJDX0JGQl9Db3JlIChzYW1lIGFzIGluIG1haW4gZXhwb3J0ZXIpLlxyXG5cdCAqICAgVXN1YWxseSBub3QgbmVlZGVkIGhlcmUsIGJlY2F1c2U6XHJcblx0ICogICAtIFNhbml0aXphdGlvbiBhbmQgY29uc2lzdGVudCByZW5kZXJpbmcgYXJlIGFscmVhZHkgZG9uZSB2aWFcclxuXHQgKiAgICAgV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyLmVtaXRfbGluZV9ib2xkX2ZpZWxkKCAuLi4gKS5cclxuXHQgKi9cclxuXHRmdW5jdGlvbiByZWdpc3Rlcl90ZXh0X2Jvb2tpbmdfZGF0YV9leHBvcnRlcigpIHtcclxuXHJcblx0XHRjb25zdCBDID0gdy5XUEJDX0JGQl9Db250ZW50RXhwb3J0ZXI7XHJcblx0XHRpZiAoICEgQyB8fCB0eXBlb2YgQy5yZWdpc3RlciAhPT0gJ2Z1bmN0aW9uJyApIHsgcmV0dXJuOyB9XHJcblx0XHRpZiAoIHR5cGVvZiBDLmhhc19leHBvcnRlciA9PT0gJ2Z1bmN0aW9uJyAmJiBDLmhhc19leHBvcnRlciggJ3RleHQnICkgKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdEMucmVnaXN0ZXIoICd0ZXh0JywgZnVuY3Rpb24gKGZpZWxkLCBlbWl0LCBleHRyYXMpIHtcclxuXHJcblx0XHRcdGV4dHJhcyA9IGV4dHJhcyB8fCB7fTtcclxuXHRcdFx0Y29uc3QgY2ZnID0gZXh0cmFzLmNmZyB8fCB7fTtcclxuXHJcblx0XHRcdGNvbnN0IEV4cCA9IHcuV1BCQ19CRkJfRXhwb3J0ZXI7XHJcblx0XHRcdGlmICggISBFeHAgfHwgdHlwZW9mIEV4cC5jb21wdXRlX25hbWUgIT09ICdmdW5jdGlvbicgKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdFx0Y29uc3QgbmFtZSA9IEV4cC5jb21wdXRlX25hbWUoICd0ZXh0JywgZmllbGQgKTtcclxuXHRcdFx0aWYgKCAhIG5hbWUgKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdFx0Y29uc3QgbGFiZWwgPSAodHlwZW9mIGZpZWxkLmxhYmVsID09PSAnc3RyaW5nJyAmJiBmaWVsZC5sYWJlbC50cmltKCkpID8gZmllbGQubGFiZWwudHJpbSgpIDogbmFtZTtcclxuXHJcblx0XHRcdC8vIFNoYXJlZCBmb3JtYXR0ZXIga2VlcHMgYWxsIHBhY2tzIGNvbnNpc3RlbnQ6LlxyXG5cdFx0XHRDLmVtaXRfbGluZV9ib2xkX2ZpZWxkKCBlbWl0LCBsYWJlbCwgbmFtZSwgY2ZnICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG5cclxuXHRpZiAoIHcuV1BCQ19CRkJfQ29udGVudEV4cG9ydGVyICYmIHR5cGVvZiB3LldQQkNfQkZCX0NvbnRlbnRFeHBvcnRlci5yZWdpc3RlciA9PT0gJ2Z1bmN0aW9uJyApIHtcclxuXHRcdHJlZ2lzdGVyX3RleHRfYm9va2luZ19kYXRhX2V4cG9ydGVyKCk7XHJcblx0fSBlbHNlIHtcclxuXHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoICd3cGJjOmJmYjpjb250ZW50LWV4cG9ydGVyLXJlYWR5JywgcmVnaXN0ZXJfdGV4dF9ib29raW5nX2RhdGFfZXhwb3J0ZXIsIHsgb25jZTogdHJ1ZSB9ICk7XHJcblx0fVxyXG5cclxufSkoIHdpbmRvdyApO1xyXG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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 |
| 391 |
|