PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
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 / includes / booking_modes_v3 / _out / booking_modes.js

booking_modes.js in Booking Calendar 11.9, at includes/booking_modes_v3/_out/booking_modes.js

250 lines 31.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 /* global jQuery, wpbc_booking_modes_config, wpbc_admin_show_message */
4 (function ($) {
5 'use strict';
6
7 var switch_busy = false;
8 var switch_message_storage_key = 'wpbc_booking_modes_v3_switch_success';
9 var switch_message_max_age = 120000;
10
11 /**
12 * Read a user-facing error from a WordPress AJAX response.
13 *
14 * @param {Object|undefined} response Parsed AJAX response.
15 * @param {string|undefined} fallback Optional fallback message.
16 * @return {string} Safe error text.
17 */
18 function get_error_message(response, fallback) {
19 if (response && response.data && typeof response.data.message === 'string' && response.data.message.length) {
20 return response.data.message;
21 }
22 return fallback || wpbc_booking_modes_config.i18n.error;
23 }
24
25 /**
26 * Show a mode-switch error through the existing Booking Calendar notifier.
27 *
28 * @param {string} message Error message.
29 * @param {number|undefined} delay Optional display duration in milliseconds.
30 * @return {void}
31 */
32 function show_error(message, delay) {
33 if (typeof window.wpbc_admin_show_message === 'function') {
34 window.wpbc_admin_show_message(message, 'error', delay || 10000, false);
35 return;
36 }
37 window.alert(message);
38 }
39
40 /**
41 * Show a successful QuickStart message through the existing notifier.
42 *
43 * @param {string} message Success message.
44 * @return {void}
45 */
46 function show_success(message) {
47 if (typeof window.wpbc_admin_show_message === 'function') {
48 window.wpbc_admin_show_message(message, 'success', 10000, false);
49 return;
50 }
51 window.alert(message);
52 }
53
54 /**
55 * Show non-blocking mode-switch progress through the admin notifier.
56 *
57 * The request must continue immediately, so this intentionally has no alert
58 * fallback when the shared Booking Calendar notifier is unavailable.
59 *
60 * @param {string} message Progress message.
61 * @return {void}
62 */
63 function show_info(message) {
64 if (typeof window.wpbc_admin_show_message === 'function') {
65 window.wpbc_admin_show_message(message, 'info', 10000, false);
66 }
67 }
68
69 /**
70 * Show the server-confirmed mode activation before redirecting.
71 *
72 * @param {string} message Success message.
73 * @return {void}
74 */
75 function show_switch_success(message) {
76 if (message && typeof window.wpbc_admin_show_message === 'function') {
77 window.wpbc_admin_show_message(message, 'success', 1500, false);
78 }
79 }
80
81 /**
82 * Save the activated mode for a V1-compatible notice on the final page.
83 *
84 * V3 uses a signed full-administration landing before the final destination,
85 * so an in-page notice shown before navigation would otherwise disappear.
86 * Session storage keeps this presentation-only state out of WordPress data
87 * and naturally isolates it to the tab that initiated the switch.
88 *
89 * @param {string} mode_id Activated mode identifier.
90 * @return {void}
91 */
92 function store_switch_success(mode_id) {
93 var normalized_mode_id = typeof mode_id === 'string' ? mode_id : '';
94 if (!normalized_mode_id) {
95 return;
96 }
97 try {
98 window.sessionStorage.setItem(switch_message_storage_key, JSON.stringify({
99 mode_id: normalized_mode_id,
100 created_at: Date.now()
101 }));
102 } catch (error) {
103 // A blocked or full browser store must never prevent mode switching.
104 }
105 }
106
107 /**
108 * Show and consume the pending switch message on the final WPBC page.
109 *
110 * The record is removed before validation or display so refreshes, malformed
111 * values, account changes, and stale records cannot replay it. Matching the
112 * localized selected mode prevents a notice from leaking into another mode.
113 *
114 * @return {void}
115 */
116 function show_pending_switch_success() {
117 var serialized_message;
118 var pending_message;
119 var current_mode_id = String(wpbc_booking_modes_config.selected_mode_id || '');
120 var success_message = wpbc_booking_modes_config.i18n.switch_success || '';
121 try {
122 serialized_message = window.sessionStorage.getItem(switch_message_storage_key);
123 window.sessionStorage.removeItem(switch_message_storage_key);
124 } catch (error) {
125 return;
126 }
127 if (!serialized_message || !current_mode_id || typeof success_message !== 'string' || !success_message) {
128 return;
129 }
130 try {
131 pending_message = JSON.parse(serialized_message);
132 } catch (error) {
133 return;
134 }
135 if (!pending_message || pending_message.mode_id !== current_mode_id || typeof pending_message.created_at !== 'number' || pending_message.created_at > Date.now() || Date.now() - pending_message.created_at > switch_message_max_age) {
136 return;
137 }
138 show_switch_success(success_message);
139 }
140
141 /**
142 * Toggle the shared switching state and all dropdown choices.
143 *
144 * @param {jQuery} $selector Mode selector container.
145 * @param {boolean} is_busy Whether a mode-switch request is active.
146 * @return {void}
147 */
148 function set_switching_state($selector, is_busy) {
149 switch_busy = is_busy;
150 $selector.toggleClass('is-switching', is_busy);
151 if (is_busy) {
152 $selector.attr('aria-busy', 'true');
153 $selector.find('.wpbc_booking_mode_option').attr('aria-disabled', 'true');
154 return;
155 }
156 $selector.removeAttr('aria-busy');
157 $selector.find('.wpbc_booking_mode_option').removeAttr('aria-disabled');
158 }
159
160 /**
161 * Persist a selected mode and follow the server-approved redirect.
162 *
163 * @param {Event} event Click event for a selector option.
164 * @return {void}
165 */
166 function switch_mode(event) {
167 var $option = $(event.currentTarget);
168 var $selector = $option.closest('.wpbc_booking_modes_selector');
169 var mode_id = String($option.data('mode-id') || '');
170 event.preventDefault();
171 if (switch_busy || !mode_id || $option.hasClass('is-current')) {
172 return;
173 }
174 set_switching_state($selector, true);
175 show_info(wpbc_booking_modes_config.i18n.saving || 'Switching Booking Calendar mode...');
176 $.ajax({
177 url: wpbc_booking_modes_config.ajax_url,
178 method: 'POST',
179 dataType: 'json',
180 data: {
181 action: wpbc_booking_modes_config.action,
182 nonce: wpbc_booking_modes_config.nonce,
183 mode_id: mode_id,
184 origin_url: window.location.href.split('#')[0],
185 fragment: window.location.hash ? window.location.hash.substring(1) : ''
186 }
187 }).done(function (response) {
188 if (!response || response.success !== true || !response.data || typeof response.data.redirect_url !== 'string' || !response.data.redirect_url.length) {
189 set_switching_state($selector, false);
190 show_error(get_error_message(response), 7000);
191 return;
192 }
193 show_switch_success(response.data.message || wpbc_booking_modes_config.i18n.switched);
194 store_switch_success(mode_id);
195 window.location.assign(response.data.redirect_url);
196 }).fail(function (xhr) {
197 set_switching_state($selector, false);
198 show_error(get_error_message(xhr.responseJSON), 7000);
199 });
200 }
201
202 /**
203 * Run a separately confirmed, state-changing QuickStart operation.
204 *
205 * @param {Event} event Click event for a QuickStart button.
206 * @return {void}
207 */
208 function run_quickstart(event) {
209 var $button = $(event.currentTarget);
210 var $actions = $button.closest('.wpbc_booking_modes_quickstart_actions');
211 var mode_id = String($button.data('mode-id') || '');
212 var quickstart = wpbc_booking_modes_config.quickstart || {};
213 event.preventDefault();
214 if (!mode_id || !quickstart.action || !quickstart.nonce || $button.prop('disabled')) {
215 return;
216 }
217 if (!window.confirm(wpbc_booking_modes_config.i18n.quickstart_confirm)) {
218 return;
219 }
220 $button.prop('disabled', true).attr('aria-busy', 'true');
221 $.ajax({
222 url: wpbc_booking_modes_config.ajax_url,
223 method: 'POST',
224 dataType: 'json',
225 data: {
226 action: quickstart.action,
227 nonce: quickstart.nonce,
228 mode_id: mode_id
229 }
230 }).done(function (response) {
231 var $test_page;
232 if (!response || response.success !== true || !response.data || typeof response.data.test_url !== 'string' || !response.data.test_url.length) {
233 show_error(get_error_message(response, wpbc_booking_modes_config.i18n.quickstart_error));
234 return;
235 }
236 $test_page = $actions.find('.wpbc_booking_modes_test_page');
237 $test_page.attr('href', response.data.test_url).removeClass('is-hidden').trigger('focus');
238 show_success(response.data.message || wpbc_booking_modes_config.i18n.test_page);
239 }).fail(function (xhr) {
240 show_error(get_error_message(xhr.responseJSON, wpbc_booking_modes_config.i18n.quickstart_error));
241 }).always(function () {
242 $button.prop('disabled', false).removeAttr('aria-busy');
243 });
244 }
245 $(document).on('click', '.wpbc_booking_mode_option', switch_mode);
246 $(document).on('click', '.wpbc_booking_modes_quickstart_button', run_quickstart);
247 $(show_pending_switch_success);
248 })(jQuery);
249 //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fb3V0L2Jvb2tpbmdfbW9kZXMuanMiLCJuYW1lcyI6WyIkIiwic3dpdGNoX2J1c3kiLCJzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSIsInN3aXRjaF9tZXNzYWdlX21heF9hZ2UiLCJnZXRfZXJyb3JfbWVzc2FnZSIsInJlc3BvbnNlIiwiZmFsbGJhY2siLCJkYXRhIiwibWVzc2FnZSIsImxlbmd0aCIsIndwYmNfYm9va2luZ19tb2Rlc19jb25maWciLCJpMThuIiwiZXJyb3IiLCJzaG93X2Vycm9yIiwiZGVsYXkiLCJ3aW5kb3ciLCJ3cGJjX2FkbWluX3Nob3dfbWVzc2FnZSIsImFsZXJ0Iiwic2hvd19zdWNjZXNzIiwic2hvd19pbmZvIiwic2hvd19zd2l0Y2hfc3VjY2VzcyIsInN0b3JlX3N3aXRjaF9zdWNjZXNzIiwibW9kZV9pZCIsIm5vcm1hbGl6ZWRfbW9kZV9pZCIsInNlc3Npb25TdG9yYWdlIiwic2V0SXRlbSIsIkpTT04iLCJzdHJpbmdpZnkiLCJjcmVhdGVkX2F0IiwiRGF0ZSIsIm5vdyIsInNob3dfcGVuZGluZ19zd2l0Y2hfc3VjY2VzcyIsInNlcmlhbGl6ZWRfbWVzc2FnZSIsInBlbmRpbmdfbWVzc2FnZSIsImN1cnJlbnRfbW9kZV9pZCIsIlN0cmluZyIsInNlbGVjdGVkX21vZGVfaWQiLCJzdWNjZXNzX21lc3NhZ2UiLCJzd2l0Y2hfc3VjY2VzcyIsImdldEl0ZW0iLCJyZW1vdmVJdGVtIiwicGFyc2UiLCJzZXRfc3dpdGNoaW5nX3N0YXRlIiwiJHNlbGVjdG9yIiwiaXNfYnVzeSIsInRvZ2dsZUNsYXNzIiwiYXR0ciIsImZpbmQiLCJyZW1vdmVBdHRyIiwic3dpdGNoX21vZGUiLCJldmVudCIsIiRvcHRpb24iLCJjdXJyZW50VGFyZ2V0IiwiY2xvc2VzdCIsInByZXZlbnREZWZhdWx0IiwiaGFzQ2xhc3MiLCJzYXZpbmciLCJhamF4IiwidXJsIiwiYWpheF91cmwiLCJtZXRob2QiLCJkYXRhVHlwZSIsImFjdGlvbiIsIm5vbmNlIiwib3JpZ2luX3VybCIsImxvY2F0aW9uIiwiaHJlZiIsInNwbGl0IiwiZnJhZ21lbnQiLCJoYXNoIiwic3Vic3RyaW5nIiwiZG9uZSIsInN1Y2Nlc3MiLCJyZWRpcmVjdF91cmwiLCJzd2l0Y2hlZCIsImFzc2lnbiIsImZhaWwiLCJ4aHIiLCJyZXNwb25zZUpTT04iLCJydW5fcXVpY2tzdGFydCIsIiRidXR0b24iLCIkYWN0aW9ucyIsInF1aWNrc3RhcnQiLCJwcm9wIiwiY29uZmlybSIsInF1aWNrc3RhcnRfY29uZmlybSIsIiR0ZXN0X3BhZ2UiLCJ0ZXN0X3VybCIsInF1aWNrc3RhcnRfZXJyb3IiLCJyZW1vdmVDbGFzcyIsInRyaWdnZXIiLCJ0ZXN0X3BhZ2UiLCJhbHdheXMiLCJkb2N1bWVudCIsIm9uIiwialF1ZXJ5Il0sInNvdXJjZXMiOlsiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fc3JjL2Jvb2tpbmdfbW9kZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIGpRdWVyeSwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZywgd3BiY19hZG1pbl9zaG93X21lc3NhZ2UgKi9cbihmdW5jdGlvbiAoJCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIHN3aXRjaF9idXN5ID0gZmFsc2U7XG5cdHZhciBzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSA9ICd3cGJjX2Jvb2tpbmdfbW9kZXNfdjNfc3dpdGNoX3N1Y2Nlc3MnO1xuXHR2YXIgc3dpdGNoX21lc3NhZ2VfbWF4X2FnZSA9IDEyMDAwMDtcblxuXHQvKipcblx0ICogUmVhZCBhIHVzZXItZmFjaW5nIGVycm9yIGZyb20gYSBXb3JkUHJlc3MgQUpBWCByZXNwb25zZS5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSByZXNwb25zZSBQYXJzZWQgQUpBWCByZXNwb25zZS5cblx0ICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBmYWxsYmFjayBPcHRpb25hbCBmYWxsYmFjayBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFNhZmUgZXJyb3IgdGV4dC5cblx0ICovXG5cdGZ1bmN0aW9uIGdldF9lcnJvcl9tZXNzYWdlKHJlc3BvbnNlLCBmYWxsYmFjaykge1xuXHRcdGlmIChcblx0XHRcdHJlc3BvbnNlXG5cdFx0XHQmJiByZXNwb25zZS5kYXRhXG5cdFx0XHQmJiB0eXBlb2YgcmVzcG9uc2UuZGF0YS5tZXNzYWdlID09PSAnc3RyaW5nJ1xuXHRcdFx0JiYgcmVzcG9uc2UuZGF0YS5tZXNzYWdlLmxlbmd0aFxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHJlc3BvbnNlLmRhdGEubWVzc2FnZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsbGJhY2sgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLmVycm9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYSBtb2RlLXN3aXRjaCBlcnJvciB0aHJvdWdoIHRoZSBleGlzdGluZyBCb29raW5nIENhbGVuZGFyIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBFcnJvciBtZXNzYWdlLlxuXHQgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IGRlbGF5IE9wdGlvbmFsIGRpc3BsYXkgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19lcnJvcihtZXNzYWdlLCBkZWxheSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ2Vycm9yJywgZGVsYXkgfHwgMTAwMDAsIGZhbHNlKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR3aW5kb3cuYWxlcnQobWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2hvdyBhIHN1Y2Nlc3NmdWwgUXVpY2tTdGFydCBtZXNzYWdlIHRocm91Z2ggdGhlIGV4aXN0aW5nIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBTdWNjZXNzIG1lc3NhZ2UuXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3N1Y2Nlc3MobWVzc2FnZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ3N1Y2Nlc3MnLCAxMDAwMCwgZmFsc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHdpbmRvdy5hbGVydChtZXNzYWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTaG93IG5vbi1ibG9ja2luZyBtb2RlLXN3aXRjaCBwcm9ncmVzcyB0aHJvdWdoIHRoZSBhZG1pbiBub3RpZmllci5cblx0ICpcblx0ICogVGhlIHJlcXVlc3QgbXVzdCBjb250aW51ZSBpbW1lZGlhdGVseSwgc28gdGhpcyBpbnRlbnRpb25hbGx5IGhhcyBubyBhbGVydFxuXHQgKiBmYWxsYmFjayB3aGVuIHRoZSBzaGFyZWQgQm9va2luZyBDYWxlbmRhciBub3RpZmllciBpcyB1bmF2YWlsYWJsZS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgUHJvZ3Jlc3MgbWVzc2FnZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNob3dfaW5mbyhtZXNzYWdlKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZShtZXNzYWdlLCAnaW5mbycsIDEwMDAwLCBmYWxzZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIHNlcnZlci1jb25maXJtZWQgbW9kZSBhY3RpdmF0aW9uIGJlZm9yZSByZWRpcmVjdGluZy5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgU3VjY2VzcyBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19zd2l0Y2hfc3VjY2VzcyhtZXNzYWdlKSB7XG5cdFx0aWYgKG1lc3NhZ2UgJiYgdHlwZW9mIHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0d2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlKG1lc3NhZ2UsICdzdWNjZXNzJywgMTUwMCwgZmFsc2UpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIHRoZSBhY3RpdmF0ZWQgbW9kZSBmb3IgYSBWMS1jb21wYXRpYmxlIG5vdGljZSBvbiB0aGUgZmluYWwgcGFnZS5cblx0ICpcblx0ICogVjMgdXNlcyBhIHNpZ25lZCBmdWxsLWFkbWluaXN0cmF0aW9uIGxhbmRpbmcgYmVmb3JlIHRoZSBmaW5hbCBkZXN0aW5hdGlvbixcblx0ICogc28gYW4gaW4tcGFnZSBub3RpY2Ugc2hvd24gYmVmb3JlIG5hdmlnYXRpb24gd291bGQgb3RoZXJ3aXNlIGRpc2FwcGVhci5cblx0ICogU2Vzc2lvbiBzdG9yYWdlIGtlZXBzIHRoaXMgcHJlc2VudGF0aW9uLW9ubHkgc3RhdGUgb3V0IG9mIFdvcmRQcmVzcyBkYXRhXG5cdCAqIGFuZCBuYXR1cmFsbHkgaXNvbGF0ZXMgaXQgdG8gdGhlIHRhYiB0aGF0IGluaXRpYXRlZCB0aGUgc3dpdGNoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbW9kZV9pZCBBY3RpdmF0ZWQgbW9kZSBpZGVudGlmaWVyLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc3RvcmVfc3dpdGNoX3N1Y2Nlc3MobW9kZV9pZCkge1xuXHRcdHZhciBub3JtYWxpemVkX21vZGVfaWQgPSB0eXBlb2YgbW9kZV9pZCA9PT0gJ3N0cmluZycgPyBtb2RlX2lkIDogJyc7XG5cblx0XHRpZiAoIW5vcm1hbGl6ZWRfbW9kZV9pZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHR3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcblx0XHRcdFx0c3dpdGNoX21lc3NhZ2Vfc3RvcmFnZV9rZXksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0XHRtb2RlX2lkOiBub3JtYWxpemVkX21vZGVfaWQsXG5cdFx0XHRcdFx0Y3JlYXRlZF9hdDogRGF0ZS5ub3coKVxuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0Ly8gQSBibG9ja2VkIG9yIGZ1bGwgYnJvd3NlciBzdG9yZSBtdXN0IG5ldmVyIHByZXZlbnQgbW9kZSBzd2l0Y2hpbmcuXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYW5kIGNvbnN1bWUgdGhlIHBlbmRpbmcgc3dpdGNoIG1lc3NhZ2Ugb24gdGhlIGZpbmFsIFdQQkMgcGFnZS5cblx0ICpcblx0ICogVGhlIHJlY29yZCBpcyByZW1vdmVkIGJlZm9yZSB2YWxpZGF0aW9uIG9yIGRpc3BsYXkgc28gcmVmcmVzaGVzLCBtYWxmb3JtZWRcblx0ICogdmFsdWVzLCBhY2NvdW50IGNoYW5nZXMsIGFuZCBzdGFsZSByZWNvcmRzIGNhbm5vdCByZXBsYXkgaXQuIE1hdGNoaW5nIHRoZVxuXHQgKiBsb2NhbGl6ZWQgc2VsZWN0ZWQgbW9kZSBwcmV2ZW50cyBhIG5vdGljZSBmcm9tIGxlYWtpbmcgaW50byBhbm90aGVyIG1vZGUuXG5cdCAqXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3BlbmRpbmdfc3dpdGNoX3N1Y2Nlc3MoKSB7XG5cdFx0dmFyIHNlcmlhbGl6ZWRfbWVzc2FnZTtcblx0XHR2YXIgcGVuZGluZ19tZXNzYWdlO1xuXHRcdHZhciBjdXJyZW50X21vZGVfaWQgPSBTdHJpbmcod3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5zZWxlY3RlZF9tb2RlX2lkIHx8ICcnKTtcblx0XHR2YXIgc3VjY2Vzc19tZXNzYWdlID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnN3aXRjaF9zdWNjZXNzIHx8ICcnO1xuXG5cdFx0dHJ5IHtcblx0XHRcdHNlcmlhbGl6ZWRfbWVzc2FnZSA9IHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHRcdHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghc2VyaWFsaXplZF9tZXNzYWdlIHx8ICFjdXJyZW50X21vZGVfaWQgfHwgdHlwZW9mIHN1Y2Nlc3NfbWVzc2FnZSAhPT0gJ3N0cmluZycgfHwgIXN1Y2Nlc3NfbWVzc2FnZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRwZW5kaW5nX21lc3NhZ2UgPSBKU09OLnBhcnNlKHNlcmlhbGl6ZWRfbWVzc2FnZSk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHQhcGVuZGluZ19tZXNzYWdlXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UubW9kZV9pZCAhPT0gY3VycmVudF9tb2RlX2lkXG5cdFx0XHR8fCB0eXBlb2YgcGVuZGluZ19tZXNzYWdlLmNyZWF0ZWRfYXQgIT09ICdudW1iZXInXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IERhdGUubm93KClcblx0XHRcdHx8IERhdGUubm93KCkgLSBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IHN3aXRjaF9tZXNzYWdlX21heF9hZ2Vcblx0XHQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRzaG93X3N3aXRjaF9zdWNjZXNzKHN1Y2Nlc3NfbWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIHRoZSBzaGFyZWQgc3dpdGNoaW5nIHN0YXRlIGFuZCBhbGwgZHJvcGRvd24gY2hvaWNlcy5cblx0ICpcblx0ICogQHBhcmFtIHtqUXVlcnl9ICRzZWxlY3RvciBNb2RlIHNlbGVjdG9yIGNvbnRhaW5lci5cblx0ICogQHBhcmFtIHtib29sZWFufSBpc19idXN5IFdoZXRoZXIgYSBtb2RlLXN3aXRjaCByZXF1ZXN0IGlzIGFjdGl2ZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCBpc19idXN5KSB7XG5cdFx0c3dpdGNoX2J1c3kgPSBpc19idXN5O1xuXHRcdCRzZWxlY3Rvci50b2dnbGVDbGFzcygnaXMtc3dpdGNoaW5nJywgaXNfYnVzeSk7XG5cblx0XHRpZiAoaXNfYnVzeSkge1xuXHRcdFx0JHNlbGVjdG9yLmF0dHIoJ2FyaWEtYnVzeScsICd0cnVlJyk7XG5cdFx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAndHJ1ZScpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRzZWxlY3Rvci5yZW1vdmVBdHRyKCdhcmlhLWJ1c3knKTtcblx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLnJlbW92ZUF0dHIoJ2FyaWEtZGlzYWJsZWQnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQZXJzaXN0IGEgc2VsZWN0ZWQgbW9kZSBhbmQgZm9sbG93IHRoZSBzZXJ2ZXItYXBwcm92ZWQgcmVkaXJlY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IENsaWNrIGV2ZW50IGZvciBhIHNlbGVjdG9yIG9wdGlvbi5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHN3aXRjaF9tb2RlKGV2ZW50KSB7XG5cdFx0dmFyICRvcHRpb24gPSAkKGV2ZW50LmN1cnJlbnRUYXJnZXQpO1xuXHRcdHZhciAkc2VsZWN0b3IgPSAkb3B0aW9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfc2VsZWN0b3InKTtcblx0XHR2YXIgbW9kZV9pZCA9IFN0cmluZygkb3B0aW9uLmRhdGEoJ21vZGUtaWQnKSB8fCAnJyk7XG5cblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0aWYgKHN3aXRjaF9idXN5IHx8ICFtb2RlX2lkIHx8ICRvcHRpb24uaGFzQ2xhc3MoJ2lzLWN1cnJlbnQnKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCB0cnVlKTtcblx0XHRzaG93X2luZm8od3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnNhdmluZyB8fCAnU3dpdGNoaW5nIEJvb2tpbmcgQ2FsZW5kYXIgbW9kZS4uLicpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiB3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWQsXG5cdFx0XHRcdG9yaWdpbl91cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0sXG5cdFx0XHRcdGZyYWdtZW50OiB3aW5kb3cubG9jYXRpb24uaGFzaCA/IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cmluZygxKSA6ICcnXG5cdFx0XHR9XG5cdFx0fSkuZG9uZShmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEucmVkaXJlY3RfdXJsICE9PSAnc3RyaW5nJ1xuXHRcdFx0XHR8fCAhcmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwubGVuZ3RoXG5cdFx0XHQpIHtcblx0XHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdFx0c2hvd19lcnJvcihnZXRfZXJyb3JfbWVzc2FnZShyZXNwb25zZSksIDcwMDApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHNob3dfc3dpdGNoX3N1Y2Nlc3MocmVzcG9uc2UuZGF0YS5tZXNzYWdlIHx8IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5zd2l0Y2hlZCk7XG5cdFx0XHRzdG9yZV9zd2l0Y2hfc3VjY2Vzcyhtb2RlX2lkKTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5hc3NpZ24ocmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwpO1xuXHRcdH0pLmZhaWwoZnVuY3Rpb24gKHhocikge1xuXHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UoeGhyLnJlc3BvbnNlSlNPTiksIDcwMDApO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJ1biBhIHNlcGFyYXRlbHkgY29uZmlybWVkLCBzdGF0ZS1jaGFuZ2luZyBRdWlja1N0YXJ0IG9wZXJhdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgQ2xpY2sgZXZlbnQgZm9yIGEgUXVpY2tTdGFydCBidXR0b24uXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBydW5fcXVpY2tzdGFydChldmVudCkge1xuXHRcdHZhciAkYnV0dG9uID0gJChldmVudC5jdXJyZW50VGFyZ2V0KTtcblx0XHR2YXIgJGFjdGlvbnMgPSAkYnV0dG9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9hY3Rpb25zJyk7XG5cdFx0dmFyIG1vZGVfaWQgPSBTdHJpbmcoJGJ1dHRvbi5kYXRhKCdtb2RlLWlkJykgfHwgJycpO1xuXHRcdHZhciBxdWlja3N0YXJ0ID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5xdWlja3N0YXJ0IHx8IHt9O1xuXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdGlmICghbW9kZV9pZCB8fCAhcXVpY2tzdGFydC5hY3Rpb24gfHwgIXF1aWNrc3RhcnQubm9uY2UgfHwgJGJ1dHRvbi5wcm9wKCdkaXNhYmxlZCcpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCF3aW5kb3cuY29uZmlybSh3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmkxOG4ucXVpY2tzdGFydF9jb25maXJtKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCB0cnVlKS5hdHRyKCdhcmlhLWJ1c3knLCAndHJ1ZScpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiBxdWlja3N0YXJ0LmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHF1aWNrc3RhcnQubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWRcblx0XHRcdH1cblx0XHR9KS5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHRcdFx0dmFyICR0ZXN0X3BhZ2U7XG5cblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEudGVzdF91cmwgIT09ICdzdHJpbmcnXG5cdFx0XHRcdHx8ICFyZXNwb25zZS5kYXRhLnRlc3RfdXJsLmxlbmd0aFxuXHRcdFx0KSB7XG5cdFx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UocmVzcG9uc2UsIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0JHRlc3RfcGFnZSA9ICRhY3Rpb25zLmZpbmQoJy53cGJjX2Jvb2tpbmdfbW9kZXNfdGVzdF9wYWdlJyk7XG5cdFx0XHQkdGVzdF9wYWdlLmF0dHIoJ2hyZWYnLCByZXNwb25zZS5kYXRhLnRlc3RfdXJsKS5yZW1vdmVDbGFzcygnaXMtaGlkZGVuJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdHNob3dfc3VjY2VzcyhyZXNwb25zZS5kYXRhLm1lc3NhZ2UgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnRlc3RfcGFnZSk7XG5cdFx0fSkuZmFpbChmdW5jdGlvbiAoeGhyKSB7XG5cdFx0XHRzaG93X2Vycm9yKGdldF9lcnJvcl9tZXNzYWdlKHhoci5yZXNwb25zZUpTT04sIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0fSkuYWx3YXlzKGZ1bmN0aW9uICgpIHtcblx0XHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSkucmVtb3ZlQXR0cignYXJpYS1idXN5Jyk7XG5cdFx0fSk7XG5cdH1cblxuXHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicsIHN3aXRjaF9tb2RlKTtcblx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9idXR0b24nLCBydW5fcXVpY2tzdGFydCk7XG5cdCQoc2hvd19wZW5kaW5nX3N3aXRjaF9zdWNjZXNzKTtcbn0oalF1ZXJ5KSk7XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQyxXQUFVQSxDQUFDLEVBQUU7RUFDYixZQUFZOztFQUVaLElBQUlDLFdBQVcsR0FBRyxLQUFLO0VBQ3ZCLElBQUlDLDBCQUEwQixHQUFHLHNDQUFzQztFQUN2RSxJQUFJQyxzQkFBc0IsR0FBRyxNQUFNOztFQUVuQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLGlCQUFpQkEsQ0FBQ0MsUUFBUSxFQUFFQyxRQUFRLEVBQUU7SUFDOUMsSUFDQ0QsUUFBUSxJQUNMQSxRQUFRLENBQUNFLElBQUksSUFDYixPQUFPRixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTyxLQUFLLFFBQVEsSUFDekNILFFBQVEsQ0FBQ0UsSUFBSSxDQUFDQyxPQUFPLENBQUNDLE1BQU0sRUFDOUI7TUFDRCxPQUFPSixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTztJQUM3QjtJQUVBLE9BQU9GLFFBQVEsSUFBSUkseUJBQXlCLENBQUNDLElBQUksQ0FBQ0MsS0FBSztFQUN4RDs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLFVBQVVBLENBQUNMLE9BQU8sRUFBRU0sS0FBSyxFQUFFO0lBQ25DLElBQUksT0FBT0MsTUFBTSxDQUFDQyx1QkFBdUIsS0FBSyxVQUFVLEVBQUU7TUFDekRELE1BQU0sQ0FBQ0MsdUJBQXVCLENBQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUVNLEtBQUssSUFBSSxLQUFLLEVBQUUsS0FBSyxDQUFDO01BQ3ZFO0lBQ0Q7SUFFQUMsTUFBTSxDQUFDRSxLQUFLLENBQUNULE9BQU8sQ0FBQztFQUN0Qjs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDQyxTQUFTVSxZQUFZQSxDQUFDVixPQUFPLEVBQUU7SUFDOUIsSUFB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
250