PageSourceSearch

https://www.fs-medizin-kiel.de/wp-content/plugins/booking/_dist/all/_out/wpbc_all.js?ver=10.14.1

js fs-medizin-kiel.de collected 2026-10-08 19:50:42 UTC 457,588 bytes, 3,411 lines download raw bytes

1"use strict";
2
3function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4/**
5 * =====================================================================================================================
6 * JavaScript Util Functions		../includes/__js/utils/wpbc_utils.js
7 * =====================================================================================================================
8 */
9
10/**
11 * Trim  strings and array joined with  (,)
12 *
13 * @param string_to_trim   string / array
14 * @returns string
15 */
16function wpbc_trim(string_to_trim) {
17  if (Array.isArray(string_to_trim)) {
18    string_to_trim = string_to_trim.join(',');
19  }
20  if ('string' == typeof string_to_trim) {
21    string_to_trim = string_to_trim.trim();
22  }
23  return string_to_trim;
24}
25
26/**
27 * Check if element in array
28 *
29 * @param array_here		array
30 * @param p_val				element to  check
31 * @returns {boolean}
32 */
33function wpbc_in_array(array_here, p_val) {
34  for (var i = 0, l = array_here.length; i < l; i++) {
35    if (array_here[i] == p_val) {
36      return true;
37    }
38  }
39  return false;
40}
41"use strict";
42/**
43 * =====================================================================================================================
44 *	includes/__js/wpbc/wpbc.js
45 * =====================================================================================================================
46 */
47
48/**
49 * Deep Clone of object or array
50 *
51 * @param obj
52 * @returns {any}
53 */
54function wpbc_clone_obj(obj) {
55  return JSON.parse(JSON.stringify(obj));
56}
57
58/**
59 * Main _wpbc JS object
60 */
61
62var _wpbc = function (obj, $) {
63  // Secure parameters for Ajax	------------------------------------------------------------------------------------
64  var p_secure = obj.security_obj = obj.security_obj || {
65    user_id: 0,
66    nonce: '',
67    locale: ''
68  };
69  obj.set_secure_param = function (param_key, param_val) {
70    p_secure[param_key] = param_val;
71  };
72  obj.get_secure_param = function (param_key) {
73    return p_secure[param_key];
74  };
75
76  // Calendars 	----------------------------------------------------------------------------------------------------
77  var p_calendars = obj.calendars_obj = obj.calendars_obj || {
78    // sort            : "booking_id",
79    // sort_type       : "DESC",
80    // page_num        : 1,
81    // page_items_count: 10,
82    // create_date     : "",
83    // keyword         : "",
84    // source          : ""
85  };
86
87  /**
88   *  Check if calendar for specific booking resource defined   ::   true | false
89   *
90   * @param {string|int} resource_id
91   * @returns {boolean}
92   */
93  obj.calendar__is_defined = function (resource_id) {
94    return 'undefined' !== typeof p_calendars['calendar_' + resource_id];
95  };
96
97  /**
98   *  Create Calendar initializing
99   *
100   * @param {string|int} resource_id
101   */
102  obj.calendar__init = function (resource_id) {
103    p_calendars['calendar_' + resource_id] = {};
104    p_calendars['calendar_' + resource_id]['id'] = resource_id;
105    p_calendars['calendar_' + resource_id]['pending_days_selectable'] = false;
106  };
107
108  /**
109   * Check  if the type of this property  is INT
110   * @param property_name
111   * @returns {boolean}
112   */
113  obj.calendar__is_prop_int = function (property_name) {
114    // FixIn: 9.9.0.29.
115
116    var p_calendar_int_properties = ['dynamic__days_min', 'dynamic__days_max', 'fixed__days_num'];
117    var is_include = p_calendar_int_properties.includes(property_name);
118    return is_include;
119  };
120
121  /**
122   * Set params for all  calendars
123   *
124   * @param {object} calendars_obj		Object { calendar_1: {} }
125   * 												 calendar_3: {}, ... }
126   */
127  obj.calendars_all__set = function (calendars_obj) {
128    p_calendars = calendars_obj;
129  };
130
131  /**
132   * Get bookings in all calendars
133   *
134   * @returns {object|{}}
135   */
136  obj.calendars_all__get = function () {
137    return p_calendars;
138  };
139
140  /**
141   * Get calendar object   ::   { id: 1, … }
142   *
143   * @param {string|int} resource_id				  '2'
144   * @returns {object|boolean}					{ id: 2 ,… }
145   */
146  obj.calendar__get_parameters = function (resource_id) {
147    if (obj.calendar__is_defined(resource_id)) {
148      return p_calendars['calendar_' + resource_id];
149    } else {
150      return false;
151    }
152  };
153
154  /**
155   * Set calendar object   ::   { dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
156   *
157   * if calendar object  not defined, then  it's will be defined and ID set
158   * if calendar exist, then  system set  as new or overwrite only properties from calendar_property_obj parameter,  but other properties will be existed and not overwrite, like 'id'
159   *
160   * @param {string|int} resource_id				  '2'
161   * @param {object} calendar_property_obj					  {  dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }  }
162   * @param {boolean} is_complete_overwrite		  if 'true' (default: 'false'),  then  only overwrite or add  new properties in  calendar_property_obj
163   * @returns {*}
164   *
165   * Examples:
166   *
167   * Common usage in PHP:
168   *   			echo "  _wpbc.calendar__set(  " .intval( $resource_id ) . ", { 'dates': " . wp_json_encode( $availability_per_days_arr ) . " } );";
169   */
170  obj.calendar__set_parameters = function (resource_id, calendar_property_obj) {
171    var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
172    if (!obj.calendar__is_defined(resource_id) || true === is_complete_overwrite) {
173      obj.calendar__init(resource_id);
174    }
175    for (var prop_name in calendar_property_obj) {
176      p_calendars['calendar_' + resource_id][prop_name] = calendar_property_obj[prop_name];
177    }
178    return p_calendars['calendar_' + resource_id];
179  };
180
181  /**
182   * Set property  to  calendar
183   * @param resource_id	"1"
184   * @param prop_name		name of property
185   * @param prop_value	value of property
186   * @returns {*}			calendar object
187   */
188  obj.calendar__set_param_value = function (resource_id, prop_name, prop_value) {
189    if (!obj.calendar__is_defined(resource_id)) {
190      obj.calendar__init(resource_id);
191    }
192    p_calendars['calendar_' + resource_id][prop_name] = prop_value;
193    return p_calendars['calendar_' + resource_id];
194  };
195
196  /**
197   *  Get calendar property value   	::   mixed | null
198   *
199   * @param {string|int}  resource_id		'1'
200   * @param {string} prop_name			'selection_mode'
201   * @returns {*|null}					mixed | null
202   */
203  obj.calendar__get_param_value = function (resource_id, prop_name) {
204    if (obj.calendar__is_defined(resource_id) && 'undefined' !== typeof p_calendars['calendar_' + resource_id][prop_name]) {
205      // FixIn: 9.9.0.29.
206      if (obj.calendar__is_prop_int(prop_name)) {
207        p_calendars['calendar_' + resource_id][prop_name] = parseInt(p_calendars['calendar_' + resource_id][prop_name]);
208      }
209      return p_calendars['calendar_' + resource_id][prop_name];
210    }
211    return null; // If some property not defined, then null;
212  };
213  // -----------------------------------------------------------------------------------------------------------------
214
215  // Bookings 	----------------------------------------------------------------------------------------------------
216  var p_bookings = obj.bookings_obj = obj.bookings_obj || {
217    // calendar_1: Object {
218    //						   id:     1
219    //						 , dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, …
220    // }
221  };
222
223  /**
224   *  Check if bookings for specific booking resource defined   ::   true | false
225   *
226   * @param {string|int} resource_id
227   * @returns {boolean}
228   */
229  obj.bookings_in_calendar__is_defined = function (resource_id) {
230    return 'undefined' !== typeof p_bookings['calendar_' + resource_id];
231  };
232
233  /**
234   * Get bookings calendar object   ::   { id: 1 , dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
235   *
236   * @param {string|int} resource_id				  '2'
237   * @returns {object|boolean}					{ id: 2 , dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
238   */
239  obj.bookings_in_calendar__get = function (resource_id) {
240    if (obj.bookings_in_calendar__is_defined(resource_id)) {
241      return p_bookings['calendar_' + resource_id];
242    } else {
243      return false;
244    }
245  };
246
247  /**
248   * Set bookings calendar object   ::   { dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
249   *
250   * if calendar object  not defined, then  it's will be defined and ID set
251   * if calendar exist, then  system set  as new or overwrite only properties from calendar_obj parameter,  but other properties will be existed and not overwrite, like 'id'
252   *
253   * @param {string|int} resource_id				  '2'
254   * @param {object} calendar_obj					  {  dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }  }
255   * @returns {*}
256   *
257   * Examples:
258   *
259   * Common usage in PHP:
260   *   			echo "  _wpbc.bookings_in_calendar__set(  " .intval( $resource_id ) . ", { 'dates': " . wp_json_encode( $availability_per_days_arr ) . " } );";
261   */
262  obj.bookings_in_calendar__set = function (resource_id, calendar_obj) {
263    if (!obj.bookings_in_calendar__is_defined(resource_id)) {
264      p_bookings['calendar_' + resource_id] = {};
265      p_bookings['calendar_' + resource_id]['id'] = resource_id;
266    }
267    for (var prop_name in calendar_obj) {
268      p_bookings['calendar_' + resource_id][prop_name] = calendar_obj[prop_name];
269    }
270    return p_bookings['calendar_' + resource_id];
271  };
272
273  // Dates
274
275  /**
276   *  Get bookings data for ALL Dates in calendar   ::   false | { "2023-07-22": {…}, "2023-07-23": {…}, … }
277   *
278   * @param {string|int} resource_id			'1'
279   * @returns {object|boolean}				false | Object {
280  															"2023-07-24": Object { ['summary']['status_for_day']: "available", day_availability: 1, max_capacity: 1, … }
281  															"2023-07-26": Object { ['summary']['status_for_day']: "full_day_booking", ['summary']['status_for_bookings']: "pending", day_availability: 0, … }
282  															"2023-07-29": Object { ['summary']['status_for_day']: "resource_availability", day_availability: 0, max_capacity: 1, … }
283  															"2023-07-30": {…}, "2023-07-31": {…}, …
284  														}
285   */
286  obj.bookings_in_calendar__get_dates = function (resource_id) {
287    if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates']) {
288      return p_bookings['calendar_' + resource_id]['dates'];
289    }
290    return false; // If some property not defined, then false;
291  };
292
293  /**
294   * Set bookings dates in calendar object   ::    { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
295   *
296   * if calendar object  not defined, then  it's will be defined and 'id', 'dates' set
297   * if calendar exist, then system add a  new or overwrite only dates from dates_obj parameter,
298   * but other dates not from parameter dates_obj will be existed and not overwrite.
299   *
300   * @param {string|int} resource_id				  '2'
301   * @param {object} dates_obj					  { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
302   * @param {boolean} is_complete_overwrite		  if false,  then  only overwrite or add  dates from 	dates_obj
303   * @returns {*}
304   *
305   * Examples:
306   *   			_wpbc.bookings_in_calendar__set_dates( resource_id, { "2023-07-21": {…}, "2023-07-22": {…}, … }  );		<-   overwrite ALL dates
307   *   			_wpbc.bookings_in_calendar__set_dates( resource_id, { "2023-07-22": {…} },  false  );					<-   add or overwrite only  	"2023-07-22": {}
308   *
309   * Common usage in PHP:
310   *   			echo "  _wpbc.bookings_in_calendar__set_dates(  " . intval( $resource_id ) . ",  " . wp_json_encode( $availability_per_days_arr ) . "  );  ";
311   */
312  obj.bookings_in_calendar__set_dates = function (resource_id, dates_obj) {
313    var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
314    if (!obj.bookings_in_calendar__is_defined(resource_id)) {
315      obj.bookings_in_calendar__set(resource_id, {
316        'dates': {}
317      });
318    }
319    if ('undefined' === typeof p_bookings['calendar_' + resource_id]['dates']) {
320      p_bookings['calendar_' + resource_id]['dates'] = {};
321    }
322    if (is_complete_overwrite) {
323      // Complete overwrite all  booking dates
324      p_bookings['calendar_' + resource_id]['dates'] = dates_obj;
325    } else {
326      // Add only  new or overwrite exist booking dates from  parameter. Booking dates not from  parameter  will  be without chnanges
327      for (var prop_name in dates_obj) {
328        p_bookings['calendar_' + resource_id]['dates'][prop_name] = dates_obj[prop_name];
329      }
330    }
331    return p_bookings['calendar_' + resource_id];
332  };
333
334  /**
335   *  Get bookings data for specific date in calendar   ::   false | { day_availability: 1, ... }
336   *
337   * @param {string|int} resource_id			'1'
338   * @param {string} sql_class_day			'2023-07-21'
339   * @returns {object|boolean}				false | {
340  														day_availability: 4
341  														max_capacity: 4															//  >= Business Large
342  														2: Object { is_day_unavailable: false, _day_status: "available" }
343  														10: Object { is_day_unavailable: false, _day_status: "available" }		//  >= Business Large ...
344  														11: Object { is_day_unavailable: false, _day_status: "available" }
345  														12: Object { is_day_unavailable: false, _day_status: "available" }
346  													}
347   */
348  obj.bookings_in_calendar__get_for_date = function (resource_id, sql_class_day) {
349    if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates'] && 'undefined' !== typeof p_bookings['calendar_' + resource_id]['dates'][sql_class_day]) {
350      return p_bookings['calendar_' + resource_id]['dates'][sql_class_day];
351    }
352    return false; // If some property not defined, then false;
353  };
354
355  // Any  PARAMS   in bookings
356
357  /**
358   * Set property  to  booking
359   * @param resource_id	"1"
360   * @param prop_name		name of property
361   * @param prop_value	value of property
362   * @returns {*}			booking object
363   */
364  obj.booking__set_param_value = function (resource_id, prop_name, prop_value) {
365    if (!obj.bookings_in_calendar__is_defined(resource_id)) {
366      p_bookings['calendar_' + resource_id] = {};
367      p_bookings['calendar_' + resource_id]['id'] = resource_id;
368    }
369    p_bookings['calendar_' + resource_id][prop_name] = prop_value;
370    return p_bookings['calendar_' + resource_id];
371  };
372
373  /**
374   *  Get booking property value   	::   mixed | null
375   *
376   * @param {string|int}  resource_id		'1'
377   * @param {string} prop_name			'selection_mode'
378   * @returns {*|null}					mixed | null
379   */
380  obj.booking__get_param_value = function (resource_id, prop_name) {
381    if (obj.bookings_in_calendar__is_defined(resource_id) && 'undefined' !== typeof p_bookings['calendar_' + resource_id][prop_name]) {
382      return p_bookings['calendar_' + resource_id][prop_name];
383    }
384    return null; // If some property not defined, then null;
385  };
386
387  /**
388   * Set bookings for all  calendars
389   *
390   * @param {object} calendars_obj		Object { calendar_1: { id: 1, dates: Object { "2023-07-22": {…}, "2023-07-23": {…}, "2023-07-24": {…}, … } }
391   * 												 calendar_3: {}, ... }
392   */
393  obj.bookings_in_calendars__set_all = function (calendars_obj) {
394    p_bookings = calendars_obj;
395  };
396
397  /**
398   * Get bookings in all calendars
399   *
400   * @returns {object|{}}
401   */
402  obj.bookings_in_calendars__get_all = function () {
403    return p_bookings;
404  };
405  // -----------------------------------------------------------------------------------------------------------------
406
407  // Seasons 	----------------------------------------------------------------------------------------------------
408  var p_seasons = obj.seasons_obj = obj.seasons_obj || {
409    // calendar_1: Object {
410    //						   id:     1
411    //						 , dates:  Object { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, …
412    // }
413  };
414
415  /**
416   * Add season names for dates in calendar object   ::    { "2023-07-21": [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ], "2023-07-22": [...], ... }
417   *
418   *
419   * @param {string|int} resource_id				  '2'
420   * @param {object} dates_obj					  { "2023-07-21": {…}, "2023-07-22": {…}, "2023-07-23": {…}, … }
421   * @param {boolean} is_complete_overwrite		  if false,  then  only  add  dates from 	dates_obj
422   * @returns {*}
423   *
424   * Examples:
425   *   			_wpbc.seasons__set( resource_id, { "2023-07-21": [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ], "2023-07-22": [...], ... }  );
426   */
427  obj.seasons__set = function (resource_id, dates_obj) {
428    var is_complete_overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
429    if ('undefined' === typeof p_seasons['calendar_' + resource_id]) {
430      p_seasons['calendar_' + resource_id] = {};
431    }
432    if (is_complete_overwrite) {
433      // Complete overwrite all  season dates
434      p_seasons['calendar_' + resource_id] = dates_obj;
435    } else {
436      // Add only  new or overwrite exist booking dates from  parameter. Booking dates not from  parameter  will  be without chnanges
437      for (var prop_name in dates_obj) {
438        if ('undefined' === typeof p_seasons['calendar_' + resource_id][prop_name]) {
439          p_seasons['calendar_' + resource_id][prop_name] = [];
440        }
441        for (var season_name_key in dates_obj[prop_name]) {
442          p_seasons['calendar_' + resource_id][prop_name].push(dates_obj[prop_name][season_name_key]);
443        }
444      }
445    }
446    return p_seasons['calendar_' + resource_id];
447  };
448
449  /**
450   *  Get bookings data for specific date in calendar   ::   [] | [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ]
451   *
452   * @param {string|int} resource_id			'1'
453   * @param {string} sql_class_day			'2023-07-21'
454   * @returns {object|boolean}				[]  |  [ 'wpbc_season_september_2023', 'wpbc_season_september_2024' ]
455   */
456  obj.seasons__get_for_date = function (resource_id, sql_class_day) {
457    if ('undefined' !== typeof p_seasons['calendar_' + resource_id] && 'undefined' !== typeof p_seasons['calendar_' + resource_id][sql_class_day]) {
458      return p_seasons['calendar_' + resource_id][sql_class_day];
459    }
460    return []; // If not defined, then [];
461  };
462
463  // Other parameters 			------------------------------------------------------------------------------------
464  var p_other = obj.other_obj = obj.other_obj || {};
465  obj.set_other_param = function (param_key, param_val) {
466    p_other[param_key] = param_val;
467  };
468  obj.get_other_param = function (param_key) {
469    return p_other[param_key];
470  };
471
472  /**
473   * Get all other params
474   *
475   * @returns {object|{}}
476   */
477  obj.get_other_param__all = function () {
478    return p_other;
479  };
480
481  // Messages 			        ------------------------------------------------------------------------------------
482  var p_messages = obj.messages_obj = obj.messages_obj || {};
483  obj.set_message = function (param_key, param_val) {
484    p_messages[param_key] = param_val;
485  };
486  obj.get_message = function (param_key) {
487    return p_messages[param_key];
488  };
489
490  /**
491   * Get all other params
492   *
493   * @returns {object|{}}
494   */
495  obj.get_messages__all = function () {
496    return p_messages;
497  };
498
499  // -----------------------------------------------------------------------------------------------------------------
500
501  return obj;
502}(_wpbc || {}, jQuery);
503
504/**
505 * Extend _wpbc with  new methods        // FixIn: 9.8.6.2.
506 *
507 * @type {*|{}}
508 * @private
509 */
510_wpbc = function (obj, $) {
511  // Load Balancer 	-----------------------------------------------------------------------------------------------
512
513  var p_balancer = obj.balancer_obj = obj.balancer_obj || {
514    'max_threads': 2,
515    'in_process': [],
516    'wait': []
517  };
518
519  /**
520   * Set  max parallel request  to  load
521   *
522   * @param max_threads
523   */
524  obj.balancer__set_max_threads = function (max_threads) {
525    p_balancer['max_threads'] = max_threads;
526  };
527
528  /**
529   *  Check if balancer for specific booking resource defined   ::   true | false
530   *
531   * @param {string|int} resource_id
532   * @returns {boolean}
533   */
534  obj.balancer__is_defined = function (resource_id) {
535    return 'undefined' !== typeof p_balancer['balancer_' + resource_id];
536  };
537
538  /**
539   *  Create balancer initializing
540   *
541   * @param {string|int} resource_id
542   */
543  obj.balancer__init = function (resource_id, function_name) {
544    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
545    var balance_obj = {};
546    balance_obj['resource_id'] = resource_id;
547    balance_obj['priority'] = 1;
548    balance_obj['function_name'] = function_name;
549    balance_obj['params'] = wpbc_clone_obj(params);
550    if (obj.balancer__is_already_run(resource_id, function_name)) {
551      return 'run';
552    }
553    if (obj.balancer__is_already_wait(resource_id, function_name)) {
554      return 'wait';
555    }
556    if (obj.balancer__can_i_run()) {
557      obj.balancer__add_to__run(balance_obj);
558      return 'run';
559    } else {
560      obj.balancer__add_to__wait(balance_obj);
561      return 'wait';
562    }
563  };
564
565  /**
566   * Can I Run ?
567   * @returns {boolean}
568   */
569  obj.balancer__can_i_run = function () {
570    return p_balancer['in_process'].length < p_balancer['max_threads'];
571  };
572
573  /**
574   * Add to WAIT
575   * @param balance_obj
576   */
577  obj.balancer__add_to__wait = function (balance_obj) {
578    p_balancer['wait'].push(balance_obj);
579  };
580
581  /**
582   * Remove from Wait
583   *
584   * @param resource_id
585   * @param function_name
586   * @returns {*|boolean}
587   */
588  obj.balancer__remove_from__wait_list = function (resource_id, function_name) {
589    var removed_el = false;
590    if (p_balancer['wait'].length) {
591      // FixIn: 9.8.10.1.
592      for (var i in p_balancer['wait']) {
593        if (resource_id === p_balancer['wait'][i]['resource_id'] && function_name === p_balancer['wait'][i]['function_name']) {
594          removed_el = p_balancer['wait'].splice(i, 1);
595          removed_el = removed_el.pop();
596          p_balancer['wait'] = p_balancer['wait'].filter(function (v) {
597            return v;
598          }); // Reindex array
599          return removed_el;
600        }
601      }
602    }
603    return removed_el;
604  };
605
606  /**
607  * Is already WAIT
608  *
609  * @param resource_id
610  * @param function_name
611  * @returns {boolean}
612  */
613  obj.balancer__is_already_wait = function (resource_id, function_name) {
614    if (p_balancer['wait'].length) {
615      // FixIn: 9.8.10.1.
616      for (var i in p_balancer['wait']) {
617        if (resource_id === p_balancer['wait'][i]['resource_id'] && function_name === p_balancer['wait'][i]['function_name']) {
618          return true;
619        }
620      }
621    }
622    return false;
623  };
624
625  /**
626   * Add to RUN
627   * @param balance_obj
628   */
629  obj.balancer__add_to__run = function (balance_obj) {
630    p_balancer['in_process'].push(balance_obj);
631  };
632
633  /**
634  * Remove from RUN list
635  *
636  * @param resource_id
637  * @param function_name
638  * @returns {*|boolean}
639  */
640  obj.balancer__remove_from__run_list = function (resource_id, function_name) {
641    var removed_el = false;
642    if (p_balancer['in_process'].length) {
643      // FixIn: 9.8.10.1.
644      for (var i in p_balancer['in_process']) {
645        if (resource_id === p_balancer['in_process'][i]['resource_id'] && function_name === p_balancer['in_process'][i]['function_name']) {
646          removed_el = p_balancer['in_process'].splice(i, 1);
647          removed_el = removed_el.pop();
648          p_balancer['in_process'] = p_balancer['in_process'].filter(function (v) {
649            return v;
650          }); // Reindex array
651          return removed_el;
652        }
653      }
654    }
655    return removed_el;
656  };
657
658  /**
659  * Is already RUN
660  *
661  * @param resource_id
662  * @param function_name
663  * @returns {boolean}
664  */
665  obj.balancer__is_already_run = function (resource_id, function_name) {
666    if (p_balancer['in_process'].length) {
667      // FixIn: 9.8.10.1.
668      for (var i in p_balancer['in_process']) {
669        if (resource_id === p_balancer['in_process'][i]['resource_id'] && function_name === p_balancer['in_process'][i]['function_name']) {
670          return true;
671        }
672      }
673    }
674    return false;
675  };
676  obj.balancer__run_next = function () {
677    // Get 1st from  Wait list
678    var removed_el = false;
679    if (p_balancer['wait'].length) {
680      // FixIn: 9.8.10.1.
681      for (var i in p_balancer['wait']) {
682        removed_el = obj.balancer__remove_from__wait_list(p_balancer['wait'][i]['resource_id'], p_balancer['wait'][i]['function_name']);
683        break;
684      }
685    }
686    if (false !== removed_el) {
687      // Run
688      obj.balancer__run(removed_el);
689    }
690  };
691
692  /**
693   * Run
694   * @param balance_obj
695   */
696  obj.balancer__run = function (balance_obj) {
697    switch (balance_obj['function_name']) {
698      case 'wpbc_calendar__load_data__ajx':
699        // Add to run list
700        obj.balancer__add_to__run(balance_obj);
701        wpbc_calendar__load_data__ajx(balance_obj['params']);
702        break;
703      default:
704    }
705  };
706  return obj;
707}(_wpbc || {}, jQuery);
708
709/**
710 * -- Help functions ----------------------------------------------------------------------------------------------
711*/
712
713function wpbc_balancer__is_wait(params, function_name) {
714  //console.log('::wpbc_balancer__is_wait',params , function_name );
715  if ('undefined' !== typeof params['resource_id']) {
716    var balancer_status = _wpbc.balancer__init(params['resource_id'], function_name, params);
717    return 'wait' === balancer_status;
718  }
719  return false;
720}
721function wpbc_balancer__completed(resource_id, function_name) {
722  //console.log('::wpbc_balancer__completed',resource_id , function_name );
723  _wpbc.balancer__remove_from__run_list(resource_id, function_name);
724  _wpbc.balancer__run_next();
725}
726/**
727 * =====================================================================================================================
728 *	includes/__js/cal/wpbc_cal.js
729 * =====================================================================================================================
730 */
731
732/**
733 * Order or child booking resources saved here:  	_wpbc.booking__get_param_value( resource_id, 'resources_id_arr__in_dates' )		[2,10,12,11]
734 */
735
736/**
737 * How to check  booked times on  specific date: ?
738 *
739			_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21');
740
741			console.log(
742						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds,
743						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_seconds,
744						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_seconds,
745						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds
746					);
747 *  OR
748			console.log(
749						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_readable,
750						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[10].booked_time_slots.merged_readable,
751						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[11].booked_time_slots.merged_readable,
752						_wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_readable
753					);
754 *
755 */
756
757/**
758 * Days selection:
759 * 					wpbc_calendar__unselect_all_dates( resource_id );
760 *
761 *					var resource_id = 1;
762 * 	Example 1:		var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, '2024-05-15', '2024-05-25' );
763 * 	Example 2:		var num_selected_days = wpbc_auto_select_dates_in_calendar( resource_id, ['2024-05-09','2024-05-19','2024-05-25'] );
764 *
765 */
766
767/**
768 * C A L E N D A R  ---------------------------------------------------------------------------------------------------
769 */
770
771/**
772 *  Show WPBC Calendar
773 *
774 * @param resource_id			- resource ID
775 * @returns {boolean}
776 */
777function wpbc_calendar_show(resource_id) {
778  // If no calendar HTML tag,  then  exit
779  if (0 === jQuery('#calendar_booking' + resource_id).length) {
780    return false;
781  }
782
783  // If the calendar with the same Booking resource is activated already, then exit.
784  if (true === jQuery('#calendar_booking' + resource_id).hasClass('hasDatepick')) {
785    return false;
786  }
787
788  // -----------------------------------------------------------------------------------------------------------------
789  // Days selection
790  // -----------------------------------------------------------------------------------------------------------------
791  var local__is_range_select = false;
792  var local__multi_days_select_num = 365; // multiple | fixed
793  if ('dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
794    local__is_range_select = true;
795    local__multi_days_select_num = 0;
796  }
797  if ('single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
798    local__multi_days_select_num = 0;
799  }
800
801  // -----------------------------------------------------------------------------------------------------------------
802  // Min - Max days to scroll/show
803  // -----------------------------------------------------------------------------------------------------------------
804  var local__min_date = 0;
805  local__min_date = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], 0, 0, 0); // FixIn: 9.9.0.17.
806  //console.log( local__min_date );
807  var local__max_date = _wpbc.calendar__get_param_value(resource_id, 'booking_max_monthes_in_calendar');
808  //local__max_date = new Date(2024, 5, 28);  It is here issue of not selectable dates, but some dates showing in calendar as available, but we can not select it.
809
810  //// Define last day in calendar (as a last day of month (and not date, which is related to actual 'Today' date).
811  //// E.g. if today is 2023-09-25, and we set 'Number of months to scroll' as 5 months, then last day will be 2024-02-29 and not the 2024-02-25.
812  // var cal_last_day_in_month = jQuery.datepick._determineDate( null, local__max_date, new Date() );
813  // cal_last_day_in_month = new Date( cal_last_day_in_month.getFullYear(), cal_last_day_in_month.getMonth() + 1, 0 );
814  // local__max_date = cal_last_day_in_month;			// FixIn: 10.0.0.26.
815
816  // Get start / end dates from  the Booking Calendar shortcode. Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31'  resource_id=1] // FixIn: 10.13.1.4.
817  if (false !== wpbc_calendar__get_dates_start(resource_id)) {
818    local__min_date = wpbc_calendar__get_dates_start(resource_id); // E.g. - local__min_date = new Date( 2025, 0, 1 );
819  }
820  if (false !== wpbc_calendar__get_dates_end(resource_id)) {
821    local__max_date = wpbc_calendar__get_dates_end(resource_id); // E.g. - local__max_date = new Date( 2025, 11, 31 );
822  }
823
824  // In case we edit booking in past or have specific parameter in URL.
825  if (location.href.indexOf('page=wpbc-new') != -1 && (location.href.indexOf('booking_hash') != -1 // Comment this line for ability to add  booking in past days at  Booking > Add booking page.
826  || location.href.indexOf('allow_past') != -1 // FixIn: 10.7.1.2.
827  )) {
828    // local__min_date = null;
829    // FixIn: 10.14.1.4.
830    local__min_date = new Date(_wpbc.get_other_param('time_local_arr')[0], parseInt(_wpbc.get_other_param('time_local_arr')[1]) - 1, _wpbc.get_other_param('time_local_arr')[2], _wpbc.get_other_param('time_local_arr')[3], _wpbc.get_other_param('time_local_arr')[4], 0);
831    local__max_date = null;
832  }
833  var local__start_weekday = _wpbc.calendar__get_param_value(resource_id, 'booking_start_day_weeek');
834  var local__number_of_months = parseInt(_wpbc.calendar__get_param_value(resource_id, 'calendar_number_of_months'));
835  jQuery('#calendar_booking' + resource_id).text(''); // Remove all HTML in calendar tag
836  // -----------------------------------------------------------------------------------------------------------------
837  // Show calendar
838  // -----------------------------------------------------------------------------------------------------------------
839  jQuery('#calendar_booking' + resource_id).datepick({
840    beforeShowDay: function beforeShowDay(js_date) {
841      return wpbc__calendar__apply_css_to_days(js_date, {
842        'resource_id': resource_id
843      }, this);
844    },
845    onSelect: function onSelect(string_dates, js_dates_arr) {
846      /**
847      *	string_dates   =   '23.08.2023 - 26.08.2023'    |    '23.08.2023 - 23.08.2023'    |    '19.09.2023, 24.08.2023, 30.09.2023'
848      *  js_dates_arr   =   range: [ Date (Aug 23 2023), Date (Aug 25 2023)]     |     multiple: [ Date(Oct 24 2023), Date(Oct 20 2023), Date(Oct 16 2023) ]
849      */
850      return wpbc__calendar__on_select_days(string_dates, {
851        'resource_id': resource_id
852      }, this);
853    },
854    onHover: function onHover(string_date, js_date) {
855      return wpbc__calendar__on_hover_days(string_date, js_date, {
856        'resource_id': resource_id
857      }, this);
858    },
859    onChangeMonthYear: function onChangeMonthYear(year, real_month, js_date__1st_day_in_month) {},
860    showOn: 'both',
861    numberOfMonths: local__number_of_months,
862    stepMonths: 1,
863    // prevText      : '&laquo;',
864    // nextText      : '&raquo;',
865    prevText: '&lsaquo;',
866    nextText: '&rsaquo;',
867    dateFormat: 'dd.mm.yy',
868    changeMonth: false,
869    changeYear: false,
870    minDate: local__min_date,
871    maxDate: local__max_date,
872    // '1Y',
873    // minDate: new Date(2020, 2, 1), maxDate: new Date(2020, 9, 31),             	// Ability to set any  start and end date in calendar
874    showStatus: false,
875    multiSeparator: ', ',
876    closeAtTop: false,
877    firstDay: local__start_weekday,
878    gotoCurrent: false,
879    hideIfNoPrevNext: true,
880    multiSelect: local__multi_days_select_num,
881    rangeSelect: local__is_range_select,
882    // showWeeks: true,
883    useThemeRoller: false
884  });
885
886  // -----------------------------------------------------------------------------------------------------------------
887  // Clear today date highlighting
888  // -----------------------------------------------------------------------------------------------------------------
889  setTimeout(function () {
890    wpbc_calendars__clear_days_highlighting(resource_id);
891  }, 500); // FixIn: 7.1.2.8.
892
893  // -----------------------------------------------------------------------------------------------------------------
894  // Scroll calendar to  specific month
895  // -----------------------------------------------------------------------------------------------------------------
896  var start_bk_month = _wpbc.calendar__get_param_value(resource_id, 'calendar_scroll_to');
897  if (false !== start_bk_month) {
898    wpbc_calendar__scroll_to(resource_id, start_bk_month[0], start_bk_month[1]);
899  }
900}
901
902/**
903 * Apply CSS to calendar date cells
904 *
905 * @param date										-  JavaScript Date Obj:  		Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time)
906 * @param calendar_params_arr						-  Calendar Settings Object:  	{
907 *																  						"resource_id": 4
908 *																					}
909 * @param datepick_this								- this of datepick Obj
910 * @returns {(*|string)[]|(boolean|string)[]}		- [ {true -available | false - unavailable}, 'CSS classes for calendar day cell' ]
911 */
912function wpbc__calendar__apply_css_to_days(date, calendar_params_arr, datepick_this) {
913  var today_date = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], 0, 0, 0); // Today JS_Date_Obj.
914  var class_day = wpbc__get__td_class_date(date); // '1-9-2023'
915  var sql_class_day = wpbc__get__sql_class_date(date); // '2023-01-09'
916  var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1'
917
918  // Get Selected dates in calendar
919  var selected_dates_sql = wpbc_get__selected_dates_sql__as_arr(resource_id);
920
921  // Get Data --------------------------------------------------------------------------------------------------------
922  var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day);
923
924  // Array with CSS classes for date ---------------------------------------------------------------------------------
925  var css_classes__for_date = [];
926  css_classes__for_date.push('sql_date_' + sql_class_day); //  'sql_date_2023-07-21'
927  css_classes__for_date.push('cal4date-' + class_day); //  'cal4date-7-21-2023'
928  css_classes__for_date.push('wpbc_weekday_' + date.getDay()); //  'wpbc_weekday_4'
929
930  // Define Selected Check In/Out dates in TD  -----------------------------------------------------------------------
931  if (selected_dates_sql.length
932  //&&  ( selected_dates_sql[ 0 ] !== selected_dates_sql[ (selected_dates_sql.length - 1) ] )
933  ) {
934    if (sql_class_day === selected_dates_sql[0]) {
935      css_classes__for_date.push('selected_check_in');
936      css_classes__for_date.push('selected_check_in_out');
937    }
938    if (selected_dates_sql.length > 1 && sql_class_day === selected_dates_sql[selected_dates_sql.length - 1]) {
939      css_classes__for_date.push('selected_check_out');
940      css_classes__for_date.push('selected_check_in_out');
941    }
942  }
943  var is_day_selectable = false;
944
945  // If something not defined,  then  this date closed --------------------------------------------------------------- // FixIn: 10.12.4.6.
946  if (false === date_bookings_obj || 'undefined' === typeof date_bookings_obj[resource_id]) {
947    css_classes__for_date.push('date_user_unavailable');
948    return [is_day_selectable, css_classes__for_date.join(' ')];
949  }
950
951  // -----------------------------------------------------------------------------------------------------------------
952  //   date_bookings_obj  - Defined.            Dates can be selectable.
953  // -----------------------------------------------------------------------------------------------------------------
954
955  // -----------------------------------------------------------------------------------------------------------------
956  // Add season names to the day CSS classes -- it is required for correct  work  of conditional fields --------------
957  var season_names_arr = _wpbc.seasons__get_for_date(resource_id, sql_class_day);
958  for (var season_key in season_names_arr) {
959    css_classes__for_date.push(season_names_arr[season_key]); //  'wpdevbk_season_september_2023'
960  }
961  // -----------------------------------------------------------------------------------------------------------------
962
963  // Cost Rate -------------------------------------------------------------------------------------------------------
964  css_classes__for_date.push('rate_' + date_bookings_obj[resource_id]['date_cost_rate'].toString().replace(/[\.\s]/g, '_')); //  'rate_99_00' -> 99.00
965
966  if (parseInt(date_bookings_obj['day_availability']) > 0) {
967    is_day_selectable = true;
968    css_classes__for_date.push('date_available');
969    css_classes__for_date.push('reserved_days_count' + parseInt(date_bookings_obj['max_capacity'] - date_bookings_obj['day_availability']));
970  } else {
971    is_day_selectable = false;
972    css_classes__for_date.push('date_user_unavailable');
973  }
974  switch (date_bookings_obj['summary']['status_for_day']) {
975    case 'available':
976      break;
977    case 'time_slots_booking':
978      css_classes__for_date.push('timespartly', 'times_clock');
979      break;
980    case 'full_day_booking':
981      css_classes__for_date.push('full_day_booking');
982      break;
983    case 'season_filter':
984      css_classes__for_date.push('date_user_unavailable', 'season_unavailable');
985      date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date
986      break;
987    case 'resource_availability':
988      css_classes__for_date.push('date_user_unavailable', 'resource_unavailable');
989      date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date
990      break;
991    case 'weekday_unavailable':
992      css_classes__for_date.push('date_user_unavailable', 'weekday_unavailable');
993      date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date
994      break;
995    case 'from_today_unavailable':
996      css_classes__for_date.push('date_user_unavailable', 'from_today_unavailable');
997      date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date
998      break;
999    case 'limit_available_from_today':
1000      css_classes__for_date.push('date_user_unavailable', 'limit_available_from_today');
1001      date_bookings_obj['summary']['status_for_bookings'] = ''; // Reset booking status color for possible old bookings on this date
1002      break;
1003    case 'change_over':
1004      /*
1005       *
1006      //  check_out_time_date2approve 	 	check_in_time_date2approve
1007      //  check_out_time_date2approve 	 	check_in_time_date_approved
1008      //  check_in_time_date2approve 		 	check_out_time_date_approved
1009      //  check_out_time_date_approved 	 	check_in_time_date_approved
1010       */
1011
1012      css_classes__for_date.push('timespartly', 'check_in_time', 'check_out_time');
1013      // FixIn: 10.0.0.2.
1014      if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved_pending') > -1) {
1015        css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date2approve');
1016      }
1017      if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending_approved') > -1) {
1018        css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date_approved');
1019      }
1020      break;
1021    case 'check_in':
1022      css_classes__for_date.push('timespartly', 'check_in_time');
1023
1024      // FixIn: 9.9.0.33.
1025      if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending') > -1) {
1026        css_classes__for_date.push('check_in_time_date2approve');
1027      } else if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved') > -1) {
1028        css_classes__for_date.push('check_in_time_date_approved');
1029      }
1030      break;
1031    case 'check_out':
1032      css_classes__for_date.push('timespartly', 'check_out_time');
1033
1034      // FixIn: 9.9.0.33.
1035      if (date_bookings_obj['summary']['status_for_bookings'].indexOf('pending') > -1) {
1036        css_classes__for_date.push('check_out_time_date2approve');
1037      } else if (date_bookings_obj['summary']['status_for_bookings'].indexOf('approved') > -1) {
1038        css_classes__for_date.push('check_out_time_date_approved');
1039      }
1040      break;
1041    default:
1042      // mixed statuses: 'change_over check_out' .... variations.... check more in 		function wpbc_get_availability_per_days_arr()
1043      date_bookings_obj['summary']['status_for_day'] = 'available';
1044  }
1045  if ('available' != date_bookings_obj['summary']['status_for_day']) {
1046    var is_set_pending_days_selectable = _wpbc.calendar__get_param_value(resource_id, 'pending_days_selectable'); // set pending days selectable          // FixIn: 8.6.1.18.
1047
1048    switch (date_bookings_obj['summary']['status_for_bookings']) {
1049      case '':
1050        // Usually  it's means that day  is available or unavailable without the bookings
1051        break;
1052      case 'pending':
1053        css_classes__for_date.push('date2approve');
1054        is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable;
1055        break;
1056      case 'approved':
1057        css_classes__for_date.push('date_approved');
1058        break;
1059
1060      // Situations for "change-over" days: ----------------------------------------------------------------------
1061      case 'pending_pending':
1062        css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date2approve');
1063        is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable;
1064        break;
1065      case 'pending_approved':
1066        css_classes__for_date.push('check_out_time_date2approve', 'check_in_time_date_approved');
1067        is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable;
1068        break;
1069      case 'approved_pending':
1070        css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date2approve');
1071        is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable;
1072        break;
1073      case 'approved_approved':
1074        css_classes__for_date.push('check_out_time_date_approved', 'check_in_time_date_approved');
1075        break;
1076      default:
1077    }
1078  }
1079  return [is_day_selectable, css_classes__for_date.join(' ')];
1080}
1081
1082/**
1083 * Mouseover calendar date cells
1084 *
1085 * @param string_date
1086 * @param date										-  JavaScript Date Obj:  		Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time)
1087 * @param calendar_params_arr						-  Calendar Settings Object:  	{
1088 *																  						"resource_id": 4
1089 *																					}
1090 * @param datepick_this								- this of datepick Obj
1091 * @returns {boolean}
1092 */
1093function wpbc__calendar__on_hover_days(string_date, date, calendar_params_arr, datepick_this) {
1094  if (null === date) {
1095    wpbc_calendars__clear_days_highlighting('undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'); // FixIn: 10.5.2.4.
1096    return false;
1097  }
1098  var class_day = wpbc__get__td_class_date(date); // '1-9-2023'
1099  var sql_class_day = wpbc__get__sql_class_date(date); // '2023-01-09'
1100  var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1'
1101
1102  // Get Data --------------------------------------------------------------------------------------------------------
1103  var date_booking_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day); // {...}
1104
1105  if (!date_booking_obj) {
1106    return false;
1107  }
1108
1109  // T o o l t i p s -------------------------------------------------------------------------------------------------
1110  var tooltip_text = '';
1111  if (date_booking_obj['summary']['tooltip_availability'].length > 0) {
1112    tooltip_text += date_booking_obj['summary']['tooltip_availability'];
1113  }
1114  if (date_booking_obj['summary']['tooltip_day_cost'].length > 0) {
1115    tooltip_text += date_booking_obj['summary']['tooltip_day_cost'];
1116  }
1117  if (date_booking_obj['summary']['tooltip_times'].length > 0) {
1118    tooltip_text += date_booking_obj['summary']['tooltip_times'];
1119  }
1120  if (date_booking_obj['summary']['tooltip_booking_details'].length > 0) {
1121    tooltip_text += date_booking_obj['summary']['tooltip_booking_details'];
1122  }
1123  wpbc_set_tooltip___for__calendar_date(tooltip_text, resource_id, class_day);
1124
1125  //  U n h o v e r i n g    in    UNSELECTABLE_CALENDAR  ------------------------------------------------------------
1126  var is_unselectable_calendar = jQuery('#calendar_booking_unselectable' + resource_id).length > 0; // FixIn: 8.0.1.2.
1127  var is_booking_form_exist = jQuery('#booking_form_div' + resource_id).length > 0;
1128  if (is_unselectable_calendar && !is_booking_form_exist) {
1129    /**
1130     *  Un Hover all dates in calendar (without the booking form), if only Availability Calendar here and we do not insert Booking form by mistake.
1131     */
1132
1133    wpbc_calendars__clear_days_highlighting(resource_id); // Clear days highlighting
1134
1135    var css_of_calendar = '.wpbc_only_calendar #calendar_booking' + resource_id;
1136    jQuery(css_of_calendar + ' .datepick-days-cell, ' + css_of_calendar + ' .datepick-days-cell a').css('cursor', 'default'); // Set cursor to Default
1137    return false;
1138  }
1139
1140  //  D a y s    H o v e r i n g  ------------------------------------------------------------------------------------
1141  if (location.href.indexOf('page=wpbc') == -1 || location.href.indexOf('page=wpbc-new') > 0 || location.href.indexOf('page=wpbc-setup') > 0 || location.href.indexOf('page=wpbc-availability') > 0 || location.href.indexOf('page=wpbc-settings') > 0 && location.href.indexOf('&tab=form') > 0) {
1142    // The same as dates selection,  but for days hovering
1143
1144    if ('function' == typeof wpbc__calendar__do_days_highlight__bs) {
1145      wpbc__calendar__do_days_highlight__bs(sql_class_day, date, resource_id);
1146    }
1147  }
1148}
1149
1150/**
1151 * Select calendar date cells
1152 *
1153 * @param date										-  JavaScript Date Obj:  		Mon Dec 11 2023 00:00:00 GMT+0200 (Eastern European Standard Time)
1154 * @param calendar_params_arr						-  Calendar Settings Object:  	{
1155 *																  						"resource_id": 4
1156 *																					}
1157 * @param datepick_this								- this of datepick Obj
1158 *
1159 */
1160function wpbc__calendar__on_select_days(date, calendar_params_arr, datepick_this) {
1161  var resource_id = 'undefined' !== typeof calendar_params_arr['resource_id'] ? calendar_params_arr['resource_id'] : '1'; // '1'
1162
1163  // Set unselectable,  if only Availability Calendar  here (and we do not insert Booking form by mistake).
1164  var is_unselectable_calendar = jQuery('#calendar_booking_unselectable' + resource_id).length > 0; // FixIn: 8.0.1.2.
1165  var is_booking_form_exist = jQuery('#booking_form_div' + resource_id).length > 0;
1166  if (is_unselectable_calendar && !is_booking_form_exist) {
1167    wpbc_calendar__unselect_all_dates(resource_id); // Unselect Dates
1168    jQuery('.wpbc_only_calendar .popover_calendar_hover').remove(); // Hide all opened popovers
1169    return false;
1170  }
1171  jQuery('#date_booking' + resource_id).val(date); // Add selected dates to  hidden textarea
1172
1173  if ('function' === typeof wpbc__calendar__do_days_select__bs) {
1174    wpbc__calendar__do_days_select__bs(date, resource_id);
1175  }
1176  wpbc_disable_time_fields_in_booking_form(resource_id);
1177
1178  // Hook -- trigger day selection -----------------------------------------------------------------------------------
1179  var mouse_clicked_dates = date; // Can be: "05.10.2023 - 07.10.2023"  |  "10.10.2023 - 10.10.2023"  |
1180  var all_selected_dates_arr = wpbc_get__selected_dates_sql__as_arr(resource_id); // Can be: [ "2023-10-05", "2023-10-06", "2023-10-07", … ]
1181  jQuery(".booking_form_div").trigger("date_selected", [resource_id, mouse_clicked_dates, all_selected_dates_arr]);
1182}
1183
1184// Mark middle selected dates with 0.5 opacity		// FixIn: 10.3.0.9.
1185jQuery(document).ready(function () {
1186  jQuery(".booking_form_div").on('date_selected', function (event, resource_id, date) {
1187    if ('fixed' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode') || 'dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
1188      var closed_timer = setTimeout(function () {
1189        var middle_days_opacity = _wpbc.get_other_param('calendars__days_selection__middle_days_opacity');
1190        jQuery('#calendar_booking' + resource_id + ' .datepick-current-day').not(".selected_check_in_out").css('opacity', middle_days_opacity);
1191      }, 10);
1192    }
1193  });
1194});
1195
1196/**
1197 * --  T i m e    F i e l d s     start  --------------------------------------------------------------------------
1198 */
1199
1200/**
1201 * Disable time slots in booking form depend on selected dates and booked dates/times
1202 *
1203 * @param resource_id
1204 */
1205function wpbc_disable_time_fields_in_booking_form(resource_id) {
1206  /**
1207   * 	1. Get all time fields in the booking form as array  of objects
1208   * 					[
1209   * 					 	   {	jquery_option:      jQuery_Object {}
1210   * 								name:               'rangetime2[]'
1211   * 								times_as_seconds:   [ 21600, 23400 ]
1212   * 								value_option_24h:   '06:00 - 06:30'
1213   * 					     }
1214   * 					  ...
1215   * 						   {	jquery_option:      jQuery_Object {}
1216   * 								name:               'starttime2[]'
1217   * 								times_as_seconds:   [ 21600 ]
1218   * 								value_option_24h:   '06:00'
1219   *  					    }
1220   * 					 ]
1221   */
1222  var time_fields_obj_arr = wpbc_get__time_fields__in_booking_form__as_arr(resource_id);
1223
1224  // 2. Get all selected dates in  SQL format  like this [ "2023-08-23", "2023-08-24", "2023-08-25", ... ]
1225  var selected_dates_arr = wpbc_get__selected_dates_sql__as_arr(resource_id);
1226
1227  // 3. Get child booking resources  or single booking resource  that  exist  in dates
1228  var child_resources_arr = wpbc_clone_obj(_wpbc.booking__get_param_value(resource_id, 'resources_id_arr__in_dates'));
1229  var sql_date;
1230  var child_resource_id;
1231  var merged_seconds;
1232  var time_fields_obj;
1233  var is_intersect;
1234  var is_check_in;
1235  var today_time__real = new Date(_wpbc.get_other_param('time_local_arr')[0], parseInt(_wpbc.get_other_param('time_local_arr')[1]) - 1, _wpbc.get_other_param('time_local_arr')[2], _wpbc.get_other_param('time_local_arr')[3], _wpbc.get_other_param('time_local_arr')[4], 0);
1236  var today_time__shift = new Date(_wpbc.get_other_param('today_arr')[0], parseInt(_wpbc.get_other_param('today_arr')[1]) - 1, _wpbc.get_other_param('today_arr')[2], _wpbc.get_other_param('today_arr')[3], _wpbc.get_other_param('today_arr')[4], 0);
1237
1238  // 4. Loop  all  time Fields options		// FixIn: 10.3.0.2.
1239  for (var field_key = 0; field_key < time_fields_obj_arr.length; field_key++) {
1240    time_fields_obj_arr[field_key].disabled = 0; // By default, this time field is not disabled.
1241
1242    time_fields_obj = time_fields_obj_arr[field_key]; // { times_as_seconds: [ 21600, 23400 ], value_option_24h: '06:00 - 06:30', name: 'rangetime2[]', jquery_option: jQuery_Object {}}
1243
1244    // Loop  all  selected dates.
1245    for (var i = 0; i < selected_dates_arr.length; i++) {
1246      // Get Date: '2023-08-18'.
1247      sql_date = selected_dates_arr[i];
1248      var is_time_in_past = wpbc_check_is_time_in_past(today_time__shift, sql_date, time_fields_obj);
1249      // Exception  for 'End Time' field,  when  selected several dates. // FixIn: 10.14.1.5.
1250      if ('On' !== _wpbc.calendar__get_param_value(resource_id, 'booking_recurrent_time') && -1 !== time_fields_obj.name.indexOf('endtime') && selected_dates_arr.length > 1) {
1251        is_time_in_past = wpbc_check_is_time_in_past(today_time__shift, selected_dates_arr[selected_dates_arr.length - 1], time_fields_obj);
1252      }
1253      if (is_time_in_past) {
1254        // This time for selected date already  in the past.
1255        time_fields_obj_arr[field_key].disabled = 1;
1256        break; // exist  from   Dates LOOP.
1257      }
1258      // FixIn: 9.9.0.31.
1259      if ('Off' === _wpbc.calendar__get_param_value(resource_id, 'booking_recurrent_time') && selected_dates_arr.length > 1) {
1260        //TODO: skip some fields checking if it's start / end time for mulple dates  selection  mode.
1261        //TODO: we need to fix situation  for entimes,  when  user  select  several  dates,  and in start  time booked 00:00 - 15:00 , but systsme block untill 15:00 the end time as well,  which  is wrong,  because it 2 or 3 dates selection  and end date can be fullu  available
1262
1263        if (0 == i && time_fields_obj['name'].indexOf('endtime') >= 0) {
1264          break;
1265        }
1266        if (selected_dates_arr.length - 1 == i && time_fields_obj['name'].indexOf('starttime') >= 0) {
1267          break;
1268        }
1269      }
1270      var how_many_resources_intersected = 0;
1271      // Loop all resources ID
1272      // for ( var res_key in child_resources_arr ){	 						// FixIn: 10.3.0.2.
1273      for (var res_key = 0; res_key < child_resources_arr.length; res_key++) {
1274        child_resource_id = child_resources_arr[res_key];
1275
1276        // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[12].booked_time_slots.merged_seconds		= [ "07:00:11 - 07:30:02", "10:00:11 - 00:00:00" ]
1277        // _wpbc.bookings_in_calendar__get_for_date(2,'2023-08-21')[2].booked_time_slots.merged_seconds			= [  [ 25211, 27002 ], [ 36011, 86400 ]  ]
1278
1279        if (false !== _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_date)) {
1280          merged_seconds = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_date)[child_resource_id].booked_time_slots.merged_seconds; // [  [ 25211, 27002 ], [ 36011, 86400 ]  ]
1281        } else {
1282          merged_seconds = [];
1283        }
1284        if (time_fields_obj.times_as_seconds.length > 1) {
1285          is_intersect = wpbc_is_intersect__range_time_interval([[parseInt(time_fields_obj.times_as_seconds[0]) + 20, parseInt(time_fields_obj.times_as_seconds[1]) - 20]], merged_seconds);
1286        } else {
1287          is_check_in = -1 !== time_fields_obj.name.indexOf('start');
1288          is_intersect = wpbc_is_intersect__one_time_interval(is_check_in ? parseInt(time_fields_obj.times_as_seconds) + 20 : parseInt(time_fields_obj.times_as_seconds) - 20, merged_seconds);
1289        }
1290        if (is_intersect) {
1291          how_many_resources_intersected++; // Increase
1292        }
1293      }
1294      if (child_resources_arr.length == how_many_resources_intersected) {
1295        // All resources intersected,  then  it's means that this time-slot or time must  be  Disabled, and we can  exist  from   selected_dates_arr LOOP
1296
1297        time_fields_obj_arr[field_key].disabled = 1;
1298        break; // exist  from   Dates LOOP
1299      }
1300    }
1301  }
1302
1303  // 5. Now we can disable time slot in HTML by  using  ( field.disabled == 1 ) property
1304  wpbc__html__time_field_options__set_disabled(time_fields_obj_arr);
1305  jQuery(".booking_form_div").trigger('wpbc_hook_timeslots_disabled', [resource_id, selected_dates_arr]); // Trigger hook on disabling timeslots.		Usage: 	jQuery( ".booking_form_div" ).on( 'wpbc_hook_timeslots_disabled', function ( event, bk_type, all_dates ){ ... } );		// FixIn: 8.7.11.9.
1306}
1307
1308/**
1309 * Check if specific time(-slot) already  in the past for selected date
1310 *
1311 * @param js_current_time_to_check		- JS Date
1312 * @param sql_date						- '2025-01-26'
1313 * @param time_fields_obj				- Object
1314 * @returns {boolean}
1315 */
1316function wpbc_check_is_time_in_past(js_current_time_to_check, sql_date, time_fields_obj) {
1317  // FixIn: 10.9.6.4
1318  var sql_date_arr = sql_date.split('-');
1319  var sql_date__midnight = new Date(parseInt(sql_date_arr[0]), parseInt(sql_date_arr[1]) - 1, parseInt(sql_date_arr[2]), 0, 0, 0);
1320  var sql_date__midnight_miliseconds = sql_date__midnight.getTime();
1321  var is_intersect = false;
1322  if (time_fields_obj.times_as_seconds.length > 1) {
1323    if (js_current_time_to_check.getTime() > sql_date__midnight_miliseconds + (parseInt(time_fields_obj.times_as_seconds[0]) + 20) * 1000) {
1324      is_intersect = true;
1325    }
1326    if (js_current_time_to_check.getTime() > sql_date__midnight_miliseconds + (parseInt(time_fields_obj.times_as_seconds[1]) - 20) * 1000) {
1327      is_intersect = true;
1328    }
1329  } else {
1330    var is_check_in = -1 !== time_fields_obj.name.indexOf('start');
1331    var times_as_seconds_check = is_check_in ? parseInt(time_fields_obj.times_as_seconds) + 20 : parseInt(time_fields_obj.times_as_seconds) - 20;
1332    times_as_seconds_check = sql_date__midnight_miliseconds + times_as_seconds_check * 1000;
1333    if (js_current_time_to_check.getTime() > times_as_seconds_check) {
1334      is_intersect = true;
1335    }
1336  }
1337  return is_intersect;
1338}
1339
1340/**
1341 * Is number inside /intersect  of array of intervals ?
1342 *
1343 * @param time_A		     	- 25800
1344 * @param time_interval_B		- [  [ 25211, 27002 ], [ 36011, 86400 ]  ]
1345 * @returns {boolean}
1346 */
1347function wpbc_is_intersect__one_time_interval(time_A, time_interval_B) {
1348  for (var j = 0; j < time_interval_B.length; j++) {
1349    if (parseInt(time_A) > parseInt(time_interval_B[j][0]) && parseInt(time_A) < parseInt(time_interval_B[j][1])) {
1350      return true;
1351    }
1352
1353    // if ( ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 0 ] ) ) || ( parseInt( time_A ) == parseInt( time_interval_B[ j ][ 1 ] ) ) ) {
1354    // 			// Time A just  at  the border of interval
1355    // }
1356  }
1357  return false;
1358}
1359
1360/**
1361 * Is these array of intervals intersected ?
1362 *
1363 * @param time_interval_A		- [ [ 21600, 23400 ] ]
1364 * @param time_interval_B		- [  [ 25211, 27002 ], [ 36011, 86400 ]  ]
1365 * @returns {boolean}
1366 */
1367function wpbc_is_intersect__range_time_interval(time_interval_A, time_interval_B) {
1368  var is_intersect;
1369  for (var i = 0; i < time_interval_A.length; i++) {
1370    for (var j = 0; j < time_interval_B.length; j++) {
1371      is_intersect = wpbc_intervals__is_intersected(time_interval_A[i], time_interval_B[j]);
1372      if (is_intersect) {
1373        return true;
1374      }
1375    }
1376  }
1377  return false;
1378}
1379
1380/**
1381 * Get all time fields in the booking form as array  of objects
1382 *
1383 * @param resource_id
1384 * @returns []
1385 *
1386 * 		Example:
1387 * 					[
1388 * 					 	   {
1389 * 								value_option_24h:   '06:00 - 06:30'
1390 * 								times_as_seconds:   [ 21600, 23400 ]
1391 * 					 	   		jquery_option:      jQuery_Object {}
1392 * 								name:               'rangetime2[]'
1393 * 					     }
1394 * 					  ...
1395 * 						   {
1396 * 								value_option_24h:   '06:00'
1397 * 								times_as_seconds:   [ 21600 ]
1398 * 						   		jquery_option:      jQuery_Object {}
1399 * 								name:               'starttime2[]'
1400 *  					    }
1401 * 					 ]
1402 */
1403function wpbc_get__time_fields__in_booking_form__as_arr(resource_id) {
1404  /**
1405  * Fields with  []  like this   select[name="rangetime1[]"]
1406  * it's when we have 'multiple' in shortcode:   [select* rangetime multiple  "06:00 - 06:30" ... ]
1407  */
1408  var time_fields_arr = ['select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]'];
1409  var time_fields_obj_arr = [];
1410
1411  // Loop all Time Fields
1412  for (var ctf = 0; ctf < time_fields_arr.length; ctf++) {
1413    var time_field = time_fields_arr[ctf];
1414    var time_option = jQuery(time_field + ' option');
1415
1416    // Loop all options in time field
1417    for (var j = 0; j < time_option.length; j++) {
1418      var jquery_option = jQuery(time_field + ' option:eq(' + j + ')');
1419      var value_option_seconds_arr = jquery_option.val().split('-');
1420      var times_as_seconds = [];
1421
1422      // Get time as seconds
1423      if (value_option_seconds_arr.length) {
1424        // FixIn: 9.8.10.1.
1425        for (var i = 0; i < value_option_seconds_arr.length; i++) {
1426          // FixIn: 10.0.0.56.
1427          // value_option_seconds_arr[i] = '14:00 '  | ' 16:00'   (if from 'rangetime') and '16:00'  if (start/end time)
1428
1429          var start_end_times_arr = value_option_seconds_arr[i].trim().split(':');
1430          var time_in_seconds = parseInt(start_end_times_arr[0]) * 60 * 60 + parseInt(start_end_times_arr[1]) * 60;
1431          times_as_seconds.push(time_in_seconds);
1432        }
1433      }
1434      time_fields_obj_arr.push({
1435        'name': jQuery(time_field).attr('name'),
1436        'value_option_24h': jquery_option.val(),
1437        'jquery_option': jquery_option,
1438        'times_as_seconds': times_as_seconds
1439      });
1440    }
1441  }
1442  return time_fields_obj_arr;
1443}
1444
1445/**
1446 * Disable HTML options and add booked CSS class
1447 *
1448 * @param time_fields_obj_arr      - this value is from  the func:  	wpbc_get__time_fields__in_booking_form__as_arr( resource_id )
1449 * 					[
1450 * 					 	   {	jquery_option:      jQuery_Object {}
1451 * 								name:               'rangetime2[]'
1452 * 								times_as_seconds:   [ 21600, 23400 ]
1453 * 								value_option_24h:   '06:00 - 06:30'
1454 * 	  						    disabled = 1
1455 * 					     }
1456 * 					  ...
1457 * 						   {	jquery_option:      jQuery_Object {}
1458 * 								name:               'starttime2[]'
1459 * 								times_as_seconds:   [ 21600 ]
1460 * 								value_option_24h:   '06:00'
1461 *   							disabled = 0
1462 *  					    }
1463 * 					 ]
1464 *
1465 */
1466function wpbc__html__time_field_options__set_disabled(time_fields_obj_arr) {
1467  var jquery_option;
1468  for (var i = 0; i < time_fields_obj_arr.length; i++) {
1469    var jquery_option = time_fields_obj_arr[i].jquery_option;
1470    if (1 == time_fields_obj_arr[i].disabled) {
1471      jquery_option.prop('disabled', true); // Make disable some options
1472      jquery_option.addClass('booked'); // Add "booked" CSS class
1473
1474      // if this booked element selected --> then deselect  it
1475      if (jquery_option.prop('selected')) {
1476        jquery_option.prop('selected', false);
1477        jquery_option.parent().find('option:not([disabled]):first').prop('selected', true).trigger("change");
1478      }
1479    } else {
1480      jquery_option.prop('disabled', false); // Make active all times
1481      jquery_option.removeClass('booked'); // Remove class "booked"
1482    }
1483  }
1484}
1485
1486/**
1487 * Check if this time_range | Time_Slot is Full Day  booked
1488 *
1489 * @param timeslot_arr_in_seconds		- [ 36011, 86400 ]
1490 * @returns {boolean}
1491 */
1492function wpbc_is_this_timeslot__full_day_booked(timeslot_arr_in_seconds) {
1493  if (timeslot_arr_in_seconds.length > 1 && parseInt(timeslot_arr_in_seconds[0]) < 30 && parseInt(timeslot_arr_in_seconds[1]) > 24 * 60 * 60 - 30) {
1494    return true;
1495  }
1496  return false;
1497}
1498
1499// -----------------------------------------------------------------------------------------------------------------
1500/*  ==  S e l e c t e d    D a t e s  /  T i m e - F i e l d s  ==
1501// ----------------------------------------------------------------------------------------------------------------- */
1502
1503/**
1504 *  Get all selected dates in SQL format like this [ "2023-08-23", "2023-08-24" , ... ]
1505 *
1506 * @param resource_id
1507 * @returns {[]}			[ "2023-08-23", "2023-08-24", "2023-08-25", "2023-08-26", "2023-08-27", "2023-08-28", "2023-08-29" ]
1508 */
1509function wpbc_get__selected_dates_sql__as_arr(resource_id) {
1510  var selected_dates_arr = [];
1511  selected_dates_arr = jQuery('#date_booking' + resource_id).val().split(',');
1512  if (selected_dates_arr.length) {
1513    // FixIn: 9.8.10.1.
1514    for (var i = 0; i < selected_dates_arr.length; i++) {
1515      // FixIn: 10.0.0.56.
1516      selected_dates_arr[i] = selected_dates_arr[i].trim();
1517      selected_dates_arr[i] = selected_dates_arr[i].split('.');
1518      if (selected_dates_arr[i].length > 1) {
1519        selected_dates_arr[i] = selected_dates_arr[i][2] + '-' + selected_dates_arr[i][1] + '-' + selected_dates_arr[i][0];
1520      }
1521    }
1522  }
1523
1524  // Remove empty elements from an array
1525  selected_dates_arr = selected_dates_arr.filter(function (n) {
1526    return parseInt(n);
1527  });
1528  selected_dates_arr.sort();
1529  return selected_dates_arr;
1530}
1531
1532/**
1533 * Get all time fields in the booking form as array  of objects
1534 *
1535 * @param resource_id
1536 * @param is_only_selected_time
1537 * @returns []
1538 *
1539 * 		Example:
1540 * 					[
1541 * 					 	   {
1542 * 								value_option_24h:   '06:00 - 06:30'
1543 * 								times_as_seconds:   [ 21600, 23400 ]
1544 * 					 	   		jquery_option:      jQuery_Object {}
1545 * 								name:               'rangetime2[]'
1546 * 					     }
1547 * 					  ...
1548 * 						   {
1549 * 								value_option_24h:   '06:00'
1550 * 								times_as_seconds:   [ 21600 ]
1551 * 						   		jquery_option:      jQuery_Object {}
1552 * 								name:               'starttime2[]'
1553 *  					    }
1554 * 					 ]
1555 */
1556function wpbc_get__selected_time_fields__in_booking_form__as_arr(resource_id) {
1557  var is_only_selected_time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
1558  /**
1559   * Fields with  []  like this   select[name="rangetime1[]"]
1560   * it's when we have 'multiple' in shortcode:   [select* rangetime multiple  "06:00 - 06:30" ... ]
1561   */
1562  var time_fields_arr = ['select[name="rangetime' + resource_id + '"]', 'select[name="rangetime' + resource_id + '[]"]', 'select[name="starttime' + resource_id + '"]', 'select[name="starttime' + resource_id + '[]"]', 'select[name="endtime' + resource_id + '"]', 'select[name="endtime' + resource_id + '[]"]', 'select[name="durationtime' + resource_id + '"]', 'select[name="durationtime' + resource_id + '[]"]'];
1563  var time_fields_obj_arr = [];
1564
1565  // Loop all Time Fields
1566  for (var ctf = 0; ctf < time_fields_arr.length; ctf++) {
1567    var time_field = time_fields_arr[ctf];
1568    var time_option;
1569    if (is_only_selected_time) {
1570      time_option = jQuery('#booking_form' + resource_id + ' ' + time_field + ' option:selected'); // Exclude conditional  fields,  because of using '#booking_form3 ...'
1571    } else {
1572      time_option = jQuery('#booking_form' + resource_id + ' ' + time_field + ' option'); // All  time fields
1573    }
1574
1575    // Loop all options in time field
1576    for (var j = 0; j < time_option.length; j++) {
1577      var jquery_option = jQuery(time_option[j]); // Get only  selected options 	//jQuery( time_field + ' option:eq(' + j + ')' );
1578      var value_option_seconds_arr = jquery_option.val().split('-');
1579      var times_as_seconds = [];
1580
1581      // Get time as seconds
1582      if (value_option_seconds_arr.length) {
1583        // FixIn: 9.8.10.1.
1584        for (var i = 0; i < value_option_seconds_arr.length; i++) {
1585          // FixIn: 10.0.0.56.
1586          // value_option_seconds_arr[i] = '14:00 '  | ' 16:00'   (if from 'rangetime') and '16:00'  if (start/end time)
1587
1588          var start_end_times_arr = value_option_seconds_arr[i].trim().split(':');
1589          var time_in_seconds = parseInt(start_end_times_arr[0]) * 60 * 60 + parseInt(start_end_times_arr[1]) * 60;
1590          times_as_seconds.push(time_in_seconds);
1591        }
1592      }
1593      time_fields_obj_arr.push({
1594        'name': jQuery('#booking_form' + resource_id + ' ' + time_field).attr('name'),
1595        'value_option_24h': jquery_option.val(),
1596        'jquery_option': jquery_option,
1597        'times_as_seconds': times_as_seconds
1598      });
1599    }
1600  }
1601
1602  // Text:   [starttime] - [endtime] -----------------------------------------------------------------------------
1603
1604  var text_time_fields_arr = ['input[name="starttime' + resource_id + '"]', 'input[name="endtime' + resource_id + '"]'];
1605  for (var tf = 0; tf < text_time_fields_arr.length; tf++) {
1606    var text_jquery = jQuery('#booking_form' + resource_id + ' ' + text_time_fields_arr[tf]); // Exclude conditional  fields,  because of using '#booking_form3 ...'
1607    if (text_jquery.length > 0) {
1608      var time__h_m__arr = text_jquery.val().trim().split(':'); // '14:00'
1609      if (0 == time__h_m__arr.length) {
1610        continue; // Not entered time value in a field
1611      }
1612      if (1 == time__h_m__arr.length) {
1613        if ('' === time__h_m__arr[0]) {
1614          continue; // Not entered time value in a field
1615        }
1616        time__h_m__arr[1] = 0;
1617      }
1618      var text_time_in_seconds = parseInt(time__h_m__arr[0]) * 60 * 60 + parseInt(time__h_m__arr[1]) * 60;
1619      var text_times_as_seconds = [];
1620      text_times_as_seconds.push(text_time_in_seconds);
1621      time_fields_obj_arr.push({
1622        'name': text_jquery.attr('name'),
1623        'value_option_24h': text_jquery.val(),
1624        'jquery_option': text_jquery,
1625        'times_as_seconds': text_times_as_seconds
1626      });
1627    }
1628  }
1629  return time_fields_obj_arr;
1630}
1631
1632// ---------------------------------------------------------------------------------------------------------------------
1633/*  ==  S U P P O R T    for    C A L E N D A R  ==
1634// --------------------------------------------------------------------------------------------------------------------- */
1635
1636/**
1637 * Get Calendar datepick  Instance
1638 * @param resource_id  of booking resource
1639 * @returns {*|null}
1640 */
1641function wpbc_calendar__get_inst(resource_id) {
1642  if ('undefined' === typeof resource_id) {
1643    resource_id = '1';
1644  }
1645  if (jQuery('#calendar_booking' + resource_id).length > 0) {
1646    return jQuery.datepick._getInst(jQuery('#calendar_booking' + resource_id).get(0));
1647  }
1648  return null;
1649}
1650
1651/**
1652 * Unselect  all dates in calendar and visually update this calendar
1653 *
1654 * @param resource_id		ID of booking resource
1655 * @returns {boolean}		true on success | false,  if no such  calendar
1656 */
1657function wpbc_calendar__unselect_all_dates(resource_id) {
1658  if ('undefined' === typeof resource_id) {
1659    resource_id = '1';
1660  }
1661  var inst = wpbc_calendar__get_inst(resource_id);
1662  if (null !== inst) {
1663    // Unselect all dates and set  properties of Datepick
1664    jQuery('#date_booking' + resource_id).val(''); //FixIn: 5.4.3
1665    inst.stayOpen = false;
1666    inst.dates = [];
1667    jQuery.datepick._updateDatepick(inst);
1668    return true;
1669  }
1670  return false;
1671}
1672
1673/**
1674 * Clear days highlighting in All or specific Calendars
1675 *
1676    * @param resource_id  - can be skiped to  clear highlighting in all calendars
1677    */
1678function wpbc_calendars__clear_days_highlighting(resource_id) {
1679  if ('undefined' !== typeof resource_id) {
1680    jQuery('#calendar_booking' + resource_id + ' .datepick-days-cell-over').removeClass('datepick-days-cell-over'); // Clear in specific calendar
1681  } else {
1682    jQuery('.datepick-days-cell-over').removeClass('datepick-days-cell-over'); // Clear in all calendars
1683  }
1684}
1685
1686/**
1687 * Scroll to specific month in calendar
1688 *
1689 * @param resource_id		ID of resource
1690 * @param year				- real year  - 2023
1691 * @param month				- real month - 12
1692 * @returns {boolean}
1693 */
1694function wpbc_calendar__scroll_to(resource_id, year, month) {
1695  if ('undefined' === typeof resource_id) {
1696    resource_id = '1';
1697  }
1698  var inst = wpbc_calendar__get_inst(resource_id);
1699  if (null !== inst) {
1700    year = parseInt(year);
1701    month = parseInt(month) - 1; // In JS date,  month -1
1702
1703    inst.cursorDate = new Date();
1704    // In some cases,  the setFullYear can  set  only Year,  and not the Month and day      // FixIn: 6.2.3.5.
1705    inst.cursorDate.setFullYear(year, month, 1);
1706    inst.cursorDate.setMonth(month);
1707    inst.cursorDate.setDate(1);
1708    inst.drawMonth = inst.cursorDate.getMonth();
1709    inst.drawYear = inst.cursorDate.getFullYear();
1710    jQuery.datepick._notifyChange(inst);
1711    jQuery.datepick._adjustInstDate(inst);
1712    jQuery.datepick._showDate(inst);
1713    jQuery.datepick._updateDatepick(inst);
1714    return true;
1715  }
1716  return false;
1717}
1718
1719/**
1720 * Is this date selectable in calendar (mainly it's means AVAILABLE date)
1721 *
1722 * @param {int|string} resource_id		1
1723 * @param {string} sql_class_day		'2023-08-11'
1724 * @returns {boolean}					true | false
1725 */
1726function wpbc_is_this_day_selectable(resource_id, sql_class_day) {
1727  // Get Data --------------------------------------------------------------------------------------------------------
1728  var date_bookings_obj = _wpbc.bookings_in_calendar__get_for_date(resource_id, sql_class_day);
1729  var is_day_selectable = parseInt(date_bookings_obj['day_availability']) > 0;
1730  if (typeof date_bookings_obj['summary'] === 'undefined') {
1731    return is_day_selectable;
1732  }
1733  if ('available' != date_bookings_obj['summary']['status_for_day']) {
1734    var is_set_pending_days_selectable = _wpbc.calendar__get_param_value(resource_id, 'pending_days_selectable'); // set pending days selectable          // FixIn: 8.6.1.18.
1735
1736    switch (date_bookings_obj['summary']['status_for_bookings']) {
1737      case 'pending':
1738      // Situations for "change-over" days:
1739      case 'pending_pending':
1740      case 'pending_approved':
1741      case 'approved_pending':
1742        is_day_selectable = is_day_selectable ? true : is_set_pending_days_selectable;
1743        break;
1744      default:
1745    }
1746  }
1747  return is_day_selectable;
1748}
1749
1750/**
1751 * Is date to check IN array of selected dates
1752 *
1753 * @param {date}js_date_to_check		- JS Date			- simple  JavaScript Date object
1754 * @param {[]} js_dates_arr			- [ JSDate, ... ]   - array  of JS dates
1755 * @returns {boolean}
1756 */
1757function wpbc_is_this_day_among_selected_days(js_date_to_check, js_dates_arr) {
1758  for (var date_index = 0; date_index < js_dates_arr.length; date_index++) {
1759    // FixIn: 8.4.5.16.
1760    if (js_dates_arr[date_index].getFullYear() === js_date_to_check.getFullYear() && js_dates_arr[date_index].getMonth() === js_date_to_check.getMonth() && js_dates_arr[date_index].getDate() === js_date_to_check.getDate()) {
1761      return true;
1762    }
1763  }
1764  return false;
1765}
1766
1767/**
1768 * Get SQL Class Date '2023-08-01' from  JS Date
1769 *
1770 * @param date				JS Date
1771 * @returns {string}		'2023-08-12'
1772 */
1773function wpbc__get__sql_class_date(date) {
1774  var sql_class_day = date.getFullYear() + '-';
1775  sql_class_day += date.getMonth() + 1 < 10 ? '0' : '';
1776  sql_class_day += date.getMonth() + 1 + '-';
1777  sql_class_day += date.getDate() < 10 ? '0' : '';
1778  sql_class_day += date.getDate();
1779  return sql_class_day;
1780}
1781
1782/**
1783 * Get JS Date from  the SQL date format '2024-05-14'
1784 * @param sql_class_date
1785 * @returns {Date}
1786 */
1787function wpbc__get__js_date(sql_class_date) {
1788  var sql_class_date_arr = sql_class_date.split('-');
1789  var date_js = new Date();
1790  date_js.setFullYear(parseInt(sql_class_date_arr[0]), parseInt(sql_class_date_arr[1]) - 1, parseInt(sql_class_date_arr[2])); // year, month, date
1791
1792  // Without this time adjust Dates selection  in Datepicker can not work!!!
1793  date_js.setHours(0);
1794  date_js.setMinutes(0);
1795  date_js.setSeconds(0);
1796  date_js.setMilliseconds(0);
1797  return date_js;
1798}
1799
1800/**
1801 * Get TD Class Date '1-31-2023' from  JS Date
1802 *
1803 * @param date				JS Date
1804 * @returns {string}		'1-31-2023'
1805 */
1806function wpbc__get__td_class_date(date) {
1807  var td_class_day = date.getMonth() + 1 + '-' + date.getDate() + '-' + date.getFullYear(); // '1-9-2023'
1808
1809  return td_class_day;
1810}
1811
1812/**
1813 * Get date params from  string date
1814 *
1815 * @param date			string date like '31.5.2023'
1816 * @param separator		default '.'  can be skipped.
1817 * @returns {  {date: number, month: number, year: number}  }
1818 */
1819function wpbc__get__date_params__from_string_date(date, separator) {
1820  separator = 'undefined' !== typeof separator ? separator : '.';
1821  var date_arr = date.split(separator);
1822  var date_obj = {
1823    'year': parseInt(date_arr[2]),
1824    'month': parseInt(date_arr[1]) - 1,
1825    'date': parseInt(date_arr[0])
1826  };
1827  return date_obj; // for 		 = new Date( date_obj.year , date_obj.month , date_obj.date );
1828}
1829
1830/**
1831 * Add Spin Loader to  calendar
1832 * @param resource_id
1833 */
1834function wpbc_calendar__loading__start(resource_id) {
1835  if (!jQuery('#calendar_booking' + resource_id).next().hasClass('wpbc_spins_loader_wrapper')) {
1836    jQuery('#calendar_booking' + resource_id).after('<div class="wpbc_spins_loader_wrapper"><div class="wpbc_spins_loader"></div></div>');
1837  }
1838  if (!jQuery('#calendar_booking' + resource_id).hasClass('wpbc_calendar_blur_small')) {
1839    jQuery('#calendar_booking' + resource_id).addClass('wpbc_calendar_blur_small');
1840  }
1841  wpbc_calendar__blur__start(resource_id);
1842}
1843
1844/**
1845 * Remove Spin Loader to  calendar
1846 * @param resource_id
1847 */
1848function wpbc_calendar__loading__stop(resource_id) {
1849  jQuery('#calendar_booking' + resource_id + ' + .wpbc_spins_loader_wrapper').remove();
1850  jQuery('#calendar_booking' + resource_id).removeClass('wpbc_calendar_blur_small');
1851  wpbc_calendar__blur__stop(resource_id);
1852}
1853
1854/**
1855 * Add Blur to  calendar
1856 * @param resource_id
1857 */
1858function wpbc_calendar__blur__start(resource_id) {
1859  if (!jQuery('#calendar_booking' + resource_id).hasClass('wpbc_calendar_blur')) {
1860    jQuery('#calendar_booking' + resource_id).addClass('wpbc_calendar_blur');
1861  }
1862}
1863
1864/**
1865 * Remove Blur in  calendar
1866 * @param resource_id
1867 */
1868function wpbc_calendar__blur__stop(resource_id) {
1869  jQuery('#calendar_booking' + resource_id).removeClass('wpbc_calendar_blur');
1870}
1871
1872// .................................................................................................................
1873/*  ==  Calendar Update  - View  ==
1874// ................................................................................................................. */
1875
1876/**
1877 * Update Look  of calendar
1878 *
1879 * @param resource_id
1880 */
1881function wpbc_calendar__update_look(resource_id) {
1882  var inst = wpbc_calendar__get_inst(resource_id);
1883  jQuery.datepick._updateDatepick(inst);
1884}
1885
1886/**
1887 * Update dynamically Number of Months in calendar
1888 *
1889 * @param resource_id int
1890 * @param months_number int
1891 */
1892function wpbc_calendar__update_months_number(resource_id, months_number) {
1893  var inst = wpbc_calendar__get_inst(resource_id);
1894  if (null !== inst) {
1895    inst.settings['numberOfMonths'] = months_number;
1896    //_wpbc.calendar__set_param_value( resource_id, 'calendar_number_of_months', months_number );
1897    wpbc_calendar__update_look(resource_id);
1898  }
1899}
1900
1901/**
1902 * Show calendar in  different Skin
1903 *
1904 * @param selected_skin_url
1905 */
1906function wpbc__calendar__change_skin(selected_skin_url) {
1907  //console.log( 'SKIN SELECTION ::', selected_skin_url );
1908
1909  // Remove CSS skin
1910  var stylesheet = document.getElementById('wpbc-calendar-skin-css');
1911  stylesheet.parentNode.removeChild(stylesheet);
1912
1913  // Add new CSS skin
1914  var headID = document.getElementsByTagName("head")[0];
1915  var cssNode = document.createElement('link');
1916  cssNode.type = 'text/css';
1917  cssNode.setAttribute("id", "wpbc-calendar-skin-css");
1918  cssNode.rel = 'stylesheet';
1919  cssNode.media = 'screen';
1920  cssNode.href = selected_skin_url; //"http://beta/wp-content/plugins/booking/css/skins/green-01.css";
1921  headID.appendChild(cssNode);
1922}
1923function wpbc__css__change_skin(selected_skin_url) {
1924  var stylesheet_id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'wpbc-time_picker-skin-css';
1925  // Remove CSS skin
1926  var stylesheet = document.getElementById(stylesheet_id);
1927  stylesheet.parentNode.removeChild(stylesheet);
1928
1929  // Add new CSS skin
1930  var headID = document.getElementsByTagName("head")[0];
1931  var cssNode = document.createElement('link');
1932  cssNode.type = 'text/css';
1933  cssNode.setAttribute("id", stylesheet_id);
1934  cssNode.rel = 'stylesheet';
1935  cssNode.media = 'screen';
1936  cssNode.href = selected_skin_url; //"http://beta/wp-content/plugins/booking/css/skins/green-01.css";
1937  headID.appendChild(cssNode);
1938}
1939
1940// ---------------------------------------------------------------------------------------------------------------------
1941/*  ==  S U P P O R T    M A T H  ==
1942// --------------------------------------------------------------------------------------------------------------------- */
1943
1944/**
1945 * Merge several  intersected intervals or return not intersected:                        [[1,3],[2,6],[8,10],[15,18]]  ->   [[1,6],[8,10],[15,18]]
1946 *
1947 * @param [] intervals			 [ [1,3],[2,4],[6,8],[9,10],[3,7] ]
1948 * @returns []					 [ [1,8],[9,10] ]
1949 *
1950 * Exmample: wpbc_intervals__merge_inersected(  [ [1,3],[2,4],[6,8],[9,10],[3,7] ]  );
1951 */
1952function wpbc_intervals__merge_inersected(intervals) {
1953  if (!intervals || intervals.length === 0) {
1954    return [];
1955  }
1956  var merged = [];
1957  intervals.sort(function (a, b) {
1958    return a[0] - b[0];
1959  });
1960  var mergedInterval = intervals[0];
1961  for (var i = 1; i < intervals.length; i++) {
1962    var interval = intervals[i];
1963    if (interval[0] <= mergedInterval[1]) {
1964      mergedInterval[1] = Math.max(mergedInterval[1], interval[1]);
1965    } else {
1966      merged.push(mergedInterval);
1967      mergedInterval = interval;
1968    }
1969  }
1970  merged.push(mergedInterval);
1971  return merged;
1972}
1973
1974/**
1975 * Is 2 intervals intersected:       [36011, 86392]    <=>    [1, 43192]  =>  true      ( intersected )
1976 *
1977 * Good explanation  here https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
1978 *
1979 * @param  interval_A   - [ 36011, 86392 ]
1980 * @param  interval_B   - [     1, 43192 ]
1981 *
1982 * @return bool
1983 */
1984function wpbc_intervals__is_intersected(interval_A, interval_B) {
1985  if (0 == interval_A.length || 0 == interval_B.length) {
1986    return false;
1987  }
1988  interval_A[0] = parseInt(interval_A[0]);
1989  interval_A[1] = parseInt(interval_A[1]);
1990  interval_B[0] = parseInt(interval_B[0]);
1991  interval_B[1] = parseInt(interval_B[1]);
1992  var is_intersected = Math.max(interval_A[0], interval_B[0]) - Math.min(interval_A[1], interval_B[1]);
1993
1994  // if ( 0 == is_intersected ) {
1995  //	                                 // Such ranges going one after other, e.g.: [ 12, 15 ] and [ 15, 21 ]
1996  // }
1997
1998  if (is_intersected < 0) {
1999    return true; // INTERSECTED
2000  }
2001  return false; // Not intersected
2002}
2003
2004/**
2005 * Get the closets ABS value of element in array to the current myValue
2006 *
2007 * @param myValue 	- int element to search closet 			4
2008 * @param myArray	- array of elements where to search 	[5,8,1,7]
2009 * @returns int												5
2010 */
2011function wpbc_get_abs_closest_value_in_arr(myValue, myArray) {
2012  if (myArray.length == 0) {
2013    // If the array is empty -> return  the myValue
2014    return myValue;
2015  }
2016  var obj = myArray[0];
2017  var diff = Math.abs(myValue - obj); // Get distance between  1st element
2018  var closetValue = myArray[0]; // Save 1st element
2019
2020  for (var i = 1; i < myArray.length; i++) {
2021    obj = myArray[i];
2022    if (Math.abs(myValue - obj) < diff) {
2023      // we found closer value -> save it
2024      diff = Math.abs(myValue - obj);
2025      closetValue = obj;
2026    }
2027  }
2028  return closetValue;
2029}
2030
2031// ---------------------------------------------------------------------------------------------------------------------
2032/*  ==  T O O L T I P S  ==
2033// --------------------------------------------------------------------------------------------------------------------- */
2034
2035/**
2036 * Define tooltip to show,  when  mouse over Date in Calendar
2037 *
2038 * @param  tooltip_text			- Text to show				'Booked time: 12:00 - 13:00<br>Cost: $20.00'
2039 * @param  resource_id			- ID of booking resource	'1'
2040 * @param  td_class				- SQL class					'1-9-2023'
2041 * @returns {boolean}					- defined to show or not
2042 */
2043function wpbc_set_tooltip___for__calendar_date(tooltip_text, resource_id, td_class) {
2044  //TODO: make escaping of text for quot symbols,  and JS/HTML...
2045
2046  jQuery('#calendar_booking' + resource_id + ' td.cal4date-' + td_class).attr('data-content', tooltip_text);
2047  var td_el = jQuery('#calendar_booking' + resource_id + ' td.cal4date-' + td_class).get(0); // FixIn: 9.0.1.1.
2048
2049  if ('undefined' !== typeof td_el && undefined == td_el._tippy && '' !== tooltip_text) {
2050    wpbc_tippy(td_el, {
2051      content: function content(reference) {
2052        var popover_content = reference.getAttribute('data-content');
2053        return '<div class="popover popover_tippy">' + '<div class="popover-content">' + popover_content + '</div>' + '</div>';
2054      },
2055      allowHTML: true,
2056      trigger: 'mouseenter focus',
2057      interactive: false,
2058      hideOnClick: true,
2059      interactiveBorder: 10,
2060      maxWidth: 550,
2061      theme: 'wpbc-tippy-times',
2062      placement: 'top',
2063      delay: [400, 0],
2064      // FixIn: 9.4.2.2.
2065      //delay			 : [0, 9999999999],						// Debuge  tooltip
2066      ignoreAttributes: true,
2067      touch: true,
2068      //['hold', 500], // 500ms delay				// FixIn: 9.2.1.5.
2069      appendTo: function appendTo() {
2070        return document.body;
2071      }
2072    });
2073    return true;
2074  }
2075  return false;
2076}
2077
2078// ---------------------------------------------------------------------------------------------------------------------
2079/*  ==  Dates Functions  ==
2080// --------------------------------------------------------------------------------------------------------------------- */
2081
2082/**
2083 * Get number of dates between 2 JS Dates
2084 *
2085 * @param date1		JS Date
2086 * @param date2		JS Date
2087 * @returns {number}
2088 */
2089function wpbc_dates__days_between(date1, date2) {
2090  // The number of milliseconds in one day
2091  var ONE_DAY = 1000 * 60 * 60 * 24;
2092
2093  // Convert both dates to milliseconds
2094  var date1_ms = date1.getTime();
2095  var date2_ms = date2.getTime();
2096
2097  // Calculate the difference in milliseconds
2098  var difference_ms = date1_ms - date2_ms;
2099
2100  // Convert back to days and return
2101  return Math.round(difference_ms / ONE_DAY);
2102}
2103
2104/**
2105 * Check  if this array  of dates is consecutive array  of dates or not.
2106 * 		e.g.  ['2024-05-09','2024-05-19','2024-05-30'] -> false
2107 * 		e.g.  ['2024-05-09','2024-05-10','2024-05-11'] -> true
2108 * @param sql_dates_arr	 array		e.g.: ['2024-05-09','2024-05-19','2024-05-30']
2109 * @returns {boolean}
2110 */
2111function wpbc_dates__is_consecutive_dates_arr_range(sql_dates_arr) {
2112  // FixIn: 10.0.0.50.
2113
2114  if (sql_dates_arr.length > 1) {
2115    var previos_date = wpbc__get__js_date(sql_dates_arr[0]);
2116    var current_date;
2117    for (var i = 1; i < sql_dates_arr.length; i++) {
2118      current_date = wpbc__get__js_date(sql_dates_arr[i]);
2119      if (wpbc_dates__days_between(current_date, previos_date) != 1) {
2120        return false;
2121      }
2122      previos_date = current_date;
2123    }
2124  }
2125  return true;
2126}
2127
2128// ---------------------------------------------------------------------------------------------------------------------
2129/*  ==  Auto Dates Selection  ==
2130// --------------------------------------------------------------------------------------------------------------------- */
2131
2132/**
2133 *  == How to  use ? ==
2134 *
2135 *  For Dates selection, we need to use this logic!     We need select the dates only after booking data loaded!
2136 *
2137 *  Check example bellow.
2138 *
2139 *	// Fire on all booking dates loaded
2140 *	jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function ( event, loaded_resource_id ){
2141 *
2142 *		if ( loaded_resource_id == select_dates_in_calendar_id ){
2143 *			wpbc_auto_select_dates_in_calendar( select_dates_in_calendar_id, '2024-05-15', '2024-05-25' );
2144 *		}
2145 *	} );
2146 *
2147 */
2148
2149/**
2150 * Try to Auto select dates in specific calendar by simulated clicks in datepicker
2151 *
2152 * @param resource_id		1
2153 * @param check_in_ymd		'2024-05-09'		OR  	['2024-05-09','2024-05-19','2024-05-20']
2154 * @param check_out_ymd		'2024-05-15'		Optional
2155 *
2156 * @returns {number}		number of selected dates
2157 *
2158 * 	Example 1:				var num_selected_days = wpbc_auto_select_dates_in_calendar( 1, '2024-05-15', '2024-05-25' );
2159 * 	Example 2:				var num_selected_days = wpbc_auto_select_dates_in_calendar( 1, ['2024-05-09','2024-05-19','2024-05-20'] );
2160 */
2161function wpbc_auto_select_dates_in_calendar(resource_id, check_in_ymd) {
2162  var check_out_ymd = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
2163  // FixIn: 10.0.0.47.
2164
2165  console.log('WPBC_AUTO_SELECT_DATES_IN_CALENDAR( RESOURCE_ID, CHECK_IN_YMD, CHECK_OUT_YMD )', resource_id, check_in_ymd, check_out_ymd);
2166  if ('2100-01-01' == check_in_ymd || '2100-01-01' == check_out_ymd || '' == check_in_ymd && '' == check_out_ymd) {
2167    return 0;
2168  }
2169
2170  // -----------------------------------------------------------------------------------------------------------------
2171  // If 	check_in_ymd  =  [ '2024-05-09','2024-05-19','2024-05-30' ]				ARRAY of DATES						// FixIn: 10.0.0.50.
2172  // -----------------------------------------------------------------------------------------------------------------
2173  var dates_to_select_arr = [];
2174  if (Array.isArray(check_in_ymd)) {
2175    dates_to_select_arr = wpbc_clone_obj(check_in_ymd);
2176
2177    // -------------------------------------------------------------------------------------------------------------
2178    // Exceptions to  set  	MULTIPLE DAYS 	mode
2179    // -------------------------------------------------------------------------------------------------------------
2180    // if dates as NOT CONSECUTIVE: ['2024-05-09','2024-05-19','2024-05-30'], -> set MULTIPLE DAYS mode
2181    if (dates_to_select_arr.length > 0 && '' == check_out_ymd && !wpbc_dates__is_consecutive_dates_arr_range(dates_to_select_arr)) {
2182      wpbc_cal_days_select__multiple(resource_id);
2183    }
2184    // if multiple days to select, but enabled SINGLE day mode, -> set MULTIPLE DAYS mode
2185    if (dates_to_select_arr.length > 1 && '' == check_out_ymd && 'single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2186      wpbc_cal_days_select__multiple(resource_id);
2187    }
2188    // -------------------------------------------------------------------------------------------------------------
2189    check_in_ymd = dates_to_select_arr[0];
2190    if ('' == check_out_ymd) {
2191      check_out_ymd = dates_to_select_arr[dates_to_select_arr.length - 1];
2192    }
2193  }
2194  // -----------------------------------------------------------------------------------------------------------------
2195
2196  if ('' == check_in_ymd) {
2197    check_in_ymd = check_out_ymd;
2198  }
2199  if ('' == check_out_ymd) {
2200    check_out_ymd = check_in_ymd;
2201  }
2202  if ('undefined' === typeof resource_id) {
2203    resource_id = '1';
2204  }
2205  var inst = wpbc_calendar__get_inst(resource_id);
2206  if (null !== inst) {
2207    // Unselect all dates and set  properties of Datepick
2208    jQuery('#date_booking' + resource_id).val(''); //FixIn: 5.4.3
2209    inst.stayOpen = false;
2210    inst.dates = [];
2211    var check_in_js = wpbc__get__js_date(check_in_ymd);
2212    var td_cell = wpbc_get_clicked_td(inst.id, check_in_js);
2213
2214    // Is ome type of error, then select multiple days selection  mode.
2215    if ('' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2216      _wpbc.calendar__set_param_value(resource_id, 'days_select_mode', 'multiple');
2217    }
2218
2219    // ---------------------------------------------------------------------------------------------------------
2220    //  == DYNAMIC ==
2221    if ('dynamic' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2222      // 1-st click
2223      inst.stayOpen = false;
2224      jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime());
2225      if (0 === inst.dates.length) {
2226        return 0; // First click  was unsuccessful, so we must not make other click
2227      }
2228
2229      // 2-nd click
2230      var check_out_js = wpbc__get__js_date(check_out_ymd);
2231      var td_cell_out = wpbc_get_clicked_td(inst.id, check_out_js);
2232      inst.stayOpen = true;
2233      jQuery.datepick._selectDay(td_cell_out, '#' + inst.id, check_out_js.getTime());
2234    }
2235
2236    // ---------------------------------------------------------------------------------------------------------
2237    //  == FIXED ==
2238    if ('fixed' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2239      jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime());
2240    }
2241
2242    // ---------------------------------------------------------------------------------------------------------
2243    //  == SINGLE ==
2244    if ('single' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2245      //jQuery.datepick._restrictMinMax( inst, jQuery.datepick._determineDate( inst, check_in_js, null ) );		// Do we need to run  this ? Please note, check_in_js must  have time,  min, sec defined to 0!
2246      jQuery.datepick._selectDay(td_cell, '#' + inst.id, check_in_js.getTime());
2247    }
2248
2249    // ---------------------------------------------------------------------------------------------------------
2250    //  == MULTIPLE ==
2251    if ('multiple' === _wpbc.calendar__get_param_value(resource_id, 'days_select_mode')) {
2252      var dates_arr;
2253      if (dates_to_select_arr.length > 0) {
2254        // Situation, when we have dates array: ['2024-05-09','2024-05-19','2024-05-30'].  and not the Check In / Check  out dates as parameter in this function
2255        dates_arr = wpbc_get_selection_dates_js_str_arr__from_arr(dates_to_select_arr);
2256      } else {
2257        dates_arr = wpbc_get_selection_dates_js_str_arr__from_check_in_out(check_in_ymd, check_out_ymd, inst);
2258      }
2259      if (0 === dates_arr.dates_js.length) {
2260        return 0;
2261      }
2262
2263      // For Calendar Days selection
2264      for (var j = 0; j < dates_arr.dates_js.length; j++) {
2265        // Loop array of dates
2266
2267        var str_date = wpbc__get__sql_class_date(dates_arr.dates_js[j]);
2268
2269        // Date unavailable !
2270        if (0 == _wpbc.bookings_in_calendar__get_for_date(resource_id, str_date).day_availability) {
2271          return 0;
2272        }
2273        if (dates_arr.dates_js[j] != -1) {
2274          inst.dates.push(dates_arr.dates_js[j]);
2275        }
2276      }
2277      var check_out_date = dates_arr.dates_js[dates_arr.dates_js.length - 1];
2278      inst.dates.push(check_out_date); // Need add one additional SAME date for correct  works of dates selection !!!!!
2279
2280      var checkout_timestamp = check_out_date.getTime();
2281      var td_cell = wpbc_get_clicked_td(inst.id, check_out_date);
2282      jQuery.datepick._selectDay(td_cell, '#' + inst.id, checkout_timestamp);
2283    }
2284    if (0 !== inst.dates.length) {
2285      // Scroll to specific month, if we set dates in some future months
2286      wpbc_calendar__scroll_to(resource_id, inst.dates[0].getFullYear(), inst.dates[0].getMonth() + 1);
2287    }
2288    return inst.dates.length;
2289  }
2290  return 0;
2291}
2292
2293/**
2294 * Get HTML td element (where was click in calendar  day  cell)
2295 *
2296 * @param calendar_html_id			'calendar_booking1'
2297 * @param date_js					JS Date
2298 * @returns {*|jQuery}				Dom HTML td element
2299 */
2300function wpbc_get_clicked_td(calendar_html_id, date_js) {
2301  var td_cell = jQuery('#' + calendar_html_id + ' .sql_date_' + wpbc__get__sql_class_date(date_js)).get(0);
2302  return td_cell;
2303}
2304
2305/**
2306 * Get arrays of JS and SQL dates as dates array
2307 *
2308 * @param check_in_ymd							'2024-05-15'
2309 * @param check_out_ymd							'2024-05-25'
2310 * @param inst									Datepick Inst. Use wpbc_calendar__get_inst( resource_id );
2311 * @returns {{dates_js: *[], dates_str: *[]}}
2312 */
2313function wpbc_get_selection_dates_js_str_arr__from_check_in_out(check_in_ymd, check_out_ymd, inst) {
2314  var original_array = [];
2315  var date;
2316  var bk_distinct_dates = [];
2317  var check_in_date = check_in_ymd.split('-');
2318  var check_out_date = check_out_ymd.split('-');
2319  date = new Date();
2320  date.setFullYear(check_in_date[0], check_in_date[1] - 1, check_in_date[2]); // year, month, date
2321  var original_check_in_date = date;
2322  original_array.push(jQuery.datepick._restrictMinMax(inst, jQuery.datepick._determineDate(inst, date, null))); //add date
2323  if (!wpbc_in_array(bk_distinct_dates, check_in_date[2] + '.' + check_in_date[1] + '.' + check_in_date[0])) {
2324    bk_distinct_dates.push(parseInt(check_in_date[2]) + '.' + parseInt(check_in_date[1]) + '.' + check_in_date[0]);
2325  }
2326  var date_out = new Date();
2327  date_out.setFullYear(check_out_date[0], check_out_date[1] - 1, check_out_date[2]); // year, month, date
2328  var original_check_out_date = date_out;
2329  var mewDate = new Date(original_check_in_date.getFullYear(), original_check_in_date.getMonth(), original_check_in_date.getDate());
2330  mewDate.setDate(original_check_in_date.getDate() + 1);
2331  while (original_check_out_date > date && original_check_in_date != original_check_out_date) {
2332    date = new Date(mewDate.getFullYear(), mewDate.getMonth(), mewDate.getDate());
2333    original_array.push(jQuery.datepick._restrictMinMax(inst, jQuery.datepick._determineDate(inst, date, null))); //add date
2334    if (!wpbc_in_array(bk_distinct_dates, date.getDate() + '.' + parseInt(date.getMonth() + 1) + '.' + date.getFullYear())) {
2335      bk_distinct_dates.push(parseInt(date.getDate()) + '.' + parseInt(date.getMonth() + 1) + '.' + date.getFullYear());
2336    }
2337    mewDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
2338    mewDate.setDate(mewDate.getDate() + 1);
2339  }
2340  original_array.pop();
2341  bk_distinct_dates.pop();
2342  return {
2343    'dates_js': original_array,
2344    'dates_str': bk_distinct_dates
2345  };
2346}
2347
2348/**
2349 * Get arrays of JS and SQL dates as dates array
2350 *
2351 * @param dates_to_select_arr	= ['2024-05-09','2024-05-19','2024-05-30']
2352 *
2353 * @returns {{dates_js: *[], dates_str: *[]}}
2354 */
2355function wpbc_get_selection_dates_js_str_arr__from_arr(dates_to_select_arr) {
2356  // FixIn: 10.0.0.50.
2357
2358  var original_array = [];
2359  var bk_distinct_dates = [];
2360  var one_date_str;
2361  for (var d = 0; d < dates_to_select_arr.length; d++) {
2362    original_array.push(wpbc__get__js_date(dates_to_select_arr[d]));
2363    one_date_str = dates_to_select_arr[d].split('-');
2364    if (!wpbc_in_array(bk_distinct_dates, one_date_str[2] + '.' + one_date_str[1] + '.' + one_date_str[0])) {
2365      bk_distinct_dates.push(parseInt(one_date_str[2]) + '.' + parseInt(one_date_str[1]) + '.' + one_date_str[0]);
2366    }
2367  }
2368  return {
2369    'dates_js': original_array,
2370    'dates_str': original_array
2371  };
2372}
2373
2374// =====================================================================================================================
2375/*  ==  Auto Fill Fields / Auto Select Dates  ==
2376// ===================================================================================================================== */
2377
2378jQuery(document).ready(function () {
2379  var url_params = new URLSearchParams(window.location.search);
2380
2381  // Disable days selection  in calendar,  after  redirection  from  the "Search results page,  after  search  availability" 			// FixIn: 8.8.2.3.
2382  if ('On' != _wpbc.get_other_param('is_enabled_booking_search_results_days_select')) {
2383    if (url_params.has('wpbc_select_check_in') && url_params.has('wpbc_select_check_out') && url_params.has('wpbc_select_calendar_id')) {
2384      var select_dates_in_calendar_id = parseInt(url_params.get('wpbc_select_calendar_id'));
2385
2386      // Fire on all booking dates loaded
2387      jQuery('body').on('wpbc_calendar_ajx__loaded_data', function (event, loaded_resource_id) {
2388        if (loaded_resource_id == select_dates_in_calendar_id) {
2389          wpbc_auto_select_dates_in_calendar(select_dates_in_calendar_id, url_params.get('wpbc_select_check_in'), url_params.get('wpbc_select_check_out'));
2390        }
2391      });
2392    }
2393  }
2394  if (url_params.has('wpbc_auto_fill')) {
2395    var wpbc_auto_fill_value = url_params.get('wpbc_auto_fill');
2396
2397    // Convert back.     Some systems do not like symbol '~' in URL, so  we need to replace to  some other symbols
2398    wpbc_auto_fill_value = wpbc_auto_fill_value.replaceAll('_^_', '~');
2399    wpbc_auto_fill_booking_fields(wpbc_auto_fill_value);
2400  }
2401});
2402
2403/**
2404 * Autofill / select booking form  fields by  values from  the GET request  parameter: ?wpbc_auto_fill=
2405 *
2406 * @param auto_fill_str
2407 */
2408function wpbc_auto_fill_booking_fields(auto_fill_str) {
2409  // FixIn: 10.0.0.48.
2410
2411  if ('' == auto_fill_str) {
2412    return;
2413  }
2414
2415  // console.log( 'WPBC_AUTO_FILL_BOOKING_FIELDS( AUTO_FILL_STR )', auto_fill_str);
2416
2417  var fields_arr = wpbc_auto_fill_booking_fields__parse(auto_fill_str);
2418  for (var i = 0; i < fields_arr.length; i++) {
2419    jQuery('[name="' + fields_arr[i]['name'] + '"]').val(fields_arr[i]['value']);
2420  }
2421}
2422
2423/**
2424 * Parse data from  get parameter:	?wpbc_auto_fill=visitors231^2~max_capacity231^2
2425 *
2426 * @param data_str      =   'visitors231^2~max_capacity231^2';
2427 * @returns {*}
2428 */
2429function wpbc_auto_fill_booking_fields__parse(data_str) {
2430  var filter_options_arr = [];
2431  var data_arr = data_str.split('~');
2432  for (var j = 0; j < data_arr.length; j++) {
2433    var my_form_field = data_arr[j].split('^');
2434    var filter_name = 'undefined' !== typeof my_form_field[0] ? my_form_field[0] : '';
2435    var filter_value = 'undefined' !== typeof my_form_field[1] ? my_form_field[1] : '';
2436    filter_options_arr.push({
2437      'name': filter_name,
2438      'value': filter_value
2439    });
2440  }
2441  return filter_options_arr;
2442}
2443
2444/**
2445 * Parse data from  get parameter:	?search_get__custom_params=...
2446 *
2447 * @param data_str      =   'text^search_field__display_check_in^23.05.2024~text^search_field__display_check_out^26.05.2024~selectbox-one^search_quantity^2~selectbox-one^location^Spain~selectbox-one^max_capacity^2~selectbox-one^amenity^parking~checkbox^search_field__extend_search_days^5~submit^^Search~hidden^search_get__check_in_ymd^2024-05-23~hidden^search_get__check_out_ymd^2024-05-26~hidden^search_get__time^~hidden^search_get__quantity^2~hidden^search_get__extend^5~hidden^search_get__users_id^~hidden^search_get__custom_params^~';
2448 * @returns {*}
2449 */
2450function wpbc_auto_fill_search_fields__parse(data_str) {
2451  var filter_options_arr = [];
2452  var data_arr = data_str.split('~');
2453  for (var j = 0; j < data_arr.length; j++) {
2454    var my_form_field = data_arr[j].split('^');
2455    var filter_type = 'undefined' !== typeof my_form_field[0] ? my_form_field[0] : '';
2456    var filter_name = 'undefined' !== typeof my_form_field[1] ? my_form_field[1] : '';
2457    var filter_value = 'undefined' !== typeof my_form_field[2] ? my_form_field[2] : '';
2458    filter_options_arr.push({
2459      'type': filter_type,
2460      'name': filter_name,
2461      'value': filter_value
2462    });
2463  }
2464  return filter_options_arr;
2465}
2466
2467// ---------------------------------------------------------------------------------------------------------------------
2468/*  ==  Auto Update number of months in calendars ON screen size changed  ==
2469// --------------------------------------------------------------------------------------------------------------------- */
2470
2471/**
2472 * Auto Update Number of Months in Calendar, e.g.:  		if    ( WINDOW_WIDTH <= 782px )   >>> 	MONTHS_NUMBER = 1
2473 *   ELSE:  number of months defined in shortcode.
2474 * @param resource_id int
2475 *
2476 */
2477function wpbc_calendar__auto_update_months_number__on_resize(resource_id) {
2478  if (true === _wpbc.get_other_param('is_allow_several_months_on_mobile')) {
2479    return false;
2480  }
2481  var local__number_of_months = parseInt(_wpbc.calendar__get_param_value(resource_id, 'calendar_number_of_months'));
2482  if (local__number_of_months > 1) {
2483    if (jQuery(window).width() <= 782) {
2484      wpbc_calendar__update_months_number(resource_id, 1);
2485    } else {
2486      wpbc_calendar__update_months_number(resource_id, local__number_of_months);
2487    }
2488  }
2489}
2490
2491/**
2492 * Auto Update Number of Months in   ALL   Calendars
2493 *
2494 */
2495function wpbc_calendars__auto_update_months_number() {
2496  var all_calendars_arr = _wpbc.calendars_all__get();
2497
2498  // This LOOP "for in" is GOOD, because we check  here keys    'calendar_' === calendar_id.slice( 0, 9 )
2499  for (var calendar_id in all_calendars_arr) {
2500    if ('calendar_' === calendar_id.slice(0, 9)) {
2501      var resource_id = parseInt(calendar_id.slice(9)); //  'calendar_3' -> 3
2502      if (resource_id > 0) {
2503        wpbc_calendar__auto_update_months_number__on_resize(resource_id);
2504      }
2505    }
2506  }
2507}
2508
2509/**
2510 * If browser window changed,  then  update number of months.
2511 */
2512jQuery(window).on('resize', function () {
2513  wpbc_calendars__auto_update_months_number();
2514});
2515
2516/**
2517 * Auto update calendar number of months on initial page load
2518 */
2519jQuery(document).ready(function () {
2520  var closed_timer = setTimeout(function () {
2521    wpbc_calendars__auto_update_months_number();
2522  }, 100);
2523});
2524
2525// ---------------------------------------------------------------------------------------------------------------------
2526/*  ==  Check: calendar_dates_start: "2026-01-01", calendar_dates_end: "2026-12-31" ==  // FixIn: 10.13.1.4.
2527// --------------------------------------------------------------------------------------------------------------------- */
2528/**
2529 * Get Start JS Date of starting dates in calendar, from the _wpbc object.
2530 *
2531 * @param integer resource_id - resource ID, e.g.: 1.
2532 */
2533function wpbc_calendar__get_dates_start(resource_id) {
2534  return wpbc_calendar__get_date_parameter(resource_id, 'calendar_dates_start');
2535}
2536
2537/**
2538 * Get End JS Date of ending dates in calendar, from the _wpbc object.
2539 *
2540 * @param integer resource_id - resource ID, e.g.: 1.
2541 */
2542function wpbc_calendar__get_dates_end(resource_id) {
2543  return wpbc_calendar__get_date_parameter(resource_id, 'calendar_dates_end');
2544}
2545
2546/**
2547 * Get validates date parameter.
2548 *
2549 * @param resource_id   - 1
2550 * @param parameter_str - 'calendar_dates_start' | 'calendar_dates_end' | ...
2551 */
2552function wpbc_calendar__get_date_parameter(resource_id, parameter_str) {
2553  var date_expected_ymd = _wpbc.calendar__get_param_value(resource_id, parameter_str);
2554  if (!date_expected_ymd) {
2555    return false; // '' | 0 | null | undefined  -> false.
2556  }
2557  if (-1 !== date_expected_ymd.indexOf('-')) {
2558    var date_expected_ymd_arr = date_expected_ymd.split('-'); // '2025-07-26' -> ['2025', '07', '26']
2559
2560    if (date_expected_ymd_arr.length > 0) {
2561      var year = date_expected_ymd_arr.length > 0 ? parseInt(date_expected_ymd_arr[0]) : new Date().getFullYear(); // Year.
2562      var month = date_expected_ymd_arr.length > 1 ? parseInt(date_expected_ymd_arr[1]) - 1 : 0; // (month - 1) or 0 - Jan.
2563      var day = date_expected_ymd_arr.length > 2 ? parseInt(date_expected_ymd_arr[2]) : 1; // date or Otherwise 1st of month
2564
2565      var date_js = new Date(year, month, day, 0, 0, 0, 0);
2566      return date_js;
2567    }
2568  }
2569  return false; // Fallback,  if we not parsed this parameter  'calendar_dates_start' = '2025-07-26',  for example because of 'calendar_dates_start' = 'sfsdf'.
2570}
2571/**
2572 * ====================================================================================================================
2573 *	includes/__js/cal/days_select_custom.js
2574 * ====================================================================================================================
2575 */
2576
2577// FixIn: 9.8.9.2.
2578
2579/**
2580 * Re-Init Calendar and Re-Render it.
2581 *
2582 * @param resource_id
2583 */
2584function wpbc_cal__re_init(resource_id) {
2585  // Remove CLASS  for ability to re-render and reinit calendar.
2586  jQuery('#calendar_booking' + resource_id).removeClass('hasDatepick');
2587  wpbc_calendar_show(resource_id);
2588}
2589
2590/**
2591 * Re-Init previously  saved days selection  variables.
2592 *
2593 * @param resource_id
2594 */
2595function wpbc_cal_days_select__re_init(resource_id) {
2596  _wpbc.calendar__set_param_value(resource_id, 'saved_variable___days_select_initial', {
2597    'dynamic__days_min': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_min'),
2598    'dynamic__days_max': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_max'),
2599    'dynamic__days_specific': _wpbc.calendar__get_param_value(resource_id, 'dynamic__days_specific'),
2600    'dynamic__week_days__start': _wpbc.calendar__get_param_value(resource_id, 'dynamic__week_days__start'),
2601    'fixed__days_num': _wpbc.calendar__get_param_value(resource_id, 'fixed__days_num'),
2602    'fixed__week_days__start': _wpbc.calendar__get_param_value(resource_id, 'fixed__week_days__start')
2603  });
2604}
2605
2606// ---------------------------------------------------------------------------------------------------------------------
2607
2608/**
2609 * Set Single Day selection - after page load
2610 *
2611 * @param resource_id		ID of booking resource
2612 */
2613function wpbc_cal_ready_days_select__single(resource_id) {
2614  // Re-define selection, only after page loaded with all init vars
2615  jQuery(document).ready(function () {
2616    // Wait 1 second, just to  be sure, that all init vars defined
2617    setTimeout(function () {
2618      wpbc_cal_days_select__single(resource_id);
2619    }, 1000);
2620  });
2621}
2622
2623/**
2624 * Set Single Day selection
2625 * Can be run at any  time,  when  calendar defined - useful for console run.
2626 *
2627 * @param resource_id		ID of booking resource
2628 */
2629function wpbc_cal_days_select__single(resource_id) {
2630  _wpbc.calendar__set_parameters(resource_id, {
2631    'days_select_mode': 'single'
2632  });
2633  wpbc_cal_days_select__re_init(resource_id);
2634  wpbc_cal__re_init(resource_id);
2635}
2636
2637// ---------------------------------------------------------------------------------------------------------------------
2638
2639/**
2640 * Set Multiple Days selection  - after page load
2641 *
2642 * @param resource_id		ID of booking resource
2643 */
2644function wpbc_cal_ready_days_select__multiple(resource_id) {
2645  // Re-define selection, only after page loaded with all init vars
2646  jQuery(document).ready(function () {
2647    // Wait 1 second, just to  be sure, that all init vars defined
2648    setTimeout(function () {
2649      wpbc_cal_days_select__multiple(resource_id);
2650    }, 1000);
2651  });
2652}
2653
2654/**
2655 * Set Multiple Days selection
2656 * Can be run at any  time,  when  calendar defined - useful for console run.
2657 *
2658 * @param resource_id		ID of booking resource
2659 */
2660function wpbc_cal_days_select__multiple(resource_id) {
2661  _wpbc.calendar__set_parameters(resource_id, {
2662    'days_select_mode': 'multiple'
2663  });
2664  wpbc_cal_days_select__re_init(resource_id);
2665  wpbc_cal__re_init(resource_id);
2666}
2667
2668// ---------------------------------------------------------------------------------------------------------------------
2669
2670/**
2671 * Set Fixed Days selection with  1 mouse click  - after page load
2672 *
2673 * @integer resource_id			- 1				   -- ID of booking resource (calendar) -
2674 * @integer days_number			- 3				   -- number of days to  select	-
2675 * @array week_days__start	- [-1] | [ 1, 5]   --  { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2676 */
2677function wpbc_cal_ready_days_select__fixed(resource_id, days_number) {
2678  var week_days__start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [-1];
2679  // Re-define selection, only after page loaded with all init vars
2680  jQuery(document).ready(function () {
2681    // Wait 1 second, just to  be sure, that all init vars defined
2682    setTimeout(function () {
2683      wpbc_cal_days_select__fixed(resource_id, days_number, week_days__start);
2684    }, 1000);
2685  });
2686}
2687
2688/**
2689 * Set Fixed Days selection with  1 mouse click
2690 * Can be run at any  time,  when  calendar defined - useful for console run.
2691 *
2692 * @integer resource_id			- 1				   -- ID of booking resource (calendar) -
2693 * @integer days_number			- 3				   -- number of days to  select	-
2694 * @array week_days__start	- [-1] | [ 1, 5]   --  { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2695 */
2696function wpbc_cal_days_select__fixed(resource_id, days_number) {
2697  var week_days__start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [-1];
2698  _wpbc.calendar__set_parameters(resource_id, {
2699    'days_select_mode': 'fixed'
2700  });
2701  _wpbc.calendar__set_parameters(resource_id, {
2702    'fixed__days_num': parseInt(days_number)
2703  }); // Number of days selection with 1 mouse click
2704  _wpbc.calendar__set_parameters(resource_id, {
2705    'fixed__week_days__start': week_days__start
2706  }); // { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2707
2708  wpbc_cal_days_select__re_init(resource_id);
2709  wpbc_cal__re_init(resource_id);
2710}
2711
2712// ---------------------------------------------------------------------------------------------------------------------
2713
2714/**
2715 * Set Range Days selection  with  2 mouse clicks  - after page load
2716 *
2717 * @integer resource_id			- 1				   		-- ID of booking resource (calendar)
2718 * @integer days_min			- 7				   		-- Min number of days to select
2719 * @integer days_max			- 30			   		-- Max number of days to select
2720 * @array days_specific			- [] | [7,14,21,28]		-- Restriction for Specific number of days selection
2721 * @array week_days__start		- [-1] | [ 1, 5]   		--  { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2722 */
2723function wpbc_cal_ready_days_select__range(resource_id, days_min, days_max) {
2724  var days_specific = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2725  var week_days__start = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [-1];
2726  // Re-define selection, only after page loaded with all init vars
2727  jQuery(document).ready(function () {
2728    // Wait 1 second, just to  be sure, that all init vars defined
2729    setTimeout(function () {
2730      wpbc_cal_days_select__range(resource_id, days_min, days_max, days_specific, week_days__start);
2731    }, 1000);
2732  });
2733}
2734
2735/**
2736 * Set Range Days selection  with  2 mouse clicks
2737 * Can be run at any  time,  when  calendar defined - useful for console run.
2738 *
2739 * @integer resource_id			- 1				   		-- ID of booking resource (calendar)
2740 * @integer days_min			- 7				   		-- Min number of days to select
2741 * @integer days_max			- 30			   		-- Max number of days to select
2742 * @array days_specific			- [] | [7,14,21,28]		-- Restriction for Specific number of days selection
2743 * @array week_days__start		- [-1] | [ 1, 5]   		--  { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2744 */
2745function wpbc_cal_days_select__range(resource_id, days_min, days_max) {
2746  var days_specific = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2747  var week_days__start = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [-1];
2748  _wpbc.calendar__set_parameters(resource_id, {
2749    'days_select_mode': 'dynamic'
2750  });
2751  _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_min', parseInt(days_min)); // Min. Number of days selection with 2 mouse clicks
2752  _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_max', parseInt(days_max)); // Max. Number of days selection with 2 mouse clicks
2753  _wpbc.calendar__set_param_value(resource_id, 'dynamic__days_specific', days_specific); // Example [5,7]
2754  _wpbc.calendar__set_param_value(resource_id, 'dynamic__week_days__start', week_days__start); // { -1 - Any | 0 - Su,  1 - Mo,  2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat }
2755
2756  wpbc_cal_days_select__re_init(resource_id);
2757  wpbc_cal__re_init(resource_id);
2758}
2759
2760/**
2761 * ====================================================================================================================
2762 *	includes/__js/cal_ajx_load/wpbc_cal_ajx.js
2763 * ====================================================================================================================
2764 */
2765
2766// ---------------------------------------------------------------------------------------------------------------------
2767//  A j a x    L o a d    C a l e n d a r    D a t a
2768// ---------------------------------------------------------------------------------------------------------------------
2769
2770function wpbc_calendar__load_data__ajx(params) {
2771  // FixIn: 9.8.6.2.
2772  wpbc_calendar__loading__start(params['resource_id']);
2773
2774  // Trigger event for calendar before loading Booking data,  but after showing Calendar.
2775  if (jQuery('#calendar_booking' + params['resource_id']).length > 0) {
2776    var target_elm = jQuery('body').trigger("wpbc_calendar_ajx__before_loaded_data", [params['resource_id']]);
2777    //jQuery( 'body' ).on( 'wpbc_calendar_ajx__before_loaded_data', function( event, resource_id ) { ... } );
2778  }
2779  if (wpbc_balancer__is_wait(params, 'wpbc_calendar__load_data__ajx')) {
2780    return false;
2781  }
2782
2783  // FixIn: 9.8.6.2.
2784  wpbc_calendar__blur__stop(params['resource_id']);
2785
2786  // -----------------------------------------------------------------------------------------------------------------
2787  // == Get start / end dates from  the Booking Calendar shortcode. ==
2788  // Example: [booking calendar_dates_start='2026-01-01' calendar_dates_end='2026-12-31'  resource_id=1]              // FixIn: 10.13.1.4.
2789  // -----------------------------------------------------------------------------------------------------------------
2790  if (false !== wpbc_calendar__get_dates_start(params['resource_id'])) {
2791    if (!params['dates_to_check']) {
2792      params['dates_to_check'] = [];
2793    }
2794    var dates_start = wpbc_calendar__get_dates_start(params['resource_id']); // E.g. - local__min_date = new Date( 2025, 0, 1 );
2795    if (false !== dates_start) {
2796      params['dates_to_check'][0] = wpbc__get__sql_class_date(dates_start);
2797    }
2798  }
2799  if (false !== wpbc_calendar__get_dates_end(params['resource_id'])) {
2800    if (!params['dates_to_check']) {
2801      params['dates_to_check'] = [];
2802    }
2803    var dates_end = wpbc_calendar__get_dates_end(params['resource_id']); // E.g. - local__min_date = new Date( 2025, 0, 1 );
2804    if (false !== dates_end) {
2805      params['dates_to_check'][1] = wpbc__get__sql_class_date(dates_end);
2806      if (!params['dates_to_check'][0]) {
2807        params['dates_to_check'][0] = wpbc__get__sql_class_date(new Date());
2808      }
2809    }
2810  }
2811  // -----------------------------------------------------------------------------------------------------------------
2812
2813  // console.groupEnd(); console.time('resource_id_' + params['resource_id']);
2814  console.groupCollapsed('WPBC_AJX_CALENDAR_LOAD');
2815  console.log(' == Before Ajax Send - calendars_all__get() == ', _wpbc.calendars_all__get());
2816  if ('function' === typeof wpbc_hook__init_timeselector) {
2817    wpbc_hook__init_timeselector();
2818  }
2819
2820  // Start Ajax
2821  jQuery.post(wpbc_url_ajax, {
2822    action: 'WPBC_AJX_CALENDAR_LOAD',
2823    wpbc_ajx_user_id: _wpbc.get_secure_param('user_id'),
2824    nonce: _wpbc.get_secure_param('nonce'),
2825    wpbc_ajx_locale: _wpbc.get_secure_param('locale'),
2826    calendar_request_params: params // Usually like: { 'resource_id': 1, 'max_days_count': 365 }
2827  },
2828  /**
2829   * S u c c e s s
2830   *
2831   * @param response_data		-	its object returned from  Ajax - class-live-search.php
2832   * @param textStatus		-	'success'
2833   * @param jqXHR				-	Object
2834   */
2835  function (response_data, textStatus, jqXHR) {
2836    // console.timeEnd('resource_id_' + response_data['resource_id']);
2837    console.log(' == Response WPBC_AJX_CALENDAR_LOAD == ', response_data);
2838    console.groupEnd();
2839
2840    // FixIn: 9.8.6.2.
2841    var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url(this.data);
2842    wpbc_balancer__completed(ajx_post_data__resource_id, 'wpbc_calendar__load_data__ajx');
2843
2844    // Probably Error
2845    if (_typeof(response_data) !== 'object' || response_data === null) {
2846      var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data);
2847      var message_type = 'info';
2848      if ('' === response_data) {
2849        response_data = 'The server responds with an empty string. The server probably stopped working unexpectedly. <br>Please check your <strong>error.log</strong> in your server configuration for relative errors.';
2850        message_type = 'warning';
2851      }
2852
2853      // Show Message
2854      wpbc_front_end__show_message(response_data, {
2855        'type': message_type,
2856        'show_here': {
2857          'jq_node': jq_node,
2858          'where': 'after'
2859        },
2860        'is_append': true,
2861        'style': 'text-align:left;',
2862        'delay': 0
2863      });
2864      return;
2865    }
2866
2867    // Show Calendar
2868    wpbc_calendar__loading__stop(response_data['resource_id']);
2869
2870    // -------------------------------------------------------------------------------------------------
2871    // Bookings - Dates
2872    _wpbc.bookings_in_calendar__set_dates(response_data['resource_id'], response_data['ajx_data']['dates']);
2873
2874    // Bookings - Child or only single booking resource in dates
2875    _wpbc.booking__set_param_value(response_data['resource_id'], 'resources_id_arr__in_dates', response_data['ajx_data']['resources_id_arr__in_dates']);
2876
2877    // Aggregate booking resources,  if any ?
2878    _wpbc.booking__set_param_value(response_data['resource_id'], 'aggregate_resource_id_arr', response_data['ajx_data']['aggregate_resource_id_arr']);
2879    // -------------------------------------------------------------------------------------------------
2880
2881    // Update calendar
2882    wpbc_calendar__update_look(response_data['resource_id']);
2883    if ('function' === typeof wpbc_hook__init_timeselector) {
2884      wpbc_hook__init_timeselector();
2885    }
2886    if ('undefined' !== typeof response_data['ajx_data']['ajx_after_action_message'] && '' != response_data['ajx_data']['ajx_after_action_message'].replace(/\n/g, "<br />")) {
2887      var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data);
2888
2889      // Show Message
2890      wpbc_front_end__show_message(response_data['ajx_data']['ajx_after_action_message'].replace(/\n/g, "<br />"), {
2891        'type': 'undefined' !== typeof response_data['ajx_data']['ajx_after_action_message_status'] ? response_data['ajx_data']['ajx_after_action_message_status'] : 'info',
2892        'show_here': {
2893          'jq_node': jq_node,
2894          'where': 'after'
2895        },
2896        'is_append': true,
2897        'style': 'text-align:left;',
2898        'delay': 10000
2899      });
2900    }
2901
2902    // Trigger event that calendar has been		 // FixIn: 10.0.0.44.
2903    if (jQuery('#calendar_booking' + response_data['resource_id']).length > 0) {
2904      var target_elm = jQuery('body').trigger("wpbc_calendar_ajx__loaded_data", [response_data['resource_id']]);
2905      //jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function( event, resource_id ) { ... } );
2906    }
2907
2908    //jQuery( '#ajax_respond' ).html( response_data );		// For ability to show response, add such DIV element to page
2909  }).fail(function (jqXHR, textStatus, errorThrown) {
2910    if (window.console && window.console.log) {
2911      console.log('Ajax_Error', jqXHR, textStatus, errorThrown);
2912    }
2913    var ajx_post_data__resource_id = wpbc_get_resource_id__from_ajx_post_data_url(this.data);
2914    wpbc_balancer__completed(ajx_post_data__resource_id, 'wpbc_calendar__load_data__ajx');
2915
2916    // Get Content of Error Message
2917    var error_message = '<strong>' + 'Error!' + '</strong> ' + errorThrown;
2918    if (jqXHR.status) {
2919      error_message += ' (<b>' + jqXHR.status + '</b>)';
2920      if (403 == jqXHR.status) {
2921        error_message += '<br> Probably nonce for this page has been expired. Please <a href="javascript:void(0)" onclick="javascript:location.reload();">reload the page</a>.';
2922        error_message += '<br> Otherwise, please check this <a style="font-weight: 600;" href="https://wpbookingcalendar.com/faq/request-do-not-pass-security-check/?after_update=10.1.1">troubleshooting instruction</a>.<br>';
2923      }
2924    }
2925    var message_show_delay = 3000;
2926    if (jqXHR.responseText) {
2927      error_message += ' ' + jqXHR.responseText;
2928      message_show_delay = 10;
2929    }
2930    error_message = error_message.replace(/\n/g, "<br />");
2931    var jq_node = wpbc_get_calendar__jq_node__for_messages(this.data);
2932
2933    /**
2934     * If we make fast clicking on different pages,
2935     * then under calendar will show error message with  empty  text, because ajax was not received.
2936     * To  not show such warnings we are set delay  in 3 seconds.  var message_show_delay = 3000;
2937     */
2938    var closed_timer = setTimeout(function () {
2939      // Show Message
2940      wpbc_front_end__show_message(error_message, {
2941        'type': 'error',
2942        'show_here': {
2943          'jq_node': jq_node,
2944          'where': 'after'
2945        },
2946        'is_append': true,
2947        'style': 'text-align:left;',
2948        'css_class': 'wpbc_fe_message_alt',
2949        'delay': 0
2950      });
2951    }, parseInt(message_show_delay));
2952  })
2953  // .done(   function ( data, textStatus, jqXHR ) {   if ( window.console && window.console.log ){ console.log( 'second success', data, textStatus, jqXHR ); }    })
2954  // .always( function ( data_jqXHR, textStatus, jqXHR_errorThrown ) {   if ( window.console && window.console.log ){ console.log( 'always finished', data_jqXHR, textStatus, jqXHR_errorThrown ); }     })
2955  ; // End Ajax
2956}
2957
2958// ---------------------------------------------------------------------------------------------------------------------
2959// Support
2960// ---------------------------------------------------------------------------------------------------------------------
2961
2962/**
2963 * Get Calendar jQuery node for showing messages during Ajax
2964 * This parameter:   calendar_request_params[resource_id]   parsed from this.data Ajax post  data
2965 *
2966 * @param ajx_post_data_url_params		 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params'
2967 * @returns {string}	''#calendar_booking1'  |   '.booking_form_div' ...
2968 *
2969 * Example    var jq_node  = wpbc_get_calendar__jq_node__for_messages( this.data );
2970 */
2971function wpbc_get_calendar__jq_node__for_messages(ajx_post_data_url_params) {
2972  var jq_node = '.booking_form_div';
2973  var calendar_resource_id = wpbc_get_resource_id__from_ajx_post_data_url(ajx_post_data_url_params);
2974  if (calendar_resource_id > 0) {
2975    jq_node = '#calendar_booking' + calendar_resource_id;
2976  }
2977  return jq_node;
2978}
2979
2980/**
2981 * Get resource ID from ajx post data url   usually  from  this.data  = 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params'
2982 *
2983 * @param ajx_post_data_url_params		 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params'
2984 * @returns {int}						 1 | 0  (if errror then  0)
2985 *
2986 * Example    var jq_node  = wpbc_get_calendar__jq_node__for_messages( this.data );
2987 */
2988function wpbc_get_resource_id__from_ajx_post_data_url(ajx_post_data_url_params) {
2989  // Get booking resource ID from Ajax Post Request  -> this.data = 'action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params'
2990  var calendar_resource_id = wpbc_get_uri_param_by_name('calendar_request_params[resource_id]', ajx_post_data_url_params);
2991  if (null !== calendar_resource_id && '' !== calendar_resource_id) {
2992    calendar_resource_id = parseInt(calendar_resource_id);
2993    if (calendar_resource_id > 0) {
2994      return calendar_resource_id;
2995    }
2996  }
2997  return 0;
2998}
2999
3000/**
3001 * Get parameter from URL  -  parse URL parameters,  like this: action=WPBC_AJX_CALENDAR_LOAD...&calendar_request_params%5Bresource_id%5D=2&calendar_request_params%5Bbooking_hash%5D=&calendar_request_params
3002 * @param name  parameter  name,  like 'calendar_request_params[resource_id]'
3003 * @param url	'parameter  string URL'
3004 * @returns {string|null}   parameter value
3005 *
3006 * Example: 		wpbc_get_uri_param_by_name( 'calendar_request_params[resource_id]', this.data );  -> '2'
3007 */
3008function wpbc_get_uri_param_by_name(name, url) {
3009  url = decodeURIComponent(url);
3010  name = name.replace(/[\[\]]/g, '\\$&');
3011  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
3012    results = regex.exec(url);
3013  if (!results) return null;
3014  if (!results[2]) return '';
3015  return decodeURIComponent(results[2].replace(/\+/g, ' '));
3016}
3017
3018/**
3019 * =====================================================================================================================
3020 *	includes/__js/front_end_messages/wpbc_fe_messages.js
3021 * =====================================================================================================================
3022 */
3023
3024// ---------------------------------------------------------------------------------------------------------------------
3025// Show Messages at Front-Edn side
3026// ---------------------------------------------------------------------------------------------------------------------
3027
3028/**
3029 * Show message in content
3030 *
3031 * @param message				Message HTML
3032 * @param params = {
3033 *								'type'     : 'warning',							// 'error' | 'warning' | 'info' | 'success'
3034 *								'show_here' : {
3035 *													'jq_node' : '',				// any jQuery node definition
3036 *													'where'   : 'inside'		// 'inside' | 'before' | 'after' | 'right' | 'left'
3037 *											  },
3038 *								'is_append': true,								// Apply  only if 	'where'   : 'inside'
3039 *								'style'    : 'text-align:left;',				// styles, if needed
3040 *							    'css_class': '',								// For example can  be: 'wpbc_fe_message_alt'
3041 *								'delay'    : 0,									// how many microsecond to  show,  if 0  then  show forever
3042 *								'if_visible_not_show': false					// if true,  then do not show message,  if previos message was not hided (not apply if 'where'   : 'inside' )
3043 *				};
3044 * Examples:
3045 * 			var html_id = wpbc_front_end__show_message( 'You can test days selection in calendar', {} );
3046 *
3047 *			var notice_message_id = wpbc_front_end__show_message( _wpbc.get_message( 'message_check_required' ), { 'type': 'warning', 'delay': 10000, 'if_visible_not_show': true,
3048 *																  'show_here': {'where': 'right', 'jq_node': el,} } );
3049 *
3050 *			wpbc_front_end__show_message( response_data[ 'ajx_data' ][ 'ajx_after_action_message' ].replace( /\n/g, "<br />" ),
3051 *											{   'type'     : ( 'undefined' !== typeof( response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] ) )
3052 *															  ? response_data[ 'ajx_data' ][ 'ajx_after_action_message_status' ] : 'info',
3053 *												'show_here': {'jq_node': jq_node, 'where': 'after'},
3054 *												'css_class':'wpbc_fe_message_alt',
3055 *												'delay'    : 10000
3056 *											} );
3057 *
3058 *
3059 * @returns string  - HTML ID		or 0 if not showing during this time.
3060 */
3061function wpbc_front_end__show_message(message) {
3062  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3063  var params_default = {
3064    'type': 'warning',
3065    // 'error' | 'warning' | 'info' | 'success'
3066    'show_here': {
3067      'jq_node': '',
3068      // any jQuery node definition
3069      'where': 'inside' // 'inside' | 'before' | 'after' | 'right' | 'left'
3070    },
3071    'is_append': true,
3072    // Apply  only if 	'where'   : 'inside'
3073    'style': 'text-align:left;',
3074    // styles, if needed
3075    'css_class': '',
3076    // For example can  be: 'wpbc_fe_message_alt'
3077    'delay': 0,
3078    // how many microsecond to  show,  if 0  then  show forever
3079    'if_visible_not_show': false,
3080    // if true,  then do not show message,  if previos message was not hided (not apply if 'where'   : 'inside' )
3081    'is_scroll': true // is scroll  to  this element
3082  };
3083  for (var p_key in params) {
3084    params_default[p_key] = params[p_key];
3085  }
3086  params = params_default;
3087  var unique_div_id = new Date();
3088  unique_div_id = 'wpbc_notice_' + unique_div_id.getTime();
3089  params['css_class'] += ' wpbc_fe_message';
3090  if (params['type'] == 'error') {
3091    params['css_class'] += ' wpbc_fe_message_error';
3092    message = '<i class="menu_icon icon-1x wpbc_icn_report_gmailerrorred"></i>' + message;
3093  }
3094  if (params['type'] == 'warning') {
3095    params['css_class'] += ' wpbc_fe_message_warning';
3096    message = '<i class="menu_icon icon-1x wpbc_icn_warning"></i>' + message;
3097  }
3098  if (params['type'] == 'info') {
3099    params['css_class'] += ' wpbc_fe_message_info';
3100  }
3101  if (params['type'] == 'success') {
3102    params['css_class'] += ' wpbc_fe_message_success';
3103    message = '<i class="menu_icon icon-1x wpbc_icn_done_outline"></i>' + message;
3104  }
3105  var scroll_to_element = '<div id="' + unique_div_id + '_scroll" style="display:none;"></div>';
3106  message = '<div id="' + unique_div_id + '" class="wpbc_front_end__message ' + params['css_class'] + '" style="' + params['style'] + '">' + message + '</div>';
3107  var jq_el_message = false;
3108  var is_show_message = true;
3109  if ('inside' === params['show_here']['where']) {
3110    if (params['is_append']) {
3111      jQuery(params['show_here']['jq_node']).append(scroll_to_element);
3112      jQuery(params['show_here']['jq_node']).append(message);
3113    } else {
3114      jQuery(params['show_here']['jq_node']).html(scroll_to_element + message);
3115    }
3116  } else if ('before' === params['show_here']['where']) {
3117    jq_el_message = jQuery(params['show_here']['jq_node']).siblings('[id^="wpbc_notice_"]');
3118    if (params['if_visible_not_show'] && jq_el_message.is(':visible')) {
3119      is_show_message = false;
3120      unique_div_id = jQuery(jq_el_message.get(0)).attr('id');
3121    }
3122    if (is_show_message) {
3123      jQuery(params['show_here']['jq_node']).before(scroll_to_element);
3124      jQuery(params['show_here']['jq_node']).before(message);
3125    }
3126  } else if ('after' === params['show_here']['where']) {
3127    jq_el_message = jQuery(params['show_here']['jq_node']).nextAll('[id^="wpbc_notice_"]');
3128    if (params['if_visible_not_show'] && jq_el_message.is(':visible')) {
3129      is_show_message = false;
3130      unique_div_id = jQuery(jq_el_message.get(0)).attr('id');
3131    }
3132    if (is_show_message) {
3133      jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to  set  here before(for handy scroll)
3134      jQuery(params['show_here']['jq_node']).after(message);
3135    }
3136  } else if ('right' === params['show_here']['where']) {
3137    jq_el_message = jQuery(params['show_here']['jq_node']).nextAll('.wpbc_front_end__message_container_right').find('[id^="wpbc_notice_"]');
3138    if (params['if_visible_not_show'] && jq_el_message.is(':visible')) {
3139      is_show_message = false;
3140      unique_div_id = jQuery(jq_el_message.get(0)).attr('id');
3141    }
3142    if (is_show_message) {
3143      jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to  set  here before(for handy scroll)
3144      jQuery(params['show_here']['jq_node']).after('<div class="wpbc_front_end__message_container_right">' + message + '</div>');
3145    }
3146  } else if ('left' === params['show_here']['where']) {
3147    jq_el_message = jQuery(params['show_here']['jq_node']).siblings('.wpbc_front_end__message_container_left').find('[id^="wpbc_notice_"]');
3148    if (params['if_visible_not_show'] && jq_el_message.is(':visible')) {
3149      is_show_message = false;
3150      unique_div_id = jQuery(jq_el_message.get(0)).attr('id');
3151    }
3152    if (is_show_message) {
3153      jQuery(params['show_here']['jq_node']).before(scroll_to_element); // We need to  set  here before(for handy scroll)
3154      jQuery(params['show_here']['jq_node']).before('<div class="wpbc_front_end__message_container_left">' + message + '</div>');
3155    }
3156  }
3157  if (is_show_message && parseInt(params['delay']) > 0) {
3158    var closed_timer = setTimeout(function () {
3159      jQuery('#' + unique_div_id).fadeOut(1500);
3160    }, parseInt(params['delay']));
3161    var closed_timer2 = setTimeout(function () {
3162      jQuery('#' + unique_div_id).trigger('hide');
3163    }, parseInt(params['delay']) + 1501);
3164  }
3165
3166  // Check  if showed message in some hidden parent section and show it. But it must  be lower than '.wpbc_container'
3167  var parent_els = jQuery('#' + unique_div_id).parents().map(function () {
3168    if (!jQuery(this).is('visible') && jQuery('.wpbc_container').has(this)) {
3169      jQuery(this).show();
3170    }
3171  });
3172  if (params['is_scroll']) {
3173    wpbc_do_scroll('#' + unique_div_id + '_scroll');
3174  }
3175  return unique_div_id;
3176}
3177
3178/**
3179 * Error message. 	Preset of parameters for real message function.
3180 *
3181 * @param el		- any jQuery node definition
3182 * @param message	- Message HTML
3183 * @returns string  - HTML ID		or 0 if not showing during this time.
3184 */
3185function wpbc_front_end__show_message__error(jq_node, message) {
3186  var notice_message_id = wpbc_front_end__show_message(message, {
3187    'type': 'error',
3188    'delay': 10000,
3189    'if_visible_not_show': true,
3190    'show_here': {
3191      'where': 'right',
3192      'jq_node': jq_node
3193    }
3194  });
3195  return notice_message_id;
3196}
3197
3198/**
3199 * Error message UNDER element. 	Preset of parameters for real message function.
3200 *
3201 * @param el		- any jQuery node definition
3202 * @param message	- Message HTML
3203 * @returns string  - HTML ID		or 0 if not showing during this time.
3204 */
3205function wpbc_front_end__show_message__error_under_element(jq_node, message, message_delay) {
3206  if ('undefined' === typeof message_delay) {
3207    message_delay = 0;
3208  }
3209  var notice_message_id = wpbc_front_end__show_message(message, {
3210    'type': 'error',
3211    'delay': message_delay,
3212    'if_visible_not_show': true,
3213    'show_here': {
3214      'where': 'after',
3215      'jq_node': jq_node
3216    }
3217  });
3218  return notice_message_id;
3219}
3220
3221/**
3222 * Error message UNDER element. 	Preset of parameters for real message function.
3223 *
3224 * @param el		- any jQuery node definition
3225 * @param message	- Message HTML
3226 * @returns string  - HTML ID		or 0 if not showing during this time.
3227 */
3228function wpbc_front_end__show_message__error_above_element(jq_node, message, message_delay) {
3229  if ('undefined' === typeof message_delay) {
3230    message_delay = 10000;
3231  }
3232  var notice_message_id = wpbc_front_end__show_message(message, {
3233    'type': 'error',
3234    'delay': message_delay,
3235    'if_visible_not_show': true,
3236    'show_here': {
3237      'where': 'before',
3238      'jq_node': jq_node
3239    }
3240  });
3241  return notice_message_id;
3242}
3243
3244/**
3245 * Warning message. 	Preset of parameters for real message function.
3246 *
3247 * @param el		- any jQuery node definition
3248 * @param message	- Message HTML
3249 * @returns string  - HTML ID		or 0 if not showing during this time.
3250 */
3251function wpbc_front_end__show_message__warning(jq_node, message) {
3252  var notice_message_id = wpbc_front_end__show_message(message, {
3253    'type': 'warning',
3254    'delay': 10000,
3255    'if_visible_not_show': true,
3256    'show_here': {
3257      'where': 'right',
3258      'jq_node': jq_node
3259    }
3260  });
3261  wpbc_highlight_error_on_form_field(jq_node);
3262  return notice_message_id;
3263}
3264
3265/**
3266 * Warning message UNDER element. 	Preset of parameters for real message function.
3267 *
3268 * @param el		- any jQuery node definition
3269 * @param message	- Message HTML
3270 * @returns string  - HTML ID		or 0 if not showing during this time.
3271 */
3272function wpbc_front_end__show_message__warning_under_element(jq_node, message) {
3273  var notice_message_id = wpbc_front_end__show_message(message, {
3274    'type': 'warning',
3275    'delay': 10000,
3276    'if_visible_not_show': true,
3277    'show_here': {
3278      'where': 'after',
3279      'jq_node': jq_node
3280    }
3281  });
3282  return notice_message_id;
3283}
3284
3285/**
3286 * Warning message ABOVE element. 	Preset of parameters for real message function.
3287 *
3288 * @param el		- any jQuery node definition
3289 * @param message	- Message HTML
3290 * @returns string  - HTML ID		or 0 if not showing during this time.
3291 */
3292function wpbc_front_end__show_message__warning_above_element(jq_node, message) {
3293  var notice_message_id = wpbc_front_end__show_message(message, {
3294    'type': 'warning',
3295    'delay': 10000,
3296    'if_visible_not_show': true,
3297    'show_here': {
3298      'where': 'before',
3299      'jq_node': jq_node
3300    }
3301  });
3302  return notice_message_id;
3303}
3304
3305/**
3306 * Highlight Error in specific field
3307 *
3308 * @param jq_node					string or jQuery element,  where scroll  to
3309 */
3310function wpbc_highlight_error_on_form_field(jq_node) {
3311  if (!jQuery(jq_node).length) {
3312    return;
3313  }
3314  if (!jQuery(jq_node).is(':input')) {
3315    // Situation with  checkboxes or radio  buttons
3316    var jq_node_arr = jQuery(jq_node).find(':input');
3317    if (!jq_node_arr.length) {
3318      return;
3319    }
3320    jq_node = jq_node_arr.get(0);
3321  }
3322  var params = {};
3323  params['delay'] = 10000;
3324  if (!jQuery(jq_node).hasClass('wpbc_form_field_error')) {
3325    jQuery(jq_node).addClass('wpbc_form_field_error');
3326    if (parseInt(params['delay']) > 0) {
3327      var closed_timer = setTimeout(function () {
3328        jQuery(jq_node).removeClass('wpbc_form_field_error');
3329      }, parseInt(params['delay']));
3330    }
3331  }
3332}
3333
3334/**
3335 * Scroll to specific element
3336 *
3337 * @param jq_node					string or jQuery element,  where scroll  to
3338 * @param extra_shift_offset		int shift offset from  jq_node
3339 */
3340function wpbc_do_scroll(jq_node) {
3341  var extra_shift_offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
3342  if (!jQuery(jq_node).length) {
3343    return;
3344  }
3345  var targetOffset = jQuery(jq_node).offset().top;
3346  if (targetOffset <= 0) {
3347    if (0 != jQuery(jq_node).nextAll(':visible').length) {
3348      targetOffset = jQuery(jq_node).nextAll(':visible').first().offset().top;
3349    } else if (0 != jQuery(jq_node).parent().nextAll(':visible').length) {
3350      targetOffset = jQuery(jq_node).parent().nextAll(':visible').first().offset().top;
3351    }
3352  }
3353  if (jQuery('#wpadminbar').length > 0) {
3354    targetOffset = targetOffset - 50 - 50;
3355  } else {
3356    targetOffset = targetOffset - 20 - 50;
3357  }
3358  targetOffset += extra_shift_offset;
3359
3360  // Scroll only  if we did not scroll before
3361  if (!jQuery('html,body').is(':animated')) {
3362    jQuery('html,body').animate({
3363      scrollTop: targetOffset
3364    }, 500);
3365  }
3366}
3367
3368// FixIn: 10.2.0.4.
3369/**
3370 * Define Popovers for Timelines in WP Booking Calendar
3371 *
3372 * @returns {string|boolean}
3373 */
3374function wpbc_define_tippy_popover() {
3375  if ('function' !== typeof wpbc_tippy) {
3376    console.log('WPBC Error. wpbc_tippy was not defined.');
3377    return false;
3378  }
3379  wpbc_tippy('.popover_bottom.popover_click', {
3380    content: function content(reference) {
3381      var popover_title = reference.getAttribute('data-original-title');
3382      var popover_content = reference.getAttribute('data-content');
3383      return '<div class="popover popover_tippy">' + '<div class="popover-close"><a href="javascript:void(0)" onclick="javascript:this.parentElement.parentElement.parentElement.parentElement.parentElement._tippy.hide();" >&times;</a></div>' + popover_content + '</div>';
3384    },
3385    allowHTML: true,
3386    trigger: 'manual',
3387    interactive: true,
3388    hideOnClick: false,
3389    interactiveBorder: 10,
3390    maxWidth: 550,
3391    theme: 'wpbc-tippy-popover',
3392    placement: 'bottom-start',
3393    touch: ['hold', 500]
3394  });
3395  jQuery('.popover_bottom.popover_click').on('click', function () {
3396    if (this._tippy.state.isVisible) {
3397      this._tippy.hide();
3398    } else {
3399      this._tippy.show();
3400    }
3401  });
3402  wpbc_define_hide_tippy_on_scroll();
3403}
3404function wpbc_define_hide_tippy_on_scroll() {
3405  jQuery('.flex_tl__scrolling_section2,.flex_tl__scrolling_sections').on('scroll', function (event) {
3406    if ('function' === typeof wpbc_tippy) {
3407      wpbc_tippy.hideAll();
3408    }
3409  });
3410}
3411//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Rpc3QvYWxsL19vdXQvd3BiY19hbGwuanMiLCJuYW1lcyI6WyJ3cGJjX3RyaW0iLCJzdHJpbmdfdG9fdHJpbSIsIkFycmF5IiwiaXNBcnJheSIsImpvaW4iLCJ0cmltIiwid3BiY19pbl9hcnJheSIsImFycmF5X2hlcmUiLCJwX3ZhbCIsImkiLCJsIiwibGVuZ3RoIiwid3BiY19jbG9uZV9vYmoiLCJvYmoiLCJKU09OIiwicGFyc2UiLCJzdHJpbmdpZnkiLCJfd3BiYyIsIiQiLCJwX3NlY3VyZSIsInNlY3VyaXR5X29iaiIsInVzZXJfaWQiLCJub25jZSIsImxvY2FsZSIsInNldF9zZWN1cmVfcGFyYW0iLCJwYXJhbV9rZXkiLCJwYXJhbV92YWwiLCJ
3411nZXRfc2VjdXJlX3BhcmFtIiwicF9jYWxlbmRhcnMiLCJjYWxlbmRhcnNfb2JqIiwiY2FsZW5kYXJfX2lzX2RlZmluZWQiLCJyZXNvdXJjZV9pZCIsImNhbGVuZGFyX19pbml0IiwiY2FsZW5kYXJfX2lzX3Byb3BfaW50IiwicHJvcGVydHlfbmFtZSIsInBfY2FsZW5kYXJfaW50X3Byb3BlcnRpZXMiLCJpc19pbmNsdWRlIiwiaW5jbHVkZXMiLCJjYWxlbmRhcnNfYWxsX19zZXQiLCJjYWxlbmRhcnNfYWxsX19nZXQiLCJjYWxlbmRhcl9fZ2V0X3BhcmFtZXRlcnMiLCJjYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMiLCJjYWxlbmRhcl9wcm9wZXJ0eV9vYmoiLCJpc19jb21wbGV0ZV9vdmVyd3JpdGUiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJwcm9wX25hbWUiLCJjYWxlbmRhcl9fc2V0X3BhcmFtX3ZhbHVlIiwicHJvcF92YWx1ZSIsImNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUiLCJwYXJzZUludCIsInBfYm9va2luZ3MiLCJib29raW5nc19vYmoiLCJib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCIsImJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXQiLCJib29raW5nc19pbl9jYWxlbmRhcl9fc2V0IiwiY2FsZW5kYXJfb2JqIiwiYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9kYXRlcyIsImJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMiLCJkYXRlc19vYmoiLCJib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlIiwic3FsX2NsYXNzX2RheSIsImJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSIsImJvb2tpbmdfX2dldF9wYXJhbV92YWx1ZSIsImJvb2tpbmdzX2luX2NhbGVuZGFyc19fc2V0X2FsbCIsImJvb2tpbmdzX2luX2NhbGVuZGFyc19fZ2V0X2FsbCIsInBfc2Vhc29ucyIsInNlYXNvbnNfb2JqIiwic2Vhc29uc19fc2V0Iiwic2Vhc29uX25hbWVfa2V5IiwicHVzaCIsInNlYXNvbnNfX2dldF9mb3JfZGF0ZSIsInBfb3RoZXIiLCJvdGhlcl9vYmoiLCJzZXRfb3RoZXJfcGFyYW0iLCJnZXRfb3RoZXJfcGFyYW0iLCJnZXRfb3RoZXJfcGFyYW1fX2FsbCIsInBfbWVzc2FnZXMiLCJtZXNzYWdlc19vYmoiLCJzZXRfbWVzc2FnZSIsImdldF9tZXNzYWdlIiwiZ2V0X21lc3NhZ2VzX19hbGwiLCJqUXVlcnkiLCJwX2JhbGFuY2VyIiwiYmFsYW5jZXJfb2JqIiwiYmFsYW5jZXJfX3NldF9tYXhfdGhyZWFkcyIsIm1heF90aHJlYWRzIiwiYmFsYW5jZXJfX2lzX2RlZmluZWQiLCJiYWxhbmNlcl9faW5pdCIsImZ1bmN0aW9uX25
3411hbWUiLCJwYXJhbXMiLCJiYWxhbmNlX29iaiIsImJhbGFuY2VyX19pc19hbHJlYWR5X3J1biIsImJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQiLCJiYWxhbmNlcl9fY2FuX2lfcnVuIiwiYmFsYW5jZXJfX2FkZF90b19fcnVuIiwiYmFsYW5jZXJfX2FkZF90b19fd2FpdCIsImJhbGFuY2VyX19yZW1vdmVfZnJvbV9fd2FpdF9saXN0IiwicmVtb3ZlZF9lbCIsInNwbGljZSIsInBvcCIsImZpbHRlciIsInYiLCJiYWxhbmNlcl9fcmVtb3ZlX2Zyb21fX3J1bl9saXN0IiwiYmFsYW5jZXJfX3J1bl9uZXh0IiwiYmFsYW5jZXJfX3J1biIsIndwYmNfY2FsZW5kYXJfX2xvYWRfZGF0YV9fYWp4Iiwid3BiY19iYWxhbmNlcl9faXNfd2FpdCIsImJhbGFuY2VyX3N0YXR1cyIsIndwYmNfYmFsYW5jZXJfX2NvbXBsZXRlZCIsIndwYmNfY2FsZW5kYXJfc2hvdyIsImhhc0NsYXNzIiwibG9jYWxfX2lzX3JhbmdlX3NlbGVjdCIsImxvY2FsX19tdWx0aV9kYXlzX3NlbGVjdF9udW0iLCJsb2NhbF9fbWluX2RhdGUiLCJEYXRlIiwibG9jYWxfX21heF9kYXRlIiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0Iiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX2VuZCIsImxvY2F0aW9uIiwiaHJlZiIsImluZGV4T2YiLCJsb2NhbF9fc3RhcnRfd2Vla2RheSIsImxvY2FsX19udW1iZXJfb2ZfbW9udGhzIiwidGV4dCIsImRhdGVwaWNrIiwiYmVmb3JlU2hvd0RheSIsImpzX2RhdGUiLCJ3cGJjX19jYWxlbmRhcl9fYXBwbHlfY3NzX3RvX2RheXMiLCJvblNlbGVjdCIsInN0cmluZ19kYXRlcyIsImpzX2RhdGVzX2FyciIsIndwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyIsIm9uSG92ZXIiLCJzdHJpbmdfZGF0ZSIsIndwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzIiwib25DaGFuZ2VNb250aFllYXIiLCJ5ZWFyIiwicmVhbF9tb250aCIsImpzX2RhdGVfXzFzdF9kYXlfaW5fbW9udGgiLCJzaG93T24iLCJudW1iZXJPZk1vbnRocyIsInN0ZXBNb250aHMiLCJwcmV2VGV4dCIsIm5leHRUZXh0IiwiZGF0ZUZvcm1hdCIsImNoYW5nZU1vbnRoIiwiY2hhbmdlWWVhciIsIm1pbkRhdGUiLCJtYXhEYXRlIiwic2hvd1N0YXR1cyIsIm11bHRpU2VwYXJhdG9yIiwiY2xvc2VBdFRvcCIsImZpcnN0RGF5IiwiZ290b0N1cnJlbnQiLCJoaWRlSWZOb1ByZXZOZXh0IiwibXVsdGlTZWxlY3QiLCJyYW5nZVNlbGVjdCIsInVzZVRoZW1lUm9sbGVyIiwic2V0VGltZW91dCIsIndwYmNfY2FsZW5kYXJzX19jbGVhcl9kYXlzX2hpZ2hsaWdodGluZyIsInN0YXJ0X2JrX21vbnRoIiwid3BiY19jYWxlbmRhcl9fc2Nyb2xsX3RvIiwiZGF0ZSIsImNhbGVuZGFyX3BhcmFtc19hcnIiLCJkYXRlcGlja190aGlzIiwidG9kYXlfZGF0ZSIsImNsYXNzX2RheSIsIndwYmNfX2dldF9fdGRfY2xhc3NfZGF0ZSIsIndwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUiLCJzZWxlY3RlZF9kYXRlc19zcWwiLCJ3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIiLCJkYXRlX2Jvb2tpbmdzX29iaiIsImNzc19jbGFzc2VzX19mb3JfZGF0ZSIsImdldERheSIsImlzX2RheV9zZWxlY3RhYmxlIiwic2Vhc29uX25hbWVzX2FyciIsInNlYXNvbl9rZXkiLCJ0b1N0cmluZyIsInJlcGxhY2UiLCJpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGUiLCJkYXRlX2Jvb2tpbmdfb2JqIiwidG9vbHRpcF90ZXh0Iiwid3BiY19zZXRfdG9vbHRpcF9fX2Zvcl9fY2FsZW5kYXJfZGF0ZSIsImlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciIsImlzX2Jvb2tpbmdfZm9ybV9leGlzdCIsImNzc19vZl9jYWxlbmRhciIsImNzcyIsIndwYmNfX2NhbGVuZGFyX19kb19kYXlzX2hpZ2hsaWdodF9fYnMiLCJ3cGJjX2NhbGVuZGFyX191bnNlbGVjdF9hbGxfZGF0ZXMiLCJyZW1vdmUiLCJ2YWwiLCJ3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzIiwid3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSIsIm1vdXNlX2NsaWNrZWRfZGF0ZXMiLCJhbGxfc2VsZWN0ZWRfZGF0ZXNfYXJyIiwidHJpZ2dlciIsImRvY3VtZW50IiwicmVhZHkiLCJvbiIsImV2ZW50IiwiY2xvc2VkX3RpbWVyIiwibWlkZGxlX2RheXNfb3BhY2l0eSIsIm5vdCIsInRpbWVfZmllbGRzX29ial9hcnIiLCJ3cGJjX2dldF9fdGltZV9maWVsZHNfX2luX2Jvb2tpbmdfZm9ybV9fYXNfYXJyIiwic2VsZWN0ZWRfZGF0ZXNfYXJyIiwiY2hpbGRfcmVzb3VyY2VzX2FyciIsInNxbF9kYXRlIiwiY2hpbGRfcmVzb3VyY2VfaWQiLCJtZXJnZWRfc2Vjb25kcyIsInRpbWVfZmllbGRzX29iaiIsImlzX2ludGVyc2VjdCIsImlzX2NoZWNrX2luIiwidG9kYXlfdGltZV9fcmVhbCIsInRvZGF5X3RpbWVfX3NoaWZ0IiwiZmllbGRfa2V5IiwiZGlzYWJsZWQiLCJpc190aW1lX2luX3Bhc3QiLCJ3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCIsIm5hbWUiLCJob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQiLCJyZXNfa2V5IiwiYm9va2VkX3RpbWVfc2xvdHMiLCJ0aW1lc19hc19zZWNvbmRzIiwid3BiY19pc19pbnRlcnNlY3RfX3JhbmdlX3RpbWVfaW50ZXJ2YWwiLCJ3cGJjX2lzX2ludGVyc2VjdF9fb25lX3RpbWVfaW50ZXJ2YWwiLCJ3cGJjX19odG1sX190aW1lX2ZpZWxkX29wdGlvbnNfX3NldF9kaXNhYmxlZCIsImpzX2N1cnJlbnRfdGltZV90b19jaGVjayIsInNxbF9kYXRlX2FyciIsInNwbGl0Iiwic3FsX2RhdGVfX21pZG5pZ2h0Iiwic3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzIiwiZ2V0VGltZSIsInRpbWVzX2FzX3NlY29uZHNfY2hlY2siLCJ0aW1lX0EiLCJ0aW1lX2ludGVydmFsX0IiLCJqIiwidGltZV9pbnRlcnZhbF9BIiwid3BiY19pbnRlcnZhbHNfX2lzX2ludGVyc2VjdGVkIiwidGltZV9maWVsZHNfYXJyIiwiY3RmIiwidGltZV9maWVsZCIsInRpbWVfb3B0aW9uIiwianF1ZXJ5X29wdGlvbiIsInZhbHVlX29wdGlvbl9zZWNvbmRzX2FyciIsInN0YXJ0X2VuZF90aW1lc19hcnIiLCJ0aW1lX2luX3NlY29uZHMiLCJhdHRyIiwicHJvcCIsImFkZENsYXNzIiwicGFyZW50IiwiZmluZCIsInJlbW92ZUNsYXNzIiwid3BiY19pc190aGlzX3RpbWVzbG90X19mdWxsX2RheV9ib29rZWQiLCJ0aW1lc2xvdF9hcnJfaW5fc2Vjb25kcyIsIm4iLCJzb3J0Iiwid3BiY19nZXRfX3NlbGVjdGVkX3RpbWVfZmllbGRzX19pbl9ib29raW5nX2Zvcm1fX2FzX2FyciIsImlzX29ubHlfc2VsZWN0ZWRfdGltZSIsInRleHRfdGltZV9maWVsZHNfYXJyIiwidGYiLCJ0ZXh0X2pxdWVyeSIsInRpbWVfX2hfbV9fYXJyIiwidGV4dF90aW1lX2luX3NlY29uZHMiLCJ0ZXh0X3RpbWVzX2FzX3
3411NlY29uZHMiLCJ3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCIsIl9nZXRJbnN0IiwiZ2V0IiwiaW5zdCIsInN0YXlPcGVuIiwiZGF0ZXMiLCJfdXBkYXRlRGF0ZXBpY2siLCJtb250aCIsImN1cnNvckRhdGUiLCJzZXRGdWxsWWVhciIsInNldE1vbnRoIiwic2V0RGF0ZSIsImRyYXdNb250aCIsImdldE1vbnRoIiwiZHJhd1llYXIiLCJnZXRGdWxsWWVhciIsIl9ub3RpZnlDaGFuZ2UiLCJfYWRqdXN0SW5zdERhdGUiLCJfc2hvd0RhdGUiLCJ3cGJjX2lzX3RoaXNfZGF5X3NlbGVjdGFibGUiLCJ3cGJjX2lzX3RoaXNfZGF5X2Ftb25nX3NlbGVjdGVkX2RheXMiLCJqc19kYXRlX3RvX2NoZWNrIiwiZGF0ZV9pbmRleCIsImdldERhdGUiLCJ3cGJjX19nZXRfX2pzX2RhdGUiLCJzcWxfY2xhc3NfZGF0ZSIsInNxbF9jbGFzc19kYXRlX2FyciIsImRhdGVfanMiLCJzZXRIb3VycyIsInNldE1pbnV0ZXMiLCJzZXRTZWNvbmRzIiwic2V0TWlsbGlzZWNvbmRzIiwidGRfY2xhc3NfZGF5Iiwid3BiY19fZ2V0X19kYXRlX3BhcmFtc19fZnJvbV9zdHJpbmdfZGF0ZSIsInNlcGFyYXRvciIsImRhdGVfYXJyIiwiZGF0ZV9vYmoiLCJ3cGJjX2NhbGVuZGFyX19sb2FkaW5nX19zdGFydCIsIm5leHQiLCJhZnRlciIsIndwYmNfY2FsZW5kYXJfX2JsdXJfX3N0YXJ0Iiwid3BiY19jYWxlbmRhcl9fbG9hZGluZ19fc3RvcCIsIndwYmNfY2FsZW5kYXJfX2JsdXJfX3N0b3AiLCJ3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayIsIndwYmNfY2FsZW5kYXJfX3VwZGF0ZV9tb250aHNfbnVtYmVyIiwibW9udGhzX251bWJlciIsInNldHRpbmdzIiwid3BiY19fY2FsZW5kYXJfX2NoYW5nZV9za2luIiwic2VsZWN0ZWRfc2tpbl91cmwiLCJzdHlsZXNoZWV0IiwiZ2V0RWxlbWVudEJ5SWQiLCJwYXJlbnROb2RlIiwicmVtb3ZlQ2hpbGQiLCJoZWFkSUQiLCJnZXRFbGVtZW50c0J5VGFnTmFtZSIsImNzc05vZGUiLCJjcmVhdGVFbGVtZW50IiwidHlwZSIsInNldEF0dHJpYnV0ZSIsInJlbCIsIm1lZGlhIiwiYXBwZW5kQ2hpbGQiLCJ3cGJjX19jc3NfX2NoYW5nZV9za2luIiwic3R5bGVzaGVldF9pZCIsIndwYmNfaW50ZXJ2YWxzX19tZXJnZV9pbmVyc2VjdGVkIiwiaW50ZXJ2YWxzIiwibWVyZ2VkIiwiYSIsImIiLCJtZXJnZWRJbnRlcnZhbCIsImludGVydmFsIiwiTWF0aCIsIm1heCIsImludGVydmFsX0EiLCJpbnRlcnZhbF9CIiwiaXNfaW50ZXJzZWN0ZWQiLCJtaW4iLCJ3cGJjX2dldF9hYnNfY2xvc2VzdF92YWx1ZV9pbl9hcnIiLCJteVZhbHVlIiwibXlBcnJheSIsImRpZmYiLCJhYnMiLCJjbG9zZXRWYWx1ZSIsInRkX2NsYXNzIiwidGRfZWwiLCJfdGlwcHkiLCJ3cGJjX3RpcHB5IiwiY29udGVudCIsInJlZmVyZW5jZSIsInBvcG92ZXJfY29udGVudCIsImdldEF0dHJpYnV0ZSIsImFsbG93SFRNTCIsImludGVyYWN0aXZlIiwiaGlkZU9uQ2xpY2siLCJpbnRlcmFjdGl2ZUJvcmRlciIsIm1heFdpZHRoIiwidGhlbWUiLCJwbGFjZW1lbnQiLCJkZWxheSIsImlnbm9yZUF0dHJpYnV0ZXMiLCJ0b3VjaCIsImFwcGVuZFRvIiwiYm9keSIsIndwYmNfZGF0ZXNfX2RheXNfYmV0d2VlbiIsImRhdGUxIiwiZGF0ZTIiLCJPTkVfREFZIiwiZGF0ZTFfbXMiLCJkYXRlMl9tcyIsImRpZmZlcmVuY2VfbXMiLCJyb3VuZCIsIndwYmNfZGF0ZXNfX2lzX2NvbnNlY3V0aXZlX2RhdGVzX2Fycl9yYW5nZSIsInNxbF9kYXRlc19hcnIiLCJwcmV2aW9zX2RhdGUiLCJjdXJyZW50X2RhdGUiLCJ3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyIiwiY2hlY2tfaW5feW1kIiwiY2hlY2tfb3V0X3ltZCIsImNvbnNvbGUiLCJsb2ciLCJkYXRlc190b19zZWxlY3RfYXJyIiwid3BiY19jYWxfZGF5c19zZWxlY3RfX211bHRpcGxlIiwiY2hlY2tfaW5fanMiLCJ0ZF9jZWxsIiwid3BiY19nZXRfY2xpY2tlZF90ZCIsImlkIiwiX3NlbGVjdERheSIsImNoZWNrX291dF9qcyIsInRkX2NlbGxfb3V0IiwiZGF0ZXNfYXJyIiwid3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fYXJyIiwid3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0IiwiZGF0ZXNfanMiLCJzdHJfZGF0ZSIsImRheV9hdmFpbGFiaWxpdHkiLCJjaGVja19vdXRfZGF0ZSIsImNoZWNrb3V0X3RpbWVzdGFtcCIsImNhbGVuZGFyX2h0bWxfaWQiLCJvcmlnaW5hbF9hcnJheSIsImJrX2Rpc3RpbmN0X2RhdGVzIiwiY2hlY2tfaW5fZGF0ZSIsIm9yaWdpbmFsX2NoZWNrX2luX2RhdGUiLCJfcmVzdHJpY3RNaW5NYXgiLCJfZGV0ZXJtaW5lRGF0ZSIsImRhdGVfb3V0Iiwib3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUiLCJtZXdEYXRlIiwib25lX2RhdGVfc3RyIiwiZCIsInVybF9wYXJhbXMiLCJVUkxTZWFyY2hQYXJhbXMiLCJ3aW5kb3ciLCJzZWFyY2giLCJoYXMiLCJzZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXJfaWQiLCJsb2FkZWRfcmVzb3VyY2VfaWQiLCJ3cGJjX2F1dG9fZmlsbF92YWx1ZSIsInJlcGxhY2VBbGwiLCJ3cGJjX2F1dG9fZmlsbF9ib29raW5nX2ZpZWxkcyIsImF1dG9fZmlsbF9zdHIiLCJmaWVsZHNfYXJyIiwid3BiY19hdXRvX2ZpbGxfYm9va2luZ19maWVsZHNfX3BhcnNlIiwiZGF0YV9zdHIiLCJmaWx0ZXJfb3B0aW9uc19hcnIiLCJkYXRhX2FyciIsIm15X2Zvcm1fZmllbGQiLCJmaWx0ZXJfbmFtZSIsImZpbHRlcl92YWx1ZSIsIndwYmNfYXV0b19maWxsX3NlYXJjaF9maWVsZHNfX3BhcnNlIiwiZmlsdGVyX3R5cGUiLCJ3cGJjX2NhbGVuZGFyX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyX19vbl9yZXNpemUiLCJ3aWR0aCIsIndwYmNfY2FsZW5kYXJzX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyIiwiYWxsX2NhbGVuZGFyc19hcnIiLCJjYWxlbmRhcl9pZCIsInNsaWNlIiwid3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVfcGFyYW1ldGVyIiwicGFyYW1ldGVyX3N0ciIsImRhdGVfZXhwZWN0ZWRfeW1kIiwiZGF0ZV9leHBlY3RlZF95bWRfYXJyIiwiZGF5Iiwid3BiY19jYWxfX3JlX2luaXQiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fcmVfaW5pdCIsIndwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19zaW5nbGUiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX211bHRpcGxlIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX2ZpeGVkIiwiZGF5c19udW1iZXIiLCJ3ZWVrX2RheXNfX3N0YXJ0Iiwid3BiY19jYWxfZGF5c19zZWxlY3RfX2ZpeGVkIiwid3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX3JhbmdlIiwiZGF5c19taW4iLCJkYXlzX21heCIsImRheXNfc3BlY2lmaWMiLCJ3cGJjX2NhbF9kYXlzX3NlbGVjdF9fcmFuZ2UiLCJ0YXJnZXRfZWxtIiwiZGF0ZXNfc3RhcnQiLCJkYXRlc19lbmQiLCJncm91cENvbGxhcHNlZCIsIndwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IiLCJwb3N0Iiwid3BiY191cmxfYWpheCIsImFjdGlvbiIsIndwYmNfYWp4X3VzZXJfaWQiLCJ3cGJjX2FqeF9sb2NhbGUiLCJjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyIsInJlc3BvbnNlX2RhdGEiLCJ0ZXh0U3RhdHVzIiwianFYSFIiLCJncm91cEVuZCIsImFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkIiwid3BiY19nZXRfcmVzb3VyY2VfaWRfX2Zyb21fYWp4X3Bvc3RfZGF0YV91cmwiLCJkYXRhIiwiX3R5cGVvZiIsImpxX25vZGUiLCJ3cGJjX2dldF9jYWxlbmRhcl9fanFfbm9kZV9fZm9yX21lc3NhZ2VzIiwibWVzc2FnZV90eXBlIiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSIsImZhaWwiLCJlcnJvclRocm93biIsImVycm9yX21lc3NhZ2UiLCJzdGF0dXMiLCJtZXNzYWdlX3Nob3dfZGVsYXkiLCJyZXNwb25zZVRleHQiLCJhanhfcG9zdF9kYXRhX3VybF9wYXJhbXMiLCJjYWxlbmRhcl9yZXNvdXJjZV9pZCIsIndwYmNfZ2V0X3VyaV9wYXJhbV9ieV9uYW1lIiwidXJsIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwicmVnZXgiLCJSZWdFeHAiLCJyZXN1bHRzIiwiZXhlYyIsIm1lc3NhZ2UiLCJwYXJhbXNfZGVmYXVsdCIsInBfa2V5IiwidW5
3411pcXVlX2Rpdl9pZCIsInNjcm9sbF90b19lbGVtZW50IiwianFfZWxfbWVzc2FnZSIsImlzX3Nob3dfbWVzc2FnZSIsImFwcGVuZCIsImh0bWwiLCJzaWJsaW5ncyIsImlzIiwiYmVmb3JlIiwibmV4dEFsbCIsImZhZGVPdXQiLCJjbG9zZWRfdGltZXIyIiwicGFyZW50X2VscyIsInBhcmVudHMiLCJtYXAiLCJzaG93Iiwid3BiY19kb19zY3JvbGwiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX19lcnJvciIsIm5vdGljZV9tZXNzYWdlX2lkIiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fZXJyb3JfdW5kZXJfZWxlbWVudCIsIm1lc3NhZ2VfZGVsYXkiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX19lcnJvcl9hYm92ZV9lbGVtZW50Iiwid3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fd2FybmluZyIsIndwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX193YXJuaW5nX3VuZGVyX2VsZW1lbnQiLCJ3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlX193YXJuaW5nX2Fib3ZlX2VsZW1lbnQiLCJqcV9ub2RlX2FyciIsImV4dHJhX3NoaWZ0X29mZnNldCIsInRhcmdldE9mZnNldCIsIm9mZnNldCIsInRvcCIsImZpcnN0IiwiYW5pbWF0ZSIsInNjcm9sbFRvcCIsIndwYmNfZGVmaW5lX3RpcHB5X3BvcG92ZXIiLCJwb3BvdmVyX3RpdGxlIiwic3RhdGUiLCJpc1Zpc2libGUiLCJoaWRlIiwid3BiY19kZWZpbmVfaGlkZV90aXBweV9vbl9zY3JvbGwiLCJoaWRlQWxsIl0sInNvdXJjZXMiOlsid3BiY191dGlscy5qcyIsIndwYmMuanMiLCJhanhfbG9hZF9iYWxhbmNlci5qcyIsIndwYmNfY2FsLmpzIiwiZGF5c19zZWxlY3RfY3VzdG9tLmpzIiwid3BiY19jYWxfYWp4LmpzIiwid3BiY19mZV9tZXNzYWdlcy5qcyIsInRpbWVsaW5lX3BvcG92ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKiBKYXZhU2NyaXB0IFV0aWwgRnVuY3Rpb25zXHRcdC4uL2luY2x1ZGVzL19fanMvdXRpbHMvd3BiY191dGlscy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vKipcclxuICogVHJpbSAgc3RyaW5ncyBhbmQgYXJyYXkgam9pbmVkIHdpdGggICgsKVxyXG4gKlxyXG4gKiBAcGFyYW0gc3RyaW5nX3RvX3RyaW0gICBzdHJpbmcgLyBhcnJheVxyXG4gKiBAcmV0dXJucyBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfdHJpbSggc3RyaW5nX3RvX3RyaW0gKXtcclxuXHJcbiAgICBpZiAoIEFycmF5LmlzQXJyYXkoIHN0cmluZ190b190cmltICkgKXtcclxuICAgICAgICBzdHJpbmdfdG9fdHJpbSA9IHN0cmluZ190b190cmltLmpvaW4oICcsJyApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICggJ3N0cmluZycgPT0gdHlwZW9mIChzdHJpbmdfdG9fdHJpbSkgKXtcclxuICAgICAgICBzdHJpbmdfdG9fdHJpbSA9IHN0cmluZ190b190cmltLnRyaW0oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RyaW5nX3RvX3RyaW07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBlbGVtZW50IGluIGFycmF5XHJcbiAqXHJcbiAqIEBwYXJhbSBhcnJheV9oZXJlXHRcdGFycmF5XHJcbiAqIEBwYXJhbSBwX3ZhbFx0XHRcdFx0ZWxlbWVudCB0byAgY2hlY2tcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2luX2FycmF5KCBhcnJheV9oZXJlLCBwX3ZhbCApe1xyXG5cdGZvciAoIHZhciBpID0gMCwgbCA9IGFycmF5X2hlcmUubGVuZ3RoOyBpIDwgbDsgaSsrICl7XHJcblx0XHRpZiAoIGFycmF5X2hlcmVbIGkgXSA9PSBwX3ZhbCApe1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGZhbHNlO1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG4vKipcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqXHRpbmNsdWRlcy9fX2pzL3dwYmMvd3BiYy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vKipcclxuICogRGVlcCBDbG9uZSBvZiBvYmplY3Qgb3IgYXJyYXlcclxuICpcclxuICogQHBhcmFtIG9ialxyXG4gKiBAcmV0dXJucyB7YW55fVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jbG9uZV9vYmooIG9iaiApe1xyXG5cclxuXHRyZXR1cm4gSlNPTi5wYXJzZSggSlNPTi5zdHJpbmdpZnkoIG9iaiApICk7XHJcbn1cclxuXHJcblxyXG5cclxuLyoqXHJcbiAqIE1haW4gX3dwYmMgSlMgb2JqZWN0XHJcbiAqL1xyXG5cclxudmFyIF93cGJjID0gKGZ1bmN0aW9uICggb2JqLCAkKSB7XHJcblxyXG5cdC8vIFNlY3VyZSBwYXJhbWV0ZXJzIGZvciBBamF4XHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgcF9zZWN1cmUgPSBvYmouc2VjdXJpdHlfb2JqID0gb2JqLnNlY3VyaXR5X29iaiB8fCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVzZXJfaWQ6IDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG5vbmNlICA6ICcnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRsb2NhbGUgOiAnJ1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICB9O1xyXG5cdG9iai5zZXRfc2VjdXJlX3BhcmFtID0gZnVuY3Rpb24gKCBwYXJhbV9rZXksIHBhcmFtX3ZhbCApIHtcclxuXHRcdH
3411Bfc2VjdXJlWyBwYXJhbV9rZXkgXSA9IHBhcmFtX3ZhbDtcclxuXHR9O1xyXG5cclxuXHRvYmouZ2V0X3NlY3VyZV9wYXJhbSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5ICkge1xyXG5cdFx0cmV0dXJuIHBfc2VjdXJlWyBwYXJhbV9rZXkgXTtcclxuXHR9O1xyXG5cclxuXHJcblx0Ly8gQ2FsZW5kYXJzIFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBwX2NhbGVuZGFycyA9IG9iai5jYWxlbmRhcnNfb2JqID0gb2JqLmNhbGVuZGFyc19vYmogfHwge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBzb3J0ICAgICAgICAgICAgOiBcImJvb2tpbmdfaWRcIixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gc29ydF90eXBlICAgICAgIDogXCJERVNDXCIsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHBhZ2VfbnVtICAgICAgICA6IDEsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIHBhZ2VfaXRlbXNfY291bnQ6IDEwLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBjcmVhdGVfZGF0ZSAgICAgOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBrZXl3b3JkICAgICAgICAgOiBcIlwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBzb3VyY2UgICAgICAgICAgOiBcIlwiXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIENoZWNrIGlmIGNhbGVuZGFyIGZvciBzcGVjaWZpYyBib29raW5nIHJlc291cmNlIGRlZmluZWQgICA6OiAgIHRydWUgfCBmYWxzZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cmV0dXJuICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mKCBwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdICkgKTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiAgQ3JlYXRlIENhbGVuZGFyIGluaXRpYWxpemluZ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcl9faW5pdCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSA9IHt9O1xyXG5cdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2lkJyBdID0gcmVzb3VyY2VfaWQ7XHJcblx0XHRwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyAncGVuZGluZ19kYXlzX3NlbGVjdGFibGUnIF0gPSBmYWxzZTtcclxuXHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgIGlmIHRoZSB0eXBlIG9mIHRoaXMgcHJvcGVydHkgIGlzIElOVFxyXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eV9uYW1lXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19pc19wcm9wX2ludCA9IGZ1bmN0aW9uICggcHJvcGVydHlfbmFtZSApIHtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjkuMC4yOS5cclxuXHJcblx0XHR2YXIgcF9jYWxlbmRhcl9pbnRfcHJvcGVydGllcyA9IFsnZHluYW1pY19fZGF5c19taW4nLCAnZHluYW1pY19fZGF5c19tYXgnLCAnZml4ZWRfX2RheXNfbnVtJ107XHJcblxyXG5cdFx0dmFyIGlzX2luY2x1ZGUgPSBwX2NhbGVuZGFyX2ludF9wcm9wZXJ0aWVzLmluY2x1ZGVzKCBwcm9wZXJ0eV9uYW1lICk7XHJcblxyXG5cdFx0cmV0dXJuIGlzX2luY2x1ZGU7XHJcblx0fTtcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBwYXJhbXMgZm9yIGFsbCAgY2FsZW5kYXJzXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJzX29ialx0XHRPYmplY3QgeyBjYWxlbmRhcl8xOiB7fSB9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGNhbGVuZGFyXzM6IHt9LCAuLi4gfVxyXG5cdCAqL1xyXG5cdG9iai5jYWxlbmRhcnNfYWxsX19zZXQgPSBmdW5jdGlvbiAoIGNhbGVuZGFyc19vYmogKSB7XHJcblx0XHRwX2NhbGVuZGFycyA9IGNhbGVuZGFyc19vYmo7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGJvb2tpbmdzIGluIGFsbCBjYWxlbmRhcnNcclxuXHQgKlxyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8e319XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyc19hbGxfX2dldCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybiBwX2NhbGVuZGFycztcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgY2FsZW5kYXIgb2JqZWN0ICAgOjogICB7IGlkOiAxLCDigKYgfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fGJvb2xlYW59XHRcdFx0XHRcdHsgaWQ6IDIgLOKApiB9XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19nZXRfcGFyYW1ldGVycyA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0aWYgKCBvYmouY2FsZW5kYXJfX2lzX2RlZmluZWQoIHJlc291cmNlX2lkICkgKXtcclxuXHJcblx0XHRcdHJldHVybiBwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogaWYgY2FsZW5kYXIgb2JqZWN0ICBub3QgZGVmaW5lZCwgdGhlbiAgaXQncyB3aWxsIGJlIGRlZmluZWQgYW5kIElEIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuICBzeXN0ZW0gc2V0ICBhcyBuZXcgb3Igb3ZlcndyaXRlIG9ubHkgcHJvcGVydGllcyBmcm9tIGNhbGVuZGFyX3Byb3BlcnR5X29iaiBwYXJhbWV0ZXIsICBidXQgb3RoZXIgcHJvcGVydGllcyB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUsIGxpa2UgJ2lkJ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJfcHJvcGVydHlfb2JqXHRcdFx0XHRcdCAgeyAgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfSAgfVxyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNfY29tcGxldGVfb3ZlcndyaXRlXHRcdCAgaWYgJ3RydWUnIChkZWZhdWx0OiAnZmFsc2UnKSwgIHRoZW4gIG9ubHkgb3ZlcndyaXRlIG9yIGFkZCAgbmV3IHByb3BlcnRpZXMgaW4gIGNhbGVuZGFyX3Byb3BlcnR5X29ialxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuY2FsZW5kYXJfX3NldCggIFwiIC5pbnR2YWw
3411oICRyZXNvdXJjZV9pZCApIC4gXCIsIHsgJ2RhdGVzJzogXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiIH0gKTtcIjtcclxuXHQgKi9cclxuXHRvYmouY2FsZW5kYXJfX3NldF9wYXJhbWV0ZXJzID0gZnVuY3Rpb24gKCByZXNvdXJjZV9pZCwgY2FsZW5kYXJfcHJvcGVydHlfb2JqLCBpc19jb21wbGV0ZV9vdmVyd3JpdGUgPSBmYWxzZSAgKSB7XHJcblxyXG5cdFx0aWYgKCAoIW9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSkgfHwgKHRydWUgPT09IGlzX2NvbXBsZXRlX292ZXJ3cml0ZSkgKXtcclxuXHRcdFx0b2JqLmNhbGVuZGFyX19pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoIHZhciBwcm9wX25hbWUgaW4gY2FsZW5kYXJfcHJvcGVydHlfb2JqICl7XHJcblxyXG5cdFx0XHRwX2NhbGVuZGFyc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSA9IGNhbGVuZGFyX3Byb3BlcnR5X29ialsgcHJvcF9uYW1lIF07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF07XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0IHByb3BlcnR5ICB0byAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFwiMVwiXHJcblx0ICogQHBhcmFtIHByb3BfbmFtZVx0XHRuYW1lIG9mIHByb3BlcnR5XHJcblx0ICogQHBhcmFtIHByb3BfdmFsdWVcdHZhbHVlIG9mIHByb3BlcnR5XHJcblx0ICogQHJldHVybnMgeyp9XHRcdFx0Y2FsZW5kYXIgb2JqZWN0XHJcblx0ICovXHJcblx0b2JqLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBwcm9wX25hbWUsIHByb3BfdmFsdWUgKSB7XHJcblxyXG5cdFx0aWYgKCAoIW9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSkgKXtcclxuXHRcdFx0b2JqLmNhbGVuZGFyX19pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdID0gcHJvcF92YWx1ZTtcclxuXHJcblx0XHRyZXR1cm4gcF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGNhbGVuZGFyIHByb3BlcnR5IHZhbHVlICAgXHQ6OiAgIG1peGVkIHwgbnVsbFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSAgcmVzb3VyY2VfaWRcdFx0JzEnXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHByb3BfbmFtZVx0XHRcdCdzZWxlY3Rpb25fbW9kZSdcclxuXHQgKiBAcmV0dXJucyB7KnxudWxsfVx0XHRcdFx0XHRtaXhlZCB8IG51bGxcclxuXHQgKi9cclxuXHRvYmouY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCwgcHJvcF9uYW1lICl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0Ly8gRml4SW46IDkuOS4wLjI5LlxyXG5cdFx0XHRpZiAoIG9iai5jYWxlbmRhcl9faXNfcHJvcF9pbnQoIHByb3BfbmFtZSApICl7XHJcblx0XHRcdFx0cF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gPSBwYXJzZUludCggcF9jYWxlbmRhcnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gIHBfY2FsZW5kYXJzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBudWxsO1x0XHQvLyBJZiBzb21lIHByb3BlcnR5IG5vdCBkZWZpbmVkLCB0aGVuIG51bGw7XHJcblx0fTtcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHJcblx0Ly8gQm9va2luZ3MgXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfYm9va2luZ3MgPSBvYmouYm9va2luZ3Nfb2JqID0gb2JqLmJvb2tpbmdzX29iaiB8fCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gY2FsZW5kYXJfMTogT2JqZWN0IHtcclxuIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHQgICBpZDogICAgIDFcclxuIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9cdFx0XHRcdFx0XHQgLCBkYXRlczogIE9iamVjdCB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKAplxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIENoZWNrIGlmIGJvb2tpbmdzIGZvciBzcGVjaWZpYyBib29raW5nIHJlc291cmNlIGRlZmluZWQgICA6OiAgIHRydWUgfCBmYWxzZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQgKSB7XHJcblxyXG5cdFx0cmV0dXJuICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mKCBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gKSApO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBib29raW5ncyBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgaWQ6IDEgLCBkYXRlczogIE9iamVjdCB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKApiB9XHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge3N0cmluZ3xpbnR9IHJlc291cmNlX2lkXHRcdFx0XHQgICcyJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdFx0eyBpZDogMiAsIGRhdGVzOiAgT2JqZWN0IHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldCA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdGlmICggb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApICl7XHJcblxyXG5cdFx0XHRyZXR1cm4gcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBib29raW5ncyBjYWxlbmRhciBvYmplY3QgICA6OiAgIHsgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogaWYgY2FsZW5kYXIgb2JqZWN0ICBub3QgZGVmaW5lZCwgdGhlbiAgaXQncyB3aWxsIGJlIGRlZmluZWQgYW5kIElEIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuICBzeXN0ZW0gc2V0ICBhcyBuZXcgb3Igb3ZlcndyaXRlIG9ubHkgcHJvcGVydGllcyBmcm9tIGNhbGVuZGFyX29iaiBwYXJhbWV0ZXIsICBidXQgb3RoZXIgcHJvcGVydGllcyB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUsIGxpa2UgJ2lkJ1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdFx0ICAnMidcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gY2FsZW5kYXJfb2JqXHRcdFx0XHRcdCAgeyAgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfSAgfVxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldCggIFwiIC5pbnR2YWw
3411oICRyZXNvdXJjZV9pZCApIC4gXCIsIHsgJ2RhdGVzJzogXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiIH0gKTtcIjtcclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldCA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCwgY2FsZW5kYXJfb2JqICl7XHJcblxyXG5cdFx0aWYgKCAhIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApe1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gPSB7fTtcclxuXHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyAnaWQnIF0gPSByZXNvdXJjZV9pZDtcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKCB2YXIgcHJvcF9uYW1lIGluIGNhbGVuZGFyX29iaiApe1xyXG5cclxuXHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSA9IGNhbGVuZGFyX29ialsgcHJvcF9uYW1lIF07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXTtcclxuXHR9O1xyXG5cclxuXHQvLyBEYXRlc1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIEFMTCBEYXRlcyBpbiBjYWxlbmRhciAgIDo6ICAgZmFsc2UgfCB7IFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKYgfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdCcxJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdGZhbHNlIHwgT2JqZWN0IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjRcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwiYXZhaWxhYmxlXCIsIGRheV9hdmFpbGFiaWxpdHk6IDEsIG1heF9jYXBhY2l0eTogMSwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjZcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwiZnVsbF9kYXlfYm9va2luZ1wiLCBbJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncyddOiBcInBlbmRpbmdcIiwgZGF5X2F2YWlsYWJpbGl0eTogMCwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMjlcIjogT2JqZWN0IHsgWydzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5J106IFwicmVzb3VyY2VfYXZhaWxhYmlsaXR5XCIsIGRheV9hdmFpbGFiaWxpdHk6IDAsIG1heF9jYXBhY2l0eTogMSwg4oCmIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcIjIwMjMtMDctMzBcIjoge+KApn0sIFwiMjAyMy0wNy0zMVwiOiB74oCmfSwg4oCmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9kYXRlcyA9IGZ1bmN0aW9uKCByZXNvdXJjZV9pZCl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHRcdC8vIElmIHNvbWUgcHJvcGVydHkgbm90IGRlZmluZWQsIHRoZW4gZmFsc2U7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogU2V0IGJvb2tpbmdzIGRhdGVzIGluIGNhbGVuZGFyIG9iamVjdCAgIDo6ICAgIHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKlxyXG5cdCAqIGlmIGNhbGVuZGFyIG9iamVjdCAgbm90IGRlZmluZWQsIHRoZW4gIGl0J3Mgd2lsbCBiZSBkZWZpbmVkIGFuZCAnaWQnLCAnZGF0ZXMnIHNldFxyXG5cdCAqIGlmIGNhbGVuZGFyIGV4aXN0LCB0aGVuIHN5c3RlbSBhZGQgYSAgbmV3IG9yIG92ZXJ3cml0ZSBvbmx5IGRhdGVzIGZyb20gZGF0ZXNfb2JqIHBhcmFtZXRlcixcclxuXHQgKiBidXQgb3RoZXIgZGF0ZXMgbm90IGZyb20gcGFyYW1ldGVyIGRhdGVzX29iaiB3aWxsIGJlIGV4aXN0ZWQgYW5kIG5vdCBvdmVyd3JpdGUuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge3N0cmluZ3xpbnR9IHJlc291cmNlX2lkXHRcdFx0XHQgICcyJ1xyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBkYXRlc19vYmpcdFx0XHRcdFx0ICB7IFwiMjAyMy0wNy0yMVwiOiB74oCmfSwgXCIyMDIzLTA3LTIyXCI6IHvigKZ9LCBcIjIwMjMtMDctMjNcIjoge+KApn0sIOKApiB9XHJcblx0ICogQHBhcmFtIHtib29sZWFufSBpc19jb21wbGV0ZV9vdmVyd3JpdGVcdFx0ICBpZiBmYWxzZSwgIHRoZW4gIG9ubHkgb3ZlcndyaXRlIG9yIGFkZCAgZGF0ZXMgZnJvbSBcdGRhdGVzX29ialxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqXHJcblx0ICogRXhhbXBsZXM6XHJcblx0ICogICBcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fc2V0X2RhdGVzKCByZXNvdXJjZV9pZCwgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwg4oCmIH0gICk7XHRcdDwtICAgb3ZlcndyaXRlIEFMTCBkYXRlc1xyXG5cdCAqICAgXHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldF9kYXRlcyggcmVzb3VyY2VfaWQsIHsgXCIyMDIzLTA3LTIyXCI6IHvigKZ9IH0sICBmYWxzZSAgKTtcdFx0XHRcdFx0PC0gICBhZGQgb3Igb3ZlcndyaXRlIG9ubHkgIFx0XCIyMDIzLTA3LTIyXCI6IHt9XHJcblx0ICpcclxuXHQgKiBDb21tb24gdXNhZ2UgaW4gUEhQOlxyXG5cdCAqICAgXHRcdFx0ZWNobyBcIiAgX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX3NldF9kYXRlcyggIFwiIC4gaW50dmFsKCAkcmVzb3VyY2VfaWQgKSAuIFwiLCAgXCIgLiB3cF9qc29uX2VuY29kZSggJGF2YWlsYWJpbGl0eV9wZXJfZGF5c19hcnIgKSAuIFwiICApOyAgXCI7XHJcblx0ICovXHJcblx0b2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIGRhdGVzX29iaiAsIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSA9IHRydWUgKXtcclxuXHJcblx0XHRpZiAoICFvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJfX2lzX2RlZmluZWQoIHJlc291cmNlX2lkICkgKXtcclxuXHRcdFx0b2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXQoIHJlc291cmNlX2lkLCB7ICdkYXRlcyc6IHt9IH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdKSApe1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXSA9IHt9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGlzX2NvbXBsZXRlX292ZXJ3cml0ZSl7XHJcblxyXG5cdFx0XHQvLyBDb21wbGV0ZSBvdmVyd3JpdGUgYWxsICBib29raW5nIGRhdGVzXHJcblx0XHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdID0gZGF0ZXNfb2JqO1xyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIEFkZCBvbmx5ICBuZXcgb3Igb3ZlcndyaXRlIGV4aXN0IGJvb2tpbmcgZGF0ZXMgZnJvbSAgcGFyYW1ldGVyLiBCb29raW5nIGRhdGVzIG5vdCBmcm9tICBwYXJhbWV0ZXIgIHdpbGwgIGJlIHdpdGhvdXQgY2huYW5nZXNcclxuXHRcdFx0Zm9yICggdmFyIHByb3BfbmFtZSBpbiBkYXRlc19vYmogKXtcclxuXHJcblx0XHRcdFx0cF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWydkYXRlcyddWy
3411Bwcm9wX25hbWUgXSA9IGRhdGVzX29ialsgcHJvcF9uYW1lIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdH07XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIHNwZWNpZmljIGRhdGUgaW4gY2FsZW5kYXIgICA6OiAgIGZhbHNlIHwgeyBkYXlfYXZhaWxhYmlsaXR5OiAxLCAuLi4gfVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSByZXNvdXJjZV9pZFx0XHRcdCcxJ1xyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcWxfY2xhc3NfZGF5XHRcdFx0JzIwMjMtMDctMjEnXHJcblx0ICogQHJldHVybnMge29iamVjdHxib29sZWFufVx0XHRcdFx0ZmFsc2UgfCB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRheV9hdmFpbGFiaWxpdHk6IDRcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWF4X2NhcGFjaXR5OiA0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gID49IEJ1c2luZXNzIExhcmdlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdDI6IE9iamVjdCB7IGlzX2RheV91bmF2YWlsYWJsZTogZmFsc2UsIF9kYXlfc3RhdHVzOiBcImF2YWlsYWJsZVwiIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0MTA6IE9iamVjdCB7IGlzX2RheV91bmF2YWlsYWJsZTogZmFsc2UsIF9kYXlfc3RhdHVzOiBcImF2YWlsYWJsZVwiIH1cdFx0Ly8gID49IEJ1c2luZXNzIExhcmdlIC4uLlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQxMTogT2JqZWN0IHsgaXNfZGF5X3VuYXZhaWxhYmxlOiBmYWxzZSwgX2RheV9zdGF0dXM6IFwiYXZhaWxhYmxlXCIgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQxMjogT2JqZWN0IHsgaXNfZGF5X3VuYXZhaWxhYmxlOiBmYWxzZSwgX2RheV9zdGF0dXM6IFwiYXZhaWxhYmxlXCIgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlID0gZnVuY3Rpb24oIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICl7XHJcblxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIG9iai5ib29raW5nc19pbl9jYWxlbmRhcl9faXNfZGVmaW5lZCggcmVzb3VyY2VfaWQgKSApXHJcblx0XHRcdCYmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgJ2RhdGVzJyBdICkgKVxyXG5cdFx0XHQmJiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YgKCBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXVsgc3FsX2NsYXNzX2RheSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdkYXRlcycgXVsgc3FsX2NsYXNzX2RheSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmYWxzZTtcdFx0Ly8gSWYgc29tZSBwcm9wZXJ0eSBub3QgZGVmaW5lZCwgdGhlbiBmYWxzZTtcclxuXHR9O1xyXG5cclxuXHJcblx0Ly8gQW55ICBQQVJBTVMgICBpbiBib29raW5nc1xyXG5cclxuXHQvKipcclxuXHQgKiBTZXQgcHJvcGVydHkgIHRvICBib29raW5nXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHRcIjFcIlxyXG5cdCAqIEBwYXJhbSBwcm9wX25hbWVcdFx0bmFtZSBvZiBwcm9wZXJ0eVxyXG5cdCAqIEBwYXJhbSBwcm9wX3ZhbHVlXHR2YWx1ZSBvZiBwcm9wZXJ0eVxyXG5cdCAqIEByZXR1cm5zIHsqfVx0XHRcdGJvb2tpbmcgb2JqZWN0XHJcblx0ICovXHJcblx0b2JqLmJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQsIHByb3BfbmFtZSwgcHJvcF92YWx1ZSApIHtcclxuXHJcblx0XHRpZiAoICEgb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApICl7XHJcblx0XHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSA9IHt9O1xyXG5cdFx0XHRwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bICdpZCcgXSA9IHJlc291cmNlX2lkO1xyXG5cdFx0fVxyXG5cclxuXHRcdHBfYm9va2luZ3NbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgcHJvcF9uYW1lIF0gPSBwcm9wX3ZhbHVlO1xyXG5cclxuXHRcdHJldHVybiBwX2Jvb2tpbmdzWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF07XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogIEdldCBib29raW5nIHByb3BlcnR5IHZhbHVlICAgXHQ6OiAgIG1peGVkIHwgbnVsbFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtzdHJpbmd8aW50fSAgcmVzb3VyY2VfaWRcdFx0JzEnXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IHByb3BfbmFtZVx0XHRcdCdzZWxlY3Rpb25fbW9kZSdcclxuXHQgKiBAcmV0dXJucyB7KnxudWxsfVx0XHRcdFx0XHRtaXhlZCB8IG51bGxcclxuXHQgKi9cclxuXHRvYmouYm9va2luZ19fZ2V0X3BhcmFtX3ZhbHVlID0gZnVuY3Rpb24oIHJlc291cmNlX2lkLCBwcm9wX25hbWUgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggb2JqLmJvb2tpbmdzX2luX2NhbGVuZGFyX19pc19kZWZpbmVkKCByZXNvdXJjZV9pZCApIClcclxuXHRcdFx0JiYgKCAndW5kZWZpbmVkJyAhPT0gdHlwZW9mICggcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXSApIClcclxuXHRcdCl7XHJcblx0XHRcdHJldHVybiAgcF9ib29raW5nc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdWyBwcm9wX25hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcdFx0Ly8gSWYgc29tZSBwcm9wZXJ0eSBub3QgZGVmaW5lZCwgdGhlbiBudWxsO1xyXG5cdH07XHJcblxyXG5cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCBib29raW5ncyBmb3IgYWxsICBjYWxlbmRhcnNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBjYWxlbmRhcnNfb2JqXHRcdE9iamVjdCB7IGNhbGVuZGFyXzE6IHsgaWQ6IDEsIGRhdGVzOiBPYmplY3QgeyBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwgXCIyMDIzLTA3LTI0XCI6IHvigKZ9LCDigKYgfSB9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGNhbGVuZGFyXzM6IHt9LCAuLi4gfVxyXG5cdCAqL1xyXG5cdG9iai5ib29raW5nc19pbl9jYWxlbmRhcnNfX3NldF9hbGwgPSBmdW5jdGlvbiAoIGNhbGVuZGFyc19vYmogKSB7XHJcblx0XHRwX2Jvb2tpbmdzID0gY2FsZW5kYXJzX29iajtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgYm9va2luZ3MgaW4gYWxsIGNhbGVuZGFyc1xyXG5cdCAqXHJcblx0ICogQHJldHVybnMge29iamVjdHx7fX1cclxuXHQgKi9cclxuXHRvYmouYm9va2luZ3NfaW5fY2FsZW5kYXJzX19nZXRfYWxsID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0cmV0dXJuIHBfYm9va2luZ3M7XHJcblx0fTtcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHJcblxyXG5cclxuXHQvLyBTZWFzb25zIFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBwX3NlYXNvbnMgPSBvYmouc2Vhc29uc19vYmogPSBvYmouc2Vhc29uc19vYmogfHwge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGNhbGVuZGFyXzE6IE9iamVjdCB7X
3411HJcbiBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0ICAgaWQ6ICAgICAxXHJcbiBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vXHRcdFx0XHRcdFx0ICwgZGF0ZXM6ICBPYmplY3QgeyBcIjIwMjMtMDctMjFcIjoge+KApn0sIFwiMjAyMy0wNy0yMlwiOiB74oCmfSwgXCIyMDIzLTA3LTIzXCI6IHvigKZ9LCDigKZcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEFkZCBzZWFzb24gbmFtZXMgZm9yIGRhdGVzIGluIGNhbGVuZGFyIG9iamVjdCAgIDo6ICAgIHsgXCIyMDIzLTA3LTIxXCI6IFsgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDIzJywgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDI0JyBdLCBcIjIwMjMtMDctMjJcIjogWy4uLl0sIC4uLiB9XHJcblx0ICpcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcdFx0XHRcdCAgJzInXHJcblx0ICogQHBhcmFtIHtvYmplY3R9IGRhdGVzX29ialx0XHRcdFx0XHQgIHsgXCIyMDIzLTA3LTIxXCI6IHvigKZ9LCBcIjIwMjMtMDctMjJcIjoge+KApn0sIFwiMjAyMy0wNy0yM1wiOiB74oCmfSwg4oCmIH1cclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IGlzX2NvbXBsZXRlX292ZXJ3cml0ZVx0XHQgIGlmIGZhbHNlLCAgdGhlbiAgb25seSAgYWRkICBkYXRlcyBmcm9tIFx0ZGF0ZXNfb2JqXHJcblx0ICogQHJldHVybnMgeyp9XHJcblx0ICpcclxuXHQgKiBFeGFtcGxlczpcclxuXHQgKiAgIFx0XHRcdF93cGJjLnNlYXNvbnNfX3NldCggcmVzb3VyY2VfaWQsIHsgXCIyMDIzLTA3LTIxXCI6IFsgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDIzJywgJ3dwYmNfc2Vhc29uX3NlcHRlbWJlcl8yMDI0JyBdLCBcIjIwMjMtMDctMjJcIjogWy4uLl0sIC4uLiB9ICApO1xyXG5cdCAqL1xyXG5cdG9iai5zZWFzb25zX19zZXQgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIGRhdGVzX29iaiAsIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSA9IGZhbHNlICl7XHJcblxyXG5cdFx0aWYgKCAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXSkgKXtcclxuXHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF0gPSB7fTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGlzX2NvbXBsZXRlX292ZXJ3cml0ZSApe1xyXG5cclxuXHRcdFx0Ly8gQ29tcGxldGUgb3ZlcndyaXRlIGFsbCAgc2Vhc29uIGRhdGVzXHJcblx0XHRcdHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdID0gZGF0ZXNfb2JqO1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgb25seSAgbmV3IG9yIG92ZXJ3cml0ZSBleGlzdCBib29raW5nIGRhdGVzIGZyb20gIHBhcmFtZXRlci4gQm9va2luZyBkYXRlcyBub3QgZnJvbSAgcGFyYW1ldGVyICB3aWxsICBiZSB3aXRob3V0IGNobmFuZ2VzXHJcblx0XHRcdGZvciAoIHZhciBwcm9wX25hbWUgaW4gZGF0ZXNfb2JqICl7XHJcblxyXG5cdFx0XHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAocF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdKSApe1xyXG5cdFx0XHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdID0gW107XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGZvciAoIHZhciBzZWFzb25fbmFtZV9rZXkgaW4gZGF0ZXNfb2JqWyBwcm9wX25hbWUgXSApe1xyXG5cdFx0XHRcdFx0cF9zZWFzb25zWyAnY2FsZW5kYXJfJyArIHJlc291cmNlX2lkIF1bIHByb3BfbmFtZSBdLnB1c2goIGRhdGVzX29ialsgcHJvcF9uYW1lIF1bIHNlYXNvbl9uYW1lX2tleSBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdO1xyXG5cdH07XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGJvb2tpbmdzIGRhdGEgZm9yIHNwZWNpZmljIGRhdGUgaW4gY2FsZW5kYXIgICA6OiAgIFtdIHwgWyAnd3BiY19zZWFzb25fc2VwdGVtYmVyXzIwMjMnLCAnd3BiY19zZWFzb25fc2VwdGVtYmVyXzIwMjQnIF1cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcdFx0XHQnMSdcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gc3FsX2NsYXNzX2RheVx0XHRcdCcyMDIzLTA3LTIxJ1xyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R8Ym9vbGVhbn1cdFx0XHRcdFtdICB8ICBbICd3cGJjX3NlYXNvbl9zZXB0ZW1iZXJfMjAyMycsICd3cGJjX3NlYXNvbl9zZXB0ZW1iZXJfMjAyNCcgXVxyXG5cdCAqL1xyXG5cdG9iai5zZWFzb25zX19nZXRfZm9yX2RhdGUgPSBmdW5jdGlvbiggcmVzb3VyY2VfaWQsIHNxbF9jbGFzc19kYXkgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHBfc2Vhc29uc1sgJ2NhbGVuZGFyXycgKyByZXNvdXJjZV9pZCBdICkgKVxyXG5cdFx0XHQmJiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YgKCBwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgc3FsX2NsYXNzX2RheSBdICkgKVxyXG5cdFx0KXtcclxuXHRcdFx0cmV0dXJuICBwX3NlYXNvbnNbICdjYWxlbmRhcl8nICsgcmVzb3VyY2VfaWQgXVsgc3FsX2NsYXNzX2RheSBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBbXTtcdFx0Ly8gSWYgbm90IGRlZmluZWQsIHRoZW4gW107XHJcblx0fTtcclxuXHJcblxyXG5cdC8vIE90aGVyIHBhcmFtZXRlcnMgXHRcdFx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfb3RoZXIgPSBvYmoub3RoZXJfb2JqID0gb2JqLm90aGVyX29iaiB8fCB7IH07XHJcblxyXG5cdG9iai5zZXRfb3RoZXJfcGFyYW0gPSBmdW5jdGlvbiAoIHBhcmFtX2tleSwgcGFyYW1fdmFsICkge1xyXG5cdFx0cF9vdGhlclsgcGFyYW1fa2V5IF0gPSBwYXJhbV92YWw7XHJcblx0fTtcclxuXHJcblx0b2JqLmdldF9vdGhlcl9wYXJhbSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5ICkge1xyXG5cdFx0cmV0dXJuIHBfb3RoZXJbIHBhcmFtX2tleSBdO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBhbGwgb3RoZXIgcGFyYW1zXHJcblx0ICpcclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fHt9fVxyXG5cdCAqL1xyXG5cdG9iai5nZXRfb3RoZXJfcGFyYW1fX2FsbCA9IGZ1bmN0aW9uICgpIHtcclxuXHRcdHJldHVybi
3411BwX290aGVyO1xyXG5cdH07XHJcblxyXG5cdC8vIE1lc3NhZ2VzIFx0XHRcdCAgICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIHBfbWVzc2FnZXMgPSBvYmoubWVzc2FnZXNfb2JqID0gb2JqLm1lc3NhZ2VzX29iaiB8fCB7IH07XHJcblxyXG5cdG9iai5zZXRfbWVzc2FnZSA9IGZ1bmN0aW9uICggcGFyYW1fa2V5LCBwYXJhbV92YWwgKSB7XHJcblx0XHRwX21lc3NhZ2VzWyBwYXJhbV9rZXkgXSA9IHBhcmFtX3ZhbDtcclxuXHR9O1xyXG5cclxuXHRvYmouZ2V0X21lc3NhZ2UgPSBmdW5jdGlvbiAoIHBhcmFtX2tleSApIHtcclxuXHRcdHJldHVybiBwX21lc3NhZ2VzWyBwYXJhbV9rZXkgXTtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgYWxsIG90aGVyIHBhcmFtc1xyXG5cdCAqXHJcblx0ICogQHJldHVybnMge29iamVjdHx7fX1cclxuXHQgKi9cclxuXHRvYmouZ2V0X21lc3NhZ2VzX19hbGwgPSBmdW5jdGlvbiAoKSB7XHJcblx0XHRyZXR1cm4gcF9tZXNzYWdlcztcclxuXHR9O1xyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRyZXR1cm4gb2JqO1xyXG5cclxufSggX3dwYmMgfHwge30sIGpRdWVyeSApKTtcclxuIiwiLyoqXHJcbiAqIEV4dGVuZCBfd3BiYyB3aXRoICBuZXcgbWV0aG9kcyAgICAgICAgLy8gRml4SW46IDkuOC42LjIuXHJcbiAqXHJcbiAqIEB0eXBlIHsqfHt9fVxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuIF93cGJjID0gKGZ1bmN0aW9uICggb2JqLCAkKSB7XHJcblxyXG5cdC8vIExvYWQgQmFsYW5jZXIgXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHR2YXIgcF9iYWxhbmNlciA9IG9iai5iYWxhbmNlcl9vYmogPSBvYmouYmFsYW5jZXJfb2JqIHx8IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbWF4X3RocmVhZHMnOiAyLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpbl9wcm9jZXNzJyA6IFtdLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3YWl0JyAgICAgICA6IFtdXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH07XHJcblxyXG5cdCAvKipcclxuXHQgICogU2V0ICBtYXggcGFyYWxsZWwgcmVxdWVzdCAgdG8gIGxvYWRcclxuXHQgICpcclxuXHQgICogQHBhcmFtIG1heF90aHJlYWRzXHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fc2V0X21heF90aHJlYWRzID0gZnVuY3Rpb24gKCBtYXhfdGhyZWFkcyApe1xyXG5cclxuXHRcdHBfYmFsYW5jZXJbICdtYXhfdGhyZWFkcycgXSA9IG1heF90aHJlYWRzO1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqICBDaGVjayBpZiBiYWxhbmNlciBmb3Igc3BlY2lmaWMgYm9va2luZyByZXNvdXJjZSBkZWZpbmVkICAgOjogICB0cnVlIHwgZmFsc2VcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRvYmouYmFsYW5jZXJfX2lzX2RlZmluZWQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkICkge1xyXG5cclxuXHRcdHJldHVybiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiggcF9iYWxhbmNlclsgJ2JhbGFuY2VyXycgKyByZXNvdXJjZV9pZCBdICkgKTtcclxuXHR9O1xyXG5cclxuXHJcblx0LyoqXHJcblx0ICogIENyZWF0ZSBiYWxhbmNlciBpbml0aWFsaXppbmdcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfGludH0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRvYmouYmFsYW5jZXJfX2luaXQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICwgcGFyYW1zID17fSkge1xyXG5cclxuXHRcdHZhciBiYWxhbmNlX29iaiA9IHt9O1xyXG5cdFx0YmFsYW5jZV9vYmpbICdyZXNvdXJjZV9pZCcgXSAgID0gcmVzb3VyY2VfaWQ7XHJcblx0XHRiYWxhbmNlX29ialsgJ3ByaW9yaXR5JyBdICAgICAgPSAxO1xyXG5cdFx0YmFsYW5jZV9vYmpbICdmdW5jdGlvbl9uYW1lJyBdID0gZnVuY3Rpb25fbmFtZTtcclxuXHRcdGJhbGFuY2Vfb2JqWyAncGFyYW1zJyBdICAgICAgICA9IHdwYmNfY2xvbmVfb2JqKCBwYXJhbXMgKTtcclxuXHJcblxyXG5cdFx0aWYgKCBvYmouYmFsYW5jZXJfX2lzX2FscmVhZHlfcnVuKCByZXNvdXJjZV9pZCwgZnVuY3Rpb25fbmFtZSApICl7XHJcblx0XHRcdHJldHVybiAncnVuJztcclxuXHRcdH1cclxuXHRcdGlmICggb2JqLmJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICkgKXtcclxuXHRcdFx0cmV0dXJuICd3YWl0JztcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0aWYgKCBvYmouYmFsYW5jZXJfX2Nhbl9pX3J1bigpICl7XHJcblx0XHRcdG9iai5iYWxhbmNlcl9fYWRkX3RvX19ydW4oIGJhbGFuY2Vfb2JqICk7XHJcblx0XHRcdHJldHVybiAncnVuJztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG9iai5iYWxhbmNlcl9fYWRkX3RvX193YWl0KCBiYWxhbmNlX29iaiApO1xyXG5cdFx0XHRyZXR1cm4gJ3dhaXQnO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdCAvKipcclxuXHQgICogQ2FuIEkgUnVuID9cclxuXHQgICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fY2FuX2lfcnVuID0gZnVuY3Rpb24gKCl7XHJcblx0XHRyZXR1cm4gKCBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5sZW5ndGggPCBwX2JhbGFuY2VyWyAnbWF4X3RocmVhZHMnIF0gKTtcclxuXHR9XHJcblxyXG5cdFx0IC8qKlxyXG5cdFx0ICAqIEFkZCB0byBXQUlUXHJcblx0XHQgICogQHBhcmFtIGJhbGFuY2Vfb2JqXHJcblx0XHQgICovXHJcblx0XHRvYmouYmFsYW5jZXJfX2FkZF90b19fd2FpdCA9IGZ1bmN0aW9uICggYmFsYW5jZV9vYmogKSB7XHJcblx0XHRcdHBfYmFsYW5jZXJbJ3dhaXQnXS5wdXNoKCBiYWxhbmNlX29iaiApO
34111xyXG5cdFx0fVxyXG5cclxuXHRcdCAvKipcclxuXHRcdCAgKiBSZW1vdmUgZnJvbSBXYWl0XHJcblx0XHQgICpcclxuXHRcdCAgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCAgKiBAcGFyYW0gZnVuY3Rpb25fbmFtZVxyXG5cdFx0ICAqIEByZXR1cm5zIHsqfGJvb2xlYW59XHJcblx0XHQgICovXHJcblx0XHRvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX193YWl0X2xpc3QgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHR2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0aWYgKCBwX2JhbGFuY2VyWyAnd2FpdCcgXS5sZW5ndGggKXtcdFx0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRcdGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICd3YWl0JyBdICl7XHJcblx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdChyZXNvdXJjZV9pZCA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ3Jlc291cmNlX2lkJyBdKVxyXG5cdFx0XHRcdFx0XHQmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQpe1xyXG5cdFx0XHRcdFx0XHRyZW1vdmVkX2VsID0gcF9iYWxhbmNlclsgJ3dhaXQnIF0uc3BsaWNlKCBpLCAxICk7XHJcblx0XHRcdFx0XHRcdHJlbW92ZWRfZWwgPSByZW1vdmVkX2VsLnBvcCgpO1xyXG5cdFx0XHRcdFx0XHRwX2JhbGFuY2VyWyAnd2FpdCcgXSA9IHBfYmFsYW5jZXJbICd3YWl0JyBdLmZpbHRlciggZnVuY3Rpb24gKCB2ICl7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHY7XHJcblx0XHRcdFx0XHRcdH0gKTtcdFx0XHRcdFx0Ly8gUmVpbmRleCBhcnJheVxyXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVtb3ZlZF9lbDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHJlbW92ZWRfZWw7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQqIElzIGFscmVhZHkgV0FJVFxyXG5cdFx0KlxyXG5cdFx0KiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCogQHBhcmFtIGZ1bmN0aW9uX25
3411hbWVcclxuXHRcdCogQHJldHVybnMge2Jvb2xlYW59XHJcblx0XHQqL1xyXG5cdFx0b2JqLmJhbGFuY2VyX19pc19hbHJlYWR5X3dhaXQgPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHRpZiAoIHBfYmFsYW5jZXJbICd3YWl0JyBdLmxlbmd0aCApe1x0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRcdGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICd3YWl0JyBdICl7XHJcblx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdChyZXNvdXJjZV9pZCA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ3Jlc291cmNlX2lkJyBdKVxyXG5cdFx0XHRcdFx0XHQmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQpe1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQgLyoqXHJcblx0XHQgICogQWRkIHRvIFJVTlxyXG5cdFx0ICAqIEBwYXJhbSBiYWxhbmNlX29ialxyXG5cdFx0ICAqL1xyXG5cdFx0b2JqLmJhbGFuY2VyX19hZGRfdG9fX3J1biA9IGZ1bmN0aW9uICggYmFsYW5jZV9vYmogKSB7XHJcblx0XHRcdHBfYmFsYW5jZXJbJ2luX3Byb2Nlc3MnXS5wdXNoKCBiYWxhbmNlX29iaiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8qKlxyXG5cdFx0KiBSZW1vdmUgZnJvbSBSVU4gbGlzdFxyXG5cdFx0KlxyXG5cdFx0KiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHRcdCogQHBhcmFtIGZ1bmN0aW9uX25
3411hbWVcclxuXHRcdCogQHJldHVybnMgeyp8Ym9vbGVhbn1cclxuXHRcdCovXHJcblx0XHRvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX19ydW5fbGlzdCA9IGZ1bmN0aW9uICggcmVzb3VyY2VfaWQsIGZ1bmN0aW9uX25hbWUgKXtcclxuXHJcblx0XHRcdCB2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0IGlmICggcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0ubGVuZ3RoICl7XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0IGZvciAoIHZhciBpIGluIHBfYmFsYW5jZXJbICdpbl9wcm9jZXNzJyBdICl7XHJcblx0XHRcdFx0XHQgaWYgKFxyXG5cdFx0XHRcdFx0XHQgKHJlc291cmNlX2lkID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAncmVzb3VyY2VfaWQnIF0pXHJcblx0XHRcdFx0XHRcdCAmJiAoZnVuY3Rpb25fbmFtZSA9PT0gcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF1bIGkgXVsgJ2Z1bmN0aW9uX25hbWUnIF0pXHJcblx0XHRcdFx0XHQgKXtcclxuXHRcdFx0XHRcdFx0IHJlbW92ZWRfZWwgPSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5zcGxpY2UoIGksIDEgKTtcclxuXHRcdFx0XHRcdFx0IHJlbW92ZWRfZWwgPSByZW1vdmVkX2VsLnBvcCgpO1xyXG5cdFx0XHRcdFx0XHQgcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0gPSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXS5maWx0ZXIoIGZ1bmN0aW9uICggdiApe1xyXG5cdFx0XHRcdFx0XHRcdCByZXR1cm4gdjtcclxuXHRcdFx0XHRcdFx0IH0gKTtcdFx0Ly8gUmVpbmRleCBhcnJheVxyXG5cdFx0XHRcdFx0XHQgcmV0dXJuIHJlbW92ZWRfZWw7XHJcblx0XHRcdFx0XHQgfVxyXG5cdFx0XHRcdCB9XHJcblx0XHRcdCB9XHJcblx0XHRcdCByZXR1cm4gcmVtb3ZlZF9lbDtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCogSXMgYWxyZWFkeSBSVU5cclxuXHRcdCpcclxuXHRcdCogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0XHQqIEBwYXJhbSBmdW5jdGlvbl9uYW1lXHJcblx0XHQqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0Ki9cclxuXHRcdG9iai5iYWxhbmNlcl9faXNfYWxyZWFkeV9ydW4gPSBmdW5jdGlvbiAoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICl7XHJcblxyXG5cdFx0XHRpZiAoIHBfYmFsYW5jZXJbICdpbl9wcm9jZXNzJyBdLmxlbmd0aCApe1x0XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0Zm9yICggdmFyIGkgaW4gcF9iYWxhbmNlclsgJ2luX3Byb2Nlc3MnIF0gKXtcclxuXHRcdFx0XHRcdGlmIChcclxuXHRcdFx0XHRcdFx0KHJlc291cmNlX2lkID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAncmVzb3VyY2VfaWQnIF0pXHJcblx0XHRcdFx0XHRcdCYmIChmdW5jdGlvbl9uYW1lID09PSBwX2JhbGFuY2VyWyAnaW5fcHJvY2VzcycgXVsgaSBdWyAnZnVuY3Rpb25fbmFtZScgXSlcclxuXHRcdFx0XHRcdCl7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cclxuXHJcblx0b2JqLmJhbGFuY2VyX19ydW5fbmV4dCA9IGZ1bmN0aW9uICgpe1xyXG5cclxuXHRcdC8vIEdldCAxc3QgZnJvbSAgV2FpdCBsaXN0XHJcblx0XHR2YXIgcmVtb3ZlZF9lbCA9IGZhbHNlO1xyXG5cdFx0aWYgKCBwX2JhbGFuY2VyWyAnd2FpdCcgXS5sZW5ndGggKXtcdFx0XHRcdFx0Ly8gRml4SW46IDkuOC4xMC4xLlxyXG5cdFx0XHRmb3IgKCB2YXIgaSBpbiBwX2JhbGFuY2VyWyAnd2FpdCcgXSApe1xyXG5cdFx0XHRcdHJlbW92ZWRfZWwgPSBvYmouYmFsYW5jZXJfX3JlbW92ZV9mcm9tX193YWl0X2xpc3QoIHBfYmFsYW5jZXJbICd3YWl0JyBdWyBpIF1bICdyZXNvdXJjZV9pZCcgXSwgcF9iYWxhbmNlclsgJ3dhaXQnIF1bIGkgXVsgJ2Z1bmN0aW9uX25
3411hbWUnIF0gKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggZmFsc2UgIT09IHJlbW92ZWRfZWwgKXtcclxuXHJcblx0XHRcdC8vIFJ1blxyXG5cdFx0XHRvYmouYmFsYW5jZXJfX3J1biggcmVtb3ZlZF9lbCApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0IC8qKlxyXG5cdCAgKiBSdW5cclxuXHQgICogQHBhcmFtIGJhbGFuY2Vfb2JqXHJcblx0ICAqL1xyXG5cdG9iai5iYWxhbmNlcl9fcnVuID0gZnVuY3Rpb24gKCBiYWxhbmNlX29iaiApe1xyXG5cclxuXHRcdHN3aXRjaCAoIGJhbGFuY2Vfb2JqWyAnZnVuY3Rpb25fbmFtZScgXSApe1xyXG5cclxuXHRcdFx0Y2FzZSAnd3BiY19jYWxlbmRhcl9fbG9hZF9kYXRhX19hangnOlxyXG5cclxuXHRcdFx0XHQvLyBBZGQgdG8gcnVuIGxpc3RcclxuXHRcdFx0XHRvYmouYmFsYW5jZXJfX2FkZF90b19fcnVuKCBiYWxhbmNlX29iaiApO1xyXG5cclxuXHRcdFx0XHR3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCggYmFsYW5jZV9vYmpbICdwYXJhbXMnIF0gKVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0ZGVmYXVsdDpcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBvYmo7XHJcblxyXG59KCBfd3BiYyB8fCB7fSwgalF1ZXJ5ICkpO1xyXG5cclxuXHJcbiBcdC8qKlxyXG4gXHQgKiAtLSBIZWxwIGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0ICovXHJcblxyXG5cdGZ1bmN0aW9uIHdwYmNfYmFsYW5jZXJfX2lzX3dhaXQoIHBhcmFtcywgZnVuY3Rpb25fbmFtZSApe1xyXG4vL2NvbnNvbGUubG9nKCc6OndwYmNfYmFsYW5jZXJfX2lzX3dhaXQnLHBhcmFtcyAsIGZ1bmN0aW9uX25
3411hbWUgKTtcclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAocGFyYW1zWyAncmVzb3VyY2VfaWQnIF0pICl7XHJcblxyXG5cdFx0XHR2YXIgYmFsYW5jZXJfc3RhdHVzID0gX3dwYmMuYmFsYW5jZXJfX2luaXQoIHBhcmFtc1sgJ3Jlc291cmNlX2lkJyBdLCBmdW5jdGlvbl9uYW1lLCBwYXJhbXMgKTtcclxuXHJcblx0XHRcdHJldHVybiAoICd3YWl0JyA9PT0gYmFsYW5jZXJfc3RhdHVzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblxyXG5cdGZ1bmN0aW9uIHdwYmNfYmFsYW5jZXJfX2NvbXBsZXRlZCggcmVzb3VyY2VfaWQgLCBmdW5jdGlvbl9uYW1lICl7XHJcbi8vY29uc29sZS5sb2coJzo6d3BiY19iYWxhbmNlcl9fY29tcGxldGVkJyxyZXNvdXJjZV9pZCAsIGZ1bmN0aW9uX25hbWUgKTtcclxuXHRcdF93cGJjLmJhbGFuY2VyX19yZW1vdmVfZnJvbV9fcnVuX2xpc3QoIHJlc291cmNlX2lkLCBmdW5jdGlvbl9uYW1lICk7XHJcblx0XHRfd3BiYy5iYWxhbmNlcl9fcnVuX25leHQoKTtcclxuXHR9IiwiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWwvd3BiY19jYWwuanNcclxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIE9yZGVyIG9yIGNoaWxkIGJvb2tpbmcgcmVzb3VyY2VzIHNhdmVkIGhlcmU6ICBcdF93cGJjLmJvb2tpbmdfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdyZXNvdXJjZXNfaWRfYXJyX19pbl9kYXRlcycgKVx0XHRbMiwxMCwxMiwxMV1cclxuICovXHJcblxyXG4vKipcclxuICogSG93IHRvIGNoZWNrICBib29rZWQgdGltZXMgb24gIHNwZWNpZmljIGRhdGU6ID9cclxuICpcclxuXHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJyk7XHJcblxyXG5cdFx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHMsXHJcblx0XHRcdFx0XHRcdF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoMiwnMjAyMy0wOC0yMScpWzEwXS5ib29rZWRfdGltZV9zbG90cy5tZXJnZWRfc2Vjb25kcyxcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMTFdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHNcclxuXHRcdFx0XHRcdCk7XHJcbiAqICBPUlxyXG5cdFx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XHRcdFx0X3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMF0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMV0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlLFxyXG5cdFx0XHRcdFx0XHRfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKDIsJzIwMjMtMDgtMjEnKVsxMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3JlYWRhYmxlXHJcblx0XHRcdFx0XHQpO1xyXG4gKlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBEYXlzIHNlbGVjdGlvbjpcclxuICogXHRcdFx0XHRcdHdwYmNfY2FsZW5kYXJfX3Vuc2VsZWN0X2FsbF9kYXRlcyggcmVzb3VyY2VfaWQgKTtcclxuICpcclxuICpcdFx0XHRcdFx0dmFyIHJlc291cmNlX2lkID0gMTtcclxuICogXHRFeGFtcGxlIDE6XHRcdHZhciBudW1fc2VsZWN0ZWRfZGF5cyA9IHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHJlc291cmNlX2lkLCAnMjAyNC0wNS0xNScsICcyMDI0LTA1LTI1JyApO1xyXG4gKiBcdEV4YW1wbGUgMjpcdFx0dmFyIG51bV9zZWxlY3RlZF9kYXlzID0gd3BiY19hdXRvX3NlbGVjdF9kYXRlc19pbl9jYWxlbmRhciggcmVzb3VyY2VfaWQsIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTI1J10gKTtcclxuICpcclxuICovXHJcblxyXG5cclxuLyoqXHJcbiAqIEMgQSBMIEUgTiBEIEEgUiAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAqL1xyXG5cclxuXHJcbi8qKlxyXG4gKiAgU2hvdyBXUEJDIENhbGVuZGFyXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZFx0XHRcdC0gcmVzb3VyY2UgSURcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2NhbGVuZGFyX3Nob3coIHJlc291cmNlX2lkICl7XHJcblxyXG5cdC8vIElmIG5vIGNhbGVuZGFyIEhUTUwgdGFnLCAgdGhlbiAgZXhpdFxyXG5cdGlmICggMCA9PT0galF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5sZW5ndGggKXsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG5cdC8vIElmIHRoZSBjYWxlbmRhciB3aXRoIHRoZSBzYW1lIEJvb2tpbmcgcmVzb3VyY2UgaXMgYWN0aXZhdGVkIGFscmVhZHksIHRoZW4gZXhpdC5cclxuXHRpZiAoIHRydWUgPT09IGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkuaGFzQ2xhc3MoICdoYXNEYXRlcGljaycgKSApeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBEYXlzIHNlbGVjdGlvblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0dmFyIGxvY2FsX19pc19yYW5nZV9zZWxlY3QgPSBmYWxzZTtcclxuXHR2YXIgbG9jYWxfX211bHRpX2RheXNfc2VsZWN0X251bSAgID0gMzY1O1x0XHRcdFx0XHQvLyBtdWx0aXBsZSB8IGZpeGVkXHJcblx0aWYgKCAnZHluYW1pYycgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0bG9jYWxfX2lzX3JhbmdlX3NlbGVjdCA9IHRydWU7XHJcblx0XHRsb2NhbF9fbXVsdGlfZGF5c19zZWxlY3RfbnVtID0gMDtcclxuXHR9XHJcblx0aWYgKCAnc2luZ2xlJyAgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0bG9jYWxfX211bHRpX2RheXNfc2VsZWN0X251bSA9IDA7XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIE1pbiAtIE1heCBkYXlzIHRvIHNjcm9sbC9zaG93XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgbG9jYWxfX21pbl9kYXRlID0gMDtcclxuIFx0bG9jYWxfX21pbl9kYXRlID0gbmV3IERhdGUoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgKVsgMCBdLCAocGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgKVsgMSBdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAyIF0sIDAsIDAsIDAgKTtcdFx0XHQvLyBGaXhJbjogOS45LjAuMTcuXHJcbi8vY29uc29sZS5sb2coIGxvY2FsX19taW5fZGF0ZSApO1xyXG5cdHZhciBsb2NhbF9fbWF4X2RhdGUgPSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2Jvb2tpbmdfbWF4X21vbnRoZXNfaW5fY2FsZW5kYXInICk7XHJcblx0Ly9sb2NhbF9fbWF4X2RhdGUgPSBuZXcgRGF0ZSgyMDI0LCA1LCAyOCk7ICBJdCBpcyBoZXJlIGlzc3VlIG9mIG5vdCBzZWxlY3RhYmxlIGRhdGVzLCBidXQgc29tZSBkYXRlcyBzaG93aW5nIGluIGNhbGVuZGFyIGFzIGF2YWlsYWJsZSwgYnV0IHdlIGNhbiBub3Qgc2VsZWN0IGl0LlxyXG5cclxuXHQvLy8vIERlZmluZSBsYXN0IGRheSBpbiBjYWxlbmRhciAoYXMgYSBsYXN0IGRheSBvZiBtb250aCAoYW5kIG5vdCBkYXRlLCB3aGljaCBpcyByZWxhdGVkIHRvIGFjdHVhbCAnVG9kYXknIGRhdGUpLlxyXG5cdC8vLy8gRS5nLiBpZiB0b2RheSBpcyAyMDIzLTA5LTI1LCBhbmQgd2Ugc2V0ICdOdW1iZXIgb2YgbW9udGhzIHRvIHNjcm9sbCcgYXMgNSBtb250aHMsIHRoZW4gbGFzdCBkYXkgd2lsbCBiZSAyMDI0LTAyLTI5IGFuZCBub3QgdGhlIDIwMjQtMDItMjUuXHJcblx0Ly8gdmFyIGNhbF9sYXN0X2RheV9pbl9tb250aCA9IGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggbnVsbCwgbG9jYWxfX21heF9kYXRlLCBuZXcgRGF0ZSgpICk7XHJcblx0Ly8gY2FsX2xhc3RfZGF5X2luX2
34111vbnRoID0gbmV3IERhdGUoIGNhbF9sYXN0X2RheV9pbl9tb250aC5nZXRGdWxsWWVhcigpLCBjYWxfbGFzdF9kYXlfaW5fbW9udGguZ2V0TW9udGgoKSArIDEsIDAgKTtcclxuXHQvLyBsb2NhbF9fbWF4X2RhdGUgPSBjYWxfbGFzdF9kYXlfaW5fbW9udGg7XHRcdFx0Ly8gRml4SW46IDEwLjAuMC4yNi5cclxuXHJcblx0Ly8gR2V0IHN0YXJ0IC8gZW5kIGRhdGVzIGZyb20gIHRoZSBCb29raW5nIENhbGVuZGFyIHNob3J0Y29kZS4gRXhhbXBsZTogW2Jvb2tpbmcgY2FsZW5kYXJfZGF0ZXNfc3RhcnQ9JzIwMjYtMDEtMDEnIGNhbGVuZGFyX2RhdGVzX2VuZD0nMjAyNi0xMi0zMScgIHJlc291cmNlX2lkPTFdIC8vIEZpeEluOiAxMC4xMy4xLjQuXHJcblx0aWYgKCBmYWxzZSAhPT0gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0KCByZXNvdXJjZV9pZCApICkge1xyXG5cdFx0bG9jYWxfX21pbl9kYXRlID0gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX3N0YXJ0KCByZXNvdXJjZV9pZCApOyAgLy8gRS5nLiAtIGxvY2FsX19taW5fZGF0ZSA9IG5ldyBEYXRlKCAyMDI1LCAwLCAxICk7XHJcblx0fVxyXG5cdGlmICggZmFsc2UgIT09IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHJlc291cmNlX2lkICkgKSB7XHJcblx0XHRsb2NhbF9fbWF4X2RhdGUgPSB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfZW5kKCByZXNvdXJjZV9pZCApOyAgICAvLyBFLmcuIC0gbG9jYWxfX21heF9kYXRlID0gbmV3IERhdGUoIDIwMjUsIDExLCAzMSApO1xyXG5cdH1cclxuXHJcblx0Ly8gSW4gY2FzZSB3ZSBlZGl0IGJvb2tpbmcgaW4gcGFzdCBvciBoYXZlIHNwZWNpZmljIHBhcmFtZXRlciBpbiBVUkwuXHJcblx0aWYgKCAgICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCdwYWdlPXdwYmMtbmV3JykgIT0gLTEgKVxyXG5cdFx0JiYgKFxyXG5cdFx0XHQgICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCdib29raW5nX2hhc2gnKSAhPSAtMSApICAgICAgICAgICAgICAgICAgLy8gQ29tbWVudCB0aGlzIGxpbmUgZm9yIGFiaWxpdHkgdG8gYWRkICBib29raW5nIGluIHBhc3QgZGF5cyBhdCAgQm9va2luZyA+IEFkZCBib29raW5nIHBhZ2UuXHJcblx0XHQgICB8fCAoIGxvY2F0aW9uLmhyZWYuaW5kZXhPZignYWxsb3dfcGFzdCcpICE9IC0xICkgICAgICAgICAgICAgICAgLy8gRml4SW46IDEwLjcuMS4yLlxyXG5cdFx0KVxyXG5cdCl7XHJcblx0XHQvLyBsb2NhbF9fbWluX2RhdGUgPSBudWxsO1xyXG5cdFx0Ly8gRml4SW46IDEwLjE0LjEuNC5cclxuXHRcdGxvY2FsX19taW5fZGF0ZSAgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMF0sICggcGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzFdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMl0sIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzNdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0aW1lX2xvY2FsX2FycicgKVs0XSwgMCApO1xyXG5cdFx0bG9jYWxfX21heF9kYXRlID0gbnVsbDtcclxuXHR9XHJcblxyXG5cdHZhciBsb2NhbF9fc3RhcnRfd2Vla2RheSAgICA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnYm9va2luZ19zdGFydF9kYXlfd2VlZWsnICk7XHJcblx0dmFyIGxvY2FsX19udW1iZXJfb2ZfbW9udGhzID0gcGFyc2VJbnQoIF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnY2FsZW5kYXJfbnVtYmVyX29mX21vbnRocycgKSApO1xyXG5cclxuXHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLnRleHQoICcnICk7XHRcdFx0XHRcdC8vIFJlbW92ZSBhbGwgSFRNTCBpbiBjYWxlbmRhciB0YWdcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIFNob3cgY2FsZW5kYXJcclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdGpRdWVyeSgnI2NhbGVuZGFyX2Jvb2tpbmcnKyByZXNvdXJjZV9pZCkuZGF0ZXBpY2soXHJcblx0XHRcdHtcclxuXHRcdFx0XHRiZWZvcmVTaG93RGF5OiBmdW5jdGlvbiAoIGpzX2RhdGUgKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19hcHBseV9jc3NfdG9fZGF5cygganNfZGF0ZSwgeydyZXNvdXJjZV9pZCc6IHJlc291cmNlX2lkfSwgdGhpcyApO1xyXG5cdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRvblNlbGVjdDogZnVuY3Rpb24gKCBzdHJpbmdfZGF0ZXMsIGpzX2RhdGVzX2FyciApeyAgLyoqXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKlx0c3RyaW5nX2RhdGVzICAgPSAgICcyMy4wOC4yMDIzIC0gMjYuMDguMjAyMycgICAgfCAgICAnMjMuMDguMjAyMyAtIDIzLjA4LjIwMjMnICAgIHwgICAgJzE5LjA5LjIwMjMsIDI0LjA4LjIwMjMsIDMwLjA5LjIwMjMnXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKiAganNfZGF0ZXNfYXJyICAgPSAgIHJhbmdlOiBbIERhdGUgKEF1ZyAyMyAyMDIzKSwgRGF0ZSAoQXVnIDI1IDIwMjMpXSAgICAgfCAgICAgbXVsdGlwbGU6IFsgRGF0ZShPY3QgMjQgMjAyMyksIERhdGUoT2N0IDIwIDIwMjMpLCBEYXRlKE9jdCAxNiAyMDIzKSBdXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKi9cclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyggc3RyaW5nX2RhdGVzLCB7J3Jlc291cmNlX2lkJzogcmVzb3VyY2VfaWR9LCB0aGlzICk7XHJcblx0XHRcdFx0XHRcdFx0ICB9LFxyXG5cdFx0XHRcdG9uSG92ZXI6IGZ1bmN0aW9uICggc3RyaW5nX2RhdGUsIGpzX2RhdGUgKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHdwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzKCBzdHJpbmdfZGF0ZSwganNfZGF0ZSwgeydyZXNvdXJjZV9pZCc6IHJlc291cmNlX2lkfSwgdGhpcyApO1xyXG5cdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRvbkNoYW5nZU1vbnRoWWVhcjogZnVuY3Rpb24gKCB5ZWFyLCByZWFsX21vbnRoLCBqc19kYXRlX18xc3RfZGF5X2luX2
34111vbnRoICl7IH0sXHJcblx0XHRcdFx0c2hvd09uICAgICAgICA6ICdib3RoJyxcclxuXHRcdFx0XHRudW1iZXJPZk1vbnRoczogbG9jYWxfX251bWJlcl9vZl9tb250aHMsXHJcblx0XHRcdFx0c3RlcE1vbnRocyAgICA6IDEsXHJcblx0XHRcdFx0Ly8gcHJldlRleHQgICAgICA6ICcmbGFxdW87JyxcclxuXHRcdFx0XHQvLyBuZXh0VGV4dCAgICAgIDogJyZyYXF1bzsnLFxyXG5cdFx0XHRcdHByZXZUZXh0ICAgICAgOiAnJmxzYXF1bzsnLFxyXG5cdFx0XHRcdG5leHRUZXh0ICAgICAgOiAnJnJzYXF1bzsnLFxyXG5cdFx0XHRcdGRhdGVGb3JtYXQgICAgOiAnZGQubW0ueXknLFxyXG5cdFx0XHRcdGNoYW5nZU1vbnRoICAgOiBmYWxzZSxcclxuXHRcdFx0XHRjaGFuZ2VZZWFyICAgIDogZmFsc2UsXHJcblx0XHRcdFx0bWluRGF0ZSAgICAgICA6IGxvY2FsX19taW5fZGF0ZSxcclxuXHRcdFx0XHRtYXhEYXRlICAgICAgIDogbG9jYWxfX21heF9kYXRlLCBcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzFZJyxcclxuXHRcdFx0XHQvLyBtaW5EYXRlOiBuZXcgRGF0ZSgyMDIwLCAyLCAxKSwgbWF4RGF0ZTogbmV3IERhdGUoMjAyMCwgOSwgMzEpLCAgICAgICAgICAgICBcdC8vIEFiaWxpdHkgdG8gc2V0IGFueSAgc3RhcnQgYW5kIGVuZCBkYXRlIGluIGNhbGVuZGFyXHJcblx0XHRcdFx0c2hvd1N0YXR1cyAgICAgIDogZmFsc2UsXHJcblx0XHRcdFx0bXVsdGlTZXBhcmF0b3IgIDogJywgJyxcclxuXHRcdFx0XHRjbG9zZUF0VG9wICAgICAgOiBmYWxzZSxcclxuXHRcdFx0XHRmaXJzdERheSAgICAgICAgOiBsb2NhbF9fc3RhcnRfd2Vla2RheSxcclxuXHRcdFx0XHRnb3RvQ3VycmVudCAgICAgOiBmYWxzZSxcclxuXHRcdFx0XHRoaWRlSWZOb1ByZXZOZXh0OiB0cnVlLFxyXG5cdFx0XHRcdG11bHRpU2VsZWN0ICAgICA6IGxvY2FsX19tdWx0aV9kYXlzX3NlbGVjdF9udW0sXHJcblx0XHRcdFx0cmFuZ2VTZWxlY3QgICAgIDogbG9jYWxfX2lzX3JhbmdlX3NlbGVjdCxcclxuXHRcdFx0XHQvLyBzaG93V2Vla3M6IHRydWUsXHJcblx0XHRcdFx0dXNlVGhlbWVSb2xsZXI6IGZhbHNlXHJcblx0XHRcdH1cclxuXHQpO1xyXG5cclxuXHJcblx0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBDbGVhciB0b2RheSBkYXRlIGhpZ2hsaWdodGluZ1xyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0c2V0VGltZW91dCggZnVuY3Rpb24gKCl7ICB3cGJjX2NhbGVuZGFyc19fY2xlYXJfZGF5c19oaWdobGlnaHRpbmcoIHJlc291cmNlX2lkICk7ICB9LCA1MDAgKTsgICAgICAgICAgICAgICAgICAgIFx0Ly8gRml4SW46IDcuMS4yLjguXHJcblx0XHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvLyBTY3JvbGwgY2FsZW5kYXIgdG8gIHNwZWNpZmljIG1vbnRoXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHR2YXIgc3RhcnRfYmtfbW9udGggPSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2NhbGVuZGFyX3Njcm9sbF90bycgKTtcclxuXHRpZiAoIGZhbHNlICE9PSBzdGFydF9ia19tb250aCApe1xyXG5cdFx0d3BiY19jYWxlbmRhcl9fc2Nyb2xsX3RvKCByZXNvdXJjZV9pZCwgc3RhcnRfYmtfbW9udGhbIDAgXSwgc3RhcnRfYmtfbW9udGhbIDEgXSApO1xyXG5cdH1cclxufVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogQXBwbHkgQ1NTIHRvIGNhbGVuZGFyIGRhdGUgY2VsbHNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRcdFx0XHRcdFx0XHQtICBKYXZhU2NyaXB0IERhdGUgT2JqOiAgXHRcdE1vbiBEZWMgMTEgMjAyMyAwMDowMDowMCBHTVQrMDIwMCAoRWFzdGVybiBFdXJvcGVhbiBTdGFuZGFyZCBUaW1lKVxyXG5cdCAqIEBwYXJhbSBjYWxlbmRhcl9wYXJhbXNfYXJyXHRcdFx0XHRcdFx0LSAgQ2FsZW5kYXIgU2V0dGluZ3MgT2JqZWN0OiAgXHR7XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgXHRcdFx0XHRcdFx0XCJyZXNvdXJjZV9pZFwiOiA0XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0ICogQHBhcmFtIGRhdGVwaWNrX3RoaXNcdFx0XHRcdFx0XHRcdFx0LSB0aGlzIG9mIGRhdGVwaWNrIE9ialxyXG5cdCAqIEByZXR1cm5zIHsoKnxzdHJpbmcpW118KGJvb2xlYW58c3RyaW5nKVtdfVx0XHQtIFsge3RydWUgLWF2YWlsYWJsZSB8IGZhbHNlIC0gdW5hdmFpbGFibGV9LCAnQ1NTIGNsYXNzZXMgZm9yIGNhbGVuZGFyIGRheSBjZWxsJyBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fY2FsZW5kYXJfX2FwcGx5X2Nzc190b19kYXlzKCBkYXRlLCBjYWxlbmRhcl9wYXJhbXNfYXJyLCBkYXRlcGlja190aGlzICl7XHJcblxyXG5cdFx0dmFyIHRvZGF5X2RhdGUgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAwIF0sIChwYXJzZUludCggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyApWyAxIF0gKSAtIDEpLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0b2RheV9hcnInIClbIDIgXSwgMCwgMCwgMCApO1x0XHRcdFx0XHRcdFx0XHQvLyBUb2RheSBKU19EYXRlX09iai5cclxuXHRcdHZhciBjbGFzc19kYXkgICAgID0gd3BiY19fZ2V0X190ZF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzEtOS0yMDIzJ1xyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzIwMjMtMDEtMDknXHJcblx0XHR2YXIgcmVzb3VyY2VfaWQgPSAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdKSApID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnOyBcdFx0Ly8gJzEnXHJcblxyXG5cdFx0Ly8gR2V0IFNlbGVjdGVkIGRhdGVzIGluIGNhbGVuZGFyXHJcblx0XHR2YXIgc2VsZWN0ZWRfZGF0ZXNfc3FsID0gd3BiY19nZXRfX3NlbGVjdGVkX2RhdGVzX3NxbF9fYXNfYXJyKCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdC8vIEdldCBEYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHR2YXIgZGF0ZV9ib29raW5nc19vYmogPSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2NsYXNzX2RheSApO1xyXG5cclxuXHJcblx0XHQvLyBBcnJheSB3aXRoIENTUyBjbGFzc2VzIGZvciBkYXRlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIGNzc19jbGFzc2VzX19mb3JfZGF0ZSA9IFtdO1xyXG5cdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdzcWxfZGF0ZV8nICAgICArIHNxbF9jbGFzc19kYXkgKTtcdFx0XHRcdC8vICAnc3FsX2RhdGVfMjAyMy0wNy0yMSdcclxuXHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2FsNGRhdGUtJyAgICAgKyBjbGFzc19kYXkgKTtcdFx0XHRcdFx0Ly8gICdjYWw0ZGF0ZS03LTIxLTIwMjMnXHJcblx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3dwYmNfd2Vla2RheV8nICsgZGF0ZS5nZXREYXkoKSApO1x0XHRcdFx0Ly8gICd3cGJjX3dlZWtkYXlfNCdcclxuXHJcblx0XHQvLyBEZWZpbmUgU2VsZWN0ZWQgQ2hlY2sgSW4vT3V0IGRhdGVzIGluIFREICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0aWYgKFxyXG5cdFx0XHRcdCggc2VsZWN0ZWRfZGF0ZXNfc3FsLmxlbmd0aCAgKVxyXG5cdFx0XHQvLyYmICAoIHNlbGVjdGVkX2RhdGVzX3NxbFsgMCBdICE9PSBzZWxlY3RlZF9kYXRlc19zcWxbIChzZWxlY3RlZF9kYXRlc19zcWwubGVuZ3RoIC0gMSkgXSApXHJcblx0XHQpe1xyXG5cdFx0XHRpZiAoIHNxbF9jbGFzc19kYXkgPT09IHNlbGVjdGVkX2RhdGVzX3NxbFsgMCBdICl7XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdzZWxlY3RlZF9jaGVja19pbicgKTtcclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3NlbGVjdGVkX2NoZWNrX2luX291dCcgKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoICAoIHNlbGVjdGVkX2RhdGVzX3NxbC5sZW5ndGggPiAxICkgJiYgKCBzcWxfY2xhc3NfZGF5ID09PSBzZWxlY3RlZF9kYXRlc19zcWxbIChzZWxlY3RlZF9kYXRlc19zcWwubGVuZ3RoIC0gMSkgXSApICkge1xyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnc2VsZWN0ZWRfY2hlY2tfb3V0JyApO1xyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnc2VsZWN0ZWRfY2hlY2tfaW5fb3V0JyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdHZhciBpc19kYXlfc2VsZWN0YWJsZSA9IGZhbHNlO1xyXG5cclxuXHRcdC8vIElmIHNvbWV0aGluZyBub3QgZGVmaW5lZCwgIHRoZW4gIHRoaXMgZGF0ZSBjbG9zZWQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vIEZpeEluOiAxMC4xMi40LjYuXHJcblx0XHRpZiAoIChmYWxzZSA9PT0gZGF0ZV9ib29raW5nc19vYmopIHx8ICgndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChkYXRlX2Jvb2tpbmdzX29ialtyZXNvdXJjZV9pZF0pKSApIHtcclxuXHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJyApO1xyXG5cclxuXHRcdFx0cmV0dXJuIFsgaXNfZGF5X3NlbGVjdGFibGUsIGNzc19jbGFzc2VzX19mb3JfZGF0ZS5qb2luKCcgJykgIF07XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyAgIGRhdGVfYm9va2luZ3Nfb2JqICAtIERlZmluZWQuICAgICAgICAgICAgRGF0ZXMgY2FuIGJlIHNlbGVjdGFibGUuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyBBZGQgc2Vhc29uIG5hbWVzIHRvIHRoZSBkYXkgQ1NTIGNsYXNzZXMgLS0gaXQgaXMgcmVxdWlyZWQgZm9yIGNvcnJlY3QgIHdvcmsgIG9mIGNvbmRpdGlvbmFsIGZpZWxkcyAtLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIHNlYXNvbl9uYW1lc19hcnIgPSBfd3BiYy5zZWFzb25zX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICk7XHJcblxyXG5cdFx0Zm9yICggdmFyIHNlYXNvbl9rZXkgaW4gc2Vhc29uX25hbWVzX2FyciApe1xyXG5cclxuXHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goIHNlYXNvbl9uYW1lc19hcnJbIHNlYXNvbl9rZXkgXSApO1x0XHRcdFx0Ly8gICd3cGRldmJrX3NlYXNvbl9zZXB0ZW1iZXJfMjAyMydcclxuXHRcdH1cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cclxuXHRcdC8vIENvc3QgUmF0ZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3JhdGVfJyArIGRhdGVfYm9va2luZ3Nfb2JqWyByZXNvdXJjZV9pZCBdWyAnZGF0ZV9jb3N0X3JhdGUnIF0udG9TdHJpbmc
3411oKS5yZXBsYWNlKCAvW1xcLlxcc10vZywgJ18nICkgKTtcdFx0XHRcdFx0XHQvLyAgJ3JhdGVfOTlfMDAnIC0+IDk5LjAwXHJcblxyXG5cclxuXHRcdGlmICggcGFyc2VJbnQoIGRhdGVfYm9va2luZ3Nfb2JqWyAnZGF5X2F2YWlsYWJpbGl0eScgXSApID4gMCApe1xyXG5cdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IHRydWU7XHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV9hdmFpbGFibGUnICk7XHJcblx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAncmVzZXJ2ZWRfZGF5c19jb3VudCcgKyBwYXJzZUludCggZGF0ZV9ib29raW5nc19vYmpbICdtYXhfY2FwYWNpdHknIF0gLSBkYXRlX2Jvb2tpbmdzX29ialsgJ2RheV9hdmFpbGFiaWxpdHknIF0gKSApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aXNfZGF5X3NlbGVjdGFibGUgPSBmYWxzZTtcclxuXHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdHN3aXRjaCAoIGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2RheScgXSApe1xyXG5cclxuXHRcdFx0Y2FzZSAnYXZhaWxhYmxlJzpcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ3RpbWVfc2xvdHNfYm9va2luZyc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICd0aW1lc3BhcnRseScsICd0aW1lc19jbG9jaycgKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ2Z1bGxfZGF5X2Jvb2tpbmcnOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZnVsbF9kYXlfYm9va2luZycgKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ3NlYXNvbl9maWx0ZXInOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJywgJ3NlYXNvbl91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAncmVzb3VyY2VfYXZhaWxhYmlsaXR5JzpcclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2RhdGVfdXNlcl91bmF2YWlsYWJsZScsICdyZXNvdXJjZV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnd2Vla2RheV91bmF2YWlsYWJsZSc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnLCAnd2Vla2RheV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnZnJvbV90b2RheV91bmF2YWlsYWJsZSc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX3VzZXJfdW5hdmFpbGFibGUnLCAnZnJvbV90b2RheV91bmF2YWlsYWJsZScgKTtcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSA9ICcnO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXNldCBib29raW5nIHN0YXR1cyBjb2xvciBmb3IgcG9zc2libGUgb2xkIGJvb2tpbmdzIG9uIHRoaXMgZGF0ZVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnbGltaXRfYXZhaWxhYmxlX2Zyb21fdG9kYXknOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnZGF0ZV91c2VyX3VuYXZhaWxhYmxlJywgJ2xpbWl0X2F2YWlsYWJsZV9mcm9tX3RvZGF5JyApO1xyXG5cdFx0XHRcdGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2Jvb2tpbmdzJyBdID0gJyc7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFJlc2V0IGJvb2tpbmcgc3RhdHVzIGNvbG9yIGZvciBwb3NzaWJsZSBvbGQgYm9va2luZ3Mgb24gdGhpcyBkYXRlXHJcblx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRjYXNlICdjaGFuZ2Vfb3Zlcic6XHJcblx0XHRcdFx0LypcclxuXHRcdFx0XHQgKlxyXG5cdFx0XHRcdC8vICBjaGVja19vdXRfdGltZV9kYXRlMmFwcHJvdmUgXHQgXHRjaGVja19pbl90aW1lX2RhdGUyYXBwcm92ZVxyXG5cdFx0XHRcdC8vICBjaGVja19vdXRfdGltZV9kYXRlMmFwcHJvdmUgXHQgXHRjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWRcclxuXHRcdFx0XHQvLyAgY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUgXHRcdCBcdGNoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWRcclxuXHRcdFx0XHQvLyAgY2hlY2tfb3V0X3RpbWVfZGF0ZV9hcHByb3ZlZCBcdCBcdGNoZWNrX2luX3RpbWVfZGF0ZV9hcHByb3ZlZFxyXG5cdFx0XHRcdCAqL1xyXG5cclxuXHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ3RpbWVzcGFydGx5JywgJ2NoZWNrX2luX3RpbWUnLCAnY2hlY2tfb3V0X3RpbWUnICk7XHJcblx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC4yLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAnYXBwcm92ZWRfcGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnLCAnY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3R
3411hdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZ19hcHByb3ZlZCcgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGUyYXBwcm92ZScsICdjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0Y2FzZSAnY2hlY2tfaW4nOlxyXG5cdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAndGltZXNwYXJ0bHknLCAnY2hlY2tfaW5fdGltZScgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4SW46IDkuOS4wLjMzLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX2luX3RpbWVfZGF0ZTJhcHByb3ZlJyApO1xyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeScgXVsgJ3N0YXR1c19mb3JfYm9va2luZ3MnIF0uaW5kZXhPZiggJ2FwcHJvdmVkJyApID4gLTEgKXtcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfaW5fdGltZV9kYXRlX2FwcHJvdmVkJyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdGNhc2UgJ2NoZWNrX291dCc6XHJcblx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICd0aW1lc3BhcnRseScsICdjaGVja19vdXRfdGltZScgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4SW46IDkuOS4wLjMzLlxyXG5cdFx0XHRcdGlmICggZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5JyBdWyAnc3RhdHVzX2Zvcl9ib29raW5ncycgXS5pbmRleE9mKCAncGVuZGluZycgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGUyYXBwcm92ZScgKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknIF1bICdzdGF0dXNfZm9yX2Jvb2tpbmdzJyBdLmluZGV4T2YoICdhcHByb3ZlZCcgKSA+IC0xICl7XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0XHQvLyBtaXhlZCBzdGF0dXNlczogJ2NoYW5nZV9vdmVyIGNoZWNrX291dCcgLi4uLiB2YXJpYXRpb25zLi4uLiBjaGVjayBtb3JlIGluIFx0XHRmdW5jdGlvbiB3cGJjX2dldF9hdmFpbGFiaWxpdHlfcGVyX2RheXNfYXJyKClcclxuXHRcdFx0XHRkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9kYXknIF0gPSAnYXZhaWxhYmxlJztcclxuXHRcdH1cclxuXHJcblxyXG5cclxuXHRcdGlmICggJ2F2YWlsYWJsZScgIT0gZGF0ZV9ib29raW5nc19vYmpbICdzdW1tYXJ5J11bJ3N0YXR1c19mb3JfZGF5JyBdICl7XHJcblxyXG5cdFx0XHR2YXIgaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlID0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdwZW5kaW5nX2RheXNfc2VsZWN0YWJsZScgKTtcdC8vIHNldCBwZW5kaW5nIGRheXMgc2VsZWN0YWJsZSAgICAgICAgICAvLyBGaXhJbjogOC42LjEuMTguXHJcblxyXG5cdFx0XHRzd2l0Y2ggKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSApe1xyXG5cclxuXHRcdFx0XHRjYXNlICcnOlxyXG5cdFx0XHRcdFx0Ly8gVXN1YWxseSAgaXQncyBtZWFucyB0aGF0IGRheSAgaXMgYXZhaWxhYmxlIG9yIHVuYXZhaWxhYmxlIHdpdGhvdXQgdGhlIGJvb2tpbmdzXHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZyc6XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2RhdGUyYXBwcm92ZScgKTtcclxuXHRcdFx0XHRcdGlzX2RheV9zZWxlY3RhYmxlID0gKGlzX2RheV9zZWxlY3RhYmxlKSA/IHRydWUgOiBpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWQnOlxyXG5cdFx0XHRcdFx0Y3NzX2NsYXNzZXNfX2Zvcl9kYXRlLnB1c2goICdkYXRlX2FwcHJvdmVkJyApO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbnMgZm9yIFwiY2hhbmdlLW92ZXJcIiBkYXlzOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZ19wZW5kaW5nJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZTJhcHByb3ZlJywgJ2NoZWNrX2luX3RpbWVfZGF0ZTJhcHByb3ZlJyApO1xyXG5cdFx0XHRcdFx0aXNfZGF5X3NlbGVjdGFibGUgPSAoaXNfZGF5X3NlbGVjdGFibGUpID8gdHJ1ZSA6IGlzX3NldF9wZW5kaW5nX2RheXNfc2VsZWN0YWJsZTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdFx0XHRjYXNlICdwZW5kaW5nX2FwcHJvdmVkJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZTJhcHByb3ZlJywgJ2NoZWNrX2luX3RpbWVfZGF0ZV9hcHByb3ZlZCcgKTtcclxuXHRcdFx0XHRcdGlzX2RheV9zZWxlY3RhYmxlID0gKGlzX2RheV9zZWxlY3RhYmxlKSA/IHRydWUgOiBpc19zZXRfcGVuZGluZ19kYXlzX3NlbGVjdGFibGU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWRfcGVuZGluZyc6XHJcblx0XHRcdFx0XHRjc3NfY2xhc3Nlc19fZm9yX2RhdGUucHVzaCggJ2NoZWNrX291dF90aW1lX2RhdGVfYXBwcm92ZWQnLCAnY2hlY2tfaW5fdGltZV9kYXRlMmFwcHJvdmUnICk7XHJcblx0XHRcdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IChpc19kYXlfc2VsZWN0YWJsZSkgPyB0cnVlIDogaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblxyXG5cdFx0XHRcdGNhc2UgJ2FwcHJvdmVkX2FwcHJvdmVkJzpcclxuXHRcdFx0XHRcdGNzc19jbGFzc2VzX19mb3JfZGF0ZS5wdXNoKCAnY2hlY2tfb3V0X3RpbWVfZGF0ZV9hcHByb3ZlZCcsICdjaGVja19pbl90aW1lX2RhdGVfYXBwcm92ZWQnICk7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gWyBpc19kYXlfc2VsZWN0YWJsZSwgY3NzX2NsYXNzZXNfX2Zvcl9kYXRlLmpvaW4oICcgJyApIF07XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogTW91c2VvdmVyIGNhbGVuZGFyIGRhdGUgY2VsbHNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBzdHJpbmdfZGF0ZVxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRcdFx0XHRcdFx0XHQtICBKYXZhU2NyaXB0IERhdGUgT2JqOiAgXHRcdE1vbiBEZWMgMTEgMjAyMyAwMDowMDowMCBHTVQrMDIwMCAoRWFzdGVybiBFdXJvcGVhbiBTdGFuZGFyZCBUaW
34111lKVxyXG5cdCAqIEBwYXJhbSBjYWxlbmRhcl9wYXJhbXNfYXJyXHRcdFx0XHRcdFx0LSAgQ2FsZW5kYXIgU2V0dGluZ3MgT2JqZWN0OiAgXHR7XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgXHRcdFx0XHRcdFx0XCJyZXNvdXJjZV9pZFwiOiA0XHJcblx0ICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0ICogQHBhcmFtIGRhdGVwaWNrX3RoaXNcdFx0XHRcdFx0XHRcdFx0LSB0aGlzIG9mIGRhdGVwaWNrIE9ialxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19vbl9ob3Zlcl9kYXlzKCBzdHJpbmdfZGF0ZSwgZGF0ZSwgY2FsZW5kYXJfcGFyYW1zX2FyciwgZGF0ZXBpY2tfdGhpcyApIHtcclxuXHJcblx0XHRpZiAoIG51bGwgPT09IGRhdGUgKSB7XHJcblx0XHRcdHdwYmNfY2FsZW5kYXJzX19jbGVhcl9kYXlzX2hpZ2hsaWdodGluZyggKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKGNhbGVuZGFyX3BhcmFtc19hcnJbICdyZXNvdXJjZV9pZCcgXSkpID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnICk7XHRcdC8vIEZpeEluOiAxMC41LjIuNC5cclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjbGFzc19kYXkgICAgID0gd3BiY19fZ2V0X190ZF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzEtOS0yMDIzJ1xyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzIwMjMtMDEtMDknXHJcblx0XHR2YXIgcmVzb3VyY2VfaWQgPSAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdKSApID8gY2FsZW5kYXJfcGFyYW1zX2FyclsgJ3Jlc291cmNlX2lkJyBdIDogJzEnO1x0XHQvLyAnMSdcclxuXHJcblx0XHQvLyBHZXQgRGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIGRhdGVfYm9va2luZ19vYmogPSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2NsYXNzX2RheSApO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyB7Li4ufVxyXG5cclxuXHRcdGlmICggISBkYXRlX2Jvb2tpbmdfb2JqICl7IHJldHVybiBmYWxzZTsgfVxyXG5cclxuXHJcblx0XHQvLyBUIG8gbyBsIHQgaSBwIHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIHRvb2x0aXBfdGV4dCA9ICcnO1xyXG5cdFx0aWYgKCBkYXRlX2Jvb2tpbmdfb2JqWyAnc3VtbWFyeSddWyd0b29sdGlwX2F2YWlsYWJpbGl0eScgXS5sZW5ndGggPiAwICl7XHJcblx0XHRcdHRvb2x0aXBfdGV4dCArPSAgZGF0ZV9ib29raW5nX29ialsgJ3N1bW1hcnknXVsndG9vbHRpcF9hdmFpbGFiaWxpdHknIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfZGF5X2Nvc3QnIF0ubGVuZ3RoID4gMCApe1xyXG5cdFx0XHR0b29sdGlwX3RleHQgKz0gIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfZGF5X2Nvc3QnIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfdGltZXMnIF0ubGVuZ3RoID4gMCApe1xyXG5cdFx0XHR0b29sdGlwX3RleHQgKz0gIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfdGltZXMnIF07XHJcblx0XHR9XHJcblx0XHRpZiAoIGRhdGVfYm9va2luZ19vYmpbICdzdW1tYXJ5J11bJ3Rvb2x0aXBfYm9va2luZ19kZXRhaWxzJyBdLmxlbmd0aCA+IDAgKXtcclxuXHRcdFx0dG9vbHRpcF90ZXh0ICs9ICBkYXRlX2Jvb2tpbmdfb2JqWyAnc3VtbWFyeSddWyd0b29sdGlwX2Jvb2tpbmdfZGV0YWlscycgXTtcclxuXHRcdH1cclxuXHRcdHdwYmNfc2V0X3Rvb2x0aXBfX19mb3JfX2NhbGVuZGFyX2RhdGUoIHRvb2x0aXBfdGV4dCwgcmVzb3VyY2VfaWQsIGNsYXNzX2RheSApO1xyXG5cclxuXHJcblxyXG5cdFx0Ly8gIFUgbiBoIG8gdiBlIHIgaSBuIGcgICAgaW4gICAgVU5TRUxFQ1RBQkxFX0NBTEVOREFSICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdHZhciBpc191bnNlbGVjdGFibGVfY2FsZW5kYXIgPSAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nX3Vuc2VsZWN0YWJsZScgKyByZXNvdXJjZV9pZCApLmxlbmd0aCA+IDApO1x0XHRcdFx0Ly8gRml4SW46IDguMC4xLjIuXHJcblx0XHR2YXIgaXNfYm9va2luZ19mb3JtX2V4aXN0ICAgID0gKCBqUXVlcnkoICcjYm9va2luZ19mb3JtX2RpdicgKyByZXNvdXJjZV9pZCApLmxlbmd0aCA+IDAgKTtcclxuXHJcblx0XHRpZiAoICggaXNfdW5zZWxlY3RhYmxlX2NhbGVuZGFyICkgJiYgKCAhIGlzX2Jvb2tpbmdfZm9ybV9leGlzdCApICl7XHJcblxyXG5cdFx0XHQvKipcclxuXHRcdFx0ICogIFVuIE
3411hvdmVyIGFsbCBkYXRlcyBpbiBjYWxlbmRhciAod2l0aG91dCB0aGUgYm9va2luZyBmb3JtKSwgaWYgb25seSBBdmFpbGFiaWxpdHkgQ2FsZW5kYXIgaGVyZSBhbmQgd2UgZG8gbm90IGluc2VydCBCb29raW5nIGZvcm0gYnkgbWlzdGFrZS5cclxuXHRcdFx0ICovXHJcblxyXG5cdFx0XHR3cGJjX2NhbGVuZGFyc19fY2xlYXJfZGF5c19oaWdobGlnaHRpbmcoIHJlc291cmNlX2lkICk7IFx0XHRcdFx0XHRcdFx0Ly8gQ2xlYXIgZGF5cyBoaWdobGlnaHRpbmdcclxuXHJcblx0XHRcdHZhciBjc3Nfb2ZfY2FsZW5kYXIgPSAnLndwYmNfb25seV9jYWxlbmRhciAjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZDtcclxuXHRcdFx0alF1ZXJ5KCBjc3Nfb2ZfY2FsZW5kYXIgKyAnIC5kYXRlcGljay1kYXlzLWNlbGwsICdcclxuXHRcdFx0XHQgICsgY3NzX29mX2NhbGVuZGFyICsgJyAuZGF0ZXBpY2stZGF5cy1jZWxsIGEnICkuY3NzKCAnY3Vyc29yJywgJ2RlZmF1bHQnICk7XHQvLyBTZXQgY3Vyc29yIHRvIERlZmF1bHRcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHJcblxyXG5cdFx0Ly8gIEQgYSB5IHMgICAgSCBvIHYgZSByIGkgbiBnICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdGlmIChcclxuXHRcdFx0ICAgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMnICkgPT0gLTEgKVxyXG5cdFx0XHR8fCAoIGxvY2F0aW9uLmhyZWYuaW5kZXhPZiggJ3BhZ2U9d3BiYy1uZXcnICkgPiAwIClcclxuXHRcdFx0fHwgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMtc2V0dXAnICkgPiAwIClcclxuXHRcdFx0fHwgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICdwYWdlPXdwYmMtYXZhaWxhYmlsaXR5JyApID4gMCApXHJcblx0XHRcdHx8ICggICggbG9jYXRpb24uaHJlZi5pbmRleE9mKCAncGFnZT13cGJjLXNldHRpbmdzJyApID4gMCApICAmJlxyXG5cdFx0XHRcdCAgKCBsb2NhdGlvbi5ocmVmLmluZGV4T2YoICcmdGFiPWZvcm0nICkgPiAwIClcclxuXHRcdFx0ICAgKVxyXG5cdFx0KXtcclxuXHRcdFx0Ly8gVGhlIHNhbWUgYXMgZGF0ZXMgc2VsZWN0aW9uLCAgYnV0IGZvciBkYXlzIGhvdmVyaW5nXHJcblxyXG5cdFx0XHRpZiAoICdmdW5jdGlvbicgPT0gdHlwZW9mKCB3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19oaWdobGlnaHRfX2JzICkgKXtcclxuXHRcdFx0XHR3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19oaWdobGlnaHRfX2JzKCBzcWxfY2xhc3NfZGF5LCBkYXRlLCByZXNvdXJjZV9pZCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNlbGVjdCBjYWxlbmRhciBkYXRlIGNlbGxzXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZVx0XHRcdFx0XHRcdFx0XHRcdFx0LSAgSmF2YVNjcmlwdCBEYXRlIE9iajogIFx0XHRNb24gRGVjIDExIDIwMjMgMDA6MDA6MDAgR01UKzAyMDAgKEVhc3Rlcm4gRXVyb3BlYW4gU3RhbmRhcmQgVGltZSlcclxuXHQgKiBAcGFyYW0gY2FsZW5kYXJfcGFyYW1zX2Fyclx0XHRcdFx0XHRcdC0gIENhbGVuZGFyIFNldHRpbmdzIE9iamVjdDogIFx0e1xyXG5cdCAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgIFx0XHRcdFx0XHRcdFwicmVzb3VyY2VfaWRcIjogNFxyXG5cdCAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdCAqIEBwYXJhbSBkYXRlcGlja190aGlzXHRcdFx0XHRcdFx0XHRcdC0gdGhpcyBvZiBkYXRlcGljayBPYmpcclxuXHQgKlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19vbl9zZWxlY3RfZGF5cyggZGF0ZSwgY2FsZW5kYXJfcGFyYW1zX2FyciwgZGF0ZXBpY2tfdGhpcyApe1xyXG5cclxuXHRcdHZhciByZXNvdXJjZV9pZCA9ICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZihjYWxlbmRhcl9wYXJhbXNfYXJyWyAncmVzb3VyY2VfaWQnIF0pICkgPyBjYWxlbmRhcl9wYXJhbXNfYXJyWyAncmVzb3VyY2VfaWQnIF0gOiAnMSc7XHRcdC8vICcxJ1xyXG5cclxuXHRcdC8vIFNldCB1bnNlbGVjdGFibGUsICBpZiBvbmx5IEF2YWlsYWJpbGl0eSBDYWxlbmRhciAgaGVyZSAoYW5kIHdlIGRvIG5vdCBpbnNlcnQgQm9va2luZyBmb3JtIGJ5IG1pc3Rha2UpLlxyXG5cdFx0dmFyIGlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciA9ICggalF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmdfdW5zZWxlY3RhYmxlJyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCk7XHRcdFx0XHQvLyBGaXhJbjogOC4wLjEuMi5cclxuXHRcdHZhciBpc19ib29raW5nX2Zvcm1fZXhpc3QgICAgPSAoIGpRdWVyeSggJyNib29raW5nX2Zvcm1fZGl2JyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCApO1xyXG5cdFx0aWYgKCAoIGlzX3Vuc2VsZWN0YWJsZV9jYWxlbmRhciApICYmICggISBpc19ib29raW5nX2Zvcm1fZXhpc3QgKSApe1xyXG5cdFx0XHR3cGJjX2NhbGVuZGFyX191bnNlbGVjdF9hbGxfZGF0ZXMoIHJlc291cmNlX2lkICk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBVbnNlbGVjdCBEYXRlc1xyXG5cdFx0XHRqUXVlcnkoJy53cGJjX29ubHlfY2FsZW5kYXIgLnBvcG92ZXJfY2FsZW5kYXJfaG92ZXInKS5yZW1vdmUoKTsgICAgICAgICAgICAgICAgICAgICAgXHRcdFx0XHRcdFx0XHQvLyBIaWRlIGFsbCBvcGVuZWQgcG9wb3ZlcnNcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGpRdWVyeSggJyNkYXRlX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS52YWwoIGRhdGUgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEFkZCBzZWxlY3RlZCBkYXRlcyB0byAgaGlkZGVuIHRleHRhcmVhXHJcblxyXG5cclxuXHRcdGlmICggJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mICh3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzKSApeyB3cGJjX19jYWxlbmRhcl9fZG9fZGF5c19zZWxlY3RfX2JzKCBkYXRlLCByZXNvdXJjZV9pZCApOyB9XHJcblxyXG5cdFx0d3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSggcmVzb3VyY2VfaWQgKTtcclxuXHJcblx0XHQvLyBIb29rIC0tIHRyaWdnZXIgZGF5IHNlbGVjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdFx0dmFyIG1vdXNlX2NsaWNrZWRfZGF0ZXMgPSBkYXRlO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FuIGJlOiBcIjA1LjEwLjIwMjMgLSAwNy4xMC4yMDIzXCIgIHwgIFwiMTAuMTAuMjAyMyAtIDEwLjEwLjIwMjNcIiAgfFxyXG5cdFx0dmFyIGFsbF9zZWxlY3RlZF9kYXRlc19hcnIgPSB3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIoIHJlc291cmNlX2lkICk7XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FuIGJlOiBbIFwiMjAyMy0xMC0wNVwiLCBcIjIwMjMtMTAtMDZcIiwgXCIyMDIzLTEwLTA3XCIsIOKApiBdXHJcblx0XHRqUXVlcnkoIFwiLmJvb2tpbmdfZm9ybV9kaXZcIiApLnRyaWdnZXIoIFwiZGF0ZV9zZWxlY3RlZFwiLCBbIHJlc291cmNlX2lkLCBtb3VzZV9jbGlja2VkX2RhdGVzLCBhbGxfc2VsZWN0ZWRfZGF0ZXNfYXJyIF0gKTtcclxuXHR9XHJcblxyXG5cdC8vIE1hcmsgbWlkZGxlIHNlbGVjdGVkIGRhdGVzIHdpdGggMC41IG9wYWNpdHlcdFx0Ly8gRml4SW46IDEwLjMuMC45LlxyXG5cdGpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblx0XHRqUXVlcnkoIFwiLmJvb2tpbmdfZm9ybV9kaXZcIiApLm9uKCAnZGF0ZV9zZWxlY3RlZCcsIGZ1bmN0aW9uICggZXZlbnQsIHJlc291cmNlX2lkLCBkYXRlICl7XHJcblx0XHRcdFx0aWYgKFxyXG5cdFx0XHRcdFx0ICAgKCAgJ2ZpeGVkJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKVxyXG5cdFx0XHRcdFx0fHwgKCdkeW5hbWljJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKVxyXG5cdFx0XHRcdCl7XHJcblx0XHRcdFx0XHR2YXIgY2xvc2VkX3RpbWVyID0gc2V0VGltZW91dCggZnVuY3Rpb24gKCl7XHJcblx0XHRcdFx0XHRcdHZhciBtaWRkbGVfZGF5c19vcGFjaXR5ID0gX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAnY2FsZW5kYXJzX19kYXlzX3NlbGVjdGlvbl9fbWlkZGxlX2RheXNfb3BhY2l0eScgKTtcclxuXHRcdFx0XHRcdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKyAnIC5kYXRlcGljay1jdXJyZW50LWRheScgKS5ub3QoIFwiLnNlbGVjdGVkX2NoZWNrX2luX291dFwiICkuY3NzKCAnb3BhY2l0eScsIG1pZGRsZV9kYXlzX29wYWNpdHkgKTtcclxuXHRcdFx0XHRcdH0sIDEwICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0gKTtcclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIC0tICBUIGkgbSBlICAgIEYgaSBlIGwgZCBzICAgICBzdGFydCAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQgKi9cclxuXHJcblx0LyoqXHJcblx0ICogRGlzYWJsZSB0aW1lIHNsb3RzIGluIGJvb2tpbmcgZm9ybSBkZXBlbmQgb24gc2VsZWN0ZWQgZGF0ZXMgYW5kIGJvb2tlZCBkYXRlcy90aW1lc1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19kaXNhYmxlX3RpbWVfZmllbGRzX2luX2Jvb2tpbmdfZm9ybSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFx0MS4gR2V0IGFsbCB0aW1lIGZpZWxkcyBpbiB0aGUgYm9va2luZyBmb3JtIGFzIGFycmF5ICBvZiBvYmplY3RzXHJcblx0XHQgKiBcdFx0XHRcdFx0W1xyXG5cdFx0ICogXHRcdFx0XHRcdCBcdCAgIHtcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbW
3411U6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR0aW1lc19hc19zZWNvbmRzOiAgIFsgMjE2MDAsIDIzNDAwIF1cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCAtIDA2OjMwJ1xyXG5cdFx0ICogXHRcdFx0XHRcdCAgICAgfVxyXG5cdFx0ICogXHRcdFx0XHRcdCAgLi4uXHJcblx0XHQgKiBcdFx0XHRcdFx0XHQgICB7XHRqcXVlcnlfb3B0aW9uOiAgICAgIGpRdWVyeV9PYmplY3Qge31cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHRuYW1lOiAgICAgICAgICAgICAgICdzdGFydHRpbWUyW10nXHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwIF1cclxuXHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHRcdCAqICBcdFx0XHRcdFx0ICAgIH1cclxuXHRcdCAqIFx0XHRcdFx0XHQgXVxyXG5cdFx0ICovXHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqX2FyciA9IHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdFx0Ly8gMi4gR2V0IGFsbCBzZWxlY3RlZCBkYXRlcyBpbiAgU1FMIGZvcm1hdCAgbGlrZSB0aGlzIFsgXCIyMDIzLTA4LTIzXCIsIFwiMjAyMy0wOC0yNFwiLCBcIjIwMjMtMDgtMjVcIiwgLi4uIF1cclxuXHRcdHZhciBzZWxlY3RlZF9kYXRlc19hcnIgPSB3cGJjX2dldF9fc2VsZWN0ZWRfZGF0ZXNfc3FsX19hc19hcnIoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdFx0Ly8gMy4gR2V0IGNoaWxkIGJvb2tpbmcgcmVzb3VyY2VzICBvciBzaW5nbGUgYm9va2luZyByZXNvdXJjZSAgdGhhdCAgZXhpc3QgIGluIGRhdGVzXHJcblx0XHR2YXIgY2hpbGRfcmVzb3VyY2VzX2FyciA9IHdwYmNfY2xvbmVfb2JqKCBfd3BiYy5ib29raW5nX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAncmVzb3VyY2VzX2lkX2Fycl9faW5fZGF0ZXMnICkgKTtcclxuXHJcblx0XHR2YXIgc3FsX2RhdGU7XHJcblx0XHR2YXIgY2hpbGRfcmVzb3VyY2VfaWQ7XHJcblx0XHR2YXIgbWVyZ2VkX3NlY29uZHM7XHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqO1xyXG5cdFx0dmFyIGlzX2ludGVyc2VjdDtcclxuXHRcdHZhciBpc19jaGVja19pbjtcclxuXHJcblx0XHR2YXIgdG9kYXlfdGltZV9fcmVhbCAgPSBuZXcgRGF0ZSggX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMF0sICggcGFyc2VJbnQoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzFdICkgLSAxKSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndGltZV9sb2NhbF9hcnInIClbMl0sIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RpbWVfbG9jYWxfYXJyJyApWzNdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0aW1lX2xvY2FsX2FycicgKVs0XSwgMCApO1xyXG5cdFx0dmFyIHRvZGF5X3RpbWVfX3NoaWZ0ID0gbmV3IERhdGUoIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgICAgICApWzBdLCAoIHBhcnNlSW50KCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICAgICAgJ3RvZGF5X2FycicgKVsxXSApIC0gMSksIF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ3RvZGF5X2FycicgICAgICApWzJdLCBfd3BiYy5nZXRfb3RoZXJfcGFyYW0oICd0b2RheV9hcnInICAgICAgKVszXSwgX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAndG9kYXlfYXJyJyAgICAgIClbNF0sIDAgKTtcclxuXHJcblx0XHQvLyA0LiBMb29wICBhbGwgIHRpbWUgRmllbGRzIG9wdGlvbnNcdFx0Ly8gRml4SW46IDEwLjMuMC4yLlxyXG5cdFx0Zm9yICggbGV0IGZpZWxkX2tleSA9IDA7IGZpZWxkX2tleSA8IHRpbWVfZmllbGRzX29ial9hcnIubGVuZ3RoOyBmaWVsZF9rZXkrKyApe1xyXG5cclxuXHRcdFx0dGltZV9maWVsZHNfb2JqX2FyclsgZmllbGRfa2V5IF0uZGlzYWJsZWQgPSAwOyAgICAgICAgICAvLyBCeSBkZWZhdWx0LCB0aGlzIHRpbWUgZmllbGQgaXMgbm90IGRpc2FibGVkLlxyXG5cclxuXHRcdFx0dGltZV9maWVsZHNfb2JqID0gdGltZV9maWVsZHNfb2JqX2FyclsgZmllbGRfa2V5IF07XHRcdC8vIHsgdGltZXNfYXNfc2Vjb25kczogWyAyMTYwMCwgMjM0MDAgXSwgdmFsdWVfb3B0aW9uXzI0aDogJzA2OjAwIC0gMDY6MzAnLCBuYW1lOiAncmFuZ2V0aW1lMltdJywganF1ZXJ5X29wdGlvbjogalF1ZXJ5X09iamVjdCB7fX1cclxuXHJcblx0XHRcdC8vIExvb3AgIGFsbCAgc2VsZWN0ZWQgZGF0ZXMuXHJcblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHNlbGVjdGVkX2RhdGVzX2Fyci5sZW5ndGg7IGkrKyApIHtcclxuXHJcblx0XHRcdFx0Ly8gR2V0IERhdGU6ICcyMDIzLTA4LTE4Jy5cclxuXHRcdFx0XHRzcWxfZGF0ZSA9IHNlbGVjdGVkX2RhdGVzX2FycltpXTtcclxuXHJcblx0XHRcdFx0dmFyIGlzX3RpbWVfaW5fcGFzdCA9IHdwYmNfY2hlY2tfaXNfdGltZV9pbl9wYXN0KCB0b2RheV90aW1lX19zaGlmdCwgc3FsX2RhdGUsIHRpbWVfZmllbGRzX29iaiApO1xyXG5cdFx0XHRcdC8vIEV4Y2VwdGlvbiAgZm9yICdFbmQgVGltZScgZmllbGQsICB3aGVuICBzZWxlY3RlZCBzZXZlcmFsIGRhdGVzLiAvLyBGaXhJbjogMTAuMTQuMS41LlxyXG5cdFx0XHRcdGlmICggKCdPbicgIT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnYm9va2luZ19yZWN1cnJlbnRfdGltZScgKSkgJiZcclxuXHRcdFx0XHRcdCgtMSAhPT0gdGltZV9maWVsZHNfb2JqLm5hbWUuaW5kZXhPZiggJ2VuZHRpbWUnICkpICYmXHJcblx0XHRcdFx0XHQoc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCA+IDEpXHJcblx0XHRcdFx0KSB7XHJcblx0XHRcdFx0XHRpc190aW1lX2luX3Bhc3QgPSB3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCggdG9kYXlfdGltZV9fc2hpZnQsIHNlbGVjdGVkX2RhdGVzX2Fyclsoc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCAtIDEpXSwgdGltZV9maWVsZHNfb2JqICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggaXNfdGltZV9pbl9wYXN0ICkge1xyXG5cdFx0XHRcdFx0Ly8gVGhpcyB0aW1lIGZvciBzZWxlY3RlZCBkYXRlIGFscmVhZHkgIGluIHRoZSBwYXN0LlxyXG5cdFx0XHRcdFx0dGltZV9maWVsZHNfb2JqX2FycltmaWVsZF9rZXldLmRpc2FibGVkID0gMTtcclxuXHRcdFx0XHRcdGJyZWFrO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBleGlzdCAgZnJvbSAgIERhdGVzIExPT1AuXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdC8vIEZpeEluOiA5LjkuMC4zMS5cclxuXHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHQgICAoICdPZmYnID09PSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2Jvb2tpbmdfcmVjdXJyZW50X3RpbW
3411UnICkgKVxyXG5cdFx0XHRcdFx0JiYgKCBzZWxlY3RlZF9kYXRlc19hcnIubGVuZ3RoPjEgKVxyXG5cdFx0XHRcdCl7XHJcblx0XHRcdFx0XHQvL1RPRE86IHNraXAgc29tZSBmaWVsZHMgY2hlY2tpbmcgaWYgaXQncyBzdGFydCAvIGVuZCB0aW1lIGZvciBtdWxwbGUgZGF0ZXMgIHNlbGVjdGlvbiAgbW9kZS5cclxuXHRcdFx0XHRcdC8vVE9ETzogd2UgbmVlZCB0byBmaXggc2l0dWF0aW9uICBmb3IgZW50aW1lcywgIHdoZW4gIHVzZXIgIHNlbGVjdCAgc2V2ZXJhbCAgZGF0ZXMsICBhbmQgaW4gc3RhcnQgIHRpbWUgYm9va2VkIDAwOjAwIC0gMTU6MDAgLCBidXQgc3lzdHNtZSBibG9jayB1bnRpbGwgMTU6MDAgdGhlIGVuZCB0aW1lIGFzIHdlbGwsICB3aGljaCAgaXMgd3JvbmcsICBiZWNhdXNlIGl0IDIgb3IgMyBkYXRlcyBzZWxlY3Rpb24gIGFuZCBlbmQgZGF0ZSBjYW4gYmUgZnVsbHUgIGF2YWlsYWJsZVxyXG5cclxuXHRcdFx0XHRcdGlmICggKDAgPT0gaSkgJiYgKHRpbWVfZmllbGRzX29ialsgJ25hbWUnIF0uaW5kZXhPZiggJ2VuZHRpbWUnICkgPj0gMCkgKXtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZiAoICggKHNlbGVjdGVkX2RhdGVzX2Fyci5sZW5ndGgtMSkgPT0gaSApICYmICh0aW1lX2ZpZWxkc19vYmpbICduYW1lJyBdLmluZGV4T2YoICdzdGFydHRpbWUnICkgPj0gMCkgKXtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHJcblxyXG5cdFx0XHRcdHZhciBob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQgPSAwO1xyXG5cdFx0XHRcdC8vIExvb3AgYWxsIHJlc291cmNlcyBJRFxyXG5cdFx0XHRcdFx0Ly8gZm9yICggdmFyIHJlc19rZXkgaW4gY2hpbGRfcmVzb3VyY2VzX2FyciApe1x0IFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4zLjAuMi5cclxuXHRcdFx0XHRmb3IgKCBsZXQgcmVzX2tleSA9IDA7IHJlc19rZXkgPCBjaGlsZF9yZXNvdXJjZXNfYXJyLmxlbmd0aDsgcmVzX2tleSsrICl7XHJcblxyXG5cdFx0XHRcdFx0Y2hpbGRfcmVzb3VyY2VfaWQgPSBjaGlsZF9yZXNvdXJjZXNfYXJyWyByZXNfa2V5IF07XHJcblxyXG5cdFx0XHRcdFx0Ly8gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMTJdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzXHRcdD0gWyBcIjA3OjAwOjExIC0gMDc6MzA6MDJcIiwgXCIxMDowMDoxMSAtIDAwOjAwOjAwXCIgXVxyXG5cdFx0XHRcdFx0Ly8gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSgyLCcyMDIzLTA4LTIxJylbMl0uYm9va2VkX3RpbWVfc2xvdHMubWVyZ2VkX3NlY29uZHNcdFx0XHQ9IFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHJcblx0XHRcdFx0XHRpZiAoIGZhbHNlICE9PSBfd3BiYy5ib29raW5nc19pbl9jYWxlbmRhcl9fZ2V0X2Zvcl9kYXRlKCByZXNvdXJjZV9pZCwgc3FsX2RhdGUgKSApe1xyXG5cdFx0XHRcdFx0XHRtZXJnZWRfc2Vjb25kcyA9IF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfZGF0ZSApWyBjaGlsZF9yZXNvdXJjZV9pZCBdLmJvb2tlZF90aW1lX3Nsb3RzLm1lcmdlZF9zZWNvbmRzO1x0XHQvLyBbICBbIDI1MjExLCAyNzAwMiBdLCBbIDM2MDExLCA4NjQwMCBdICBdXHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRtZXJnZWRfc2Vjb25kcyA9IFtdO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcy5sZW5ndGggPiAxICl7XHJcblx0XHRcdFx0XHRcdGlzX2ludGVyc2VjdCA9IHdwYmNfaXNfaW50ZXJzZWN0X19yYW5nZV90aW1lX2ludGVydmFsKCAgW1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRbXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHNbMF0gKSArIDIwICksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHNbMV0gKSAtIDIwIClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0LCBtZXJnZWRfc2Vjb25kcyApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0aXNfY2hlY2tfaW4gPSAoLTEgIT09IHRpbWVfZmllbGRzX29iai5uYW1lLmluZGV4T2YoICdzdGFydCcgKSk7XHJcblx0XHRcdFx0XHRcdGlzX2ludGVyc2VjdCA9IHdwYmNfaXNfaW50ZXJzZWN0X19vbmVfdGltZV9pbnRlcnZhbChcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggKCBpc19jaGVja19pbiApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgID8gcGFyc2VJbnQoIHRpbWVfZmllbGRzX29iai50aW1lc19hc19zZWNvbmRzICkgKyAyMFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICA6IHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcyApIC0gMjBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCwgbWVyZ2VkX3NlY29uZHMgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmIChpc19pbnRlcnNlY3Qpe1xyXG5cdFx0XHRcdFx0XHRob3dfbWFueV9yZXNvdXJjZXNfaW50ZXJzZWN0ZWQrKztcdFx0XHQvLyBJbmNyZWFzZVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmICggY2hpbGRfcmVzb3VyY2VzX2Fyci5sZW5ndGggPT0gaG93X2
34111hbnlfcmVzb3VyY2VzX2ludGVyc2VjdGVkICkge1xyXG5cdFx0XHRcdFx0Ly8gQWxsIHJlc291cmNlcyBpbnRlcnNlY3RlZCwgIHRoZW4gIGl0J3MgbWVhbnMgdGhhdCB0aGlzIHRpbWUtc2xvdCBvciB0aW1lIG11c3QgIGJlICBEaXNhYmxlZCwgYW5kIHdlIGNhbiAgZXhpc3QgIGZyb20gICBzZWxlY3RlZF9kYXRlc19hcnIgTE9PUFxyXG5cclxuXHRcdFx0XHRcdHRpbWVfZmllbGRzX29ial9hcnJbIGZpZWxkX2tleSBdLmRpc2FibGVkID0gMTtcclxuXHRcdFx0XHRcdGJyZWFrO1x0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBleGlzdCAgZnJvbSAgIERhdGVzIExPT1BcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblxyXG5cdFx0Ly8gNS4gTm93IHdlIGNhbiBkaXNhYmxlIHRpbWUgc2xvdCBpbiBIVE1MIGJ5ICB1c2luZyAgKCBmaWVsZC5kaXNhYmxlZCA9PSAxICkgcHJvcGVydHlcclxuXHRcdHdwYmNfX2h0bWxfX3RpbWVfZmllbGRfb3B0aW9uc19fc2V0X2Rpc2FibGVkKCB0aW1lX2ZpZWxkc19vYmpfYXJyICk7XHJcblxyXG5cdFx0alF1ZXJ5KCBcIi5ib29raW5nX2Zvcm1fZGl2XCIgKS50cmlnZ2VyKCAnd3BiY19ob29rX3RpbWVzbG90c19kaXNhYmxlZCcsIFtyZXNvdXJjZV9pZCwgc2VsZWN0ZWRfZGF0ZXNfYXJyXSApO1x0XHRcdFx0XHQvLyBUcmlnZ2VyIGhvb2sgb24gZGlzYWJsaW5nIHRpbWVzbG90cy5cdFx0VXNhZ2U6IFx0alF1ZXJ5KCBcIi5ib29raW5nX2Zvcm1fZGl2XCIgKS5vbiggJ3dwYmNfaG9va190aW1lc2xvdHNfZGlzYWJsZWQnLCBmdW5jdGlvbiAoIGV2ZW50LCBia190eXBlLCBhbGxfZGF0ZXMgKXsgLi4uIH0gKTtcdFx0Ly8gRml4SW46IDguNy4xMS45LlxyXG5cdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBDaGVjayBpZiBzcGVjaWZpYyB0aW1lKC1zbG90KSBhbHJlYWR5ICBpbiB0aGUgcGFzdCBmb3Igc2VsZWN0ZWQgZGF0ZVxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSBqc19jdXJyZW50X3RpbWVfdG9fY2hlY2tcdFx0LSBKUyBEYXRlXHJcblx0XHQgKiBAcGFyYW0gc3FsX2RhdGVcdFx0XHRcdFx0XHQtICcyMDI1LTAxLTI2J1xyXG5cdFx0ICogQHBhcmFtIHRpbWVfZmllbGRzX29ialx0XHRcdFx0LSBPYmplY3RcclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2NoZWNrX2lzX3RpbWVfaW5fcGFzdCgganNfY3VycmVudF90aW1lX3RvX2NoZWNrLCBzcWxfZGF0ZSwgdGltZV9maWVsZHNfb2JqICkge1xyXG5cclxuXHRcdFx0Ly8gRml4SW46IDEwLjkuNi40XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9hcnIgPSBzcWxfZGF0ZS5zcGxpdCggJy0nICk7XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9fbWlkbmlnaHQgPSBuZXcgRGF0ZSggcGFyc2VJbnQoIHNxbF9kYXRlX2FyclswXSApLCAoIHBhcnNlSW50KCBzcWxfZGF0ZV9hcnJbMV0gKSAtIDEgKSwgcGFyc2VJbnQoIHNxbF9kYXRlX2FyclsyXSApLCAwLCAwLCAwICk7XHJcblx0XHRcdHZhciBzcWxfZGF0ZV9fbWlkbmlnaHRfbWlsaXNlY29uZHMgPSBzcWxfZGF0ZV9fbWlkbmlnaHQuZ2V0VGltZSgpO1xyXG5cclxuXHRcdFx0dmFyIGlzX2ludGVyc2VjdCA9IGZhbHNlO1xyXG5cclxuXHRcdFx0aWYgKCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kcy5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiAoc3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzICsgKHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kc1swXSApICsgMjApICogMTAwMCkgKSB7XHJcblx0XHRcdFx0XHRpc19pbnRlcnNlY3QgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiAoc3FsX2RhdGVfX21pZG5pZ2h0X21pbGlzZWNvbmRzICsgKHBhcnNlSW50KCB0aW1lX2ZpZWxkc19vYmoudGltZXNfYXNfc2Vjb25kc1sxXSApIC0gMjApICogMTAwMCkgKSB7XHJcblx0XHRcdFx0XHRpc19pbnRlcnNlY3QgPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dmFyIGlzX2NoZWNrX2luID0gKC0xICE9PSB0aW1lX2ZpZWxkc19vYmoubmFtZS5pbmRleE9mKCAnc3RhcnQnICkpO1xyXG5cclxuXHRcdFx0XHR2YXIgdGltZXNfYXNfc2Vjb25kc19jaGVjayA9IChpc19jaGVja19pbikgPyBwYXJzZUludCggdGltZV9maWVsZHNfb2JqLnRpbWVzX2FzX3NlY29uZHMgKSArIDIwIDogcGFyc2VJbnQoIHRpbWVfZmllbGRzX29iai50aW1lc19hc19zZWNvbmRzICkgLSAyMDtcclxuXHJcblx0XHRcdFx0dGltZXNfYXNfc2Vjb25kc19jaGVjayA9IHNxbF9kYXRlX19taWRuaWdodF9taWxpc2Vjb25kcyArIHRpbWVzX2FzX3NlY29uZHNfY2hlY2sgKiAxMDAwO1xyXG5cclxuXHRcdFx0XHRpZiAoIGpzX2N1cnJlbnRfdGltZV90b19jaGVjay5nZXRUaW1lKCkgPiB0aW1lc19hc19zZWNvbmRzX2NoZWNrICkge1xyXG5cdFx0XHRcdFx0aXNfaW50ZXJzZWN0ID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBpc19pbnRlcnNlY3Q7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyBudW1iZXIgaW5zaWRlIC9pbnRlcnNlY3QgIG9mIGFycmF5IG9mIGludGVydmFscyA/XHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIHRpbWVfQVx0XHQgICAgIFx0LSAyNTgwMFxyXG5cdFx0ICogQHBhcmFtIHRpbWVfaW50ZXJ2YWxfQlx0XHQtIFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2lzX2ludGVyc2VjdF9fb25lX3RpbWVfaW50ZXJ2YWwoIHRpbWVfQSwgdGltZV9pbnRlcnZhbF9CICl7XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCB0aW1lX2ludGVydmFsX0IubGVuZ3RoOyBqKysgKXtcclxuXHJcblx0XHRcdFx0aWYgKCAocGFyc2VJbnQoIHRpbWVfQSApID4gcGFyc2VJbnQoIHRpbWVfaW50ZXJ2YWxfQlsgaiBdWyAwIF0gKSkgJiYgKHBhcnNlSW50KCB0aW1lX0EgKSA8IHBhcnNlSW50KCB0aW1lX2ludGVydmFsX0JbIGogXVsgMSBdICkpICl7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gaWYgKCAoIHBhcnNlSW50KCB0aW1lX0EgKSA9PSBwYXJzZUludCggdGltZV9pbnRlcnZhbF9CWyBqIF1bIDAgXSApICkgfHwgKCBwYXJzZUludCggdGltZV9BICkgPT0gcGFyc2VJbnQoIHRpbWVfaW50ZXJ2YWxfQlsgaiBdWyAxIF0gKSApICkge1xyXG5cdFx0XHRcdC8vIFx0XHRcdC8vIFRpbWUgQSBqdXN0ICBhdCAgdGhlIGJvcmRlciBvZiBpbnRlcnZhbFxyXG5cdFx0XHRcdC8vIH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdCAgICByZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyB0aGVzZSBhcnJheSBvZiBpbnRlcnZhbHMgaW50ZXJzZWN0ZWQgP1xyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSB0aW1lX2ludGVydmFsX0FcdFx0LSBbIFsgMjE2MDAsIDIzNDAwIF0gXVxyXG5cdFx0ICogQHBhcmFtIHRpbWVfaW50ZXJ2YWxfQlx0XHQtIFsgIFsgMjUyMTEsIDI3MDAyIF0sIFsgMzYwMTEsIDg2NDAwIF0gIF1cclxuXHRcdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2lzX2ludGVyc2VjdF9fcmFuZ2VfdGltZV9pbnRlcnZhbCggdGltZV9pbnRlcnZhbF9BLCB0aW1lX2ludGVydmFsX0IgKXtcclxuXHJcblx0XHRcdHZhciBpc19pbnRlcnNlY3Q7XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aW1lX2ludGVydmFsX0EubGVuZ3RoOyBpKysgKXtcclxuXHJcblx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgdGltZV9pbnRlcnZhbF9CLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdFx0aXNfaW50ZXJzZWN0ID0gd3BiY19pbnRlcnZhbHNfX2lzX2ludGVyc2VjdGVkKCB0aW1lX2ludGVydmFsX0FbIGkgXSwgdGltZV9pbnRlcnZhbF9CWyBqIF0gKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIGlzX2ludGVyc2VjdCApe1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybi
3411BmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvKipcclxuXHRcdCAqIEdldCBhbGwgdGltZSBmaWVsZHMgaW4gdGhlIGJvb2tpbmcgZm9ybSBhcyBhcnJheSAgb2Ygb2JqZWN0c1xyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSByZXNvdXJjZV9pZFxyXG5cdFx0ICogQHJldHVybnMgW11cclxuXHRcdCAqXHJcblx0XHQgKiBcdFx0RXhhbXBsZTpcclxuXHRcdCAqIFx0XHRcdFx0XHRbXHJcblx0XHQgKiBcdFx0XHRcdFx0IFx0ICAge1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwIC0gMDY6MzAnXHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwLCAyMzQwMCBdXHJcblx0XHQgKiBcdFx0XHRcdFx0IFx0ICAgXHRcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHRcdCAqIFx0XHRcdFx0XHQgICAgIH1cclxuXHRcdCAqIFx0XHRcdFx0XHQgIC4uLlxyXG5cdFx0ICogXHRcdFx0XHRcdFx0ICAge1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwJ1xyXG5cdFx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCBdXHJcblx0XHQgKiBcdFx0XHRcdFx0XHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0bmFtZTogICAgICAgICAgICAgICAnc3RhcnR0aW1lMltdJ1xyXG5cdFx0ICogIFx0XHRcdFx0XHQgICAgfVxyXG5cdFx0ICogXHRcdFx0XHRcdCBdXHJcblx0XHQgKi9cclxuXHRcdGZ1bmN0aW9uIHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkICl7XHJcblx0XHQgICAgLyoqXHJcblx0XHRcdCAqIEZpZWxkcyB3aXRoICBbXSAgbGlrZSB0aGlzICAgc2VsZWN0W25hbWU9XCJyYW5nZXRpbWUxW11cIl1cclxuXHRcdFx0ICogaXQncyB3aGVuIHdlIGhhdmUgJ211bHRpcGxlJyBpbiBzaG9ydGNvZGU6ICAgW3NlbGVjdCogcmFuZ2V0aW1lIG11bHRpcGxlICBcIjA2OjAwIC0gMDY6MzBcIiAuLi4gXVxyXG5cdFx0XHQgKi9cclxuXHRcdFx0dmFyIHRpbWVfZmllbGRzX2Fycj1bXHJcblx0XHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInJhbmdldGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJyYW5nZXRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJzdGFydHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwic3RhcnR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwiZW5kdGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJlbmR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJ1xyXG5cdFx0XHRcdFx0XHRcdFx0XTtcclxuXHJcblx0XHRcdHZhciB0aW1lX2ZpZWxkc19vYmpfYXJyID0gW107XHJcblxyXG5cdFx0XHQvLyBMb29wIGFsbCBUaW1lIEZpZWxkc1xyXG5cdFx0XHRmb3IgKCB2YXIgY3RmPSAwOyBjdGYgPCB0aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyBjdGYrKyApe1xyXG5cclxuXHRcdFx0XHR2YXIgdGltZV9maWVsZCA9IHRpbWVfZmllbGRzX2FyclsgY3RmIF07XHJcblx0XHRcdFx0dmFyIHRpbWVfb3B0aW9uID0galF1ZXJ5KCB0aW1lX2ZpZWxkICsgJyBvcHRpb24nICk7XHJcblxyXG5cdFx0XHRcdC8vIExvb3AgYWxsIG9wdGlvbnMgaW4gdGltZSBmaWVsZFxyXG5cdFx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IHRpbWVfb3B0aW9uLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdFx0dmFyIGpxdWVyeV9vcHRpb24gPSBqUXVlcnkoIHRpbWVfZmllbGQgKyAnIG9wdGlvbjplcSgnICsgaiArICcpJyApO1xyXG5cdFx0XHRcdFx0dmFyIHZhbHVlX29wdGlvbl9zZWNvbmRzX2FyciA9IGpxdWVyeV9vcHRpb24udmFsKCkuc3BsaXQoICctJyApO1xyXG5cdFx0XHRcdFx0dmFyIHRpbWVzX2FzX3NlY29uZHMgPSBbXTtcclxuXHJcblx0XHRcdFx0XHQvLyBHZXQgdGltZSBhcyBzZWNvbmRzXHJcblx0XHRcdFx0XHRpZiAoIHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGggKXtcdFx0XHRcdFx0XHRcdFx0XHQvLyBGaXhJbjogOS44LjEwLjEuXHJcblx0XHRcdFx0XHRcdGZvciAoIGxldCBpID0gMDsgaSA8IHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGg7IGkrKyApe1x0XHQvLyBGaXhJbjogMTAuMC4wLjU2LlxyXG5cdFx0XHRcdFx0XHRcdC8vIHZhbHVlX29wdGlvbl9zZWNvbmRzX2FycltpXSA9ICcxNDowMCAnICB8ICcgMTY6MDAnICAgKGlmIGZyb20gJ3JhbmdldGltZScpIGFuZCAnMTY6MDAnICBpZiAoc3RhcnQvZW5kIHRpbWUpXHJcblxyXG5cdFx0XHRcdFx0XHRcdHZhciBzdGFydF9lbmRfdGltZXNfYXJyID0gdmFsdWVfb3B0aW9uX3NlY29uZHNfYXJyWyBpIF0udHJpbSgpLnNwbGl0KCAnOicgKTtcclxuXHJcblx0XHRcdFx0XHRcdFx0dmFyIHRpbWVfaW5fc2Vjb25kcyA9IHBhcnNlSW50KCBzdGFydF9lbmRfdGltZXNfYXJyWyAwIF0gKSAqIDYwICogNjAgKyBwYXJzZUludCggc3RhcnRfZW5kX3RpbWVzX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kcy5wdXNoKCB0aW1lX2luX3NlY29uZHMgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHRpbWVfZmllbGRzX29ial9hcnIucHVzaCgge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbmFtZScgICAgICAgICAgICA6IGpRdWVyeSggdGltZV9maWVsZCApLmF0dHIoICduYW1lJyApLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWVfb3B0aW9uXzI0aCc6IGpxdWVyeV9vcHRpb24udmFsKCksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcXVlcnlfb3B0aW9uJyAgIDoganF1ZXJ5X29wdGlvbixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3RpbWVzX2FzX3
3411NlY29uZHMnOiB0aW1lc19hc19zZWNvbmRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gdGltZV9maWVsZHNfb2JqX2FycjtcclxuXHRcdH1cclxuXHJcblx0XHRcdC8qKlxyXG5cdFx0XHQgKiBEaXNhYmxlIEhUTUwgb3B0aW9ucyBhbmQgYWRkIGJvb2tlZCBDU1MgY2xhc3NcclxuXHRcdFx0ICpcclxuXHRcdFx0ICogQHBhcmFtIHRpbWVfZmllbGRzX29ial9hcnIgICAgICAtIHRoaXMgdmFsdWUgaXMgZnJvbSAgdGhlIGZ1bmM6ICBcdHdwYmNfZ2V0X190aW1lX2ZpZWxkc19faW5fYm9va2luZ19mb3JtX19hc19hcnIoIHJlc291cmNlX2lkIClcclxuXHRcdFx0ICogXHRcdFx0XHRcdFtcclxuXHRcdFx0ICogXHRcdFx0XHRcdCBcdCAgIHtcdGpxdWVyeV9vcHRpb246ICAgICAgalF1ZXJ5X09iamVjdCB7fVxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0bmFtZTogICAgICAgICAgICAgICAncmFuZ2V0aW1lMltdJ1xyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwLCAyMzQwMCBdXHJcblx0XHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCAtIDA2OjMwJ1xyXG5cdFx0XHQgKiBcdCAgXHRcdFx0XHRcdFx0ICAgIGRpc2FibGVkID0gMVxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0ICAgICB9XHJcblx0XHRcdCAqIFx0XHRcdFx0XHQgIC4uLlxyXG5cdFx0XHQgKiBcdFx0XHRcdFx0XHQgICB7XHRqcXVlcnlfb3B0aW9uOiAgICAgIGpRdWVyeV9PYmplY3Qge31cclxuXHRcdFx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3N0YXJ0dGltZTJbXSdcclxuXHRcdFx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCBdXHJcblx0XHRcdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHRcdFx0ICogICBcdFx0XHRcdFx0XHRcdGRpc2FibGVkID0gMFxyXG5cdFx0XHQgKiAgXHRcdFx0XHRcdCAgICB9XHJcblx0XHRcdCAqIFx0XHRcdFx0XHQgXVxyXG5cdFx0XHQgKlxyXG5cdFx0XHQgKi9cclxuXHRcdFx0ZnVuY3Rpb24gd3BiY19faHRtbF9fdGltZV9maWVsZF9vcHRpb25zX19zZXRfZGlzYWJsZWQoIHRpbWVfZmllbGRzX29ial9hcnIgKXtcclxuXHJcblx0XHRcdFx0dmFyIGpxdWVyeV9vcHRpb247XHJcblxyXG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHRpbWVfZmllbGRzX29ial9hcnIubGVuZ3RoOyBpKysgKXtcclxuXHJcblx0XHRcdFx0XHR2YXIganF1ZXJ5X29wdGlvbiA9IHRpbWVfZmllbGRzX29ial9hcnJbIGkgXS5qcXVlcnlfb3B0aW9uO1xyXG5cclxuXHRcdFx0XHRcdGlmICggMSA9PSB0aW1lX2ZpZWxkc19vYmpfYXJyWyBpIF0uZGlzYWJsZWQgKXtcclxuXHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wcm9wKCAnZGlzYWJsZWQnLCB0cnVlICk7IFx0XHQvLyBNYWtlIGRpc2FibGUgc29tZSBvcHRpb25zXHJcblx0XHRcdFx0XHRcdGpxdWVyeV9vcHRpb24uYWRkQ2xhc3MoICdib29rZWQnICk7ICAgICAgICAgICBcdC8vIEFkZCBcImJvb2tlZFwiIENTUyBjbGFzc1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gaWYgdGhpcyBib29rZWQgZWxlbWVudCBzZWxlY3RlZCAtLT4gdGhlbiBkZXNlbGVjdCAgaXRcclxuXHRcdFx0XHRcdFx0aWYgKCBqcXVlcnlfb3B0aW9uLnByb3AoICdzZWxlY3RlZCcgKSApe1xyXG5cdFx0XHRcdFx0XHRcdGpxdWVyeV9vcHRpb24ucHJvcCggJ3NlbGVjdGVkJywgZmFsc2UgKTtcclxuXHJcblx0XHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wYXJlbnQoKS5maW5kKCAnb3B0aW9uOm5vdChbZGlzYWJsZWRdKTpmaXJzdCcgKS5wcm9wKCAnc2VsZWN0ZWQnLCB0cnVlICkudHJpZ2dlciggXCJjaGFuZ2VcIiApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0anF1ZXJ5X29wdGlvbi5wcm9wKCAnZGlzYWJsZWQnLCBmYWxzZSApOyAgXHRcdC8vIE1ha2UgYWN0aXZlIGFsbCB0aW1lc1xyXG5cdFx0XHRcdFx0XHRqcXVlcnlfb3B0aW9uLnJlbW92ZUNsYXNzKCAnYm9va2VkJyApOyAgIFx0XHQvLyBSZW1vdmUgY2xhc3MgXCJib29rZWRcIlxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ2hlY2sgaWYgdGhpcyB0aW1lX3JhbmdlIHwgVGltZV9TbG90IGlzIEZ1bGwgRGF5ICBib29rZWRcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kc1x0XHQtIFsgMzYwMTEsIDg2NDAwIF1cclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2lzX3RoaXNfdGltZXNsb3RfX2Z1bGxfZGF5X2Jvb2tlZCggdGltZXNsb3RfYXJyX2luX3NlY29uZHMgKXtcclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdFx0KCB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kcy5sZW5ndGggPiAxIClcclxuXHRcdFx0JiYgKCBwYXJzZUludCggdGltZXNsb3RfYXJyX2luX3NlY29uZHNbIDAgXSApIDwgMzAgKVxyXG5cdFx0XHQmJiAoIHBhcnNlSW50KCB0aW1lc2xvdF9hcnJfaW5fc2Vjb25kc1sgMSBdICkgPiAgKCAoMjQgKiA2MCAqIDYwKSAtIDMwKSApXHJcblx0XHQpe1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHQvKiAgPT0gIFMgZSBsIGUgYyB0IGUgZCAgICBEIGEgdCBlIHMgIC8gIFQgaSBtIGUgLSBGIGkgZSBsIGQgcyAgPT1cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvKipcclxuXHQgKiAgR2V0IGFsbCBzZWxlY3RlZCBkYXRlcyBpbiBTUUwgZm9ybWF0IGxpa2UgdGhpcyBbIFwiMjAyMy0wOC0yM1wiLCBcIjIwMjMtMDgtMjRcIiAsIC4uLiBdXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKiBAcmV0dXJucyB7W119XHRcdFx0WyBcIjIwMjMtMDgtMjNcIiwgXCIyMDIzLTA4LTI0XCIsIFwiMjAyMy0wOC0yNVwiLCBcIjIwMjMtMDgtMjZcIiwgXCIyMDIzLTA4LTI3XCIsIFwiMjAyMy0wOC0yOFwiLCBcIjIwMjMtMDgtMjlc
3411IiBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfX3NlbGVjdGVkX2RhdGVzX3NxbF9fYXNfYXJyKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdHZhciBzZWxlY3RlZF9kYXRlc19hcnIgPSBbXTtcclxuXHRcdHNlbGVjdGVkX2RhdGVzX2FyciA9IGpRdWVyeSggJyNkYXRlX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS52YWwoKS5zcGxpdCgnLCcpO1xyXG5cclxuXHRcdGlmICggc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aCApe1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjguMTAuMS5cclxuXHRcdFx0Zm9yICggbGV0IGkgPSAwOyBpIDwgc2VsZWN0ZWRfZGF0ZXNfYXJyLmxlbmd0aDsgaSsrICl7XHRcdFx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC41Ni5cclxuXHRcdFx0XHRzZWxlY3RlZF9kYXRlc19hcnJbIGkgXSA9IHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLnRyaW0oKTtcclxuXHRcdFx0XHRzZWxlY3RlZF9kYXRlc19hcnJbIGkgXSA9IHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLnNwbGl0KCAnLicgKTtcclxuXHRcdFx0XHRpZiAoIHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdLmxlbmd0aCA+IDEgKXtcclxuXHRcdFx0XHRcdHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdID0gc2VsZWN0ZWRfZGF0ZXNfYXJyWyBpIF1bIDIgXSArICctJyArIHNlbGVjdGVkX2RhdGVzX2FyclsgaSBdWyAxIF0gKyAnLScgKyBzZWxlY3RlZF9kYXRlc19hcnJbIGkgXVsgMCBdO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSBlbXB0eSBlbGVtZW50cyBmcm9tIGFuIGFycmF5XHJcblx0XHRzZWxlY3RlZF9kYXRlc19hcnIgPSBzZWxlY3RlZF9kYXRlc19hcnIuZmlsdGVyKCBmdW5jdGlvbiAoIG4gKXsgcmV0dXJuIHBhcnNlSW50KG4pOyB9ICk7XHJcblxyXG5cdFx0c2VsZWN0ZWRfZGF0ZXNfYXJyLnNvcnQoKTtcclxuXHJcblx0XHRyZXR1cm4gc2VsZWN0ZWRfZGF0ZXNfYXJyO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBhbGwgdGltZSBmaWVsZHMgaW4gdGhlIGJvb2tpbmcgZm9ybSBhcyBhcnJheSAgb2Ygb2JqZWN0c1xyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICogQHBhcmFtIGlzX29ubHlfc2VsZWN0ZWRfdGltZVxyXG5cdCAqIEByZXR1cm5zIFtdXHJcblx0ICpcclxuXHQgKiBcdFx0RXhhbXBsZTpcclxuXHQgKiBcdFx0XHRcdFx0W1xyXG5cdCAqIFx0XHRcdFx0XHQgXHQgICB7XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdHZhbHVlX29wdGlvbl8yNGg6ICAgJzA2OjAwIC0gMDY6MzAnXHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdHRpbWVzX2FzX3NlY29uZHM6ICAgWyAyMTYwMCwgMjM0MDAgXVxyXG5cdCAqIFx0XHRcdFx0XHQgXHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3JhbmdldGltZTJbXSdcclxuXHQgKiBcdFx0XHRcdFx0ICAgICB9XHJcblx0ICogXHRcdFx0XHRcdCAgLi4uXHJcblx0ICogXHRcdFx0XHRcdFx0ICAge1xyXG5cdCAqIFx0XHRcdFx0XHRcdFx0XHR2YWx1ZV9vcHRpb25fMjRoOiAgICcwNjowMCdcclxuXHQgKiBcdFx0XHRcdFx0XHRcdFx0dGltZXNfYXNfc2Vjb25kczogICBbIDIxNjAwIF1cclxuXHQgKiBcdFx0XHRcdFx0XHQgICBcdFx0anF1ZXJ5X29wdGlvbjogICAgICBqUXVlcnlfT2JqZWN0IHt9XHJcblx0ICogXHRcdFx0XHRcdFx0XHRcdG5hbWU6ICAgICAgICAgICAgICAgJ3N0YXJ0dGltZTJbXSdcclxuXHQgKiAgXHRcdFx0XHRcdCAgICB9XHJcblx0ICogXHRcdFx0XHRcdCBdXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfX3NlbGVjdGVkX3RpbWVfZmllbGRzX19pbl9ib29raW5nX2Zvcm1fX2FzX2FyciggcmVzb3VyY2VfaWQsIGlzX29ubHlfc2VsZWN0ZWRfdGltZSA9IHRydWUgKXtcclxuXHRcdC8qKlxyXG5cdFx0ICogRmllbGRzIHdpdGggIFtdICBsaWtlIHRoaXMgICBzZWxlY3RbbmFtZT1cInJhbmdldGltZTFbXVwiXVxyXG5cdFx0ICogaXQncyB3aGVuIHdlIGhhdmUgJ211bHRpcGxlJyBpbiBzaG9ydGNvZGU6ICAgW3NlbGVjdCogcmFuZ2V0aW1lIG11bHRpcGxlICBcIjA2OjAwIC0gMDY6MzBcIiAuLi4gXVxyXG5cdFx0ICovXHJcblx0XHR2YXIgdGltZV9maWVsZHNfYXJyPVtcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInJhbmdldGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwicmFuZ2V0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cInN0YXJ0dGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwic3RhcnR0aW1lJyArIHJlc291cmNlX2lkICsgJ1tdXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdCdzZWxlY3RbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0J3NlbGVjdFtuYW1lPVwiZHVyYXRpb250aW1lJyArIHJlc291cmNlX2lkICsgJ1wiXScsXHJcblx0XHRcdFx0XHRcdFx0XHQnc2VsZWN0W25hbWU9XCJkdXJhdGlvbnRpbWUnICsgcmVzb3VyY2VfaWQgKyAnW11cIl0nXHJcblx0XHRcdFx0XHRcdFx0XTtcclxuXHJcblx0XHR2YXIgdGltZV9maWVsZHNfb2JqX2FyciA9IFtdO1xyXG5cclxuXHRcdC8vIExvb3AgYWxsIFRpbWUgRmllbGRzXHJcblx0XHRmb3IgKCB2YXIgY3RmPSAwOyBjdGYgPCB0aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyBjdGYrKyApe1xyXG5cclxuXHRcdFx0dmFyIHRpbWVfZmllbGQgPSB0aW1lX2ZpZWxkc19hcnJbIGN0ZiBdO1xyXG5cclxuXHRcdFx0dmFyIHRpbWVfb3B0aW9uO1xyXG5cdFx0XHRpZiAoIGlzX29ubHlfc2VsZWN0ZWRfdGltZSApe1xyXG5cdFx0XHRcdHRpbWVfb3B0aW9uID0galF1ZXJ5KCAnI2Jvb2tpbmdfZm9ybScgKyByZXNvdXJjZV9pZCArICcgJyArIHRpbWVfZmllbGQgKyAnIG9wdGlvbjpzZWxlY3RlZCcgKTtcdFx0XHQvLyBFeGNsdWRlIGNvbmRpdGlvbmFsICBmaWVsZHMsICBiZWNhdXNlIG9mIHVzaW5nICcjYm9va2luZ19mb3JtMyAuLi4nXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGltZV9vcHRpb24gPSBqUXVlcnkoICcjYm9va2luZ19mb3JtJyArIHJlc291cmNlX2lkICsgJyAnICsgdGltZV9maWVsZCArICcgb3B0aW9uJyApO1x0XHRcdFx0Ly8gQWxsICB0aW1lIGZpZWxkc1xyXG5cdFx0XHR9XHJcblxyXG5cclxuXHRcdFx0Ly8gTG9vcCBhbGwgb3B0aW9ucyBpbiB0aW1lIGZpZWxkXHJcblx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IHRpbWVfb3B0aW9uLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHRcdHZhciBqcXVlcnlfb3B0aW9uID0galF1ZXJ5KCB0aW1lX29wdGlvblsgaiBdICk7XHRcdC8vIEdldCBvbmx5ICBzZWxlY3RlZCBvcHRpb25zIFx0Ly9qUXVlcnkoIHRpbWVfZmllbGQgKyAnIG9wdGlvbjplcSgnICsgaiArICcpJyApO1xyXG5cdFx0XHRcdHZhciB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnIgPSBqcXVlcnlfb3B0aW9uLnZhbCgpLnNwbGl0KCAnLScgKTtcclxuXHRcdFx0XHR2YXIgdGltZXNfYXNfc2Vjb25kcyA9IFtdO1xyXG5cclxuXHRcdFx0XHQvLyBHZXQgdGltZSBhcyBzZWNvbmRzXHJcblx0XHRcdFx0aWYgKCB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnIubGVuZ3RoICl7XHRcdFx0XHQgXHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiA5LjguMTAuMS5cclxuXHRcdFx0XHRcdGZvciAoIGxldCBpID0gMDsgaSA8IHZhbHVlX29wdGlvbl9zZWNvbmRzX2Fyci5sZW5ndGg7IGkrKyApe1x0XHRcdFx0XHQvLyBGaXhJbjogMTAuMC4wLjU2LlxyXG5cdFx0XHRcdFx0XHQvLyB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnJbaV0gPSAnMTQ6MDAgJyAgfCAnIDE2OjAwJyAgIChpZiBmcm9tICdyYW5nZXRpbWUnKSBhbmQgJzE2OjAwJyAgaWYgKHN0YXJ0L2VuZCB0aW1lKVxyXG5cclxuXHRcdFx0XHRcdFx0dmFyIHN0YXJ0X2VuZF90aW1lc19hcnIgPSB2YWx1ZV9vcHRpb25fc2Vjb25kc19hcnJbIGkgXS50cmltKCkuc3BsaXQoICc6JyApO1xyXG5cclxuXHRcdFx0XHRcdFx0dmFyIHRpbWVfaW5fc2Vjb25kcyA9IHBhcnNlSW50KCBzdGFydF9lbmRfdGltZXNfYXJyWyAwIF0gKSAqIDYwICogNjAgKyBwYXJzZUludCggc3RhcnRfZW5kX3RpbWVzX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0XHRcdHRpbWVzX2FzX3
3411NlY29uZHMucHVzaCggdGltZV9pbl9zZWNvbmRzICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR0aW1lX2ZpZWxkc19vYmpfYXJyLnB1c2goIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgICAgICAgICAgIDogalF1ZXJ5KCAnI2Jvb2tpbmdfZm9ybScgKyByZXNvdXJjZV9pZCArICcgJyArIHRpbWVfZmllbGQgKS5hdHRyKCAnbmFtZScgKSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd2YWx1ZV9vcHRpb25fMjRoJzoganF1ZXJ5X29wdGlvbi52YWwoKSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcXVlcnlfb3B0aW9uJyAgIDoganF1ZXJ5X29wdGlvbixcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0aW1lc19hc19zZWNvbmRzJzogdGltZXNfYXNfc2Vjb25kc1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFRleHQ6ICAgW3N0YXJ0dGltZV0gLSBbZW5kdGltZV0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0XHR2YXIgdGV4dF90aW1lX2ZpZWxkc19hcnI9W1xyXG5cdFx0XHRcdFx0XHRcdFx0XHQnaW5wdXRbbmFtZT1cInN0YXJ0dGltZScgKyByZXNvdXJjZV9pZCArICdcIl0nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnaW5wdXRbbmFtZT1cImVuZHRpbWUnICsgcmVzb3VyY2VfaWQgKyAnXCJdJyxcclxuXHRcdFx0XHRcdFx0XHRcdF07XHJcblx0XHRmb3IgKCB2YXIgdGY9IDA7IHRmIDwgdGV4dF90aW1lX2ZpZWxkc19hcnIubGVuZ3RoOyB0ZisrICl7XHJcblxyXG5cdFx0XHR2YXIgdGV4dF9qcXVlcnkgPSBqUXVlcnkoICcjYm9va2luZ19mb3JtJyArIHJlc291cmNlX2lkICsgJyAnICsgdGV4dF90aW1lX2ZpZWxkc19hcnJbIHRmIF0gKTtcdFx0XHRcdFx0XHRcdFx0Ly8gRXhjbHVkZSBjb25kaXRpb25hbCAgZmllbGRzLCAgYmVjYXVzZSBvZiB1c2luZyAnI2Jvb2tpbmdfZm9ybTMgLi4uJ1xyXG5cdFx0XHRpZiAoIHRleHRfanF1ZXJ5Lmxlbmd0aCA+IDAgKXtcclxuXHJcblx0XHRcdFx0dmFyIHRpbWVfX2hfbV9fYXJyID0gdGV4dF9qcXVlcnkudmFsKCkudHJpbSgpLnNwbGl0KCAnOicgKTtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gJzE0OjAwJ1xyXG5cdFx0XHRcdGlmICggMCA9PSB0aW1lX19oX21fX2Fyci5sZW5ndGggKXtcclxuXHRcdFx0XHRcdGNvbnRpbnVlO1x0XHRcdFx0XHRcdFx0XHRcdC8vIE5vdCBlbnRlcmVkIHRpbWUgdmFsdWUgaW4gYSBmaWVsZFxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIDEgPT0gdGltZV9faF9tX19hcnIubGVuZ3RoICl7XHJcblx0XHRcdFx0XHRpZiAoICcnID09PSB0aW1lX19oX21fX2FyclsgMCBdICl7XHJcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1x0XHRcdFx0XHRcdFx0XHQvLyBOb3QgZW50ZXJlZCB0aW1lIHZhbHVlIGluIGEgZmllbGRcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHRpbWVfX2hfbV9fYXJyWyAxIF0gPSAwO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR2YXIgdGV4dF90aW1lX2luX3NlY29uZHMgPSBwYXJzZUludCggdGltZV9faF9tX19hcnJbIDAgXSApICogNjAgKiA2MCArIHBhcnNlSW50KCB0aW1lX19oX21fX2FyclsgMSBdICkgKiA2MDtcclxuXHJcblx0XHRcdFx0dmFyIHRleHRfdGltZXNfYXNfc2Vjb25kcyA9IFtdO1xyXG5cdFx0XHRcdHRleHRfdGltZXNfYXNfc2Vjb25kcy5wdXNoKCB0ZXh0X3RpbWVfaW5fc2Vjb25kcyApO1xyXG5cclxuXHRcdFx0XHR0aW1lX2ZpZWxkc19vYmpfYXJyLnB1c2goIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgICAgICAgICAgIDogdGV4dF9qcXVlcnkuYXR0ciggJ25hbWUnICksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWVfb3B0aW9uXzI0aCc6IHRleHRfanF1ZXJ5LnZhbCgpLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxdWVyeV9vcHRpb24nICAgOiB0ZXh0X2pxdWVyeSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0aW1lc19hc19zZWNvbmRzJzogdGV4dF90aW1lc19hc19zZWNvbmRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRpbWVfZmllbGRzX29ial9hcnI7XHJcblx0fVxyXG5cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBTIFUgUCBQIE8gUiBUICAgIGZvciAgICBDIEEgTCBFIE4gRCBBIFIgID09XHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgQ2FsZW5kYXIgZGF0ZXBpY2sgIEluc3RhbmNlXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkICBvZiBib29raW5nIHJlc291cmNlXHJcblx0ICogQHJldHVybnMgeyp8bnVsbH1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHJlc291cmNlX2lkKSApe1xyXG5cdFx0XHRyZXNvdXJjZV9pZCA9ICcxJztcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkubGVuZ3RoID4gMCApe1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmRhdGVwaWNrLl9nZXRJbnN0KCBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmdldCggMCApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBVbnNlbGVjdCAgYWxsIGRhdGVzIGluIGNhbGVuZGFyIGFuZCB2aXN1YWxseSB1cGRhdGUgdGhpcyBjYWxlbmRhclxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cdFx0dHJ1ZSBvbiBzdWNjZXNzIHwgZmFsc2UsICBpZiBubyBzdWNoICBjYWxlbmRhclxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX3Vuc2VsZWN0X2FsbF9kYXRlcyggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKHJl
3411c291cmNlX2lkKSApe1xyXG5cdFx0XHRyZXNvdXJjZV9pZCA9ICcxJztcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApXHJcblxyXG5cdFx0aWYgKCBudWxsICE9PSBpbnN0ICl7XHJcblxyXG5cdFx0XHQvLyBVbnNlbGVjdCBhbGwgZGF0ZXMgYW5kIHNldCAgcHJvcGVydGllcyBvZiBEYXRlcGlja1xyXG5cdFx0XHRqUXVlcnkoICcjZGF0ZV9ib29raW5nJyArIHJlc291cmNlX2lkICkudmFsKCAnJyApOyAgICAgIC8vRml4SW46IDUuNC4zXHJcblx0XHRcdGluc3Quc3RheU9wZW4gPSBmYWxzZTtcclxuXHRcdFx0aW5zdC5kYXRlcyA9IFtdO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3VwZGF0ZURhdGVwaWNrKCBpbnN0ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gdHJ1ZVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBDbGVhciBkYXlzIGhpZ2hsaWdodGluZyBpbiBBbGwgb3Igc3BlY2lmaWMgQ2FsZW5kYXJzXHJcblx0ICpcclxuICAgICAqIEBwYXJhbSByZXNvdXJjZV9pZCAgLSBjYW4gYmUgc2tpcGVkIHRvICBjbGVhciBoaWdobGlnaHRpbmcgaW4gYWxsIGNhbGVuZGFyc1xyXG4gICAgICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcnNfX2NsZWFyX2RheXNfaGlnaGxpZ2h0aW5nKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAoIHJlc291cmNlX2lkICkgKXtcclxuXHJcblx0XHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyAuZGF0ZXBpY2stZGF5cy1jZWxsLW92ZXInICkucmVtb3ZlQ2xhc3MoICdkYXRlcGljay1kYXlzLWNlbGwtb3ZlcicgKTtcdFx0Ly8gQ2xlYXIgaW4gc3BlY2lmaWMgY2FsZW5kYXJcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRqUXVlcnkoICcuZGF0ZXBpY2stZGF5cy1jZWxsLW92ZXInICkucmVtb3ZlQ2xhc3MoICdkYXRlcGljay1kYXlzLWNlbGwtb3ZlcicgKTtcdFx0XHRcdFx0XHRcdFx0Ly8gQ2xlYXIgaW4gYWxsIGNhbGVuZGFyc1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogU2Nyb2xsIHRvIHNwZWNpZmljIG1vbnRoIGluIGNhbGVuZGFyXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFx0SUQgb2YgcmVzb3VyY2VcclxuXHQgKiBAcGFyYW0geWVhclx0XHRcdFx0LSByZWFsIHllYXIgIC0gMjAyM1xyXG5cdCAqIEBwYXJhbSBtb250aFx0XHRcdFx0LSByZWFsIG1vbnRoIC0gMTJcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19zY3JvbGxfdG8oIHJlc291cmNlX2lkLCB5ZWFyLCBtb250aCApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAocmVzb3VyY2VfaWQpICl7IHJlc291cmNlX2lkID0gJzEnOyB9XHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApXHJcblx0XHRpZiAoIG51bGwgIT09IGluc3QgKXtcclxuXHJcblx0XHRcdHllYXIgID0gcGFyc2VJbnQoIHllYXIgKTtcclxuXHRcdFx0bW9udGggPSBwYXJzZUludCggbW9udGggKSAtIDE7XHRcdC8vIEluIEpTIGRhdGUsICBtb250aCAtMVxyXG5cclxuXHRcdFx0aW5zdC5jdXJzb3JEYXRlID0gbmV3IERhdGUoKTtcclxuXHRcdFx0Ly8gSW4gc29tZSBjYXNlcywgIHRoZSBzZXRGdWxsWWVhciBjYW4gIHNldCAgb25seSBZZWFyLCAgYW5kIG5vdCB0aGUgTW9udGggYW5kIGRheSAgICAgIC8vIEZpeEluOiA2LjIuMy41LlxyXG5cdFx0XHRpbnN0LmN1cnNvckRhdGUuc2V0RnVsbFllYXIoIHllYXIsIG1vbnRoLCAxICk7XHJcblx0XHRcdGluc3QuY3Vyc29yRGF0ZS5zZXRNb250aCggbW9udGggKTtcclxuXHRcdFx0aW5zdC5jdXJzb3JEYXRlLnNldERhdGUoIDEgKTtcclxuXHJcblx0XHRcdGluc3QuZHJhd01vbnRoID0gaW5zdC5jdXJzb3JEYXRlLmdldE1vbnRoKCk7XHJcblx0XHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LmN1cnNvckRhdGUuZ2V0RnVsbFllYXIoKTtcclxuXHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fbm90aWZ5Q2hhbmdlKCBpbnN0ICk7XHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fYWRqdXN0SW5zdERhdGUoIGluc3QgKTtcclxuXHRcdFx0alF1ZXJ5LmRhdGVwaWNrLl9zaG93RGF0ZSggaW5zdCApO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3VwZGF0ZURhdGVwaWNrKCBpbnN0ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIElzIHRoaXMgZGF0ZSBzZWxlY3RhYmxlIGluIGNhbGVuZGFyIChtYWlubHkgaXQncyBtZWFucyBBVkFJTEFCTEUgZGF0ZSlcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7aW50fHN0cmluZ30gcmVzb3VyY2VfaWRcdFx0MVxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzcWxfY2xhc3NfZGF5XHRcdCcyMDIzLTA4LTExJ1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVx0XHRcdFx0XHR0cnVlIHwgZmFsc2VcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2lzX3RoaXNfZGF5X3NlbGVjdGFibGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICl7XHJcblxyXG5cdFx0Ly8gR2V0IERhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdHZhciBkYXRlX2Jvb2tpbmdzX29iaiA9IF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19nZXRfZm9yX2RhdGUoIHJlc291cmNlX2lkLCBzcWxfY2xhc3NfZGF5ICk7XHJcblxyXG5cdFx0dmFyIGlzX2RheV9zZWxlY3RhYmxlID0gKCBwYXJzZUludCggZGF0ZV9ib29raW5nc19vYmpbICdkYXlfYXZhaWxhYmlsaXR5JyBdICkgPiAwICk7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgKGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeScgXSkgPT09ICd1bmRlZmluZWQnICl7XHJcblx0XHRcdHJldHVybi
3411Bpc19kYXlfc2VsZWN0YWJsZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoICdhdmFpbGFibGUnICE9IGRhdGVfYm9va2luZ3Nfb2JqWyAnc3VtbWFyeSddWydzdGF0dXNfZm9yX2RheScgXSApe1xyXG5cclxuXHRcdFx0dmFyIGlzX3NldF9wZW5kaW5nX2RheXNfc2VsZWN0YWJsZSA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAncGVuZGluZ19kYXlzX3NlbGVjdGFibGUnICk7XHRcdC8vIHNldCBwZW5kaW5nIGRheXMgc2VsZWN0YWJsZSAgICAgICAgICAvLyBGaXhJbjogOC42LjEuMTguXHJcblxyXG5cdFx0XHRzd2l0Y2ggKCBkYXRlX2Jvb2tpbmdzX29ialsgJ3N1bW1hcnknXVsnc3RhdHVzX2Zvcl9ib29raW5ncycgXSApe1xyXG5cdFx0XHRcdGNhc2UgJ3BlbmRpbmcnOlxyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbnMgZm9yIFwiY2hhbmdlLW92ZXJcIiBkYXlzOlxyXG5cdFx0XHRcdGNhc2UgJ3BlbmRpbmdfcGVuZGluZyc6XHJcblx0XHRcdFx0Y2FzZSAncGVuZGluZ19hcHByb3ZlZCc6XHJcblx0XHRcdFx0Y2FzZSAnYXBwcm92ZWRfcGVuZGluZyc6XHJcblx0XHRcdFx0XHRpc19kYXlfc2VsZWN0YWJsZSA9IChpc19kYXlfc2VsZWN0YWJsZSkgPyB0cnVlIDogaXNfc2V0X3BlbmRpbmdfZGF5c19zZWxlY3RhYmxlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBpc19kYXlfc2VsZWN0YWJsZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIElzIGRhdGUgdG8gY2hlY2sgSU4gYXJyYXkgb2Ygc2VsZWN0ZWQgZGF0ZXNcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7ZGF0ZX1qc19kYXRlX3RvX2NoZWNrXHRcdC0gSlMgRGF0ZVx0XHRcdC0gc2ltcGxlICBKYXZhU2NyaXB0IERhdGUgb2JqZWN0XHJcblx0ICogQHBhcmFtIHtbXX0ganNfZGF0ZXNfYXJyXHRcdFx0LSBbIEpTRGF0ZSwgLi4uIF0gICAtIGFycmF5ICBvZiBKUyBkYXRlc1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfaXNfdGhpc19kYXlfYW1vbmdfc2VsZWN0ZWRfZGF5cygganNfZGF0ZV90b19jaGVjaywganNfZGF0ZXNfYXJyICl7XHJcblxyXG5cdFx0Zm9yICggdmFyIGRhdGVfaW5kZXggPSAwOyBkYXRlX2luZGV4IDwganNfZGF0ZXNfYXJyLmxlbmd0aCA7IGRhdGVfaW5kZXgrKyApeyAgICAgXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRml4SW46IDguNC41LjE2LlxyXG5cdFx0XHRpZiAoICgganNfZGF0ZXNfYXJyWyBkYXRlX2luZGV4IF0uZ2V0RnVsbFllYXIoKSA9PT0ganNfZGF0ZV90b19jaGVjay5nZXRGdWxsWWVhcigpICkgJiZcclxuXHRcdFx0XHQgKCBqc19kYXRlc19hcnJbIGRhdGVfaW5kZXggXS5nZXRNb250aCgpID09PSBqc19kYXRlX3RvX2NoZWNrLmdldE1vbnRoKCkgKSAmJlxyXG5cdFx0XHRcdCAoIGpzX2RhdGVzX2FyclsgZGF0ZV9pbmRleCBdLmdldERhdGUoKSA9PT0ganNfZGF0ZV90b19jaGVjay5nZXREYXRlKCkgKSApIHtcclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuICBmYWxzZTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBTUUwgQ2xhc3MgRGF0ZSAnMjAyMy0wOC0wMScgZnJvbSAgSlMgRGF0ZVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGRhdGVcdFx0XHRcdEpTIERhdGVcclxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVx0XHQnMjAyMy0wOC0xMidcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlICl7XHJcblxyXG5cdFx0dmFyIHNxbF9jbGFzc19kYXkgPSBkYXRlLmdldEZ1bGxZZWFyKCkgKyAnLSc7XHJcblx0XHRcdHNxbF9jbGFzc19kYXkgKz0gKCAoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSA8IDEwICkgPyAnMCcgOiAnJztcclxuXHRcdFx0c3FsX2NsYXNzX2RheSArPSAoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSArICctJ1xyXG5cdFx0XHRzcWxfY2xhc3NfZGF5ICs9ICggZGF0ZS5nZXREYXRlKCkgPCAxMCApID8gJzAnIDogJyc7XHJcblx0XHRcdHNxbF9jbGFzc19kYXkgKz0gZGF0ZS5nZXREYXRlKCk7XHJcblxyXG5cdFx0XHRyZXR1cm4gc3FsX2NsYXNzX2RheTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBKUyBEYXRlIGZyb20gIHRoZSBTUUwgZGF0ZSBmb3JtYXQgJzIwMjQtMDUtMTQnXHJcblx0ICogQHBhcmFtIHNxbF9jbGFzc19kYXRlXHJcblx0ICogQHJldHVybnMge0RhdGV9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fZ2V0X19qc19kYXRlKCBzcWxfY2xhc3NfZGF0ZSApe1xyXG5cclxuXHRcdHZhciBzcWxfY2xhc3NfZGF0ZV9hcnIgPSBzcWxfY2xhc3NfZGF0ZS5zcGxpdCggJy0nICk7XHJcblxyXG5cdFx0dmFyIGRhdGVfanMgPSBuZXcgRGF0ZSgpO1xyXG5cclxuXHRcdGRhdGVfanMuc2V0RnVsbFllYXIoIHBhcnNlSW50KCBzcWxfY2xhc3NfZGF0ZV9hcnJbIDAgXSApLCAocGFyc2VJbnQoIHNxbF9jbGFzc19kYXRlX2FyclsgMSBdICkgLSAxKSwgcGFyc2VJbnQoIHNxbF9jbGFzc19kYXRlX2FyclsgMiBdICkgKTsgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblxyXG5cdFx0Ly8gV2l0aG91dCB0aGlzIHRpbWUgYWRqdXN0IERhdGVzIHNlbGVjdGlvbiAgaW4gRGF0ZXBpY2tlciBjYW4gbm90IHdvcmshISFcclxuXHRcdGRhdGVfanMuc2V0SG91cnMoMCk7XHJcblx0XHRkYXRlX2pzLnNldE1pbnV0ZXMoMCk7XHJcblx0XHRkYXRlX2pzLnNldFNlY29uZHMoMCk7XHJcblx0XHRkYXRlX2pzLnNldE1pbGxpc2Vjb25kcygwKTtcclxuXHJcblx0XHRyZXR1cm4gZGF0ZV9qcztcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBURCBDbGFzcyBEYXRlICcxLTMxLTIwMjMnIGZyb20gIEpTIERhdGVcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRlXHRcdFx0XHRKUyBEYXRlXHJcblx0ICogQHJldHVybnMge3N0cmluZ31cdFx0JzEtMzEtMjAyMydcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX19nZXRfX3RkX2NsYXNzX2RhdGUoIGRhdGUgKXtcclxuXHJcblx0XHR2YXIgdGRfY2xhc3NfZGF5ID0gKGRhdGUuZ2V0TW9udGgoKSArIDEpICsgJy0nICsgZGF0ZS5nZXREYXRlKCkgKyAnLScgKyBkYXRlLmdldEZ1bGxZZWFyKCk7XHRcdFx0XHRcdFx0XHRcdC8vICcxLTktMjAyMydcclxuXHJcblx0XHRyZXR1cm4gdGRfY2xhc3NfZGF5O1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGRhdGUgcGFyYW1zIGZyb20gIHN0cmluZyBkYXRlXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZVx0XHRcdHN0cmluZyBkYXRlIGxpa2UgJzMxLjUuMjAyMydcclxuXHQgKiBAcGFyYW0gc2VwYXJhdG9yXHRcdGRlZmF1bHQgJy4nICBjYW4gYmUgc2tpcHBlZC5cclxuXHQgKiBAcmV0dXJucyB7ICB7ZGF0ZTogbnVtYmVyLCBtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXJ9ICB9XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19fZ2V0X19kYXRlX3BhcmFtc19fZnJvbV9zdHJpbmdfZGF0ZSggZGF0ZSAsIHNlcGFyYXRvcil7XHJcblxyXG5cdFx0c2VwYXJhdG9yID0gKCAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChzZXBhcmF0b3IpICkgPyBzZXBhcmF0b3IgOiAnLic7XHJcblxyXG5cdFx0dmFyIGRhdGVfYXJyID0gZGF0ZS5zcGxpdCggc2
3411VwYXJhdG9yICk7XHJcblx0XHR2YXIgZGF0ZV9vYmogPSB7XHJcblx0XHRcdCd5ZWFyJyA6ICBwYXJzZUludCggZGF0ZV9hcnJbIDIgXSApLFxyXG5cdFx0XHQnbW9udGgnOiAocGFyc2VJbnQoIGRhdGVfYXJyWyAxIF0gKSAtIDEpLFxyXG5cdFx0XHQnZGF0ZScgOiAgcGFyc2VJbnQoIGRhdGVfYXJyWyAwIF0gKVxyXG5cdFx0fTtcclxuXHRcdHJldHVybiBkYXRlX29iajtcdFx0Ly8gZm9yIFx0XHQgPSBuZXcgRGF0ZSggZGF0ZV9vYmoueWVhciAsIGRhdGVfb2JqLm1vbnRoICwgZGF0ZV9vYmouZGF0ZSApO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQWRkIFNwaW4gTG9hZGVyIHRvICBjYWxlbmRhclxyXG5cdCAqIEBwYXJhbSByZXNvdXJjZV9pZFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0YXJ0KCByZXNvdXJjZV9pZCApe1xyXG5cdFx0aWYgKCAhIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkubmV4dCgpLmhhc0NsYXNzKCAnd3BiY19zcGluc19sb2FkZXJfd3JhcHBlcicgKSApe1xyXG5cdFx0XHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmFmdGVyKCAnPGRpdiBjbGFzcz1cIndwYmNfc3BpbnNfbG9hZGVyX3dyYXBwZXJcIj48ZGl2IGNsYXNzPVwid3BiY19zcGluc19sb2FkZXJcIj48L2Rpdj48L2Rpdj4nICk7XHJcblx0XHR9XHJcblx0XHRpZiAoICEgalF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5oYXNDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cl9zbWFsbCcgKSApe1xyXG5cdFx0XHRqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmFkZENsYXNzKCAnd3BiY19jYWxlbmRhcl9ibHVyX3NtYWxsJyApO1xyXG5cdFx0fVxyXG5cdFx0d3BiY19jYWxlbmRhcl9fYmx1cl9fc3RhcnQoIHJlc291cmNlX2lkICk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgU3BpbiBMb2FkZXIgdG8gIGNhbGVuZGFyXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fbG9hZGluZ19fc3RvcCggcmVzb3VyY2VfaWQgKXtcclxuXHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyArIC53cGJjX3NwaW5zX2xvYWRlcl93cmFwcGVyJyApLnJlbW92ZSgpO1xyXG5cdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5yZW1vdmVDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cl9zbWFsbCcgKTtcclxuXHRcdHdwYmNfY2FsZW5kYXJfX2JsdXJfX3N0b3AoIHJlc291cmNlX2lkICk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBBZGQgQmx1ciB0byAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19ibHVyX19zdGFydCggcmVzb3VyY2VfaWQgKXtcclxuXHRcdGlmICggISBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyByZXNvdXJjZV9pZCApLmhhc0NsYXNzKCAnd3BiY19jYWxlbmRhcl9ibHVyJyApICl7XHJcblx0XHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkuYWRkQ2xhc3MoICd3cGJjX2NhbGVuZGFyX2JsdXInICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgQmx1ciBpbiAgY2FsZW5kYXJcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19ibHVyX19zdG9wKCByZXNvdXJjZV9pZCApe1xyXG5cdFx0alF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKS5yZW1vdmVDbGFzcyggJ3dwYmNfY2FsZW5kYXJfYmx1cicgKTtcclxuXHR9XHJcblxyXG5cclxuXHQvLyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLlxyXG5cdC8qICA9PSAgQ2FsZW5kYXIgVXBkYXRlICAtIFZpZXcgID09XHJcblx0Ly8gLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gKi9cclxuXHJcblx0LyoqXHJcblx0ICogVXBkYXRlIExvb2sgIG9mIGNhbGVuZGFyXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHR2YXIgaW5zdCA9IHdwYmNfY2FsZW5kYXJfX2dldF9pbnN0KCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdGpRdWVyeS5kYXRlcGljay5fdXBkYXRlRGF0ZXBpY2soIGluc3QgKTtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGUgZHluYW1pY2FsbHkgTnVtYmVyIG9mIE1vbnRocyBpbiBjYWxlbmRhclxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHJlc291cmNlX2lkIGludFxyXG5cdCAqIEBwYXJhbSBtb250aHNfbnVtYmVyIGludFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJfX3VwZGF0ZV9tb250aHNfbnVtYmVyKCByZXNvdXJjZV9pZCwgbW9udGhzX251bWJlciApe1xyXG5cdFx0dmFyIGluc3QgPSB3cGJjX2NhbGVuZGFyX19nZXRfaW5zdCggcmVzb3VyY2VfaWQgKTtcclxuXHRcdGlmICggbnVsbCAhPT0gaW5zdCApe1xyXG5cdFx0XHRpbnN0LnNldHRpbmdzWyAnbnVtYmVyT2ZNb250aHMnIF0gPSBtb250aHNfbnVtYmVyO1xyXG5cdFx0XHQvL193cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnY2FsZW5kYXJfbnVtYmVyX29mX21vbnRocycsIG1vbnRoc19udW1iZXIgKTtcclxuXHRcdFx0d3BiY19jYWxlbmRhcl9fdXBkYXRlX2xvb2soIHJlc291cmNlX2lkICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogU2hvdyBjYWxlbmRhciBpbiAgZGlmZmVyZW50IFNraW5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBzZWxlY3RlZF9za2luX3VybFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfX2NhbGVuZGFyX19jaGFuZ2Vfc2tpbiggc2VsZWN0ZWRfc2tpbl91cmwgKXtcclxuXHJcblx0Ly9jb25zb2xlLmxvZyggJ1NLSU4gU0VMRUNUSU9OIDo6Jywgc2VsZWN0ZWRfc2tpbl91cmwgKTtcclxuXHJcblx0XHQvLyBSZW1vdmUgQ1NTIHNraW5cclxuXHRcdHZhciBzdHlsZXNoZWV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoICd3cGJjLWNhbGVuZGFyLXNraW4tY3NzJyApO1xyXG5cdFx0c3R5bGVzaGVldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzdHlsZXNoZWV0ICk7XHJcblxyXG5cclxuXHRcdC8vIEFkZCBuZXcgQ1NTIHNraW5cclxuXHRcdHZhciBoZWFkSUQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJoZWFkXCIgKVsgMCBdO1xyXG5cdFx0dmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTtcclxuXHRcdGNzc05vZGUudHlwZSA9ICd0ZXh0L2Nzcyc7XHJcblx0XHRjc3NOb2RlLnNldEF0dHJpYnV0ZSggXCJpZFwiLCBcIndwYmMtY2FsZW5kYXItc2tpbi1jc3NcIiApO1xyXG5cdFx0Y3NzTm9kZS5yZWwgPSAnc3R5bGVzaGVldCc7XHJcblx0XHRjc3NOb2RlLm1lZGlhID0gJ3NjcmVlbic7XHJcblx0XHRjc3NOb2RlLmhyZWYgPSBzZWxlY3RlZF9za2luX3VybDtcdC8vXCJodHRwOi8vYmV0YS93cC1jb250ZW50L3BsdWdpbnMvYm9va2luZy9jc3Mvc2tpbnMvZ3JlZW4tMDEuY3NzXCI7XHJcblx0XHRoZWFkSUQuYXBwZW5kQ2hpbGQoIGNzc05vZGUgKTtcclxuXHR9XHJcblxyXG5cclxuXHRmdW5jdGlvbiB3cGJjX19jc3NfX2NoYW5nZV9za2luKCBzZWxlY3RlZF9za2luX3VybCwgc3R5bGVzaGVldF9pZCA9ICd3cGJjLXRpbWVfcGlja2VyLXNraW4tY3NzJyApe1xyXG5cclxuXHRcdC8vIFJlbW92ZSBDU1Mgc2tpblxyXG5cdFx0dmFyIHN0eWxlc2hlZXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggc3R5bGVzaGVldF9pZCApO1xyXG5cdFx0c3R5bGVzaGVldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzdHlsZXNoZWV0ICk7XHJcblxyXG5cclxuXHRcdC8vIEFkZCBuZXcgQ1NTIHNraW5cclxuXHRcdHZhciBoZWFkSUQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJoZWFkXCIgKVsgMCBdO1xyXG5cdFx0dmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTtcclxuXHRcdGNzc05vZGUudHlwZSA9ICd0ZXh0L2Nzcyc7XHJcblx0XHRjc3NOb2RlLnNldEF0dHJpYnV0ZSggXCJpZFwiLCBzdHlsZXNoZWV0X2lkICk7XHJcblx0XHRjc3NOb2RlLnJlbCA9ICdzdHlsZXNoZWV0JztcclxuXHRcdGNzc05vZGUubWVkaWEgPSAnc2NyZWVuJztcclxuXHRcdGNzc05vZGUuaHJlZiA9IHNlbGVjdGVkX3NraW5fdXJsO1x0Ly9cImh0dHA6Ly9iZXRhL3dwLWNvbnRlbnQvcGx1Z2lucy9ib29raW5nL2Nzcy9za2lucy9ncmVlbi0wMS5jc3NcIjtcclxuXHRcdGhlYWRJRC5hcHBlbmRDaGlsZCggY3NzTm9kZSApO1xyXG5cdH1cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBTIFUgUCBQIE8gUiBUICAgIE0gQSBUIEggID09XHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogTWVyZ2Ugc2V2ZXJhbCAgaW50ZXJzZWN0ZWQgaW50ZXJ2YWxzIG9yIHJldHVybi
3411Bub3QgaW50ZXJzZWN0ZWQ6ICAgICAgICAgICAgICAgICAgICAgICAgW1sxLDNdLFsyLDZdLFs4LDEwXSxbMTUsMThdXSAgLT4gICBbWzEsNl0sWzgsMTBdLFsxNSwxOF1dXHJcblx0XHQgKlxyXG5cdFx0ICogQHBhcmFtIFtdIGludGVydmFsc1x0XHRcdCBbIFsxLDNdLFsyLDRdLFs2LDhdLFs5LDEwXSxbMyw3XSBdXHJcblx0XHQgKiBAcmV0dXJucyBbXVx0XHRcdFx0XHQgWyBbMSw4XSxbOSwxMF0gXVxyXG5cdFx0ICpcclxuXHRcdCAqIEV4bWFtcGxlOiB3cGJjX2ludGVydmFsc19fbWVyZ2VfaW5lcnNlY3RlZCggIFsgWzEsM10sWzIsNF0sWzYsOF0sWzksMTBdLFszLDddIF0gICk7XHJcblx0XHQgKi9cclxuXHRcdGZ1bmN0aW9uIHdwYmNfaW50ZXJ2YWxzX19tZXJnZV9pbmVyc2VjdGVkKCBpbnRlcnZhbHMgKXtcclxuXHJcblx0XHRcdGlmICggISBpbnRlcnZhbHMgfHwgaW50ZXJ2YWxzLmxlbmd0aCA9PT0gMCApe1xyXG5cdFx0XHRcdHJldHVybiBbXTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIG1lcmdlZCA9IFtdO1xyXG5cdFx0XHRpbnRlcnZhbHMuc29ydCggZnVuY3Rpb24gKCBhLCBiICl7XHJcblx0XHRcdFx0cmV0dXJuIGFbIDAgXSAtIGJbIDAgXTtcclxuXHRcdFx0fSApO1xyXG5cclxuXHRcdFx0dmFyIG1lcmdlZEludGVydmFsID0gaW50ZXJ2YWxzWyAwIF07XHJcblxyXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDE7IGkgPCBpbnRlcnZhbHMubGVuZ3RoOyBpKysgKXtcclxuXHRcdFx0XHR2YXIgaW50ZXJ2YWwgPSBpbnRlcnZhbHNbIGkgXTtcclxuXHJcblx0XHRcdFx0aWYgKCBpbnRlcnZhbFsgMCBdIDw9IG1lcmdlZEludGVydmFsWyAxIF0gKXtcclxuXHRcdFx0XHRcdG1lcmdlZEludGVydmFsWyAxIF0gPSBNYXRoLm1heCggbWVyZ2VkSW50ZXJ2YWxbIDEgXSwgaW50ZXJ2YWxbIDEgXSApO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRtZXJnZWQucHVzaCggbWVyZ2VkSW50ZXJ2YWwgKTtcclxuXHRcdFx0XHRcdG1lcmdlZEludGVydmFsID0gaW50ZXJ2YWw7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRtZXJnZWQucHVzaCggbWVyZ2VkSW50ZXJ2YWwgKTtcclxuXHRcdFx0cmV0dXJuIG1lcmdlZDtcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBJcyAyIGludGVydmFscyBpbnRlcnNlY3RlZDogICAgICAgWzM2MDExLCA4NjM5Ml0gICAgPD0+ICAgIFsxLCA0MzE5Ml0gID0+ICB0cnVlICAgICAgKCBpbnRlcnNlY3RlZCApXHJcblx0XHQgKlxyXG5cdFx0ICogR29vZCBleHBsYW5hdGlvbiAgaGVyZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMjY5NDM0L3doYXRzLXRoZS1tb3N0LWVmZmljaWVudC13YXktdG8tdGVzdC1pZi10d28tcmFuZ2VzLW92ZXJsYXBcclxuXHRcdCAqXHJcblx0XHQgKiBAcGFyYW0gIGludGVydmFsX0EgICAtIFsgMzYwMTEsIDg2MzkyIF1cclxuXHRcdCAqIEBwYXJhbSAgaW50ZXJ2YWxfQiAgIC0gWyAgICAgMSwgNDMxOTIgXVxyXG5cdFx0ICpcclxuXHRcdCAqIEByZXR1cm4gYm9vbFxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2ludGVydmFsc19faXNfaW50ZXJzZWN0ZWQoIGludGVydmFsX0EsIGludGVydmFsX0IgKSB7XHJcblxyXG5cdFx0XHRpZiAoXHJcblx0XHRcdFx0XHQoIDAgPT0gaW50ZXJ2YWxfQS5sZW5ndGggKVxyXG5cdFx0XHRcdCB8fCAoIDAgPT0gaW50ZXJ2YWxfQi5sZW5ndGggKVxyXG5cdFx0XHQpe1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aW50ZXJ2YWxfQVsgMCBdID0gcGFyc2VJbnQoIGludGVydmFsX0FbIDAgXSApO1xyXG5cdFx0XHRpbnRlcnZhbF9BWyAxIF0gPSBwYXJzZUludCggaW50ZXJ2YWxfQVsgMSBdICk7XHJcblx0XHRcdGludGVydmFsX0JbIDAgXSA9IHBhcnNlSW50KCBpbnRlcnZhbF9CWyAwIF0gKTtcclxuXHRcdFx0aW50ZXJ2YWxfQlsgMSBdID0gcGFyc2VJbnQoIGludGVydmFsX0JbIDEgXSApO1xyXG5cclxuXHRcdFx0dmFyIGlzX2ludGVyc2VjdGVkID0gTWF0aC5tYXgoIGludGVydmFsX0FbIDAgXSwgaW50ZXJ2YWxfQlsgMCBdICkgLSBNYXRoLm1pbiggaW50ZXJ2YWxfQVsgMSBdLCBpbnRlcnZhbF9CWyAxIF0gKTtcclxuXHJcblx0XHRcdC8vIGlmICggMCA9PSBpc19pbnRlcnNlY3RlZCApIHtcclxuXHRcdFx0Ly9cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2ggcmFuZ2VzIGdvaW5nIG9uZSBhZnRlciBvdGhlciwgZS5nLjogWyAxMiwgMTUgXSBhbmQgWyAxNSwgMjEgXVxyXG5cdFx0XHQvLyB9XHJcblxyXG5cdFx0XHRpZiAoIGlzX2ludGVyc2VjdGVkIDwgMCApIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAvLyBJTlRFUlNFQ1RFRFxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7ICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3QgaW50ZXJzZWN0ZWRcclxuXHRcdH1cclxuXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBHZXQgdGhlIGNsb3NldHMgQUJTIHZhbHVlIG9mIGVsZW1lbnQgaW4gYXJyYXkgdG8gdGhlIGN1cnJlbnQgbXlWYWx1ZVxyXG5cdFx0ICpcclxuXHRcdCAqIEBwYXJhbSBteVZhbHVlIFx0LSBpbnQgZWxlbWVudCB0byBzZWFyY2ggY2xvc2V0IFx0XHRcdDRcclxuXHRcdCAqIEBwYXJhbSBteUFycmF5XHQtIGFycmF5IG9mIGVsZW1lbnRzIHdoZXJlIHRvIHNlYXJjaCBcdFs1LDgsMSw3XVxyXG5cdFx0ICogQHJldHVybnMgaW50XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0NVxyXG5cdFx0ICovXHJcblx0XHRmdW5jdGlvbiB3cGJjX2dldF9hYnNfY2xvc2VzdF92YWx1ZV9pbl9hcnIoIG15VmFsdWUsIG15QXJyYXkgKXtcclxuXHJcblx0XHRcdGlmICggbXlBcnJheS5sZW5ndGggPT0gMCApeyBcdFx0XHRcdFx0XHRcdFx0Ly8gSWYgdGhlIGFycmF5IGlzIGVtcHR5IC0+IHJldHVybiAgdGhlIG15VmFsdWVcclxuXHRcdFx0XHRyZXR1cm4gbXlWYWx1ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIG9iaiA9IG15QXJyYXlbIDAgXTtcclxuXHRcdFx0dmFyIGRpZmYgPSBNYXRoLmFicyggbXlWYWx1ZSAtIG9iaiApOyAgICAgICAgICAgICBcdC8vIEdldCBkaXN0YW5jZSBiZXR3ZWVuICAxc3QgZWxlbWVudFxyXG5cdFx0XHR2YXIgY2xvc2V0VmFsdWUgPSBteUFycmF5WyAwIF07ICAgICAgICAgICAgICAgICAgIFx0XHRcdC8vIFNhdmUgMXN0IGVsZW1lbnRcclxuXHJcblx0XHRcdGZvciAoIHZhciBpID0gMTsgaSA8IG15QXJyYXkubGVuZ3RoOyBpKysgKXtcclxuXHRcdFx0XHRvYmogPSBteUFycmF5WyBpIF07XHJcblxyXG5cdFx0XHRcdGlmICggTWF0aC5hYnMoIG15VmFsdWUgLSBvYmogKSA8IGRpZmYgKXsgICAgIFx0XHRcdC8vIHdlIGZvdW5kIGNsb3NlciB2YWx1ZSAtPiBzY
3411XZlIGl0XHJcblx0XHRcdFx0XHRkaWZmID0gTWF0aC5hYnMoIG15VmFsdWUgLSBvYmogKTtcclxuXHRcdFx0XHRcdGNsb3NldFZhbHVlID0gb2JqO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGNsb3NldFZhbHVlO1xyXG5cdFx0fVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT0gIFQgTyBPIEwgVCBJIFAgUyAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8qKlxyXG5cdCAqIERlZmluZSB0b29sdGlwIHRvIHNob3csICB3aGVuICBtb3VzZSBvdmVyIERhdGUgaW4gQ2FsZW5kYXJcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSAgdG9vbHRpcF90ZXh0XHRcdFx0LSBUZXh0IHRvIHNob3dcdFx0XHRcdCdCb29rZWQgdGltZTogMTI6MDAgLSAxMzowMDxicj5Db3N0OiAkMjAuMDAnXHJcblx0ICogQHBhcmFtICByZXNvdXJjZV9pZFx0XHRcdC0gSUQgb2YgYm9va2luZyByZXNvdXJjZVx0JzEnXHJcblx0ICogQHBhcmFtICB0ZF9jbGFzc1x0XHRcdFx0LSBTUUwgY2xhc3NcdFx0XHRcdFx0JzEtOS0yMDIzJ1xyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVx0XHRcdFx0XHQtIGRlZmluZWQgdG8gc2hvdyBvciBub3RcclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX3NldF90b29sdGlwX19fZm9yX19jYWxlbmRhcl9kYXRlKCB0b29sdGlwX3RleHQsIHJlc291cmNlX2lkLCB0ZF9jbGFzcyApe1xyXG5cclxuXHRcdC8vVE9ETzogbWFrZSBlc2NhcGluZyBvZiB0ZXh0IGZvciBxdW90IHN5bWJvbHMsICBhbmQgSlMvSFRNTC4uLlxyXG5cclxuXHRcdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICsgJyB0ZC5jYWw0ZGF0ZS0nICsgdGRfY2xhc3MgKS5hdHRyKCAnZGF0YS1jb250ZW50JywgdG9vbHRpcF90ZXh0ICk7XHJcblxyXG5cdFx0dmFyIHRkX2VsID0galF1ZXJ5KCAnI2NhbGVuZGFyX2Jvb2tpbmcnICsgcmVzb3VyY2VfaWQgKyAnIHRkLmNhbDRkYXRlLScgKyB0ZF9jbGFzcyApLmdldCggMCApO1x0XHRcdFx0XHQvLyBGaXhJbjogOS4wLjEuMS5cclxuXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZih0ZF9lbCkgKVxyXG5cdFx0XHQmJiAoIHVuZGVmaW5lZCA9PSB0ZF9lbC5fdGlwcHkgKVxyXG5cdFx0XHQmJiAoICcnICE9PSB0b29sdGlwX3RleHQgKVxyXG5cdFx0KXtcclxuXHJcblx0XHRcdHdwYmNfdGlwcHkoIHRkX2VsICwge1xyXG5cdFx0XHRcdFx0Y29udGVudCggcmVmZXJlbmNlICl7XHJcblxyXG5cdFx0XHRcdFx0XHR2YXIgcG9wb3Zlcl9jb250ZW50ID0gcmVmZXJlbmNlLmdldEF0dHJpYnV0ZSggJ2RhdGEtY29udGVudCcgKTtcclxuXHJcblx0XHRcdFx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cInBvcG92ZXIgcG9wb3Zlcl90aXBweVwiPidcclxuXHRcdFx0XHRcdFx0XHRcdFx0KyAnPGRpdiBjbGFzcz1cInBvcG92ZXItY29udGVudFwiPidcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQrIHBvcG92ZXJfY29udGVudFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQrICc8L2Rpdj4nXHJcblx0XHRcdFx0XHRcdFx0ICsgJzwvZGl2Pic7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0YWxsb3dIVE1MICAgICAgICA6IHRydWUsXHJcblx0XHRcdFx0XHR0cmlnZ2VyXHRcdFx0IDogJ21vdXNlZW50ZXIgZm9jdXMnLFxyXG5cdFx0XHRcdFx0aW50ZXJhY3RpdmUgICAgICA6IGZhbHNlLFxyXG5cdFx0XHRcdFx0aGlkZU9uQ2xpY2sgICAgICA6IHRydWUsXHJcblx0XHRcdFx0XHRpbnRlcmFjdGl2ZUJvcmRlcjogMTAsXHJcblx0XHRcdFx0XHRtYXhXaWR0aCAgICAgICAgIDogNTUwLFxyXG5cdFx0XHRcdFx0dGhlbWUgICAgICAgICAgICA6ICd3cGJjLXRpcHB5LXRpbWVzJyxcclxuXHRcdFx0XHRcdHBsYWNlbWVudCAgICAgICAgOiAndG9wJyxcclxuXHRcdFx0XHRcdGRlbGF5XHRcdFx0IDogWzQwMCwgMF0sXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRml4SW46IDkuNC4yLjIuXHJcblx0XHRcdFx0XHQvL2RlbGF5XHRcdFx0IDogWzAsIDk5OTk5OTk5OTldLFx0XHRcdFx0XHRcdC8vIERlYnVnZSAgdG9vbHRpcFxyXG5cdFx0XHRcdFx0aWdub3JlQXR0cmlidXRlcyA6IHRydWUsXHJcblx0XHRcdFx0XHR0b3VjaFx0XHRcdCA6IHRydWUsXHRcdFx0XHRcdFx0XHRcdC8vWydob2xkJywgNTAwXSwgLy8gNTAwbXMgZGVsYXlcdFx0XHRcdC8vIEZpeEluOiA5LjIuMS41LlxyXG5cdFx0XHRcdFx0YXBwZW5kVG86ICgpID0+IGRvY3VtZW50LmJvZHksXHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0cmV0dXJuICB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiAgZmFsc2U7XHJcblx0fVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT0gIERhdGVzIEZ1bmN0aW9ucyAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4vKipcclxuICogR2V0IG51bWJlciBvZiBkYXRlcyBiZXR3ZWVuIDIgSlMgRGF0ZXNcclxuICpcclxuICogQHBhcmFtIGRhdGUxXHRcdEpTIERhdGVcclxuICogQHBhcmFtIGRhdGUyXHRcdEpTIERhdGVcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZGF0ZXNfX2RheXNfYmV0d2VlbihkYXRlMSwgZGF0ZTIpIHtcclxuXHJcbiAgICAvLyBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpbiBvbmUgZGF5XHJcbiAgICB2YXIgT05FX0RBWSA9IDEwMDAgKiA2MCAqIDYwICogMjQ7XHJcblxyXG4gICAgLy8gQ29udmVydCBib3RoIGRhdGVzIHRvIG1pbGxpc2Vjb25kc1xyXG4gICAgdmFyIGRhdGUxX21zID0gZGF0ZTEuZ2V0VGltZSgpO1xyXG4gICAgdmFyIGRhdGUyX21zID0gZGF0ZTIuZ2V0VGltZSgpO1xyXG5cclxuICAgIC8vIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiBtaWxsaXNlY29uZHNcclxuICAgIHZhciBkaWZmZXJlbmNlX21zID0gIGRhdGUxX21zIC0gZGF0ZTJfbXM7XHJcblxyXG4gICAgLy8gQ29udmVydCBiYWNrIHRvIGRheXMgYW5kIHJldHVyblxyXG4gICAgcmV0dXJuIE1hdGgucm91bmQoZGlmZmVyZW5jZV9tcy9PTkVfREFZKTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBDaGVjayAgaWYgdGhpcyBhcnJheSAgb2YgZGF0ZXMgaXMgY29uc2VjdXRpdmUgYXJyYXkgIG9mIGRhdGVzIG9yIG5vdC5cclxuICogXHRcdGUuZy4gIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTMwJ10gLT4gZmFsc2VcclxuICogXHRcdGUuZy4gIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTAnLCcyMDI0LTA1LTExJ10gLT4gdHJ1ZVxyXG4gKiBAcGFyYW0gc3FsX2RhdGVzX2Fyclx0IGFycmF5XHRcdGUuZy46IFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTMwJ11cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2RhdGVzX19pc19jb25zZWN1dGl2ZV9kYXRlc19hcnJfcmFuZ2UoIHNxbF9kYXRlc19hcnIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNTAuXHJcblxyXG5cdGlmICggc3FsX2RhdGVzX2Fyci5sZW5ndGggPiAxICl7XHJcblx0XHR2YXIgcHJldmlvc19kYXRlID0gd3BiY19fZ2V0X19qc19kYXRlKCBzcWxfZGF0ZXNfYXJyWyAwIF0gKTtcclxuXHRcdHZhciBjdXJyZW50X2RhdGU7XHJcblxyXG5cdFx0Zm9yICggdmFyIGkgPSAxOyBpIDwgc3FsX2RhdGVzX2Fyci5sZW5ndGg7IGkrKyApe1xyXG5cdFx0XHRjdXJyZW50X2RhdGUgPSB3cGJjX19nZXRfX2pzX2RhdGUoIHNxbF9kYXRlc19hcnJbaV0gKTtcclxuXHJcblx0XHRcdGlmICggd3BiY19kYXRlc19fZGF5c19iZXR3ZWVuKCBjdXJyZW50X2RhdGUsIHByZXZpb3NfZGF0ZSApICE9IDEgKXtcclxuXHRcdFx0XHRyZXR1cm4gIGZhbHNlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRwcmV2aW9zX2RhdGUgPSBjdXJyZW50X2RhdGU7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdHJ1ZTtcclxufVxyXG5cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4vKiAgPT
34110gIEF1dG8gRGF0ZXMgU2VsZWN0aW9uICA9PVxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHJcbi8qKlxyXG4gKiAgPT0gSG93IHRvICB1c2UgPyA9PVxyXG4gKlxyXG4gKiAgRm9yIERhdGVzIHNlbGVjdGlvbiwgd2UgbmVlZCB0byB1c2UgdGhpcyBsb2dpYyEgICAgIFdlIG5lZWQgc2VsZWN0IHRoZSBkYXRlcyBvbmx5IGFmdGVyIGJvb2tpbmcgZGF0YSBsb2FkZWQhXHJcbiAqXHJcbiAqICBDaGVjayBleGFtcGxlIGJlbGxvdy5cclxuICpcclxuICpcdC8vIEZpcmUgb24gYWxsIGJvb2tpbmcgZGF0ZXMgbG9hZGVkXHJcbiAqXHRqUXVlcnkoICdib2R5JyApLm9uKCAnd3BiY19jYWxlbmRhcl9hanhfX2xvYWRlZF9kYXRhJywgZnVuY3Rpb24gKCBldmVudCwgbG9hZGVkX3Jlc291cmNlX2lkICl7XHJcbiAqXHJcbiAqXHRcdGlmICggbG9hZGVkX3Jlc291cmNlX2lkID09IHNlbGVjdF9kYXRlc19pbl9jYWxlbmRhcl9pZCApe1xyXG4gKlx0XHRcdHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHNlbGVjdF9kYXRlc19pbl9jYWxlbmRhcl9pZCwgJzIwMjQtMDUtMTUnLCAnMjAyNC0wNS0yNScgKTtcclxuICpcdFx0fVxyXG4gKlx0fSApO1xyXG4gKlxyXG4gKi9cclxuXHJcblxyXG4vKipcclxuICogVHJ5IHRvIEF1dG8gc2VsZWN0IGRhdGVzIGluIHNwZWNpZmljIGNhbGVuZGFyIGJ5IHNpbXVsYXRlZCBjbGlja3MgaW4gZGF0ZXBpY2tlclxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcdFx0MVxyXG4gKiBAcGFyYW0gY2hlY2tfaW5feW1kXHRcdCcyMDI0LTA1LTA5J1x0XHRPUiAgXHRbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0yMCddXHJcbiAqIEBwYXJhbSBjaGVja19vdXRfeW1kXHRcdCcyMDI0LTA1LTE1J1x0XHRPcHRpb25hbFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVx0XHRudW1iZXIgb2Ygc2VsZWN0ZWQgZGF0ZXNcclxuICpcclxuICogXHRFeGFtcGxlIDE6XHRcdFx0XHR2YXIgbnVtX3NlbGVjdGVkX2RheXMgPSB3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyKCAxLCAnMjAyNC0wNS0xNScsICcyMDI0LTA1LTI1JyApO1xyXG4gKiBcdEV4YW1wbGUgMjpcdFx0XHRcdHZhciBudW1fc2VsZWN0ZWRfZGF5cyA9IHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIDEsIFsnMjAyNC0wNS0wOScsJzIwMjQtMDUtMTknLCcyMDI0LTA1LTIwJ10gKTtcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfYXV0b19zZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXIoIHJlc291cmNlX2lkLCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgPSAnJyApe1x0XHRcdFx0XHRcdFx0XHQvLyBGaXhJbjogMTAuMC4wLjQ3LlxyXG5cclxuXHRjb25zb2xlLmxvZyggJ1dQQkNfQVVUT19TRUxFQ1RfREFURVNfSU5fQ0FMRU5EQVIoIFJFU09VUkNFX0lELCBDSEVDS19JTl9ZTUQsIENIRUNLX09VVF9ZTUQgKScsIHJlc291cmNlX2lkLCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgKTtcclxuXHJcblx0aWYgKFxyXG5cdFx0ICAgKCAnMjEwMC0wMS0wMScgPT0gY2hlY2tfaW5feW1kIClcclxuXHRcdHx8ICggJzIxMDAtMDEtMDEnID09IGNoZWNrX291dF95bWQgKVxyXG5cdFx0fHwgKCAoICcnID09IGNoZWNrX2luX3ltZCApICYmICggJycgPT0gY2hlY2tfb3V0X3ltZCApIClcclxuXHQpe1xyXG5cdFx0cmV0dXJuIDA7XHJcblx0fVxyXG5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdC8vIElmIFx0Y2hlY2tfaW5feW1kICA9ICBbICcyMDI0LTA1LTA5JywnMjAyNC0wNS0xOScsJzIwMjQtMDUtMzAnIF1cdFx0XHRcdEFSUkFZIG9mIERBVEVTXHRcdFx0XHRcdFx0Ly8gRml4SW46IDEwLjAuMC41MC5cclxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cdHZhciBkYXRlc190b19zZWxlY3RfYXJyID0gW107XHJcblx0aWYgKCBBcnJheS5pc0FycmF5KCBjaGVja19pbl95bWQgKSApe1xyXG5cdFx0ZGF0ZXNfdG9fc2VsZWN0X2FyciA9IHdwYmNfY2xvbmVfb2JqKCBjaGVja19pbl95bWQgKTtcclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0XHQvLyBFeGNlcHRpb25zIHRvICBzZXQgIFx0TVVMVElQTEUgREFZUyBcdG1vZGVcclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vIGlmIGRhdGVzIGFzIE5PVCBDT05TRUNVVElWRTogWycyMDI0LTA1LTA5JywnMjAyNC0wNS0xOScsJzIwMjQtMDUtMzAnXSwgLT4gc2V0IE1VTFRJUExFIERBWVMgbW9kZVxyXG5cdFx0aWYgKFxyXG5cdFx0XHQgICAoIGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoID4gMCApXHJcblx0XHRcdCYmICggJycgPT0gY2hlY2tfb3V0X3ltZCApXHJcblx0XHRcdCYmICggISB3cGJjX2RhdGVzX19pc19jb25zZWN1dGl2ZV9kYXRlc19hcnJfcmFuZ2UoIGRhdGVzX3RvX3NlbGVjdF9hcnIgKSApXHJcblx0XHQpe1xyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fbXVsdGlwbGUoIHJlc291cmNlX2lkICk7XHJcblx0XHR9XHJcblx0XHQvLyBpZiBtdWx0aXBsZSBkYXlzIHRvIHNlbGVjdCwgYnV0IGVuYWJsZWQgU0lOR0xFIGRheSBtb2RlLCAtPiBzZXQgTVVMVElQTEUgREFZUyBtb2RlXHJcblx0XHRpZiAoXHJcblx0XHRcdCAgICggZGF0ZXNfdG9fc2VsZWN0X2Fyci5sZW5ndGggPiAxIClcclxuXHRcdFx0JiYgKCAnJyA9PSBjaGVja19vdXRfeW1kIClcclxuXHRcdFx0JiYgKCAnc2luZ2xlJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApIClcclxuXHRcdCl7XHJcblx0XHRcdHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKTtcclxuXHRcdH1cclxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdGNoZWNrX2luX3ltZCA9IGRhdGVzX3RvX3NlbGVjdF9hcnJbIDAgXTtcclxuXHRcdGlmICggJycgPT0gY2hlY2tfb3V0X3ltZCApe1xyXG5cdFx0XHRjaGVja19vdXRfeW1kID0gZGF0ZXNfdG9fc2VsZWN0X2FyclsgKGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoLTEpIF07XHJcblx0XHR9XHJcblx0fVxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cclxuXHRpZiAoICcnID09IGNoZWNrX2luX3ltZCApe1xyXG5cdFx0Y2hlY2tfaW5feW1kID0gY2hlY2tfb3V0X3ltZDtcclxuXHR9XHJcblx0aWYgKCAnJyA9PSBjaGVja19vdXRfeW1kICl7XHJcblx0XHRjaGVja19vdXRfeW1kID0gY2hlY2tfaW5feW1kO1xyXG5cdH1cclxuXHJcblx0aWYgKCAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIChyZXNvdXJjZV9pZCkgKXtcclxuXHRcdHJlc291cmNlX2lkID0gJzEnO1xyXG5cdH1cclxuXHJcblxyXG5cdHZhciBpbnN0ID0gd3BiY19jYWxlbmRhcl9fZ2V0X2luc3QoIHJlc291cmNlX2lkICk7XHJcblxyXG5cdGlmICggbnVsbCAhPT0gaW5zdCApe1xyXG5cclxuXHRcdC8vIFVuc2VsZWN0IGFsbCBkYXRlcyBhbmQgc2V0ICBwcm9wZXJ0aWVzIG9mIERhdGVwaWNrXHJcblx0XHRqUXVlcnkoICcjZGF0ZV9ib29raW5nJyArIHJlc291cmNlX2lkICkudmFsKCAnJyApOyAgICAgIFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvL0ZpeEluOiA1LjQuM1xyXG5cdFx0aW5zdC5zdGF5T3BlbiA9IGZ
3411hbHNlO1xyXG5cdFx0aW5zdC5kYXRlcyA9IFtdO1xyXG5cdFx0dmFyIGNoZWNrX2luX2pzID0gd3BiY19fZ2V0X19qc19kYXRlKCBjaGVja19pbl95bWQgKTtcclxuXHRcdHZhciB0ZF9jZWxsICAgICA9IHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGluc3QuaWQsIGNoZWNrX2luX2pzICk7XHJcblxyXG5cdFx0Ly8gSXMgb21lIHR5cGUgb2YgZXJyb3IsIHRoZW4gc2VsZWN0IG11bHRpcGxlIGRheXMgc2VsZWN0aW9uICBtb2RlLlxyXG5cdFx0aWYgKCAnJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApICkge1xyXG4gXHRcdFx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJywgJ211bHRpcGxlJyApO1xyXG5cdFx0fVxyXG5cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBEWU5BTUlDID09XHJcblx0XHRpZiAoICdkeW5hbWljJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApICl7XHJcblx0XHRcdC8vIDEtc3QgY2xpY2tcclxuXHRcdFx0aW5zdC5zdGF5T3BlbiA9IGZhbHNlO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERheSggdGRfY2VsbCwgJyMnICsgaW5zdC5pZCwgY2hlY2tfaW5fanMuZ2V0VGltZSgpICk7XHJcblx0XHRcdGlmICggMCA9PT0gaW5zdC5kYXRlcy5sZW5ndGggKXtcclxuXHRcdFx0XHRyZXR1cm4gMDsgIFx0XHRcdFx0XHRcdFx0XHQvLyBGaXJzdCBjbGljayAgd2FzIHVuc3VjY2Vzc2Z1bCwgc28gd2UgbXVzdCBub3QgbWFrZSBvdGhlciBjbGlja1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyAyLW5kIGNsaWNrXHJcblx0XHRcdHZhciBjaGVja19vdXRfanMgPSB3cGJjX19nZXRfX2pzX2RhdGUoIGNoZWNrX291dF95bWQgKTtcclxuXHRcdFx0dmFyIHRkX2NlbGxfb3V0ID0gd3BiY19nZXRfY2xpY2tlZF90ZCggaW5zdC5pZCwgY2hlY2tfb3V0X2pzICk7XHJcblx0XHRcdGluc3Quc3RheU9wZW4gPSB0cnVlO1xyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERheSggdGRfY2VsbF9vdXQsICcjJyArIGluc3QuaWQsIGNoZWNrX291dF9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBGSVhFRCA9PVxyXG5cdFx0aWYgKCAgJ2ZpeGVkJyA9PT0gX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkYXlzX3NlbGVjdF9tb2RlJyApKSB7XHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fc2VsZWN0RGF5KCB0ZF9jZWxsLCAnIycgKyBpbnN0LmlkLCBjaGVja19pbl9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBTSU5HTEUgPT1cclxuXHRcdGlmICggJ3NpbmdsZScgPT09IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZGF5c19zZWxlY3RfbW9kZScgKSApe1xyXG5cdFx0XHQvL2pRdWVyeS5kYXRlcGljay5fcmVzdHJpY3RNaW5NYXgoIGluc3QsIGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggaW5zdCwgY2hlY2tfaW5fanMsIG51bGwgKSApO1x0XHQvLyBEbyB3ZSBuZWVkIHRvIHJ1biAgdGhpcyA/IFBsZWFzZSBub3RlLCBjaGVja19pbl9qcyBtdXN0ICBoYXZlIHRpbWUsICBtaW4sIHNlYyBkZWZpbmVkIHRvIDAhXHJcblx0XHRcdGpRdWVyeS5kYXRlcGljay5fc2VsZWN0RGF5KCB0ZF9jZWxsLCAnIycgKyBpbnN0LmlkLCBjaGVja19pbl9qcy5nZXRUaW1lKCkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdC8vICA9PSBNVUxUSVBMRSA9PVxyXG5cdFx0aWYgKCAnbXVsdGlwbGUnID09PSBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2RheXNfc2VsZWN0X21vZGUnICkgKXtcclxuXHJcblx0XHRcdHZhciBkYXRlc19hcnI7XHJcblxyXG5cdFx0XHRpZiAoIGRhdGVzX3RvX3NlbGVjdF9hcnIubGVuZ3RoID4gMCApe1xyXG5cdFx0XHRcdC8vIFNpdHVhdGlvbiwgd2hlbiB3ZSBoYXZlIGRhdGVzIGFycmF5OiBbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0zMCddLiAgYW5kIG5vdCB0aGUgQ2hlY2sgSW4gLyBDaGVjayAgb3V0IGRhdGVzIGFzIHBhcmFtZXRlciBpbiB0aGlzIGZ1bmN0aW9uXHJcblx0XHRcdFx0ZGF0ZXNfYXJyID0gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fYXJyKCBkYXRlc190b19zZWxlY3RfYXJyICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0ZGF0ZXNfYXJyID0gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0KCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQsIGluc3QgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCAwID09PSBkYXRlc19hcnIuZGF0ZXNfanMubGVuZ3RoICl7XHJcblx0XHRcdFx0cmV0dXJuIDA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEZvciBDYWxlbmRhciBEYXlzIHNlbGVjdGlvblxyXG5cdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCBkYXRlc19hcnIuZGF0ZXNfanMubGVuZ3RoOyBqKysgKXsgICAgICAgLy8gTG9vcCBhcnJheSBvZiBkYXRlc1xyXG5cclxuXHRcdFx0XHR2YXIgc3RyX2RhdGUgPSB3cGJjX19nZXRfX3NxbF9jbGFzc19kYXRlKCBkYXRlc19hcnIuZGF0ZXNfanNbIGogXSApO1xyXG5cclxuXHRcdFx0XHQvLyBEYXRlIHVuYXZhaWxhYmxlICFcclxuXHRcdFx0XHRpZiAoIDAgPT0gX3dwYmMuYm9va2luZ3NfaW5fY2FsZW5kYXJfX2dldF9mb3JfZGF0ZSggcmVzb3VyY2VfaWQsIHN0cl9kYXRlICkuZGF5X2F2YWlsYWJpbGl0eSApe1xyXG5cdFx0XHRcdFx0cmV0dXJuIDA7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIGRhdGVzX2Fyci5kYXRlc19qc1sgaiBdICE9IC0xICkge1xyXG5cdFx0XHRcdFx0aW5zdC5kYXRlcy5wdXNoKCBkYXRlc19hcnIuZGF0ZXNfanNbIGogXSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dmFyIGNoZWNrX291dF9kYXRlID0gZGF0ZXNfYXJyLmRhdGVzX2pzWyAoZGF0ZXNfYXJyLmRhdGVzX2pzLmxlbmd0aCAtIDEpIF07XHJcblxyXG5cdFx0XHRpbnN0LmRhdGVzLnB1c2goIGNoZWNrX291dF9kYXRlICk7IFx0XHRcdC8vIE5lZWQgYWRkIG9uZSBhZGRpdGlvbmFsIFNBTUUgZGF0ZSBmb3IgY29ycmVjdCAgd29ya3Mgb2YgZGF0ZXMgc2VsZWN0aW9uICEhISEhXHJcblxyXG5cdFx0XHR2YXIgY2hlY2tvdXRfdGltZXN0YW1wID0gY2hlY2tfb3V0X2RhdGUuZ2V0VGltZSgpO1xyXG5cdFx0XHR2YXIgdGRfY2VsbCA9IHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGluc3QuaWQsIGNoZWNrX291dF9kYXRlICk7XHJcblxyXG5cdFx0XHRqUXVlcnkuZGF0ZXBpY2suX3NlbGVjdERhe
3411SggdGRfY2VsbCwgJyMnICsgaW5zdC5pZCwgY2hlY2tvdXRfdGltZXN0YW1wICk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdGlmICggMCAhPT0gaW5zdC5kYXRlcy5sZW5ndGggKXtcclxuXHRcdFx0Ly8gU2Nyb2xsIHRvIHNwZWNpZmljIG1vbnRoLCBpZiB3ZSBzZXQgZGF0ZXMgaW4gc29tZSBmdXR1cmUgbW9udGhzXHJcblx0XHRcdHdwYmNfY2FsZW5kYXJfX3Njcm9sbF90byggcmVzb3VyY2VfaWQsIGluc3QuZGF0ZXNbIDAgXS5nZXRGdWxsWWVhcigpLCBpbnN0LmRhdGVzWyAwIF0uZ2V0TW9udGgoKSsxICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGluc3QuZGF0ZXMubGVuZ3RoO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIDA7XHJcbn1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IEhUTUwgdGQgZWxlbWVudCAod2hlcmUgd2FzIGNsaWNrIGluIGNhbGVuZGFyICBkYXkgIGNlbGwpXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gY2FsZW5kYXJfaHRtbF9pZFx0XHRcdCdjYWxlbmRhcl9ib29raW5nMSdcclxuXHQgKiBAcGFyYW0gZGF0ZV9qc1x0XHRcdFx0XHRKUyBEYXRlXHJcblx0ICogQHJldHVybnMgeyp8alF1ZXJ5fVx0XHRcdFx0RG9tIEhUTUwgdGQgZWxlbWVudFxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X2NsaWNrZWRfdGQoIGNhbGVuZGFyX2h0bWxfaWQsIGRhdGVfanMgKXtcclxuXHJcblx0ICAgIHZhciB0ZF9jZWxsID0galF1ZXJ5KCAnIycgKyBjYWxlbmRhcl9odG1sX2lkICsgJyAuc3FsX2RhdGVfJyArIHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVfanMgKSApLmdldCggMCApO1xyXG5cclxuXHRcdHJldHVybiB0ZF9jZWxsO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGFycmF5cyBvZiBKUyBhbmQgU1FMIGRhdGVzIGFzIGRhdGVzIGFycmF5XHJcblx0ICpcclxuXHQgKiBAcGFyYW0gY2hlY2tfaW5feW1kXHRcdFx0XHRcdFx0XHQnMjAyNC0wNS0xNSdcclxuXHQgKiBAcGFyYW0gY2hlY2tfb3V0X3ltZFx0XHRcdFx0XHRcdFx0JzIwMjQtMDUtMjUnXHJcblx0ICogQHBhcmFtIGluc3RcdFx0XHRcdFx0XHRcdFx0XHREYXRlcGljayBJbnN0LiBVc2Ugd3BiY19jYWxlbmRhcl9fZ2V0X2luc3QoIHJlc291cmNlX2lkICk7XHJcblx0ICogQHJldHVybnMge3tkYXRlc19qczogKltdLCBkYXRlc19zdHI6ICpbXX19XHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfc2VsZWN0aW9uX2RhdGVzX2pzX3N0cl9hcnJfX2Zyb21fY2hlY2tfaW5fb3V0KCBjaGVja19pbl95bWQsIGNoZWNrX291dF95bWQgLCBpbnN0ICl7XHJcblxyXG5cdFx0dmFyIG9yaWdpbmFsX2FycmF5ID0gW107XHJcblx0XHR2YXIgZGF0ZTtcclxuXHRcdHZhciBia19kaXN0aW5jdF9kYXRlcyA9IFtdO1xyXG5cclxuXHRcdHZhciBjaGVja19pbl9kYXRlID0gY2hlY2tfaW5feW1kLnNwbGl0KCAnLScgKTtcclxuXHRcdHZhciBjaGVja19vdXRfZGF0ZSA9IGNoZWNrX291dF95bWQuc3BsaXQoICctJyApO1xyXG5cclxuXHRcdGRhdGUgPSBuZXcgRGF0ZSgpO1xyXG5cdFx0ZGF0ZS5zZXRGdWxsWWVhciggY2hlY2tfaW5fZGF0ZVsgMCBdLCAoY2hlY2tfaW5fZGF0ZVsgMSBdIC0gMSksIGNoZWNrX2luX2RhdGVbIDIgXSApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblx0XHR2YXIgb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZSA9IGRhdGU7XHJcblx0XHRvcmlnaW5hbF9hcnJheS5wdXNoKCBqUXVlcnkuZGF0ZXBpY2suX3Jlc3RyaWN0TWluTWF4KCBpbnN0LCBqUXVlcnkuZGF0ZXBpY2suX2RldGVybWluZURhdGUoIGluc3QsIGRhdGUsIG51bGwgKSApICk7IC8vYWRkIGRhdGVcclxuXHRcdGlmICggISB3cGJjX2luX2FycmF5KCBia19kaXN0aW5jdF9kYXRlcywgKGNoZWNrX2luX2RhdGVbIDIgXSArICcuJyArIGNoZWNrX2luX2RhdGVbIDEgXSArICcuJyArIGNoZWNrX2luX2RhdGVbIDAgXSkgKSApe1xyXG5cdFx0XHRia19kaXN0aW5jdF9kYXRlcy5wdXNoKCBwYXJzZUludChjaGVja19pbl9kYXRlWyAyIF0pICsgJy4nICsgcGFyc2VJbnQoY2hlY2tfaW5fZGF0ZVsgMSBdKSArICcuJyArIGNoZWNrX2luX2RhdGVbIDAgXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBkYXRlX291dCA9IG5ldyBEYXRlKCk7XHJcblx0XHRkYXRlX291dC5zZXRGdWxsWWVhciggY2hlY2tfb3V0X2RhdGVbIDAgXSwgKGNoZWNrX291dF9kYXRlWyAxIF0gLSAxKSwgY2hlY2tfb3V0X2RhdGVbIDIgXSApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHllYXIsIG1vbnRoLCBkYXRlXHJcblx0XHR2YXIgb3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUgPSBkYXRlX291dDtcclxuXHJcblx0XHR2YXIgbWV3RGF0ZSA9IG5ldyBEYXRlKCBvcmlnaW5hbF9jaGVja19pbl9kYXRlLmdldEZ1bGxZZWFyKCksIG9yaWdpbmFsX2NoZWNrX2luX2RhdGUuZ2V0TW9udGgoKSwgb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZS5nZXREYXRlKCkgKTtcclxuXHRcdG1ld0RhdGUuc2V0RGF0ZSggb3JpZ2luYWxfY2hlY2tfaW5fZGF0ZS5nZXREYXRlKCkgKyAxICk7XHJcblxyXG5cdFx0d2hpbGUgKFxyXG5cdFx0XHQob3JpZ2luYWxfY2hlY2tfb3V0X2RhdGUgPiBkYXRlKSAmJlxyXG5cdFx0XHQob3JpZ2luYWxfY2hlY2tfaW5fZGF0ZSAhPSBvcmlnaW5hbF9jaGVja19vdXRfZGF0ZSkgKXtcclxuXHRcdFx0ZGF0ZSA9IG5ldyBEYXRlKCBtZXdEYXRlLmdldEZ1bGxZZWFyKCksIG1ld0RhdGUuZ2V0TW9udGgoKSwgbWV3RGF0ZS5nZXREYXRlKCkgKTtcclxuXHJcblx0XHRcdG9yaWdpbmFsX2FycmF5LnB1c2goIGpRdWVyeS5kYXRlcGljay5fcmVzdHJpY3RNaW5NYXgoIGluc3QsIGpRdWVyeS5kYXRlcGljay5fZGV0ZXJtaW5lRGF0ZSggaW5zdCwgZGF0ZSwgbnVsbCApICkgKTsgLy9hZGQgZGF0ZVxyXG5cdFx0XHRpZiAoICF3cGJjX2luX2FycmF5KCBia19kaXN0aW5jdF9kYXRlcywgKGRhdGUuZ2V0RGF0ZSgpICsgJy4nICsgcGFyc2VJbnQoIGRhdGUuZ2V0TW9udGgoKSArIDEgKSArICcuJyArIGRhdGUuZ2V0RnVsbFllYXIoKSkgKSApe1xyXG5cdFx0XHRcdGJrX2Rpc3RpbmN0X2RhdGVzLnB1c2goIChwYXJzZUludChkYXRlLmdldERhdGUoKSkgKyAnLicgKyBwYXJzZUludCggZGF0ZS5nZXRNb250aCgpICsgMSApICsgJy4nICsgZGF0ZS5nZXRGdWxsWWVhcigpKSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRtZXdEYXRlID0gbmV3IERhdGUoIGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSApO1xyXG5cdFx0XHRtZXdEYXRlLnNldERhdGUoIG1ld0RhdGUuZ2V0RGF0ZSgpICsgMSApO1xyXG5cdFx0fVxyXG5cdFx0b3JpZ2luYWxfYXJyYXkucG9wKCk7XHJcblx0XHRia19kaXN0aW5jdF9kYXRlcy5wb3AoKTtcclxuXHJcblx0XHRyZXR1cm4geydkYXRlc19qcyc6IG9yaWdpbmFsX2FycmF5LCAnZGF0ZXNfc3RyJzogYmtfZGlzdGluY3RfZGF0ZXN9O1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IGFycmF5cyBvZiBKUyBhbmQgU1FMIGRhdGVzIGFzIGRhdGVzIGFycmF5XHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0ZXNfdG9fc2VsZWN0X2Fyclx0PSBbJzIwMjQtMDUtMDknLCcyMDI0LTA1LTE5JywnMjAyNC0wNS0zMCddXHJcblx0ICpcclxuXHQgKiBAcmV0dXJucyB7e2RhdGVzX2pzOiAqW10sIGRhdGVzX3N0cjogKltdfX1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2dldF9zZWxlY3Rpb25fZGF0ZXNfanNfc3RyX2Fycl9fZnJvbV9hcnIoIGRhdGVzX3RvX3NlbGVjdF9hcnIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNTAuXHJcblxyXG5cdFx0dmFyIG9yaWdpbmFsX2FycmF5ICAgID0gW107XHJcblx0XHR2YXIgYmtfZGlzdGluY3RfZGF0ZXMgPSBbXTtcclxuXHRcdHZhciBvbmVfZGF0ZV9zdHI7XHJcblxyXG5cdFx0Zm9yICggdmFyIGQgPSAwOyBkIDwgZGF0ZXNfdG9fc2VsZWN0X2Fyci5sZW5ndGg7IGQrKyApe1
3411xyXG5cclxuXHRcdFx0b3JpZ2luYWxfYXJyYXkucHVzaCggd3BiY19fZ2V0X19qc19kYXRlKCBkYXRlc190b19zZWxlY3RfYXJyWyBkIF0gKSApO1xyXG5cclxuXHRcdFx0b25lX2RhdGVfc3RyID0gZGF0ZXNfdG9fc2VsZWN0X2FyclsgZCBdLnNwbGl0KCctJylcclxuXHRcdFx0aWYgKCAhIHdwYmNfaW5fYXJyYXkoIGJrX2Rpc3RpbmN0X2RhdGVzLCAob25lX2RhdGVfc3RyWyAyIF0gKyAnLicgKyBvbmVfZGF0ZV9zdHJbIDEgXSArICcuJyArIG9uZV9kYXRlX3N0clsgMCBdKSApICl7XHJcblx0XHRcdFx0YmtfZGlzdGluY3RfZGF0ZXMucHVzaCggcGFyc2VJbnQob25lX2RhdGVfc3RyWyAyIF0pICsgJy4nICsgcGFyc2VJbnQob25lX2RhdGVfc3RyWyAxIF0pICsgJy4nICsgb25lX2RhdGVfc3RyWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB7J2RhdGVzX2pzJzogb3JpZ2luYWxfYXJyYXksICdkYXRlc19zdHInOiBvcmlnaW5hbF9hcnJheX07XHJcblx0fVxyXG5cclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbi8qICA9PSAgQXV0byBGaWxsIEZpZWxkcyAvIEF1dG8gU2VsZWN0IERhdGVzICA9PVxyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cclxuXHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblxyXG5cdHZhciB1cmxfcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyggd2luZG93LmxvY2F0aW9uLnNlYXJjaCApO1xyXG5cclxuXHQvLyBEaXNhYmxlIGRheXMgc2VsZWN0aW9uICBpbiBjYWxlbmRhciwgIGFmdGVyICByZWRpcmVjdGlvbiAgZnJvbSAgdGhlIFwiU2VhcmNoIHJlc3VsdHMgcGFnZSwgIGFmdGVyICBzZWFyY2ggIGF2YWlsYWJpbGl0eVwiIFx0XHRcdC8vIEZpeEluOiA4LjguMi4zLlxyXG5cdGlmICAoICdPbicgIT0gX3dwYmMuZ2V0X290aGVyX3BhcmFtKCAnaXNfZW5hYmxlZF9ib29raW5nX3NlYXJjaF9yZXN1bHRzX2RheXNfc2VsZWN0JyApICkge1xyXG5cdFx0aWYgKFxyXG5cdFx0XHQoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19zZWxlY3RfY2hlY2tfaW4nICkgKSAmJlxyXG5cdFx0XHQoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19zZWxlY3RfY2hlY2tfb3V0JyApICkgJiZcclxuXHRcdFx0KCB1cmxfcGFyYW1zLmhhcyggJ3dwYmNfc2VsZWN0X2NhbGVuZGFyX2lkJyApIClcclxuXHRcdCl7XHJcblxyXG5cdFx0XHR2YXIgc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyX2lkID0gcGFyc2VJbnQoIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2FsZW5kYXJfaWQnICkgKTtcclxuXHJcblx0XHRcdC8vIEZpcmUgb24gYWxsIGJvb2tpbmcgZGF0ZXMgbG9hZGVkXHJcblx0XHRcdGpRdWVyeSggJ2JvZHknICkub24oICd3cGJjX2NhbGVuZGFyX2FqeF9fbG9hZGVkX2RhdGEnLCBmdW5jdGlvbiAoIGV2ZW50LCBsb2FkZWRfcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0XHRcdFx0aWYgKCBsb2FkZWRfcmVzb3VyY2VfaWQgPT0gc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyX2lkICl7XHJcblx0XHRcdFx0XHR3cGJjX2F1dG9fc2VsZWN0X2RhdGVzX2luX2NhbGVuZGFyKCBzZWxlY3RfZGF0ZXNfaW5fY2FsZW5kYXJfaWQsIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2hlY2tfaW4nICksIHVybF9wYXJhbXMuZ2V0KCAnd3BiY19zZWxlY3RfY2hlY2tfb3V0JyApICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9ICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoIHVybF9wYXJhbXMuaGFzKCAnd3BiY19hdXRvX2ZpbGwnICkgKXtcclxuXHJcblx0XHR2YXIgd3BiY19hdXRvX2ZpbGxfdmFsdWUgPSB1cmxfcGFyYW1zLmdldCggJ3dwYmNfYXV0b19maWxsJyApO1xyXG5cclxuXHRcdC8vIENvbnZlcnQgYmFjay4gICAgIFNvbWUgc3lzdGVtcyBkbyBub3QgbGlrZSBzeW1ib2wgJ34nIGluIFVSTCwgc28gIHdlIG5lZWQgdG8gcmVwbGFjZSB0byAgc29tZSBvdGhlciBzeW1ib2xzXHJcblx0XHR3cGJjX2F1dG9fZmlsbF92YWx1ZSA9IHdwYmNfYXV0b19maWxsX3ZhbHVlLnJlcGxhY2VBbGwoICdfXl8nLCAnficgKTtcclxuXHJcblx0XHR3cGJjX2F1dG9fZmlsbF9ib29raW5nX2ZpZWxkcyggd3BiY19hdXRvX2ZpbGxfdmFsdWUgKTtcclxuXHR9XHJcblxyXG59ICk7XHJcblxyXG4vKipcclxuICogQXV0b2ZpbGwgLyBzZWxlY3QgYm9va2luZyBmb3JtICBmaWVsZHMgYnkgIHZhbHVlcyBmcm9tICB0aGUgR0VUIHJlcXVlc3QgIHBhcmFtZXRlcjogP3dwYmNfYXV0b19maWxsPVxyXG4gKlxyXG4gKiBAcGFyYW0gYXV0b19maWxsX3N0clxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19hdXRvX2ZpbGxfYm9va2luZ19maWVsZHMoIGF1dG9fZmlsbF9zdHIgKXtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpeEluOiAxMC4wLjAuNDguXHJcblxyXG5cdGlmICggJycgPT0gYXV0b19maWxsX3N0ciApe1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcbi8vIGNvbnNvbGUubG9nKCAnV1BCQ19BVVRPX0ZJTExfQk9PS0lOR19GSUVMRFMoIEFVVE9fRklMTF9TVFIgKScsIGF1dG9fZmlsbF9zdHIpO1xyXG5cclxuXHR2YXIgZmllbGRzX2FyciA9IHdwYmNfYXV0b19maWxsX2Jvb2tpbmdfZmllbGRzX19wYXJzZSggYXV0b19maWxsX3N0ciApO1xyXG5cclxuXHRmb3IgKCBsZXQgaSA9IDA7IGkgPCBmaWVsZHNfYXJyLmxlbmd0aDsgaSsrICl7XHJcblx0XHRqUXVlcnkoICdbbmFtZT1cIicgKyBmaWVsZHNfYXJyWyBpIF1bICduYW1lJyBdICsgJ1wiXScgKS52YWwoIGZpZWxkc19hcnJbIGkgXVsgJ3ZhbHVlJyBdICk7XHJcblx0fVxyXG59XHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhcnNlIGRhdGEgZnJvbSAgZ2V0IHBhcmFtZXRlcjpcdD93cGJjX2F1dG9fZmlsbD12aXNpdG9yczIzMV4yfm1heF9jYXBhY2l0eTIzMV4yXHJcblx0ICpcclxuXHQgKiBAcGFyYW0gZGF0YV9zdHIgICAgICA9ICAgJ3Zpc2l0b3JzMjMxXjJ+bWF4X2NhcGFjaXR5MjMxXjInO1xyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfYXV0b19maWxsX2Jvb2tpbmdfZmllbGRzX19wYXJzZSggZGF0YV9zdHIgKXtcclxuXHJcblx0XHR2YXIgZmlsdGVyX29wdGlvbnNfYXJyID0gW107XHJcblxyXG5cdFx0dmFyIGRhdGFfYXJyID0gZGF0YV9zdHIuc3BsaXQoICd+JyApO1xyXG5cclxuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IGRhdGFfYXJyLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHR2YXIgbXlfZm9ybV9maWVsZCA9IGRhdGFfYXJyWyBqIF0uc3BsaXQoICdeJyApO1xyXG5cclxuXHRcdFx0dmFyIGZpbHRlcl9uYW1lICA9ICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChteV9mb3JtX2ZpZWxkWyAwIF0pKSA/IG15X2Zvcm1fZmllbGRbIDAgXSA6ICcnO1xyXG5cdFx0XHR2YXIgZmlsdGVyX3ZhbHVlID0gKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKG15X2Zvcm1fZmllbGRbIDEgXSkpID8gbXlfZm9ybV9maWVsZFsgMSBdIDogJyc7XHJcblxyXG5cdFx0XHRmaWx0ZXJfb3B0aW9uc19hcnIucHVzaChcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnbmFtZScgIDogZmlsdGVyX25hbWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndmFsdWUnIDogZmlsdGVyX3ZhbHVlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0ICAgKTtcclxuXHRcdH1cclxuXHRcdHJldHVybi
3411BmaWx0ZXJfb3B0aW9uc19hcnI7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBQYXJzZSBkYXRhIGZyb20gIGdldCBwYXJhbWV0ZXI6XHQ/c2VhcmNoX2dldF9fY3VzdG9tX3BhcmFtcz0uLi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBkYXRhX3N0ciAgICAgID0gICAndGV4dF5zZWFyY2hfZmllbGRfX2Rpc3BsYXlfY2hlY2tfaW5eMjMuMDUuMjAyNH50ZXh0XnNlYXJjaF9maWVsZF9fZGlzcGxheV9jaGVja19vdXReMjYuMDUuMjAyNH5zZWxlY3Rib3gtb25lXnNlYXJjaF9xdWFudGl0eV4yfnNlbGVjdGJveC1vbmVebG9jYXRpb25eU3BhaW5+c2VsZWN0Ym94LW9uZV5tYXhfY2FwYWNpdHleMn5zZWxlY3Rib3gtb25lXmFtZW5pdHlecGFya2luZ35jaGVja2JveF5zZWFyY2hfZmllbGRfX2V4dGVuZF9zZWFyY2hfZGF5c141fnN1Ym1pdF5eU2VhcmNofmhpZGRlbl5zZWFyY2hfZ2V0X19jaGVja19pbl95bWReMjAyNC0wNS0yM35oaWRkZW5ec2VhcmNoX2dldF9fY2hlY2tfb3V0X3ltZF4yMDI0LTA1LTI2fmhpZGRlbl5zZWFyY2hfZ2V0X190aW1lXn5oaWRkZW5ec2VhcmNoX2dldF9fcXVhbnRpdHleMn5oaWRkZW5ec2VhcmNoX2dldF9fZXh0ZW5kXjV+aGlkZGVuXnNlYXJjaF9nZXRfX3VzZXJzX2lkXn5oaWRkZW5ec2VhcmNoX2dldF9fY3VzdG9tX3BhcmFtc15+JztcclxuXHQgKiBAcmV0dXJucyB7Kn1cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2F1dG9fZmlsbF9zZWFyY2hfZmllbGRzX19wYXJzZSggZGF0YV9zdHIgKXtcclxuXHJcblx0XHR2YXIgZmlsdGVyX29wdGlvbnNfYXJyID0gW107XHJcblxyXG5cdFx0dmFyIGRhdGFfYXJyID0gZGF0YV9zdHIuc3BsaXQoICd+JyApO1xyXG5cclxuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IGRhdGFfYXJyLmxlbmd0aDsgaisrICl7XHJcblxyXG5cdFx0XHR2YXIgbXlfZm9ybV9maWVsZCA9IGRhdGFfYXJyWyBqIF0uc3BsaXQoICdeJyApO1xyXG5cclxuXHRcdFx0dmFyIGZpbHRlcl90eXBlICA9ICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIChteV9mb3JtX2ZpZWxkWyAwIF0pKSA/IG15X2Zvcm1fZmllbGRbIDAgXSA6ICcnO1xyXG5cdFx0XHR2YXIgZmlsdGVyX25hbWUgID0gKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgKG15X2Zvcm1fZmllbGRbIDEgXSkpID8gbXlfZm9ybV9maWVsZFsgMSBdIDogJyc7XHJcblx0XHRcdHZhciBmaWx0ZXJfdmFsdWUgPSAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAobXlfZm9ybV9maWVsZFsgMiBdKSkgPyBteV9mb3JtX2ZpZWxkWyAyIF0gOiAnJztcclxuXHJcblx0XHRcdGZpbHRlcl9vcHRpb25zX2Fyci5wdXNoKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgOiBmaWx0ZXJfdHlwZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCduYW1lJyAgOiBmaWx0ZXJfbmFtZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd2YWx1ZScgOiBmaWx0ZXJfdmFsdWVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHQgICApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGZpbHRlcl9vcHRpb25zX2FycjtcclxuXHR9XHJcblxyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8qICA9PSAgQXV0byBVcGRhdGUgbnVtYmVyIG9mIG1vbnRocyBpbiBjYWxlbmRhcnMgT04gc2NyZWVuIHNpemUgY2hhbmdlZCAgPT1cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG4vKipcclxuICogQXV0byBVcGRhdGUgTnVtYmVyIG9mIE1vbnRocyBpbiBDYWxlbmRhciwgZS5nLjogIFx0XHRpZiAgICAoIFdJTkRPV19XSURUSCA8PSA3ODJweCApICAgPj4+IFx0TU9OVEhTX05VTUJFUiA9IDFcclxuICogICBFTFNFOiAgbnVtYmVyIG9mIG1vbnRocyBkZWZpbmVkIGluIHNob3J0Y29kZS5cclxuICogQHBhcmFtIHJlc291cmNlX2lkIGludFxyXG4gKlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fYXV0b191cGRhdGVfbW9udGhzX251bWJlcl9fb25fcmVzaXplKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRpZiAoIHRydWUgPT09IF93cGJjLmdldF9vdGhlcl9wYXJhbSggJ2lzX2FsbG93X3NldmVyYWxfbW9udGhzX29uX21vYmlsZScgKSApIHtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdHZhciBsb2NhbF9fbnVtYmVyX29mX21vbnRocyA9IHBhcnNlSW50KCBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2NhbGVuZGFyX251bWJlcl9vZl9tb250aHMnICkgKTtcclxuXHJcblx0aWYgKCBsb2NhbF9fbnVtYmVyX29mX21vbnRocyA+IDEgKXtcclxuXHJcblx0XHRpZiAoIGpRdWVyeSggd2luZG93ICkud2lkdGgoKSA8PSA3ODIgKXtcclxuXHRcdFx0d3BiY19jYWxlbmRhcl9fdXBkYXRlX21vbnRoc19udW1iZXIoIHJlc291cmNlX2lkLCAxICk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR3cGJjX2NhbGVuZGFyX191cGRhdGVfbW9udGhzX251bWJlciggcmVzb3VyY2VfaWQsIGxvY2FsX19udW1iZXJfb2ZfbW9udGhzICk7XHJcblx0XHR9XHJcblxyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEF1dG8gVXBkYXRlIE51bWJlciBvZiBNb250aHMgaW4gICBBTEwgICBDYWxlbmRhcnNcclxuICpcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsZW5kYXJzX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyKCl7XHJcblxyXG5cdHZhciBhbGxfY2FsZW5kYXJzX2FyciA9IF93cGJjLmNhbGVuZGFyc19hbGxfX2dldCgpO1xyXG5cclxuXHQvLyBUaGlzIExPT1AgXCJmb3IgaW5cIiBpcyBHT09ELCBiZWNhdXNlIHdlIGNoZWNrICBoZXJlIGtleXMgICAgJ2NhbGVuZGFyXycgPT09IGNhbGVuZGFyX2lkLnNsaWNlKCAwLCA5IClcclxuXHRmb3IgKCB2YXIgY2FsZW5kYXJfaWQgaW4gYWxsX2NhbGVuZGFyc19hcnIgKXtcclxuXHRcdGlmICggJ2NhbGVuZGFyXycgPT09IGNhbGVuZGFyX2lkLnNsaWNlKCAwLCA5ICkgKXtcclxuXHRcdFx0dmFyIHJlc291cmNlX2lkID0gcGFyc2VJbnQoIGNhbGVuZGFyX2lkLnNsaWNlKCA5ICkgKTtcdFx0XHQvLyAgJ2NhbGVuZGFyXzMnIC0+IDNcclxuXHRcdFx0aWYgKCByZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0XHR3cGJjX2NhbGVuZGFyX19hdXRvX3VwZGF0ZV9tb250aHNfbnVtYmVyX19vbl9yZXNpemUoIHJlc291cmNlX2lkICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJZiBicm93c2VyIHdpbmRvdyBjaGFuZ2VkLCAgdGhlbiAgdXBkYXRlIG51bWJlciBvZiBtb250aHMuXHJcbiAqL1xyXG5qUXVlcnkoIHdpbmRvdyApLm9uKCAncmVzaXplJywgZnVuY3Rpb24gKCl7XHJcblx0d3BiY19jYWxlbmRhcnNfX2F1dG9fdXBkYXRlX21vbnRoc19udW1iZXIoKTtcclxufSApO1xyXG5cclxuLyoqXHJcbiAqIEF1dG8gdXBkYXRlIGNhbGVuZGFyIG51bWJlciBvZiBtb250aHMgb24gaW5pdGlhbCBwYWdlIGxvYWRcclxuICovXHJcbmpRdWVyeSggZG9jdW1lbnQgKS5yZWFkeSggZnVuY3Rpb24gKCl7XHJcblx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cdFx0d3BiY19jYWxlbmRhcnNfX2F1dG9fdXBkYXRlX21vbnRoc19udW1iZXIoKTtcclxuXHR9LCAxM
3411DAgKTtcclxufSk7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLyogID09ICBDaGVjazogY2FsZW5kYXJfZGF0ZXNfc3RhcnQ6IFwiMjAyNi0wMS0wMVwiLCBjYWxlbmRhcl9kYXRlc19lbmQ6IFwiMjAyNi0xMi0zMVwiID09ICAvLyBGaXhJbjogMTAuMTMuMS40LlxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHQvKipcclxuXHQgKiBHZXQgU3RhcnQgSlMgRGF0ZSBvZiBzdGFydGluZyBkYXRlcyBpbiBjYWxlbmRhciwgZnJvbSB0aGUgX3dwYmMgb2JqZWN0LlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGludGVnZXIgcmVzb3VyY2VfaWQgLSByZXNvdXJjZSBJRCwgZS5nLjogMS5cclxuXHQgKi9cclxuXHRmdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfc3RhcnQoIHJlc291cmNlX2lkICkge1xyXG5cdFx0cmV0dXJuIHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlX3BhcmFtZXRlciggcmVzb3VyY2VfaWQsICdjYWxlbmRhcl9kYXRlc19zdGFydCcgKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBFbmQgSlMgRGF0ZSBvZiBlbmRpbmcgZGF0ZXMgaW4gY2FsZW5kYXIsIGZyb20gdGhlIF93cGJjIG9iamVjdC5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBpbnRlZ2VyIHJlc291cmNlX2lkIC0gcmVzb3VyY2UgSUQsIGUuZy46IDEuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVzX2VuZChyZXNvdXJjZV9pZCkge1xyXG5cdFx0cmV0dXJuIHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlX3BhcmFtZXRlciggcmVzb3VyY2VfaWQsICdjYWxlbmRhcl9kYXRlc19lbmQnICk7XHJcblx0fVxyXG5cclxuLyoqXHJcbiAqIEdldCB2YWxpZGF0ZXMgZGF0ZSBwYXJhbWV0ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZCAgIC0gMVxyXG4gKiBAcGFyYW0gcGFyYW1ldGVyX3N0ciAtICdjYWxlbmRhcl9kYXRlc19zdGFydCcgfCAnY2FsZW5kYXJfZGF0ZXNfZW5kJyB8IC4uLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxlbmRhcl9fZ2V0X2RhdGVfcGFyYW1ldGVyKHJlc291cmNlX2lkLCBwYXJhbWV0ZXJfc3RyKSB7XHJcblxyXG5cdHZhciBkYXRlX2V4cGVjdGVkX3ltZCA9IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCBwYXJhbWV0ZXJfc3RyICk7XHJcblxyXG5cdGlmICggISBkYXRlX2V4cGVjdGVkX3ltZCApIHtcclxuXHRcdHJldHVybiBmYWxzZTsgICAgICAgICAgICAgLy8gJycgfCAwIHwgbnVsbCB8IHVuZGVmaW5lZCAgLT4gZmFsc2UuXHJcblx0fVxyXG5cclxuXHRpZiAoIC0xICE9PSBkYXRlX2V4cGVjdGVkX3ltZC5pbmRleE9mKCAnLScgKSApIHtcclxuXHJcblx0XHR2YXIgZGF0ZV9leHBlY3RlZF95bWRfYXJyID0gZGF0ZV9leHBlY3RlZF95bWQuc3BsaXQoICctJyApO1x0Ly8gJzIwMjUtMDctMjYnIC0+IFsnMjAyNScsICcwNycsICcyNiddXHJcblxyXG5cdFx0aWYgKCBkYXRlX2V4cGVjdGVkX3ltZF9hcnIubGVuZ3RoID4gMCApIHtcclxuXHRcdFx0dmFyIHllYXIgID0gKGRhdGVfZXhwZWN0ZWRfeW1kX2Fyci5sZW5ndGggPiAwKSA/IHBhcnNlSW50KCBkYXRlX2V4cGVjdGVkX3ltZF9hcnJbMF0gKSA6IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcdC8vIFllYXIuXHJcblx0XHRcdHZhciBtb250aCA9IChkYXRlX2V4cGVjdGVkX3ltZF9hcnIubGVuZ3RoID4gMSkgPyAocGFyc2VJbnQoIGRhdGVfZXhwZWN0ZWRfeW1kX2FyclsxXSApIC0gMSkgOiAwOyAgLy8gKG1vbnRoIC0gMSkgb3IgMCAtIEphbi5cclxuXHRcdFx0dmFyIGRheSAgID0gKGRhdGVfZXhwZWN0ZWRfeW1kX2Fyci5sZW5ndGggPiAyKSA/IHBhcnNlSW50KCBkYXRlX2V4cGVjdGVkX3ltZF9hcnJbMl0gKSA6IDE7ICAvLyBkYXRlIG9yIE90aGVyd2lzZSAxc3Qgb2YgbW9udGhcclxuXHJcblx0XHRcdHZhciBkYXRlX2pzID0gbmV3IERhdGUoIHllYXIsIG1vbnRoLCBkYXksIDAsIDAsIDAsIDAgKTtcclxuXHJcblx0XHRcdHJldHVybiBkYXRlX2pzO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGZhbHNlOyAgLy8gRmFsbGJhY2ssICBpZiB3ZSBub3QgcGFyc2VkIHRoaXMgcGFyYW1ldGVyICAnY2FsZW5kYXJfZGF0ZXNfc3RhcnQnID0gJzIwMjUtMDctMjYnLCAgZm9yIGV4YW1wbGUgYmVjYXVzZSBvZiAnY2FsZW5kYXJfZGF0ZXNfc3RhcnQnID0gJ3Nmc2RmJy5cclxufSIsIi8qKlxyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWwvZGF5c19zZWxlY3RfY3VzdG9tLmpzXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLy8gRml4SW46IDkuOC45LjIuXHJcblxyXG4vKipcclxuICogUmUtSW5pdCBDYWxlbmRhciBhbmQgUmUtUmVuZGVyIGl0LlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX19yZV9pbml0KCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHQvLyBSZW1vdmUgQ0xBU1MgIGZvciBhYmlsaXR5IHRvIHJlLXJlbmRlciBhbmQgcmVpbml0IGNhbGVuZGFyLlxyXG5cdGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc291cmNlX2lkICkucmVtb3ZlQ2xhc3MoICdoYXNEYXRlcGljaycgKTtcclxuXHR3cGJjX2NhbGVuZGFyX3Nob3coIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUmUtSW5
3411pdCBwcmV2aW91c2x5ICBzYXZlZCBkYXlzIHNlbGVjdGlvbiAgdmFyaWFibGVzLlxyXG4gKlxyXG4gKiBAcGFyYW0gcmVzb3VyY2VfaWRcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19yZV9pbml0KCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ3NhdmVkX3ZhcmlhYmxlX19fZGF5c19zZWxlY3RfaW5pdGlhbCdcclxuXHRcdCwge1xyXG5cdFx0XHQnZHluYW1pY19fZGF5c19taW4nICAgICAgICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19taW4nICksXHJcblx0XHRcdCdkeW5hbWljX19kYXlzX21heCcgICAgICAgIDogX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX19kYXlzX21heCcgKSxcclxuXHRcdFx0J2R5bmFtaWNfX2RheXNfc3BlY2lmaWMnICAgOiBfd3BiYy5jYWxlbmRhcl9fZ2V0X3BhcmFtX3ZhbHVlKCByZXNvdXJjZV9pZCwgJ2R5bmFtaWNfX2RheXNfc3BlY2lmaWMnICksXHJcblx0XHRcdCdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JzogX3dwYmMuY2FsZW5kYXJfX2dldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JyApLFxyXG5cdFx0XHQnZml4ZWRfX2RheXNfbnVtJyAgICAgICAgICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZml4ZWRfX2RheXNfbnVtJyApLFxyXG5cdFx0XHQnZml4ZWRfX3dlZWtfZGF5c19fc3RhcnQnICA6IF93cGJjLmNhbGVuZGFyX19nZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZml4ZWRfX3dlZWtfZGF5c19fc3RhcnQnIClcclxuXHRcdH1cclxuXHQpO1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTZXQgU2luZ2xlIERheSBzZWxlY3Rpb24gLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19zaW5nbGUoIHJlc291cmNlX2lkICl7XHJcblxyXG5cdC8vIFJlLWRlZmluZSBzZWxlY3Rpb24sIG9ubHkgYWZ0ZXIgcGFnZSBsb2FkZWQgd2l0aCBhbGwgaW5pdCB2YXJzXHJcblx0alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG5cclxuXHRcdC8vIFdhaXQgMSBzZWNvbmQsIGp1c3QgdG8gIGJlIHN1cmUsIHRoYXQgYWxsIGluaXQgdmFycyBkZWZpbmVkXHJcblx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlKCByZXNvdXJjZV9pZCApO1xyXG5cclxuXHRcdH0sIDEwMDApO1xyXG5cdH0pO1xyXG59XHJcblxyXG4vKipcclxuICogU2V0IFNpbmdsZSBEYXkgc2VsZWN0aW9uXHJcbiAqIENhbiBiZSBydW4gYXQgYW55ICB0aW1lLCAgd2hlbiAgY2FsZW5kYXIgZGVmaW5lZCAtIHVzZWZ1bCBmb3IgY29uc29sZSBydW4uXHJcbiAqXHJcbiAqIEBwYXJhbSByZXNvdXJjZV9pZFx0XHRJRCBvZiBib29raW5nIHJlc291cmNlXHJcbiAqL1xyXG5mdW5jdGlvbiB3cGJjX2NhbF9kYXlzX3NlbGVjdF9fc2luZ2xlKCByZXNvdXJjZV9pZCApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2RheXNfc2VsZWN0X21vZGUnOiAnc2luZ2xlJ30gKTtcclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIFNldCBNdWx0aXBsZSBEYXlzIHNlbGVjdGlvbiAgLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0Ly8gUmUtZGVmaW5lIHNlbGVjdGlvbiwgb25seSBhZnRlciBwYWdlIGxvYWRlZCB3aXRoIGFsbCBpbml0IHZhcnNcclxuXHRqUXVlcnkoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0Ly8gV2FpdCAxIHNlY29uZCwganVzdCB0byAgYmUgc3VyZSwgdGhhdCBhbGwgaW5pdCB2YXJzIGRlZmluZWRcclxuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuXHJcblx0XHRcdHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKTtcclxuXHJcblx0XHR9LCAxMDAwKTtcclxuXHR9KTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBTZXQgTXVsdGlwbGUgRGF5cyBzZWxlY3Rpb25cclxuICogQ2FuIGJlIHJ1biBhdCBhbnkgIHRpbWUsICB3aGVuICBjYWxlbmRhciBkZWZpbmVkIC0gdXNlZnVsIGZvciBjb25zb2xlIHJ1bi5cclxuICpcclxuICogQHBhcmFtIHJlc291cmNlX2lkXHRcdElEIG9mIGJvb2tpbmcgcmVzb3VyY2VcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19tdWx0aXBsZSggcmVzb3VyY2VfaWQgKXtcclxuXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbWV0ZXJzKCByZXNvdXJjZV9pZCwgeydkYXlzX3NlbGVjdF9tb2RlJzogJ211bHRpcGxlJ30gKTtcclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTZXQgRml4ZWQgRGF5cyBzZWxlY3Rpb24gd2l0aCAgMSBtb3VzZSBjbGljayAgLSBhZnRlciBwYWdlIGxvYWRcclxuICpcclxuICogQGludGVnZXIgcmVzb3VyY2VfaWRcdFx0XHQtIDFcdFx0XHRcdCAgIC0tIElEIG9mIGJvb2tpbmcgcmVzb3VyY2UgKGNhbGVuZGFyKSAtXHJcbiAqIEBpbnRlZ2VyIGRheXNfbnVtYmVyXHRcdFx0LSAzXHRcdFx0XHQgICAtLSBudW1iZXIgb2YgZGF5cyB0byAgc2VsZWN0XHQtXHJcbiAqIEBhcnJheSB3ZWVrX2RheXNfX3N0YXJ0XHQtIFstMV0gfCBbIDEsIDVdICAgLS0gIHsgLTEgLSBBbnkgfCAwIC0gU3UsICAxIC0gTW8sICAyIC0gVHUsIDMgLSBXZSwgNCAtIFRoLCA1IC0gRnIsIDYgLSBTYXQgfVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxfcmVhZHlfZGF5c19zZWxlY3RfX2ZpeGVkKCByZXNvdXJjZV9pZCwgZGF5c19udW1iZXIsIHdlZWtfZGF5c19fc3RhcnQgPSBbLTFdICl7XHJcblxyXG5cdC8vIFJlLWRlZmluZSBzZWxlY3Rpb24sIG9ubHkgYWZ0ZXIgcGFnZSBsb2FkZWQgd2l0aCBhbGwgaW5pdCB2YXJzXHJcblx0alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpe1xyXG5cclxuXHRcdC8vIFdhaXQgMSBzZWNvbmQsIGp1c3QgdG8gIGJlIHN1cmUsIHRoYXQgYWxsIGluaXQgdmFycyBkZWZpbmVkXHJcblx0XHRzZXRUaW
34111lb3V0KGZ1bmN0aW9uKCl7XHJcblxyXG5cdFx0XHR3cGJjX2NhbF9kYXlzX3NlbGVjdF9fZml4ZWQoIHJlc291cmNlX2lkLCBkYXlzX251bWJlciwgd2Vla19kYXlzX19zdGFydCApO1xyXG5cclxuXHRcdH0sIDEwMDApO1xyXG5cdH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNldCBGaXhlZCBEYXlzIHNlbGVjdGlvbiB3aXRoICAxIG1vdXNlIGNsaWNrXHJcbiAqIENhbiBiZSBydW4gYXQgYW55ICB0aW1lLCAgd2hlbiAgY2FsZW5kYXIgZGVmaW5lZCAtIHVzZWZ1bCBmb3IgY29uc29sZSBydW4uXHJcbiAqXHJcbiAqIEBpbnRlZ2VyIHJlc291cmNlX2lkXHRcdFx0LSAxXHRcdFx0XHQgICAtLSBJRCBvZiBib29raW5nIHJlc291cmNlIChjYWxlbmRhcikgLVxyXG4gKiBAaW50ZWdlciBkYXlzX251bWJlclx0XHRcdC0gM1x0XHRcdFx0ICAgLS0gbnVtYmVyIG9mIGRheXMgdG8gIHNlbGVjdFx0LVxyXG4gKiBAYXJyYXkgd2Vla19kYXlzX19zdGFydFx0LSBbLTFdIHwgWyAxLCA1XSAgIC0tICB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX2RheXNfc2VsZWN0X19maXhlZCggcmVzb3VyY2VfaWQsIGRheXNfbnVtYmVyLCB3ZWVrX2RheXNfX3N0YXJ0ID0gWy0xXSApe1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2RheXNfc2VsZWN0X21vZGUnOiAnZml4ZWQnfSApO1xyXG5cclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2ZpeGVkX19kYXlzX251bSc6IHBhcnNlSW50KCBkYXlzX251bWJlciApfSApO1x0XHRcdC8vIE51bWJlciBvZiBkYXlzIHNlbGVjdGlvbiB3aXRoIDEgbW91c2UgY2xpY2tcclxuXHRfd3BiYy5jYWxlbmRhcl9fc2V0X3BhcmFtZXRlcnMoIHJlc291cmNlX2lkLCB7J2ZpeGVkX193ZWVrX2RheXNfX3N0YXJ0Jzogd2Vla19kYXlzX19zdGFydH0gKTsgXHQvLyB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuXHJcblx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcblx0d3BiY19jYWxfX3JlX2luaXQoIHJlc291cmNlX2lkICk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIFNldCBSYW5nZSBEYXlzIHNlbGVjdGlvbiAgd2l0aCAgMiBtb3VzZSBjbGlja3MgIC0gYWZ0ZXIgcGFnZSBsb2FkXHJcbiAqXHJcbiAqIEBpbnRlZ2VyIHJlc291cmNlX2lkXHRcdFx0LSAxXHRcdFx0XHQgICBcdFx0LS0gSUQgb2YgYm9va2luZyByZXNvdXJjZSAoY2FsZW5kYXIpXHJcbiAqIEBpbnRlZ2VyIGRheXNfbWluXHRcdFx0LSA3XHRcdFx0XHQgICBcdFx0LS0gTWluIG51bWJlciBvZiBkYXlzIHRvIHNlbGVjdFxyXG4gKiBAaW50ZWdlciBkYXlzX21heFx0XHRcdC0gMzBcdFx0XHQgICBcdFx0LS0gTWF4IG51bWJlciBvZiBkYXlzIHRvIHNlbGVjdFxyXG4gKiBAYXJyYXkgZGF5c19zcGVjaWZpY1x0XHRcdC0gW10gfCBbNywxNCwyMSwyOF1cdFx0LS0gUmVzdHJpY3Rpb24gZm9yIFNwZWNpZmljIG51bWJlciBvZiBkYXlzIHNlbGVjdGlvblxyXG4gKiBAYXJyYXkgd2Vla19kYXlzX19zdGFydFx0XHQtIFstMV0gfCBbIDEsIDVdICAgXHRcdC0tICB7IC0xIC0gQW55IHwgMCAtIFN1LCAgMSAtIE1vLCAgMiAtIFR1LCAzIC0gV2UsIDQgLSBUaCwgNSAtIEZyLCA2IC0gU2F0IH1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfY2FsX3JlYWR5X2RheXNfc2VsZWN0X19yYW5nZSggcmVzb3VyY2VfaWQsIGRheXNfbWluLCBkYXlzX21heCwgZGF5c19zcGVjaWZpYyA9IFtdLCB3ZWVrX2RheXNfX3N0YXJ0ID0gWy0xXSApe1xyXG5cclxuXHQvLyBSZS1kZWZpbmUgc2VsZWN0aW9uLCBvbmx5IGFmdGVyIHBhZ2UgbG9hZGVkIHdpdGggYWxsIGluaXQgdmFyc1xyXG5cdGpRdWVyeShkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXtcclxuXHJcblx0XHQvLyBXYWl0IDEgc2Vjb25kLCBqdXN0IHRvICBiZSBzdXJlLCB0aGF0IGFsbCBpbml0IHZhcnMgZGVmaW5lZFxyXG5cdFx0c2V0VGltZW91dChmdW5jdGlvbigpe1xyXG5cclxuXHRcdFx0d3BiY19jYWxfZGF5c19zZWxlY3RfX3JhbmdlKCByZXNvdXJjZV9pZCwgZGF5c19taW4sIGRheXNfbWF4LCBkYXlzX3NwZWNpZmljLCB3ZWVrX2RheXNfX3N0YXJ0ICk7XHJcblx0XHR9LCAxMDAwKTtcclxuXHR9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNldCBSYW5nZSBEYXlzIHNlbGVjdGlvbiAgd2l0aCAgMiBtb3VzZSBjbGlja3NcclxuICogQ2FuIGJlIHJ1biBhdCBhbnkgIHRpbWUsICB3aGVuICBjYWxlbmRhciBkZWZpbmVkIC0gdXNlZnVsIGZvciBjb25zb2xlIHJ1bi5cclxuICpcclxuICogQGludGVnZXIgcmVzb3VyY2VfaWRcdFx0XHQtIDFcdFx0XHRcdCAgIFx0XHQtLSBJRCBvZiBib29raW5nIHJlc291cmNlIChjYWxlbmRhcilcclxuICogQGludGVnZXIgZGF5c19taW5cdFx0XHQtIDdcdFx0XHRcdCAgIFx0XHQtLSBNaW4gbnVtYmVyIG9mIGRheXMgdG8gc2VsZWN0XHJcbiAqIEBpbnRlZ2VyIGRheXNfbWF4XHRcdFx0LSAzMFx0XHRcdCAgIFx0XHQtLSBNYXggbnVtYmVyIG9mIGRheXMgdG8gc2VsZWN0XHJcbiAqIEBhcnJheSBkYXlzX3NwZWNpZmljXHRcdFx0LSBbXSB8IFs3LDE0LDIxLDI4XVx0XHQtLSBSZXN0cmljdGlvbiBmb3IgU3BlY2lmaWMgbnVtYmVyIG9mIGRheXMgc2VsZWN0aW9uXHJcbiAqIEBhcnJheSB3ZWVrX2RheXNfX3N0YXJ0XHRcdC0gWy0xXSB8IFsgMSwgNV0gICBcdFx0LS0gIHsgLTEgLSBBbnkgfCAwIC0gU3UsICAxIC0gTW8sICAyIC0gVHUsIDMgLSBXZSwgNCAtIFRoLCA1IC0gRnIsIDYgLSBTYXQgfVxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19jYWxfZGF5c19zZWxlY3RfX3JhbmdlKCByZXNvdXJjZV9pZCwgZGF5c19taW4sIGRheXNfbWF4LCBkYXlzX3NwZWNpZmljID0gW10sIHdlZWtfZGF5c19fc3RhcnQgPSBbLTFdICl7XHJcblxyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1ldGVycyggIHJlc291cmNlX2lkLCB7J2R
3411heXNfc2VsZWN0X21vZGUnOiAnZHluYW1pYyd9ICApO1xyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19taW4nICAgICAgICAgLCBwYXJzZUludCggZGF5c19taW4gKSAgKTsgICAgICAgICAgIFx0XHQvLyBNaW4uIE51bWJlciBvZiBkYXlzIHNlbGVjdGlvbiB3aXRoIDIgbW91c2UgY2xpY2tzXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX19kYXlzX21heCcgICAgICAgICAsIHBhcnNlSW50KCBkYXlzX21heCApICApOyAgICAgICAgICBcdFx0Ly8gTWF4LiBOdW1iZXIgb2YgZGF5cyBzZWxlY3Rpb24gd2l0aCAyIG1vdXNlIGNsaWNrc1xyXG5cdF93cGJjLmNhbGVuZGFyX19zZXRfcGFyYW1fdmFsdWUoIHJlc291cmNlX2lkLCAnZHluYW1pY19fZGF5c19zcGVjaWZpYycgICAgLCBkYXlzX3NwZWNpZmljICApO1x0ICAgICAgXHRcdFx0XHQvLyBFeGFtcGxlIFs1LDddXHJcblx0X3dwYmMuY2FsZW5kYXJfX3NldF9wYXJhbV92YWx1ZSggcmVzb3VyY2VfaWQsICdkeW5hbWljX193ZWVrX2RheXNfX3N0YXJ0JyAsIHdlZWtfZGF5c19fc3RhcnQgICk7ICBcdFx0XHRcdFx0Ly8geyAtMSAtIEFueSB8IDAgLSBTdSwgIDEgLSBNbywgIDIgLSBUdSwgMyAtIFdlLCA0IC0gVGgsIDUgLSBGciwgNiAtIFNhdCB9XHJcblxyXG5cdHdwYmNfY2FsX2RheXNfc2VsZWN0X19yZV9pbml0KCByZXNvdXJjZV9pZCApO1xyXG5cdHdwYmNfY2FsX19yZV9pbml0KCByZXNvdXJjZV9pZCApO1xyXG59XHJcbiIsIi8qKlxyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9jYWxfYWp4X2xvYWQvd3BiY19jYWxfYWp4LmpzXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcbiAqL1xyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vICBBIGogYSB4ICAgIEwgbyBhIGQgICAgQyBhIGwgZSBuIGQgYSByICAgIEQgYSB0IGFcclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5mdW5jdGlvbiB3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCggcGFyYW1zICl7XHJcblxyXG5cdC8vIEZpeEluOiA5LjguNi4yLlxyXG5cdHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0YXJ0KCBwYXJhbXNbJ3Jlc291cmNlX2lkJ10gKTtcclxuXHJcblx0Ly8gVHJpZ2dlciBldmVudCBmb3IgY2FsZW5kYXIgYmVmb3JlIGxvYWRpbmcgQm9va2luZyBkYXRhLCAgYnV0IGFmdGVyIHNob3dpbmcgQ2FsZW5kYXIuXHJcblx0aWYgKCBqUXVlcnkoICcjY2FsZW5kYXJfYm9va2luZycgKyBwYXJhbXNbJ3Jlc291cmNlX2lkJ10gKS5sZW5ndGggPiAwICl7XHJcblx0XHR2YXIgdGFyZ2V0X2VsbSA9IGpRdWVyeSggJ2JvZHknICkudHJpZ2dlciggXCJ3cGJjX2NhbGVuZGFyX2FqeF9fYmVmb3JlX2xvYWRlZF9kYXRhXCIsIFtwYXJhbXNbJ3Jlc291cmNlX2lkJ11dICk7XHJcblx0XHQgLy9qUXVlcnkoICdib2R5JyApLm9uKCAnd3BiY19jYWxlbmRhcl9hanhfX2JlZm9yZV9sb2FkZWRfZGF0YScsIGZ1bmN0aW9uKCBldmVudCwgcmVzb3VyY2VfaWQgKSB7IC4uLiB9ICk7XHJcblx0fVxyXG5cclxuXHRpZiAoIHdwYmNfYmFsYW5jZXJfX2lzX3dhaXQoIHBhcmFtcyAsICd3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCcgKSApe1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0Ly8gRml4SW46IDkuOC42LjIuXHJcblx0d3BiY19jYWxlbmRhcl9fYmx1cl9fc3RvcCggcGFyYW1zWydyZXNvdXJjZV9pZCddICk7XHJcblxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblx0Ly8gPT0gR2V0IHN0YXJ0IC8gZW5kIGRhdGVzIGZyb20gIHRoZSBCb29raW5nIENhbGVuZGFyIHNob3J0Y29kZS4gPT1cclxuXHQvLyBFeGFtcGxlOiBbYm9va2luZyBjYWxlbmRhcl9kYXRlc19zdGFydD0nMjAyNi0wMS0wMScgY2FsZW5kYXJfZGF0ZXNfZW5kPScyMDI2LTEyLTMxJyAgcmVzb3VyY2VfaWQ9MV0gICAgICAgICAgICAgIC8vIEZpeEluOiAxMC4xMy4xLjQuXHJcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRpZiAoIGZhbHNlICE9PSB3cGJjX2NhbGVuZGFyX19nZXRfZGF0ZXNfc3RhcnQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApICkge1xyXG5cdFx0aWYgKCAhIHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXSApIHsgcGFyYW1zWydkYXRlc190b19jaGVjayddID0gW107IH1cclxuXHRcdHZhciBkYXRlc19zdGFydCA9IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19zdGFydCggcGFyYW1zWydyZXNvdXJjZV9pZCddICk7ICAvLyBFLmcuIC0gbG9jYWxfX21pbl9kYXRlID0gbmV3IERhdGUoIDIwMjUsIDAsIDEgKTtcclxuXHRcdGlmICggZmFsc2UgIT09IGRhdGVzX3N0YXJ0ICl7XHJcblx0XHRcdHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXVswXSA9IHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVzX3N0YXJ0ICk7XHJcblx0XHR9XHJcblx0fVxyXG5cdGlmICggZmFsc2UgIT09IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApICkge1xyXG5cdFx0aWYgKCAhcGFyYW1zWydkYXRlc190b19jaGVjayddICkgeyBwYXJhbXNbJ2RhdGVzX3RvX2NoZWNrJ10gPSBbXTsgfVxyXG5cdFx0dmFyIGRhdGVzX2VuZCA9IHdwYmNfY2FsZW5kYXJfX2dldF9kYXRlc19lbmQoIHBhcmFtc1sncmVzb3VyY2VfaWQnXSApOyAgLy8gRS5nLiAtIGxvY2FsX19taW5fZGF0ZSA9IG5ldyBEYXRlKCAyMDI1LCAwLCAxICk7XHJcblx0XHRpZiAoIGZhbHNlICE9PSBkYXRlc19lbmQgKSB7XHJcblx0XHRcdHBhcmFtc1snZGF0ZXNfdG9fY2hlY2snXVsxXSA9IHdwYmNfX2dldF9fc3FsX2NsYXNzX2RhdGUoIGRhdGVzX2VuZCApO1xyXG5cdFx0XHRpZiAoICFwYXJhbXNbJ2RhdGVzX3RvX2NoZWNrJ11bMF0gKSB7XHJcblx0XHRcdFx0cGFyYW1zWydkYXRlc190b19jaGVjayddWzBdID0gd3BiY19fZ2V0X19zcWxfY2xhc3NfZGF0ZSggbmV3IERhdGUoKSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4vLyBjb25zb2xlLmdyb3VwRW5kKCk7IGNvbnNvbGUudGltZSgncmVzb3VyY2VfaWRfJyArIHBhcmFtc1sncmVzb3VyY2VfaWQnXSk7XHJcbmNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQoICdXUEJDX0FKWF9DQUxFTkRBUl9MT0FEJyApOyBjb25zb2xlLmxvZyggJyA9PSBCZWZvcmUgQWpheCBTZW5kIC0gY2FsZW5kYXJzX2FsbF9fZ2V0KCkgPT0gJyAsIF93cGJjLmNhbGVuZGFyc19hbGxfX2dldCgpICk7XHJcblx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IpICkge1xyXG5cdFx0d3BiY19ob29rX19pbml0X3RpbWVzZWxlY3RvcigpO1xyXG5cdH1cclxuXHJcblx0Ly8gU3RhcnQgQWpheFxyXG5cdGpRdWVyeS5wb3N0KCB3cGJjX3VybF9hamF4LFxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGFjdGlvbiAgICAgICAgICA6ICdXUEJDX0FKWF9DQUxFTkRBUl9MT0FEJyxcclxuXHRcdFx0XHRcdHdwYmNfYWp4X3VzZXJfaWQ6IF93cGJjLmdldF9zZWN1cmVfcGFyYW0oICd1c2VyX2lkJyApLFxyXG5cdFx0XHRcdFx0bm9uY2UgICAgICAgICAgIDogX3dwYmMuZ2V0X3NlY3VyZV9wYXJhbSggJ25vbmNlJyApLFxyXG5cdFx0XHRcdFx0d3BiY19hanhfbG9jYWxlIDogX3dwYmMuZ2V0X3NlY3VyZV9wYXJhbSggJ2xvY2FsZScgKSxcclxuXHJcblx0XHRcdFx0XHRjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyA6IHBhcmFtcyBcdFx0XHRcdFx0XHQvLyBVc3VhbGx5IGxpa2U6IHsgJ3Jlc291cmNlX2lkJzogMSwgJ21heF9kYXlzX2NvdW50JzogMzY1IH1cclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHQvKipcclxuXHRcdFx0XHQgKiBTIHUgYyBjIGUgcyBzXHJcblx0XHRcdFx0ICpcclxuXHRcdFx0XHQgKiBAcGFyYW0gcmVzcG9uc2VfZGF0YVx0XHQtXHRpdHMgb2JqZWN0IHJldHVybmVkIGZyb20gIEFqYXggLSBjbGFzcy1saXZlLXNlYXJjaC5waHBcclxuXHRcdFx0XHQgKiBAcGFyYW0gdGV4dFN0YXR1c1x0XHQtXHQnc3VjY2VzcydcclxuXHRcdFx0XHQgKiBAcGFyYW0ganFYSFJcdFx0XHRcdC1cdE9iamVjdFxyXG5cdFx0XHRcdCAqL1xyXG5cdFx0XHRcdGZ1bmN0aW9uICggcmVzcG9uc2VfZGF0YSwgdGV4dFN0YXR1cywganFYSFIgKSB7XHJcbi8vIGNvbnNvbGUudGltZUVuZCgncmVzb3VyY2VfaWRfJyArIHJlc3BvbnNlX2RhdGFbJ3Jlc291cmNlX2lkJ10pO1xyXG5jb25zb2xlLmxvZyggJyA9PSBSZXNwb25zZSBXUEJDX0FKWF9DQUxFTkRBUl9MT0FEID09ICcsIHJlc3BvbnNlX2RhdGEgKTsgY29uc29sZS5ncm91cEVuZCgpO1xyXG5cclxuXHRcdFx0XHRcdC8vIEZpeEluOiA5LjguNi4yLlxyXG5cdFx0XHRcdFx0dmFyIGFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkID0gd3BiY19nZXRfcmVzb3VyY2VfaWRfX2Zyb21fYWp4X3Bvc3RfZGF0YV91cmwoIHRoaXMuZGF0YSApO1xyXG5cdFx0XHRcdFx0d3BiY19iYWxhbmNlcl9fY29tcGxldGVkKCBhanhfcG9zdF9kYXRhX19yZXNvdXJjZV9pZCAsICd3cGJjX2NhbGVuZGFyX19sb2FkX2RhdGFfX2FqeCcgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBQcm9iYWJseSBFcnJvclxyXG5cdFx0XHRcdFx0aWYgKCAodHlwZW9mIHJlc3BvbnNlX2RhdGEgIT09ICdvYmplY3QnKSB8fCAocmVzcG9uc2VfZGF0YSA9PT0gbnVsbCkgKXtcclxuXHJcblx0XHRcdFx0XHRcdHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdFx0XHRcdFx0XHR2YXIgbWVzc2FnZV90eXBlID0gJ2luZm8nO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCAnJyA9PT0gcmVzcG9uc2VfZGF0YSApe1xyXG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlX2RhdGEgPSAnVGhlIHNlcnZlciByZXNwb25kcyB3aXRoIGFuIGVtcHR5IHN0cmluZy4gVGhlIHNlcnZlciBwcm9iYWJseSBzdG9wcGVkIHdvcmtpbmcgdW5leHBlY3RlZGx5LiA8YnI+UGxlYXNlIGNoZWNrIHlvdXIgPHN0cm9uZz5lcnJvci5sb2c8L3N0cm9uZz4gaW4geW91ciBzZXJ2ZXIgY29uZmlndXJhdGlvbiBmb3IgcmVsYXRpdmUgZXJyb3JzLic7XHJcblx0XHRcdFx0XHRcdFx0bWVzc2FnZV90eXBlID0gJ3dhcm5pbmcnO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0d3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggcmVzcG9uc2VfZGF0YSAsIHsgJ3R
34115cGUnICAgICA6IG1lc3NhZ2VfdHlwZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZSc6IHsnanFfbm9kZSc6IGpxX25vZGUsICd3aGVyZSc6ICdhZnRlcid9LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaXNfYXBwZW5kJzogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFNob3cgQ2FsZW5kYXJcclxuXHRcdFx0XHRcdHdwYmNfY2FsZW5kYXJfX2xvYWRpbmdfX3N0b3AoIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSApO1xyXG5cclxuXHRcdFx0XHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHRcdFx0XHRcdC8vIEJvb2tpbmdzIC0gRGF0ZXNcclxuXHRcdFx0XHRcdF93cGJjLmJvb2tpbmdzX2luX2NhbGVuZGFyX19zZXRfZGF0ZXMoICByZXNwb25zZV9kYXRhWyAncmVzb3VyY2VfaWQnIF0sIHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsnZGF0ZXMnXSAgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBCb29raW5ncyAtIENoaWxkIG9yIG9ubHkgc2luZ2xlIGJvb2tpbmcgcmVzb3VyY2UgaW4gZGF0ZXNcclxuXHRcdFx0XHRcdF93cGJjLmJvb2tpbmdfX3NldF9wYXJhbV92YWx1ZSggcmVzcG9uc2VfZGF0YVsgJ3Jlc291cmNlX2lkJyBdLCAncmVzb3VyY2VzX2lkX2Fycl9faW5fZGF0ZXMnLCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdyZXNvdXJjZXNfaWRfYXJyX19pbl9kYXRlcycgXSApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEFnZ3JlZ2F0ZSBib29raW5nIHJlc291cmNlcywgIGlmIGFueSA/XHJcblx0XHRcdFx0XHRfd3BiYy5ib29raW5nX19zZXRfcGFyYW1fdmFsdWUoIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSwgJ2FnZ3JlZ2F0ZV9yZXNvdXJjZV9pZF9hcnInLCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhZ2dyZWdhdGVfcmVzb3VyY2VfaWRfYXJyJyBdICk7XHJcblx0XHRcdFx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5cdFx0XHRcdFx0Ly8gVXBkYXRlIGNhbGVuZGFyXHJcblx0XHRcdFx0XHR3cGJjX2NhbGVuZGFyX191cGRhdGVfbG9vayggcmVzcG9uc2VfZGF0YVsgJ3Jlc291cmNlX2lkJyBdICk7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfaG9va19faW5pdF90aW1lc2VsZWN0b3IpICkge1xyXG5cdFx0XHRcdFx0XHR3cGJjX2hvb2tfX2luaXRfdGltZXNlbGVjdG9yKCk7XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0aWYgKFxyXG5cdFx0XHRcdFx0XHRcdCggJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiAocmVzcG9uc2VfZGF0YVsgJ2FqeF9kYXRhJyBdWyAnYWp4X2FmdGVyX2FjdGlvbl9tZXNzYWdlJyBdKSApXHJcblx0XHRcdFx0XHRcdCAmJiAoICcnICE9IHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsgJ2FqeF9hZnRlcl9hY3Rpb25fbWVzc2FnZScgXS5yZXBsYWNlKCAvXFxuL2csIFwiPGJyIC8+XCIgKSApXHJcblx0XHRcdFx0XHQpe1xyXG5cclxuXHRcdFx0XHRcdFx0dmFyIGpxX25vZGUgID0gd3BiY19nZXRfY2FsZW5kYXJfX2pxX25vZGVfX2Zvcl9tZXNzYWdlcyggdGhpcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0d3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggcmVzcG9uc2VfZGF0YVsgJ2FqeF9kYXRhJyBdWyAnYWp4X2FmdGVyX2FjdGlvbl9tZXNzYWdlJyBdLnJlcGxhY2UoIC9cXG4vZywgXCI8YnIgLz5cIiApLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0eyAgICd0eXBlJyAgICAgOiAoICd1bmRlZmluZWQnICE9PSB0eXBlb2YoIHJlc3BvbnNlX2RhdGFbICdhanhfZGF0YScgXVsgJ2FqeF9hZnRlcl9hY3Rpb25fbWVzc2FnZV9zdGF0dXMnIF0gKSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgPyByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdIDogJ2luZm8nLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJzogeydqcV9ub2RlJzoganFfbm9kZSwgJ3doZXJlJzogJ2FmdGVyJ30sXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpc19hcHBlbmQnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc3R5bGUnICAgIDogJ3RleHQtYWxpZ246bGVmdDsnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgIDogMTAwMDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBUcmlnZ2VyIGV2ZW50IHRoYXQgY2FsZW5kYXIgaGFzIGJlZW5cdFx0IC8vIEZpeEluOiAxMC4wLjAuNDQuXHJcblx0XHRcdFx0XHRpZiAoIGpRdWVyeSggJyNjYWxlbmRhcl9ib29raW5nJyArIHJlc3BvbnNlX2RhdGFbICdyZXNvdXJjZV9pZCcgXSApLmxlbmd0aCA+IDAgKXtcclxuXHRcdFx0XHRcdFx0dmFyIHRhcmdldF9lbG0gPSBqUXVlcnkoICdib2R5JyApLnRyaWdnZXIoIFwid3BiY19jYWxlbmRhcl9hanhfX2xvYWRlZF9kYXRhXCIsIFtyZXNwb25zZV9kYXRhWyAncmVzb3VyY2VfaWQnIF1dICk7XHJcblx0XHRcdFx0XHRcdCAvL2pRdWVyeSggJ2JvZHknICkub24oICd3cGJjX2NhbGVuZGFyX2FqeF9fbG9hZGVkX2RhdGEnLCBmdW5jdGlvbiggZXZlbnQsIHJlc291cmNlX2lkICkgeyAuLi4gfSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8valF1ZXJ5KCAnI2FqYXhfcmVzcG9uZCcgKS5odG1sKCByZXNwb25zZV9kYXRhICk7XHRcdC8vIEZvciBhYmlsaXR5IHRvIHNob3cgcmVzcG9uc2UsIGFkZCBzdWNoIERJViBlbGVtZW50IHRvIHBhZ2VcclxuXHRcdFx0XHR9XHJcblx0XHRcdCAgKS5mYWlsKCBmdW5jdGlvbiAoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApIHsgICAgaWYgKCB3aW5kb3cuY29uc29sZSAmJiB3aW5kb3cuY29uc29sZS5sb2cgKXsgY29uc29sZS5sb2coICd
3411BamF4X0Vycm9yJywganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7IH1cclxuXHJcblx0XHRcdFx0XHR2YXIgYWp4X3Bvc3RfZGF0YV9fcmVzb3VyY2VfaWQgPSB3cGJjX2dldF9yZXNvdXJjZV9pZF9fZnJvbV9hanhfcG9zdF9kYXRhX3VybCggdGhpcy5kYXRhICk7XHJcblx0XHRcdFx0XHR3cGJjX2JhbGFuY2VyX19jb21wbGV0ZWQoIGFqeF9wb3N0X2RhdGFfX3Jlc291cmNlX2lkICwgJ3dwYmNfY2FsZW5kYXJfX2xvYWRfZGF0YV9fYWp4JyApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEdldCBDb250ZW50IG9mIEVycm9yIE1lc3NhZ2VcclxuXHRcdFx0XHRcdHZhciBlcnJvcl9tZXNzYWdlID0gJzxzdHJvbmc+JyArICdFcnJvciEnICsgJzwvc3Ryb25nPiAnICsgZXJyb3JUaHJvd24gO1xyXG5cdFx0XHRcdFx0aWYgKCBqcVhIUi5zdGF0dXMgKXtcclxuXHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnICg8Yj4nICsganFYSFIuc3RhdHVzICsgJzwvYj4pJztcclxuXHRcdFx0XHRcdFx0aWYgKDQwMyA9PSBqcVhIUi5zdGF0dXMgKXtcclxuXHRcdFx0XHRcdFx0XHRlcnJvcl9tZXNzYWdlICs9ICc8YnI+IFByb2JhYmx5IG5vbmNlIGZvciB0aGlzIHBhZ2UgaGFzIGJlZW4gZXhwaXJlZC4gUGxlYXNlIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiBvbmNsaWNrPVwiamF2YXNjcmlwdDpsb2NhdGlvbi5yZWxvYWQoKTtcIj5yZWxvYWQgdGhlIHBhZ2U8L2E+Lic7XHJcblx0XHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnPGJyPiBPdGhlcndpc2UsIHBsZWFzZSBjaGVjayB0aGlzIDxhIHN0eWxlPVwiZm9udC13ZWlnaHQ6IDYwMDtcIiBocmVmPVwiaHR0cHM6Ly93cGJvb2tpbmdjYWxlbmRhci5jb20vZmFxL3JlcXVlc3QtZG8tbm90LXBhc3Mtc2VjdXJpdHktY2hlY2svP2FmdGVyX3VwZGF0ZT0xMC4xLjFcIj50cm91Ymxlc2hvb3RpbmcgaW5zdHJ1Y3Rpb248L2E+Ljxicj4nXHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHZhciBtZXNzYWdlX3Nob3dfZGVsYXkgPSAzMDAwO1xyXG5cdFx0XHRcdFx0aWYgKCBqcVhIUi5yZXNwb25zZVRleHQgKXtcclxuXHRcdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSArPSAnICcgKyBqcVhIUi5yZXNwb25zZVRleHQ7XHJcblx0XHRcdFx0XHRcdG1lc3NhZ2Vfc2hvd19kZWxheSA9IDEwO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZXJyb3JfbWVzc2FnZSA9IGVycm9yX21lc3NhZ2UucmVwbGFjZSggL1xcbi9nLCBcIjxiciAvPlwiICk7XHJcblxyXG5cdFx0XHRcdFx0dmFyIGpxX25vZGUgID0gd3BiY19nZXRfY2FsZW5kYXJfX2pxX25vZGVfX2Zvcl9tZXNzYWdlcyggdGhpcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdFx0LyoqXHJcblx0XHRcdFx0XHQgKiBJZiB3ZSBtYWtlIGZhc3QgY2xpY2tpbmcgb24gZGlmZmVyZW50IHBhZ2VzLFxyXG5cdFx0XHRcdFx0ICogdGhlbiB1bmRlciBjYWxlbmRhciB3aWxsIHNob3cgZXJyb3IgbWVzc2FnZSB3aXRoICBlbXB0eSAgdGV4dCwgYmVjYXVzZSBhamF4IHdhcyBub3QgcmVjZWl2ZWQuXHJcblx0XHRcdFx0XHQgKiBUbyAgbm90IHNob3cgc3VjaCB3YXJuaW5ncyB3ZSBhcmUgc2V0IGRlbGF5ICBpbiAzIHNlY29uZHMuICB2YXIgbWVzc2FnZV9zaG93X2RlbGF5ID0gMzAwMDtcclxuXHRcdFx0XHRcdCAqL1xyXG5cdFx0XHRcdFx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTaG93IE1lc3NhZ2VcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCBlcnJvcl9tZXNzYWdlICwgeyAndHlwZScgICAgIDogJ2Vycm9yJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJzogeydqcV9ub2RlJzoganFfbm9kZSwgJ3doZXJlJzogJ2FmdGVyJ30sXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lzX2FwcGVuZCc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnY3NzX2NsYXNzJzond3BiY19mZV9tZXNzYWdlX2FsdCcsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDBcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICAgfSAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICBwYXJzZUludCggbWVzc2FnZV9zaG93X2RlbGF5ICkgICApO1xyXG5cclxuXHRcdFx0ICB9KVxyXG5cdCAgICAgICAgICAvLyAuZG9uZSggICBmdW5jdGlvbiAoIGRhdGEsIHRleHRTdGF0dXMsIGpxWEhSICkgeyAgIGlmICggd2luZG93LmNvbnNvbGUgJiYgd2luZG93LmNvbnNvbGUubG9nICl7IGNvbnNvbGUubG9nKCAnc2Vjb25kIHN1Y2Nlc3MnLCBkYXRhLCB0ZXh0U3RhdHVzLCBqcVhIUiApOyB9ICAgIH0pXHJcblx0XHRcdCAgLy8gLmFsd2F5cyggZnVuY3Rpb24gKCBkYXRhX2pxWEhSLCB0ZXh0U3RhdHVzLCBqcVhIUl9lcnJvclRocm93biApIHsgICBpZiAoIHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLmxvZyApeyBjb25zb2xlLmxvZyggJ2Fsd2F5cyBmaW5pc2hlZCcsIGRhdGFfanFYSFIsIHRleHRTdGF0dXMsIGpxWEhSX2Vycm9yVGhyb3duICk7IH0gICAgIH0pXHJcblx0XHRcdCAgOyAgLy8gRW5kIEFqYXhcclxufVxyXG5cclxuXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU3VwcG9ydFxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcblx0LyoqXHJcblx0ICogR2V0IENhbGVuZGFyIGpRdWVyeSBub2RlIGZvciBzaG93aW5nIG1lc3NhZ2VzIGR1cmluZyBBamF4XHJcblx0ICogVGhpcyBwYXJhbWV0ZXI6ICAgY2FsZW5kYXJfcmVx
3411dWVzdF9wYXJhbXNbcmVzb3VyY2VfaWRdICAgcGFyc2VkIGZyb20gdGhpcy5kYXRhIEFqYXggcG9zdCAgZGF0YVxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGFqeF9wb3N0X2RhdGFfdXJsX3BhcmFtc1x0XHQgJ2FjdGlvbj1XUEJDX0FKWF9DQUxFTkRBUl9MT0FELi4uJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCcmVzb3VyY2VfaWQlNUQ9MiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QmJvb2tpbmdfaGFzaCU1RD0mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMnXHJcblx0ICogQHJldHVybnMge3N0cmluZ31cdCcnI2NhbGVuZGFyX2Jvb2tpbmcxJyAgfCAgICcuYm9va2luZ19mb3JtX2RpdicgLi4uXHJcblx0ICpcclxuXHQgKiBFeGFtcGxlICAgIHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIGFqeF9wb3N0X2RhdGFfdXJsX3BhcmFtcyApe1xyXG5cclxuXHRcdHZhciBqcV9ub2RlID0gJy5ib29raW5nX2Zvcm1fZGl2JztcclxuXHJcblx0XHR2YXIgY2FsZW5kYXJfcmVzb3VyY2VfaWQgPSB3cGJjX2dldF9yZXNvdXJjZV9pZF9fZnJvbV9hanhfcG9zdF9kYXRhX3VybCggYWp4X3Bvc3RfZGF0YV91cmxfcGFyYW1zICk7XHJcblxyXG5cdFx0aWYgKCBjYWxlbmRhcl9yZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0anFfbm9kZSA9ICcjY2FsZW5kYXJfYm9va2luZycgKyBjYWxlbmRhcl9yZXNvdXJjZV9pZDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ganFfbm9kZTtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgcmVzb3VyY2UgSUQgZnJvbSBhanggcG9zdCBkYXRhIHVybCAgIHVzdWFsbHkgIGZyb20gIHRoaXMuZGF0YSAgPSAnYWN0aW9uPVdQQkNfQUpYX0NBTEVOREFSX0xPQUQuLi4mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJyZXNvdXJjZV9pZCU1RD0yJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCYm9va2luZ19oYXNoJTVEPSZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcydcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBhanhfcG9zdF9kYXRhX3VybF9wYXJhbXNcdFx0ICdhY3Rpb249V1BCQ19BSlhfQ0FMRU5EQVJfTE9BRC4uLiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QnJlc291cmNlX2lkJTVEPTImY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJib29raW5nX2hhc2glNUQ9JmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJ1xyXG5cdCAqIEByZXR1cm5zIHtpbnR9XHRcdFx0XHRcdFx0IDEgfCAwICAoaWYgZXJycm9yIHRoZW4gIDApXHJcblx0ICpcclxuXHQgKiBFeGFtcGxlICAgIHZhciBqcV9ub2RlICA9IHdwYmNfZ2V0X2NhbGVuZGFyX19qcV9ub2RlX19mb3JfbWVzc2FnZXMoIHRoaXMuZGF0YSApO1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZ2V0X3Jlc291cmNlX2lkX19mcm9tX2FqeF9wb3N0X2RhdGFfdXJsKCBhanhfcG9zdF9kYXRhX3VybF9wYXJhbXMgKXtcclxuXHJcblx0XHQvLyBHZXQgYm9va2luZyByZXNvdXJjZSBJRCBmcm9tIEFqYXggUG9zdCBSZXF1ZXN0ICAtPiB0aGlzLmRhdGEgPSAnYWN0aW9uPVdQQkNfQUpYX0NBTEVOREFSX0xPQUQuLi4mY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJyZXNvdXJjZV9pZCU1RD0yJmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zJTVCYm9va2luZ19oYXNoJTVEPSZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcydcclxuXHRcdHZhciBjYWxlbmRhcl9yZXNvdXJjZV9pZCA9IHdwYmNfZ2V0X3VyaV9wYXJhbV9ieV9uYW1lKCAnY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXNbcmVzb3VyY2VfaWRdJywgYWp4X3Bvc3RfZGF0YV91cmxfcGFyYW1zICk7XHJcblx0XHRpZiAoIChudWxsICE9PSBjYWxlbmRhcl9yZXNvdXJjZV9pZCkgJiYgKCcnICE9PSBjYWxlbmRhcl9yZXNvdXJjZV9pZCkgKXtcclxuXHRcdFx0Y2FsZW5kYXJfcmVzb3VyY2VfaWQgPSBwYXJzZUludCggY2FsZW5kYXJfcmVzb3VyY2VfaWQgKTtcclxuXHRcdFx0aWYgKCBjYWxlbmRhcl9yZXNvdXJjZV9pZCA+IDAgKXtcclxuXHRcdFx0XHRyZXR1cm4gY2FsZW5kYXJfcmVzb3VyY2VfaWQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiAwO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEdldCBwYXJhbWV0ZXIgZnJvbSBVUkwgIC0gIHBhcnNlIFVSTCBwYXJhbWV0ZXJzLCAgbGlrZSB0aGlzOiBhY3Rpb249V1BCQ19BSlhfQ0FMRU5EQVJfTE9BRC4uLiZjYWxlbmRhcl9yZXF1ZXN0X3BhcmFtcyU1QnJlc291cmNlX2lkJTVEPTImY2FsZW5kYXJfcmVxdWVzdF9wYXJhbXMlNUJib29raW5nX2hhc2glNUQ9JmNhbGVuZGFyX3JlcXVlc3RfcGFyYW1zXHJcblx0ICogQHBhcmFtIG5hbWUgIHBhcmFtZXRlciAgbmFtZSwgIGxpa2UgJ2NhbGVuZGFyX3JlcXVlc3RfcGFyYW1zW3Jlc291cmNlX2lkXSdcclxuXHQgKiBAcGFyYW0gdXJsXHQncGFyYW1ldGVyICBzdHJpbmcgVVJMJ1xyXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gICBwYXJhbWV0ZXIgdmFsdWVcclxuXHQgKlxyXG5cdCAqIEV4YW1wbGU6IFx0XHR3cGJjX2dldF91cmlfcGFyYW1fYnlfbmFtZSggJ2NhbGVuZGFyX3JlcXVlc3RfcGFyYW1zW3Jlc291cmNlX2lkXScsIHRoaXMuZGF0YSApOyAgLT4gJzInXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19nZXRfdXJpX3BhcmFtX2J5X25hbWUoIG5hbWUsIHVybCApe1xyXG5cclxuXHRcdHVybCA9IGRlY29kZVVSSUNvbXBvbmVudCggdXJsICk7XHJcblxyXG5cdFx0bmFtZSA9IG5hbWUucmVwbGFjZSggL1tcXFtcXF1dL2csICdcXFxcJCYnICk7XHJcblx0XHR2YXIgcmVnZXggPSBuZXcgUmVnRXhwKCAnWz8mXScgKyBuYW1lICsgJyg9KFteJiNdKil8JnwjfCQpJyApLFxyXG5cdFx0XHRyZXN1bHRzID0gcmVnZXguZXhlYyggdXJsICk7XHJcblx0XHRpZiAoICFyZXN1bHRzICkgcmV0dXJuIG51bGw7XHJcblx0XHRpZiAoICFyZXN1bHRzWyAyIF0gKSByZXR1cm4gJyc7XHJcblx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KCByZXN1bHRzWyAyIF0ucmVwbGFjZSggL1xcKy9nLCAnICcgKSApO1xyXG5cdH1cclxuIiwiLyoqXHJcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gKlx0aW5jbHVkZXMvX19qcy9mcm9udF9lbmRfbWVzc2FnZXMvd3BiY19mZV9tZXNzYWdlcy5qc1xyXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICovXHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU2hvdyBNZXNzYWdlcyBhdCBGcm9udC1FZG4gc2lkZVxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBTaG93IG1lc3NhZ2UgaW4gY29udGVudFxyXG4gKlxyXG4gKiBAcGFyYW0gbWVzc2FnZVx0XHRcdFx0TWVzc2FnZSBIVE1MXHJcbiAqIEBwYXJhbSBwYXJhbXMgPSB7XHJcbiAqXHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgOiAnd2FybmluZycsXHRcdFx0XHRcdFx0XHQvLyAnZXJyb3InIHwgJ3dhcm5pbmcnIHwgJ2luZm8nIHwgJ3N1Y2Nlc3MnXHJcbiAqXHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnIDoge1xyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxX25vZGUnIDogJycsXHRcdFx0XHQvLyBhbnkgalF1ZXJ5IG5vZGUgZGVmaW5pdGlvblxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3doZXJlJyAgIDogJ2luc2lkZSdcdFx0Ly8gJ2luc2lkZScgfCAnYmVmb3JlJyB8ICdhZnRlcicgfCAncmlnaHQnIHwgJ2xlZnQnXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgfSxcclxuICpcdFx0XHRcdFx0XHRcdFx0J2lzX2FwcGVuZCc6IHRydWUsXHRcdFx0XHRcdFx0XHRcdC8vIEFwcGx5ICBvbmx5IGlmIFx0J3doZXJlJyAgIDogJ2luc2lkZSdcclxuICpcdFx0XHRcdFx0XHRcdFx0J3N0eWxlJyAgICA6ICd0ZXh0LWFsaWduOmxlZnQ7JyxcdFx0XHRcdC8vIHN0eWxlcywgaWYgbmVlZGVkXHJcbiAqXHRcdFx0XHRcdFx0XHQgICAgJ2Nzc19jbGFzcyc6ICcnLFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgZXhhbXBsZSBjYW4gIGJlOiAnd3BiY19mZV9tZXNzYWdlX2FsdCdcclxuICpcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDAsXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaG93IG1hbnkgbWljcm9zZWNvbmQgdG8gIHNob3csICBpZiAwICB0aGVuICBzaG93IGZvcmV2ZXJcclxuICpcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiBmYWxzZVx0XHRcdFx0XHQvLyBpZiB0cnVlLCAgdGhlbiBkbyBub3Qgc2hvdyBtZXNzYWdlLCAgaWYgcHJldmlvcyBtZXNzYWdlIHdhcyBub3QgaGlkZWQgKG5vdCBhcHBseSBpZiAnd2hlcmUnICAgOiAnaW5zaWRlJyApXHJcbiAqXHRcdFx0XHR9O1xyXG4gKiBFeGFtcGxlczpcclxuICogXHRcdFx0dmFyIGh0bWxfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCAnWW91IGNhbiB0ZXN0IGRheXMgc2VsZWN0aW9uIGluIGNhbGVuZGFyJywge30gKTtcclxuICpcclxuICpcdFx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCBfd3BiYy5nZXRfbWVzc2FnZSggJ21lc3NhZ2VfY2hlY2tfcmVxdWlyZWQnICksIHsgJ3R5cGUnOiAnd2FybmluZycsICdkZWxheSc6IDEwMDAwLCAnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICdzaG93X2hlcmUnOiB7J3doZXJlJzogJ3JpZ2h0JywgJ2pxX25vZGUnOiBlbCx9IH0gKTtcclxuICpcclxuICpcdFx0XHR3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2UnIF0ucmVwbGFjZSggL1xcbi9nLCBcIjxiciAvPlwiICksXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHsgICAndHlwZScgICAgIDogKCAn
3411dW5kZWZpbmVkJyAhPT0gdHlwZW9mKCByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdICkgKVxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgPyByZXNwb25zZV9kYXRhWyAnYWp4X2RhdGEnIF1bICdhanhfYWZ0ZXJfYWN0aW9uX21lc3NhZ2Vfc3RhdHVzJyBdIDogJ2luZm8nLFxyXG4gKlx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnOiB7J2pxX25vZGUnOiBqcV9ub2RlLCAnd2hlcmUnOiAnYWZ0ZXInfSxcclxuICpcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnY3NzX2NsYXNzJzond3BiY19mZV9tZXNzYWdlX2FsdCcsXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICA6IDEwMDAwXHJcbiAqXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcclxuICpcclxuICpcclxuICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG4gKi9cclxuZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZSggbWVzc2FnZSwgcGFyYW1zID0ge30gKXtcclxuXHJcblx0dmFyIHBhcmFtc19kZWZhdWx0ID0ge1xyXG5cdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICA6ICd3YXJuaW5nJyxcdFx0XHRcdFx0XHRcdC8vICdlcnJvcicgfCAnd2FybmluZycgfCAnaW5mbycgfCAnc3VjY2VzcydcclxuXHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnIDoge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcV9ub2RlJyA6ICcnLFx0XHRcdFx0Ly8gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICAgOiAnaW5zaWRlJ1x0XHQvLyAnaW5zaWRlJyB8ICdiZWZvcmUnIHwgJ2FmdGVyJyB8ICdyaWdodCcgfCAnbGVmdCdcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgfSxcclxuXHRcdFx0XHRcdFx0XHRcdCdpc19hcHBlbmQnOiB0cnVlLFx0XHRcdFx0XHRcdFx0XHQvLyBBcHBseSAgb25seSBpZiBcdCd3aGVyZScgICA6ICdpbnNpZGUnXHJcblx0XHRcdFx0XHRcdFx0XHQnc3R5bGUnICAgIDogJ3RleHQtYWxpZ246bGVmdDsnLFx0XHRcdFx0Ly8gc3R5bGVzLCBpZiBuZWVkZWRcclxuXHRcdFx0XHRcdFx0XHQgICAgJ2Nzc19jbGFzcyc6ICcnLFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgZXhhbXBsZSBjYW4gIGJlOiAnd3BiY19mZV9tZXNzYWdlX2FsdCdcclxuXHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgOiAwLFx0XHRcdFx0XHRcdFx0XHRcdC8vIGhvdyBtYW55IG1pY3Jvc2Vjb25kIHRvICBzaG93LCAgaWYgMCAgdGhlbiAgc2hvdyBmb3JldmVyXHJcblx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IGZhbHNlLFx0XHRcdFx0XHQvLyBpZiB0cnVlLCAgdGhlbiBkbyBub3Qgc2hvdyBtZXNzYWdlLCAgaWYgcHJldmlvcyBtZXNzYWdlIHdhcyBub3QgaGlkZWQgKG5vdCBhcHBseSBpZiAnd2hlcmUnICAgOiAnaW5zaWRlJyApXHJcblx0XHRcdFx0XHRcdFx0XHQnaXNfc2Nyb2xsJzogdHJ1ZVx0XHRcdFx0XHRcdFx0XHQvLyBpcyBzY3JvbGwgIHRvICB0aGlzIGVsZW1lbnRcclxuXHRcdFx0XHRcdFx0fTtcclxuXHRmb3IgKCB2YXIgcF9rZXkgaW4gcGFyYW1zICl7XHJcblx0XHRwYXJhbXNfZGVmYXVsdFsgcF9rZXkgXSA9IHBhcmFtc1sgcF9rZXkgXTtcclxuXHR9XHJcblx0cGFyYW1zID0gcGFyYW1zX2RlZmF1bHQ7XHJcblxyXG4gICAgdmFyIHVuaXF1ZV9kaXZfaWQgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdW5pcXVlX2Rpdl9pZCA9ICd3cGJjX25vdGljZV8nICsgdW5pcXVlX2Rpdl9pZC5nZXRUaW1lKCk7XHJcblxyXG5cdHBhcmFtc1snY3NzX2NsYXNzJ10gKz0gJyB3cGJjX2ZlX21lc3NhZ2UnO1xyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ2Vycm9yJyApe1xyXG5cdFx0cGFyYW1zWydjc3NfY2xhc3MnXSArPSAnIHdwYmNfZmVfbWVzc2FnZV9lcnJvcic7XHJcblx0XHRtZXNzYWdlID0gJzxpIGNsYXNzPVwibWVudV9pY29uIGljb24tMXggd3BiY19pY25fcmVwb3J0X2dtYWlsZXJyb3JyZWRcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ3dhcm5pbmcnICl7XHJcblx0XHRwYXJhbXNbJ2Nzc19jbGFzcyddICs9ICcgd3BiY19mZV9tZXNzYWdlX3dhcm5pbmcnO1xyXG5cdFx0bWVzc2FnZSA9ICc8aSBjbGFzcz1cIm1lbnVfaWNvbiBpY29uLTF4IHdwYmNfaWNuX3dhcm5pbmdcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cdGlmICggcGFyYW1zWyd0eXBlJ10gPT0gJ2luZm8nICl7XHJcblx0XHRwYXJhbXNbJ2Nzc19jbGFzcyddICs9ICcgd3BiY19mZV9tZXNzYWdlX2luZm8nO1xyXG5cdH1cclxuXHRpZiAoIHBhcmFtc1sndHlwZSddID09ICdzdWNjZXNzJyApe1xyXG5cdFx0cGFyYW1zWydjc3NfY2xhc3MnXSArPSAnIHdwYmNfZmVfbWVzc2FnZV9zdWNjZXNzJztcclxuXHRcdG1lc3NhZ2UgPSAnPGkgY2xhc3M9XCJtZW51X2ljb24gaWNvbi0xeCB3cGJjX2ljbl9kb25lX291dGxpbmVcIj48L2k+JyArIG1lc3NhZ2U7XHJcblx0fVxyXG5cclxuXHR2YXIgc2Nyb2xsX3RvX2VsZW1lbnQgPSAnPGRpdiBpZD1cIicgKyB1bmlxdWVfZGl2X2lkICsgJ19zY3JvbGxcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj48L2Rpdj4nO1xyXG5cdG1lc3NhZ2UgPSAnPGRpdiBpZD1cIicgKyB1bmlxdWVfZGl2X2lkICsgJ1wiIGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2UgJyArIHBhcmFtc1snY3NzX2NsYXNzJ10gKyAnXCIgc3R5bGU9XCInICsgcGFyYW1zWyAnc3R5bGUnIF0gKyAnXCI+JyArIG1lc3NhZ2UgKyAnPC9kaXY+JztcclxuXHJcblxyXG5cdHZhciBqcV9lbF9tZXNzYWdlID0gZmFsc2U7XHJcblx0dmFyIGlzX3Nob3dfbWVzc2FnZSA9IHRydWU7XHJcblxyXG5cdGlmICggJ2luc2lkZScgPT09IHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ3doZXJlJyBdICl7XHJcblxyXG5cdFx0aWYgKCBwYXJhbXNbICdpc19hcHBlbmQnIF0gKXtcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYXBwZW5kKCBzY3JvbGxfdG9fZWxlbWVudCApO1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5hcHBlbmQo
3411IG1lc3NhZ2UgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmh0bWwoIHNjcm9sbF90b19lbGVtZW50ICsgbWVzc2FnZSApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2UgaWYgKCAnYmVmb3JlJyA9PT0gcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnd2hlcmUnIF0gKXtcclxuXHJcblx0XHRqcV9lbF9tZXNzYWdlID0galF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuc2libGluZ3MoICdbaWRePVwid3BiY19ub3RpY2VfXCJdJyApO1xyXG5cdFx0aWYgKCAocGFyYW1zWyAnaWZfdmlzaWJsZV9ub3Rfc2hvdycgXSkgJiYgKGpxX2VsX21lc3NhZ2UuaXMoICc6dmlzaWJsZScgKSkgKXtcclxuXHRcdFx0aXNfc2hvd19tZXNzYWdlID0gZmFsc2U7XHJcblx0XHRcdHVuaXF1ZV9kaXZfaWQgPSBqUXVlcnkoIGpxX2VsX21lc3NhZ2UuZ2V0KCAwICkgKS5hdHRyKCAnaWQnICk7XHJcblx0XHR9XHJcblx0XHRpZiAoIGlzX3Nob3dfbWVzc2FnZSApe1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoIHNjcm9sbF90b19lbGVtZW50ICk7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmJlZm9yZSggbWVzc2FnZSApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2UgaWYgKCAnYWZ0ZXInID09PSBwYXJhbXNbICdzaG93X2hlcmUnIF1bICd3aGVyZScgXSApe1xyXG5cclxuXHRcdGpxX2VsX21lc3NhZ2UgPSBqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5uZXh0QWxsKCAnW2lkXj1cIndwYmNfbm90aWNlX1wiXScgKTtcclxuXHRcdGlmICggKHBhcmFtc1sgJ2lmX3Zpc2libGVfbm90X3Nob3cnIF0pICYmIChqcV9lbF9tZXNzYWdlLmlzKCAnOnZpc2libGUnICkpICl7XHJcblx0XHRcdGlzX3Nob3dfbWVzc2FnZSA9IGZhbHNlO1xyXG5cdFx0XHR1bmlxdWVfZGl2X2lkID0galF1ZXJ5KCBqcV9lbF9tZXNzYWdlLmdldCggMCApICkuYXR0ciggJ2lkJyApO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBpc19zaG93X21lc3NhZ2UgKXtcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYmVmb3JlKCBzY3JvbGxfdG9fZWxlbWVudCApO1x0XHQvLyBXZSBuZWVkIHRvICBzZXQgIGhlcmUgYmVmb3JlKGZvciBoYW5keSBzY3JvbGwpXHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmFmdGVyKCBtZXNzYWdlICk7XHJcblx0XHR9XHJcblxyXG5cdH0gZWxzZSBpZiAoICdyaWdodCcgPT09IHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ3doZXJlJyBdICl7XHJcblxyXG5cdFx0anFfZWxfbWVzc2FnZSA9IGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLm5leHRBbGwoICcud3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX3JpZ2h0JyApLmZpbmQoICdbaWRePVwid3BiY19ub3RpY2VfXCJdJyApO1xyXG5cdFx0aWYgKCAocGFyYW1zWyAnaWZfdmlzaWJsZV9ub3Rfc2hvdycgXSkgJiYgKGpxX2VsX21lc3NhZ2UuaXMoICc6dmlzaWJsZScgKSkgKXtcclxuXHRcdFx0aXNfc2hvd19tZXNzYWdlID0gZmFsc2U7XHJcblx0XHRcdHVuaXF1ZV9kaXZfaWQgPSBqUXVlcnkoIGpxX2VsX21lc3NhZ2UuZ2V0KCAwICkgKS5hdHRyKCAnaWQnICk7XHJcblx0XHR9XHJcblx0XHRpZiAoIGlzX3Nob3dfbWVzc2FnZSApe1xyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoIHNjcm9sbF90b19lbGVtZW50ICk7XHRcdC8vIFdlIG5lZWQgdG8gIHNldCAgaGVyZSBiZWZvcmUoZm9yIGhhbmR5IHNjcm9sbClcclxuXHRcdFx0alF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuYWZ0ZXIoICc8ZGl2IGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX3JpZ2h0XCI+JyArIG1lc3NhZ2UgKyAnPC9kaXY+JyApO1xyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAoICdsZWZ0JyA9PT0gcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnd2hlcmUnIF0gKXtcclxuXHJcblx0XHRqcV9lbF9tZXNzYWdlID0galF1ZXJ5KCBwYXJhbXNbICdzaG93X2hlcmUnIF1bICdqcV9ub2RlJyBdICkuc2libGluZ3MoICcud3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX2xlZnQnICkuZmluZCggJ1tpZF49XCJ3cGJjX25vdGljZV9cIl0nICk7XHJcblx0XHRpZiAoIChwYXJhbXNbICdpZl92aXNpYmxlX25vdF9zaG93JyBdKSAmJiAoanFfZWxfbWVzc2FnZS5pcyggJzp2aXNpYmxlJyApKSApe1xyXG5cdFx0XHRpc19zaG93X21lc3NhZ2UgPSBmYWxzZTtcclxuXHRcdFx0dW5pcXVlX2Rpdl9pZCA9IGpRdWVyeSgganFfZWxfbWVzc2FnZS5nZXQoIDAgKSApLmF0dHIoICdpZCcgKTtcclxuXHRcdH1cclxuXHRcdGlmICggaXNfc2hvd19tZXNzYWdlICl7XHJcblx0XHRcdGpRdWVyeSggcGFyYW1zWyAnc2hvd19oZXJlJyBdWyAnanFfbm9kZScgXSApLmJlZm9yZSggc2Nyb2xsX3RvX2VsZW1lbnQgKTtcdFx0Ly8gV2UgbmVlZCB0byAgc2V0ICBoZXJlIGJlZm9yZShmb3IgaGFuZHkgc2Nyb2xsKVxyXG5cdFx0XHRqUXVlcnkoIHBhcmFtc1sgJ3Nob3dfaGVyZScgXVsgJ2pxX25vZGUnIF0gKS5iZWZvcmUoICc8ZGl2IGNsYXNzPVwid3BiY19mcm9udF9lbmRfX21lc3NhZ2VfY29udGFpbmVyX2xlZnRcIj4nICsgbWVzc2FnZSArICc8L2Rpdj4nICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoICAgKCBpc19zaG93X21lc3NhZ2UgKSAgJiYgICggcGFyc2VJbnQoIHBhcmFtc1sgJ2RlbGF5JyBdICkgPiAwICkgICApe1xyXG5cdFx0dmFyIGNsb3NlZF90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uICgpe1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGpRdWVyeSggJyMnICsgdW5pcXVlX2Rpdl9pZCApLmZhZGVPdXQoIDE1MDAgKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9ICwgcGFyc2VJbnQoIHBhcmFtc1sgJ2RlbGF5JyBdICkgICApO1xyXG5cclxuXHRcdHZhciBjbG9zZWRfdGltZXIyID0gc2V0VGltZW91dCggZnVuY3Rpb24gKCl7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoICcjJyArIHVuaXF1ZV9kaXZfaWQgKS50cmlnZ2VyKCAnaGlkZScgKTtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9LCAoIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApICsgMTUwMSApICk7XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayAgaWYgc2hvd2VkIG1lc3NhZ2UgaW4gc29tZSBoaWRkZW4gcGFyZW50IHNlY3Rpb24gYW5kIHNob3cgaXQuIEJ1dCBpdCBtdXN0ICBiZSBsb3dlciB0aGFuICcud3BiY19jb250YWluZXInXHJcblx0dmFyIHBhcmVudF9lbHMgPSBqUXVlcnkoICcjJyArIHVuaXF1ZV9kaXZfaWQgKS5wYXJlbnRzKCkubWFwKCBmdW5jdGlvbiAoKXtcclxuXHRcdGlmICggKCFqUXVlcnkoIHRoaXMgKS5pcyggJ3Zpc2libGUnICkpICYmIChqUXVlcnkoICcud3BiY19jb250YWluZXInICkuaGFzKCB0aGlzICkpICl7XHJcblx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcclxuXHRcdH1cclxuXHR9ICk7XHJcblxyXG5cdGlmICggcGFyYW1zWyAnaXNfc2Nyb2xsJyBdICl7XHJcblx0XHR3cGJjX2RvX3Njcm9sbCggJy
3411MnICsgdW5pcXVlX2Rpdl9pZCArICdfc2Nyb2xsJyApO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHVuaXF1ZV9kaXZfaWQ7XHJcbn1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEVycm9yIG1lc3NhZ2UuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX2Vycm9yKCBqcV9ub2RlLCBtZXNzYWdlICl7XHJcblxyXG5cdFx0dmFyIG5vdGljZV9tZXNzYWdlX2lkID0gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtZXNzYWdlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgICAgICAgICAgIDogJ2Vycm9yJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgICAgICAgICAgIDogMTAwMDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ3JpZ2h0JyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdqcV9ub2RlJzoganFfbm9kZVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCAgIH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xyXG5cdFx0cmV0dXJuIG5vdGljZV9tZXNzYWdlX2lkO1xyXG5cdH1cclxuXHJcblxyXG5cdC8qKlxyXG5cdCAqIEVycm9yIG1lc3NhZ2UgVU5ERVIgZWxlbWVudC4gXHRQcmVzZXQgb2YgcGFyYW1ldGVycyBmb3IgcmVhbCBtZXNzYWdlIGZ1bmN0aW9uLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGVsXHRcdC0gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHQgKiBAcGFyYW0gbWVzc2FnZVx0LSBNZXNzYWdlIEhUTUxcclxuXHQgKiBAcmV0dXJucyBzdHJpbmcgIC0gSFRNTCBJRFx0XHRvciAwIGlmIG5vdCBzaG93aW5nIGR1cmluZyB0aGlzIHRpbWUuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fZXJyb3JfdW5kZXJfZWxlbWVudCgganFfbm9kZSwgbWVzc2FnZSwgbWVzc2FnZV9kZWxheSApe1xyXG5cclxuXHRcdGlmICggJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAobWVzc2FnZV9kZWxheSkgKXtcclxuXHRcdFx0bWVzc2FnZV9kZWxheSA9IDBcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1lc3NhZ2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICAgICAgICAgICAgOiAnZXJyb3InLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICAgICAgICAgICAgOiBtZXNzYWdlX2RlbGF5LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZScgICAgICAgICAgOiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICA6ICdhZnRlcicsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBFcnJvciBtZXNzYWdlIFVOREVSIGVsZW1lbnQuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX2Vycm9yX2Fib3ZlX2VsZW1lbnQoIGpxX25vZGUsIG1lc3NhZ2UsIG1lc3NhZ2VfZGVsYXkgKXtcclxuXHJcblx0XHRpZiAoICd1bmRlZmluZWQnID09PSB0eXBlb2YgKG1lc3NhZ2VfZGVsYXkpICl7XHJcblx0XHRcdG1lc3NhZ2VfZGVsYXkgPSAxMDAwMFxyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBub3RpY2VfbWVzc2FnZV9pZCA9IHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2UoXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWVzc2FnZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndHlwZScgICAgICAgICAgICAgICA6ICdlcnJvcicsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgICAgICAgICAgICA6IG1lc3NhZ2VfZGVsYXksXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ2JlZm9yZScsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybi
3411Bub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBXYXJuaW5nIG1lc3NhZ2UuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX3dhcm5pbmcoIGpxX25vZGUsIG1lc3NhZ2UgKXtcclxuXHJcblx0XHR2YXIgbm90aWNlX21lc3NhZ2VfaWQgPSB3cGJjX2Zyb250X2VuZF9fc2hvd19tZXNzYWdlKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1lc3NhZ2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3R5cGUnICAgICAgICAgICAgICAgOiAnd2FybmluZycsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnZGVsYXknICAgICAgICAgICAgICA6IDEwMDAwLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2lmX3Zpc2libGVfbm90X3Nob3cnOiB0cnVlLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3Nob3dfaGVyZScgICAgICAgICAgOiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnd2hlcmUnICA6ICdyaWdodCcsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHdwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQoIGpxX25vZGUgKTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cclxuXHQvKipcclxuXHQgKiBXYXJuaW5nIG1lc3NhZ2UgVU5ERVIgZWxlbWVudC4gXHRQcmVzZXQgb2YgcGFyYW1ldGVycyBmb3IgcmVhbCBtZXNzYWdlIGZ1bmN0aW9uLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGVsXHRcdC0gYW55IGpRdWVyeSBub2RlIGRlZmluaXRpb25cclxuXHQgKiBAcGFyYW0gbWVzc2FnZVx0LSBNZXNzYWdlIEhUTUxcclxuXHQgKiBAcmV0dXJucyBzdHJpbmcgIC0gSFRNTCBJRFx0XHRvciAwIGlmIG5vdCBzaG93aW5nIGR1cmluZyB0aGlzIHRpbWUuXHJcblx0ICovXHJcblx0ZnVuY3Rpb24gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZV9fd2FybmluZ191bmRlcl9lbGVtZW50KCBqcV9ub2RlLCBtZXNzYWdlICl7XHJcblxyXG5cdFx0dmFyIG5vdGljZV9tZXNzYWdlX2lkID0gd3BiY19mcm9udF9lbmRfX3Nob3dfbWVzc2FnZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRtZXNzYWdlLF
3411xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd0eXBlJyAgICAgICAgICAgICAgIDogJ3dhcm5pbmcnLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2RlbGF5JyAgICAgICAgICAgICAgOiAxMDAwMCxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdpZl92aXNpYmxlX25vdF9zaG93JzogdHJ1ZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdzaG93X2hlcmUnICAgICAgICAgIDoge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J3doZXJlJyAgOiAnYWZ0ZXInLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0J2pxX25vZGUnOiBqcV9ub2RlXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICAgfVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRyZXR1cm4gbm90aWNlX21lc3NhZ2VfaWQ7XHJcblx0fVxyXG5cclxuXHJcblx0LyoqXHJcblx0ICogV2FybmluZyBtZXNzYWdlIEFCT1ZFIGVsZW1lbnQuIFx0UHJlc2V0IG9mIHBhcmFtZXRlcnMgZm9yIHJlYWwgbWVzc2FnZSBmdW5jdGlvbi5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBlbFx0XHQtIGFueSBqUXVlcnkgbm9kZSBkZWZpbml0aW9uXHJcblx0ICogQHBhcmFtIG1lc3NhZ2VcdC0gTWVzc2FnZSBIVE1MXHJcblx0ICogQHJldHVybnMgc3RyaW5nICAtIEhUTUwgSURcdFx0b3IgMCBpZiBub3Qgc2hvd2luZyBkdXJpbmcgdGhpcyB0aW1lLlxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2VfX3dhcm5pbmdfYWJvdmVfZWxlbWVudCgganFfbm9kZSwgbWVzc2FnZSApe1xyXG5cclxuXHRcdHZhciBub3RpY2VfbWVzc2FnZV9pZCA9IHdwYmNfZnJvbnRfZW5kX19zaG93X21lc3NhZ2UoXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWVzc2FnZSxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQndHlwZScgICAgICAgICAgICAgICA6ICd3YXJuaW5nJyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCdkZWxheScgICAgICAgICAgICAgIDogMTAwMDAsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnaWZfdmlzaWJsZV9ub3Rfc2hvdyc6IHRydWUsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnc2hvd19oZXJlJyAgICAgICAgICA6IHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCd3aGVyZScgIDogJ2JlZm9yZScsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQnanFfbm9kZSc6IGpxX25vZGVcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcclxuXHRcdHJldHVybiBub3RpY2VfbWVzc2FnZV9pZDtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEhpZ2hsaWdodCBFcnJvciBpbiBzcGVjaWZpYyBmaWVsZFxyXG5cdCAqXHJcblx0ICogQHBhcmFtIGpxX25vZGVcdFx0XHRcdFx0c3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LCAgd2hlcmUgc2Nyb2xsICB0b1xyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIHdwYmNfaGlnaGxpZ2h0X2Vycm9yX29uX2Zvcm1fZmllbGQoIGpxX25vZGUgKXtcclxuXHJcblx0XHRpZiAoICFqUXVlcnkoIGpxX25vZGUgKS5sZW5ndGggKXtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCAhIGpRdWVyeSgganFfbm9kZSApLmlzKCAnOmlucHV0JyApICl7XHJcblx0XHRcdC8vIFNpdHVhdGlvbiB3aXRoICBjaGVja2JveGVzIG9yIHJhZGlvICBidXR0b25zXHJcblx0XHRcdHZhciBqcV9ub2RlX2FyciA9IGpRdWVyeSgganFfbm9kZSApLmZpbmQoICc6aW5wdXQnICk7XHJcblx0XHRcdGlmICggIWpxX25vZGVfYXJyLmxlbmd0aCApe1xyXG5cdFx0XHRcdHJldHVyblxyXG5cdFx0XHR9XHJcblx0XHRcdGpxX25vZGUgPSBqcV9ub2RlX2Fyci5nZXQoIDAgKTtcclxuXHRcdH1cclxuXHRcdHZhciBwYXJhbXMgPSB7fTtcclxuXHRcdHBhcmFtc1sgJ2RlbGF5JyBdID0gMTAwMDA7XHJcblxyXG5cdFx0aWYgKCAhalF1ZXJ5KCBqcV9ub2RlICkuaGFzQ2xhc3MoICd3cGJjX2Zvcm1fZmllbGRfZXJyb3InICkgKXtcclxuXHJcblx0XHRcdGpRdWVyeSgganFfbm9kZSApLmFkZENsYXNzKCAnd3BiY19mb3JtX2ZpZWxkX2Vycm9yJyApXHJcblxyXG5cdFx0XHRpZiAoIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApID4gMCApe1xyXG5cdFx0XHRcdHZhciBjbG9zZWRfdGltZXIgPSBzZXRUaW1lb3V0KCBmdW5jdGlvbiAoKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IGpRdWVyeSgganFfbm9kZSApLnJlbW92ZUNsYXNzKCAnd3BiY19mb3JtX2ZpZWxkX2Vycm9yJyApO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ICB9XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgICAsIHBhcnNlSW50KCBwYXJhbXNbICdkZWxheScgXSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuLyoqXHJcbiAqIFNjcm9sbCB0byBzcGVjaWZpYyBlbGVtZW50XHJcbiAqXHJcbiAqIEBwYXJhbSBqcV9ub2RlXHRcdFx0XHRcdHN0cmluZyBvciBqUXVlcnkgZWxlbWVudCwgIHdoZXJlIHNjcm9sbCAgdG9cclxuICogQHBhcmFtIGV4dHJhX3NoaWZ0X29mZnNldFx0XHRpbnQgc2hpZnQgb2Zmc2V0IGZyb20gIGpxX25vZGVcclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZG9fc2Nyb2xsKCBqcV9ub2RlICwgZXh0cmFfc2hpZnRfb2Zmc2V0ID0gMCApe1xyXG5cclxuXHRpZiAoICFqUXVlcnkoIGpxX25vZGUgKS5sZW5ndGggKXtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0dmFyIHRhcmdldE9mZnNldCA9IGpRdWVyeSgganFfbm9kZSApLm9mZnNldCgpLnRvcDtcclxuXHJcblx0aWYgKCB0YXJnZXRPZmZzZXQgPD0gMCApe1xyXG5cdFx0aWYgKCAwICE9IGpRdWVyeSgganFfbm9kZSApLm5leHRBbGwoICc6dmlzaWJsZScgKS5sZW5ndGggKXtcclxuXHRcdFx0dGFyZ2V0T2Zmc2V0ID0galF1ZXJ5KCBqcV9ub2RlICkubmV4dEFsbCggJzp2aXNpYmxlJyApLmZpcnN0KCkub2Zmc2V0KCkudG9wO1xyXG5cdFx0fSBlbHNlIGlmICggMCAhPSBqUXVlcnkoIGpxX25vZGUgKS5wYXJlbnQoKS5uZXh0QWxsKCAnOnZpc2libGUnICkubGVuZ3RoICl7XHJcblx0XHRcdHRhcmdldE9mZnNldCA9IGpRdWVyeSgganFfbm9kZSApLnBhcmVudCgpLm5leHRBbGwoICc6dmlzaWJsZScgKS5maXJzdCgpLm9mZnNldCgpLnRvcDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGlmICggalF1ZXJ5KCAnI3dwYWRtaW5iYXInICkubGVuZ3RoID4gMCApe1xyXG5cdFx0dGFyZ2V0T2Zmc2V0ID0gdGFyZ2V0T2Zmc2V0IC0gNTAgLSA1MDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGFyZ2V0T2Zmc2V0ID0gdGFyZ2V0T2Zmc2V0IC0gMjAgLSA1MDtcclxuXHR9XHJcblx0dGFyZ2V0T2Zmc2V0ICs9IGV4dHJhX3NoaWZ0X29mZnNldDtcclxuXHJcblx0Ly8gU2Nyb2xsIG9ubHkgIGlmIHdlIGRpZCBub3Qgc2Nyb2xsIGJlZm9yZVxyXG5cdGlmICggISBqUXVlcnkoICdodG1sLGJvZHknICkuaXMoICc6YW5pbWF0ZWQnICkgKXtcclxuXHRcdGpRdWVyeSggJ2h0bWwsYm9keScgKS5hbmltYXRlKCB7c2Nyb2xsVG9wOiB0YXJnZXRPZmZzZXR9LCA1MDAgKTtcclxuXHR9XHJcbn1cclxuXHJcbiIsIlxyXG4vLyBGaXhJbjogMTAuMi4wLjQuXHJcbi8qKlxyXG4gKiBEZWZpbmUgUG9wb3ZlcnMgZm9yIFRpbWVsaW5lcyBpbiBXUCBCb29raW5nIENhbGVuZGFyXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd8Ym9vbGVhbn1cclxuICovXHJcbmZ1bmN0aW9uIHdwYmNfZGVmaW5lX3RpcHB5X3BvcG92ZXIoKXtcclxuXHRpZiAoICdmdW5jdGlvbicgIT09I
3411HR5cGVvZiAod3BiY190aXBweSkgKXtcclxuXHRcdGNvbnNvbGUubG9nKCAnV1BCQyBFcnJvci4gd3BiY190aXBweSB3YXMgbm90IGRlZmluZWQuJyApO1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHR3cGJjX3RpcHB5KCAnLnBvcG92ZXJfYm90dG9tLnBvcG92ZXJfY2xpY2snLCB7XHJcblx0XHRjb250ZW50KCByZWZlcmVuY2UgKXtcclxuXHRcdFx0dmFyIHBvcG92ZXJfdGl0bGUgPSByZWZlcmVuY2UuZ2V0QXR0cmlidXRlKCAnZGF0YS1vcmlnaW5hbC10aXRsZScgKTtcclxuXHRcdFx0dmFyIHBvcG92ZXJfY29udGVudCA9IHJlZmVyZW5jZS5nZXRBdHRyaWJ1dGUoICdkYXRhLWNvbnRlbnQnICk7XHJcblx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cInBvcG92ZXIgcG9wb3Zlcl90aXBweVwiPidcclxuXHRcdFx0XHQrICc8ZGl2IGNsYXNzPVwicG9wb3Zlci1jbG9zZVwiPjxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiBvbmNsaWNrPVwiamF2YXNjcmlwdDp0aGlzLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5fdGlwcHkuaGlkZSgpO1wiID4mdGltZXM7PC9hPjwvZGl2PidcclxuXHRcdFx0XHQrIHBvcG92ZXJfY29udGVudFxyXG5cdFx0XHRcdCsgJzwvZGl2Pic7XHJcblx0XHR9LFxyXG5cdFx0YWxsb3dIVE1MICAgICAgICA6IHRydWUsXHJcblx0XHR0cmlnZ2VyICAgICAgICAgIDogJ21hbnVhbCcsXHJcblx0XHRpbnRlcmFjdGl2ZSAgICAgIDogdHJ1ZSxcclxuXHRcdGhpZGVPbkNsaWNrICAgICAgOiBmYWxzZSxcclxuXHRcdGludGVyYWN0aXZlQm9yZGVyOiAxMCxcclxuXHRcdG1heFdpZHRoICAgICAgICAgOiA1NTAsXHJcblx0XHR0aGVtZSAgICAgICAgICAgIDogJ3dwYmMtdGlwcHktcG9wb3ZlcicsXHJcblx0XHRwbGFjZW1lbnQgICAgICAgIDogJ2JvdHRvbS1zdGFydCcsXHJcblx0XHR0b3VjaCAgICAgICAgICAgIDogWydob2xkJywgNTAwXSxcclxuXHR9ICk7XHJcblx0alF1ZXJ5KCAnLnBvcG92ZXJfYm90dG9tLnBvcG92ZXJfY2xpY2snICkub24oICdjbGljaycsIGZ1bmN0aW9uICgpe1xyXG5cdFx0aWYgKCB0aGlzLl90
3411aXBweS5zdGF0ZS5pc1Zpc2libGUgKXtcclxuXHRcdFx0dGhpcy5fdGlwcHkuaGlkZSgpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5fdGlwcHkuc2hvdygpO1xyXG5cdFx0fVxyXG5cdH0gKTtcclxuXHR3cGJjX2RlZmluZV9oaWRlX3RpcHB5X29uX3Njcm9sbCgpO1xyXG59XHJcblxyXG5cclxuXHJcbmZ1bmN0aW9uIHdwYmNfZGVmaW5lX2hpZGVfdGlwcHlfb25fc2Nyb2xsKCl7XHJcblx0alF1ZXJ5KCAnLmZsZXhfdGxfX3Njcm9sbGluZ19zZWN0aW9uMiwuZmxleF90bF9fc2Nyb2xsaW5nX3NlY3Rpb25zJyApLm9uKCAnc2Nyb2xsJywgZnVuY3Rpb24gKCBldmVudCApe1xyXG5cdFx0aWYgKCAnZnVuY3Rpb24nID09PSB0eXBlb2YgKHdwYmNfdGlwcHkpICl7XHJcblx0XHRcdHdwYmNfdGlwcHkuaGlkZUFsbCgpO1xyXG5cdFx0fVxyXG5cdH0gKTtcclxufVxyXG4iXSwibWFwcGluZ3MiOiI7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUEsVUFBQUMsY0FBQTtFQUVBLElBQUFDLEtBQUEsQ0FBQUMsT0FBQSxDQUFBRixjQUFBO0lBQ0FBLGNBQUEsR0FBQUEsY0FBQSxDQUFBRyxJQUFBO0VBQ0E7RUFFQSx1QkFBQUgsY0FBQTtJQUNBQSxjQUFBLEdBQUFBLGNBQUEsQ0FBQUksSUFBQTtFQUNBO0VBRUEsT0FBQUosY0FBQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBQUssY0FBQUMsVUFBQSxFQUFBQyxLQUFBO0VBQ0EsU0FBQUMsQ0FBQSxNQUFBQyxDQUFBLEdBQUFILFVBQUEsQ0FBQUksTUFBQSxFQUFBRixDQUFBLEdBQUFDLENBQUEsRUFBQUQsQ0FBQTtJQUNBLElBQUFGLFVBQUEsQ0FBQUUsQ0FBQSxLQUFBRCxLQUFBO01BQ0E7SUFDQTtFQUNBO0VBQ0E7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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.