PluginProbe
Booking Calendar / 10.1.3
Booking Calendar v10.1.3
11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 All 205 releases
booking / _dist / all / _out / wpbc_all.js

wpbc_all.js in Booking Calendar 10.1.3, at _dist/all/_out/wpbc_all.js

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