PluginProbe
Booking Calendar / 11.2.1
Booking Calendar v11.2.1
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 / _dist / all / _out / wpbc_all_admin.js

wpbc_all_admin.js in Booking Calendar 11.2.1, at _dist/all/_out/wpbc_all_admin.js

2,070 lines 239.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 /**
4 * Blink specific HTML element to set attention to this element.
5 *
6 * @param {string} element_to_blink - class or id of element: '.wpbc_widget_available_unavailable'
7 * @param {int} how_many_times - 4
8 * @param {int} how_long_to_blink - 350
9 */
10 function wpbc_blink_element(element_to_blink, how_many_times = 4, how_long_to_blink = 350) {
11 for (let i = 0; i < how_many_times; i++) {
12 jQuery(element_to_blink).fadeOut(how_long_to_blink).fadeIn(how_long_to_blink);
13 }
14 jQuery(element_to_blink).animate({
15 opacity: 1
16 }, 500);
17 }
18
19 /**
20 * Support Functions - Spin Icon in Buttons ------------------------------------------------------------------ */
21
22 /**
23 * Remove spin icon from button and Enable this button.
24 *
25 * @param button_clicked_element_id - HTML ID attribute of this button
26 * @return string - CSS classes that was previously in button icon
27 */
28 function wpbc_button__remove_spin(button_clicked_element_id) {
29 var previos_classes = '';
30 if (undefined != button_clicked_element_id && '' != button_clicked_element_id) {
31 var jElement = jQuery('#' + button_clicked_element_id);
32 if (jElement.length) {
33 previos_classes = wpbc_button_disable_loading_icon(jElement.get(0));
34 }
35 }
36 return previos_classes;
37 }
38
39 /**
40 * Show Loading (rotating arrow) icon for button that has been clicked
41 *
42 * @param this_button - this object of specific button
43 * @return string - CSS classes that was previously in button icon
44 */
45 function wpbc_button_enable_loading_icon(this_button) {
46 var jButton = jQuery(this_button);
47 var jIcon = jButton.find('i');
48 var previos_classes = jIcon.attr('class');
49 jIcon.removeClass().addClass('menu_icon icon-1x wpbc_icn_rotate_right wpbc_spin'); // Set Rotate icon.
50 // jIcon.addClass( 'wpbc_animation_pause' ); // Pause animation.
51 // jIcon.addClass( 'wpbc_ui_red' ); // Set icon color red.
52
53 jIcon.attr('wpbc_previous_class', previos_classes);
54 jButton.addClass('disabled'); // Disable button
55 // We need to set here attr instead of prop, because for A elements, attribute 'disabled' do not added with jButton.prop( "disabled", true );.
56
57 jButton.attr('wpbc_previous_onclick', jButton.attr('onclick')); // Save this value.
58 jButton.attr('onclick', ''); // Disable actions "on click".
59
60 return previos_classes;
61 }
62
63 /**
64 * Hide Loading (rotating arrow) icon for button that was clicked and show previous icon and enable button
65 *
66 * @param this_button - this object of specific button
67 * @return string - CSS classes that was previously in button icon
68 */
69 function wpbc_button_disable_loading_icon(this_button) {
70 var jButton = jQuery(this_button);
71 var jIcon = jButton.find('i');
72 var previos_classes = jIcon.attr('wpbc_previous_class');
73 if (undefined != previos_classes && '' != previos_classes) {
74 jIcon.removeClass().addClass(previos_classes);
75 }
76 jButton.removeClass('disabled'); // Remove Disable button.
77
78 var previous_onclick = jButton.attr('wpbc_previous_onclick');
79 if (undefined != previous_onclick && '' != previous_onclick) {
80 jButton.attr('onclick', previous_onclick);
81 }
82 return previos_classes;
83 }
84
85 /**
86 * On selection of radio button, adjust attributes of radio container
87 *
88 * @param _this
89 */
90 function wpbc_ui_el__radio_container_selection(_this) {
91 if (jQuery(_this).is(':checked')) {
92 jQuery(_this).parents('.wpbc_ui_radio_section').find('.wpbc_ui_radio_container').removeAttr('data-selected');
93 jQuery(_this).parents('.wpbc_ui_radio_container:not(.disabled)').attr('data-selected', true);
94 }
95 if (jQuery(_this).is(':disabled')) {
96 jQuery(_this).parents('.wpbc_ui_radio_container').addClass('disabled');
97 }
98 }
99
100 /**
101 * On click on Radio Container, we will select the radio button and then adjust attributes of radio container
102 *
103 * @param _this
104 */
105 function wpbc_ui_el__radio_container_click(_this) {
106 if (jQuery(_this).hasClass('disabled')) {
107 return false;
108 }
109 var j_radio = jQuery(_this).find('input[type=radio]:not(.wpbc-form-radio-internal)');
110 if (j_radio.length) {
111 j_radio.prop('checked', true).trigger('change');
112 }
113 }
114 "use strict";
115 // =====================================================================================================================
116 // == Full Screen - support functions ==
117 // =====================================================================================================================
118
119 /**
120 * Check Full screen mode, by removing top tab
121 */
122 function wpbc_check_full_screen_mode() {
123 if (jQuery('body').hasClass('wpbc_admin_full_screen')) {
124 jQuery('html').removeClass('wp-toolbar');
125 } else {
126 jQuery('html').addClass('wp-toolbar');
127 }
128 wpbc_check_buttons_max_min_in_full_screen_mode();
129 }
130 function wpbc_check_buttons_max_min_in_full_screen_mode() {
131 if (jQuery('body').hasClass('wpbc_admin_full_screen')) {
132 jQuery('.wpbc_ui__top_nav__btn_full_screen').addClass('wpbc_ui__hide');
133 jQuery('.wpbc_ui__top_nav__btn_normal_screen').removeClass('wpbc_ui__hide');
134 } else {
135 jQuery('.wpbc_ui__top_nav__btn_full_screen').removeClass('wpbc_ui__hide');
136 jQuery('.wpbc_ui__top_nav__btn_normal_screen').addClass('wpbc_ui__hide');
137 }
138 }
139 jQuery(document).ready(function () {
140 wpbc_check_full_screen_mode();
141 });
142 /**
143 * Checkbox Selection functions for Listing.
144 */
145
146 /**
147 * Selections of several checkboxes like in gMail with shift :)
148 * Need to have this structure:
149 * .wpbc_selectable_table
150 * .wpbc_selectable_head
151 * .check-column
152 * :checkbox
153 * .wpbc_selectable_body
154 * .wpbc_row
155 * .check-column
156 * :checkbox
157 * .wpbc_selectable_foot
158 * .check-column
159 * :checkbox
160 */
161 function wpbc_define_gmail_checkbox_selection($) {
162 var checks,
163 first,
164 last,
165 checked,
166 sliced,
167 lastClicked = false;
168
169 // Check all checkboxes.
170 $('.wpbc_selectable_body').find('.check-column').find(':checkbox').on('click', function (e) {
171 if ('undefined' == e.shiftKey) {
172 return true;
173 }
174 if (e.shiftKey) {
175 if (!lastClicked) {
176 return true;
177 }
178 checks = $(lastClicked).closest('.wpbc_selectable_body').find(':checkbox').filter(':visible:enabled');
179 first = checks.index(lastClicked);
180 last = checks.index(this);
181 checked = $(this).prop('checked');
182 if (0 < first && 0 < last && first != last) {
183 sliced = last > first ? checks.slice(first, last) : checks.slice(last, first);
184 sliced.prop('checked', function () {
185 if ($(this).closest('.wpbc_row').is(':visible')) {
186 return checked;
187 }
188 return false;
189 }).trigger('change');
190 }
191 }
192 lastClicked = this;
193
194 // toggle "check all" checkboxes.
195 var unchecked = $(this).closest('.wpbc_selectable_body').find(':checkbox').filter(':visible:enabled').not(':checked');
196 $(this).closest('.wpbc_selectable_table').children('.wpbc_selectable_head, .wpbc_selectable_foot').find(':checkbox').prop('checked', function () {
197 return 0 === unchecked.length;
198 }).trigger('change');
199 return true;
200 });
201
202 // Head || Foot clicking to select / deselect ALL.
203 $('.wpbc_selectable_head, .wpbc_selectable_foot').find('.check-column :checkbox').on('click', function (event) {
204 var $this = $(this),
205 $table = $this.closest('.wpbc_selectable_table'),
206 controlChecked = $this.prop('checked'),
207 toggle = event.shiftKey || $this.data('wp-toggle');
208 $table.children('.wpbc_selectable_body').filter(':visible').find('.check-column').find(':checkbox').prop('checked', function () {
209 if ($(this).is(':hidden,:disabled')) {
210 return false;
211 }
212 if (toggle) {
213 return !$(this).prop('checked');
214 } else if (controlChecked) {
215 return true;
216 }
217 return false;
218 }).trigger('change');
219 $table.children('.wpbc_selectable_head, .wpbc_selectable_foot').filter(':visible').find('.check-column').find(':checkbox').prop('checked', function () {
220 if (toggle) {
221 return false;
222 } else if (controlChecked) {
223 return true;
224 }
225 return false;
226 });
227 });
228
229 // Visually show selected border.
230 $('.wpbc_selectable_body').find('.check-column :checkbox').on('change', function (event) {
231 if (jQuery(this).is(':checked')) {
232 jQuery(this).closest('.wpbc_list_row').addClass('row_selected_color');
233 } else {
234 jQuery(this).closest('.wpbc_list_row').removeClass('row_selected_color');
235 }
236
237 // Disable text selection while pressing 'shift'.
238 document.getSelection().removeAllRanges();
239
240 // Show or hide buttons on Actions toolbar at Booking Listing page, if we have some selected bookings.
241 wpbc_show_hide_action_buttons_for_selected_bookings();
242 });
243 wpbc_show_hide_action_buttons_for_selected_bookings();
244 }
245
246 /**
247 * Get ID array of selected elements
248 */
249 function wpbc_get_selected_row_id() {
250 var $table = jQuery('.wpbc__wrap__booking_listing .wpbc_selectable_table');
251 var checkboxes = $table.children('.wpbc_selectable_body').filter(':visible').find('.check-column').find(':checkbox');
252 var selected_id = [];
253 jQuery.each(checkboxes, function (key, checkbox) {
254 if (jQuery(checkbox).is(':checked')) {
255 var element_id = wpbc_get_row_id_from_element(checkbox);
256 selected_id.push(element_id);
257 }
258 });
259 return selected_id;
260 }
261
262 /**
263 * Get ID of row, based on clciked element
264 *
265 * @param this_inbound_element - ususlly this
266 * @returns {number}
267 */
268 function wpbc_get_row_id_from_element(this_inbound_element) {
269 var element_id = jQuery(this_inbound_element).closest('.wpbc_listing_usual_row').attr('id');
270 element_id = parseInt(element_id.replace('row_id_', ''));
271 return element_id;
272 }
273
274 /**
275 * == Booking Listing == Show or hide buttons on Actions toolbar at page, if we have some selected bookings.
276 */
277 function wpbc_show_hide_action_buttons_for_selected_bookings() {
278 var selected_rows_arr = wpbc_get_selected_row_id();
279 if (selected_rows_arr.length > 0) {
280 jQuery('.hide_button_if_no_selection').show();
281 } else {
282 jQuery('.hide_button_if_no_selection').hide();
283 }
284 }
285 "use strict";
286 // =====================================================================================================================
287 // == Left Bar - expand / colapse functions ==
288 // =====================================================================================================================
289
290 /**
291 * Expand Vertical Left Bar.
292 */
293 function wpbc_admin_ui__sidebar_left__do_max() {
294 jQuery('.wpbc_settings_page_wrapper').removeClass('min max compact none');
295 jQuery('.wpbc_settings_page_wrapper').addClass('max');
296 jQuery('.wpbc_ui__top_nav__btn_open_left_vertical_nav').addClass('wpbc_ui__hide');
297 jQuery('.wpbc_ui__top_nav__btn_hide_left_vertical_nav').removeClass('wpbc_ui__hide');
298 jQuery('.wp-admin').removeClass('wpbc_page_wrapper_left_min wpbc_page_wrapper_left_max wpbc_page_wrapper_left_compact wpbc_page_wrapper_left_none');
299 jQuery('.wp-admin').addClass('wpbc_page_wrapper_left_max');
300 }
301
302 /**
303 * Hide Vertical Left Bar.
304 */
305 function wpbc_admin_ui__sidebar_left__do_min() {
306 jQuery('.wpbc_settings_page_wrapper').removeClass('min max compact none');
307 jQuery('.wpbc_settings_page_wrapper').addClass('min');
308 jQuery('.wpbc_ui__top_nav__btn_open_left_vertical_nav').removeClass('wpbc_ui__hide');
309 jQuery('.wpbc_ui__top_nav__btn_hide_left_vertical_nav').addClass('wpbc_ui__hide');
310 jQuery('.wp-admin').removeClass('wpbc_page_wrapper_left_min wpbc_page_wrapper_left_max wpbc_page_wrapper_left_compact wpbc_page_wrapper_left_none');
311 jQuery('.wp-admin').addClass('wpbc_page_wrapper_left_min');
312 }
313
314 /**
315 * Colapse Vertical Left Bar.
316 */
317 function wpbc_admin_ui__sidebar_left__do_compact() {
318 jQuery('.wpbc_settings_page_wrapper').removeClass('min max compact none');
319 jQuery('.wpbc_settings_page_wrapper').addClass('compact');
320 jQuery('.wpbc_ui__top_nav__btn_open_left_vertical_nav').removeClass('wpbc_ui__hide');
321 jQuery('.wpbc_ui__top_nav__btn_hide_left_vertical_nav').addClass('wpbc_ui__hide');
322 jQuery('.wp-admin').removeClass('wpbc_page_wrapper_left_min wpbc_page_wrapper_left_max wpbc_page_wrapper_left_compact wpbc_page_wrapper_left_none');
323 jQuery('.wp-admin').addClass('wpbc_page_wrapper_left_compact');
324 }
325
326 /**
327 * Completely Hide Vertical Left Bar.
328 */
329 function wpbc_admin_ui__sidebar_left__do_hide() {
330 jQuery('.wpbc_settings_page_wrapper').removeClass('min max compact none');
331 jQuery('.wpbc_settings_page_wrapper').addClass('none');
332 jQuery('.wpbc_ui__top_nav__btn_open_left_vertical_nav').removeClass('wpbc_ui__hide');
333 jQuery('.wpbc_ui__top_nav__btn_hide_left_vertical_nav').addClass('wpbc_ui__hide');
334 // Hide top "Menu" button with divider.
335 jQuery('.wpbc_ui__top_nav__btn_show_left_vertical_nav,.wpbc_ui__top_nav__btn_show_left_vertical_nav_divider').addClass('wpbc_ui__hide');
336 jQuery('.wp-admin').removeClass('wpbc_page_wrapper_left_min wpbc_page_wrapper_left_max wpbc_page_wrapper_left_compact wpbc_page_wrapper_left_none');
337 jQuery('.wp-admin').addClass('wpbc_page_wrapper_left_none');
338 }
339
340 /**
341 * Action on click "Go Back" - show root menu
342 * or some other section in left sidebar.
343 *
344 * @param string menu_to_show - menu slug.
345 */
346 function wpbc_admin_ui__sidebar_left__show_section(menu_to_show) {
347 jQuery('.wpbc_ui_el__vert_left_bar__section').addClass('wpbc_ui__hide');
348 jQuery('.wpbc_ui_el__vert_left_bar__section_' + menu_to_show).removeClass('wpbc_ui__hide');
349 }
350
351 // =====================================================================================================================
352 // == Right Side Bar - expand / colapse functions ==
353 // =====================================================================================================================
354
355 /**
356 * Expand Vertical Right Bar.
357 */
358 function wpbc_admin_ui__sidebar_right__do_max() {
359 jQuery('.wpbc_settings_page_wrapper').removeClass('min_right max_right compact_right none_right');
360 jQuery('.wpbc_settings_page_wrapper').addClass('max_right');
361 jQuery('.wpbc_ui__top_nav__btn_open_right_vertical_nav').addClass('wpbc_ui__hide');
362 jQuery('.wpbc_ui__top_nav__btn_hide_right_vertical_nav').removeClass('wpbc_ui__hide');
363 }
364
365 /**
366 * Hide Vertical Right Bar.
367 */
368 function wpbc_admin_ui__sidebar_right__do_min() {
369 jQuery('.wpbc_settings_page_wrapper').removeClass('min_right max_right compact_right none_right');
370 jQuery('.wpbc_settings_page_wrapper').addClass('min_right');
371 jQuery('.wpbc_ui__top_nav__btn_open_right_vertical_nav').removeClass('wpbc_ui__hide');
372 jQuery('.wpbc_ui__top_nav__btn_hide_right_vertical_nav').addClass('wpbc_ui__hide');
373 }
374
375 /**
376 * Colapse Vertical Right Bar.
377 */
378 function wpbc_admin_ui__sidebar_right__do_compact() {
379 jQuery('.wpbc_settings_page_wrapper').removeClass('min_right max_right compact_right none_right');
380 jQuery('.wpbc_settings_page_wrapper').addClass('compact_right');
381 jQuery('.wpbc_ui__top_nav__btn_open_right_vertical_nav').removeClass('wpbc_ui__hide');
382 jQuery('.wpbc_ui__top_nav__btn_hide_right_vertical_nav').addClass('wpbc_ui__hide');
383 }
384
385 /**
386 * Completely Hide Vertical Right Bar.
387 */
388 function wpbc_admin_ui__sidebar_right__do_hide() {
389 jQuery('.wpbc_settings_page_wrapper').removeClass('min_right max_right compact_right none_right');
390 jQuery('.wpbc_settings_page_wrapper').addClass('none_right');
391 jQuery('.wpbc_ui__top_nav__btn_open_right_vertical_nav').removeClass('wpbc_ui__hide');
392 jQuery('.wpbc_ui__top_nav__btn_hide_right_vertical_nav').addClass('wpbc_ui__hide');
393 // Hide top "Menu" button with divider.
394 jQuery('.wpbc_ui__top_nav__btn_show_right_vertical_nav,.wpbc_ui__top_nav__btn_show_right_vertical_nav_divider').addClass('wpbc_ui__hide');
395 }
396
397 /**
398 * Action on click "Go Back" - show root menu
399 * or some other section in right sidebar.
400 *
401 * @param string menu_to_show - menu slug.
402 */
403 function wpbc_admin_ui__sidebar_right__show_section(menu_to_show) {
404 jQuery('.wpbc_ui_el__vert_right_bar__section').addClass('wpbc_ui__hide');
405 jQuery('.wpbc_ui_el__vert_right_bar__section_' + menu_to_show).removeClass('wpbc_ui__hide');
406 }
407
408 // =====================================================================================================================
409 // == End Right Side Bar section ==
410 // =====================================================================================================================
411
412 /**
413 * Get anchor(s) array from URL.
414 * Doc: https://developer.mozilla.org/en-US/docs/Web/API/Location
415 *
416 * @returns {*[]}
417 */
418 function wpbc_url_get_anchors_arr() {
419 var hashes = window.location.hash.replace('%23', '#');
420 var hashes_arr = hashes.split('#');
421 var result = [];
422 var hashes_arr_length = hashes_arr.length;
423 for (var i = 0; i < hashes_arr_length; i++) {
424 if (hashes_arr[i].length > 0) {
425 result.push(hashes_arr[i]);
426 }
427 }
428 return result;
429 }
430
431 /**
432 * Auto Expand Settings section based on URL anchor, after page loaded.
433 */
434 jQuery(document).ready(function () {
435 wpbc_admin_ui__redirect_legacy_general_availability_url();
436 });
437 jQuery(document).ready(function () {
438 wpbc_admin_ui__do_expand_section();
439 setTimeout('wpbc_admin_ui__do_expand_section', 10);
440 });
441 jQuery(document).ready(function () {
442 wpbc_admin_ui__do_expand_section();
443 setTimeout('wpbc_admin_ui__do_expand_section', 150);
444 });
445
446 /**
447 * Redirect old Settings > Availability anchors to the dedicated General Availability page.
448 */
449 function wpbc_admin_ui__redirect_legacy_general_availability_url() {
450 if (window.location.href.indexOf('page=wpbc-settings') > -1 && (window.location.hash.indexOf('wpbc_general_settings_availability_metabox') > -1 || window.location.hash.indexOf('wpbc_general_settings_availability_tab') > -1)) {
451 window.location.replace(window.location.href.split('?')[0] + '?page=wpbc-availability&tab=general_availability');
452 }
453 }
454
455 /**
456 * Expand section in General Settings page and select Menu item.
457 */
458 function wpbc_admin_ui__do_expand_section() {
459 // window.location.hash = #section_id / doc: https://developer.mozilla.org/en-US/docs/Web/API/Location .
460 var anchors_arr = wpbc_url_get_anchors_arr();
461 var anchors_arr_length = anchors_arr.length;
462 if (anchors_arr_length > 0) {
463 var one_anchor_prop_value = anchors_arr[0].split('do_expand__');
464 if (one_anchor_prop_value.length > 1) {
465 // 'wpbc_general_settings_calendar_metabox'
466 var section_to_show = one_anchor_prop_value[1];
467 var section_id_to_show = '#' + section_to_show;
468
469 // -- Remove selected background in all left menu items ---------------------------------------------------
470 jQuery('.wpbc_ui_el__vert_nav_item ').removeClass('active');
471 // Set left menu selected.
472 jQuery('.do_expand__' + section_to_show + '_link').addClass('active');
473 var selected_title = jQuery('.do_expand__' + section_to_show + '_link a .wpbc_ui_el__vert_nav_title ').text();
474
475 // Expand section, if it colapsed.
476 if (!jQuery('.do_expand__' + section_to_show + '_link').parents('.wpbc_ui_el__level__folder').hasClass('expanded')) {
477 jQuery('.wpbc_ui_el__level__folder').removeClass('expanded');
478 jQuery('.do_expand__' + section_to_show + '_link').parents('.wpbc_ui_el__level__folder').addClass('expanded');
479 }
480
481 // -- Expand section ---------------------------------------------------------------------------------------
482 var container_to_hide_class = '.postbox';
483 // Hide sections '.postbox' in admin page and show specific one.
484 jQuery('.wpbc_admin_page ' + container_to_hide_class).hide();
485 jQuery('.wpbc_container_always_hide__on_left_nav_click').hide();
486 jQuery(section_id_to_show).show();
487
488 // Show all other sections, if provided in URL: ..?page=wpbc-settings#do_expand__wpbc_general_settings_capacity_metabox#wpbc_general_settings_capacity_upgrade_metabox .
489 for (let i = 1; i < anchors_arr_length; i++) {
490 jQuery('#' + anchors_arr[i]).show();
491 }
492 if (false) {
493 var targetOffset = wpbc_scroll_to(section_id_to_show);
494 }
495
496 // -- Set Value to Input about selected Nav element --------------------------------------------------------------- // FixIn: 9.8.6.1.
497 var section_id_tab = section_id_to_show.substring(0, section_id_to_show.length - 8) + '_tab';
498 if (container_to_hide_class == section_id_to_show) {
499 section_id_tab = '#wpbc_general_settings_all_tab';
500 }
501 if ('#wpbc_general_settings_capacity_metabox,#wpbc_general_settings_capacity_upgrade_metabox' == section_id_to_show) {
502 section_id_tab = '#wpbc_general_settings_capacity_tab';
503 }
504 jQuery('#form_visible_section').val(section_id_tab);
505 }
506
507 // Like blinking some elements.
508 wpbc_admin_ui__do__anchor__another_actions();
509 }
510 }
511 function wpbc_admin_ui__is_in_mobile_screen_size() {
512 return wpbc_admin_ui__is_in_this_screen_size(605);
513 }
514 function wpbc_admin_ui__is_in_this_screen_size(size) {
515 return window.screen.width <= size;
516 }
517
518 /**
519 * Open settings page | Expand section | Select Menu item.
520 */
521 function wpbc_admin_ui__do__open_url__expand_section(url, section_id) {
522 // window.location.href = url + '&do_expand=' + section_id + '#do_expand__' + section_id; //.
523 window.location.href = url + '#do_expand__' + section_id;
524 if (wpbc_admin_ui__is_in_mobile_screen_size()) {
525 wpbc_admin_ui__sidebar_left__do_min();
526 }
527 wpbc_admin_ui__do_expand_section();
528 }
529
530 /**
531 * Check for Other actions: Like blinking some elements in settings page. E.g. Days selection or change-over days.
532 */
533 function wpbc_admin_ui__do__anchor__another_actions() {
534 var anchors_arr = wpbc_url_get_anchors_arr();
535 var anchors_arr_length = anchors_arr.length;
536
537 // Other actions: Like blinking some elements.
538 for (var i = 0; i < anchors_arr_length; i++) {
539 var this_anchor = anchors_arr[i];
540 var this_anchor_prop_value = this_anchor.split('do_other_actions__');
541 if (this_anchor_prop_value.length > 1) {
542 var section_action = this_anchor_prop_value[1];
543 switch (section_action) {
544 case 'blink_day_selections':
545 // wpbc_ui_settings__panel__click( '#wpbc_general_settings_calendar_tab a', '#wpbc_general_settings_calendar_metabox', 'Days Selection' );.
546 wpbc_blink_element('.wpbc_tr_set_gen_booking_type_of_day_selections', 4, 350);
547 wpbc_scroll_to('.wpbc_tr_set_gen_booking_type_of_day_selections');
548 break;
549 case 'blink_change_over_days':
550 // wpbc_ui_settings__panel__click( '#wpbc_general_settings_calendar_tab a', '#wpbc_general_settings_calendar_metabox', 'Changeover Days' );.
551 wpbc_blink_element('.wpbc_tr_set_gen_booking_range_selection_time_is_active', 4, 350);
552 wpbc_scroll_to('.wpbc_tr_set_gen_booking_range_selection_time_is_active');
553 break;
554 case 'blink_captcha':
555 wpbc_blink_element('.wpbc_tr_set_gen_booking_is_use_captcha', 4, 350);
556 wpbc_scroll_to('.wpbc_tr_set_gen_booking_is_use_captcha');
557 break;
558 default:
559 }
560 }
561 }
562 }
563
564 /**
565 * Copy txt to clipbrd from Text fields.
566 *
567 * @param html_element_id - e.g. 'data_field'
568 * @returns {boolean}
569 */
570 function wpbc_copy_text_to_clipbrd_from_element(html_element_id) {
571 // Get the text field.
572 var copyText = document.getElementById(html_element_id);
573
574 // Select the text field.
575 copyText.select();
576 copyText.setSelectionRange(0, 99999); // For mobile devices.
577
578 // Copy the text inside the text field.
579 var is_copied = wpbc_copy_text_to_clipbrd(copyText.value);
580 if (!is_copied) {
581 console.error('Oops, unable to copy', copyText.value);
582 }
583 return is_copied;
584 }
585
586 /**
587 * Copy txt to clipbrd.
588 *
589 * @param text
590 * @returns {boolean}
591 */
592 function wpbc_copy_text_to_clipbrd(text) {
593 if (!navigator.clipboard) {
594 return wpbc_fallback_copy_text_to_clipbrd(text);
595 }
596 navigator.clipboard.writeText(text).then(function () {
597 // console.log( 'Async: Copying to clipboard was successful!' );.
598 return true;
599 }, function (err) {
600 // console.error( 'Async: Could not copy text: ', err );.
601 return false;
602 });
603 }
604
605 /**
606 * Copy txt to clipbrd - depricated method.
607 *
608 * @param text
609 * @returns {boolean}
610 */
611 function wpbc_fallback_copy_text_to_clipbrd(text) {
612 // -----------------------------------------------------------------------------------------------------------------
613 // var textArea = document.createElement( "textarea" );
614 // textArea.value = text;
615 //
616 // // Avoid scrolling to bottom.
617 // textArea.style.top = "0";
618 // textArea.style.left = "0";
619 // textArea.style.position = "fixed";
620 // textArea.style.zIndex = "999999999";
621 // document.body.appendChild( textArea );
622 // textArea.focus();
623 // textArea.select();
624
625 // -----------------------------------------------------------------------------------------------------------------
626 // Now get it as HTML (original here https://stackoverflow.com/questions/34191780/javascript-copy-string-to-clipboard-as-text-html ).
627
628 // [1] - Create container for the HTML.
629 var container = document.createElement('div');
630 container.innerHTML = text;
631
632 // [2] - Hide element.
633 container.style.position = 'fixed';
634 container.style.pointerEvents = 'none';
635 container.style.opacity = 0;
636
637 // Detect all style sheets of the page.
638 var activeSheets = Array.prototype.slice.call(document.styleSheets).filter(function (sheet) {
639 return !sheet.disabled;
640 });
641
642 // [3] - Mount the container to the DOM to make `contentWindow` available.
643 document.body.appendChild(container);
644
645 // [4] - Copy to clipboard.
646 window.getSelection().removeAllRanges();
647 var range = document.createRange();
648 range.selectNode(container);
649 window.getSelection().addRange(range);
650 // -----------------------------------------------------------------------------------------------------------------
651
652 var result = false;
653 try {
654 result = document.execCommand('copy');
655 // console.log( 'Fallback: Copying text command was ' + msg ); //.
656 } catch (err) {
657 // console.error( 'Fallback: Oops, unable to copy', err ); //.
658 }
659 // document.body.removeChild( textArea ); //.
660
661 // [5.4] - Enable CSS.
662 var activeSheets_length = activeSheets.length;
663 for (var i = 0; i < activeSheets_length; i++) {
664 activeSheets[i].disabled = false;
665 }
666
667 // [6] - Remove the container
668 document.body.removeChild(container);
669 return result;
670 }
671 /**
672 * WPBC Collapsible Groups
673 *
674 * Universal, dependency-free controller for expanding/collapsing grouped sections in right-side panels (Inspector/Library/Form Settings, or any other WPBC page).
675 *
676 * === How to use it (quick) ? ===
677 *
678 * -- 1. Markup (independent mode: multiple open allowed) --
679 * <div class="wpbc_collapsible">
680 * <section class="wpbc_ui__collapsible_group is-open">
681 * <button type="button" class="group__header"><h3>General</h3></button>
682 * <div class="group__fields">…</div>
683 * </section>
684 * <section class="wpbc_ui__collapsible_group">
685 * <button type="button" class="group__header"><h3>Advanced</h3></button>
686 * <div class="group__fields">…</div>
687 * </section>
688 * </div>
689 *
690 * -- 2. Exclusive/accordion mode (one open at a time) --
691 * <div class="wpbc_collapsible wpbc_collapsible--exclusive">…</div>
692 *
693 * -- 3. Auto-init --
694 * The script auto-initializes on DOMContentLoaded. No extra code needed.
695 *
696 * -- 4. Programmatic control (optional)
697 * const root = document.querySelector('#wpbc_bfb__inspector');
698 * const api = root.__wpbc_collapsible_instance; // set by auto-init
699 *
700 * api.open_by_heading('Validation'); // open by heading text
701 * api.open_by_index(0); // open the first group
702 *
703 * -- 5.Listen to events (e.g., to persist “open group” state) --
704 * root.addEventListener('wpbc:collapsible:open', (e) => { console.log( e.detail.group ); });
705 * root.addEventListener('wpbc:collapsible:close', (e) => { console.log( e.detail.group ); });
706 *
707 *
708 *
709 * Markup expectations (minimal):
710 * <div class="wpbc_collapsible [wpbc_collapsible--exclusive]">
711 * <section class="wpbc_ui__collapsible_group [is-open]">
712 * <button type="button" class="group__header"> ... </button>
713 * <div class="group__fields"> ... </div>
714 * </section>
715 * ... more <section> ...
716 * </div>
717 *
718 * Notes:
719 * - Add `is-open` to any section you want initially expanded.
720 * - Add `wpbc_collapsible--exclusive` to the container for "open one at a time" behavior.
721 * - Works with your existing BFB markup (classes used there are the defaults).
722 *
723 * Accessibility:
724 * - Sets aria-expanded on .group__header
725 * - Sets aria-hidden + [hidden] on .group__fields
726 * - ArrowUp/ArrowDown move focus between headers; Enter/Space toggles
727 *
728 * Events (bubbles from the <section>):
729 * - 'wpbc:collapsible:open' (detail: { group, root, instance })
730 * - 'wpbc:collapsible:close' (detail: { group, root, instance })
731 *
732 * Public API (instance methods):
733 * - init(), destroy(), refresh()
734 * - expand(group, [exclusive]), collapse(group), toggle(group)
735 * - open_by_index(index), open_by_heading(text)
736 * - is_exclusive(), is_open(group)
737 *
738 * @version 2025-08-26
739 * @since 2025-08-26
740 */
741 // ---------------------------------------------------------------------------------------------------------------------
742 // == File /collapsible_groups.js == Time point: 2025-08-26 14:13
743 // ---------------------------------------------------------------------------------------------------------------------
744 (function (w, d) {
745 'use strict';
746
747 class WPBC_Collapsible_Groups {
748 /**
749 * Create a collapsible controller for a container.
750 *
751 * @param {HTMLElement|string} root_el
752 * The container element (or CSS selector) that wraps collapsible groups.
753 * The container usually has the class `.wpbc_collapsible`.
754 * @param {Object} [opts={}]
755 * @param {string} [opts.group_selector='.wpbc_ui__collapsible_group']
756 * Selector for each collapsible group inside the container.
757 * @param {string} [opts.header_selector='.group__header']
758 * Selector for the clickable header inside a group.
759 * @param {string} [opts.fields_selector='.group__fields']
760 * Selector for the content/panel element inside a group.
761 * @param {string} [opts.open_class='is-open']
762 * Class name that indicates the group is open.
763 * @param {boolean} [opts.exclusive=false]
764 * If true, only one group can be open at a time in this container.
765 *
766 * @constructor
767 * @since 2025-08-26
768 */
769 constructor(root_el, opts = {}) {
770 this.root = typeof root_el === 'string' ? d.querySelector(root_el) : root_el;
771 this.opts = Object.assign({
772 group_selector: '.wpbc_ui__collapsible_group',
773 header_selector: '.group__header',
774 fields_selector: '.group__fields,.group__content',
775 open_class: 'is-open',
776 exclusive: false
777 }, opts);
778
779 // Bound handlers (for add/removeEventListener symmetry).
780 /** @private */
781 this._on_click = this._on_click.bind(this);
782 /** @private */
783 this._on_keydown = this._on_keydown.bind(this);
784
785 /** @type {HTMLElement[]} @private */
786 this._groups = [];
787 /** @type {MutationObserver|null} @private */
788 this._observer = null;
789 }
790
791 /**
792 * Initialize the controller: cache groups, attach listeners, set ARIA,
793 * and start observing DOM changes inside the container.
794 *
795 * @returns {WPBC_Collapsible_Groups} The instance (chainable).
796 * @listens click
797 * @listens keydown
798 * @since 2025-08-26
799 */
800 init() {
801 if (!this.root) {
802 return this;
803 }
804 this._groups = Array.prototype.slice.call(this.root.querySelectorAll(this.opts.group_selector));
805 this.root.addEventListener('click', this._on_click, false);
806 this.root.addEventListener('keydown', this._on_keydown, false);
807
808 // Observe dynamic inserts/removals (Inspector re-renders).
809 this._observer = new MutationObserver(() => {
810 this.refresh();
811 });
812 this._observer.observe(this.root, {
813 childList: true,
814 subtree: true
815 });
816 this._sync_all_aria();
817 return this;
818 }
819
820 /**
821 * Tear down the controller: detach listeners, stop the observer,
822 * and drop internal references.
823 *
824 * @returns {void}
825 * @since 2025-08-26
826 */
827 destroy() {
828 if (!this.root) {
829 return;
830 }
831 this.root.removeEventListener('click', this._on_click, false);
832 this.root.removeEventListener('keydown', this._on_keydown, false);
833 if (this._observer) {
834 this._observer.disconnect();
835 this._observer = null;
836 }
837 this._groups = [];
838 }
839
840 /**
841 * Re-scan the DOM for current groups and re-apply ARIA to all of them.
842 * Useful after dynamic (re)renders.
843 *
844 * @returns {void}
845 * @since 2025-08-26
846 */
847 refresh() {
848 if (!this.root) {
849 return;
850 }
851 this._groups = Array.prototype.slice.call(this.root.querySelectorAll(this.opts.group_selector));
852 this._sync_all_aria();
853 }
854
855 /**
856 * Check whether the container is in exclusive (accordion) mode.
857 *
858 * Order of precedence:
859 * 1) Explicit option `opts.exclusive`
860 * 2) Container has class `.wpbc_collapsible--exclusive`
861 * 3) Container matches `[data-wpbc-accordion="exclusive"]`
862 *
863 * @returns {boolean} True if exclusive mode is active.
864 * @since 2025-08-26
865 */
866 is_exclusive() {
867 return !!(this.opts.exclusive || this.root.classList.contains('wpbc_collapsible--exclusive') || this.root.matches('[data-wpbc-accordion="exclusive"]'));
868 }
869
870 /**
871 * Determine whether a specific group is open.
872 *
873 * @param {HTMLElement} group The group element to test.
874 * @returns {boolean} True if the group is currently open.
875 * @since 2025-08-26
876 */
877 is_open(group) {
878 return group.classList.contains(this.opts.open_class);
879 }
880
881 /**
882 * Open a group. Honors exclusive mode by collapsing all sibling groups
883 * (queried from the live DOM at call-time).
884 *
885 * @param {HTMLElement} group The group element to open.
886 * @param {boolean} [exclusive]
887 * If provided, overrides container mode for this action only.
888 * @returns {void}
889 * @fires CustomEvent#wpbc:collapsible:open
890 * @since 2025-08-26
891 */
892 expand(group, exclusive) {
893 if (!group) {
894 return;
895 }
896 const do_exclusive = typeof exclusive === 'boolean' ? exclusive : this.is_exclusive();
897 if (do_exclusive) {
898 // Always use the live DOM, not the cached list.
899 Array.prototype.forEach.call(this.root.querySelectorAll(this.opts.group_selector), g => {
900 if (g !== group) {
901 this._set_open(g, false);
902 }
903 });
904 }
905 this._set_open(group, true);
906 }
907
908 /**
909 * Close a group.
910 *
911 * @param {HTMLElement} group The group element to close.
912 * @returns {void}
913 * @fires CustomEvent#wpbc:collapsible:close
914 * @since 2025-08-26
915 */
916 collapse(group) {
917 if (!group) {
918 return;
919 }
920 this._set_open(group, false);
921 }
922
923 /**
924 * Toggle a group's open/closed state.
925 *
926 * @param {HTMLElement} group The group element to toggle.
927 * @returns {void}
928 * @since 2025-08-26
929 */
930 toggle(group) {
931 if (!group) {
932 return;
933 }
934 this[this.is_open(group) ? 'collapse' : 'expand'](group);
935 }
936
937 /**
938 * Open a group by its index within the container (0-based).
939 *
940 * @param {number} index Zero-based index of the group.
941 * @returns {void}
942 * @since 2025-08-26
943 */
944 open_by_index(index) {
945 const group = this._groups[index];
946 if (group) {
947 this.expand(group);
948 }
949 }
950
951 /**
952 * Open a group by matching text contained within the <h3> inside the header.
953 * The comparison is case-insensitive and substring-based.
954 *
955 * @param {string} text Text to match against the heading contents.
956 * @returns {void}
957 * @since 2025-08-26
958 */
959 open_by_heading(text) {
960 if (!text) {
961 return;
962 }
963 const t = String(text).toLowerCase();
964 const match = this._groups.find(g => {
965 const h = g.querySelector(this.opts.header_selector + ' h3');
966 return h && h.textContent.toLowerCase().indexOf(t) !== -1;
967 });
968 if (match) {
969 this.expand(match);
970 }
971 }
972
973 // -------------------------------------------------------------------------------------------------------------
974 // Internal
975 // -------------------------------------------------------------------------------------------------------------
976
977 /**
978 * Delegated click handler for headers.
979 *
980 * @private
981 * @param {MouseEvent} ev The click event.
982 * @returns {void}
983 * @since 2025-08-26
984 */
985 _on_click(ev) {
986 const btn = ev.target.closest(this.opts.header_selector);
987 if (!btn || !this.root.contains(btn)) {
988 return;
989 }
990 ev.preventDefault();
991 ev.stopPropagation();
992 const group = btn.closest(this.opts.group_selector);
993 if (group) {
994 this.toggle(group);
995 }
996 }
997
998 /**
999 * Keyboard handler for header interactions and roving focus:
1000 * - Enter/Space toggles the active group.
1001 * - ArrowUp/ArrowDown moves focus between group headers.
1002 *
1003 * @private
1004 * @param {KeyboardEvent} ev The keyboard event.
1005 * @returns {void}
1006 * @since 2025-08-26
1007 */
1008 _on_keydown(ev) {
1009 const btn = ev.target.closest(this.opts.header_selector);
1010 if (!btn) {
1011 return;
1012 }
1013 const key = ev.key;
1014
1015 // Toggle on Enter / Space.
1016 if (key === 'Enter' || key === ' ') {
1017 ev.preventDefault();
1018 const group = btn.closest(this.opts.group_selector);
1019 if (group) {
1020 this.toggle(group);
1021 }
1022 return;
1023 }
1024
1025 // Move focus with ArrowUp/ArrowDown between headers in this container.
1026 if (key === 'ArrowUp' || key === 'ArrowDown') {
1027 ev.preventDefault();
1028 const headers = Array.prototype.map.call(this.root.querySelectorAll(this.opts.group_selector), g => g.querySelector(this.opts.header_selector)).filter(Boolean);
1029 const idx = headers.indexOf(btn);
1030 if (idx !== -1) {
1031 const next_idx = key === 'ArrowDown' ? Math.min(headers.length - 1, idx + 1) : Math.max(0, idx - 1);
1032 headers[next_idx].focus();
1033 }
1034 }
1035 }
1036
1037 /**
1038 * Apply ARIA synchronization to all known groups based on their open state.
1039 *
1040 * @private
1041 * @returns {void}
1042 * @since 2025-08-26
1043 */
1044 _sync_all_aria() {
1045 this._groups.forEach(g => this._sync_group_aria(g));
1046 }
1047
1048 /**
1049 * Sync ARIA attributes and visibility on a single group.
1050 *
1051 * @private
1052 * @param {HTMLElement} group The group element to sync.
1053 * @returns {void}
1054 * @since 2025-08-26
1055 */
1056 _sync_group_aria(group) {
1057 const is_open = this.is_open(group);
1058 const header = group.querySelector(this.opts.header_selector);
1059 // Only direct children that match.
1060 const panels = Array.prototype.filter.call(group.children, el => el.matches(this.opts.fields_selector));
1061
1062 // Header ARIA.
1063 if (header) {
1064 header.setAttribute('role', 'button');
1065 header.setAttribute('aria-expanded', is_open ? 'true' : 'false');
1066 if (panels.length) {
1067 // Ensure each panel has an id; then wire aria-controls with space-separated ids.
1068 const ids = panels.map(p => {
1069 if (!p.id) p.id = this._generate_id('wpbc_collapsible_panel');
1070 return p.id;
1071 });
1072 header.setAttribute('aria-controls', ids.join(' '));
1073 }
1074 }
1075
1076 // (3) Panels ARIA + visibility.
1077 panels.forEach(p => {
1078 p.hidden = !is_open; // actual visibility.
1079 p.setAttribute('aria-hidden', is_open ? 'false' : 'true'); // ARIA.
1080 });
1081 }
1082
1083 /**
1084 * Internal state change: set a group's open/closed state, sync ARIA,
1085 * manage focus on collapse, and emit a custom event.
1086 *
1087 * @private
1088 * @param {HTMLElement} group The group element to mutate.
1089 * @param {boolean} open Whether the group should be open.
1090 * @returns {void}
1091 * @fires CustomEvent#wpbc:collapsible:open
1092 * @fires CustomEvent#wpbc:collapsible:close
1093 * @since 2025-08-26
1094 */
1095 _set_open(group, open) {
1096 if (!open && group.contains(document.activeElement)) {
1097 const header = group.querySelector(this.opts.header_selector);
1098 header && header.focus();
1099 }
1100 group.classList.toggle(this.opts.open_class, open);
1101 this._sync_group_aria(group);
1102 const ev_name = open ? 'wpbc:collapsible:open' : 'wpbc:collapsible:close';
1103 group.dispatchEvent(new CustomEvent(ev_name, {
1104 bubbles: true,
1105 detail: {
1106 group,
1107 root: this.root,
1108 instance: this
1109 }
1110 }));
1111 }
1112
1113 /**
1114 * Generate a unique DOM id with the specified prefix.
1115 *
1116 * @private
1117 * @param {string} prefix The id prefix to use.
1118 * @returns {string} A unique element id not present in the document.
1119 * @since 2025-08-26
1120 */
1121 _generate_id(prefix) {
1122 let i = 1;
1123 let id;
1124 do {
1125 id = prefix + '_' + i++;
1126 } while (d.getElementById(id));
1127 return id;
1128 }
1129 }
1130
1131 /**
1132 * Auto-initialize collapsible controllers on the page.
1133 * Finds top-level `.wpbc_collapsible` containers (ignoring nested ones),
1134 * and instantiates {@link WPBC_Collapsible_Groups} on each.
1135 *
1136 * @function WPBC_Collapsible_AutoInit
1137 * @returns {void}
1138 * @since 2025-08-26
1139 * @example
1140 * // Runs automatically on DOMContentLoaded; can also be called manually:
1141 * WPBC_Collapsible_AutoInit();
1142 */
1143 function wpbc_collapsible__auto_init() {
1144 var ROOT = '.wpbc_collapsible';
1145 var nodes = Array.prototype.slice.call(d.querySelectorAll(ROOT)).filter(function (n) {
1146 return !n.parentElement || !n.parentElement.closest(ROOT);
1147 });
1148 nodes.forEach(function (node) {
1149 if (node.__wpbc_collapsible_instance) {
1150 return;
1151 }
1152 var exclusive = node.classList.contains('wpbc_collapsible--exclusive') || node.matches('[data-wpbc-accordion="exclusive"]');
1153 node.__wpbc_collapsible_instance = new WPBC_Collapsible_Groups(node, {
1154 exclusive
1155 }).init();
1156 });
1157 }
1158
1159 // Export to global for manual control if needed.
1160 w.WPBC_Collapsible_Groups = WPBC_Collapsible_Groups;
1161 w.WPBC_Collapsible_AutoInit = wpbc_collapsible__auto_init;
1162
1163 // DOM-ready auto init.
1164 if (d.readyState === 'loading') {
1165 d.addEventListener('DOMContentLoaded', wpbc_collapsible__auto_init, {
1166 once: true
1167 });
1168 } else {
1169 wpbc_collapsible__auto_init();
1170 }
1171 })(window, document);
1172
1173 /* globals window, document */
1174 /**
1175 * WPBC Slider Length Groups
1176 *
1177 * Universal, dependency-free controller that keeps a "length" control in sync:
1178 * - number input (data-wpbc_slider_len_value)
1179 * - unit select (data-wpbc_slider_len_unit)
1180 * - range slider (data-wpbc_slider_len_range)
1181 * - writer input (data-wpbc_slider_len_writer) [optional but recommended]
1182 *
1183 * The "writer" stores the combined value like: "100%", "420px", "12.5rem".
1184 * When number/unit/slider change -> writer updates and emits 'input' (bubbles).
1185 * When writer is changed externally (apply-from-JSON, etc) -> UI updates.
1186 *
1187 * Markup expectations (minimal):
1188 * <div class="wpbc_slider_len_group"
1189 * data-wpbc_slider_len_bounds_map='{"%":{"min":30,"max":100,"step":1},"px":{"min":300,"max":2000,"step":10}}'
1190 * data-wpbc_slider_len_default_unit="%">
1191 * <input type="number" data-wpbc_slider_len_value>
1192 * <select data-wpbc_slider_len_unit>...</select>
1193 * <input type="range" data-wpbc_slider_len_range>
1194 * <input type="text" data-wpbc_slider_len_writer style="display:none;">
1195 * </div>
1196 *
1197 * Performance notes:
1198 * - MutationObserver is DISABLED by default (prevents performance issues).
1199 * - If your UI re-renders and inserts new groups dynamically, call:
1200 * WPBC_Slider_Len_AutoInit(); OR instance.refresh();
1201 * Or enable observer via: new WPBC_Slider_Len_Groups(root, { enable_observer:true }).init();
1202 *
1203 * Public API (instance methods):
1204 * - init(), destroy(), refresh()
1205 *
1206 * @version 2026-01-25
1207 * @since 2026-01-25
1208 * @file ../includes/__js/admin/slider_groups/wpbc_len_groups.js
1209 */
1210 (function (w, d) {
1211 'use strict';
1212
1213 // -------------------------------------------------------------------------------------------------
1214 // Helpers
1215 // -------------------------------------------------------------------------------------------------
1216 function clamp_num(v, min, max) {
1217 if (typeof min === 'number' && !isNaN(min)) v = Math.max(min, v);
1218 if (typeof max === 'number' && !isNaN(max)) v = Math.min(max, v);
1219 return v;
1220 }
1221 function parse_float(v) {
1222 var n = parseFloat(v);
1223 return isNaN(n) ? null : n;
1224 }
1225 function safe_json_parse(str) {
1226 try {
1227 return JSON.parse(str);
1228 } catch (e) {
1229 return null;
1230 }
1231 }
1232 function parse_len_combined(raw, default_unit) {
1233 var s = raw == null ? '' : String(raw).trim();
1234 if (!s) return {
1235 num: '',
1236 unit: default_unit || '%'
1237 };
1238 var m = s.match(/^\s*([\-]?\d+(?:\.\d+)?)\s*([a-z%]*)\s*$/i);
1239 if (!m) {
1240 // If it's not parseable, treat as number and keep default unit.
1241 return {
1242 num: s,
1243 unit: default_unit || '%'
1244 };
1245 }
1246 var num = m[1] ? String(m[1]) : '';
1247 var unit = m[2] ? String(m[2]) : '';
1248 if (!unit) unit = default_unit || '%';
1249 return {
1250 num: num,
1251 unit: unit
1252 };
1253 }
1254 function build_combined(num, unit) {
1255 if (num == null || String(num).trim() === '') return '';
1256 return String(num) + String(unit || '');
1257 }
1258 function emit_input(el) {
1259 if (!el) return;
1260 el.dispatchEvent(new Event('input', {
1261 bubbles: true
1262 }));
1263 }
1264
1265 // -------------------------------------------------------------------------------------------------
1266 // Controller
1267 // -------------------------------------------------------------------------------------------------
1268 class WPBC_Slider_Len_Groups {
1269 /**
1270 * @param {HTMLElement|string} root_el Container (or selector). If omitted, uses document.
1271 * @param {Object} [opts={}]
1272 */
1273 constructor(root_el, opts) {
1274 this.root = root_el ? typeof root_el === 'string' ? d.querySelector(root_el) : root_el : d;
1275 this.opts = Object.assign({
1276 // Strict selectors (NO backward compatibility).
1277 group_selector: '.wpbc_slider_len_group',
1278 value_selector: '[data-wpbc_slider_len_value]',
1279 unit_selector: '[data-wpbc_slider_len_unit]',
1280 range_selector: '[data-wpbc_slider_len_range]',
1281 writer_selector: '[data-wpbc_slider_len_writer]',
1282 default_unit: '%',
1283 fallback_bounds: {
1284 'px': {
1285 min: 0,
1286 max: 512,
1287 step: 1
1288 },
1289 '%': {
1290 min: 0,
1291 max: 100,
1292 step: 1
1293 },
1294 'rem': {
1295 min: 0,
1296 max: 10,
1297 step: 0.1
1298 },
1299 'em': {
1300 min: 0,
1301 max: 10,
1302 step: 0.1
1303 }
1304 },
1305 // Disabled by default for performance.
1306 enable_observer: false,
1307 observer_debounce_ms: 150
1308 }, opts || {});
1309 this._on_input = this._on_input.bind(this);
1310 this._on_change = this._on_change.bind(this);
1311 this._bounds_cache = new WeakMap(); // group -> bounds_map_object
1312 this._observer = null;
1313 this._refresh_tmr = null;
1314 }
1315 init() {
1316 if (!this.root) return this;
1317 this.root.addEventListener('input', this._on_input, true);
1318 this.root.addEventListener('change', this._on_change, true);
1319 if (this.opts.enable_observer && w.MutationObserver) {
1320 this._observer = new MutationObserver(() => {
1321 this._debounced_refresh();
1322 });
1323 this._observer.observe(this.root === d ? d.documentElement : this.root, {
1324 childList: true,
1325 subtree: true
1326 });
1327 }
1328 this.refresh();
1329 return this;
1330 }
1331 destroy() {
1332 if (!this.root) return;
1333 this.root.removeEventListener('input', this._on_input, true);
1334 this.root.removeEventListener('change', this._on_change, true);
1335 if (this._observer) {
1336 this._observer.disconnect();
1337 this._observer = null;
1338 }
1339 if (this._refresh_tmr) {
1340 clearTimeout(this._refresh_tmr);
1341 this._refresh_tmr = null;
1342 }
1343 }
1344 refresh() {
1345 if (!this.root) return;
1346 var scope = this.root === d ? d : this.root;
1347 var groups = Array.prototype.slice.call(scope.querySelectorAll(this.opts.group_selector));
1348 for (var i = 0; i < groups.length; i++) {
1349 this._sync_group_from_writer(groups[i]);
1350 this._apply_bounds_for_current_unit(groups[i]);
1351 }
1352 }
1353
1354 // -------------------------------------------------------------------------------------------------
1355 // Internal
1356 // -------------------------------------------------------------------------------------------------
1357 _debounced_refresh() {
1358 if (this._refresh_tmr) clearTimeout(this._refresh_tmr);
1359 this._refresh_tmr = setTimeout(() => {
1360 this._refresh_tmr = null;
1361 this.refresh();
1362 }, Number(this.opts.observer_debounce_ms) || 0);
1363 }
1364 _find_group(el) {
1365 return el && el.closest ? el.closest(this.opts.group_selector) : null;
1366 }
1367 _get_parts(group) {
1368 if (!group) return null;
1369 return {
1370 group: group,
1371 num: group.querySelector(this.opts.value_selector),
1372 unit: group.querySelector(this.opts.unit_selector),
1373 range: group.querySelector(this.opts.range_selector),
1374 writer: group.querySelector(this.opts.writer_selector)
1375 };
1376 }
1377 _get_default_unit(group) {
1378 var du = group && group.getAttribute ? group.getAttribute('data-wpbc_slider_len_default_unit') : '';
1379 return du ? String(du) : this.opts.default_unit;
1380 }
1381 _get_bounds_map(group) {
1382 if (!group) return null;
1383 if (this._bounds_cache.has(group)) {
1384 return this._bounds_cache.get(group);
1385 }
1386 var raw = group.getAttribute('data-wpbc_slider_len_bounds_map');
1387 var map = raw ? safe_json_parse(raw) : null;
1388 if (!map || typeof map !== 'object') map = null;
1389 this._bounds_cache.set(group, map);
1390 return map;
1391 }
1392 _get_bounds_for_unit(group, unit) {
1393 var map = this._get_bounds_map(group);
1394 if (map && unit && map[unit]) {
1395 return map[unit];
1396 }
1397 return this.opts.fallback_bounds[unit] || this.opts.fallback_bounds['px'];
1398 }
1399 _apply_bounds(parts, bounds) {
1400 if (!parts || !bounds) return;
1401 var min = bounds.min != null ? Number(bounds.min) : null;
1402 var max = bounds.max != null ? Number(bounds.max) : null;
1403 var step = bounds.step != null ? Number(bounds.step) : null;
1404 if (parts.range) {
1405 if (!isNaN(min)) parts.range.min = String(min);
1406 if (!isNaN(max)) parts.range.max = String(max);
1407 if (!isNaN(step)) parts.range.step = String(step);
1408 }
1409 if (parts.num) {
1410 if (!isNaN(min)) parts.num.min = String(min);
1411 if (!isNaN(max)) parts.num.max = String(max);
1412 if (!isNaN(step)) parts.num.step = String(step);
1413 }
1414 }
1415 _apply_bounds_for_current_unit(group) {
1416 var parts = this._get_parts(group);
1417 if (!parts || !parts.unit) return;
1418 var unit = parts.unit.value || this._get_default_unit(group);
1419 var b = this._get_bounds_for_unit(group, unit);
1420 this._apply_bounds(parts, b);
1421
1422 // Clamp current value to new bounds.
1423 var v = parse_float(parts.num && parts.num.value ? parts.num.value : parts.range ? parts.range.value : '');
1424 if (v == null) return;
1425 var min = b && b.min != null ? Number(b.min) : null;
1426 var max = b && b.max != null ? Number(b.max) : null;
1427 v = clamp_num(v, isNaN(min) ? null : min, isNaN(max) ? null : max);
1428 if (parts.num) parts.num.value = String(v);
1429 if (parts.range) parts.range.value = String(v);
1430 this._write_combined(parts, String(v), unit, /*emit*/false);
1431 }
1432 _write_combined(parts, num, unit, emit) {
1433 if (!parts) return;
1434 var combined = build_combined(num, unit);
1435 if (parts.writer) {
1436 // Avoid recursion: mark as internal write.
1437 parts.writer.__wpbc_slider_len_internal = true;
1438 parts.writer.value = combined;
1439 if (emit) emit_input(parts.writer);
1440 parts.writer.__wpbc_slider_len_internal = false;
1441 } else if (parts.num) {
1442 // If writer is missing, at least notify via number input.
1443 if (emit) emit_input(parts.num);
1444 }
1445 }
1446 _sync_group_from_writer(group) {
1447 var parts = this._get_parts(group);
1448 if (!parts || !parts.writer) return;
1449 var raw = String(parts.writer.value || '').trim();
1450 if (!raw) return;
1451 var du = this._get_default_unit(group);
1452 var p = parse_len_combined(raw, du);
1453 if (parts.unit) parts.unit.value = p.unit;
1454 if (parts.num) parts.num.value = p.num;
1455 if (parts.range) parts.range.value = p.num;
1456 }
1457 _on_input(ev) {
1458 var t = ev.target;
1459 if (!t) return;
1460 var group = this._find_group(t);
1461 if (!group) return;
1462 var parts = this._get_parts(group);
1463 if (!parts) return;
1464
1465 // Writer changed externally -> update UI.
1466 if (parts.writer && t === parts.writer) {
1467 if (t.__wpbc_slider_len_internal) return;
1468 this._sync_group_from_writer(group);
1469 this._apply_bounds_for_current_unit(group);
1470 return;
1471 }
1472
1473 // Slider moved -> update number + writer.
1474 if (t.matches && t.matches(this.opts.range_selector)) {
1475 if (parts.num) parts.num.value = t.value;
1476 var unit = parts.unit && parts.unit.value ? parts.unit.value : this._get_default_unit(group);
1477 this._write_combined(parts, t.value, unit, /*emit*/true);
1478 return;
1479 }
1480
1481 // Number typed -> update slider + writer (clamp if slider has bounds).
1482 if (t.matches && t.matches(this.opts.value_selector)) {
1483 var v = parse_float(t.value);
1484 if (v != null && parts.range) {
1485 var rmin = Number(parts.range.min);
1486 var rmax = Number(parts.range.max);
1487 v = clamp_num(v, isNaN(rmin) ? null : rmin, isNaN(rmax) ? null : rmax);
1488 parts.range.value = String(v);
1489 if (String(v) !== t.value) t.value = String(v);
1490 }
1491 var unit2 = parts.unit && parts.unit.value ? parts.unit.value : this._get_default_unit(group);
1492 this._write_combined(parts, t.value, unit2, /*emit*/true);
1493 }
1494 }
1495 _on_change(ev) {
1496 var t = ev.target;
1497 if (!t) return;
1498 var group = this._find_group(t);
1499 if (!group) return;
1500 var parts = this._get_parts(group);
1501 if (!parts) return;
1502
1503 // Unit changed -> update bounds + writer.
1504 if (t.matches && t.matches(this.opts.unit_selector)) {
1505 this._apply_bounds_for_current_unit(group);
1506 var num = parts.num ? parts.num.value : parts.range ? parts.range.value : '';
1507 var unit = t.value || this._get_default_unit(group);
1508 this._write_combined(parts, num, unit, /*emit*/true);
1509 }
1510 }
1511 }
1512
1513 // -------------------------------------------------------------------------------------------------
1514 // Auto-init
1515 // -------------------------------------------------------------------------------------------------
1516 function wpbc_slider_len_groups__auto_init() {
1517 var ROOT = '.wpbc_slider_len_groups';
1518 var nodes = Array.prototype.slice.call(d.querySelectorAll(ROOT)).filter(function (n) {
1519 return !n.parentElement || !n.parentElement.closest(ROOT);
1520 });
1521
1522 // If no explicit containers, install a single document-root instance.
1523 if (!nodes.length) {
1524 if (!d.__wpbc_slider_len_groups_global_instance) {
1525 d.__wpbc_slider_len_groups_global_instance = new WPBC_Slider_Len_Groups(d).init();
1526 }
1527 return;
1528 }
1529 nodes.forEach(function (node) {
1530 if (node.__wpbc_slider_len_groups_instance) return;
1531 node.__wpbc_slider_len_groups_instance = new WPBC_Slider_Len_Groups(node).init();
1532 });
1533 }
1534
1535 // Export globals (manual control if needed).
1536 w.WPBC_Slider_Len_Groups = WPBC_Slider_Len_Groups;
1537 w.WPBC_Slider_Len_AutoInit = wpbc_slider_len_groups__auto_init;
1538
1539 // DOM-ready auto init.
1540 if (d.readyState === 'loading') {
1541 d.addEventListener('DOMContentLoaded', wpbc_slider_len_groups__auto_init, {
1542 once: true
1543 });
1544 } else {
1545 wpbc_slider_len_groups__auto_init();
1546 }
1547 })(window, document);
1548
1549 /* globals window, document */
1550 /**
1551 * WPBC Slider Range Groups
1552 *
1553 * Universal, dependency-free controller that keeps a "range + number" pair in sync:
1554 * - number input (data-wpbc_slider_range_value)
1555 * - range slider (data-wpbc_slider_range_range)
1556 * - writer input (data-wpbc_slider_range_writer) [optional]
1557 *
1558 * If writer exists: number/slider update writer and emit 'input' on writer (bubbles).
1559 * If writer is missing: emits 'input' on the number input.
1560 * If writer changes externally: updates number/slider.
1561 *
1562 * Markup expectations (minimal):
1563 * <div class="wpbc_slider_range_group">
1564 * <input type="number" data-wpbc_slider_range_value>
1565 * <input type="range" data-wpbc_slider_range_range>
1566 * <!-- optional -->
1567 * <input type="text" data-wpbc_slider_range_writer style="display:none;">
1568 * </div>
1569 *
1570 * Performance notes:
1571 * - MutationObserver is DISABLED by default.
1572 * - If your UI re-renders and inserts new groups dynamically, call:
1573 * WPBC_Slider_Range_AutoInit(); OR instance.refresh();
1574 * Or enable observer via: new WPBC_Slider_Range_Groups(root, { enable_observer:true }).init();
1575 *
1576 * Public API (instance methods):
1577 * - init(), destroy(), refresh()
1578 *
1579 * @version 2026-01-25
1580 * @since 2026-01-25
1581 * @file ../includes/__js/admin/slider_groups/wpbc_range_groups.js
1582 */
1583 (function (w, d) {
1584 'use strict';
1585
1586 // -------------------------------------------------------------------------------------------------
1587 // Helpers
1588 // -------------------------------------------------------------------------------------------------
1589 function clamp_num(v, min, max) {
1590 if (typeof min === 'number' && !isNaN(min)) v = Math.max(min, v);
1591 if (typeof max === 'number' && !isNaN(max)) v = Math.min(max, v);
1592 return v;
1593 }
1594 function parse_float(v) {
1595 var n = parseFloat(v);
1596 return isNaN(n) ? null : n;
1597 }
1598 function emit_input(el) {
1599 if (!el) return;
1600 el.dispatchEvent(new Event('input', {
1601 bubbles: true
1602 }));
1603 }
1604
1605 // -------------------------------------------------------------------------------------------------
1606 // Controller
1607 // -------------------------------------------------------------------------------------------------
1608 class WPBC_Slider_Range_Groups {
1609 /**
1610 * @param {HTMLElement|string} root_el Container (or selector). If omitted, uses document.
1611 * @param {Object} [opts={}]
1612 */
1613 constructor(root_el, opts) {
1614 this.root = root_el ? typeof root_el === 'string' ? d.querySelector(root_el) : root_el : d;
1615 this.opts = Object.assign({
1616 // Strict selectors (NO backward compatibility).
1617 group_selector: '.wpbc_slider_range_group',
1618 value_selector: '[data-wpbc_slider_range_value]',
1619 range_selector: '[data-wpbc_slider_range_range]',
1620 writer_selector: '[data-wpbc_slider_range_writer]',
1621 // Disabled by default for performance.
1622 enable_observer: false,
1623 observer_debounce_ms: 150
1624 }, opts || {});
1625 this._on_input = this._on_input.bind(this);
1626 this._on_change = this._on_change.bind(this);
1627 this._observer = null;
1628 this._refresh_tmr = null;
1629 }
1630 init() {
1631 if (!this.root) return this;
1632 this.root.addEventListener('input', this._on_input, true);
1633 this.root.addEventListener('change', this._on_change, true);
1634 if (this.opts.enable_observer && w.MutationObserver) {
1635 this._observer = new MutationObserver(() => {
1636 this._debounced_refresh();
1637 });
1638 this._observer.observe(this.root === d ? d.documentElement : this.root, {
1639 childList: true,
1640 subtree: true
1641 });
1642 }
1643 this.refresh();
1644 return this;
1645 }
1646 destroy() {
1647 if (!this.root) return;
1648 this.root.removeEventListener('input', this._on_input, true);
1649 this.root.removeEventListener('change', this._on_change, true);
1650 if (this._observer) {
1651 this._observer.disconnect();
1652 this._observer = null;
1653 }
1654 if (this._refresh_tmr) {
1655 clearTimeout(this._refresh_tmr);
1656 this._refresh_tmr = null;
1657 }
1658 }
1659 refresh() {
1660 if (!this.root) return;
1661 var scope = this.root === d ? d : this.root;
1662 var groups = Array.prototype.slice.call(scope.querySelectorAll(this.opts.group_selector));
1663 for (var i = 0; i < groups.length; i++) {
1664 this._sync_from_writer(groups[i]);
1665 this._clamp_to_range(groups[i]);
1666 }
1667 }
1668
1669 // -------------------------------------------------------------------------------------------------
1670 // Internal
1671 // -------------------------------------------------------------------------------------------------
1672 _debounced_refresh() {
1673 if (this._refresh_tmr) clearTimeout(this._refresh_tmr);
1674 this._refresh_tmr = setTimeout(() => {
1675 this._refresh_tmr = null;
1676 this.refresh();
1677 }, Number(this.opts.observer_debounce_ms) || 0);
1678 }
1679 _find_group(el) {
1680 return el && el.closest ? el.closest(this.opts.group_selector) : null;
1681 }
1682 _get_parts(group) {
1683 if (!group) return null;
1684 return {
1685 group: group,
1686 num: group.querySelector(this.opts.value_selector),
1687 range: group.querySelector(this.opts.range_selector),
1688 writer: group.querySelector(this.opts.writer_selector)
1689 };
1690 }
1691 _write(parts, value, emit) {
1692 if (!parts) return;
1693 if (parts.writer) {
1694 parts.writer.__wpbc_slider_range_internal = true;
1695 parts.writer.value = String(value);
1696 if (emit) emit_input(parts.writer);
1697 parts.writer.__wpbc_slider_range_internal = false;
1698 } else if (parts.num) {
1699 // If writer is missing, at least notify via number input.
1700 if (emit) emit_input(parts.num);
1701 }
1702 }
1703 _sync_from_writer(group) {
1704 var parts = this._get_parts(group);
1705 if (!parts || !parts.writer) return;
1706 var raw = String(parts.writer.value || '').trim();
1707 if (!raw) return;
1708 if (parts.num) parts.num.value = raw;
1709 if (parts.range) parts.range.value = raw;
1710 }
1711 _clamp_to_range(group) {
1712 var parts = this._get_parts(group);
1713 if (!parts || !parts.range || !parts.num) return;
1714 var v = parse_float(parts.num.value);
1715 if (v == null) return;
1716 var min = Number(parts.range.min);
1717 var max = Number(parts.range.max);
1718 var vv = clamp_num(v, isNaN(min) ? null : min, isNaN(max) ? null : max);
1719 if (String(vv) !== parts.num.value) parts.num.value = String(vv);
1720 parts.range.value = String(vv);
1721 }
1722 _on_input(ev) {
1723 var t = ev.target;
1724 if (!t) return;
1725 var group = this._find_group(t);
1726 if (!group) return;
1727 var parts = this._get_parts(group);
1728 if (!parts) return;
1729
1730 // Writer changed externally -> update UI.
1731 if (parts.writer && t === parts.writer) {
1732 if (t.__wpbc_slider_range_internal) return;
1733 this._sync_from_writer(group);
1734 this._clamp_to_range(group);
1735 return;
1736 }
1737
1738 // Range moved -> update number + writer.
1739 if (t.matches && t.matches(this.opts.range_selector)) {
1740 if (parts.num) parts.num.value = t.value;
1741 this._write(parts, t.value, /*emit*/true);
1742 return;
1743 }
1744
1745 // Number typed -> update range + writer (clamp by slider bounds).
1746 if (t.matches && t.matches(this.opts.value_selector)) {
1747 if (parts.range) {
1748 var v = parse_float(t.value);
1749 if (v != null) {
1750 var min = Number(parts.range.min);
1751 var max = Number(parts.range.max);
1752 v = clamp_num(v, isNaN(min) ? null : min, isNaN(max) ? null : max);
1753 parts.range.value = String(v);
1754 if (String(v) !== t.value) t.value = String(v);
1755 }
1756 }
1757 this._write(parts, t.value, /*emit*/true);
1758 }
1759 }
1760 _on_change(ev) {
1761 // No special "change" handling needed currently; kept for symmetry/future.
1762 }
1763 }
1764
1765 // -------------------------------------------------------------------------------------------------
1766 // Auto-init
1767 // -------------------------------------------------------------------------------------------------
1768 function wpbc_slider_range_groups__auto_init() {
1769 var ROOT = '.wpbc_slider_range_groups';
1770 var nodes = Array.prototype.slice.call(d.querySelectorAll(ROOT)).filter(function (n) {
1771 return !n.parentElement || !n.parentElement.closest(ROOT);
1772 });
1773 if (!nodes.length) {
1774 if (!d.__wpbc_slider_range_groups_global_instance) {
1775 d.__wpbc_slider_range_groups_global_instance = new WPBC_Slider_Range_Groups(d).init();
1776 }
1777 return;
1778 }
1779 nodes.forEach(function (node) {
1780 if (node.__wpbc_slider_range_groups_instance) return;
1781 node.__wpbc_slider_range_groups_instance = new WPBC_Slider_Range_Groups(node).init();
1782 });
1783 }
1784
1785 // Export globals.
1786 w.WPBC_Slider_Range_Groups = WPBC_Slider_Range_Groups;
1787 w.WPBC_Slider_Range_AutoInit = wpbc_slider_range_groups__auto_init;
1788 if (d.readyState === 'loading') {
1789 d.addEventListener('DOMContentLoaded', wpbc_slider_range_groups__auto_init, {
1790 once: true
1791 });
1792 } else {
1793 wpbc_slider_range_groups__auto_init();
1794 }
1795 })(window, document);
1796
1797 /**
1798 * Booking Calendar — Generic UI Tabs Utility (JS)
1799 *
1800 * Purpose: Lightweight, dependency-free tabs controller for any small tab group in admin UIs.
1801 * - Auto-initializes groups marked with data-wpbc-tabs.
1802 * - Assigns ARIA roles and toggles aria-selected/aria-hidden/tabindex.
1803 * - Supports keyboard navigation (Left/Right/Home/End).
1804 * - Public API: window.wpbc_ui_tabs.{init_on, init_group, set_active}
1805 * - Emits 'wpbc:tabs:change' on the group root when the active tab changes.
1806 *
1807 * Markup contract:
1808 * - Root: [data-wpbc-tabs]
1809 * - Tabs: [data-wpbc-tab-key="K"]
1810 * - Panels: [data-wpbc-tab-panel="K"]
1811 *
1812 * @package Booking Calendar
1813 * @subpackage Admin\UI
1814 * @since 11.0.0
1815 * @version 1.0.0
1816 * @see /includes/__js/admin/ui_tabs/ui_tabs.js
1817 *
1818 *
1819 * How it works:
1820 * - Root node must have [data-wpbc-tabs] attribute (any value).
1821 * - Tab buttons must carry [data-wpbc-tab-key="..."] (unique per group).
1822 * - Panels must carry [data-wpbc-tab-panel="..."] with matching keys.
1823 * - Adds WAI-ARIA roles and aria-selected/hidden wiring.
1824 *
1825 * <div data-wpbc-tabs="column-styles" data-wpbc-tab-active="1" class="wpbc_ui_tabs_root" >
1826 * <!-- Top Tabs -->
1827 * <div data-wpbc-tablist="" role="tablist" class=" wpbc_ui_el__horis_top_bar__wrapper" >
1828 * <div class="wpbc_ui_el__horis_top_bar__content">
1829 * <h2 class="wpbc_ui_el__horis_nav_label">Column:</h2>
1830 *
1831 * <div class="wpbc_ui_el__horis_nav_item wpbc_ui_el__horis_nav_item__1">
1832 * <a
1833 * data-wpbc-tab-key="1"
1834 * aria-selected="true" role="tab" tabindex="0" aria-controls="wpbc_tab_panel_col_1"
1835 *
1836 * href="javascript:void(0);"
1837 * class="wpbc_ui_el__horis_nav_item__a wpbc_ui_el__horis_nav_item__single"
1838 * id="wpbc_tab_col_1"
1839 * title="Column 1"
1840 * ><span class="wpbc_ui_el__horis_nav_title">Title 1</span></a>
1841 * </div>
1842 * ...
1843 * </div>
1844 * </div>
1845 * <!-- Tabs Content -->
1846 * <div class="wpbc_tab__panel group__fields" data-wpbc-tab-panel="1" id="wpbc_tab_panel_col_1" role="tabpanel" aria-labelledby="wpbc_tab_col_1">
1847 * ...
1848 * </div>
1849 * ...
1850 * </div>
1851 *
1852 * Public API:
1853 * - wpbc_ui_tabs.init_on(root_or_selector) // find and init groups within a container
1854 * - wpbc_ui_tabs.init_group(root_el) // init a single group root
1855 * - wpbc_ui_tabs.set_active(root_el, key) // programmatically change active tab
1856 *
1857 * Events:
1858 * - Dispatches CustomEvent 'wpbc:tabs:change' on root when tab changes:
1859 * detail: { active_key: '2', prev_key: '1' }
1860 *
1861 * Switch a local (generic) tabs group to tab 3: var group = document.querySelector('[data-wpbc-tabs="column-styles"]'); if ( group ) { wpbc_ui_tabs.set_active(group, '3'); }
1862 */
1863 (function (w) {
1864 'use strict';
1865
1866 if (w.wpbc_ui_tabs) {
1867 return;
1868 }
1869
1870 /**
1871 * Internal: toggle active state.
1872 *
1873 * @param {HTMLElement} root_el
1874 * @param {string} key
1875 * @param {boolean} should_emit
1876 */
1877 function set_active_internal(root_el, key, should_emit) {
1878 var tab_btns = root_el.querySelectorAll('[data-wpbc-tab-key]');
1879 var panels = root_el.querySelectorAll('[data-wpbc-tab-panel]');
1880 var prev_key = root_el.getAttribute('data-wpbc-tab-active') || null;
1881 if (String(prev_key) === String(key)) {
1882 return;
1883 }
1884
1885 // Buttons: aria + class
1886 for (var i = 0; i < tab_btns.length; i++) {
1887 var btn = tab_btns[i];
1888 var b_key = btn.getAttribute('data-wpbc-tab-key');
1889 var is_on = String(b_key) === String(key);
1890 btn.setAttribute('role', 'tab');
1891 btn.setAttribute('aria-selected', is_on ? 'true' : 'false');
1892 btn.setAttribute('tabindex', is_on ? '0' : '-1');
1893 if (is_on) {
1894 btn.classList.add('active');
1895 } else {
1896 btn.classList.remove('active');
1897 }
1898 }
1899
1900 // Panels: aria + visibility
1901 for (var j = 0; j < panels.length; j++) {
1902 var pn = panels[j];
1903 var pkey = pn.getAttribute('data-wpbc-tab-panel');
1904 var show = String(pkey) === String(key);
1905 pn.setAttribute('role', 'tabpanel');
1906 pn.setAttribute('aria-hidden', show ? 'false' : 'true');
1907 if (show) {
1908 pn.removeAttribute('hidden');
1909 } else {
1910 pn.setAttribute('hidden', '');
1911 }
1912 }
1913 root_el.setAttribute('data-wpbc-tab-active', String(key));
1914 if (should_emit) {
1915 try {
1916 var ev = new w.CustomEvent('wpbc:tabs:change', {
1917 bubbles: true,
1918 detail: {
1919 active_key: String(key),
1920 prev_key: prev_key
1921 }
1922 });
1923 root_el.dispatchEvent(ev);
1924 } catch (_e) {}
1925 }
1926 }
1927
1928 /**
1929 * Internal: get ordered keys from buttons.
1930 *
1931 * @param {HTMLElement} root_el
1932 * @returns {string[]}
1933 */
1934 function get_keys(root_el) {
1935 var list = [];
1936 var btns = root_el.querySelectorAll('[data-wpbc-tab-key]');
1937 for (var i = 0; i < btns.length; i++) {
1938 var k = btns[i].getAttribute('data-wpbc-tab-key');
1939 if (k != null && k !== '') {
1940 list.push(String(k));
1941 }
1942 }
1943 return list;
1944 }
1945
1946 /**
1947 * Internal: move focus between tabs using keyboard.
1948 *
1949 * @param {HTMLElement} root_el
1950 * @param {number} dir +1 (next) / -1 (prev)
1951 */
1952 function focus_relative(root_el, dir) {
1953 var keys = get_keys(root_el);
1954 var current = root_el.getAttribute('data-wpbc-tab-active') || keys[0] || null;
1955 var idx = Math.max(0, keys.indexOf(String(current)));
1956 var next = keys[(idx + (dir > 0 ? 1 : keys.length - 1)) % keys.length];
1957 var next_btn = root_el.querySelector('[data-wpbc-tab-key="' + next + '"]');
1958 if (next_btn) {
1959 next_btn.focus();
1960 set_active_internal(root_el, next, true);
1961 }
1962 }
1963
1964 /**
1965 * Initialize a single tabs group root.
1966 *
1967 * @param {HTMLElement} root_el
1968 */
1969 function init_group(root_el) {
1970 if (!root_el || root_el.__wpbc_tabs_inited) {
1971 return;
1972 }
1973 root_el.__wpbc_tabs_inited = true;
1974
1975 // Roles
1976 var tablist = root_el.querySelector('[data-wpbc-tablist]') || root_el;
1977 tablist.setAttribute('role', 'tablist');
1978
1979 // Default active: from attribute or first button
1980 var keys = get_keys(root_el);
1981 var def = root_el.getAttribute('data-wpbc-tab-active') || keys[0] || '1';
1982 set_active_internal(root_el, def, false);
1983
1984 // Clicks
1985 root_el.addEventListener('click', function (e) {
1986 var btn = e.target.closest ? e.target.closest('[data-wpbc-tab-key]') : null;
1987 if (!btn || !root_el.contains(btn)) {
1988 return;
1989 }
1990 e.preventDefault();
1991 var key = btn.getAttribute('data-wpbc-tab-key');
1992 if (key != null) {
1993 set_active_internal(root_el, key, true);
1994 }
1995 }, true);
1996
1997 // Keyboard (Left/Right/Home/End)
1998 root_el.addEventListener('keydown', function (e) {
1999 var tgt = e.target;
2000 if (!tgt || !tgt.hasAttribute || !tgt.hasAttribute('data-wpbc-tab-key')) {
2001 return;
2002 }
2003 switch (e.key) {
2004 case 'ArrowLeft':
2005 e.preventDefault();
2006 focus_relative(root_el, -1);
2007 break;
2008 case 'ArrowRight':
2009 e.preventDefault();
2010 focus_relative(root_el, +1);
2011 break;
2012 case 'Home':
2013 e.preventDefault();
2014 set_active_internal(root_el, get_keys(root_el)[0] || '1', true);
2015 break;
2016 case 'End':
2017 e.preventDefault();
2018 var ks = get_keys(root_el);
2019 set_active_internal(root_el, ks[ks.length - 1] || '1', true);
2020 break;
2021 }
2022 }, true);
2023 }
2024
2025 /**
2026 * Initialize all groups within a container (or document).
2027 *
2028 * @param {HTMLElement|string|null} container
2029 */
2030 function init_on(container) {
2031 var ctx = container ? typeof container === 'string' ? document.querySelector(container) : container : document;
2032 if (!ctx) {
2033 return;
2034 }
2035 var groups = ctx.querySelectorAll('[data-wpbc-tabs]');
2036 for (var i = 0; i < groups.length; i++) {
2037 init_group(groups[i]);
2038 }
2039 }
2040
2041 /**
2042 * Programmatically set active tab by key.
2043 *
2044 * @param {HTMLElement} root_el
2045 * @param {string|number} key
2046 */
2047 function set_active(root_el, key) {
2048 if (root_el && root_el.hasAttribute && root_el.hasAttribute('data-wpbc-tabs')) {
2049 set_active_internal(root_el, String(key), true);
2050 }
2051 }
2052
2053 // Public API (snake_case)
2054 w.wpbc_ui_tabs = {
2055 init_on: init_on,
2056 init_group: init_group,
2057 set_active: set_active
2058 };
2059
2060 // Auto-init on DOM ready
2061 if (document.readyState === 'loading') {
2062 document.addEventListener('DOMContentLoaded', function () {
2063 init_on(document);
2064 });
2065 } else {
2066 init_on(document);
2067 }
2068 })(window);
2069 //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Rpc3QvYWxsL19vdXQvd3BiY19hbGxfYWRtaW4uanMiLCJuYW1lcyI6WyJ3cGJjX2JsaW5rX2VsZW1lbnQiLCJlbGVtZW50X3RvX2JsaW5rIiwiaG93X21hbnlfdGltZXMiLCJob3dfbG9uZ190b19ibGluayIsImkiLCJqUXVlcnkiLCJmYWRlT3V0IiwiZmFkZUluIiwiYW5pbWF0ZSIsIm9wYWNpdHkiLCJ3cGJjX2J1dHRvbl9fcmVtb3ZlX3NwaW4iLCJidXR0b25fY2xpY2tlZF9lbGVtZW50X2lkIiwicHJldmlvc19jbGFzc2VzIiwidW5kZWZpbmVkIiwiakVsZW1lbnQiLCJsZW5ndGgiLCJ3cGJjX2J1dHRvbl9kaXNhYmxlX2xvYWRpbmdfaWNvbiIsImdldCIsIndwYmNfYnV0dG9uX2VuYWJsZV9sb2FkaW5nX2ljb24iLCJ0aGlzX2J1dHRvbiIsImpCdXR0b24iLCJqSWNvbiIsImZpbmQiLCJhdHRyIiwicmVtb3ZlQ2xhc3MiLCJhZGRDbGFzcyIsInByZXZpb3VzX29uY2xpY2siLCJ3cGJjX3VpX2VsX19yYWRpb19jb250YWluZXJfc2VsZWN0aW9uIiwiX3RoaXMiLCJpcyIsInBhcmVudHMiLCJyZW1vdmVBdHRyIiwid3BiY191aV9lbF9fcmFkaW9fY29udGFpbmVyX2NsaWNrIiwiaGFzQ2xhc3MiLCJqX3JhZGlvIiwicHJvcCIsInRyaWdnZXIiLCJ3cGJjX2NoZWNrX2Z1bGxfc2NyZWVuX21vZGUiLCJ3cGJjX2NoZWNrX2J1dHRvbnNfbWF4X21pbl9pbl9mdWxsX3NjcmVlbl9tb2RlIiwiZG9jdW1lbnQiLCJyZWFkeSIsIndwYmNfZGVmaW5lX2dtYWlsX2NoZWNrYm94X3NlbGVjdGlvbiIsIiQiLCJjaGVja3MiLCJmaXJzdCIsImxhc3QiLCJjaGVja2VkIiwic2xpY2VkIiwibGFzdENsaWNrZWQiLCJvbiIsImUiLCJzaGlmdEtleSIsImNsb3Nlc3QiLCJmaWx0ZXIiLCJpbmRleCIsInNsaWNlIiwidW5jaGVja2VkIiwibm90IiwiY2hpbGRyZW4iLCJldmVudCIsIiR0aGlzIiwiJHRhYmxlIiwiY29udHJvbENoZWNrZWQiLCJ0b2dnbGUiLCJkYXRhIiwiZ2V0U2VsZWN0aW9uIiwicmVtb3ZlQWxsUmFuZ2VzIiwid3BiY19zaG93X2hpZGVfYWN0aW9uX2J1dHRvbnNfZm9yX3NlbGVjdGVkX2Jvb2tpbmdzIiwid3BiY19nZXRfc2VsZWN0ZWRfcm93X2lkIiwiY2hlY2tib3hlcyIsInNlbGVjdGVkX2lkIiwiZWFjaCIsImtleSIsImNoZWNrYm94IiwiZWxlbWVudF9pZCIsIndwYmNfZ2V0X3Jvd19pZF9mcm9tX2VsZW1lbnQiLCJwdXNoIiwidGhpc19pbmJvdW5kX2VsZW1lbnQiLCJwYXJzZUludCIsInJlcGxhY2UiLCJzZWxlY3RlZF9yb3dzX2FyciIsInNob3ciLCJoaWRlIiwid3BiY19hZG1pbl91aV9fc2lkZWJhcl9sZWZ0X19kb19tYXgiLCJ3cGJjX2FkbWluX3VpX19zaWRlYmFyX2xlZnRfX2RvX21pbiIsIndwYmNfYWRtaW5fdWlfX3NpZGViYXJfbGVmdF9fZG9fY29tcGFjdCIsIndwYmNfYWRtaW5fdWlfX3NpZGViYXJfbGVmdF9fZG9faGlkZSIsIndwYmNfYWRtaW5fdWlfX3NpZGViYXJfbGVmdF9fc2hvd19zZWN0aW9uIiwibWVudV90b19zaG93Iiwid3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fbWF4Iiwid3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fbWluIiwid3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fY29tcGFjdCIsIndwYmNfYWRtaW5fdWlfX3NpZGViYXJfcmlnaHRfX2RvX2hpZGUiLCJ3cGJjX2FkbWluX3VpX19zaWRlYmFyX3JpZ2h0X19zaG93X3NlY3Rpb24iLCJ3cGJjX3VybF9nZXRfYW5jaG9yc19hcnIiLCJoYXNoZXMiLCJ3aW5kb3ciLCJsb2NhdGlvbiIsImhhc2giLCJoYXNoZXNfYXJyIiwic3BsaXQiLCJyZXN1bHQiLCJoYXNoZXNfYXJyX2xlbmd0aCIsIndwYmNfYWRtaW5fdWlfX3JlZGlyZWN0X2xlZ2FjeV9nZW5lcmFsX2F2YWlsYWJpbGl0eV91cmwiLCJ3cGJjX2FkbWluX3VpX19kb19leHBhbmRfc2VjdGlvbiIsInNldFRpbWVvdXQiLCJocmVmIiwiaW5kZXhPZiIsImFuY2hvcnNfYXJyIiwiYW5jaG9yc19hcnJfbGVuZ3RoIiwib25lX2FuY2hvcl9wcm9wX3ZhbHVlIiwic2VjdGlvbl90b19zaG93Iiwic2VjdGlvbl9pZF90b19zaG93Iiwic2VsZWN0ZWRfdGl0bGUiLCJ0ZXh0IiwiY29udGFpbmVyX3RvX2hpZGVfY2xhc3MiLCJ0YXJnZXRPZmZzZXQiLCJ3cGJjX3Njcm9sbF90byIsInNlY3Rpb25faWRfdGFiIiwic3Vic3RyaW5nIiwidmFsIiwid3BiY19hZG1pbl91aV9fZG9fX2FuY2hvcl9fYW5vdGhlcl9hY3Rpb25zIiwid3BiY19hZG1pbl91aV9faXNfaW5fbW9iaWxlX3NjcmVlbl9zaXplIiwid3BiY19hZG1pbl91aV9faXNfaW5fdGhpc19zY3JlZW5fc2l6ZSIsInNpemUiLCJzY3JlZW4iLCJ3aWR0aCIsIndwYmNfYWRtaW5fdWlfX2RvX19vcGVuX3VybF9fZXhwYW5kX3NlY3Rpb24iLCJ1cmwiLCJzZWN0aW9uX2lkIiwidGhpc19hbmNob3IiLCJ0aGlzX2FuY2hvcl9wcm9wX3ZhbHVlIiwic2VjdGlvbl9hY3Rpb24iLCJ3cGJjX2NvcHlfdGV4dF90b19jbGlwYnJkX2Zyb21fZWxlbWVudCIsImh0bWxfZWxlbWVudF9pZCIsImNvcHlUZXh0IiwiZ2V0RWxlbWVudEJ5SWQiLCJzZWxlY3QiLCJzZXRTZWxlY3Rpb25SYW5nZSIsImlzX2NvcGllZCIsIndwYmNfY29weV90ZXh0X3RvX2NsaXBicmQiLCJ2YWx1ZSIsImNvbnNvbGUiLCJlcnJvciIsIm5hdmlnYXRvciIsImNsaXBib2FyZCIsIndwYmNfZmFsbGJhY2tfY29weV90ZXh0X3RvX2NsaXBicmQiLCJ3cml0ZVRleHQiLCJ0aGVuIiwiZXJyIiwiY29udGFpbmVyIiwiY3JlYXRlRWxlbWVudCIsImlubmVySFRNTCIsInN0eWxlIiwicG9zaXRpb24iLCJwb2ludGVyRXZlbnRzIiwiYWN0aXZlU2hlZXRzIiwiQXJyYXkiLCJwcm90b3R5cGUiLCJjYWxsIiwic3R5bGVTaGVldHMiLCJzaGVldCIsImRpc2FibGVkIiwiYm9keSIsImFwcGVuZENoaWxkIiwicmFuZ2UiLCJjcmVhdGVSYW5nZSIsInNlbGVjdE5vZGUiLCJhZGRSYW5nZSIsImV4ZWNDb21tYW5kIiwiYWN0aXZlU2hlZXRzX2xlbmd0aCIsInJlbW92ZUNoaWxkIiwidyIsImQiLCJXUEJDX0NvbGxhcHNpYmxlX0dyb3VwcyIsImNvbnN0cnVjdG9yIiwicm9vdF9lbCIsIm9wdHMiLCJyb290IiwicXVlcnlTZWxlY3RvciIsIk9iamVjdCIsImFzc2lnbiIsImdyb3VwX3NlbGVjdG9yIiwiaGVhZGVyX3NlbGVjdG9yIiwiZmllbGRzX3NlbGVjdG9yIiwib3Blbl9jbGFzcyIsImV4Y2x1c2l2ZSIsIl9vbl9jbGljayIsImJpbmQiLCJfb25fa2V5ZG93biIsIl9ncm91cHMiLCJfb2JzZXJ2ZXIiLCJpbml0IiwicXVlcnlTZWxlY3RvckFsbCIsImFkZEV2ZW50TGlzdGVuZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwicmVmcmVzaCIsIm9ic2VydmUiLCJjaGlsZExpc3QiLCJzdWJ0cmVlIiwiX3N5bmNfYWxsX2FyaWEiLCJkZXN0cm95IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImRpc2Nvbm5lY3QiLCJpc19leGNsdXNpdmUiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsIm1hdGNoZXMiLCJpc19vcGVuIiwiZ3JvdXAiLCJleHBhbmQiLCJkb19leGNsdXNpdmUiLCJmb3JFYWNoIiwiZyIsIl9zZXRfb3BlbiIsImNvbGxhcHNlIiwib3Blbl9ieV9pbmRleCIsIm9wZW5fYnlfaGVhZGluZyIsInQiLCJTdHJpbmciLCJ0b0xvd2VyQ2FzZSIsIm1hdGNoIiwiaCIsInRleHRDb250ZW50IiwiZXYiLCJidG4iLCJ0YXJnZXQiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BQcm9wYWdhdGlvbiIsImhlYWRlcnMiLCJtYXAiLCJCb29sZWFuIiwiaWR4IiwibmV4dF9pZHgiLCJNYXRoIiwibWluIiwibWF4IiwiZm9jdXMiLCJfc3luY19ncm91cF9hcmlhIiwiaGVhZGVyIiwicGFuZWxzIiwiZWwiLCJzZXRBdHRyaWJ1dGUiLCJpZHMiLCJwIiwiaWQiLCJfZ2VuZXJhdGVfaWQiLCJqb2luIiwiaGlkZGVuIiwib3BlbiIsImFjdGl2ZUVsZW1lbnQiLCJldl9uYW1lIiwiZGlzcGF0Y2hFdmVudCIsIkN1c3RvbUV2ZW50IiwiYnViYmxlcyIsImRldGFpbCIsImluc3RhbmNlIiwicHJlZml4Iiwid3BiY19jb2xsYXBzaWJsZV9fYXV0b19pbml0IiwiUk9PVCIsIm5vZGVzIiwibiIsInBhcmVudEVsZW1lbnQiLCJub2RlIiwiX193cGJjX2NvbGxhcHNpYmxlX2luc3RhbmNlIiwiV1BCQ19Db2xsYXBzaWJsZV9BdXRvSW5pdCIsInJlYWR5U3RhdGUiLCJvbmNlIiwiY2xhbXBfbnVtIiwidiIsImlzTmFOIiwicGFyc2VfZmxvYXQiLCJwYXJzZUZsb2F0Iiwic2FmZV9qc29uX3BhcnNlIiwic3RyIiwiSlNPTiIsInBhcnNlIiwicGFyc2VfbGVuX2NvbWJpbmVkIiwicmF3IiwiZGVmYXVsdF91bml0IiwicyIsInRyaW0iLCJudW0iLCJ1bml0IiwibSIsImJ1aWxkX2NvbWJpbmVkIiwiZW1pdF9pbnB1dCIsIkV2ZW50IiwiV1BCQ19TbGlkZXJfTGVuX0dyb3VwcyIsInZhbHVlX3NlbGVjdG9yIiwidW5pdF9zZWxlY3RvciIsInJhbmdlX3NlbGVjdG9yIiwid3JpdGVyX3NlbGVjdG9yIiwiZmFsbGJhY2tfYm91bmRzIiwic3RlcCIsImVuYWJsZV9vYnNlcnZlciIsIm9ic2VydmVyX2RlYm91bmNlX21zIiwiX29uX2lucHV0IiwiX29uX2NoYW5nZSIsIl9ib3VuZHNfY2FjaGUiLCJXZWFrTWFwIiwiX3JlZnJlc2hfdG1yIiwiX2RlYm91bmNlZF9yZWZyZXNoIiwiZG9jdW1lbnRFbGVtZW50IiwiY2xlYXJUaW1lb3V0Iiwic2NvcGUiLCJncm91cHMiLCJfc3luY19ncm91cF9mcm9tX3dyaXRlciIsIl9hcHBseV9ib3VuZHNfZm9yX2N1cnJlbnRfdW5pdCIsIk51bWJlciIsIl9maW5kX2dyb3VwIiwiX2dldF9wYXJ0cyIsIndyaXRlciIsIl9nZXRfZGVmYXVsdF91bml0IiwiZHUiLCJnZXRBdHRyaWJ1dGUiLCJfZ2V0X2JvdW5kc19tYXAiLCJoYXMiLCJzZXQiLCJfZ2V0X2JvdW5kc19mb3JfdW5pdCIsIl9hcHBseV9ib3VuZHMiLCJwYXJ0cyIsImJvdW5kcyIsImIiLCJfd3JpdGVfY29tYmluZWQiLCJlbWl0IiwiY29tYmluZWQiLCJfX3dwYmNfc2xpZGVyX2xlbl9pbnRlcm5hbCIsInJtaW4iLCJybWF4IiwidW5pdDIiLCJ3cGJjX3NsaWRlcl9sZW5fZ3JvdXBzX19hdXRvX2luaXQiLCJfX3dwYmNfc2xpZGVyX2xlbl9ncm91cHNfZ2xvYmFsX2luc3RhbmNlIiwiX193cGJjX3NsaWRlcl9sZW5fZ3JvdXBzX2luc3RhbmNlIiwiV1BCQ19TbGlkZXJfTGVuX0F1dG9Jbml0IiwiV1BCQ19TbGlkZXJfUmFuZ2VfR3JvdXBzIiwiX3N5bmNfZnJvbV93cml0ZXIiLCJfY2xhbXBfdG9fcmFuZ2UiLCJfd3JpdGUiLCJfX3dwYmNfc2xpZGVyX3JhbmdlX2ludGVybmFsIiwidnYiLCJ3cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfX2F1dG9faW5pdCIsIl9fd3BiY19zbGlkZXJfcmFuZ2VfZ3JvdXBzX2dsb2JhbF9pbnN0YW5jZSIsIl9fd3BiY19zbGlkZXJfcmFuZ2VfZ3JvdXBzX2luc3RhbmNlIiwiV1BCQ19TbGlkZXJfUmFuZ2VfQXV0b0luaXQiLCJ3cGJjX3VpX3RhYnMiLCJzZXRfYWN0aXZlX2ludGVybmFsIiwic2hvdWxkX2VtaXQiLCJ0YWJfYnRucyIsInByZXZfa2V5IiwiYl9rZXkiLCJpc19vbiIsImFkZCIsInJlbW92ZSIsImoiLCJwbiIsInBrZXkiLCJyZW1vdmVBdHRyaWJ1dGUiLCJhY3RpdmVfa2V5IiwiX2UiLCJnZXRfa2V5cyIsImxpc3QiLCJidG5zIiwiayIsImZvY3VzX3JlbGF0aXZlIiwiZGlyIiwia2V5cyIsImN1cnJlbnQiLCJuZXh0IiwibmV4dF9idG4iLCJpbml0X2dyb3VwIiwiX193cGJjX3RhYnNfaW5pdGVkIiwidGFibGlzdCIsImRlZiIsInRndCIsImhhc0F0dHJpYnV0ZSIsImtzIiwiaW5pdF9vbiIsImN0eCIsInNldF9hY3RpdmUiXSwic291cmNlcyI6WyJ1aV9lbGVtZW50cy5qcyIsInVpX2xvYWRpbmdfc3Bpbi5qcyIsInVpX3JhZGlvX2NvbnRhaW5lci5qcyIsInVpX2Z1bGxfc2NyZWVuX21vZGUuanMiLCJnbWFpbF9jaGVja2JveF9zZWxlY3Rpb24uanMiLCJib29raW5nc19jaGVja2JveF9zZWxlY3Rpb24uanMiLCJ1aV9zaWRlYmFyX2xlZnRfX2FjdGlvbnMuanMiLCJjb3B5X3RleHRfdG9fY2xpcGJyZC5qcyIsImNvbGxhcHNpYmxlX2dyb3Vwcy5qcyIsIndwYmNfbGVuX2dyb3Vwcy5qcyIsIndwYmNfcmFuZ2VfZ3JvdXBzLmpzIiwidWlfdGFicy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcclxuLyoqXHJcbiAqIEJsaW5rIHNwZWNpZmljIEhUTUwgZWxlbWVudCB0byBzZXQgYXR0ZW50aW9uIHRvIHRoaXMgZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IGVsZW1lbnRfdG9fYmxpbmtcdFx0ICAtIGNsYXNzIG9yIGlkIG9mIGVsZW1lbnQ6ICcud3BiY193aWRnZXRfYXZhaWxhYmxlX3VuYXZhaWxhYmxlJ1xyXG4gKiBAcGFyYW0ge2ludH0gaG93X21hbnlfdGltZXNcdFx0XHQgIC0gNFxyXG4gKiBAcGFyYW0ge2ludH0gaG93X2xvbmdfdG9fYmxpbmtcdFx0ICAtIDM1MFxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19ibGlua19lbGVtZW50KCBlbGVtZW50X3RvX2JsaW5rLCBob3dfbWFueV90aW1lcyA9IDQsIGhvd19sb25nX3RvX2JsaW5rID0gMzUwICl7XHJcblxyXG5cdGZvciAoIGxldCBpID0gMDsgaSA8IGhvd19tYW55X3RpbWVzOyBpKysgKXtcclxuXHRcdGpRdWVyeSggZWxlbWVudF90b19ibGluayApLmZhZGVPdXQoIGhvd19sb25nX3RvX2JsaW5rICkuZmFkZUluKCBob3dfbG9uZ190b19ibGluayApO1xyXG5cdH1cclxuICAgIGpRdWVyeSggZWxlbWVudF90b19ibGluayApLmFuaW1hdGUoIHtvcGFjaXR5OiAxfSwgNTAwICk7XHJcbn1cclxuIiwiLyoqXHJcbiAqICAgU3VwcG9ydCBGdW5jdGlvbnMgLSBTcGluIEljb24gaW4gQnV0dG9ucyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4vKipcclxuICogUmVtb3ZlIHNwaW4gaWNvbiBmcm9tICBidXR0b24gYW5kIEVuYWJsZSB0aGlzIGJ1dHRvbi5cclxuICpcclxuICogQHBhcmFtIGJ1dHRvbl9jbGlja2VkX2VsZW1lbnRfaWRcdFx0LSBIVE1MIElEIGF0dHJpYnV0ZSBvZiB0aGlzIGJ1dHRvblxyXG4gKiBAcmV0dXJuIHN0cmluZ1x0XHRcdFx0XHRcdC0gQ1NTIGNsYXNzZXMgdGhhdCB3YXMgcHJldmlvdXNseSBpbiBidXR0b24gaWNvblxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19idXR0b25fX3JlbW92ZV9zcGluKGJ1dHRvbl9jbGlja2VkX2VsZW1lbnRfaWQpIHtcclxuXHJcblx0dmFyIHByZXZpb3NfY2xhc3NlcyA9ICcnO1xyXG5cdGlmIChcclxuXHRcdCh1bmRlZmluZWQgIT0gYnV0dG9uX2NsaWNrZWRfZWxlbWVudF9pZClcclxuXHRcdCYmICgnJyAhPSBidXR0b25fY2xpY2tlZF9lbGVtZW50X2lkKVxyXG5cdCkge1xyXG5cdFx0dmFyIGpFbGVtZW50ID0galF1ZXJ5KCAnIycgKyBidXR0b25fY2xpY2tlZF9lbGVtZW50X2lkICk7XHJcblx0XHRpZiAoIGpFbGVtZW50Lmxlbmd0aCApIHtcclxuXHRcdFx0cHJldmlvc19jbGFzc2VzID0gd3BiY19idXR0b25fZGlzYWJsZV9sb2FkaW5nX2ljb24oIGpFbGVtZW50LmdldCggMCApICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcHJldmlvc19jbGFzc2VzO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNob3cgTG9hZGluZyAocm90YXRpbmcgYXJyb3cpIGljb24gZm9yIGJ1dHRvbiB0aGF0IGhhcyBiZWVuIGNsaWNrZWRcclxuICpcclxuICogQHBhcmFtIHRoaXNfYnV0dG9uXHRcdC0gdGhpcyBvYmplY3Qgb2Ygc3BlY2lmaWMgYnV0dG9uXHJcbiAqIEByZXR1cm4gc3RyaW5nXHRcdFx0LSBDU1MgY2xhc3NlcyB0aGF0IHdhcyBwcmV2aW91c2x5IGluIGJ1dHRvbiBpY29uXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2J1dHRvbl9lbmFibGVfbG9hZGluZ19pY29uKHRoaXNfYnV0dG9uKSB7XHJcblxyXG5cdHZhciBqQnV0dG9uICAgICAgICAgPSBqUXVlcnkoIHRoaXNfYnV0dG9uICk7XHJcblx0dmFyIGpJY29uICAgICAgICAgICA9IGpCdXR0b24uZmluZCggJ2knICk7XHJcblx0dmFyIHByZXZpb3NfY2xhc3NlcyA9IGpJY29uLmF0dHIoICdjbGFzcycgKTtcclxuXHJcblx0akljb24ucmVtb3ZlQ2xhc3MoKS5hZGRDbGFzcyggJ21lbnVfaWNvbiBpY29uLTF4IHdwYmNfaWNuX3JvdGF0ZV9yaWdodCB3cGJjX3NwaW4nICk7XHQvLyBTZXQgUm90YXRlIGljb24uXHJcblx0Ly8gakljb24uYWRkQ2xhc3MoICd3cGJjX2FuaW1hdGlvbl9wYXVzZScgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBQYXVzZSBhbmltYXRpb24uXHJcblx0Ly8gakljb24uYWRkQ2xhc3MoICd3cGJjX3VpX3JlZCcgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU2V0IGljb24gY29sb3IgcmVkLlxyXG5cclxuXHRqSWNvbi5hdHRyKCAnd3BiY19wcmV2aW91c19jbGFzcycsIHByZXZpb3NfY2xhc3NlcyApXHJcblxyXG5cdGpCdXR0b24uYWRkQ2xhc3MoICdkaXNhYmxlZCcgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEaXNhYmxlIGJ1dHRvblxyXG5cdC8vIFdlIG5lZWQgdG8gIHNldCAgaGVyZSBhdHRyIGluc3RlYWQgb2YgcHJvcCwgYmVjYXVzZSBmb3IgQSBlbGVtZW50cywgIGF0dHJpYnV0ZSAnZGlzYWJsZWQnIGRvICBub3QgYWRkZWQgd2l0aCBqQnV0dG9uLnByb3AoIFwiZGlzYWJsZWRcIiwgdHJ1ZSApOy5cclxuXHJcblx0akJ1dHRvbi5hdHRyKCAnd3BiY19wcmV2aW91c19vbmNsaWNrJywgakJ1dHRvbi5hdHRyKCAnb25jbGljaycgKSApO1x0XHQvLyBTYXZlIHRoaXMgdmFsdWUuXHJcblx0akJ1dHRvbi5hdHRyKCAnb25jbGljaycsICcnICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERpc2FibGUgYWN0aW9ucyBcIm9uIGNsaWNrXCIuXHJcblxyXG5cdHJldHVybiBwcmV2aW9zX2NsYXNzZXM7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogSGlkZSBMb2FkaW5nIChyb3RhdGluZyBhcnJvdykgaWNvbiBmb3IgYnV0dG9uIHRoYXQgd2FzIGNsaWNrZWQgYW5kIHNob3cgcHJldmlvdXMgaWNvbiBhbmQgZW5hYmxlIGJ1dHRvblxyXG4gKlxyXG4gKiBAcGFyYW0gdGhpc19idXR0b25cdFx0LSB0aGlzIG9iamVjdCBvZiBzcGVjaWZpYyBidXR0b25cclxuICogQHJldHVybiBzdHJpbmdcdFx0XHQtIENTUyBjbGFzc2VzIHRoYXQgd2FzIHByZXZpb3VzbHkgaW4gYnV0dG9uIGljb25cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYnV0dG9uX2Rpc2FibGVfbG9hZGluZ19pY29uKHRoaXNfYnV0dG9uKSB7XHJcblxyXG5cdHZhciBqQnV0dG9uID0galF1ZXJ5KCB0aGlzX2J1dHRvbiApO1xyXG5cdHZhciBqSWNvbiAgID0gakJ1dHRvbi5maW5kKCAnaScgKTtcclxuXHJcblx0dmFyIHByZXZpb3NfY2xhc3NlcyA9IGpJY29uLmF0dHIoICd3cGJjX3ByZXZpb3VzX2NsYXNzJyApO1xyXG5cdGlmIChcclxuXHRcdCh1bmRlZmluZWQgIT0gcHJldmlvc19jbGFzc2VzKVxyXG5cdFx0JiYgKCcnICE9IHByZXZpb3NfY2xhc3NlcylcclxuXHQpIHtcclxuXHRcdGpJY29uLnJlbW92ZUNsYXNzKCkuYWRkQ2xhc3MoIHByZXZpb3NfY2xhc3NlcyApO1xyXG5cdH1cclxuXHJcblx0akJ1dHRvbi5yZW1vdmVDbGFzcyggJ2Rpc2FibGVkJyApO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFJlbW92ZSBEaXNhYmxlIGJ1dHRvbi5cclxuXHJcblx0dmFyIHByZXZpb3VzX29uY2xpY2sgPSBqQnV0dG9uLmF0dHIoICd3cGJjX3ByZXZpb3VzX29uY2xpY2snIClcclxuXHRpZiAoXHJcblx0XHQodW5kZWZpbmVkICE9IHByZXZpb3VzX29uY2xpY2spXHJcblx0XHQmJiAoJycgIT0gcHJldmlvdXNfb25jbGljaylcclxuXHQpIHtcclxuXHRcdGpCdXR0b24uYXR0ciggJ29uY2xpY2snLCBwcmV2aW91c19vbmNsaWNrICk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcHJldmlvc19jbGFzc2VzO1xyXG59XHJcbiIsIi8qKlxyXG4gKiBPbiBzZWxlY3Rpb24gIG9mIHJhZGlvIGJ1dHRvbiwgYWRqdXN0IGF0dHJpYnV0ZXMgb2YgcmFkaW8gY29udGFpbmVyXHJcbiAqXHJcbiAqIEBwYXJhbSBfdGhpc1xyXG4gKi9cclxuZnVuY3Rpb24gd3BiY191aV9lbF9fcmFkaW9fY29udGFpbmVyX3NlbGVjdGlvbihfdGhpcykge1xyXG5cclxuXHRpZiAoIGpRdWVyeSggX3RoaXMgKS5pcyggJzpjaGVja2VkJyApICkge1xyXG5cdFx0alF1ZXJ5KCBfdGhpcyApLnBhcmVudHMoICcud3BiY191aV9yYWRpb19zZWN0aW9uJyApLmZpbmQoICcud3BiY191aV9yYWRpb19jb250YWluZXInICkucmVtb3ZlQXR0ciggJ2RhdGEtc2VsZWN0ZWQnICk7XHJcblx0XHRqUXVlcnkoIF90aGlzICkucGFyZW50cyggJy53cGJjX3VpX3JhZGlvX2NvbnRhaW5lcjpub3QoLmRpc2FibGVkKScgKS5hdHRyKCAnZGF0YS1zZWxlY3RlZCcsIHRydWUgKTtcclxuXHR9XHJcblxyXG5cdGlmICggalF1ZXJ5KCBfdGhpcyApLmlzKCAnOmRpc2FibGVkJyApICkge1xyXG5cdFx0alF1ZXJ5KCBfdGhpcyApLnBhcmVudHMoICcud3BiY191aV9yYWRpb19jb250YWluZXInICkuYWRkQ2xhc3MoICdkaXNhYmxlZCcgKTtcclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPbiBjbGljayBvbiBSYWRpbyBDb250YWluZXIsIHdlIHdpbGwgIHNlbGVjdCAgdGhlICByYWRpbyBidXR0b24gICAgYW5kIHRoZW4gYWRqdXN0IGF0dHJpYnV0ZXMgb2YgcmFkaW8gY29udGFpbmVyXHJcbiAqXHJcbiAqIEBwYXJhbSBfdGhpc1xyXG4gKi9cclxuZnVuY3Rpb24gd3BiY191aV9lbF9fcmFkaW9fY29udGFpbmVyX2NsaWNrKF90aGlzKSB7XHJcblxyXG5cdGlmICggalF1ZXJ5KCBfdGhpcyApLmhhc0NsYXNzKCAnZGlzYWJsZWQnICkgKSB7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHR2YXIgal9yYWRpbyA9IGpRdWVyeSggX3RoaXMgKS5maW5kKCAnaW5wdXRbdHlwZT1yYWRpb106bm90KC53cGJjLWZvcm0tcmFkaW8taW50ZXJuYWwpJyApO1xyXG5cdGlmICggal9yYWRpby5sZW5ndGggKSB7XHJcblx0XHRqX3JhZGlvLnByb3AoICdjaGVja2VkJywgdHJ1ZSApLnRyaWdnZXIoICdjaGFuZ2UnICk7XHJcblx0fVxyXG5cclxufSIsIlwidXNlIHN0cmljdFwiO1xyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuLy8gPT0gRnVsbCBTY3JlZW4gIC0gIHN1cHBvcnQgZnVuY3Rpb25zICAgPT1cclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4vKipcclxuICogQ2hlY2sgRnVsbCAgc2NyZWVuIG1vZGUsICBieSAgcmVtb3ZpbmcgdG9wIHRhYlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jaGVja19mdWxsX3NjcmVlbl9tb2RlKCl7XHJcblx0aWYgKCBqUXVlcnkoICdib2R5JyApLmhhc0NsYXNzKCAnd3BiY19hZG1pbl9mdWxsX3NjcmVlbicgKSApIHtcclxuXHRcdGpRdWVyeSggJ2h0bWwnICkucmVtb3ZlQ2xhc3MoICd3cC10b29sYmFyJyApO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRqUXVlcnkoICdodG1sJyApLmFkZENsYXNzKCAnd3AtdG9vbGJhcicgKTtcclxuXHR9XHJcblx0d3BiY19jaGVja19idXR0b25zX21heF9taW5faW5fZnVsbF9zY3JlZW5fbW9kZSgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiB3cGJjX2NoZWNrX2J1dHRvbnNfbWF4X21pbl9pbl9mdWxsX3NjcmVlbl9tb2RlKCkge1xyXG5cdGlmICggalF1ZXJ5KCAnYm9keScgKS5oYXNDbGFzcyggJ3dwYmNfYWRtaW5fZnVsbF9zY3JlZW4nICkgKSB7XHJcblx0XHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2Z1bGxfc2NyZWVuJyAgICkuYWRkQ2xhc3MoICAgICd3cGJjX3VpX19oaWRlJyApO1xyXG5cdFx0alF1ZXJ5KCAnLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9ub3JtYWxfc2NyZWVuJyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0alF1ZXJ5KCAnLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9mdWxsX3NjcmVlbicgICApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRcdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5fbm9ybWFsX3NjcmVlbicgKS5hZGRDbGFzcyggICAgJ3dwYmNfdWlfX2hpZGUnICk7XHJcblx0fVxyXG59XHJcblxyXG5qUXVlcnkoIGRvY3VtZW50ICkucmVhZHkoIGZ1bmN0aW9uICgpIHtcclxuXHR3cGJjX2NoZWNrX2Z1bGxfc2NyZWVuX21vZGUoKTtcclxufSApOyIsIi8qKlxyXG4gKiBDaGVja2JveCBTZWxlY3Rpb24gZnVuY3Rpb25zIGZvciBMaXN0aW5nLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBTZWxlY3Rpb25zIG9mIHNldmVyYWwgIGNoZWNrYm94ZXMgbGlrZSBpbiBnTWFpbCB3aXRoIHNoaWZ0IDopXHJcbiAqIE5lZWQgdG8gIGhhdmUgdGhpcyBzdHJ1Y3R1cmU6XHJcbiAqIC53cGJjX3NlbGVjdGFibGVfdGFibGVcclxuICogICAgICAud3BiY19zZWxlY3RhYmxlX2hlYWRcclxuICogICAgICAgICAgICAgIC5jaGVjay1jb2x1bW5cclxuICogICAgICAgICAgICAgICAgICA6Y2hlY2tib3hcclxuICogICAgICAud3BiY19zZWxlY3RhYmxlX2JvZHlcclxuICogICAgICAgICAgLndwYmNfcm93XHJcbiAqICAgICAgICAgICAgICAuY2hlY2stY29sdW1uXHJcbiAqICAgICAgICAgICAgICAgICAgOmNoZWNrYm94XHJcbiAqICAgICAgLndwYmNfc2VsZWN0YWJsZV9mb290XHJcbiAqICAgICAgICAgICAgICAuY2hlY2stY29sdW1uXHJcbiAqICAgICAgICAgICAgICAgICAgOmNoZWNrYm94XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2RlZmluZV9nbWFpbF9jaGVja2JveF9zZWxlY3Rpb24oICQgKXtcclxuXHJcblx0dmFyIGNoZWNrcywgZmlyc3QsIGxhc3QsIGNoZWNrZWQsIHNsaWNlZCwgbGFzdENsaWNrZWQgPSBmYWxzZTtcclxuXHJcblx0Ly8gQ2hlY2sgYWxsIGNoZWNrYm94ZXMuXHJcblx0JCggJy53cGJjX3NlbGVjdGFibGVfYm9keScgKS5maW5kKCAnLmNoZWNrLWNvbHVtbicgKS5maW5kKCAnOmNoZWNrYm94JyApLm9uKFxyXG5cdFx0J2NsaWNrJyxcclxuXHRcdGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGlmICggJ3VuZGVmaW5lZCcgPT0gZS5zaGlmdEtleSApIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIGUuc2hpZnRLZXkgKSB7XHJcblx0XHRcdFx0aWYgKCAhIGxhc3RDbGlja2VkICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGNoZWNrcyAgPSAkKCBsYXN0Q2xpY2tlZCApLmNsb3Nlc3QoICcud3BiY19zZWxlY3RhYmxlX2JvZHknICkuZmluZCggJzpjaGVja2JveCcgKS5maWx0ZXIoICc6dmlzaWJsZTplbmFibGVkJyApO1xyXG5cdFx0XHRcdGZpcnN0ICAgPSBjaGVja3MuaW5kZXgoIGxhc3RDbGlja2VkICk7XHJcblx0XHRcdFx0bGFzdCAgICA9IGNoZWNrcy5pbmRleCggdGhpcyApO1xyXG5cdFx0XHRcdGNoZWNrZWQgPSAkKCB0aGlzICkucHJvcCggJ2NoZWNrZWQnICk7XHJcblx0XHRcdFx0aWYgKCAwIDwgZmlyc3QgJiYgMCA8IGxhc3QgJiYgZmlyc3QgIT0gbGFzdCApIHtcclxuXHRcdFx0XHRcdHNsaWNlZCA9IChsYXN0ID4gZmlyc3QpID8gY2hlY2tzLnNsaWNlKCBmaXJzdCwgbGFzdCApIDogY2hlY2tzLnNsaWNlKCBsYXN0LCBmaXJzdCApO1xyXG5cdFx0XHRcdFx0c2xpY2VkLnByb3AoXHJcblx0XHRcdFx0XHRcdCdjaGVja2VkJyxcclxuXHRcdFx0XHRcdFx0ZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICggJCggdGhpcyApLmNsb3Nlc3QoICcud3BiY19yb3cnICkuaXMoICc6dmlzaWJsZScgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiBjaGVja2VkO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdCkudHJpZ2dlciggJ2NoYW5nZScgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0bGFzdENsaWNrZWQgPSB0aGlzO1xyXG5cclxuXHRcdFx0Ly8gdG9nZ2xlIFwiY2hlY2sgYWxsXCIgY2hlY2tib3hlcy5cclxuXHRcdFx0dmFyIHVuY2hlY2tlZCA9ICQoIHRoaXMgKS5jbG9zZXN0KCAnLndwYmNfc2VsZWN0YWJsZV9ib2R5JyApLmZpbmQoICc6Y2hlY2tib3gnICkuZmlsdGVyKCAnOnZpc2libGU6ZW5hYmxlZCcgKS5ub3QoICc6Y2hlY2tlZCcgKTtcclxuXHRcdFx0JCggdGhpcyApLmNsb3Nlc3QoICcud3BiY19zZWxlY3RhYmxlX3RhYmxlJyApLmNoaWxkcmVuKCAnLndwYmNfc2VsZWN0YWJsZV9oZWFkLCAud3BiY19zZWxlY3RhYmxlX2Zvb3QnICkuZmluZCggJzpjaGVja2JveCcgKS5wcm9wKFxyXG5cdFx0XHRcdCdjaGVja2VkJyxcclxuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gKDAgPT09IHVuY2hlY2tlZC5sZW5ndGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0KS50cmlnZ2VyKCAnY2hhbmdlJyApO1xyXG5cclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0KTtcclxuXHJcblx0Ly8gSGVhZCB8fCBGb290IGNsaWNraW5nIHRvICBzZWxlY3QgLyBkZXNlbGVjdCBBTEwuXHJcblx0JCggJy53cGJjX3NlbGVjdGFibGVfaGVhZCwgLndwYmNfc2VsZWN0YWJsZV9mb290JyApLmZpbmQoICcuY2hlY2stY29sdW1uIDpjaGVja2JveCcgKS5vbihcclxuXHRcdCdjbGljaycsXHJcblx0XHRmdW5jdGlvbiAoZXZlbnQpIHtcclxuXHRcdFx0dmFyICR0aGlzICAgICAgICAgID0gJCggdGhpcyApLFxyXG5cdFx0XHRcdCR0YWJsZSAgICAgICAgID0gJHRoaXMuY2xvc2VzdCggJy53cGJjX3NlbGVjdGFibGVfdGFibGUnICksXHJcblx0XHRcdFx0Y29udHJvbENoZWNrZWQgPSAkdGhpcy5wcm9wKCAnY2hlY2tlZCcgKSxcclxuXHRcdFx0XHR0b2dnbGUgICAgICAgICA9IGV2ZW50LnNoaWZ0S2V5IHx8ICR0aGlzLmRhdGEoICd3cC10b2dnbGUnICk7XHJcblxyXG5cdFx0XHQkdGFibGUuY2hpbGRyZW4oICcud3BiY19zZWxlY3RhYmxlX2JvZHknICkuZmlsdGVyKCAnOnZpc2libGUnIClcclxuXHRcdFx0XHQuZmluZCggJy5jaGVjay1jb2x1bW4nICkuZmluZCggJzpjaGVja2JveCcgKVxyXG5cdFx0XHRcdC5wcm9wKFxyXG5cdFx0XHRcdFx0J2NoZWNrZWQnLFxyXG5cdFx0XHRcdFx0ZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRpZiAoICQoIHRoaXMgKS5pcyggJzpoaWRkZW4sOmRpc2FibGVkJyApICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRpZiAoIHRvZ2dsZSApIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gISAkKCB0aGlzICkucHJvcCggJ2NoZWNrZWQnICk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnRyb2xDaGVja2VkICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpLnRyaWdnZXIoICdjaGFuZ2UnICk7XHJcblxyXG5cdFx0XHQkdGFibGUuY2hpbGRyZW4oICcud3BiY19zZWxlY3RhYmxlX2hlYWQsICAud3BiY19zZWxlY3RhYmxlX2Zvb3QnICkuZmlsdGVyKCAnOnZpc2libGUnIClcclxuXHRcdFx0XHQuZmluZCggJy5jaGVjay1jb2x1bW4nICkuZmluZCggJzpjaGVja2JveCcgKVxyXG5cdFx0XHRcdC5wcm9wKFxyXG5cdFx0XHRcdFx0J2NoZWNrZWQnLFxyXG5cdFx0XHRcdFx0ZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIHRvZ2dsZSApIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnRyb2xDaGVja2VkICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpO1xyXG5cdFx0fVxyXG5cdCk7XHJcblxyXG5cclxuXHQvLyBWaXN1YWxseSAgc2hvdyBzZWxlY3RlZCBib3JkZXIuXHJcblx0JCggJy53cGJjX3NlbGVjdGFibGVfYm9keScgKS5maW5kKCAnLmNoZWNrLWNvbHVtbiA6Y2hlY2tib3gnICkub24oXHJcblx0XHQnY2hhbmdlJyxcclxuXHRcdGZ1bmN0aW9uIChldmVudCkge1xyXG5cdFx0XHRpZiAoIGpRdWVyeSggdGhpcyApLmlzKCAnOmNoZWNrZWQnICkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuY2xvc2VzdCggJy53cGJjX2xpc3Rfcm93JyApLmFkZENsYXNzKCAncm93X3NlbGVjdGVkX2NvbG9yJyApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmNsb3Nlc3QoICcud3BiY19saXN0X3JvdycgKS5yZW1vdmVDbGFzcyggJ3Jvd19zZWxlY3RlZF9jb2xvcicgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gRGlzYWJsZSB0ZXh0IHNlbGVjdGlvbiB3aGlsZSBwcmVzc2luZyAnc2hpZnQnLlxyXG5cdFx0XHRkb2N1bWVudC5nZXRTZWxlY3Rpb24oKS5yZW1vdmVBbGxSYW5nZXMoKTtcclxuXHJcblx0XHRcdC8vIFNob3cgb3IgaGlkZSBidXR0b25zIG9uIEFjdGlvbnMgdG9vbGJhciAgYXQgIEJvb2tpbmcgTGlzdGluZyAgcGFnZSwgIGlmIHdlIGhhdmUgc29tZSBzZWxlY3RlZCBib29raW5ncy5cclxuXHRcdFx0d3BiY19zaG93X2hpZGVfYWN0aW9uX2J1dHRvbnNfZm9yX3NlbGVjdGVkX2Jvb2tpbmdzKCk7XHJcblx0XHR9XHJcblx0KTtcclxuXHJcblx0d3BiY19zaG93X2hpZGVfYWN0aW9uX2J1dHRvbnNfZm9yX3NlbGVjdGVkX2Jvb2tpbmdzKCk7XHJcbn1cclxuIiwiXHJcbi8qKlxyXG4gKiBHZXQgSUQgYXJyYXkgIG9mIHNlbGVjdGVkIGVsZW1lbnRzXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2dldF9zZWxlY3RlZF9yb3dfaWQoKSB7XHJcblxyXG5cdHZhciAkdGFibGUgICAgICA9IGpRdWVyeSggJy53cGJjX193cmFwX19ib29raW5nX2xpc3RpbmcgLndwYmNfc2VsZWN0YWJsZV90YWJsZScgKTtcclxuXHR2YXIgY2hlY2tib3hlcyAgPSAkdGFibGUuY2hpbGRyZW4oICcud3BiY19zZWxlY3RhYmxlX2JvZHknICkuZmlsdGVyKCAnOnZpc2libGUnICkuZmluZCggJy5jaGVjay1jb2x1bW4nICkuZmluZCggJzpjaGVja2JveCcgKTtcclxuXHR2YXIgc2VsZWN0ZWRfaWQgPSBbXTtcclxuXHJcblx0alF1ZXJ5LmVhY2goXHJcblx0XHRjaGVja2JveGVzLFxyXG5cdFx0ZnVuY3Rpb24gKGtleSwgY2hlY2tib3gpIHtcclxuXHRcdFx0aWYgKCBqUXVlcnkoIGNoZWNrYm94ICkuaXMoICc6Y2hlY2tlZCcgKSApIHtcclxuXHRcdFx0XHR2YXIgZWxlbWVudF9pZCA9IHdwYmNfZ2V0X3Jvd19pZF9mcm9tX2VsZW1lbnQoIGNoZWNrYm94ICk7XHJcblx0XHRcdFx0c2VsZWN0ZWRfaWQucHVzaCggZWxlbWVudF9pZCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0KTtcclxuXHJcblx0cmV0dXJuIHNlbGVjdGVkX2lkO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBJRCBvZiByb3csICBiYXNlZCBvbiBjbGNpa2VkIGVsZW1lbnRcclxuICpcclxuICogQHBhcmFtIHRoaXNfaW5ib3VuZF9lbGVtZW50ICAtIHVzdXNsbHkgIHRoaXNcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZ2V0X3Jvd19pZF9mcm9tX2VsZW1lbnQodGhpc19pbmJvdW5kX2VsZW1lbnQpIHtcclxuXHJcblx0dmFyIGVsZW1lbnRfaWQgPSBqUXVlcnkoIHRoaXNfaW5ib3VuZF9lbGVtZW50ICkuY2xvc2VzdCggJy53cGJjX2xpc3RpbmdfdXN1YWxfcm93JyApLmF0dHIoICdpZCcgKTtcclxuXHJcblx0ZWxlbWVudF9pZCA9IHBhcnNlSW50KCBlbGVtZW50X2lkLnJlcGxhY2UoICdyb3dfaWRfJywgJycgKSApO1xyXG5cclxuXHRyZXR1cm4gZWxlbWVudF9pZDtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiA9PSBCb29raW5nIExpc3RpbmcgPT0gU2hvdyBvciBoaWRlIGJ1dHRvbnMgb24gQWN0aW9ucyB0b29sYmFyICBhdCAgICBwYWdlLCAgaWYgd2UgaGF2ZSBzb21lIHNlbGVjdGVkIGJvb2tpbmdzLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19zaG93X2hpZGVfYWN0aW9uX2J1dHRvbnNfZm9yX3NlbGVjdGVkX2Jvb2tpbmdzKCl7XHJcblxyXG5cdHZhciBzZWxlY3RlZF9yb3dzX2FyciA9IHdwYmNfZ2V0X3NlbGVjdGVkX3Jvd19pZCgpO1xyXG5cclxuXHRpZiAoIHNlbGVjdGVkX3Jvd3NfYXJyLmxlbmd0aCA+IDAgKSB7XHJcblx0XHRqUXVlcnkoICcuaGlkZV9idXR0b25faWZfbm9fc2VsZWN0aW9uJyApLnNob3coKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0alF1ZXJ5KCAnLmhpZGVfYnV0dG9uX2lmX25vX3NlbGVjdGlvbicgKS5oaWRlKCk7XHJcblx0fVxyXG59IiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4vLyA9PSBMZWZ0IEJhciAgLSAgZXhwYW5kIC8gY29sYXBzZSBmdW5jdGlvbnMgICA9PVxyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbi8qKlxyXG4gKiBFeHBhbmQgVmVydGljYWwgTGVmdCBCYXIuXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19zaWRlYmFyX2xlZnRfX2RvX21heCgpIHtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkucmVtb3ZlQ2xhc3MoICdtaW4gbWF4IGNvbXBhY3Qgbm9uZScgKTtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkuYWRkQ2xhc3MoICdtYXgnICk7XHJcblx0alF1ZXJ5KCAnLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9vcGVuX2xlZnRfdmVydGljYWxfbmF2JyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2hpZGVfbGVmdF92ZXJ0aWNhbF9uYXYnICkucmVtb3ZlQ2xhc3MoICd3cGJjX3VpX19oaWRlJyApO1xyXG5cclxuXHRqUXVlcnkoICcud3AtYWRtaW4nICkucmVtb3ZlQ2xhc3MoICd3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X21pbiB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X21heCB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X2NvbXBhY3Qgd3BiY19wYWdlX3dyYXBwZXJfbGVmdF9ub25lJyApO1xyXG5cdGpRdWVyeSggJy53cC1hZG1pbicgKS5hZGRDbGFzcyggJ3dwYmNfcGFnZV93cmFwcGVyX2xlZnRfbWF4JyApO1xyXG59XHJcblxyXG4vKipcclxuICogSGlkZSBWZXJ0aWNhbCBMZWZ0IEJhci5cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYWRtaW5fdWlfX3NpZGViYXJfbGVmdF9fZG9fbWluKCkge1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5yZW1vdmVDbGFzcyggJ21pbiBtYXggY29tcGFjdCBub25lJyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5hZGRDbGFzcyggJ21pbicgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX29wZW5fbGVmdF92ZXJ0aWNhbF9uYXYnICkucmVtb3ZlQ2xhc3MoICd3cGJjX3VpX19oaWRlJyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5faGlkZV9sZWZ0X3ZlcnRpY2FsX25hdicgKS5hZGRDbGFzcyggJ3dwYmNfdWlfX2hpZGUnICk7XHJcblxyXG5cdGpRdWVyeSggJy53cC1hZG1pbicgKS5yZW1vdmVDbGFzcyggJ3dwYmNfcGFnZV93cmFwcGVyX2xlZnRfbWluIHdwYmNfcGFnZV93cmFwcGVyX2xlZnRfbWF4IHdwYmNfcGFnZV93cmFwcGVyX2xlZnRfY29tcGFjdCB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X25vbmUnICk7XHJcblx0alF1ZXJ5KCAnLndwLWFkbWluJyApLmFkZENsYXNzKCAnd3BiY19wYWdlX3dyYXBwZXJfbGVmdF9taW4nICk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb2xhcHNlIFZlcnRpY2FsIExlZnQgQmFyLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hZG1pbl91aV9fc2lkZWJhcl9sZWZ0X19kb19jb21wYWN0KCkge1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5yZW1vdmVDbGFzcyggJ21pbiBtYXggY29tcGFjdCBub25lJyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5hZGRDbGFzcyggJ2NvbXBhY3QnICk7XHJcblx0alF1ZXJ5KCAnLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9vcGVuX2xlZnRfdmVydGljYWxfbmF2JyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2hpZGVfbGVmdF92ZXJ0aWNhbF9uYXYnICkuYWRkQ2xhc3MoICd3cGJjX3VpX19oaWRlJyApO1xyXG5cclxuXHRqUXVlcnkoICcud3AtYWRtaW4nICkucmVtb3ZlQ2xhc3MoICd3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X21pbiB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X21heCB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X2NvbXBhY3Qgd3BiY19wYWdlX3dyYXBwZXJfbGVmdF9ub25lJyApO1xyXG5cdGpRdWVyeSggJy53cC1hZG1pbicgKS5hZGRDbGFzcyggJ3dwYmNfcGFnZV93cmFwcGVyX2xlZnRfY29tcGFjdCcgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXBsZXRlbHkgSGlkZSBWZXJ0aWNhbCBMZWZ0IEJhci5cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYWRtaW5fdWlfX3NpZGViYXJfbGVmdF9fZG9faGlkZSgpIHtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkucmVtb3ZlQ2xhc3MoICdtaW4gbWF4IGNvbXBhY3Qgbm9uZScgKTtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkuYWRkQ2xhc3MoICdub25lJyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5fb3Blbl9sZWZ0X3ZlcnRpY2FsX25hdicgKS5yZW1vdmVDbGFzcyggJ3dwYmNfdWlfX2hpZGUnICk7XHJcblx0alF1ZXJ5KCAnLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9oaWRlX2xlZnRfdmVydGljYWxfbmF2JyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHQvLyBIaWRlIHRvcCBcIk1lbnVcIiBidXR0b24gd2l0aCBkaXZpZGVyLlxyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5fc2hvd19sZWZ0X3ZlcnRpY2FsX25hdiwud3BiY191aV9fdG9wX25hdl9fYnRuX3Nob3dfbGVmdF92ZXJ0aWNhbF9uYXZfZGl2aWRlcicgKS5hZGRDbGFzcyggJ3dwYmNfdWlfX2hpZGUnICk7XHJcblxyXG5cdGpRdWVyeSggJy53cC1hZG1pbicgKS5yZW1vdmVDbGFzcyggJ3dwYmNfcGFnZV93cmFwcGVyX2xlZnRfbWluIHdwYmNfcGFnZV93cmFwcGVyX2xlZnRfbWF4IHdwYmNfcGFnZV93cmFwcGVyX2xlZnRfY29tcGFjdCB3cGJjX3BhZ2Vfd3JhcHBlcl9sZWZ0X25vbmUnICk7XHJcblx0alF1ZXJ5KCAnLndwLWFkbWluJyApLmFkZENsYXNzKCAnd3BiY19wYWdlX3dyYXBwZXJfbGVmdF9ub25lJyApO1xyXG59XHJcblxyXG4vKipcclxuICogQWN0aW9uIG9uIGNsaWNrIFwiR28gQmFja1wiIC0gc2hvdyByb290IG1lbnVcclxuICogb3Igc29tZSBvdGhlciBzZWN0aW9uIGluIGxlZnQgc2lkZWJhci5cclxuICpcclxuICogQHBhcmFtIHN0cmluZyBtZW51X3RvX3Nob3cgLSBtZW51IHNsdWcuXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19zaWRlYmFyX2xlZnRfX3Nob3dfc2VjdGlvbiggbWVudV90b19zaG93ICkge1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX2VsX192ZXJ0X2xlZnRfYmFyX19zZWN0aW9uJyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKVxyXG5cdGpRdWVyeSggJy53cGJjX3VpX2VsX192ZXJ0X2xlZnRfYmFyX19zZWN0aW9uXycgKyBtZW51X3RvX3Nob3cgKS5yZW1vdmVDbGFzcyggJ3dwYmNfdWlfX2hpZGUnICk7XHJcbn1cclxuXHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4vLyA9PSBSaWdodCBTaWRlIEJhciAgLSAgZXhwYW5kIC8gY29sYXBzZSBmdW5jdGlvbnMgICA9PVxyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbi8qKlxyXG4gKiBFeHBhbmQgVmVydGljYWwgUmlnaHQgQmFyLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fbWF4KCkge1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5yZW1vdmVDbGFzcyggJ21pbl9yaWdodCBtYXhfcmlnaHQgY29tcGFjdF9yaWdodCBub25lX3JpZ2h0JyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5hZGRDbGFzcyggJ21heF9yaWdodCcgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX29wZW5fcmlnaHRfdmVydGljYWxfbmF2JyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2hpZGVfcmlnaHRfdmVydGljYWxfbmF2JyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEhpZGUgVmVydGljYWwgUmlnaHQgQmFyLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fbWluKCkge1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5yZW1vdmVDbGFzcyggJ21pbl9yaWdodCBtYXhfcmlnaHQgY29tcGFjdF9yaWdodCBub25lX3JpZ2h0JyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3NldHRpbmdzX3BhZ2Vfd3JhcHBlcicgKS5hZGRDbGFzcyggJ21pbl9yaWdodCcgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX29wZW5fcmlnaHRfdmVydGljYWxfbmF2JyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2hpZGVfcmlnaHRfdmVydGljYWxfbmF2JyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbGFwc2UgVmVydGljYWwgUmlnaHQgQmFyLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hZG1pbl91aV9fc2lkZWJhcl9yaWdodF9fZG9fY29tcGFjdCgpIHtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkucmVtb3ZlQ2xhc3MoICdtaW5fcmlnaHQgbWF4X3JpZ2h0IGNvbXBhY3RfcmlnaHQgbm9uZV9yaWdodCcgKTtcclxuXHRqUXVlcnkoICcud3BiY19zZXR0aW5nc19wYWdlX3dyYXBwZXInICkuYWRkQ2xhc3MoICdjb21wYWN0X3JpZ2h0JyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5fb3Blbl9yaWdodF92ZXJ0aWNhbF9uYXYnICkucmVtb3ZlQ2xhc3MoICd3cGJjX3VpX19oaWRlJyApO1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5faGlkZV9yaWdodF92ZXJ0aWNhbF9uYXYnICkuYWRkQ2xhc3MoICd3cGJjX3VpX19oaWRlJyApO1xyXG59XHJcblxyXG4vKipcclxuICogQ29tcGxldGVseSBIaWRlIFZlcnRpY2FsIFJpZ2h0IEJhci5cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYWRtaW5fdWlfX3NpZGViYXJfcmlnaHRfX2RvX2hpZGUoKSB7XHJcblx0alF1ZXJ5KCAnLndwYmNfc2V0dGluZ3NfcGFnZV93cmFwcGVyJyApLnJlbW92ZUNsYXNzKCAnbWluX3JpZ2h0IG1heF9yaWdodCBjb21wYWN0X3JpZ2h0IG5vbmVfcmlnaHQnICk7XHJcblx0alF1ZXJ5KCAnLndwYmNfc2V0dGluZ3NfcGFnZV93cmFwcGVyJyApLmFkZENsYXNzKCAnbm9uZV9yaWdodCcgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX29wZW5fcmlnaHRfdmVydGljYWxfbmF2JyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHRqUXVlcnkoICcud3BiY191aV9fdG9wX25hdl9fYnRuX2hpZGVfcmlnaHRfdmVydGljYWxfbmF2JyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxuXHQvLyBIaWRlIHRvcCBcIk1lbnVcIiBidXR0b24gd2l0aCBkaXZpZGVyLlxyXG5cdGpRdWVyeSggJy53cGJjX3VpX190b3BfbmF2X19idG5fc2hvd19yaWdodF92ZXJ0aWNhbF9uYXYsLndwYmNfdWlfX3RvcF9uYXZfX2J0bl9zaG93X3JpZ2h0X3ZlcnRpY2FsX25hdl9kaXZpZGVyJyApLmFkZENsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEFjdGlvbiBvbiBjbGljayBcIkdvIEJhY2tcIiAtIHNob3cgcm9vdCBtZW51XHJcbiAqIG9yIHNvbWUgb3RoZXIgc2VjdGlvbiBpbiByaWdodCBzaWRlYmFyLlxyXG4gKlxyXG4gKiBAcGFyYW0gc3RyaW5nIG1lbnVfdG9fc2hvdyAtIG1lbnUgc2x1Zy5cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYWRtaW5fdWlfX3NpZGViYXJfcmlnaHRfX3Nob3dfc2VjdGlvbiggbWVudV90b19zaG93ICkge1xyXG5cdGpRdWVyeSggJy53cGJjX3VpX2VsX192ZXJ0X3JpZ2h0X2Jhcl9fc2VjdGlvbicgKS5hZGRDbGFzcyggJ3dwYmNfdWlfX2hpZGUnIClcclxuXHRqUXVlcnkoICcud3BiY191aV9lbF9fdmVydF9yaWdodF9iYXJfX3NlY3Rpb25fJyArIG1lbnVfdG9fc2hvdyApLnJlbW92ZUNsYXNzKCAnd3BiY191aV9faGlkZScgKTtcclxufVxyXG5cclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbi8vID09IEVuZCBSaWdodCBTaWRlIEJhciAgc2VjdGlvbiAgID09XHJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuLyoqXHJcbiAqIEdldCBhbmNob3IocykgYXJyYXkgIGZyb20gIFVSTC5cclxuICogRG9jOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTG9jYXRpb25cclxuICpcclxuICogQHJldHVybnMgeypbXX1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfdXJsX2dldF9hbmNob3JzX2FycigpIHtcclxuXHR2YXIgaGFzaGVzICAgICAgICAgICAgPSB3aW5kb3cubG9jYXRpb24uaGFzaC5yZXBsYWNlKCAnJTIzJywgJyMnICk7XHJcblx0dmFyIGhhc2hlc19hcnIgICAgICAgID0gaGFzaGVzLnNwbGl0KCAnIycgKTtcclxuXHR2YXIgcmVzdWx0ICAgICAgICAgICAgPSBbXTtcclxuXHR2YXIgaGFzaGVzX2Fycl9sZW5ndGggPSBoYXNoZXNfYXJyLmxlbmd0aDtcclxuXHJcblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgaGFzaGVzX2Fycl9sZW5ndGg7IGkrKyApIHtcclxuXHRcdGlmICggaGFzaGVzX2FycltpXS5sZW5ndGggPiAwICkge1xyXG5cdFx0XHRyZXN1bHQucHVzaCggaGFzaGVzX2FycltpXSApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRyZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG4vKipcclxuICogQXV0byBFeHBhbmQgU2V0dGluZ3Mgc2VjdGlvbiBiYXNlZCBvbiBVUkwgYW5jaG9yLCBhZnRlciAgcGFnZSBsb2FkZWQuXHJcbiAqL1xyXG5qUXVlcnkoIGRvY3VtZW50ICkucmVhZHkoIGZ1bmN0aW9uICgpIHsgd3BiY19hZG1pbl91aV9fcmVkaXJlY3RfbGVnYWN5X2dlbmVyYWxfYXZhaWxhYmlsaXR5X3VybCgpOyB9ICk7XHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCkgeyB3cGJjX2FkbWluX3VpX19kb19leHBhbmRfc2VjdGlvbigpOyBzZXRUaW1lb3V0KCAnd3BiY19hZG1pbl91aV9fZG9fZXhwYW5kX3NlY3Rpb24nLCAxMCApOyB9ICk7XHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCkgeyB3cGJjX2FkbWluX3VpX19kb19leHBhbmRfc2VjdGlvbigpOyBzZXRUaW1lb3V0KCAnd3BiY19hZG1pbl91aV9fZG9fZXhwYW5kX3NlY3Rpb24nLCAxNTAgKTsgfSApO1xyXG5cclxuLyoqXHJcbiAqIFJlZGlyZWN0IG9sZCBTZXR0aW5ncyA+IEF2YWlsYWJpbGl0eSBhbmNob3JzIHRvIHRoZSBkZWRpY2F0ZWQgR2VuZXJhbCBBdmFpbGFiaWxpdHkgcGFnZS5cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYWRtaW5fdWlfX3JlZGlyZWN0X2xlZ2FjeV9nZW5lcmFsX2F2YWlsYWJpbGl0eV91cmwoKSB7XHJcblxyXG5cdGlmIChcclxuXHRcdCAgICggd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZiggJ3BhZ2U9d3BiYy1zZXR0aW5ncycgKSA+IC0xIClcclxuXHRcdCYmIChcclxuXHRcdFx0ICAgKCB3aW5kb3cubG9jYXRpb24uaGFzaC5pbmRleE9mKCAnd3BiY19nZW5lcmFsX3NldHRpbmdzX2F2YWlsYWJpbGl0eV9tZXRhYm94JyApID4gLTEgKVxyXG5cdFx0XHR8fCAoIHdpbmRvdy5sb2NhdGlvbi5oYXNoLmluZGV4T2YoICd3cGJjX2dlbmVyYWxfc2V0dGluZ3NfYXZhaWxhYmlsaXR5X3RhYicgKSA+IC0xIClcclxuXHRcdClcclxuXHQpIHtcclxuXHRcdHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKCB3aW5kb3cubG9jYXRpb24uaHJlZi5zcGxpdCggJz8nIClbMF0gKyAnP3BhZ2U9d3BiYy1hdmFpbGFiaWxpdHkmdGFiPWdlbmVyYWxfYXZhaWxhYmlsaXR5JyApO1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEV4cGFuZCBzZWN0aW9uIGluICBHZW5lcmFsIFNldHRpbmdzIHBhZ2UgYW5kIHNlbGVjdCBNZW51IGl0ZW0uXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19kb19leHBhbmRfc2VjdGlvbigpIHtcclxuXHJcblx0Ly8gd2luZG93LmxvY2F0aW9uLmhhc2ggID0gI3NlY3Rpb25faWQgIC8gIGRvYzogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0xvY2F0aW9uIC5cclxuXHR2YXIgYW5jaG9yc19hcnIgICAgICAgID0gd3BiY191cmxfZ2V0X2FuY2hvcnNfYXJyKCk7XHJcblx0dmFyIGFuY2hvcnNfYXJyX2xlbmd0aCA9IGFuY2hvcnNfYXJyLmxlbmd0aDtcclxuXHJcblx0aWYgKCBhbmNob3JzX2Fycl9sZW5ndGggPiAwICkge1xyXG5cdFx0dmFyIG9uZV9hbmNob3JfcHJvcF92YWx1ZSA9IGFuY2hvcnNfYXJyWzBdLnNwbGl0KCAnZG9fZXhwYW5kX18nICk7XHJcblx0XHRpZiAoIG9uZV9hbmNob3JfcHJvcF92YWx1ZS5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0Ly8gJ3dwYmNfZ2VuZXJhbF9zZXR0aW5nc19jYWxlbmRhcl9tZXRhYm94J1xyXG5cdFx0XHR2YXIgc2VjdGlvbl90b19zaG93ICAgID0gb25lX2FuY2hvcl9wcm9wX3ZhbHVlWzFdO1xyXG5cdFx0XHR2YXIgc2VjdGlvbl9pZF90b19zaG93ID0gJyMnICsgc2VjdGlvbl90b19zaG93O1xyXG5cclxuXHJcblx0XHRcdC8vIC0tIFJlbW92ZSBzZWxlY3RlZCBiYWNrZ3JvdW5kIGluIGFsbCBsZWZ0ICBtZW51ICBpdGVtcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdFx0alF1ZXJ5KCAnLndwYmNfdWlfZWxfX3ZlcnRfbmF2X2l0ZW0gJyApLnJlbW92ZUNsYXNzKCAnYWN0aXZlJyApO1xyXG5cdFx0XHQvLyBTZXQgbGVmdCBtZW51IHNlbGVjdGVkLlxyXG5cdFx0XHRqUXVlcnkoICcuZG9fZXhwYW5kX18nICsgc2VjdGlvbl90b19zaG93ICsgJ19saW5rJyApLmFkZENsYXNzKCAnYWN0aXZlJyApO1xyXG5cdFx0XHR2YXIgc2VsZWN0ZWRfdGl0bGUgPSBqUXVlcnkoICcuZG9fZXhwYW5kX18nICsgc2VjdGlvbl90b19zaG93ICsgJ19saW5rIGEgLndwYmNfdWlfZWxfX3ZlcnRfbmF2X3RpdGxlICcgKS50ZXh0KCk7XHJcblxyXG5cdFx0XHQvLyBFeHBhbmQgc2VjdGlvbiwgaWYgaXQgY29sYXBzZWQuXHJcblx0XHRcdGlmICggISBqUXVlcnkoICcuZG9fZXhwYW5kX18nICsgc2VjdGlvbl90b19zaG93ICsgJ19saW5rJyApLnBhcmVudHMoICcud3BiY191aV9lbF9fbGV2ZWxfX2ZvbGRlcicgKS5oYXNDbGFzcyggJ2V4cGFuZGVkJyApICkge1xyXG5cdFx0XHRcdGpRdWVyeSggJy53cGJjX3VpX2VsX19sZXZlbF9fZm9sZGVyJyApLnJlbW92ZUNsYXNzKCAnZXhwYW5kZWQnICk7XHJcblx0XHRcdFx0alF1ZXJ5KCAnLmRvX2V4cGFuZF9fJyArIHNlY3Rpb25fdG9fc2hvdyArICdfbGluaycgKS5wYXJlbnRzKCAnLndwYmNfdWlfZWxfX2xldmVsX19mb2xkZXInICkuYWRkQ2xhc3MoICdleHBhbmRlZCcgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gLS0gRXhwYW5kIHNlY3Rpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRcdHZhciBjb250YWluZXJfdG9faGlkZV9jbGFzcyA9ICcucG9zdGJveCc7XHJcblx0XHRcdC8vIEhpZGUgc2VjdGlvbnMgJy5wb3N0Ym94JyBpbiBhZG1pbiBwYWdlIGFuZCBzaG93IHNwZWNpZmljIG9uZS5cclxuXHRcdFx0alF1ZXJ5KCAnLndwYmNfYWRtaW5fcGFnZSAnICsgY29udGFpbmVyX3RvX2hpZGVfY2xhc3MgKS5oaWRlKCk7XHJcblx0XHRcdGpRdWVyeSggJy53cGJjX2NvbnRhaW5lcl9hbHdheXNfaGlkZV9fb25fbGVmdF9uYXZfY2xpY2snICkuaGlkZSgpO1xyXG5cdFx0XHRqUXVlcnkoIHNlY3Rpb25faWRfdG9fc2hvdyApLnNob3coKTtcclxuXHJcblx0XHRcdC8vIFNob3cgYWxsIG90aGVyIHNlY3Rpb25zLCAgaWYgcHJvdmlkZWQgaW4gVVJMOiAuLj9wYWdlPXdwYmMtc2V0dGluZ3MjZG9fZXhwYW5kX193cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FwYWNpdHlfbWV0YWJveCN3cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FwYWNpdHlfdXBncmFkZV9tZXRhYm94IC5cclxuXHRcdFx0Zm9yICggbGV0IGkgPSAxOyBpIDwgYW5jaG9yc19hcnJfbGVuZ3RoOyBpKysgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCAnIycgKyBhbmNob3JzX2FycltpXSApLnNob3coKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCBmYWxzZSApIHtcclxuXHRcdFx0XHR2YXIgdGFyZ2V0T2Zmc2V0ID0gd3BiY19zY3JvbGxfdG8oIHNlY3Rpb25faWRfdG9fc2hvdyApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyAtLSBTZXQgVmFsdWUgdG8gSW5wdXQgYWJvdXQgc2VsZWN0ZWQgTmF2IGVsZW1lbnQgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAvLyBGaXhJbjogOS44LjYuMS5cclxuXHRcdFx0dmFyIHNlY3Rpb25faWRfdGFiID0gc2VjdGlvbl9pZF90b19zaG93LnN1YnN0cmluZyggMCwgc2VjdGlvbl9pZF90b19zaG93Lmxlbmd0aCAtIDggKSArICdfdGFiJztcclxuXHRcdFx0aWYgKCBjb250YWluZXJfdG9faGlkZV9jbGFzcyA9PSBzZWN0aW9uX2lkX3RvX3Nob3cgKSB7XHJcblx0XHRcdFx0c2VjdGlvbl9pZF90YWIgPSAnI3dwYmNfZ2VuZXJhbF9zZXR0aW5nc19hbGxfdGFiJ1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICggJyN3cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FwYWNpdHlfbWV0YWJveCwjd3BiY19nZW5lcmFsX3NldHRpbmdzX2NhcGFjaXR5X3VwZ3JhZGVfbWV0YWJveCcgPT0gc2VjdGlvbl9pZF90b19zaG93ICkge1xyXG5cdFx0XHRcdHNlY3Rpb25faWRfdGFiID0gJyN3cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FwYWNpdHlfdGFiJ1xyXG5cdFx0XHR9XHJcblx0XHRcdGpRdWVyeSggJyNmb3JtX3Zpc2libGVfc2VjdGlvbicgKS52YWwoIHNlY3Rpb25faWRfdGFiICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTGlrZSBibGlua2luZyBzb21lIGVsZW1lbnRzLlxyXG5cdFx0d3BiY19hZG1pbl91aV9fZG9fX2FuY2hvcl9fYW5vdGhlcl9hY3Rpb25zKCk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19pc19pbl9tb2JpbGVfc2NyZWVuX3NpemUoKSB7XHJcblx0cmV0dXJuIHdwYmNfYWRtaW5fdWlfX2lzX2luX3RoaXNfc2NyZWVuX3NpemUoIDYwNSApO1xyXG59XHJcblxyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19pc19pbl90aGlzX3NjcmVlbl9zaXplKHNpemUpIHtcclxuXHRyZXR1cm4gKHdpbmRvdy5zY3JlZW4ud2lkdGggPD0gc2l6ZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPcGVuIHNldHRpbmdzIHBhZ2UgIHwgIEV4cGFuZCBzZWN0aW9uICB8ICBTZWxlY3QgTWVudSBpdGVtLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hZG1pbl91aV9fZG9fX29wZW5fdXJsX19leHBhbmRfc2VjdGlvbih1cmwsIHNlY3Rpb25faWQpIHtcclxuXHJcblx0Ly8gd2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmwgKyAnJmRvX2V4cGFuZD0nICsgc2VjdGlvbl9pZCArICcjZG9fZXhwYW5kX18nICsgc2VjdGlvbl9pZDsgLy8uXHJcblx0d2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmwgKyAnI2RvX2V4cGFuZF9fJyArIHNlY3Rpb25faWQ7XHJcblxyXG5cdGlmICggd3BiY19hZG1pbl91aV9faXNfaW5fbW9iaWxlX3NjcmVlbl9zaXplKCkgKSB7XHJcblx0XHR3cGJjX2FkbWluX3VpX19zaWRlYmFyX2xlZnRfX2RvX21pbigpO1xyXG5cdH1cclxuXHJcblx0d3BiY19hZG1pbl91aV9fZG9fZXhwYW5kX3NlY3Rpb24oKTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBDaGVjayAgZm9yIE90aGVyIGFjdGlvbnM6ICBMaWtlIGJsaW5raW5nIHNvbWUgZWxlbWVudHMgaW4gc2V0dGluZ3MgcGFnZS4gRS5nLiBEYXlzIHNlbGVjdGlvbiAgb3IgIGNoYW5nZS1vdmVyIGRheXMuXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2FkbWluX3VpX19kb19fYW5jaG9yX19hbm90aGVyX2FjdGlvbnMoKSB7XHJcblxyXG5cdHZhciBhbmNob3JzX2FyciAgICAgICAgPSB3cGJjX3VybF9nZXRfYW5jaG9yc19hcnIoKTtcclxuXHR2YXIgYW5jaG9yc19hcnJfbGVuZ3RoID0gYW5jaG9yc19hcnIubGVuZ3RoO1xyXG5cclxuXHQvLyBPdGhlciBhY3Rpb25zOiAgTGlrZSBibGlua2luZyBzb21lIGVsZW1lbnRzLlxyXG5cdGZvciAoIHZhciBpID0gMDsgaSA8IGFuY2hvcnNfYXJyX2xlbmd0aDsgaSsrICkge1xyXG5cclxuXHRcdHZhciB0aGlzX2FuY2hvciA9IGFuY2hvcnNfYXJyW2ldO1xyXG5cclxuXHRcdHZhciB0aGlzX2FuY2hvcl9wcm9wX3ZhbHVlID0gdGhpc19hbmNob3Iuc3BsaXQoICdkb19vdGhlcl9hY3Rpb25zX18nICk7XHJcblxyXG5cdFx0aWYgKCB0aGlzX2FuY2hvcl9wcm9wX3ZhbHVlLmxlbmd0aCA+IDEgKSB7XHJcblxyXG5cdFx0XHR2YXIgc2VjdGlvbl9hY3Rpb24gPSB0aGlzX2FuY2hvcl9wcm9wX3ZhbHVlWzFdO1xyXG5cclxuXHRcdFx0c3dpdGNoICggc2VjdGlvbl9hY3Rpb24gKSB7XHJcblxyXG5cdFx0XHRcdGNhc2UgJ2JsaW5rX2RheV9zZWxlY3Rpb25zJzpcclxuXHRcdFx0XHRcdC8vIHdwYmNfdWlfc2V0dGluZ3NfX3BhbmVsX19jbGljayggJyN3cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FsZW5kYXJfdGFiIGEnLCAnI3dwYmNfZ2VuZXJhbF9zZXR0aW5nc19jYWxlbmRhcl9tZXRhYm94JywgJ0RheXMgU2VsZWN0aW9uJyApOy5cclxuXHRcdFx0XHRcdHdwYmNfYmxpbmtfZWxlbWVudCggJy53cGJjX3RyX3NldF9nZW5fYm9va2luZ190eXBlX29mX2RheV9zZWxlY3Rpb25zJywgNCwgMzUwICk7XHJcblx0XHRcdFx0XHRcdHdwYmNfc2Nyb2xsX3RvKCAnLndwYmNfdHJfc2V0X2dlbl9ib29raW5nX3R5cGVfb2ZfZGF5X3NlbGVjdGlvbnMnICk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYmxpbmtfY2hhbmdlX292ZXJfZGF5cyc6XHJcblx0XHRcdFx0XHQvLyB3cGJjX3VpX3NldHRpbmdzX19wYW5lbF9fY2xpY2soICcjd3BiY19nZW5lcmFsX3NldHRpbmdzX2NhbGVuZGFyX3RhYiBhJywgJyN3cGJjX2dlbmVyYWxfc2V0dGluZ3NfY2FsZW5kYXJfbWV0YWJveCcsICdDaGFuZ2VvdmVyIERheXMnICk7LlxyXG5cdFx0XHRcdFx0d3BiY19ibGlua19lbGVtZW50KCAnLndwYmNfdHJfc2V0X2dlbl9ib29raW5nX3JhbmdlX3NlbGVjdGlvbl90aW1lX2lzX2FjdGl2ZScsIDQsIDM1MCApO1xyXG5cdFx0XHRcdFx0XHR3cGJjX3Njcm9sbF90byggJy53cGJjX3RyX3NldF9nZW5fYm9va2luZ19yYW5nZV9zZWxlY3Rpb25fdGltZV9pc19hY3RpdmUnICk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYmxpbmtfY2FwdGNoYSc6XHJcblx0XHRcdFx0XHR3cGJjX2JsaW5rX2VsZW1lbnQoICcud3BiY190cl9zZXRfZ2VuX2Jvb2tpbmdfaXNfdXNlX2NhcHRjaGEnLCA0LCAzNTAgKTtcclxuXHRcdFx0XHRcdFx0d3BiY19zY3JvbGxfdG8oICcud3BiY190cl9zZXRfZ2VuX2Jvb2tpbmdfaXNfdXNlX2NhcHRjaGEnICk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufVxyXG4iLCIvKipcclxuICogQ29weSB0eHQgdG8gY2xpcGJyZCBmcm9tIFRleHQgZmllbGRzLlxyXG4gKlxyXG4gKiBAcGFyYW0gaHRtbF9lbGVtZW50X2lkICAtIGUuZy4gJ2RhdGFfZmllbGQnXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jb3B5X3RleHRfdG9fY2xpcGJyZF9mcm9tX2VsZW1lbnQoIGh0bWxfZWxlbWVudF9pZCApIHtcclxuXHQvLyBHZXQgdGhlIHRleHQgZmllbGQuXHJcblx0dmFyIGNvcHlUZXh0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIGh0bWxfZWxlbWVudF9pZCApO1xyXG5cclxuXHQvLyBTZWxlY3QgdGhlIHRleHQgZmllbGQuXHJcblx0Y29weVRleHQuc2VsZWN0KCk7XHJcblx0Y29weVRleHQuc2V0U2VsZWN0aW9uUmFuZ2UoIDAsIDk5OTk5ICk7IC8vIEZvciBtb2JpbGUgZGV2aWNlcy5cclxuXHJcblx0Ly8gQ29weSB0aGUgdGV4dCBpbnNpZGUgdGhlIHRleHQgZmllbGQuXHJcblx0dmFyIGlzX2NvcGllZCA9IHdwYmNfY29weV90ZXh0X3RvX2NsaXBicmQoIGNvcHlUZXh0LnZhbHVlICk7XHJcblx0aWYgKCAhIGlzX2NvcGllZCApIHtcclxuXHRcdGNvbnNvbGUuZXJyb3IoICdPb3BzLCB1bmFibGUgdG8gY29weScsIGNvcHlUZXh0LnZhbHVlICk7XHJcblx0fVxyXG5cdHJldHVybiBpc19jb3BpZWQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb3B5IHR4dCB0byBjbGlwYnJkLlxyXG4gKlxyXG4gKiBAcGFyYW0gdGV4dFxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY29weV90ZXh0X3RvX2NsaXBicmQodGV4dCkge1xyXG5cclxuXHRpZiAoICEgbmF2aWdhdG9yLmNsaXBib2FyZCApIHtcclxuXHRcdHJldHVybiB3cGJjX2ZhbGxiYWNrX2NvcHlfdGV4dF90b19jbGlwYnJkKCB0ZXh0ICk7XHJcblx0fVxyXG5cclxuXHRuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCggdGV4dCApLnRoZW4oXHJcblx0XHRmdW5jdGlvbiAoKSB7XHJcblx0XHRcdC8vIGNvbnNvbGUubG9nKCAnQXN5bmM6IENvcHlpbmcgdG8gY2xpcGJvYXJkIHdhcyBzdWNjZXNzZnVsIScgKTsuXHJcblx0XHRcdHJldHVybiAgdHJ1ZTtcclxuXHRcdH0sXHJcblx0XHRmdW5jdGlvbiAoZXJyKSB7XHJcblx0XHRcdC8vIGNvbnNvbGUuZXJyb3IoICdBc3luYzogQ291bGQgbm90IGNvcHkgdGV4dDogJywgZXJyICk7LlxyXG5cdFx0XHRyZXR1cm4gIGZhbHNlO1xyXG5cdFx0fVxyXG5cdCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb3B5IHR4dCB0byBjbGlwYnJkIC0gZGVwcmljYXRlZCBtZXRob2QuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19mYWxsYmFja19jb3B5X3RleHRfdG9fY2xpcGJyZCggdGV4dCApIHtcclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyB2YXIgdGV4dEFyZWEgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwidGV4dGFyZWFcIiApO1xyXG5cdC8vIHRleHRBcmVhLnZhbHVlID0gdGV4dDtcclxuXHQvL1xyXG5cdC8vIC8vIEF2b2lkIHNjcm9sbGluZyB0byBib3R0b20uXHJcblx0Ly8gdGV4dEFyZWEuc3R5bGUudG9wICAgICAgPSBcIjBcIjtcclxuXHQvLyB0ZXh0QXJlYS5zdHlsZS5sZWZ0ICAgICA9IFwiMFwiO1xyXG5cdC8vIHRleHRBcmVhLnN0eWxlLnBvc2l0aW9uID0gXCJmaXhlZFwiO1xyXG5cdC8vIHRleHRBcmVhLnN0eWxlLnpJbmRleCAgID0gXCI5OTk5OTk5OTlcIjtcclxuXHQvLyBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKCB0ZXh0QXJlYSApO1xyXG5cdC8vIHRleHRBcmVhLmZvY3VzKCk7XHJcblx0Ly8gdGV4dEFyZWEuc2VsZWN0KCk7XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gTm93IGdldCBpdCBhcyBIVE1MICAob3JpZ2luYWwgaGVyZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNDE5MTc4MC9qYXZhc2NyaXB0LWNvcHktc3RyaW5nLXRvLWNsaXBib2FyZC1hcy10ZXh0LWh0bWwgKS5cclxuXHJcblx0Ly8gWzFdIC0gQ3JlYXRlIGNvbnRhaW5lciBmb3IgdGhlIEhUTUwuXHJcblx0dmFyIGNvbnRhaW5lciAgICAgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICdkaXYnICk7XHJcblx0Y29udGFpbmVyLmlubmVySFRNTCA9IHRleHQ7XHJcblxyXG5cdC8vIFsyXSAtIEhpZGUgZWxlbWVudC5cclxuXHRjb250YWluZXIuc3R5bGUucG9zaXRpb24gICAgICA9ICdmaXhlZCc7XHJcblx0Y29udGFpbmVyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XHJcblx0Y29udGFpbmVyLnN0eWxlLm9wYWNpdHkgICAgICAgPSAwO1xyXG5cclxuXHQvLyBEZXRlY3QgYWxsIHN0eWxlIHNoZWV0cyBvZiB0aGUgcGFnZS5cclxuXHR2YXIgYWN0aXZlU2hlZXRzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoIGRvY3VtZW50LnN0eWxlU2hlZXRzICkuZmlsdGVyKFxyXG5cdFx0ZnVuY3Rpb24gKHNoZWV0KSB7XHJcblx0XHRcdHJldHVybiAhIHNoZWV0LmRpc2FibGVkO1xyXG5cdFx0fVxyXG5cdCk7XHJcblxyXG5cdC8vIFszXSAtIE1vdW50IHRoZSBjb250YWluZXIgdG8gdGhlIERPTSB0byBtYWtlIGBjb250ZW50V2luZG93YCBhdmFpbGFibGUuXHJcblx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XHJcblxyXG5cdC8vIFs0XSAtIENvcHkgdG8gY2xpcGJvYXJkLlxyXG5cdHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5yZW1vdmVBbGxSYW5nZXMoKTtcclxuXHJcblx0dmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcclxuXHRyYW5nZS5zZWxlY3ROb2RlKCBjb250YWluZXIgKTtcclxuXHR3aW5kb3cuZ2V0U2VsZWN0aW9uKCkuYWRkUmFuZ2UoIHJhbmdlICk7XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0dmFyIHJlc3VsdCA9IGZhbHNlO1xyXG5cclxuXHR0cnkge1xyXG5cdFx0cmVzdWx0ID0gZG9jdW1lbnQuZXhlY0NvbW1hbmQoICdjb3B5JyApO1xyXG5cdFx0Ly8gY29uc29sZS5sb2coICdGYWxsYmFjazogQ29weWluZyB0ZXh0IGNvbW1hbmQgd2FzICcgKyBtc2cgKTsgLy8uXHJcblx0fSBjYXRjaCAoIGVyciApIHtcclxuXHRcdC8vIGNvbnNvbGUuZXJyb3IoICdGYWxsYmFjazogT29wcywgdW5hYmxlIHRvIGNvcHknLCBlcnIgKTsgLy8uXHJcblx0fVxyXG5cdC8vIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoIHRleHRBcmVhICk7IC8vLlxyXG5cclxuXHQvLyBbNS40XSAtIEVuYWJsZSBDU1MuXHJcblx0dmFyIGFjdGl2ZVNoZWV0c19sZW5ndGggPSBhY3RpdmVTaGVldHMubGVuZ3RoO1xyXG5cdGZvciAoIHZhciBpID0gMDsgaSA8IGFjdGl2ZVNoZWV0c19sZW5ndGg7IGkrKyApIHtcclxuXHRcdGFjdGl2ZVNoZWV0c1tpXS5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cdH1cclxuXHJcblx0Ly8gWzZdIC0gUmVtb3ZlIHRoZSBjb250YWluZXJcclxuXHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcclxuXHJcblx0cmV0dXJuICByZXN1bHQ7XHJcbn0iLCIvKipcclxuICogV1BCQyBDb2xsYXBzaWJsZSBHcm91cHNcclxuICpcclxuICogVW5pdmVyc2FsLCBkZXBlbmRlbmN5LWZyZWUgY29udHJvbGxlciBmb3IgZXhwYW5kaW5nL2NvbGxhcHNpbmcgZ3JvdXBlZCBzZWN0aW9ucyBpbiByaWdodC1zaWRlIHBhbmVscyAoSW5zcGVjdG9yL0xpYnJhcnkvRm9ybSBTZXR0aW5ncywgb3IgYW55IG90aGVyIFdQQkMgcGFnZSkuXHJcbiAqXHJcbiAqIFx0XHQ9PT0gSG93IHRvIHVzZSBpdCAocXVpY2spID8gPT09XHJcbiAqXHJcbiAqXHRcdC0tIDEuIE1hcmt1cCAoaW5kZXBlbmRlbnQgbW9kZTogbXVsdGlwbGUgb3BlbiBhbGxvd2VkKSAtLVxyXG4gKlx0XHRcdDxkaXYgY2xhc3M9XCJ3cGJjX2NvbGxhcHNpYmxlXCI+XHJcbiAqXHRcdFx0ICA8c2VjdGlvbiBjbGFzcz1cIndwYmNfdWlfX2NvbGxhcHNpYmxlX2dyb3VwIGlzLW9wZW5cIj5cclxuICpcdFx0XHRcdDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZ3JvdXBfX2hlYWRlclwiPjxoMz5HZW5lcmFsPC9oMz48L2J1dHRvbj5cclxuICpcdFx0XHRcdDxkaXYgY2xhc3M9XCJncm91cF9fZmllbGRzXCI+4oCmPC9kaXY+XHJcbiAqXHRcdFx0ICA8L3NlY3Rpb24+XHJcbiAqXHRcdFx0ICA8c2VjdGlvbiBjbGFzcz1cIndwYmNfdWlfX2NvbGxhcHNpYmxlX2dyb3VwXCI+XHJcbiAqXHRcdFx0XHQ8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImdyb3VwX19oZWFkZXJcIj48aDM+QWR2YW5jZWQ8L2gzPjwvYnV0dG9uPlxyXG4gKlx0XHRcdFx0PGRpdiBjbGFzcz1cImdyb3VwX19maWVsZHNcIj7igKY8L2Rpdj5cclxuICpcdFx0XHQgIDwvc2VjdGlvbj5cclxuICpcdFx0XHQ8L2Rpdj5cclxuICpcclxuICpcdFx0LS0gMi4gRXhjbHVzaXZlL2FjY29yZGlvbiBtb2RlIChvbmUgb3BlbiBhdCBhIHRpbWUpIC0tXHJcbiAqXHRcdFx0PGRpdiBjbGFzcz1cIndwYmNfY29sbGFwc2libGUgd3BiY19jb2xsYXBzaWJsZS0tZXhjbHVzaXZlXCI+4oCmPC9kaXY+XHJcbiAqXHJcbiAqXHRcdC0tIDMuIEF1dG8taW5pdCAtLVxyXG4gKlx0XHRcdFRoZSBzY3JpcHQgYXV0by1pbml0aWFsaXplcyBvbiBET01Db250ZW50TG9hZGVkLiBObyBleHRyYSBjb2RlIG5lZWRlZC5cclxuICpcclxuICpcdFx0LS0gNC4gUHJvZ3JhbW1hdGljIGNvbnRyb2wgKG9wdGlvbmFsKVxyXG4gKlx0XHRcdGNvbnN0IHJvb3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjd3BiY19iZmJfX2luc3BlY3RvcicpO1xyXG4gKlx0XHRcdGNvbnN0IGFwaSAgPSByb290Ll9fd3BiY19jb2xsYXBzaWJsZV9pbnN0YW5jZTsgLy8gc2V0IGJ5IGF1dG8taW5pdFxyXG4gKlxyXG4gKlx0XHRcdGFwaS5vcGVuX2J5X2hlYWRpbmcoJ1ZhbGlkYXRpb24nKTsgLy8gb3BlbiBieSBoZWFkaW5nIHRleHRcclxuICpcdFx0XHRhcGkub3Blbl9ieV9pbmRleCgwKTsgICAgICAgICAgICAgIC8vIG9wZW4gdGhlIGZpcnN0IGdyb3VwXHJcbiAqXHJcbiAqXHRcdC0tIDUuTGlzdGVuIHRvIGV2ZW50cyAoZS5nLiwgdG8gcGVyc2lzdCDigJxvcGVuIGdyb3Vw4oCdIHN0YXRlKSAtLVxyXG4gKlx0XHRcdHJvb3QuYWRkRXZlbnRMaXN0ZW5lcignd3BiYzpjb2xsYXBzaWJsZTpvcGVuJywgIChlKSA9PiB7IGNvbnNvbGUubG9nKCAgZS5kZXRhaWwuZ3JvdXAgKTsgfSk7XHJcbiAqXHRcdFx0cm9vdC5hZGRFdmVudExpc3RlbmVyKCd3cGJjOmNvbGxhcHNpYmxlOmNsb3NlJywgKGUpID0+IHsgY29uc29sZS5sb2coICBlLmRldGFpbC5ncm91cCApOyB9KTtcclxuICpcclxuICpcclxuICpcclxuICogTWFya3VwIGV4cGVjdGF0aW9ucyAobWluaW1hbCk6XHJcbiAqICA8ZGl2IGNsYXNzPVwid3BiY19jb2xsYXBzaWJsZSBbd3BiY19jb2xsYXBzaWJsZS0tZXhjbHVzaXZlXVwiPlxyXG4gKiAgICA8c2VjdGlvbiBjbGFzcz1cIndwYmNfdWlfX2NvbGxhcHNpYmxlX2dyb3VwIFtpcy1vcGVuXVwiPlxyXG4gKiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiZ3JvdXBfX2hlYWRlclwiPiAuLi4gPC9idXR0b24+XHJcbiAqICAgICAgPGRpdiBjbGFzcz1cImdyb3VwX19maWVsZHNcIj4gLi4uIDwvZGl2PlxyXG4gKiAgICA8L3NlY3Rpb24+XHJcbiAqICAgIC4uLiBtb3JlIDxzZWN0aW9uPiAuLi5cclxuICogIDwvZGl2PlxyXG4gKlxyXG4gKiBOb3RlczpcclxuICogIC0gQWRkIGBpcy1vcGVuYCB0byBhbnkgc2VjdGlvbiB5b3Ugd2FudCBpbml0aWFsbHkgZXhwYW5kZWQuXHJcbiAqICAtIEFkZCBgd3BiY19jb2xsYXBzaWJsZS0tZXhjbHVzaXZlYCB0byB0aGUgY29udGFpbmVyIGZvciBcIm9wZW4gb25lIGF0IGEgdGltZVwiIGJlaGF2aW9yLlxyXG4gKiAgLSBXb3JrcyB3aXRoIHlvdXIgZXhpc3RpbmcgQkZCIG1hcmt1cCAoY2xhc3NlcyB1c2VkIHRoZXJlIGFyZSB0aGUgZGVmYXVsdHMpLlxyXG4gKlxyXG4gKiBBY2Nlc3NpYmlsaXR5OlxyXG4gKiAgLSBTZXRzIGFyaWEtZXhwYW5kZWQgb24gLmdyb3VwX19oZWFkZXJcclxuICogIC0gU2V0cyBhcmlhLWhpZGRlbiArIFtoaWRkZW5dIG9uIC5ncm91cF9fZmllbGRzXHJcbiAqICAtIEFycm93VXAvQXJyb3dEb3duIG1vdmUgZm9jdXMgYmV0d2VlbiBoZWFkZXJzOyBFbnRlci9TcGFjZSB0b2dnbGVzXHJcbiAqXHJcbiAqIEV2ZW50cyAoYnViYmxlcyBmcm9tIHRoZSA8c2VjdGlvbj4pOlxyXG4gKiAgLSAnd3BiYzpjb2xsYXBzaWJsZTpvcGVuJyAgKGRldGFpbDogeyBncm91cCwgcm9vdCwgaW5zdGFuY2UgfSlcclxuICogIC0gJ3dwYmM6Y29sbGFwc2libGU6Y2xvc2UnIChkZXRhaWw6IHsgZ3JvdXAsIHJvb3QsIGluc3RhbmNlIH0pXHJcbiAqXHJcbiAqIFB1YmxpYyBBUEkgKGluc3RhbmNlIG1ldGhvZHMpOlxyXG4gKiAgLSBpbml0KCksIGRlc3Ryb3koKSwgcmVmcmVzaCgpXHJcbiAqICAtIGV4cGFuZChncm91cCwgW2V4Y2x1c2l2ZV0pLCBjb2xsYXBzZShncm91cCksIHRvZ2dsZShncm91cClcclxuICogIC0gb3Blbl9ieV9pbmRleChpbmRleCksIG9wZW5fYnlfaGVhZGluZyh0ZXh0KVxyXG4gKiAgLSBpc19leGNsdXNpdmUoKSwgaXNfb3Blbihncm91cClcclxuICpcclxuICogQHZlcnNpb24gMjAyNS0wOC0yNlxyXG4gKiBAc2luY2UgMjAyNS0wOC0yNlxyXG4gKi9cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vID09IEZpbGUgIC9jb2xsYXBzaWJsZV9ncm91cHMuanMgPT0gVGltZSBwb2ludDogMjAyNS0wOC0yNiAxNDoxM1xyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuKGZ1bmN0aW9uICh3LCBkKSB7XHJcblx0J3VzZSBzdHJpY3QnO1xyXG5cclxuXHRjbGFzcyBXUEJDX0NvbGxhcHNpYmxlX0dyb3VwcyB7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDcmVhdGUgYSBjb2xsYXBzaWJsZSBjb250cm9sbGVyIGZvciBhIGNvbnRhaW5lci5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHN0cmluZ30gcm9vdF9lbFxyXG5cdFx0ICogICAgICAgIFRoZSBjb250YWluZXIgZWxlbWVudCAob3IgQ1NTIHNlbGVjdG9yKSB0aGF0IHdyYXBzIGNvbGxhcHNpYmxlIGdyb3Vwcy5cclxuXHRcdCAqICAgICAgICBUaGUgY29udGFpbmVyIHVzdWFsbHkgaGFzIHRoZSBjbGFzcyBgLndwYmNfY29sbGFwc2libGVgLlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRzPXt9XVxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9ICBbb3B0cy5ncm91cF9zZWxlY3Rvcj0nLndwYmNfdWlfX2NvbGxhcHNpYmxlX2dyb3VwJ11cclxuXHRcdCAqICAgICAgICBTZWxlY3RvciBmb3IgZWFjaCBjb2xsYXBzaWJsZSBncm91cCBpbnNpZGUgdGhlIGNvbnRhaW5lci5cclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSAgW29wdHMuaGVhZGVyX3NlbGVjdG9yPScuZ3JvdXBfX2hlYWRlciddXHJcblx0XHQgKiAgICAgICAgU2VsZWN0b3IgZm9yIHRoZSBjbGlja2FibGUgaGVhZGVyIGluc2lkZSBhIGdyb3VwLlxyXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9ICBbb3B0cy5maWVsZHNfc2VsZWN0b3I9Jy5ncm91cF9fZmllbGRzJ11cclxuXHRcdCAqICAgICAgICBTZWxlY3RvciBmb3IgdGhlIGNvbnRlbnQvcGFuZWwgZWxlbWVudCBpbnNpZGUgYSBncm91cC5cclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSAgW29wdHMub3Blbl9jbGFzcz0naXMtb3BlbiddXHJcblx0XHQgKiAgICAgICAgQ2xhc3MgbmFtZSB0aGF0IGluZGljYXRlcyB0aGUgZ3JvdXAgaXMgb3Blbi5cclxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuZXhjbHVzaXZlPWZhbHNlXVxyXG5cdFx0ICogICAgICAgIElmIHRydWUsIG9ubHkgb25lIGdyb3VwIGNhbiBiZSBvcGVuIGF0IGEgdGltZSBpbiB0aGlzIGNvbnRhaW5lci5cclxuXHRcdCAqXHJcblx0XHQgKiBAY29uc3RydWN0b3JcclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdGNvbnN0cnVjdG9yKHJvb3RfZWwsIG9wdHMgPSB7fSkge1xyXG5cdFx0XHR0aGlzLnJvb3QgPSAodHlwZW9mIHJvb3RfZWwgPT09ICdzdHJpbmcnKSA/IGQucXVlcnlTZWxlY3Rvciggcm9vdF9lbCApIDogcm9vdF9lbDtcclxuXHRcdFx0dGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbigge1xyXG5cdFx0XHRcdGdyb3VwX3NlbGVjdG9yIDogJy53cGJjX3VpX19jb2xsYXBzaWJsZV9ncm91cCcsXHJcblx0XHRcdFx0aGVhZGVyX3NlbGVjdG9yOiAnLmdyb3VwX19oZWFkZXInLFxyXG5cdFx0XHRcdGZpZWxkc19zZWxlY3RvcjogJy5ncm91cF9fZmllbGRzLC5ncm91cF9fY29udGVudCcsXHJcblx0XHRcdFx0b3Blbl9jbGFzcyAgICAgOiAnaXMtb3BlbicsXHJcblx0XHRcdFx0ZXhjbHVzaXZlICAgICAgOiBmYWxzZVxyXG5cdFx0XHR9LCBvcHRzICk7XHJcblxyXG5cdFx0XHQvLyBCb3VuZCBoYW5kbGVycyAoZm9yIGFkZC9yZW1vdmVFdmVudExpc3RlbmVyIHN5bW1ldHJ5KS5cclxuXHRcdFx0LyoqIEBwcml2YXRlICovXHJcblx0XHRcdHRoaXMuX29uX2NsaWNrID0gdGhpcy5fb25fY2xpY2suYmluZCggdGhpcyApO1xyXG5cdFx0XHQvKiogQHByaXZhdGUgKi9cclxuXHRcdFx0dGhpcy5fb25fa2V5ZG93biA9IHRoaXMuX29uX2tleWRvd24uYmluZCggdGhpcyApO1xyXG5cclxuXHRcdFx0LyoqIEB0eXBlIHtIVE1MRWxlbWVudFtdfSBAcHJpdmF0ZSAqL1xyXG5cdFx0XHR0aGlzLl9ncm91cHMgPSBbXTtcclxuXHRcdFx0LyoqIEB0eXBlIHtNdXRhdGlvbk9ic2VydmVyfG51bGx9IEBwcml2YXRlICovXHJcblx0XHRcdHRoaXMuX29ic2VydmVyID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEluaXRpYWxpemUgdGhlIGNvbnRyb2xsZXI6IGNhY2hlIGdyb3VwcywgYXR0YWNoIGxpc3RlbmVycywgc2V0IEFSSUEsXHJcblx0XHQgKiBhbmQgc3RhcnQgb2JzZXJ2aW5nIERPTSBjaGFuZ2VzIGluc2lkZSB0aGUgY29udGFpbmVyLlxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm5zIHtXUEJDX0NvbGxhcHNpYmxlX0dyb3Vwc30gVGhlIGluc3RhbmNlIChjaGFpbmFibGUpLlxyXG5cdFx0ICogQGxpc3RlbnMgY2xpY2tcclxuXHRcdCAqIEBsaXN0ZW5zIGtleWRvd25cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdGluaXQoKSB7XHJcblx0XHRcdGlmICggIXRoaXMucm9vdCApIHtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLl9ncm91cHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChcclxuXHRcdFx0XHR0aGlzLnJvb3QucXVlcnlTZWxlY3RvckFsbCggdGhpcy5vcHRzLmdyb3VwX3NlbGVjdG9yIClcclxuXHRcdFx0KTtcclxuXHRcdFx0dGhpcy5yb290LmFkZEV2ZW50TGlzdGVuZXIoICdjbGljaycsIHRoaXMuX29uX2NsaWNrLCBmYWxzZSApO1xyXG5cdFx0XHR0aGlzLnJvb3QuYWRkRXZlbnRMaXN0ZW5lciggJ2tleWRvd24nLCB0aGlzLl9vbl9rZXlkb3duLCBmYWxzZSApO1xyXG5cclxuXHRcdFx0Ly8gT2JzZXJ2ZSBkeW5hbWljIGluc2VydHMvcmVtb3ZhbHMgKEluc3BlY3RvciByZS1yZW5kZXJzKS5cclxuXHRcdFx0dGhpcy5fb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlciggKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzaCgpO1xyXG5cdFx0XHR9ICk7XHJcblx0XHRcdHRoaXMuX29ic2VydmVyLm9ic2VydmUoIHRoaXMucm9vdCwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSApO1xyXG5cclxuXHRcdFx0dGhpcy5fc3luY19hbGxfYXJpYSgpO1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFRlYXIgZG93biB0aGUgY29udHJvbGxlcjogZGV0YWNoIGxpc3RlbmVycywgc3RvcCB0aGUgb2JzZXJ2ZXIsXHJcblx0XHQgKiBhbmQgZHJvcCBpbnRlcm5hbCByZWZlcmVuY2VzLlxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0ZGVzdHJveSgpIHtcclxuXHRcdFx0aWYgKCAhdGhpcy5yb290ICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lciggJ2NsaWNrJywgdGhpcy5fb25fY2xpY2ssIGZhbHNlICk7XHJcblx0XHRcdHRoaXMucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCAna2V5ZG93bicsIHRoaXMuX29uX2tleWRvd24sIGZhbHNlICk7XHJcblx0XHRcdGlmICggdGhpcy5fb2JzZXJ2ZXIgKSB7XHJcblx0XHRcdFx0dGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG5cdFx0XHRcdHRoaXMuX29ic2VydmVyID0gbnVsbDtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLl9ncm91cHMgPSBbXTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJlLXNjYW4gdGhlIERPTSBmb3IgY3VycmVudCBncm91cHMgYW5kIHJlLWFwcGx5IEFSSUEgdG8gYWxsIG9mIHRoZW0uXHJcblx0XHQgKiBVc2VmdWwgYWZ0ZXIgZHluYW1pYyAocmUpcmVuZGVycy5cclxuXHRcdCAqXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdHJlZnJlc2goKSB7XHJcblx0XHRcdGlmICggIXRoaXMucm9vdCApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5fZ3JvdXBzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXHJcblx0XHRcdFx0dGhpcy5yb290LnF1ZXJ5U2VsZWN0b3JBbGwoIHRoaXMub3B0cy5ncm91cF9zZWxlY3RvciApXHJcblx0XHRcdCk7XHJcblx0XHRcdHRoaXMuX3N5bmNfYWxsX2FyaWEoKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIENoZWNrIHdoZXRoZXIgdGhlIGNvbnRhaW5lciBpcyBpbiBleGNsdXNpdmUgKGFjY29yZGlvbikgbW9kZS5cclxuXHRcdCAqXHJcblx0XHQgKiBPcmRlciBvZiBwcmVjZWRlbmNlOlxyXG5cdFx0ICogIDEpIEV4cGxpY2l0IG9wdGlvbiBgb3B0cy5leGNsdXNpdmVgXHJcblx0XHQgKiAgMikgQ29udGFpbmVyIGhhcyBjbGFzcyBgLndwYmNfY29sbGFwc2libGUtLWV4Y2x1c2l2ZWBcclxuXHRcdCAqICAzKSBDb250YWluZXIgbWF0Y2hlcyBgW2RhdGEtd3BiYy1hY2NvcmRpb249XCJleGNsdXNpdmVcIl1gXHJcblx0XHQgKlxyXG5cdFx0ICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgZXhjbHVzaXZlIG1vZGUgaXMgYWN0aXZlLlxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0aXNfZXhjbHVzaXZlKCkge1xyXG5cdFx0XHRyZXR1cm4gISEoXHJcblx0XHRcdFx0dGhpcy5vcHRzLmV4Y2x1c2l2ZSB8fFxyXG5cdFx0XHRcdHRoaXMucm9vdC5jbGFzc0xpc3QuY29udGFpbnMoICd3cGJjX2NvbGxhcHNpYmxlLS1leGNsdXNpdmUnICkgfHxcclxuXHRcdFx0XHR0aGlzLnJvb3QubWF0Y2hlcyggJ1tkYXRhLXdwYmMtYWNjb3JkaW9uPVwiZXhjbHVzaXZlXCJdJyApXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBEZXRlcm1pbmUgd2hldGhlciBhIHNwZWNpZmljIGdyb3VwIGlzIG9wZW4uXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZ3JvdXAgVGhlIGdyb3VwIGVsZW1lbnQgdG8gdGVzdC5cclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBncm91cCBpcyBjdXJyZW50bHkgb3Blbi5cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdGlzX29wZW4oZ3JvdXApIHtcclxuXHRcdFx0cmV0dXJuIGdyb3VwLmNsYXNzTGlzdC5jb250YWlucyggdGhpcy5vcHRzLm9wZW5fY2xhc3MgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIE9wZW4gYSBncm91cC4gSG9ub3JzIGV4Y2x1c2l2ZSBtb2RlIGJ5IGNvbGxhcHNpbmcgYWxsIHNpYmxpbmcgZ3JvdXBzXHJcblx0XHQgKiAocXVlcmllZCBmcm9tIHRoZSBsaXZlIERPTSBhdCBjYWxsLXRpbWUpLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGdyb3VwIFRoZSBncm91cCBlbGVtZW50IHRvIG9wZW4uXHJcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtleGNsdXNpdmVdXHJcblx0XHQgKiAgICAgICAgSWYgcHJvdmlkZWQsIG92ZXJyaWRlcyBjb250YWluZXIgbW9kZSBmb3IgdGhpcyBhY3Rpb24gb25seS5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQGZpcmVzIEN1c3RvbUV2ZW50I3dwYmM6Y29sbGFwc2libGU6b3BlblxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0ZXhwYW5kKGdyb3VwLCBleGNsdXNpdmUpIHtcclxuXHRcdFx0aWYgKCAhZ3JvdXAgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGRvX2V4Y2x1c2l2ZSA9ICh0eXBlb2YgZXhjbHVzaXZlID09PSAnYm9vbGVhbicpID8gZXhjbHVzaXZlIDogdGhpcy5pc19leGNsdXNpdmUoKTtcclxuXHRcdFx0aWYgKCBkb19leGNsdXNpdmUgKSB7XHJcblx0XHRcdFx0Ly8gQWx3YXlzIHVzZSB0aGUgbGl2ZSBET00sIG5vdCB0aGUgY2FjaGVkIGxpc3QuXHJcblx0XHRcdFx0QXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChcclxuXHRcdFx0XHRcdHRoaXMucm9vdC5xdWVyeVNlbGVjdG9yQWxsKCB0aGlzLm9wdHMuZ3JvdXBfc2VsZWN0b3IgKSxcclxuXHRcdFx0XHRcdChnKSA9PiB7XHJcblx0XHRcdFx0XHRcdGlmICggZyAhPT0gZ3JvdXAgKSB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5fc2V0X29wZW4oIGcsIGZhbHNlICk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHRoaXMuX3NldF9vcGVuKCBncm91cCwgdHJ1ZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQ2xvc2UgYSBncm91cC5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBncm91cCBUaGUgZ3JvdXAgZWxlbWVudCB0byBjbG9zZS5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQGZpcmVzIEN1c3RvbUV2ZW50I3dwYmM6Y29sbGFwc2libGU6Y2xvc2VcclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdGNvbGxhcHNlKGdyb3VwKSB7XHJcblx0XHRcdGlmICggIWdyb3VwICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLl9zZXRfb3BlbiggZ3JvdXAsIGZhbHNlICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBUb2dnbGUgYSBncm91cCdzIG9wZW4vY2xvc2VkIHN0YXRlLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGdyb3VwIFRoZSBncm91cCBlbGVtZW50IHRvIHRvZ2dsZS5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0dG9nZ2xlKGdyb3VwKSB7XHJcblx0XHRcdGlmICggIWdyb3VwICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzW3RoaXMuaXNfb3BlbiggZ3JvdXAgKSA/ICdjb2xsYXBzZScgOiAnZXhwYW5kJ10oIGdyb3VwICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBPcGVuIGEgZ3JvdXAgYnkgaXRzIGluZGV4IHdpdGhpbiB0aGUgY29udGFpbmVyICgwLWJhc2VkKS5cclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggWmVyby1iYXNlZCBpbmRleCBvZiB0aGUgZ3JvdXAuXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdG9wZW5fYnlfaW5kZXgoaW5kZXgpIHtcclxuXHRcdFx0Y29uc3QgZ3JvdXAgPSB0aGlzLl9ncm91cHNbaW5kZXhdO1xyXG5cdFx0XHRpZiAoIGdyb3VwICkge1xyXG5cdFx0XHRcdHRoaXMuZXhwYW5kKCBncm91cCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBPcGVuIGEgZ3JvdXAgYnkgbWF0Y2hpbmcgdGV4dCBjb250YWluZWQgd2l0aGluIHRoZSA8aDM+IGluc2lkZSB0aGUgaGVhZGVyLlxyXG5cdFx0ICogVGhlIGNvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZSBhbmQgc3Vic3RyaW5nLWJhc2VkLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQgdG8gbWF0Y2ggYWdhaW5zdCB0aGUgaGVhZGluZyBjb250ZW50cy5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0b3Blbl9ieV9oZWFkaW5nKHRleHQpIHtcclxuXHRcdFx0aWYgKCAhdGV4dCApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0Y29uc3QgdCAgICAgPSBTdHJpbmcoIHRleHQgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRjb25zdCBtYXRjaCA9IHRoaXMuX2dyb3Vwcy5maW5kKCAoZykgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IGggPSBnLnF1ZXJ5U2VsZWN0b3IoIHRoaXMub3B0cy5oZWFkZXJfc2VsZWN0b3IgKyAnIGgzJyApO1xyXG5cdFx0XHRcdHJldHVybiBoICYmIGgudGV4dENvbnRlbnQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCB0ICkgIT09IC0xO1xyXG5cdFx0XHR9ICk7XHJcblx0XHRcdGlmICggbWF0Y2ggKSB7XHJcblx0XHRcdFx0dGhpcy5leHBhbmQoIG1hdGNoICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyBJbnRlcm5hbFxyXG5cdFx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogRGVsZWdhdGVkIGNsaWNrIGhhbmRsZXIgZm9yIGhlYWRlcnMuXHJcblx0XHQgKlxyXG5cdFx0ICogQHByaXZhdGVcclxuXHRcdCAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXYgVGhlIGNsaWNrIGV2ZW50LlxyXG5cdFx0ICogQHJldHVybnMge3ZvaWR9XHJcblx0XHQgKiBAc2luY2UgMjAyNS0wOC0yNlxyXG5cdFx0ICovXHJcblx0XHRfb25fY2xpY2soZXYpIHtcclxuXHRcdFx0Y29uc3QgYnRuID0gZXYudGFyZ2V0LmNsb3Nlc3QoIHRoaXMub3B0cy5oZWFkZXJfc2VsZWN0b3IgKTtcclxuXHRcdFx0aWYgKCAhYnRuIHx8ICF0aGlzLnJvb3QuY29udGFpbnMoIGJ0biApICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRldi5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRldi5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0Y29uc3QgZ3JvdXAgPSBidG4uY2xvc2VzdCggdGhpcy5vcHRzLmdyb3VwX3NlbGVjdG9yICk7XHJcblx0XHRcdGlmICggZ3JvdXAgKSB7XHJcblx0XHRcdFx0dGhpcy50b2dnbGUoIGdyb3VwICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEtleWJvYXJkIGhhbmRsZXIgZm9yIGhlYWRlciBpbnRlcmFjdGlvbnMgYW5kIHJvdmluZyBmb2N1czpcclxuXHRcdCAqICAtIEVudGVyL1NwYWNlIHRvZ2dsZXMgdGhlIGFjdGl2ZSBncm91cC5cclxuXHRcdCAqICAtIEFycm93VXAvQXJyb3dEb3duIG1vdmVzIGZvY3VzIGJldHdlZW4gZ3JvdXAgaGVhZGVycy5cclxuXHRcdCAqXHJcblx0XHQgKiBAcHJpdmF0ZVxyXG5cdFx0ICogQHBhcmFtIHtLZXlib2FyZEV2ZW50fSBldiBUaGUga2V5Ym9hcmQgZXZlbnQuXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdF9vbl9rZXlkb3duKGV2KSB7XHJcblx0XHRcdGNvbnN0IGJ0biA9IGV2LnRhcmdldC5jbG9zZXN0KCB0aGlzLm9wdHMuaGVhZGVyX3NlbGVjdG9yICk7XHJcblx0XHRcdGlmICggIWJ0biApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGNvbnN0IGtleSA9IGV2LmtleTtcclxuXHJcblx0XHRcdC8vIFRvZ2dsZSBvbiBFbnRlciAvIFNwYWNlLlxyXG5cdFx0XHRpZiAoIGtleSA9PT0gJ0VudGVyJyB8fCBrZXkgPT09ICcgJyApIHtcclxuXHRcdFx0XHRldi5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdGNvbnN0IGdyb3VwID0gYnRuLmNsb3Nlc3QoIHRoaXMub3B0cy5ncm91cF9zZWxlY3RvciApO1xyXG5cdFx0XHRcdGlmICggZ3JvdXAgKSB7XHJcblx0XHRcdFx0XHR0aGlzLnRvZ2dsZSggZ3JvdXAgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBNb3ZlIGZvY3VzIHdpdGggQXJyb3dVcC9BcnJvd0Rvd24gYmV0d2VlbiBoZWFkZXJzIGluIHRoaXMgY29udGFpbmVyLlxyXG5cdFx0XHRpZiAoIGtleSA9PT0gJ0Fycm93VXAnIHx8IGtleSA9PT0gJ0Fycm93RG93bicgKSB7XHJcblx0XHRcdFx0ZXYucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHRjb25zdCBoZWFkZXJzID0gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKFxyXG5cdFx0XHRcdFx0dGhpcy5yb290LnF1ZXJ5U2VsZWN0b3JBbGwoIHRoaXMub3B0cy5ncm91cF9zZWxlY3RvciApLFxyXG5cdFx0XHRcdFx0KGcpID0+IGcucXVlcnlTZWxlY3RvciggdGhpcy5vcHRzLmhlYWRlcl9zZWxlY3RvciApXHJcblx0XHRcdFx0KS5maWx0ZXIoIEJvb2xlYW4gKTtcclxuXHRcdFx0XHRjb25zdCBpZHggICAgID0gaGVhZGVycy5pbmRleE9mKCBidG4gKTtcclxuXHRcdFx0XHRpZiAoIGlkeCAhPT0gLTEgKSB7XHJcblx0XHRcdFx0XHRjb25zdCBuZXh0X2lkeCA9IChrZXkgPT09ICdBcnJvd0Rvd24nKVxyXG5cdFx0XHRcdFx0XHQ/IE1hdGgubWluKCBoZWFkZXJzLmxlbmd0aCAtIDEsIGlkeCArIDEgKVxyXG5cdFx0XHRcdFx0XHQ6IE1hdGgubWF4KCAwLCBpZHggLSAxICk7XHJcblx0XHRcdFx0XHRoZWFkZXJzW25leHRfaWR4XS5mb2N1cygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQXBwbHkgQVJJQSBzeW5jaHJvbml6YXRpb24gdG8gYWxsIGtub3duIGdyb3VwcyBiYXNlZCBvbiB0aGVpciBvcGVuIHN0YXRlLlxyXG5cdFx0ICpcclxuXHRcdCAqIEBwcml2YXRlXHJcblx0XHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdF9zeW5jX2FsbF9hcmlhKCkge1xyXG5cdFx0XHR0aGlzLl9ncm91cHMuZm9yRWFjaCggKGcpID0+IHRoaXMuX3N5bmNfZ3JvdXBfYXJpYSggZyApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBTeW5jIEFSSUEgYXR0cmlidXRlcyBhbmQgdmlzaWJpbGl0eSBvbiBhIHNpbmdsZSBncm91cC5cclxuXHRcdCAqXHJcblx0XHQgKiBAcHJpdmF0ZVxyXG5cdFx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZ3JvdXAgVGhlIGdyb3VwIGVsZW1lbnQgdG8gc3luYy5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQHNpbmNlIDIwMjUtMDgtMjZcclxuXHRcdCAqL1xyXG5cdFx0X3N5bmNfZ3JvdXBfYXJpYShncm91cCkge1xyXG5cdFx0XHRjb25zdCBpc19vcGVuID0gdGhpcy5pc19vcGVuKCBncm91cCApO1xyXG5cdFx0XHRjb25zdCBoZWFkZXIgID0gZ3JvdXAucXVlcnlTZWxlY3RvciggdGhpcy5vcHRzLmhlYWRlcl9zZWxlY3RvciApO1xyXG5cdFx0XHQvLyBPbmx5IGRpcmVjdCBjaGlsZHJlbiB0aGF0IG1hdGNoLlxyXG5cdFx0XHRjb25zdCBwYW5lbHMgPSBBcnJheS5wcm90b3R5cGUuZmlsdGVyLmNhbGwoIGdyb3VwLmNoaWxkcmVuLCAoZWwpID0+IGVsLm1hdGNoZXMoIHRoaXMub3B0cy5maWVsZHNfc2VsZWN0b3IgKSApO1xyXG5cclxuXHRcdFx0Ly8gSGVhZGVyIEFSSUEuXHJcblx0XHRcdGlmICggaGVhZGVyICkge1xyXG5cdFx0XHRcdGhlYWRlci5zZXRBdHRyaWJ1dGUoICdyb2xlJywgJ2J1dHRvbicgKTtcclxuXHRcdFx0XHRoZWFkZXIuc2V0QXR0cmlidXRlKCAnYXJpYS1leHBhbmRlZCcsIGlzX29wZW4gPyAndHJ1ZScgOiAnZmFsc2UnICk7XHJcblxyXG5cdFx0XHRcdGlmICggcGFuZWxzLmxlbmd0aCApIHtcclxuXHRcdFx0XHRcdC8vIEVuc3VyZSBlYWNoIHBhbmVsIGhhcyBhbiBpZDsgdGhlbiB3aXJlIGFyaWEtY29udHJvbHMgd2l0aCBzcGFjZS1zZXBhcmF0ZWQgaWRzLlxyXG5cdFx0XHRcdFx0Y29uc3QgaWRzID0gcGFuZWxzLm1hcCggKHApID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKCAhcC5pZCApIHAuaWQgPSB0aGlzLl9nZW5lcmF0ZV9pZCggJ3dwYmNfY29sbGFwc2libGVfcGFuZWwnICk7XHJcblx0XHRcdFx0XHRcdHJldHVybiBwLmlkO1xyXG5cdFx0XHRcdFx0fSApO1xyXG5cdFx0XHRcdFx0aGVhZGVyLnNldEF0dHJpYnV0ZSggJ2FyaWEtY29udHJvbHMnLCBpZHMuam9pbiggJyAnICkgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vICgzKSBQYW5lbHMgQVJJQSArIHZpc2liaWxpdHkuXHJcblx0XHRcdHBhbmVscy5mb3JFYWNoKCAocCkgPT4ge1xyXG5cdFx0XHRcdHAuaGlkZGVuID0gIWlzX29wZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFjdHVhbCB2aXNpYmlsaXR5LlxyXG5cdFx0XHRcdHAuc2V0QXR0cmlidXRlKCAnYXJpYS1oaWRkZW4nLCBpc19vcGVuID8gJ2ZhbHNlJyA6ICd0cnVlJyApOyAvLyBBUklBLlxyXG5cdFx0XHR9ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJbnRlcm5hbCBzdGF0ZSBjaGFuZ2U6IHNldCBhIGdyb3VwJ3Mgb3Blbi9jbG9zZWQgc3RhdGUsIHN5bmMgQVJJQSxcclxuXHRcdCAqIG1hbmFnZSBmb2N1cyBvbiBjb2xsYXBzZSwgYW5kIGVtaXQgYSBjdXN0b20gZXZlbnQuXHJcblx0XHQgKlxyXG5cdFx0ICogQHByaXZhdGVcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGdyb3VwIFRoZSBncm91cCBlbGVtZW50IHRvIG11dGF0ZS5cclxuXHRcdCAqIEBwYXJhbSB7Ym9vbGVhbn0gb3BlbiBXaGV0aGVyIHRoZSBncm91cCBzaG91bGQgYmUgb3Blbi5cclxuXHRcdCAqIEByZXR1cm5zIHt2b2lkfVxyXG5cdFx0ICogQGZpcmVzIEN1c3RvbUV2ZW50I3dwYmM6Y29sbGFwc2libGU6b3BlblxyXG5cdFx0ICogQGZpcmVzIEN1c3RvbUV2ZW50I3dwYmM6Y29sbGFwc2libGU6Y2xvc2VcclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdF9zZXRfb3Blbihncm91cCwgb3Blbikge1xyXG5cdFx0XHRpZiAoICFvcGVuICYmIGdyb3VwLmNvbnRhaW5zKCBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICkgKSB7XHJcblx0XHRcdFx0Y29uc3QgaGVhZGVyID0gZ3JvdXAucXVlcnlTZWxlY3RvciggdGhpcy5vcHRzLmhlYWRlcl9zZWxlY3RvciApO1xyXG5cdFx0XHRcdGhlYWRlciAmJiBoZWFkZXIuZm9jdXMoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRncm91cC5jbGFzc0xpc3QudG9nZ2xlKCB0aGlzLm9wdHMub3Blbl9jbGFzcywgb3BlbiApO1xyXG5cdFx0XHR0aGlzLl9zeW5jX2dyb3VwX2FyaWEoIGdyb3VwICk7XHJcblx0XHRcdGNvbnN0IGV2X25hbWUgPSBvcGVuID8gJ3dwYmM6Y29sbGFwc2libGU6b3BlbicgOiAnd3BiYzpjb2xsYXBzaWJsZTpjbG9zZSc7XHJcblx0XHRcdGdyb3VwLmRpc3BhdGNoRXZlbnQoIG5ldyBDdXN0b21FdmVudCggZXZfbmFtZSwge1xyXG5cdFx0XHRcdGJ1YmJsZXM6IHRydWUsXHJcblx0XHRcdFx0ZGV0YWlsIDogeyBncm91cCwgcm9vdDogdGhpcy5yb290LCBpbnN0YW5jZTogdGhpcyB9XHJcblx0XHRcdH0gKSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogR2VuZXJhdGUgYSB1bmlxdWUgRE9NIGlkIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguXHJcblx0XHQgKlxyXG5cdFx0ICogQHByaXZhdGVcclxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXggVGhlIGlkIHByZWZpeCB0byB1c2UuXHJcblx0XHQgKiBAcmV0dXJucyB7c3RyaW5nfSBBIHVuaXF1ZSBlbGVtZW50IGlkIG5vdCBwcmVzZW50IGluIHRoZSBkb2N1bWVudC5cclxuXHRcdCAqIEBzaW5jZSAyMDI1LTA4LTI2XHJcblx0XHQgKi9cclxuXHRcdF9nZW5lcmF0ZV9pZChwcmVmaXgpIHtcclxuXHRcdFx0bGV0IGkgPSAxO1xyXG5cdFx0XHRsZXQgaWQ7XHJcblx0XHRcdGRvIHtcclxuXHRcdFx0XHRpZCA9IHByZWZpeCArICdfJyArIChpKyspO1xyXG5cdFx0XHR9XHJcblx0XHRcdHdoaWxlICggZC5nZXRFbGVtZW50QnlJZCggaWQgKSApO1xyXG5cdFx0XHRyZXR1cm4gaWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBBdXRvLWluaXRpYWxpemUgY29sbGFwc2libGUgY29udHJvbGxlcnMgb24gdGhlIHBhZ2UuXHJcblx0ICogRmluZHMgdG9wLWxldmVsIGAud3BiY19jb2xsYXBzaWJsZWAgY29udGFpbmVycyAoaWdub3JpbmcgbmVzdGVkIG9uZXMpLFxyXG5cdCAqIGFuZCBpbnN0YW50aWF0ZXMge0BsaW5rIFdQQkNfQ29sbGFwc2libGVfR3JvdXBzfSBvbiBlYWNoLlxyXG5cdCAqXHJcblx0ICogQGZ1bmN0aW9uIFdQQkNfQ29sbGFwc2libGVfQXV0b0luaXRcclxuXHQgKiBAcmV0dXJucyB7dm9pZH1cclxuXHQgKiBAc2luY2UgMjAyNS0wOC0yNlxyXG5cdCAqIEBleGFtcGxlXHJcblx0ICogLy8gUnVucyBhdXRvbWF0aWNhbGx5IG9uIERPTUNvbnRlbnRMb2FkZWQ7IGNhbiBhbHNvIGJlIGNhbGxlZCBtYW51YWxseTpcclxuXHQgKiBXUEJDX0NvbGxhcHNpYmxlX0F1dG9Jbml0KCk7XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19jb2xsYXBzaWJsZV9fYXV0b19pbml0KCkge1xyXG5cdFx0dmFyIFJPT1QgID0gJy53cGJjX2NvbGxhcHNpYmxlJztcclxuXHRcdHZhciBub2RlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBkLnF1ZXJ5U2VsZWN0b3JBbGwoIFJPT1QgKSApXHJcblx0XHRcdC5maWx0ZXIoIGZ1bmN0aW9uIChuKSB7XHJcblx0XHRcdFx0cmV0dXJuICFuLnBhcmVudEVsZW1lbnQgfHwgIW4ucGFyZW50RWxlbWVudC5jbG9zZXN0KCBST09UICk7XHJcblx0XHRcdH0gKTtcclxuXHJcblx0XHRub2Rlcy5mb3JFYWNoKCBmdW5jdGlvbiAobm9kZSkge1xyXG5cdFx0XHRpZiAoIG5vZGUuX193cGJjX2NvbGxhcHNpYmxlX2luc3RhbmNlICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR2YXIgZXhjbHVzaXZlID0gbm9kZS5jbGFzc0xpc3QuY29udGFpbnMoICd3cGJjX2NvbGxhcHNpYmxlLS1leGNsdXNpdmUnICkgfHwgbm9kZS5tYXRjaGVzKCAnW2RhdGEtd3BiYy1hY2NvcmRpb249XCJleGNsdXNpdmVcIl0nICk7XHJcblxyXG5cdFx0XHRub2RlLl9fd3BiY19jb2xsYXBzaWJsZV9pbnN0YW5jZSA9IG5ldyBXUEJDX0NvbGxhcHNpYmxlX0dyb3Vwcyggbm9kZSwgeyBleGNsdXNpdmUgfSApLmluaXQoKTtcclxuXHRcdH0gKTtcclxuXHR9XHJcblxyXG5cdC8vIEV4cG9ydCB0byBnbG9iYWwgZm9yIG1hbnVhbCBjb250cm9sIGlmIG5lZWRlZC5cclxuXHR3LldQQkNfQ29sbGFwc2libGVfR3JvdXBzICAgPSBXUEJDX0NvbGxhcHNpYmxlX0dyb3VwcztcclxuXHR3LldQQkNfQ29sbGFwc2libGVfQXV0b0luaXQgPSB3cGJjX2NvbGxhcHNpYmxlX19hdXRvX2luaXQ7XHJcblxyXG5cdC8vIERPTS1yZWFkeSBhdXRvIGluaXQuXHJcblx0aWYgKCBkLnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJyApIHtcclxuXHRcdGQuYWRkRXZlbnRMaXN0ZW5lciggJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cGJjX2NvbGxhcHNpYmxlX19hdXRvX2luaXQsIHsgb25jZTogdHJ1ZSB9ICk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHdwYmNfY29sbGFwc2libGVfX2F1dG9faW5pdCgpO1xyXG5cdH1cclxufSkoIHdpbmRvdywgZG9jdW1lbnQgKTtcclxuIiwiLyogZ2xvYmFscyB3aW5kb3csIGRvY3VtZW50ICovXHJcbi8qKlxyXG4gKiBXUEJDIFNsaWRlciBMZW5ndGggR3JvdXBzXHJcbiAqXHJcbiAqIFVuaXZlcnNhbCwgZGVwZW5kZW5jeS1mcmVlIGNvbnRyb2xsZXIgdGhhdCBrZWVwcyBhIFwibGVuZ3RoXCIgY29udHJvbCBpbiBzeW5jOlxyXG4gKiAgLSBudW1iZXIgaW5wdXQgIChkYXRhLXdwYmNfc2xpZGVyX2xlbl92YWx1ZSlcclxuICogIC0gdW5pdCBzZWxlY3QgICAoZGF0YS13cGJjX3NsaWRlcl9sZW5fdW5pdClcclxuICogIC0gcmFuZ2Ugc2xpZGVyICAoZGF0YS13cGJjX3NsaWRlcl9sZW5fcmFuZ2UpXHJcbiAqICAtIHdyaXRlciBpbnB1dCAgKGRhdGEtd3BiY19zbGlkZXJfbGVuX3dyaXRlcikgIFtvcHRpb25hbCBidXQgcmVjb21tZW5kZWRdXHJcbiAqXHJcbiAqIFRoZSBcIndyaXRlclwiIHN0b3JlcyB0aGUgY29tYmluZWQgdmFsdWUgbGlrZTogXCIxMDAlXCIsIFwiNDIwcHhcIiwgXCIxMi41cmVtXCIuXHJcbiAqIFdoZW4gbnVtYmVyL3VuaXQvc2xpZGVyIGNoYW5nZSAtPiB3cml0ZXIgdXBkYXRlcyBhbmQgZW1pdHMgJ2lucHV0JyAoYnViYmxlcykuXHJcbiAqIFdoZW4gd3JpdGVyIGlzIGNoYW5nZWQgZXh0ZXJuYWxseSAoYXBwbHktZnJvbS1KU09OLCBldGMpIC0+IFVJIHVwZGF0ZXMuXHJcbiAqXHJcbiAqIE1hcmt1cCBleHBlY3RhdGlvbnMgKG1pbmltYWwpOlxyXG4gKiAgPGRpdiBjbGFzcz1cIndwYmNfc2xpZGVyX2xlbl9ncm91cFwiXHJcbiAqICAgICAgIGRhdGEtd3BiY19zbGlkZXJfbGVuX2JvdW5kc19tYXA9J3tcIiVcIjp7XCJtaW5cIjozMCxcIm1heFwiOjEwMCxcInN0ZXBcIjoxfSxcInB4XCI6e1wibWluXCI6MzAwLFwibWF4XCI6MjAwMCxcInN0ZXBcIjoxMH19J1xyXG4gKiAgICAgICBkYXRhLXdwYmNfc2xpZGVyX2xlbl9kZWZhdWx0X3VuaXQ9XCIlXCI+XHJcbiAqICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZGF0YS13cGJjX3NsaWRlcl9sZW5fdmFsdWU+XHJcbiAqICAgIDxzZWxlY3QgZGF0YS13cGJjX3NsaWRlcl9sZW5fdW5pdD4uLi48L3NlbGVjdD5cclxuICogICAgPGlucHV0IHR5cGU9XCJyYW5nZVwiIGRhdGEtd3BiY19zbGlkZXJfbGVuX3JhbmdlPlxyXG4gKiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBkYXRhLXdwYmNfc2xpZGVyX2xlbl93cml0ZXIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XHJcbiAqICA8L2Rpdj5cclxuICpcclxuICogUGVyZm9ybWFuY2Ugbm90ZXM6XHJcbiAqIC0gTXV0YXRpb25PYnNlcnZlciBpcyBESVNBQkxFRCBieSBkZWZhdWx0IChwcmV2ZW50cyBwZXJmb3JtYW5jZSBpc3N1ZXMpLlxyXG4gKiAtIElmIHlvdXIgVUkgcmUtcmVuZGVycyBhbmQgaW5zZXJ0cyBuZXcgZ3JvdXBzIGR5bmFtaWNhbGx5LCBjYWxsOlxyXG4gKiAgICAgV1BCQ19TbGlkZXJfTGVuX0F1dG9Jbml0KCk7ICBPUiBpbnN0YW5jZS5yZWZyZXNoKCk7XHJcbiAqICAgT3IgZW5hYmxlIG9ic2VydmVyIHZpYTogbmV3IFdQQkNfU2xpZGVyX0xlbl9Hcm91cHMocm9vdCwgeyBlbmFibGVfb2JzZXJ2ZXI6dHJ1ZSB9KS5pbml0KCk7XHJcbiAqXHJcbiAqIFB1YmxpYyBBUEkgKGluc3RhbmNlIG1ldGhvZHMpOlxyXG4gKiAgLSBpbml0KCksIGRlc3Ryb3koKSwgcmVmcmVzaCgpXHJcbiAqXHJcbiAqIEB2ZXJzaW9uIDIwMjYtMDEtMjVcclxuICogQHNpbmNlICAgMjAyNi0wMS0yNVxyXG4gKiBAZmlsZSAgICAuLi9pbmNsdWRlcy9fX2pzL2FkbWluL3NsaWRlcl9ncm91cHMvd3BiY19sZW5fZ3JvdXBzLmpzXHJcbiAqL1xyXG4oZnVuY3Rpb24gKHcsIGQpIHtcclxuXHQndXNlIHN0cmljdCc7XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBIZWxwZXJzXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdGZ1bmN0aW9uIGNsYW1wX251bSh2LCBtaW4sIG1heCkge1xyXG5cdFx0aWYgKHR5cGVvZiBtaW4gPT09ICdudW1iZXInICYmICFpc05hTihtaW4pKSB2ID0gTWF0aC5tYXgobWluLCB2KTtcclxuXHRcdGlmICh0eXBlb2YgbWF4ID09PSAnbnVtYmVyJyAmJiAhaXNOYU4obWF4KSkgdiA9IE1hdGgubWluKG1heCwgdik7XHJcblx0XHRyZXR1cm4gdjtcclxuXHR9XHJcblxyXG5cdGZ1bmN0aW9uIHBhcnNlX2Zsb2F0KHYpIHtcclxuXHRcdHZhciBuID0gcGFyc2VGbG9hdCh2KTtcclxuXHRcdHJldHVybiBpc05hTihuKSA/IG51bGwgOiBuO1xyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gc2FmZV9qc29uX3BhcnNlKHN0cikge1xyXG5cdFx0dHJ5IHtcclxuXHRcdFx0cmV0dXJuIEpTT04ucGFyc2Uoc3RyKTtcclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBwYXJzZV9sZW5fY29tYmluZWQocmF3LCBkZWZhdWx0X3VuaXQpIHtcclxuXHRcdHZhciBzID0gKHJhdyA9PSBudWxsKSA/ICcnIDogU3RyaW5nKHJhdykudHJpbSgpO1xyXG5cdFx0aWYgKCFzKSByZXR1cm4geyBudW06ICcnLCB1bml0OiBkZWZhdWx0X3VuaXQgfHwgJyUnIH07XHJcblxyXG5cdFx0dmFyIG0gPSBzLm1hdGNoKC9eXFxzKihbXFwtXT9cXGQrKD86XFwuXFxkKyk/KVxccyooW2EteiVdKilcXHMqJC9pKTtcclxuXHRcdGlmICghbSkge1xyXG5cdFx0XHQvLyBJZiBpdCdzIG5vdCBwYXJzZWFibGUsIHRyZWF0IGFzIG51bWJlciBhbmQga2VlcCBkZWZhdWx0IHVuaXQuXHJcblx0XHRcdHJldHVybiB7IG51bTogcywgdW5pdDogZGVmYXVsdF91bml0IHx8ICclJyB9O1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBudW0gID0gbVsxXSA/IFN0cmluZyhtWzFdKSA6ICcnO1xyXG5cdFx0dmFyIHVuaXQgPSBtWzJdID8gU3RyaW5nKG1bMl0pIDogJyc7XHJcblx0XHRpZiAoIXVuaXQpIHVuaXQgPSBkZWZhdWx0X3VuaXQgfHwgJyUnO1xyXG5cclxuXHRcdHJldHVybiB7IG51bTogbnVtLCB1bml0OiB1bml0IH07XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBidWlsZF9jb21iaW5lZChudW0sIHVuaXQpIHtcclxuXHRcdGlmIChudW0gPT0gbnVsbCB8fCBTdHJpbmcobnVtKS50cmltKCkgPT09ICcnKSByZXR1cm4gJyc7XHJcblx0XHRyZXR1cm4gU3RyaW5nKG51bSkgKyBTdHJpbmcodW5pdCB8fCAnJyk7XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBlbWl0X2lucHV0KGVsKSB7XHJcblx0XHRpZiAoIWVsKSByZXR1cm47XHJcblx0XHRlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaW5wdXQnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xyXG5cdH1cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIENvbnRyb2xsZXJcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Y2xhc3MgV1BCQ19TbGlkZXJfTGVuX0dyb3VwcyB7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHN0cmluZ30gcm9vdF9lbCBDb250YWluZXIgKG9yIHNlbGVjdG9yKS4gSWYgb21pdHRlZCwgdXNlcyBkb2N1bWVudC5cclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cz17fV1cclxuXHRcdCAqL1xyXG5cdFx0Y29uc3RydWN0b3Iocm9vdF9lbCwgb3B0cykge1xyXG5cdFx0XHR0aGlzLnJvb3QgPSByb290X2VsXHJcblx0XHRcdFx0PyAoKHR5cGVvZiByb290X2VsID09PSAnc3RyaW5nJykgPyBkLnF1ZXJ5U2VsZWN0b3Iocm9vdF9lbCkgOiByb290X2VsKVxyXG5cdFx0XHRcdDogZDtcclxuXHJcblx0XHRcdHRoaXMub3B0cyA9IE9iamVjdC5hc3NpZ24oe1xyXG5cdFx0XHRcdC8vIFN0cmljdCBzZWxlY3RvcnMgKE5PIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkpLlxyXG5cdFx0XHRcdGdyb3VwX3NlbGVjdG9yICA6ICcud3BiY19zbGlkZXJfbGVuX2dyb3VwJyxcclxuXHRcdFx0XHR2YWx1ZV9zZWxlY3RvciAgOiAnW2RhdGEtd3BiY19zbGlkZXJfbGVuX3ZhbHVlXScsXHJcblx0XHRcdFx0dW5pdF9zZWxlY3RvciAgIDogJ1tkYXRhLXdwYmNfc2xpZGVyX2xlbl91bml0XScsXHJcblx0XHRcdFx0cmFuZ2Vfc2VsZWN0b3IgIDogJ1tkYXRhLXdwYmNfc2xpZGVyX2xlbl9yYW5nZV0nLFxyXG5cdFx0XHRcdHdyaXRlcl9zZWxlY3RvciA6ICdbZGF0YS13cGJjX3NsaWRlcl9sZW5fd3JpdGVyXScsXHJcblxyXG5cdFx0XHRcdGRlZmF1bHRfdW5pdCAgICA6ICclJyxcclxuXHJcblx0XHRcdFx0ZmFsbGJhY2tfYm91bmRzIDoge1xyXG5cdFx0XHRcdFx0J3B4JyA6IHsgbWluOiAwLCAgIG1heDogNTEyLCAgc3RlcDogMSAgIH0sXHJcblx0XHRcdFx0XHQnJScgIDogeyBtaW46IDAsICAgbWF4OiAxMDAsICBzdGVwOiAxICAgfSxcclxuXHRcdFx0XHRcdCdyZW0nOiB7IG1pbjogMCwgICBtYXg6IDEwLCAgIHN0ZXA6IDAuMSB9LFxyXG5cdFx0XHRcdFx0J2VtJyA6IHsgbWluOiAwLCAgIG1heDogMTAsICAgc3RlcDogMC4xIH1cclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHQvLyBEaXNhYmxlZCBieSBkZWZhdWx0IGZvciBwZXJmb3JtYW5jZS5cclxuXHRcdFx0XHRlbmFibGVfb2JzZXJ2ZXIgICAgIDogZmFsc2UsXHJcblx0XHRcdFx0b2JzZXJ2ZXJfZGVib3VuY2VfbXM6IDE1MFxyXG5cdFx0XHR9LCBvcHRzIHx8IHt9KTtcclxuXHJcblx0XHRcdHRoaXMuX29uX2lucHV0ICA9IHRoaXMuX29uX2lucHV0LmJpbmQodGhpcyk7XHJcblx0XHRcdHRoaXMuX29uX2NoYW5nZSA9IHRoaXMuX29uX2NoYW5nZS5iaW5kKHRoaXMpO1xyXG5cclxuXHRcdFx0dGhpcy5fYm91bmRzX2NhY2hlID0gbmV3IFdlYWtNYXAoKTsgLy8gZ3JvdXAgLT4gYm91bmRzX21hcF9vYmplY3RcclxuXHRcdFx0dGhpcy5fb2JzZXJ2ZXIgICAgID0gbnVsbDtcclxuXHRcdFx0dGhpcy5fcmVmcmVzaF90bXIgID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHRpbml0KCkge1xyXG5cdFx0XHRpZiAoIXRoaXMucm9vdCkgcmV0dXJuIHRoaXM7XHJcblxyXG5cdFx0XHR0aGlzLnJvb3QuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAgdGhpcy5fb25faW5wdXQsICB0cnVlKTtcclxuXHRcdFx0dGhpcy5yb290LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX29uX2NoYW5nZSwgdHJ1ZSk7XHJcblxyXG5cdFx0XHRpZiAodGhpcy5vcHRzLmVuYWJsZV9vYnNlcnZlciAmJiB3Lk11dGF0aW9uT2JzZXJ2ZXIpIHtcclxuXHRcdFx0XHR0aGlzLl9vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHsgdGhpcy5fZGVib3VuY2VkX3JlZnJlc2goKTsgfSk7XHJcblx0XHRcdFx0dGhpcy5fb2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLnJvb3QgPT09IGQgPyBkLmRvY3VtZW50RWxlbWVudCA6IHRoaXMucm9vdCwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHRoaXMucmVmcmVzaCgpO1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH1cclxuXHJcblx0XHRkZXN0cm95KCkge1xyXG5cdFx0XHRpZiAoIXRoaXMucm9vdCkgcmV0dXJuO1xyXG5cclxuXHRcdFx0dGhpcy5yb290LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2lucHV0JywgIHRoaXMuX29uX2lucHV0LCAgdHJ1ZSk7XHJcblx0XHRcdHRoaXMucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbl9jaGFuZ2UsIHRydWUpO1xyXG5cclxuXHRcdFx0aWYgKHRoaXMuX29ic2VydmVyKSB7XHJcblx0XHRcdFx0dGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG5cdFx0XHRcdHRoaXMuX29ic2VydmVyID0gbnVsbDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRoaXMuX3JlZnJlc2hfdG1yKSB7XHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRoaXMuX3JlZnJlc2hfdG1yKTtcclxuXHRcdFx0XHR0aGlzLl9yZWZyZXNoX3RtciA9IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZWZyZXNoKCkge1xyXG5cdFx0XHRpZiAoIXRoaXMucm9vdCkgcmV0dXJuO1xyXG5cclxuXHRcdFx0dmFyIHNjb3BlICA9ICh0aGlzLnJvb3QgPT09IGQgPyBkIDogdGhpcy5yb290KTtcclxuXHRcdFx0dmFyIGdyb3VwcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKHNjb3BlLnF1ZXJ5U2VsZWN0b3JBbGwodGhpcy5vcHRzLmdyb3VwX3NlbGVjdG9yKSk7XHJcblxyXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGdyb3Vwcy5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHRcdHRoaXMuX3N5bmNfZ3JvdXBfZnJvbV93cml0ZXIoZ3JvdXBzW2ldKTtcclxuXHRcdFx0XHR0aGlzLl9hcHBseV9ib3VuZHNfZm9yX2N1cnJlbnRfdW5pdChncm91cHNbaV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0Ly8gSW50ZXJuYWxcclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdF9kZWJvdW5jZWRfcmVmcmVzaCgpIHtcclxuXHRcdFx0aWYgKHRoaXMuX3JlZnJlc2hfdG1yKSBjbGVhclRpbWVvdXQodGhpcy5fcmVmcmVzaF90bXIpO1xyXG5cdFx0XHR0aGlzLl9yZWZyZXNoX3RtciA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuX3JlZnJlc2hfdG1yID0gbnVsbDtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2goKTtcclxuXHRcdFx0fSwgTnVtYmVyKHRoaXMub3B0cy5vYnNlcnZlcl9kZWJvdW5jZV9tcykgfHwgMCk7XHJcblx0XHR9XHJcblxyXG5cdFx0X2ZpbmRfZ3JvdXAoZWwpIHtcclxuXHRcdFx0cmV0dXJuIChlbCAmJiBlbC5jbG9zZXN0KSA/IGVsLmNsb3Nlc3QodGhpcy5vcHRzLmdyb3VwX3NlbGVjdG9yKSA6IG51bGw7XHJcblx0XHR9XHJcblxyXG5cdFx0X2dldF9wYXJ0cyhncm91cCkge1xyXG5cdFx0XHRpZiAoIWdyb3VwKSByZXR1cm4gbnVsbDtcclxuXHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRncm91cCA6IGdyb3VwLFxyXG5cdFx0XHRcdG51bSAgIDogZ3JvdXAucXVlcnlTZWxlY3Rvcih0aGlzLm9wdHMudmFsdWVfc2VsZWN0b3IpLFxyXG5cdFx0XHRcdHVuaXQgIDogZ3JvdXAucXVlcnlTZWxlY3Rvcih0aGlzLm9wdHMudW5pdF9zZWxlY3RvciksXHJcblx0XHRcdFx0cmFuZ2UgOiBncm91cC5xdWVyeVNlbGVjdG9yKHRoaXMub3B0cy5yYW5nZV9zZWxlY3RvciksXHJcblx0XHRcdFx0d3JpdGVyOiBncm91cC5xdWVyeVNlbGVjdG9yKHRoaXMub3B0cy53cml0ZXJfc2VsZWN0b3IpXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0X2dldF9kZWZhdWx0X3VuaXQoZ3JvdXApIHtcclxuXHRcdFx0dmFyIGR1ID0gKGdyb3VwICYmIGdyb3VwLmdldEF0dHJpYnV0ZSlcclxuXHRcdFx0XHQ/IGdyb3VwLmdldEF0dHJpYnV0ZSgnZGF0YS13cGJjX3NsaWRlcl9sZW5fZGVmYXVsdF91bml0JylcclxuXHRcdFx0XHQ6ICcnO1xyXG5cdFx0XHRyZXR1cm4gZHUgPyBTdHJpbmcoZHUpIDogdGhpcy5vcHRzLmRlZmF1bHRfdW5pdDtcclxuXHRcdH1cclxuXHJcblx0XHRfZ2V0X2JvdW5kc19tYXAoZ3JvdXApIHtcclxuXHRcdFx0aWYgKCFncm91cCkgcmV0dXJuIG51bGw7XHJcblx0XHRcdGlmICh0aGlzLl9ib3VuZHNfY2FjaGUuaGFzKGdyb3VwKSkge1xyXG5cdFx0XHRcdHJldHVybiB0aGlzLl9ib3VuZHNfY2FjaGUuZ2V0KGdyb3VwKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIHJhdyA9IGdyb3VwLmdldEF0dHJpYnV0ZSgnZGF0YS13cGJjX3NsaWRlcl9sZW5fYm91bmRzX21hcCcpO1xyXG5cdFx0XHR2YXIgbWFwID0gcmF3ID8gc2FmZV9qc29uX3BhcnNlKHJhdykgOiBudWxsO1xyXG5cdFx0XHRpZiAoIW1hcCB8fCB0eXBlb2YgbWFwICE9PSAnb2JqZWN0JykgbWFwID0gbnVsbDtcclxuXHJcblx0XHRcdHRoaXMuX2JvdW5kc19jYWNoZS5zZXQoZ3JvdXAsIG1hcCk7XHJcblx0XHRcdHJldHVybiBtYXA7XHJcblx0XHR9XHJcblxyXG5cdFx0X2dldF9ib3VuZHNfZm9yX3VuaXQoZ3JvdXAsIHVuaXQpIHtcclxuXHRcdFx0dmFyIG1hcCA9IHRoaXMuX2dldF9ib3VuZHNfbWFwKGdyb3VwKTtcclxuXHRcdFx0aWYgKG1hcCAmJiB1bml0ICYmIG1hcFt1bml0XSkge1xyXG5cdFx0XHRcdHJldHVybiBtYXBbdW5pdF07XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHRoaXMub3B0cy5mYWxsYmFja19ib3VuZHNbdW5pdF0gfHwgdGhpcy5vcHRzLmZhbGxiYWNrX2JvdW5kc1sncHgnXTtcclxuXHRcdH1cclxuXHJcblx0XHRfYXBwbHlfYm91bmRzKHBhcnRzLCBib3VuZHMpIHtcclxuXHRcdFx0aWYgKCFwYXJ0cyB8fCAhYm91bmRzKSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgbWluICA9IChib3VuZHMubWluICAhPSBudWxsKSA/IE51bWJlcihib3VuZHMubWluKSAgOiBudWxsO1xyXG5cdFx0XHR2YXIgbWF4ICA9IChib3VuZHMubWF4ICAhPSBudWxsKSA/IE51bWJlcihib3VuZHMubWF4KSAgOiBudWxsO1xyXG5cdFx0XHR2YXIgc3RlcCA9IChib3VuZHMuc3RlcCAhPSBudWxsKSA/IE51bWJlcihib3VuZHMuc3RlcCkgOiBudWxsO1xyXG5cclxuXHRcdFx0aWYgKHBhcnRzLnJhbmdlKSB7XHJcblx0XHRcdFx0aWYgKCFpc05hTihtaW4pKSAgcGFydHMucmFuZ2UubWluICA9IFN0cmluZyhtaW4pO1xyXG5cdFx0XHRcdGlmICghaXNOYU4obWF4KSkgIHBhcnRzLnJhbmdlLm1heCAgPSBTdHJpbmcobWF4KTtcclxuXHRcdFx0XHRpZiAoIWlzTmFOKHN0ZXApKSBwYXJ0cy5yYW5nZS5zdGVwID0gU3RyaW5nKHN0ZXApO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChwYXJ0cy5udW0pIHtcclxuXHRcdFx0XHRpZiAoIWlzTmFOKG1pbikpICBwYXJ0cy5udW0ubWluICA9IFN0cmluZyhtaW4pO1xyXG5cdFx0XHRcdGlmICghaXNOYU4obWF4KSkgIHBhcnRzLm51bS5tYXggID0gU3RyaW5nKG1heCk7XHJcblx0XHRcdFx0aWYgKCFpc05hTihzdGVwKSkgcGFydHMubnVtLnN0ZXAgPSBTdHJpbmcoc3RlcCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRfYXBwbHlfYm91bmRzX2Zvcl9jdXJyZW50X3VuaXQoZ3JvdXApIHtcclxuXHRcdFx0dmFyIHBhcnRzID0gdGhpcy5fZ2V0X3BhcnRzKGdyb3VwKTtcclxuXHRcdFx0aWYgKCFwYXJ0cyB8fCAhcGFydHMudW5pdCkgcmV0dXJuO1xyXG5cclxuXHRcdFx0dmFyIHVuaXQgPSBwYXJ0cy51bml0LnZhbHVlIHx8IHRoaXMuX2dldF9kZWZhdWx0X3VuaXQoZ3JvdXApO1xyXG5cdFx0XHR2YXIgYiAgICA9IHRoaXMuX2dldF9ib3VuZHNfZm9yX3VuaXQoZ3JvdXAsIHVuaXQpO1xyXG5cclxuXHRcdFx0dGhpcy5fYXBwbHlfYm91bmRzKHBhcnRzLCBiKTtcclxuXHJcblx0XHRcdC8vIENsYW1wIGN1cnJlbnQgdmFsdWUgdG8gbmV3IGJvdW5kcy5cclxuXHRcdFx0dmFyIHYgPSBwYXJzZV9mbG9hdChwYXJ0cy5udW0gJiYgcGFydHMubnVtLnZhbHVlID8gcGFydHMubnVtLnZhbHVlIDogKHBhcnRzLnJhbmdlID8gcGFydHMucmFuZ2UudmFsdWUgOiAnJykpO1xyXG5cdFx0XHRpZiAodiA9PSBudWxsKSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgbWluID0gKGIgJiYgYi5taW4gIT0gbnVsbCkgPyBOdW1iZXIoYi5taW4pIDogbnVsbDtcclxuXHRcdFx0dmFyIG1heCA9IChiICYmIGIubWF4ICE9IG51bGwpID8gTnVtYmVyKGIubWF4KSA6IG51bGw7XHJcblx0XHRcdHYgPSBjbGFtcF9udW0odiwgaXNOYU4obWluKSA/IG51bGwgOiBtaW4sIGlzTmFOKG1heCkgPyBudWxsIDogbWF4KTtcclxuXHJcblx0XHRcdGlmIChwYXJ0cy5udW0pICAgcGFydHMubnVtLnZhbHVlICAgPSBTdHJpbmcodik7XHJcblx0XHRcdGlmIChwYXJ0cy5yYW5nZSkgcGFydHMucmFuZ2UudmFsdWUgPSBTdHJpbmcodik7XHJcblxyXG5cdFx0XHR0aGlzLl93cml0ZV9jb21iaW5lZChwYXJ0cywgU3RyaW5nKHYpLCB1bml0LCAvKmVtaXQqLyBmYWxzZSk7XHJcblx0XHR9XHJcblxyXG5cdFx0X3dyaXRlX2NvbWJpbmVkKHBhcnRzLCBudW0sIHVuaXQsIGVtaXQpIHtcclxuXHRcdFx0aWYgKCFwYXJ0cykgcmV0dXJuO1xyXG5cclxuXHRcdFx0dmFyIGNvbWJpbmVkID0gYnVpbGRfY29tYmluZWQobnVtLCB1bml0KTtcclxuXHJcblx0XHRcdGlmIChwYXJ0cy53cml0ZXIpIHtcclxuXHRcdFx0XHQvLyBBdm9pZCByZWN1cnNpb246IG1hcmsgYXMgaW50ZXJuYWwgd3JpdGUuXHJcblx0XHRcdFx0cGFydHMud3JpdGVyLl9fd3BiY19zbGlkZXJfbGVuX2ludGVybmFsID0gdHJ1ZTtcclxuXHRcdFx0XHRwYXJ0cy53cml0ZXIudmFsdWUgPSBjb21iaW5lZDtcclxuXHRcdFx0XHRpZiAoZW1pdCkgZW1pdF9pbnB1dChwYXJ0cy53cml0ZXIpO1xyXG5cdFx0XHRcdHBhcnRzLndyaXRlci5fX3dwYmNfc2xpZGVyX2xlbl9pbnRlcm5hbCA9IGZhbHNlO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHBhcnRzLm51bSkge1xyXG5cdFx0XHRcdC8vIElmIHdyaXRlciBpcyBtaXNzaW5nLCBhdCBsZWFzdCBub3RpZnkgdmlhIG51bWJlciBpbnB1dC5cclxuXHRcdFx0XHRpZiAoZW1pdCkgZW1pdF9pbnB1dChwYXJ0cy5udW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0X3N5bmNfZ3JvdXBfZnJvbV93cml0ZXIoZ3JvdXApIHtcclxuXHRcdFx0dmFyIHBhcnRzID0gdGhpcy5fZ2V0X3BhcnRzKGdyb3VwKTtcclxuXHRcdFx0aWYgKCFwYXJ0cyB8fCAhcGFydHMud3JpdGVyKSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgcmF3ID0gU3RyaW5nKHBhcnRzLndyaXRlci52YWx1ZSB8fCAnJykudHJpbSgpO1xyXG5cdFx0XHRpZiAoIXJhdykgcmV0dXJuO1xyXG5cclxuXHRcdFx0dmFyIGR1ID0gdGhpcy5fZ2V0X2RlZmF1bHRfdW5pdChncm91cCk7XHJcblx0XHRcdHZhciBwICA9IHBhcnNlX2xlbl9jb21iaW5lZChyYXcsIGR1KTtcclxuXHJcblx0XHRcdGlmIChwYXJ0cy51bml0KSAgcGFydHMudW5pdC52YWx1ZSAgPSBwLnVuaXQ7XHJcblx0XHRcdGlmIChwYXJ0cy5udW0pICAgcGFydHMubnVtLnZhbHVlICAgPSBwLm51bTtcclxuXHRcdFx0aWYgKHBhcnRzLnJhbmdlKSBwYXJ0cy5yYW5nZS52YWx1ZSA9IHAubnVtO1xyXG5cdFx0fVxyXG5cclxuXHRcdF9vbl9pbnB1dChldikge1xyXG5cdFx0XHR2YXIgdCA9IGV2LnRhcmdldDtcclxuXHRcdFx0aWYgKCF0KSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgZ3JvdXAgPSB0aGlzLl9maW5kX2dyb3VwKHQpO1xyXG5cdFx0XHRpZiAoIWdyb3VwKSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgcGFydHMgPSB0aGlzLl9nZXRfcGFydHMoZ3JvdXApO1xyXG5cdFx0XHRpZiAoIXBhcnRzKSByZXR1cm47XHJcblxyXG5cdFx0XHQvLyBXcml0ZXIgY2hhbmdlZCBleHRlcm5hbGx5IC0+IHVwZGF0ZSBVSS5cclxuXHRcdFx0aWYgKHBhcnRzLndyaXRlciAmJiB0ID09PSBwYXJ0cy53cml0ZXIpIHtcclxuXHRcdFx0XHRpZiAodC5fX3dwYmNfc2xpZGVyX2xlbl9pbnRlcm5hbCkgcmV0dXJuO1xyXG5cdFx0XHRcdHRoaXMuX3N5bmNfZ3JvdXBfZnJvbV93cml0ZXIoZ3JvdXApO1xyXG5cdFx0XHRcdHRoaXMuX2FwcGx5X2JvdW5kc19mb3JfY3VycmVudF91bml0KGdyb3VwKTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNsaWRlciBtb3ZlZCAtPiB1cGRhdGUgbnVtYmVyICsgd3JpdGVyLlxyXG5cdFx0XHRpZiAodC5tYXRjaGVzICYmIHQubWF0Y2hlcyh0aGlzLm9wdHMucmFuZ2Vfc2VsZWN0b3IpKSB7XHJcblx0XHRcdFx0aWYgKHBhcnRzLm51bSkgcGFydHMubnVtLnZhbHVlID0gdC52YWx1ZTtcclxuXHJcblx0XHRcdFx0dmFyIHVuaXQgPSAocGFydHMudW5pdCAmJiBwYXJ0cy51bml0LnZhbHVlKSA/IHBhcnRzLnVuaXQudmFsdWUgOiB0aGlzLl9nZXRfZGVmYXVsdF91bml0KGdyb3VwKTtcclxuXHRcdFx0XHR0aGlzLl93cml0ZV9jb21iaW5lZChwYXJ0cywgdC52YWx1ZSwgdW5pdCwgLyplbWl0Ki8gdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBOdW1iZXIgdHlwZWQgLT4gdXBkYXRlIHNsaWRlciArIHdyaXRlciAoY2xhbXAgaWYgc2xpZGVyIGhhcyBib3VuZHMpLlxyXG5cdFx0XHRpZiAodC5tYXRjaGVzICYmIHQubWF0Y2hlcyh0aGlzLm9wdHMudmFsdWVfc2VsZWN0b3IpKSB7XHJcblx0XHRcdFx0dmFyIHYgPSBwYXJzZV9mbG9hdCh0LnZhbHVlKTtcclxuXHJcblx0XHRcdFx0aWYgKHYgIT0gbnVsbCAmJiBwYXJ0cy5yYW5nZSkge1xyXG5cdFx0XHRcdFx0dmFyIHJtaW4gPSBOdW1iZXIocGFydHMucmFuZ2UubWluKTtcclxuXHRcdFx0XHRcdHZhciBybWF4ID0gTnVtYmVyKHBhcnRzLnJhbmdlLm1heCk7XHJcblx0XHRcdFx0XHR2ID0gY2xhbXBfbnVtKHYsIGlzTmFOKHJtaW4pID8gbnVsbCA6IHJtaW4sIGlzTmFOKHJtYXgpID8gbnVsbCA6IHJtYXgpO1xyXG5cclxuXHRcdFx0XHRcdHBhcnRzLnJhbmdlLnZhbHVlID0gU3RyaW5nKHYpO1xyXG5cdFx0XHRcdFx0aWYgKFN0cmluZyh2KSAhPT0gdC52YWx1ZSkgdC52YWx1ZSA9IFN0cmluZyh2KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHZhciB1bml0MiA9IChwYXJ0cy51bml0ICYmIHBhcnRzLnVuaXQudmFsdWUpID8gcGFydHMudW5pdC52YWx1ZSA6IHRoaXMuX2dldF9kZWZhdWx0X3VuaXQoZ3JvdXApO1xyXG5cdFx0XHRcdHRoaXMuX3dyaXRlX2NvbWJpbmVkKHBhcnRzLCB0LnZhbHVlLCB1bml0MiwgLyplbWl0Ki8gdHJ1ZSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRfb25fY2hhbmdlKGV2KSB7XHJcblx0XHRcdHZhciB0ID0gZXYudGFyZ2V0O1xyXG5cdFx0XHRpZiAoIXQpIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBncm91cCA9IHRoaXMuX2ZpbmRfZ3JvdXAodCk7XHJcblx0XHRcdGlmICghZ3JvdXApIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBwYXJ0cyA9IHRoaXMuX2dldF9wYXJ0cyhncm91cCk7XHJcblx0XHRcdGlmICghcGFydHMpIHJldHVybjtcclxuXHJcblx0XHRcdC8vIFVuaXQgY2hhbmdlZCAtPiB1cGRhdGUgYm91bmRzICsgd3JpdGVyLlxyXG5cdFx0XHRpZiAodC5tYXRjaGVzICYmIHQubWF0Y2hlcyh0aGlzLm9wdHMudW5pdF9zZWxlY3RvcikpIHtcclxuXHRcdFx0XHR0aGlzLl9hcHBseV9ib3VuZHNfZm9yX2N1cnJlbnRfdW5pdChncm91cCk7XHJcblxyXG5cdFx0XHRcdHZhciBudW0gID0gcGFydHMubnVtID8gcGFydHMubnVtLnZhbHVlIDogKHBhcnRzLnJhbmdlID8gcGFydHMucmFuZ2UudmFsdWUgOiAnJyk7XHJcblx0XHRcdFx0dmFyIHVuaXQgPSB0LnZhbHVlIHx8IHRoaXMuX2dldF9kZWZhdWx0X3VuaXQoZ3JvdXApO1xyXG5cdFx0XHRcdHRoaXMuX3dyaXRlX2NvbWJpbmVkKHBhcnRzLCBudW0sIHVuaXQsIC8qZW1pdCovIHRydWUpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gQXV0by1pbml0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdGZ1bmN0aW9uIHdwYmNfc2xpZGVyX2xlbl9ncm91cHNfX2F1dG9faW5pdCgpIHtcclxuXHRcdHZhciBST09UICA9ICcud3BiY19zbGlkZXJfbGVuX2dyb3Vwcyc7XHJcblx0XHR2YXIgbm9kZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChkLnF1ZXJ5U2VsZWN0b3JBbGwoUk9PVCkpXHJcblx0XHRcdC5maWx0ZXIoZnVuY3Rpb24gKG4pIHsgcmV0dXJuICFuLnBhcmVudEVsZW1lbnQgfHwgIW4ucGFyZW50RWxlbWVudC5jbG9zZXN0KFJPT1QpOyB9KTtcclxuXHJcblx0XHQvLyBJZiBubyBleHBsaWNpdCBjb250YWluZXJzLCBpbnN0YWxsIGEgc2luZ2xlIGRvY3VtZW50LXJvb3QgaW5zdGFuY2UuXHJcblx0XHRpZiAoIW5vZGVzLmxlbmd0aCkge1xyXG5cdFx0XHRpZiAoIWQuX193cGJjX3NsaWRlcl9sZW5fZ3JvdXBzX2dsb2JhbF9pbnN0YW5jZSkge1xyXG5cdFx0XHRcdGQuX193cGJjX3NsaWRlcl9sZW5fZ3JvdXBzX2dsb2JhbF9pbnN0YW5jZSA9IG5ldyBXUEJDX1NsaWRlcl9MZW5fR3JvdXBzKGQpLmluaXQoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0bm9kZXMuZm9yRWFjaChmdW5jdGlvbiAobm9kZSkge1xyXG5cdFx0XHRpZiAobm9kZS5fX3dwYmNfc2xpZGVyX2xlbl9ncm91cHNfaW5zdGFuY2UpIHJldHVybjtcclxuXHRcdFx0bm9kZS5fX3dwYmNfc2xpZGVyX2xlbl9ncm91cHNfaW5zdGFuY2UgPSBuZXcgV1BCQ19TbGlkZXJfTGVuX0dyb3Vwcyhub2RlKS5pbml0KCk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8vIEV4cG9ydCBnbG9iYWxzIChtYW51YWwgY29udHJvbCBpZiBuZWVkZWQpLlxyXG5cdHcuV1BCQ19TbGlkZXJfTGVuX0dyb3VwcyAgID0gV1BCQ19TbGlkZXJfTGVuX0dyb3VwcztcclxuXHR3LldQQkNfU2xpZGVyX0xlbl9BdXRvSW5pdCA9IHdwYmNfc2xpZGVyX2xlbl9ncm91cHNfX2F1dG9faW5pdDtcclxuXHJcblx0Ly8gRE9NLXJlYWR5IGF1dG8gaW5pdC5cclxuXHRpZiAoZC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycpIHtcclxuXHRcdGQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIHdwYmNfc2xpZGVyX2xlbl9ncm91cHNfX2F1dG9faW5pdCwgeyBvbmNlOiB0cnVlIH0pO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR3cGJjX3NsaWRlcl9sZW5fZ3JvdXBzX19hdXRvX2luaXQoKTtcclxuXHR9XHJcblxyXG59KSh3aW5kb3csIGRvY3VtZW50KTtcclxuIiwiLyogZ2xvYmFscyB3aW5kb3csIGRvY3VtZW50ICovXHJcbi8qKlxyXG4gKiBXUEJDIFNsaWRlciBSYW5nZSBHcm91cHNcclxuICpcclxuICogVW5pdmVyc2FsLCBkZXBlbmRlbmN5LWZyZWUgY29udHJvbGxlciB0aGF0IGtlZXBzIGEgXCJyYW5nZSArIG51bWJlclwiIHBhaXIgaW4gc3luYzpcclxuICogIC0gbnVtYmVyIGlucHV0ICAoZGF0YS13cGJjX3NsaWRlcl9yYW5nZV92YWx1ZSlcclxuICogIC0gcmFuZ2Ugc2xpZGVyICAoZGF0YS13cGJjX3NsaWRlcl9yYW5nZV9yYW5nZSlcclxuICogIC0gd3JpdGVyIGlucHV0ICAoZGF0YS13cGJjX3NsaWRlcl9yYW5nZV93cml0ZXIpIFtvcHRpb25hbF1cclxuICpcclxuICogSWYgd3JpdGVyIGV4aXN0czogbnVtYmVyL3NsaWRlciB1cGRhdGUgd3JpdGVyIGFuZCBlbWl0ICdpbnB1dCcgb24gd3JpdGVyIChidWJibGVzKS5cclxuICogSWYgd3JpdGVyIGlzIG1pc3Npbmc6IGVtaXRzICdpbnB1dCcgb24gdGhlIG51bWJlciBpbnB1dC5cclxuICogSWYgd3JpdGVyIGNoYW5nZXMgZXh0ZXJuYWxseTogdXBkYXRlcyBudW1iZXIvc2xpZGVyLlxyXG4gKlxyXG4gKiBNYXJrdXAgZXhwZWN0YXRpb25zIChtaW5pbWFsKTpcclxuICogIDxkaXYgY2xhc3M9XCJ3cGJjX3NsaWRlcl9yYW5nZV9ncm91cFwiPlxyXG4gKiAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGRhdGEtd3BiY19zbGlkZXJfcmFuZ2VfdmFsdWU+XHJcbiAqICAgIDxpbnB1dCB0eXBlPVwicmFuZ2VcIiAgZGF0YS13cGJjX3NsaWRlcl9yYW5nZV9yYW5nZT5cclxuICogICAgPCEtLSBvcHRpb25hbCAtLT5cclxuICogICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZGF0YS13cGJjX3NsaWRlcl9yYW5nZV93cml0ZXIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+XHJcbiAqICA8L2Rpdj5cclxuICpcclxuICogUGVyZm9ybWFuY2Ugbm90ZXM6XHJcbiAqIC0gTXV0YXRpb25PYnNlcnZlciBpcyBESVNBQkxFRCBieSBkZWZhdWx0LlxyXG4gKiAtIElmIHlvdXIgVUkgcmUtcmVuZGVycyBhbmQgaW5zZXJ0cyBuZXcgZ3JvdXBzIGR5bmFtaWNhbGx5LCBjYWxsOlxyXG4gKiAgICAgV1BCQ19TbGlkZXJfUmFuZ2VfQXV0b0luaXQoKTsgT1IgaW5zdGFuY2UucmVmcmVzaCgpO1xyXG4gKiAgIE9yIGVuYWJsZSBvYnNlcnZlciB2aWE6IG5ldyBXUEJDX1NsaWRlcl9SYW5nZV9Hcm91cHMocm9vdCwgeyBlbmFibGVfb2JzZXJ2ZXI6dHJ1ZSB9KS5pbml0KCk7XHJcbiAqXHJcbiAqIFB1YmxpYyBBUEkgKGluc3RhbmNlIG1ldGhvZHMpOlxyXG4gKiAgLSBpbml0KCksIGRlc3Ryb3koKSwgcmVmcmVzaCgpXHJcbiAqXHJcbiAqIEB2ZXJzaW9uIDIwMjYtMDEtMjVcclxuICogQHNpbmNlICAgMjAyNi0wMS0yNVxyXG4gKiBAZmlsZSAgICAuLi9pbmNsdWRlcy9fX2pzL2FkbWluL3NsaWRlcl9ncm91cHMvd3BiY19yYW5nZV9ncm91cHMuanNcclxuICovXHJcbihmdW5jdGlvbiAodywgZCkge1xyXG5cdCd1c2Ugc3RyaWN0JztcclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIEhlbHBlcnNcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0ZnVuY3Rpb24gY2xhbXBfbnVtKHYsIG1pbiwgbWF4KSB7XHJcblx0XHRpZiAodHlwZW9mIG1pbiA9PT0gJ251bWJlcicgJiYgIWlzTmFOKG1pbikpIHYgPSBNYXRoLm1heChtaW4sIHYpO1xyXG5cdFx0aWYgKHR5cGVvZiBtYXggPT09ICdudW1iZXInICYmICFpc05hTihtYXgpKSB2ID0gTWF0aC5taW4obWF4LCB2KTtcclxuXHRcdHJldHVybiB2O1xyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gcGFyc2VfZmxvYXQodikge1xyXG5cdFx0dmFyIG4gPSBwYXJzZUZsb2F0KHYpO1xyXG5cdFx0cmV0dXJuIGlzTmFOKG4pID8gbnVsbCA6IG47XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBlbWl0X2lucHV0KGVsKSB7XHJcblx0XHRpZiAoIWVsKSByZXR1cm47XHJcblx0XHRlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaW5wdXQnLCB7IGJ1YmJsZXM6IHRydWUgfSkpO1xyXG5cdH1cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIENvbnRyb2xsZXJcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Y2xhc3MgV1BCQ19TbGlkZXJfUmFuZ2VfR3JvdXBzIHtcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8c3RyaW5nfSByb290X2VsIENvbnRhaW5lciAob3Igc2VsZWN0b3IpLiBJZiBvbWl0dGVkLCB1c2VzIGRvY3VtZW50LlxyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRzPXt9XVxyXG5cdFx0ICovXHJcblx0XHRjb25zdHJ1Y3Rvcihyb290X2VsLCBvcHRzKSB7XHJcblx0XHRcdHRoaXMucm9vdCA9IHJvb3RfZWxcclxuXHRcdFx0XHQ/ICgodHlwZW9mIHJvb3RfZWwgPT09ICdzdHJpbmcnKSA/IGQucXVlcnlTZWxlY3Rvcihyb290X2VsKSA6IHJvb3RfZWwpXHJcblx0XHRcdFx0OiBkO1xyXG5cclxuXHRcdFx0dGhpcy5vcHRzID0gT2JqZWN0LmFzc2lnbih7XHJcblx0XHRcdFx0Ly8gU3RyaWN0IHNlbGVjdG9ycyAoTk8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSkuXHJcblx0XHRcdFx0Z3JvdXBfc2VsZWN0b3IgIDogJy53cGJjX3NsaWRlcl9yYW5nZV9ncm91cCcsXHJcblx0XHRcdFx0dmFsdWVfc2VsZWN0b3IgIDogJ1tkYXRhLXdwYmNfc2xpZGVyX3JhbmdlX3ZhbHVlXScsXHJcblx0XHRcdFx0cmFuZ2Vfc2VsZWN0b3IgIDogJ1tkYXRhLXdwYmNfc2xpZGVyX3JhbmdlX3JhbmdlXScsXHJcblx0XHRcdFx0d3JpdGVyX3NlbGVjdG9yIDogJ1tkYXRhLXdwYmNfc2xpZGVyX3JhbmdlX3dyaXRlcl0nLFxyXG5cclxuXHRcdFx0XHQvLyBEaXNhYmxlZCBieSBkZWZhdWx0IGZvciBwZXJmb3JtYW5jZS5cclxuXHRcdFx0XHRlbmFibGVfb2JzZXJ2ZXIgICAgIDogZmFsc2UsXHJcblx0XHRcdFx0b2JzZXJ2ZXJfZGVib3VuY2VfbXM6IDE1MFxyXG5cdFx0XHR9LCBvcHRzIHx8IHt9KTtcclxuXHJcblx0XHRcdHRoaXMuX29uX2lucHV0ICA9IHRoaXMuX29uX2lucHV0LmJpbmQodGhpcyk7XHJcblx0XHRcdHRoaXMuX29uX2NoYW5nZSA9IHRoaXMuX29uX2NoYW5nZS5iaW5kKHRoaXMpO1xyXG5cclxuXHRcdFx0dGhpcy5fb2JzZXJ2ZXIgICAgPSBudWxsO1xyXG5cdFx0XHR0aGlzLl9yZWZyZXNoX3RtciA9IG51bGw7XHJcblx0XHR9XHJcblxyXG5cdFx0aW5pdCgpIHtcclxuXHRcdFx0aWYgKCF0aGlzLnJvb3QpIHJldHVybiB0aGlzO1xyXG5cclxuXHRcdFx0dGhpcy5yb290LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgIHRoaXMuX29uX2lucHV0LCAgdHJ1ZSk7XHJcblx0XHRcdHRoaXMucm9vdC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbl9jaGFuZ2UsIHRydWUpO1xyXG5cclxuXHRcdFx0aWYgKHRoaXMub3B0cy5lbmFibGVfb2JzZXJ2ZXIgJiYgdy5NdXRhdGlvbk9ic2VydmVyKSB7XHJcblx0XHRcdFx0dGhpcy5fb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7IHRoaXMuX2RlYm91bmNlZF9yZWZyZXNoKCk7IH0pO1xyXG5cdFx0XHRcdHRoaXMuX29ic2VydmVyLm9ic2VydmUodGhpcy5yb290ID09PSBkID8gZC5kb2N1bWVudEVsZW1lbnQgOiB0aGlzLnJvb3QsIHsgY2hpbGRMaXN0OiB0cnVlLCBzdWJ0cmVlOiB0cnVlIH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLnJlZnJlc2goKTtcclxuXHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHR9XHJcblxyXG5cdFx0ZGVzdHJveSgpIHtcclxuXHRcdFx0aWYgKCF0aGlzLnJvb3QpIHJldHVybjtcclxuXHJcblx0XHRcdHRoaXMucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCdpbnB1dCcsICB0aGlzLl9vbl9pbnB1dCwgIHRydWUpO1xyXG5cdFx0XHR0aGlzLnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fb25fY2hhbmdlLCB0cnVlKTtcclxuXHJcblx0XHRcdGlmICh0aGlzLl9vYnNlcnZlcikge1xyXG5cdFx0XHRcdHRoaXMuX29ic2VydmVyLmRpc2Nvbm5lY3QoKTtcclxuXHRcdFx0XHR0aGlzLl9vYnNlcnZlciA9IG51bGw7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICh0aGlzLl9yZWZyZXNoX3Rtcikge1xyXG5cdFx0XHRcdGNsZWFyVGltZW91dCh0aGlzLl9yZWZyZXNoX3Rtcik7XHJcblx0XHRcdFx0dGhpcy5fcmVmcmVzaF90bXIgPSBudWxsO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmVmcmVzaCgpIHtcclxuXHRcdFx0aWYgKCF0aGlzLnJvb3QpIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBzY29wZSAgPSAodGhpcy5yb290ID09PSBkID8gZCA6IHRoaXMucm9vdCk7XHJcblx0XHRcdHZhciBncm91cHMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChzY29wZS5xdWVyeVNlbGVjdG9yQWxsKHRoaXMub3B0cy5ncm91cF9zZWxlY3RvcikpO1xyXG5cclxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBncm91cHMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0XHR0aGlzLl9zeW5jX2Zyb21fd3JpdGVyKGdyb3Vwc1tpXSk7XHJcblx0XHRcdFx0dGhpcy5fY2xhbXBfdG9fcmFuZ2UoZ3JvdXBzW2ldKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vIEludGVybmFsXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRfZGVib3VuY2VkX3JlZnJlc2goKSB7XHJcblx0XHRcdGlmICh0aGlzLl9yZWZyZXNoX3RtcikgY2xlYXJUaW1lb3V0KHRoaXMuX3JlZnJlc2hfdG1yKTtcclxuXHRcdFx0dGhpcy5fcmVmcmVzaF90bXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuXHRcdFx0XHR0aGlzLl9yZWZyZXNoX3RtciA9IG51bGw7XHJcblx0XHRcdFx0dGhpcy5yZWZyZXNoKCk7XHJcblx0XHRcdH0sIE51bWJlcih0aGlzLm9wdHMub2JzZXJ2ZXJfZGVib3VuY2VfbXMpIHx8IDApO1xyXG5cdFx0fVxyXG5cclxuXHRcdF9maW5kX2dyb3VwKGVsKSB7XHJcblx0XHRcdHJldHVybiAoZWwgJiYgZWwuY2xvc2VzdCkgPyBlbC5jbG9zZXN0KHRoaXMub3B0cy5ncm91cF9zZWxlY3RvcikgOiBudWxsO1xyXG5cdFx0fVxyXG5cclxuXHRcdF9nZXRfcGFydHMoZ3JvdXApIHtcclxuXHRcdFx0aWYgKCFncm91cCkgcmV0dXJuIG51bGw7XHJcblx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0Z3JvdXAgOiBncm91cCxcclxuXHRcdFx0XHRudW0gICA6IGdyb3VwLnF1ZXJ5U2VsZWN0b3IodGhpcy5vcHRzLnZhbHVlX3NlbGVjdG9yKSxcclxuXHRcdFx0XHRyYW5nZSA6IGdyb3VwLnF1ZXJ5U2VsZWN0b3IodGhpcy5vcHRzLnJhbmdlX3NlbGVjdG9yKSxcclxuXHRcdFx0XHR3cml0ZXI6IGdyb3VwLnF1ZXJ5U2VsZWN0b3IodGhpcy5vcHRzLndyaXRlcl9zZWxlY3RvcilcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHRfd3JpdGUocGFydHMsIHZhbHVlLCBlbWl0KSB7XHJcblx0XHRcdGlmICghcGFydHMpIHJldHVybjtcclxuXHJcblx0XHRcdGlmIChwYXJ0cy53cml0ZXIpIHtcclxuXHRcdFx0XHRwYXJ0cy53cml0ZXIuX193cGJjX3NsaWRlcl9yYW5nZV9pbnRlcm5hbCA9IHRydWU7XHJcblx0XHRcdFx0cGFydHMud3JpdGVyLnZhbHVlID0gU3RyaW5nKHZhbHVlKTtcclxuXHRcdFx0XHRpZiAoZW1pdCkgZW1pdF9pbnB1dChwYXJ0cy53cml0ZXIpO1xyXG5cdFx0XHRcdHBhcnRzLndyaXRlci5fX3dwYmNfc2xpZGVyX3JhbmdlX2ludGVybmFsID0gZmFsc2U7XHJcblx0XHRcdH0gZWxzZSBpZiAocGFydHMubnVtKSB7XHJcblx0XHRcdFx0Ly8gSWYgd3JpdGVyIGlzIG1pc3NpbmcsIGF0IGxlYXN0IG5vdGlmeSB2aWEgbnVtYmVyIGlucHV0LlxyXG5cdFx0XHRcdGlmIChlbWl0KSBlbWl0X2lucHV0KHBhcnRzLm51bSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRfc3luY19mcm9tX3dyaXRlcihncm91cCkge1xyXG5cdFx0XHR2YXIgcGFydHMgPSB0aGlzLl9nZXRfcGFydHMoZ3JvdXApO1xyXG5cdFx0XHRpZiAoIXBhcnRzIHx8ICFwYXJ0cy53cml0ZXIpIHJldHVybjtcclxuXHJcblx0XHRcdHZhciByYXcgPSBTdHJpbmcocGFydHMud3JpdGVyLnZhbHVlIHx8ICcnKS50cmltKCk7XHJcblx0XHRcdGlmICghcmF3KSByZXR1cm47XHJcblxyXG5cdFx0XHRpZiAocGFydHMubnVtKSAgIHBhcnRzLm51bS52YWx1ZSAgID0gcmF3O1xyXG5cdFx0XHRpZiAocGFydHMucmFuZ2UpIHBhcnRzLnJhbmdlLnZhbHVlID0gcmF3O1xyXG5cdFx0fVxyXG5cclxuXHRcdF9jbGFtcF90b19yYW5nZShncm91cCkge1xyXG5cdFx0XHR2YXIgcGFydHMgPSB0aGlzLl9nZXRfcGFydHMoZ3JvdXApO1xyXG5cdFx0XHRpZiAoIXBhcnRzIHx8ICFwYXJ0cy5yYW5nZSB8fCAhcGFydHMubnVtKSByZXR1cm47XHJcblxyXG5cdFx0XHR2YXIgdiA9IHBhcnNlX2Zsb2F0KHBhcnRzLm51bS52YWx1ZSk7XHJcblx0XHRcdGlmICh2ID09IG51bGwpIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBtaW4gPSBOdW1iZXIocGFydHMucmFuZ2UubWluKTtcclxuXHRcdFx0dmFyIG1heCA9IE51bWJlcihwYXJ0cy5yYW5nZS5tYXgpO1xyXG5cdFx0XHR2YXIgdnYgID0gY2xhbXBfbnVtKHYsIGlzTmFOKG1pbikgPyBudWxsIDogbWluLCBpc05hTihtYXgpID8gbnVsbCA6IG1heCk7XHJcblxyXG5cdFx0XHRpZiAoU3RyaW5nKHZ2KSAhPT0gcGFydHMubnVtLnZhbHVlKSBwYXJ0cy5udW0udmFsdWUgPSBTdHJpbmcodnYpO1xyXG5cdFx0XHRwYXJ0cy5yYW5nZS52YWx1ZSA9IFN0cmluZyh2dik7XHJcblx0XHR9XHJcblxyXG5cdFx0X29uX2lucHV0KGV2KSB7XHJcblx0XHRcdHZhciB0ID0gZXYudGFyZ2V0O1xyXG5cdFx0XHRpZiAoIXQpIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBncm91cCA9IHRoaXMuX2ZpbmRfZ3JvdXAodCk7XHJcblx0XHRcdGlmICghZ3JvdXApIHJldHVybjtcclxuXHJcblx0XHRcdHZhciBwYXJ0cyA9IHRoaXMuX2dldF9wYXJ0cyhncm91cCk7XHJcblx0XHRcdGlmICghcGFydHMpIHJldHVybjtcclxuXHJcblx0XHRcdC8vIFdyaXRlciBjaGFuZ2VkIGV4dGVybmFsbHkgLT4gdXBkYXRlIFVJLlxyXG5cdFx0XHRpZiAocGFydHMud3JpdGVyICYmIHQgPT09IHBhcnRzLndyaXRlcikge1xyXG5cdFx0XHRcdGlmICh0Ll9fd3BiY19zbGlkZXJfcmFuZ2VfaW50ZXJuYWwpIHJldHVybjtcclxuXHRcdFx0XHR0aGlzLl9zeW5jX2Zyb21fd3JpdGVyKGdyb3VwKTtcclxuXHRcdFx0XHR0aGlzLl9jbGFtcF90b19yYW5nZShncm91cCk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBSYW5nZSBtb3ZlZCAtPiB1cGRhdGUgbnVtYmVyICsgd3JpdGVyLlxyXG5cdFx0XHRpZiAodC5tYXRjaGVzICYmIHQubWF0Y2hlcyh0aGlzLm9wdHMucmFuZ2Vfc2VsZWN0b3IpKSB7XHJcblx0XHRcdFx0aWYgKHBhcnRzLm51bSkgcGFydHMubnVtLnZhbHVlID0gdC52YWx1ZTtcclxuXHRcdFx0XHR0aGlzLl93cml0ZShwYXJ0cywgdC52YWx1ZSwgLyplbWl0Ki8gdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBOdW1iZXIgdHlwZWQgLT4gdXBkYXRlIHJhbmdlICsgd3JpdGVyIChjbGFtcCBieSBzbGlkZXIgYm91bmRzKS5cclxuXHRcdFx0aWYgKHQubWF0Y2hlcyAmJiB0Lm1hdGNoZXModGhpcy5vcHRzLnZhbHVlX3NlbGVjdG9yKSkge1xyXG5cdFx0XHRcdGlmIChwYXJ0cy5yYW5nZSkge1xyXG5cdFx0XHRcdFx0dmFyIHYgPSBwYXJzZV9mbG9hdCh0LnZhbHVlKTtcclxuXHRcdFx0XHRcdGlmICh2ICE9IG51bGwpIHtcclxuXHRcdFx0XHRcdFx0dmFyIG1pbiA9IE51bWJlcihwYXJ0cy5yYW5nZS5taW4pO1xyXG5cdFx0XHRcdFx0XHR2YXIgbWF4ID0gTnVtYmVyKHBhcnRzLnJhbmdlLm1heCk7XHJcblx0XHRcdFx0XHRcdHYgPSBjbGFtcF9udW0odiwgaXNOYU4obWluKSA/IG51bGwgOiBtaW4sIGlzTmFOKG1heCkgPyBudWxsIDogbWF4KTtcclxuXHJcblx0XHRcdFx0XHRcdHBhcnRzLnJhbmdlLnZhbHVlID0gU3RyaW5nKHYpO1xyXG5cdFx0XHRcdFx0XHRpZiAoU3RyaW5nKHYpICE9PSB0LnZhbHVlKSB0LnZhbHVlID0gU3RyaW5nKHYpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLl93cml0ZShwYXJ0cywgdC52YWx1ZSwgLyplbWl0Ki8gdHJ1ZSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRfb25fY2hhbmdlKGV2KSB7XHJcblx0XHRcdC8vIE5vIHNwZWNpYWwgXCJjaGFuZ2VcIiBoYW5kbGluZyBuZWVkZWQgY3VycmVudGx5OyBrZXB0IGZvciBzeW1tZXRyeS9mdXR1cmUuXHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gQXV0by1pbml0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdGZ1bmN0aW9uIHdwYmNfc2xpZGVyX3JhbmdlX2dyb3Vwc19fYXV0b19pbml0KCkge1xyXG5cdFx0dmFyIFJPT1QgID0gJy53cGJjX3NsaWRlcl9yYW5nZV9ncm91cHMnO1xyXG5cdFx0dmFyIG5vZGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZC5xdWVyeVNlbGVjdG9yQWxsKFJPT1QpKVxyXG5cdFx0XHQuZmlsdGVyKGZ1bmN0aW9uIChuKSB7IHJldHVybiAhbi5wYXJlbnRFbGVtZW50IHx8ICFuLnBhcmVudEVsZW1lbnQuY2xvc2VzdChST09UKTsgfSk7XHJcblxyXG5cdFx0aWYgKCFub2Rlcy5sZW5ndGgpIHtcclxuXHRcdFx0aWYgKCFkLl9fd3BiY19zbGlkZXJfcmFuZ2VfZ3JvdXBzX2dsb2JhbF9pbnN0YW5jZSkge1xyXG5cdFx0XHRcdGQuX193cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfZ2xvYmFsX2luc3RhbmNlID0gbmV3IFdQQkNfU2xpZGVyX1JhbmdlX0dyb3VwcyhkKS5pbml0KCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdG5vZGVzLmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcclxuXHRcdFx0aWYgKG5vZGUuX193cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfaW5zdGFuY2UpIHJldHVybjtcclxuXHRcdFx0bm9kZS5fX3dwYmNfc2xpZGVyX3JhbmdlX2dyb3Vwc19pbnN0YW5jZSA9IG5ldyBXUEJDX1NsaWRlcl9SYW5nZV9Hcm91cHMobm9kZSkuaW5pdCgpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvLyBFeHBvcnQgZ2xvYmFscy5cclxuXHR3LldQQkNfU2xpZGVyX1JhbmdlX0dyb3VwcyAgID0gV1BCQ19TbGlkZXJfUmFuZ2VfR3JvdXBzO1xyXG5cdHcuV1BCQ19TbGlkZXJfUmFuZ2VfQXV0b0luaXQgPSB3cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfX2F1dG9faW5pdDtcclxuXHJcblx0aWYgKGQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XHJcblx0XHRkLmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfX2F1dG9faW5pdCwgeyBvbmNlOiB0cnVlIH0pO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR3cGJjX3NsaWRlcl9yYW5nZV9ncm91cHNfX2F1dG9faW5pdCgpO1xyXG5cdH1cclxuXHJcbn0pKHdpbmRvdywgZG9jdW1lbnQpO1xyXG4iLCIvKipcclxuICogQm9va2luZyBDYWxlbmRhciDigJQgR2VuZXJpYyBVSSBUYWJzIFV0aWxpdHkgKEpTKVxyXG4gKlxyXG4gKiBQdXJwb3NlOiBMaWdodHdlaWdodCwgZGVwZW5kZW5jeS1mcmVlIHRhYnMgY29udHJvbGxlciBmb3IgYW55IHNtYWxsIHRhYiBncm91cCBpbiBhZG1pbiBVSXMuXHJcbiAqIC0gQXV0by1pbml0aWFsaXplcyBncm91cHMgbWFya2VkIHdpdGggZGF0YS13cGJjLXRhYnMuXHJcbiAqIC0gQXNzaWducyBBUklBIHJvbGVzIGFuZCB0b2dnbGVzIGFyaWEtc2VsZWN0ZWQvYXJpYS1oaWRkZW4vdGFiaW5kZXguXHJcbiAqIC0gU3VwcG9ydHMga2V5Ym9hcmQgbmF2aWdhdGlvbiAoTGVmdC9SaWdodC9Ib21lL0VuZCkuXHJcbiAqIC0gUHVibGljIEFQSTogd2luZG93LndwYmNfdWlfdGFicy57aW5pdF9vbiwgaW5pdF9ncm91cCwgc2V0X2FjdGl2ZX1cclxuICogLSBFbWl0cyAnd3BiYzp0YWJzOmNoYW5nZScgb24gdGhlIGdyb3VwIHJvb3Qgd2hlbiB0aGUgYWN0aXZlIHRhYiBjaGFuZ2VzLlxyXG4gKlxyXG4gKiBNYXJrdXAgY29udHJhY3Q6XHJcbiAqIC0gUm9vdDogICBbZGF0YS13cGJjLXRhYnNdXHJcbiAqIC0gVGFiczogICBbZGF0YS13cGJjLXRhYi1rZXk9XCJLXCJdXHJcbiAqIC0gUGFuZWxzOiBbZGF0YS13cGJjLXRhYi1wYW5lbD1cIktcIl1cclxuICpcclxuICogQHBhY2thZ2UgICBCb29raW5nIENhbGVuZGFyXHJcbiAqIEBzdWJwYWNrYWdlIEFkbWluXFxVSVxyXG4gKiBAc2luY2UgICAgIDExLjAuMFxyXG4gKiBAdmVyc2lvbiAgIDEuMC4wXHJcbiAqIEBzZWUgICAgICAgL2luY2x1ZGVzL19fanMvYWRtaW4vdWlfdGFicy91aV90YWJzLmpzXHJcbiAqXHJcbiAqXHJcbiAqIEhvdyBpdCB3b3JrczpcclxuICogLSBSb290IG5vZGUgbXVzdCBoYXZlIFtkYXRhLXdwYmMtdGFic10gYXR0cmlidXRlIChhbnkgdmFsdWUpLlxyXG4gKiAtIFRhYiBidXR0b25zIG11c3QgY2FycnkgW2RhdGEtd3BiYy10YWIta2V5PVwiLi4uXCJdICh1bmlxdWUgcGVyIGdyb3VwKS5cclxuICogLSBQYW5lbHMgbXVzdCBjYXJyeSBbZGF0YS13cGJjLXRhYi1wYW5lbD1cIi4uLlwiXSB3aXRoIG1hdGNoaW5nIGtleXMuXHJcbiAqIC0gQWRkcyBXQUktQVJJQSByb2xlcyBhbmQgYXJpYS1zZWxlY3RlZC9oaWRkZW4gd2lyaW5nLlxyXG4gKlxyXG4gKiA8ZGl2IGRhdGEtd3BiYy10YWJzPVwiY29sdW1uLXN0eWxlc1wiIGRhdGEtd3BiYy10YWItYWN0aXZlPVwiMVwiICAgIGNsYXNzPVwid3BiY191aV90YWJzX3Jvb3RcIiA+XHJcbiAqICAgIDwhLS0gVG9wIFRhYnMgLS0+XHJcbiAqICAgIDxkaXYgZGF0YS13cGJjLXRhYmxpc3Q9XCJcIiByb2xlPVwidGFibGlzdFwiICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIiB3cGJjX3VpX2VsX19ob3Jpc190b3BfYmFyX193cmFwcGVyXCIgPlxyXG4gKiAgICAgICAgPGRpdiBjbGFzcz1cIndwYmNfdWlfZWxfX2hvcmlzX3RvcF9iYXJfX2NvbnRlbnRcIj5cclxuICogICAgICAgICAgICA8aDIgY2xhc3M9XCJ3cGJjX3VpX2VsX19ob3Jpc19uYXZfbGFiZWxcIj5Db2x1bW46PC9oMj5cclxuICpcclxuICogICAgICAgICAgICA8ZGl2IGNsYXNzPVwid3BiY191aV9lbF9faG9yaXNfbmF2X2l0ZW0gd3BiY191aV9lbF9faG9yaXNfbmF2X2l0ZW1fXzFcIj5cclxuICogICAgICAgICAgICAgICAgPGFcclxuICogICAgICAgICAgICAgICAgICAgIGRhdGEtd3BiYy10YWIta2V5PVwiMVwiXHJcbiAqICAgICAgICAgICAgICAgICAgICBhcmlhLXNlbGVjdGVkPVwidHJ1ZVwiIHJvbGU9XCJ0YWJcIiB0YWJpbmRleD1cIjBcIiBhcmlhLWNvbnRyb2xzPVwid3BiY190YWJfcGFuZWxfY29sXzFcIlxyXG4gKlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCJcclxuICogICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIndwYmNfdWlfZWxfX2hvcmlzX25hdl9pdGVtX19hIHdwYmNfdWlfZWxfX2hvcmlzX25hdl9pdGVtX19zaW5nbGVcIlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIGlkPVwid3BiY190YWJfY29sXzFcIlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ29sdW1uIDFcIlxyXG4gKiAgICAgICAgICAgICAgICA+PHNwYW4gY2xhc3M9XCJ3cGJjX3VpX2VsX19ob3Jpc19uYXZfdGl0bGVcIj5UaXRsZSAxPC9zcGFuPjwvYT5cclxuICogICAgICAgICAgICA8L2Rpdj5cclxuICogICAgICAgICAgICAuLi5cclxuICogICAgICAgIDwvZGl2PlxyXG4gKiAgICA8L2Rpdj5cclxuICogICAgPCEtLSBUYWJzIENvbnRlbnQgLS0+XHJcbiAqICAgIDxkaXYgY2xhc3M9XCJ3cGJjX3RhYl9fcGFuZWwgZ3JvdXBfX2ZpZWxkc1wiIGRhdGEtd3BiYy10YWItcGFuZWw9XCIxXCIgaWQ9XCJ3cGJjX3RhYl9wYW5lbF9jb2xfMVwiIHJvbGU9XCJ0YWJwYW5lbFwiIGFyaWEtbGFiZWxsZWRieT1cIndwYmNfdGFiX2NvbF8xXCI+XHJcbiAqICAgICAgICAuLi5cclxuICogICAgPC9kaXY+XHJcbiAqICAgIC4uLlxyXG4gKiA8L2Rpdj5cclxuICpcclxuICogUHVibGljIEFQSTpcclxuICogICAtIHdwYmNfdWlfdGFicy5pbml0X29uKHJvb3Rfb3Jfc2VsZWN0b3IpICAgLy8gZmluZCBhbmQgaW5pdCBncm91cHMgd2l0aGluIGEgY29udGFpbmVyXHJcbiAqICAgLSB3cGJjX3VpX3RhYnMuaW5pdF9ncm91cChyb290X2VsKSAgICAgICAgIC8vIGluaXQgYSBzaW5nbGUgZ3JvdXAgcm9vdFxyXG4gKiAgIC0gd3BiY191aV90YWJzLnNldF9hY3RpdmUocm9vdF9lbCwga2V5KSAgICAvLyBwcm9ncmFtbWF0aWNhbGx5IGNoYW5nZSBhY3RpdmUgdGFiXHJcbiAqXHJcbiAqIEV2ZW50czpcclxuICogICAtIERpc3BhdGNoZXMgQ3VzdG9tRXZlbnQgJ3dwYmM6dGFiczpjaGFuZ2UnIG9uIHJvb3Qgd2hlbiB0YWIgY2hhbmdlczpcclxuICogICAgICAgZGV0YWlsOiB7IGFjdGl2ZV9rZXk6ICcyJywgcHJldl9rZXk6ICcxJyB9XHJcbiAqXHJcbiAqIFN3aXRjaCBhIGxvY2FsIChnZW5lcmljKSB0YWJzIGdyb3VwIHRvIHRhYiAzOiAgICAgdmFyIGdyb3VwID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtd3BiYy10YWJzPVwiY29sdW1uLXN0eWxlc1wiXScpOyBpZiAoIGdyb3VwICkgeyB3cGJjX3VpX3RhYnMuc2V0X2FjdGl2ZShncm91cCwgJzMnKTsgfVxyXG4gKi9cclxuKGZ1bmN0aW9uICggdyApIHtcclxuXHQndXNlIHN0cmljdCc7XHJcblxyXG5cdGlmICggdy53cGJjX3VpX3RhYnMgKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBJbnRlcm5hbDogdG9nZ2xlIGFjdGl2ZSBzdGF0ZS5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHJvb3RfZWxcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gICAgICBrZXlcclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59ICAgICBzaG91bGRfZW1pdFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHNldF9hY3RpdmVfaW50ZXJuYWwoIHJvb3RfZWwsIGtleSwgc2hvdWxkX2VtaXQgKSB7XHJcblx0XHR2YXIgdGFiX2J0bnMgPSByb290X2VsLnF1ZXJ5U2VsZWN0b3JBbGwoICdbZGF0YS13cGJjLXRhYi1rZXldJyApO1xyXG5cdFx0dmFyIHBhbmVscyAgID0gcm9vdF9lbC5xdWVyeVNlbGVjdG9yQWxsKCAnW2RhdGEtd3BiYy10YWItcGFuZWxdJyApO1xyXG5cclxuXHRcdHZhciBwcmV2X2tleSA9IHJvb3RfZWwuZ2V0QXR0cmlidXRlKCAnZGF0YS13cGJjLXRhYi1hY3RpdmUnICkgfHwgbnVsbDtcclxuXHRcdGlmICggU3RyaW5nKCBwcmV2X2tleSApID09PSBTdHJpbmcoIGtleSApICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQnV0dG9uczogYXJpYSArIGNsYXNzXHJcblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCB0YWJfYnRucy5sZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0dmFyIGJ0biAgID0gdGFiX2J0bnNbaV07XHJcblx0XHRcdHZhciBiX2tleSA9IGJ0bi5nZXRBdHRyaWJ1dGUoICdkYXRhLXdwYmMtdGFiLWtleScgKTtcclxuXHRcdFx0dmFyIGlzX29uID0gU3RyaW5nKCBiX2tleSApID09PSBTdHJpbmcoIGtleSApO1xyXG5cclxuXHRcdFx0YnRuLnNldEF0dHJpYnV0ZSggJ3JvbGUnLCAndGFiJyApO1xyXG5cdFx0XHRidG4uc2V0QXR0cmlidXRlKCAnYXJpYS1zZWxlY3RlZCcsIGlzX29uID8gJ3RydWUnIDogJ2ZhbHNlJyApO1xyXG5cdFx0XHRidG4uc2V0QXR0cmlidXRlKCAndGFiaW5kZXgnLCBpc19vbiA/ICcwJyA6ICctMScgKTtcclxuXHJcblx0XHRcdGlmICggaXNfb24gKSB7XHJcblx0XHRcdFx0YnRuLmNsYXNzTGlzdC5hZGQoICdhY3RpdmUnICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0YnRuLmNsYXNzTGlzdC5yZW1vdmUoICdhY3RpdmUnICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBQYW5lbHM6IGFyaWEgKyB2aXNpYmlsaXR5XHJcblx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCBwYW5lbHMubGVuZ3RoOyBqKysgKSB7XHJcblx0XHRcdHZhciBwbiAgID0gcGFuZWxzW2pdO1xyXG5cdFx0XHR2YXIgcGtleSA9IHBuLmdldEF0dHJpYnV0ZSggJ2RhdGEtd3BiYy10YWItcGFuZWwnICk7XHJcblx0XHRcdHZhciBzaG93ID0gU3RyaW5nKCBwa2V5ICkgPT09IFN0cmluZygga2V5ICk7XHJcblxyXG5cdFx0XHRwbi5zZXRBdHRyaWJ1dGUoICdyb2xlJywgJ3RhYnBhbmVsJyApO1xyXG5cdFx0XHRwbi5zZXRBdHRyaWJ1dGUoICdhcmlhLWhpZGRlbicsIHNob3cgPyAnZmFsc2UnIDogJ3RydWUnICk7XHJcblx0XHRcdGlmICggc2hvdyApIHtcclxuXHRcdFx0XHRwbi5yZW1vdmVBdHRyaWJ1dGUoICdoaWRkZW4nICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cG4uc2V0QXR0cmlidXRlKCAnaGlkZGVuJywgJycgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJvb3RfZWwuc2V0QXR0cmlidXRlKCAnZGF0YS13cGJjLXRhYi1hY3RpdmUnLCBTdHJpbmcoIGtleSApICk7XHJcblxyXG5cdFx0aWYgKCBzaG91bGRfZW1pdCApIHtcclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHR2YXIgZXYgPSBuZXcgdy5DdXN0b21FdmVudCggJ3dwYmM6dGFiczpjaGFuZ2UnLCB7XHJcblx0XHRcdFx0XHRidWJibGVzIDogdHJ1ZSxcclxuXHRcdFx0XHRcdGRldGFpbCAgOiB7IGFjdGl2ZV9rZXkgOiBTdHJpbmcoIGtleSApLCBwcmV2X2tleSA6IHByZXZfa2V5IH1cclxuXHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0cm9vdF9lbC5kaXNwYXRjaEV2ZW50KCBldiApO1xyXG5cdFx0XHR9IGNhdGNoICggX2UgKSB7fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogSW50ZXJuYWw6IGdldCBvcmRlcmVkIGtleXMgZnJvbSBidXR0b25zLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcm9vdF9lbFxyXG5cdCAqIEByZXR1cm5zIHtzdHJpbmdbXX1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiBnZXRfa2V5cyggcm9vdF9lbCApIHtcclxuXHRcdHZhciBsaXN0ID0gW107XHJcblx0XHR2YXIgYnRucyA9IHJvb3RfZWwucXVlcnlTZWxlY3RvckFsbCggJ1tkYXRhLXdwYmMtdGFiLWtleV0nICk7XHJcblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBidG5zLmxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHR2YXIgayA9IGJ0bnNbaV0uZ2V0QXR0cmlidXRlKCAnZGF0YS13cGJjLXRhYi1rZXknICk7XHJcblx0XHRcdGlmICggayAhPSBudWxsICYmIGsgIT09ICcnICkge1xyXG5cdFx0XHRcdGxpc3QucHVzaCggU3RyaW5nKCBrICkgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGxpc3Q7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBJbnRlcm5hbDogbW92ZSBmb2N1cyBiZXR3ZWVuIHRhYnMgdXNpbmcga2V5Ym9hcmQuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSByb290X2VsXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9ICAgICAgZGlyICArMSAobmV4dCkgLyAtMSAocHJldilcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBmb2N1c19yZWxhdGl2ZSggcm9vdF9lbCwgZGlyICkge1xyXG5cdFx0dmFyIGtleXMgICAgPSBnZXRfa2V5cyggcm9vdF9lbCApO1xyXG5cdFx0dmFyIGN1cnJlbnQgPSByb290X2VsLmdldEF0dHJpYnV0ZSggJ2RhdGEtd3BiYy10YWItYWN0aXZlJyApIHx8IGtleXNbMF0gfHwgbnVsbDtcclxuXHRcdHZhciBpZHggICAgID0gTWF0aC5tYXgoIDAsIGtleXMuaW5kZXhPZiggU3RyaW5nKCBjdXJyZW50ICkgKSApO1xyXG5cdFx0dmFyIG5leHQgICAgPSBrZXlzWyAoIGlkeCArICggZGlyID4gMCA/IDEgOiBrZXlzLmxlbmd0aCAtIDEgKSApICUga2V5cy5sZW5ndGggXTtcclxuXHJcblx0XHR2YXIgbmV4dF9idG4gPSByb290X2VsLnF1ZXJ5U2VsZWN0b3IoICdbZGF0YS13cGJjLXRhYi1rZXk9XCInICsgbmV4dCArICdcIl0nICk7XHJcblx0XHRpZiAoIG5leHRfYnRuICkge1xyXG5cdFx0XHRuZXh0X2J0bi5mb2N1cygpO1xyXG5cdFx0XHRzZXRfYWN0aXZlX2ludGVybmFsKCByb290X2VsLCBuZXh0LCB0cnVlICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBJbml0aWFsaXplIGEgc2luZ2xlIHRhYnMgZ3JvdXAgcm9vdC5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHJvb3RfZWxcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBpbml0X2dyb3VwKCByb290X2VsICkge1xyXG5cdFx0aWYgKCAhIHJvb3RfZWwgfHwgcm9vdF9lbC5fX3dwYmNfdGFic19pbml0ZWQgKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdHJvb3RfZWwuX193cGJjX3RhYnNfaW5pdGVkID0gdHJ1ZTtcclxuXHJcblx0XHQvLyBSb2xlc1xyXG5cdFx0dmFyIHRhYmxpc3QgPSByb290X2VsLnF1ZXJ5U2VsZWN0b3IoICdbZGF0YS13cGJjLXRhYmxpc3RdJyApIHx8IHJvb3RfZWw7XHJcblx0XHR0YWJsaXN0LnNldEF0dHJpYnV0ZSggJ3JvbGUnLCAndGFibGlzdCcgKTtcclxuXHJcblx0XHQvLyBEZWZhdWx0IGFjdGl2ZTogZnJvbSBhdHRyaWJ1dGUgb3IgZmlyc3QgYnV0dG9uXHJcblx0XHR2YXIga2V5cyA9IGdldF9rZXlzKCByb290X2VsICk7XHJcblx0XHR2YXIgZGVmICA9IHJvb3RfZWwuZ2V0QXR0cmlidXRlKCAnZGF0YS13cGJjLXRhYi1hY3RpdmUnICkgfHwgKCBrZXlzWzBdIHx8ICcxJyApO1xyXG5cdFx0c2V0X2FjdGl2ZV9pbnRlcm5hbCggcm9vdF9lbCwgZGVmLCBmYWxzZSApO1xyXG5cclxuXHRcdC8vIENsaWNrc1xyXG5cdFx0cm9vdF9lbC5hZGRFdmVudExpc3RlbmVyKCAnY2xpY2snLCBmdW5jdGlvbiAoIGUgKSB7XHJcblx0XHRcdHZhciBidG4gPSBlLnRhcmdldC5jbG9zZXN0ID8gZS50YXJnZXQuY2xvc2VzdCggJ1tkYXRhLXdwYmMtdGFiLWtleV0nICkgOiBudWxsO1xyXG5cdFx0XHRpZiAoICEgYnRuIHx8ICEgcm9vdF9lbC5jb250YWlucyggYnRuICkgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0dmFyIGtleSA9IGJ0bi5nZXRBdHRyaWJ1dGUoICdkYXRhLXdwYmMtdGFiLWtleScgKTtcclxuXHRcdFx0aWYgKCBrZXkgIT0gbnVsbCApIHtcclxuXHRcdFx0XHRzZXRfYWN0aXZlX2ludGVybmFsKCByb290X2VsLCBrZXksIHRydWUgKTtcclxuXHRcdFx0fVxyXG5cdFx0fSwgdHJ1ZSApO1xyXG5cclxuXHRcdC8vIEtleWJvYXJkIChMZWZ0L1JpZ2h0L0hvbWUvRW5kKVxyXG5cdFx0cm9vdF9lbC5hZGRFdmVudExpc3RlbmVyKCAna2V5ZG93bicsIGZ1bmN0aW9uICggZSApIHtcclxuXHRcdFx0dmFyIHRndCA9IGUudGFyZ2V0O1xyXG5cdFx0XHRpZiAoICEgdGd0IHx8ICEgdGd0Lmhhc0F0dHJpYnV0ZSB8fCAhIHRndC5oYXNBdHRyaWJ1dGUoICdkYXRhLXdwYmMtdGFiLWtleScgKSApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdFx0c3dpdGNoICggZS5rZXkgKSB7XHJcblx0XHRcdGNhc2UgJ0Fycm93TGVmdCc6XHJcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpOyBmb2N1c19yZWxhdGl2ZSggcm9vdF9lbCwgLTEgKTsgYnJlYWs7XHJcblx0XHRcdGNhc2UgJ0Fycm93UmlnaHQnOlxyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTsgZm9jdXNfcmVsYXRpdmUoIHJvb3RfZWwsICsxICk7IGJyZWFrO1xyXG5cdFx0XHRjYXNlICdIb21lJzpcclxuXHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7IHNldF9hY3RpdmVfaW50ZXJuYWwoIHJvb3RfZWwsICggZ2V0X2tleXMoIHJvb3RfZWwgKVswXSB8fCAnMScgKSwgdHJ1ZSApOyBicmVhaztcclxuXHRcdFx0Y2FzZSAnRW5kJzpcclxuXHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7IHZhciBrcyA9IGdldF9rZXlzKCByb290X2VsICk7IHNldF9hY3RpdmVfaW50ZXJuYWwoIHJvb3RfZWwsICgga3NbIGtzLmxlbmd0aCAtIDEgXSB8fCAnMScgKSwgdHJ1ZSApOyBicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0fSwgdHJ1ZSApO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogSW5pdGlhbGl6ZSBhbGwgZ3JvdXBzIHdpdGhpbiBhIGNvbnRhaW5lciAob3IgZG9jdW1lbnQpLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudHxzdHJpbmd8bnVsbH0gY29udGFpbmVyXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gaW5pdF9vbiggY29udGFpbmVyICkge1xyXG5cdFx0dmFyIGN0eCA9IGNvbnRhaW5lciA/ICggdHlwZW9mIGNvbnRhaW5lciA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCBjb250YWluZXIgKSA6IGNvbnRhaW5lciApIDogZG9jdW1lbnQ7XHJcblx0XHRpZiAoICEgY3R4ICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHR2YXIgZ3JvdXBzID0gY3R4LnF1ZXJ5U2VsZWN0b3JBbGwoICdbZGF0YS13cGJjLXRhYnNdJyApO1xyXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgZ3JvdXBzLmxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHRpbml0X2dyb3VwKCBncm91cHNbaV0gKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIFByb2dyYW1tYXRpY2FsbHkgc2V0IGFjdGl2ZSB0YWIgYnkga2V5LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcm9vdF9lbFxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0ga2V5XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gc2V0X2FjdGl2ZSggcm9vdF9lbCwga2V5ICkge1xyXG5cdFx0aWYgKCByb290X2VsICYmIHJvb3RfZWwuaGFzQXR0cmlidXRlICYmIHJvb3RfZWwuaGFzQXR0cmlidXRlKCAnZGF0YS13cGJjLXRhYnMnICkgKSB7XHJcblx0XHRcdHNldF9hY3RpdmVfaW50ZXJuYWwoIHJvb3RfZWwsIFN0cmluZygga2V5ICksIHRydWUgKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIFB1YmxpYyBBUEkgKHNuYWtlX2Nhc2UpXHJcblx0dy53cGJjX3VpX3RhYnMgPSB7XHJcblx0XHRpbml0X29uICAgIDogaW5pdF9vbixcclxuXHRcdGluaXRfZ3JvdXAgOiBpbml0X2dyb3VwLFxyXG5cdFx0c2V0X2FjdGl2ZSA6IHNldF9hY3RpdmVcclxuXHR9O1xyXG5cclxuXHQvLyBBdXRvLWluaXQgb24gRE9NIHJlYWR5XHJcblx0aWYgKCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycgKSB7XHJcblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCAnRE9NQ29udGVudExvYWRlZCcsIGZ1bmN0aW9uICgpIHsgaW5pdF9vbiggZG9jdW1lbnQgKTsgfSApO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRpbml0X29uKCBkb2N1bWVudCApO1xyXG5cdH1cclxuXHJcbn0pKCB3aW5kb3cgKTtcclxuIl0sIm1hcHBpbmdzIjoiOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUEsbUJBQUFDLGdCQUFBLEVBQUFDLGNBQUEsTUFBQUMsaUJBQUE7RUFFQSxTQUFBQyxDQUFBLE1BQUFBLENBQUEsR0FBQUYsY0FBQSxFQUFBRSxDQUFBO0lBQ0FDLE1BQUEsQ0FBQUosZ0JBQUEsRUFBQUssT0FBQSxDQUFBSCxpQkFBQSxFQUFBSSxNQUFBLENBQUFKLGlCQUFBO0VBQ0E7RUFDQUUsTUFBQSxDQUFBSixnQkFBQSxFQUFBTyxPQUFBO0lBQUFDLE9BQUE7RUFBQTtBQUNBOztBQ2RBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUMseUJBQUFDLHlCQUFBO0VBRUEsSUFBQUMsZUFBQTtFQUNBLElBQ0FDLFNBQUEsSUFBQUYseUJBQUEsSUFDQSxNQUFBQSx5QkFBQSxFQUNBO0lBQ0EsSUFBQUcsUUFBQSxHQUFBVCxNQUFBLE9BQUFNLHlCQUFBO0lBQ0EsSUFBQUcsUUFBQSxDQUFBQyxNQUFBO01B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
2070