PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.6.2
JetFormBuilder — Dynamic Blocks Form Builder v3.6.2
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / assets / build / frontend / calculated.field.js
jetformbuilder / assets / build / frontend Last commit date
advanced.reporting.asset.php 1 month ago advanced.reporting.js 1 month ago calculated.field.asset.php 1 month ago calculated.field.js 1 month ago conditional.block.asset.php 1 month ago conditional.block.js 1 month ago dynamic.value.asset.php 1 month ago dynamic.value.js 1 month ago main.asset.php 1 month ago main.css 1 month ago main.js 1 month ago media.field.asset.php 1 month ago media.field.js 1 month ago media.field.restrictions.asset.php 1 month ago media.field.restrictions.js 1 month ago multi.step.asset.php 1 month ago multi.step.js 1 month ago
calculated.field.js
370 lines
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ "./frontend/calculated.field/functions.js"
6 /*!************************************************!*\
7 !*** ./frontend/calculated.field/functions.js ***!
8 \************************************************/
9 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ convertMillisToDateString: () => (/* binding */ convertMillisToDateString),
14 /* harmony export */ getCalculatedWrapper: () => (/* binding */ getCalculatedWrapper),
15 /* harmony export */ isCalculated: () => (/* binding */ isCalculated)
16 /* harmony export */ });
17 function getCalculatedWrapper(node) {
18 return node.closest('.jet-form-builder__calculated-field');
19 }
20
21 /**
22 * @param node {HTMLElement}
23 * @return {boolean}
24 */
25 function isCalculated(node) {
26 var _getCalculatedWrapper;
27 return !!((_getCalculatedWrapper = getCalculatedWrapper(node)?.dataset?.formula?.length) !== null && _getCalculatedWrapper !== void 0 ? _getCalculatedWrapper : '');
28 }
29
30 /**
31 * Formats milliseconds into a string according to the specified format.
32 *
33 * Supported placeholders:
34 * YYYY — 4-digit year (2024)
35 * MM — month with leading zero (01–12)
36 * M — month without leading zero (1–12)
37 * MMM — abbreviated month name (Jan–Dec)
38 * MMMM — full month name (January–December)
39 * DD — day of month with leading zero (01–31)
40 * D — day of month without leading zero (1–31)
41 * HH — hours with leading zero (00–23) in 24-hour format
42 * H — hours without leading zero (0–23) in 24-hour format
43 * hh — hours with leading zero (01–12) in 12-hour format
44 * h — hours without leading zero (1–12) in 12-hour format
45 * mm — minutes with leading zero (00–59)
46 * m — minutes without leading zero (0–59)
47 * ss — seconds with leading zero (00–59)
48 * s — seconds without leading zero (0–59)
49 * dddd — full day of week name (Monday–Sunday)
50 * ddd — abbreviated day of week name (Mon–Sun)
51 * A — AM/PM designation
52 *
53 * @param {number|string} millisInput — milliseconds
54 * @param {string} format — format string
55 * @returns {string|number}
56 */
57 function convertMillisToDateString(millisInput, format = 'YYYY-MM-DD') {
58 const millis = eval(millisInput);
59 if (!millis || isNaN(millis) || null === millis || 0 === millis) {
60 return 0;
61 }
62 const date = new Date(millis);
63 const monthsFull = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
64 const monthsShort = monthsFull.map(m => m.slice(0, 3));
65 const daysFull = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
66 const daysShort = daysFull.map(d => d.slice(0, 3));
67 const hours12 = date.getHours() % 12 || 12; // Convert 0 to 12 for 12-hour format
68 const ampm = date.getHours() >= 12 ? 'PM' : 'AM';
69 const map = {
70 YYYY: date.getFullYear(),
71 MM: String(date.getMonth() + 1).padStart(2, '0'),
72 M: date.getMonth() + 1,
73 MMM: monthsShort[date.getMonth()],
74 MMMM: monthsFull[date.getMonth()],
75 DD: String(date.getDate()).padStart(2, '0'),
76 D: date.getDate(),
77 HH: String(date.getHours()).padStart(2, '0'),
78 H: date.getHours(),
79 hh: String(hours12).padStart(2, '0'),
80 // 12-hour format with leading zero
81 h: hours12,
82 // 12-hour format without leading zero
83 mm: String(date.getMinutes()).padStart(2, '0'),
84 m: date.getMinutes(),
85 ss: String(date.getSeconds()).padStart(2, '0'),
86 s: date.getSeconds(),
87 dddd: daysFull[date.getDay()],
88 ddd: daysShort[date.getDay()],
89 A: ampm // AM/PM
90 };
91 const sortedKeys = Object.keys(map).sort((a, b) => b.length - a.length);
92
93 // Use temporary placeholders to prevent conflicts
94 let formatted = format;
95 const placeholders = {};
96
97 // First pass: replace format tokens with unique placeholders
98 sortedKeys.forEach((key, index) => {
99 const placeholder = `\x00${index}\x00`; // Use index-based unique identifier
100 placeholders[placeholder] = String(map[key]);
101
102 // Use word boundaries for single-letter tokens to avoid replacing letters in text
103 const pattern = key.length <= 2 && /^[a-zA-Z]+$/.test(key) ? new RegExp(`\\b${key}\\b`, 'g') : new RegExp(key, 'g');
104 formatted = formatted.replace(pattern, placeholder);
105 });
106
107 // Second pass: replace placeholders with actual values
108 for (const [placeholder, value] of Object.entries(placeholders)) {
109 formatted = formatted.split(placeholder).join(value);
110 }
111 return formatted;
112 }
113
114
115 /***/ },
116
117 /***/ "./frontend/calculated.field/input.js"
118 /*!********************************************!*\
119 !*** ./frontend/calculated.field/input.js ***!
120 \********************************************/
121 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
122
123 __webpack_require__.r(__webpack_exports__);
124 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
125 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
126 /* harmony export */ });
127 /* harmony import */ var _functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./functions */ "./frontend/calculated.field/functions.js");
128 var _window$JetFormBuilde;
129
130 const {
131 InputData,
132 CalculatedFormula
133 } = window.JetFormBuilderAbstract;
134 const {
135 applyFilters
136 } = JetPlugins.hooks;
137 const {
138 applyFilters: deprecatedApplyFilters = false
139 } = (_window$JetFormBuilde = window?.JetFormBuilderMain?.filters) !== null && _window$JetFormBuilde !== void 0 ? _window$JetFormBuilde : {};
140
141 // eslint-disable-next-line max-lines-per-function
142 function CalculatedData() {
143 InputData.call(this);
144 this.formula = '';
145 this.precision = 0;
146 this.sepDecimal = '';
147 this.sepThousands = '';
148 this.visibleValNode = null;
149 this.valueTypeProp = 'number';
150 this.isSupported = function (node) {
151 return (0,_functions__WEBPACK_IMPORTED_MODULE_0__.isCalculated)(node);
152 };
153 this.setValue = function () {
154 const formula = new CalculatedFormula(this, {
155 forceFunction: true
156 });
157 formula.observe(this.formula);
158 formula.setResult = () => {
159 if ('date' === this.valueTypeProp) {
160 const date_formula = formula.calculate();
161 this.value.current = (0,_functions__WEBPACK_IMPORTED_MODULE_0__.convertMillisToDateString)(date_formula, this.dateFormat);
162 } else {
163 this.value.current = formula.calculate();
164 }
165 };
166 formula.relatedCallback = input => {
167 const value = applyFilters('jet.fb.calculated.callback', false, input, this);
168 if (false !== value) {
169 return value;
170 }
171 const response = 'number' === this.valueTypeProp ? input.calcValue : input.value.current;
172 if (false === deprecatedApplyFilters) {
173 return response;
174 }
175 const filterResult = deprecatedApplyFilters('forms/calculated-field-value', input.value.current, jQuery(input.nodes[0]));
176 return filterResult === input.value.current ? response : filterResult;
177 };
178 formula.emptyValue = () => 'number' === this.valueTypeProp ? 0 : '';
179 formula.setResult();
180 this.value.current = this.value.applySanitizers(this.value.current);
181 this.beforeSubmit(resolve => {
182 this.value.silence();
183 this.value.current = null;
184 this.value.silence();
185 formula.setResult();
186 resolve();
187 }, this);
188 };
189 this.setNode = function (node) {
190 InputData.prototype.setNode.call(this, node);
191 InputData.prototype.reQueryValue = () => {};
192 const {
193 formula,
194 precision,
195 sepDecimal,
196 valueType,
197 sepThousands,
198 dateFormat
199 } = (0,_functions__WEBPACK_IMPORTED_MODULE_0__.getCalculatedWrapper)(node).dataset;
200 this.formula = formula;
201 this.precision = +precision;
202 this.sepDecimal = sepDecimal !== null && sepDecimal !== void 0 ? sepDecimal : '';
203 this.sepThousands = sepThousands !== null && sepThousands !== void 0 ? sepThousands : '';
204 this.visibleValNode = node.nextElementSibling;
205 this.valueTypeProp = valueType;
206 this.dateFormat = dateFormat;
207 this.inputType = 'calculated';
208 };
209 this.addListeners = function () {
210 // silence is golden
211 };
212
213 // calculated field can't be validated
214 this.report = () => {};
215 this.reQueryValue = () => {};
216 this.revertValue = () => {};
217 }
218 CalculatedData.prototype = Object.create(InputData.prototype);
219 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CalculatedData);
220
221 /***/ },
222
223 /***/ "./frontend/calculated.field/signal.js"
224 /*!*********************************************!*\
225 !*** ./frontend/calculated.field/signal.js ***!
226 \*********************************************/
227 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
228
229 __webpack_require__.r(__webpack_exports__);
230 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
231 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
232 /* harmony export */ });
233 /* harmony import */ var _functions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./functions */ "./frontend/calculated.field/functions.js");
234
235 const {
236 BaseSignal
237 } = window.JetFormBuilderAbstract;
238
239 /**
240 * @property {CalculatedData} input Related input instance
241 */
242 function SignalCalculated() {
243 BaseSignal.call(this);
244 this.isSupported = function (node) {
245 return (0,_functions__WEBPACK_IMPORTED_MODULE_0__.isCalculated)(node);
246 };
247 this.baseSignal = function () {
248 const [node] = this.input.nodes;
249 const isNumber = 'number' === this.input.valueTypeProp;
250 this.input.calcValue = isNumber ? this.withPrecision() : this.input.value.current;
251 this.input.value.silence();
252 this.input.value.current = isNumber ? this.convertValue() : this.input.value.current;
253 this.input.value.silence();
254 this.input.visibleValNode.textContent = this.input.value.current;
255 node.value = this.input.calcValue;
256 };
257 this.runSignal = function () {
258 this.baseSignal();
259 const [node] = this.input.nodes;
260 this.triggerJQuery(node);
261 };
262 }
263 SignalCalculated.prototype = Object.create(BaseSignal.prototype);
264 SignalCalculated.prototype.convertValue = function () {
265 const value = this.input.value.current;
266 if (Number.isNaN(Number(value))) {
267 return 0;
268 }
269 const parts = this.withPrecision().toString().split('.');
270 if (this.input.sepThousands) {
271 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.input.sepThousands);
272 }
273 return parts.join(this.input.sepDecimal);
274 };
275 SignalCalculated.prototype.withPrecision = function () {
276 return Number(this.input.value.current).toFixed(this.input.precision);
277 };
278 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SignalCalculated);
279
280 /***/ }
281
282 /******/ });
283 /************************************************************************/
284 /******/ // The module cache
285 /******/ var __webpack_module_cache__ = {};
286 /******/
287 /******/ // The require function
288 /******/ function __webpack_require__(moduleId) {
289 /******/ // Check if module is in cache
290 /******/ var cachedModule = __webpack_module_cache__[moduleId];
291 /******/ if (cachedModule !== undefined) {
292 /******/ return cachedModule.exports;
293 /******/ }
294 /******/ // Create a new module (and put it into the cache)
295 /******/ var module = __webpack_module_cache__[moduleId] = {
296 /******/ // no module.id needed
297 /******/ // no module.loaded needed
298 /******/ exports: {}
299 /******/ };
300 /******/
301 /******/ // Execute the module function
302 /******/ if (!(moduleId in __webpack_modules__)) {
303 /******/ delete __webpack_module_cache__[moduleId];
304 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
305 /******/ e.code = 'MODULE_NOT_FOUND';
306 /******/ throw e;
307 /******/ }
308 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
309 /******/
310 /******/ // Return the exports of the module
311 /******/ return module.exports;
312 /******/ }
313 /******/
314 /************************************************************************/
315 /******/ /* webpack/runtime/define property getters */
316 /******/ (() => {
317 /******/ // define getter functions for harmony exports
318 /******/ __webpack_require__.d = (exports, definition) => {
319 /******/ for(var key in definition) {
320 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
321 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
322 /******/ }
323 /******/ }
324 /******/ };
325 /******/ })();
326 /******/
327 /******/ /* webpack/runtime/hasOwnProperty shorthand */
328 /******/ (() => {
329 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
330 /******/ })();
331 /******/
332 /******/ /* webpack/runtime/make namespace object */
333 /******/ (() => {
334 /******/ // define __esModule on exports
335 /******/ __webpack_require__.r = (exports) => {
336 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
337 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
338 /******/ }
339 /******/ Object.defineProperty(exports, '__esModule', { value: true });
340 /******/ };
341 /******/ })();
342 /******/
343 /************************************************************************/
344 var __webpack_exports__ = {};
345 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
346 (() => {
347 /*!*******************************************!*\
348 !*** ./frontend/calculated.field/main.js ***!
349 \*******************************************/
350 __webpack_require__.r(__webpack_exports__);
351 /* harmony import */ var _input__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./input */ "./frontend/calculated.field/input.js");
352 /* harmony import */ var _signal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./signal */ "./frontend/calculated.field/signal.js");
353
354
355 const {
356 addFilter
357 } = JetPlugins.hooks;
358 addFilter('jet.fb.inputs', 'jet-form-builder/calculated-field', function (inputs) {
359 inputs = [_input__WEBPACK_IMPORTED_MODULE_0__["default"], ...inputs];
360 return inputs;
361 });
362 addFilter('jet.fb.signals', 'jet-form-builder/calculated-field', function (signals) {
363 signals = [_signal__WEBPACK_IMPORTED_MODULE_1__["default"], ...signals];
364 return signals;
365 });
366 })();
367
368 /******/ })()
369 ;
370 //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJvbnRlbmQvY2FsY3VsYXRlZC5maWVsZC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBRUE7QUFJQTtBQUVBO0FBSUE7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7OztBQy9HQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUVBO0FBSUE7QUFDQTtBQUNBO0FBRUE7QUFNQTtBQUdBO0FBRUE7QUFHQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7O0FBR0E7QUFDQTtBQUVBO0FBRUE7QUFDQTtBQUVBO0FBRUE7Ozs7Ozs7Ozs7Ozs7OztBQzNIQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUVBO0FBRUE7QUFJQTtBQUNBO0FBR0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTtBQUVBO0FBQ0E7QUFJQTtBQUVBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7Ozs7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBOzs7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDTkE7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUVBO0FBSUE7QUFFQTtBQUNBO0FBR0E7QUFJQTtBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qZmIvLi9mcm9udGVuZC9jYWxjdWxhdGVkLmZpZWxkL2Z1bmN0aW9ucy5qcyIsIndlYnBhY2s6Ly9qZmIvLi9mcm9udGVuZC9jYWxjdWxhdGVkLmZpZWxkL2lucHV0LmpzIiwid2VicGFjazovL2pmYi8uL2Zyb250ZW5kL2NhbGN1bGF0ZWQuZmllbGQvc2lnbmFsLmpzIiwid2VicGFjazovL2pmYi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9qZmIvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL2pmYi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL2pmYi93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL2pmYi8uL2Zyb250ZW5kL2NhbGN1bGF0ZWQuZmllbGQvbWFpbi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApIHtcblx0cmV0dXJuIG5vZGUuY2xvc2VzdCggJy5qZXQtZm9ybS1idWlsZGVyX19jYWxjdWxhdGVkLWZpZWxkJyApO1xufVxuXG4vKipcbiAqIEBwYXJhbSAgbm9kZSB7SFRNTEVsZW1lbnR9XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0NhbGN1bGF0ZWQoIG5vZGUgKSB7XG5cdHJldHVybiAhIShcblx0XHRnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApPy5kYXRhc2V0Py5mb3JtdWxhPy5sZW5ndGggPz8gJydcblx0KTtcbn1cblxuLyoqXG4gKiBGb3JtYXRzIG1pbGxpc2Vjb25kcyBpbnRvIGEgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGZvcm1hdC5cbiAqXG4gKiBTdXBwb3J0ZWQgcGxhY2Vob2xkZXJzOlxuICogWVlZWSDigJQgNC1kaWdpdCB5ZWFyICgyMDI0KVxuICogTU0gICDigJQgbW9udGggd2l0aCBsZWFkaW5nIHplcm8gKDAx4oCTMTIpXG4gKiBNICAgIOKAlCBtb250aCB3aXRob3V0IGxlYWRpbmcgemVybyAoMeKAkzEyKVxuICogTU1NICDigJQgYWJicmV2aWF0ZWQgbW9udGggbmFtZSAoSmFu4oCTRGVjKVxuICogTU1NTSDigJQgZnVsbCBtb250aCBuYW1lIChKYW51YXJ54oCTRGVjZW1iZXIpXG4gKiBERCAgIOKAlCBkYXkgb2YgbW9udGggd2l0aCBsZWFkaW5nIHplcm8gKDAx4oCTMzEpXG4gKiBEICAgIOKAlCBkYXkgb2YgbW9udGggd2l0aG91dCBsZWFkaW5nIHplcm8gKDHigJMzMSlcbiAqIEhIICAg4oCUIGhvdXJzIHdpdGggbGVhZGluZyB6ZXJvICgwMOKAkzIzKSBpbiAyNC1ob3VyIGZvcm1hdFxuICogSCAgICDigJQgaG91cnMgd2l0aG91dCBsZWFkaW5nIHplcm8gKDDigJMyMykgaW4gMjQtaG91ciBmb3JtYXRcbiAqIGhoICAg4oCUIGhvdXJzIHdpdGggbGVhZGluZyB6ZXJvICgwMeKAkzEyKSBpbiAxMi1ob3VyIGZvcm1hdFxuICogaCAgICDigJQgaG91cnMgd2l0aG91dCBsZWFkaW5nIHplcm8gKDHigJMxMikgaW4gMTItaG91ciBmb3JtYXRcbiAqIG1tICAg4oCUIG1pbnV0ZXMgd2l0aCBsZWFkaW5nIHplcm8gKDAw4oCTNTkpXG4gKiBtICAgIOKAlCBtaW51dGVzIHdpdGhvdXQgbGVhZGluZyB6ZXJvICgw4oCTNTkpXG4gKiBzcyAgIOKAlCBzZWNvbmRzIHdpdGggbGVhZGluZyB6ZXJvICgwMOKAkzU5KVxuICogcyAgICDigJQgc2Vjb25kcyB3aXRob3V0IGxlYWRpbmcgemVybyAoMOKAkzU5KVxuICogZGRkZCDigJQgZnVsbCBkYXkgb2Ygd2VlayBuYW1lIChNb25kYXnigJNTdW5kYXkpXG4gKiBkZGQgIOKAlCBhYmJyZXZpYXRlZCBkYXkgb2Ygd2VlayBuYW1lIChNb27igJNTdW4pXG4gKiBBICAgIOKAlCBBTS9QTSBkZXNpZ25hdGlvblxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gbWlsbGlzSW5wdXQg4oCUIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCDigJQgZm9ybWF0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ3xudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRNaWxsaXNUb0RhdGVTdHJpbmcoIG1pbGxpc0lucHV0LCBmb3JtYXQgPSAnWVlZWS1NTS1ERCcgKSB7XG5cdGNvbnN0IG1pbGxpcyA9IGV2YWwoIG1pbGxpc0lucHV0ICk7XG5cblx0aWYgKCAhbWlsbGlzIHx8IGlzTmFOKCBtaWxsaXMgKSB8fCBudWxsID09PSBtaWxsaXMgfHwgMCA9PT0gbWlsbGlzICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Y29uc3QgZGF0ZSA9IG5ldyBEYXRlKCBtaWxsaXMgKTtcblxuXHRjb25zdCBtb250aHNGdWxsID0gW1xuXHRcdCdKYW51YXJ5JywgJ0ZlYnJ1YXJ5JywgJ01hcmNoJywgJ0FwcmlsJywgJ01heScsICdKdW5lJyxcblx0XHQnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXG5cdF07XG5cdGNvbnN0IG1vbnRoc1Nob3J0ID0gbW9udGhzRnVsbC5tYXAoIG0gPT4gbS5zbGljZSggMCwgMyApICk7XG5cblx0Y29uc3QgZGF5c0Z1bGwgPSBbXG5cdFx0J1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLCAnVGh1cnNkYXknLCAnRnJpZGF5JywgJ1NhdHVyZGF5J1xuXHRdO1xuXG5cdGNvbnN0IGRheXNTaG9ydCA9IGRheXNGdWxsLm1hcCggZCA9PiBkLnNsaWNlKCAwLCAzICkgKTtcblxuXHRjb25zdCBob3VyczEyID0gZGF0ZS5nZXRIb3VycygpICUgMTIgfHwgMTI7IC8vIENvbnZlcnQgMCB0byAxMiBmb3IgMTItaG91ciBmb3JtYXRcblx0Y29uc3QgYW1wbSAgICA9IGRhdGUuZ2V0SG91cnMoKSA+PSAxMiA/ICdQTScgOiAnQU0nO1xuXG5cdGNvbnN0IG1hcCA9IHtcblx0XHRZWVlZOiBkYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0TU06IFN0cmluZyggZGF0ZS5nZXRNb250aCgpICsgMSApLnBhZFN0YXJ0KCAyLCAnMCcgKSxcblx0XHRNOiBkYXRlLmdldE1vbnRoKCkgKyAxLFxuXHRcdE1NTTogbW9udGhzU2hvcnRbIGRhdGUuZ2V0TW9udGgoKSBdLFxuXHRcdE1NTU06IG1vbnRoc0Z1bGxbIGRhdGUuZ2V0TW9udGgoKSBdLFxuXHRcdEREOiBTdHJpbmcoIGRhdGUuZ2V0RGF0ZSgpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdEQ6IGRhdGUuZ2V0RGF0ZSgpLFxuXHRcdEhIOiBTdHJpbmcoIGRhdGUuZ2V0SG91cnMoKSApLnBhZFN0YXJ0KCAyLCAnMCcgKSxcblx0XHRIOiBkYXRlLmdldEhvdXJzKCksXG5cdFx0aGg6IFN0cmluZyggaG91cnMxMiApLnBhZFN0YXJ0KCAyLCAnMCcgKSwgLy8gMTItaG91ciBmb3JtYXQgd2l0aCBsZWFkaW5nIHplcm9cblx0XHRoOiBob3VyczEyLCAvLyAxMi1ob3VyIGZvcm1hdCB3aXRob3V0IGxlYWRpbmcgemVyb1xuXHRcdG1tOiBTdHJpbmcoIGRhdGUuZ2V0TWludXRlcygpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdG06IGRhdGUuZ2V0TWludXRlcygpLFxuXHRcdHNzOiBTdHJpbmcoIGRhdGUuZ2V0U2Vjb25kcygpICkucGFkU3RhcnQoIDIsICcwJyApLFxuXHRcdHM6IGRhdGUuZ2V0U2Vjb25kcygpLFxuXHRcdGRkZGQ6IGRheXNGdWxsWyBkYXRlLmdldERheSgpIF0sXG5cdFx0ZGRkOiBkYXlzU2hvcnRbIGRhdGUuZ2V0RGF5KCkgXSxcblx0XHRBOiBhbXBtLCAvLyBBTS9QTVxuXHR9O1xuXG5cdGNvbnN0IHNvcnRlZEtleXMgPSBPYmplY3Qua2V5cyggbWFwICkuc29ydCggKCBhLCBiICkgPT4gYi5sZW5ndGggLSBhLmxlbmd0aCApO1xuXG5cdC8vIFVzZSB0ZW1wb3JhcnkgcGxhY2Vob2xkZXJzIHRvIHByZXZlbnQgY29uZmxpY3RzXG5cdGxldCBmb3JtYXR0ZWQgPSBmb3JtYXQ7XG5cdGNvbnN0IHBsYWNlaG9sZGVycyA9IHt9O1xuXG5cdC8vIEZpcnN0IHBhc3M6IHJlcGxhY2UgZm9ybWF0IHRva2VucyB3aXRoIHVuaXF1ZSBwbGFjZWhvbGRlcnNcblx0c29ydGVkS2V5cy5mb3JFYWNoKCAoIGtleSwgaW5kZXggKSA9PiB7XG5cdFx0Y29uc3QgcGxhY2Vob2xkZXIgPSBgXFx4MDAke2luZGV4fVxceDAwYDsgLy8gVXNlIGluZGV4LWJhc2VkIHVuaXF1ZSBpZGVudGlmaWVyXG5cdFx0cGxhY2Vob2xkZXJzW3BsYWNlaG9sZGVyXSA9IFN0cmluZyggbWFwW2tleV0gKTtcblxuXHRcdC8vIFVzZSB3b3JkIGJvdW5kYXJpZXMgZm9yIHNpbmdsZS1sZXR0ZXIgdG9rZW5zIHRvIGF2b2lkIHJlcGxhY2luZyBsZXR0ZXJzIGluIHRleHRcblx0XHRjb25zdCBwYXR0ZXJuID0ga2V5Lmxlbmd0aCA8PSAyICYmIC9eW2EtekEtWl0rJC8udGVzdCgga2V5IClcblx0XHRcdD8gbmV3IFJlZ0V4cCggYFxcXFxiJHtrZXl9XFxcXGJgLCAnZycgKVxuXHRcdFx0OiBuZXcgUmVnRXhwKCBrZXksICdnJyApO1xuXG5cdFx0Zm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoIHBhdHRlcm4sIHBsYWNlaG9sZGVyICk7XG5cdH0gKTtcblxuXHQvLyBTZWNvbmQgcGFzczogcmVwbGFjZSBwbGFjZWhvbGRlcnMgd2l0aCBhY3R1YWwgdmFsdWVzXG5cdGZvciAoIGNvbnN0IFtwbGFjZWhvbGRlciwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKCBwbGFjZWhvbGRlcnMgKSApIHtcblx0XHRmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQuc3BsaXQoIHBsYWNlaG9sZGVyICkuam9pbiggdmFsdWUgKTtcblx0fVxuXG5cdHJldHVybiBmb3JtYXR0ZWQ7XG59XG5cbmV4cG9ydCB7IGlzQ2FsY3VsYXRlZCwgZ2V0Q2FsY3VsYXRlZFdyYXBwZXIsIGNvbnZlcnRNaWxsaXNUb0RhdGVTdHJpbmcgfTsiLCJpbXBvcnQgeyBnZXRDYWxjdWxhdGVkV3JhcHBlciwgaXNDYWxjdWxhdGVkLCBjb252ZXJ0TWlsbGlzVG9EYXRlU3RyaW5nIH0gZnJvbSAnLi9mdW5jdGlvbnMnO1xuXG5jb25zdCB7XG5cdCAgICAgIElucHV0RGF0YSxcblx0ICAgICAgQ2FsY3VsYXRlZEZvcm11bGEsXG4gICAgICB9ID0gd2luZG93LkpldEZvcm1CdWlsZGVyQWJzdHJhY3Q7XG5jb25zdCB7XG5cdCAgICAgIGFwcGx5RmlsdGVycyxcbiAgICAgIH0gPSBKZXRQbHVnaW5zLmhvb2tzO1xuXG5jb25zdCB7XG5cdCAgICAgIGFwcGx5RmlsdGVyczogZGVwcmVjYXRlZEFwcGx5RmlsdGVycyA9IGZhbHNlLFxuICAgICAgfSA9IHdpbmRvdz8uSmV0Rm9ybUJ1aWxkZXJNYWluPy5maWx0ZXJzID8/IHt9O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxpbmVzLXBlci1mdW5jdGlvblxuZnVuY3Rpb24gQ2FsY3VsYXRlZERhdGEoKSB7XG5cdElucHV0RGF0YS5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5mb3JtdWxhICAgICAgICA9ICcnO1xuXHR0aGlzLnByZWNpc2lvbiAgICAgID0gMDtcblx0dGhpcy5zZXBEZWNpbWFsICAgICA9ICcnO1xuXHR0aGlzLnNlcFRob3VzYW5kcyAgID0gJyc7XG5cdHRoaXMudmlzaWJsZVZhbE5vZGUgPSBudWxsO1xuXHR0aGlzLnZhbHVlVHlwZVByb3AgID0gJ251bWJlcic7XG5cblx0dGhpcy5pc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICggbm9kZSApIHtcblx0XHRyZXR1cm4gaXNDYWxjdWxhdGVkKCBub2RlICk7XG5cdH07XG5cdHRoaXMuc2V0VmFsdWUgICAgPSBmdW5jdGlvbiAoKSB7XG5cdFx0Y29uc3QgZm9ybXVsYSA9IG5ldyBDYWxjdWxhdGVkRm9ybXVsYSggdGhpcywgeyBmb3JjZUZ1bmN0aW9uOiB0cnVlIH0gKTtcblxuXHRcdGZvcm11bGEub2JzZXJ2ZSggdGhpcy5mb3JtdWxhICk7XG5cdFx0Zm9ybXVsYS5zZXRSZXN1bHQgICAgICAgPSAoKSA9PiB7XG5cdFx0XHRpZiAoICdkYXRlJyA9PT0gdGhpcy52YWx1ZVR5cGVQcm9wICkge1xuXHRcdFx0XHRjb25zdCBkYXRlX2Zvcm11bGEgPSBmb3JtdWxhLmNhbGN1bGF0ZSgpO1xuXHRcdFx0XHR0aGlzLnZhbHVlLmN1cnJlbnQgPSBjb252ZXJ0TWlsbGlzVG9EYXRlU3RyaW5nKCBkYXRlX2Zvcm11bGEsIHRoaXMuZGF0ZUZvcm1hdCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy52YWx1ZS5jdXJyZW50ID0gZm9ybXVsYS5jYWxjdWxhdGUoKTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGZvcm11bGEucmVsYXRlZENhbGxiYWNrID0gKCBpbnB1dCApID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlID0gYXBwbHlGaWx0ZXJzKFxuXHRcdFx0XHQnamV0LmZiLmNhbGN1bGF0ZWQuY2FsbGJhY2snLFxuXHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0aW5wdXQsXG5cdFx0XHRcdHRoaXMsXG5cdFx0XHQpO1xuXG5cdFx0XHRpZiAoIGZhbHNlICE9PSB2YWx1ZSApIHtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCByZXNwb25zZSA9ICdudW1iZXInID09PSB0aGlzLnZhbHVlVHlwZVByb3Bcblx0XHRcdCAgICAgICAgICAgICAgICAgPyBpbnB1dC5jYWxjVmFsdWVcblx0XHRcdCAgICAgICAgICAgICAgICAgOiBpbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdFx0XHRpZiAoIGZhbHNlID09PSBkZXByZWNhdGVkQXBwbHlGaWx0ZXJzICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzcG9uc2U7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGZpbHRlclJlc3VsdCA9IGRlcHJlY2F0ZWRBcHBseUZpbHRlcnMoXG5cdFx0XHRcdCdmb3Jtcy9jYWxjdWxhdGVkLWZpZWxkLXZhbHVlJyxcblx0XHRcdFx0aW5wdXQudmFsdWUuY3VycmVudCxcblx0XHRcdFx0alF1ZXJ5KCBpbnB1dC5ub2Rlc1sgMCBdICksXG5cdFx0XHQpO1xuXG5cdFx0XHRyZXR1cm4gZmlsdGVyUmVzdWx0ID09PSBpbnB1dC52YWx1ZS5jdXJyZW50XG5cdFx0XHQgICAgICAgPyByZXNwb25zZVxuXHRcdFx0ICAgICAgIDogZmlsdGVyUmVzdWx0O1xuXHRcdH07XG5cblx0XHRmb3JtdWxhLmVtcHR5VmFsdWUgPSAoKSA9PiAnbnVtYmVyJyA9PT0gdGhpcy52YWx1ZVR5cGVQcm9wXG5cdFx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG5cdFx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJztcblx0XHRmb3JtdWxhLnNldFJlc3VsdCgpO1xuXHRcdHRoaXMudmFsdWUuY3VycmVudCA9IHRoaXMudmFsdWUuYXBwbHlTYW5pdGl6ZXJzKCB0aGlzLnZhbHVlLmN1cnJlbnQgKTtcblxuXHRcdHRoaXMuYmVmb3JlU3VibWl0KCAoIHJlc29sdmUgKSA9PiB7XG5cdFx0XHR0aGlzLnZhbHVlLnNpbGVuY2UoKTtcblx0XHRcdHRoaXMudmFsdWUuY3VycmVudCA9IG51bGw7XG5cdFx0XHR0aGlzLnZhbHVlLnNpbGVuY2UoKTtcblxuXHRcdFx0Zm9ybXVsYS5zZXRSZXN1bHQoKTtcblx0XHRcdHJlc29sdmUoKTtcblx0XHR9LCB0aGlzICk7XG5cdH07XG5cblx0dGhpcy5zZXROb2RlICAgICAgPSBmdW5jdGlvbiAoIG5vZGUgKSB7XG5cdFx0SW5wdXREYXRhLnByb3RvdHlwZS5zZXROb2RlLmNhbGwoIHRoaXMsIG5vZGUgKTtcblx0XHRJbnB1dERhdGEucHJvdG90eXBlLnJlUXVlcnlWYWx1ZSA9ICgpID0+IHt9O1xuXG5cdFx0Y29uc3Qge1xuXHRcdFx0ICAgICAgZm9ybXVsYSxcblx0XHRcdCAgICAgIHByZWNpc2lvbixcblx0XHRcdCAgICAgIHNlcERlY2ltYWwsXG5cdFx0XHQgICAgICB2YWx1ZVR5cGUsXG5cdFx0XHQgICAgICBzZXBUaG91c2FuZHMsXG5cdFx0XHQgICAgICBkYXRlRm9ybWF0LFxuXHRcdCAgICAgIH0gPSBnZXRDYWxjdWxhdGVkV3JhcHBlciggbm9kZSApLmRhdGFzZXQ7XG5cblx0XHR0aGlzLmZvcm11bGEgICAgICAgID0gZm9ybXVsYTtcblx0XHR0aGlzLnByZWNpc2lvbiAgICAgID0gK3ByZWNpc2lvbjtcblx0XHR0aGlzLnNlcERlY2ltYWwgICAgID0gc2VwRGVjaW1hbCA/PyAnJztcblx0XHR0aGlzLnNlcFRob3VzYW5kcyAgID0gc2VwVGhvdXNhbmRzID8/ICcnO1xuXHRcdHRoaXMudmlzaWJsZVZhbE5vZGUgPSBub2RlLm5leHRFbGVtZW50U2libGluZztcblx0XHR0aGlzLnZhbHVlVHlwZVByb3AgID0gdmFsdWVUeXBlO1xuXHRcdHRoaXMuZGF0ZUZvcm1hdCAgICAgPSBkYXRlRm9ybWF0O1xuXHRcdHRoaXMuaW5wdXRUeXBlICAgICAgPSAnY2FsY3VsYXRlZCc7XG5cdH07XG5cdHRoaXMuYWRkTGlzdGVuZXJzID0gZnVuY3Rpb24gKCkge1xuXHRcdC8vIHNpbGVuY2UgaXMgZ29sZGVuXG5cdH07XG5cblx0Ly8gY2FsY3VsYXRlZCBmaWVsZCBjYW4ndCBiZSB2YWxpZGF0ZWRcblx0dGhpcy5yZXBvcnQgPSAoKSA9PiB7fTtcblxuXHR0aGlzLnJlUXVlcnlWYWx1ZSA9ICgpID0+IHt9O1xuXG5cdHRoaXMucmV2ZXJ0VmFsdWUgPSAoKSA9PiB7fTtcbn1cblxuQ2FsY3VsYXRlZERhdGEucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggSW5wdXREYXRhLnByb3RvdHlwZSApO1xuXG5leHBvcnQgZGVmYXVsdCBDYWxjdWxhdGVkRGF0YTtcbiIsImltcG9ydCB7IGlzQ2FsY3VsYXRlZCB9IGZyb20gJy4vZnVuY3Rpb25zJztcblxuY29uc3Qge1xuXHQgICAgICBCYXNlU2lnbmFsLFxuICAgICAgfSA9IHdpbmRvdy5KZXRGb3JtQnVpbGRlckFic3RyYWN0O1xuXG4vKipcbiAqIEBwcm9wZXJ0eSB7Q2FsY3VsYXRlZERhdGF9IGlucHV0IFJlbGF0ZWQgaW5wdXQgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gU2lnbmFsQ2FsY3VsYXRlZCgpIHtcblx0QmFzZVNpZ25hbC5jYWxsKCB0aGlzICk7XG5cblx0dGhpcy5pc1N1cHBvcnRlZCA9IGZ1bmN0aW9uICggbm9kZSApIHtcblx0XHRyZXR1cm4gaXNDYWxjdWxhdGVkKCBub2RlICk7XG5cdH07XG5cblx0dGhpcy5iYXNlU2lnbmFsID0gZnVuY3Rpb24gKCkge1xuXHRcdGNvbnN0IFsgbm9kZSBdID0gdGhpcy5pbnB1dC5ub2RlcztcblxuXHRcdGNvbnN0IGlzTnVtYmVyID0gJ251bWJlcicgPT09IHRoaXMuaW5wdXQudmFsdWVUeXBlUHJvcDtcblxuXHRcdHRoaXMuaW5wdXQuY2FsY1ZhbHVlID0gaXNOdW1iZXJcblx0XHQgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy53aXRoUHJlY2lzaW9uKClcblx0XHQgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdFx0dGhpcy5pbnB1dC52YWx1ZS5zaWxlbmNlKCk7XG5cdFx0dGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50ID0gaXNOdW1iZXJcblx0XHQgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuY29udmVydFZhbHVlKClcblx0XHQgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuaW5wdXQudmFsdWUuY3VycmVudDtcblx0XHR0aGlzLmlucHV0LnZhbHVlLnNpbGVuY2UoKTtcblxuXHRcdHRoaXMuaW5wdXQudmlzaWJsZVZhbE5vZGUudGV4dENvbnRlbnQgPSB0aGlzLmlucHV0LnZhbHVlLmN1cnJlbnQ7XG5cblx0XHRub2RlLnZhbHVlID0gdGhpcy5pbnB1dC5jYWxjVmFsdWU7XG5cdH07XG5cblx0dGhpcy5ydW5TaWduYWwgPSBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5iYXNlU2lnbmFsKCk7XG5cblx0XHRjb25zdCBbIG5vZGUgXSA9IHRoaXMuaW5wdXQubm9kZXM7XG5cblx0XHR0aGlzLnRyaWdnZXJKUXVlcnkoIG5vZGUgKTtcblx0fTtcbn1cblxuU2lnbmFsQ2FsY3VsYXRlZC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBCYXNlU2lnbmFsLnByb3RvdHlwZSApO1xuXG5TaWduYWxDYWxjdWxhdGVkLnByb3RvdHlwZS5jb252ZXJ0VmFsdWUgPSBmdW5jdGlvbiAoKSB7XG5cdGNvbnN0IHZhbHVlID0gdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50O1xuXG5cdGlmICggTnVtYmVyLmlzTmFOKCBOdW1iZXIoIHZhbHVlICkgKSApIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdGNvbnN0IHBhcnRzID0gdGhpcy53aXRoUHJlY2lzaW9uKCkudG9TdHJpbmcoKS5zcGxpdCggJy4nICk7XG5cblx0aWYgKCB0aGlzLmlucHV0LnNlcFRob3VzYW5kcyApIHtcblx0XHRwYXJ0c1sgMCBdID0gcGFydHNbIDAgXS5yZXBsYWNlKFxuXHRcdFx0L1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csXG5cdFx0XHR0aGlzLmlucHV0LnNlcFRob3VzYW5kcyxcblx0XHQpO1xuXHR9XG5cblx0cmV0dXJuIHBhcnRzLmpvaW4oIHRoaXMuaW5wdXQuc2VwRGVjaW1hbCApO1xufTtcblxuU2lnbmFsQ2FsY3VsYXRlZC5wcm90b3R5cGUud2l0aFByZWNpc2lvbiA9IGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIE51bWJlciggdGhpcy5pbnB1dC52YWx1ZS5jdXJyZW50ICkudG9GaXhlZCggdGhpcy5pbnB1dC5wcmVjaXNpb24gKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNpZ25hbENhbGN1bGF0ZWQ7IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRpZiAoIShtb2R1bGVJZCBpbiBfX3dlYnBhY2tfbW9kdWxlc19fKSkge1xuXHRcdGRlbGV0ZSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRcdHZhciBlID0gbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIiArIG1vZHVsZUlkICsgXCInXCIpO1xuXHRcdGUuY29kZSA9ICdNT0RVTEVfTk9UX0ZPVU5EJztcblx0XHR0aHJvdyBlO1xuXHR9XG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsImltcG9ydCBDYWxjdWxhdGVkRGF0YSBmcm9tICcuL2lucHV0JztcbmltcG9ydCBTaWduYWxDYWxjdWxhdGVkIGZyb20gJy4vc2lnbmFsJztcblxuY29uc3QgeyBhZGRGaWx0ZXIgfSA9IEpldFBsdWdpbnMuaG9va3M7XG5cbmFkZEZpbHRlcihcblx0J2pldC5mYi5pbnB1dHMnLFxuXHQnamV0LWZvcm0tYnVpbGRlci9jYWxjdWxhdGVkLWZpZWxkJyxcblx0ZnVuY3Rpb24gKCBpbnB1dHMgKSB7XG5cdFx0aW5wdXRzID0gWyBDYWxjdWxhdGVkRGF0YSwgLi4uaW5wdXRzIF07XG5cblx0XHRyZXR1cm4gaW5wdXRzO1xuXHR9LFxuKTtcblxuYWRkRmlsdGVyKFxuXHQnamV0LmZiLnNpZ25hbHMnLFxuXHQnamV0LWZvcm0tYnVpbGRlci9jYWxjdWxhdGVkLWZpZWxkJyxcblx0ZnVuY3Rpb24gKCBzaWduYWxzICkge1xuXHRcdHNpZ25hbHMgPSBbIFNpZ25hbENhbGN1bGF0ZWQsIC4uLnNpZ25hbHMgXTtcblxuXHRcdHJldHVybiBzaWduYWxzO1xuXHR9LFxuKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=